feat(wms): 新增报表透视表组件并优化操作状态显示

refactor: 替换select为tag显示操作状态
feat: 添加今天按钮到时间范围选择器
fix: 移除调试用的console.log
style: 调整按钮间距样式
feat: 新增厂家材质透视表和宽度厚度统计表
refactor: 优化导出功能去除orderBy参数
feat: 添加表面处理等查询条件
feat: 在coilTable中添加settings插槽
feat: 使用下拉菜单整合报表操作按钮
This commit is contained in:
2026-05-05 14:52:24 +08:00
parent 723ccc9e58
commit fa198181ee
11 changed files with 491 additions and 91 deletions

View File

@@ -0,0 +1,195 @@
<template>
<el-table :data="tableData" border :style="{ width: '100%', marginBottom: '20px' }">
<el-table-column :prop="config.rowField" :label="config.rowLabel" :width="config.rowWidth" align="center"
fixed></el-table-column>
<template v-for="colVal in columnValues">
<el-table-column :key="'group_' + colVal" :label="colVal + ''" align="center">
<template v-for="summary in config.summaryColumns">
<el-table-column :key="`${colVal}_${summary.prop}`" :label="summary.label" align="center">
<template #default="scope">
<!-- 强制显示值 -->
<span>{{ scope.row[`${summary.prop}_${colVal}`] || '--' }}</span>
</template>
</el-table-column>
</template>
</el-table-column>
</template>
<el-table-column label="合计" align="center">
<template v-for="summary in config.summaryColumns">
<el-table-column :key="'total_' + summary.prop" :prop="'total_' + summary.prop" :label="summary.label"
:width="summary.width" align="center"></el-table-column>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
name: 'CrossTable',
props: {
data: {
type: Array,
required: true
},
config: {
type: Object,
required: true
}
},
computed: {
// 第一步:统计数据,生成行、列和单元格统计值
statisticsData() {
const {
rowField,
columnField,
summaryColumns,
formatKey
} = this.config
const formatNum = (num) => {
if (num === null || num === undefined) return null
return parseFloat(num).toFixed(2)
}
const formatKeyFn = formatKey || formatNum
// 数据结构rowValues 行列表colValues 列列表cellStats[row][col][prop] = 统计值
const rowValues = new Set()
const colValues = new Set()
const cellStats = new Map() // Map<rowKey, Map<colKey, { prop: value }>>
// 遍历原始数据,统计每个单元格
this.data.forEach(item => {
const colVal = item[columnField]
const rowVal = item[rowField]
if (colVal != null && colVal !== '' && rowVal != null && rowVal !== '') {
const colKey = formatKeyFn(colVal)
const rowKey = formatKeyFn(rowVal)
rowValues.add(rowKey)
colValues.add(colKey)
// 初始化单元格
if (!cellStats.has(rowKey)) {
cellStats.set(rowKey, new Map())
}
const rowStats = cellStats.get(rowKey)
if (!rowStats.has(colKey)) {
const initial = {}
summaryColumns.forEach(sc => {
initial[sc.prop] = 0
})
rowStats.set(colKey, initial)
}
const cell = rowStats.get(colKey)
// 累计统计值
summaryColumns.forEach(sc => {
if (sc.field === '') {
cell[sc.prop] += 1
} else {
cell[sc.prop] += parseFloat(item[sc.field]) || 0
}
})
}
})
// 排序并返回
return {
rowValues: Array.from(rowValues).map(v => parseFloat(v)).sort((a, b) => a - b).map(v => formatKeyFn(v)),
colValues: Array.from(colValues).map(v => parseFloat(v)).sort((a, b) => a - b).map(v => formatKeyFn(v)),
cellStats
}
},
// 第二步:根据统计数据生成 Element-UI Table 可用的数据
tableData() {
const {
rowField,
summaryColumns,
formatValue
} = this.config
const { rowValues, colValues, cellStats } = this.statisticsData
// 生成每一行数据
const rows = rowValues.map(rowKey => {
const row = { [rowField]: parseFloat(rowKey) }
const rowStats = cellStats.get(rowKey)
const rowTotals = {}
summaryColumns.forEach(sc => {
rowTotals[sc.prop] = 0
})
// 填充每一列的数据
colValues.forEach(colKey => {
const cell = rowStats?.get(colKey) || {}
summaryColumns.forEach(sc => {
const val = cell[sc.prop] || 0
row[`${sc.prop}_${colKey}`] = formatValue ? formatValue(val, sc) : val.toFixed(3)
rowTotals[sc.prop] += val
})
})
// 填充行合计
summaryColumns.forEach(sc => {
row[`total_${sc.prop}`] = formatValue ? formatValue(rowTotals[sc.prop], sc) : rowTotals[sc.prop].toFixed(3)
})
return row
})
// 在 tableData 计算属性中,生成 rows 后添加
console.log('Generated row sample:', rows[0])
console.log('Field names:', Object.keys(rows[0] || {}))
console.log('rows length:', rows.length)
console.log('colValues:', colValues)
console.log('summaryColumns:', summaryColumns)
// 生成合计行
const totalRow = { [rowField]: '合计' }
const grandTotals = {}
summaryColumns.forEach(sc => {
grandTotals[sc.prop] = 0
})
colValues.forEach(colKey => {
const colTotals = {}
summaryColumns.forEach(sc => {
colTotals[sc.prop] = 0
})
rows.forEach(row => {
summaryColumns.forEach(sc => {
const val = parseFloat(row[`${sc.prop}_${colKey}`]) || 0
colTotals[sc.prop] += val
grandTotals[sc.prop] += val
})
})
summaryColumns.forEach(sc => {
totalRow[`${sc.prop}_${colKey}`] = formatValue ? formatValue(colTotals[sc.prop], sc) : colTotals[sc.prop].toFixed(3)
})
})
// 填充总合计
summaryColumns.forEach(sc => {
totalRow[`total_${sc.prop}`] = formatValue ? formatValue(grandTotals[sc.prop], sc) : grandTotals[sc.prop].toFixed(3)
})
console.log(rows, 'rows')
return [...rows, totalRow]
},
columnValues() {
console.log(this.statisticsData.colValues, 'colValues')
return this.statisticsData.colValues
}
}
}
</script>
<style scoped></style>