diff --git a/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts b/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts index dc82abf5..dca61bc0 100644 --- a/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts +++ b/backend/services/contribution-service/src/application/services/contribution-calculation.service.ts @@ -56,11 +56,9 @@ export class ContributionCalculationService { const userReferral = await this.syncedDataRepository.findSyncedReferralByAccountSequence(adoption.accountSequence); // 获取上线链条(最多15级) - // 注意:不依赖 referrerAccountSequence(可能为 null 由于 CDC 同步顺序问题) - // 改用 ancestorPath 来构建上线链 let ancestorChain: SyncedReferral[] = []; - if (userReferral) { - ancestorChain = await this.buildAncestorChainFromReferral(userReferral); + if (userReferral?.referrerAccountSequence) { + ancestorChain = await this.buildAncestorChain(userReferral.referrerAccountSequence); } // 获取认种人的算力账户(用于判断 TEAM_BONUS 解锁状态) @@ -90,10 +88,8 @@ export class ContributionCalculationService { await this.updateAdopterUnlockStatus(adoption.accountSequence); // 更新直接上线的解锁状态 - // 使用 ancestorPath 或 referrerAccountSequence 来获取直接上线 - const directReferrer = await this.getDirectReferrer(userReferral); - if (directReferrer) { - await this.updateReferrerUnlockStatus(directReferrer); + if (userReferral?.referrerAccountSequence) { + await this.updateReferrerUnlockStatus(userReferral.referrerAccountSequence); } // 发布分配结果到 Kafka(通过 Outbox 模式) @@ -152,71 +148,7 @@ export class ContributionCalculationService { } /** - * 获取直接上线的 accountSequence - * 优先使用 ancestorPath,因为 referrerAccountSequence 可能为 null(CDC 同步顺序问题) - */ - private async getDirectReferrer(userReferral: SyncedReferral | null): Promise { - if (!userReferral) { - return null; - } - - // 优先使用 referrerAccountSequence - if (userReferral.referrerAccountSequence) { - return userReferral.referrerAccountSequence; - } - - // 回退:使用 ancestorPath 的第一个元素(直接上线的 userId) - if (userReferral.ancestorPath) { - const ancestorUserIds = userReferral.ancestorPath - .split(',') - .filter((id) => id.trim()); - - if (ancestorUserIds.length > 0) { - const directReferrerUserId = BigInt(ancestorUserIds[0].trim()); - const referrerReferral = await this.syncedDataRepository.findSyncedReferralByOriginalUserId(directReferrerUserId); - if (referrerReferral) { - return referrerReferral.accountSequence; - } - } - } - - return null; - } - - /** - * 从 referral 记录构建上线链条 - * 使用 ancestor_path 而不是 referrerAccountSequence,以避免 CDC 同步顺序问题 - */ - private async buildAncestorChainFromReferral(userReferral: SyncedReferral): Promise { - const ancestors: SyncedReferral[] = []; - - // 优先使用 ancestor_path 来构建上线链 - if (userReferral.ancestorPath) { - const ancestorUserIds = userReferral.ancestorPath - .split(',') - .filter((id) => id.trim()) - .map((id) => BigInt(id.trim())); - - // ancestor_path 存储的是从直接上线到根的 user_id 列表 - for (let i = 0; i < ancestorUserIds.length && ancestors.length < 15; i++) { - const ancestorUserId = ancestorUserIds[i]; - const ancestorReferral = await this.syncedDataRepository.findSyncedReferralByOriginalUserId(ancestorUserId); - if (ancestorReferral) { - ancestors.push(ancestorReferral); - } else { - this.logger.warn(`Ancestor referral not found for userId: ${ancestorUserId}`); - } - } - } else if (userReferral.referrerAccountSequence) { - // 回退方案:使用 referrerAccountSequence 逐级查找 - return await this.syncedDataRepository.findAncestorChain(userReferral.referrerAccountSequence, 15); - } - - return ancestors; - } - - /** - * 构建上线链条(保留向后兼容) + * 构建上线链条 */ private async buildAncestorChain(startAccountSequence: string): Promise { return await this.syncedDataRepository.findAncestorChain(startAccountSequence, 15); @@ -400,29 +332,28 @@ export class ContributionCalculationService { * 更新上线的解锁状态(直推用户认种后) */ private async updateReferrerUnlockStatus(referrerAccountSequence: string): Promise { - let account = await this.contributionAccountRepository.findByAccountSequence(referrerAccountSequence); + const account = await this.contributionAccountRepository.findByAccountSequence(referrerAccountSequence); + if (!account) return; - // 如果账户不存在,先创建一个 - if (!account) { - account = ContributionAccountAggregate.create(referrerAccountSequence); - } - - // 重新计算直推认种用户数(从数据库实时查询) + // 重新计算直推认种用户数 const directReferralAdoptedCount = await this.syncedDataRepository.getDirectReferralAdoptedCount( referrerAccountSequence, ); - // 直接设置计数值(不是增量更新),确保数据一致性 + // 更新解锁状态 const currentCount = account.directReferralAdoptedCount; - if (directReferralAdoptedCount !== currentCount) { - account.setDirectReferralAdoptedCount(directReferralAdoptedCount); + if (directReferralAdoptedCount > currentCount) { + // 需要增量更新 + for (let i = currentCount; i < directReferralAdoptedCount; i++) { + account.incrementDirectReferralAdoptedCount(); + } await this.contributionAccountRepository.save(account); // 发布账户更新事件到 outbox(用于 CDC 同步到 mining-admin-service) await this.publishContributionAccountUpdatedEvent(account); this.logger.debug( - `Updated referrer ${referrerAccountSequence} unlock status: count=${directReferralAdoptedCount}, level=${account.unlockedLevelDepth}, bonus=${account.unlockedBonusTiers}`, + `Updated referrer ${referrerAccountSequence} unlock status: level=${account.unlockedLevelDepth}, bonus=${account.unlockedBonusTiers}`, ); } } diff --git a/backend/services/contribution-service/src/infrastructure/persistence/repositories/synced-data.repository.ts b/backend/services/contribution-service/src/infrastructure/persistence/repositories/synced-data.repository.ts index e784a29e..c8f986f1 100644 --- a/backend/services/contribution-service/src/infrastructure/persistence/repositories/synced-data.repository.ts +++ b/backend/services/contribution-service/src/infrastructure/persistence/repositories/synced-data.repository.ts @@ -255,52 +255,25 @@ export class SyncedDataRepository implements ISyncedDataRepository { async findAncestorChain(accountSequence: string, maxLevel: number = 15): Promise { const ancestors: SyncedReferral[] = []; + let currentSequence = accountSequence; - // 首先获取起始账户的 referral 记录,以获取 ancestor_path - const startReferral = await this.findSyncedReferralByAccountSequence(accountSequence); - if (!startReferral) { - // 如果起始账户没有 referral 记录,尝试直接返回该账户作为第一级上线 - // (用于处理 CDC 顺序问题:上线的 referral 记录可能存在但 referrerAccountSequence 为空) - return ancestors; - } - - // 把起始账户(直接上线)加入链条 - ancestors.push(startReferral); - - // 如果有 ancestor_path,使用它来构建完整的上线链 - if (startReferral.ancestorPath) { - const ancestorUserIds = startReferral.ancestorPath - .split(',') - .filter((id) => id.trim()) - .map((id) => BigInt(id.trim())); - - // ancestor_path 是从直接上线到根的 user_id 列表 - // 我们需要找到对应的 SyncedReferral 记录 - for (let i = 0; i < ancestorUserIds.length && ancestors.length < maxLevel; i++) { - const ancestorUserId = ancestorUserIds[i]; - const ancestorReferral = await this.findSyncedReferralByOriginalUserId(ancestorUserId); - if (ancestorReferral) { - ancestors.push(ancestorReferral); - } + for (let i = 0; i < maxLevel; i++) { + // 获取当前账户的 referral 记录(包含该账户作为上线的信息) + const referral = await this.findSyncedReferralByAccountSequence(currentSequence); + if (!referral) { + break; } - } else { - // 如果没有 ancestor_path,回退到使用 referrerAccountSequence 逐级查找 - let currentSequence = startReferral.referrerAccountSequence; - while (currentSequence && ancestors.length < maxLevel) { - const referral = await this.findSyncedReferralByAccountSequence(currentSequence); - if (!referral) { - break; - } + // 把当前账户加入上线链条 + ancestors.push(referral); - ancestors.push(referral); - - if (!referral.referrerAccountSequence) { - break; - } - - currentSequence = referral.referrerAccountSequence; + // 如果没有更上级的推荐人,终止 + if (!referral.referrerAccountSequence) { + break; } + + // 继续向上追溯 + currentSequence = referral.referrerAccountSequence; } return ancestors;