rwadurian/backend/services/contribution-service/src/domain/aggregates/contribution-account.aggreg...

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