From 8e6c592cb1940a909d14a013de35767effbbad0a Mon Sep 17 00:00:00 2001
From: wangrong <wangrong@shsening.com>
Date: 星期六, 26 九月 2026 20:33:22 +0800
Subject: [PATCH] 修改首页显示bug

---
 src/modules/base/middleware/authority.ts |    4 +
 src/modules/report/service/screen.ts     |   95 ++++++++++++++++++++++++-----------------------
 2 files changed, 51 insertions(+), 48 deletions(-)

diff --git a/src/modules/base/middleware/authority.ts b/src/modules/base/middleware/authority.ts
index d0fd5ed..6f1e934 100644
--- a/src/modules/base/middleware/authority.ts
+++ b/src/modules/base/middleware/authority.ts
@@ -100,7 +100,9 @@
           if (
             new RegExp(`^${adminUrl}?.*/comm/`).test(url) ||
             // 瀛楀吀鎺ュ彛
-            url == '/admin/dict/info/data'
+            url == '/admin/dict/info/data' ||
+            // 椹鹃┒鑸遍椤垫眹鎬伙細鑿滃崟銆岄椤点�嶆病鏈夋寜閽潈闄愶紝鏈櫥璁� report:screen:query 鏃堕潪瓒呯浼� 403
+            url == '/admin/report/screen/query'
           ) {
             await next();
             return;
diff --git a/src/modules/report/service/screen.ts b/src/modules/report/service/screen.ts
index 3f1ab70..02518ae 100644
--- a/src/modules/report/service/screen.ts
+++ b/src/modules/report/service/screen.ts
@@ -28,7 +28,7 @@
 
 const ITEM_COLORS = ['#3b82f6', '#22c55e', '#f59e0b', '#a855f7', '#06b6d4', '#ef4444', '#94a3b8'];
 
-/** 鏃ヨ〃鍒椾笌鍨冨溇绉嶇被缂栫爜銆傞椤靛垎绫荤粺璁″彧绱姞鍏朵腑鐘舵�佷负鍚敤鐨勭紪鐮併�� */
+/** 鏃ヨ〃鍒椾笌鍨冨溇绉嶇被缂栫爜锛岄椤� KPI/瓒嬪娍鍙e緞浠ユ湰琛ㄤ负鍑嗭紝涓嶈绉嶇被琛ㄥ惎鐢ㄧ姸鎬併�� */
 const WASTE_FIELDS: {
   code: string;
   weight: string;
@@ -51,6 +51,9 @@
     group: (idx === '006' ? 'elec' : idx === '004' ? 'fabric' : undefined) as 'elec' | 'fabric' | undefined,
   })),
 ];
+
+/** 浜斿ぇ绫伙紱瀛愮被宸叉粴鍏� SW62锛屾�婚噺涓嶅啀鎶� SW62001鈥�007 鍔犱竴閬嶃�� */
+const MAIN_WASTE_FIELDS = WASTE_FIELDS.filter(f => /^SW6[0-4]$/.test(f.code));
 
 type OrdersByType = {
   axis: string[];
@@ -143,21 +146,21 @@
       safe('骞村害绔欑偣鏃ユ眹鎬�', () => this.sumSite(yearStart, yearEnd), emptySum),
     ]);
 
-    const enabledWaste = await safe(
-      '鍚敤鍨冨溇绉嶇被',
-      () => this.enabledWaste(),
-      { names: new Map<string, string>(), codes: new Set<string>() }
+    const wasteNames = await safe(
+      '鍨冨溇绉嶇被鍚嶇О',
+      () => this.wasteNames(),
+      new Map<string, string>()
     );
-    const wasteMix = this.buildWasteMix(period, enabledWaste);
-    const recycleItems = this.buildRecycleItems(period, enabledWaste);
+    const wasteMix = this.buildWasteMix(period, wasteNames);
+    const recycleItems = this.buildRecycleItems(period, wasteNames);
     const { axis, trend } = await safe(
       '鍥炴敹瓒嬪娍',
-      () => this.buildTrend(range || 'month', dates, enabledWaste.codes),
+      () => this.buildTrend(range || 'month', dates),
       { axis: [], trend: { weight: [], value: [], carbon: [] } }
     );
     const yearCarbon = await safe(
       '骞村害纰冲噺鎺�',
-      () => this.buildYearCarbon(enabledWaste.codes),
+      () => this.buildYearCarbon(),
       Array.from({ length: 12 }, () => 0)
     );
     const ranks = await safe(
@@ -208,10 +211,10 @@
       sites: [],
     });
 
-    const periodStat = this.statEnabled(period, enabledWaste.codes);
-    const todayStat = this.statEnabled(todayRow, enabledWaste.codes);
-    const totalStat = this.statEnabled(totalRow, enabledWaste.codes);
-    const yearStat = this.statEnabled(yearRow, enabledWaste.codes);
+    const periodStat = this.statKpi(period);
+    const todayStat = this.statKpi(todayRow);
+    const totalStat = this.statKpi(totalRow);
+    const yearStat = this.statKpi(yearRow);
 
     return {
       range: range || 'month',
@@ -357,6 +360,11 @@
       .addSelect('SUM(a.timeSw63)', 'timeSw63')
       .addSelect('SUM(a.timeSw64)', 'timeSw64')
       .addSelect('SUM(a.carbonTotal)', 'carbonTotal')
+      .addSelect('SUM(a.carbonSw60)', 'carbonSw60')
+      .addSelect('SUM(a.carbonSw61)', 'carbonSw61')
+      .addSelect('SUM(a.carbonSw62)', 'carbonSw62')
+      .addSelect('SUM(a.carbonSw63)', 'carbonSw63')
+      .addSelect('SUM(a.carbonSw64)', 'carbonSw64')
       .addSelect('SUM(a.estimatedSalesSw62)', 'estimatedSalesSw62');
 
     for (const i of ['001', '002', '003', '004', '005', '006', '007']) {
@@ -371,34 +379,30 @@
     return (await qb.getRawOne()) || {};
   }
 
-  /** 鍚嶇О鍙栧叏閮ㄧ绫伙紱codes 浠嶅彧鍚惎鐢ㄩ」锛屼緵 KPI/瓒嬪娍娌跨敤鍘熷彛寰勩�傚垎绫诲浘涓嶅啀鐢� codes 杩囨护銆� */
-  private async enabledWaste() {
+  /** 绉嶇被鍚嶇О浠呬綔灞曠ず锛屼笉鍙備笌 KPI 杩囨护銆� */
+  private async wasteNames() {
     const list = await this.wasteTypeRepo.find({
-      select: ['code', 'name', 'status'],
+      select: ['code', 'name'],
     });
     const names = new Map<string, string>();
-    const codes = new Set<string>();
     list.forEach(e => {
-      const code = String(e.code).toUpperCase();
-      names.set(code, e.name);
-      if (Number(e.status) === 1) {
-        codes.add(code);
-      }
+      names.set(String(e.code).toUpperCase(), e.name);
     });
-    return { names, codes };
+    return names;
   }
 
-  /** 鍙疮鍔犲惎鐢ㄧ绫诲搴旂殑鏃ヨ〃鍒楋紝閬垮厤绂佺敤绉嶇被杩涘叆閲嶉噺銆佺⒊鎺掑拰閿�鍞銆� */
-  private statEnabled(row: any, codes: Set<string>) {
-    const on = WASTE_FIELDS.filter(f => codes.has(f.code));
-    const sum = (pick: (f: (typeof WASTE_FIELDS)[number]) => string | undefined) =>
-      on.reduce((s, f) => s + n(row?.[pick(f)]), 0);
+  /** 鎸� WASTE_FIELDS 姹囨�伙紱鎬婚噺鐢ㄤ簲澶х被锛屽垎缁勬寚鏍囩敤 group 瀛楁銆� */
+  private statKpi(row: any) {
+    const sum = (
+      fields: typeof WASTE_FIELDS,
+      pick: (f: (typeof WASTE_FIELDS)[number]) => string | undefined
+    ) => fields.reduce((s, f) => s + n(row?.[pick(f)]), 0);
     const ofGroup = (group: 'recyclable' | 'bulk' | 'elec' | 'fabric') =>
-      on.filter(f => f.group === group).reduce((s, f) => s + n(row?.[f.weight]), 0);
+      WASTE_FIELDS.filter(f => f.group === group).reduce((s, f) => s + n(row?.[f.weight]), 0);
     return {
-      weight: sum(f => f.weight),
-      carbon: sum(f => f.carbon),
-      sales: sum(f => f.sales),
+      weight: sum(MAIN_WASTE_FIELDS, f => f.weight),
+      carbon: sum(MAIN_WASTE_FIELDS, f => f.carbon),
+      sales: sum(MAIN_WASTE_FIELDS, f => f.sales),
       recyclable: ofGroup('recyclable'),
       bulk: ofGroup('bulk'),
       elec: ofGroup('elec'),
@@ -406,16 +410,14 @@
     };
   }
 
-  private enabledExpr(codes: Set<string>, pick: (f: (typeof WASTE_FIELDS)[number]) => string | undefined) {
-    const cols = WASTE_FIELDS.filter(f => codes.has(f.code))
-      .map(pick)
-      .filter((col): col is string => !!col);
+  private kpiExpr(pick: (f: (typeof WASTE_FIELDS)[number]) => string | undefined) {
+    const cols = MAIN_WASTE_FIELDS.map(pick).filter((col): col is string => !!col);
     if (!cols.length) return '0';
     return cols.map(col => `IFNULL(a.${col},0)`).join(' + ');
   }
 
   /** 棣栭〉鍒嗙被鍏ㄩ噺杩斿洖锛屼笉鎸夌绫诲惎鐢ㄧ姸鎬佽鍓紱0 鍊肩敱鍓嶇鍥捐〃闅愯棌銆� */
-  private buildWasteMix(row: any, waste: { names: Map<string, string>; codes: Set<string> }) {
+  private buildWasteMix(row: any, names: Map<string, string>) {
     const items = [
       { code: 'SW62', key: 'Sw62' },
       { code: 'SW64', key: 'Sw64' },
@@ -424,7 +426,7 @@
       { code: 'SW60', key: 'Sw60' },
     ];
     return items.map(e => ({
-      name: waste.names.get(e.code) || this.defaultWasteName(e.code),
+      name: names.get(e.code) || this.defaultWasteName(e.code),
       code: e.code,
       weight: round(n(row[`weight${e.key}`]), 1),
       value: e.code === 'SW62' ? round(n(row.estimatedSalesSw62), 0) : 0,
@@ -446,12 +448,12 @@
   }
 
   /** 鍙洖鏀� 7 瀛愮被鍏ㄩ噺杩斿洖锛涚⒊鍊间繚鐣欑鍙凤紙鍑忔帓鍙负璐燂級锛屽浘琛ㄤ晶鍙栫粷瀵瑰�煎睍绀恒�� */
-  private buildRecycleItems(row: any, waste: { names: Map<string, string>; codes: Set<string> }) {
+  private buildRecycleItems(row: any, names: Map<string, string>) {
     const fallback = ['搴熺焊', '濉戞枡', '閲戝睘', '缁囩墿', '鐜荤拑', '鐢靛瓙浜у搧', '鍏朵粬鍙洖鏀�'];
     return ['001', '002', '003', '004', '005', '006', '007']
       .map((idx, i) => ({ idx, i, code: `SW62${idx}` }))
       .map(e => ({
-        name: waste.names.get(e.code) || fallback[e.i],
+        name: names.get(e.code) || fallback[e.i],
         code: e.code,
         weight: round(n(row[`weightSw62${e.idx}`]), 1),
         value: round(n(row[`estimatedSalesSw62${e.idx}`]), 0),
@@ -462,8 +464,7 @@
 
   private async buildTrend(
     range: string,
-    dates: { start: string; end: string; startTime: string; endTime: string },
-    codes: Set<string>
+    dates: { start: string; end: string; startTime: string; endTime: string }
   ) {
     const trendStart =
       range === 'today' ? moment().subtract(6, 'day').format('YYYY-MM-DD') : dates.start;
@@ -472,9 +473,9 @@
     const qb = this.dailySite
       .createQueryBuilder('a')
       .select('a.date', 'date')
-      .addSelect(`SUM(${this.enabledExpr(codes, f => f.weight)})`, 'weight')
-      .addSelect(`SUM(${this.enabledExpr(codes, f => f.sales)})`, 'value')
-      .addSelect(`SUM(${this.enabledExpr(codes, f => f.carbon)})`, 'carbon')
+      .addSelect(`SUM(${this.kpiExpr(f => f.weight)})`, 'weight')
+      .addSelect(`SUM(${this.kpiExpr(f => f.sales)})`, 'value')
+      .addSelect(`SUM(${this.kpiExpr(f => f.carbon)})`, 'carbon')
       .where('a.date BETWEEN :start AND :end', { start: trendStart, end: trendEnd })
       .groupBy('a.date')
       .orderBy('a.date', 'ASC');
@@ -527,13 +528,13 @@
     return { axis, trend: { weight, value, carbon } };
   }
 
-  private async buildYearCarbon(codes: Set<string>) {
+  private async buildYearCarbon() {
     const start = moment().startOf('year').format('YYYY-MM-DD');
     const end = moment().endOf('year').format('YYYY-MM-DD');
     const qb = this.dailySite
       .createQueryBuilder('a')
       .select('MONTH(a.date)', 'm')
-      .addSelect(`SUM(${this.enabledExpr(codes, f => f.carbon)})`, 'carbon')
+      .addSelect(`SUM(${this.kpiExpr(f => f.carbon)})`, 'carbon')
       .where('a.date BETWEEN :start AND :end', { start, end })
       .groupBy('MONTH(a.date)');
     this.applyDept(qb, 'a');

--
Gitblit v1.9.1