fix(identity-service): regenerate avatar if missing during account recovery
When recovering account via mnemonic or phone, check if avatarUrl is null and regenerate a new random avatar SVG if needed. This fixes the bug where users see no avatar after recovering their account. 🤖 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
9dd4bb3ac5
commit
7f2511227f
|
|
@ -7,6 +7,7 @@ import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.se
|
||||||
import { BlockchainClientService } from '@/infrastructure/external/blockchain/blockchain-client.service';
|
import { BlockchainClientService } from '@/infrastructure/external/blockchain/blockchain-client.service';
|
||||||
import { ApplicationError } from '@/shared/exceptions/domain.exception';
|
import { ApplicationError } from '@/shared/exceptions/domain.exception';
|
||||||
import { RecoverAccountResult } from '../index';
|
import { RecoverAccountResult } from '../index';
|
||||||
|
import { generateRandomAvatarSvg } from '@/shared/utils/random-identity.util';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RecoverByMnemonicHandler {
|
export class RecoverByMnemonicHandler {
|
||||||
|
|
@ -40,6 +41,14 @@ export class RecoverByMnemonicHandler {
|
||||||
|
|
||||||
this.logger.log(`Mnemonic verified successfully for account ${command.accountSequence}`);
|
this.logger.log(`Mnemonic verified successfully for account ${command.accountSequence}`);
|
||||||
|
|
||||||
|
// 如果头像为空,重新生成一个
|
||||||
|
let avatarUrl = account.avatarUrl;
|
||||||
|
if (!avatarUrl) {
|
||||||
|
this.logger.log(`Account ${command.accountSequence} has no avatar, generating new one`);
|
||||||
|
avatarUrl = generateRandomAvatarSvg();
|
||||||
|
account.updateProfile({ avatarUrl });
|
||||||
|
}
|
||||||
|
|
||||||
account.addDevice(command.newDeviceId, command.deviceName);
|
account.addDevice(command.newDeviceId, command.deviceName);
|
||||||
account.recordLogin();
|
account.recordLogin();
|
||||||
await this.userRepository.save(account);
|
await this.userRepository.save(account);
|
||||||
|
|
@ -57,7 +66,7 @@ export class RecoverByMnemonicHandler {
|
||||||
userId: account.userId.toString(),
|
userId: account.userId.toString(),
|
||||||
accountSequence: account.accountSequence.value,
|
accountSequence: account.accountSequence.value,
|
||||||
nickname: account.nickname,
|
nickname: account.nickname,
|
||||||
avatarUrl: account.avatarUrl,
|
avatarUrl,
|
||||||
referralCode: account.referralCode.value,
|
referralCode: account.referralCode.value,
|
||||||
accessToken: tokens.accessToken,
|
accessToken: tokens.accessToken,
|
||||||
refreshToken: tokens.refreshToken,
|
refreshToken: tokens.refreshToken,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Injectable, Inject } from '@nestjs/common';
|
import { Injectable, Inject, Logger } from '@nestjs/common';
|
||||||
import { RecoverByPhoneCommand } from './recover-by-phone.command';
|
import { RecoverByPhoneCommand } from './recover-by-phone.command';
|
||||||
import { UserAccountRepository, USER_ACCOUNT_REPOSITORY } from '@/domain/repositories/user-account.repository.interface';
|
import { UserAccountRepository, USER_ACCOUNT_REPOSITORY } from '@/domain/repositories/user-account.repository.interface';
|
||||||
import { AccountSequence, PhoneNumber } from '@/domain/value-objects';
|
import { AccountSequence, PhoneNumber } from '@/domain/value-objects';
|
||||||
|
|
@ -7,9 +7,12 @@ import { RedisService } from '@/infrastructure/redis/redis.service';
|
||||||
import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.service';
|
import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.service';
|
||||||
import { ApplicationError } from '@/shared/exceptions/domain.exception';
|
import { ApplicationError } from '@/shared/exceptions/domain.exception';
|
||||||
import { RecoverAccountResult } from '../index';
|
import { RecoverAccountResult } from '../index';
|
||||||
|
import { generateRandomAvatarSvg } from '@/shared/utils/random-identity.util';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class RecoverByPhoneHandler {
|
export class RecoverByPhoneHandler {
|
||||||
|
private readonly logger = new Logger(RecoverByPhoneHandler.name);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(USER_ACCOUNT_REPOSITORY)
|
@Inject(USER_ACCOUNT_REPOSITORY)
|
||||||
private readonly userRepository: UserAccountRepository,
|
private readonly userRepository: UserAccountRepository,
|
||||||
|
|
@ -31,6 +34,14 @@ export class RecoverByPhoneHandler {
|
||||||
const cachedCode = await this.redisService.get(`sms:recover:${phoneNumber.value}`);
|
const cachedCode = await this.redisService.get(`sms:recover:${phoneNumber.value}`);
|
||||||
if (cachedCode !== command.smsCode) throw new ApplicationError('验证码错误或已过期');
|
if (cachedCode !== command.smsCode) throw new ApplicationError('验证码错误或已过期');
|
||||||
|
|
||||||
|
// 如果头像为空,重新生成一个
|
||||||
|
let avatarUrl = account.avatarUrl;
|
||||||
|
if (!avatarUrl) {
|
||||||
|
this.logger.log(`Account ${command.accountSequence} has no avatar, generating new one`);
|
||||||
|
avatarUrl = generateRandomAvatarSvg();
|
||||||
|
account.updateProfile({ avatarUrl });
|
||||||
|
}
|
||||||
|
|
||||||
account.addDevice(command.newDeviceId, command.deviceName);
|
account.addDevice(command.newDeviceId, command.deviceName);
|
||||||
account.recordLogin();
|
account.recordLogin();
|
||||||
await this.userRepository.save(account);
|
await this.userRepository.save(account);
|
||||||
|
|
@ -49,7 +60,7 @@ export class RecoverByPhoneHandler {
|
||||||
userId: account.userId.toString(),
|
userId: account.userId.toString(),
|
||||||
accountSequence: account.accountSequence.value,
|
accountSequence: account.accountSequence.value,
|
||||||
nickname: account.nickname,
|
nickname: account.nickname,
|
||||||
avatarUrl: account.avatarUrl,
|
avatarUrl,
|
||||||
referralCode: account.referralCode.value,
|
referralCode: account.referralCode.value,
|
||||||
accessToken: tokens.accessToken,
|
accessToken: tokens.accessToken,
|
||||||
refreshToken: tokens.refreshToken,
|
refreshToken: tokens.refreshToken,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue