feat(mining-admin-service): 完善用户详情API返回字段

- getUserDetail 添加以下字段:
  - nickname: 昵称
  - referral: 推荐人信息 (referrerAccountSequence, referrerNickname, depth)
  - adoption: 认种统计 (personalAdoptionCount, directReferralAdoptions, teamAdoptions)
  - team: 团队统计 (directReferralCount, teamMemberCount)

- 从 synced_referrals 表获取推荐关系
- 从 synced_adoptions 表统计认种数量
- 通过 ancestorPath 计算团队成员和团队认种

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-12 03:11:19 -08:00
parent 7b310c554b
commit 5cff606e87
1 changed files with 115 additions and 2 deletions

View File

@ -89,6 +89,7 @@ export class UsersService {
contributionAccount: true,
miningAccount: true,
tradingAccount: true,
referral: true,
},
});
@ -96,7 +97,87 @@ export class UsersService {
throw new NotFoundException(`用户 ${accountSequence} 不存在`);
}
return this.formatUserDetail(user);
// 获取个人认种数量(从 synced_adoptions 统计)
const personalAdoptionStats = await this.prisma.syncedAdoption.aggregate({
where: { accountSequence },
_sum: { treeCount: true },
_count: { id: true },
});
// 获取直推人数和直推认种数量
const directReferrals = await this.prisma.syncedReferral.findMany({
where: { referrerAccountSequence: accountSequence },
select: { accountSequence: true },
});
const directReferralCount = directReferrals.length;
// 获取直推认种数量
let directReferralAdoptions = 0;
if (directReferrals.length > 0) {
const directAdoptionStats = await this.prisma.syncedAdoption.aggregate({
where: {
accountSequence: {
in: directReferrals.map((r) => r.accountSequence),
},
},
_sum: { treeCount: true },
});
directReferralAdoptions = directAdoptionStats._sum.treeCount || 0;
}
// 获取团队认种数量(通过 ancestorPath 包含当前用户的所有下级)
// 先获取当前用户的 originalUserId
const currentReferral = await this.prisma.syncedReferral.findUnique({
where: { accountSequence },
select: { originalUserId: true },
});
let teamAdoptions = 0;
let teamMemberCount = 0;
if (currentReferral?.originalUserId) {
// 找出所有 ancestorPath 包含当前用户 originalUserId 的用户(即所有下级)
const teamMembers = await this.prisma.syncedReferral.findMany({
where: {
ancestorPath: {
contains: currentReferral.originalUserId.toString(),
},
},
select: { accountSequence: true },
});
teamMemberCount = teamMembers.length;
if (teamMembers.length > 0) {
const teamAdoptionStats = await this.prisma.syncedAdoption.aggregate({
where: {
accountSequence: {
in: teamMembers.map((m) => m.accountSequence),
},
},
_sum: { treeCount: true },
});
teamAdoptions = teamAdoptionStats._sum.treeCount || 0;
}
}
// 获取推荐人昵称
let referrerNickname = null;
if (user.referral?.referrerAccountSequence) {
const referrer = await this.prisma.syncedUser.findUnique({
where: { accountSequence: user.referral.referrerAccountSequence },
select: { nickname: true, phone: true },
});
referrerNickname = referrer?.nickname || this.maskPhone(referrer?.phone || '');
}
return this.formatUserDetail(user, {
personalAdoptionCount: personalAdoptionStats._sum.treeCount || 0,
personalAdoptionOrders: personalAdoptionStats._count.id || 0,
directReferralCount,
directReferralAdoptions,
teamAdoptions,
teamMemberCount,
referrerNickname,
});
}
/**
@ -382,16 +463,48 @@ export class UsersService {
};
}
private formatUserDetail(user: any) {
private formatUserDetail(
user: any,
extra?: {
personalAdoptionCount: number;
personalAdoptionOrders: number;
directReferralCount: number;
directReferralAdoptions: number;
teamAdoptions: number;
teamMemberCount: number;
referrerNickname: string | null;
},
) {
return {
accountSequence: user.accountSequence,
phone: user.phone,
nickname: user.nickname || null,
status: user.status,
kycStatus: user.kycStatus,
realName: user.realName,
isLegacyUser: user.isLegacyUser,
createdAt: user.createdAt,
syncedAt: user.syncedAt,
// 推荐关系
referral: user.referral
? {
referrerAccountSequence: user.referral.referrerAccountSequence,
referrerNickname: extra?.referrerNickname || null,
depth: user.referral.depth,
}
: null,
// 认种统计
adoption: {
personalAdoptionCount: extra?.personalAdoptionCount || 0,
personalAdoptionOrders: extra?.personalAdoptionOrders || 0,
directReferralAdoptions: extra?.directReferralAdoptions || 0,
teamAdoptions: extra?.teamAdoptions || 0,
},
// 团队统计
team: {
directReferralCount: extra?.directReferralCount || 0,
teamMemberCount: extra?.teamMemberCount || 0,
},
contribution: user.contributionAccount
? {
personalContribution: