import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; import { KafkaService } from '../../infrastructure'; import { ReferralService } from '../services'; import { CreateReferralRelationshipCommand } from '../commands'; /** * identity-service 发布的账户创建事件结构 */ interface UserAccountCreatedPayload { userId: string; accountSequence: string; // 格式: D + YYMMDD + 5位序号 inviterSequence: string | null; // 格式: D + YYMMDD + 5位序号 registeredAt: string; // UserAccountCreated 有 phoneNumber, UserAccountAutoCreated 没有 phoneNumber?: string; initialDeviceId?: string; } interface IdentityEvent { eventId: string; eventType: string; occurredAt: string; payload: UserAccountCreatedPayload; } /** * 用户注册事件处理器 * 监听 identity-service 发出的用户创建事件 * 支持两种创建方式: * - identity.UserAccountAutoCreated: 免密快捷创建 * - identity.UserAccountCreated: 手机号密码创建 */ @Injectable() export class UserRegisteredHandler implements OnModuleInit { private readonly logger = new Logger(UserRegisteredHandler.name); constructor( private readonly kafkaService: KafkaService, private readonly referralService: ReferralService, ) {} async onModuleInit() { await this.kafkaService.subscribe( 'referral-service-user-account-created', ['identity.UserAccountAutoCreated', 'identity.UserAccountCreated'], this.handleMessage.bind(this), ); this.logger.log('Subscribed to identity.UserAccountAutoCreated and identity.UserAccountCreated events'); } private async handleMessage(topic: string, message: Record): Promise { const event = message as unknown as IdentityEvent; // 验证事件类型 if (event.eventType !== 'UserAccountAutoCreated' && event.eventType !== 'UserAccountCreated') { this.logger.debug(`Ignoring event type: ${event.eventType}`); return; } const payload = event.payload; try { this.logger.log( `Processing ${event.eventType} event: accountSequence=${payload.accountSequence}, inviterSequence=${payload.inviterSequence}`, ); // 从 accountSequence 提取数值部分作为 userId // accountSequence 格式: D + YYMMDD + 5位序号 (例如: D25121200000) // 去掉 "D" 前缀后得到 11 位数字,作为全局唯一的 userId // 这样可以避免依赖 identity-service 的临时 userId (可能是 0) const userIdFromSequence = BigInt(payload.accountSequence.substring(1)); // 去掉 "D" 前缀 const command = new CreateReferralRelationshipCommand( userIdFromSequence, // 使用从 accountSequence 提取的数值作为 userId payload.accountSequence, // 完整的 accountSequence 字符串 null, // referrerCode - 不通过推荐码查找 payload.inviterSequence, // 通过 accountSequence 查找推荐人 ); const result = await this.referralService.createReferralRelationship(command); this.logger.log( `Created referral relationship for accountSequence=${payload.accountSequence}, code: ${result.referralCode}, inviter: ${payload.inviterSequence ?? 'none'}`, ); } catch (error) { this.logger.error( `Failed to create referral relationship for accountSequence=${payload.accountSequence}:`, error, ); } } }