Files
xgy-oa/klp-ui/src/views/wms/coil/panels/Perspective/TrimStatistics.vue
砂糖 f5904fa7f3 feat(wms): 添加次品标签页并优化钢卷统计表格
refactor(LeftList): 移除表单包装简化对话框结构
feat(Perspective): 新增宽度分类统计组件
perf(TrimStatistics): 优化表格宽度分组和过滤逻辑
2026-03-09 17:19:06 +08:00

287 lines
9.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="trim-statistics-table">
<el-table
:data="filteredTableData"
border
stripe
:span-method="objectSpanMethod"
style="width: 100%;"
>
<!-- 厚度列 -->
<el-table-column
prop="thickness"
label="厚度"
width="80"
align="center"
/>
<!-- 冷硬卷板净边料现货库存 独立表头组 -->
<el-table-column
label="冷硬卷板净边料现货库存"
align="center"
>
<el-table-column
label="总计"
align="center"
>
<el-table-column label="数量(件)" prop="trimmedTotalCount" width="80" align="center" />
<el-table-column label="重量(吨)" prop="trimmedTotalWeight" width="80" align="center" />
</el-table-column>
<!-- 净边料独立宽度列合并后的分组 -->
<el-table-column
v-for="group in trimmedWidthGroups"
:key="'trimmed-' + group.key"
:label="group.label"
align="center"
>
<el-table-column label="数量(件)" :prop="`trimmed_${group.key}_count`" width="80" align="center" />
<el-table-column label="重量(吨)" :prop="`trimmed_${group.key}_weight`" width="80" align="center" />
</el-table-column>
</el-table-column>
<!-- 冷硬卷板毛边料现货库存 独立表头组 -->
<el-table-column
label="冷硬卷板毛边料现货库存"
align="center"
>
<el-table-column
label="总计"
align="center"
>
<el-table-column label="数量(件)" prop="untrimmedTotalCount" width="80" align="center" />
<el-table-column label="重量(吨)" prop="untrimmedTotalWeight" width="80" align="center" />
</el-table-column>
<!-- 毛边料独立宽度列合并后的分组 -->
<el-table-column
v-for="group in untrimmedWidthGroups"
:key="'untrimmed-' + group.key"
:label="group.label"
align="center"
>
<el-table-column label="数量(件)" :prop="`untrimmed_${group.key}_count`" width="80" align="center" />
<el-table-column label="重量(吨)" :prop="`untrimmed_${group.key}_weight`" width="80" align="center" />
</el-table-column>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'TrimStatistics',
props: {
data: {
type: Array,
default: () => []
},
// 可配置的宽度分组规则(支持自定义)
widthGroupRules: {
type: Object,
default: () => ({
'1000系列': ['1000', '1000~1005', '1010/1015'],
'1200基础系列': ['1200/1202', '1200~1215'],
'1218基础系列': ['1218/1220', '1218~1235', '1210/1215'],
'1240系列': ['1240/1252'],
'1225系列': ['1225/1235'],
'1250+系列': ['1250~1265', '1260-1265']
})
}
},
computed: {
// ========== 净边料相关计算 ==========
// 提取净边料所有原始宽度
rawTrimmedWidths() {
const widthSet = new Set();
this.data.forEach(item => {
item.trimmedList.forEach(trimmed => {
if (trimmed.width) widthSet.add(trimmed.width);
});
});
return Array.from(widthSet);
},
// 净边料宽度分组(合并相近宽度)
trimmedWidthGroups() {
return this.generateWidthGroups(this.rawTrimmedWidths);
},
// ========== 毛边料相关计算 ==========
// 提取毛边料所有原始宽度
rawUntrimmedWidths() {
const widthSet = new Set();
this.data.forEach(item => {
item.untrimmedList.forEach(untrimmed => {
if (untrimmed.width) widthSet.add(untrimmed.width);
});
});
return Array.from(widthSet);
},
// 毛边料宽度分组(合并相近宽度)
untrimmedWidthGroups() {
return this.generateWidthGroups(this.rawUntrimmedWidths);
},
// 处理后的原始表格数据
tableData() {
return this.data.map(item => {
const row = {
thickness: item.thickness,
trimmedTotalCount: 0,
trimmedTotalWeight: 0,
untrimmedTotalCount: 0,
untrimmedTotalWeight: 0
};
// 初始化净边料分组数据
this.trimmedWidthGroups.forEach(group => {
row[`trimmed_${group.key}_count`] = 0;
row[`trimmed_${group.key}_weight`] = 0;
});
// 初始化毛边料分组数据
this.untrimmedWidthGroups.forEach(group => {
row[`untrimmed_${group.key}_count`] = 0;
row[`untrimmed_${group.key}_weight`] = 0;
});
// 处理净边料数据(按分组求和)
item.trimmedList.forEach(trimmed => {
const width = trimmed.width;
const count = Number(trimmed.coilCount) || 0;
const weight = Number(trimmed.totalWeight) || 0;
// 找到宽度所属的分组并累加
this.trimmedWidthGroups.forEach(group => {
if (group.includesWidth(width)) {
row[`trimmed_${group.key}_count`] += count;
row[`trimmed_${group.key}_weight`] = (row[`trimmed_${group.key}_weight`] + weight).toFixed(3);
}
});
// 累加总计
row.trimmedTotalCount += count;
row.trimmedTotalWeight = (Number(row.trimmedTotalWeight) + weight).toFixed(3);
});
// 处理毛边料数据(按分组求和)
item.untrimmedList.forEach(untrimmed => {
const width = untrimmed.width;
const count = Number(untrimmed.coilCount) || 0;
const weight = Number(untrimmed.totalWeight) || 0;
// 找到宽度所属的分组并累加
this.untrimmedWidthGroups.forEach(group => {
if (group.includesWidth(width)) {
row[`untrimmed_${group.key}_count`] += count;
row[`untrimmed_${group.key}_weight`] = (row[`untrimmed_${group.key}_weight`] + weight).toFixed(3);
}
});
// 累加总计
row.untrimmedTotalCount += count;
row.untrimmedTotalWeight = (Number(row.untrimmedTotalWeight) + weight).toFixed(3);
});
return row;
});
},
// 过滤掉全0的行
filteredTableData() {
return this.tableData.filter(row => {
let hasNonZeroData = false;
// 检查净边料总计
if (Number(row.trimmedTotalCount) > 0 || Number(row.trimmedTotalWeight) > 0) {
hasNonZeroData = true;
}
// 检查毛边料总计
if (Number(row.untrimmedTotalCount) > 0 || Number(row.untrimmedTotalWeight) > 0) {
hasNonZeroData = true;
}
// 检查净边料分组列
if (!hasNonZeroData) {
this.trimmedWidthGroups.forEach(group => {
if (Number(row[`trimmed_${group.key}_count`]) > 0 || Number(row[`trimmed_${group.key}_weight`]) > 0) {
hasNonZeroData = true;
}
});
}
// 检查毛边料分组列
if (!hasNonZeroData) {
this.untrimmedWidthGroups.forEach(group => {
if (Number(row[`untrimmed_${group.key}_count`]) > 0 || Number(row[`untrimmed_${group.key}_weight`]) > 0) {
hasNonZeroData = true;
}
});
}
return hasNonZeroData;
});
}
},
methods: {
// 生成宽度分组(核心方法)
generateWidthGroups(rawWidths) {
const groups = [];
const usedWidths = new Set();
// 遍历分组规则,匹配原始宽度
Object.entries(this.widthGroupRules).forEach(([groupLabel, widthList]) => {
// 筛选出当前分组包含的原始宽度
const matchedWidths = rawWidths.filter(width => widthList.includes(width));
if (matchedWidths.length === 0) return;
// 创建分组对象
const groupKey = groupLabel.replace(/[^a-zA-Z0-9]/g, '_');
groups.push({
key: groupKey,
label: groupLabel,
widths: matchedWidths,
includesWidth: function(width) {
return this.widths.includes(width);
}
});
// 标记已使用的宽度
matchedWidths.forEach(width => usedWidths.add(width));
});
// 处理未匹配到分组的宽度(单独成组)
rawWidths.forEach(width => {
if (!usedWidths.has(width)) {
const groupKey = width.replace(/[^a-zA-Z0-9]/g, '_');
groups.push({
key: groupKey,
label: width,
widths: [width],
includesWidth: function(width) {
return this.widths.includes(width);
}
});
}
});
return groups;
},
// 合并表头的跨度方法
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
return { rowspan: 1, colspan: 1 };
}
}
};
</script>
<style scoped>
.trim-statistics-table {
padding: 10px;
overflow-x: auto;
}
.el-table {
--el-table-header-text-color: #333;
--el-table-row-hover-bg-color: #f5f7fa;
}
</style>