This commit is contained in:
hailin 2025-11-24 02:50:45 -08:00
parent c6c2545095
commit 3aaac6af6f
10 changed files with 43 additions and 43 deletions

View File

@ -55,7 +55,7 @@ export class AutoCreateAccountHandler {
await this.userRepository.saveWallets(account.userId, Array.from(wallets.values())); await this.userRepository.saveWallets(account.userId, Array.from(wallets.values()));
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.deviceId, deviceId: command.deviceId,
}); });
@ -64,7 +64,7 @@ export class AutoCreateAccountHandler {
account.clearDomainEvents(); account.clearDomainEvents();
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
referralCode: account.referralCode.value, referralCode: account.referralCode.value,
mnemonic: mnemonic.value, mnemonic: mnemonic.value,

View File

@ -41,7 +41,7 @@ export class RecoverByMnemonicHandler {
await this.userRepository.save(account); await this.userRepository.save(account);
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.newDeviceId, deviceId: command.newDeviceId,
}); });
@ -50,7 +50,7 @@ export class RecoverByMnemonicHandler {
account.clearDomainEvents(); account.clearDomainEvents();
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
nickname: account.nickname, nickname: account.nickname,
avatarUrl: account.avatarUrl, avatarUrl: account.avatarUrl,

View File

@ -37,7 +37,7 @@ export class RecoverByPhoneHandler {
await this.redisService.delete(`sms:recover:${phoneNumber.value}`); await this.redisService.delete(`sms:recover:${phoneNumber.value}`);
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.newDeviceId, deviceId: command.newDeviceId,
}); });
@ -46,7 +46,7 @@ export class RecoverByPhoneHandler {
account.clearDomainEvents(); account.clearDomainEvents();
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
nickname: account.nickname, nickname: account.nickname,
avatarUrl: account.avatarUrl, avatarUrl: account.avatarUrl,

View File

@ -21,7 +21,7 @@ export class GetMyProfileHandler {
private toDTO(account: UserAccount): UserProfileDTO { private toDTO(account: UserAccount): UserProfileDTO {
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
phoneNumber: account.phoneNumber?.masked() || null, phoneNumber: account.phoneNumber?.masked() || null,
nickname: account.nickname, nickname: account.nickname,

View File

@ -70,7 +70,7 @@ export class UserApplicationService {
await this.userRepository.saveWallets(account.userId, Array.from(wallets.values())); await this.userRepository.saveWallets(account.userId, Array.from(wallets.values()));
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.deviceId, deviceId: command.deviceId,
}); });
@ -79,7 +79,7 @@ export class UserApplicationService {
account.clearDomainEvents(); account.clearDomainEvents();
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
referralCode: account.referralCode.value, referralCode: account.referralCode.value,
mnemonic: mnemonic.value, mnemonic: mnemonic.value,
@ -116,7 +116,7 @@ export class UserApplicationService {
await this.userRepository.save(account); await this.userRepository.save(account);
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.newDeviceId, deviceId: command.newDeviceId,
}); });
@ -125,7 +125,7 @@ export class UserApplicationService {
account.clearDomainEvents(); account.clearDomainEvents();
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
nickname: account.nickname, nickname: account.nickname,
avatarUrl: account.avatarUrl, avatarUrl: account.avatarUrl,
@ -154,7 +154,7 @@ export class UserApplicationService {
await this.redisService.delete(`sms:recover:${phoneNumber.value}`); await this.redisService.delete(`sms:recover:${phoneNumber.value}`);
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.newDeviceId, deviceId: command.newDeviceId,
}); });
@ -163,7 +163,7 @@ export class UserApplicationService {
account.clearDomainEvents(); account.clearDomainEvents();
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
nickname: account.nickname, nickname: account.nickname,
avatarUrl: account.avatarUrl, avatarUrl: account.avatarUrl,
@ -186,13 +186,13 @@ export class UserApplicationService {
await this.userRepository.save(account); await this.userRepository.save(account);
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.deviceId, deviceId: command.deviceId,
}); });
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
accessToken: tokens.accessToken, accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken, refreshToken: tokens.refreshToken,
@ -243,13 +243,13 @@ export class UserApplicationService {
account.clearDomainEvents(); account.clearDomainEvents();
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.deviceId, deviceId: command.deviceId,
}); });
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
referralCode: account.referralCode.value, referralCode: account.referralCode.value,
accessToken: tokens.accessToken, accessToken: tokens.accessToken,
@ -272,13 +272,13 @@ export class UserApplicationService {
await this.redisService.delete(`sms:login:${phoneNumber.value}`); await this.redisService.delete(`sms:login:${phoneNumber.value}`);
const tokens = await this.tokenService.generateTokenPair({ const tokens = await this.tokenService.generateTokenPair({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
deviceId: command.deviceId, deviceId: command.deviceId,
}); });
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
accessToken: tokens.accessToken, accessToken: tokens.accessToken,
refreshToken: tokens.refreshToken, refreshToken: tokens.refreshToken,
@ -370,7 +370,7 @@ export class UserApplicationService {
account.removeDevice(command.deviceIdToRemove); account.removeDevice(command.deviceIdToRemove);
await this.userRepository.save(account); await this.userRepository.save(account);
await this.tokenService.revokeDeviceTokens(account.userId.value, command.deviceIdToRemove); await this.tokenService.revokeDeviceTokens(account.userId.toString(), command.deviceIdToRemove);
await this.eventPublisher.publishAll(account.domainEvents); await this.eventPublisher.publishAll(account.domainEvents);
account.clearDomainEvents(); account.clearDomainEvents();
} }
@ -386,7 +386,7 @@ export class UserApplicationService {
if (!account) return null; if (!account) return null;
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
nickname: account.nickname, nickname: account.nickname,
avatarUrl: account.avatarUrl, avatarUrl: account.avatarUrl,
@ -395,7 +395,7 @@ export class UserApplicationService {
private toUserProfileDTO(account: UserAccount): UserProfileDTO { private toUserProfileDTO(account: UserAccount): UserProfileDTO {
return { return {
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: account.accountSequence.value, accountSequence: account.accountSequence.value,
phoneNumber: account.phoneNumber?.masked() || null, phoneNumber: account.phoneNumber?.masked() || null,
nickname: account.nickname, nickname: account.nickname,

View File

@ -106,7 +106,7 @@ export class UserAccount {
); );
account.addDomainEvent(new UserAccountAutoCreatedEvent({ account.addDomainEvent(new UserAccountAutoCreatedEvent({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: params.accountSequence.value, accountSequence: params.accountSequence.value,
initialDeviceId: params.initialDeviceId, initialDeviceId: params.initialDeviceId,
inviterSequence: params.inviterSequence?.value || null, inviterSequence: params.inviterSequence?.value || null,
@ -132,8 +132,9 @@ export class UserAccount {
params.initialDeviceId, params.deviceName || '未命名设备', new Date(), new Date(), params.initialDeviceId, params.deviceName || '未命名设备', new Date(), new Date(),
)); ));
// UserID将由数据库自动生成(autoincrement)这里使用临时值0
const account = new UserAccount( const account = new UserAccount(
UserId.generate(), params.accountSequence, devices, params.phoneNumber, UserId.create(0), params.accountSequence, devices, params.phoneNumber,
`用户${params.accountSequence.value}`, null, params.inviterSequence, `用户${params.accountSequence.value}`, null, params.inviterSequence,
ReferralCode.generate(), params.province, params.city, null, ReferralCode.generate(), params.province, params.city, null,
new Map(), null, KYCStatus.NOT_VERIFIED, AccountStatus.ACTIVE, new Map(), null, KYCStatus.NOT_VERIFIED, AccountStatus.ACTIVE,
@ -141,7 +142,7 @@ export class UserAccount {
); );
account.addDomainEvent(new UserAccountCreatedEvent({ account.addDomainEvent(new UserAccountCreatedEvent({
userId: account.userId.value, userId: account.userId.toString(),
accountSequence: params.accountSequence.value, accountSequence: params.accountSequence.value,
phoneNumber: params.phoneNumber.value, phoneNumber: params.phoneNumber.value,
initialDeviceId: params.initialDeviceId, initialDeviceId: params.initialDeviceId,
@ -201,7 +202,7 @@ export class UserAccount {
} else { } else {
this._devices.set(deviceId, new DeviceInfo(deviceId, deviceName || '未命名设备', new Date(), new Date())); this._devices.set(deviceId, new DeviceInfo(deviceId, deviceName || '未命名设备', new Date(), new Date()));
this.addDomainEvent(new DeviceAddedEvent({ this.addDomainEvent(new DeviceAddedEvent({
userId: this.userId.value, userId: this.userId.toString(),
accountSequence: this.accountSequence.value, accountSequence: this.accountSequence.value,
deviceId, deviceId,
deviceName: deviceName || '未命名设备', deviceName: deviceName || '未命名设备',
@ -216,7 +217,7 @@ export class UserAccount {
if (this._devices.size <= 1) throw new DomainError('至少保留一个设备'); if (this._devices.size <= 1) throw new DomainError('至少保留一个设备');
this._devices.delete(deviceId); this._devices.delete(deviceId);
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new DeviceRemovedEvent({ userId: this.userId.value, deviceId })); this.addDomainEvent(new DeviceRemovedEvent({ userId: this.userId.toString(), deviceId }));
} }
isDeviceAuthorized(deviceId: string): boolean { isDeviceAuthorized(deviceId: string): boolean {
@ -241,7 +242,7 @@ export class UserAccount {
this._city = city; this._city = city;
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new UserLocationUpdatedEvent({ this.addDomainEvent(new UserLocationUpdatedEvent({
userId: this.userId.value, province: province.value, city: city.value, userId: this.userId.toString(), province: province.value, city: city.value,
})); }));
} }
@ -250,7 +251,7 @@ export class UserAccount {
if (this._phoneNumber) throw new DomainError('已绑定手机号,不可重复绑定'); if (this._phoneNumber) throw new DomainError('已绑定手机号,不可重复绑定');
this._phoneNumber = phoneNumber; this._phoneNumber = phoneNumber;
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new PhoneNumberBoundEvent({ userId: this.userId.value, phoneNumber: phoneNumber.value })); this.addDomainEvent(new PhoneNumberBoundEvent({ userId: this.userId.toString(), phoneNumber: phoneNumber.value }));
} }
bindWalletAddress(chainType: ChainType, address: string): void { bindWalletAddress(chainType: ChainType, address: string): void {
@ -259,7 +260,7 @@ export class UserAccount {
const walletAddress = WalletAddress.create({ userId: this.userId, chainType, address }); const walletAddress = WalletAddress.create({ userId: this.userId, chainType, address });
this._walletAddresses.set(chainType, walletAddress); this._walletAddresses.set(chainType, walletAddress);
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new WalletAddressBoundEvent({ userId: this.userId.value, chainType, address })); this.addDomainEvent(new WalletAddressBoundEvent({ userId: this.userId.toString(), chainType, address }));
} }
bindMultipleWalletAddresses(wallets: Map<ChainType, WalletAddress>): void { bindMultipleWalletAddresses(wallets: Map<ChainType, WalletAddress>): void {
@ -270,7 +271,7 @@ export class UserAccount {
} }
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new MultipleWalletAddressesBoundEvent({ this.addDomainEvent(new MultipleWalletAddressesBoundEvent({
userId: this.userId.value, userId: this.userId.toString(),
addresses: Array.from(wallets.entries()).map(([chainType, wallet]) => ({ chainType, address: wallet.address })), addresses: Array.from(wallets.entries()).map(([chainType, wallet]) => ({ chainType, address: wallet.address })),
})); }));
} }
@ -282,7 +283,7 @@ export class UserAccount {
this._kycStatus = KYCStatus.PENDING; this._kycStatus = KYCStatus.PENDING;
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new KYCSubmittedEvent({ this.addDomainEvent(new KYCSubmittedEvent({
userId: this.userId.value, realName: kycInfo.realName, idCardNumber: kycInfo.idCardNumber, userId: this.userId.toString(), realName: kycInfo.realName, idCardNumber: kycInfo.idCardNumber,
})); }));
} }
@ -290,14 +291,14 @@ export class UserAccount {
if (this._kycStatus !== KYCStatus.PENDING) throw new DomainError('只有待审核状态才能通过KYC'); if (this._kycStatus !== KYCStatus.PENDING) throw new DomainError('只有待审核状态才能通过KYC');
this._kycStatus = KYCStatus.VERIFIED; this._kycStatus = KYCStatus.VERIFIED;
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new KYCVerifiedEvent({ userId: this.userId.value, verifiedAt: new Date() })); this.addDomainEvent(new KYCVerifiedEvent({ userId: this.userId.toString(), verifiedAt: new Date() }));
} }
rejectKYC(reason: string): void { rejectKYC(reason: string): void {
if (this._kycStatus !== KYCStatus.PENDING) throw new DomainError('只有待审核状态才能拒绝KYC'); if (this._kycStatus !== KYCStatus.PENDING) throw new DomainError('只有待审核状态才能拒绝KYC');
this._kycStatus = KYCStatus.REJECTED; this._kycStatus = KYCStatus.REJECTED;
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new KYCRejectedEvent({ userId: this.userId.value, reason })); this.addDomainEvent(new KYCRejectedEvent({ userId: this.userId.toString(), reason }));
} }
recordLogin(): void { recordLogin(): void {
@ -310,7 +311,7 @@ export class UserAccount {
if (this._status === AccountStatus.FROZEN) throw new DomainError('账户已冻结'); if (this._status === AccountStatus.FROZEN) throw new DomainError('账户已冻结');
this._status = AccountStatus.FROZEN; this._status = AccountStatus.FROZEN;
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new UserAccountFrozenEvent({ userId: this.userId.value, reason })); this.addDomainEvent(new UserAccountFrozenEvent({ userId: this.userId.toString(), reason }));
} }
unfreeze(): void { unfreeze(): void {
@ -323,7 +324,7 @@ export class UserAccount {
if (this._status === AccountStatus.DEACTIVATED) throw new DomainError('账户已注销'); if (this._status === AccountStatus.DEACTIVATED) throw new DomainError('账户已注销');
this._status = AccountStatus.DEACTIVATED; this._status = AccountStatus.DEACTIVATED;
this._updatedAt = new Date(); this._updatedAt = new Date();
this.addDomainEvent(new UserAccountDeactivatedEvent({ userId: this.userId.value, deactivatedAt: new Date() })); this.addDomainEvent(new UserAccountDeactivatedEvent({ userId: this.userId.toString(), deactivatedAt: new Date() }));
} }
getWalletAddress(chainType: ChainType): WalletAddress | null { getWalletAddress(chainType: ChainType): WalletAddress | null {

View File

@ -78,7 +78,7 @@ export class WalletGeneratorService {
wallets: Map<ChainType, WalletAddress>; wallets: Map<ChainType, WalletAddress>;
} { } {
const mnemonic = Mnemonic.generate(); const mnemonic = Mnemonic.generate();
const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.value); const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.toString());
const wallets = new Map<ChainType, WalletAddress>(); const wallets = new Map<ChainType, WalletAddress>();
const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC]; const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC];
@ -97,7 +97,7 @@ export class WalletGeneratorService {
} }
recoverWalletSystem(params: { userId: UserId; mnemonic: Mnemonic; deviceId: string }): Map<ChainType, WalletAddress> { recoverWalletSystem(params: { userId: UserId; mnemonic: Mnemonic; deviceId: string }): Map<ChainType, WalletAddress> {
const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.value); const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.toString());
const wallets = new Map<ChainType, WalletAddress>(); const wallets = new Map<ChainType, WalletAddress>();
const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC]; const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC];

View File

@ -10,7 +10,7 @@ export class WalletGeneratorService {
wallets: Map<ChainType, WalletAddress>; wallets: Map<ChainType, WalletAddress>;
} { } {
const mnemonic = Mnemonic.generate(); const mnemonic = Mnemonic.generate();
const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.value); const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.toString());
const wallets = new Map<ChainType, WalletAddress>(); const wallets = new Map<ChainType, WalletAddress>();
const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC]; const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC];
@ -29,7 +29,7 @@ export class WalletGeneratorService {
} }
recoverWalletSystem(params: { userId: UserId; mnemonic: Mnemonic; deviceId: string }): Map<ChainType, WalletAddress> { recoverWalletSystem(params: { userId: UserId; mnemonic: Mnemonic; deviceId: string }): Map<ChainType, WalletAddress> {
const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.value); const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.toString());
const wallets = new Map<ChainType, WalletAddress>(); const wallets = new Map<ChainType, WalletAddress>();
const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC]; const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC];

View File

@ -10,7 +10,7 @@ export class WalletGeneratorServiceImpl {
wallets: Map<ChainType, WalletAddress>; wallets: Map<ChainType, WalletAddress>;
} { } {
const mnemonic = Mnemonic.generate(); const mnemonic = Mnemonic.generate();
const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.value); const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.toString());
const wallets = new Map<ChainType, WalletAddress>(); const wallets = new Map<ChainType, WalletAddress>();
const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC]; const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC];
@ -29,7 +29,7 @@ export class WalletGeneratorServiceImpl {
} }
recoverWalletSystem(params: { userId: UserId; mnemonic: Mnemonic; deviceId: string }): Map<ChainType, WalletAddress> { recoverWalletSystem(params: { userId: UserId; mnemonic: Mnemonic; deviceId: string }): Map<ChainType, WalletAddress> {
const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.value); const encryptionKey = this.deriveEncryptionKey(params.deviceId, params.userId.toString());
const wallets = new Map<ChainType, WalletAddress>(); const wallets = new Map<ChainType, WalletAddress>();
const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC]; const chains = [ChainType.KAVA, ChainType.DST, ChainType.BSC];

View File

@ -13,7 +13,6 @@ import { ConfigService } from '@nestjs/config';
import { Mnemonic, UserId, ChainType, CHAIN_CONFIG } from '@/domain/value-objects'; import { Mnemonic, UserId, ChainType, CHAIN_CONFIG } from '@/domain/value-objects';
import { WalletAddress } from '@/domain/entities/wallet-address.entity'; import { WalletAddress } from '@/domain/entities/wallet-address.entity';
import { DomainError } from '@/shared/exceptions/domain.exception'; import { DomainError } from '@/shared/exceptions/domain.exception';
import { v4 as uuidv4 } from 'uuid';
export interface WalletSystemResult { export interface WalletSystemResult {
mnemonic: Mnemonic; mnemonic: Mnemonic;