rwadurian/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart

248 lines
7.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/constants/app_colors.dart';
import '../../../core/utils/format_utils.dart';
import '../../providers/user_providers.dart';
import '../../providers/contribution_providers.dart';
class ContributionPage extends ConsumerWidget {
const ContributionPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final user = ref.watch(userNotifierProvider);
final accountSequence = user.accountSequence ?? '';
final contributionAsync = ref.watch(contributionProvider(accountSequence));
return Scaffold(
appBar: AppBar(
title: const Text('我的算力'),
backgroundColor: AppColors.primary,
foregroundColor: Colors.white,
),
body: RefreshIndicator(
onRefresh: () async {
ref.invalidate(contributionProvider(accountSequence));
},
child: contributionAsync.when(
data: (contribution) {
if (contribution == null) {
return const Center(child: Text('暂无数据'));
}
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 总算力卡片
_buildTotalCard(contribution.effectiveContribution),
const SizedBox(height: 24),
// 算力构成
const Text(
'算力构成',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
_buildBreakdownCard(contribution),
const SizedBox(height: 24),
// 解锁状态
const Text(
'解锁状态',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
_buildUnlockStatus(contribution),
],
),
);
},
loading: () => const Center(child: CircularProgressIndicator()),
error: (error, _) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.error_outline, size: 48, color: AppColors.error),
const SizedBox(height: 16),
Text('加载失败: $error'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () => ref.invalidate(contributionProvider(accountSequence)),
child: const Text('重试'),
),
],
),
),
),
),
);
}
Widget _buildTotalCard(String effectiveContribution) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [AppColors.primary, Color(0xFF16A34A)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
),
child: Column(
children: [
const Text(
'有效算力',
style: TextStyle(color: Colors.white70, fontSize: 14),
),
const SizedBox(height: 8),
Text(
formatAmount(effectiveContribution),
style: const TextStyle(
color: Colors.white,
fontSize: 42,
fontWeight: FontWeight.bold,
),
),
],
),
);
}
Widget _buildBreakdownCard(contribution) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
_buildBreakdownRow(
'个人算力',
contribution.personalContribution,
'70%',
AppColors.primary,
),
const Divider(),
_buildBreakdownRow(
'系统算力',
contribution.systemContribution,
'15%',
AppColors.secondary,
),
const Divider(),
_buildBreakdownRow(
'团队层级',
contribution.teamLevelContribution,
'7.5%',
AppColors.warning,
),
const Divider(),
_buildBreakdownRow(
'团队奖励',
contribution.teamBonusContribution,
'7.5%',
Colors.purple,
),
],
),
),
);
}
Widget _buildBreakdownRow(String label, String value, String rate, Color color) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
children: [
Container(
width: 4,
height: 24,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(label, style: const TextStyle(fontSize: 14)),
Text(
'占比 $rate',
style: const TextStyle(color: AppColors.textMuted, fontSize: 12),
),
],
),
),
Text(
formatAmount(value),
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
],
),
);
}
Widget _buildUnlockStatus(contribution) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
_buildUnlockRow(
'已解锁层级',
'${contribution.unlockedLevelDepth}/15 层',
contribution.unlockedLevelDepth / 15,
),
const SizedBox(height: 16),
_buildUnlockRow(
'已解锁奖励档',
'${contribution.unlockedBonusTiers}/3 档',
contribution.unlockedBonusTiers / 3,
),
const SizedBox(height: 16),
Row(
children: [
const Icon(Icons.info_outline, size: 16, color: AppColors.textMuted),
const SizedBox(width: 8),
Expanded(
child: Text(
'直推认种人数: ${contribution.directReferralAdoptedCount}',
style: const TextStyle(color: AppColors.textMuted, fontSize: 12),
),
),
],
),
],
),
),
);
}
Widget _buildUnlockRow(String label, String value, double progress) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label),
Text(value, style: const TextStyle(fontWeight: FontWeight.bold)),
],
),
const SizedBox(height: 8),
LinearProgressIndicator(
value: progress,
backgroundColor: AppColors.border,
valueColor: const AlwaysStoppedAnimation<Color>(AppColors.primary),
),
],
);
}
}