fix(wallet-service): 修复账本统计双重计算问题

排除临时性流水类型(冻结/解冻)的收支统计:
- PLANT_FREEZE(认种冻结)
- PLANT_UNFREEZE(认种解冻)
- FREEZE(通用冻结)
- UNFREEZE(通用解冻)

问题原因:认种流程产生两笔流水(冻结+支付),导致一笔支出被统计两次
修复后:只统计最终的实际支付,冻结/解冻作为中间状态不计入收支

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-23 20:38:27 -08:00
parent 69fa43ebee
commit 336306d6c0
1 changed files with 35 additions and 11 deletions

View File

@ -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<string, { totalAmount: number; count: number }>();
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);