wangrong
2026-09-26 22c5f37a587bfb3363534fed05647faf5f93c8fe
src/modules/report/service/taskservicesite.ts
@@ -55,18 +55,33 @@
        // 3. 内存聚合核心:定义支持动态键名累加的对象字典
        const siteAggMap = new Map<string, any>();
        // 映射表:将明细里的 garbageType 映射到你 Entity 里的字段后缀
        // 源数据 garbageType 为大写 SW62001…SW62007,没有单独的 SW62 流水。
        // 先按 7 个子类分别累计,再把重量/碳排/销售额汇总进 SW62。
        const SW62_SUB_CODES = [
            'SW62001', 'SW62002', 'SW62003', 'SW62004',
            'SW62005', 'SW62006', 'SW62007',
        ];
        const SW62_SUB_SUFFIXES = SW62_SUB_CODES.map(code => `Sw${code.slice(2)}`);
        const typeSuffixes = [
            'Sw60', 'Sw61', 'Sw62', 'Sw63', 'Sw64',
            ...SW62_SUB_SUFFIXES,
        ];
        const typeKeyMap: Record<string, string> = {
            'SW60': 'Sw60', 'SW61': 'Sw61', 'SW62': 'Sw62', 'SW63': 'Sw63', 'SW64': 'Sw64',
            'Sw62001': 'Sw62001', 'Sw62002': 'Sw62002', 'Sw62003': 'Sw62003',
            'Sw62004': 'Sw62004', 'Sw62005': 'Sw62005', 'Sw62006': 'Sw62006', 'Sw62007': 'Sw62007'
            SW60: 'Sw60',
            SW61: 'Sw61',
            SW63: 'Sw63',
            SW64: 'Sw64',
        };
        for (const code of SW62_SUB_CODES) {
            const suffix = `Sw${code.slice(2)}`;
            typeKeyMap[code] = suffix;
            typeKeyMap[suffix] = suffix;
        }
        for (const row of rawDetails) {
            const siteId = row.siteId;
            const weight = Number(row.weight) || 0;
            const gType = row.garbageType || 'SW64';
            const gType = String(row.garbageType || 'SW64').trim().toUpperCase();
            const fieldSuffix = typeKeyMap[gType];
            // 初始化该站点的聚合结构
@@ -79,7 +94,7 @@
                    weightTotal: 0, timeTotal: 0, carbonTotal: 0
                };
                // 动态初始化宽表里各子类型的 0 值
                Object.values(typeKeyMap).forEach(suffix => {
                typeSuffixes.forEach(suffix => {
                    initData[`weight${suffix}`] = 0;
                    initData[`time${suffix}`] = 0;
                    initData[`carbon${suffix}`] = 0;
@@ -119,6 +134,24 @@
            }
        }
        // SW62 没有独立流水,用 7 个子类重量/碳排/销售额加总写入父类字段
        for (const agg of siteAggMap.values()) {
            let weightSw62 = 0;
            let carbonSw62 = 0;
            let salesSw62 = 0;
            let timeSw62 = 0;
            for (const suffix of SW62_SUB_SUFFIXES) {
                weightSw62 += Number(agg[`weight${suffix}`]) || 0;
                carbonSw62 += Number(agg[`carbon${suffix}`]) || 0;
                salesSw62 += Number(agg[`estimatedSales${suffix}`]) || 0;
                timeSw62 = Math.max(timeSw62, Number(agg[`time${suffix}`]) || 0);
            }
            agg.weightSw62 = weightSw62;
            agg.carbonSw62 = carbonSw62;
            agg.estimatedSalesSw62 = salesSw62;
            agg.timeSw62 = timeSw62;
        }
        // 4. 高性能写入:转换为数组,利用批量插入 + ON DUPLICATE KEY UPDATE 提交给 MySQL
        const finalRecords = Array.from(siteAggMap.values()).map(item => {
            // 浮点数防精度丢失处理,保留两位小数