feat: 新增钢卷相关字段并优化页面功能

1.  在可选列配置中新增合同号、原料厚度字段,调整原料材质字段位置
2.  优化库存预警页面操作按钮权限逻辑,移除多余的状态判断
3.  新增钢卷异常管理弹窗组件,重构异常页面结构
4.  优化报表页面的分页加载和数据展示逻辑
5.  调整表单布局和代码格式,优化用户体验
This commit is contained in:
2026-06-23 09:57:29 +08:00
parent 29d99a4f8d
commit 2d008f64ea
9 changed files with 195 additions and 936 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div class="app-container" v-loading="loading">
<div class="app-container" v-loading="statsLoading || loading">
<!-- all 类型视图选择器 -->
<div v-if="reportType === 'all'" style="margin-bottom: 10px;">
<el-radio-group v-model="viewType" @change="handleViewTypeChange">
@@ -387,10 +387,14 @@
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="产出钢卷" name="output">
<coil-table :columns="outputColumns" :data="outList" :highlight-config="{ rows: commonCoilIds }"></coil-table>
<coil-table :columns="outputColumns" :data="outTableList" :total="outTableTotal" :page-num="outPageNum"
:page-size="tablePageSize" :loading="tableLoading" :highlight-config="{ rows: commonCoilIds }"
@size-change="handleOutSizeChange" @current-change="handleOutPageChange"></coil-table>
</el-tab-pane>
<el-tab-pane label="投入钢卷" name="loss">
<coil-table :columns="lossColumns" :data="lossList" :highlight-config="{ rows: commonCoilIds }"></coil-table>
<coil-table :columns="lossColumns" :data="lossTableList" :total="lossTableTotal" :page-num="lossPageNum"
:page-size="tablePageSize" :loading="tableLoading" :highlight-config="{ rows: commonCoilIds }"
@size-change="handleLossSizeChange" @current-change="handleLossPageChange"></coil-table>
</el-tab-pane>
</el-tabs>
</template>
@@ -399,17 +403,25 @@
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="投入钢卷" name="loss">
<coil-table :data="lossList" :columns="lossColumns" :loading="loading" height="calc(100vh - 360px)" />
<coil-table :data="lossTableList" :total="lossTableTotal" :page-num="lossPageNum" :page-size="tablePageSize"
:columns="lossColumns" v-loading="tableLoading" height="calc(100vh - 360px)"
@size-change="handleLossSizeChange" @current-change="handleLossPageChange" />
</el-tab-pane>
<el-tab-pane label="产出钢卷" name="output">
<coil-table :data="outList" :columns="outputColumns" :loading="loading" height="calc(100vh - 360px)" />
<coil-table :data="outTableList" :total="outTableTotal" :page-num="outPageNum" :page-size="tablePageSize"
:columns="outputColumns" v-loading="tableLoading" height="calc(100vh - 360px)"
@size-change="handleOutSizeChange" @current-change="handleOutPageChange" />
</el-tab-pane>
</el-tabs>
</template>
<!-- out 类型只显示产出钢卷 -->
<coil-table v-else-if="reportType === 'out'" :columns="outputColumns" :data="outList"></coil-table>
<coil-table v-else-if="reportType === 'out'" :columns="outputColumns" :data="outTableList" :total="outTableTotal"
:page-num="outPageNum" :page-size="tablePageSize" :loading="tableLoading"
@size-change="handleOutSizeChange" @current-change="handleOutPageChange"></coil-table>
<!-- loss 类型只显示投入钢卷 -->
<coil-table v-else-if="reportType === 'loss'" :columns="lossColumns" :data="lossList"></coil-table>
<coil-table v-else-if="reportType === 'loss'" :columns="lossColumns" :data="lossTableList" :total="lossTableTotal"
:page-num="lossPageNum" :page-size="tablePageSize" :loading="tableLoading"
@size-change="handleLossSizeChange" @current-change="handleLossPageChange"></coil-table>
<el-dialog title="列设置" :visible.sync="settingVisible" width="50%">
<el-radio-group v-model="activeColumnConfig">
@@ -425,7 +437,7 @@
</template>
<script>
import { listCoilWithIds } from "@/api/wms/coil";
import { listLightCoil, listCoilWithIds } from "@/api/wms/coil";
import {
listLightPendingAction,
} from '@/api/wms/pendingAction';
@@ -532,6 +544,7 @@ export default {
activeColumnConfig: 'coil-report-loss',
settingVisible: false,
loading: false,
statsLoading: false,
dayDate: currentDay,
monthDate: currentMonth,
yearDate: currentYear,
@@ -550,7 +563,7 @@ export default {
'钢卷号': ['enterCoilNo', 'supplierCoilNo', 'currentCoilNo'],
'时间': ['createTime', 'exportTime', 'exportBy'],
'物理属性': ['netWeight', 'length', 'specification', 'actualThickness', 'theoreticalThickness', 'theoreticalLength', 'scheduleThickness'],
'材质属性': ['material', 'manufacturer', 'surfaceTreatmentDesc', 'zincLayer', 'packingStatus', 'temperGrade', 'coatingType', 'chromePlateCoilNo'],
'材质属性': ['material', 'manufacturer', 'surfaceTreatmentDesc', 'zincLayer', 'packingStatus', 'temperGrade', 'coatingType', 'chromePlateCoilNo', 'rawMaterialThickness'],
'用途': ['purpose', 'businessPurpose'],
'状态': ['qualityStatus', 'statusDesc', 'isRelatedToOrderText'],
'其他': ['itemName', 'itemId', 'packagingRequirement', 'trimmingRequirement', 'transferType', 'contractNo', 'saleName', 'remark', 'team'],
@@ -582,6 +595,15 @@ export default {
lossColumns: [],
outputColumns: [],
actionIds: '',
outCoilIds: '',
outTableList: [],
lossTableList: [],
outTableTotal: 0,
lossTableTotal: 0,
outPageNum: 1,
lossPageNum: 1,
tablePageSize: 20,
tableLoading: false,
lengthThreshold: 0,
thicknessThreshold: 0
}
@@ -690,6 +712,9 @@ export default {
}
},
immediate: true
},
activeTab() {
this.loadTableData()
}
},
created() {
@@ -792,13 +817,15 @@ export default {
}
},
handleQuery() {
this.outPageNum = 1
this.lossPageNum = 1
this.getList()
},
async getList() {
this.loading = true;
this.statsLoading = true;
this.loading = false;
if (this.reportType === 'all') {
// all 类型使用 comprehensive 方式查询
const res = await listLightPendingAction({
enterCoilNo: this.queryParams.enterCoilNo,
startTime: this.queryParams.startTime,
@@ -806,27 +833,27 @@ export default {
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);
this.actionIds = lossActionIds.join(',')
const outIds = [...new Set(res.data.filter(item => item.processedCoilIds).map(item => item.processedCoilIds))];
this.outCoilIds = outIds.join(',')
if (lossIds.length === 0 || outIds.length === 0) {
if (lossActionIds.length === 0 || outIds.length === 0) {
this.$message({ message: '查询结果为空', type: 'warning' })
this.loading = false;
this.statsLoading = false;
return
}
const [lossRes, outRes] = await Promise.all([
listCoilWithIds({ ...this.queryParams, actionIds: lossActionIds.join(',') || '', startTime: '', endTime: '', selectType: 'raw_material' }),
listCoilWithIds({ ...this.queryParams, coilIds: outIds.join(',') || '', startTime: '', endTime: '', byCreateTimeStart: this.queryParams.startTime, byCreateTimeEnd: this.queryParams.endTime, selectType: 'product' }),
listLightCoil({ ...this.queryParams, actionIds: this.actionIds, startTime: '', endTime: '', selectType: 'raw_material' }),
listLightCoil({ ...this.queryParams, coilIds: this.outCoilIds, startTime: '', endTime: '', byCreateTimeStart: this.queryParams.startTime, byCreateTimeEnd: this.queryParams.endTime, selectType: 'product' }),
]);
this.lossList = lossRes.rows.map(item => {
this.lossList = lossRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
});
this.outList = outRes.rows.map(item => {
this.outList = outRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
});
@@ -839,7 +866,8 @@ export default {
this.initMonthChart()
})
}
this.loading = false;
this.statsLoading = false;
this.loadTableData()
return
}
@@ -850,40 +878,40 @@ export default {
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);
this.actionIds = lossActionIds.join(',')
const outIds = [...new Set(res.data.filter(item => item.processedCoilIds).map(item => item.processedCoilIds))];
this.outCoilIds = outIds.join(',')
if (lossIds.length === 0 || outIds.length === 0) {
if (lossActionIds.length === 0 || outIds.length === 0) {
this.$message({ message: '查询结果为空', type: 'warning' })
this.loading = false;
this.statsLoading = false;
return
}
const [lossRes, outRes] = await Promise.all([
listCoilWithIds({ ...this.queryParams, actionIds: lossActionIds.join(',') || '', startTime: '', endTime: '', selectType: 'raw_material' }),
listCoilWithIds({ ...this.queryParams, coilIds: outIds.join(',') || '', startTime: '', endTime: '', byCreateTimeStart: this.queryParams.startTime, byCreateTimeEnd: this.queryParams.endTime, selectType: 'product' }),
listLightCoil({ ...this.queryParams, actionIds: this.actionIds, startTime: '', endTime: '', selectType: 'raw_material' }),
listLightCoil({ ...this.queryParams, coilIds: this.outCoilIds, startTime: '', endTime: '', byCreateTimeStart: this.queryParams.startTime, byCreateTimeEnd: this.queryParams.endTime, selectType: 'product' }),
]);
if (this.reportType === 'out') {
this.outList = outRes.rows.map(item => {
this.outList = outRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
});
this.lossList = [];
} else if (this.reportType === 'loss') {
this.lossList = lossRes.rows.map(item => {
this.lossList = lossRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
});
this.outList = [];
} else {
this.lossList = lossRes.rows.map(item => {
this.lossList = lossRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
});
this.outList = outRes.rows.map(item => {
this.outList = outRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
});
@@ -900,7 +928,8 @@ export default {
})
}
this.loading = false;
this.statsLoading = false;
this.loadTableData()
},
// all 类型:获取昨日数据(逻辑同 getList时间向前推一天
async getYesterdayData() {
@@ -931,15 +960,15 @@ export default {
}
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' }),
listLightCoil({ ...yesterdayParams, actionIds: lossActionIds.join(',') || '', startTime: '', endTime: '', selectType: 'raw_material' }),
listLightCoil({ ...yesterdayParams, coilIds: outIds.join(',') || '', startTime: '', endTime: '', byCreateTimeStart: start, byCreateTimeEnd: end, selectType: 'product' }),
])
const yesterdayLossList = lossRes.rows.map(item => {
const yesterdayLossList = lossRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
})
const yesterdayOutList = outRes.rows.map(item => {
const yesterdayOutList = outRes.map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
})
@@ -1181,6 +1210,89 @@ export default {
loadColumns() {
this.lossColumns = JSON.parse(localStorage.getItem('preference-tableColumns-coil-report-loss') || '[]') || []
this.outputColumns = JSON.parse(localStorage.getItem('preference-tableColumns-coil-report-output') || '[]') || []
},
loadTableData() {
if (this.reportType === 'out') {
this.loadOutTableData()
} else if (this.reportType === 'loss') {
this.loadLossTableData()
} else {
if (this.activeTab === 'output') {
this.loadOutTableData()
} else {
this.loadLossTableData()
}
}
},
async loadOutTableData() {
if (!this.outCoilIds) {
this.outTableList = []
this.outTableTotal = 0
return
}
this.tableLoading = true
try {
const res = await listCoilWithIds({
...this.queryParams,
coilIds: this.outCoilIds,
startTime: '', endTime: '',
byCreateTimeStart: this.queryParams.startTime,
byCreateTimeEnd: this.queryParams.endTime,
selectType: 'product',
pageSize: this.tablePageSize,
pageNum: this.outPageNum,
})
this.outTableList = (res.rows || []).map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
})
this.outTableTotal = res.total || 0
} finally {
this.tableLoading = false
}
},
async loadLossTableData() {
if (!this.actionIds) {
this.lossTableList = []
this.lossTableTotal = 0
return
}
this.tableLoading = true
try {
const res = await listCoilWithIds({
...this.queryParams,
actionIds: this.actionIds,
startTime: '', endTime: '',
selectType: 'raw_material',
pageSize: this.tablePageSize,
pageNum: this.lossPageNum,
})
this.lossTableList = (res.rows || []).map(item => {
const [thickness, width] = item.specification?.split('*') || []
return { ...item, computedThickness: parseFloat(thickness), computedWidth: parseFloat(width) }
})
this.lossTableTotal = res.total || 0
} finally {
this.tableLoading = false
}
},
handleOutSizeChange(size) {
this.tablePageSize = size
this.outPageNum = 1
this.loadOutTableData()
},
handleOutPageChange(page) {
this.outPageNum = page
this.loadOutTableData()
},
handleLossSizeChange(size) {
this.tablePageSize = size
this.lossPageNum = 1
this.loadLossTableData()
},
handleLossPageChange(page) {
this.lossPageNum = page
this.loadLossTableData()
}
}
}