feat(frontend): 多项功能改进

- 将所有 USDT 文本替换为 积分
- 监控页面:将"挖矿待开启"改为"开启监控",开启时显示关闭按钮
- 我的伞下:树图默认居中显示
- 树图节点:长按查看详情(序列号、认种数、直推人数)
- 分享页面:显示推荐码并支持复制

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-15 04:04:21 -08:00
parent 8d68b292c8
commit 6dd7e64a95
13 changed files with 456 additions and 212 deletions

View File

@ -214,7 +214,7 @@ export default function AuthorizationPage() {
/>
</div>
<div className={styles.authorization__formGroup}>
<label className={styles.authorization__formLabel}>USDT</label>
<label className={styles.authorization__formLabel}></label>
<input
className={styles.authorization__formInput}
type="text"
@ -227,7 +227,7 @@ export default function AuthorizationPage() {
</div>
<div className={styles.authorization__formRow}>
<div className={styles.authorization__formGroup}>
<label className={styles.authorization__formLabel}> 1 USDT</label>
<label className={styles.authorization__formLabel}> 1 </label>
<input
className={styles.authorization__formInput}
type="text"
@ -296,7 +296,7 @@ export default function AuthorizationPage() {
/>
</div>
<div className={styles.authorization__formGroup}>
<label className={styles.authorization__formLabel}>USDT</label>
<label className={styles.authorization__formLabel}></label>
<input
className={styles.authorization__formInput}
type="text"
@ -309,7 +309,7 @@ export default function AuthorizationPage() {
</div>
<div className={styles.authorization__formRow}>
<div className={styles.authorization__formGroup}>
<label className={styles.authorization__formLabel}> 1 USDT</label>
<label className={styles.authorization__formLabel}> 1 </label>
<input
className={styles.authorization__formInput}
type="text"

View File

@ -58,7 +58,7 @@ const mockTargets: AssessmentTarget[] = [
export default function SettingsPage() {
// 结算参数设置
const [settlementCurrencies, setSettlementCurrencies] = useState<string[]>(['BNB', 'USDT']);
const [settlementCurrencies, setSettlementCurrencies] = useState<string[]>(['BNB', '积分']);
const [defaultCurrency, setDefaultCurrency] = useState('');
// 龙虎榜设置
@ -144,7 +144,7 @@ export default function SettingsPage() {
<div className={styles.settings__fieldGroup}>
<label className={styles.settings__label}></label>
<div className={styles.settings__checkboxGroup}>
{['BNB', 'OG', 'USDT', 'DST'].map(currency => (
{['BNB', 'OG', '积分', 'DST'].map(currency => (
<label key={currency} className={styles.settings__checkboxItem}>
<input
type="checkbox"

View File

@ -56,7 +56,7 @@ export const ASSESSMENT_CYCLE_LABELS: Record<string, string> = {
};
// 结算货币
export const CURRENCIES = ['BNB', 'OG', 'USDT', 'DST'] as const;
export const CURRENCIES = ['BNB', 'OG', '积分', 'DST'] as const;
// 龙虎榜类型
export const LEADERBOARD_TYPES = {

View File

@ -25,7 +25,7 @@ export function formatCurrency(amount: number, currency = 'CNY'): string {
const symbols: Record<string, string> = {
CNY: '¥',
USD: '$',
USDT: 'USDT ',
USDT: '积分 ',
BTC: 'BTC ',
};
const symbol = symbols[currency] || '';

View File

@ -238,7 +238,7 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
//
const Expanded(
child: Text(
'充值 USDT',
'充值 积分',
style: TextStyle(
fontSize: 18,
fontFamily: 'Inter',
@ -263,7 +263,7 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(
'可用余额: $_balance USDT',
'可用余额: $_balance 积分',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
@ -577,7 +577,7 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
return Container(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 48),
child: Text(
'仅支持 USDT,错充将无法追回',
'仅支持 积分,错充将无法追回',
style: TextStyle(
fontSize: 12,
fontFamily: 'Inter',

View File

@ -4,15 +4,14 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import '../../../../core/di/injection_container.dart';
///
enum MiningStatus {
///
enum MonitorStatus {
pending, //
mining, //
paused, //
active, //
}
/// -
///
/// -
///
class MiningPage extends ConsumerStatefulWidget {
const MiningPage({super.key});
@ -21,8 +20,8 @@ class MiningPage extends ConsumerStatefulWidget {
}
class _MiningPageState extends ConsumerState<MiningPage> {
//
MiningStatus _miningStatus = MiningStatus.pending;
//
MonitorStatus _monitorStatus = MonitorStatus.pending;
//
String _serialNumber = '--';
@ -131,9 +130,9 @@ class _MiningPageState extends ConsumerState<MiningPage> {
context: context,
builder: (context) => AlertDialog(
title: const Text('监控说明'),
content: const Text('监控是您查看挖矿状态的工具。\n\n'
'开启挖矿后,您将开始获得收益\n\n'
'收益与您的算力和团队规模相关'),
content: const Text('监控是您查看榴莲种植实况的工具。\n\n'
'开启监控后,您可以实时查看种植基地的视频流\n\n'
'目前功能正在开发中,敬请期待'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
@ -144,28 +143,29 @@ class _MiningPageState extends ConsumerState<MiningPage> {
);
}
///
void _toggleMining() {
///
void _startMonitor() {
setState(() {
if (_miningStatus == MiningStatus.pending) {
_miningStatus = MiningStatus.mining;
} else if (_miningStatus == MiningStatus.mining) {
_miningStatus = MiningStatus.paused;
} else {
_miningStatus = MiningStatus.mining;
}
_monitorStatus = MonitorStatus.active;
});
// TODO:
}
///
void _stopMonitor() {
setState(() {
_monitorStatus = MonitorStatus.pending;
});
// TODO:
}
///
String _getStatusText() {
switch (_miningStatus) {
case MiningStatus.pending:
return '挖矿待开启';
case MiningStatus.mining:
return '挖矿中';
case MiningStatus.paused:
return '挖矿已暂停';
switch (_monitorStatus) {
case MonitorStatus.pending:
return '开启监控';
case MonitorStatus.active:
return '监控中';
}
}
@ -212,24 +212,7 @@ class _MiningPageState extends ConsumerState<MiningPage> {
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
//
const SizedBox(width: 48),
//
const Expanded(
child: Text(
'监控',
style: TextStyle(
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w700,
height: 1.25,
letterSpacing: -0.27,
color: Color(0xFF5D4037),
),
textAlign: TextAlign.center,
),
),
//
//
GestureDetector(
onTap: _showHelpInfo,
child: Container(
@ -259,6 +242,38 @@ class _MiningPageState extends ConsumerState<MiningPage> {
),
),
),
//
const Expanded(
child: Text(
'监控',
style: TextStyle(
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w700,
height: 1.25,
letterSpacing: -0.27,
color: Color(0xFF5D4037),
),
textAlign: TextAlign.center,
),
),
//
if (_monitorStatus == MonitorStatus.active)
GestureDetector(
onTap: _stopMonitor,
child: Container(
width: 48,
height: 48,
alignment: Alignment.center,
child: const Icon(
Icons.close,
size: 24,
color: Color(0xFF8B5A2B),
),
),
)
else
const SizedBox(width: 48), //
],
),
);
@ -329,7 +344,7 @@ class _MiningPageState extends ConsumerState<MiningPage> {
);
}
///
///
Widget _buildMiningStatusArea() {
return Padding(
padding: const EdgeInsets.all(16),
@ -339,104 +354,119 @@ class _MiningPageState extends ConsumerState<MiningPage> {
color: const Color(0x66FFFFFF),
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//
GestureDetector(
onTap: _toggleMining,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _miningStatus == MiningStatus.mining
? const Color(0xFFD4AF37)
: Colors.transparent,
border: Border.all(
color: _miningStatus == MiningStatus.mining
? const Color(0xFFD4AF37)
: const Color(0xFFD4AF37).withOpacity(0.5),
width: 3,
),
),
child: Icon(
Icons.power_settings_new,
size: 48,
color: _miningStatus == MiningStatus.mining
? Colors.white
: const Color(0xFFD4AF37).withOpacity(0.5),
),
),
),
const SizedBox(height: 16),
//
Text(
_getStatusText(),
style: const TextStyle(
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w500,
height: 1.56,
color: Color(0xFF8B5A2B),
),
),
//
if (_miningStatus == MiningStatus.mining) ...[
const SizedBox(height: 24),
_buildMiningStats(),
],
],
),
child: _monitorStatus == MonitorStatus.active
? _buildMonitorActiveView()
: _buildMonitorPendingView(),
),
);
}
///
Widget _buildMiningStats() {
return Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: const Color(0x33D4AF37),
borderRadius: BorderRadius.circular(8),
),
child: Column(
children: [
_buildStatRow('个人算力', '100 H/s'),
const SizedBox(height: 8),
_buildStatRow('团队算力', '1,000 H/s'),
const SizedBox(height: 8),
_buildStatRow('今日收益', '0.00 DST'),
const SizedBox(height: 8),
_buildStatRow('累计收益', '0.00 DST'),
],
),
);
}
///
Widget _buildStatRow(String label, String value) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
///
Widget _buildMonitorPendingView() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//
GestureDetector(
onTap: _startMonitor,
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent,
border: Border.all(
color: const Color(0xFFD4AF37).withOpacity(0.5),
width: 3,
),
),
child: Icon(
Icons.videocam_outlined,
size: 48,
color: const Color(0xFFD4AF37).withOpacity(0.5),
),
),
),
const SizedBox(height: 16),
//
Text(
label,
_getStatusText(),
style: const TextStyle(
fontSize: 14,
fontSize: 18,
fontFamily: 'Inter',
height: 1.5,
fontWeight: FontWeight.w500,
height: 1.56,
color: Color(0xFF8B5A2B),
),
),
Text(
value,
style: const TextStyle(
const SizedBox(height: 8),
const Text(
'点击开启实时监控',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
height: 1.5,
color: Color(0xFF5D4037),
color: Color(0x998B5A2B),
),
),
],
);
}
///
Widget _buildMonitorActiveView() {
return Column(
children: [
//
Expanded(
child: Container(
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.circular(8),
),
child: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.videocam,
size: 64,
color: Color(0xFFD4AF37),
),
SizedBox(height: 16),
Text(
'监控中',
style: TextStyle(
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Color(0xFFD4AF37),
),
),
SizedBox(height: 8),
Text(
'视频流功能开发中...',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
color: Colors.white70,
),
),
],
),
),
),
),
//
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
'点击右上角 × 关闭监控',
style: TextStyle(
fontSize: 12,
fontFamily: 'Inter',
color: const Color(0xFF8B5A2B).withOpacity(0.6),
),
),
),
],

View File

@ -358,7 +358,7 @@ class _PlantingQuantityPageState extends ConsumerState<PlantingQuantityPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'可用余额 (USDT)',
'可用余额 (积分)',
style: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
@ -651,7 +651,7 @@ class _PlantingQuantityPageState extends ConsumerState<PlantingQuantityPage> {
children: [
//
Text(
'每棵价格:${_pricePerTree.toInt()} USDT',
'每棵价格:${_pricePerTree.toInt()} 积分',
style: const TextStyle(
fontSize: 16,
fontFamily: 'Inter',

View File

@ -628,7 +628,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
builder: (dialogContext) => AlertDialog(
title: const Text('确认领取'),
content: Text(
'确定领取全部收益吗?\nUSDT: ${_formatNumber(_pendingUsdt)}\n算力: ${_formatNumber(_pendingPower)}',
'确定领取全部收益吗?\n积分: ${_formatNumber(_pendingUsdt)}\n算力: ${_formatNumber(_pendingPower)}',
),
actions: [
TextButton(
@ -1230,10 +1230,10 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
//
_buildEarningsSection(),
const SizedBox(height: 16),
//
//
_buildSettlementSection(),
const SizedBox(height: 16),
//
//
_buildExpiredSection(),
const SizedBox(height: 16),
//
@ -1264,7 +1264,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
initialTarget: _authCityCompanyInitialTarget,
monthlyTarget: _authCityCompanyMonthlyTarget,
monthIndex: _authCityCompanyMonthIndex,
rewardDescription: '每新增认种 1 棵可获得 40 USDT',
rewardDescription: '每新增认种 1 棵可获得 40 积分',
),
],
//
@ -1278,7 +1278,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
initialTarget: _authProvinceCompanyInitialTarget,
monthlyTarget: _authProvinceCompanyMonthlyTarget,
monthIndex: _authProvinceCompanyMonthIndex,
rewardDescription: '每新增认种 1 棵可获得 20 USDT',
rewardDescription: '每新增认种 1 棵可获得 20 积分',
),
],
//
@ -1292,7 +1292,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
initialTarget: _cityCompanyInitialTarget,
monthlyTarget: _cityCompanyMonthlyTarget,
monthIndex: _cityCompanyMonthIndex,
rewardDescription: '每新增认种 1 棵可获得 35 USDT',
rewardDescription: '每新增认种 1 棵可获得 35 积分',
),
],
//
@ -1306,7 +1306,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
initialTarget: _provinceCompanyInitialTarget,
monthlyTarget: _provinceCompanyMonthlyTarget,
monthIndex: _provinceCompanyMonthIndex,
rewardDescription: '每新增认种 1 棵可获得 15 USDT',
rewardDescription: '每新增认种 1 棵可获得 15 积分',
),
],
const SizedBox(height: 16),
@ -1430,7 +1430,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'待领取 (USDT)',
'待领取 (积分)',
style: TextStyle(
fontSize: 12,
fontFamily: 'Inter',
@ -1516,13 +1516,13 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
//
final List<String> amountParts = [];
if (item.usdtAmount > 0) {
amountParts.add('${_formatNumber(item.usdtAmount)} USDT');
amountParts.add('${_formatNumber(item.usdtAmount)} 积分');
}
if (item.hashpowerAmount > 0) {
amountParts.add('${_formatNumber(item.hashpowerAmount)} 算力');
}
// 0
final amountText = amountParts.isNotEmpty ? amountParts.join(' ') : '0 USDT';
final amountText = amountParts.isNotEmpty ? amountParts.join(' ') : '0 积分';
return Container(
margin: const EdgeInsets.only(bottom: 8),
@ -1622,7 +1622,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'可结算 (USDT)',
'可结算 (积分)',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
@ -1649,7 +1649,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'已结算 (USDT)',
'已结算 (积分)',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
@ -1730,7 +1730,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'已过期 (USDT)',
'已过期 (积分)',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
@ -1800,7 +1800,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
),
child: const Center(
child: Text(
'充值 USDT (KAVA / BSC)',
'充值 积分 (KAVA / BSC)',
style: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
@ -1826,7 +1826,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
),
child: const Center(
child: Text(
'进入交易 (卖出 DST → USDT)',
'进入交易 (卖出 DST → 积分)',
style: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
@ -2356,7 +2356,7 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
Expanded(
child: Text(
_communityBenefitActive
? '每新增认种 1 棵可获得 80 USDT'
? '每新增认种 1 棵可获得 80 积分'
: '需团队认种达到 $_communityInitialTarget 棵激活',
style: TextStyle(
fontSize: 14,

View File

@ -81,10 +81,22 @@ class _TeamTreeWidgetState extends State<TeamTreeWidget> {
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SingleChildScrollView(
child: _buildTreeLevel([widget.rootNode], 0),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: screenWidth,
),
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: _buildTreeLevel([widget.rootNode], 0),
),
),
),
),
);
}
@ -174,6 +186,7 @@ class _TeamTreeWidgetState extends State<TeamTreeWidget> {
Widget _buildNodeBox(TeamTreeNode node) {
return GestureDetector(
onTap: () => _handleNodeTap(node),
onLongPress: () => _showNodeDetails(node),
child: Container(
width: nodeWidth,
height: nodeHeight,
@ -380,6 +393,26 @@ class _TeamTreeWidgetState extends State<TeamTreeWidget> {
}
}
///
void _showNodeDetails(TeamTreeNode node) {
showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (context) => _NodeDetailsSheet(
node: node,
onExpandTap: node.hasChildren
? () {
Navigator.pop(context);
_handleNodeTap(node);
}
: null,
),
);
}
///
void _showHiddenNodesSheet(List<TeamTreeNode> hiddenNodes) {
showModalBottomSheet(
@ -595,3 +628,120 @@ class _TreeLinePainter extends CustomPainter {
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
///
class _NodeDetailsSheet extends StatelessWidget {
final TeamTreeNode node;
final VoidCallback? onExpandTap;
const _NodeDetailsSheet({
required this.node,
this.onExpandTap,
});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'成员详情',
style: TextStyle(
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w700,
color: Color(0xFF5D4037),
),
),
GestureDetector(
onTap: () => Navigator.pop(context),
child: const Icon(
Icons.close,
color: Color(0xFF999999),
size: 24,
),
),
],
),
const SizedBox(height: 20),
//
_buildDetailRow('序列号', node.accountSequence),
const SizedBox(height: 12),
//
_buildDetailRow('个人认种', '${node.personalPlantingCount}'),
const SizedBox(height: 12),
//
_buildDetailRow('团队认种', '${node.teamPlantingCount}'),
const SizedBox(height: 12),
//
_buildDetailRow('直推人数', '${node.directReferralCount}'),
const SizedBox(height: 24),
//
if (onExpandTap != null)
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: onExpandTap,
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFD4AF37),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
node.isExpanded ? '收起下级' : '展开下级 (${node.directReferralCount}人)',
style: const TextStyle(
fontSize: 16,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
),
),
),
),
//
SizedBox(height: MediaQuery.of(context).padding.bottom + 8),
],
),
);
}
Widget _buildDetailRow(String label, String value) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: const TextStyle(
fontSize: 14,
fontFamily: 'Inter',
color: Color(0xFF8B5A2B),
),
),
Text(
value,
style: const TextStyle(
fontSize: 14,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Color(0xFF5D4037),
),
),
],
);
}
}

View File

@ -30,6 +30,8 @@ class _SharePageState extends ConsumerState<SharePage> {
bool _isLoading = true;
///
String? _errorMessage;
/// API
String? _referralCode;
@override
void initState() {
@ -57,8 +59,8 @@ class _SharePageState extends ConsumerState<SharePage> {
if (mounted) {
setState(() {
// 使 APK +
final referralCode = linkResponse.referralCode;
_displayLink = '$_apkDownloadUrl?ref=$referralCode';
_referralCode = linkResponse.referralCode;
_displayLink = '$_apkDownloadUrl?ref=$_referralCode';
_isLoading = false;
});
}
@ -69,6 +71,7 @@ class _SharePageState extends ConsumerState<SharePage> {
_isLoading = false;
// 使
if (widget.referralCode != null && widget.referralCode!.isNotEmpty) {
_referralCode = widget.referralCode;
_displayLink = '$_apkDownloadUrl?ref=${widget.referralCode}';
} else {
_displayLink = _apkDownloadUrl;
@ -193,44 +196,105 @@ class _SharePageState extends ConsumerState<SharePage> {
/// QR
Widget _buildQrCodeSection() {
return Container(
width: 256,
height: 256,
decoration: BoxDecoration(
color: const Color(0xFFFAF3E3),
borderRadius: BorderRadius.circular(24),
boxShadow: const [
BoxShadow(
color: Color(0x1A8C6A3E), // rgba(140, 106, 62, 0.1)
blurRadius: 30,
offset: Offset(0, 8),
return Column(
children: [
Container(
width: 256,
height: 256,
decoration: BoxDecoration(
color: const Color(0xFFFAF3E3),
borderRadius: BorderRadius.circular(24),
boxShadow: const [
BoxShadow(
color: Color(0x1A8C6A3E), // rgba(140, 106, 62, 0.1)
blurRadius: 30,
offset: Offset(0, 8),
),
],
),
child: Center(
child: _isLoading
? const CircularProgressIndicator(
color: Color(0xFFD4A84B),
strokeWidth: 2,
)
: QrImageView(
data: _displayLink,
version: QrVersions.auto,
size: 200,
backgroundColor: Colors.transparent,
eyeStyle: const QrEyeStyle(
eyeShape: QrEyeShape.square,
color: Color(0xFF8C6A3E),
),
dataModuleStyle: const QrDataModuleStyle(
dataModuleShape: QrDataModuleShape.square,
color: Color(0xFF8C6A3E),
),
),
),
),
//
if (_referralCode != null && _referralCode!.isNotEmpty) ...[
const SizedBox(height: 16),
Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
decoration: BoxDecoration(
color: const Color(0xFFF8F1E2),
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'我的推荐码:',
style: TextStyle(
fontSize: 14,
fontFamily: 'Segoe UI',
color: Color(0xFF8C6A3E),
),
),
Text(
_referralCode!,
style: const TextStyle(
fontSize: 16,
fontFamily: 'Segoe UI',
fontWeight: FontWeight.w700,
color: Color(0xFFD4A84B),
letterSpacing: 1,
),
),
const SizedBox(width: 8),
GestureDetector(
onTap: _copyReferralCode,
child: const Icon(
Icons.copy_outlined,
color: Color(0xFF8C6A3E),
size: 18,
),
),
],
),
),
],
),
child: Center(
child: _isLoading
? const CircularProgressIndicator(
color: Color(0xFFD4A84B),
strokeWidth: 2,
)
: QrImageView(
data: _displayLink,
version: QrVersions.auto,
size: 200,
backgroundColor: Colors.transparent,
eyeStyle: const QrEyeStyle(
eyeShape: QrEyeShape.square,
color: Color(0xFF8C6A3E),
),
dataModuleStyle: const QrDataModuleStyle(
dataModuleShape: QrDataModuleShape.square,
color: Color(0xFF8C6A3E),
),
),
),
],
);
}
///
void _copyReferralCode() {
if (_referralCode != null && _referralCode!.isNotEmpty) {
Clipboard.setData(ClipboardData(text: _referralCode!));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('推荐码已复制'),
backgroundColor: Color(0xFFD4A84B),
duration: Duration(seconds: 2),
),
);
}
}
///
Widget _buildLinkSection() {
return Padding(

View File

@ -93,7 +93,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
builder: (context) => AlertDialog(
title: const Text('确认结算'),
content: Text(
'确定将 ${_formatNumber(_settleableAmount)} USDT 结算为 ${_getCurrencyName(_selectedCurrency)} 吗?',
'确定将 ${_formatNumber(_settleableAmount)} 积分 结算为 ${_getCurrencyName(_selectedCurrency)} 吗?',
),
actions: [
TextButton(
@ -169,7 +169,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
builder: (context) => AlertDialog(
title: const Text('卖出 DST'),
content: Text(
'确定将 ${_formatNumber(_dstBalance)} DST 转换为 USDT 吗?',
'确定将 ${_formatNumber(_dstBalance)} DST 转换为 积分 吗?',
),
actions: [
TextButton(
@ -329,7 +329,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
),
)
: Text(
'${_formatNumber(_settleableAmount)} USDT',
'${_formatNumber(_settleableAmount)} 积分',
style: const TextStyle(
fontSize: 32,
fontFamily: 'Inter',
@ -409,7 +409,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
const SizedBox(width: 8),
_buildCurrencyChip(SettlementCurrency.og, 'OG'),
const SizedBox(width: 8),
_buildCurrencyChip(SettlementCurrency.usdt, 'USDT'),
_buildCurrencyChip(SettlementCurrency.usdt, '积分'),
const SizedBox(width: 8),
_buildCurrencyChip(SettlementCurrency.dst, 'DST'),
],
@ -480,7 +480,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
),
child: const Center(
child: Text(
'卖出 DST 转换为 USDT(暂未开放)',
'卖出 DST 转换为 积分(暂未开放)',
style: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
@ -590,7 +590,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
),
)
: Text(
'USDT 余额: ${_formatNumber(_usdtBalance)}',
'积分 余额: ${_formatNumber(_usdtBalance)}',
style: const TextStyle(
fontSize: 14,
fontFamily: 'Inter',

View File

@ -340,13 +340,13 @@ class _WithdrawConfirmPageState extends ConsumerState<WithdrawConfirmPage> {
const SizedBox(height: 12),
_buildDetailRow('提款地址', _formatAddress(widget.params.address)),
const SizedBox(height: 12),
_buildDetailRow('提款金额', '${widget.params.amount.toStringAsFixed(2)} USDT'),
_buildDetailRow('提款金额', '${widget.params.amount.toStringAsFixed(2)} 积分'),
const SizedBox(height: 12),
_buildDetailRow('手续费', '${fee.toStringAsFixed(2)} USDT'),
_buildDetailRow('手续费', '${fee.toStringAsFixed(2)} 积分'),
const Divider(color: Color(0x33D4AF37), height: 24),
_buildDetailRow(
'实际到账',
'${actual.toStringAsFixed(2)} USDT',
'${actual.toStringAsFixed(2)} 积分',
isHighlight: true,
),
],

View File

@ -154,7 +154,7 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
}
if (amount < _minAmount) {
_showErrorSnackBar('最小提款金额为 $_minAmount USDT');
_showErrorSnackBar('最小提款金额为 $_minAmount 积分');
return;
}
@ -365,7 +365,7 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
//
const Expanded(
child: Text(
'提款 USDT',
'提款 积分',
style: TextStyle(
fontSize: 18,
fontFamily: 'Inter',
@ -426,7 +426,7 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
const Padding(
padding: EdgeInsets.only(bottom: 4),
child: Text(
'USDT',
'积分',
style: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
@ -675,7 +675,7 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
height: 1.4,
color: Color(0x995D4037),
),
suffixText: 'USDT',
suffixText: '积分',
suffixStyle: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
@ -687,7 +687,7 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
),
const SizedBox(height: 8),
Text(
'最小提款金额: $_minAmount USDT',
'最小提款金额: $_minAmount 积分',
style: const TextStyle(
fontSize: 12,
fontFamily: 'Inter',
@ -718,11 +718,11 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
children: [
_buildFeeRow('手续费率', '${(_feeRate * 100).toStringAsFixed(1)}%'),
const SizedBox(height: 8),
_buildFeeRow('手续费', '${fee.toStringAsFixed(2)} USDT'),
_buildFeeRow('手续费', '${fee.toStringAsFixed(2)} 积分'),
const Divider(color: Color(0x33D4AF37), height: 24),
_buildFeeRow(
'预计到账',
'${actual > 0 ? actual.toStringAsFixed(2) : '0.00'} USDT',
'${actual > 0 ? actual.toStringAsFixed(2) : '0.00'} 积分',
isHighlight: true,
),
],