fix: 添加遗漏的 registerByPhone 方法到 user-application.service.ts
修复构建错误:Property 'registerByPhone' does not exist on type 'UserApplicationService' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2897a0c74c
commit
b4dafc9e38
|
|
@ -43,6 +43,7 @@ import {
|
|||
} from '@/domain/events';
|
||||
import {
|
||||
AutoCreateAccountCommand,
|
||||
RegisterByPhoneCommand,
|
||||
RecoverByMnemonicCommand,
|
||||
RecoverByPhoneCommand,
|
||||
AutoLoginCommand,
|
||||
|
|
@ -206,6 +207,136 @@ export class UserApplicationService {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号注册 (验证码+密码一步到位)
|
||||
*
|
||||
* - 验证短信验证码
|
||||
* - 创建账户并绑定手机号
|
||||
* - 设置密码
|
||||
* - 触发钱包生成
|
||||
* - 返回 token
|
||||
*/
|
||||
async registerByPhone(
|
||||
command: RegisterByPhoneCommand,
|
||||
): Promise<AutoCreateAccountResult> {
|
||||
const phoneNumber = PhoneNumber.create(command.phoneNumber);
|
||||
|
||||
// 1. 验证短信验证码
|
||||
const cachedCode = await this.redisService.get(
|
||||
`sms:register:${phoneNumber.value}`,
|
||||
);
|
||||
if (cachedCode !== command.smsCode) {
|
||||
throw new ApplicationError('验证码错误或已过期');
|
||||
}
|
||||
|
||||
// 2. 检查手机号是否已注册
|
||||
const phoneValidation =
|
||||
await this.validatorService.validatePhoneNumber(phoneNumber);
|
||||
if (!phoneValidation.isValid) {
|
||||
throw new ApplicationError(phoneValidation.errorMessage!);
|
||||
}
|
||||
|
||||
// 3. 验证邀请码
|
||||
let inviterSequence: AccountSequence | null = null;
|
||||
if (command.inviterReferralCode) {
|
||||
const referralCode = ReferralCode.create(command.inviterReferralCode);
|
||||
const referralValidation =
|
||||
await this.validatorService.validateReferralCode(referralCode);
|
||||
if (!referralValidation.isValid) {
|
||||
throw new ApplicationError(referralValidation.errorMessage!);
|
||||
}
|
||||
const inviter =
|
||||
await this.userRepository.findByReferralCode(referralCode);
|
||||
inviterSequence = inviter!.accountSequence;
|
||||
}
|
||||
|
||||
// 4. 生成用户序列号
|
||||
const accountSequence =
|
||||
await this.sequenceGenerator.generateNextUserSequence();
|
||||
|
||||
// 5. 生成用户名和头像
|
||||
const identity = generateIdentity(accountSequence.value);
|
||||
|
||||
// 6. 构建设备名称字符串
|
||||
let deviceNameStr = '未命名设备';
|
||||
if (command.deviceName) {
|
||||
const parts: string[] = [];
|
||||
if (command.deviceName.model) parts.push(command.deviceName.model);
|
||||
if (command.deviceName.platform) parts.push(command.deviceName.platform);
|
||||
if (command.deviceName.osVersion)
|
||||
parts.push(command.deviceName.osVersion);
|
||||
if (parts.length > 0) deviceNameStr = parts.join(' ');
|
||||
}
|
||||
|
||||
// 7. 创建用户账户(带手机号)
|
||||
const account = UserAccount.create({
|
||||
accountSequence,
|
||||
phoneNumber,
|
||||
initialDeviceId: command.deviceId,
|
||||
deviceName: deviceNameStr,
|
||||
deviceInfo: command.deviceName,
|
||||
inviterSequence,
|
||||
});
|
||||
|
||||
// 8. 设置随机用户名和头像
|
||||
account.updateProfile({
|
||||
nickname: identity.username,
|
||||
avatarUrl: identity.avatarSvg,
|
||||
});
|
||||
|
||||
// 9. 保存账户
|
||||
await this.userRepository.save(account);
|
||||
|
||||
// 10. 设置密码
|
||||
const bcrypt = await import('bcrypt');
|
||||
const passwordHash = await bcrypt.hash(command.password, 10);
|
||||
await this.prisma.userAccount.update({
|
||||
where: { userId: account.userId.value },
|
||||
data: { passwordHash },
|
||||
});
|
||||
|
||||
// 11. 删除验证码
|
||||
await this.redisService.delete(`sms:register:${phoneNumber.value}`);
|
||||
|
||||
// 12. 生成 Token
|
||||
const tokens = await this.tokenService.generateTokenPair({
|
||||
userId: account.userId.toString(),
|
||||
accountSequence: account.accountSequence.value,
|
||||
deviceId: command.deviceId,
|
||||
});
|
||||
|
||||
// 13. 发布领域事件
|
||||
await this.eventPublisher.publishAll(account.domainEvents);
|
||||
account.clearDomainEvents();
|
||||
|
||||
// 14. 发布 MPC Keygen 请求事件 (触发后台生成钱包)
|
||||
const sessionId = crypto.randomUUID();
|
||||
await this.eventPublisher.publish(
|
||||
new MpcKeygenRequestedEvent({
|
||||
sessionId,
|
||||
userId: account.userId.toString(),
|
||||
accountSequence: account.accountSequence.value,
|
||||
username: `user_${account.accountSequence.value}`,
|
||||
threshold: 2,
|
||||
totalParties: 3,
|
||||
requireDelegate: true,
|
||||
}),
|
||||
);
|
||||
|
||||
this.logger.log(
|
||||
`Account registered by phone: sequence=${accountSequence.value}, phone=${phoneNumber.value}, MPC keygen requested`,
|
||||
);
|
||||
|
||||
return {
|
||||
userSerialNum: account.accountSequence.value,
|
||||
referralCode: account.referralCode.value,
|
||||
username: account.nickname,
|
||||
avatarSvg: account.avatarUrl || identity.avatarSvg,
|
||||
accessToken: tokens.accessToken,
|
||||
refreshToken: tokens.refreshToken,
|
||||
};
|
||||
}
|
||||
|
||||
async recoverByMnemonic(
|
||||
command: RecoverByMnemonicCommand,
|
||||
): Promise<RecoverAccountResult> {
|
||||
|
|
|
|||
Loading…
Reference in New Issue