diff --git a/backend/services/authorization-service/src/application/services/authorization-application.service.ts b/backend/services/authorization-service/src/application/services/authorization-application.service.ts index fda98987..bf77b6f4 100644 --- a/backend/services/authorization-service/src/application/services/authorization-application.service.ts +++ b/backend/services/authorization-service/src/application/services/authorization-application.service.ts @@ -859,12 +859,20 @@ export class AuthorizationApplicationService { const communityStats = await this.statsRepository.findByAccountSequence( nearestCommunity.userId.accountSequence, ) - const currentTeamCount = communityStats?.totalTeamPlantingCount ?? 0 + const rawTeamCount = communityStats?.totalTeamPlantingCount ?? 0 + + // 重要:由于 referral-service 和 reward-service 都消费同一个 Kafka 事件, + // 存在竞态条件,此时查询到的 totalTeamPlantingCount 可能已经包含了本次认种。 + // 因此需要减去本次认种数量来还原"认种前"的团队数。 + // 注意:如果 referral-service 还没处理完,rawTeamCount 可能还是旧值, + // 此时 currentTeamCount 可能为负数,需要取 max(0, ...) + const currentTeamCount = Math.max(0, rawTeamCount - treeCount) const initialTarget = nearestCommunity.getInitialTarget() // 社区初始考核目标:10棵 this.logger.debug( `[getCommunityRewardDistribution] Community ${nearestCommunity.userId.accountSequence} ` + - `benefitActive=false, currentTeamCount=${currentTeamCount}, initialTarget=${initialTarget}`, + `benefitActive=false, rawTeamCount=${rawTeamCount}, treeCount=${treeCount}, ` + + `currentTeamCount(before)=${currentTeamCount}, initialTarget=${initialTarget}`, ) // 6. 查找上级社区(用于接收考核前的权益) @@ -1023,9 +1031,15 @@ export class AuthorizationApplicationService { // 5. 权益未激活,计算考核分配 const stats = await this.statsRepository.findByAccountSequence(nearestAuthProvince.userId.accountSequence) - const currentTeamCount = stats?.totalTeamPlantingCount ?? 0 + const rawTeamCount = stats?.totalTeamPlantingCount ?? 0 + // 修复竞态条件:减去本次认种数量来还原"认种前"的团队数 + const currentTeamCount = Math.max(0, rawTeamCount - treeCount) const initialTarget = nearestAuthProvince.getInitialTarget() // 500棵 + this.logger.debug( + `[getProvinceTeamRewardDistribution] rawTeamCount=${rawTeamCount}, treeCount=${treeCount}, currentTeamCount(before)=${currentTeamCount}`, + ) + // 6. 查找上级(用于接收考核前的权益) let parentAccountSequence: number = HEADQUARTERS_ACCOUNT_SEQUENCE let parentReason = '上级为总部社区' @@ -1227,9 +1241,15 @@ export class AuthorizationApplicationService { // 5. 权益未激活,计算考核分配 const stats = await this.statsRepository.findByAccountSequence(nearestAuthCity.userId.accountSequence) - const currentTeamCount = stats?.totalTeamPlantingCount ?? 0 + const rawTeamCount = stats?.totalTeamPlantingCount ?? 0 + // 修复竞态条件:减去本次认种数量来还原"认种前"的团队数 + const currentTeamCount = Math.max(0, rawTeamCount - treeCount) const initialTarget = nearestAuthCity.getInitialTarget() // 100棵 + this.logger.debug( + `[getCityTeamRewardDistribution] rawTeamCount=${rawTeamCount}, treeCount=${treeCount}, currentTeamCount(before)=${currentTeamCount}`, + ) + // 6. 查找上级 let parentAccountSequence: number = HEADQUARTERS_ACCOUNT_SEQUENCE let parentReason = '上级为总部社区'