feat(profile): 支持显示多笔待领取奖励明细
- 新增 PendingRewardItem 数据模型,对接 GET /rewards/pending 接口 - 修改 ProfilePage 并行加载汇总数据和待领取列表 - 重构收益区域 UI,展示每笔奖励的权益类型、金额和独立倒计时 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
cd742856c0
commit
6eea4463f8
|
|
@ -1,6 +1,65 @@
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import '../network/api_client.dart';
|
import '../network/api_client.dart';
|
||||||
|
|
||||||
|
/// 待领取奖励条目 (从 GET /rewards/pending 获取)
|
||||||
|
class PendingRewardItem {
|
||||||
|
final String id;
|
||||||
|
final String rightType;
|
||||||
|
final double usdtAmount;
|
||||||
|
final double hashpowerAmount;
|
||||||
|
final DateTime createdAt;
|
||||||
|
final DateTime expireAt;
|
||||||
|
final int remainingTimeMs;
|
||||||
|
final String memo;
|
||||||
|
|
||||||
|
PendingRewardItem({
|
||||||
|
required this.id,
|
||||||
|
required this.rightType,
|
||||||
|
required this.usdtAmount,
|
||||||
|
required this.hashpowerAmount,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.expireAt,
|
||||||
|
required this.remainingTimeMs,
|
||||||
|
required this.memo,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory PendingRewardItem.fromJson(Map<String, dynamic> json) {
|
||||||
|
return PendingRewardItem(
|
||||||
|
id: json['id']?.toString() ?? '',
|
||||||
|
rightType: json['rightType'] ?? '',
|
||||||
|
usdtAmount: (json['usdtAmount'] ?? 0).toDouble(),
|
||||||
|
hashpowerAmount: (json['hashpowerAmount'] ?? 0).toDouble(),
|
||||||
|
createdAt: DateTime.tryParse(json['createdAt'] ?? '') ?? DateTime.now(),
|
||||||
|
expireAt: DateTime.tryParse(json['expireAt'] ?? '') ?? DateTime.now(),
|
||||||
|
remainingTimeMs: (json['remainingTimeMs'] ?? 0).toInt(),
|
||||||
|
memo: json['memo'] ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 计算剩余秒数
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 奖励汇总信息 (从 reward-service 获取)
|
/// 奖励汇总信息 (从 reward-service 获取)
|
||||||
class RewardSummary {
|
class RewardSummary {
|
||||||
final double pendingUsdt;
|
final double pendingUsdt;
|
||||||
|
|
@ -107,4 +166,57 @@ class RewardService {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 获取待领取奖励列表
|
||||||
|
///
|
||||||
|
/// 调用 GET /rewards/pending (reward-service)
|
||||||
|
/// 返回所有待领取的奖励条目,每条包含倒计时信息
|
||||||
|
Future<List<PendingRewardItem>> getPendingRewards() async {
|
||||||
|
try {
|
||||||
|
debugPrint('[RewardService] ========== 获取待领取奖励列表 ==========');
|
||||||
|
debugPrint('[RewardService] 请求: GET /rewards/pending');
|
||||||
|
|
||||||
|
final response = await _apiClient.get('/rewards/pending');
|
||||||
|
|
||||||
|
debugPrint('[RewardService] 响应状态码: ${response.statusCode}');
|
||||||
|
debugPrint('[RewardService] 响应数据类型: ${response.data.runtimeType}');
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final responseData = response.data;
|
||||||
|
debugPrint('[RewardService] 原始响应数据: $responseData');
|
||||||
|
|
||||||
|
// API 返回格式可能是直接数组或 { data: [...] }
|
||||||
|
List<dynamic> dataList;
|
||||||
|
if (responseData is List) {
|
||||||
|
dataList = responseData;
|
||||||
|
} else if (responseData is Map<String, dynamic>) {
|
||||||
|
dataList = responseData['data'] as List<dynamic>? ?? [];
|
||||||
|
} else {
|
||||||
|
dataList = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
debugPrint('[RewardService] 解析到 ${dataList.length} 条待领取奖励');
|
||||||
|
|
||||||
|
final items = dataList
|
||||||
|
.map((item) => PendingRewardItem.fromJson(item as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (var item in items) {
|
||||||
|
debugPrint('[RewardService] - ${item.rightTypeName}: ${item.usdtAmount} USDT, ${item.hashpowerAmount} 算力, 剩余 ${item.remainingSeconds}s');
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import '../../../../core/di/injection_container.dart';
|
import '../../../../core/di/injection_container.dart';
|
||||||
import '../../../../core/services/referral_service.dart';
|
import '../../../../core/services/referral_service.dart';
|
||||||
|
import '../../../../core/services/reward_service.dart';
|
||||||
import '../../../../routes/route_paths.dart';
|
import '../../../../routes/route_paths.dart';
|
||||||
import '../../../../routes/app_router.dart';
|
import '../../../../routes/app_router.dart';
|
||||||
|
|
||||||
|
|
@ -70,6 +71,9 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
bool _isLoadingWallet = true;
|
bool _isLoadingWallet = true;
|
||||||
String? _walletError;
|
String? _walletError;
|
||||||
|
|
||||||
|
// 待领取奖励列表(每一笔单独显示)
|
||||||
|
List<PendingRewardItem> _pendingRewards = [];
|
||||||
|
|
||||||
// 倒计时
|
// 倒计时
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
int _remainingSeconds = 0;
|
int _remainingSeconds = 0;
|
||||||
|
|
@ -362,8 +366,16 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
|
|
||||||
debugPrint('[ProfilePage] 获取 rewardServiceProvider...');
|
debugPrint('[ProfilePage] 获取 rewardServiceProvider...');
|
||||||
final rewardService = ref.read(rewardServiceProvider);
|
final rewardService = ref.read(rewardServiceProvider);
|
||||||
debugPrint('[ProfilePage] 调用 getMyRewardSummary()...');
|
|
||||||
final summary = await rewardService.getMyRewardSummary();
|
// 并行加载汇总数据和待领取列表
|
||||||
|
debugPrint('[ProfilePage] 调用 getMyRewardSummary() 和 getPendingRewards()...');
|
||||||
|
final results = await Future.wait([
|
||||||
|
rewardService.getMyRewardSummary(),
|
||||||
|
rewardService.getPendingRewards(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final summary = results[0] as RewardSummary;
|
||||||
|
final pendingRewards = results[1] as List<PendingRewardItem>;
|
||||||
|
|
||||||
debugPrint('[ProfilePage] -------- 收益数据加载成功 --------');
|
debugPrint('[ProfilePage] -------- 收益数据加载成功 --------');
|
||||||
debugPrint('[ProfilePage] 待领取 USDT: ${summary.pendingUsdt}');
|
debugPrint('[ProfilePage] 待领取 USDT: ${summary.pendingUsdt}');
|
||||||
|
|
@ -374,6 +386,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
debugPrint('[ProfilePage] 已过期 算力: ${summary.expiredTotalHashpower}');
|
debugPrint('[ProfilePage] 已过期 算力: ${summary.expiredTotalHashpower}');
|
||||||
debugPrint('[ProfilePage] 过期时间: ${summary.pendingExpireAt}');
|
debugPrint('[ProfilePage] 过期时间: ${summary.pendingExpireAt}');
|
||||||
debugPrint('[ProfilePage] 剩余秒数: ${summary.pendingRemainingSeconds}');
|
debugPrint('[ProfilePage] 剩余秒数: ${summary.pendingRemainingSeconds}');
|
||||||
|
debugPrint('[ProfilePage] 待领取奖励条目数: ${pendingRewards.length}');
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
debugPrint('[ProfilePage] 更新 UI 状态...');
|
debugPrint('[ProfilePage] 更新 UI 状态...');
|
||||||
|
|
@ -385,12 +398,14 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
_expiredUsdt = summary.expiredTotalUsdt;
|
_expiredUsdt = summary.expiredTotalUsdt;
|
||||||
_expiredPower = summary.expiredTotalHashpower;
|
_expiredPower = summary.expiredTotalHashpower;
|
||||||
_remainingSeconds = summary.pendingRemainingSeconds;
|
_remainingSeconds = summary.pendingRemainingSeconds;
|
||||||
|
_pendingRewards = pendingRewards;
|
||||||
_isLoadingWallet = false;
|
_isLoadingWallet = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
debugPrint('[ProfilePage] UI 状态更新完成');
|
debugPrint('[ProfilePage] UI 状态更新完成');
|
||||||
debugPrint('[ProfilePage] _pendingUsdt: $_pendingUsdt');
|
debugPrint('[ProfilePage] _pendingUsdt: $_pendingUsdt');
|
||||||
debugPrint('[ProfilePage] _remainingSeconds: $_remainingSeconds');
|
debugPrint('[ProfilePage] _remainingSeconds: $_remainingSeconds');
|
||||||
|
debugPrint('[ProfilePage] _pendingRewards: ${_pendingRewards.length} 条');
|
||||||
|
|
||||||
// 启动倒计时(如果有待领取收益)
|
// 启动倒计时(如果有待领取收益)
|
||||||
if (_remainingSeconds > 0) {
|
if (_remainingSeconds > 0) {
|
||||||
|
|
@ -1115,115 +1130,246 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// 倒计时
|
// 汇总信息区域
|
||||||
Column(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
const Text(
|
// 倒计时
|
||||||
'24 小时倒计时',
|
Expanded(
|
||||||
style: TextStyle(
|
child: Column(
|
||||||
fontSize: 12,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
fontFamily: 'Inter',
|
children: [
|
||||||
fontWeight: FontWeight.w500,
|
const Text(
|
||||||
height: 1.5,
|
'24小时倒计时',
|
||||||
color: Color(0xCC5D4037),
|
style: TextStyle(
|
||||||
),
|
fontSize: 12,
|
||||||
),
|
fontFamily: 'Inter',
|
||||||
Text(
|
fontWeight: FontWeight.w500,
|
||||||
_formatCountdown(),
|
height: 1.5,
|
||||||
style: const TextStyle(
|
color: Color(0xCC5D4037),
|
||||||
fontSize: 14,
|
),
|
||||||
fontFamily: 'Consolas',
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
height: 1.25,
|
|
||||||
letterSpacing: 0.7,
|
|
||||||
color: Color(0xFFD4AF37),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
// 待领取 USDT
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const Text(
|
|
||||||
'待领取 (USDT)',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: 'Inter',
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
height: 1.5,
|
|
||||||
color: Color(0xCC5D4037),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
_formatNumber(_pendingUsdt),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
fontFamily: 'Inter',
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
height: 1.25,
|
|
||||||
color: Color(0xFF5D4037),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 11),
|
|
||||||
// 待领取 算力
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const Text(
|
|
||||||
'待领取 (算力)',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: 'Inter',
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
height: 1.5,
|
|
||||||
color: Color(0xCC5D4037),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
_formatNumber(_pendingPower),
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 20,
|
|
||||||
fontFamily: 'Inter',
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
height: 1.25,
|
|
||||||
color: Color(0xFF5D4037),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const SizedBox(height: 15),
|
|
||||||
// 领取全部按钮
|
|
||||||
GestureDetector(
|
|
||||||
onTap: _claimAllEarnings,
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
height: 40,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color(0xFFD4AF37),
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
child: const Center(
|
|
||||||
child: Text(
|
|
||||||
'领取全部',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontFamily: 'Inter',
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
height: 1.5,
|
|
||||||
letterSpacing: 0.21,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
),
|
||||||
|
Text(
|
||||||
|
_formatCountdown(),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: 'Consolas',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.25,
|
||||||
|
letterSpacing: 0.7,
|
||||||
|
color: Color(0xFFD4AF37),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// 汇总待领取 USDT
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'待领取 (USDT)',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
height: 1.5,
|
||||||
|
color: Color(0xCC5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
_formatNumber(_pendingUsdt),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.25,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// 汇总待领取算力
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
'待领取 (算力)',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
height: 1.5,
|
||||||
|
color: Color(0xCC5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
_formatNumber(_pendingPower),
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.25,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// 待领取奖励列表
|
||||||
|
if (_pendingRewards.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),
|
||||||
|
// 奖励条目列表
|
||||||
|
...(_pendingRewards.map((item) => _buildPendingRewardItem(item))),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 15),
|
||||||
|
// 领取全部按钮
|
||||||
|
GestureDetector(
|
||||||
|
onTap: _claimAllEarnings,
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFD4AF37),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: const Center(
|
||||||
|
child: Text(
|
||||||
|
'领取全部',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1.5,
|
||||||
|
letterSpacing: 0.21,
|
||||||
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 构建单条待领取奖励项
|
||||||
|
Widget _buildPendingRewardItem(PendingRewardItem item) {
|
||||||
|
final remainingSeconds = item.remainingSeconds;
|
||||||
|
final hours = (remainingSeconds ~/ 3600).toString().padLeft(2, '0');
|
||||||
|
final minutes = ((remainingSeconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||||
|
final seconds = (remainingSeconds % 60).toString().padLeft(2, '0');
|
||||||
|
final countdown = '$hours:$minutes:$seconds';
|
||||||
|
|
||||||
|
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.rightTypeName,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Icon(
|
||||||
|
Icons.timer_outlined,
|
||||||
|
size: 14,
|
||||||
|
color: Color(0xFFD4AF37),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
countdown,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontFamily: 'Consolas',
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Color(0xFFD4AF37),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
// 第二行:金额信息
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
if (item.usdtAmount > 0) ...[
|
||||||
|
Text(
|
||||||
|
'${_formatNumber(item.usdtAmount)} USDT',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (item.hashpowerAmount > 0) const SizedBox(width: 16),
|
||||||
|
],
|
||||||
|
if (item.hashpowerAmount > 0)
|
||||||
|
Text(
|
||||||
|
'${_formatNumber(item.hashpowerAmount)} 算力',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Color(0xFF5D4037),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// 第三行:备注信息(如果有)
|
||||||
|
if (item.memo.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
item.memo,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
fontFamily: 'Inter',
|
||||||
|
color: Color(0x995D4037),
|
||||||
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
);
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 构建结算区域
|
/// 构建结算区域
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue