From 7f2511227f8502fdf80ff7857e31485d9108be77 Mon Sep 17 00:00:00 2001 From: hailin Date: Tue, 9 Dec 2025 18:07:36 -0800 Subject: [PATCH] fix(identity-service): regenerate avatar if missing during account recovery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../recover-by-mnemonic.handler.ts | 11 ++++++++++- .../recover-by-phone/recover-by-phone.handler.ts | 15 +++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts b/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts index 40bc4bfb..ab7a6e84 100644 --- a/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts +++ b/backend/services/identity-service/src/application/commands/recover-by-mnemonic/recover-by-mnemonic.handler.ts @@ -7,6 +7,7 @@ import { EventPublisherService } from '@/infrastructure/kafka/event-publisher.se import { BlockchainClientService } from '@/infrastructure/external/blockchain/blockchain-client.service'; import { ApplicationError } from '@/shared/exceptions/domain.exception'; import { RecoverAccountResult } from '../index'; +import { generateRandomAvatarSvg } from '@/shared/utils/random-identity.util'; @Injectable() export class RecoverByMnemonicHandler { @@ -40,6 +41,14 @@ export class RecoverByMnemonicHandler { 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.recordLogin(); await this.userRepository.save(account); @@ -57,7 +66,7 @@ export class RecoverByMnemonicHandler { userId: account.userId.toString(), accountSequence: account.accountSequence.value, nickname: account.nickname, - avatarUrl: account.avatarUrl, + avatarUrl, referralCode: account.referralCode.value, accessToken: tokens.accessToken, refreshToken: tokens.refreshToken, diff --git a/backend/services/identity-service/src/application/commands/recover-by-phone/recover-by-phone.handler.ts b/backend/services/identity-service/src/application/commands/recover-by-phone/recover-by-phone.handler.ts index 5a27eb1b..585d515f 100644 --- a/backend/services/identity-service/src/application/commands/recover-by-phone/recover-by-phone.handler.ts +++ b/backend/services/identity-service/src/application/commands/recover-by-phone/recover-by-phone.handler.ts @@ -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 { UserAccountRepository, USER_ACCOUNT_REPOSITORY } from '@/domain/repositories/user-account.repository.interface'; 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 { ApplicationError } from '@/shared/exceptions/domain.exception'; import { RecoverAccountResult } from '../index'; +import { generateRandomAvatarSvg } from '@/shared/utils/random-identity.util'; @Injectable() export class RecoverByPhoneHandler { + private readonly logger = new Logger(RecoverByPhoneHandler.name); + constructor( @Inject(USER_ACCOUNT_REPOSITORY) private readonly userRepository: UserAccountRepository, @@ -31,6 +34,14 @@ export class RecoverByPhoneHandler { const cachedCode = await this.redisService.get(`sms:recover:${phoneNumber.value}`); 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.recordLogin(); await this.userRepository.save(account); @@ -49,7 +60,7 @@ export class RecoverByPhoneHandler { userId: account.userId.toString(), accountSequence: account.accountSequence.value, nickname: account.nickname, - avatarUrl: account.avatarUrl, + avatarUrl, referralCode: account.referralCode.value, accessToken: tokens.accessToken, refreshToken: tokens.refreshToken,