diff --git a/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart b/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart index 6206a609..fc2d462f 100644 --- a/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart +++ b/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart @@ -6,6 +6,7 @@ import '../../../core/router/routes.dart'; import '../../../core/utils/format_utils.dart'; import '../../../core/network/price_websocket_service.dart'; import '../../../core/constants/app_constants.dart'; +import '../../../core/constants/app_colors.dart'; import '../../../domain/entities/asset_display.dart'; import '../../providers/user_providers.dart'; import '../../providers/asset_providers.dart'; @@ -193,7 +194,7 @@ class _AssetPageState extends ConsumerState { } return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), + backgroundColor: AppColors.backgroundOf(context), body: SafeArea( bottom: false, child: LayoutBuilder( @@ -220,19 +221,19 @@ class _AssetPageState extends ConsumerState { children: [ const SizedBox(height: 8), // 总资产卡片 - 始终显示,数字部分闪烁,实时刷新 - _buildTotalAssetCard(asset, isLoading, _calculateTotalAssetValue(asset), _currentShareBalance, perSecondEarning), + _buildTotalAssetCard(context, asset, isLoading, _calculateTotalAssetValue(asset), _currentShareBalance, perSecondEarning), const SizedBox(height: 24), // 快捷操作按钮 _buildQuickActions(context), const SizedBox(height: 24), // 资产列表 - 始终显示,数字部分闪烁,实时刷新 - _buildAssetList(asset, isLoading, _currentShareBalance, perSecondEarning), + _buildAssetList(context, asset, isLoading, _currentShareBalance, perSecondEarning), const SizedBox(height: 24), // 交易统计 - _buildEarningsCard(asset, isLoading), + _buildEarningsCard(context, asset, isLoading), const SizedBox(height: 24), // 账户列表 - _buildAccountList(asset, isLoading), + _buildAccountList(context, asset, isLoading), const SizedBox(height: 24), ], ), @@ -250,24 +251,25 @@ class _AssetPageState extends ConsumerState { Widget _buildAppBar(BuildContext context, user) { return Container( - color: _bgGray.withOpacity(0.9), + color: AppColors.surfaceOf(context).withOpacity(0.9), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), - child: const Center( + child: Center( child: Text( '我的资产', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Color(0xFF111827), + color: AppColors.textPrimaryOf(context), ), ), ), ); } - Widget _buildTotalAssetCard(AssetDisplay? asset, bool isLoading, double totalAssetValue, double currentShareBalance, String perSecondEarning) { + Widget _buildTotalAssetCard(BuildContext context, AssetDisplay? asset, bool isLoading, double totalAssetValue, double currentShareBalance, String perSecondEarning) { // 使用传入的每秒增长值(来自 mining-service) final growthPerSecond = double.tryParse(perSecondEarning) ?? 0.0; + final isDark = AppColors.isDark(context); // 使用实时计算的总资产值(积分股价值 + 积分值余额) final displayValue = asset != null && totalAssetValue > 0 @@ -282,11 +284,11 @@ class _AssetPageState extends ConsumerState { return Container( decoration: BoxDecoration( - color: Colors.white, + color: AppColors.cardOf(context), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.04), + color: isDark ? Colors.black.withOpacity(0.3) : Colors.black.withOpacity(0.04), blurRadius: 30, offset: const Offset(0, 8), ), @@ -302,7 +304,7 @@ class _AssetPageState extends ConsumerState { width: 128, height: 128, decoration: BoxDecoration( - color: _serenade, + color: isDark ? _orange.withOpacity(0.1) : _serenade, borderRadius: BorderRadius.circular(64), ), ), @@ -334,18 +336,18 @@ class _AssetPageState extends ConsumerState { // 标题行 Row( children: [ - const Text( + Text( '总资产估值', style: TextStyle( fontSize: 14, - color: _grayText, + color: AppColors.textSecondaryOf(context), ), ), const SizedBox(width: 8), Icon( Icons.visibility_outlined, size: 14, - color: _grayText.withOpacity(0.5), + color: AppColors.textMutedOf(context), ), ], ), @@ -378,7 +380,7 @@ class _AssetPageState extends ConsumerState { Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( - color: _feta, + color: isDark ? _green.withOpacity(0.15) : _feta, borderRadius: BorderRadius.circular(8), ), child: Row( @@ -410,36 +412,45 @@ class _AssetPageState extends ConsumerState { } Widget _buildQuickActions(BuildContext context) { + final isDark = AppColors.isDark(context); return Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildQuickActionItem( + context, Icons.add, '接收', _orange, () => context.push(Routes.receiveShares), + isDark, ), _buildQuickActionItem( + context, Icons.remove, '发送', _orange, () => context.push(Routes.sendShares), + isDark, ), _buildQuickActionItem( + context, Icons.people_outline, 'C2C', _orange, () => context.push(Routes.c2cMarket), + isDark, ), ], ); } Widget _buildQuickActionItem( + BuildContext context, IconData icon, String label, Color color, VoidCallback onTap, + bool isDark, ) { return GestureDetector( onTap: onTap, @@ -450,7 +461,7 @@ class _AssetPageState extends ConsumerState { width: 48, height: 48, decoration: BoxDecoration( - color: _serenade, + color: isDark ? _orange.withOpacity(0.15) : _serenade, borderRadius: BorderRadius.circular(16), ), child: Icon(icon, color: color, size: 24), @@ -458,10 +469,10 @@ class _AssetPageState extends ConsumerState { const SizedBox(height: 8), Text( label, - style: const TextStyle( + style: TextStyle( fontSize: 12, fontWeight: FontWeight.w500, - color: _riverBed, + color: AppColors.textSecondaryOf(context), ), ), ], @@ -469,7 +480,7 @@ class _AssetPageState extends ConsumerState { ); } - Widget _buildAssetList(AssetDisplay? asset, bool isLoading, double currentShareBalance, String perSecondEarning) { + Widget _buildAssetList(BuildContext context, AssetDisplay? asset, bool isLoading, double currentShareBalance, String perSecondEarning) { // 使用实时积分股余额 final shareBalance = asset != null && currentShareBalance > 0 ? currentShareBalance @@ -477,14 +488,16 @@ class _AssetPageState extends ConsumerState { final multiplier = double.tryParse(asset?.burnMultiplier ?? '0') ?? 0; final multipliedAsset = shareBalance * multiplier; final currentPrice = double.tryParse(asset?.currentPrice ?? '0') ?? 0; + final isDark = AppColors.isDark(context); return Column( children: [ // 积分股 - 实时刷新 _buildAssetItem( + context: context, icon: Icons.trending_up, iconColor: _orange, - iconBgColor: _serenade, + iconBgColor: isDark ? _orange.withOpacity(0.15) : _serenade, title: '积分股', amount: asset != null ? shareBalance.toString() : null, isLoading: isLoading, @@ -497,9 +510,10 @@ class _AssetPageState extends ConsumerState { const SizedBox(height: 16), // 积分值(现金余额) _buildAssetItem( + context: context, icon: Icons.eco, iconColor: _green, - iconBgColor: _feta, + iconBgColor: isDark ? _green.withOpacity(0.15) : _feta, title: '积分值', amount: asset?.cashBalance, isLoading: isLoading, @@ -508,9 +522,10 @@ class _AssetPageState extends ConsumerState { const SizedBox(height: 16), // 冻结积分股 _buildAssetItem( + context: context, icon: Icons.lock_outline, iconColor: _orange, - iconBgColor: _serenade, + iconBgColor: isDark ? _orange.withOpacity(0.15) : _serenade, title: '冻结积分股', amount: asset?.frozenShares, isLoading: isLoading, @@ -521,6 +536,7 @@ class _AssetPageState extends ConsumerState { } Widget _buildAssetItem({ + required BuildContext context, required IconData icon, required Color iconColor, required Color iconBgColor, @@ -535,14 +551,15 @@ class _AssetPageState extends ConsumerState { Color? badgeBgColor, String? subtitle, }) { + final isDark = AppColors.isDark(context); return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( - color: Colors.white, + color: AppColors.cardOf(context), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: isDark ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -571,10 +588,10 @@ class _AssetPageState extends ConsumerState { children: [ Text( title, - style: const TextStyle( + style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, - color: Color(0xFF111827), + color: AppColors.textPrimaryOf(context), ), ), if (badge != null) ...[ @@ -582,7 +599,7 @@ class _AssetPageState extends ConsumerState { Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( - color: badgeBgColor ?? _scandal, + color: badgeBgColor ?? (isDark ? _green.withOpacity(0.2) : _scandal), borderRadius: BorderRadius.circular(9999), ), child: Text( @@ -603,10 +620,10 @@ class _AssetPageState extends ConsumerState { data: amount != null ? formatAmount(amount) : null, isLoading: isLoading, placeholder: '--', - style: const TextStyle( + style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: Color(0xFF111827), + color: AppColors.textPrimaryOf(context), ), ), // 估值 @@ -615,9 +632,9 @@ class _AssetPageState extends ConsumerState { data: isLoading ? null : '≈ $valueInCny', isLoading: isLoading, placeholder: '≈ ¥--', - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color(0xFF9CA3AF), + color: AppColors.textMutedOf(context), ), ), // 副标题 @@ -626,9 +643,9 @@ class _AssetPageState extends ConsumerState { padding: const EdgeInsets.only(top: 3), child: Text( subtitle, - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color(0xFF9CA3AF), + color: AppColors.textMutedOf(context), ), ), ), @@ -642,7 +659,7 @@ class _AssetPageState extends ConsumerState { Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( - color: _serenade, + color: isDark ? _orange.withOpacity(0.15) : _serenade, borderRadius: BorderRadius.circular(12), ), child: DataText( @@ -679,21 +696,22 @@ class _AssetPageState extends ConsumerState { ), ), // 箭头 - Icon(Icons.chevron_right, size: 14, color: _grayText.withOpacity(0.5)), + Icon(Icons.chevron_right, size: 14, color: AppColors.textMutedOf(context)), ], ), ); } - Widget _buildEarningsCard(AssetDisplay? asset, bool isLoading) { + Widget _buildEarningsCard(BuildContext context, AssetDisplay? asset, bool isLoading) { + final isDark = AppColors.isDark(context); return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( - color: Colors.white, + color: AppColors.cardOf(context), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: isDark ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -713,12 +731,12 @@ class _AssetPageState extends ConsumerState { ), ), const SizedBox(width: 8), - const Text( + Text( '交易统计', style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, - color: _darkText, + color: AppColors.textPrimaryOf(context), ), ), ], @@ -728,6 +746,7 @@ class _AssetPageState extends ConsumerState { Row( children: [ _buildEarningsItem( + context, '累计买入', asset != null ? formatCompact(asset.totalBought) : null, _orange, @@ -736,9 +755,10 @@ class _AssetPageState extends ConsumerState { Container( width: 1, height: 40, - color: _serenade, + color: isDark ? AppColors.borderOf(context) : _serenade, ), _buildEarningsItem( + context, '累计卖出', asset != null ? formatCompact(asset.totalSold) : null, _green, @@ -747,12 +767,13 @@ class _AssetPageState extends ConsumerState { Container( width: 1, height: 40, - color: _serenade, + color: isDark ? AppColors.borderOf(context) : _serenade, ), _buildEarningsItem( + context, '销毁倍数', asset != null ? '${formatDecimal(asset.burnMultiplier, 4)}x' : null, - const Color(0xFF9CA3AF), + AppColors.textMutedOf(context), isLoading, ), ], @@ -762,15 +783,15 @@ class _AssetPageState extends ConsumerState { ); } - Widget _buildEarningsItem(String label, String? value, Color valueColor, bool isLoading) { + Widget _buildEarningsItem(BuildContext context, String label, String? value, Color valueColor, bool isLoading) { return Expanded( child: Column( children: [ Text( label, - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: _grayText, + color: AppColors.textSecondaryOf(context), ), textAlign: TextAlign.center, ), @@ -791,11 +812,13 @@ class _AssetPageState extends ConsumerState { ); } - Widget _buildAccountList(AssetDisplay? asset, bool isLoading) { + Widget _buildAccountList(BuildContext context, AssetDisplay? asset, bool isLoading) { + final isDark = AppColors.isDark(context); return Column( children: [ // 交易账户(可用现金) _buildAccountItem( + context: context, icon: Icons.account_balance_wallet, iconColor: _orange, title: '可用积分值', @@ -804,11 +827,12 @@ class _AssetPageState extends ConsumerState { unit: '积分值', status: '可交易', statusColor: _green, - statusBgColor: _feta, + statusBgColor: isDark ? _green.withOpacity(0.15) : _feta, ), const SizedBox(height: 16), // 冻结现金 _buildAccountItem( + context: context, icon: Icons.lock_outline, iconColor: _orange, title: '冻结积分值', @@ -816,8 +840,8 @@ class _AssetPageState extends ConsumerState { isLoading: isLoading, unit: '积分值', status: '挂单中', - statusColor: const Color(0xFF9CA3AF), - statusBgColor: Colors.white, + statusColor: AppColors.textMutedOf(context), + statusBgColor: AppColors.cardOf(context), statusBorder: true, ), ], @@ -825,6 +849,7 @@ class _AssetPageState extends ConsumerState { } Widget _buildAccountItem({ + required BuildContext context, required IconData icon, required Color iconColor, required String title, @@ -836,14 +861,15 @@ class _AssetPageState extends ConsumerState { required Color statusBgColor, bool statusBorder = false, }) { + final isDark = AppColors.isDark(context); return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( - color: Colors.white, + color: AppColors.cardOf(context), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.black.withOpacity(0.05), + color: isDark ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 2, offset: const Offset(0, 1), ), @@ -856,7 +882,7 @@ class _AssetPageState extends ConsumerState { width: 36, height: 36, decoration: BoxDecoration( - color: _serenade, + color: isDark ? _orange.withOpacity(0.15) : _serenade, borderRadius: BorderRadius.circular(18), ), child: Icon(icon, color: iconColor, size: 20), @@ -869,10 +895,10 @@ class _AssetPageState extends ConsumerState { children: [ Text( title, - style: const TextStyle( + style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, - color: Color(0xFF111827), + color: AppColors.textPrimaryOf(context), ), ), const SizedBox(height: 2), @@ -890,9 +916,9 @@ class _AssetPageState extends ConsumerState { ), Text( ' $unit', - style: const TextStyle( + style: TextStyle( fontSize: 12, - color: Color(0xFF9CA3AF), + color: AppColors.textMutedOf(context), ), ), ], @@ -906,7 +932,7 @@ class _AssetPageState extends ConsumerState { decoration: BoxDecoration( color: statusBgColor, borderRadius: BorderRadius.circular(9999), - border: statusBorder ? Border.all(color: const Color(0xFFE5E7EB)) : null, + border: statusBorder ? Border.all(color: AppColors.borderOf(context)) : null, ), child: Text( status, @@ -918,7 +944,7 @@ class _AssetPageState extends ConsumerState { ), const SizedBox(width: 8), // 箭头 - Icon(Icons.chevron_right, size: 14, color: _grayText.withOpacity(0.5)), + Icon(Icons.chevron_right, size: 14, color: AppColors.textMutedOf(context)), ], ), ); diff --git a/frontend/mining-app/lib/presentation/pages/auth/login_page.dart b/frontend/mining-app/lib/presentation/pages/auth/login_page.dart index 5d946752..6a1f8eee 100644 --- a/frontend/mining-app/lib/presentation/pages/auth/login_page.dart +++ b/frontend/mining-app/lib/presentation/pages/auth/login_page.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/router/routes.dart'; +import '../../../core/constants/app_colors.dart'; import '../../providers/user_providers.dart'; class LoginPage extends ConsumerStatefulWidget { @@ -106,9 +107,10 @@ class _LoginPageState extends ConsumerState { @override Widget build(BuildContext context) { final userState = ref.watch(userNotifierProvider); + final isDark = AppColors.isDark(context); return Scaffold( - backgroundColor: Colors.white, + backgroundColor: AppColors.backgroundOf(context), body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(24), @@ -125,7 +127,7 @@ class _LoginPageState extends ConsumerState { width: 80, height: 80, decoration: BoxDecoration( - color: _orange.withOpacity(0.1), + color: _orange.withOpacity(isDark ? 0.2 : 0.1), borderRadius: BorderRadius.circular(20), ), child: const Icon( @@ -138,23 +140,23 @@ class _LoginPageState extends ConsumerState { const SizedBox(height: 24), - const Text( + Text( '欢迎回来', style: TextStyle( fontSize: 28, fontWeight: FontWeight.bold, - color: _darkText, + color: AppColors.textPrimaryOf(context), ), textAlign: TextAlign.center, ), const SizedBox(height: 8), - const Text( + Text( '登录您的股行账户', style: TextStyle( fontSize: 16, - color: _grayText, + color: AppColors.textSecondaryOf(context), ), textAlign: TextAlign.center, ), @@ -163,9 +165,9 @@ class _LoginPageState extends ConsumerState { // 登录方式切换 Container( - decoration: const BoxDecoration( + decoration: BoxDecoration( border: Border( - bottom: BorderSide(color: _borderGray, width: 1), + bottom: BorderSide(color: AppColors.borderOf(context), width: 1), ), ), child: Row( @@ -189,7 +191,7 @@ class _LoginPageState extends ConsumerState { style: TextStyle( fontSize: 16, fontWeight: _isPasswordLogin ? FontWeight.bold : FontWeight.normal, - color: _isPasswordLogin ? _orange : _lightGray, + color: _isPasswordLogin ? _orange : AppColors.textMutedOf(context), ), ), ), @@ -214,7 +216,7 @@ class _LoginPageState extends ConsumerState { style: TextStyle( fontSize: 16, fontWeight: !_isPasswordLogin ? FontWeight.bold : FontWeight.normal, - color: !_isPasswordLogin ? _orange : _lightGray, + color: !_isPasswordLogin ? _orange : AppColors.textMutedOf(context), ), ), ), @@ -230,25 +232,25 @@ class _LoginPageState extends ConsumerState { TextFormField( controller: _phoneController, keyboardType: TextInputType.phone, - style: const TextStyle(color: _darkText), + style: TextStyle(color: AppColors.textPrimaryOf(context)), decoration: InputDecoration( labelText: '手机号', - labelStyle: const TextStyle(color: _grayText), - prefixIcon: const Icon(Icons.phone_outlined, color: _grayText), + labelStyle: TextStyle(color: AppColors.textSecondaryOf(context)), + prefixIcon: Icon(Icons.phone_outlined, color: AppColors.textSecondaryOf(context)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: _borderGray), + borderSide: BorderSide(color: AppColors.borderOf(context)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: _borderGray), + borderSide: BorderSide(color: AppColors.borderOf(context)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: _orange, width: 2), ), filled: true, - fillColor: Colors.white, + fillColor: AppColors.cardOf(context), ), validator: (value) { if (value == null || value.isEmpty) { @@ -268,32 +270,32 @@ class _LoginPageState extends ConsumerState { TextFormField( controller: _passwordController, obscureText: _obscurePassword, - style: const TextStyle(color: _darkText), + style: TextStyle(color: AppColors.textPrimaryOf(context)), decoration: InputDecoration( labelText: '密码', - labelStyle: const TextStyle(color: _grayText), - prefixIcon: const Icon(Icons.lock_outline, color: _grayText), + labelStyle: TextStyle(color: AppColors.textSecondaryOf(context)), + prefixIcon: Icon(Icons.lock_outline, color: AppColors.textSecondaryOf(context)), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility_off_outlined : Icons.visibility_outlined, - color: _grayText, + color: AppColors.textSecondaryOf(context), ), onPressed: () => setState(() => _obscurePassword = !_obscurePassword), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: _borderGray), + borderSide: BorderSide(color: AppColors.borderOf(context)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: _borderGray), + borderSide: BorderSide(color: AppColors.borderOf(context)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: _orange, width: 2), ), filled: true, - fillColor: Colors.white, + fillColor: AppColors.cardOf(context), ), validator: (value) { if (value == null || value.isEmpty) { @@ -310,26 +312,26 @@ class _LoginPageState extends ConsumerState { controller: _smsCodeController, keyboardType: TextInputType.number, maxLength: 6, - style: const TextStyle(color: _darkText), + style: TextStyle(color: AppColors.textPrimaryOf(context)), decoration: InputDecoration( labelText: '验证码', - labelStyle: const TextStyle(color: _grayText), - prefixIcon: const Icon(Icons.sms_outlined, color: _grayText), + labelStyle: TextStyle(color: AppColors.textSecondaryOf(context)), + prefixIcon: Icon(Icons.sms_outlined, color: AppColors.textSecondaryOf(context)), counterText: '', border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: _borderGray), + borderSide: BorderSide(color: AppColors.borderOf(context)), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: _borderGray), + borderSide: BorderSide(color: AppColors.borderOf(context)), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: _orange, width: 2), ), filled: true, - fillColor: Colors.white, + fillColor: AppColors.cardOf(context), ), validator: (value) { if (value == null || value.isEmpty) { @@ -349,8 +351,8 @@ class _LoginPageState extends ConsumerState { child: ElevatedButton( onPressed: _countDown > 0 ? null : _sendSmsCode, style: ElevatedButton.styleFrom( - backgroundColor: _countDown > 0 ? _bgGray : _orange.withOpacity(0.1), - foregroundColor: _countDown > 0 ? _lightGray : _orange, + backgroundColor: _countDown > 0 ? AppColors.backgroundOf(context) : _orange.withOpacity(isDark ? 0.2 : 0.1), + foregroundColor: _countDown > 0 ? AppColors.textMutedOf(context) : _orange, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), @@ -408,9 +410,9 @@ class _LoginPageState extends ConsumerState { alignment: Alignment.centerRight, child: TextButton( onPressed: () => context.push(Routes.forgotPassword), - child: const Text( + child: Text( '忘记密码?', - style: TextStyle(color: _grayText), + style: TextStyle(color: AppColors.textSecondaryOf(context)), ), ), ), @@ -421,9 +423,9 @@ class _LoginPageState extends ConsumerState { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text( + Text( '还没有账号?', - style: TextStyle(color: _grayText), + style: TextStyle(color: AppColors.textSecondaryOf(context)), ), TextButton( onPressed: () => context.push(Routes.register), diff --git a/frontend/mining-app/lib/presentation/pages/c2c/c2c_market_page.dart b/frontend/mining-app/lib/presentation/pages/c2c/c2c_market_page.dart index 5b87b30f..3d7d7f2f 100644 --- a/frontend/mining-app/lib/presentation/pages/c2c/c2c_market_page.dart +++ b/frontend/mining-app/lib/presentation/pages/c2c/c2c_market_page.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/router/routes.dart'; import '../../../core/utils/format_utils.dart'; +import '../../../core/constants/app_colors.dart'; import '../../../data/models/c2c_order_model.dart'; import '../../providers/c2c_providers.dart'; import '../../providers/user_providers.dart'; @@ -52,20 +53,20 @@ class _C2cMarketPageState extends ConsumerState final asset = assetAsync.valueOrNull; return Scaffold( - backgroundColor: _bgGray, + backgroundColor: AppColors.backgroundOf(context), appBar: AppBar( - backgroundColor: Colors.white, + backgroundColor: AppColors.cardOf(context), elevation: 0, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: _darkText), + icon: Icon(Icons.arrow_back, color: AppColors.textPrimaryOf(context)), onPressed: () => context.pop(), ), - title: const Text( + title: Text( 'C2C交易', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, - color: _darkText, + color: AppColors.textPrimaryOf(context), ), ), centerTitle: true, @@ -78,7 +79,7 @@ class _C2cMarketPageState extends ConsumerState bottom: TabBar( controller: _tabController, labelColor: _orange, - unselectedLabelColor: _grayText, + unselectedLabelColor: AppColors.textSecondaryOf(context), indicatorColor: _orange, indicatorWeight: 3, tabs: const [ @@ -91,15 +92,15 @@ class _C2cMarketPageState extends ConsumerState body: Column( children: [ // 资产概览 - _buildAssetOverview(asset), + _buildAssetOverview(context, asset), // 订单列表 Expanded( child: TabBarView( controller: _tabController, children: [ - _buildOrderList('SELL'), // 购买页面显示卖单 - _buildOrderList('BUY'), // 出售页面显示买单 - _buildMyOrderList(), + _buildOrderList(context, 'SELL'), // 购买页面显示卖单 + _buildOrderList(context, 'BUY'), // 出售页面显示买单 + _buildMyOrderList(context), ], ), ), @@ -108,7 +109,7 @@ class _C2cMarketPageState extends ConsumerState ); } - Widget _buildAssetOverview(asset) { + Widget _buildAssetOverview(BuildContext context, asset) { final availableShares = asset?.availableShares ?? '0'; final availableCash = asset?.availableCash ?? '0'; @@ -116,7 +117,7 @@ class _C2cMarketPageState extends ConsumerState margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( - color: Colors.white, + color: AppColors.cardOf(context), borderRadius: BorderRadius.circular(12), ), child: Row( @@ -125,9 +126,9 @@ class _C2cMarketPageState extends ConsumerState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( '可用积分股', - style: TextStyle(fontSize: 12, color: _grayText), + style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context)), ), const SizedBox(height: 4), Text( @@ -141,16 +142,16 @@ class _C2cMarketPageState extends ConsumerState ], ), ), - Container(width: 1, height: 40, color: _bgGray), + Container(width: 1, height: 40, color: AppColors.borderOf(context)), Expanded( child: Padding( padding: const EdgeInsets.only(left: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text( + Text( '可用积分值', - style: TextStyle(fontSize: 12, color: _grayText), + style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context)), ), const SizedBox(height: 4), Text( @@ -170,7 +171,7 @@ class _C2cMarketPageState extends ConsumerState ); } - Widget _buildOrderList(String type) { + Widget _buildOrderList(BuildContext context, String type) { final ordersAsync = ref.watch(c2cOrdersProvider(type)); return ordersAsync.when( @@ -181,9 +182,9 @@ class _C2cMarketPageState extends ConsumerState child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(Icons.error_outline, size: 48, color: _grayText), + Icon(Icons.error_outline, size: 48, color: AppColors.textMutedOf(context)), const SizedBox(height: 8), - Text('加载失败', style: TextStyle(color: _grayText)), + Text('加载失败', style: TextStyle(color: AppColors.textSecondaryOf(context))), const SizedBox(height: 8), ElevatedButton( onPressed: () => ref.invalidate(c2cOrdersProvider(type)), @@ -199,16 +200,16 @@ class _C2cMarketPageState extends ConsumerState child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.inbox_outlined, size: 64, color: _grayText.withOpacity(0.5)), + Icon(Icons.inbox_outlined, size: 64, color: AppColors.textMutedOf(context)), const SizedBox(height: 16), Text( type == 'SELL' ? '暂无出售广告' : '暂无购买广告', - style: TextStyle(fontSize: 16, color: _grayText), + style: TextStyle(fontSize: 16, color: AppColors.textSecondaryOf(context)), ), const SizedBox(height: 8), Text( '点击右上角发布广告', - style: TextStyle(fontSize: 14, color: _grayText.withOpacity(0.7)), + style: TextStyle(fontSize: 14, color: AppColors.textMutedOf(context)), ), ], ), @@ -224,7 +225,7 @@ class _C2cMarketPageState extends ConsumerState itemCount: orders.length, itemBuilder: (context, index) { final order = orders[index]; - return _buildOrderCard(order, type == 'SELL'); + return _buildOrderCard(context, order, type == 'SELL'); }, ), ); @@ -232,7 +233,7 @@ class _C2cMarketPageState extends ConsumerState ); } - Widget _buildMyOrderList() { + Widget _buildMyOrderList(BuildContext context) { final ordersAsync = ref.watch(myC2cOrdersProvider); return ordersAsync.when( @@ -243,9 +244,9 @@ class _C2cMarketPageState extends ConsumerState child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Icon(Icons.error_outline, size: 48, color: _grayText), + Icon(Icons.error_outline, size: 48, color: AppColors.textMutedOf(context)), const SizedBox(height: 8), - Text('加载失败', style: TextStyle(color: _grayText)), + Text('加载失败', style: TextStyle(color: AppColors.textSecondaryOf(context))), ], ), ), @@ -256,11 +257,11 @@ class _C2cMarketPageState extends ConsumerState child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.history, size: 64, color: _grayText.withOpacity(0.5)), + Icon(Icons.history, size: 64, color: AppColors.textMutedOf(context)), const SizedBox(height: 16), Text( '暂无订单记录', - style: TextStyle(fontSize: 16, color: _grayText), + style: TextStyle(fontSize: 16, color: AppColors.textSecondaryOf(context)), ), ], ), @@ -276,7 +277,7 @@ class _C2cMarketPageState extends ConsumerState itemCount: orders.length, itemBuilder: (context, index) { final order = orders[index]; - return _buildMyOrderCard(order); + return _buildMyOrderCard(context, order); }, ), ); @@ -284,9 +285,10 @@ class _C2cMarketPageState extends ConsumerState ); } - Widget _buildOrderCard(C2cOrderModel order, bool isBuyAction) { + Widget _buildOrderCard(BuildContext context, C2cOrderModel order, bool isBuyAction) { final user = ref.read(userNotifierProvider); final isMyOrder = order.makerAccountSequence == user.accountSequence; + final isDark = AppColors.isDark(context); return GestureDetector( onTap: isMyOrder ? null : () => _showTakeOrderDialog(order, isBuyAction), @@ -294,7 +296,7 @@ class _C2cMarketPageState extends ConsumerState margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( - color: Colors.white, + color: AppColors.cardOf(context), borderRadius: BorderRadius.circular(12), ), child: Column( @@ -308,7 +310,7 @@ class _C2cMarketPageState extends ConsumerState height: 40, decoration: BoxDecoration( shape: BoxShape.circle, - color: (isBuyAction ? _green : _red).withOpacity(0.1), + color: (isBuyAction ? _green : _red).withOpacity(isDark ? 0.2 : 0.1), ), child: Center( child: Text( @@ -328,10 +330,10 @@ class _C2cMarketPageState extends ConsumerState children: [ Text( order.makerNickname ?? _maskPhone(order.makerPhone ?? ''), - style: const TextStyle( + style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, - color: _darkText, + color: AppColors.textPrimaryOf(context), ), ), if (isMyOrder) @@ -345,7 +347,7 @@ class _C2cMarketPageState extends ConsumerState Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( - color: (isBuyAction ? _green : _red).withOpacity(0.1), + color: (isBuyAction ? _green : _red).withOpacity(isDark ? 0.2 : 0.1), borderRadius: BorderRadius.circular(4), ), child: Text( @@ -367,14 +369,14 @@ class _C2cMarketPageState extends ConsumerState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('单价', style: TextStyle(fontSize: 12, color: _grayText)), + Text('单价', style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context))), const SizedBox(height: 4), Text( '${formatPrice(order.price)} 积分值', - style: const TextStyle( + style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, - color: _darkText, + color: AppColors.textPrimaryOf(context), ), ), ], @@ -384,14 +386,14 @@ class _C2cMarketPageState extends ConsumerState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text('数量', style: TextStyle(fontSize: 12, color: _grayText)), + Text('数量', style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context))), const SizedBox(height: 4), Text( '${formatAmount(order.quantity)} 积分股', - style: const TextStyle( + style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, - color: _darkText, + color: AppColors.textPrimaryOf(context), ), ), ], @@ -404,13 +406,13 @@ class _C2cMarketPageState extends ConsumerState Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( - color: _bgGray, + color: isDark ? AppColors.backgroundOf(context) : _bgGray, borderRadius: BorderRadius.circular(8), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text('总金额', style: TextStyle(fontSize: 12, color: _grayText)), + Text('总金额', style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context))), Text( '${formatAmount(order.totalAmount)} 积分值', style: const TextStyle( @@ -426,7 +428,7 @@ class _C2cMarketPageState extends ConsumerState const SizedBox(height: 8), Text( '备注: ${order.remark}', - style: TextStyle(fontSize: 12, color: _grayText), + style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context)), maxLines: 2, overflow: TextOverflow.ellipsis, ), @@ -437,14 +439,15 @@ class _C2cMarketPageState extends ConsumerState ); } - Widget _buildMyOrderCard(C2cOrderModel order) { + Widget _buildMyOrderCard(BuildContext context, C2cOrderModel order) { + final isDark = AppColors.isDark(context); return GestureDetector( onTap: () => context.push(Routes.c2cOrderDetail, extra: order.orderNo), child: Container( margin: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.all(16), decoration: BoxDecoration( - color: Colors.white, + color: AppColors.cardOf(context), borderRadius: BorderRadius.circular(12), ), child: Column( @@ -459,7 +462,7 @@ class _C2cMarketPageState extends ConsumerState Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( - color: (order.isBuy ? _green : _red).withOpacity(0.1), + color: (order.isBuy ? _green : _red).withOpacity(isDark ? 0.2 : 0.1), borderRadius: BorderRadius.circular(4), ), child: Text( @@ -474,11 +477,11 @@ class _C2cMarketPageState extends ConsumerState const SizedBox(width: 8), Text( order.orderNo, - style: const TextStyle(fontSize: 12, color: _grayText), + style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context)), ), ], ), - _buildStatusBadge(order.status), + _buildStatusBadge(context, order.status), ], ), const SizedBox(height: 12), @@ -488,10 +491,10 @@ class _C2cMarketPageState extends ConsumerState Expanded( child: Text( '${formatAmount(order.quantity)} 积分股', - style: const TextStyle( + style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, - color: _darkText, + color: AppColors.textPrimaryOf(context), ), ), ), @@ -509,7 +512,7 @@ class _C2cMarketPageState extends ConsumerState // 时间 Text( '创建于 ${_formatDateTime(order.createdAt)}', - style: const TextStyle(fontSize: 12, color: _grayText), + style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(context)), ), ], ), @@ -517,39 +520,40 @@ class _C2cMarketPageState extends ConsumerState ); } - Widget _buildStatusBadge(C2cOrderStatus status) { + Widget _buildStatusBadge(BuildContext context, C2cOrderStatus status) { + final isDark = AppColors.isDark(context); Color bgColor; Color textColor; String text; switch (status) { case C2cOrderStatus.pending: - bgColor = _orange.withOpacity(0.1); + bgColor = _orange.withOpacity(isDark ? 0.2 : 0.1); textColor = _orange; text = '待接单'; break; case C2cOrderStatus.matched: - bgColor = Colors.blue.withOpacity(0.1); + bgColor = Colors.blue.withOpacity(isDark ? 0.2 : 0.1); textColor = Colors.blue; text = '待付款'; break; case C2cOrderStatus.paid: - bgColor = Colors.purple.withOpacity(0.1); + bgColor = Colors.purple.withOpacity(isDark ? 0.2 : 0.1); textColor = Colors.purple; text = '待确认'; break; case C2cOrderStatus.completed: - bgColor = _green.withOpacity(0.1); + bgColor = _green.withOpacity(isDark ? 0.2 : 0.1); textColor = _green; text = '已完成'; break; case C2cOrderStatus.cancelled: - bgColor = _grayText.withOpacity(0.1); - textColor = _grayText; + bgColor = AppColors.textMutedOf(context).withOpacity(isDark ? 0.2 : 0.1); + textColor = AppColors.textMutedOf(context); text = '已取消'; break; case C2cOrderStatus.expired: - bgColor = _red.withOpacity(0.1); + bgColor = _red.withOpacity(isDark ? 0.2 : 0.1); textColor = _red; text = '已过期'; break; @@ -584,37 +588,47 @@ class _C2cMarketPageState extends ConsumerState void _showTakeOrderDialog(C2cOrderModel order, bool isBuyAction) { showDialog( context: context, - builder: (context) => AlertDialog( - title: Text(isBuyAction ? '确认购买' : '确认出售'), + builder: (dialogContext) => AlertDialog( + backgroundColor: AppColors.cardOf(dialogContext), + title: Text( + isBuyAction ? '确认购买' : '确认出售', + style: TextStyle(color: AppColors.textPrimaryOf(dialogContext)), + ), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('数量: ${formatAmount(order.quantity)} 积分股'), + Text( + '数量: ${formatAmount(order.quantity)} 积分股', + style: TextStyle(color: AppColors.textPrimaryOf(dialogContext)), + ), const SizedBox(height: 8), - Text('单价: ${formatPrice(order.price)} 积分值'), + Text( + '单价: ${formatPrice(order.price)} 积分值', + style: TextStyle(color: AppColors.textPrimaryOf(dialogContext)), + ), const SizedBox(height: 8), Text( '总金额: ${formatAmount(order.totalAmount)} 积分值', - style: const TextStyle(fontWeight: FontWeight.bold), + style: TextStyle(fontWeight: FontWeight.bold, color: AppColors.textPrimaryOf(dialogContext)), ), const SizedBox(height: 16), Text( isBuyAction ? '您将使用积分值购买对方的积分股' : '您将出售积分股换取对方的积分值', - style: TextStyle(fontSize: 12, color: _grayText), + style: TextStyle(fontSize: 12, color: AppColors.textSecondaryOf(dialogContext)), ), ], ), actions: [ TextButton( - onPressed: () => Navigator.pop(context), - child: const Text('取消'), + onPressed: () => Navigator.pop(dialogContext), + child: Text('取消', style: TextStyle(color: AppColors.textSecondaryOf(dialogContext))), ), TextButton( onPressed: () async { - Navigator.pop(context); + Navigator.pop(dialogContext); await _takeOrder(order); }, child: Text(