diff --git a/backend/services/mining-admin-service/src/api/controllers/users.controller.ts b/backend/services/mining-admin-service/src/api/controllers/users.controller.ts index c8017d3a..07cb0182 100644 --- a/backend/services/mining-admin-service/src/api/controllers/users.controller.ts +++ b/backend/services/mining-admin-service/src/api/controllers/users.controller.ts @@ -102,4 +102,43 @@ export class UsersController { status, }); } + + @Get(':accountSequence/referral-tree') + @ApiOperation({ summary: '获取用户引荐关系树' }) + @ApiParam({ name: 'accountSequence', type: String }) + @ApiQuery({ name: 'direction', required: false, type: String, description: 'up, down, both' }) + @ApiQuery({ name: 'depth', required: false, type: Number }) + async getReferralTree( + @Param('accountSequence') accountSequence: string, + @Query('direction') direction?: string, + @Query('depth') depth?: number, + ) { + return this.usersService.getReferralTree(accountSequence, direction || 'both', depth || 1); + } + + @Get(':accountSequence/planting-ledger') + @ApiOperation({ summary: '获取用户认种分类账' }) + @ApiParam({ name: 'accountSequence', type: String }) + @ApiQuery({ name: 'page', required: false, type: Number }) + @ApiQuery({ name: 'pageSize', required: false, type: Number }) + async getPlantingLedger( + @Param('accountSequence') accountSequence: string, + @Query('page') page?: number, + @Query('pageSize') pageSize?: number, + ) { + return this.usersService.getPlantingLedger(accountSequence, page ?? 1, pageSize ?? 20); + } + + @Get(':accountSequence/wallet-ledger') + @ApiOperation({ summary: '获取用户钱包流水' }) + @ApiParam({ name: 'accountSequence', type: String }) + @ApiQuery({ name: 'page', required: false, type: Number }) + @ApiQuery({ name: 'pageSize', required: false, type: Number }) + async getWalletLedger( + @Param('accountSequence') accountSequence: string, + @Query('page') page?: number, + @Query('pageSize') pageSize?: number, + ) { + return this.usersService.getWalletLedger(accountSequence, page ?? 1, pageSize ?? 20); + } } diff --git a/backend/services/mining-admin-service/src/application/services/users.service.ts b/backend/services/mining-admin-service/src/application/services/users.service.ts index 34dafad3..15411dfc 100644 --- a/backend/services/mining-admin-service/src/application/services/users.service.ts +++ b/backend/services/mining-admin-service/src/application/services/users.service.ts @@ -252,6 +252,99 @@ export class UsersService { }; } + /** + * 获取用户引荐关系树 + * TODO: 从 identity-service 同步推荐关系数据 + */ + async getReferralTree(accountSequence: string, direction: string, depth: number) { + const user = await this.prisma.syncedUser.findUnique({ + where: { accountSequence }, + include: { contributionAccount: 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 同步', + }; + } + + /** + * 获取用户认种分类账 + * TODO: 从 adoption-service 同步认种数据 + */ + async getPlantingLedger(accountSequence: string, page: number, pageSize: number) { + const user = await this.prisma.syncedUser.findUnique({ + where: { accountSequence }, + }); + + if (!user) { + throw new NotFoundException(`用户 ${accountSequence} 不存在`); + } + + // 返回空数据,数据需要从 adoption-service 同步 + return { + summary: { + totalOrders: 0, + totalTreeCount: 0, + totalAmount: '0', + effectiveTreeCount: 0, + firstPlantingAt: null, + lastPlantingAt: null, + }, + items: [], + total: 0, + page, + pageSize, + totalPages: 0, + note: '认种数据需要从 adoption-service 同步', + }; + } + + /** + * 获取用户钱包流水 + * TODO: 从 mining-service 同步钱包流水数据 + */ + async getWalletLedger(accountSequence: string, page: number, pageSize: number) { + const user = await this.prisma.syncedUser.findUnique({ + where: { accountSequence }, + include: { miningAccount: true }, + }); + + if (!user) { + throw new NotFoundException(`用户 ${accountSequence} 不存在`); + } + + const mining = user.miningAccount; + + return { + summary: { + availableBalance: mining?.availableBalance?.toString() || '0', + frozenBalance: mining?.frozenBalance?.toString() || '0', + totalMined: mining?.totalMined?.toString() || '0', + }, + items: [], + total: 0, + page, + pageSize, + totalPages: 0, + note: '钱包流水数据需要从 mining-service 同步', + }; + } + // =========================================================================== // 辅助方法 // =========================================================================== diff --git a/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx b/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx index 207f4ddc..c3a3d817 100644 --- a/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx +++ b/frontend/mining-admin-web/src/features/users/components/referral-tree.tsx @@ -25,7 +25,7 @@ export function ReferralTree({ accountSequence }: ReferralTreeProps) { // 当 referralTree 数据加载完成后,自动展开当前用户的直推下级 useEffect(() => { - if (referralTree && referralTree.directReferrals.length > 0) { + if (referralTree?.currentUser && referralTree.directReferrals?.length > 0) { setExpandedNodes((prev) => ({ ...prev, [referralTree.currentUser.accountSequence]: referralTree.directReferrals, @@ -112,16 +112,16 @@ export function ReferralTree({ accountSequence }: ReferralTreeProps) { {/* 向上的引荐人链 */}
引荐人链 (向上)
- {referralTree.ancestors.length > 0 ? ( + {(referralTree.ancestors?.length ?? 0) > 0 ? (- 直推下级 ({referralTree.directReferrals.length}) + 直推下级 ({referralTree.directReferrals?.length ?? 0})