From 336306d6c0a359b921d60137a98123b4655e8e3e Mon Sep 17 00:00:00 2001 From: hailin Date: Tue, 23 Dec 2025 20:38:27 -0800 Subject: [PATCH] =?UTF-8?q?fix(wallet-service):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=B4=A6=E6=9C=AC=E7=BB=9F=E8=AE=A1=E5=8F=8C=E9=87=8D=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 排除临时性流水类型(冻结/解冻)的收支统计: - PLANT_FREEZE(认种冻结) - PLANT_UNFREEZE(认种解冻) - FREEZE(通用冻结) - UNFREEZE(通用解冻) 问题原因:认种流程产生两笔流水(冻结+支付),导致一笔支出被统计两次 修复后:只统计最终的实际支付,冻结/解冻作为中间状态不计入收支 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../services/wallet-application.service.ts | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/backend/services/wallet-service/src/application/services/wallet-application.service.ts b/backend/services/wallet-service/src/application/services/wallet-application.service.ts index 3c568686..d16634fc 100644 --- a/backend/services/wallet-service/src/application/services/wallet-application.service.ts +++ b/backend/services/wallet-service/src/application/services/wallet-application.service.ts @@ -1967,19 +1967,32 @@ export class WalletApplicationService { } // 计算收支 + // 排除临时性流水类型(冻结/解冻),避免双重计算 + // 例如:认种流程会产生 PLANT_FREEZE(-100) + PLANT_PAYMENT(-100),实际只支出 100 + const excludeFromStats = new Set([ + 'PLANT_FREEZE', // 认种冻结(临时) + 'PLANT_UNFREEZE', // 认种解冻(回滚) + 'FREEZE', // 通用冻结(临时) + 'UNFREEZE', // 通用解冻(回滚) + ]); + let totalIncome = 0; let totalExpense = 0; const byTypeMap = new Map(); for (const entry of entries) { const amount = Number(entry.amount); - if (amount > 0) { - totalIncome += amount; - } else { - totalExpense += Math.abs(amount); + + // 只计算非临时性流水的收支统计 + if (!excludeFromStats.has(entry.entryType)) { + if (amount > 0) { + totalIncome += amount; + } else { + totalExpense += Math.abs(amount); + } } - // 按类型汇总 + // 按类型汇总(包含所有类型,方便查看明细) const existing = byTypeMap.get(entry.entryType) || { totalAmount: 0, count: 0 }; existing.totalAmount += amount; existing.count += 1; @@ -2047,6 +2060,14 @@ export class WalletApplicationService { } // 填充数据 + // 排除临时性流水类型(冻结/解冻),避免双重计算 + const excludeFromStats = new Set([ + 'PLANT_FREEZE', // 认种冻结(临时) + 'PLANT_UNFREEZE', // 认种解冻(回滚) + 'FREEZE', // 通用冻结(临时) + 'UNFREEZE', // 通用解冻(回滚) + ]); + let periodIncome = 0; let periodExpense = 0; @@ -2055,12 +2076,15 @@ export class WalletApplicationService { const amount = Number(entry.amount); const existing = dailyMap.get(dateStr) || { income: 0, expense: 0, count: 0 }; - if (amount > 0) { - existing.income += amount; - periodIncome += amount; - } else { - existing.expense += Math.abs(amount); - periodExpense += Math.abs(amount); + // 只计算非临时性流水的收支统计 + if (!excludeFromStats.has(entry.entryType)) { + if (amount > 0) { + existing.income += amount; + periodIncome += amount; + } else { + existing.expense += Math.abs(amount); + periodExpense += Math.abs(amount); + } } existing.count += 1; dailyMap.set(dateStr, existing);