59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
/**
|
|
* ReferralChain Value Object
|
|
* 推荐链: 存储从直接推荐人到顶层的有序 userId 数组
|
|
* chain[0] = 直接推荐人, chain[1] = 推荐人的推荐人, ...
|
|
*/
|
|
export class ReferralChain {
|
|
private static readonly MAX_DEPTH = 50;
|
|
|
|
private constructor(private readonly _chain: string[]) {
|
|
if (_chain.length > ReferralChain.MAX_DEPTH) {
|
|
throw new Error(`推荐链深度不能超过 ${ReferralChain.MAX_DEPTH}`);
|
|
}
|
|
}
|
|
|
|
static empty(): ReferralChain {
|
|
return new ReferralChain([]);
|
|
}
|
|
|
|
static fromArray(chain: string[]): ReferralChain {
|
|
return new ReferralChain([...chain]);
|
|
}
|
|
|
|
/**
|
|
* 构建新用户的推荐链: 将推荐人 prepend 到其推荐链前
|
|
*/
|
|
static buildFromReferrer(referrerId: string, referrerChain: string[]): ReferralChain {
|
|
const chain = [referrerId, ...referrerChain];
|
|
return new ReferralChain(chain.slice(0, ReferralChain.MAX_DEPTH));
|
|
}
|
|
|
|
get depth(): number {
|
|
return this._chain.length;
|
|
}
|
|
|
|
/** 直接推荐人 (chain[0]) */
|
|
get directReferrer(): string | null {
|
|
return this._chain[0] ?? null;
|
|
}
|
|
|
|
/** 获取第 N 级上级 (1-based, 1 = 直接推荐人) */
|
|
getReferrerAtLevel(level: number): string | null {
|
|
return this._chain[level - 1] ?? null;
|
|
}
|
|
|
|
/** 所有祖先 */
|
|
getAllAncestors(): string[] {
|
|
return [...this._chain];
|
|
}
|
|
|
|
toArray(): string[] {
|
|
return [...this._chain];
|
|
}
|
|
|
|
/** 检查 userId 是否已在链中 (防止循环推荐) */
|
|
contains(userId: string): boolean {
|
|
return this._chain.includes(userId);
|
|
}
|
|
}
|