111
This commit is contained in:
@@ -13,7 +13,7 @@ import 'components/records_link_row.dart';
|
||||
import '../orders/fund_orders_page.dart';
|
||||
import 'transfer_page.dart';
|
||||
|
||||
/// 资产页面 - Matching .pen design spec (CMcqs)
|
||||
/// 資產頁面 - Matching .pen design spec (CMcqs)
|
||||
class AssetPage extends StatefulWidget {
|
||||
const AssetPage({super.key});
|
||||
|
||||
@@ -78,24 +78,24 @@ class _AssetPageState extends State<AssetPage> with AutomaticKeepAliveClientMixi
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16, bottom: 8),
|
||||
child: Text(
|
||||
'资产',
|
||||
'資產',
|
||||
style: AppTextStyles.displaySmall(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
// 资金账户 + 交易账户 左右并排
|
||||
// 資金賬戶 + 交易賬戶 左右並排
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: BalanceCard(
|
||||
label: '资金账户',
|
||||
label: '資金賬戶',
|
||||
balance: provider.fundAccount?.balance ?? provider.overview?.fundBalance ?? '0.00',
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Expanded(
|
||||
child: BalanceCard(
|
||||
label: '交易账户',
|
||||
label: '交易賬戶',
|
||||
balance: _calculateTradeTotal(provider),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,7 +3,7 @@ import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
|
||||
/// 账户标签切换器 — .pen node UE6xC
|
||||
/// 賬戶標籤切換器 — .pen node UE6xC
|
||||
/// height: 40, padding: 3, cornerRadius: md, fill: $bg-tertiary
|
||||
/// activeTab: fill $bg-primary, cornerRadius sm, shadow blur 3, color #0000000D, offset y 1
|
||||
/// activeTabText: 14px, fontWeight 600, fill $text-primary
|
||||
@@ -31,13 +31,13 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
children: [
|
||||
_buildTab(
|
||||
context: context,
|
||||
label: '资金账户',
|
||||
label: '資金賬戶',
|
||||
isSelected: selectedIndex == 0,
|
||||
onTap: () => onChanged(0),
|
||||
),
|
||||
_buildTab(
|
||||
context: context,
|
||||
label: '交易账户',
|
||||
label: '交易賬戶',
|
||||
isSelected: selectedIndex == 1,
|
||||
onTap: () => onChanged(1),
|
||||
),
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_theme_extension.dart';
|
||||
|
||||
/// 操作按钮行 — .pen node pIpHe
|
||||
/// 操作按鈕行 — .pen node pIpHe
|
||||
/// gap: 12, three buttons evenly distributed
|
||||
/// Each button: circle 48x48 fill $bg-tertiary, cornerRadius 24
|
||||
/// icon: 20px $accent-primary (lucide: arrow-up-right / arrow-down-left / repeat)
|
||||
@@ -38,7 +38,7 @@ class ActionButtonsRow extends StatelessWidget {
|
||||
const SizedBox(width: 12),
|
||||
ActionButton(
|
||||
icon: LucideIcons.arrowDownLeft,
|
||||
label: '提现',
|
||||
label: '提現',
|
||||
accentColor: accentColor,
|
||||
bgColor: bgColor,
|
||||
onTap: onWithdraw,
|
||||
@@ -46,7 +46,7 @@ class ActionButtonsRow extends StatelessWidget {
|
||||
const SizedBox(width: 12),
|
||||
ActionButton(
|
||||
icon: LucideIcons.repeat,
|
||||
label: '划转',
|
||||
label: '劃轉',
|
||||
accentColor: accentColor,
|
||||
bgColor: bgColor,
|
||||
onTap: onTransfer,
|
||||
@@ -56,7 +56,7 @@ class ActionButtonsRow extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// 单个操作按钮 — matching .pen btn1/btn2/btn3
|
||||
/// 單個操作按鈕 — matching .pen btn1/btn2/btn3
|
||||
class ActionButton extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final String label;
|
||||
|
||||
@@ -17,7 +17,7 @@ import '../../../shared/ui_constants.dart';
|
||||
// Dialog helpers — shared sub-widgets
|
||||
// ============================================
|
||||
|
||||
/// 信息行 — 用于对话框中显示 label/value 键值对
|
||||
/// 信息行 — 用於對話框中顯示 label/value 鍵值對
|
||||
class InfoRow extends StatelessWidget {
|
||||
final String label;
|
||||
final String value;
|
||||
@@ -54,7 +54,7 @@ class InfoRow extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// 钱包地址卡片 — 用于充值结果对话框中展示钱包地址
|
||||
/// 錢包地址卡片 — 用於充值結果對話框中展示錢包地址
|
||||
class WalletAddressCard extends StatelessWidget {
|
||||
final String address;
|
||||
final String network;
|
||||
@@ -94,7 +94,7 @@ class WalletAddressCard extends StatelessWidget {
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(text: address));
|
||||
ToastUtils.show('地址已复制到剪贴板');
|
||||
ToastUtils.show('地址已複製到剪貼板');
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(AppSpacing.xs),
|
||||
@@ -113,7 +113,7 @@ class WalletAddressCard extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
'网络: $network',
|
||||
'網絡: $network',
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
@@ -126,7 +126,7 @@ class WalletAddressCard extends StatelessWidget {
|
||||
// Dialog functions — kept from original with style updates
|
||||
// ============================================
|
||||
|
||||
/// 充值对话框
|
||||
/// 充值對話框
|
||||
void showDepositDialog(BuildContext context) {
|
||||
final amountController = TextEditingController();
|
||||
final formKey = GlobalKey<ShadFormState>();
|
||||
@@ -183,14 +183,14 @@ void showDepositDialog(BuildContext context) {
|
||||
child: ShadInputFormField(
|
||||
id: 'amount',
|
||||
controller: amountController,
|
||||
label: const Text('充值金额'),
|
||||
label: const Text('充值金額'),
|
||||
placeholder: const Text('最低 1000 USDT'),
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||||
validator: (v) {
|
||||
if (v == null || v.isEmpty) return '请输入金额';
|
||||
if (v == null || v.isEmpty) return '請輸入金額';
|
||||
final n = double.tryParse(v);
|
||||
if (n == null || n <= 0) return '请输入有效金额';
|
||||
if (n < 1000) return '单笔最低充值1000 USDT';
|
||||
if (n == null || n <= 0) return '請輸入有效金額';
|
||||
if (n < 1000) return '單筆最低充值1000 USDT';
|
||||
return null;
|
||||
},
|
||||
),
|
||||
@@ -222,7 +222,7 @@ void showDepositDialog(BuildContext context) {
|
||||
if (response.success && response.data != null) {
|
||||
showDepositResultDialog(context, response.data!);
|
||||
} else {
|
||||
showResultDialog(context, '申请失败', response.message);
|
||||
showResultDialog(context, '申請失敗', response.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,7 +240,7 @@ void showDepositDialog(BuildContext context) {
|
||||
);
|
||||
}
|
||||
|
||||
/// 充值结果对话框 — 展示钱包地址和确认打款
|
||||
/// 充值結果對話框 — 展示錢包地址和確認打款
|
||||
void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
final orderNo = data['orderNo'] as String? ?? '';
|
||||
final amount = data['amount']?.toString() ?? '0.00';
|
||||
@@ -268,7 +268,7 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'充值申请成功',
|
||||
'充值申請成功',
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
@@ -276,12 +276,12 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
InfoRow(label: '订单号', value: orderNo),
|
||||
InfoRow(label: '訂單號', value: orderNo),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
InfoRow(label: '充值金额', value: '$amount USDT', isBold: true),
|
||||
InfoRow(label: '充值金額', value: '$amount USDT', isBold: true),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
Text(
|
||||
'请向以下地址转账:',
|
||||
'請向以下地址轉賬:',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -304,7 +304,7 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'转账完成后请点击"已打款"按钮确认',
|
||||
'轉賬完成後請點擊"已打款"按鈕確認',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: AppColorScheme.warning,
|
||||
),
|
||||
@@ -318,7 +318,7 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
children: [
|
||||
Expanded(
|
||||
child: NeonButton(
|
||||
text: '稍后确认',
|
||||
text: '稍後確認',
|
||||
type: NeonButtonType.outline,
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
height: 44,
|
||||
@@ -336,8 +336,8 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
if (context.mounted) {
|
||||
showResultDialog(
|
||||
context,
|
||||
response.success ? '确认成功' : '确认失败',
|
||||
response.success ? '请等待管理员审核' : response.message,
|
||||
response.success ? '確認成功' : '確認失敗',
|
||||
response.success ? '請等待管理員審核' : response.message,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -354,13 +354,13 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
);
|
||||
}
|
||||
|
||||
/// 提现对话框
|
||||
/// 提現對話框
|
||||
void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
final amountController = TextEditingController();
|
||||
final addressController = TextEditingController();
|
||||
final contactController = TextEditingController();
|
||||
final formKey = GlobalKey<ShadFormState>();
|
||||
final feeNotifier = ValueNotifier<String>('提现将扣除10%手续费');
|
||||
final feeNotifier = ValueNotifier<String>('提現將扣除10%手續費');
|
||||
final networksNotifier = ValueNotifier<List<String>>([]);
|
||||
final selectedNetworkNotifier = ValueNotifier<String?>(null);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
@@ -370,13 +370,13 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
if (amount > 0) {
|
||||
final fee = amount * 0.1;
|
||||
final receivable = amount - fee;
|
||||
feeNotifier.value = '手续费(10%): -${fee.toStringAsFixed(2)} USDT | 应收款: ${receivable.toStringAsFixed(2)} USDT';
|
||||
feeNotifier.value = '手續費(10%): -${fee.toStringAsFixed(2)} USDT | 應收款: ${receivable.toStringAsFixed(2)} USDT';
|
||||
} else {
|
||||
feeNotifier.value = '提现将扣除10%手续费';
|
||||
feeNotifier.value = '提現將扣除10%手續費';
|
||||
}
|
||||
});
|
||||
|
||||
// 获取网络列表
|
||||
// 獲取網絡列表
|
||||
context.read<AssetProvider>().getWalletNetworks().then((list) {
|
||||
networksNotifier.value = list;
|
||||
if (list.isNotEmpty) {
|
||||
@@ -411,7 +411,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'提现',
|
||||
'提現',
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
@@ -420,7 +420,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
'安全地将您的资产转移到外部钱包地址',
|
||||
'安全地將您的資產轉移到外部錢包地址',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -443,7 +443,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'可用余额: ',
|
||||
'可用餘額: ',
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -467,13 +467,13 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
ShadInputFormField(
|
||||
id: 'amount',
|
||||
controller: amountController,
|
||||
label: const Text('提现金额'),
|
||||
placeholder: const Text('请输入提现金额(USDT)'),
|
||||
label: const Text('提現金額'),
|
||||
placeholder: const Text('請輸入提現金額(USDT)'),
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||||
validator: Validators.amount,
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
// 手续费/应收款提示
|
||||
// 手續費/應收款提示
|
||||
ValueListenableBuilder<String>(
|
||||
valueListenable: feeNotifier,
|
||||
builder: (_, feeText, __) {
|
||||
@@ -501,7 +501,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
},
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
// 提现网络选择
|
||||
// 提現網絡選擇
|
||||
ValueListenableBuilder<List<String>>(
|
||||
valueListenable: networksNotifier,
|
||||
builder: (_, networks, __) {
|
||||
@@ -509,7 +509,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('提现网络', style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
Text('提現網絡', style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
)),
|
||||
const SizedBox(height: AppSpacing.xs),
|
||||
@@ -517,7 +517,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
valueListenable: selectedNetworkNotifier,
|
||||
builder: (_, selected, __) {
|
||||
return ShadSelect<String>(
|
||||
placeholder: const Text('选择提现网络'),
|
||||
placeholder: const Text('選擇提現網絡'),
|
||||
initialValue: selected,
|
||||
selectedOptionBuilder: (context, val) => Text(val),
|
||||
onChanged: (value) {
|
||||
@@ -535,16 +535,16 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
ShadInputFormField(
|
||||
id: 'address',
|
||||
controller: addressController,
|
||||
label: const Text('目标地址'),
|
||||
placeholder: const Text('请输入提现地址'),
|
||||
validator: (v) => Validators.required(v, '提现地址'),
|
||||
label: const Text('目標地址'),
|
||||
placeholder: const Text('請輸入提現地址'),
|
||||
validator: (v) => Validators.required(v, '提現地址'),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
ShadInputFormField(
|
||||
id: 'contact',
|
||||
controller: contactController,
|
||||
label: const Text('联系方式(可选)'),
|
||||
placeholder: const Text('联系方式'),
|
||||
label: const Text('聯繫方式(可選)'),
|
||||
placeholder: const Text('聯繫方式'),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -580,8 +580,8 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
if (context.mounted) {
|
||||
showResultDialog(
|
||||
context,
|
||||
response.success ? '申请成功' : '申请失败',
|
||||
response.success ? '请等待管理员审批' : response.message,
|
||||
response.success ? '申請成功' : '申請失敗',
|
||||
response.success ? '請等待管理員審批' : response.message,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -612,7 +612,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
);
|
||||
}
|
||||
|
||||
/// 通用结果对话框 — 展示操作成功/失败信息
|
||||
/// 通用結果對話框 — 展示操作成功/失敗信息
|
||||
void showResultDialog(BuildContext context, String title, String? message) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
@@ -646,7 +646,7 @@ void showResultDialog(BuildContext context, String title, String? message) {
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: NeonButton(
|
||||
text: '确定',
|
||||
text: '確定',
|
||||
type: NeonButtonType.primary,
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
height: 44,
|
||||
|
||||
@@ -4,7 +4,7 @@ import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
|
||||
/// 余额卡片 — 显示单个账户的 USDT 余额
|
||||
/// 餘額卡片 — 顯示單個賬戶的 USDT 餘額
|
||||
class BalanceCard extends StatelessWidget {
|
||||
final String label;
|
||||
final String balance;
|
||||
@@ -20,7 +20,7 @@ class BalanceCard extends StatelessWidget {
|
||||
final displayBalance = balance;
|
||||
|
||||
return SizedBox(
|
||||
width: double.infinity, // 确保卡片撑满宽度
|
||||
width: double.infinity, // 確保卡片撐滿寬度
|
||||
child: GlassPanel(
|
||||
padding: const EdgeInsets.all(20),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
|
||||
@@ -5,8 +5,8 @@ import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../data/models/account_models.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
|
||||
/// 持仓区域
|
||||
/// Header: "我的资产" + "查看全部 >"
|
||||
/// 持倉區域
|
||||
/// Header: "我的資產" + "查看全部 >"
|
||||
/// Holdings Card: cornerRadius lg, fill $surface-card, stroke $border-default 1px
|
||||
class HoldingsSection extends StatelessWidget {
|
||||
final List holdings;
|
||||
@@ -19,14 +19,14 @@ class HoldingsSection extends StatelessWidget {
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
// Header row: "我的资产" + "查看全部 >"
|
||||
// Header row: "我的資產" + "查看全部 >"
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: AppSpacing.sm),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'我的资产',
|
||||
'我的資產',
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
Text(
|
||||
@@ -44,7 +44,7 @@ class HoldingsSection extends StatelessWidget {
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||
child: Text(
|
||||
'暂无持仓',
|
||||
'暫無持倉',
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -78,7 +78,7 @@ class HoldingsSection extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// 持仓行分隔线 — .pen node BCCbR / yejhE
|
||||
/// 持倉行分隔線 — .pen node BCCbR / yejhE
|
||||
/// fill: $border-default, height: 1, opacity: 0.5
|
||||
class HoldingDivider extends StatelessWidget {
|
||||
const HoldingDivider({super.key});
|
||||
@@ -94,7 +94,7 @@ class HoldingDivider extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// 持仓行 — matching .pen nodes dAt4j / eK6vq / jiSUK
|
||||
/// 持倉行 — matching .pen nodes dAt4j / eK6vq / jiSUK
|
||||
/// padding [14, 16], space_between layout
|
||||
/// Left: avatar circle (36x36, radius 18, fill $accent-light) + coin info (gap 2)
|
||||
/// Right: value + pnl (gap 2, align end)
|
||||
|
||||
@@ -5,7 +5,7 @@ import '../../../../core/theme/app_theme_extension.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
|
||||
/// 订单记录链接行
|
||||
/// 訂單記錄鏈接行
|
||||
/// cornerRadius: lg, fill: $surface-card, padding: [14, 16], stroke: $border-default 1px
|
||||
class RecordsLinkRow extends StatelessWidget {
|
||||
final VoidCallback onTap;
|
||||
@@ -25,7 +25,7 @@ class RecordsLinkRow extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'订单记录',
|
||||
'訂單記錄',
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
|
||||
@@ -8,7 +8,7 @@ import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../data/models/account_models.dart';
|
||||
|
||||
/// 划转页面
|
||||
/// 劃轉頁面
|
||||
class TransferPage extends StatefulWidget {
|
||||
const TransferPage({super.key});
|
||||
|
||||
@@ -19,7 +19,7 @@ class TransferPage extends StatefulWidget {
|
||||
class _TransferPageState extends State<TransferPage> {
|
||||
final _amountController = TextEditingController();
|
||||
final _focusNode = FocusNode();
|
||||
int _direction = 1; // 1: 资金→交易, 2: 交易→资金
|
||||
int _direction = 1; // 1: 資金→交易, 2: 交易→資金
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
@@ -38,26 +38,26 @@ class _TransferPageState extends State<TransferPage> {
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 数据访问
|
||||
// 數據訪問
|
||||
// ============================================
|
||||
|
||||
/// 获取资金账户余额(安全检查)
|
||||
/// 獲取資金賬戶餘額(安全檢查)
|
||||
String get _fundBalance {
|
||||
try {
|
||||
final provider = context.read<AssetProvider>();
|
||||
final balance = provider.fundAccount?.balance ?? provider.overview?.fundBalance ?? '0.00';
|
||||
// 确保返回的是有效的数字格式
|
||||
// 確保返回的是有效的數字格式
|
||||
return _formatBalance(balance);
|
||||
} catch (e) {
|
||||
return '0.00';
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取交易账户 USDT 余额(安全检查)
|
||||
/// 獲取交易賬戶 USDT 餘額(安全檢查)
|
||||
String get _tradeUsdtBalance {
|
||||
try {
|
||||
final provider = context.read<AssetProvider>();
|
||||
// 先检查列表是否为空
|
||||
// 先檢查列表是否為空
|
||||
if (provider.tradeAccounts.isEmpty) {
|
||||
return '0.00';
|
||||
}
|
||||
@@ -81,32 +81,32 @@ class _TransferPageState extends State<TransferPage> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取当前可用余额(根据方向)
|
||||
/// 獲取當前可用餘額(根據方向)
|
||||
String get _availableBalance => _direction == 1 ? _fundBalance : _tradeUsdtBalance;
|
||||
|
||||
/// 从账户名
|
||||
String get _fromLabel => _direction == 1 ? '资金账户' : '交易账户';
|
||||
String get _toLabel => _direction == 1 ? '交易账户' : '资金账户';
|
||||
/// 從賬戶名
|
||||
String get _fromLabel => _direction == 1 ? '資金賬戶' : '交易賬戶';
|
||||
String get _toLabel => _direction == 1 ? '交易賬戶' : '資金賬戶';
|
||||
String get _fromBalance => _direction == 1 ? _fundBalance : _tradeUsdtBalance;
|
||||
String get _toBalance => _direction == 1 ? _tradeUsdtBalance : _fundBalance;
|
||||
|
||||
// ============================================
|
||||
// 业务逻辑
|
||||
// 業務邏輯
|
||||
// ============================================
|
||||
|
||||
/// 执行划转
|
||||
/// 執行劃轉
|
||||
Future<void> _doTransfer() async {
|
||||
final amount = _amountController.text;
|
||||
final available = double.tryParse(_availableBalance) ?? 0;
|
||||
final transferAmount = double.tryParse(amount) ?? 0;
|
||||
|
||||
if (transferAmount <= 0) {
|
||||
_showSnackBar('请输入有效的划转金额');
|
||||
_showSnackBar('請輸入有效的劃轉金額');
|
||||
return;
|
||||
}
|
||||
|
||||
if (transferAmount > available) {
|
||||
_showSnackBar('余额不足');
|
||||
_showSnackBar('餘額不足');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -121,10 +121,10 @@ class _TransferPageState extends State<TransferPage> {
|
||||
if (mounted) {
|
||||
if (response.success) {
|
||||
_amountController.clear();
|
||||
_showSnackBar('划转成功');
|
||||
_showSnackBar('劃轉成功');
|
||||
Navigator.of(context).pop(true);
|
||||
} else {
|
||||
_showSnackBar(response.message ?? '划转失败');
|
||||
_showSnackBar(response.message ?? '劃轉失敗');
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -140,14 +140,14 @@ class _TransferPageState extends State<TransferPage> {
|
||||
);
|
||||
}
|
||||
|
||||
/// 设置快捷百分比金额
|
||||
/// 設置快捷百分比金額
|
||||
void _setQuickAmount(double percent) {
|
||||
final available = double.tryParse(_availableBalance) ?? 0;
|
||||
final amount = available * percent;
|
||||
_amountController.text = amount.toStringAsFixed(8).replaceAll(RegExp(r'\.?0+$'), '');
|
||||
}
|
||||
|
||||
/// 切换方向
|
||||
/// 切換方向
|
||||
void _toggleDirection() {
|
||||
setState(() {
|
||||
_direction = _direction == 1 ? 2 : 1;
|
||||
@@ -155,7 +155,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 构建 UI
|
||||
// 構建 UI
|
||||
// ============================================
|
||||
|
||||
@override
|
||||
@@ -173,7 +173,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
title: Text(
|
||||
'账户划转',
|
||||
'賬戶劃轉',
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
centerTitle: true,
|
||||
@@ -205,7 +205,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
|
||||
Widget _buildTransferDirectionCard() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
// 金色主题感知: Dark #D4AF37 (primary), Light #F59E0B (secondary)
|
||||
// 金色主題感知: Dark #D4AF37 (primary), Light #F59E0B (secondary)
|
||||
final goldAccent = colorScheme.brightness == Brightness.dark
|
||||
? colorScheme.primary
|
||||
: colorScheme.secondary;
|
||||
@@ -225,7 +225,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
key: 'src-$_direction',
|
||||
beginOffset: const Offset(0, -1),
|
||||
child: _buildAccountRow(
|
||||
label: '从',
|
||||
label: '從',
|
||||
accountName: _fromLabel,
|
||||
balance: _fromBalance,
|
||||
),
|
||||
@@ -239,7 +239,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
height: 40,
|
||||
margin: const EdgeInsets.symmetric(vertical: AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
// 椭圆形半透明金色背景
|
||||
// 橢圓形半透明金色背景
|
||||
color: goldAccent.withValues(alpha: 0.15),
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
@@ -272,7 +272,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
);
|
||||
}
|
||||
|
||||
/// 统一的 AnimatedSwitcher 构造
|
||||
/// 統一的 AnimatedSwitcher 構造
|
||||
Widget _animatedSwitcher({
|
||||
required String key,
|
||||
required Offset beginOffset,
|
||||
@@ -313,7 +313,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
label == '从' ? LucideIcons.wallet : LucideIcons.trendingUp,
|
||||
label == '從' ? LucideIcons.wallet : LucideIcons.trendingUp,
|
||||
size: 18,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
@@ -342,14 +342,14 @@ class _TransferPageState extends State<TransferPage> {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Label row: "划转金额" + "全部划转"
|
||||
// Label row: "劃轉金額" + "全部劃轉"
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('划转金额', style: AppTextStyles.headlineSmall(context).copyWith(color: colorScheme.onSurfaceVariant)),
|
||||
Text('劃轉金額', style: AppTextStyles.headlineSmall(context).copyWith(color: colorScheme.onSurfaceVariant)),
|
||||
GestureDetector(
|
||||
onTap: () => _setQuickAmount(1.0),
|
||||
child: Text('全部划转', style: AppTextStyles.labelLarge(context).copyWith(
|
||||
child: Text('全部劃轉', style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.secondary,
|
||||
fontWeight: FontWeight.w600,
|
||||
)),
|
||||
@@ -461,7 +461,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'划转即时到账,无需手续费',
|
||||
'劃轉即時到賬,無需手續費',
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(color: upColor),
|
||||
),
|
||||
),
|
||||
@@ -472,7 +472,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
|
||||
Widget _buildConfirmButton() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
// 金色主题感知: Dark #D4AF37 (primary), Light #F59E0B (secondary)
|
||||
// 金色主題感知: Dark #D4AF37 (primary), Light #F59E0B (secondary)
|
||||
final goldAccent = colorScheme.brightness == Brightness.dark
|
||||
? colorScheme.primary
|
||||
: colorScheme.secondary;
|
||||
@@ -498,7 +498,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
),
|
||||
)
|
||||
: const Text(
|
||||
'确认划转',
|
||||
'確認劃轉',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
|
||||
Reference in New Issue
Block a user