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, }; } }