From 85751acc46cea86cedc6264a6d119a61bf8f7870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Sat, 4 Jul 2026 13:19:32 +0800 Subject: [PATCH] =?UTF-8?q?feat(cost/comprehensive):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B1=87=E6=80=BB=E8=A1=8C=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=A1=A8=E6=A0=BC=E6=95=B0=E6=8D=AE=E6=B1=82=E5=92=8C?= =?UTF-8?q?=E4=B8=8E=E5=B9=B3=E5=9D=87=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增summaryRows计算属性,生成总和与平均两行汇总数据 2. 新增tableData计算属性,将汇总行合并到原表格数据中 3. 为汇总行添加专属样式,高亮显示并加粗文字 4. 优化表格列渲染逻辑,普通行保留编辑能力,汇总行仅展示静态数据 5. 调整删除按钮逻辑,仅对非汇总行生效并修复删除索引问题 6. 新增rowClassName方法为汇总行添加专属CSS类 --- klp-ui/src/views/cost/comprehensive.vue | 98 ++++++++++++++++++++----- 1 file changed, 79 insertions(+), 19 deletions(-) diff --git a/klp-ui/src/views/cost/comprehensive.vue b/klp-ui/src/views/cost/comprehensive.vue index 4afc366f3..845b899a0 100644 --- a/klp-ui/src/views/cost/comprehensive.vue +++ b/klp-ui/src/views/cost/comprehensive.vue @@ -30,9 +30,9 @@ - + - + - + @@ -82,7 +95,7 @@ - 删除 + 删除 @@ -494,6 +507,45 @@ export default { }) return col && col.color ? { background: col.color, color: '#fff' } : {} } + }, + summaryRows() { + const rows = this.gridRows.filter(r => r.detailDate) + if (!rows.length) return [] + const detailCols = this.allCols.filter(c => c.$type === 'detail') + const metricCols = this.allCols.filter(c => c.$type === 'metric') + const calc = (type) => { + const row = { detailDate: type === 'sum' ? '总和' : '平均', $isSummary: true, $summaryType: type } + const n = rows.length || 1 + detailCols.forEach(col => { + if (col.isShift) { + const s1 = rows.reduce((a, r) => a + (parseFloat(r['q' + col.itemId + '_1']) || 0), 0) + const s2 = rows.reduce((a, r) => a + (parseFloat(r['q' + col.itemId + '_2']) || 0), 0) + row['q' + col.itemId + '_1'] = type === 'sum' ? s1.toFixed(2) : (s1 / n).toFixed(2) + row['q' + col.itemId + '_2'] = type === 'sum' ? s2.toFixed(2) : (s2 / n).toFixed(2) + row['q' + col.itemId] = type === 'sum' ? (s1 + s2).toFixed(2) : ((s1 + s2) / n).toFixed(2) + } else { + const s = rows.reduce((a, r) => a + (parseFloat(r['q' + col.itemId]) || 0), 0) + row['q' + col.itemId] = type === 'sum' ? s.toFixed(2) : (s / n).toFixed(2) + } + }) + metricCols.forEach(col => { + if (col.isShift) { + const s1 = rows.reduce((a, r) => a + (parseFloat(r['mv' + col.mIdx + '_1']) || 0), 0) + const s2 = rows.reduce((a, r) => a + (parseFloat(r['mv' + col.mIdx + '_2']) || 0), 0) + row['mv' + col.mIdx + '_1'] = type === 'sum' ? s1.toFixed(2) : (s1 / n).toFixed(2) + row['mv' + col.mIdx + '_2'] = type === 'sum' ? s2.toFixed(2) : (s2 / n).toFixed(2) + row['mv' + col.mIdx] = type === 'sum' ? (s1 + s2).toFixed(2) : ((s1 + s2) / n).toFixed(2) + } else { + const s = rows.reduce((a, r) => a + (parseFloat(r['mv' + col.mIdx]) || 0), 0) + row['mv' + col.mIdx] = type === 'sum' ? s.toFixed(2) : (s / n).toFixed(2) + } + }) + return row + } + return [calc('sum'), calc('avg')] + }, + tableData() { + return [...this.summaryRows, ...this.gridRows] } }, watch: { configOpen(v) { if (!v) this.rpOpen = false } }, @@ -509,6 +561,10 @@ export default { } }, methods: { + rowClassName({ row }) { + if (row.$isSummary) return 'summary-row' + return '' + }, /* report */ getList() { this.loading = true @@ -1142,4 +1198,8 @@ export default { .ica-backfill { color: #67c23a; margin-right: 1px; } .ica:hover { opacity: 0.7; } /deep/ .anomaly-input .el-input__inner { background: #fef0f0 !important; border-color: #f56c6c !important; } +/deep/ .summary-row td { background: #f0f7ff !important; font-weight: bold; } +/deep/ .summary-row td .cell { color: #303133; } +.summary-label { font-weight: bold; color: #303133; padding: 0 5px; } +.summary-val { font-weight: bold; color: #303133; }