2026-03-09 16:07:07 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="trim-statistics-table">
|
|
|
|
|
|
<el-table
|
2026-03-09 17:19:06 +08:00
|
|
|
|
:data="filteredTableData"
|
2026-03-09 16:07:07 +08:00
|
|
|
|
border
|
|
|
|
|
|
stripe
|
|
|
|
|
|
:span-method="objectSpanMethod"
|
|
|
|
|
|
style="width: 100%;"
|
|
|
|
|
|
>
|
|
|
|
|
|
<!-- 厚度列 -->
|
|
|
|
|
|
<el-table-column
|
|
|
|
|
|
prop="thickness"
|
|
|
|
|
|
label="厚度"
|
|
|
|
|
|
width="80"
|
|
|
|
|
|
align="center"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
2026-03-09 17:19:06 +08:00
|
|
|
|
<!-- 冷硬卷板净边料现货库存 独立表头组 -->
|
2026-03-09 16:07:07 +08:00
|
|
|
|
<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>
|
2026-03-09 17:19:06 +08:00
|
|
|
|
<!-- 净边料独立宽度列(合并后的分组) -->
|
2026-03-09 16:07:07 +08:00
|
|
|
|
<el-table-column
|
2026-03-09 17:19:06 +08:00
|
|
|
|
v-for="group in trimmedWidthGroups"
|
|
|
|
|
|
:key="'trimmed-' + group.key"
|
|
|
|
|
|
:label="group.label"
|
2026-03-09 16:07:07 +08:00
|
|
|
|
align="center"
|
|
|
|
|
|
>
|
2026-03-09 17:19:06 +08:00
|
|
|
|
<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" />
|
2026-03-09 16:07:07 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
|
2026-03-09 17:19:06 +08:00
|
|
|
|
<!-- 冷硬卷板毛边料现货库存 独立表头组 -->
|
2026-03-09 16:07:07 +08:00
|
|
|
|
<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>
|
2026-03-09 17:19:06 +08:00
|
|
|
|
<!-- 毛边料独立宽度列(合并后的分组) -->
|
2026-03-09 16:07:07 +08:00
|
|
|
|
<el-table-column
|
2026-03-09 17:19:06 +08:00
|
|
|
|
v-for="group in untrimmedWidthGroups"
|
|
|
|
|
|
:key="'untrimmed-' + group.key"
|
|
|
|
|
|
:label="group.label"
|
2026-03-09 16:07:07 +08:00
|
|
|
|
align="center"
|
|
|
|
|
|
>
|
2026-03-09 17:19:06 +08:00
|
|
|
|
<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" />
|
2026-03-09 16:07:07 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
export default {
|
|
|
|
|
|
name: 'TrimStatistics',
|
|
|
|
|
|
props: {
|
|
|
|
|
|
data: {
|
|
|
|
|
|
type: Array,
|
|
|
|
|
|
default: () => []
|
2026-03-09 17:19:06 +08:00
|
|
|
|
},
|
|
|
|
|
|
// 可配置的宽度分组规则(支持自定义)
|
|
|
|
|
|
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']
|
|
|
|
|
|
})
|
2026-03-09 16:07:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
computed: {
|
2026-03-09 17:19:06 +08:00
|
|
|
|
// ========== 净边料相关计算 ==========
|
|
|
|
|
|
// 提取净边料所有原始宽度
|
|
|
|
|
|
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);
|
2026-03-09 16:07:07 +08:00
|
|
|
|
},
|
2026-03-09 17:19:06 +08:00
|
|
|
|
// 毛边料宽度分组(合并相近宽度)
|
|
|
|
|
|
untrimmedWidthGroups() {
|
|
|
|
|
|
return this.generateWidthGroups(this.rawUntrimmedWidths);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 处理后的原始表格数据
|
2026-03-09 16:07:07 +08:00
|
|
|
|
tableData() {
|
|
|
|
|
|
return this.data.map(item => {
|
|
|
|
|
|
const row = {
|
|
|
|
|
|
thickness: item.thickness,
|
2026-03-09 17:19:06 +08:00
|
|
|
|
trimmedTotalCount: 0,
|
|
|
|
|
|
trimmedTotalWeight: 0,
|
|
|
|
|
|
untrimmedTotalCount: 0,
|
|
|
|
|
|
untrimmedTotalWeight: 0
|
2026-03-09 16:07:07 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-03-09 17:19:06 +08:00
|
|
|
|
// 初始化净边料分组数据
|
|
|
|
|
|
this.trimmedWidthGroups.forEach(group => {
|
|
|
|
|
|
row[`trimmed_${group.key}_count`] = 0;
|
|
|
|
|
|
row[`trimmed_${group.key}_weight`] = 0;
|
2026-03-09 16:07:07 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2026-03-09 17:19:06 +08:00
|
|
|
|
// 初始化毛边料分组数据
|
|
|
|
|
|
this.untrimmedWidthGroups.forEach(group => {
|
|
|
|
|
|
row[`untrimmed_${group.key}_count`] = 0;
|
|
|
|
|
|
row[`untrimmed_${group.key}_weight`] = 0;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 处理净边料数据(按分组求和)
|
2026-03-09 16:07:07 +08:00
|
|
|
|
item.trimmedList.forEach(trimmed => {
|
2026-03-09 17:19:06 +08:00
|
|
|
|
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);
|
2026-03-09 16:07:07 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
2026-03-09 17:19:06 +08:00
|
|
|
|
// 处理毛边料数据(按分组求和)
|
2026-03-09 16:07:07 +08:00
|
|
|
|
item.untrimmedList.forEach(untrimmed => {
|
2026-03-09 17:19:06 +08:00
|
|
|
|
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);
|
2026-03-09 16:07:07 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return row;
|
|
|
|
|
|
});
|
2026-03-09 17:19:06 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 过滤掉全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;
|
|
|
|
|
|
});
|
2026-03-09 16:07:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2026-03-09 17:19:06 +08:00
|
|
|
|
// 生成宽度分组(核心方法)
|
|
|
|
|
|
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;
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 合并表头的跨度方法
|
2026-03-09 16:07:07 +08:00
|
|
|
|
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>
|