257 lines
8.5 KiB
TypeScript
257 lines
8.5 KiB
TypeScript
import Decimal from 'decimal.js';
|
|
import { ContributionAmount } from '../value-objects/contribution-amount.vo';
|
|
|
|
/**
|
|
* 贡献值来源类型
|
|
*/
|
|
export enum ContributionSourceType {
|
|
PERSONAL = 'PERSONAL', // 来自自己认种
|
|
TEAM_LEVEL = 'TEAM_LEVEL', // 来自团队层级
|
|
TEAM_BONUS = 'TEAM_BONUS', // 来自团队额外奖励
|
|
}
|
|
|
|
/**
|
|
* 算力账户聚合根
|
|
* 管理用户的贡献值/算力
|
|
*/
|
|
export class ContributionAccountAggregate {
|
|
private _id: bigint | null;
|
|
private _accountSequence: string;
|
|
private _personalContribution: ContributionAmount;
|
|
private _teamLevelContribution: ContributionAmount;
|
|
private _teamBonusContribution: ContributionAmount;
|
|
private _totalContribution: ContributionAmount;
|
|
private _effectiveContribution: ContributionAmount;
|
|
private _hasAdopted: boolean;
|
|
private _directReferralAdoptedCount: number;
|
|
private _unlockedLevelDepth: number;
|
|
private _unlockedBonusTiers: number;
|
|
private _version: number;
|
|
private _createdAt: Date;
|
|
private _updatedAt: Date;
|
|
|
|
constructor(props: {
|
|
id?: bigint | null;
|
|
accountSequence: string;
|
|
personalContribution?: ContributionAmount;
|
|
teamLevelContribution?: ContributionAmount;
|
|
teamBonusContribution?: ContributionAmount;
|
|
totalContribution?: ContributionAmount;
|
|
effectiveContribution?: ContributionAmount;
|
|
hasAdopted?: boolean;
|
|
directReferralAdoptedCount?: number;
|
|
unlockedLevelDepth?: number;
|
|
unlockedBonusTiers?: number;
|
|
version?: number;
|
|
createdAt?: Date;
|
|
updatedAt?: Date;
|
|
}) {
|
|
this._id = props.id ?? null;
|
|
this._accountSequence = props.accountSequence;
|
|
this._personalContribution = props.personalContribution ?? ContributionAmount.zero();
|
|
this._teamLevelContribution = props.teamLevelContribution ?? ContributionAmount.zero();
|
|
this._teamBonusContribution = props.teamBonusContribution ?? ContributionAmount.zero();
|
|
this._totalContribution = props.totalContribution ?? ContributionAmount.zero();
|
|
this._effectiveContribution = props.effectiveContribution ?? ContributionAmount.zero();
|
|
this._hasAdopted = props.hasAdopted ?? false;
|
|
this._directReferralAdoptedCount = props.directReferralAdoptedCount ?? 0;
|
|
this._unlockedLevelDepth = props.unlockedLevelDepth ?? 0;
|
|
this._unlockedBonusTiers = props.unlockedBonusTiers ?? 0;
|
|
this._version = props.version ?? 1;
|
|
this._createdAt = props.createdAt ?? new Date();
|
|
this._updatedAt = props.updatedAt ?? new Date();
|
|
}
|
|
|
|
// Getters
|
|
get id(): bigint | null { return this._id; }
|
|
get accountSequence(): string { return this._accountSequence; }
|
|
get personalContribution(): ContributionAmount { return this._personalContribution; }
|
|
get teamLevelContribution(): ContributionAmount { return this._teamLevelContribution; }
|
|
get teamBonusContribution(): ContributionAmount { return this._teamBonusContribution; }
|
|
get totalContribution(): ContributionAmount { return this._totalContribution; }
|
|
get effectiveContribution(): ContributionAmount { return this._effectiveContribution; }
|
|
get hasAdopted(): boolean { return this._hasAdopted; }
|
|
get directReferralAdoptedCount(): number { return this._directReferralAdoptedCount; }
|
|
get unlockedLevelDepth(): number { return this._unlockedLevelDepth; }
|
|
get unlockedBonusTiers(): number { return this._unlockedBonusTiers; }
|
|
get version(): number { return this._version; }
|
|
get createdAt(): Date { return this._createdAt; }
|
|
get updatedAt(): Date { return this._updatedAt; }
|
|
|
|
/**
|
|
* 添加个人贡献值
|
|
*/
|
|
addPersonalContribution(amount: ContributionAmount): void {
|
|
this._personalContribution = this._personalContribution.add(amount);
|
|
this.recalculateTotal();
|
|
}
|
|
|
|
/**
|
|
* 添加团队层级贡献值
|
|
*/
|
|
addTeamLevelContribution(amount: ContributionAmount): void {
|
|
this._teamLevelContribution = this._teamLevelContribution.add(amount);
|
|
this.recalculateTotal();
|
|
}
|
|
|
|
/**
|
|
* 添加团队额外奖励贡献值
|
|
*/
|
|
addTeamBonusContribution(amount: ContributionAmount): void {
|
|
this._teamBonusContribution = this._teamBonusContribution.add(amount);
|
|
this.recalculateTotal();
|
|
}
|
|
|
|
/**
|
|
* 标记用户已认种
|
|
*/
|
|
markAsAdopted(): void {
|
|
this._hasAdopted = true;
|
|
this.updateUnlockStatus();
|
|
}
|
|
|
|
/**
|
|
* 增加直推认种用户数
|
|
*/
|
|
incrementDirectReferralAdoptedCount(): void {
|
|
this._directReferralAdoptedCount++;
|
|
this.updateUnlockStatus();
|
|
}
|
|
|
|
/**
|
|
* 设置直推认种用户数
|
|
*/
|
|
setDirectReferralAdoptedCount(count: number): void {
|
|
this._directReferralAdoptedCount = count;
|
|
this.updateUnlockStatus();
|
|
}
|
|
|
|
/**
|
|
* 更新有效贡献值(扣除过期的)
|
|
*/
|
|
updateEffectiveContribution(effective: ContributionAmount): void {
|
|
this._effectiveContribution = effective;
|
|
this._updatedAt = new Date();
|
|
}
|
|
|
|
/**
|
|
* 重新计算总贡献值
|
|
*/
|
|
private recalculateTotal(): void {
|
|
this._totalContribution = this._personalContribution
|
|
.add(this._teamLevelContribution)
|
|
.add(this._teamBonusContribution);
|
|
this._effectiveContribution = this._totalContribution; // 初始时有效=总量
|
|
this._updatedAt = new Date();
|
|
}
|
|
|
|
/**
|
|
* 更新解锁状态
|
|
* 根据直推认种用户数和是否认种过
|
|
*/
|
|
private updateUnlockStatus(): void {
|
|
// 层级解锁规则
|
|
if (this._directReferralAdoptedCount >= 5) {
|
|
this._unlockedLevelDepth = 15;
|
|
} else if (this._directReferralAdoptedCount >= 3) {
|
|
this._unlockedLevelDepth = 10;
|
|
} else if (this._directReferralAdoptedCount >= 1) {
|
|
this._unlockedLevelDepth = 5;
|
|
} else {
|
|
this._unlockedLevelDepth = 0;
|
|
}
|
|
|
|
// 额外奖励解锁规则
|
|
let bonusTiers = 0;
|
|
if (this._hasAdopted) bonusTiers++;
|
|
if (this._directReferralAdoptedCount >= 2) bonusTiers++;
|
|
if (this._directReferralAdoptedCount >= 4) bonusTiers++;
|
|
this._unlockedBonusTiers = bonusTiers;
|
|
|
|
this._updatedAt = new Date();
|
|
}
|
|
|
|
/**
|
|
* 增加版本号(乐观锁)
|
|
*/
|
|
incrementVersion(): void {
|
|
this._version++;
|
|
this._updatedAt = new Date();
|
|
}
|
|
|
|
/**
|
|
* 创建新账户
|
|
*/
|
|
static create(accountSequence: string): ContributionAccountAggregate {
|
|
return new ContributionAccountAggregate({ accountSequence });
|
|
}
|
|
|
|
/**
|
|
* 从持久化数据恢复
|
|
*/
|
|
static fromPersistence(data: {
|
|
id: bigint;
|
|
accountSequence: string;
|
|
personalContribution: Decimal;
|
|
teamLevelContribution: Decimal;
|
|
teamBonusContribution: Decimal;
|
|
totalContribution: Decimal;
|
|
effectiveContribution: Decimal;
|
|
hasAdopted: boolean;
|
|
directReferralAdoptedCount: number;
|
|
unlockedLevelDepth: number;
|
|
unlockedBonusTiers: number;
|
|
version: number;
|
|
createdAt: Date;
|
|
updatedAt: Date;
|
|
}): ContributionAccountAggregate {
|
|
return new ContributionAccountAggregate({
|
|
id: data.id,
|
|
accountSequence: data.accountSequence,
|
|
personalContribution: new ContributionAmount(data.personalContribution),
|
|
teamLevelContribution: new ContributionAmount(data.teamLevelContribution),
|
|
teamBonusContribution: new ContributionAmount(data.teamBonusContribution),
|
|
totalContribution: new ContributionAmount(data.totalContribution),
|
|
effectiveContribution: new ContributionAmount(data.effectiveContribution),
|
|
hasAdopted: data.hasAdopted,
|
|
directReferralAdoptedCount: data.directReferralAdoptedCount,
|
|
unlockedLevelDepth: data.unlockedLevelDepth,
|
|
unlockedBonusTiers: data.unlockedBonusTiers,
|
|
version: data.version,
|
|
createdAt: data.createdAt,
|
|
updatedAt: data.updatedAt,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 转换为持久化数据
|
|
*/
|
|
toPersistence(): {
|
|
accountSequence: string;
|
|
personalContribution: Decimal;
|
|
teamLevelContribution: Decimal;
|
|
teamBonusContribution: Decimal;
|
|
totalContribution: Decimal;
|
|
effectiveContribution: Decimal;
|
|
hasAdopted: boolean;
|
|
directReferralAdoptedCount: number;
|
|
unlockedLevelDepth: number;
|
|
unlockedBonusTiers: number;
|
|
version: number;
|
|
} {
|
|
return {
|
|
accountSequence: this._accountSequence,
|
|
personalContribution: this._personalContribution.value,
|
|
teamLevelContribution: this._teamLevelContribution.value,
|
|
teamBonusContribution: this._teamBonusContribution.value,
|
|
totalContribution: this._totalContribution.value,
|
|
effectiveContribution: this._effectiveContribution.value,
|
|
hasAdopted: this._hasAdopted,
|
|
directReferralAdoptedCount: this._directReferralAdoptedCount,
|
|
unlockedLevelDepth: this._unlockedLevelDepth,
|
|
unlockedBonusTiers: this._unlockedBonusTiers,
|
|
version: this._version,
|
|
};
|
|
}
|
|
}
|