diff --git a/backend/services/wallet-service/src/api/controllers/wallet.controller.ts b/backend/services/wallet-service/src/api/controllers/wallet.controller.ts index 355749b4..2a6f18a8 100644 --- a/backend/services/wallet-service/src/api/controllers/wallet.controller.ts +++ b/backend/services/wallet-service/src/api/controllers/wallet.controller.ts @@ -117,4 +117,38 @@ export class WalletController { }>> { return this.walletService.getPendingRewards(user.accountSequence); } + + @Get('settleable-rewards') + @ApiOperation({ summary: '查询可结算奖励列表', description: '获取用户的逐笔可结算奖励(已领取待结算)' }) + @ApiResponse({ status: 200, description: '可结算奖励列表' }) + async getSettleableRewards( + @CurrentUser() user: CurrentUserPayload, + ): Promise> { + return this.walletService.getSettleableRewards(user.accountSequence); + } + + @Get('expired-rewards') + @ApiOperation({ summary: '查询已过期奖励列表', description: '获取用户的逐笔已过期奖励(24h未领取)' }) + @ApiResponse({ status: 200, description: '已过期奖励列表' }) + async getExpiredRewards( + @CurrentUser() user: CurrentUserPayload, + ): Promise> { + return this.walletService.getExpiredRewards(user.accountSequence); + } } diff --git a/backend/services/wallet-service/src/application/services/wallet-application.service.ts b/backend/services/wallet-service/src/application/services/wallet-application.service.ts index 5b885f74..2e1183b4 100644 --- a/backend/services/wallet-service/src/application/services/wallet-application.service.ts +++ b/backend/services/wallet-service/src/application/services/wallet-application.service.ts @@ -1622,6 +1622,62 @@ export class WalletApplicationService { })); } + /** + * 查询用户的可结算奖励列表 + * 从 pending_rewards 表中读取 status=SETTLED 的记录 + */ + async getSettleableRewards(accountSequence: string): Promise> { + const rewards = await this.pendingRewardRepo.findByAccountSequence( + accountSequence, + PendingRewardStatus.SETTLED, + ); + return rewards.map(r => ({ + id: r.id.toString(), + usdtAmount: r.usdtAmount.value, + hashpowerAmount: r.hashpowerAmount.value, + sourceOrderId: r.sourceOrderId, + allocationType: r.allocationType, + settledAt: r.settledAt?.toISOString() ?? '', + createdAt: r.createdAt.toISOString(), + })); + } + + /** + * 查询用户的已过期奖励列表 + * 从 pending_rewards 表中读取 status=EXPIRED 的记录 + */ + async getExpiredRewards(accountSequence: string): Promise> { + const rewards = await this.pendingRewardRepo.findByAccountSequence( + accountSequence, + PendingRewardStatus.EXPIRED, + ); + return rewards.map(r => ({ + id: r.id.toString(), + usdtAmount: r.usdtAmount.value, + hashpowerAmount: r.hashpowerAmount.value, + sourceOrderId: r.sourceOrderId, + allocationType: r.allocationType, + expiredAt: r.expiredAt?.toISOString() ?? '', + createdAt: r.createdAt.toISOString(), + })); + } + /** * 结算用户所有待领取奖励 * 当用户认种后调用,将 PENDING 状态的奖励转为 SETTLED diff --git a/frontend/mobile-app/lib/core/services/reward_service.dart b/frontend/mobile-app/lib/core/services/reward_service.dart index 498d3460..03a659c6 100644 --- a/frontend/mobile-app/lib/core/services/reward_service.dart +++ b/frontend/mobile-app/lib/core/services/reward_service.dart @@ -1,6 +1,26 @@ import 'package:flutter/foundation.dart'; import '../network/api_client.dart'; +/// 获取权益类型的中文名称(公共方法) +String getAllocationTypeName(String allocationType) { + switch (allocationType) { + case 'SHARE_RIGHT': + return '分享权益'; + case 'PROVINCE_AREA_RIGHT': + return '省区域权益'; + case 'PROVINCE_TEAM_RIGHT': + return '省团队权益'; + case 'CITY_AREA_RIGHT': + return '市区域权益'; + case 'CITY_TEAM_RIGHT': + return '市团队权益'; + case 'COMMUNITY_RIGHT': + return '社区权益'; + default: + return allocationType; + } +} + /// 待领取奖励条目 (从 GET /rewards/pending 获取) class PendingRewardItem { final String id; @@ -40,24 +60,79 @@ class PendingRewardItem { int get remainingSeconds => (remainingTimeMs / 1000).round(); /// 获取权益类型的中文名称 - String get rightTypeName { - switch (rightType) { - case 'SHARE_RIGHT': - return '分享权益'; - case 'PROVINCE_AREA_RIGHT': - return '省区域权益'; - case 'PROVINCE_TEAM_RIGHT': - return '省团队权益'; - case 'CITY_AREA_RIGHT': - return '市区域权益'; - case 'CITY_TEAM_RIGHT': - return '市团队权益'; - case 'COMMUNITY_RIGHT': - return '社区权益'; - default: - return rightType; - } + String get rightTypeName => getAllocationTypeName(rightType); +} + +/// 可结算奖励条目 (从 GET /wallet/settleable-rewards 获取) +class SettleableRewardItem { + final String id; + final String allocationType; + final double usdtAmount; + final double hashpowerAmount; + final DateTime createdAt; + final DateTime settledAt; + final String sourceOrderId; + + SettleableRewardItem({ + required this.id, + required this.allocationType, + required this.usdtAmount, + required this.hashpowerAmount, + required this.createdAt, + required this.settledAt, + required this.sourceOrderId, + }); + + factory SettleableRewardItem.fromJson(Map json) { + return SettleableRewardItem( + id: json['id']?.toString() ?? '', + allocationType: json['allocationType'] ?? '', + usdtAmount: (json['usdtAmount'] ?? 0).toDouble(), + hashpowerAmount: (json['hashpowerAmount'] ?? 0).toDouble(), + createdAt: DateTime.tryParse(json['createdAt'] ?? '') ?? DateTime.now(), + settledAt: DateTime.tryParse(json['settledAt'] ?? '') ?? DateTime.now(), + sourceOrderId: json['sourceOrderId'] ?? '', + ); } + + /// 获取权益类型的中文名称 + String get allocationTypeName => getAllocationTypeName(allocationType); +} + +/// 已过期奖励条目 (从 GET /wallet/expired-rewards 获取) +class ExpiredRewardItem { + final String id; + final String allocationType; + final double usdtAmount; + final double hashpowerAmount; + final DateTime createdAt; + final DateTime expiredAt; + final String sourceOrderId; + + ExpiredRewardItem({ + required this.id, + required this.allocationType, + required this.usdtAmount, + required this.hashpowerAmount, + required this.createdAt, + required this.expiredAt, + required this.sourceOrderId, + }); + + factory ExpiredRewardItem.fromJson(Map json) { + return ExpiredRewardItem( + id: json['id']?.toString() ?? '', + allocationType: json['allocationType'] ?? '', + usdtAmount: (json['usdtAmount'] ?? 0).toDouble(), + hashpowerAmount: (json['hashpowerAmount'] ?? 0).toDouble(), + createdAt: DateTime.tryParse(json['createdAt'] ?? '') ?? DateTime.now(), + expiredAt: DateTime.tryParse(json['expiredAt'] ?? '') ?? DateTime.now(), + sourceOrderId: json['sourceOrderId'] ?? '', + ); + } + + /// 获取权益类型的中文名称 + String get allocationTypeName => getAllocationTypeName(allocationType); } /// 奖励汇总信息 (从 reward-service 获取) @@ -219,4 +294,110 @@ class RewardService { rethrow; } } + + /// 获取可结算奖励列表 + /// + /// 调用 GET /wallet/settleable-rewards (wallet-service) + /// 返回所有已领取待结算的奖励条目 + Future> getSettleableRewards() async { + try { + debugPrint('[RewardService] ========== 获取可结算奖励列表 =========='); + debugPrint('[RewardService] 请求: GET /wallet/settleable-rewards'); + + final response = await _apiClient.get('/wallet/settleable-rewards'); + + debugPrint('[RewardService] 响应状态码: ${response.statusCode}'); + debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}'); + + if (response.statusCode == 200) { + final responseData = response.data; + debugPrint('[RewardService] 原始响应数据: $responseData'); + + // API 返回格式可能是直接数组或 { data: [...] } + List dataList; + if (responseData is List) { + dataList = responseData; + } else if (responseData is Map) { + dataList = responseData['data'] as List? ?? []; + } else { + dataList = []; + } + + debugPrint('[RewardService] 解析到 ${dataList.length} 条可结算奖励'); + + final items = dataList + .map((item) => SettleableRewardItem.fromJson(item as Map)) + .toList(); + + for (var item in items) { + debugPrint('[RewardService] - ${item.allocationTypeName}: ${item.usdtAmount} USDT, ${item.hashpowerAmount} 算力'); + } + debugPrint('[RewardService] ================================'); + + return items; + } + + debugPrint('[RewardService] 请求失败,状态码: ${response.statusCode}'); + debugPrint('[RewardService] 响应内容: ${response.data}'); + throw Exception('获取可结算奖励列表失败: ${response.statusCode}'); + } catch (e, stackTrace) { + debugPrint('[RewardService] !!!!!!!!!! 获取可结算奖励列表异常 !!!!!!!!!!'); + debugPrint('[RewardService] 错误: $e'); + debugPrint('[RewardService] 堆栈: $stackTrace'); + rethrow; + } + } + + /// 获取已过期奖励列表 + /// + /// 调用 GET /wallet/expired-rewards (wallet-service) + /// 返回所有已过期的奖励条目(24h未领取) + Future> getExpiredRewards() async { + try { + debugPrint('[RewardService] ========== 获取已过期奖励列表 =========='); + debugPrint('[RewardService] 请求: GET /wallet/expired-rewards'); + + final response = await _apiClient.get('/wallet/expired-rewards'); + + debugPrint('[RewardService] 响应状态码: ${response.statusCode}'); + debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}'); + + if (response.statusCode == 200) { + final responseData = response.data; + debugPrint('[RewardService] 原始响应数据: $responseData'); + + // API 返回格式可能是直接数组或 { data: [...] } + List dataList; + if (responseData is List) { + dataList = responseData; + } else if (responseData is Map) { + dataList = responseData['data'] as List? ?? []; + } else { + dataList = []; + } + + debugPrint('[RewardService] 解析到 ${dataList.length} 条已过期奖励'); + + final items = dataList + .map((item) => ExpiredRewardItem.fromJson(item as Map)) + .toList(); + + for (var item in items) { + debugPrint('[RewardService] - ${item.allocationTypeName}: ${item.usdtAmount} USDT, ${item.hashpowerAmount} 算力'); + } + debugPrint('[RewardService] ================================'); + + return items; + } + + debugPrint('[RewardService] 请求失败,状态码: ${response.statusCode}'); + debugPrint('[RewardService] 响应内容: ${response.data}'); + throw Exception('获取已过期奖励列表失败: ${response.statusCode}'); + } catch (e, stackTrace) { + debugPrint('[RewardService] !!!!!!!!!! 获取已过期奖励列表异常 !!!!!!!!!!'); + debugPrint('[RewardService] 错误: $e'); + debugPrint('[RewardService] 堆栈: $stackTrace'); + rethrow; + } + } } diff --git a/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart b/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart index a281a7e1..ae6ffb40 100644 --- a/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart +++ b/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart @@ -59,6 +59,9 @@ class _ProfilePageState extends ConsumerState { // 直推数据(从 referral-service 获取) List> _referrals = []; + // 团队树根节点(缓存以保持展开状态) + TeamTreeNode? _teamTreeRootNode; + // 社区考核数据(从 authorization-service 获取) bool _hasCommunityAuth = false; // 是否有社区授权 bool _communityBenefitActive = false; // 社区权益是否激活 @@ -112,6 +115,12 @@ class _ProfilePageState extends ConsumerState { // 待领取奖励列表(每一笔单独显示) List _pendingRewards = []; + // 可结算奖励列表(逐笔显示) + List _settleableRewards = []; + + // 已过期奖励列表(逐笔显示) + List _expiredRewards = []; + // 倒计时 Timer? _timer; int _remainingSeconds = 0; @@ -569,15 +578,19 @@ class _ProfilePageState extends ConsumerState { debugPrint('[ProfilePage] 获取 rewardServiceProvider...'); final rewardService = ref.read(rewardServiceProvider); - // 并行加载汇总数据和待领取列表 - debugPrint('[ProfilePage] 调用 getMyRewardSummary() 和 getPendingRewards()...'); + // 并行加载汇总数据、待领取列表、可结算列表、已过期列表 + debugPrint('[ProfilePage] 调用 getMyRewardSummary()、getPendingRewards()、getSettleableRewards()、getExpiredRewards()...'); final results = await Future.wait([ rewardService.getMyRewardSummary(), rewardService.getPendingRewards(), + rewardService.getSettleableRewards(), + rewardService.getExpiredRewards(), ]); final summary = results[0] as RewardSummary; final pendingRewards = results[1] as List; + final settleableRewards = results[2] as List; + final expiredRewards = results[3] as List; debugPrint('[ProfilePage] -------- 收益数据加载成功 --------'); debugPrint('[ProfilePage] 待领取 USDT: ${summary.pendingUsdt}'); @@ -589,6 +602,8 @@ class _ProfilePageState extends ConsumerState { debugPrint('[ProfilePage] 过期时间: ${summary.pendingExpireAt}'); debugPrint('[ProfilePage] 剩余秒数: ${summary.pendingRemainingSeconds}'); debugPrint('[ProfilePage] 待领取奖励条目数: ${pendingRewards.length}'); + debugPrint('[ProfilePage] 可结算奖励条目数: ${settleableRewards.length}'); + debugPrint('[ProfilePage] 已过期奖励条目数: ${expiredRewards.length}'); if (mounted) { debugPrint('[ProfilePage] 更新 UI 状态...'); @@ -601,6 +616,8 @@ class _ProfilePageState extends ConsumerState { _expiredPower = summary.expiredTotalHashpower; _remainingSeconds = summary.pendingRemainingSeconds; _pendingRewards = pendingRewards; + _settleableRewards = settleableRewards; + _expiredRewards = expiredRewards; _isLoadingWallet = false; _walletError = null; _walletRetryCount = 0; @@ -610,6 +627,8 @@ class _ProfilePageState extends ConsumerState { debugPrint('[ProfilePage] _pendingUsdt: $_pendingUsdt'); debugPrint('[ProfilePage] _remainingSeconds: $_remainingSeconds'); debugPrint('[ProfilePage] _pendingRewards: ${_pendingRewards.length} 条'); + debugPrint('[ProfilePage] _settleableRewards: ${_settleableRewards.length} 条'); + debugPrint('[ProfilePage] _expiredRewards: ${_expiredRewards.length} 条'); // 启动倒计时(如果有待领取收益) if (_remainingSeconds > 0) { @@ -1415,55 +1434,38 @@ class _ProfilePageState extends ConsumerState { width: 1, ), ), - child: Column( + child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 第一行:推荐人序列号 | 下级社区 - Row( - children: [ - Expanded( - child: _buildInfoItem('推荐人的序列号', _referrerSerial), - ), - Expanded( - child: _buildInfoItem('下级社区', _childCommunity), - ), - ], + // 左列:推荐人序列号、所属社区、上线社区、下级社区 + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildInfoItem('推荐人的序列号', _referrerSerial), + const SizedBox(height: 12), + _buildInfoItem('所属社区', _community), + const SizedBox(height: 12), + _buildInfoItem('上线社区', _parentCommunity), + const SizedBox(height: 12), + _buildInfoItem('下级社区', _childCommunity), + ], + ), ), - const SizedBox(height: 12), - // 第二行:所属社区 | 市团队 - Row( - children: [ - Expanded( - child: _buildInfoItem('所属社区', _community), - ), - Expanded( - child: _buildInfoItem('市团队', _authCityCompany), - ), - ], - ), - const SizedBox(height: 12), - // 第三行:上级社区 | 市区域 - Row( - children: [ - Expanded( - child: _buildInfoItem('上级社区', _parentCommunity), - ), - Expanded( - child: _buildInfoItem('市区域', _cityCompany), - ), - ], - ), - const SizedBox(height: 12), - // 第四行:省团队 | 省区域 - Row( - children: [ - Expanded( - child: _buildInfoItem('省团队', _authProvinceCompany), - ), - Expanded( - child: _buildInfoItem('省区域', _provinceCompany), - ), - ], + // 右列:市团队、省团队、市区域、省区域 + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildInfoItem('市团队', _authCityCompany), + const SizedBox(height: 12), + _buildInfoItem('省团队', _authProvinceCompany), + const SizedBox(height: 12), + _buildInfoItem('市区域', _cityCompany), + const SizedBox(height: 12), + _buildInfoItem('省区域', _provinceCompany), + ], + ), ), ], ), @@ -1574,7 +1576,7 @@ class _ProfilePageState extends ConsumerState { // 直推列表 _buildReferralList(), const SizedBox(height: 16), - // 我的伞下 + // 我的团队 _buildMyTeamTree(), const SizedBox(height: 16), // 分享邀请按钮 @@ -1972,6 +1974,24 @@ class _ProfilePageState extends ConsumerState { ), ], ), + // 可结算奖励明细列表 + if (_settleableRewards.isNotEmpty) ...[ + const SizedBox(height: 16), + const Divider(color: Color(0x33D4AF37), height: 1), + const SizedBox(height: 12), + const Text( + '可结算明细', + style: TextStyle( + fontSize: 14, + fontFamily: 'Inter', + fontWeight: FontWeight.w600, + color: Color(0xFF5D4037), + ), + ), + const SizedBox(height: 8), + // 奖励条目列表 + ...(_settleableRewards.map((item) => _buildSettleableRewardItem(item))), + ], const SizedBox(height: 11), // 已结算 USDT Row( @@ -2026,6 +2046,85 @@ class _ProfilePageState extends ConsumerState { ); } + /// 构建单条可结算奖励项 + Widget _buildSettleableRewardItem(SettleableRewardItem item) { + // 格式化结算时间 + final settledDate = '${item.settledAt.month}/${item.settledAt.day} ${item.settledAt.hour.toString().padLeft(2, '0')}:${item.settledAt.minute.toString().padLeft(2, '0')}'; + + // 构建金额显示文本 + final List amountParts = []; + if (item.usdtAmount > 0) { + amountParts.add('${_formatNumber(item.usdtAmount)} 积分'); + } + if (item.hashpowerAmount > 0) { + amountParts.add('${_formatNumber(item.hashpowerAmount)} 算力'); + } + final amountText = amountParts.isNotEmpty ? amountParts.join(' ') : '0 积分'; + + return Container( + margin: const EdgeInsets.only(bottom: 8), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: const Color(0x22D4AF37), + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 第一行:权益类型 + 结算时间 + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + item.allocationTypeName, + style: const TextStyle( + fontSize: 14, + fontFamily: 'Inter', + fontWeight: FontWeight.w600, + color: Color(0xFF5D4037), + ), + ), + Row( + children: [ + const Icon( + Icons.check_circle_outline, + size: 14, + color: Color(0xFF4CAF50), + ), + const SizedBox(width: 4), + Text( + settledDate, + style: const TextStyle( + fontSize: 12, + fontFamily: 'Inter', + fontWeight: FontWeight.w500, + color: Color(0xFF4CAF50), + ), + ), + ], + ), + ], + ), + const SizedBox(height: 8), + // 第二行:金额信息 + Text( + amountText, + style: const TextStyle( + fontSize: 16, + fontFamily: 'Inter', + fontWeight: FontWeight.w700, + color: Color(0xFF5D4037), + ), + ), + ], + ), + ); + } + /// 构建已过期区域 Widget _buildExpiredSection() { return SizedBox( @@ -2107,12 +2206,109 @@ class _ProfilePageState extends ConsumerState { ), ], ), + // 已过期奖励明细列表 + if (_expiredRewards.isNotEmpty) ...[ + const SizedBox(height: 16), + const Divider(color: Color(0x33D4AF37), height: 1), + const SizedBox(height: 12), + const Text( + '已过期明细', + style: TextStyle( + fontSize: 14, + fontFamily: 'Inter', + fontWeight: FontWeight.w600, + color: Color(0xFF5D4037), + ), + ), + const SizedBox(height: 8), + // 奖励条目列表 + ...(_expiredRewards.map((item) => _buildExpiredRewardItem(item))), + ], ], ), ), ); } + /// 构建单条已过期奖励项 + Widget _buildExpiredRewardItem(ExpiredRewardItem item) { + // 格式化过期时间 + final expiredDate = '${item.expiredAt.month}/${item.expiredAt.day} ${item.expiredAt.hour.toString().padLeft(2, '0')}:${item.expiredAt.minute.toString().padLeft(2, '0')}'; + + // 构建金额显示文本 + final List amountParts = []; + if (item.usdtAmount > 0) { + amountParts.add('${_formatNumber(item.usdtAmount)} 积分'); + } + if (item.hashpowerAmount > 0) { + amountParts.add('${_formatNumber(item.hashpowerAmount)} 算力'); + } + final amountText = amountParts.isNotEmpty ? amountParts.join(' ') : '0 积分'; + + return Container( + margin: const EdgeInsets.only(bottom: 8), + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: const Color(0xFFF5F5F5), // 灰色背景表示已过期 + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: const Color(0x22999999), + width: 1, + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 第一行:权益类型 + 过期时间 + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + item.allocationTypeName, + style: const TextStyle( + fontSize: 14, + fontFamily: 'Inter', + fontWeight: FontWeight.w600, + color: Color(0xFF999999), // 灰色文字 + ), + ), + Row( + children: [ + const Icon( + Icons.cancel_outlined, + size: 14, + color: Color(0xFFE57373), // 红色图标 + ), + const SizedBox(width: 4), + Text( + expiredDate, + style: const TextStyle( + fontSize: 12, + fontFamily: 'Inter', + fontWeight: FontWeight.w500, + color: Color(0xFFE57373), // 红色文字 + ), + ), + ], + ), + ], + ), + const SizedBox(height: 8), + // 第二行:金额信息 + Text( + amountText, + style: const TextStyle( + fontSize: 16, + fontFamily: 'Inter', + fontWeight: FontWeight.w700, + color: Color(0xFF999999), // 灰色文字 + ), + ), + ], + ), + ); + } + /// 构建操作按钮 Widget _buildActionButtons() { return Column( @@ -2358,15 +2554,22 @@ class _ProfilePageState extends ConsumerState { ); } - /// 构建我的伞下树 + /// 构建我的团队树 Widget _buildMyTeamTree() { - // 创建根节点(自己) - final rootNode = TeamTreeNode.createRoot( - accountSequence: _serialNumber, - personalPlantingCount: _personalPlantingCount, - teamPlantingCount: _teamPlantingCount, - directReferralCount: _directReferralCount, - ); + // 创建或更新根节点(缓存以保持展开状态) + // 只有在数据变化时才创建新的根节点 + if (_teamTreeRootNode == null || + _teamTreeRootNode!.accountSequence != _serialNumber || + _teamTreeRootNode!.personalPlantingCount != _personalPlantingCount || + _teamTreeRootNode!.teamPlantingCount != _teamPlantingCount || + _teamTreeRootNode!.directReferralCount != _directReferralCount) { + _teamTreeRootNode = TeamTreeNode.createRoot( + accountSequence: _serialNumber, + personalPlantingCount: _personalPlantingCount, + teamPlantingCount: _teamPlantingCount, + directReferralCount: _directReferralCount, + ); + } return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -2374,7 +2577,7 @@ class _ProfilePageState extends ConsumerState { const Padding( padding: EdgeInsets.only(top: 8), child: Text( - '我的伞下', + '我的团队', style: TextStyle( fontSize: 16, fontFamily: 'Inter', @@ -2411,7 +2614,7 @@ class _ProfilePageState extends ConsumerState { ), ) : TeamTreeWidget( - rootNode: rootNode, + rootNode: _teamTreeRootNode!, referralService: ref.read(referralServiceProvider), ), ),