This commit is contained in:
sion
2026-04-06 11:31:28 +08:00
parent d4b0c6c128
commit 4f4f5df83e
3 changed files with 174 additions and 13 deletions

View File

@@ -67,28 +67,70 @@ class _BillsPageState extends State<BillsPage> with SingleTickerProviderStateMix
List<Map<String, dynamic>> _parseWelfareRecords(Map<String, dynamic> data) {
final records = <Map<String, dynamic>>[];
// 新人福利
final newUser = data['newUserBonus'] as Map<String, dynamic>?;
if (newUser != null) {
final claimed = newUser['claimed'] as bool? ?? false;
final eligible = newUser['eligible'] as bool? ?? false;
// 状态: 1=已领取, 0=可领取(待领取), 2=不可用(未解锁)
final int status;
if (claimed) {
status = 1;
} else if (eligible) {
status = 0;
} else {
status = 2;
}
records.add({
'type': 'new_user',
'title': '新人福利',
'amount': newUser['amount']?.toString() ?? '0.00',
'status': newUser['status'] ?? 0,
'amount': newUser['amount']?.toString() ?? '100.00',
'status': status,
'time': newUser['claimTime'] ?? newUser['createTime'],
});
}
// 推广福利列表
final referrals = data['referralBonuses'] as List?;
if (referrals != null) {
for (var r in referrals) {
final map = r as Map<String, dynamic>;
final referralRewards = data['referralRewards'] as List<dynamic>? ?? [];
for (var r in referralRewards) {
final map = r as Map<String, dynamic>;
final username = map['username'] as String? ?? '用户';
final milestones = map['milestones'] as List<dynamic>? ?? [];
final claimableCount = map['claimableCount'] as int? ?? 0;
// 每个 milestone 生成一条记录
for (var m in milestones) {
final ms = m as Map<String, dynamic>;
final earned = ms['earned'] as bool? ?? false;
final claimable = ms['claimable'] as bool? ?? false;
final milestoneVal = ms['milestone'] as int? ?? 1;
final int status;
if (earned) {
status = 1; // 已领取
} else if (claimable) {
status = 0; // 可领取
} else {
status = 2; // 未达标
}
records.add({
'type': 'referral',
'title': '推广福利 - ${map['referredUsername'] ?? '用户'}',
'amount': map['amount']?.toString() ?? '0.00',
'status': map['status'] ?? 0,
'time': map['claimTime'] ?? map['createTime'],
'title': '推广福利 - $username (${milestoneVal}000)',
'amount': '100.00',
'status': status,
'time': ms['claimTime'] ?? ms['createTime'],
});
}
// 如果没有 milestone 但有 claimableCount也生成记录
if (milestones.isEmpty && claimableCount > 0) {
records.add({
'type': 'referral',
'title': '推广福利 - $username',
'amount': '${claimableCount * 100}',
'status': 0,
'time': null,
});
}
}
@@ -340,7 +382,7 @@ class _BillsPageState extends State<BillsPage> with SingleTickerProviderStateMix
final amount = double.tryParse(record['amount']?.toString() ?? '0') ?? 0;
final status = record['status'] as int? ?? 0;
// status: 0=待领取, 1=已领取, 2=已过期
// status: 0=待领取, 1=已领取, 2=未达标
String statusText;
Color statusColor;
switch (status) {
@@ -349,7 +391,7 @@ class _BillsPageState extends State<BillsPage> with SingleTickerProviderStateMix
statusColor = context.appColors.up;
break;
case 2:
statusText = '已过期';
statusText = '未达标';
statusColor = colorScheme.onSurfaceVariant;
break;
default:

View File

@@ -355,6 +355,19 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
final referralRewards =
_welfareData?['referralRewards'] as List<dynamic>? ?? [];
// 汇总统计
int totalEarned = 0;
int totalClaimable = 0;
for (var r in referralRewards) {
final map = r as Map<String, dynamic>;
final milestones = map['milestones'] as List<dynamic>? ?? [];
for (var m in milestones) {
final ms = m as Map<String, dynamic>;
if (ms['claimed'] as bool? ?? false) totalEarned++;
if (ms['claimable'] as bool? ?? false) totalClaimable++;
}
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -370,6 +383,29 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
color: context.appColors.onSurfaceMuted,
),
),
// 汇总统计
if (referralRewards.isNotEmpty) ...[
const SizedBox(height: 12),
Container(
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm),
decoration: BoxDecoration(
color: context.appColors.surfaceCard,
borderRadius: BorderRadius.circular(AppRadius.md),
border: Border.all(color: context.appColors.ghostBorder),
),
child: Row(
children: [
_buildStatItem('已邀请', '${referralRewards.length}'),
Container(width: 1, height: 20, color: context.appColors.ghostBorder),
_buildStatItem('已获得', '${totalEarned * 100} USDT'),
if (totalClaimable > 0) ...[
Container(width: 1, height: 20, color: context.appColors.ghostBorder),
_buildStatItem('待领取', '$totalClaimable个', highlight: true),
],
],
),
),
],
const SizedBox(height: 12),
// 推广列表卡片
@@ -384,6 +420,23 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
);
}
Widget _buildStatItem(String label, String value, {bool highlight = false}) {
return Expanded(
child: Column(
children: [
Text(label, style: AppTextStyles.bodySmall(context).copyWith(
color: context.colors.onSurfaceVariant,
)),
const SizedBox(height: 2),
Text(value, style: AppTextStyles.headlineSmall(context).copyWith(
fontWeight: FontWeight.w700,
color: highlight ? context.appColors.up : context.colors.onSurface,
)),
],
),
);
}
Widget _buildEmptyReferralList(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(32),
@@ -416,6 +469,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
final totalDeposit = data['totalDeposit']?.toString() ?? '0';
final claimableCount = data['claimableCount'] as int? ?? 0;
final milestones = data['milestones'] as List<dynamic>? ?? [];
final userId = data['userId'] as int? ?? 0;
final isLast = index == referralRewards.length - 1;
// 进度计算
@@ -446,7 +500,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
Text(
username,
style: AppTextStyles.headlineSmall(context).copyWith(
fontWeight: FontWeight.w500, // 添加 w500
fontWeight: FontWeight.w500,
),
),
const SizedBox(width: 10),
@@ -472,6 +526,11 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
),
),
),
// 里程碑详情
if (milestones.isNotEmpty) ...[
const SizedBox(height: 12),
_buildMilestoneDetails(milestones, userId),
],
],
),
),
@@ -487,6 +546,66 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
);
}
/// 里程碑详情行 — 显示每个里程碑状态
Widget _buildMilestoneDetails(List<dynamic> milestones, int userId) {
final upColor = context.appColors.up;
return Wrap(
spacing: 6,
runSpacing: 6,
children: milestones.map((m) {
final ms = m as Map<String, dynamic>;
final milestoneVal = ms['milestone'] as int? ?? 1;
final earned = ms['earned'] as bool? ?? false;
final claimed = ms['claimed'] as bool? ?? false;
final claimable = ms['claimable'] as bool? ?? false;
final threshold = ms['threshold']?.toString() ?? '${milestoneVal * 1000}';
Color bgColor;
Color textColor;
String label;
if (claimed) {
bgColor = upColor.withValues(alpha: 0.1);
textColor = upColor;
label = '${threshold}';
} else if (claimable) {
bgColor = context.appColors.accentPrimary.withValues(alpha: 0.15);
textColor = context.appColors.accentPrimary;
label = '${threshold}🎁';
} else if (earned) {
bgColor = upColor.withValues(alpha: 0.06);
textColor = upColor;
label = '${threshold}';
} else {
bgColor = context.appColors.surfaceCardHigh;
textColor = context.colors.onSurfaceVariant;
label = '${threshold}';
}
return GestureDetector(
onTap: claimable ? () => _claimReferralBonus(userId, milestoneVal) : null,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(AppRadius.sm),
border: claimable ? Border.all(color: textColor.withValues(alpha: 0.3)) : null,
),
child: Text(
label,
style: AppTextStyles.bodySmall(context).copyWith(
fontSize: 11,
fontWeight: FontWeight.w600,
color: textColor,
),
),
),
);
}).toList(),
);
}
Widget _buildAvatar(String username) {
return Container(
width: 32,