From 12a887e074e928ef703930cb4e3d6d10ddc0d3ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Wed, 3 Jun 2026 16:31:51 +0800 Subject: [PATCH] =?UTF-8?q?refactor(wms-report):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=8A=A5=E8=A1=A8=E9=A1=B5=E9=9D=A2=E6=A8=A1=E6=9D=BF=EF=BC=8C?= =?UTF-8?q?=E6=8F=90=E5=8F=96=E5=85=AC=E5=85=B1=E9=80=BB=E8=BE=91=E4=B8=BA?= =?UTF-8?q?action-template?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 将merge、repair下的多个报表页面重构为使用action-template组件 2. 提取自定义导出功能为公共组件CustomExport并复用至receive.vue和action-template 3. 统一报表页面的查询、导出、列配置等公共逻辑 --- .../wms/report/components/CustomExport.vue | 306 +++++++++++++++++ klp-ui/src/views/wms/report/merge/acid.vue | 6 +- klp-ui/src/views/wms/report/merge/duge.vue | 6 +- klp-ui/src/views/wms/report/merge/index.vue | 293 +--------------- klp-ui/src/views/wms/report/merge/lajiao.vue | 6 +- klp-ui/src/views/wms/report/merge/shuang.vue | 6 +- klp-ui/src/views/wms/report/merge/tuozhi.vue | 6 +- klp-ui/src/views/wms/report/merge/zinc.vue | 6 +- klp-ui/src/views/wms/report/receive.vue | 317 ++---------------- klp-ui/src/views/wms/report/repair/acid.vue | 6 +- klp-ui/src/views/wms/report/repair/duge.vue | 6 +- klp-ui/src/views/wms/report/repair/index.vue | 294 +--------------- klp-ui/src/views/wms/report/repair/lajiao.vue | 6 +- klp-ui/src/views/wms/report/repair/shuang.vue | 6 +- klp-ui/src/views/wms/report/repair/tuozhi.vue | 6 +- klp-ui/src/views/wms/report/repair/zinc.vue | 6 +- .../src/views/wms/report/template/action.vue | 255 ++++++++++---- 17 files changed, 574 insertions(+), 963 deletions(-) create mode 100644 klp-ui/src/views/wms/report/components/CustomExport.vue diff --git a/klp-ui/src/views/wms/report/components/CustomExport.vue b/klp-ui/src/views/wms/report/components/CustomExport.vue new file mode 100644 index 00000000..78294350 --- /dev/null +++ b/klp-ui/src/views/wms/report/components/CustomExport.vue @@ -0,0 +1,306 @@ + + + + + diff --git a/klp-ui/src/views/wms/report/merge/acid.vue b/klp-ui/src/views/wms/report/merge/acid.vue index 6d304a44..48187771 100644 --- a/klp-ui/src/views/wms/report/merge/acid.vue +++ b/klp-ui/src/views/wms/report/merge/acid.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/merge/duge.vue b/klp-ui/src/views/wms/report/merge/duge.vue index 1b66f178..e6962d60 100644 --- a/klp-ui/src/views/wms/report/merge/duge.vue +++ b/klp-ui/src/views/wms/report/merge/duge.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/merge/index.vue b/klp-ui/src/views/wms/report/merge/index.vue index a8d4ad22..22759902 100644 --- a/klp-ui/src/views/wms/report/merge/index.vue +++ b/klp-ui/src/views/wms/report/merge/index.vue @@ -1,299 +1,14 @@ - - \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/merge/lajiao.vue b/klp-ui/src/views/wms/report/merge/lajiao.vue index bef9cd1f..f286c012 100644 --- a/klp-ui/src/views/wms/report/merge/lajiao.vue +++ b/klp-ui/src/views/wms/report/merge/lajiao.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/merge/shuang.vue b/klp-ui/src/views/wms/report/merge/shuang.vue index dd5b4c70..8425954a 100644 --- a/klp-ui/src/views/wms/report/merge/shuang.vue +++ b/klp-ui/src/views/wms/report/merge/shuang.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/merge/tuozhi.vue b/klp-ui/src/views/wms/report/merge/tuozhi.vue index 140b3917..19515db9 100644 --- a/klp-ui/src/views/wms/report/merge/tuozhi.vue +++ b/klp-ui/src/views/wms/report/merge/tuozhi.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/merge/zinc.vue b/klp-ui/src/views/wms/report/merge/zinc.vue index a3c5b7ac..c2dc55cd 100644 --- a/klp-ui/src/views/wms/report/merge/zinc.vue +++ b/klp-ui/src/views/wms/report/merge/zinc.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/receive.vue b/klp-ui/src/views/wms/report/receive.vue index fc538522..028626bd 100644 --- a/klp-ui/src/views/wms/report/receive.vue +++ b/klp-ui/src/views/wms/report/receive.vue @@ -86,66 +86,18 @@ - - -
- -
- 全选 - 反选 - 清空 -
-
-
-
-
可选列
-
- -
-
{{ gName }}
-
- {{ field.label }} -
-
-
-
-
-
-
- 导出顺序 - {{ orderedColumns.length }} -
-
- -
- - {{ orderedColumns.indexOf(field) + 1 }} - {{ exportColumns[field] || field }} - -
-
-
勾选左侧列后出现在此处,可拖拽排序
-
-
-
- -
+ diff --git a/klp-ui/src/views/wms/report/repair/acid.vue b/klp-ui/src/views/wms/report/repair/acid.vue index 8f47606c..17979897 100644 --- a/klp-ui/src/views/wms/report/repair/acid.vue +++ b/klp-ui/src/views/wms/report/repair/acid.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/repair/duge.vue b/klp-ui/src/views/wms/report/repair/duge.vue index 193929e7..3f10d736 100644 --- a/klp-ui/src/views/wms/report/repair/duge.vue +++ b/klp-ui/src/views/wms/report/repair/duge.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/repair/index.vue b/klp-ui/src/views/wms/report/repair/index.vue index 171dcd42..339eb81a 100644 --- a/klp-ui/src/views/wms/report/repair/index.vue +++ b/klp-ui/src/views/wms/report/repair/index.vue @@ -1,300 +1,14 @@ - - \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/repair/lajiao.vue b/klp-ui/src/views/wms/report/repair/lajiao.vue index 05f7b331..880fedb7 100644 --- a/klp-ui/src/views/wms/report/repair/lajiao.vue +++ b/klp-ui/src/views/wms/report/repair/lajiao.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/repair/shuang.vue b/klp-ui/src/views/wms/report/repair/shuang.vue index bb17c5f1..1a1b2ad8 100644 --- a/klp-ui/src/views/wms/report/repair/shuang.vue +++ b/klp-ui/src/views/wms/report/repair/shuang.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/repair/tuozhi.vue b/klp-ui/src/views/wms/report/repair/tuozhi.vue index be758dde..97f8ec32 100644 --- a/klp-ui/src/views/wms/report/repair/tuozhi.vue +++ b/klp-ui/src/views/wms/report/repair/tuozhi.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/repair/zinc.vue b/klp-ui/src/views/wms/report/repair/zinc.vue index f11f138f..df5af0b2 100644 --- a/klp-ui/src/views/wms/report/repair/zinc.vue +++ b/klp-ui/src/views/wms/report/repair/zinc.vue @@ -1,14 +1,14 @@ \ No newline at end of file diff --git a/klp-ui/src/views/wms/report/template/action.vue b/klp-ui/src/views/wms/report/template/action.vue index 6e75bb3f..ae699b49 100644 --- a/klp-ui/src/views/wms/report/template/action.vue +++ b/klp-ui/src/views/wms/report/template/action.vue @@ -137,15 +137,19 @@ 查询 + 列配置 导出产出钢卷 + @click="exportData">导出产出 导出消耗钢卷 - 列设置 + @click="exportLossData">导出消耗 保存产出报表 + @click="openCustomExport('output')">自定义导出产出 保存消耗报表 + @click="openCustomExport('loss')">自定义导出消耗 + 保存产出 + 保存消耗 @@ -278,6 +282,30 @@ + + +
+ + +
+
+
+ + +
+ + +
+
+
@@ -318,6 +346,14 @@ + + @@ -337,6 +373,7 @@ import CoilTable from "@/views/wms/report/components/coilTable"; import ColumnsSetting from "@/views/wms/report/components/setting/columns"; import TimeRangePicker from "@/views/wms/report/components/timeRangePicker.vue"; import SplitSummary from "@/views/wms/report/components/summary/splitSummary.vue"; +import CustomExport from "@/views/wms/report/components/CustomExport.vue"; import { saveReportFile } from "@/views/wms/report/js/reportFile"; import * as echarts from 'echarts'; @@ -372,6 +409,7 @@ export default { ColumnsSetting, TimeRangePicker, SplitSummary, + CustomExport, }, dicts: ['product_coil_status', 'coil_material', 'coil_itemname', 'coil_manufacturer', 'coil_quality_status'], data() { @@ -437,6 +475,19 @@ export default { viewType: 'custom', yesterdaySummary: {}, monthChart: null, + dayChart: null, + customExportVisible: false, + customExportType: 'output', + columnGroups: { + '基本信息': ['itemTypeDesc', 'warehouseName', 'actualWarehouseName', 'dataTypeText'], + '钢卷号': ['enterCoilNo', 'supplierCoilNo', 'currentCoilNo'], + '时间': ['createTime', 'exportTime', 'exportBy'], + '物理属性': ['netWeight', 'length', 'specification', 'actualThickness', 'theoreticalThickness', 'theoreticalLength'], + '材质属性': ['material', 'manufacturer', 'surfaceTreatmentDesc', 'zincLayer', 'packingStatus', 'temperGrade', 'coatingType', 'chromePlateCoilNo'], + '用途': ['purpose', 'businessPurpose'], + '状态': ['qualityStatus', 'statusDesc', 'isRelatedToOrderText'], + '其他': ['itemName', 'itemId', 'packagingRequirement', 'trimmingRequirement', 'transferType', 'saleName', 'remark', 'team'], + }, queryParams: { startTime: start, endTime: end, @@ -523,6 +574,9 @@ export default { }) return commonIds }, + customExportStorageKey() { + return `coil-report-action-${this.actionType}` + }, }, watch: { warehouseOptions: { @@ -718,10 +772,21 @@ export default { }); } + if (this.reportType === 'day') { + this.$nextTick(() => { + this.initDayChart() + }) + } + if (this.reportType === 'month') { + this.$nextTick(() => { + this.initMonthChart() + }) + } + this.loading = false; }, - // all 类型:获取昨日数据 - getYesterdayData() { + // all 类型:获取昨日数据(逻辑同 getList,时间向前推一天) + async getYesterdayData() { const yesterday = new Date(this.dayDate) yesterday.setDate(yesterday.getDate() - 1) const year = yesterday.getFullYear() @@ -730,66 +795,37 @@ export default { const yesterdayDate = `${year}-${month}-${day}` const { start, end } = this.getDayTimeRange(yesterdayDate) - Promise.all([ - listCoilWithIds({ - selectType: 'raw_material', - itemType: 'raw_material', - warehouseIds: this.warehouseIds.join(','), - ...this.queryParams, - startTime: start, - endTime: end, - pageSize: 99999, - pageNum: 1, - }), - listCoilWithIds({ - selectType: 'product', - itemType: 'product', - warehouseIds: this.warehouseIds.join(','), - ...this.queryParams, - startTime: start, - endTime: end, - pageSize: 99999, - pageNum: 1, - }), - ]).then((resList) => { - const list = resList.flatMap(res => res.rows) - const yesterdayList = list.sort( - (a, b) => new Date(b.createTime) - new Date(a.createTime) - ).map(item => { - if (!item.selectType) { - item.selectType = item.itemType === 'product' ? 'product' : 'raw_material' - } - return item - }) + const yesterdayParams = { + ...this.queryParams, + startTime: start, + endTime: end, + } - listLightPendingAction({ - actionStatus: 2, - actionType: this.actionType, - pageSize: 99999, - pageNum: 1, - startTime: start, - endTime: end, - }).then((lossRes) => { - const lossActions = lossRes.rows - const lossCoilIds = lossActions.map(item => item.coilId).join(',') + const res = await listLightPendingAction({ ...yesterdayParams, actionTypes: this.actionType, actionStatus: 2 }) + const lossIds = res.data.filter(item => item.coilId).map(item => item.coilId) + const lossActionIds = res.data.filter(item => item.actionId).map(item => item.actionId) + const outIds = [...new Set(res.data.filter(item => item.processedCoilIds).map(item => item.processedCoilIds))] - if (lossCoilIds) { - listCoilWithIds({ - ...this.queryParams, - startTime: undefined, - endTime: undefined, - coilIds: lossCoilIds, - pageSize: 99999, - pageNum: 1, - }).then(res => { - const yesterdayLossList = res.rows - this.yesterdaySummary = calcSummary(yesterdayList, yesterdayLossList) - }) - } else { - this.yesterdaySummary = calcSummary(yesterdayList, []) - } - }) + if (lossIds.length === 0 || outIds.length === 0) { + this.yesterdaySummary = {} + return + } + + const [lossRes, outRes] = await Promise.all([ + listCoilWithIds({ ...yesterdayParams, actionIds: lossActionIds.join(',') || '', startTime: '', endTime: '', selectType: 'raw_material' }), + listCoilWithIds({ ...yesterdayParams, coilIds: outIds.join(',') || '', startTime: '', endTime: '', byCreateTimeStart: start, byCreateTimeEnd: end, selectType: 'product' }), + ]) + + const yesterdayLossList = lossRes.rows.map(item => { + const [thickness, width] = item.specification?.split('*') || [] + return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) } }) + const yesterdayOutList = outRes.rows.map(item => { + const [thickness, width] = item.specification?.split('*') || [] + return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) } + }) + + this.yesterdaySummary = calcSummary(yesterdayOutList, yesterdayLossList) }, // all 类型:初始化月视图折线图 initMonthChart() { @@ -852,6 +888,97 @@ export default { this.monthChart.resize() }) }, + // day 类型:初始化小时数据折线图 + initDayChart() { + if (!this.$refs.dayChart) return + + if (this.dayChart) { + this.dayChart.dispose() + } + + this.dayChart = echarts.init(this.$refs.dayChart) + + const hourlyData = {} + for (let h = 0; h < 24; h++) { + hourlyData[h] = { outCount: 0, outTotalWeight: 0, lossCount: 0, lossTotalWeight: 0 } + } + + this.outList.forEach(item => { + const timeStr = item.createTime?.split(' ')[1] || '00:00:00' + const hour = parseInt(timeStr.split(':')[0]) + if (hourlyData[hour] !== undefined) { + hourlyData[hour].outCount++ + hourlyData[hour].outTotalWeight += parseFloat(item.netWeight) || 0 + } + }) + + this.lossList.forEach(item => { + const timeStr = item.actionCompleteTime?.split(' ')[1] || '00:00:00' + const hour = parseInt(timeStr.split(':')[0]) + if (hourlyData[hour] !== undefined) { + hourlyData[hour].lossCount++ + hourlyData[hour].lossTotalWeight += parseFloat(item.netWeight) || 0 + } + }) + + const hours = Object.keys(hourlyData).map(Number).sort((a, b) => a - b) + const hourLabels = hours.map(h => `${String(h).padStart(2, '0')}:00`) + const outCountData = hours.map(h => hourlyData[h].outCount) + const outTotalWeightData = hours.map(h => hourlyData[h].outTotalWeight.toFixed(2)) + const lossCountData = hours.map(h => hourlyData[h].lossCount) + const lossTotalWeightData = hours.map(h => hourlyData[h].lossTotalWeight.toFixed(2)) + + const option = { + tooltip: { + trigger: 'axis', + axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } } + }, + legend: { data: ['产出数量', '产出总重', '消耗数量', '消耗总重'] }, + grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, + xAxis: [{ type: 'category', boundaryGap: false, data: hourLabels }], + yAxis: [ + { type: 'value', name: '数量', position: 'left' }, + { type: 'value', name: '重量(t)', position: 'right' } + ], + series: [ + { name: '产出数量', type: 'line', data: outCountData, yAxisIndex: 0 }, + { name: '产出总重', type: 'line', data: outTotalWeightData, yAxisIndex: 1 }, + { name: '消耗数量', type: 'line', data: lossCountData, yAxisIndex: 0 }, + { name: '消耗总重', type: 'line', data: lossTotalWeightData, yAxisIndex: 1 } + ] + } + + this.dayChart.setOption(option) + + window.addEventListener('resize', () => { + this.dayChart.resize() + }) + }, + // 自定义导出 + openCustomExport(type) { + if (type === 'output' && this.outList.length === 0) { + this.$message({ message: '暂无产出数据可导出', type: 'warning' }) + return + } + if (type === 'loss' && this.lossList.length === 0) { + this.$message({ message: '暂无消耗数据可导出', type: 'warning' }) + return + } + this.customExportType = type + this.$refs.customExport.open() + }, + handleCustomExport(orderedColumns) { + const { pageNum, pageSize, startTime, endTime, ...filters } = this.queryParams + const type = this.customExportType + const ids = type === 'loss' + ? { actionIds: this.actionIds } + : { coilIds: this.outList.map(item => item.coilId).join(',') } + this.download('wms/materialCoil/exportCustomOrdered', { + ...filters, + ...ids, + columnsOrdered: orderedColumns.join(','), + }, `materialCoil_${new Date().getTime()}.xlsx`) + }, exportData() { if (this.outList.length === 0) { this.$message.warning('暂无数据可导出')