267 lines
6.7 KiB
TypeScript
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;
|
|
}
|
|
}
|