rwadurian/backend/services/leaderboard-service/src/domain/entities/virtual-account.entity.ts

267 lines
6.7 KiB
TypeScript

import { VirtualAccountType } from '../value-objects/virtual-account-type.enum';
/**
* 虚拟账户实体
*
* 用于管理系统虚拟账户,包括:
* - 排名虚拟账户(用于占据榜单前列位置)
* - 系统省公司账户
* - 系统市公司账户
* - 总部社区账户
*/
export class VirtualAccount {
private _id: bigint | null = null;
private readonly _accountType: VirtualAccountType;
private _displayName: string;
private _avatar: string | null;
private readonly _provinceCode: string | null;
private readonly _cityCode: string | null;
private _minScore: number | null;
private _maxScore: number | null;
private _currentScore: number;
private _usdtBalance: number;
private _hashpowerBalance: number;
private _isActive: boolean;
private readonly _createdAt: Date;
private constructor(
accountType: VirtualAccountType,
displayName: string,
avatar: string | null,
provinceCode: string | null,
cityCode: string | null,
minScore: number | null,
maxScore: number | null,
) {
this._accountType = accountType;
this._displayName = displayName;
this._avatar = avatar;
this._provinceCode = provinceCode;
this._cityCode = cityCode;
this._minScore = minScore;
this._maxScore = maxScore;
this._currentScore = 0;
this._usdtBalance = 0;
this._hashpowerBalance = 0;
this._isActive = true;
this._createdAt = new Date();
}
// ============ Getters ============
get id(): bigint | null { return this._id; }
get accountType(): VirtualAccountType { return this._accountType; }
get displayName(): string { return this._displayName; }
get avatar(): string | null { return this._avatar; }
get provinceCode(): string | null { return this._provinceCode; }
get cityCode(): string | null { return this._cityCode; }
get minScore(): number | null { return this._minScore; }
get maxScore(): number | null { return this._maxScore; }
get currentScore(): number { return this._currentScore; }
get usdtBalance(): number { return this._usdtBalance; }
get hashpowerBalance(): number { return this._hashpowerBalance; }
get isActive(): boolean { return this._isActive; }
get createdAt(): Date { return this._createdAt; }
// ============ 工厂方法 ============
/**
* 创建排名虚拟账户
*/
static createRankingVirtual(params: {
displayName: string;
avatar?: string;
minScore: number;
maxScore: number;
}): VirtualAccount {
return new VirtualAccount(
VirtualAccountType.RANKING_VIRTUAL,
params.displayName,
params.avatar || null,
null,
null,
params.minScore,
params.maxScore,
);
}
/**
* 创建系统省公司账户
*/
static createSystemProvince(provinceCode: string, provinceName: string): VirtualAccount {
return new VirtualAccount(
VirtualAccountType.SYSTEM_PROVINCE,
`系统省公司-${provinceName}`,
null,
provinceCode,
null,
null,
null,
);
}
/**
* 创建系统市公司账户
*/
static createSystemCity(cityCode: string, cityName: string): VirtualAccount {
return new VirtualAccount(
VirtualAccountType.SYSTEM_CITY,
`系统市公司-${cityName}`,
null,
null,
cityCode,
null,
null,
);
}
/**
* 创建总部社区账户
*/
static createHeadquarters(): VirtualAccount {
return new VirtualAccount(
VirtualAccountType.HEADQUARTERS,
'总部',
null,
null,
null,
null,
null,
);
}
// ============ 领域行为 ============
/**
* 生成随机分值
*/
generateRandomScore(): number {
if (this._minScore === null || this._maxScore === null) {
return 0;
}
this._currentScore = Math.floor(
Math.random() * (this._maxScore - this._minScore + 1) + this._minScore
);
return this._currentScore;
}
/**
* 设置当前分值
*/
setCurrentScore(score: number): void {
this._currentScore = score;
}
/**
* 增加余额
*/
addBalance(usdtAmount: number, hashpowerAmount: number): void {
this._usdtBalance += usdtAmount;
this._hashpowerBalance += hashpowerAmount;
}
/**
* 扣减余额
*/
deductBalance(usdtAmount: number, hashpowerAmount: number): void {
if (this._usdtBalance < usdtAmount) {
throw new Error('USDT余额不足');
}
if (this._hashpowerBalance < hashpowerAmount) {
throw new Error('算力余额不足');
}
this._usdtBalance -= usdtAmount;
this._hashpowerBalance -= hashpowerAmount;
}
/**
* 激活账户
*/
activate(): void {
this._isActive = true;
}
/**
* 停用账户
*/
deactivate(): void {
this._isActive = false;
}
/**
* 更新显示信息
*/
updateDisplayInfo(displayName: string, avatar?: string): void {
this._displayName = displayName;
if (avatar !== undefined) {
this._avatar = avatar;
}
}
/**
* 更新分值范围
*/
updateScoreRange(minScore: number, maxScore: number): void {
if (minScore > maxScore) {
throw new Error('最小分值不能大于最大分值');
}
this._minScore = minScore;
this._maxScore = maxScore;
}
/**
* 判断是否是排名虚拟账户
*/
isRankingVirtual(): boolean {
return this._accountType === VirtualAccountType.RANKING_VIRTUAL;
}
/**
* 判断是否是系统账户(省/市公司或总部)
*/
isSystemAccount(): boolean {
return [
VirtualAccountType.SYSTEM_PROVINCE,
VirtualAccountType.SYSTEM_CITY,
VirtualAccountType.HEADQUARTERS,
].includes(this._accountType);
}
setId(id: bigint): void {
this._id = id;
}
// ============ 重建 ============
static reconstitute(data: {
id: bigint;
accountType: VirtualAccountType;
displayName: string;
avatar: string | null;
provinceCode: string | null;
cityCode: string | null;
minScore: number | null;
maxScore: number | null;
currentScore: number;
usdtBalance: number;
hashpowerBalance: number;
isActive: boolean;
createdAt: Date;
}): VirtualAccount {
const account = new VirtualAccount(
data.accountType,
data.displayName,
data.avatar,
data.provinceCode,
data.cityCode,
data.minScore,
data.maxScore,
);
account._id = data.id;
account._currentScore = data.currentScore;
account._usdtBalance = data.usdtBalance;
account._hashpowerBalance = data.hashpowerBalance;
account._isActive = data.isActive;
return account;
}
}