686 lines
23 KiB
Dart
686 lines
23 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:intl/intl.dart';
|
|
import '../../../core/constants/app_colors.dart';
|
|
import '../../../core/utils/format_utils.dart';
|
|
import '../../../domain/entities/contribution.dart';
|
|
import '../../../domain/entities/contribution_record.dart';
|
|
import '../../providers/user_providers.dart';
|
|
import '../../providers/contribution_providers.dart';
|
|
import '../../widgets/shimmer_loading.dart';
|
|
|
|
class ContributionPage extends ConsumerWidget {
|
|
const ContributionPage({super.key});
|
|
|
|
// 设计色彩
|
|
static const Color _orange = Color(0xFFFF6B00);
|
|
static const Color _green = Color(0xFF22C55E);
|
|
static const Color _grayText = Color(0xFF6B7280);
|
|
static const Color _darkText = Color(0xFF1F2937);
|
|
static const Color _bgGray = Color(0xFFF3F4F6);
|
|
static const Color _lightGray = Color(0xFFF9FAFB);
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final user = ref.watch(userNotifierProvider);
|
|
final accountSequence = user.accountSequence ?? '';
|
|
final contributionAsync = ref.watch(contributionProvider(accountSequence));
|
|
final recordsParams = ContributionRecordsParams(
|
|
accountSequence: accountSequence,
|
|
page: 1,
|
|
pageSize: 3,
|
|
);
|
|
final recordsAsync = ref.watch(contributionRecordsProvider(recordsParams));
|
|
|
|
// 获取预估收益
|
|
final estimatedEarnings = ref.watch(estimatedEarningsProvider(accountSequence));
|
|
final statsAsync = ref.watch(contributionStatsProvider);
|
|
|
|
// Extract loading state and data from AsyncValue
|
|
final isLoading = contributionAsync.isLoading;
|
|
final contribution = contributionAsync.valueOrNull;
|
|
final hasError = contributionAsync.hasError;
|
|
final error = contributionAsync.error;
|
|
final isStatsLoading = statsAsync.isLoading;
|
|
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFFF5F5F5),
|
|
body: SafeArea(
|
|
bottom: false,
|
|
child: RefreshIndicator(
|
|
onRefresh: () async {
|
|
ref.invalidate(contributionProvider(accountSequence));
|
|
ref.invalidate(contributionRecordsProvider(recordsParams));
|
|
ref.invalidate(contributionStatsProvider);
|
|
},
|
|
child: hasError && contribution == null
|
|
? 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('重试'),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
: CustomScrollView(
|
|
slivers: [
|
|
// 顶部导航栏
|
|
SliverToBoxAdapter(child: _buildAppBar(context)),
|
|
// 内容
|
|
SliverPadding(
|
|
padding: const EdgeInsets.all(16),
|
|
sliver: SliverList(
|
|
delegate: SliverChildListDelegate([
|
|
// 总贡献值卡片
|
|
_buildTotalContributionCard(contribution, isLoading),
|
|
const SizedBox(height: 16),
|
|
// 三栏统计
|
|
_buildThreeColumnStats(contribution, isLoading),
|
|
const SizedBox(height: 16),
|
|
// 今日预估收益
|
|
_buildTodayEstimateCard(estimatedEarnings, isLoading || isStatsLoading),
|
|
const SizedBox(height: 16),
|
|
// 贡献值明细
|
|
_buildContributionDetailCard(context, ref, recordsAsync),
|
|
const SizedBox(height: 16),
|
|
// 团队层级统计
|
|
_buildTeamStatsCard(contribution, isLoading),
|
|
const SizedBox(height: 16),
|
|
// 贡献值失效倒计时
|
|
_buildExpirationCard(contribution, recordsAsync, isLoading),
|
|
const SizedBox(height: 100),
|
|
]),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildAppBar(BuildContext context) {
|
|
return Container(
|
|
color: _lightGray,
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
child: Row(
|
|
children: [
|
|
// Logo
|
|
Container(
|
|
width: 32,
|
|
height: 32,
|
|
decoration: BoxDecoration(
|
|
color: _orange.withOpacity(0.1),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: const Icon(Icons.eco, color: _orange, size: 20),
|
|
),
|
|
const SizedBox(width: 8),
|
|
const Text(
|
|
'榴莲生态',
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
color: _darkText,
|
|
letterSpacing: 0.45,
|
|
),
|
|
),
|
|
const Spacer(),
|
|
// 客服
|
|
IconButton(
|
|
icon: const Icon(Icons.headset_mic_outlined, color: _grayText),
|
|
onPressed: () {},
|
|
),
|
|
// 通知(带红点)
|
|
Stack(
|
|
children: [
|
|
IconButton(
|
|
icon: const Icon(Icons.notifications_outlined, color: _grayText),
|
|
onPressed: () {},
|
|
),
|
|
Positioned(
|
|
right: 10,
|
|
top: 10,
|
|
child: Container(
|
|
width: 8,
|
|
height: 8,
|
|
decoration: const BoxDecoration(
|
|
color: Colors.red,
|
|
shape: BoxShape.circle,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTotalContributionCard(Contribution? contribution, bool isLoading) {
|
|
final total = contribution?.totalContribution ?? '0';
|
|
return Container(
|
|
padding: const EdgeInsets.all(20),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
const Text(
|
|
'总贡献值',
|
|
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: _grayText),
|
|
),
|
|
Icon(Icons.visibility_outlined, color: _grayText.withOpacity(0.5), size: 18),
|
|
],
|
|
),
|
|
const SizedBox(height: 8),
|
|
DataText(
|
|
data: isLoading ? null : formatAmount(total),
|
|
isLoading: isLoading,
|
|
placeholder: '----',
|
|
style: const TextStyle(
|
|
fontSize: 30,
|
|
fontWeight: FontWeight.bold,
|
|
color: _orange,
|
|
letterSpacing: -0.75,
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
// 有效期标签
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
|
decoration: BoxDecoration(
|
|
color: _lightGray,
|
|
borderRadius: BorderRadius.circular(999),
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(Icons.info_outline, size: 14, color: _grayText.withOpacity(0.7)),
|
|
const SizedBox(width: 6),
|
|
Text(
|
|
'贡献值有效期: 730 天',
|
|
style: TextStyle(fontSize: 12, color: _grayText.withOpacity(0.9)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildThreeColumnStats(Contribution? contribution, bool isLoading) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(20),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
_buildStatColumn('个人贡献值', contribution?.personalContribution, isLoading, false),
|
|
_buildStatColumn('团队层级', contribution?.teamLevelContribution, isLoading, true),
|
|
_buildStatColumn('团队奖励', contribution?.teamBonusContribution, isLoading, true),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildStatColumn(String label, String? value, bool isLoading, bool showLeftBorder) {
|
|
return Expanded(
|
|
child: Container(
|
|
decoration: showLeftBorder
|
|
? const BoxDecoration(
|
|
border: Border(left: BorderSide(color: Color(0xFFE5E7EB), width: 1)),
|
|
)
|
|
: null,
|
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
|
child: Column(
|
|
children: [
|
|
Text(label, style: const TextStyle(fontSize: 12, color: _grayText)),
|
|
const SizedBox(height: 4),
|
|
DataText(
|
|
data: value != null ? formatAmount(value) : null,
|
|
isLoading: isLoading,
|
|
placeholder: '--',
|
|
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: _darkText),
|
|
textAlign: TextAlign.center,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTodayEstimateCard(EstimatedEarnings earnings, bool isLoading) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(20),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
// 图标
|
|
Container(
|
|
width: 40,
|
|
height: 40,
|
|
decoration: BoxDecoration(
|
|
color: _green.withOpacity(0.1),
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: const Icon(Icons.trending_up, color: _green, size: 24),
|
|
),
|
|
const SizedBox(width: 12),
|
|
// 文字说明
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text(
|
|
'今日预估收益',
|
|
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: _grayText),
|
|
),
|
|
Text(
|
|
'基于当前贡献值占比计算',
|
|
style: TextStyle(fontSize: 12, color: _grayText.withOpacity(0.7)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// 收益数值
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
children: [
|
|
isLoading
|
|
? const ShimmerText(
|
|
placeholder: '-- 积分股',
|
|
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: _green),
|
|
)
|
|
: Text.rich(
|
|
TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: earnings.isValid ? formatAmount(earnings.dailyShares) : '--',
|
|
style: const TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
color: _green,
|
|
),
|
|
),
|
|
const TextSpan(
|
|
text: ' 积分股',
|
|
style: TextStyle(fontSize: 12, color: _green),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildContributionDetailCard(
|
|
BuildContext context,
|
|
WidgetRef ref,
|
|
AsyncValue<ContributionRecordsPage?> recordsAsync,
|
|
) {
|
|
final isRecordsLoading = recordsAsync.isLoading;
|
|
final recordsPage = recordsAsync.valueOrNull;
|
|
|
|
return Container(
|
|
padding: const EdgeInsets.all(20),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
// 标题行
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
const Text(
|
|
'贡献值明细',
|
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: _darkText),
|
|
),
|
|
GestureDetector(
|
|
onTap: () {
|
|
// TODO: 跳转到完整记录页面
|
|
},
|
|
child: const Row(
|
|
children: [
|
|
Text('查看全部', style: TextStyle(fontSize: 12, color: _orange)),
|
|
Icon(Icons.chevron_right, size: 14, color: _orange),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
// 明细列表
|
|
if (isRecordsLoading)
|
|
_buildRecordsShimmer()
|
|
else if (recordsAsync.hasError && recordsPage == null)
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 20),
|
|
child: Text(
|
|
'加载失败',
|
|
style: TextStyle(fontSize: 14, color: _grayText.withOpacity(0.7)),
|
|
),
|
|
)
|
|
else if (recordsPage == null || recordsPage.data.isEmpty)
|
|
const Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 20),
|
|
child: Text(
|
|
'暂无贡献值记录',
|
|
style: TextStyle(fontSize: 14, color: _grayText),
|
|
),
|
|
)
|
|
else
|
|
Column(
|
|
children: recordsPage.data.asMap().entries.map((entry) {
|
|
final index = entry.key;
|
|
final record = entry.value;
|
|
return Column(
|
|
children: [
|
|
_buildDetailRow(record),
|
|
if (index < recordsPage.data.length - 1) const Divider(height: 24),
|
|
],
|
|
);
|
|
}).toList(),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildRecordsShimmer() {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
|
child: Column(
|
|
children: [
|
|
_buildShimmerDetailRow(),
|
|
const Divider(height: 24),
|
|
_buildShimmerDetailRow(),
|
|
const Divider(height: 24),
|
|
_buildShimmerDetailRow(),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildShimmerDetailRow() {
|
|
return Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: const [
|
|
ShimmerText(
|
|
placeholder: '认种贡献',
|
|
style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: _darkText),
|
|
),
|
|
SizedBox(height: 2),
|
|
ShimmerText(
|
|
placeholder: '2024-01-01 12:00',
|
|
style: TextStyle(fontSize: 12, color: _grayText),
|
|
),
|
|
],
|
|
),
|
|
const ShimmerText(
|
|
placeholder: '+1,000',
|
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: _green),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildDetailRow(ContributionRecord record) {
|
|
final dateFormat = DateFormat('yyyy-MM-dd HH:mm');
|
|
final formattedDate = dateFormat.format(record.createdAt);
|
|
final amount = '+${formatAmount(record.finalContribution)}';
|
|
|
|
return Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
record.displayTitle,
|
|
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: _darkText),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(formattedDate, style: const TextStyle(fontSize: 12, color: _grayText)),
|
|
],
|
|
),
|
|
Text(
|
|
amount,
|
|
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: _green),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildTeamStatsCard(Contribution? contribution, bool isLoading) {
|
|
return Container(
|
|
padding: const EdgeInsets.all(20),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text(
|
|
'团队层级统计',
|
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: _darkText),
|
|
),
|
|
const SizedBox(height: 16),
|
|
// 第一行
|
|
Row(
|
|
children: [
|
|
_buildTeamStatItem(
|
|
'直推人数',
|
|
contribution?.directReferralAdoptedCount.toString(),
|
|
'人',
|
|
isLoading,
|
|
),
|
|
const SizedBox(width: 16),
|
|
_buildTeamStatItem(
|
|
'已解锁奖励',
|
|
contribution?.unlockedBonusTiers.toString(),
|
|
'档',
|
|
isLoading,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
// 第二行
|
|
Row(
|
|
children: [
|
|
_buildTeamStatItem(
|
|
'已解锁层级',
|
|
contribution?.unlockedLevelDepth.toString(),
|
|
'级',
|
|
isLoading,
|
|
),
|
|
const SizedBox(width: 16),
|
|
_buildTeamStatItem(
|
|
'是否认种',
|
|
contribution != null ? (contribution.hasAdopted == true ? '是' : '否') : null,
|
|
'',
|
|
isLoading,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTeamStatItem(String label, String? value, String unit, bool isLoading) {
|
|
return Expanded(
|
|
child: Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: _bgGray,
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(label, style: const TextStyle(fontSize: 12, color: _grayText)),
|
|
const SizedBox(height: 4),
|
|
isLoading
|
|
? ShimmerText(
|
|
placeholder: unit.isNotEmpty ? '-- $unit' : '--',
|
|
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: _orange),
|
|
)
|
|
: Text.rich(
|
|
TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: '${value ?? '0'} ',
|
|
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: _orange),
|
|
),
|
|
if (unit.isNotEmpty)
|
|
TextSpan(
|
|
text: unit,
|
|
style: const TextStyle(fontSize: 12, color: _grayText),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildExpirationCard(
|
|
Contribution? contribution,
|
|
AsyncValue<ContributionRecordsPage?> recordsAsync,
|
|
bool isLoading,
|
|
) {
|
|
final isRecordsLoading = recordsAsync.isLoading;
|
|
final recordsPage = recordsAsync.valueOrNull;
|
|
|
|
// 从记录中获取最近的过期日期
|
|
DateTime? nearestExpireDate;
|
|
if (recordsPage != null && recordsPage.data.isNotEmpty) {
|
|
// 找到未过期记录中最近的过期日期
|
|
final activeRecords = recordsPage.data.where((r) => !r.isExpired).toList();
|
|
if (activeRecords.isNotEmpty) {
|
|
activeRecords.sort((a, b) => a.expireDate.compareTo(b.expireDate));
|
|
nearestExpireDate = activeRecords.first.expireDate;
|
|
}
|
|
}
|
|
|
|
// 计算剩余天数和进度
|
|
final now = DateTime.now();
|
|
int daysRemaining = 730; // 默认值
|
|
double progress = 1.0;
|
|
String expireDateText = '暂无过期信息';
|
|
|
|
if (nearestExpireDate != null) {
|
|
daysRemaining = nearestExpireDate.difference(now).inDays;
|
|
if (daysRemaining < 0) daysRemaining = 0;
|
|
// 假设总有效期为730天
|
|
progress = daysRemaining / 730;
|
|
if (progress > 1) progress = 1;
|
|
if (progress < 0) progress = 0;
|
|
expireDateText = '您的贡献值将于 ${DateFormat('yyyy-MM-dd').format(nearestExpireDate)} 失效';
|
|
}
|
|
|
|
final showShimmer = isLoading || isRecordsLoading;
|
|
|
|
return Container(
|
|
padding: const EdgeInsets.all(20),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// 标题
|
|
const Row(
|
|
children: [
|
|
Icon(Icons.timer_outlined, color: _orange, size: 24),
|
|
SizedBox(width: 8),
|
|
Text(
|
|
'贡献值失效倒计时',
|
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: _darkText),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 12),
|
|
// 进度条
|
|
ClipRRect(
|
|
borderRadius: BorderRadius.circular(5),
|
|
child: LinearProgressIndicator(
|
|
value: showShimmer ? 1.0 : progress,
|
|
minHeight: 10,
|
|
backgroundColor: _bgGray,
|
|
valueColor: AlwaysStoppedAnimation<Color>(
|
|
showShimmer ? _bgGray : _orange,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
// 说明文字
|
|
showShimmer
|
|
? const ShimmerText(
|
|
placeholder: '您的贡献值将于 ---- 失效',
|
|
style: TextStyle(fontSize: 12, color: _grayText),
|
|
)
|
|
: Text(
|
|
expireDateText,
|
|
style: const TextStyle(fontSize: 12, color: _grayText),
|
|
),
|
|
const SizedBox(height: 4),
|
|
showShimmer
|
|
? const ShimmerText(
|
|
placeholder: '剩余 --- 天',
|
|
style: TextStyle(fontSize: 12, color: _orange, fontWeight: FontWeight.w500),
|
|
)
|
|
: Text(
|
|
'剩余 $daysRemaining 天',
|
|
style: const TextStyle(fontSize: 12, color: _orange, fontWeight: FontWeight.w500),
|
|
),
|
|
const SizedBox(height: 8),
|
|
// 提示
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
|
decoration: BoxDecoration(
|
|
color: _bgGray,
|
|
borderRadius: BorderRadius.circular(4),
|
|
),
|
|
child: const Text(
|
|
'* 运营账号贡献值永不失效',
|
|
style: TextStyle(fontSize: 10, color: _orange),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|