diff --git a/backend/services/admin-service/src/api/controllers/user-detail.controller.ts b/backend/services/admin-service/src/api/controllers/user-detail.controller.ts index 137da697..03e30ccc 100644 --- a/backend/services/admin-service/src/api/controllers/user-detail.controller.ts +++ b/backend/services/admin-service/src/api/controllers/user-detail.controller.ts @@ -131,16 +131,21 @@ export class UserDetailController { throw new NotFoundException(`用户 ${accountSequence} 不存在`); } - const referralInfo = await this.userDetailRepository.getReferralInfo(accountSequence); + // 获取引荐信息和实时统计 + const [referralInfo, personalAdoptionCount, directReferralCount] = await Promise.all([ + this.userDetailRepository.getReferralInfo(accountSequence), + this.userDetailRepository.getPersonalAdoptionCount(accountSequence), + this.userDetailRepository.getDirectReferralCount(accountSequence), + ]); const currentUser: ReferralNodeDto = { accountSequence: user.accountSequence, userId: user.userId.toString(), nickname: user.nickname, avatar: user.avatarUrl, - personalAdoptions: user.personalAdoptionCount, + personalAdoptions: personalAdoptionCount, depth: referralInfo?.depth || 0, - directReferralCount: referralInfo?.directReferralCount || 0, + directReferralCount: directReferralCount, isCurrentUser: true, }; diff --git a/backend/services/admin-service/src/domain/repositories/user-detail-query.repository.ts b/backend/services/admin-service/src/domain/repositories/user-detail-query.repository.ts index 21823e3d..a17a74d3 100644 --- a/backend/services/admin-service/src/domain/repositories/user-detail-query.repository.ts +++ b/backend/services/admin-service/src/domain/repositories/user-detail-query.repository.ts @@ -251,6 +251,11 @@ export interface IUserDetailQueryRepository { */ getPersonalAdoptionCount(accountSequence: string): Promise; + /** + * 获取用户直推数量 + */ + getDirectReferralCount(accountSequence: string): Promise; + /** * 获取用户团队统计(团队地址数、团队认种量) * 团队包括所有直推和间推用户 diff --git a/backend/services/admin-service/src/infrastructure/persistence/repositories/user-detail-query.repository.impl.ts b/backend/services/admin-service/src/infrastructure/persistence/repositories/user-detail-query.repository.impl.ts index 9d7b62ad..ab4f252e 100644 --- a/backend/services/admin-service/src/infrastructure/persistence/repositories/user-detail-query.repository.impl.ts +++ b/backend/services/admin-service/src/infrastructure/persistence/repositories/user-detail-query.repository.impl.ts @@ -60,7 +60,7 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository const ancestorIds = referral.ancestorPath.slice(0, depth); if (ancestorIds.length === 0) return []; - // 获取祖先用户信息 + // 获取祖先用户信息和引荐关系 const [users, referrals] = await Promise.all([ this.prisma.userQueryView.findMany({ where: { userId: { in: ancestorIds } }, @@ -69,19 +69,41 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository accountSequence: true, nickname: true, avatarUrl: true, - personalAdoptionCount: true, }, }), this.prisma.referralQueryView.findMany({ where: { userId: { in: ancestorIds } }, select: { userId: true, + accountSequence: true, depth: true, - directReferralCount: true, }, }), ]); + // 实时统计:获取每个祖先的认种数量和直推数量 + const accountSequences = users.map(u => u.accountSequence); + const [adoptionCounts, directReferralCounts] = await Promise.all([ + // 统计每个用户的认种订单数量(状态为 MINING_ENABLED) + this.prisma.plantingOrderQueryView.groupBy({ + by: ['accountSequence'], + where: { + accountSequence: { in: accountSequences }, + status: 'MINING_ENABLED', + }, + _count: { id: true }, + }), + // 统计每个用户的直推数量 + this.prisma.referralQueryView.groupBy({ + by: ['referrerId'], + where: { referrerId: { in: ancestorIds } }, + _count: { userId: true }, + }), + ]); + + const adoptionCountMap = new Map(adoptionCounts.map(a => [a.accountSequence, a._count.id])); + const directCountMap = new Map(directReferralCounts.map(d => [d.referrerId.toString(), d._count.userId])); + // 合并数据 const referralMap = new Map(referrals.map((r) => [r.userId.toString(), r])); const userMap = new Map(users.map((u) => [u.userId.toString(), u])); @@ -94,9 +116,9 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository accountSequence: user?.accountSequence || '', nickname: user?.nickname || null, avatarUrl: user?.avatarUrl || null, - personalAdoptionCount: user?.personalAdoptionCount || 0, + personalAdoptionCount: adoptionCountMap.get(user?.accountSequence || '') || 0, depth: ref?.depth || index, - directReferralCount: ref?.directReferralCount || 0, + directReferralCount: directCountMap.get(id.toString()) || 0, }; }); } @@ -115,24 +137,45 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository userId: true, accountSequence: true, depth: true, - directReferralCount: true, }, }); if (directReferrals.length === 0) return []; // 获取用户信息 + const userIds = directReferrals.map((r) => r.userId); const users = await this.prisma.userQueryView.findMany({ - where: { userId: { in: directReferrals.map((r) => r.userId) } }, + where: { userId: { in: userIds } }, select: { userId: true, accountSequence: true, nickname: true, avatarUrl: true, - personalAdoptionCount: true, }, }); + // 实时统计:获取每个用户的认种数量和直推数量 + const userAccountSequences = directReferrals.map(r => r.accountSequence); + const [adoptionCounts, directReferralCounts] = await Promise.all([ + // 统计每个用户的认种订单数量(状态为 MINING_ENABLED) + this.prisma.plantingOrderQueryView.groupBy({ + by: ['accountSequence'], + where: { + accountSequence: { in: userAccountSequences }, + status: 'MINING_ENABLED', + }, + _count: { id: true }, + }), + // 统计每个用户的直推数量 + this.prisma.referralQueryView.groupBy({ + by: ['referrerId'], + where: { referrerId: { in: userIds } }, + _count: { userId: true }, + }), + ]); + + const adoptionCountMap = new Map(adoptionCounts.map(a => [a.accountSequence, a._count.id])); + const directCountMap = new Map(directReferralCounts.map(d => [d.referrerId.toString(), d._count.userId])); const userMap = new Map(users.map((u) => [u.userId.toString(), u])); return directReferrals.map((ref) => { @@ -142,9 +185,9 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository accountSequence: ref.accountSequence, nickname: user?.nickname || null, avatarUrl: user?.avatarUrl || null, - personalAdoptionCount: user?.personalAdoptionCount || 0, + personalAdoptionCount: adoptionCountMap.get(ref.accountSequence) || 0, depth: ref.depth, - directReferralCount: ref.directReferralCount, + directReferralCount: directCountMap.get(ref.userId.toString()) || 0, }; }); } @@ -428,21 +471,32 @@ export class UserDetailQueryRepositoryImpl implements IUserDetailQueryRepository } async getPersonalAdoptionCount(accountSequence: string): Promise { + // 统计用户的认种订单数量(状态为 MINING_ENABLED) + const count = await this.prisma.plantingOrderQueryView.count({ + where: { + accountSequence, + status: 'MINING_ENABLED', + }, + }); + + return count; + } + + async getDirectReferralCount(accountSequence: string): Promise { // 先获取用户的 userId - const user = await this.prisma.userQueryView.findUnique({ + const referral = await this.prisma.referralQueryView.findUnique({ where: { accountSequence }, select: { userId: true }, }); - if (!user) return 0; + if (!referral) return 0; - // 从 PlantingPositionQueryView 获取有效认种树数 - const position = await this.prisma.plantingPositionQueryView.findUnique({ - where: { userId: user.userId }, - select: { effectiveTreeCount: true }, + // 统计以该用户为 referrerId 的用户数量 + const count = await this.prisma.referralQueryView.count({ + where: { referrerId: referral.userId }, }); - return position?.effectiveTreeCount || 0; + return count; } async getTeamStats(accountSequence: string): Promise<{ teamAddressCount: number; teamAdoptionCount: number }> {