From 43f28a422544a3b0b4d9e630004ff4a939941c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= Date: Tue, 7 Apr 2026 17:40:01 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(=E5=BC=82=E5=B8=B8=E7=AE=A1=E7=90=86):?= =?UTF-8?q?=20=E9=87=8D=E6=9E=84=E5=BC=82=E5=B8=B8=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=B9=B6=E6=96=B0=E5=A2=9E=E5=A4=9A=E9=80=89?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增MutiSelect组件支持下拉多选和复选框两种模式 - 重构异常管理界面,支持直接在表格中编辑异常记录 - 优化钢卷信息展示,增加刷新功能 - 修改AbnormalForm组件,使用MutiSelect替代原有单选组件 - 确保异常记录列表始终显示至少10行,方便快速添加 --- klp-ui/src/components/MutiSelect/index.vue | 126 +++++++- klp-ui/src/main.js | 2 + .../wms/coil/components/AbnormalForm.vue | 60 +++- .../wms/coil/components/ExceptionManager.vue | 277 +++++++++++++++--- 4 files changed, 397 insertions(+), 68 deletions(-) diff --git a/klp-ui/src/components/MutiSelect/index.vue b/klp-ui/src/components/MutiSelect/index.vue index 489547fd..a06ee71c 100644 --- a/klp-ui/src/components/MutiSelect/index.vue +++ b/klp-ui/src/components/MutiSelect/index.vue @@ -1,10 +1,51 @@ - + \ No newline at end of file + + + \ No newline at end of file diff --git a/klp-ui/src/main.js b/klp-ui/src/main.js index 7cef69ae..c44635d5 100644 --- a/klp-ui/src/main.js +++ b/klp-ui/src/main.js @@ -46,6 +46,7 @@ import VueMeta from 'vue-meta' import DictData from '@/components/DictData' import KLPTable from '@/components/KLPUI/KLPTable/index.vue' import MemoInput from '@/components/MemoInput/index.vue' +import MutiSelect from '@/components/MutiSelect/index.vue' import CurrentCoilNo from '@/components/KLPService/Renderer/CurrentCoilNo.vue' import DictSelect from '@/components/DictSelect' @@ -81,6 +82,7 @@ Vue.component('ImageUpload', ImageUpload) Vue.component('ImagePreview', ImagePreview) Vue.component('KLPTable', KLPTable) Vue.component('MemoInput', MemoInput) +Vue.component('MutiSelect', MutiSelect) Vue.component('DictSelect', DictSelect) Vue.component('CurrentCoilNo', CurrentCoilNo) diff --git a/klp-ui/src/views/wms/coil/components/AbnormalForm.vue b/klp-ui/src/views/wms/coil/components/AbnormalForm.vue index dd2763af..dbb571a9 100644 --- a/klp-ui/src/views/wms/coil/components/AbnormalForm.vue +++ b/klp-ui/src/views/wms/coil/components/AbnormalForm.vue @@ -4,20 +4,18 @@ - - - 上板面 - - - 下板面 - - + + + - - {{ - dict.label }} - + + @@ -84,7 +82,12 @@ export default { return { rules: { position: [ - { required: true, message: '请选择位置', trigger: 'change' } + { required: true, message: '请选择位置', trigger: 'change' }, + { validator: this.validateArray, trigger: 'change' } + ], + plateSurface: [ + { required: true, message: '请选择上下板面', trigger: 'change' }, + { validator: this.validateArray, trigger: 'change' } ], startPosition: [ { required: true, message: '请输入开始位置', trigger: ['blur', 'change'] }, @@ -106,10 +109,26 @@ export default { computed: { formData: { get() { - return this.value || {}; + const data = this.value || {}; + // 接收时将CSV字符串解析成数组 + // if (data.plateSurface && typeof data.plateSurface === 'string') { + // data.plateSurface = data.plateSurface?.split(',') ?? []; + // } + // if (data.position && typeof data.position === 'string') { + // data.position = data.position?.split(',') ?? []; + // } + return data; }, set(newVal) { - this.$emit('input', { ...newVal }); + // 发送时将数组转为CSV + const data = { ...newVal }; + // if (data.plateSurface && Array.isArray(data.plateSurface)) { + // data.plateSurface = data.plateSurface?.join(',') ?? ''; + // } + // if (data.position && Array.isArray(data.position)) { + // data.position = data.position?.join(',') ?? ''; + // } + this.$emit('input', data); } } }, @@ -129,7 +148,8 @@ export default { this.formData = { abnormalId: undefined, coilId: currentCoilId, - position: undefined, + position: [], + plateSurface: [], startPosition: undefined, endPosition: undefined, length: undefined, @@ -161,6 +181,14 @@ export default { } else { callback(); } + }, + /** 校验数组 */ + validateArray(rule, value, callback) { + if (!value || value.length === 0) { + callback(new Error('请至少选择一个选项')); + } else { + callback(); + } } } }; diff --git a/klp-ui/src/views/wms/coil/components/ExceptionManager.vue b/klp-ui/src/views/wms/coil/components/ExceptionManager.vue index 25d5a486..fb935c46 100644 --- a/klp-ui/src/views/wms/coil/components/ExceptionManager.vue +++ b/klp-ui/src/views/wms/coil/components/ExceptionManager.vue @@ -1,43 +1,14 @@ + + \ No newline at end of file diff --git a/klp-ui/src/views/wms/delivery/components/detailTable.vue b/klp-ui/src/views/wms/delivery/components/detailTable.vue index 3e7b703a..cbb59e7c 100644 --- a/klp-ui/src/views/wms/delivery/components/detailTable.vue +++ b/klp-ui/src/views/wms/delivery/components/detailTable.vue @@ -38,6 +38,7 @@ + @@ -47,9 +48,11 @@ + + @@ -241,6 +244,9 @@ export default { if (coil) { item.actualWarehouseName = coil.actualWarehouseName; item.surfaceTreatmentDesc = coil.surfaceTreatmentDesc; + item.qualityStatus = coil.qualityStatus; + item.warehouseName = coil.warehouseName; + item.manufacturer = coil.manufacturer; } }); } diff --git a/klp-ui/src/views/wms/delivery/components/planList.vue b/klp-ui/src/views/wms/delivery/components/planList.vue index 3443b760..36cc3bd7 100644 --- a/klp-ui/src/views/wms/delivery/components/planList.vue +++ b/klp-ui/src/views/wms/delivery/components/planList.vue @@ -1,5 +1,5 @@ - @@ -521,6 +524,7 @@ import LogTable from "@/views/wms/warehouse/components/LogTable.vue"; import { getCoilTagPrintType } from '@/views/wms/coil/js/coilPrint'; import DragResizeBox from '@/components/DragResizeBox/index.vue'; import ProcessFlow from '../components/ProcessFlow.vue'; +import { listDeliveryWaybillDetail, delDeliveryWaybillDetail } from "@/api/wms/deliveryWaybillDetail"; export default { name: "MaterialCoil", @@ -825,6 +829,9 @@ export default { ], }, productionTimeFormVisible: false, + // 统计数据:已发货的数量和未发货的数量 + shippedCount: 0, + unshippedCount: 0, }; }, computed: { @@ -873,6 +880,35 @@ export default { // 初始化时计算一次 this.calculateProductionDuration(); }, + async handleRemoveFromWaybill(row) { + const coilId = row.coilId; + // 根据id查询所在的单据明细 + const res = await listDeliveryWaybillDetail({ coilId }); + + if (res.rows.length != 1) { + this.$message({ + message: '发货单查找失败', + type: 'error', + }); + return; + } + console.log(res.rows) + const detailId = res.rows[0].detailId; + // 二次确认是否移除 + this.$modal.confirm('确认要将该钢卷从发货单中移除吗?', { + title: '确认移除', + type: 'warning', + }).then(() => { + delDeliveryWaybillDetail(detailId).then(res => { + this.$message({ + message: '移除成功', + type: 'success', + }); + this.getList(); + }); + }) + // 打开一个弹窗列出查询到的所有单据明细 + }, // 格式化毫秒值为xx天xx小时xx分钟 formatDuration(milliseconds) { if (!milliseconds || milliseconds < 0) return ''; @@ -1022,6 +1058,14 @@ export default { this.total = res.total; this.loading = false; }) + // 获取统计数据:已发货的数量和未发货的数量 + listBoundCoil({ ...query, status: 0 }).then(res => { + this.unshippedCount = res.total; + }) + // 获取统计数据:已发货的数量和未发货的数量 + listBoundCoil({ ...query, status: 1 }).then(res => { + this.shippedCount = res.total; + }) return; } listMaterialCoil(query).then(response => { @@ -1147,25 +1191,6 @@ export default { this.single = selection.length !== 1 this.multiple = !selection.length }, - /** 新增按钮操作 */ - handleAdd() { - this.isCheck = false; - this.reset(); - - // 如果父组件传入了 materialType,使用它作为默认值 - if (this.querys.materialType) { - this.form.materialType = this.querys.materialType; - // 同时设置对应的 itemType - if (this.querys.materialType === '成品') { - this.form.itemType = 'product'; - } else if (this.querys.materialType === '原料') { - this.form.itemType = 'raw_material'; - } - } - - this.open = true; - this.title = "添加钢卷物料"; - }, /** 修改按钮操作 */ handleUpdate(row) { this.isCheck = false;