|
|
|
|
@ -28,23 +28,19 @@
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 新增规则 Modal -->
|
|
|
|
|
<Modal v-model="showModal" title="新增维护规则" @on-ok="handleSubmit" @on-cancel="handleCancel">
|
|
|
|
|
<Modal v-model="showModal" title="新增维护规则" :footer="null" @on-cancel="handleCancel">
|
|
|
|
|
<Form ref="form" :model="form" :rules="rules" :label-width="120">
|
|
|
|
|
<FormItem label="规则名称" prop="name">
|
|
|
|
|
<Input v-model="form.name" placeholder="请输入规则名称"></Input>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="重复周期" prop="cycle">
|
|
|
|
|
<Select v-model="form.cycle">
|
|
|
|
|
<Option value="monthly">每月</Option>
|
|
|
|
|
<Option value="quarterly">每季度</Option>
|
|
|
|
|
<Option value="half">每半年</Option>
|
|
|
|
|
<Option value="yearly">每年</Option>
|
|
|
|
|
<Option v-for="item in cycleOptions" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="起始日期设定" prop="startSetting">
|
|
|
|
|
<Select v-model="form.startSetting">
|
|
|
|
|
<Option value="specific_date">从每年第一天开始运算</Option>
|
|
|
|
|
<Option value="first_association">首次关联物资时</Option>
|
|
|
|
|
<Option v-for="item in startStandardOptions" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="生成计划时机" prop="timing">
|
|
|
|
|
@ -60,14 +56,17 @@
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="未完成时下次计划" prop="nextPlan">
|
|
|
|
|
<Select v-model="form.nextPlan">
|
|
|
|
|
<Option value="skip">暂停生成(直到上次计划已经执行完成)</Option>
|
|
|
|
|
<Option value="force">强制生成(忽略未完成状态)</Option>
|
|
|
|
|
<Option v-for="item in nextPlanOptions" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="备注" prop="notes">
|
|
|
|
|
<Input v-model="form.notes" type="textarea" :rows="3" placeholder="请输入备注"></Input>
|
|
|
|
|
</FormItem>
|
|
|
|
|
</Form>
|
|
|
|
|
<div slot="footer" style="text-align: right;">
|
|
|
|
|
<Button @click="handleCancel">取消</Button>
|
|
|
|
|
<Button type="primary" @click="handleCustomSubmit" style="margin-left: 8px;">确定</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
<!-- 编辑规则 Modal -->
|
|
|
|
|
@ -78,16 +77,12 @@
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="重复周期" prop="cycle">
|
|
|
|
|
<Select v-model="editForm.cycle">
|
|
|
|
|
<Option value="monthly">每月</Option>
|
|
|
|
|
<Option value="quarterly">每季度</Option>
|
|
|
|
|
<Option value="half">每半年</Option>
|
|
|
|
|
<Option value="yearly">每年</Option>
|
|
|
|
|
<Option v-for="item in cycleOptions" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="起始日期设定" prop="startSetting">
|
|
|
|
|
<Select v-model="editForm.startSetting">
|
|
|
|
|
<Option value="specific_date">从每年第一天开始运算</Option>
|
|
|
|
|
<Option value="first_association">首次关联物资时</Option>
|
|
|
|
|
<Option v-for="item in startStandardOptions" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="生成计划时机" prop="timing">
|
|
|
|
|
@ -103,8 +98,7 @@
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="未完成时下次计划" prop="nextPlan">
|
|
|
|
|
<Select v-model="editForm.nextPlan">
|
|
|
|
|
<Option value="skip">暂停生成(直到上次计划已经执行完成)</Option>
|
|
|
|
|
<Option value="force">强制生成(忽略未完成状态)</Option>
|
|
|
|
|
<Option v-for="item in nextPlanOptions" :key="item.value" :value="item.value">{{ item.label }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</FormItem>
|
|
|
|
|
<FormItem label="备注" prop="notes">
|
|
|
|
|
@ -113,29 +107,83 @@
|
|
|
|
|
</Form>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
<!-- 删除确认 Modal -->
|
|
|
|
|
<Modal v-model="showDeleteModal" title="删除确认" @on-ok="handleDeleteConfirm" @on-cancel="handleDeleteCancel">
|
|
|
|
|
<p>确定要删除该维护规则吗?此操作不可恢复。</p>
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
<!-- 关联物资 Modal -->
|
|
|
|
|
<Modal v-model="showAssociateModal" title="关联物资" @on-ok="handleAssociateSubmit" @on-cancel="handleAssociateCancel">
|
|
|
|
|
<Modal v-model="showAssociateModal" title="关联物资" @on-ok="handleAssociateSubmit" @on-cancel="handleAssociateCancel" width="1000">
|
|
|
|
|
<div class="associate-content">
|
|
|
|
|
<div class="search-box">
|
|
|
|
|
<Input v-model="associateSearch" placeholder="搜索物资" style="width: 200px; margin-bottom: 16px;"></Input>
|
|
|
|
|
<div class="associate-toolbar">
|
|
|
|
|
<Input v-model="associateSearch" placeholder="搜索物资名称..." style="width: 250px; margin-right: 10px;" clearable></Input>
|
|
|
|
|
<Select v-model="select.storehouses_id" @on-change="getWarehouseNames" style="width: 120px; margin-right: 10px;" clearable placeholder="仓库类型">
|
|
|
|
|
<Option v-for="item in warehouseTypes" :key="item.id" :value="item.id">{{ item.name }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
<Select v-model="select.area" @on-change="getWarehouseNames" style="width: 120px; margin-right: 10px;" clearable placeholder="所在区域">
|
|
|
|
|
<Option v-for="item in warehouseAreas" :key="item.id" :value="item.id">{{ item.value }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
<Select v-model="associateWarehouseName" style="width: 120px; margin-right: 10px;" clearable placeholder="仓库名称">
|
|
|
|
|
<Option v-for="warehouse in warehouseNames" :key="warehouse.value" :value="warehouse.value">{{ warehouse.label }}</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
<Button type="primary" @click="searchMaterialsPost">搜索</Button>
|
|
|
|
|
<Button style="margin-left: 8px;" @click="resetAssociateSearch">重置</Button>
|
|
|
|
|
</div>
|
|
|
|
|
<Table :columns="associateColumns" :data="associateList" :height="400">
|
|
|
|
|
<template slot-scope="{ row }" slot="selection">
|
|
|
|
|
<Checkbox v-model="row.selected"></Checkbox>
|
|
|
|
|
<Table :columns="associateColumns" :data="associateList" :height="400" style="margin-top: 15px;">
|
|
|
|
|
<template slot-scope="{ row }" slot="action">
|
|
|
|
|
<div style="display: flex; gap: 8px; justify-content: center;">
|
|
|
|
|
<Button
|
|
|
|
|
v-if="row.equipment_maintain_config && row.equipment_maintain_config.id === currentRule.id"
|
|
|
|
|
type="error"
|
|
|
|
|
size="small"
|
|
|
|
|
style="border-radius: 6px;"
|
|
|
|
|
@click="toggleAssociation(row)"
|
|
|
|
|
:title="row.equipment_maintain_config ? `已关联规则: ${row.equipment_maintain_config.name}` : ''"
|
|
|
|
|
>
|
|
|
|
|
解除绑定
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
v-else-if="row.equipment_maintain_config"
|
|
|
|
|
type="warning"
|
|
|
|
|
size="small"
|
|
|
|
|
style="border-radius: 6px;"
|
|
|
|
|
@click="toggleAssociation(row)"
|
|
|
|
|
:title="row.equipment_maintain_config ? `已关联规则: ${row.equipment_maintain_config.name}` : ''"
|
|
|
|
|
>
|
|
|
|
|
重新绑定
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
v-else
|
|
|
|
|
type="primary"
|
|
|
|
|
size="small"
|
|
|
|
|
style="border-radius: 6px;"
|
|
|
|
|
@click="toggleAssociation(row)"
|
|
|
|
|
>
|
|
|
|
|
绑定
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</Table>
|
|
|
|
|
<div class="pagination-container">
|
|
|
|
|
<el-pagination
|
|
|
|
|
@size-change="handleAssociatePageSizeChange"
|
|
|
|
|
@current-change="handleAssociatePageChange"
|
|
|
|
|
:current-page="associateCurrentPage"
|
|
|
|
|
:page-sizes="[10, 20, 50, 100]"
|
|
|
|
|
:page-size="associatePageSize"
|
|
|
|
|
layout="total, sizes, prev, pager, next, jumper"
|
|
|
|
|
:total="associateTotal"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Modal>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { Button, Modal, Form, FormItem, Input, Select, Option, InputNumber, Table, Checkbox } from 'view-design';
|
|
|
|
|
import { Button, Modal, Form, FormItem, Input, Select, Option, InputNumber, Table, Checkbox, Page } from 'view-design';
|
|
|
|
|
import { getStorehouseTypeList } from '@/api/system/storehouseType';
|
|
|
|
|
import { getparameteritem } from "@/api/system/dictionary.js";
|
|
|
|
|
import { index } from "@/api/system/baseForm.js";
|
|
|
|
|
import { saveMaintainConfig, getMaintainConfigList, deleteMaintainConfig } from '@/api/maintenance/maintenance.js';
|
|
|
|
|
import { saveStocksItem } from '@/api/stocks-item.js';
|
|
|
|
|
import request from '@/utils/request';
|
|
|
|
|
import qs from 'qs';
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
components: {
|
|
|
|
|
@ -148,29 +196,47 @@ export default {
|
|
|
|
|
Option,
|
|
|
|
|
InputNumber,
|
|
|
|
|
Table,
|
|
|
|
|
Checkbox
|
|
|
|
|
Checkbox,
|
|
|
|
|
Page
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
select: {
|
|
|
|
|
page: 1,
|
|
|
|
|
page_size: 10,
|
|
|
|
|
page_size: 999,
|
|
|
|
|
keyword: '',
|
|
|
|
|
table_name: 'materialstorages',
|
|
|
|
|
area: '',
|
|
|
|
|
storehouses_id: ''
|
|
|
|
|
},
|
|
|
|
|
total: 0,
|
|
|
|
|
list: [],
|
|
|
|
|
cycleOptions: [
|
|
|
|
|
{ value: '1', label: '每月' },
|
|
|
|
|
{ value: '3', label: '每季度' },
|
|
|
|
|
{ value: '6', label: '每半年' },
|
|
|
|
|
{ value: '12', label: '每年' }
|
|
|
|
|
],
|
|
|
|
|
startStandardOptions: [
|
|
|
|
|
{ value: '1', label: '从每年第一天开始运算' },
|
|
|
|
|
{ value: '2', label: '首次关联物资时' }
|
|
|
|
|
],
|
|
|
|
|
nextPlanOptions: [
|
|
|
|
|
{ value: '1', label: '暂停生成(直到上次计划已经执行完成)' },
|
|
|
|
|
{ value: '2', label: '强制生成(忽略未完成状态)' }
|
|
|
|
|
],
|
|
|
|
|
table: [
|
|
|
|
|
{ label: '序号', type: 'index', width: 60 },
|
|
|
|
|
{ label: '规则名称', prop: 'name', minWidth: 160 },
|
|
|
|
|
{ label: '重复周期', prop: 'cycle', minWidth: 120 },
|
|
|
|
|
{ label: '起始日期设定', prop: 'startSetting', minWidth: 160 },
|
|
|
|
|
{ label: '生成计划时机', prop: 'timing', minWidth: 120 },
|
|
|
|
|
{ label: '已用于物资数', prop: 'materialCount', minWidth: 120 },
|
|
|
|
|
{ label: '未完成时下次计划', prop: 'nextPlan', minWidth: 160 }
|
|
|
|
|
{ label: '重复周期', prop: 'month_frequency', minWidth: 120, formatter: row => this.cycleOptions.find(opt => opt.value == row.month_frequency)?.label || row.month_frequency },
|
|
|
|
|
{ label: '起始日期设定', prop: 'start_standard', minWidth: 160, formatter: row => this.startStandardOptions.find(opt => opt.value == row.start_standard)?.label || row.start_standard },
|
|
|
|
|
{ label: '生成计划时机(天)', prop: 'advance_days', minWidth: 120 },
|
|
|
|
|
{ label: '已用于物资数', prop: 'stocks_items_count', minWidth: 120 },
|
|
|
|
|
{ label: '未完成时下次计划', prop: 'next_plan_type', minWidth: 160, formatter: row => this.nextPlanOptions.find(opt => opt.value == row.next_plan_type)?.label || row.next_plan_type },
|
|
|
|
|
],
|
|
|
|
|
tableHeight: 550,
|
|
|
|
|
showModal: false,
|
|
|
|
|
showEditModal: false,
|
|
|
|
|
showDeleteModal: false,
|
|
|
|
|
showAssociateModal: false,
|
|
|
|
|
form: {
|
|
|
|
|
name: '',
|
|
|
|
|
@ -199,47 +265,59 @@ export default {
|
|
|
|
|
nextPlan: [{ required: true, message: '请选择未完成时下次计划', trigger: 'change' }]
|
|
|
|
|
},
|
|
|
|
|
associateSearch: '',
|
|
|
|
|
associateWarehouseName: '',
|
|
|
|
|
associatePageSize: 100,
|
|
|
|
|
associateCurrentPage: 1,
|
|
|
|
|
associateTotal: 0,
|
|
|
|
|
associateColumns: [
|
|
|
|
|
{
|
|
|
|
|
type: 'selection',
|
|
|
|
|
width: 60,
|
|
|
|
|
align: 'center'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '物资名称',
|
|
|
|
|
key: 'name',
|
|
|
|
|
key: 'zichanmingcheng',
|
|
|
|
|
minWidth: 120
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '物资编号',
|
|
|
|
|
key: 'code',
|
|
|
|
|
title: '物资代码',
|
|
|
|
|
key: 'wuzibianma',
|
|
|
|
|
minWidth: 120
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '仓库',
|
|
|
|
|
key: 'warehouse',
|
|
|
|
|
title: '规格型号',
|
|
|
|
|
key: 'guigexinghao',
|
|
|
|
|
minWidth: 120
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
associateList: [
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '3号水泵',
|
|
|
|
|
code: 'SB001',
|
|
|
|
|
warehouse: '外塘河仓库',
|
|
|
|
|
selected: false
|
|
|
|
|
title: '仓库名称',
|
|
|
|
|
key: 'material_info',
|
|
|
|
|
minWidth: 120,
|
|
|
|
|
render: (h, params) => {
|
|
|
|
|
return h('span', params.row.material_info?.suozaicangku || '');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '柴油发电机',
|
|
|
|
|
code: 'FD001',
|
|
|
|
|
warehouse: '胥口仓库',
|
|
|
|
|
selected: false
|
|
|
|
|
title: '操作',
|
|
|
|
|
slot: 'action',
|
|
|
|
|
width: 200,
|
|
|
|
|
fixed: 'right',
|
|
|
|
|
align: 'center',
|
|
|
|
|
headerAlign: 'center',
|
|
|
|
|
className: 'table-col-action'
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
currentRule: null
|
|
|
|
|
associateList: [],
|
|
|
|
|
currentRule: null,
|
|
|
|
|
ruleAssociations: new Map(),
|
|
|
|
|
warehouseTypes: [],
|
|
|
|
|
warehouseAreas: [],
|
|
|
|
|
warehouseNames: [],
|
|
|
|
|
allWarehouses: [],
|
|
|
|
|
currentWarehouseNames: []
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
this.getList()
|
|
|
|
|
this.getList();
|
|
|
|
|
this.getWarehouseTypes();
|
|
|
|
|
this.getWarehouseAreas();
|
|
|
|
|
this.getWarehouseNames();
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.calcTableHeight();
|
|
|
|
|
@ -248,39 +326,29 @@ export default {
|
|
|
|
|
beforeDestroy() {
|
|
|
|
|
window.removeEventListener('resize', this.calcTableHeight);
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
associateWarehouseArea(val) {
|
|
|
|
|
if (val) {
|
|
|
|
|
this.getWarehouseNames(val);
|
|
|
|
|
} else {
|
|
|
|
|
this.warehouseNames = [];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
async getList() {
|
|
|
|
|
try {
|
|
|
|
|
// TODO: 调用API获取数据
|
|
|
|
|
this.list = [
|
|
|
|
|
{
|
|
|
|
|
name: '水泵月度检查',
|
|
|
|
|
cycle: '每月',
|
|
|
|
|
startSetting: '每年第一天开始运算',
|
|
|
|
|
timing: '提前 7 天',
|
|
|
|
|
materialCount: 5,
|
|
|
|
|
nextPlan: '暂停生成'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '发电机季度保养',
|
|
|
|
|
cycle: '每季度',
|
|
|
|
|
startSetting: '首次关联物资时',
|
|
|
|
|
timing: '提前 14 天',
|
|
|
|
|
materialCount: 2,
|
|
|
|
|
nextPlan: '强制生成'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '挡板年度检修',
|
|
|
|
|
cycle: '每年',
|
|
|
|
|
startSetting: '每年第一天开始运算',
|
|
|
|
|
timing: '提前 30 天',
|
|
|
|
|
materialCount: 12,
|
|
|
|
|
nextPlan: '暂停生成'
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
this.total = this.list.length;
|
|
|
|
|
const res = await getMaintainConfigList({
|
|
|
|
|
page: this.select.page,
|
|
|
|
|
page_size: this.select.page_size,
|
|
|
|
|
// 可加其它筛选参数
|
|
|
|
|
});
|
|
|
|
|
if (res && res.data) {
|
|
|
|
|
this.list = res.data;
|
|
|
|
|
this.total = res.total;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.$message.error('获取维护规则失败');
|
|
|
|
|
this.$message.error('获取运维规则列表失败');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
pageChange(e) {
|
|
|
|
|
@ -298,15 +366,20 @@ export default {
|
|
|
|
|
this.tableHeight = Math.max(windowHeight - header - 100, minTableHeight);
|
|
|
|
|
},
|
|
|
|
|
showAddRuleModal() {
|
|
|
|
|
this.form = {
|
|
|
|
|
name: '',
|
|
|
|
|
cycle: '',
|
|
|
|
|
startSetting: '',
|
|
|
|
|
timingUnit: 'days',
|
|
|
|
|
timingValue: 7,
|
|
|
|
|
timingPeriod: 'days',
|
|
|
|
|
nextPlan: '',
|
|
|
|
|
notes: ''
|
|
|
|
|
};
|
|
|
|
|
this.showModal = true;
|
|
|
|
|
},
|
|
|
|
|
handleSubmit() {
|
|
|
|
|
this.$refs.form.validate((valid) => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
// TODO: 提交表单数据
|
|
|
|
|
this.$message.success('保存成功');
|
|
|
|
|
this.showModal = false;
|
|
|
|
|
this.getList();
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
if (this.$refs.form) {
|
|
|
|
|
this.$refs.form.resetFields();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
@ -318,13 +391,13 @@ export default {
|
|
|
|
|
this.currentRule = row;
|
|
|
|
|
this.editForm = {
|
|
|
|
|
name: row.name,
|
|
|
|
|
cycle: row.cycle,
|
|
|
|
|
startSetting: row.startSetting,
|
|
|
|
|
cycle: String(row.month_frequency),
|
|
|
|
|
startSetting: String(row.start_standard),
|
|
|
|
|
timingUnit: 'days',
|
|
|
|
|
timingValue: 7,
|
|
|
|
|
timingValue: row.advance_days,
|
|
|
|
|
timingPeriod: 'days',
|
|
|
|
|
nextPlan: row.nextPlan,
|
|
|
|
|
notes: row.notes || ''
|
|
|
|
|
nextPlan: String(row.next_plan_type),
|
|
|
|
|
notes: row.remark || ''
|
|
|
|
|
};
|
|
|
|
|
this.showEditModal = true;
|
|
|
|
|
},
|
|
|
|
|
@ -344,29 +417,295 @@ export default {
|
|
|
|
|
},
|
|
|
|
|
handleDelete(row) {
|
|
|
|
|
this.currentRule = row;
|
|
|
|
|
this.showDeleteModal = true;
|
|
|
|
|
},
|
|
|
|
|
handleDeleteConfirm() {
|
|
|
|
|
// TODO: 实现删除逻辑
|
|
|
|
|
this.$message.success('删除成功');
|
|
|
|
|
this.showDeleteModal = false;
|
|
|
|
|
this.getList();
|
|
|
|
|
},
|
|
|
|
|
handleDeleteCancel() {
|
|
|
|
|
this.showDeleteModal = false;
|
|
|
|
|
this.$confirm('确认要删除该维护规则吗?', '提示', {
|
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
|
type: 'warning'
|
|
|
|
|
}).then(async () => {
|
|
|
|
|
try {
|
|
|
|
|
await deleteMaintainConfig({ id: this.currentRule.id });
|
|
|
|
|
this.$message.success('删除成功');
|
|
|
|
|
this.getList();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.$message.error('删除失败');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
handleAssociate(row) {
|
|
|
|
|
this.currentRule = row;
|
|
|
|
|
this.showAssociateModal = true;
|
|
|
|
|
// 重置弹窗相关数据
|
|
|
|
|
this.associateSearch = '';
|
|
|
|
|
this.select.storehouses_id = '';
|
|
|
|
|
this.select.area = '';
|
|
|
|
|
this.associateWarehouseName = '';
|
|
|
|
|
this.associateCurrentPage = 1;
|
|
|
|
|
// 先关闭再打开,确保弹窗能弹出
|
|
|
|
|
this.showAssociateModal = false;
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.showAssociateModal = true;
|
|
|
|
|
this.loadAssociations();
|
|
|
|
|
this.searchMaterialsPost();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
loadAssociations() {
|
|
|
|
|
// Load saved associations from localStorage
|
|
|
|
|
const saved = localStorage.getItem('ruleAssociations');
|
|
|
|
|
if (saved) {
|
|
|
|
|
const parsed = JSON.parse(saved);
|
|
|
|
|
Object.entries(parsed).forEach(([ruleId, materials]) => {
|
|
|
|
|
this.ruleAssociations.set(ruleId, new Set(materials));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
saveAssociations() {
|
|
|
|
|
const serialized = {};
|
|
|
|
|
this.ruleAssociations.forEach((materials, ruleId) => {
|
|
|
|
|
serialized[ruleId] = Array.from(materials);
|
|
|
|
|
});
|
|
|
|
|
localStorage.setItem('ruleAssociations', JSON.stringify(serialized));
|
|
|
|
|
},
|
|
|
|
|
async searchMaterialsPost() {
|
|
|
|
|
try {
|
|
|
|
|
const data = {
|
|
|
|
|
page_size: this.associatePageSize,
|
|
|
|
|
page: this.associateCurrentPage,
|
|
|
|
|
'show_relation[0]': 'equipmentMaintainConfig',
|
|
|
|
|
'show_relation[1]': 'materialInfo.materialstorage',
|
|
|
|
|
'filter[0][key]': 'xianwuzimingcheng',
|
|
|
|
|
'filter[0][op]': 'like',
|
|
|
|
|
'filter[0][value]': this.associateSearch ? this.associateSearch : '',
|
|
|
|
|
'filter[1][key]': 'guanliancangku',
|
|
|
|
|
'filter[1][op]': 'eq',
|
|
|
|
|
'filter[1][value]': this.associateWarehouseName ? this.associateWarehouseName : '',
|
|
|
|
|
'filter[2][key]': 'quyu_id',
|
|
|
|
|
'filter[2][op]': 'eq',
|
|
|
|
|
'filter[2][value]': this.select.area ? this.select.area : '',
|
|
|
|
|
'filter[3][key]': 'wuzileixing',
|
|
|
|
|
'filter[3][op]': 'eq',
|
|
|
|
|
'filter[3][value]': '一类一码'
|
|
|
|
|
};
|
|
|
|
|
const res = await request({
|
|
|
|
|
url: '/api/admin/stocks-item/index',
|
|
|
|
|
method: 'post',
|
|
|
|
|
data: qs.stringify(data),
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (res && res.data) {
|
|
|
|
|
this.associateList = res.data.map(material => ({
|
|
|
|
|
...material,
|
|
|
|
|
selected: this.ruleAssociations.get(this.currentRule.id)?.has(material.id) || false
|
|
|
|
|
}));
|
|
|
|
|
this.associateTotal = res.total;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('获取防汛物资列表失败:', e);
|
|
|
|
|
this.$message.error('获取防汛物资列表失败');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async toggleAssociation(row) {
|
|
|
|
|
if (!this.currentRule) return;
|
|
|
|
|
|
|
|
|
|
if (row.equipment_maintain_config?.id === this.currentRule.id) {
|
|
|
|
|
// 解除绑定
|
|
|
|
|
try {
|
|
|
|
|
await saveStocksItem({
|
|
|
|
|
id: row.id,
|
|
|
|
|
equipment_maintain_config_id: null
|
|
|
|
|
});
|
|
|
|
|
this.$message.success(`已解除绑定物资"${row.material_info.suozaicangku}"`);
|
|
|
|
|
this.searchMaterialsPost();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.$message.error('解除绑定失败');
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 绑定
|
|
|
|
|
try {
|
|
|
|
|
await saveStocksItem({
|
|
|
|
|
id: row.id,
|
|
|
|
|
equipment_maintain_config_id: this.currentRule.id
|
|
|
|
|
});
|
|
|
|
|
this.$message.success(`已成功绑定物资"${row.material_info.suozaicangku}"`);
|
|
|
|
|
this.searchMaterialsPost();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.$message.error('绑定失败');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
updateMaterialCount() {
|
|
|
|
|
const count = this.ruleAssociations.get(this.currentRule.id)?.size || 0;
|
|
|
|
|
const index = this.list.findIndex(item => item.id === this.currentRule.id);
|
|
|
|
|
if (index !== -1) {
|
|
|
|
|
this.$set(this.list[index], 'materialCount', count);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
handleAssociatePageChange(page) {
|
|
|
|
|
this.associateCurrentPage = page;
|
|
|
|
|
this.searchMaterialsPost();
|
|
|
|
|
},
|
|
|
|
|
handleAssociateSubmit() {
|
|
|
|
|
// TODO: 实现关联物资逻辑
|
|
|
|
|
this.$message.success('关联成功');
|
|
|
|
|
this.showAssociateModal = false;
|
|
|
|
|
this.getList();
|
|
|
|
|
},
|
|
|
|
|
handleAssociateCancel() {
|
|
|
|
|
this.showAssociateModal = false;
|
|
|
|
|
},
|
|
|
|
|
handleAssociatePageSizeChange(size) {
|
|
|
|
|
this.associatePageSize = size;
|
|
|
|
|
this.associateCurrentPage = 1;
|
|
|
|
|
this.searchMaterialsPost();
|
|
|
|
|
},
|
|
|
|
|
resetAssociateSearch() {
|
|
|
|
|
this.associateSearch = '';
|
|
|
|
|
this.select.storehouses_id = '';
|
|
|
|
|
this.select.area = '';
|
|
|
|
|
this.associateCurrentPage = 1;
|
|
|
|
|
this.searchMaterialsPost();
|
|
|
|
|
},
|
|
|
|
|
async getWarehouseTypes() {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getStorehouseTypeList({
|
|
|
|
|
page: 1,
|
|
|
|
|
page_size: 999
|
|
|
|
|
});
|
|
|
|
|
if (res && res.data) {
|
|
|
|
|
this.warehouseTypes = res.data;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('获取仓库类型列表失败:', e);
|
|
|
|
|
this.$message.error('获取仓库类型列表失败');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async getWarehouseAreas() {
|
|
|
|
|
try {
|
|
|
|
|
const res = await getparameteritem("area");
|
|
|
|
|
if (res && res.detail) {
|
|
|
|
|
this.warehouseAreas = res.detail;
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('获取仓库区域列表失败:', e);
|
|
|
|
|
this.$message.error('获取仓库区域列表失败');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async getWarehouseNames() {
|
|
|
|
|
try {
|
|
|
|
|
const res = await index({
|
|
|
|
|
page_size: this.select.page_size,
|
|
|
|
|
page: this.select.page,
|
|
|
|
|
table_name: this.select.table_name,
|
|
|
|
|
filter: [{
|
|
|
|
|
key: 'cangkumingcheng',
|
|
|
|
|
op: 'like',
|
|
|
|
|
value: this.select.keyword ? this.select.keyword : ''
|
|
|
|
|
}, {
|
|
|
|
|
key: 'quyu_id',
|
|
|
|
|
op: 'eq',
|
|
|
|
|
value: this.select.area ? this.select.area : ''
|
|
|
|
|
}, {
|
|
|
|
|
key: 'storehouses_id',
|
|
|
|
|
op: 'eq',
|
|
|
|
|
value: this.select.storehouses_id ? this.select.storehouses_id : ''
|
|
|
|
|
}],
|
|
|
|
|
});
|
|
|
|
|
if (res && res.data) {
|
|
|
|
|
this.warehouseNames = res.data.map(warehouse => ({
|
|
|
|
|
value: warehouse.id,
|
|
|
|
|
label: warehouse.cangkumingcheng
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('获取仓库名称列表失败:', e);
|
|
|
|
|
this.$message.error('获取仓库名称列表失败');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
clearArea(e) {
|
|
|
|
|
this.select.area = e || '';
|
|
|
|
|
this.getWarehouseNames();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
clearType(e) {
|
|
|
|
|
this.select.storehouses_id = e || '';
|
|
|
|
|
this.getWarehouseNames();
|
|
|
|
|
},
|
|
|
|
|
async getAllWarehouses() {
|
|
|
|
|
try {
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append('page', 1);
|
|
|
|
|
formData.append('page_size', 999);
|
|
|
|
|
formData.append('table_name', 'materialstorages');
|
|
|
|
|
|
|
|
|
|
const res = await index(formData);
|
|
|
|
|
if (res && res.data) {
|
|
|
|
|
this.allWarehouses = res.data;
|
|
|
|
|
this.filterWarehouses();
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('获取仓库列表失败:', e);
|
|
|
|
|
this.$message.error('获取仓库列表失败');
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
filterWarehouses() {
|
|
|
|
|
let filtered = [...this.allWarehouses];
|
|
|
|
|
|
|
|
|
|
// 按仓库类型筛选
|
|
|
|
|
if (this.select.storehouses_id) {
|
|
|
|
|
filtered = filtered.filter(warehouse =>
|
|
|
|
|
warehouse.storehouses_id === this.select.storehouses_id
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 按区域筛选
|
|
|
|
|
if (this.select.area) {
|
|
|
|
|
filtered = filtered.filter(warehouse =>
|
|
|
|
|
warehouse.quyu_id === this.select.area
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新仓库名称列表
|
|
|
|
|
this.warehouseNames = filtered.map(warehouse => ({
|
|
|
|
|
value: warehouse.id,
|
|
|
|
|
label: warehouse.cangkumingcheng
|
|
|
|
|
}));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
clearArea(e) {
|
|
|
|
|
this.select.area = e || '';
|
|
|
|
|
this.filterWarehouses();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
clearType(e) {
|
|
|
|
|
this.select.storehouses_id = e || '';
|
|
|
|
|
this.filterWarehouses();
|
|
|
|
|
},
|
|
|
|
|
async handleCustomSubmit() {
|
|
|
|
|
this.$refs.form.validate(async (valid) => {
|
|
|
|
|
if (valid) {
|
|
|
|
|
const data = {
|
|
|
|
|
name: this.form.name,
|
|
|
|
|
month_frequency: this.form.cycle,
|
|
|
|
|
start_standard: this.form.startSetting,
|
|
|
|
|
advance_days: this.form.timingValue,
|
|
|
|
|
next_plan_type: this.form.nextPlan,
|
|
|
|
|
remark: this.form.notes,
|
|
|
|
|
equipment_maintain_config_stocks_items: this.selectedMaterialIds?.map(id => [ { stocks_item_id: id } ]) || []
|
|
|
|
|
};
|
|
|
|
|
try {
|
|
|
|
|
await saveMaintainConfig(data);
|
|
|
|
|
this.$message.success('保存成功');
|
|
|
|
|
this.showModal = false;
|
|
|
|
|
this.getList();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.$message.error('保存失败');
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this.$message.error('请填写所有必填项');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -407,4 +746,17 @@ export default {
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
}
|
|
|
|
|
.associate-toolbar {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
}
|
|
|
|
|
.pagination-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: flex-end;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-top: 15px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|