92 lines
3.4 KiB
TypeScript
92 lines
3.4 KiB
TypeScript
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<string, unknown>): Promise<void> {
|
|
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,
|
|
);
|
|
}
|
|
}
|
|
}
|