fix(mining-admin-service): 实现getReferralTree返回真实推荐关系数据
- 从synced_referrals和synced_adoptions获取数据 - 实现getAncestors获取向上引荐人链 - 实现getDirectReferrals获取直推下级 - 实现getUserAdoptionStats获取认种统计 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
2025c6ce36
commit
9e9a7364b9
|
|
@ -450,32 +450,214 @@ export class UsersService {
|
|||
|
||||
/**
|
||||
* 获取用户引荐关系树
|
||||
* TODO: 从 identity-service 同步推荐关系数据
|
||||
*/
|
||||
async getReferralTree(accountSequence: string, direction: string, depth: number) {
|
||||
async getReferralTree(
|
||||
accountSequence: string,
|
||||
direction: string,
|
||||
depth: number,
|
||||
) {
|
||||
const user = await this.prisma.syncedUser.findUnique({
|
||||
where: { accountSequence },
|
||||
include: { contributionAccount: true },
|
||||
include: {
|
||||
contributionAccount: true,
|
||||
referral: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
throw new NotFoundException(`用户 ${accountSequence} 不存在`);
|
||||
}
|
||||
|
||||
// 返回基础结构,数据需要从 identity-service 同步
|
||||
return {
|
||||
currentUser: {
|
||||
accountSequence: user.accountSequence,
|
||||
nickname: user.realName || null,
|
||||
avatar: null,
|
||||
personalAdoptions: 0,
|
||||
teamAdoptions: 0,
|
||||
directReferralCount: user.contributionAccount?.directReferralCount || 0,
|
||||
},
|
||||
ancestors: [],
|
||||
directReferrals: [],
|
||||
note: '推荐关系数据需要从 identity-service 同步',
|
||||
// 获取当前用户的认种统计
|
||||
const currentUserAdoptions = await this.getUserAdoptionStats(accountSequence);
|
||||
|
||||
// 构建当前用户节点
|
||||
const currentUser = {
|
||||
accountSequence: user.accountSequence,
|
||||
nickname: user.nickname || user.realName || null,
|
||||
avatar: null,
|
||||
personalAdoptions: currentUserAdoptions.personal,
|
||||
teamAdoptions: currentUserAdoptions.team,
|
||||
directReferralCount: 0,
|
||||
};
|
||||
|
||||
// 获取直推下级数量
|
||||
const directReferralCount = await this.prisma.syncedReferral.count({
|
||||
where: { referrerAccountSequence: accountSequence },
|
||||
});
|
||||
currentUser.directReferralCount = directReferralCount;
|
||||
|
||||
// 获取向上的引荐人链 (ancestors)
|
||||
let ancestors: any[] = [];
|
||||
if (direction === 'up' || direction === 'both') {
|
||||
ancestors = await this.getAncestors(accountSequence, depth);
|
||||
}
|
||||
|
||||
// 获取直推下级 (directReferrals)
|
||||
let directReferrals: any[] = [];
|
||||
if (direction === 'down' || direction === 'both') {
|
||||
directReferrals = await this.getDirectReferrals(accountSequence);
|
||||
}
|
||||
|
||||
return {
|
||||
currentUser,
|
||||
ancestors,
|
||||
directReferrals,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户认种统计
|
||||
*/
|
||||
private async getUserAdoptionStats(
|
||||
accountSequence: string,
|
||||
): Promise<{ personal: number; team: number }> {
|
||||
// 个人认种
|
||||
const personalStats = await this.prisma.syncedAdoption.aggregate({
|
||||
where: { accountSequence },
|
||||
_sum: { treeCount: true },
|
||||
});
|
||||
|
||||
// 获取用户的 originalUserId
|
||||
const referral = await this.prisma.syncedReferral.findUnique({
|
||||
where: { accountSequence },
|
||||
select: { originalUserId: true },
|
||||
});
|
||||
|
||||
let teamCount = 0;
|
||||
if (referral?.originalUserId) {
|
||||
// 团队认种 = 所有下级的认种总和
|
||||
const teamMembers = await this.prisma.syncedReferral.findMany({
|
||||
where: {
|
||||
ancestorPath: { contains: referral.originalUserId.toString() },
|
||||
},
|
||||
select: { accountSequence: true },
|
||||
});
|
||||
|
||||
if (teamMembers.length > 0) {
|
||||
const teamStats = await this.prisma.syncedAdoption.aggregate({
|
||||
where: {
|
||||
accountSequence: { in: teamMembers.map((m) => m.accountSequence) },
|
||||
},
|
||||
_sum: { treeCount: true },
|
||||
});
|
||||
teamCount = teamStats._sum.treeCount || 0;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
personal: personalStats._sum.treeCount || 0,
|
||||
team: teamCount,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取向上的引荐人链
|
||||
*/
|
||||
private async getAncestors(
|
||||
accountSequence: string,
|
||||
maxDepth: number = 10,
|
||||
): Promise<any[]> {
|
||||
const ancestors: any[] = [];
|
||||
|
||||
// 获取当前用户的推荐关系
|
||||
const referral = await this.prisma.syncedReferral.findUnique({
|
||||
where: { accountSequence },
|
||||
select: { referrerAccountSequence: true, ancestorPath: true },
|
||||
});
|
||||
|
||||
if (!referral?.referrerAccountSequence) {
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
// 通过 ancestorPath 解析祖先链
|
||||
// ancestorPath 格式类似: "123,456,789" 其中 123 是直接上级的 originalUserId
|
||||
if (referral.ancestorPath) {
|
||||
const ancestorUserIds = referral.ancestorPath
|
||||
.split(',')
|
||||
.filter((id) => id.trim())
|
||||
.slice(0, maxDepth);
|
||||
|
||||
// 获取所有祖先的 referral 记录以获取 accountSequence
|
||||
const ancestorReferrals = await this.prisma.syncedReferral.findMany({
|
||||
where: {
|
||||
originalUserId: { in: ancestorUserIds.map((id) => BigInt(id)) },
|
||||
},
|
||||
select: { accountSequence: true, originalUserId: true },
|
||||
});
|
||||
|
||||
const userIdToSeq = new Map(
|
||||
ancestorReferrals.map((r) => [r.originalUserId.toString(), r.accountSequence]),
|
||||
);
|
||||
|
||||
// 按顺序获取每个祖先的详细信息
|
||||
for (const userId of ancestorUserIds) {
|
||||
const seq = userIdToSeq.get(userId);
|
||||
if (!seq) continue;
|
||||
|
||||
const user = await this.prisma.syncedUser.findUnique({
|
||||
where: { accountSequence: seq },
|
||||
select: { accountSequence: true, nickname: true, realName: true },
|
||||
});
|
||||
|
||||
if (user) {
|
||||
const adoptionStats = await this.getUserAdoptionStats(seq);
|
||||
const directCount = await this.prisma.syncedReferral.count({
|
||||
where: { referrerAccountSequence: seq },
|
||||
});
|
||||
|
||||
ancestors.push({
|
||||
accountSequence: user.accountSequence,
|
||||
nickname: user.nickname || user.realName || null,
|
||||
avatar: null,
|
||||
personalAdoptions: adoptionStats.personal,
|
||||
teamAdoptions: adoptionStats.team,
|
||||
directReferralCount: directCount,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 反转使得最近的祖先在最后(靠近当前用户)
|
||||
return ancestors.reverse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取直推下级
|
||||
*/
|
||||
private async getDirectReferrals(accountSequence: string): Promise<any[]> {
|
||||
// 获取所有直推下级
|
||||
const directReferrals = await this.prisma.syncedReferral.findMany({
|
||||
where: { referrerAccountSequence: accountSequence },
|
||||
select: { accountSequence: true },
|
||||
});
|
||||
|
||||
const results: any[] = [];
|
||||
|
||||
for (const ref of directReferrals) {
|
||||
const user = await this.prisma.syncedUser.findUnique({
|
||||
where: { accountSequence: ref.accountSequence },
|
||||
select: { accountSequence: true, nickname: true, realName: true },
|
||||
});
|
||||
|
||||
if (user) {
|
||||
const adoptionStats = await this.getUserAdoptionStats(ref.accountSequence);
|
||||
const directCount = await this.prisma.syncedReferral.count({
|
||||
where: { referrerAccountSequence: ref.accountSequence },
|
||||
});
|
||||
|
||||
results.push({
|
||||
accountSequence: user.accountSequence,
|
||||
nickname: user.nickname || user.realName || null,
|
||||
avatar: null,
|
||||
personalAdoptions: adoptionStats.personal,
|
||||
teamAdoptions: adoptionStats.team,
|
||||
directReferralCount: directCount,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue