diff --git a/backend/services/authorization-service/src/app.module.ts b/backend/services/authorization-service/src/app.module.ts index 44665663..3a0d0210 100644 --- a/backend/services/authorization-service/src/app.module.ts +++ b/backend/services/authorization-service/src/app.module.ts @@ -24,7 +24,7 @@ import { ReferralServiceClient, IdentityServiceClient, RewardServiceClient } fro // Application import { AuthorizationApplicationService, REFERRAL_REPOSITORY, TEAM_STATISTICS_REPOSITORY } from '@/application/services' -import { MonthlyAssessmentScheduler, BenefitActivationFixOTP } from '@/application/schedulers' +import { MonthlyAssessmentScheduler } from '@/application/schedulers' // API import { @@ -98,7 +98,6 @@ const MockReferralRepository = { // Application Services AuthorizationApplicationService, MonthlyAssessmentScheduler, - BenefitActivationFixOTP, // OTP: 一次性修复任务,执行后删除 // Strategies JwtStrategy, diff --git a/backend/services/authorization-service/src/application/schedulers/benefit-activation-fix.otp.ts b/backend/services/authorization-service/src/application/schedulers/benefit-activation-fix.otp.ts deleted file mode 100644 index 8e7ca1af..00000000 --- a/backend/services/authorization-service/src/application/schedulers/benefit-activation-fix.otp.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { Injectable, Inject, Logger, OnModuleInit } from '@nestjs/common' -import { RoleType, AuthorizationStatus } from '@/domain/enums' -import { - IAuthorizationRoleRepository, - AUTHORIZATION_ROLE_REPOSITORY, -} from '@/domain/repositories' -import { ITeamStatisticsRepository } from '@/domain/services' -import { EventPublisherService } from '@/infrastructure/kafka' -import { TEAM_STATISTICS_REPOSITORY } from '@/application/services' - -/** - * 一次性修复任务(OTP - One Time Program) - * - * 问题描述: - * planting-service 发送的 PlantingOrderPaid 事件中的 userId 是订单表的自增主键, - * 而不是 referral-service 中的真实 user_id。这导致 handleTreePlanted 方法 - * 查询团队统计时返回 null,社区权益无法被自动激活。 - * - * 修复逻辑: - * 1. 查找所有状态为 AUTHORIZED 但 benefitActive = false 的社区授权 - * 2. 检查每个社区的 subordinateTeamPlantingCount 是否 >= initialTarget (10) - * 3. 如果满足条件,激活权益 - * - * 使用方式: - * 1. 部署此代码 - * 2. 服务启动时自动执行修复 - * 3. 执行完成后删除此文件,重新部署 - */ -@Injectable() -export class BenefitActivationFixOTP implements OnModuleInit { - private readonly logger = new Logger(BenefitActivationFixOTP.name) - - constructor( - @Inject(AUTHORIZATION_ROLE_REPOSITORY) - private readonly authorizationRepository: IAuthorizationRoleRepository, - @Inject(TEAM_STATISTICS_REPOSITORY) - private readonly statsRepository: ITeamStatisticsRepository, - private readonly eventPublisher: EventPublisherService, - ) {} - - async onModuleInit(): Promise { - // 延迟 5 秒执行,确保所有依赖都已初始化 - setTimeout(() => { - this.executeFix().catch((error) => { - this.logger.error('[OTP] Fix execution failed:', error) - }) - }, 5000) - } - - private async executeFix(): Promise { - this.logger.log('[OTP] ========================================') - this.logger.log('[OTP] 开始执行社区权益激活修复任务...') - this.logger.log('[OTP] ========================================') - - try { - // 1. 查找所有 AUTHORIZED 状态的授权 - const authorizedRoles = await this.authorizationRepository.findByStatus( - AuthorizationStatus.AUTHORIZED, - ) - - // 过滤出社区角色且 benefitActive = false 的记录 - const unactivatedCommunities = authorizedRoles.filter( - (auth) => auth.roleType === RoleType.COMMUNITY && !auth.benefitActive, - ) - - this.logger.log(`[OTP] 找到 ${unactivatedCommunities.length} 个未激活权益的社区授权`) - - if (unactivatedCommunities.length === 0) { - this.logger.log('[OTP] 没有需要修复的记录,任务结束') - return - } - - let fixedCount = 0 - let skippedCount = 0 - - // 2. 逐个检查并修复 - for (const auth of unactivatedCommunities) { - const accountSequence = auth.userId.accountSequence - - try { - // 获取团队统计 - const teamStats = await this.statsRepository.findByAccountSequence(accountSequence) - - if (!teamStats) { - this.logger.warn(`[OTP] 未找到 ${accountSequence} 的团队统计数据,跳过`) - skippedCount++ - continue - } - - const subordinateTreeCount = teamStats.subordinateTeamPlantingCount - const initialTarget = auth.getInitialTarget() - - this.logger.debug( - `[OTP] ${accountSequence}: subordinateTreeCount=${subordinateTreeCount}, initialTarget=${initialTarget}`, - ) - - // 3. 检查是否满足激活条件 - if (subordinateTreeCount >= initialTarget) { - this.logger.log( - `[OTP] ${accountSequence} 满足激活条件 (${subordinateTreeCount}>=${initialTarget}),正在激活权益...`, - ) - - // 激活权益 - auth.activateBenefit() - await this.authorizationRepository.save(auth) - await this.eventPublisher.publishAll(auth.domainEvents) - auth.clearDomainEvents() - - fixedCount++ - this.logger.log(`[OTP] ${accountSequence} 权益激活成功`) - } else { - this.logger.debug( - `[OTP] ${accountSequence} 未满足激活条件 (${subordinateTreeCount}<${initialTarget}),跳过`, - ) - skippedCount++ - } - } catch (error) { - this.logger.error(`[OTP] 处理 ${accountSequence} 时发生错误:`, error) - skippedCount++ - } - } - - // 4. 输出修复结果 - this.logger.log('[OTP] ========================================') - this.logger.log('[OTP] 社区权益激活修复任务完成') - this.logger.log(`[OTP] 总计处理: ${unactivatedCommunities.length}`) - this.logger.log(`[OTP] 成功修复: ${fixedCount}`) - this.logger.log(`[OTP] 跳过/失败: ${skippedCount}`) - this.logger.log('[OTP] ========================================') - } catch (error) { - this.logger.error('[OTP] 修复任务执行失败:', error) - throw error - } - } -} diff --git a/backend/services/authorization-service/src/application/schedulers/index.ts b/backend/services/authorization-service/src/application/schedulers/index.ts index 3ad9dfba..ac9e816c 100644 --- a/backend/services/authorization-service/src/application/schedulers/index.ts +++ b/backend/services/authorization-service/src/application/schedulers/index.ts @@ -1,2 +1 @@ export * from './monthly-assessment.scheduler' -export * from './benefit-activation-fix.otp'