diff --git a/flutter_monisuo/build/99111e0c5b6228829e100ef67db14ea2.cache.dill.track.dill b/flutter_monisuo/build/99111e0c5b6228829e100ef67db14ea2.cache.dill.track.dill index 0001960..6535aa0 100644 Binary files a/flutter_monisuo/build/99111e0c5b6228829e100ef67db14ea2.cache.dill.track.dill and b/flutter_monisuo/build/99111e0c5b6228829e100ef67db14ea2.cache.dill.track.dill differ diff --git a/flutter_monisuo/lib/core/constants/api_endpoints.dart b/flutter_monisuo/lib/core/constants/api_endpoints.dart index bac0c4e..5ddc91e 100644 --- a/flutter_monisuo/lib/core/constants/api_endpoints.dart +++ b/flutter_monisuo/lib/core/constants/api_endpoints.dart @@ -1,111 +1,111 @@ -/// API 端点配置 +/// API 端點配置 class ApiEndpoints { ApiEndpoints._(); - /// 环境类型 + /// 環境類型 static const String _env = String.fromEnvironment('ENV', defaultValue: 'dev'); - /// 基础URL - 根据环境自动切换 + /// 基礎URL - 根據環境自動切換 static const String baseUrl = _env == 'prod' ? 'http://8.155.172.147:5010' : 'http://localhost:5010'; - /// 是否为生产环境 + /// 是否為生產環境 static const bool isProduction = _env == 'prod'; - // ==================== 用户模块 ==================== + // ==================== 用戶模塊 ==================== - /// 用户登录 + /// 用戶登錄 static const String login = '/api/user/login'; - /// 用户注册 + /// 用戶註冊 static const String register = '/api/user/register'; - /// 获取用户信息 + /// 獲取用戶信息 static const String userInfo = '/api/user/info'; - /// 上传KYC资料 + /// 上傳KYC資料 static const String kyc = '/api/user/kyc'; - /// 获取推广码 + /// 獲取推廣碼 static const String referralCode = '/api/user/referral-code'; - /// 退出登录 + /// 退出登錄 static const String logout = '/api/user/logout'; - // ==================== 行情模块 ==================== + // ==================== 行情模塊 ==================== - /// 获取币种列表 + /// 獲取幣種列表 static const String coinList = '/api/market/list'; - /// 获取币种详情 + /// 獲取幣種詳情 static const String coinDetail = '/api/market/detail'; - /// 搜索币种 + /// 搜索幣種 static const String coinSearch = '/api/market/search'; - // ==================== 交易模块 ==================== + // ==================== 交易模塊 ==================== - /// 买入 + /// 買入 static const String buy = '/api/trade/buy'; - /// 卖出 + /// 賣出 static const String sell = '/api/trade/sell'; - /// 获取交易记录 + /// 獲取交易記錄 static const String tradeOrders = '/api/trade/orders'; - /// 获取订单详情 + /// 獲取訂單詳情 static const String tradeOrderDetail = '/api/trade/order/detail'; - // ==================== 资产模块 ==================== + // ==================== 資產模塊 ==================== - /// 获取资产总览 + /// 獲取資產總覽 static const String assetOverview = '/api/asset/overview'; - /// 获取资金账户 + /// 獲取資金賬戶 static const String fundAccount = '/api/asset/fund'; - /// 获取交易账户 + /// 獲取交易賬戶 static const String tradeAccount = '/api/asset/trade'; - /// 资金划转 + /// 資金劃轉 static const String transfer = '/api/asset/transfer'; - /// 获取资金流水 + /// 獲取資金流水 static const String assetFlow = '/api/asset/flow'; - // ==================== 充提模块 ==================== + // ==================== 充提模塊 ==================== - /// 申请充值 + /// 申請充值 static const String deposit = '/api/fund/deposit'; - /// 确认已打款 + /// 確認已打款 static const String confirmPay = '/api/fund/confirmPay'; - /// 申请提现 + /// 申請提現 static const String withdraw = '/api/fund/withdraw'; - /// 取消订单 + /// 取消訂單 static const String cancelOrder = '/api/fund/cancel'; - /// 获取可用提现网络列表 + /// 獲取可用提現網絡列表 static const String walletNetworks = '/api/wallet/networks'; - /// 获取充提记录 + /// 獲取充提記錄 static const String fundOrders = '/api/fund/orders'; - /// 获取默认钱包地址 + /// 獲取默認錢包地址 static const String defaultWallet = '/api/wallet/default'; - // ==================== 福利模块 ==================== + // ==================== 福利模塊 ==================== - /// 福利中心状态 + /// 福利中心狀態 static const String bonusWelfare = '/api/bonus/welfare'; - /// 领取奖励 + /// 領取獎勵 static const String bonusClaim = '/api/bonus/claim'; - /// 每日盈亏 + /// 每日盈虧 static const String dailyProfit = '/api/asset/daily-profit'; } diff --git a/flutter_monisuo/lib/core/event/app_event_bus.dart b/flutter_monisuo/lib/core/event/app_event_bus.dart index b0bc173..dff8af4 100644 --- a/flutter_monisuo/lib/core/event/app_event_bus.dart +++ b/flutter_monisuo/lib/core/event/app_event_bus.dart @@ -1,15 +1,15 @@ import 'dart:async'; -/// 应用事件类型 +/// 應用事件類型 enum AppEventType { - /// 资产变动(余额、持仓等) + /// 資產變動(餘額、持倉等) assetChanged, - /// 订单变动(充提订单状态变化) + /// 訂單變動(充提訂單狀態變化) orderChanged, } -/// 应用事件 +/// 應用事件 class AppEvent { final AppEventType type; final Map? data; @@ -17,20 +17,20 @@ class AppEvent { const AppEvent(this.type, {this.data}); } -/// 轻量级应用内事件总线 -/// 基于 StreamController.broadcast,零外部依赖 +/// 輕量級應用內事件總線 +/// 基於 StreamController.broadcast,零外部依賴 class AppEventBus { final StreamController _controller = StreamController.broadcast(); - /// 广播事件 + /// 廣播事件 void fire(AppEventType type, {Map? data}) { if (!_controller.isClosed) { _controller.add(AppEvent(type, data: data)); } } - /// 监听指定类型事件 + /// 監聽指定類型事件 StreamSubscription on( AppEventType type, void Function(AppEvent) callback, @@ -40,10 +40,10 @@ class AppEventBus { .listen(callback); } - /// 监听任意事件 + /// 監聽任意事件 Stream get stream => _controller.stream; - /// 销毁 + /// 銷燬 void dispose() { _controller.close(); } diff --git a/flutter_monisuo/lib/core/network/api_exception.dart b/flutter_monisuo/lib/core/network/api_exception.dart index b5f7e62..7d0b2b8 100644 --- a/flutter_monisuo/lib/core/network/api_exception.dart +++ b/flutter_monisuo/lib/core/network/api_exception.dart @@ -1,4 +1,4 @@ -/// API 异常类 +/// API 異常類 class ApiException implements Exception { final String message; final String code; @@ -12,7 +12,7 @@ class ApiException implements Exception { factory ApiException.unauthorized([String? message]) { return ApiException( - message: message ?? '未授权', + message: message ?? '未授權', code: '0002', statusCode: 401, ); @@ -20,14 +20,14 @@ class ApiException implements Exception { factory ApiException.networkError([String? message]) { return ApiException( - message: message ?? '网络错误', + message: message ?? '網絡錯誤', code: 'NETWORK_ERROR', ); } factory ApiException.serverError([String? message]) { return ApiException( - message: message ?? '服务器错误', + message: message ?? '服務器錯誤', code: 'SERVER_ERROR', statusCode: 500, ); diff --git a/flutter_monisuo/lib/core/network/api_response.dart b/flutter_monisuo/lib/core/network/api_response.dart index e2ab927..73b082c 100644 --- a/flutter_monisuo/lib/core/network/api_response.dart +++ b/flutter_monisuo/lib/core/network/api_response.dart @@ -1,11 +1,11 @@ -/// API 响应状态码 +/// API 響應狀態碼 class ResponseCode { static const String success = '0000'; static const String unauthorized = '0002'; static const String kycRequired = 'KYC_REQUIRED'; } -/// API 响应模型 +/// API 響應模型 class ApiResponse { final bool success; final String? message; diff --git a/flutter_monisuo/lib/core/network/dio_client.dart b/flutter_monisuo/lib/core/network/dio_client.dart index 225de44..3441a44 100644 --- a/flutter_monisuo/lib/core/network/dio_client.dart +++ b/flutter_monisuo/lib/core/network/dio_client.dart @@ -5,7 +5,7 @@ import '../storage/local_storage.dart'; import 'api_exception.dart'; import 'api_response.dart'; -/// 网络配置常量 +/// 網絡配置常量 class NetworkConfig { static const String baseUrl = ApiEndpoints.baseUrl; static const Duration connectTimeout = Duration(seconds: 15); @@ -13,11 +13,11 @@ class NetworkConfig { static const Duration sendTimeout = Duration(seconds: 15); } -/// Dio 网络客户端 +/// Dio 網絡客戶端 class DioClient { late final Dio _dio; - /// 未授权回调(token 过期时触发) + /// 未授權回調(token 過期時觸發) VoidCallback? onUnauthorized; DioClient() { @@ -43,7 +43,7 @@ class DioClient { ]); } - /// GET 请求 + /// GET 請求 Future> get( String path, { Map? queryParameters, @@ -57,7 +57,7 @@ class DioClient { } } - /// POST 请求 + /// POST 請求 Future> post( String path, { dynamic data, @@ -71,7 +71,7 @@ class DioClient { } } - /// Multipart 文件上传 + /// Multipart 文件上傳 Future> upload( String path, { required FormData formData, @@ -96,21 +96,21 @@ class DioClient { final data = response.data; if (data is Map) { final apiResponse = ApiResponse.fromJson(data, fromJson); - // 检测业务层未授权(后端返回 HTTP 200 + code "0002") - // 注意:不再自动清除用户数据,避免误判 - // 只有在 HTTP 401 时才清除用户数据 + // 檢測業務層未授權(後端返回 HTTP 200 + code "0002") + // 注意:不再自動清除用戶數據,避免誤判 + // 只有在 HTTP 401 時才清除用戶數據 if (apiResponse.isUnauthorized) { - debugPrint('业务层未授权响应: ${apiResponse.message}'); - // 不再自动调用 onUnauthorized,避免刷新时误判 + debugPrint('業務層未授權響應: ${apiResponse.message}'); + // 不再自動調用 onUnauthorized,避免刷新時誤判 // onUnauthorized?.call(); } return apiResponse; } - return ApiResponse.fail('响应数据格式错误'); + return ApiResponse.fail('響應數據格式錯誤'); } ApiResponse _handleError(DioException e) { - // 详细错误日志 + // 詳細錯誤日誌 debugPrint('=== Network Error ==='); debugPrint('Type: ${e.type}'); debugPrint('Message: ${e.message}'); @@ -122,7 +122,7 @@ class DioClient { if (_isUnauthorized(e)) { _clearUserData(); onUnauthorized?.call(); - return ApiResponse.unauthorized('登录已过期,请重新登录'); + return ApiResponse.unauthorized('登錄已過期,請重新登錄'); } final message = _getErrorMessage(e); @@ -140,28 +140,28 @@ class DioClient { String _getErrorMessage(DioException e) { switch (e.type) { case DioExceptionType.connectionTimeout: - return '连接超时,请检查网络'; + return '連接超時,請檢查網絡'; case DioExceptionType.sendTimeout: - return '发送超时,请重试'; + return '發送超時,請重試'; case DioExceptionType.receiveTimeout: - return '响应超时,请重试'; + return '響應超時,請重試'; case DioExceptionType.connectionError: - return '网络连接失败,请检查网络设置'; + return '網絡連接失敗,請檢查網絡設置'; case DioExceptionType.badResponse: final statusCode = e.response?.statusCode; if (statusCode == 500) { - return '服务器内部错误'; + return '服務器內部錯誤'; } else if (statusCode == 502 || statusCode == 503) { - return '服务暂时不可用'; + return '服務暫時不可用'; } - return '服务器错误 ($statusCode)'; + return '服務器錯誤 ($statusCode)'; default: - return e.message ?? '网络请求失败'; + return e.message ?? '網絡請求失敗'; } } } -/// 日志拦截器 +/// 日誌攔截器 class _LoggingInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { @@ -195,7 +195,7 @@ class _LoggingInterceptor extends Interceptor { } } -/// 认证拦截器 +/// 認證攔截器 class _AuthInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { diff --git a/flutter_monisuo/lib/core/storage/local_storage.dart b/flutter_monisuo/lib/core/storage/local_storage.dart index 46f46bb..5c6dc07 100644 --- a/flutter_monisuo/lib/core/storage/local_storage.dart +++ b/flutter_monisuo/lib/core/storage/local_storage.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:shared_preferences/shared_preferences.dart'; -/// 本地存储服务 +/// 本地存儲服務 class LocalStorage { LocalStorage._(); @@ -15,7 +15,7 @@ class LocalStorage { _prefs = await SharedPreferences.getInstance(); } - /// 获取实例 + /// 獲取實例 static SharedPreferences get prefs { if (_prefs == null) { throw Exception('LocalStorage not initialized. Call init() first.'); @@ -30,7 +30,7 @@ class LocalStorage { await prefs.setString(_tokenKey, token); } - /// 获取 Token + /// 獲取 Token static String? getToken() { return prefs.getString(_tokenKey); } @@ -40,17 +40,17 @@ class LocalStorage { await prefs.remove(_tokenKey); } - /// 是否已登录 + /// 是否已登錄 static bool get isLoggedIn => getToken() != null && getToken()!.isNotEmpty; - // ==================== 用户信息管理 ==================== + // ==================== 用戶信息管理 ==================== - /// 保存用户信息 + /// 保存用戶信息 static Future saveUserInfo(Map userInfo) async { await prefs.setString(_userInfoKey, jsonEncode(userInfo)); } - /// 获取用户信息 + /// 獲取用戶信息 static Map? getUserInfo() { final str = prefs.getString(_userInfoKey); if (str == null) return null; @@ -61,7 +61,7 @@ class LocalStorage { } } - /// 移除用户信息 + /// 移除用戶信息 static Future removeUserInfo() async { await prefs.remove(_userInfoKey); } @@ -73,47 +73,47 @@ class LocalStorage { await prefs.setString(key, value); } - /// 获取字符串 + /// 獲取字符串 static String? getString(String key) { return prefs.getString(key); } - /// 保存布尔值 + /// 保存布爾值 static Future setBool(String key, bool value) async { await prefs.setBool(key, value); } - /// 获取布尔值 + /// 獲取布爾值 static bool? getBool(String key) { return prefs.getBool(key); } - /// 清除所有数据 + /// 清除所有數據 static Future clearAll() async { await prefs.clear(); } - /// 清除用户数据(退出登录时调用) + /// 清除用戶數據(退出登錄時調用) static Future clearUserData() async { await removeToken(); await removeUserInfo(); } - // ==================== 引导页状态 ==================== + // ==================== 引導頁狀態 ==================== static const String _onboardingKey = 'onboarding_completed'; - /// 检查是否已完成引导页 + /// 檢查是否已完成引導頁 static bool get isOnboardingCompleted { return getBool(_onboardingKey) ?? false; } - /// 标记引导页已完成 + /// 標記引導頁已完成 static Future setOnboardingCompleted() async { await setBool(_onboardingKey, true); } - /// 重置引导页状态(用于测试) + /// 重置引導頁狀態(用於測試) static Future resetOnboarding() async { await prefs.remove(_onboardingKey); } diff --git a/flutter_monisuo/lib/core/theme/app_color_scheme.dart b/flutter_monisuo/lib/core/theme/app_color_scheme.dart index 3c4d512..16b79b4 100644 --- a/flutter_monisuo/lib/core/theme/app_color_scheme.dart +++ b/flutter_monisuo/lib/core/theme/app_color_scheme.dart @@ -1,33 +1,33 @@ import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; -/// Material Design 3 颜色系统 - Pencil Design Theme +/// Material Design 3 顏色系統 - Pencil Design Theme /// -/// 深色主题: "黑金传奇" (Black & Gold) -/// 深邃黑底 + 真金主色 + 翠绿盈利 → 金融奢华感 +/// 深色主題: "黑金傳奇" (Black & Gold) +/// 深邃黑底 + 真金主色 + 翠綠盈利 → 金融奢華感 /// 背景 #0B1120 | 主色 #D4AF37 | 盈利 #4ADE80 /// -/// 浅色主题: "白金殿堂" (White & Gold) -/// 纯净白底 + 深灰主色 + 琥珀强调 → 高端金融科技 -/// 背景 #F8FAFC | 主色 #1F2937 | 强调 #F59E0B +/// 淺色主題: "白金殿堂" (White & Gold) +/// 純淨白底 + 深灰主色 + 琥珀強調 → 高端金融科技 +/// 背景 #F8FAFC | 主色 #1F2937 | 強調 #F59E0B /// -/// 设计原则: +/// 設計原則: /// - Material Design 3 配色方案 /// - Glass Panel 毛玻璃效果 /// - Gold Glow 金色光效(原 Neon Glow) -/// - 渐变 CTA: primary → primary_container (135度) +/// - 漸變 CTA: primary → primary_container (135度) class AppColorScheme { AppColorScheme._(); // ============================================ - // 深色主题 - "Slate Dark" (Material Design 3) - // 背景 #0B1120 | 主色 #1E3A8A | 强调 #D4AF37 + // 深色主題 - "Slate Dark" (Material Design 3) + // 背景 #0B1120 | 主色 #1E3A8A | 強調 #D4AF37 // ============================================ - /// 背景基色 - Slate 深蓝黑 + /// 背景基色 - Slate 深藍黑 static const Color darkBackground = Color(0xFF0B1120); - /// Surface 层次 (从低到高) - Material Design 3 规范 + /// Surface 層次 (從低到高) - Material Design 3 規範 static const Color darkSurfaceDim = Color(0xFF0B1120); static const Color darkSurfaceLowest = Color(0xFF000000); static const Color darkSurfaceLow = Color(0xFF0F172A); @@ -38,7 +38,7 @@ class AppColorScheme { static const Color darkSurfaceBright = Color(0xFF334155); static const Color darkSurfaceVariant = Color(0xFF1E293B); - /// 兼容旧名称 + /// 兼容舊名稱 static const Color darkSurfaceContainerLowest = darkSurfaceLowest; static const Color darkSurfaceContainerLow = darkSurfaceLow; static const Color darkSurfaceHigh = darkSurfaceContainerHigh; @@ -59,7 +59,7 @@ class AppColorScheme { static const Color darkOnPrimaryFixed = Color(0xFF1F2937); static const Color darkOnPrimaryFixedVariant = Color(0xFF374151); - /// Secondary - 真金 #D4AF37 (黑金强调色) + /// Secondary - 真金 #D4AF37 (黑金強調色) static const Color darkSecondary = Color(0xFFD4AF37); static const Color darkSecondaryDim = Color(0xFFB8960E); static const Color darkSecondaryContainer = Color(0xFFE8C84A); @@ -81,7 +81,7 @@ class AppColorScheme { static const Color darkOnTertiaryFixed = Color(0xFF052E16); static const Color darkOnTertiaryFixedVariant = Color(0xFF14532D); - /// Error - Neon Red (红色 - 错误/卖出) + /// Error - Neon Red (紅色 - 錯誤/賣出) static const Color darkError = Color(0xFFff716c); static const Color darkErrorDim = Color(0xFFd7383b); static const Color darkErrorContainer = Color(0xFF9f0519); @@ -99,14 +99,14 @@ class AppColorScheme { static const Color darkSurfaceTint = Color(0xFFD4AF37); // ============================================ - // 浅色主题 - "Slate Light" (Material Design 3) - // 背景 #F8FAFC | 主色 #1E40AF | 强调 #D4AF37 + // 淺色主題 - "Slate Light" (Material Design 3) + // 背景 #F8FAFC | 主色 #1E40AF | 強調 #D4AF37 // ============================================ /// 背景基色 - Slate 50 static const Color lightBackground = Color(0xFFF8FAFC); - /// Surface 层次 (从低到高) + /// Surface 層次 (從低到高) static const Color lightSurfaceLowest = Color(0xFFFFFFFF); static const Color lightSurfaceLow = Color(0xFFF1F5F9); static const Color lightSurface = Color(0xFFF8FAFC); @@ -134,41 +134,41 @@ class AppColorScheme { static const Color lightOnSurfaceMuted = Color(0xFF94A3B8); // ============================================ - // Glass Panel 毛玻璃效果颜色 + // Glass Panel 毛玻璃效果顏色 // ============================================ /// Glass Panel 背景色 - rgba(33, 37, 47, 0.4) static const Color glassPanelBackground = Color(0x6621252F); - /// Glass Panel 边框色 - rgba(69, 72, 79, 0.15) + /// Glass Panel 邊框色 - rgba(69, 72, 79, 0.15) static const Color glassPanelBorder = Color(0x2645484f); // ============================================ - // Gold Glow 金色光效颜色(原 Neon Glow) + // Gold Glow 金色光效顏色(原 Neon Glow) // ============================================ - /// Primary Glow - 金色光晕 rgba(212, 175, 55, 0.15) + /// Primary Glow - 金色光暈 rgba(212, 175, 55, 0.15) static const Color neonGlowPrimary = Color(0x26D4AF37); - /// Secondary Glow - 蓝色光晕 rgba(30, 58, 138, 0.15) + /// Secondary Glow - 藍色光暈 rgba(30, 58, 138, 0.15) static const Color neonGlowSecondary = Color(0x261E3A8A); - /// Tertiary Glow - 绿色光晕 rgba(175, 255, 209, 0.2) + /// Tertiary Glow - 綠色光暈 rgba(175, 255, 209, 0.2) static const Color neonGlowTertiary = Color(0x33afffd1); // ============================================ - // 语义色 - 明暗通用 + // 語義色 - 明暗通用 // ============================================ - /// 涨/买入/成功 (深色主题色,亮色模式下请使用 getUpColor) + /// 漲/買入/成功 (深色主題色,亮色模式下請使用 getUpColor) static const Color up = darkTertiary; static const Color success = darkTertiary; - /// 跌/卖出/错误 - 使用 Material Design 3 error + /// 跌/賣出/錯誤 - 使用 Material Design 3 error static const Color down = Color(0xFFff716c); static const Color error = down; - /// 静默/禁用/次要 + /// 靜默/禁用/次要 static const Color muted = darkOnSurfaceVariant; /// 警告 @@ -178,50 +178,50 @@ class AppColorScheme { static const Color info = Color(0xFF2196F3); // ============================================ - // 主题感知辅助函数 - 已迁移至 AppThemeColors ThemeExtension - // 以下方法保留仅供 AppThemeColors 工厂内部使用 + // 主題感知輔助函數 - 已遷移至 AppThemeColors ThemeExtension + // 以下方法保留僅供 AppThemeColors 工廠內部使用 // ============================================ static const Color buyButtonFill = Color(0xFF059669); - /// 交易按钮卖出色 - 深红色填充,确保白色文字可读 + /// 交易按鈕賣出色 - 深紅色填充,確保白色文字可讀 static const Color sellButtonFill = Color(0xFFDC2626); // ============================================ - // 渐变预设 + // 漸變預設 // ============================================ - /// 深色 CTA 渐变 (primary → primary_container, 135度) + /// 深色 CTA 漸變 (primary → primary_container, 135度) static const LinearGradient darkCtaGradient = LinearGradient( colors: [darkPrimary, darkPrimaryContainer], begin: Alignment(-0.7, -0.7), end: Alignment(0.7, 0.7), ); - /// 浅色 CTA 渐变 + /// 淺色 CTA 漸變 static const LinearGradient lightCtaGradient = LinearGradient( colors: [lightPrimary, lightPrimaryContainer], begin: Alignment(-0.7, -0.7), end: Alignment(0.7, 0.7), ); - /// 兼容别名 + /// 兼容別名 static const LinearGradient ctaGradient = darkCtaGradient; - /// 买入按钮渐变 + /// 買入按鈕漸變 static const LinearGradient buyGradient = LinearGradient( colors: [darkTertiary, darkTertiaryContainer], begin: Alignment(-0.7, -0.7), end: Alignment(0.7, 0.7), ); - /// 卖出按钮渐变 + /// 賣出按鈕漸變 static const LinearGradient sellGradient = LinearGradient( colors: [darkError, darkErrorDim], begin: Alignment(-0.7, -0.7), end: Alignment(0.7, 0.7), ); - /// 资产卡片渐变 - 金色层次 + /// 資產卡片漸變 - 金色層次 static const LinearGradient assetCardGradient = LinearGradient( colors: [darkPrimaryContainer, darkPrimary], begin: Alignment.topLeft, @@ -229,7 +229,7 @@ class AppColorScheme { ); // ============================================ - // Shadcn ColorScheme - 深色主题 + // Shadcn ColorScheme - 深色主題 // ============================================ static ShadColorScheme get darkShad => ShadColorScheme( @@ -256,7 +256,7 @@ class AppColorScheme { ); // ============================================ - // Shadcn ColorScheme - 浅色主题 + // Shadcn ColorScheme - 淺色主題 // ============================================ static ShadColorScheme get lightShad => ShadColorScheme( @@ -283,7 +283,7 @@ class AppColorScheme { ); // ============================================ - // Material ColorScheme - 深色主题 (Material Design 3) + // Material ColorScheme - 深色主題 (Material Design 3) // ============================================ static ColorScheme get darkMaterial => ColorScheme.dark( @@ -322,17 +322,17 @@ class AppColorScheme { ); // ============================================ - // Material ColorScheme - 浅色主题 + // Material ColorScheme - 淺色主題 // ============================================ - /// 浅色主题 Error 色 + /// 淺色主題 Error 色 static const Color lightError = Color(0xFFDC2626); static const Color lightOnError = Color(0xFFFFFFFF); - /// 浅色主题 Outline 色 - Slate 500 + /// 淺色主題 Outline 色 - Slate 500 static const Color lightOutline = Color(0xFF64748B); - /// 浅色主题 Surface 色 (扩展) - Slate 系列 + /// 淺色主題 Surface 色 (擴展) - Slate 系列 static const Color lightSurfaceBright = Color(0xFFFFFFFF); static const Color lightSurfaceDim = Color(0xFFE2E8F0); static const Color lightSurfaceVariant = Color(0xFFE2E8F0); @@ -376,12 +376,12 @@ class AppColorScheme { ); // ============================================ - // 兼容性别名 - 仅保留有外部引用的 + // 兼容性別名 - 僅保留有外部引用的 // (buyButtonFill, sellButtonFill, darkCtaGradient, lightCtaGradient, - // buyGradient, sellGradient 已在上方定义,此处无需重复) + // buyGradient, sellGradient 已在上方定義,此處無需重複) // ============================================ - /// 获取买入按钮渐变(主题感知)- 用于盈利展示 + /// 獲取買入按鈕漸變(主題感知)- 用於盈利展示 } diff --git a/flutter_monisuo/lib/core/theme/app_spacing.dart b/flutter_monisuo/lib/core/theme/app_spacing.dart index 47ca9e0..eeac8d0 100644 --- a/flutter_monisuo/lib/core/theme/app_spacing.dart +++ b/flutter_monisuo/lib/core/theme/app_spacing.dart @@ -1,22 +1,22 @@ import 'package:flutter/material.dart'; -/// 间距系统 +/// 間距系統 /// -/// 使用 4px 基础单位,确保一致性 +/// 使用 4px 基礎單位,確保一致性 class AppSpacing { AppSpacing._(); // ============================================ - // 基础间距 (Base Spacing) + // 基礎間距 (Base Spacing) // ============================================ - /// 极小 - 4px + /// 極小 - 4px static const double xs = 4.0; /// 小 - 8px static const double sm = 8.0; - /// 中 - 16px (默认) + /// 中 - 16px (默認) static const double md = 16.0; /// 大 - 24px @@ -29,28 +29,28 @@ class AppSpacing { static const double xxl = 48.0; // ============================================ - // 预设 EdgeInsets + // 預設 EdgeInsets // ============================================ - /// 页面内边距 + /// 頁面內邊距 static const EdgeInsets pagePadding = EdgeInsets.all(md); - /// 卡片内边距 + /// 卡片內邊距 static const EdgeInsets cardPadding = EdgeInsets.all(md); - /// 列表项内边距 + /// 列表項內邊距 static const EdgeInsets listItemPadding = EdgeInsets.symmetric( horizontal: md, vertical: sm, ); - /// 按钮内边距 + /// 按鈕內邊距 static const EdgeInsets buttonPadding = EdgeInsets.symmetric( horizontal: lg, vertical: 14, ); - /// 输入框内边距 + /// 輸入框內邊距 static const EdgeInsets inputPadding = EdgeInsets.symmetric( horizontal: md, vertical: 14, @@ -60,98 +60,98 @@ class AppSpacing { // 便捷方法 // ============================================ - /// 获取水平间距 + /// 獲取水平間距 static SizedBox horizontal(double spacing) => SizedBox(width: spacing); - /// 获取垂直间距 + /// 獲取垂直間距 static SizedBox vertical(double spacing) => SizedBox(height: spacing); } -/// 圆角系统 - "The Kinetic Vault" & "The Ethereal Terminal" 规范 +/// 圓角系統 - "The Kinetic Vault" & "The Ethereal Terminal" 規範 /// -/// 设计规则: -/// - 按钮: xxl (24px / 1.5rem) +/// 設計規則: +/// - 按鈕: xxl (24px / 1.5rem) /// - 卡片: xl (16px) -/// - 输入框: md (8px) -/// - 标签: sm (4px) +/// - 輸入框: md (8px) +/// - 標籤: sm (4px) class AppRadius { AppRadius._(); // ============================================ - // 基础圆角 (Base Radius) + // 基礎圓角 (Base Radius) // ============================================ - /// 小圆角 - 6px (标签、徽章) — 对齐 Pencil $radius-sm + /// 小圓角 - 6px (標籤、徽章) — 對齊 Pencil $radius-sm static const double sm = 6.0; - /// 中圆角 - 10px (输入框、标签页) — 对齐 Pencil $radius-md + /// 中圓角 - 10px (輸入框、標籤頁) — 對齊 Pencil $radius-md static const double md = 10.0; - /// 大圆角 - 14px (卡片、按钮、列表) — 对齐 Pencil $radius-lg + /// 大圓角 - 14px (卡片、按鈕、列表) — 對齊 Pencil $radius-lg static const double lg = 14.0; - /// 特大圆角 - 20px (大卡片、弹窗) — 对齐 Pencil $radius-xl + /// 特大圓角 - 20px (大卡片、彈窗) — 對齊 Pencil $radius-xl static const double xl = 20.0; - /// 超大圆角 - 24px (按钮、模态框、底部抽屉) + /// 超大圓角 - 24px (按鈕、模態框、底部抽屜) static const double xxl = 24.0; - /// 圆形 - 9999px (Pill buttons) + /// 圓形 - 9999px (Pill buttons) static const double full = 9999.0; // ============================================ - // 预设 BorderRadius + // 預設 BorderRadius // ============================================ - /// 小圆角 + /// 小圓角 static BorderRadius get radiusSm => BorderRadius.circular(sm); - /// 中圆角 + /// 中圓角 static BorderRadius get radiusMd => BorderRadius.circular(md); - /// 大圆角 + /// 大圓角 static BorderRadius get radiusLg => BorderRadius.circular(lg); - /// 特大圆角 + /// 特大圓角 static BorderRadius get radiusXl => BorderRadius.circular(xl); - /// 超大圆角 + /// 超大圓角 static BorderRadius get radiusXxl => BorderRadius.circular(xxl); - /// 圆形 + /// 圓形 static BorderRadius get radiusFull => BorderRadius.circular(full); } -/// 响应式断点 +/// 響應式斷點 class AppBreakpoints { AppBreakpoints._(); - /// 手机竖屏 + /// 手機豎屏 static const double mobile = 360; - /// 手机横屏/小平板 + /// 手機橫屏/小平板 static const double tablet = 768; /// 平板/桌面 static const double desktop = 1024; - /// 检查是否为手机 + /// 檢查是否為手機 static bool isMobile(BuildContext context) { return MediaQuery.of(context).size.width < tablet; } - /// 检查是否为平板 + /// 檢查是否為平板 static bool isTablet(BuildContext context) { final width = MediaQuery.of(context).size.width; return width >= tablet && width < desktop; } - /// 检查是否为桌面 + /// 檢查是否為桌面 static bool isDesktop(BuildContext context) { return MediaQuery.of(context).size.width >= desktop; } - /// 根据屏幕宽度获取响应式值 + /// 根據屏幕寬度獲取響應式值 static T responsive( BuildContext context, { required T mobile, @@ -168,14 +168,14 @@ class AppBreakpoints { } } -/// 触摸目标尺寸 +/// 觸摸目標尺寸 class AppTouchTarget { AppTouchTarget._(); - /// 最小触摸目标 - 44x44 (iOS HIG 标准) + /// 最小觸摸目標 - 44x44 (iOS HIG 標準) static const double minSize = 44.0; - /// 确保触摸目标足够大 + /// 確保觸摸目標足夠大 static Widget ensureMinSize({ required Widget child, double minSize = AppTouchTarget.minSize, diff --git a/flutter_monisuo/lib/core/theme/app_theme.dart b/flutter_monisuo/lib/core/theme/app_theme.dart index 6d1f280..c9773ed 100644 --- a/flutter_monisuo/lib/core/theme/app_theme.dart +++ b/flutter_monisuo/lib/core/theme/app_theme.dart @@ -4,12 +4,12 @@ import 'app_color_scheme.dart'; import 'app_spacing.dart'; import 'app_theme_extension.dart'; -/// "The Kinetic Vault" & "The Ethereal Terminal" 主题配置 +/// "The Kinetic Vault" & "The Ethereal Terminal" 主題配置 class AppTheme { AppTheme._(); // ============================================ - // 深色主题 - "The Kinetic Vault" + // 深色主題 - "The Kinetic Vault" // ============================================ static ThemeData get darkTheme { @@ -23,7 +23,7 @@ class AppTheme { AppThemeColors.dark(), ], - // AppBar - 无边框规则 + // AppBar - 無邊框規則 appBarTheme: AppBarTheme( backgroundColor: AppColorScheme.darkBackground, foregroundColor: AppColorScheme.darkOnSurface, @@ -37,7 +37,7 @@ class AppTheme { ), ), - // 卡片 - 无边框,使用 surface 层次 + // 卡片 - 無邊框,使用 surface 層次 cardTheme: CardThemeData( color: AppColorScheme.darkSurface, elevation: 0, @@ -46,7 +46,7 @@ class AppTheme { ), ), - // 输入框 - Ghost Border 风格 + // 輸入框 - Ghost Border 風格 inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: AppColorScheme.darkSurfaceLow, @@ -73,7 +73,7 @@ class AppTheme { ), ), - // 按钮 - Pencil accent-primary (Gold) + // 按鈕 - Pencil accent-primary (Gold) elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: AppColorScheme.darkSecondary, @@ -97,13 +97,13 @@ class AppTheme { ), ), - // 分割线 - 使用层次而非边框 + // 分割線 - 使用層次而非邊框 dividerTheme: DividerThemeData( color: AppColorScheme.darkOutlineVariant.withValues(alpha: 0.1), thickness: 1, ), - // 底部导航 + // 底部導航 bottomNavigationBarTheme: BottomNavigationBarThemeData( backgroundColor: AppColorScheme.darkSurface, selectedItemColor: AppColorScheme.darkPrimary, @@ -115,7 +115,7 @@ class AppTheme { } // ============================================ - // 浅色主题 - "The Ethereal Terminal" + // 淺色主題 - "The Ethereal Terminal" // ============================================ static ThemeData get lightTheme { @@ -152,7 +152,7 @@ class AppTheme { ), ), - // 输入框 - 底部线条风格 + // 輸入框 - 底部線條風格 inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: AppColorScheme.lightSurfaceLow, @@ -181,7 +181,7 @@ class AppTheme { ), ), - // 按钮 - Pencil accent-primary (dark gray) + // 按鈕 - Pencil accent-primary (dark gray) elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF1F2937), @@ -205,13 +205,13 @@ class AppTheme { ), ), - // 分割线 - 不使用,用留白代替 + // 分割線 - 不使用,用留白代替 dividerTheme: DividerThemeData( color: AppColorScheme.lightOutlineVariant.withValues(alpha: 0.2), thickness: 1, ), - // 底部导航 + // 底部導航 bottomNavigationBarTheme: BottomNavigationBarThemeData( backgroundColor: AppColorScheme.lightSurfaceHighest, selectedItemColor: AppColorScheme.lightPrimary, @@ -223,19 +223,19 @@ class AppTheme { } } -/// Pencil 设计系统字体规范 +/// Pencil 設計系統字體規範 /// -/// 对齐 Pencil 变量: Inter 字体, 明确的字号/字重层级 -/// 28px (总资产) → 24px (精选价格) → 22px (页面标题) → 16px (区块标题) -/// → 14px (卡片标题/价格) → 13px (正文) → 12px (标签/副标题) → 11px (小文字) +/// 對齊 Pencil 變量: Inter 字體, 明確的字號/字重層級 +/// 28px (總資產) → 24px (精選價格) → 22px (頁面標題) → 16px (區塊標題) +/// → 14px (卡片標題/價格) → 13px (正文) → 12px (標籤/副標題) → 11px (小文字) class AppTextStyles { AppTextStyles._(); // ============================================ - // Display - 核心数字 + // Display - 核心數字 // ============================================ - /// D1 - 总资产/余额 (28px w700) — Pencil $hero-value + /// D1 - 總資產/餘額 (28px w700) — Pencil $hero-value static TextStyle displayLarge(BuildContext context) => GoogleFonts.inter( fontSize: 28, fontWeight: FontWeight.w700, @@ -244,7 +244,7 @@ class AppTextStyles { letterSpacing: -0.5, ); - /// D2 - 精选价格 (24px w700) — Pencil 行情卡片价格 + /// D2 - 精選價格 (24px w700) — Pencil 行情卡片價格 static TextStyle displayMedium(BuildContext context) => GoogleFonts.inter( fontSize: 24, fontWeight: FontWeight.w700, @@ -252,7 +252,7 @@ class AppTextStyles { height: 1.15, ); - /// D3 - 页面标题 (22px w700) — Pencil 页面大标题 + /// D3 - 頁面標題 (22px w700) — Pencil 頁面大標題 static TextStyle displaySmall(BuildContext context) => GoogleFonts.inter( fontSize: 22, fontWeight: FontWeight.w700, @@ -261,10 +261,10 @@ class AppTextStyles { ); // ============================================ - // Headline - 标题 + // Headline - 標題 // ============================================ - /// 区块/导航标题 (16px w600) — Pencil $section-title + /// 區塊/導航標題 (16px w600) — Pencil $section-title static TextStyle headlineLarge(BuildContext context) => GoogleFonts.inter( fontSize: 16, fontWeight: FontWeight.w600, @@ -272,7 +272,7 @@ class AppTextStyles { height: 1.3, ); - /// 卡片标题/价格/标签页 (14px w600) — Pencil $card-title + /// 卡片標題/價格/標籤頁 (14px w600) — Pencil $card-title static TextStyle headlineMedium(BuildContext context) => GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w600, @@ -280,7 +280,7 @@ class AppTextStyles { height: 1.35, ); - /// 副标题/持仓价值 (13px w500) + /// 副標題/持倉價值 (13px w500) static TextStyle headlineSmall(BuildContext context) => GoogleFonts.inter( fontSize: 13, fontWeight: FontWeight.w500, @@ -300,7 +300,7 @@ class AppTextStyles { height: 1.45, ); - /// 次要正文/副标题 (12px w400) — Pencil $subtitle + /// 次要正文/副標題 (12px w400) — Pencil $subtitle static TextStyle bodyMedium(BuildContext context) => GoogleFonts.inter( fontSize: 12, fontWeight: FontWeight.w400, @@ -308,7 +308,7 @@ class AppTextStyles { height: 1.45, ); - /// 辅助文字/币种全名 (11px w400) — Pencil $small-text + /// 輔助文字/幣種全名 (11px w400) — Pencil $small-text static TextStyle bodySmall(BuildContext context) => GoogleFonts.inter( fontSize: 11, fontWeight: FontWeight.w400, @@ -317,10 +317,10 @@ class AppTextStyles { ); // ============================================ - // Label - 标签 + // Label - 標籤 // ============================================ - /// 按钮/标签页标签 (12px w500) — Pencil $tab-label + /// 按鈕/標籤頁標籤 (12px w500) — Pencil $tab-label static TextStyle labelLarge(BuildContext context) => GoogleFonts.inter( fontSize: 12, fontWeight: FontWeight.w500, @@ -328,7 +328,7 @@ class AppTextStyles { height: 1.35, ); - /// 涨跌幅标签 (11px w500) — Pencil $change-badge + /// 漲跌幅標籤 (11px w500) — Pencil $change-badge static TextStyle labelMedium(BuildContext context) => GoogleFonts.inter( fontSize: 11, fontWeight: FontWeight.w500, @@ -336,7 +336,7 @@ class AppTextStyles { height: 1.35, ); - /// 涨跌幅标签-粗 (11px w600) — Pencil $change-badge-bold + /// 漲跌幅標籤-粗 (11px w600) — Pencil $change-badge-bold static TextStyle labelSmall(BuildContext context) => GoogleFonts.inter( fontSize: 11, fontWeight: FontWeight.w600, @@ -345,10 +345,10 @@ class AppTextStyles { ); // ============================================ - // 数字/金额 - Inter (等宽特性) + // 數字/金額 - Inter (等寬特性) // ============================================ - /// 大号数字 (28px w700) - 总资产、余额 + /// 大號數字 (28px w700) - 總資產、餘額 static TextStyle numberLarge(BuildContext context) => GoogleFonts.inter( fontSize: 28, fontWeight: FontWeight.w700, @@ -358,7 +358,7 @@ class AppTextStyles { fontFeatures: const [FontFeature.tabularFigures()], ); - /// 中号数字 (14px w600) - 价格、金额 + /// 中號數字 (14px w600) - 價格、金額 static TextStyle numberMedium(BuildContext context) => GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w600, @@ -367,7 +367,7 @@ class AppTextStyles { fontFeatures: const [FontFeature.tabularFigures()], ); - /// 小号数字 (12px w500) - 涨跌幅、数量 + /// 小號數字 (12px w500) - 漲跌幅、數量 static TextStyle numberSmall(BuildContext context) => GoogleFonts.inter( fontSize: 12, fontWeight: FontWeight.w500, @@ -377,7 +377,7 @@ class AppTextStyles { ); } -/// 动画时长 +/// 動畫時長 class AnimationDurations { AnimationDurations._(); diff --git a/flutter_monisuo/lib/core/theme/app_theme_extension.dart b/flutter_monisuo/lib/core/theme/app_theme_extension.dart index 6ce652f..c82ad73 100644 --- a/flutter_monisuo/lib/core/theme/app_theme_extension.dart +++ b/flutter_monisuo/lib/core/theme/app_theme_extension.dart @@ -1,48 +1,48 @@ import 'package:flutter/material.dart'; import 'app_color_scheme.dart'; -/// 自定义主题扩展 — 注册到 ThemeData.extensions 中 +/// 自定義主題擴展 — 註冊到 ThemeData.extensions 中 /// -/// 存放 ColorScheme 标准槽位无法覆盖的语义色: -/// - 卡片背景语义色(dark/light 使用不同 surface 层级) -/// - 涨跌金融色(含带透明度的背景色) -/// - 渐变预设 +/// 存放 ColorScheme 標準槽位無法覆蓋的語義色: +/// - 卡片背景語義色(dark/light 使用不同 surface 層級) +/// - 漲跌金融色(含帶透明度的背景色) +/// - 漸變預設 /// - 光效透明度等 @immutable class AppThemeColors extends ThemeExtension { - // ---- 卡片背景语义色 ---- - /// 标准卡片背景(dark: surfaceContainer, light: surfaceContainerHigh) + // ---- 卡片背景語義色 ---- + /// 標準卡片背景(dark: surfaceContainer, light: surfaceContainerHigh) final Color surfaceCard; /// 高亮卡片背景(dark: surfaceContainerHighest, light: surfaceContainerHigh) final Color surfaceCardHigh; - // ---- 文字语义 ---- - /// 弱化/辅助文字 + // ---- 文字語義 ---- + /// 弱化/輔助文字 final Color onSurfaceMuted; - // ---- 涨跌金融色 ---- - /// 涨/盈利/买入 + // ---- 漲跌金融色 ---- + /// 漲/盈利/買入 final Color up; final Color upBackground; - /// 跌/亏损/卖出 + /// 跌/虧損/賣出 final Color down; final Color downBackground; - // ---- 强调色 ---- - /// 主强调色(dark: primary 金色, light: primary 深灰) + // ---- 強調色 ---- + /// 主強調色(dark: primary 金色, light: primary 深灰) final Color accentPrimary; // ---- 光效 ---- - /// 光晕透明度(dark: 0.15, light: 0.08) + /// 光暈透明度(dark: 0.15, light: 0.08) final double glowOpacity; - // ---- 边框 ---- - /// Ghost Border(outlineVariant 带透明度) + // ---- 邊框 ---- + /// Ghost Border(outlineVariant 帶透明度) final Color ghostBorder; - // ---- 渐变预设 ---- + // ---- 漸變預設 ---- final LinearGradient ctaGradient; final LinearGradient buyGradient; final LinearGradient sellGradient; @@ -67,7 +67,7 @@ class AppThemeColors extends ThemeExtension { required this.emeraldGradient, }); - /// 深色主题工厂 + /// 深色主題工廠 factory AppThemeColors.dark() => AppThemeColors( surfaceCard: AppColorScheme.darkSurfaceContainer, surfaceCardHigh: AppColorScheme.darkSurfaceContainerHighest, @@ -90,7 +90,7 @@ class AppThemeColors extends ThemeExtension { ), ); - /// 浅色主题工厂 + /// 淺色主題工廠 factory AppThemeColors.light() => AppThemeColors( surfaceCard: AppColorScheme.lightSurfaceLowest, surfaceCardHigh: AppColorScheme.lightSurfaceContainer, @@ -198,23 +198,23 @@ class AppThemeColors extends ThemeExtension { static double lerpDouble(double a, double b, double t) => a + (b - a) * t; } -/// BuildContext 主题快捷扩展 +/// BuildContext 主題快捷擴展 /// /// 用法: /// context.colors.primary → Theme.of(context).colorScheme.primary -/// context.appColors.up → AppThemeColors 中的涨色 +/// context.appColors.up → AppThemeColors 中的漲色 /// context.isDark → 是否深色模式 extension AppThemeContext on BuildContext { - /// Material ColorScheme 快捷访问 + /// Material ColorScheme 快捷訪問 ColorScheme get colors => Theme.of(this).colorScheme; - /// 自定义语义色快捷访问 + /// 自定義語義色快捷訪問 AppThemeColors get appColors => Theme.of(this).extension()!; /// 是否深色模式 bool get isDark => Theme.of(this).brightness == Brightness.dark; - /// TextTheme 快捷访问 + /// TextTheme 快捷訪問 TextTheme get textStyles => Theme.of(this).textTheme; } diff --git a/flutter_monisuo/lib/core/utils/toast_utils.dart b/flutter_monisuo/lib/core/utils/toast_utils.dart index b06c9c0..f5f4d68 100644 --- a/flutter_monisuo/lib/core/utils/toast_utils.dart +++ b/flutter_monisuo/lib/core/utils/toast_utils.dart @@ -1,13 +1,13 @@ import 'package:flutter/material.dart'; import 'package:bot_toast/bot_toast.dart'; -/// Toast 工具类 - 提供统一的 toast 提示功能 +/// Toast 工具類 - 提供統一的 toast 提示功能 /// -/// 使用 bot_toast 实现,确保 toast 显示在所有弹窗之上 +/// 使用 bot_toast 實現,確保 toast 顯示在所有彈窗之上 class ToastUtils { ToastUtils._(); - /// 显示普通提示 + /// 顯示普通提示 static void show(String message, {Duration? duration}) { BotToast.showCustomText( toastBuilder: (_) => _buildToastWidget(message), @@ -18,7 +18,7 @@ class ToastUtils { ); } - /// 显示成功提示 + /// 顯示成功提示 static void showSuccess(String message, {Duration? duration}) { BotToast.showCustomText( toastBuilder: (_) => _buildToastWidget( @@ -32,7 +32,7 @@ class ToastUtils { ); } - /// 显示错误提示 + /// 顯示錯誤提示 static void showError(String message, {Duration? duration}) { BotToast.showCustomText( toastBuilder: (_) => _buildToastWidget( @@ -46,7 +46,7 @@ class ToastUtils { ); } - /// 显示警告提示 + /// 顯示警告提示 static void showWarning(String message, {Duration? duration}) { BotToast.showCustomText( toastBuilder: (_) => _buildToastWidget( @@ -60,7 +60,7 @@ class ToastUtils { ); } - /// 构建 toast widget + /// 構建 toast widget static Widget _buildToastWidget( String message, { Color? backgroundColor, diff --git a/flutter_monisuo/lib/data/models/account_models.dart b/flutter_monisuo/lib/data/models/account_models.dart index 56cc93b..687a33f 100644 --- a/flutter_monisuo/lib/data/models/account_models.dart +++ b/flutter_monisuo/lib/data/models/account_models.dart @@ -1,4 +1,4 @@ -/// 资产总览模型 +/// 資產總覽模型 class AssetOverview { final String totalAsset; final String fundBalance; @@ -22,7 +22,7 @@ class AssetOverview { } } -/// 资金账户模型 +/// 資金賬戶模型 class AccountFund { final int id; final int userId; @@ -51,7 +51,7 @@ class AccountFund { } } -/// 交易账户模型(持仓) +/// 交易賬戶模型(持倉) class AccountTrade { final int id; final int userId; @@ -78,7 +78,7 @@ class AccountTrade { }); factory AccountTrade.fromJson(Map json) { - // 后端返回 value(当前价值),前端用 currentValue + // 後端返回 value(當前價值),前端用 currentValue final quantityNum = double.tryParse(json['quantity']?.toString() ?? '0') ?? 0; final avgPriceNum = @@ -108,7 +108,7 @@ class AccountTrade { ); } - /// 格式化盈亏率 + /// 格式化盈虧率 String get formattedProfitRate { final prefix = profitRate >= 0 ? '+' : ''; return '$prefix${profitRate.toStringAsFixed(2)}%'; @@ -118,7 +118,7 @@ class AccountTrade { bool get isProfit => profitRate >= 0; } -/// 资金流水模型 +/// 資金流水模型 class AccountFlow { final int id; final int userId; @@ -155,26 +155,26 @@ class AccountFlow { ); } - /// 流水类型文字 + /// 流水類型文字 String get flowTypeText { switch (flowType) { case '1': return '充值'; case '2': - return '提现'; + return '提現'; case '3': - return '转入交易账户'; + return '轉入交易賬戶'; case '4': - return '从交易账户转出'; + return '從交易賬戶轉出'; case '5': - return '卖出收入'; + return '賣出收入'; case '6': - return '买入支出'; + return '買入支出'; default: return '未知'; } } - /// 是否为收入 + /// 是否為收入 bool get isIncome => ['1', '3', '5'].contains(flowType); } diff --git a/flutter_monisuo/lib/data/models/coin.dart b/flutter_monisuo/lib/data/models/coin.dart index 935b0cf..690639e 100644 --- a/flutter_monisuo/lib/data/models/coin.dart +++ b/flutter_monisuo/lib/data/models/coin.dart @@ -1,4 +1,4 @@ -/// 币种模型 +/// 幣種模型 class Coin { final int id; final String code; @@ -7,7 +7,7 @@ class Coin { final double price; final double? priceUsd; final double? priceCny; - final int priceType; // 1=实时价格, 2=管理员设置 + final int priceType; // 1=實時價格, 2=管理員設置 final double change24h; final double? high24h; final double? low24h; @@ -70,7 +70,7 @@ class Coin { }; } - /// 显示图标(Unicode 符号) + /// 顯示圖標(Unicode 符號) String get displayIcon { const icons = { 'BTC': '\u20BF', @@ -85,22 +85,22 @@ class Coin { return icons[code] ?? '\u25CF'; } - /// 格式化价格显示 + /// 格式化價格顯示 String get formattedPrice { if (price >= 1000) return price.toStringAsFixed(2); if (price >= 1) return price.toStringAsFixed(4); return price.toStringAsFixed(6); } - /// 格式化涨跌幅 + /// 格式化漲跌幅 String get formattedChange { final prefix = change24h >= 0 ? '+' : ''; return '$prefix${change24h.toStringAsFixed(2)}%'; } - /// 是否上涨 + /// 是否上漲 bool get isUp => change24h >= 0; - /// 是否为实时价格 + /// 是否為實時價格 bool get isRealtime => priceType == 1; } diff --git a/flutter_monisuo/lib/data/models/order_models.dart b/flutter_monisuo/lib/data/models/order_models.dart index ef06289..ac47011 100644 --- a/flutter_monisuo/lib/data/models/order_models.dart +++ b/flutter_monisuo/lib/data/models/order_models.dart @@ -1,14 +1,14 @@ -/// 交易订单模型 +/// 交易訂單模型 class OrderTrade { final int id; final String orderNo; final int userId; final String coinCode; - final int direction; // 1=买入, 2=卖出 + final int direction; // 1=買入, 2=賣出 final String price; final String quantity; final String amount; - final int status; // 1=待处理, 2=已完成, 3=已取消 + final int status; // 1=待處理, 2=已完成, 3=已取消 final DateTime? createTime; final DateTime? updateTime; @@ -47,13 +47,13 @@ class OrderTrade { } /// 方向文字 - String get directionText => direction == 1 ? '买入' : '卖出'; + String get directionText => direction == 1 ? '買入' : '賣出'; - /// 状态文字 + /// 狀態文字 String get statusText { switch (status) { case 1: - return '待处理'; + return '待處理'; case 2: return '已完成'; case 3: @@ -63,33 +63,33 @@ class OrderTrade { } } - /// 是否为买入 + /// 是否為買入 bool get isBuy => direction == 1; } -/// 充提订单模型 +/// 充提訂單模型 class OrderFund { final int id; final String orderNo; final int userId; final String username; - final int type; // 1=充值, 2=提现 + final int type; // 1=充值, 2=提現 final String amount; - final String? fee; // 手续费 - final String? receivableAmount; // 应收款项 + final String? fee; // 手續費 + final String? receivableAmount; // 應收款項 final int status; - // 充值状态: 1=待付款, 2=待确认, 3=已完成, 4=已驳回, 5=已取消 - // 提现状态: 1=待审批, 2=已出款, 3=已驳回, 4=已取消, 5=待财务审核 - final int? walletId; // 冷钱包ID(充值) - final String? walletAddress; // 钱包地址(充值/提现) - final String? network; // 提现网络类型 - final String? withdrawContact; // 提现联系方式 + // 充值狀態: 1=待付款, 2=待確認, 3=已完成, 4=已駁回, 5=已取消 + // 提現狀態: 1=待審批, 2=已出款, 3=已駁回, 4=已取消, 5=待財務審核 + final int? walletId; // 冷錢包ID(充值) + final String? walletAddress; // 錢包地址(充值/提現) + final String? network; // 提現網絡類型 + final String? withdrawContact; // 提現聯繫方式 final String remark; final String? rejectReason; final String? adminRemark; final DateTime? createTime; - final DateTime? payTime; // 用户确认打款时间 - final DateTime? confirmTime; // 管理员确认时间 + final DateTime? payTime; // 用戶確認打款時間 + final DateTime? confirmTime; // 管理員確認時間 OrderFund({ required this.id, @@ -143,72 +143,72 @@ class OrderFund { ); } - /// 订单类型文字 - String get typeText => type == 1 ? '充值' : '提现'; + /// 訂單類型文字 + String get typeText => type == 1 ? '充值' : '提現'; - /// 状态文字 (根据类型区分) + /// 狀態文字 (根據類型區分) String get statusText { if (type == 1) { - // 充值状态 + // 充值狀態 switch (status) { case 1: return '待付款'; case 2: - return '待确认'; + return '待確認'; case 3: return '已完成'; case 4: - return '已驳回'; + return '已駁回'; case 5: return '已取消'; default: return '未知'; } } else { - // 提现状态 + // 提現狀態 switch (status) { case 1: - return '待审批'; + return '待審批'; case 2: return '已出款'; case 3: - return '已驳回'; + return '已駁回'; case 4: return '已取消'; case 5: - return '待财务审核'; + return '待財務審核'; default: return '未知'; } } } - /// 是否为充值 + /// 是否為充值 bool get isDeposit => type == 1; /// 是否可取消 - /// 充值: 仅待付款可取消 - /// 提现: 仅待审批可取消 + /// 充值: 僅待付款可取消 + /// 提現: 僅待審批可取消 bool get canCancel { if (type == 1) { return status == 1; // 充值待付款 } else { - return status == 1; // 提现待审批 + return status == 1; // 提現待審批 } } - /// 是否可确认打款 (仅充值待付款) + /// 是否可確認打款 (僅充值待付款) bool get canConfirmPay => type == 1 && status == 1; } -/// 冷钱包模型 +/// 冷錢包模型 class ColdWallet { final int id; final String name; final String address; final String network; final bool isDefault; - final int status; // 0=禁用, 1=启用 + final int status; // 0=禁用, 1=啟用 final DateTime? createTime; ColdWallet({ diff --git a/flutter_monisuo/lib/data/models/user.dart b/flutter_monisuo/lib/data/models/user.dart index 45a0b05..b9208e5 100644 --- a/flutter_monisuo/lib/data/models/user.dart +++ b/flutter_monisuo/lib/data/models/user.dart @@ -1,4 +1,4 @@ -/// 用户模型 +/// 用戶模型 class User { final int id; final String username; @@ -62,21 +62,21 @@ class User { }; } - /// 获取头像显示文字(用户名首字母) + /// 獲取頭像顯示文字(用戶名首字母) String get avatarText => username.isNotEmpty ? username.substring(0, 1).toUpperCase() : 'U'; - /// KYC 状态文字 + /// KYC 狀態文字 String get kycStatusText { switch (kycStatus) { case 0: - return '未认证'; + return '未認證'; case 1: - return '审核中'; + return '審核中'; case 2: - return '已认证'; + return '已認證'; case 3: - return '认证失败'; + return '認證失敗'; default: return '未知'; } diff --git a/flutter_monisuo/lib/data/services/asset_service.dart b/flutter_monisuo/lib/data/services/asset_service.dart index edfb29e..ca1a14b 100644 --- a/flutter_monisuo/lib/data/services/asset_service.dart +++ b/flutter_monisuo/lib/data/services/asset_service.dart @@ -3,13 +3,13 @@ import '../../core/network/api_response.dart'; import '../../core/network/dio_client.dart'; import '../models/account_models.dart'; -/// 资产服务 +/// 資產服務 class AssetService { final DioClient _client; AssetService(this._client); - /// 获取资产总览 + /// 獲取資產總覽 Future> getOverview() async { final response = await _client.get>( ApiEndpoints.assetOverview, @@ -21,17 +21,17 @@ class AssetService { response.message, ); } - return ApiResponse.fail(response.message ?? '获取资产总览失败'); + return ApiResponse.fail(response.message ?? '獲取資產總覽失敗'); } - /// 获取资金账户 + /// 獲取資金賬戶 Future> getFundAccount() async { final response = await _client.get>( ApiEndpoints.fundAccount, ); if (response.success && response.data != null) { - // 后端返回格式: {"fund": {...}} + // 後端返回格式: {"fund": {...}} final fundData = response.data!['fund'] as Map?; if (fundData != null) { return ApiResponse.success( @@ -40,25 +40,25 @@ class AssetService { ); } } - return ApiResponse.fail(response.message ?? '获取资金账户失败'); + return ApiResponse.fail(response.message ?? '獲取資金賬戶失敗'); } - /// 获取交易账户 + /// 獲取交易賬戶 Future>> getTradeAccount() async { final response = await _client.get>( ApiEndpoints.tradeAccount, ); if (response.success && response.data != null) { - // 后端返回格式: {"positions": [...]} + // 後端返回格式: {"positions": [...]} final list = response.data!['positions'] as List?; final accounts = list?.map((e) => AccountTrade.fromJson(e as Map)).toList() ?? []; return ApiResponse.success(accounts, response.message); } - return ApiResponse.fail(response.message ?? '获取交易账户失败'); + return ApiResponse.fail(response.message ?? '獲取交易賬戶失敗'); } - /// 资金划转 + /// 資金劃轉 Future> transfer({ required int direction, required String amount, @@ -72,7 +72,7 @@ class AssetService { ); } - /// 获取资金流水 + /// 獲取資金流水 Future>> getFlow({ int? flowType, int pageNum = 1, @@ -90,7 +90,7 @@ class AssetService { ); } - /// 获取每日盈亏数据 + /// 獲取每日盈虧數據 Future>> getDailyProfit({ required int year, required int month, @@ -102,6 +102,6 @@ class AssetService { if (response.success && response.data != null) { return ApiResponse.success(response.data!, response.message); } - return ApiResponse.fail(response.message ?? '获取每日盈亏数据失败'); + return ApiResponse.fail(response.message ?? '獲取每日盈虧數據失敗'); } } diff --git a/flutter_monisuo/lib/data/services/bonus_service.dart b/flutter_monisuo/lib/data/services/bonus_service.dart index 1188109..06c7f91 100644 --- a/flutter_monisuo/lib/data/services/bonus_service.dart +++ b/flutter_monisuo/lib/data/services/bonus_service.dart @@ -2,13 +2,13 @@ import '../../core/constants/api_endpoints.dart'; import '../../core/network/api_response.dart'; import '../../core/network/dio_client.dart'; -/// 福利中心服务 +/// 福利中心服務 class BonusService { final DioClient _client; BonusService(this._client); - /// 获取福利中心状态 + /// 獲取福利中心狀態 Future>> getWelfareStatus() async { final response = await _client.get>( ApiEndpoints.bonusWelfare, @@ -16,10 +16,10 @@ class BonusService { if (response.success && response.data != null) { return ApiResponse.success(response.data!, response.message); } - return ApiResponse.fail(response.message ?? '获取福利状态失败'); + return ApiResponse.fail(response.message ?? '獲取福利狀態失敗'); } - /// 领取首充福利 + /// 領取首充福利 Future>> claimNewUserBonus() async { return _client.post>( ApiEndpoints.bonusClaim, @@ -27,7 +27,7 @@ class BonusService { ); } - /// 领取推广奖励 + /// 領取推廣獎勵 Future>> claimReferralBonus( int referredUserId, int milestone, @@ -41,4 +41,21 @@ class BonusService { }, ); } + + /// 領取間接推廣獎勵 + Future>> claimIndirectReferralBonus( + int directReferralId, + int indirectReferredUserId, + int milestone, + ) async { + return _client.post>( + ApiEndpoints.bonusClaim, + data: { + 'type': 'indirect_referral', + 'directReferralId': directReferralId, + 'indirectReferredUserId': indirectReferredUserId, + 'milestone': milestone, + }, + ); + } } diff --git a/flutter_monisuo/lib/data/services/fund_service.dart b/flutter_monisuo/lib/data/services/fund_service.dart index c44124f..0f2c2d1 100644 --- a/flutter_monisuo/lib/data/services/fund_service.dart +++ b/flutter_monisuo/lib/data/services/fund_service.dart @@ -3,13 +3,13 @@ import '../../core/network/api_response.dart'; import '../../core/network/dio_client.dart'; import '../models/order_models.dart'; -/// 充提服务 +/// 充提服務 class FundService { final DioClient _client; FundService(this._client); - /// 获取默认钱包地址 + /// 獲取默認錢包地址 Future> getDefaultWallet() async { final response = await _client.get>( ApiEndpoints.defaultWallet, @@ -21,10 +21,10 @@ class FundService { response.message, ); } - return ApiResponse.fail(response.message ?? '获取钱包地址失败'); + return ApiResponse.fail(response.message ?? '獲取錢包地址失敗'); } - /// 申请充值 + /// 申請充值 /// 返回包含 orderNo, amount, status, walletAddress, walletNetwork 的信息 Future>> deposit({ required String amount, @@ -39,7 +39,7 @@ class FundService { ); } - /// 用户确认已打款 + /// 用戶確認已打款 Future> confirmPay(String orderNo) async { return _client.post( ApiEndpoints.confirmPay, @@ -47,7 +47,7 @@ class FundService { ); } - /// 申请提现 + /// 申請提現 Future>> withdraw({ required String amount, required String withdrawAddress, @@ -67,7 +67,7 @@ class FundService { ); } - /// 获取可用的提现网络列表 + /// 獲取可用的提現網絡列表 Future>> getWalletNetworks() async { final response = await _client.get>( ApiEndpoints.walletNetworks, @@ -78,10 +78,10 @@ class FundService { response.message, ); } - return ApiResponse.fail(response.message ?? '获取网络列表失败'); + return ApiResponse.fail(response.message ?? '獲取網絡列表失敗'); } - /// 取消订单 + /// 取消訂單 Future> cancelOrder(String orderNo) async { return _client.post( ApiEndpoints.cancelOrder, @@ -89,7 +89,7 @@ class FundService { ); } - /// 获取充提记录 + /// 獲取充提記錄 Future>> getOrders({ int? type, int pageNum = 1, @@ -107,7 +107,7 @@ class FundService { ); } - /// 解析充提记录列表 + /// 解析充提記錄列表 List parseOrderList(List? list) { if (list == null) return []; return list.map((e) => OrderFund.fromJson(e as Map)).toList(); diff --git a/flutter_monisuo/lib/data/services/market_service.dart b/flutter_monisuo/lib/data/services/market_service.dart index fa7855e..934e5a9 100644 --- a/flutter_monisuo/lib/data/services/market_service.dart +++ b/flutter_monisuo/lib/data/services/market_service.dart @@ -3,13 +3,13 @@ import '../../core/network/api_response.dart'; import '../../core/network/dio_client.dart'; import '../models/coin.dart'; -/// 行情服务 +/// 行情服務 class MarketService { final DioClient _client; MarketService(this._client); - /// 获取币种列表 + /// 獲取幣種列表 Future>> getCoinList() async { final response = await _client.get>( ApiEndpoints.coinList, @@ -20,10 +20,10 @@ class MarketService { final coins = list?.map((e) => Coin.fromJson(e as Map)).toList() ?? []; return ApiResponse.success(coins, response.message); } - return ApiResponse.fail(response.message ?? '获取币种列表失败'); + return ApiResponse.fail(response.message ?? '獲取幣種列表失敗'); } - /// 获取币种详情 + /// 獲取幣種詳情 Future> getCoinDetail(String code) async { final response = await _client.get>( ApiEndpoints.coinDetail, @@ -36,10 +36,10 @@ class MarketService { response.message, ); } - return ApiResponse.fail(response.message ?? '获取币种详情失败'); + return ApiResponse.fail(response.message ?? '獲取幣種詳情失敗'); } - /// 搜索币种 + /// 搜索幣種 Future>> searchCoins(String keyword) async { final response = await _client.get>( ApiEndpoints.coinSearch, @@ -51,6 +51,6 @@ class MarketService { final coins = list?.map((e) => Coin.fromJson(e as Map)).toList() ?? []; return ApiResponse.success(coins, response.message); } - return ApiResponse.fail(response.message ?? '搜索失败'); + return ApiResponse.fail(response.message ?? '搜索失敗'); } } diff --git a/flutter_monisuo/lib/data/services/trade_service.dart b/flutter_monisuo/lib/data/services/trade_service.dart index 55f8b06..178115d 100644 --- a/flutter_monisuo/lib/data/services/trade_service.dart +++ b/flutter_monisuo/lib/data/services/trade_service.dart @@ -3,13 +3,13 @@ import '../../core/network/api_response.dart'; import '../../core/network/dio_client.dart'; import '../models/order_models.dart'; -/// 交易服务 +/// 交易服務 class TradeService { final DioClient _client; TradeService(this._client); - /// 买入 + /// 買入 Future>> buy({ required String coinCode, required String price, @@ -25,7 +25,7 @@ class TradeService { ); } - /// 卖出 + /// 賣出 Future>> sell({ required String coinCode, required String price, @@ -41,7 +41,7 @@ class TradeService { ); } - /// 获取交易记录 + /// 獲取交易記錄 Future>> getOrders({ String? coinCode, int? direction, @@ -61,7 +61,7 @@ class TradeService { ); } - /// 获取订单详情 + /// 獲取訂單詳情 Future> getOrderDetail(String orderNo) async { final response = await _client.get>( ApiEndpoints.tradeOrderDetail, @@ -74,6 +74,6 @@ class TradeService { response.message, ); } - return ApiResponse.fail(response.message ?? '获取订单详情失败'); + return ApiResponse.fail(response.message ?? '獲取訂單詳情失敗'); } } diff --git a/flutter_monisuo/lib/data/services/user_service.dart b/flutter_monisuo/lib/data/services/user_service.dart index 37cc738..13902b9 100644 --- a/flutter_monisuo/lib/data/services/user_service.dart +++ b/flutter_monisuo/lib/data/services/user_service.dart @@ -5,13 +5,13 @@ import '../../core/network/api_response.dart'; import '../../core/network/dio_client.dart'; import '../models/user.dart'; -/// 用户服务 +/// 用戶服務 class UserService { final DioClient _client; UserService(this._client); - /// 用户登录 + /// 用戶登錄 Future>> login( String username, String password, @@ -22,7 +22,7 @@ class UserService { ); } - /// 用户注册(multipart:含身份证图片和可选推广码) + /// 用戶註冊(multipart:含身份證圖片和可選推廣碼) Future>> register( String username, String password, { @@ -43,7 +43,7 @@ class UserService { ); } - /// 获取用户信息 + /// 獲取用戶信息 Future> getUserInfo() async { return _client.get( ApiEndpoints.userInfo, @@ -51,8 +51,8 @@ class UserService { ); } - /// 上传 KYC 资料(身份证正反面图片字节) - /// 使用 fromBytes 以兼容 Web 和移动端 + /// 上傳 KYC 資料(身份證正反面圖片字節) + /// 使用 fromBytes 以兼容 Web 和移動端 Future> uploadKyc( Uint8List frontBytes, Uint8List backBytes, @@ -67,7 +67,7 @@ class UserService { ); } - /// 退出登录 + /// 退出登錄 Future> logout() async { return _client.post(ApiEndpoints.logout); } diff --git a/flutter_monisuo/lib/main.dart b/flutter_monisuo/lib/main.dart index 797ee21..48013e7 100644 --- a/flutter_monisuo/lib/main.dart +++ b/flutter_monisuo/lib/main.dart @@ -27,17 +27,17 @@ import 'ui/pages/main/main_page.dart'; import 'ui/pages/onboarding/onboarding_page.dart'; void main() async { - // 确保 Flutter 绑定初始化 + // 確保 Flutter 綁定初始化 WidgetsFlutterBinding.ensureInitialized(); - // 全局错误处理 - Flutter 框架错误 + // 全局錯誤處理 - Flutter 框架錯誤 FlutterError.onError = (FlutterErrorDetails details) { FlutterError.presentError(details); debugPrint('Flutter Error: ${details.exception}'); debugPrint('Stack trace: ${details.stack}'); }; - // 全局错误处理 - 异步未捕获错误 + // 全局錯誤處理 - 異步未捕獲錯誤 PlatformDispatcher.instance.onError = (error, stack) { debugPrint('Uncaught error: $error'); debugPrint('Stack: $stack'); @@ -88,7 +88,7 @@ class MyApp extends StatelessWidget { final dioClient = DioClient(); return [ - // Theme Provider (必须放在最前面) + // Theme Provider (必須放在最前面) ChangeNotifierProvider( create: (_) => ThemeProvider()..init(), ), @@ -105,7 +105,7 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider( create: (ctx) { final authProvider = AuthProvider(ctx.read()); - // token 过期时,DioClient 回调 AuthProvider 强制登出 + // token 過期時,DioClient 回調 AuthProvider 強制登出 dioClient.onUnauthorized = authProvider.forceLogout; return authProvider; }, @@ -137,7 +137,7 @@ class MyApp extends StatelessWidget { ], builder: (context, child) { child = ShadAppBuilder(child: child!); - // 配置 BotToast 确保显示在所有内容之上 + // 配置 BotToast 確保顯示在所有內容之上 final botToastBuilder = BotToastInit(); child = botToastBuilder(context, child); return child; @@ -153,13 +153,13 @@ class MyApp extends StatelessWidget { } } -/// 根页面 - 决定显示引导页还是主页面 +/// 根頁面 - 決定顯示引導頁還是主頁面 class RootPage extends StatelessWidget { const RootPage({super.key}); @override Widget build(BuildContext context) { - // 检查是否需要显示引导页 + // 檢查是否需要顯示引導頁 if (!LocalStorage.isOnboardingCompleted) { return OnboardingPage( onComplete: () { diff --git a/flutter_monisuo/lib/providers/asset_provider.dart b/flutter_monisuo/lib/providers/asset_provider.dart index 65c6e9c..c53833e 100644 --- a/flutter_monisuo/lib/providers/asset_provider.dart +++ b/flutter_monisuo/lib/providers/asset_provider.dart @@ -7,7 +7,7 @@ import '../data/models/order_models.dart'; import '../data/services/asset_service.dart'; import '../data/services/fund_service.dart'; -/// 资产状态管理 +/// 資產狀態管理 class AssetProvider extends ChangeNotifier { final AssetService _assetService; final FundService _fundService; @@ -23,7 +23,7 @@ class AssetProvider extends ChangeNotifier { bool _isLoadingOrders = false; String? _error; - // 加载状态标记,防止重复加载 + // 加載狀態標記,防止重複加載 bool _overviewLoaded = false; bool _fundAccountLoaded = false; bool _tradeAccountLoaded = false; @@ -42,9 +42,9 @@ class AssetProvider extends ChangeNotifier { bool get isLoadingOrders => _isLoadingOrders; String? get error => _error; - /// 加载资产总览 + /// 加載資產總覽 Future loadOverview({bool force = false}) async { - // 如果已经加载过且不是强制刷新,则跳过 + // 如果已經加載過且不是強制刷新,則跳過 if (_overviewLoaded && !force && _overview != null) { return; } @@ -62,16 +62,16 @@ class AssetProvider extends ChangeNotifier { _error = response.message; } } catch (e) { - _error = '加载失败: $e'; + _error = '加載失敗: $e'; } _isLoading = false; notifyListeners(); } - /// 加载资金账户 + /// 加載資金賬戶 Future loadFundAccount({bool force = false}) async { - // 如果已经加载过且不是强制刷新,则跳过 + // 如果已經加載過且不是強制刷新,則跳過 if (_fundAccountLoaded && !force && _fundAccount != null) { return; } @@ -84,13 +84,13 @@ class AssetProvider extends ChangeNotifier { notifyListeners(); } } catch (_) { - // 忽略错误 + // 忽略錯誤 } } - /// 加载交易账户 + /// 加載交易賬戶 Future loadTradeAccount({bool force = false}) async { - // 如果已经加载过且不是强制刷新,则跳过 + // 如果已經加載過且不是強制刷新,則跳過 if (_tradeAccountLoaded && !force && _tradeAccounts.isNotEmpty) { return; } @@ -103,11 +103,11 @@ class AssetProvider extends ChangeNotifier { notifyListeners(); } } catch (_) { - // 忽略错误 + // 忽略錯誤 } } - /// 加载资金流水 + /// 加載資金流水 Future loadFlows({int? flowType, int pageNum = 1}) async { _isLoadingFlows = true; notifyListeners(); @@ -122,14 +122,14 @@ class AssetProvider extends ChangeNotifier { _flows = list?.map((e) => AccountFlow.fromJson(e as Map)).toList() ?? []; } } catch (_) { - // 忽略错误 + // 忽略錯誤 } _isLoadingFlows = false; notifyListeners(); } - /// 划转资金 + /// 劃轉資金 Future> transfer({ required int direction, required String amount, @@ -140,7 +140,7 @@ class AssetProvider extends ChangeNotifier { amount: amount, ); if (response.success) { - // 强制刷新数据 + // 強制刷新數據 await loadOverview(force: true); await loadFundAccount(force: true); await loadTradeAccount(force: true); @@ -148,11 +148,11 @@ class AssetProvider extends ChangeNotifier { } return response; } catch (e) { - return ApiResponse.fail('划转失败: $e'); + return ApiResponse.fail('劃轉失敗: $e'); } } - /// 充值 - 返回订单详情包含钱包地址 + /// 充值 - 返回訂單詳情包含錢包地址 Future>> deposit({required String amount, String? remark}) async { try { final response = await _fundService.deposit(amount: amount, remark: remark); @@ -163,11 +163,11 @@ class AssetProvider extends ChangeNotifier { } return response; } catch (e) { - return ApiResponse.fail('充值申请失败: $e'); + return ApiResponse.fail('充值申請失敗: $e'); } } - /// 确认已打款 + /// 確認已打款 Future> confirmPay(String orderNo) async { try { final response = await _fundService.confirmPay(orderNo); @@ -177,11 +177,11 @@ class AssetProvider extends ChangeNotifier { } return response; } catch (e) { - return ApiResponse.fail('确认打款失败: $e'); + return ApiResponse.fail('確認打款失敗: $e'); } } - /// 提现 + /// 提現 Future>> withdraw({ required String amount, required String withdrawAddress, @@ -205,11 +205,11 @@ class AssetProvider extends ChangeNotifier { } return response; } catch (e) { - return ApiResponse.fail('提现申请失败: $e'); + return ApiResponse.fail('提現申請失敗: $e'); } } - /// 加载充提订单 + /// 加載充提訂單 Future loadFundOrders({int? type, int pageNum = 1, int pageSize = 20}) async { _isLoadingOrders = true; notifyListeners(); @@ -225,14 +225,14 @@ class AssetProvider extends ChangeNotifier { _fundOrders = _fundService.parseOrderList(list); } } catch (_) { - // 忽略错误 + // 忽略錯誤 } _isLoadingOrders = false; notifyListeners(); } - /// 取消订单 + /// 取消訂單 Future> cancelOrder(String orderNo) async { try { final response = await _fundService.cancelOrder(orderNo); @@ -242,11 +242,11 @@ class AssetProvider extends ChangeNotifier { } return response; } catch (e) { - return ApiResponse.fail('取消订单失败: $e'); + return ApiResponse.fail('取消訂單失敗: $e'); } } - /// 获取可用提现网络列表 + /// 獲取可用提現網絡列表 Future> getWalletNetworks() async { try { final response = await _fundService.getWalletNetworks(); @@ -259,7 +259,7 @@ class AssetProvider extends ChangeNotifier { } } - /// 刷新所有资产数据 + /// 刷新所有資產數據 Future refreshAll({bool force = false}) async { await Future.wait([ loadOverview(force: force), @@ -268,7 +268,7 @@ class AssetProvider extends ChangeNotifier { ]); } - /// 重置加载状态(用于退出登录时) + /// 重置加載狀態(用於退出登錄時) void resetLoadState() { _overviewLoaded = false; _fundAccountLoaded = false; diff --git a/flutter_monisuo/lib/providers/auth_provider.dart b/flutter_monisuo/lib/providers/auth_provider.dart index 3f070ce..8a5d18b 100644 --- a/flutter_monisuo/lib/providers/auth_provider.dart +++ b/flutter_monisuo/lib/providers/auth_provider.dart @@ -6,7 +6,7 @@ import '../core/storage/local_storage.dart'; import '../data/models/user.dart'; import '../data/services/user_service.dart'; -/// 认证状态管理 +/// 認證狀態管理 class AuthProvider extends ChangeNotifier { final UserService _userService; @@ -25,7 +25,7 @@ class AuthProvider extends ChangeNotifier { bool get isLoading => _isLoading; String? get token => _token; - /// 初始化认证状态 + /// 初始化認證狀態 Future _initAuth() async { _token = LocalStorage.getToken(); _isLoggedIn = _token?.isNotEmpty == true; @@ -41,12 +41,12 @@ class AuthProvider extends ChangeNotifier { return userJson != null ? User.fromJson(userJson) : null; } - /// 登录 + /// 登錄 Future> login(String username, String password) { return _authenticate(() => _userService.login(username, password)); } - /// 注册(含身份证图片和可选推广码) + /// 註冊(含身份證圖片和可選推廣碼) Future> register( String username, String password, { @@ -63,7 +63,7 @@ class AuthProvider extends ChangeNotifier { )); } - /// 统一认证处理 + /// 統一認證處理 Future> _authenticate( Future>> Function() action, ) async { @@ -73,18 +73,18 @@ class AuthProvider extends ChangeNotifier { final response = await action(); if (!response.success || response.data == null) { - return ApiResponse.fail(response.message ?? '操作失败'); + return ApiResponse.fail(response.message ?? '操作失敗'); } return _handleAuthSuccess(response.data!, response.message); } catch (e) { - return ApiResponse.fail('操作失败: $e'); + return ApiResponse.fail('操作失敗: $e'); } finally { _setLoading(false); } } - /// 处理认证成功 + /// 處理認證成功 ApiResponse _handleAuthSuccess( Map data, String? message, @@ -107,17 +107,17 @@ class AuthProvider extends ChangeNotifier { return _user != null ? ApiResponse.success(_user!, message) - : ApiResponse.fail('用户信息获取失败'); + : ApiResponse.fail('用戶信息獲取失敗'); } - /// 退出登录 + /// 退出登錄 Future logout() async { _setLoading(true); try { await _userService.logout(); } catch (_) { - // 忽略退出登录的接口错误 + // 忽略退出登錄的接口錯誤 } _clearAuthState(); @@ -131,13 +131,13 @@ class AuthProvider extends ChangeNotifier { _isLoggedIn = false; } - /// 强制登出(token 过期时由 DioClient 回调触发) + /// 強制登出(token 過期時由 DioClient 回調觸發) void forceLogout() { _clearAuthState(); notifyListeners(); } - /// 刷新用户信息 + /// 刷新用戶信息 Future refreshUserInfo() async { if (!_isLoggedIn) return; @@ -149,11 +149,11 @@ class AuthProvider extends ChangeNotifier { notifyListeners(); } } catch (_) { - // 忽略错误 + // 忽略錯誤 } } - /// 提交KYC实名认证(真实图片上传) + /// 提交KYC實名認證(真實圖片上傳) Future> submitKyc( Uint8List frontBytes, Uint8List backBytes) async { try { @@ -164,7 +164,7 @@ class AuthProvider extends ChangeNotifier { } return response; } catch (e) { - return ApiResponse.fail('KYC提交失败: $e'); + return ApiResponse.fail('KYC提交失敗: $e'); } } diff --git a/flutter_monisuo/lib/providers/market_provider.dart b/flutter_monisuo/lib/providers/market_provider.dart index 0094b93..0545187 100644 --- a/flutter_monisuo/lib/providers/market_provider.dart +++ b/flutter_monisuo/lib/providers/market_provider.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../data/models/coin.dart'; import '../data/services/market_service.dart'; -/// 行情状态管理 +/// 行情狀態管理 class MarketProvider extends ChangeNotifier { final MarketService _marketService; @@ -18,16 +18,16 @@ class MarketProvider extends ChangeNotifier { bool get isLoading => _isLoading; String? get error => _error; - /// BTC 和 ETH(上半区展示) + /// BTC 和 ETH(上半區展示) List get featuredCoins => _allCoins.where((c) => c.code == 'BTC' || c.code == 'ETH').toList(); - /// 排除 BTC、ETH、USDT 的代币列表(下半区展示) + /// 排除 BTC、ETH、USDT 的代幣列表(下半區展示) List get otherCoins => _allCoins .where((c) => !{'BTC', 'ETH', 'USDT'}.contains(c.code)) .toList(); - /// 加载币种列表 + /// 加載幣種列表 Future loadCoins({bool force = false}) async { if (_coinsLoaded && !force && _allCoins.isNotEmpty) { return; @@ -47,14 +47,14 @@ class MarketProvider extends ChangeNotifier { _error = response.message; } } catch (e) { - _error = '加载失败: $e'; + _error = '加載失敗: $e'; } _isLoading = false; notifyListeners(); } - /// 根据代码获取币种 + /// 根據代碼獲取幣種 Coin? getCoinByCode(String code) { try { return _allCoins.firstWhere((c) => c.code == code); @@ -68,7 +68,7 @@ class MarketProvider extends ChangeNotifier { await loadCoins(force: true); } - /// 重置加载状态(用于退出登录时) + /// 重置加載狀態(用於退出登錄時) void resetLoadState() { _coinsLoaded = false; _allCoins = []; diff --git a/flutter_monisuo/lib/providers/theme_provider.dart b/flutter_monisuo/lib/providers/theme_provider.dart index d54dc63..ebd0ca9 100644 --- a/flutter_monisuo/lib/providers/theme_provider.dart +++ b/flutter_monisuo/lib/providers/theme_provider.dart @@ -1,24 +1,24 @@ import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; -/// 主题提供者 - 管理明暗主题切换 +/// 主題提供者 - 管理明暗主題切換 /// /// 功能: -/// - 支持浅色/深色/跟随系统三种模式 -/// - 持久化主题设置到本地存储 -/// - 提供主题切换方法 +/// - 支持淺色/深色/跟隨系統三種模式 +/// - 持久化主題設置到本地存儲 +/// - 提供主題切換方法 class ThemeProvider extends ChangeNotifier { static const String _themeModeKey = 'theme_mode'; ThemeMode _themeMode = ThemeMode.dark; - /// 当前主题模式 + /// 當前主題模式 ThemeMode get themeMode => _themeMode; - /// 是否为深色模式 + /// 是否為深色模式 bool get isDarkMode => _themeMode == ThemeMode.dark; - /// 初始化主题设置(从本地存储加载) + /// 初始化主題設置(從本地存儲加載) Future init() async { final prefs = await SharedPreferences.getInstance(); final modeString = prefs.getString(_themeModeKey); @@ -32,14 +32,14 @@ class ThemeProvider extends ChangeNotifier { } } - /// 切换主题(浅色/深色) + /// 切換主題(淺色/深色) Future toggleTheme() async { _themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light; await _saveThemeMode(); notifyListeners(); } - /// 设置主题模式 + /// 設置主題模式 Future setThemeMode(ThemeMode mode) async { if (_themeMode == mode) return; _themeMode = mode; @@ -47,7 +47,7 @@ class ThemeProvider extends ChangeNotifier { notifyListeners(); } - /// 保存主题设置到本地存储 + /// 保存主題設置到本地存儲 Future _saveThemeMode() async { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_themeModeKey, _themeMode.toString()); diff --git a/flutter_monisuo/lib/ui/components/asset_card.dart b/flutter_monisuo/lib/ui/components/asset_card.dart index a2ee5ac..40377a9 100644 --- a/flutter_monisuo/lib/ui/components/asset_card.dart +++ b/flutter_monisuo/lib/ui/components/asset_card.dart @@ -4,13 +4,13 @@ import 'package:flutter_animate/flutter_animate.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; -/// 资产卡片组件 - 用于显示资产总览 +/// 資產卡片組件 - 用於顯示資產總覽 /// -/// 设计规则 ("The Kinetic Vault"): -/// - 渐变背景: Neon Blue → Electric Purple -/// - 圆角: xl (16px) -/// - 无边框,使用渐变层次 -/// - 微妙阴影: 10% black, blur 10px +/// 設計規則 ("The Kinetic Vault"): +/// - 漸變背景: Neon Blue → Electric Purple +/// - 圓角: xl (16px) +/// - 無邊框,使用漸變層次 +/// - 微妙陰影: 10% black, blur 10px class AssetCard extends StatelessWidget { final String title; final String balance; @@ -23,7 +23,7 @@ class AssetCard extends StatelessWidget { const AssetCard({ super.key, - this.title = '总资产', + this.title = '總資產', required this.balance, this.subtitle, this.profit, @@ -40,7 +40,7 @@ class AssetCard extends StatelessWidget { final appColors = context.appColors; final cardGradient = gradient ?? appColors.assetGradient; - // 主题感知颜色 - 在渐变背景上使用 onPrimary + // 主題感知顏色 - 在漸變背景上使用 onPrimary final primaryTextColor = colorScheme.onPrimary; final secondaryTextColor = colorScheme.onPrimary.withValues(alpha: 0.7); @@ -63,7 +63,7 @@ class AssetCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 标题行 + // 標題行 Row( children: [ Text( @@ -80,7 +80,7 @@ class AssetCard extends StatelessWidget { ], ), const SizedBox(height: AppSpacing.sm), - // 余额 - 大标题 + // 餘額 - 大標題 Text( balance, style: theme.textTheme.h1.copyWith( @@ -89,7 +89,7 @@ class AssetCard extends StatelessWidget { fontSize: 20, ), ), - // 盈亏信息 + // 盈虧信息 if (profit != null) ...[ const SizedBox(height: AppSpacing.md), Row( @@ -101,13 +101,13 @@ class AssetCard extends StatelessWidget { ), const SizedBox(width: 6), Text( - '盈亏: $profit', + '盈虧: $profit', style: theme.textTheme.small.copyWith(color: secondaryTextColor), ), ], ), ], - // 子项 + // 子項 if (items != null && items!.isNotEmpty) ...[ const SizedBox(height: AppSpacing.lg), Row( @@ -143,7 +143,7 @@ class AssetCard extends StatelessWidget { } } -/// 资产子项 +/// 資產子項 class AssetItem { final String label; final String value; @@ -154,12 +154,12 @@ class AssetItem { }); } -/// 简洁资产卡片 - 用于列表中显示 +/// 簡潔資產卡片 - 用於列表中顯示 /// -/// 设计规则: -/// - 使用 surface 层次而非边框 -/// - 圆角: xl (16px) -/// - 涨跌标签: 15% 透明度背景 +/// 設計規則: +/// - 使用 surface 層次而非邊框 +/// - 圓角: xl (16px) +/// - 漲跌標籤: 15% 透明度背景 class AssetCardCompact extends StatelessWidget { final String title; final String balance; diff --git a/flutter_monisuo/lib/ui/components/coin_card.dart b/flutter_monisuo/lib/ui/components/coin_card.dart index 570f4df..2841750 100644 --- a/flutter_monisuo/lib/ui/components/coin_card.dart +++ b/flutter_monisuo/lib/ui/components/coin_card.dart @@ -3,12 +3,12 @@ import 'package:shadcn_ui/shadcn_ui.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; -/// 币种卡片组件 - 用于显示币种信息 +/// 幣種卡片組件 - 用於顯示幣種信息 /// -/// 设计规则: -/// - 使用 surface 层次而非边框 -/// - 圆角: xl (16px) 卡片, sm (4px) 涨跌标签 -/// - 涨跌标签: 15% 透明度背景 +/// 設計規則: +/// - 使用 surface 層次而非邊框 +/// - 圓角: xl (16px) 卡片, sm (4px) 漲跌標籤 +/// - 漲跌標籤: 15% 透明度背景 class CoinCard extends StatelessWidget { final String code; final String name; @@ -39,7 +39,7 @@ class CoinCard extends StatelessWidget { onTap: onTap, child: Row( children: [ - // 图标 - 圆形 + // 圖標 - 圓形 Container( width: 44, height: 44, @@ -59,7 +59,7 @@ class CoinCard extends StatelessWidget { ), ), const SizedBox(width: AppSpacing.sm), - // 名称 + // 名稱 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -77,7 +77,7 @@ class CoinCard extends StatelessWidget { ], ), ), - // 涨跌幅 - Dynamic Chip + // 漲跌幅 - Dynamic Chip Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6), decoration: BoxDecoration( diff --git a/flutter_monisuo/lib/ui/components/components.dart b/flutter_monisuo/lib/ui/components/components.dart index c845710..7c09811 100644 --- a/flutter_monisuo/lib/ui/components/components.dart +++ b/flutter_monisuo/lib/ui/components/components.dart @@ -1,4 +1,4 @@ -/// 自定义组件导出 +/// 自定義組件導出 library components; export 'coin_card.dart'; diff --git a/flutter_monisuo/lib/ui/components/glass_panel.dart b/flutter_monisuo/lib/ui/components/glass_panel.dart index 67bc0fa..4aec76b 100644 --- a/flutter_monisuo/lib/ui/components/glass_panel.dart +++ b/flutter_monisuo/lib/ui/components/glass_panel.dart @@ -2,43 +2,43 @@ import 'package:flutter/material.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; -/// GlassPanel - 实心背景面板 +/// GlassPanel - 實心背景面板 /// -/// Material Design 3 风格的实心背景容器 -/// 用于卡片、弹窗、底部抽屉等需要清晰背景的容器 +/// Material Design 3 風格的實心背景容器 +/// 用於卡片、彈窗、底部抽屜等需要清晰背景的容器 /// /// 示例: /// ```dart /// GlassPanel( -/// child: Text('内容'), +/// child: Text('內容'), /// ) /// ``` class GlassPanel extends StatelessWidget { - /// 子组件 + /// 子組件 final Widget child; - /// 背景色,默认使用 surfaceContainer + /// 背景色,默認使用 surfaceContainer final Color? backgroundColor; - /// 边框色 + /// 邊框色 final Color? borderColor; - /// 圆角,默认特大圆角 + /// 圓角,默認特大圓角 final BorderRadius? borderRadius; - /// 内边距 + /// 內邊距 final EdgeInsetsGeometry? padding; - /// 外边距 + /// 外邊距 final EdgeInsetsGeometry? margin; - /// 宽度 + /// 寬度 final double? width; /// 高度 final double? height; - /// 是否显示边框 + /// 是否顯示邊框 final bool showBorder; const GlassPanel({ @@ -88,33 +88,33 @@ class GlassPanel extends StatelessWidget { } } -/// GlassCard - 带实心背景的卡片 +/// GlassCard - 帶實心背景的卡片 /// -/// 用于列表项、信息展示等场景 -/// 预设了常用配置,简化使用 +/// 用於列表項、信息展示等場景 +/// 預設了常用配置,簡化使用 class GlassCard extends StatelessWidget { - /// 子组件 + /// 子組件 final Widget child; - /// 点击回调 + /// 點擊回調 final VoidCallback? onTap; - /// 长按回调 + /// 長按回調 final VoidCallback? onLongPress; - /// 内边距 + /// 內邊距 final EdgeInsetsGeometry? padding; - /// 外边距 + /// 外邊距 final EdgeInsetsGeometry? margin; - /// 圆角 + /// 圓角 final BorderRadius? borderRadius; - /// 是否显示霓虹光效 + /// 是否顯示霓虹光效 final bool showNeonGlow; - /// 霓虹光效颜色 + /// 霓虹光效顏色 final Color? neonGlowColor; const GlassCard({ @@ -170,20 +170,20 @@ class GlassCard extends StatelessWidget { } } -/// GlassBottomSheet - 实心背景底部抽屉 +/// GlassBottomSheet - 實心背景底部抽屜 /// -/// 用于弹出的底部面板 +/// 用於彈出的底部面板 class GlassBottomSheet extends StatelessWidget { - /// 子组件 + /// 子組件 final Widget child; - /// 标题 + /// 標題 final String? title; - /// 是否显示关闭按钮 + /// 是否顯示關閉按鈕 final bool showCloseButton; - /// 内边距 + /// 內邊距 final EdgeInsetsGeometry? padding; const GlassBottomSheet({ @@ -209,7 +209,7 @@ class GlassBottomSheet extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - // 顶部拖动条 + // 頂部拖動條 Container( margin: const EdgeInsets.only(top: 12, bottom: 8), width: 40, @@ -219,7 +219,7 @@ class GlassBottomSheet extends StatelessWidget { borderRadius: BorderRadius.circular(2), ), ), - // 标题栏 + // 標題欄 if (title != null || showCloseButton) Padding( padding: EdgeInsets.fromLTRB( @@ -261,7 +261,7 @@ class GlassBottomSheet extends StatelessWidget { ], ), ), - // 内容 + // 內容 Padding( padding: padding ?? EdgeInsets.fromLTRB( @@ -277,7 +277,7 @@ class GlassBottomSheet extends StatelessWidget { ); } - /// 显示底部抽屉 + /// 顯示底部抽屜 static Future show({ required BuildContext context, required Widget Function(BuildContext) builder, diff --git a/flutter_monisuo/lib/ui/components/gradient_button.dart b/flutter_monisuo/lib/ui/components/gradient_button.dart index b6edb43..06d5a15 100644 --- a/flutter_monisuo/lib/ui/components/gradient_button.dart +++ b/flutter_monisuo/lib/ui/components/gradient_button.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; -/// 渐变按钮组件 - 支持 CTA 渐变效果 +/// 漸變按鈕組件 - 支持 CTA 漸變效果 /// -/// 设计规则: -/// - 渐变方向: 135度 (primary → primary_container) -/// - 圆角: xxl (24px / 1.5rem) -/// - 无边框 +/// 設計規則: +/// - 漸變方向: 135度 (primary → primary_container) +/// - 圓角: xxl (24px / 1.5rem) +/// - 無邊框 class GradientButton extends StatelessWidget { final String text; final VoidCallback? onPressed; @@ -28,7 +28,7 @@ class GradientButton extends StatelessWidget { this.height = 48, }); - /// CTA 按钮 - 使用主题渐变 + /// CTA 按鈕 - 使用主題漸變 factory GradientButton.cta({ Key? key, required String text, @@ -47,7 +47,7 @@ class GradientButton extends StatelessWidget { ); } - /// 买入按钮 - 翡翠绿渐变 + /// 買入按鈕 - 翡翠綠漸變 factory GradientButton.buy({ Key? key, required String text, @@ -67,7 +67,7 @@ class GradientButton extends StatelessWidget { ); } - /// 卖出按钮 - 红色渐变 + /// 賣出按鈕 - 紅色漸變 factory GradientButton.sell({ Key? key, required String text, @@ -93,7 +93,7 @@ class GradientButton extends StatelessWidget { final colorScheme = context.colors; final buttonGradient = gradient ?? appColors.ctaGradient; - // 主题感知颜色 - 在渐变背景上使用 onPrimary + // 主題感知顏色 - 在漸變背景上使用 onPrimary final textColor = colorScheme.onPrimary; return Container( @@ -145,11 +145,11 @@ class GradientButton extends StatelessWidget { } } -/// Ghost 按钮 - 次要操作 +/// Ghost 按鈕 - 次要操作 /// -/// 设计规则: +/// 設計規則: /// - Ghost Border: 15% opacity outline-variant -/// - 圆角: xxl (24px) +/// - 圓角: xxl (24px) /// - 主色文字 class GhostButton extends StatelessWidget { final String text; diff --git a/flutter_monisuo/lib/ui/components/neon_glow.dart b/flutter_monisuo/lib/ui/components/neon_glow.dart index 2840e37..3bdcaa3 100644 --- a/flutter_monisuo/lib/ui/components/neon_glow.dart +++ b/flutter_monisuo/lib/ui/components/neon_glow.dart @@ -3,30 +3,30 @@ import '../../core/theme/app_color_scheme.dart'; import '../../core/theme/app_spacing.dart'; import '../../core/theme/app_theme_extension.dart'; -/// NeonGlow - 霓虹光效组件 +/// NeonGlow - 霓虹光效組件 /// -/// Material Design 3 风格的霓虹光效 -/// 用于按钮、卡片、图标等需要突出显示的元素 +/// Material Design 3 風格的霓虹光效 +/// 用於按鈕、卡片、圖標等需要突出顯示的元素 /// -/// 光效类型: +/// 光效類型: /// - Primary: 青色光效 (#72dcff) /// - Secondary: 紫色光效 (#dd8bfb) -/// - Tertiary: 绿色光效 (#afffd1) -/// - Error: 红色光效 (#ff716c) +/// - Tertiary: 綠色光效 (#afffd1) +/// - Error: 紅色光效 (#ff716c) class NeonGlow extends StatelessWidget { - /// 子组件 + /// 子組件 final Widget child; - /// 光效颜色 + /// 光效顏色 final Color glowColor; - /// 模糊半径,默认 15.0 + /// 模糊半徑,默認 15.0 final double blurRadius; - /// 扩散半径,默认 0.0 + /// 擴散半徑,默認 0.0 final double spreadRadius; - /// 圆角 + /// 圓角 final BorderRadius? borderRadius; const NeonGlow({ @@ -70,7 +70,7 @@ class NeonGlow extends StatelessWidget { ); } - /// Tertiary 霓虹光效 (绿色) + /// Tertiary 霓虹光效 (綠色) factory NeonGlow.tertiary({ Key? key, required Widget child, @@ -86,7 +86,7 @@ class NeonGlow extends StatelessWidget { ); } - /// Error 霓虹光效 (红色) + /// Error 霓虹光效 (紅色) factory NeonGlow.error({ Key? key, required Widget child, @@ -122,32 +122,32 @@ class NeonGlow extends StatelessWidget { } } -/// NeonButton - 带霓虹光效的按钮 +/// NeonButton - 帶霓虹光效的按鈕 /// -/// 预设了常用配置,简化使用 +/// 預設了常用配置,簡化使用 class NeonButton extends StatefulWidget { - /// 按钮文本 + /// 按鈕文本 final String text; - /// 点击回调 + /// 點擊回調 final VoidCallback? onPressed; - /// 按钮类型 + /// 按鈕類型 final NeonButtonType type; - /// 是否显示光效 + /// 是否顯示光效 final bool showGlow; - /// 图标 + /// 圖標 final IconData? icon; - /// 是否加载中 + /// 是否加載中 final bool isLoading; - /// 按钮宽度 + /// 按鈕寬度 final double? width; - /// 按钮高度,默认 48 + /// 按鈕高度,默認 48 final double height; const NeonButton({ @@ -258,7 +258,7 @@ class _NeonButtonState extends State } LinearGradient? get _gradient { - // 【优化】移除所有渐变效果,改为纯色背景,提升专业金融感 + // 【優化】移除所有漸變效果,改為純色背景,提升專業金融感 return null; } @@ -335,39 +335,39 @@ class _NeonButtonState extends State } } -/// 按钮类型 +/// 按鈕類型 enum NeonButtonType { - /// 主要按钮 (青色) + /// 主要按鈕 (青色) primary, - /// 次要按钮 (紫色) + /// 次要按鈕 (紫色) secondary, - /// 成功按钮 (绿色) + /// 成功按鈕 (綠色) tertiary, - /// 危险按钮 (红色) + /// 危險按鈕 (紅色) error, - /// 边框按钮 + /// 邊框按鈕 outline, } -/// NeonIcon - 带霓虹光效的图标 +/// NeonIcon - 帶霓虹光效的圖標 class NeonIcon extends StatelessWidget { - /// 图标 + /// 圖標 final IconData icon; - /// 图标大小 + /// 圖標大小 final double size; - /// 图标颜色 + /// 圖標顏色 final Color color; - /// 光效颜色,默认使用图标颜色 + /// 光效顏色,默認使用圖標顏色 final Color? glowColor; - /// 光效模糊半径 + /// 光效模糊半徑 final double glowBlur; const NeonIcon({ diff --git a/flutter_monisuo/lib/ui/components/trade_button.dart b/flutter_monisuo/lib/ui/components/trade_button.dart index 77c6c44..8766bf5 100644 --- a/flutter_monisuo/lib/ui/components/trade_button.dart +++ b/flutter_monisuo/lib/ui/components/trade_button.dart @@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; import '../../core/theme/app_color_scheme.dart'; import '../../core/theme/app_spacing.dart'; -/// 交易按钮组件 - 买入/卖出按钮 +/// 交易按鈕組件 - 買入/賣出按鈕 /// -/// 设计规则: -/// - 渐变按钮: 135度渐变 -/// - 圆角: xxl (24px / 1.5rem) -/// - 买入: 翡翠绿渐变 -/// - 卖出: 红色渐变 +/// 設計規則: +/// - 漸變按鈕: 135度漸變 +/// - 圓角: xxl (24px / 1.5rem) +/// - 買入: 翡翠綠漸變 +/// - 賣出: 紅色漸變 class TradeButton extends StatelessWidget { final bool isBuy; final String? coinCode; @@ -25,7 +25,7 @@ class TradeButton extends StatelessWidget { this.fullWidth = false, }); - /// 买入按钮 + /// 買入按鈕 const TradeButton.buy({ super.key, this.coinCode, @@ -34,7 +34,7 @@ class TradeButton extends StatelessWidget { this.fullWidth = false, }) : isBuy = true; - /// 卖出按钮 + /// 賣出按鈕 const TradeButton.sell({ super.key, this.coinCode, @@ -48,10 +48,10 @@ class TradeButton extends StatelessWidget { final colorScheme = Theme.of(context).colorScheme; final gradient = isBuy ? AppColorScheme.buyGradient : AppColorScheme.sellGradient; final text = isBuy - ? '买入${coinCode != null ? ' $coinCode' : ''}' - : '卖出${coinCode != null ? ' $coinCode' : ''}'; + ? '買入${coinCode != null ? ' $coinCode' : ''}' + : '賣出${coinCode != null ? ' $coinCode' : ''}'; - // 主题感知颜色 - 在渐变背景上使用 onPrimary + // 主題感知顏色 - 在漸變背景上使用 onPrimary final textColor = colorScheme.onPrimary; return Container( @@ -103,7 +103,7 @@ class TradeButton extends StatelessWidget { } } -/// 交易按钮组 - 同时显示买入和卖出按钮 +/// 交易按鈕組 - 同時顯示買入和賣出按鈕 class TradeButtonGroup extends StatelessWidget { final String? coinCode; final VoidCallback? onBuyPressed; diff --git a/flutter_monisuo/lib/ui/pages/asset/asset_page.dart b/flutter_monisuo/lib/ui/pages/asset/asset_page.dart index 79a54ff..71330c2 100644 --- a/flutter_monisuo/lib/ui/pages/asset/asset_page.dart +++ b/flutter_monisuo/lib/ui/pages/asset/asset_page.dart @@ -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 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), ), ), diff --git a/flutter_monisuo/lib/ui/pages/asset/components/account_tab_switcher.dart b/flutter_monisuo/lib/ui/pages/asset/components/account_tab_switcher.dart index fa3c51d..1fda48e 100644 --- a/flutter_monisuo/lib/ui/pages/asset/components/account_tab_switcher.dart +++ b/flutter_monisuo/lib/ui/pages/asset/components/account_tab_switcher.dart @@ -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), ), diff --git a/flutter_monisuo/lib/ui/pages/asset/components/action_buttons_row.dart b/flutter_monisuo/lib/ui/pages/asset/components/action_buttons_row.dart index da08045..1f80ef5 100644 --- a/flutter_monisuo/lib/ui/pages/asset/components/action_buttons_row.dart +++ b/flutter_monisuo/lib/ui/pages/asset/components/action_buttons_row.dart @@ -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; diff --git a/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart b/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart index 2078bdd..338e512 100644 --- a/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart +++ b/flutter_monisuo/lib/ui/pages/asset/components/asset_dialogs.dart @@ -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(); @@ -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 data) { final orderNo = data['orderNo'] as String? ?? ''; final amount = data['amount']?.toString() ?? '0.00'; @@ -268,7 +268,7 @@ void showDepositResultDialog(BuildContext context, Map data) { ), const SizedBox(width: AppSpacing.sm), Text( - '充值申请成功', + '充值申請成功', style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.w700, ), @@ -276,12 +276,12 @@ void showDepositResultDialog(BuildContext context, Map 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 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 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 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 data) { ); } -/// 提现对话框 +/// 提現對話框 void showWithdrawDialog(BuildContext context, String? balance) { final amountController = TextEditingController(); final addressController = TextEditingController(); final contactController = TextEditingController(); final formKey = GlobalKey(); - final feeNotifier = ValueNotifier('提现将扣除10%手续费'); + final feeNotifier = ValueNotifier('提現將扣除10%手續費'); final networksNotifier = ValueNotifier>([]); final selectedNetworkNotifier = ValueNotifier(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().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( valueListenable: feeNotifier, builder: (_, feeText, __) { @@ -501,7 +501,7 @@ void showWithdrawDialog(BuildContext context, String? balance) { }, ), const SizedBox(height: AppSpacing.md), - // 提现网络选择 + // 提現網絡選擇 ValueListenableBuilder>( 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( - 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, diff --git a/flutter_monisuo/lib/ui/pages/asset/components/balance_card.dart b/flutter_monisuo/lib/ui/pages/asset/components/balance_card.dart index a60789a..92e1cd3 100644 --- a/flutter_monisuo/lib/ui/pages/asset/components/balance_card.dart +++ b/flutter_monisuo/lib/ui/pages/asset/components/balance_card.dart @@ -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), diff --git a/flutter_monisuo/lib/ui/pages/asset/components/holdings_section.dart b/flutter_monisuo/lib/ui/pages/asset/components/holdings_section.dart index bb46c4c..e30f4f5 100644 --- a/flutter_monisuo/lib/ui/pages/asset/components/holdings_section.dart +++ b/flutter_monisuo/lib/ui/pages/asset/components/holdings_section.dart @@ -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) diff --git a/flutter_monisuo/lib/ui/pages/asset/components/records_link_row.dart b/flutter_monisuo/lib/ui/pages/asset/components/records_link_row.dart index 9ec097c..824454c 100644 --- a/flutter_monisuo/lib/ui/pages/asset/components/records_link_row.dart +++ b/flutter_monisuo/lib/ui/pages/asset/components/records_link_row.dart @@ -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, ), diff --git a/flutter_monisuo/lib/ui/pages/asset/transfer_page.dart b/flutter_monisuo/lib/ui/pages/asset/transfer_page.dart index 2bf9c87..0de350a 100644 --- a/flutter_monisuo/lib/ui/pages/asset/transfer_page.dart +++ b/flutter_monisuo/lib/ui/pages/asset/transfer_page.dart @@ -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 { 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 { } // ============================================ - // 数据访问 + // 數據訪問 // ============================================ - /// 获取资金账户余额(安全检查) + /// 獲取資金賬戶餘額(安全檢查) String get _fundBalance { try { final provider = context.read(); 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(); - // 先检查列表是否为空 + // 先檢查列表是否為空 if (provider.tradeAccounts.isEmpty) { return '0.00'; } @@ -81,32 +81,32 @@ class _TransferPageState extends State { } } - /// 获取当前可用余额(根据方向) + /// 獲取當前可用餘額(根據方向) 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 _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 { 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 { ); } - /// 设置快捷百分比金额 + /// 設置快捷百分比金額 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 { } // ============================================ - // 构建 UI + // 構建 UI // ============================================ @override @@ -173,7 +173,7 @@ class _TransferPageState extends State { onPressed: () => Navigator.of(context).pop(), ), title: Text( - '账户划转', + '賬戶劃轉', style: AppTextStyles.headlineLarge(context), ), centerTitle: true, @@ -205,7 +205,7 @@ class _TransferPageState extends State { 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 { key: 'src-$_direction', beginOffset: const Offset(0, -1), child: _buildAccountRow( - label: '从', + label: '從', accountName: _fromLabel, balance: _fromBalance, ), @@ -239,7 +239,7 @@ class _TransferPageState extends State { 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 { ); } - /// 统一的 AnimatedSwitcher 构造 + /// 統一的 AnimatedSwitcher 構造 Widget _animatedSwitcher({ required String key, required Offset beginOffset, @@ -313,7 +313,7 @@ class _TransferPageState extends State { 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 { 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 { const SizedBox(width: AppSpacing.sm), Expanded( child: Text( - '划转即时到账,无需手续费', + '劃轉即時到賬,無需手續費', style: AppTextStyles.bodyMedium(context).copyWith(color: upColor), ), ), @@ -472,7 +472,7 @@ class _TransferPageState extends State { 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 { ), ) : const Text( - '确认划转', + '確認劃轉', style: TextStyle( color: Colors.white, fontSize: 16, diff --git a/flutter_monisuo/lib/ui/pages/auth/login_page.dart b/flutter_monisuo/lib/ui/pages/auth/login_page.dart index 24e21a5..a2a9b10 100644 --- a/flutter_monisuo/lib/ui/pages/auth/login_page.dart +++ b/flutter_monisuo/lib/ui/pages/auth/login_page.dart @@ -49,13 +49,13 @@ class _LoginPageState extends State { key: formKey, child: Column( children: [ - // 顶部品牌区域 + // 頂部品牌區域 _buildBrandSection(), const SizedBox(height: AppSpacing.xxl), - // 表单区域 + // 表單區域 _buildFormSection(), const SizedBox(height: AppSpacing.xl), - // 底部注册链接 + // 底部註冊鏈接 _buildRegisterRow(), ], ), @@ -66,13 +66,13 @@ class _LoginPageState extends State { } // ============================================ - // 品牌区域 - Logo + 品牌名 + 标语 + // 品牌區域 - Logo + 品牌名 + 標語 // ============================================ Widget _buildBrandSection() { return Column( children: [ - // Logo 圆形:渐变 #1F2937 → #374151,内含 "M" + // Logo 圓形:漸變 #1F2937 → #374151,內含 "M" Container( width: _logoCircleSize, height: _logoCircleSize, @@ -105,9 +105,9 @@ class _LoginPageState extends State { textAlign: TextAlign.center, ), const SizedBox(height: AppSpacing.md), - // 标语 + // 標語 Text( - '虚拟货币模拟交易平台', + '虛擬貨幣模擬交易平臺', style: AppTextStyles.bodyLarge(context).copyWith( color: context.colors.onSurfaceVariant, ), @@ -118,7 +118,7 @@ class _LoginPageState extends State { } // ============================================ - // 表单区域 - 用户名 + 密码 + 登录按钮 + // 表單區域 - 用戶名 + 密碼 + 登錄按鈕 // ============================================ Widget _buildFormSection() { @@ -139,7 +139,7 @@ class _LoginPageState extends State { height: _inputHeight, child: ShadInputFormField( id: 'username', - placeholder: const Text('请输入用户名'), + placeholder: const Text('請輸入用戶名'), leading: Padding( padding: const EdgeInsets.only(right: AppSpacing.sm), child: Icon(LucideIcons.user, size: 18, color: context.appColors.onSurfaceMuted), @@ -166,7 +166,7 @@ class _LoginPageState extends State { height: _inputHeight, child: ShadInputFormField( id: 'password', - placeholder: const Text('请输入密码'), + placeholder: const Text('請輸入密碼'), obscureText: _obscurePassword, leading: Padding( padding: const EdgeInsets.only(right: AppSpacing.sm), @@ -196,7 +196,7 @@ class _LoginPageState extends State { } Widget _buildLoginButton() { - // 设计稿: accent-primary = light:#1F2937 / dark:#D4AF37 + // 設計稿: accent-primary = light:#1F2937 / dark:#D4AF37 final buttonColor = context.appColors.accentPrimary; final textColor = context.colors.onPrimary; @@ -222,7 +222,7 @@ class _LoginPageState extends State { ), ) : Text( - '登录', + '登錄', style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.w700, color: textColor, @@ -235,7 +235,7 @@ class _LoginPageState extends State { } // ============================================ - // 底部注册链接 + // 底部註冊鏈接 // ============================================ Widget _buildRegisterRow() { @@ -249,7 +249,7 @@ class _LoginPageState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - '还没有账户?', + '還沒有賬戶?', style: AppTextStyles.bodyLarge(context).copyWith( color: secondaryTextColor, ), @@ -258,7 +258,7 @@ class _LoginPageState extends State { GestureDetector( onTap: _navigateToRegister, child: Text( - '立即注册', + '立即註冊', style: AppTextStyles.bodyLarge(context).copyWith( fontWeight: FontWeight.w600, color: goldColor, @@ -276,20 +276,20 @@ class _LoginPageState extends State { String? _validateUsername(String? value) { if (value == null || value.isEmpty) { - return '请输入用户名'; + return '請輸入用戶名'; } if (value.length < 3) { - return '用户名至少 3 个字符'; + return '用戶名至少 3 個字符'; } return null; } String? _validatePassword(String? value) { if (value == null || value.isEmpty) { - return '请输入密码'; + return '請輸入密碼'; } if (value.length < 6) { - return '密码至少 6 个字符'; + return '密碼至少 6 個字符'; } return null; } @@ -312,7 +312,7 @@ class _LoginPageState extends State { if (response.success) { _navigateToMainPage(); } else { - _showErrorDialog(response.message ?? '用户名或密码错误'); + _showErrorDialog(response.message ?? '用戶名或密碼錯誤'); } } @@ -334,11 +334,11 @@ class _LoginPageState extends State { showShadDialog( context: context, builder: (context) => ShadDialog.alert( - title: const Text('登录失败'), + title: const Text('登錄失敗'), description: Text(message), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(context).pop(), ), ], diff --git a/flutter_monisuo/lib/ui/pages/auth/register_page.dart b/flutter_monisuo/lib/ui/pages/auth/register_page.dart index 55ed9fd..f55584b 100644 --- a/flutter_monisuo/lib/ui/pages/auth/register_page.dart +++ b/flutter_monisuo/lib/ui/pages/auth/register_page.dart @@ -11,7 +11,7 @@ import '../../components/glass_panel.dart'; import '../../components/neon_glow.dart'; import '../main/main_page.dart'; -/// 注册页面(两步注册:账号信息 + 身份证上传) +/// 註冊頁面(兩步註冊:賬號信息 + 身份證上傳) class RegisterPage extends StatefulWidget { const RegisterPage({super.key}); @@ -20,7 +20,7 @@ class RegisterPage extends StatefulWidget { } class _RegisterPageState extends State { - int _currentStep = 0; // 0: 账号信息, 1: 身份证上传 + int _currentStep = 0; // 0: 賬號信息, 1: 身份證上傳 // 第一步 final _usernameController = TextEditingController(); @@ -96,11 +96,11 @@ class _RegisterPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // 步骤指示器 + // 步驟指示器 _buildStepIndicator(colorScheme), SizedBox(height: AppSpacing.xl), - // 内容区 + // 內容區 _currentStep == 0 ? _buildStep1(colorScheme) : _buildStep2(colorScheme), ], ), @@ -114,7 +114,7 @@ class _RegisterPageState extends State { children: [ _buildStepCircle( number: '1', - label: '账号信息', + label: '賬號信息', isActive: true, isComplete: _currentStep > 0, colorScheme: colorScheme, @@ -129,7 +129,7 @@ class _RegisterPageState extends State { ), _buildStepCircle( number: '2', - label: '身份验证', + label: '身份驗證', isActive: _currentStep >= 1, isComplete: false, colorScheme: colorScheme, @@ -191,17 +191,17 @@ class _RegisterPageState extends State { ); } - /// 第一步:账号信息 + /// 第一步:賬號信息 Widget _buildStep1(ColorScheme colorScheme) { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // 标题 + // 標題 Center( child: Text( - '创建账号', + '創建賬號', style: AppTextStyles.displaySmall(context).copyWith( fontWeight: FontWeight.bold, color: colorScheme.onSurface, @@ -210,30 +210,30 @@ class _RegisterPageState extends State { ), SizedBox(height: AppSpacing.xxl), - // 用户名 + // 用戶名 TextFormField( controller: _usernameController, style: TextStyle(color: colorScheme.onSurface), decoration: InputDecoration( - hintText: '请输入账号(4-20位字母数字)', + hintText: '請輸入賬號(4-20位字母數字)', prefixIcon: Icon(Icons.person_outline, color: colorScheme.onSurfaceVariant), ), validator: (value) { - if (value == null || value.isEmpty) return '请输入账号'; - if (value.length < 4) return '账号至少4位'; - if (value.length > 20) return '账号最多20位'; + if (value == null || value.isEmpty) return '請輸入賬號'; + if (value.length < 4) return '賬號至少4位'; + if (value.length > 20) return '賬號最多20位'; return null; }, ), SizedBox(height: AppSpacing.md), - // 密码 + // 密碼 TextFormField( controller: _passwordController, obscureText: _obscurePassword, style: TextStyle(color: colorScheme.onSurface), decoration: InputDecoration( - hintText: '请输入密码(至少6位)', + hintText: '請輸入密碼(至少6位)', prefixIcon: Icon(Icons.lock_outline, color: colorScheme.onSurfaceVariant), suffixIcon: IconButton( icon: Icon( @@ -244,20 +244,20 @@ class _RegisterPageState extends State { ), ), validator: (value) { - if (value == null || value.isEmpty) return '请输入密码'; - if (value.length < 6) return '密码至少6位'; + if (value == null || value.isEmpty) return '請輸入密碼'; + if (value.length < 6) return '密碼至少6位'; return null; }, ), SizedBox(height: AppSpacing.md), - // 确认密码 + // 確認密碼 TextFormField( controller: _confirmPasswordController, obscureText: _obscureConfirmPassword, style: TextStyle(color: colorScheme.onSurface), decoration: InputDecoration( - hintText: '请再次输入密码', + hintText: '請再次輸入密碼', prefixIcon: Icon(Icons.lock_outline, color: colorScheme.onSurfaceVariant), suffixIcon: IconButton( icon: Icon( @@ -268,25 +268,25 @@ class _RegisterPageState extends State { ), ), validator: (value) { - if (value == null || value.isEmpty) return '请再次输入密码'; - if (value != _passwordController.text) return '两次密码不一致'; + if (value == null || value.isEmpty) return '請再次輸入密碼'; + if (value != _passwordController.text) return '兩次密碼不一致'; return null; }, ), SizedBox(height: AppSpacing.md), - // 推广码(可选) + // 推廣碼(可選) TextFormField( controller: _referralCodeController, style: TextStyle(color: colorScheme.onSurface), decoration: InputDecoration( - hintText: '推广码(选填)', + hintText: '推廣碼(選填)', prefixIcon: Icon(Icons.card_giftcard, color: colorScheme.onSurfaceVariant), ), ), SizedBox(height: AppSpacing.xl), - // 下一步按钮 + // 下一步按鈕 SizedBox( width: double.infinity, child: NeonButton( @@ -303,11 +303,11 @@ class _RegisterPageState extends State { ), SizedBox(height: AppSpacing.md), - // 登录链接 + // 登錄鏈接 Center( child: TextButton( onPressed: () => Navigator.pop(context), - child: Text('已有账号?立即登录', style: AppTextStyles.headlineMedium(context)), + child: Text('已有賬號?立即登錄', style: AppTextStyles.headlineMedium(context)), ), ), ], @@ -315,12 +315,12 @@ class _RegisterPageState extends State { ); } - /// 第二步:身份证上传 + /// 第二步:身份證上傳 Widget _buildStep2(ColorScheme colorScheme) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - // 标题区 + // 標題區 GlassPanel( padding: EdgeInsets.all(AppSpacing.lg), child: Column( @@ -345,7 +345,7 @@ class _RegisterPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '身份验证', + '身份驗證', style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.bold, color: colorScheme.onSurface, @@ -353,7 +353,7 @@ class _RegisterPageState extends State { ), SizedBox(height: AppSpacing.xs), Text( - '上传身份证正反面完成注册', + '上傳身份證正反面完成註冊', style: AppTextStyles.bodyMedium(context).copyWith( color: colorScheme.onSurfaceVariant, ), @@ -364,9 +364,9 @@ class _RegisterPageState extends State { ), SizedBox(height: AppSpacing.xl), - // 身份证正面 + // 身份證正面 Text( - '身份证正面(人像面)', + '身份證正面(人像面)', style: AppTextStyles.bodyLarge(context).copyWith( fontWeight: FontWeight.w600, color: colorScheme.onSurface, @@ -382,9 +382,9 @@ class _RegisterPageState extends State { ), SizedBox(height: AppSpacing.lg), - // 身份证反面 + // 身份證反面 Text( - '身份证反面(国徽面)', + '身份證反面(國徽面)', style: AppTextStyles.bodyLarge(context).copyWith( fontWeight: FontWeight.w600, color: colorScheme.onSurface, @@ -394,19 +394,19 @@ class _RegisterPageState extends State { _buildUploadZone( imageFile: _backFile, imageBytes: _backBytes, - label: '国徽面', + label: '國徽面', onTap: () => _pickImage(false), colorScheme: colorScheme, ), SizedBox(height: AppSpacing.xl), - // 注册按钮 + // 註冊按鈕 Consumer( builder: (context, auth, _) { return SizedBox( width: double.infinity, child: NeonButton( - text: _isLoading ? '注册中...' : '完成注册', + text: _isLoading ? '註冊中...' : '完成註冊', type: NeonButtonType.primary, onPressed: _canSubmit && !auth.isLoading ? _handleRegister : null, height: 48, @@ -434,7 +434,7 @@ class _RegisterPageState extends State { SizedBox(width: AppSpacing.sm), Expanded( child: Text( - '您的身份信息将被加密存储,仅用于身份验证', + '您的身份信息將被加密存儲,僅用於身份驗證', style: AppTextStyles.bodySmall(context).copyWith( color: AppColorScheme.up.withValues(alpha: 0.8), ), @@ -502,7 +502,7 @@ class _RegisterPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '$label已选择', + '$label已選擇', style: AppTextStyles.bodyMedium(context).copyWith( fontWeight: FontWeight.w600, color: AppColorScheme.darkOnPrimary, @@ -551,7 +551,7 @@ class _RegisterPageState extends State { ), SizedBox(height: AppSpacing.sm), Text( - '点击上传$label', + '點擊上傳$label', style: AppTextStyles.bodyLarge(context).copyWith( color: colorScheme.onSurfaceVariant.withValues(alpha: 0.6), ), @@ -597,11 +597,11 @@ class _RegisterPageState extends State { showShadDialog( context: context, builder: (ctx) => ShadDialog.alert( - title: const Text('注册失败'), - description: Text(response.message ?? '请稍后重试'), + title: const Text('註冊失敗'), + description: Text(response.message ?? '請稍後重試'), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), ], @@ -613,11 +613,11 @@ class _RegisterPageState extends State { showShadDialog( context: context, builder: (ctx) => ShadDialog.alert( - title: const Text('注册失败'), + title: const Text('註冊失敗'), description: Text(e.toString()), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), ], @@ -630,7 +630,7 @@ class _RegisterPageState extends State { } } -/// 虚线边框画笔 +/// 虛線邊框畫筆 class _DashedBorderPainter extends CustomPainter { final Color color; final double borderRadius; diff --git a/flutter_monisuo/lib/ui/pages/home/bills_page.dart b/flutter_monisuo/lib/ui/pages/home/bills_page.dart index 0faa6eb..72ea23a 100644 --- a/flutter_monisuo/lib/ui/pages/home/bills_page.dart +++ b/flutter_monisuo/lib/ui/pages/home/bills_page.dart @@ -9,7 +9,7 @@ import '../../../data/models/account_models.dart'; import '../../../data/services/bonus_service.dart'; import '../../../providers/asset_provider.dart'; -/// 账单页面 — 代币盈亏账单 + 新人福利账单 + 推广福利账单 +/// 賬單頁面 — 代幣盈虧賬單 + 新人福利賬單 + 推廣福利賬單 class BillsPage extends StatefulWidget { const BillsPage({super.key}); @@ -42,7 +42,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix final provider = context.read(); final bonusService = context.read(); - // 并行加载持仓和福利记录 + // 並行加載持倉和福利記錄 await provider.loadTradeAccount(force: true); final welfareResponse = await bonusService.getWelfareStatus(); @@ -73,7 +73,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix if (newUser != null) { final claimed = newUser['claimed'] as bool? ?? false; final eligible = newUser['eligible'] as bool? ?? false; - // 状态: 1=已领取, 0=可领取(待领取), 2=不可用(未解锁) + // 狀態: 1=已領取, 0=可領取(待領取), 2=不可用(未解鎖) final int status; if (claimed) { status = 1; @@ -91,15 +91,15 @@ class _BillsPageState extends State with SingleTickerProviderStateMix }); } - // 推广福利列表 + // 推廣福利列表 final referralRewards = data['referralRewards'] as List? ?? []; for (var r in referralRewards) { final map = r as Map; - final username = map['username'] as String? ?? '用户'; + final username = map['username'] as String? ?? '用戶'; final milestones = map['milestones'] as List? ?? []; final claimableCount = map['claimableCount'] as int? ?? 0; - // 每个 milestone 生成一条记录 + // 每個 milestone 生成一條記錄 for (var m in milestones) { final ms = m as Map; final earned = ms['earned'] as bool? ?? false; @@ -108,26 +108,26 @@ class _BillsPageState extends State with SingleTickerProviderStateMix final int status; if (earned) { - status = 1; // 已领取 + status = 1; // 已領取 } else if (claimable) { - status = 0; // 可领取 + status = 0; // 可領取 } else { - status = 2; // 未达标 + status = 2; // 未達標 } records.add({ 'type': 'referral', - 'title': '推广福利 - $username (${milestoneVal}000)', + 'title': '推廣福利 - $username (${milestoneVal}000)', 'amount': '100.00', 'status': status, 'time': ms['claimTime'] ?? ms['createTime'], }); } - // 如果没有 milestone 但有 claimableCount,也生成记录 + // 如果沒有 milestone 但有 claimableCount,也生成記錄 if (milestones.isEmpty && claimableCount > 0) { records.add({ 'type': 'referral', - 'title': '推广福利 - $username', + 'title': '推廣福利 - $username', 'amount': '${claimableCount * 100}', 'status': 0, 'time': null, @@ -150,7 +150,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix icon: const Icon(LucideIcons.arrowLeft, size: 20), onPressed: () => Navigator.of(context).pop(), ), - title: Text('我的账单', style: AppTextStyles.headlineLarge(context)), + title: Text('我的賬單', style: AppTextStyles.headlineLarge(context)), backgroundColor: _isDark ? AppColorScheme.darkBackground : AppColorScheme.lightBackground, elevation: 0, scrolledUnderElevation: 0, @@ -163,9 +163,9 @@ class _BillsPageState extends State with SingleTickerProviderStateMix labelStyle: AppTextStyles.headlineMedium(context).copyWith(fontWeight: FontWeight.w600), unselectedLabelStyle: AppTextStyles.headlineMedium(context), tabs: const [ - Tab(text: '代币盈亏'), + Tab(text: '代幣盈虧'), Tab(text: '新人福利'), - Tab(text: '推广福利'), + Tab(text: '推廣福利'), ], ), ), @@ -183,16 +183,16 @@ class _BillsPageState extends State with SingleTickerProviderStateMix } // ============================================ - // 代币盈亏账单 + // 代幣盈虧賬單 // ============================================ Widget _buildCoinProfitTab() { final colorScheme = Theme.of(context).colorScheme; if (_holdings.isEmpty) { - return _buildEmptyState(LucideIcons.wallet, '暂无持仓记录'); + return _buildEmptyState(LucideIcons.wallet, '暫無持倉記錄'); } - // 汇总统计 + // 彙總統計 double totalCost = 0; double totalValue = 0; double totalProfit = 0; @@ -210,7 +210,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix child: ListView( padding: const EdgeInsets.all(AppSpacing.md), children: [ - // 汇总卡片 + // 彙總卡片 Container( padding: const EdgeInsets.all(AppSpacing.lg), decoration: BoxDecoration( @@ -224,7 +224,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix ), child: Column( children: [ - Text('总盈亏 (USDT)', style: AppTextStyles.bodyMedium(context).copyWith( + Text('總盈虧 (USDT)', style: AppTextStyles.bodyMedium(context).copyWith( color: colorScheme.onSurfaceVariant, )), const SizedBox(height: AppSpacing.xs), @@ -239,9 +239,9 @@ class _BillsPageState extends State with SingleTickerProviderStateMix Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - _buildSummaryItem('总成本', totalCost.toStringAsFixed(2)), + _buildSummaryItem('總成本', totalCost.toStringAsFixed(2)), Container(width: 1, height: 16, color: colorScheme.outlineVariant.withValues(alpha: 0.3)), - _buildSummaryItem('总市值', totalValue.toStringAsFixed(2)), + _buildSummaryItem('總市值', totalValue.toStringAsFixed(2)), Container(width: 1, height: 16, color: colorScheme.outlineVariant.withValues(alpha: 0.3)), _buildSummaryItem('收益率', '${profitRate >= 0 ? '+' : ''}${profitRate.toStringAsFixed(2)}%'), ], @@ -251,7 +251,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix ), const SizedBox(height: AppSpacing.md), - // 各币种盈亏明细 + // 各幣種盈虧明細 ..._holdings.map((h) => _buildCoinProfitCard(h)), ], ), @@ -296,7 +296,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix ), child: Column( children: [ - // 币名 + 盈亏金额 + // 幣名 + 盈虧金額 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -333,11 +333,11 @@ class _BillsPageState extends State with SingleTickerProviderStateMix ], ), const SizedBox(height: AppSpacing.sm), - // 明细行 + // 明細行 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text('均价: ${h.avgPrice}', style: AppTextStyles.bodySmall(context).copyWith( + Text('均價: ${h.avgPrice}', style: AppTextStyles.bodySmall(context).copyWith( color: colorScheme.onSurfaceVariant, )), Text('市值: ${h.currentValue} USDT', style: AppTextStyles.bodySmall(context).copyWith( @@ -355,7 +355,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix } // ============================================ - // 福利账单 + // 福利賬單 // ============================================ Widget _buildWelfareTab(String type) { final records = _welfareRecords.where((r) => r['type'] == type).toList(); @@ -363,7 +363,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix if (records.isEmpty) { return _buildEmptyState( LucideIcons.gift, - type == 'new_user' ? '暂无新人福利记录' : '暂无推广福利记录', + type == 'new_user' ? '暫無新人福利記錄' : '暫無推廣福利記錄', ); } @@ -382,20 +382,20 @@ class _BillsPageState extends State with SingleTickerProviderStateMix final amount = double.tryParse(record['amount']?.toString() ?? '0') ?? 0; final status = record['status'] as int? ?? 0; - // status: 0=待领取, 1=已领取, 2=未达标 + // status: 0=待領取, 1=已領取, 2=未達標 String statusText; Color statusColor; switch (status) { case 1: - statusText = '已领取'; + statusText = '已領取'; statusColor = context.appColors.up; break; case 2: - statusText = '未达标'; + statusText = '未達標'; statusColor = colorScheme.onSurfaceVariant; break; default: - statusText = '待领取'; + statusText = '待領取'; statusColor = AppColorScheme.warning; } @@ -463,7 +463,7 @@ class _BillsPageState extends State with SingleTickerProviderStateMix } // ============================================ - // 通用组件 + // 通用組件 // ============================================ Widget _buildEmptyState(IconData icon, String text) { final colorScheme = Theme.of(context).colorScheme; diff --git a/flutter_monisuo/lib/ui/pages/home/header_bar.dart b/flutter_monisuo/lib/ui/pages/home/header_bar.dart index 5138895..adf5b33 100644 --- a/flutter_monisuo/lib/ui/pages/home/header_bar.dart +++ b/flutter_monisuo/lib/ui/pages/home/header_bar.dart @@ -6,7 +6,7 @@ import '../../../core/theme/app_color_scheme.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../providers/auth_provider.dart'; -/// 首页顶栏 - Logo + 搜索/通知/头像 +/// 首頁頂欄 - Logo + 搜索/通知/頭像 class HeaderBar extends StatelessWidget { const HeaderBar({super.key}); diff --git a/flutter_monisuo/lib/ui/pages/home/home_page.dart b/flutter_monisuo/lib/ui/pages/home/home_page.dart index 0d0e02a..85eb4cd 100644 --- a/flutter_monisuo/lib/ui/pages/home/home_page.dart +++ b/flutter_monisuo/lib/ui/pages/home/home_page.dart @@ -20,7 +20,7 @@ import 'hot_coins_section.dart'; import 'profit_analysis_page.dart'; import 'bills_page.dart'; -/// 首页 +/// 首頁 class HomePage extends StatefulWidget { const HomePage({super.key}); @@ -105,13 +105,13 @@ class _HomePageState extends State // Header HeaderBar(), SizedBox(height: AppSpacing.md), - // 资产卡片(含预估盈亏) + // 資產卡片(含預估盈虧) _AssetCard( overview: provider.overview, onDeposit: _showDeposit, ), SizedBox(height: AppSpacing.md), - // 快捷操作栏 + // 快捷操作欄 QuickActionsRow( onDeposit: _showDeposit, onWithdraw: _showWithdraw, @@ -129,10 +129,10 @@ class _HomePageState extends State ), ), SizedBox(height: AppSpacing.lg), - // 热门币种 + // 熱門幣種 HotCoinsSection(), SizedBox(height: AppSpacing.lg), - // 持仓 + // 持倉 _HoldingsSection(holdings: provider.holdings), ], ), @@ -174,7 +174,7 @@ class _HomePageState extends State } } -/// 资产卡片(含预估盈亏) +/// 資產卡片(含預估盈虧) class _AssetCard extends StatefulWidget { final AssetOverview? overview; final VoidCallback onDeposit; @@ -197,7 +197,7 @@ class _AssetCardState extends State<_AssetCard> { @override void didUpdateWidget(covariant _AssetCard oldWidget) { super.didUpdateWidget(oldWidget); - // overview 更新时重新加载盈亏数据 + // overview 更新時重新加載盈虧數據 if (widget.overview != oldWidget.overview) { _loadProfit(); } @@ -239,7 +239,7 @@ class _AssetCardState extends State<_AssetCard> { final upColor = context.appColors.up; final downColor = context.appColors.down; - // 总资产 + // 總資產 final totalAsset = widget.overview?.totalAsset ?? '0.00'; final displayAsset = _formatAsset(totalAsset); @@ -249,12 +249,12 @@ class _AssetCardState extends State<_AssetCard> { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 顶部行:总资产标签 + 充值按钮 + // 頂部行:總資產標籤 + 充值按鈕 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '预估总资产(USDT)', + '預估總資產(USDT)', style: AppTextStyles.bodyLarge(context), ), GestureDetector( @@ -284,7 +284,7 @@ class _AssetCardState extends State<_AssetCard> { ), SizedBox(height: AppSpacing.sm), - // 总资产金额 + // 總資產金額 Text( displayAsset, style: AppTextStyles.displayLarge(context).copyWith( @@ -293,13 +293,13 @@ class _AssetCardState extends State<_AssetCard> { ), SizedBox(height: AppSpacing.md), - // 盈亏统计区:预估今日盈亏 | 预估总盈亏 + // 盈虧統計區:預估今日盈虧 | 預估總盈虧 Row( children: [ - // 预估今日盈亏 + // 預估今日盈虧 Expanded( child: _ProfitStatCard( - label: '预估今日盈亏', + label: '預估今日盈虧', value: _todayProfit, upColor: upColor, downColor: downColor, @@ -310,10 +310,10 @@ class _AssetCardState extends State<_AssetCard> { ), ), SizedBox(width: AppSpacing.sm), - // 预估总盈亏 + // 預估總盈虧 Expanded( child: _ProfitStatCard( - label: '预估总盈亏', + label: '預估總盈虧', value: _totalProfit, upColor: upColor, downColor: downColor, @@ -357,7 +357,7 @@ class _WelfareCard extends StatelessWidget { ), child: Row( children: [ - // 左侧图标 + // 左側圖標 Container( width: 48, height: 48, @@ -372,7 +372,7 @@ class _WelfareCard extends StatelessWidget { ), ), SizedBox(width: AppSpacing.md), - // 中间文字 + // 中間文字 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -386,14 +386,14 @@ class _WelfareCard extends StatelessWidget { SizedBox(height: AppSpacing.xs), Text( totalClaimable > 0 - ? '您有 $totalClaimable 个奖励待领取' - : '首充奖励 + 推广奖励', + ? '您有 $totalClaimable 個獎勵待領取' + : '首充獎勵 + 推廣獎勵', style: AppTextStyles.bodyMedium(context), ), ], ), ), - // 右侧按钮 + // 右側按鈕 Container( padding: EdgeInsets.symmetric( horizontal: AppSpacing.md, @@ -440,7 +440,7 @@ class _WelfareCard extends StatelessWidget { } } -/// 持仓部分 +/// 持倉部分 class _HoldingsSection extends StatelessWidget { final List holdings; @@ -454,7 +454,7 @@ class _HoldingsSection extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '我的持仓', + '我的持倉', style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.bold, ), @@ -467,7 +467,7 @@ class _HoldingsSection extends StatelessWidget { ), child: Row( children: [ - Text('资产详情', + Text('資產詳情', style: AppTextStyles.headlineSmall(context).copyWith( fontWeight: FontWeight.bold, )), @@ -486,7 +486,7 @@ class _HoldingsSection extends StatelessWidget { } } -/// 空持仓 +/// 空持倉 class _EmptyHoldings extends StatelessWidget { const _EmptyHoldings(); @@ -505,7 +505,7 @@ class _EmptyHoldings extends StatelessWidget { Icon(LucideIcons.wallet, size: 48, color: context.colors.onSurfaceVariant), SizedBox(height: AppSpacing.md), Text( - '暂无持仓', + '暫無持倉', style: AppTextStyles.headlineMedium(context).copyWith( fontWeight: FontWeight.w600, ), @@ -521,7 +521,7 @@ class _EmptyHoldings extends StatelessWidget { } } -/// 持仓列表 +/// 持倉列表 class _HoldingsList extends StatelessWidget { final List holdings; @@ -554,7 +554,7 @@ class _HoldingsList extends StatelessWidget { } } -/// 持仓项 +/// 持倉項 class _HoldingItem extends StatelessWidget { final AccountTrade holding; @@ -615,7 +615,7 @@ class _HoldingItem extends StatelessWidget { } } -/// 盈亏统计小卡片 +/// 盈虧統計小卡片 class _ProfitStatCard extends StatelessWidget { final String label; final double value; diff --git a/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart b/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart index ea7c579..b5d7f72 100644 --- a/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart +++ b/flutter_monisuo/lib/ui/pages/home/hot_coins_section.dart @@ -4,7 +4,7 @@ import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme_extension.dart'; -/// 首页热门币种区块 +/// 首頁熱門幣種區塊 class HotCoinsSection extends StatelessWidget { const HotCoinsSection({super.key}); @@ -19,7 +19,7 @@ class HotCoinsSection extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '热门币种', + '熱門幣種', style: AppTextStyles.headlineLarge(context), ), Text( diff --git a/flutter_monisuo/lib/ui/pages/home/profit_analysis_page.dart b/flutter_monisuo/lib/ui/pages/home/profit_analysis_page.dart index 4721743..ecac65c 100644 --- a/flutter_monisuo/lib/ui/pages/home/profit_analysis_page.dart +++ b/flutter_monisuo/lib/ui/pages/home/profit_analysis_page.dart @@ -6,7 +6,7 @@ import '../../../core/theme/app_spacing.dart'; import '../../../core/theme/app_theme_extension.dart'; import '../../../data/services/asset_service.dart'; -/// 盈亏分析页面 - 月度盈亏日历 +/// 盈虧分析頁面 - 月度盈虧日曆 class ProfitAnalysisPage extends StatefulWidget { const ProfitAnalysisPage({super.key}); @@ -27,7 +27,7 @@ class _ProfitAnalysisPageState extends State { } // ============================================ - // 数据加载 + // 數據加載 // ============================================ Future _loadProfit() async { @@ -64,7 +64,7 @@ class _ProfitAnalysisPageState extends State { } // ============================================ - // 盈亏数据解析 + // 盈虧數據解析 // ============================================ double? _getDayProfit(int day) { @@ -86,7 +86,7 @@ class _ProfitAnalysisPageState extends State { } // ============================================ - // 构建 UI + // 構建 UI // ============================================ @override @@ -98,7 +98,7 @@ class _ProfitAnalysisPageState extends State { return Scaffold( backgroundColor: context.colors.surface, appBar: AppBar( - title: const Text('盈亏分析'), + title: const Text('盈虧分析'), backgroundColor: context.colors.surface, elevation: 0, scrolledUnderElevation: 0, @@ -116,19 +116,19 @@ class _ProfitAnalysisPageState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - // 月度盈亏摘要 + // 月度盈虧摘要 _buildSummarySection(), SizedBox(height: AppSpacing.md), - // 月份导航 + // 月份導航 _buildMonthNavigation(isCurrentMonth), SizedBox(height: AppSpacing.sm), - // 星期标题 + // 星期標題 _buildWeekdayHeaders(), SizedBox(height: AppSpacing.xs), - // 日历网格 + // 日曆網格 if (_isLoading) _buildLoadingIndicator() else @@ -143,7 +143,7 @@ class _ProfitAnalysisPageState extends State { ); } - /// 月度盈亏摘要 + /// 月度盈虧摘要 Widget _buildSummarySection() { final upColor = context.appColors.up; final downColor = context.appColors.down; @@ -153,7 +153,7 @@ class _ProfitAnalysisPageState extends State { return Column( children: [ Text( - '月度盈亏', + '月度盈虧', style: AppTextStyles.bodyMedium(context).copyWith( color: context.colors.onSurfaceVariant, ), @@ -172,7 +172,7 @@ class _ProfitAnalysisPageState extends State { ); } - /// 月份导航行 + /// 月份導航行 Widget _buildMonthNavigation(bool isCurrentMonth) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -193,14 +193,14 @@ class _ProfitAnalysisPageState extends State { ), ), ), - // 当前年月 + // 當前年月 Text( '${_currentMonth.year}年${_currentMonth.month}月', style: AppTextStyles.headlineMedium(context).copyWith( fontWeight: FontWeight.bold, ), ), - // 下一月(当前月禁用) + // 下一月(當前月禁用) GestureDetector( onTap: isCurrentMonth ? null : _nextMonth, child: Container( @@ -224,7 +224,7 @@ class _ProfitAnalysisPageState extends State { ); } - /// 星期标题行 + /// 星期標題行 Widget _buildWeekdayHeaders() { return Row( children: ['一', '二', '三', '四', '五', '六', '日'].map((d) { @@ -243,7 +243,7 @@ class _ProfitAnalysisPageState extends State { ); } - /// 加载指示器 + /// 加載指示器 Widget _buildLoadingIndicator() { return Padding( padding: EdgeInsets.symmetric(vertical: AppSpacing.xxl), @@ -260,7 +260,7 @@ class _ProfitAnalysisPageState extends State { ); } - /// 日历网格 + /// 日曆網格 List _buildCalendarGrid( DateTime now, bool isCurrentMonth, diff --git a/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart b/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart index 2b02d1c..7763798 100644 --- a/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart +++ b/flutter_monisuo/lib/ui/pages/home/quick_actions_row.dart @@ -3,7 +3,7 @@ import 'package:shadcn_ui/shadcn_ui.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_spacing.dart'; -/// 首页快捷操作栏 - 充值/提现/划转/盈亏/账单 +/// 首頁快捷操作欄 - 充值/提現/劃轉/盈虧/賬單 class QuickActionsRow extends StatelessWidget { const QuickActionsRow({ super.key, @@ -56,25 +56,25 @@ class QuickActionsRow extends StatelessWidget { ), _ActionItem( icon: LucideIcons.arrowDownLeft, - label: '提现', + label: '提現', colorScheme: colorScheme, onTap: onWithdraw, ), _ActionItem( icon: LucideIcons.repeat, - label: '划转', + label: '劃轉', colorScheme: colorScheme, onTap: onTransfer, ), _ActionItem( icon: LucideIcons.chartPie, - label: '盈亏', + label: '盈虧', colorScheme: colorScheme, onTap: onProfit, ), _ActionItem( icon: LucideIcons.fileText, - label: '账单', + label: '賬單', colorScheme: colorScheme, onTap: onBills, ), @@ -105,7 +105,7 @@ class _ActionItem extends StatelessWidget { ? const Color(0xFF1E293B) : const Color(0xFFF3F4F6); - // Light: #4B5563, Dark: 根据主题 + // Light: #4B5563, Dark: 根據主題 final iconColor = isDark ? colorScheme.onSurfaceVariant : const Color(0xFF4B5563); diff --git a/flutter_monisuo/lib/ui/pages/main/main_page.dart b/flutter_monisuo/lib/ui/pages/main/main_page.dart index f7c4c03..5f5d242 100644 --- a/flutter_monisuo/lib/ui/pages/main/main_page.dart +++ b/flutter_monisuo/lib/ui/pages/main/main_page.dart @@ -12,7 +12,7 @@ import '../trade/trade_page.dart'; import '../asset/asset_page.dart'; import '../mine/mine_page.dart'; -/// 底部导航项 +/// 底部導航項 class _NavItem { final String label; final IconData icon; @@ -20,7 +20,7 @@ class _NavItem { const _NavItem({required this.label, required this.icon}); } -/// 主页面 - "The Kinetic Vault" 设计风格 +/// 主頁面 - "The Kinetic Vault" 設計風格 class MainPage extends StatefulWidget { const MainPage({super.key}); @@ -31,10 +31,10 @@ class MainPage extends StatefulWidget { class MainPageState extends State { int _currentIndex = 0; final Set _loadedPages = {0}; - String? _tradeCoinCode; // 交易页面选中的币种代码 + String? _tradeCoinCode; // 交易頁面選中的幣種代碼 late final List _pages; - // 防抖:记录上次刷新时间,同一 Tab 500ms 内不重复刷新 + // 防抖:記錄上次刷新時間,同一 Tab 500ms 內不重複刷新 final Map _lastRefreshTime = {}; @override @@ -55,13 +55,13 @@ class MainPageState extends State { _currentIndex = index; _loadedPages.add(index); }); - // 切换到已加载的 Tab 时刷新数据 + // 切換到已加載的 Tab 時刷新數據 if (wasLoaded) { _refreshTab(index); } } - /// 刷新对应 Tab 的数据(带防抖) + /// 刷新對應 Tab 的數據(帶防抖) void _refreshTab(int index) { final now = DateTime.now(); final last = _lastRefreshTime[index]; @@ -69,30 +69,33 @@ class MainPageState extends State { _lastRefreshTime[index] = now; switch (index) { - case 0: // 首页 - 刷新资产概览 + case 0: // 首頁 - 刷新資產概覽 context.read().loadOverview(force: true); break; - case 1: // 行情 - 刷新币种列表 + case 1: // 行情 - 刷新幣種列表 context.read().loadCoins(force: true); break; - case 3: // 资产 - 刷新全部资产 + case 3: // 資產 - 刷新全部資產 context.read().refreshAll(force: true); break; } } - /// 切换到交易页面并选中指定币种 + /// 切換到交易頁面並選中指定幣種 void switchToTrade(String coinCode) { setState(() { _tradeCoinCode = coinCode; - _currentIndex = 2; // 交易页面索引 + _currentIndex = 2; // 交易頁面索引 _loadedPages.add(2); - // 重新构建交易页面 - _pages[2] = TradePage(initialCoinCode: _tradeCoinCode); + // 重新構建交易頁面(用 Key 強制創建新 State) + _pages[2] = TradePage( + key: ValueKey(_tradeCoinCode), + initialCoinCode: _tradeCoinCode, + ); }); } - /// 切换到指定 tab + /// 切換到指定 tab void switchToTab(int index) { setState(() { _currentIndex = index; @@ -101,10 +104,10 @@ class MainPageState extends State { } static const _navItems = [ - _NavItem(label: '首页', icon: LucideIcons.house), + _NavItem(label: '首頁', icon: LucideIcons.house), _NavItem(label: '行情', icon: LucideIcons.trendingUp), _NavItem(label: '交易', icon: LucideIcons.arrowLeftRight), - _NavItem(label: '资产', icon: LucideIcons.wallet), + _NavItem(label: '資產', icon: LucideIcons.wallet), _NavItem(label: '我的', icon: LucideIcons.user), ]; @@ -128,7 +131,7 @@ class MainPageState extends State { } } -/// 底部导航栏 - 专业信任主题 +/// 底部導航欄 - 專業信任主題 class _BottomNavBar extends StatelessWidget { final List<_NavItem> items; final int currentIndex; @@ -175,7 +178,7 @@ class _BottomNavBar extends StatelessWidget { } } -/// 导航项组件 +/// 導航項組件 class _NavItemWidget extends StatelessWidget { final _NavItem item; final bool isSelected; @@ -220,7 +223,7 @@ class _NavItemWidget extends StatelessWidget { } } -/// 懒加载 IndexedStack - 只渲染已访问过的页面 +/// 懶加載 IndexedStack - 只渲染已訪問過的頁面 class LazyIndexedStack extends StatefulWidget { final int index; final Set loadedIndexes; diff --git a/flutter_monisuo/lib/ui/pages/market/market_page.dart b/flutter_monisuo/lib/ui/pages/market/market_page.dart index 52e03e3..aba0119 100644 --- a/flutter_monisuo/lib/ui/pages/market/market_page.dart +++ b/flutter_monisuo/lib/ui/pages/market/market_page.dart @@ -10,7 +10,7 @@ import '../../../providers/market_provider.dart'; import '../../components/glass_panel.dart'; import '../main/main_page.dart'; -/// 行情页面 +/// 行情頁面 class MarketPage extends StatefulWidget { const MarketPage({super.key}); @@ -62,7 +62,7 @@ class _MarketPageState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 页面标题 "行情" + // 頁面標題 "行情" Padding( padding: const EdgeInsets.only(bottom: AppSpacing.sm), child: Text( @@ -71,13 +71,13 @@ class _MarketPageState extends State ), ), const SizedBox(height: AppSpacing.md), - // 精选区域:BTC + ETH 卡片 + // 精選區域:BTC + ETH 卡片 _buildFeaturedSection(provider), const SizedBox(height: AppSpacing.md), - // 分区标题:全部币种 + 更多 + // 分區標題:全部幣種 + 更多 _buildSectionHeader(), const SizedBox(height: AppSpacing.md), - // 币种列表卡片 + // 幣種列表卡片 _buildCoinList(provider), ], ), @@ -88,7 +88,7 @@ class _MarketPageState extends State ); } - /// 精选区域:BTC + ETH 大卡片 + /// 精選區域:BTC + ETH 大卡片 Widget _buildFeaturedSection(MarketProvider provider) { final featured = provider.featuredCoins; if (featured.isEmpty) return const SizedBox.shrink(); @@ -111,13 +111,13 @@ class _MarketPageState extends State ); } - /// 分区标题:全部币种 + 更多 + /// 分區標題:全部幣種 + 更多 Widget _buildSectionHeader() { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '全部币种', + '全部幣種', style: AppTextStyles.headlineLarge(context), ), Text( @@ -130,14 +130,14 @@ class _MarketPageState extends State ); } - /// 币种列表 + /// 幣種列表 Widget _buildCoinList(MarketProvider provider) { final coins = provider.otherCoins; if (coins.isEmpty) { return _EmptyState( icon: LucideIcons.coins, - message: '暂无数据', + message: '暫無數據', onRetry: () => provider.refresh(), ); } @@ -167,7 +167,7 @@ class _MarketPageState extends State ); } - /// 错误状态 + /// 錯誤狀態 Widget _buildErrorState(MarketProvider provider) { return Center( child: Padding( @@ -178,14 +178,14 @@ class _MarketPageState extends State Icon(LucideIcons.circleAlert, size: 48, color: context.colors.error), const SizedBox(height: AppSpacing.md), Text( - provider.error ?? '加载失败', + provider.error ?? '加載失敗', style: TextStyle(color: context.colors.error), textAlign: TextAlign.center, ), const SizedBox(height: AppSpacing.md), ShadButton( onPressed: () => provider.refresh(), - child: const Text('重试'), + child: const Text('重試'), ), ], ), @@ -194,7 +194,7 @@ class _MarketPageState extends State } } -/// 精选卡片:BTC / ETH (130px 高度,含迷你柱状图) +/// 精選卡片:BTC / ETH (130px 高度,含迷你柱狀圖) class _FeaturedCard extends StatelessWidget { final Coin coin; @@ -216,13 +216,13 @@ class _FeaturedCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - // 第一行:币种名称 + 涨跌徽章 + // 第一行:幣種名稱 + 漲跌徽章 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '${coin.code}/USDT', - style: AppTextStyles.labelLarge(context), // 缩小文字 + style: AppTextStyles.labelLarge(context), // 縮小文字 ), Container( padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xs + 2, vertical: 2), @@ -234,27 +234,27 @@ class _FeaturedCard extends StatelessWidget { coin.formattedChange, style: AppTextStyles.labelSmall(context).copyWith( color: changeColor, - fontSize: 10, // 缩小文字 + fontSize: 10, // 縮小文字 ), ), ), ], ), - // 第二行:价格 + // 第二行:價格 Text( '\$${_formatFeaturedPrice(coin)}', - style: AppTextStyles.headlineLarge(context).copyWith( // 缩小文字 + style: AppTextStyles.headlineLarge(context).copyWith( // 縮小文字 fontWeight: FontWeight.bold, ), ), - // 第三行:币种全名 + // 第三行:幣種全名 Text( coin.name, - style: AppTextStyles.bodySmall(context).copyWith( // 缩小文字 + style: AppTextStyles.bodySmall(context).copyWith( // 縮小文字 color: context.colors.onSurfaceVariant, ), ), - // 第四行:迷你柱状图 + // 第四行:迷你柱狀圖 Expanded( child: _MiniBarChart(isUp: isUp, seed: coin.code.hashCode), ), @@ -263,7 +263,7 @@ class _FeaturedCard extends StatelessWidget { ); } - /// 精选卡片使用简短价格格式(带逗号) + /// 精選卡片使用簡短價格格式(帶逗號) String _formatFeaturedPrice(Coin coin) { if (coin.price >= 1000) { return _addCommas(coin.price.toStringAsFixed(2)); @@ -288,7 +288,7 @@ class _FeaturedCard extends StatelessWidget { } } -/// 迷你柱状图(模拟价格走势) +/// 迷你柱狀圖(模擬價格走勢) class _MiniBarChart extends StatelessWidget { final bool isUp; final int seed; @@ -301,7 +301,7 @@ class _MiniBarChart extends StatelessWidget { ? context.appColors.up : context.appColors.down; - // 生成随机但确定的高度序列 + // 生成隨機但確定的高度序列 final heights = _generateHeights(); return Row( @@ -310,7 +310,7 @@ class _MiniBarChart extends StatelessWidget { children: heights.map((h) { return Expanded( child: Padding( - padding: const EdgeInsets.only(left: 2), // 增加间距 + padding: const EdgeInsets.only(left: 2), // 增加間距 child: Container( height: h, decoration: BoxDecoration( @@ -326,13 +326,13 @@ class _MiniBarChart extends StatelessWidget { List _generateHeights() { final random = Random(seed); - final base = 6.0; // 降低基础高度 - final range = 12.0; // 降低范围 + final base = 6.0; // 降低基礎高度 + final range = 12.0; // 降低範圍 return List.generate(6, (_) => base + random.nextDouble() * range); } } -/// 币种列表行 +/// 幣種列表行 class _CoinRow extends StatelessWidget { final Coin coin; @@ -354,10 +354,10 @@ class _CoinRow extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 14), child: Row( children: [ - // 头像:圆形字母头像 + // 頭像:圓形字母頭像 _CoinAvatar(letter: coin.displayIcon, code: coin.code), const SizedBox(width: AppSpacing.sm + AppSpacing.xs), - // 币种信息:交易对 + 全名 + // 幣種信息:交易對 + 全名 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -375,7 +375,7 @@ class _CoinRow extends StatelessWidget { ], ), ), - // 右侧:价格 + 涨跌标签 + // 右側:價格 + 漲跌標籤 Column( crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, @@ -412,7 +412,7 @@ class _CoinRow extends StatelessWidget { } } -/// 币种头像组件 +/// 幣種頭像組件 class _CoinAvatar extends StatelessWidget { final String letter; final String code; @@ -421,7 +421,7 @@ class _CoinAvatar extends StatelessWidget { @override Widget build(BuildContext context) { - // 使用主题变量而非硬编码 + // 使用主題變量而非硬編碼 final bgColor = context.colors.primary.withValues(alpha: context.appColors.glowOpacity); return Container( @@ -456,7 +456,7 @@ class _CoinAvatar extends StatelessWidget { } } -/// 空状态 +/// 空狀態 class _EmptyState extends StatelessWidget { final IconData icon; final String message; @@ -481,7 +481,7 @@ class _EmptyState extends StatelessWidget { const SizedBox(height: AppSpacing.md), ShadButton( onPressed: onRetry, - child: const Text('重试'), + child: const Text('重試'), ), ], ], diff --git a/flutter_monisuo/lib/ui/pages/mine/components/about_dialog_helpers.dart b/flutter_monisuo/lib/ui/pages/mine/components/about_dialog_helpers.dart index e86ec54..cee1b14 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/about_dialog_helpers.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/about_dialog_helpers.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme.dart'; -/// 信息行组件(用于关于对话框) +/// 信息行組件(用於關於對話框) class InfoRow extends StatelessWidget { final IconData icon; final String text; diff --git a/flutter_monisuo/lib/ui/pages/mine/components/avatar_circle.dart b/flutter_monisuo/lib/ui/pages/mine/components/avatar_circle.dart index 715dda4..ec1d747 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/avatar_circle.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/avatar_circle.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -/// 圆形头像组件 +/// 圓形頭像組件 /// -/// 显示用户首字母或默认比特币符号。通过 [radius] 控制大小, -/// [fontSize] 控制文字大小,[text] 可传入用户头像文字。 +/// 顯示用戶首字母或默認比特幣符號。通過 [radius] 控制大小, +/// [fontSize] 控制文字大小,[text] 可傳入用戶頭像文字。 class AvatarCircle extends StatelessWidget { final double radius; final double fontSize; diff --git a/flutter_monisuo/lib/ui/pages/mine/components/logout_button.dart b/flutter_monisuo/lib/ui/pages/mine/components/logout_button.dart index 1ba0560..893ee15 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/logout_button.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/logout_button.dart @@ -3,7 +3,7 @@ import '../../../../core/theme/app_color_scheme.dart'; import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme.dart'; -/// 退出登录按钮 +/// 退出登錄按鈕 class LogoutButton extends StatelessWidget { final VoidCallback onLogout; const LogoutButton({super.key, required this.onLogout}); @@ -24,7 +24,7 @@ class LogoutButton extends StatelessWidget { ), child: Center( child: Text( - '退出登录', + '退出登錄', style: AppTextStyles.headlineMedium(context).copyWith( color: AppColorScheme.down, ), diff --git a/flutter_monisuo/lib/ui/pages/mine/components/menu_group1.dart b/flutter_monisuo/lib/ui/pages/mine/components/menu_group1.dart index f67a919..3226e22 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/menu_group1.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/menu_group1.dart @@ -10,7 +10,7 @@ import 'menu_group_container.dart'; import 'menu_row.dart'; import 'menu_trailing_widgets.dart'; -/// 菜单分组1 - 福利中心 / 实名认证 / 安全设置 / 消息通知 +/// 菜單分組1 - 福利中心 / 實名認證 / 安全設置 / 消息通知 class MenuGroup1 extends StatelessWidget { final int kycStatus; final void Function(String) onShowComingSoon; @@ -39,11 +39,11 @@ class MenuGroup1 extends StatelessWidget { }, ), const Divider(height: 1), - // 实名认证 + // 實名認證 MenuRow( icon: LucideIcons.shieldCheck, iconColor: context.appColors.up, - title: '实名认证', + title: '實名認證', trailing: KycBadge(kycStatus: kycStatus), onTap: () { if (kycStatus == 2) { @@ -57,12 +57,12 @@ class MenuGroup1 extends StatelessWidget { }, ), const Divider(height: 1), - // 安全设置 + // 安全設置 MenuRow( icon: LucideIcons.lock, iconColor: context.colors.onSurfaceVariant, - title: '安全设置', - onTap: () => onShowComingSoon('安全设置'), + title: '安全設置', + onTap: () => onShowComingSoon('安全設置'), ), const Divider(height: 1), // 消息通知 @@ -79,7 +79,7 @@ class MenuGroup1 extends StatelessWidget { } } -/// 显示 KYC 认证状态对话框 +/// 顯示 KYC 認證狀態對話框 void showKycStatusDialog(BuildContext context) { showShadDialog( context: context, @@ -88,13 +88,13 @@ void showKycStatusDialog(BuildContext context) { children: [ Icon(Icons.check_circle, color: AppColorScheme.up, size: 20), SizedBox(width: AppSpacing.sm), - const Text('实名认证'), + const Text('實名認證'), ], ), - description: const Text('您的实名认证已通过'), + description: const Text('您的實名認證已通過'), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), ], diff --git a/flutter_monisuo/lib/ui/pages/mine/components/menu_group2.dart b/flutter_monisuo/lib/ui/pages/mine/components/menu_group2.dart index b39ddbd..ec11b7d 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/menu_group2.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/menu_group2.dart @@ -4,7 +4,7 @@ import 'menu_group_container.dart'; import 'menu_row.dart'; import 'menu_trailing_widgets.dart'; -/// 菜单分组2 - 深色模式 / 系统设置 / 关于我们 +/// 菜單分組2 - 深色模式 / 系統設置 / 關於我們 class MenuGroup2 extends StatelessWidget { final VoidCallback onShowAbout; @@ -20,21 +20,21 @@ class MenuGroup2 extends StatelessWidget { // 深色模式 const DarkModeRow(), const Divider(height: 1), - // 系统设置 + // 系統設置 MenuRow( icon: LucideIcons.settings, iconColor: colorScheme.onSurfaceVariant, - title: '系统设置', + title: '系統設置', onTap: () { - // TODO: 系统设置 + // TODO: 系統設置 }, ), const Divider(height: 1), - // 关于我们 + // 關於我們 MenuRow( icon: LucideIcons.info, iconColor: colorScheme.onSurfaceVariant, - title: '关于我们', + title: '關於我們', onTap: onShowAbout, ), ], diff --git a/flutter_monisuo/lib/ui/pages/mine/components/menu_group_container.dart b/flutter_monisuo/lib/ui/pages/mine/components/menu_group_container.dart index 04644d5..714dadb 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/menu_group_container.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/menu_group_container.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme_extension.dart'; -/// 菜单分组容器 - 统一的圆角卡片样式 +/// 菜單分組容器 - 統一的圓角卡片樣式 /// -/// 所有菜单分组共享相同的容器样式:背景色、圆角、边框。 -/// 通过 [child] 传入菜单项 Column。 +/// 所有菜單分組共享相同的容器樣式:背景色、圓角、邊框。 +/// 通過 [child] 傳入菜單項 Column。 class MenuGroupContainer extends StatelessWidget { final Widget child; diff --git a/flutter_monisuo/lib/ui/pages/mine/components/menu_row.dart b/flutter_monisuo/lib/ui/pages/mine/components/menu_row.dart index 9eff0e6..4b27240 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/menu_row.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/menu_row.dart @@ -4,9 +4,9 @@ import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme_extension.dart'; -/// 单行菜单项:图标 + 标题 + 尾部组件 (chevron) +/// 單行菜單項:圖標 + 標題 + 尾部組件 (chevron) /// -/// 图标颜色 (通常是使用主题色) +/// 圖標顏色 (通常是使用主題色) class MenuRow extends StatelessWidget { final IconData icon; final Color iconColor; diff --git a/flutter_monisuo/lib/ui/pages/mine/components/menu_trailing_widgets.dart b/flutter_monisuo/lib/ui/pages/mine/components/menu_trailing_widgets.dart index c979156..055ecb4 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/menu_trailing_widgets.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/menu_trailing_widgets.dart @@ -7,12 +7,12 @@ import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme_extension.dart'; import '../../../../providers/theme_provider.dart'; -/// KYC 状态徽章 (e.g. "已认证" green badge + chevron) +/// KYC 狀態徽章 (e.g. "已認證" green badge + chevron) /// -/// 根据 [kycStatus] 显示不同状态: -/// - 2: 已认证(绿色) -/// - 1: 审核中(橙色) -/// - 其他: 仅显示 chevron +/// 根據 [kycStatus] 顯示不同狀態: +/// - 2: 已認證(綠色) +/// - 1: 審核中(橙色) +/// - 其他: 僅顯示 chevron class KycBadge extends StatelessWidget { final int kycStatus; const KycBadge({super.key, required this.kycStatus}); @@ -32,7 +32,7 @@ class KycBadge extends StatelessWidget { borderRadius: BorderRadius.circular(AppRadius.sm), ), child: Text( - '已认证', + '已認證', style: AppTextStyles.labelMedium(context).copyWith( color: green, ), @@ -59,7 +59,7 @@ class KycBadge extends StatelessWidget { borderRadius: BorderRadius.circular(AppRadius.sm), ), child: Text( - '审核中', + '審核中', style: AppTextStyles.labelMedium(context).copyWith( color: AppColorScheme.warning, ), @@ -83,7 +83,7 @@ class KycBadge extends StatelessWidget { } } -/// 红点指示器 - 消息通知 + chevron +/// 紅點指示器 - 消息通知 + chevron class RedDotIndicator extends StatelessWidget { const RedDotIndicator({super.key}); @@ -111,7 +111,7 @@ class RedDotIndicator extends StatelessWidget { } } -/// 深色模式切换行 +/// 深色模式切換行 class DarkModeRow extends StatelessWidget { const DarkModeRow({super.key}); diff --git a/flutter_monisuo/lib/ui/pages/mine/components/profile_card.dart b/flutter_monisuo/lib/ui/pages/mine/components/profile_card.dart index 3b91dad..acd39a2 100644 --- a/flutter_monisuo/lib/ui/pages/mine/components/profile_card.dart +++ b/flutter_monisuo/lib/ui/pages/mine/components/profile_card.dart @@ -5,7 +5,7 @@ import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme_extension.dart'; import 'avatar_circle.dart'; -/// 用户资料卡片 - 头像 + 用户名 + 徽章 + chevron +/// 用戶資料卡片 - 頭像 + 用戶名 + 徽章 + chevron class ProfileCard extends StatelessWidget { final dynamic user; const ProfileCard({super.key, required this.user}); @@ -37,12 +37,12 @@ class ProfileCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - user?.username ?? '未登录', + user?.username ?? '未登錄', style: AppTextStyles.headlineLarge(context), ), const SizedBox(height: 4), Text( - '普通用户', + '普通用戶', style: AppTextStyles.bodyMedium(context).copyWith( fontWeight: FontWeight.normal, ), diff --git a/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart b/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart index 79a8383..aecadb3 100644 --- a/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart +++ b/flutter_monisuo/lib/ui/pages/mine/kyc_page.dart @@ -11,7 +11,7 @@ import '../../../providers/auth_provider.dart'; import '../../components/glass_panel.dart'; import '../../components/neon_glow.dart'; -/// KYC 实名认证页面 +/// KYC 實名認證頁面 class KycPage extends StatefulWidget { final bool returnToWithdraw; @@ -64,7 +64,7 @@ class _KycPageState extends State { backgroundColor: colorScheme.surface.withOpacity(0.0), elevation: 0, title: Text( - '实名认证', + '實名認證', style: AppTextStyles.headlineLarge(context), ), leading: IconButton( @@ -77,17 +77,17 @@ class _KycPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 步骤指示器 + // 步驟指示器 _buildStepIndicator(colorScheme), SizedBox(height: AppSpacing.xl), - // 主表单区 + // 主表單區 GlassPanel( padding: EdgeInsets.all(AppSpacing.lg), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 标题区 + // 標題區 Row( children: [ Container( @@ -107,12 +107,12 @@ class _KycPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '身份验证', + '身份驗證', style: AppTextStyles.headlineLarge(context), ), SizedBox(height: 2), Text( - '上传身份证正反面完成实名认证', + '上傳身份證正反面完成實名認證', style: AppTextStyles.bodyMedium(context), ), ], @@ -121,9 +121,9 @@ class _KycPageState extends State { ), SizedBox(height: AppSpacing.xl), - // 身份证正面上传区 + // 身份證正面上傳區 Text( - '身份证正面(人像面)', + '身份證正面(人像面)', style: AppTextStyles.headlineSmall(context), ), SizedBox(height: AppSpacing.sm), @@ -136,26 +136,26 @@ class _KycPageState extends State { ), SizedBox(height: AppSpacing.lg), - // 身份证反面上传区 + // 身份證反面上傳區 Text( - '身份证反面(国徽面)', + '身份證反面(國徽面)', style: AppTextStyles.headlineSmall(context), ), SizedBox(height: AppSpacing.sm), _buildUploadZone( imageFile: _backFile, imageBytes: _backBytes, - label: '国徽面', + label: '國徽面', onTap: () => _pickImage(false), colorScheme: colorScheme, ), SizedBox(height: AppSpacing.xl), - // 提交按钮 + // 提交按鈕 SizedBox( width: double.infinity, child: NeonButton( - text: _isSubmitting ? '提交中...' : '提交认证', + text: _isSubmitting ? '提交中...' : '提交認證', type: NeonButtonType.primary, onPressed: _canSubmit ? _submitKyc : null, height: 48, @@ -187,7 +187,7 @@ class _KycPageState extends State { SizedBox(width: AppSpacing.sm), Expanded( child: Text( - '您的身份信息将被加密存储,仅用于身份验证', + '您的身份信息將被加密存儲,僅用於身份驗證', style: AppTextStyles.bodySmall(context).copyWith( color: AppColorScheme.up.withOpacity(0.8), ), @@ -209,7 +209,7 @@ class _KycPageState extends State { children: [ _buildStepCircle( number: '1', - label: '上传证件', + label: '上傳證件', isActive: true, isComplete: isComplete, colorScheme: colorScheme, @@ -224,7 +224,7 @@ class _KycPageState extends State { ), _buildStepCircle( number: '2', - label: '认证完成', + label: '認證完成', isActive: false, isComplete: false, colorScheme: colorScheme, @@ -317,12 +317,12 @@ class _KycPageState extends State { child: Stack( fit: StackFit.expand, children: [ - // 图片预览 - 使用 memory 以兼容 Web + // 圖片預覽 - 使用 memory 以兼容 Web Image.memory( imageBytes!, fit: BoxFit.cover, ), - // 底部渐变遮罩 + 文字 + // 底部漸變遮罩 + 文字 Positioned( left: 0, right: 0, @@ -348,7 +348,7 @@ class _KycPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '$label已选择', + '$label已選擇', style: AppTextStyles.labelLarge(context).copyWith( color: colorScheme.onPrimary, ), @@ -400,7 +400,7 @@ class _KycPageState extends State { ), SizedBox(height: AppSpacing.sm), Text( - '点击上传$label', + '點擊上傳$label', style: AppTextStyles.bodyLarge(context).copyWith( color: colorScheme.onSurfaceVariant.withOpacity(0.6), ), @@ -442,13 +442,13 @@ class _KycPageState extends State { size: 20, ), SizedBox(width: AppSpacing.sm), - const Text('认证成功'), + const Text('認證成功'), ], ), - description: const Text('您的实名认证已通过,现在可以进行提现操作'), + description: const Text('您的實名認證已通過,現在可以進行提現操作'), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () { Navigator.of(ctx).pop(); Navigator.of(context).pop(); @@ -461,11 +461,11 @@ class _KycPageState extends State { showShadDialog( context: context, builder: (ctx) => ShadDialog.alert( - title: const Text('认证失败'), - description: Text(response.message ?? '请稍后重试'), + title: const Text('認證失敗'), + description: Text(response.message ?? '請稍後重試'), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), ], @@ -477,11 +477,11 @@ class _KycPageState extends State { showShadDialog( context: context, builder: (ctx) => ShadDialog.alert( - title: const Text('认证失败'), + title: const Text('認證失敗'), description: Text(e.toString()), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), ], @@ -494,7 +494,7 @@ class _KycPageState extends State { } } -/// 虚线边框画笔 +/// 虛線邊框畫筆 class _DashedBorderPainter extends CustomPainter { final Color color; final double borderRadius; diff --git a/flutter_monisuo/lib/ui/pages/mine/mine_page.dart b/flutter_monisuo/lib/ui/pages/mine/mine_page.dart index e04b796..c55e418 100644 --- a/flutter_monisuo/lib/ui/pages/mine/mine_page.dart +++ b/flutter_monisuo/lib/ui/pages/mine/mine_page.dart @@ -13,7 +13,7 @@ import 'components/menu_group1.dart'; import 'components/menu_group2.dart'; import 'components/profile_card.dart'; -/// 我的页面 - 匹配 .pen 设计稿 +/// 我的頁面 - 匹配 .pen 設計稿 class MinePage extends StatefulWidget { const MinePage({super.key}); @@ -77,10 +77,10 @@ class _MinePageState extends State children: [ Icon(Icons.construction, color: AppColorScheme.warning, size: 20), SizedBox(width: AppSpacing.sm), - const Text('功能开发中'), + const Text('功能開發中'), ], ), - description: Text('$feature功能正在开发中,敬请期待~'), + description: Text('$feature功能正在開發中,敬請期待~'), actions: [ ShadButton( child: const Text('知道了'), @@ -100,7 +100,7 @@ class _MinePageState extends State children: [ AvatarCircle(radius: 20, fontSize: 16), SizedBox(width: AppSpacing.sm + AppSpacing.xs), - const Text('模拟所'), + const Text('模擬所'), ], ), child: Column( @@ -108,7 +108,7 @@ class _MinePageState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '虚拟货币模拟交易平台', + '虛擬貨幣模擬交易平臺', style: TextStyle(color: colorScheme.onSurfaceVariant), ), SizedBox(height: AppSpacing.md), @@ -121,7 +121,7 @@ class _MinePageState extends State ), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(context).pop(), ), ], @@ -133,8 +133,8 @@ class _MinePageState extends State showShadDialog( context: context, builder: (ctx) => ShadDialog.alert( - title: const Text('确认退出'), - description: const Text('确定要退出登录吗?'), + title: const Text('確認退出'), + description: const Text('確定要退出登錄嗎?'), actions: [ ShadButton.outline( child: const Text('取消'), diff --git a/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart b/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart index 51fbd93..6c65906 100644 --- a/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart +++ b/flutter_monisuo/lib/ui/pages/mine/welfare_center_page.dart @@ -11,7 +11,7 @@ import '../../../core/event/app_event_bus.dart'; import '../../../data/services/bonus_service.dart'; import '../../../providers/asset_provider.dart'; -/// 福利中心页面 +/// 福利中心頁面 class WelfareCenterPage extends StatefulWidget { const WelfareCenterPage({super.key}); @@ -45,10 +45,10 @@ class _WelfareCenterPageState extends State { } // ============================================ - // 容器样式辅助 + // 容器樣式輔助 // ============================================ - /// 标准卡片容器 + /// 標準卡片容器 BoxDecoration _cardDecoration({Color? borderColor}) { return BoxDecoration( color: context.appColors.surfaceCard, @@ -59,11 +59,11 @@ class _WelfareCenterPageState extends State { ); } - /// 金色渐变卡片容器 + /// 金色漸變卡片容器 BoxDecoration _goldGradientDecoration() { final isDark = context.isDark; - // Light Mode: 琥珀色渐变(从 amber 15% 到深灰 5%) - // Dark Mode: 金色渐变 + // Light Mode: 琥珀色漸變(從 amber 15% 到深灰 5%) + // Dark Mode: 金色漸變 final gradientColors = isDark ? [ context.appColors.accentPrimary.withValues(alpha: 0.15), @@ -90,7 +90,7 @@ class _WelfareCenterPageState extends State { ); } - /// 状态胶囊标签 + /// 狀態膠囊標籤 Widget _statusBadge(String text, Color textColor, Color bgColor) { return Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 6), // [4,10] → [6,14] @@ -105,7 +105,7 @@ class _WelfareCenterPageState extends State { ); } - /// 全宽按钮 + /// 全寬按鈕 Widget _fullWidthButton({ required String text, required Color backgroundColor, @@ -192,7 +192,7 @@ class _WelfareCenterPageState extends State { } // ============================================ - // 推广码卡片(金色渐变边框 Hero Card) + // 推廣碼卡片(金色漸變邊框 Hero Card) // ============================================ Widget _buildReferralCodeCard(BuildContext context) { @@ -206,13 +206,13 @@ class _WelfareCenterPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Header Row: gift icon + 标题 + // Header Row: gift icon + 標題 Row( children: [ Icon(LucideIcons.gift, color: goldAccent, size: 24), const SizedBox(width: 10), Text( - '我的邀请码', + '我的邀請碼', style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.w700, ), @@ -221,9 +221,9 @@ class _WelfareCenterPageState extends State { ), const SizedBox(height: 16), Text( - referralCode.isEmpty ? '暂无邀请码' : referralCode, + referralCode.isEmpty ? '暫無邀請碼' : referralCode, style: AppTextStyles.displayMedium(context).copyWith( - fontSize: 24, // 明确设置为 24px + fontSize: 24, // 明確設置為 24px fontWeight: FontWeight.w800, color: goldAccent, letterSpacing: 2, @@ -238,7 +238,7 @@ class _WelfareCenterPageState extends State { ? null : () { Clipboard.setData(ClipboardData(text: referralCode)); - ToastUtils.show('邀请码已复制'); + ToastUtils.show('邀請碼已複製'); }, style: ElevatedButton.styleFrom( backgroundColor: goldAccent, @@ -250,7 +250,7 @@ class _WelfareCenterPageState extends State { disabledBackgroundColor: goldAccent.withValues(alpha: 0.4), ), child: Text( - '复制邀请码', + '複製邀請碼', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onPrimary), ), ), @@ -272,7 +272,7 @@ class _WelfareCenterPageState extends State { final claimed = newUserBonus?['claimed'] as bool? ?? false; final deposited = newUserBonus?['deposited'] as bool? ?? false; - // 状态判定 + // 狀態判定 String badgeText; bool showAvailableBadge; String buttonText; @@ -280,23 +280,23 @@ class _WelfareCenterPageState extends State { String description; if (claimed) { - badgeText = '已领取'; + badgeText = '已領取'; showAvailableBadge = false; - buttonText = '已领取'; + buttonText = '已領取'; canClaim = false; - description = '新人福利已领取'; + description = '新人福利已領取'; } else if (eligible) { - badgeText = '可领取'; + badgeText = '可領取'; showAvailableBadge = true; - buttonText = '立即领取'; + buttonText = '立即領取'; canClaim = true; - description = '完成首次充值即可领取'; + description = '完成首次充值即可領取'; } else { - badgeText = deposited ? '已充值' : '待解锁'; + badgeText = deposited ? '已充值' : '待解鎖'; showAvailableBadge = false; - buttonText = '未解锁'; + buttonText = '未解鎖'; canClaim = false; - description = deposited ? '已充值,等待系统确认' : '完成首次充值即可领取'; + description = deposited ? '已充值,等待系統確認' : '完成首次充值即可領取'; } return Container( @@ -306,7 +306,7 @@ class _WelfareCenterPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Header: 标题 + 状态标签 + // Header: 標題 + 狀態標籤 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -348,14 +348,14 @@ class _WelfareCenterPageState extends State { } // ============================================ - // 推广奖励列表 + // 推廣獎勵列表 // ============================================ Widget _buildReferralRewardsSection(BuildContext context) { final referralRewards = _welfareData?['referralRewards'] as List? ?? []; - // 汇总统计 + // 彙總統計 int totalEarned = 0; int totalClaimable = 0; for (var r in referralRewards) { @@ -373,17 +373,17 @@ class _WelfareCenterPageState extends State { children: [ // Section Header Text( - '推广奖励', + '推廣獎勵', style: AppTextStyles.headlineLarge(context), ), const SizedBox(height: 4), Text( - '每邀请一位好友充值达标,奖励100 USDT', + '每邀請一位好友充值達標,獎勵100 USDT', style: AppTextStyles.bodySmall(context).copyWith( color: context.appColors.onSurfaceMuted, ), ), - // 汇总统计 + // 彙總統計 if (referralRewards.isNotEmpty) ...[ const SizedBox(height: 12), Container( @@ -395,12 +395,12 @@ class _WelfareCenterPageState extends State { ), child: Row( children: [ - _buildStatItem('已邀请', '${referralRewards.length}人'), + _buildStatItem('已邀請', '${referralRewards.length}人'), Container(width: 1, height: 20, color: context.appColors.ghostBorder), - _buildStatItem('已获得', '${totalEarned * 100} USDT'), + _buildStatItem('已獲得', '${totalEarned * 100} USDT'), if (totalClaimable > 0) ...[ Container(width: 1, height: 20, color: context.appColors.ghostBorder), - _buildStatItem('待领取', '$totalClaimable个', highlight: true), + _buildStatItem('待領取', '$totalClaimable個', highlight: true), ], ], ), @@ -408,7 +408,7 @@ class _WelfareCenterPageState extends State { ], const SizedBox(height: 12), - // 推广列表卡片 + // 推廣列表卡片 Container( width: double.infinity, decoration: _cardDecoration(), @@ -450,7 +450,7 @@ class _WelfareCenterPageState extends State { ), const SizedBox(height: 8), Text( - '暂无推广用户', + '暫無推廣用戶', style: AppTextStyles.bodyLarge(context).copyWith( color: context.colors.onSurfaceVariant, ), @@ -470,18 +470,21 @@ class _WelfareCenterPageState extends State { final claimableCount = data['claimableCount'] as int? ?? 0; final milestones = data['milestones'] as List? ?? []; final userId = data['userId'] as int? ?? 0; + final indirectRefCount = data['indirectRefCount'] as int? ?? 0; + final indirectClaimableCount = data['indirectClaimableCount'] as int? ?? 0; + final indirectMilestones = data['indirectMilestones'] as List? ?? []; final isLast = index == referralRewards.length - 1; - // 进度计算 + // 進度計算 final progress = _computeProgress(milestones, totalDeposit); - // 操作按钮 + // 操作按鈕 final actionWidget = _buildReferralAction( data: data, claimableCount: claimableCount, milestones: milestones, progress: progress, ); - // 进度条颜色 + // 進度條顏色 final progressColor = _referralProgressColor(claimableCount, progress); return Column( @@ -526,11 +529,21 @@ class _WelfareCenterPageState extends State { ), ), ), - // 里程碑详情 + // 里程碑詳情 if (milestones.isNotEmpty) ...[ const SizedBox(height: 12), _buildMilestoneDetails(milestones, userId), ], + // 間接推廣獎勵 + if (indirectRefCount > 0) ...[ + const SizedBox(height: 12), + _buildIndirectSection( + userId, + indirectRefCount, + indirectClaimableCount, + indirectMilestones, + ), + ], ], ), ), @@ -546,7 +559,7 @@ class _WelfareCenterPageState extends State { ); } - /// 里程碑详情行 — 显示每个里程碑状态 + /// 里程碑詳情行 — 顯示每個里程碑狀態 Widget _buildMilestoneDetails(List milestones, int userId) { final upColor = context.appColors.up; @@ -625,7 +638,7 @@ class _WelfareCenterPageState extends State { ); } - /// 计算推荐奖励进度 + /// 計算推薦獎勵進度 double _computeProgress(List milestones, String totalDeposit) { if (milestones.isNotEmpty) { int earnedCount = milestones.where((m) { @@ -638,14 +651,14 @@ class _WelfareCenterPageState extends State { return (deposit / 1000).clamp(0.0, 1.0); } - /// 根据状态获取进度条颜色 + /// 根據狀態獲取進度條顏色 Color _referralProgressColor(int claimableCount, double progress) { if (claimableCount > 0) return context.appColors.up; if (progress > 0) return context.appColors.accentPrimary; return context.appColors.surfaceCardHigh; } - /// 构建推荐奖励的操作按钮 + /// 構建推薦獎勵的操作按鈕 Widget? _buildReferralAction({ required Map data, required int claimableCount, @@ -665,21 +678,136 @@ class _WelfareCenterPageState extends State { return GestureDetector( onTap: () => _claimReferralBonus(data['userId'] as int, milestoneValue), - child: _statusBadge('领取', profitGreen, profitGreenBg), + child: _statusBadge('領取', profitGreen, profitGreenBg), ); } if (progress > 0) { final warningColor = AppColorScheme.warning; - return _statusBadge('进行中', warningColor, warningColor.withValues(alpha: 0.15)); + return _statusBadge('進行中', warningColor, warningColor.withValues(alpha: 0.15)); } return Text( - '待达标', + '待達標', style: AppTextStyles.labelLarge(context).copyWith(color: context.appColors.onSurfaceMuted), ); } // ============================================ - // 奖励规则卡片 + // 間接推廣獎勵區塊 + // ============================================ + + Widget _buildIndirectSection( + int directReferralId, + int indirectRefCount, + int indirectClaimableCount, + List indirectMilestones, + ) { + final goldAccent = context.appColors.accentPrimary; + + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: context.appColors.surfaceCardHigh.withValues(alpha: 0.5), + borderRadius: BorderRadius.circular(AppRadius.md), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon(LucideIcons.users, size: 14, color: goldAccent), + const SizedBox(width: 6), + Text( + '已推廣 $indirectRefCount 人', + style: AppTextStyles.bodyMedium(context).copyWith( + color: context.colors.onSurfaceVariant, + ), + ), + if (indirectClaimableCount > 0) ...[ + const Spacer(), + _statusBadge( + '$indirectClaimableCount 個可領', + context.appColors.up, + context.appColors.upBackground, + ), + ], + ], + ), + // 間接里程碑標籤 + if (indirectMilestones.isNotEmpty) ...[ + const SizedBox(height: 8), + _buildIndirectMilestoneTags(directReferralId, indirectMilestones), + ], + ], + ), + ); + } + + Widget _buildIndirectMilestoneTags(int directReferralId, List milestones) { + final upColor = context.appColors.up; + + return Wrap( + spacing: 6, + runSpacing: 6, + children: milestones.map((m) { + final ms = m as Map; + final milestoneVal = ms['milestone'] as int? ?? 1; + final earned = ms['earned'] as bool? ?? false; + final claimed = ms['claimed'] as bool? ?? false; + final claimable = ms['claimable'] as bool? ?? false; + final indirectReferredUserId = ms['indirectReferredUserId'] as int? ?? 0; + + // 不顯示未達標的里程碑 + if (!earned && !claimed) return const SizedBox.shrink(); + + Color bgColor; + Color textColor; + String label; + + if (claimed) { + bgColor = upColor.withValues(alpha: 0.1); + textColor = upColor; + label = '50\u2713'; + } else if (claimable) { + bgColor = context.appColors.accentPrimary.withValues(alpha: 0.15); + textColor = context.appColors.accentPrimary; + label = '50\u{1F381}'; + } else { + bgColor = context.appColors.surfaceCardHigh; + textColor = context.colors.onSurfaceVariant; + label = '50'; + } + + return GestureDetector( + onTap: claimable + ? () => _claimIndirectReferralBonus( + directReferralId, + indirectReferredUserId, + milestoneVal, + ) + : null, + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), + decoration: BoxDecoration( + color: bgColor, + borderRadius: BorderRadius.circular(AppRadius.sm), + border: claimable ? Border.all(color: textColor.withValues(alpha: 0.3)) : null, + ), + child: Text( + label, + style: AppTextStyles.bodySmall(context).copyWith( + fontSize: 11, + fontWeight: FontWeight.w600, + color: textColor, + ), + ), + ), + ); + }).toList(), + ); + } + + // ============================================ + // 獎勵規則卡片 // ============================================ Widget _buildRulesCard(BuildContext context) { @@ -694,13 +822,14 @@ class _WelfareCenterPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '奖励规则', + '獎勵規則', style: AppTextStyles.headlineSmall(context), ), const SizedBox(height: 8), - _buildRuleItem('新用户注册完成实名认证奖励 100 USDT'), - _buildRuleItem('邀请好友充值每达 1000 USDT,双方各获得 100 USDT'), - _buildRuleItem('奖励直接发放至资金账户'), + _buildRuleItem('新用戶註冊完成實名認證獎勵 100 USDT'), + _buildRuleItem('邀請好友充值每達 1000 USDT,獎勵 100 USDT'), + _buildRuleItem('好友推廣的人充值每達 1000 USDT,額外獎勵 50 USDT'), + _buildRuleItem('獎勵直接發放至資金賬戶'), ], ), ); @@ -719,7 +848,7 @@ class _WelfareCenterPageState extends State { } // ============================================ - // 业务逻辑 + // 業務邏輯 // ============================================ Future _claimNewUserBonus() async { @@ -731,13 +860,13 @@ class _WelfareCenterPageState extends State { if (response.success) { context.read().refreshAll(force: true); context.read().fire(AppEventType.assetChanged); - ToastUtils.show('领取成功!100 USDT 已到账'); + ToastUtils.show('領取成功!100 USDT 已到賬'); _loadData(); } else { - ToastUtils.show(response.message ?? '领取失败'); + ToastUtils.show(response.message ?? '領取失敗'); } } catch (e) { - ToastUtils.show('领取失败: $e'); + ToastUtils.show('領取失敗: $e'); } } @@ -753,13 +882,40 @@ class _WelfareCenterPageState extends State { if (response.success) { context.read().refreshAll(force: true); context.read().fire(AppEventType.assetChanged); - ToastUtils.show('领取成功!100 USDT 已到账'); + ToastUtils.show('領取成功!100 USDT 已到賬'); _loadData(); } else { - ToastUtils.show(response.message ?? '领取失败'); + ToastUtils.show(response.message ?? '領取失敗'); } } catch (e) { - ToastUtils.show('领取失败: $e'); + ToastUtils.show('領取失敗: $e'); + } + } + + Future _claimIndirectReferralBonus( + int directReferralId, + int indirectReferredUserId, + int milestone, + ) async { + try { + final bonusService = context.read(); + final response = await bonusService.claimIndirectReferralBonus( + directReferralId, + indirectReferredUserId, + milestone, + ); + if (!mounted) return; + + if (response.success) { + context.read().refreshAll(force: true); + context.read().fire(AppEventType.assetChanged); + ToastUtils.show('領取成功!50 USDT 已到賬'); + _loadData(); + } else { + ToastUtils.show(response.message ?? '領取失敗'); + } + } catch (e) { + ToastUtils.show('領取失敗: $e'); } } } diff --git a/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart b/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart index dd56f7d..41d1520 100644 --- a/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart +++ b/flutter_monisuo/lib/ui/pages/onboarding/onboarding_page.dart @@ -6,12 +6,12 @@ import '../../../core/theme/app_theme.dart'; import '../../../core/theme/app_theme_extension.dart'; import '../../../core/storage/local_storage.dart'; -/// 引导页数据模型 +/// 引導頁數據模型 class _OnboardingItem { final String title; final String description; - final IconData? icon; // 图标(二选一) - final String? imagePath; // 图片路径(二选一) + final IconData? icon; // 圖標(二選一) + final String? imagePath; // 圖片路徑(二選一) final List gradientColors; const _OnboardingItem({ @@ -23,7 +23,7 @@ class _OnboardingItem { }); } -/// 首次启动引导页 +/// 首次啟動引導頁 class OnboardingPage extends StatefulWidget { final VoidCallback onComplete; @@ -39,27 +39,27 @@ class _OnboardingPageState extends State { final _items = const [ _OnboardingItem( - title: '实时行情', - description: '全球市场行情实时更新,把握每一个投资机会', - imagePath: 'assets/images/onboarding_1.png', // 替换为你的图片 + title: '實時行情', + description: '全球市場行情實時更新,把握每一個投資機會', + imagePath: 'assets/images/onboarding_1.png', // 替換為你的圖片 gradientColors: [AppColorScheme.darkPrimary, AppColorScheme.darkPrimaryContainer], ), _OnboardingItem( - title: '模拟交易', - description: '零风险体验真实交易,学习投资策略', - imagePath: 'assets/images/onboarding_2.png', // 替换为你的图片 + title: '模擬交易', + description: '零風險體驗真實交易,學習投資策略', + imagePath: 'assets/images/onboarding_2.png', // 替換為你的圖片 gradientColors: [AppColorScheme.darkTertiary, AppColorScheme.darkTertiaryContainer], ), _OnboardingItem( - title: '资产管理', - description: '清晰的资产概览,轻松管理你的投资组合', - imagePath: 'assets/images/onboarding_3.png', // 替换为你的图片 + title: '資產管理', + description: '清晰的資產概覽,輕鬆管理你的投資組合', + imagePath: 'assets/images/onboarding_3.png', // 替換為你的圖片 gradientColors: [AppColorScheme.darkSecondary, AppColorScheme.darkSecondaryFixed], ), _OnboardingItem( title: '安全可靠', - description: '数据加密存储,保护你的隐私安全', - imagePath: 'assets/images/onboarding_4.png', // 替换为你的图片 + description: '數據加密存儲,保護你的隱私安全', + imagePath: 'assets/images/onboarding_4.png', // 替換為你的圖片 gradientColors: [AppColorScheme.darkPrimaryFixed, AppColorScheme.darkPrimaryFixedDim], ), ]; @@ -97,7 +97,7 @@ class _OnboardingPageState extends State { body: SafeArea( child: Column( children: [ - // 顶部跳过按钮 + // 頂部跳過按鈕 Padding( padding: const EdgeInsets.symmetric( horizontal: AppSpacing.lg, @@ -109,7 +109,7 @@ class _OnboardingPageState extends State { TextButton( onPressed: _skip, child: Text( - '跳过', + '跳過', style: AppTextStyles.headlineMedium(context).copyWith( color: context.colors.onSurfaceVariant, ), @@ -118,7 +118,7 @@ class _OnboardingPageState extends State { ], ), ), - // 页面内容 + // 頁面內容 Expanded( child: PageView.builder( controller: _pageController, @@ -133,7 +133,7 @@ class _OnboardingPageState extends State { }, ), ), - // 底部指示器和按钮 + // 底部指示器和按鈕 Padding( padding: const EdgeInsets.fromLTRB( AppSpacing.lg, @@ -143,7 +143,7 @@ class _OnboardingPageState extends State { ), child: Column( children: [ - // 页面指示器 + // 頁面指示器 Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate( @@ -152,7 +152,7 @@ class _OnboardingPageState extends State { ), ), const SizedBox(height: AppSpacing.xl), - // 下一步/开始按钮 + // 下一步/開始按鈕 SizedBox( width: double.infinity, height: 56, @@ -167,7 +167,7 @@ class _OnboardingPageState extends State { elevation: 0, ), child: Text( - _currentPage == _items.length - 1 ? '开始使用' : '下一步', + _currentPage == _items.length - 1 ? '開始使用' : '下一步', style: AppTextStyles.headlineLarge(context).copyWith( fontWeight: FontWeight.w600, ), @@ -189,7 +189,7 @@ class _OnboardingPageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - // 图标/图片容器 + // 圖標/圖片容器 Container( width: 200, height: 200, @@ -217,7 +217,7 @@ class _OnboardingPageState extends State { height: 180, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { - // 图片加载失败时显示图标 + // 圖片加載失敗時顯示圖標 return Icon( item.icon ?? LucideIcons.image, size: 72, @@ -234,7 +234,7 @@ class _OnboardingPageState extends State { ), ), const SizedBox(height: AppSpacing.xxl + AppSpacing.lg), - // 标题 + // 標題 Text( item.title, style: AppTextStyles.displaySmall(context).copyWith( diff --git a/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart b/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart index 711d1ff..8df2707 100644 --- a/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart +++ b/flutter_monisuo/lib/ui/pages/orders/fund_order_card.dart @@ -14,7 +14,7 @@ class _FundOrderCard extends StatelessWidget { Color _getStatusColor(int status, bool isDeposit) { if (isDeposit) { - // 充值状态: 1=待付款, 2=待确认, 3=已完成, 4=已驳回, 5=已取消 + // 充值狀態: 1=待付款, 2=待確認, 3=已完成, 4=已駁回, 5=已取消 switch (status) { case 1: return AppColorScheme.warning; @@ -30,7 +30,7 @@ class _FundOrderCard extends StatelessWidget { return AppColorScheme.muted; } } else { - // 提现状态: 1=待审批, 2=已出款, 3=已驳回, 4=已取消, 5=待财务审核 + // 提現狀態: 1=待審批, 2=已出款, 3=已駁回, 4=已取消, 5=待財務審核 switch (status) { case 1: return AppColorScheme.warning; @@ -54,11 +54,11 @@ class _FundOrderCard extends StatelessWidget { case 1: return '待付款'; case 2: - return '待确认'; + return '待確認'; case 3: return '已完成'; case 4: - return '已驳回'; + return '已駁回'; case 5: return '已取消'; default: @@ -67,15 +67,15 @@ class _FundOrderCard extends StatelessWidget { } else { switch (status) { case 1: - return '待审批'; + return '待審批'; case 2: return '已出款'; case 3: - return '已驳回'; + return '已駁回'; case 4: return '已取消'; case 5: - return '待财务审核'; + return '待財務審核'; default: return '未知'; } @@ -121,7 +121,7 @@ class _FundOrderCard extends StatelessWidget { if (order.fee != null) ...[ Row( children: [ - Text('手续费(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('手續費(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text('-${order.fee} USDT', style: AppTextStyles.bodyMedium(context)), ], ), @@ -130,7 +130,7 @@ class _FundOrderCard extends StatelessWidget { if (order.receivableAmount != null) ...[ Row( children: [ - Text('到账金额: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('到賬金額: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text('${order.receivableAmount} USDT', style: AppTextStyles.bodyMedium(context).copyWith(fontWeight: FontWeight.w700)), ], ), @@ -139,7 +139,7 @@ class _FundOrderCard extends StatelessWidget { if (order.network != null) ...[ Row( children: [ - Text('提现网络: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現網絡: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text(order.network!, style: AppTextStyles.bodyMedium(context)), ], ), @@ -148,7 +148,7 @@ class _FundOrderCard extends StatelessWidget { if (order.walletAddress != null) ...[ Row( children: [ - Text('提现地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Expanded( child: Text( order.walletAddress!, @@ -164,16 +164,16 @@ class _FundOrderCard extends StatelessWidget { ], Row( children: [ - Text('订单号: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('訂單號: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text(order.orderNo, style: AppTextStyles.bodyMedium(context)), ], ), SizedBox(height: AppSpacing.xs), Row( children: [ - Text('创建时间: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('創建時間: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text( - order.createTime?.toString() ?? '无', + order.createTime?.toString() ?? '無', style: AppTextStyles.bodyMedium(context), ), ], @@ -182,7 +182,7 @@ class _FundOrderCard extends StatelessWidget { SizedBox(height: AppSpacing.xs), Row( children: [ - Text('驳回原因: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('駁回原因: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Expanded( child: Text( order.rejectReason!, @@ -206,7 +206,7 @@ class _FundOrderCard extends StatelessWidget { Expanded( child: ShadButton.outline( onPressed: () => _handleCancel(context), - child: const Text('取消订单'), + child: const Text('取消訂單'), ), ), ], @@ -222,12 +222,12 @@ class _FundOrderCard extends StatelessWidget { if (context.mounted) { if (response.success) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('已确认打款,请等待审核')), + const SnackBar(content: Text('已確認打款,請等待審核')), ); context.read().loadFundOrders(); } else { ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(response.message ?? '确认失败')), + SnackBar(content: Text(response.message ?? '確認失敗')), ); } } @@ -238,12 +238,12 @@ class _FundOrderCard extends StatelessWidget { if (context.mounted) { if (response.success) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text('订单已取消')), + const SnackBar(content: Text('訂單已取消')), ); context.read().loadFundOrders(); } else { ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(response.message ?? '取消失败')), + SnackBar(content: Text(response.message ?? '取消失敗')), ); } } diff --git a/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart b/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart index ad9f3ac..779f4cc 100644 --- a/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart +++ b/flutter_monisuo/lib/ui/pages/orders/fund_orders_list.dart @@ -22,7 +22,7 @@ class FundOrdersList extends StatelessWidget { if (orders.isEmpty) { return _EmptyState( icon: LucideIcons.receipt, - message: '暂无订单记录', + message: '暫無訂單記錄', ); } @@ -43,7 +43,7 @@ class FundOrdersList extends StatelessWidget { } } -/// 空状态组件 +/// 空狀態組件 class _EmptyState extends StatelessWidget { final IconData icon; final String message; @@ -70,7 +70,7 @@ class _EmptyState extends StatelessWidget { } } -/// 充值订单卡片 - 公开类 +/// 充值訂單卡片 - 公開類 class FundOrderCard extends StatelessWidget { final OrderFund order; @@ -78,12 +78,12 @@ class FundOrderCard extends StatelessWidget { @override Widget build(BuildContext context) { - // 直接使用 _FundOrderCard 的实现 + // 直接使用 _FundOrderCard 的實現 return _FundOrderCardContent(order: order); } } -/// 订单卡片内容 +/// 訂單卡片內容 class _FundOrderCardContent extends StatelessWidget { final OrderFund order; @@ -127,11 +127,11 @@ class _FundOrderCardContent extends StatelessWidget { case 1: return '待付款'; case 2: - return '待确认'; + return '待確認'; case 3: return '已完成'; case 4: - return '已驳回'; + return '已駁回'; case 5: return '已取消'; default: @@ -140,11 +140,11 @@ class _FundOrderCardContent extends StatelessWidget { } else { switch (status) { case 1: - return '待审批'; + return '待審批'; case 2: return '已出款'; case 3: - return '已驳回'; + return '已駁回'; case 4: return '已取消'; default: @@ -192,7 +192,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.fee != null) ...[ Row( children: [ - Text('手续费(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('手續費(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text('-${order.fee} USDT', style: AppTextStyles.bodyMedium(context)), ], ), @@ -201,7 +201,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.receivableAmount != null) ...[ Row( children: [ - Text('到账金额: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('到賬金額: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text('${order.receivableAmount} USDT', style: AppTextStyles.bodyMedium(context).copyWith(fontWeight: FontWeight.w700)), ], ), @@ -210,7 +210,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.network != null) ...[ Row( children: [ - Text('提现网络: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現網絡: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text(order.network!, style: AppTextStyles.bodyMedium(context)), ], ), @@ -219,7 +219,7 @@ class _FundOrderCardContent extends StatelessWidget { if (order.walletAddress != null) ...[ Row( children: [ - Text('提现地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('提現地址: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Expanded( child: Text( order.walletAddress!, @@ -234,16 +234,16 @@ class _FundOrderCardContent extends StatelessWidget { ], Row( children: [ - Text('订单号: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('訂單號: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text(order.orderNo, style: AppTextStyles.bodyMedium(context)), ], ), SizedBox(height: AppSpacing.xs), Row( children: [ - Text('创建时间: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), + Text('創建時間: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)), Text( - order.createTime?.toString() ?? '无', + order.createTime?.toString() ?? '無', style: AppTextStyles.bodyMedium(context), ), ], diff --git a/flutter_monisuo/lib/ui/pages/orders/fund_orders_page.dart b/flutter_monisuo/lib/ui/pages/orders/fund_orders_page.dart index 6ac9a49..6d16c14 100644 --- a/flutter_monisuo/lib/ui/pages/orders/fund_orders_page.dart +++ b/flutter_monisuo/lib/ui/pages/orders/fund_orders_page.dart @@ -13,7 +13,7 @@ import '../../../core/event/app_event_bus.dart'; import '../../../providers/asset_provider.dart'; import '../../../data/models/order_models.dart'; -/// 充提订单页面 +/// 充提訂單頁面 class FundOrdersPage extends StatefulWidget { const FundOrdersPage({super.key}); @@ -22,7 +22,7 @@ class FundOrdersPage extends StatefulWidget { } class _FundOrdersPageState extends State { - int _activeTab = 0; // 0=全部, 1=充值, 2=提现 + int _activeTab = 0; // 0=全部, 1=充值, 2=提現 StreamSubscription? _eventSub; @override @@ -53,7 +53,7 @@ class _FundOrdersPageState extends State { } // ============================================ - // 构建 UI + // 構建 UI // ============================================ @override @@ -65,7 +65,7 @@ class _FundOrdersPageState extends State { icon: const Icon(LucideIcons.arrowLeft, size: 20), onPressed: () => Navigator.of(context).pop(), ), - title: Text('充提记录', style: AppTextStyles.headlineLarge(context).copyWith(color: context.colors.onSurface)), + title: Text('充提記錄', style: AppTextStyles.headlineLarge(context).copyWith(color: context.colors.onSurface)), backgroundColor: context.colors.surface, elevation: 0, scrolledUnderElevation: 0, @@ -97,7 +97,7 @@ class _FundOrdersPageState extends State { children: [ _buildPillTab('全部', 0), _buildPillTab('充值', 1), - _buildPillTab('提现', 2), + _buildPillTab('提現', 2), ], ), ), @@ -153,7 +153,7 @@ class _FundOrdersPageState extends State { children: [ Icon(LucideIcons.inbox, size: 64, color: context.appColors.onSurfaceMuted), const SizedBox(height: AppSpacing.md), - Text('暂无订单记录', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurfaceVariant)), + Text('暫無訂單記錄', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurfaceVariant)), ], ), ); @@ -199,7 +199,7 @@ class _FundOrdersPageState extends State { ], if (order.withdrawContact != null) ...[ const SizedBox(height: AppSpacing.sm - AppSpacing.xs), - _buildDetailRow('联系方式', order.withdrawContact!), + _buildDetailRow('聯繫方式', order.withdrawContact!), ], if (order.receivableAmount != null && !order.isDeposit) ...[ const SizedBox(height: AppSpacing.sm), @@ -214,13 +214,13 @@ class _FundOrdersPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '创建: ${_formatTime(order.createTime)}', + '創建: ${_formatTime(order.createTime)}', style: AppTextStyles.bodySmall(context).copyWith(color: context.appColors.onSurfaceMuted), ), if (order.rejectReason != null) Expanded( child: Text( - '驳回: ${order.rejectReason}', + '駁回: ${order.rejectReason}', style: AppTextStyles.bodySmall(context).copyWith(color: context.appColors.down), textAlign: TextAlign.right, overflow: TextOverflow.ellipsis, @@ -241,7 +241,7 @@ class _FundOrdersPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - order.isDeposit ? '充值' : '提现', + order.isDeposit ? '充值' : '提現', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurface), ), _buildStatusBadge(order), @@ -261,7 +261,7 @@ class _FundOrdersPageState extends State { if (order.isDeposit) { switch (order.status) { case 1: // 待付款 - case 2: // 待确认 + case 2: // 待確認 bgColor = AppColorScheme.warning.withValues(alpha: 0.12); textColor = AppColorScheme.warning; break; @@ -269,14 +269,14 @@ class _FundOrdersPageState extends State { bgColor = upBg; textColor = upColor; break; - default: // 已驳回/已取消 + default: // 已駁回/已取消 bgColor = downBg; textColor = downColor; } } else { switch (order.status) { - case 1: // 待审批 - case 5: // 待财务审核 + case 1: // 待審批 + case 5: // 待財務審核 bgColor = AppColorScheme.warning.withValues(alpha: 0.12); textColor = AppColorScheme.warning; break; @@ -284,7 +284,7 @@ class _FundOrdersPageState extends State { bgColor = upBg; textColor = upColor; break; - default: // 已驳回/已取消 + default: // 已駁回/已取消 bgColor = downBg; textColor = downColor; } @@ -320,10 +320,10 @@ class _FundOrdersPageState extends State { Widget _buildDetailRows(OrderFund order) { return Column( children: [ - _buildDetailRow('订单号', order.orderNo), + _buildDetailRow('訂單號', order.orderNo), const SizedBox(height: AppSpacing.sm - AppSpacing.xs), if (order.network != null) ...[ - _buildDetailRow('网络', order.network!), + _buildDetailRow('網絡', order.network!), const SizedBox(height: AppSpacing.sm - AppSpacing.xs), ], if (order.walletAddress != null) ...[ @@ -333,7 +333,7 @@ class _FundOrdersPageState extends State { trailing: GestureDetector( onTap: () { Clipboard.setData(ClipboardData(text: order.walletAddress!)); - ToastUtils.show('地址已复制'); + ToastUtils.show('地址已複製'); }, child: Icon(LucideIcons.copy, size: 14, color: context.appColors.onSurfaceMuted), ), @@ -341,11 +341,11 @@ class _FundOrdersPageState extends State { const SizedBox(height: AppSpacing.sm - AppSpacing.xs), ], if (order.fee != null && !order.isDeposit) ...[ - _buildDetailRow('手续费', '${order.fee}%'), + _buildDetailRow('手續費', '${order.fee}%'), const SizedBox(height: AppSpacing.sm - AppSpacing.xs), ], _buildDetailRow( - '时间', + '時間', _formatTime(order.createTime), ), ], @@ -383,7 +383,7 @@ class _FundOrdersPageState extends State { // --------------------------------------------------------------------------- Widget _buildRejectionReason(OrderFund order) { return Text( - '拒绝原因: ${order.rejectReason}', + '拒絕原因: ${order.rejectReason}', style: AppTextStyles.bodyMedium(context).copyWith(color: context.appColors.down), ); } @@ -401,7 +401,7 @@ class _FundOrdersPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text('应付金额', style: AppTextStyles.headlineSmall(context).copyWith(color: context.colors.onSurfaceVariant)), + Text('應付金額', style: AppTextStyles.headlineSmall(context).copyWith(color: context.colors.onSurfaceVariant)), Text('${order.receivableAmount} USDT', style: AppTextStyles.headlineMedium(context).copyWith(color: context.colors.onSurface)), ], ), @@ -427,7 +427,7 @@ class _FundOrdersPageState extends State { borderRadius: AppRadius.radiusSm, border: Border.all(color: downColor, width: 1), ), - child: Text('取消订单', style: AppTextStyles.headlineSmall(context).copyWith(color: downColor)), + child: Text('取消訂單', style: AppTextStyles.headlineSmall(context).copyWith(color: downColor)), ), ), if (order.canCancel && order.canConfirmPay) @@ -467,14 +467,14 @@ class _FundOrdersPageState extends State { void _confirmPay(OrderFund order) async { final confirmed = await showShadConfirmDialog( context: context, - title: '确认已打款', - description: '确认您已完成向指定地址的转账?', + title: '確認已打款', + description: '確認您已完成向指定地址的轉賬?', ); if (confirmed == true && mounted) { final response = await context.read().confirmPay(order.orderNo); if (mounted) { - BotToast.showText(text: response.success ? '确认成功,请等待审核' : response.message ?? '确认失败'); + BotToast.showText(text: response.success ? '確認成功,請等待審核' : response.message ?? '確認失敗'); } } } @@ -482,15 +482,15 @@ class _FundOrdersPageState extends State { void _cancelOrder(OrderFund order) async { final confirmed = await showShadConfirmDialog( context: context, - title: '取消订单', - description: '确定要取消订单 ${order.orderNo} 吗?', + title: '取消訂單', + description: '確定要取消訂單 ${order.orderNo} 嗎?', destructive: true, ); if (confirmed == true && mounted) { final response = await context.read().cancelOrder(order.orderNo); if (mounted) { - BotToast.showText(text: response.success ? '订单已取消' : response.message ?? '取消失败'); + BotToast.showText(text: response.success ? '訂單已取消' : response.message ?? '取消失敗'); } } } @@ -512,7 +512,7 @@ class _FundOrdersPageState extends State { onPressed: () => Navigator.pop(context, false), ), TextButton( - child: Text(destructive ? '确定取消' : '确认'), + child: Text(destructive ? '確定取消' : '確認'), onPressed: () => Navigator.pop(context, true), ), ], diff --git a/flutter_monisuo/lib/ui/pages/orders/orders_page.dart b/flutter_monisuo/lib/ui/pages/orders/orders_page.dart index 97ddc42..8ed4e20 100644 --- a/flutter_monisuo/lib/ui/pages/orders/orders_page.dart +++ b/flutter_monisuo/lib/ui/pages/orders/orders_page.dart @@ -8,7 +8,7 @@ import '../../../core/theme/app_theme_extension.dart'; import '../../../providers/asset_provider.dart'; import 'fund_orders_list.dart'; -/// 订单管理页面 +/// 訂單管理頁面 class OrdersPage extends StatefulWidget { const OrdersPage({super.key}); @@ -50,7 +50,7 @@ class _OrdersPageState extends State with AutomaticKeepAliveClientMi child: Column( children: [ TabSelector( - tabs: const ['订单记录', '交易记录'], + tabs: const ['訂單記錄', '交易記錄'], selectedIndex: _activeTab, onChanged: (index) => setState(() => _activeTab = index), ), @@ -68,7 +68,7 @@ class _OrdersPageState extends State with AutomaticKeepAliveClientMi } } -/// Tab 选择器 +/// Tab 選擇器 class TabSelector extends StatelessWidget { final List tabs; final int selectedIndex; @@ -129,7 +129,7 @@ class TabSelector extends StatelessWidget { } } -/// 交易订单列表 +/// 交易訂單列表 class TradeOrdersList extends StatelessWidget { final AssetProvider provider; @@ -147,7 +147,7 @@ class TradeOrdersList extends StatelessWidget { children: [ Icon(LucideIcons.receipt, size: 48, color: theme.colorScheme.mutedForeground), SizedBox(height: AppSpacing.sm + AppSpacing.xs), - Text('暂无交易记录', style: theme.textTheme.muted), + Text('暫無交易記錄', style: theme.textTheme.muted), ], ), ), diff --git a/flutter_monisuo/lib/ui/pages/trade/components/amount_input.dart b/flutter_monisuo/lib/ui/pages/trade/components/amount_input.dart index 697ee14..ef918d1 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/amount_input.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/amount_input.dart @@ -3,10 +3,10 @@ import '../../../../core/theme/app_color_scheme.dart'; import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme.dart'; -/// 金额输入框组件(含超额提示) +/// 金額輸入框組件(含超額提示) /// -/// 设计稿:bg-tertiary,圆角md,高48。 -/// 输入金额超过可用 USDT 余额时显示警告提示。 +/// 設計稿:bg-tertiary,圓角md,高48。 +/// 輸入金額超過可用 USDT 餘額時顯示警告提示。 class AmountInput extends StatefulWidget { final TextEditingController amountController; final String maxAmount; @@ -63,7 +63,7 @@ class _AmountInputState extends State { Container( height: 48, decoration: BoxDecoration( - color: colorScheme.surfaceContainerHighest.withOpacity(0.5), // 调整透明度 + color: colorScheme.surfaceContainerHighest.withOpacity(0.5), // 調整透明度 borderRadius: BorderRadius.circular(AppRadius.md), ), child: TextField( @@ -74,7 +74,7 @@ class _AmountInputState extends State { fontWeight: FontWeight.w400, ), decoration: InputDecoration( - hintText: '请输入金额', + hintText: '請輸入金額', hintStyle: AppTextStyles.numberMedium(context).copyWith( fontWeight: FontWeight.w400, color: colorScheme.onSurfaceVariant.withOpacity(0.5), @@ -94,7 +94,7 @@ class _AmountInputState extends State { Icon(Icons.error_outline, size: 13, color: warningColor), SizedBox(width: AppSpacing.xs), Text( - '超出可用USDT余额', + '超出可用USDT餘額', style: AppTextStyles.bodySmall(context).copyWith( color: warningColor, ), diff --git a/flutter_monisuo/lib/ui/pages/trade/components/coin_avatar.dart b/flutter_monisuo/lib/ui/pages/trade/components/coin_avatar.dart index 9c6c47a..4eafb40 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/coin_avatar.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/coin_avatar.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme.dart'; -/// 币种头像组件 +/// 幣種頭像組件 /// -/// 显示币种图标或首字母的圆形头像,带主题色边框和背景。 +/// 顯示幣種圖標或首字母的圓形頭像,帶主題色邊框和背景。 class CoinAvatar extends StatelessWidget { final String? icon; const CoinAvatar({super.key, this.icon}); diff --git a/flutter_monisuo/lib/ui/pages/trade/components/coin_selector.dart b/flutter_monisuo/lib/ui/pages/trade/components/coin_selector.dart index d2b1087..4e7cc92 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/coin_selector.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/coin_selector.dart @@ -6,9 +6,9 @@ import '../../../../core/theme/app_theme_extension.dart'; import '../../../../data/models/coin.dart'; import 'coin_avatar.dart'; -/// 币种选择器组件 +/// 幣種選擇器組件 /// -/// 显示当前选中的币种交易对,点击弹出底部弹窗选择币种。 +/// 顯示當前選中的幣種交易對,點擊彈出底部彈窗選擇幣種。 class CoinSelector extends StatelessWidget { final Coin? selectedCoin; final List coins; @@ -38,7 +38,7 @@ class CoinSelector extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - // 币种信息:交易对 + 名称 + // 幣種信息:交易對 + 名稱 Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -46,19 +46,19 @@ class CoinSelector extends StatelessWidget { Text( selectedCoin != null ? '${selectedCoin!.code}/USDT' - : '选择币种', + : '選擇幣種', style: AppTextStyles.headlineLarge(context), ), const SizedBox(height: 2), Text( - selectedCoin?.name ?? '点击选择交易对', + selectedCoin?.name ?? '點擊選擇交易對', style: AppTextStyles.bodyMedium(context).copyWith( color: context.colors.onSurfaceVariant, ), ), ], ), - // 下拉箭头 + // 下拉箭頭 Icon(LucideIcons.chevronDown, size: 16, color: context.colors.onSurfaceVariant), ], @@ -83,7 +83,7 @@ class CoinSelector extends StatelessWidget { ), child: Column( children: [ - // 拖动指示器 + // 拖動指示器 Container( margin: EdgeInsets.only(top: AppSpacing.sm), width: 40, @@ -93,13 +93,13 @@ class CoinSelector extends StatelessWidget { borderRadius: BorderRadius.circular(AppRadius.sm), ), ), - // 标题栏 + // 標題欄 Padding( padding: EdgeInsets.all(AppSpacing.lg), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text('选择币种', + Text('選擇幣種', style: AppTextStyles.headlineLarge(context)), GestureDetector( onTap: () => Navigator.of(ctx).pop(), @@ -110,7 +110,7 @@ class CoinSelector extends StatelessWidget { ), ), Divider(height: 1, color: ctx.colors.outlineVariant.withValues(alpha: 0.2)), - // 币种列表 + // 幣種列表 Expanded( child: ListView.builder( padding: EdgeInsets.symmetric(vertical: AppSpacing.sm), @@ -150,7 +150,7 @@ class CoinSelector extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 第一行:币种代码 + USDT + 价格 + 涨跌幅 + // 第一行:幣種代碼 + USDT + 價格 + 漲跌幅 Row( children: [ Text(coin.code, @@ -164,7 +164,7 @@ class CoinSelector extends StatelessWidget { Text('\$${coin.formattedPrice}', style: AppTextStyles.numberMedium(context)), SizedBox(width: AppSpacing.sm), - // 涨跌幅徽章 + // 漲跌幅徽章 Container( padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( @@ -185,7 +185,7 @@ class CoinSelector extends StatelessWidget { ], ), SizedBox(height: 3), - // 第二行:币种名称 + // 第二行:幣種名稱 Text(coin.name, style: AppTextStyles.bodyMedium(context).copyWith( color: context.colors.onSurfaceVariant, diff --git a/flutter_monisuo/lib/ui/pages/trade/components/confirm_dialog.dart b/flutter_monisuo/lib/ui/pages/trade/components/confirm_dialog.dart index 78cf355..c260e23 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/confirm_dialog.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/confirm_dialog.dart @@ -5,10 +5,10 @@ import '../../../../core/theme/app_theme_extension.dart'; import '../../../components/glass_panel.dart'; import '../../../components/neon_glow.dart'; -/// 交易确认对话框 +/// 交易確認對話框 /// -/// 显示交易详情(交易对、委托价格、交易金额、交易数量), -/// 用户确认后执行交易。 +/// 顯示交易詳情(交易對、委託價格、交易金額、交易數量), +/// 用戶確認後執行交易。 class ConfirmDialog extends StatelessWidget { final bool isBuy; final String coinCode; @@ -42,19 +42,19 @@ class ConfirmDialog extends StatelessWidget { children: [ Center( child: Text( - '确认${isBuy ? '买入' : '卖出'}', + '確認${isBuy ? '買入' : '賣出'}', style: AppTextStyles.headlineLarge(context), ), ), SizedBox(height: AppSpacing.lg), - _dialogRow(context, '交易对', '$coinCode/USDT'), + _dialogRow(context, '交易對', '$coinCode/USDT'), SizedBox(height: AppSpacing.sm), - _dialogRow(context, '委托价格', '$price USDT'), + _dialogRow(context, '委託價格', '$price USDT'), SizedBox(height: AppSpacing.sm), - _dialogRow(context, '交易金额', '$amount USDT', + _dialogRow(context, '交易金額', '$amount USDT', valueColor: actionColor), SizedBox(height: AppSpacing.sm), - _dialogRow(context, '交易数量', '$quantity $coinCode'), + _dialogRow(context, '交易數量', '$quantity $coinCode'), SizedBox(height: AppSpacing.lg), Row( children: [ @@ -70,7 +70,7 @@ class ConfirmDialog extends StatelessWidget { SizedBox(width: AppSpacing.sm), Expanded( child: NeonButton( - text: '确认${isBuy ? '买入' : '卖出'}', + text: '確認${isBuy ? '買入' : '賣出'}', type: isBuy ? NeonButtonType.tertiary : NeonButtonType.error, onPressed: () => Navigator.of(context).pop(true), height: 44, diff --git a/flutter_monisuo/lib/ui/pages/trade/components/placeholder_card.dart b/flutter_monisuo/lib/ui/pages/trade/components/placeholder_card.dart index 9ed25a3..43e9f34 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/placeholder_card.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/placeholder_card.dart @@ -3,9 +3,9 @@ import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme_extension.dart'; -/// 占位卡片组件 +/// 佔位卡片組件 /// -/// 当未选择币种时显示的占位提示卡片。 +/// 當未選擇幣種時顯示的佔位提示卡片。 class PlaceholderCard extends StatelessWidget { final String message; const PlaceholderCard({ diff --git a/flutter_monisuo/lib/ui/pages/trade/components/price_card.dart b/flutter_monisuo/lib/ui/pages/trade/components/price_card.dart index 52a6615..0d19d2e 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/price_card.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/price_card.dart @@ -4,10 +4,10 @@ import '../../../../core/theme/app_theme.dart'; import '../../../../core/theme/app_theme_extension.dart'; import '../../../../data/models/coin.dart'; -/// 价格卡片组件 +/// 價格卡片組件 /// -/// 显示当前币种价格和 24h 涨跌幅。 -/// 布局:大号价格(32px bold) + 涨跌幅徽章(圆角sm,涨绿背景) + "24h 变化" 副标题。 +/// 顯示當前幣種價格和 24h 漲跌幅。 +/// 佈局:大號價格(32px bold) + 漲跌幅徽章(圓角sm,漲綠背景) + "24h 變化" 副標題。 class PriceCard extends StatelessWidget { final Coin coin; const PriceCard({super.key, required this.coin}); @@ -34,7 +34,7 @@ class PriceCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 价格行:大号价格 + 涨跌幅徽章 + // 價格行:大號價格 + 漲跌幅徽章 Row( children: [ Text( @@ -42,10 +42,10 @@ class PriceCard extends StatelessWidget { style: AppTextStyles.numberLarge(context).copyWith(fontSize: 32), ), const SizedBox(width: AppSpacing.sm), - // 涨跌幅徽章 - 圆角sm,涨绿背景 + // 漲跌幅徽章 - 圓角sm,漲綠背景 Container( padding: const EdgeInsets.symmetric( - horizontal: 8, vertical: 4), // 调整 padding + horizontal: 8, vertical: 4), // 調整 padding decoration: BoxDecoration( color: changeBgColor, borderRadius: BorderRadius.circular(AppRadius.sm), @@ -61,9 +61,9 @@ class PriceCard extends StatelessWidget { ], ), const SizedBox(height: AppSpacing.sm), - // 副标题 + // 副標題 Text( - '24h 变化', + '24h 變化', style: AppTextStyles.bodySmall(context), ), ], diff --git a/flutter_monisuo/lib/ui/pages/trade/components/trade_button.dart b/flutter_monisuo/lib/ui/pages/trade/components/trade_button.dart index 17135b3..139bae3 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/trade_button.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/trade_button.dart @@ -3,9 +3,9 @@ import '../../../../core/theme/app_color_scheme.dart'; import '../../../../core/theme/app_spacing.dart'; import '../../../../core/theme/app_theme.dart'; -/// 交易按钮组件 +/// 交易按鈕組件 /// -/// CTA 买入/卖出按钮。profit-green底 / sell-red底,圆角lg,高48,买入白字/卖出红字16px bold。 +/// CTA 買入/賣出按鈕。profit-green底 / sell-red底,圓角lg,高48,買入白字/賣出紅字16px bold。 class TradeButton extends StatelessWidget { final bool isBuy; final String? coinCode; @@ -27,7 +27,7 @@ class TradeButton extends StatelessWidget { final colorScheme = Theme.of(context).colorScheme; final fillColor = isBuy ? AppColorScheme.buyButtonFill : AppColorScheme.sellButtonFill; - // 买入按钮文字为白色,卖出按钮文字为红色 + // 買入按鈕文字為白色,賣出按鈕文字為紅色 final textColor = isBuy ? Colors.white : (enabled ? AppColorScheme.sellButtonFill : colorScheme.onSurface.withOpacity(0.3)); @@ -52,7 +52,7 @@ class TradeButton extends StatelessWidget { ), ) : Text( - '${isBuy ? '买入' : '卖出'} ${coinCode ?? ""}', + '${isBuy ? '買入' : '賣出'} ${coinCode ?? ""}', style: AppTextStyles.headlineLarge(context).copyWith( color: enabled ? textColor diff --git a/flutter_monisuo/lib/ui/pages/trade/components/trade_form_card.dart b/flutter_monisuo/lib/ui/pages/trade/components/trade_form_card.dart index 71aaaaf..3e8cb3d 100644 --- a/flutter_monisuo/lib/ui/pages/trade/components/trade_form_card.dart +++ b/flutter_monisuo/lib/ui/pages/trade/components/trade_form_card.dart @@ -6,10 +6,10 @@ import '../../../../core/theme/app_theme_extension.dart'; import '../../../../data/models/coin.dart'; import 'amount_input.dart'; -/// 交易表单卡片组件 +/// 交易表單卡片組件 /// -/// 包含买入/卖出切换、金额输入、可用余额、快捷比例按钮、计算数量行。 -/// card背景 + 圆角lg + border + padding:20 + gap:16 +/// 包含買入/賣出切換、金額輸入、可用餘額、快捷比例按鈕、計算數量行。 +/// card背景 + 圓角lg + border + padding:20 + gap:16 class TradeFormCard extends StatelessWidget { final int tradeType; final Coin? selectedCoin; @@ -43,7 +43,7 @@ class TradeFormCard extends StatelessWidget { ? context.appColors.up : context.appColors.down; - // 设计稿中 card 背景色 + // 設計稿中 card 背景色 final cardBgColor = context.appColors.surfaceCard; return Container( @@ -59,13 +59,13 @@ class TradeFormCard extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // ---- 买入/卖出切换 ---- - // 设计稿:ClipRRect + 圆角md,两等宽按钮 + // ---- 買入/賣出切換 ---- + // 設計稿:ClipRRect + 圓角md,兩等寬按鈕 ClipRRect( borderRadius: BorderRadius.circular(AppRadius.md), child: Row( children: [ - // 买入按钮 + // 買入按鈕 Expanded( child: GestureDetector( onTap: () => onTradeTypeChanged(0), @@ -84,7 +84,7 @@ class TradeFormCard extends StatelessWidget { ), child: Center( child: Text( - '买入', + '買入', style: AppTextStyles.headlineMedium(context).copyWith( color: isBuy ? Colors.white @@ -95,7 +95,7 @@ class TradeFormCard extends StatelessWidget { ), ), ), - // 卖出按钮 + // 賣出按鈕 Expanded( child: GestureDetector( onTap: () => onTradeTypeChanged(1), @@ -114,7 +114,7 @@ class TradeFormCard extends StatelessWidget { ), child: Center( child: Text( - '卖出', + '賣出', style: AppTextStyles.headlineMedium(context).copyWith( color: !isBuy ? Colors.white @@ -130,11 +130,11 @@ class TradeFormCard extends StatelessWidget { ), const SizedBox(height: AppSpacing.md + AppSpacing.sm), - // ---- 交易金额 label 行 ---- + // ---- 交易金額 label 行 ---- Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text('交易金额', + Text('交易金額', style: AppTextStyles.bodyMedium(context).copyWith( color: context.colors.onSurfaceVariant, )), @@ -144,7 +144,7 @@ class TradeFormCard extends StatelessWidget { ), const SizedBox(height: AppSpacing.sm), - // ---- 金额输入框 ---- + // ---- 金額輸入框 ---- AmountInput( amountController: amountController, maxAmount: maxAmount, @@ -154,7 +154,7 @@ class TradeFormCard extends StatelessWidget { ), const SizedBox(height: AppSpacing.sm), - // ---- 可用余额 ---- + // ---- 可用餘額 ---- Text( isBuy ? '可用: $availableUsdt USDT' @@ -165,8 +165,8 @@ class TradeFormCard extends StatelessWidget { ), const SizedBox(height: AppSpacing.md), - // ---- 快捷比例按钮 25% 50% 75% 100% ---- - // 设计稿:gap:8,圆角sm,bg-tertiary,高32 + // ---- 快捷比例按鈕 25% 50% 75% 100% ---- + // 設計稿:gap:8,圓角sm,bg-tertiary,高32 Row( children: [ _buildPctButton(context, '25%', 0.25), @@ -180,11 +180,11 @@ class TradeFormCard extends StatelessWidget { ), const SizedBox(height: AppSpacing.md + AppSpacing.sm), - // ---- 计算数量行 ---- + // ---- 計算數量行 ---- Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text('交易数量', + Text('交易數量', style: AppTextStyles.bodyMedium(context).copyWith( color: context.colors.onSurfaceVariant, )), @@ -199,7 +199,7 @@ class TradeFormCard extends StatelessWidget { ); } - /// 百分比按钮 - 设计稿:圆角sm,bg-tertiary,高32 + /// 百分比按鈕 - 設計稿:圓角sm,bg-tertiary,高32 Widget _buildPctButton(BuildContext context, String label, double pct) { return Expanded( child: GestureDetector( @@ -207,7 +207,7 @@ class TradeFormCard extends StatelessWidget { child: Container( height: 32, decoration: BoxDecoration( - color: context.colors.surfaceContainerHighest.withOpacity(0.5), // 更柔和的颜色 + color: context.colors.surfaceContainerHighest.withOpacity(0.5), // 更柔和的顏色 borderRadius: BorderRadius.circular(AppRadius.sm), ), child: Center( diff --git a/flutter_monisuo/lib/ui/pages/trade/trade_page.dart b/flutter_monisuo/lib/ui/pages/trade/trade_page.dart index ee7ce49..899f323 100644 --- a/flutter_monisuo/lib/ui/pages/trade/trade_page.dart +++ b/flutter_monisuo/lib/ui/pages/trade/trade_page.dart @@ -15,14 +15,14 @@ import 'components/trade_form_card.dart'; import 'components/trade_button.dart'; import 'components/confirm_dialog.dart'; -/// 交易页面 +/// 交易頁面 /// -/// 设计稿 Trade 页面,布局结构: -/// - 币种选择器卡片(Coin Selector Card) -/// - 价格卡片(Price Card):大号价格 + 涨跌幅徽章 + 副标题 -/// - 买入/卖出切换(Buy/Sell Toggle) -/// - 交易表单卡片(Trade Form Card):金额输入 + 快捷比例 + 计算数量 -/// - CTA 买入/卖出按钮(Buy/Sell Button) +/// 設計稿 Trade 頁面,佈局結構: +/// - 幣種選擇器卡片(Coin Selector Card) +/// - 價格卡片(Price Card):大號價格 + 漲跌幅徽章 + 副標題 +/// - 買入/賣出切換(Buy/Sell Toggle) +/// - 交易表單卡片(Trade Form Card):金額輸入 + 快捷比例 + 計算數量 +/// - CTA 買入/賣出按鈕(Buy/Sell Button) class TradePage extends StatefulWidget { final String? initialCoinCode; @@ -34,7 +34,7 @@ class TradePage extends StatefulWidget { class _TradePageState extends State with AutomaticKeepAliveClientMixin { - int _tradeType = 0; // 0=买入, 1=卖出 + int _tradeType = 0; // 0=買入, 1=賣出 Coin? _selectedCoin; final _amountController = TextEditingController(); bool _isSubmitting = false; @@ -71,14 +71,14 @@ class _TradePageState extends State super.dispose(); } - /// 获取交易账户中 USDT 可用余额 + /// 獲取交易賬戶中 USDT 可用餘額 String get _availableUsdt { final holdings = context.read().holdings; final usdt = holdings.where((h) => h.coinCode == 'USDT').firstOrNull; return usdt?.quantity ?? '0'; } - /// 获取交易账户中当前币种的持仓数量 + /// 獲取交易賬戶中當前幣種的持倉數量 String get _availableCoinQty { if (_selectedCoin == null) return '0'; final holdings = context.read().holdings; @@ -88,7 +88,7 @@ class _TradePageState extends State return pos?.quantity ?? '0'; } - /// 计算可买入/卖出的最大 USDT 金额 + /// 計算可買入/賣出的最大 USDT 金額 String get _maxAmount { if (_selectedCoin == null) return '0'; final price = _selectedCoin!.price; @@ -102,7 +102,7 @@ class _TradePageState extends State } } - /// 计算数量 + /// 計算數量 String get _calculatedQuantity { final amount = double.tryParse(_amountController.text) ?? 0; final price = _selectedCoin?.price ?? 0; @@ -121,11 +121,11 @@ class _TradePageState extends State return SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.fromLTRB( - AppSpacing.md, AppSpacing.md, AppSpacing.md, AppSpacing.xl + AppSpacing.sm, // 添加顶部间距 + AppSpacing.md, AppSpacing.md, AppSpacing.md, AppSpacing.xl + AppSpacing.sm, // 添加頂部間距 ), child: Column( children: [ - // 币种选择器卡片 + // 幣種選擇器卡片 CoinSelector( selectedCoin: _selectedCoin, coins: market.allCoins @@ -143,16 +143,16 @@ class _TradePageState extends State ), const SizedBox(height: AppSpacing.md), - // 价格卡片 + // 價格卡片 if (_selectedCoin != null) PriceCard(coin: _selectedCoin!) else PlaceholderCard( - message: '请先选择交易币种', + message: '請先選擇交易幣種', ), const SizedBox(height: AppSpacing.md), - // 交易表单卡片(内含买入/卖出切换 + 表单) + // 交易表單卡片(內含買入/賣出切換 + 表單) TradeFormCard( tradeType: _tradeType, selectedCoin: _selectedCoin, @@ -170,7 +170,7 @@ class _TradePageState extends State ), const SizedBox(height: AppSpacing.md), - // CTA 买入/卖出按钮 + // CTA 買入/賣出按鈕 SizedBox( width: double.infinity, height: 48, @@ -195,7 +195,7 @@ class _TradePageState extends State if (_selectedCoin == null) return false; final amount = double.tryParse(_amountController.text) ?? 0; if (amount <= 0) return false; - // 买入时校验不超过可用USDT + // 買入時校驗不超過可用USDT if (_tradeType == 0) { final available = double.tryParse(_availableUsdt) ?? 0; if (amount > available) return false; @@ -243,16 +243,16 @@ class _TradePageState extends State if (response.success) { _amountController.clear(); - // 刷新资产数据 + // 刷新資產數據 context.read().refreshAll(force: true); - _showResultDialog(true, '${isBuy ? '买入' : '卖出'}成功', + _showResultDialog(true, '${isBuy ? '買入' : '賣出'}成功', '$quantity $coinCode @ $price USDT'); } else { - _showResultDialog(false, '交易失败', response.message ?? '请稍后重试'); + _showResultDialog(false, '交易失敗', response.message ?? '請稍後重試'); } } catch (e) { if (mounted) { - _showResultDialog(false, '交易失败', e.toString()); + _showResultDialog(false, '交易失敗', e.toString()); } } finally { if (mounted) setState(() => _isSubmitting = false); @@ -279,7 +279,7 @@ class _TradePageState extends State description: Text(message), actions: [ ShadButton( - child: const Text('确定'), + child: const Text('確定'), onPressed: () => Navigator.of(ctx).pop(), ), ], diff --git a/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart b/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart index 3592f8e..7a87aa2 100644 --- a/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart +++ b/flutter_monisuo/lib/ui/shared/modern_bottom_sheet.dart @@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import '../../core/theme/app_spacing.dart'; -/// 现代底部抽屉模板 - 基于 modernization-v2.md 规范 +/// 現代底部抽屜模板 - 基於 modernization-v2.md 規範 /// /// 使用方法: /// ```dart /// ModernBottomSheet.show( /// context: context, -/// title: '选择币种', +/// title: '選擇幣種', /// child: YourContentWidget(), /// ); /// ``` @@ -32,7 +32,7 @@ class ModernBottomSheet extends StatelessWidget { this.onClose, }); - /// 显示底部抽屉 + /// 顯示底部抽屜 static Future show({ required BuildContext context, String? title, @@ -62,7 +62,7 @@ class ModernBottomSheet extends StatelessWidget { ); } - /// 显示操作列表 + /// 顯示操作列表 static Future showActions({ required BuildContext context, String? title, @@ -75,12 +75,12 @@ class ModernBottomSheet extends StatelessWidget { ); } - /// 显示确认操作 + /// 顯示確認操作 static Future confirmAction({ required BuildContext context, required String title, String? description, - String confirmText = '确认', + String confirmText = '確認', String cancelText = '取消', bool isDestructive = false, }) async { @@ -150,12 +150,12 @@ class ModernBottomSheet extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 拖动指示器 + // 拖動指示器 if (showDragHandle) _buildDragHandle(theme), - // 标题行 + // 標題行 if (title != null || titleWidget != null || showCloseButton) _buildHeader(context, theme), - // 内容 + // 內容 child, ], ), @@ -183,7 +183,7 @@ class ModernBottomSheet extends StatelessWidget { padding: const EdgeInsets.only(bottom: AppSpacing.md), child: Row( children: [ - // 标题 + // 標題 Expanded( child: titleWidget ?? Text( title!, @@ -192,7 +192,7 @@ class ModernBottomSheet extends StatelessWidget { ), ), ), - // 关闭按钮 + // 關閉按鈕 if (showCloseButton) GestureDetector( onTap: () { @@ -238,7 +238,7 @@ class _ActionList extends StatelessWidget { } } -/// 操作项 +/// 操作項 class _ActionTile extends StatelessWidget { final ModernSheetAction action; @@ -289,7 +289,7 @@ class _ActionTile extends StatelessWidget { } } -/// 底部抽屉操作配置 +/// 底部抽屜操作配置 class ModernSheetAction { final String label; final IconData? icon; diff --git a/flutter_monisuo/lib/ui/shared/modern_dialog.dart b/flutter_monisuo/lib/ui/shared/modern_dialog.dart index fa5b6b9..8241456 100644 --- a/flutter_monisuo/lib/ui/shared/modern_dialog.dart +++ b/flutter_monisuo/lib/ui/shared/modern_dialog.dart @@ -2,17 +2,17 @@ import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import '../../core/theme/app_spacing.dart'; -/// 现代弹窗模板 - 基于 modernization-v2.md 规范 +/// 現代彈窗模板 - 基於 modernization-v2.md 規範 /// /// 使用方法: /// ```dart /// ModernDialog.show( /// context: context, -/// title: '确认操作', -/// description: '确定要执行此操作吗?', +/// title: '確認操作', +/// description: '確定要執行此操作嗎?', /// actions: [ /// ModernDialogAction(label: '取消', isDestructive: false), -/// ModernDialogAction(label: '确认', isPrimary: true), +/// ModernDialogAction(label: '確認', isPrimary: true), /// ], /// ); /// ``` @@ -34,7 +34,7 @@ class ModernDialog extends StatelessWidget { this.onClose, }); - /// 显示现代弹窗 + /// 顯示現代彈窗 static Future show({ required BuildContext context, String? title, @@ -57,12 +57,12 @@ class ModernDialog extends StatelessWidget { ); } - /// 显示确认弹窗 + /// 顯示確認彈窗 static Future confirm({ required BuildContext context, required String title, String? description, - String confirmText = '确认', + String confirmText = '確認', String cancelText = '取消', bool isDestructive = false, }) async { @@ -83,7 +83,7 @@ class ModernDialog extends StatelessWidget { return result ?? false; } - /// 显示信息弹窗 + /// 顯示信息彈窗 static Future info({ required BuildContext context, required String title, @@ -116,7 +116,7 @@ class ModernDialog extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 标题 + // 標題 if (titleWidget != null) titleWidget! else if (title != null) @@ -136,12 +136,12 @@ class ModernDialog extends StatelessWidget { ), const SizedBox(height: AppSpacing.md), ], - // 自定义内容 + // 自定義內容 if (content != null) ...[ content!, const SizedBox(height: AppSpacing.lg), ], - // 按钮 + // 按鈕 if (actions != null && actions!.isNotEmpty) Row( mainAxisAlignment: MainAxisAlignment.end, @@ -189,7 +189,7 @@ class ModernDialog extends StatelessWidget { } } -/// 弹窗按钮配置 +/// 彈窗按鈕配置 class ModernDialogAction { final String label; final dynamic returnValue; diff --git a/flutter_monisuo/lib/ui/shared/ui_constants.dart b/flutter_monisuo/lib/ui/shared/ui_constants.dart index 470ff03..a0e7492 100644 --- a/flutter_monisuo/lib/ui/shared/ui_constants.dart +++ b/flutter_monisuo/lib/ui/shared/ui_constants.dart @@ -1,94 +1,94 @@ -/// UI 常量整合导出 +/// UI 常量整合導出 /// -/// 统一导出所有设计 token,方便使用 +/// 統一導出所有設計 token,方便使用 /// 使用方式: import 'ui/shared/ui_constants.dart'; -// 导出颜色系统 +// 導出顏色系統 export '../../core/theme/app_color_scheme.dart'; -// 导出主题配置 (包含 AppTextStyles, AppSpacing, AppRadius, AppBreakpoints) +// 導出主題配置 (包含 AppTextStyles, AppSpacing, AppRadius, AppBreakpoints) export '../../core/theme/app_theme.dart'; -/// 表单验证器 +/// 表單驗證器 /// -/// 提供常用的表单验证方法 +/// 提供常用的表單驗證方法 class Validators { Validators._(); - /// 金额验证 + /// 金額驗證 static String? amount(String? value) { if (value == null || value.isEmpty) { - return '请输入金额'; + return '請輸入金額'; } final amount = double.tryParse(value); if (amount == null || amount <= 0) { - return '请输入有效金额'; + return '請輸入有效金額'; } return null; } - /// 价格验证 + /// 價格驗證 static String? price(String? value) { if (value == null || value.isEmpty) { - return '请输入价格'; + return '請輸入價格'; } final price = double.tryParse(value); if (price == null || price <= 0) { - return '请输入有效价格'; + return '請輸入有效價格'; } return null; } - /// 数量验证 + /// 數量驗證 static String? quantity(String? value) { if (value == null || value.isEmpty) { - return '请输入数量'; + return '請輸入數量'; } final quantity = double.tryParse(value); if (quantity == null || quantity <= 0) { - return '请输入有效数量'; + return '請輸入有效數量'; } return null; } - /// 必填字段验证 + /// 必填字段驗證 static String? required(String? value, String fieldName) { if (value == null || value.isEmpty) { - return '请输入$fieldName'; + return '請輸入$fieldName'; } return null; } - /// 用户名验证 + /// 用戶名驗證 static String? username(String? value) { if (value == null || value.isEmpty) { - return '请输入用户名'; + return '請輸入用戶名'; } if (value.length < 3) { - return '用户名至少 3 个字符'; + return '用戶名至少 3 個字符'; } return null; } - /// 密码验证 + /// 密碼驗證 static String? password(String? value) { if (value == null || value.isEmpty) { - return '请输入密码'; + return '請輸入密碼'; } if (value.length < 6) { - return '密码至少 6 个字符'; + return '密碼至少 6 個字符'; } return null; } - /// 邮箱验证 + /// 郵箱驗證 static String? email(String? value) { if (value == null || value.isEmpty) { - return '请输入邮箱'; + return '請輸入郵箱'; } final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); if (!emailRegex.hasMatch(value)) { - return '请输入有效的邮箱地址'; + return '請輸入有效的郵箱地址'; } return null; } diff --git a/src/main/java/com/it/rattan/monisuo/controller/BonusController.java b/src/main/java/com/it/rattan/monisuo/controller/BonusController.java index 173fc1a..ad7c655 100644 --- a/src/main/java/com/it/rattan/monisuo/controller/BonusController.java +++ b/src/main/java/com/it/rattan/monisuo/controller/BonusController.java @@ -36,7 +36,7 @@ public class BonusController { /** * 领取奖励 - * body: { type: "new_user"|"referral", referredUserId?, milestone? } + * body: { type: "new_user"|"referral"|"indirect_referral", referredUserId?, milestone?, directReferralId? } */ @PostMapping("/claim") public Result> claim(@RequestBody Map params) { @@ -62,6 +62,18 @@ public class BonusController { Long referredUserId = Long.valueOf(referredUserIdObj.toString()); int milestone = Integer.parseInt(milestoneObj.toString()); return Result.success("领取成功", bonusService.claimReferralBonus(userId, referredUserId, milestone)); + } else if ("indirect_referral".equals(type)) { + Object directReferralIdObj = params.get("directReferralId"); + Object indirectReferredUserIdObj = params.get("indirectReferredUserId"); + Object milestoneObj = params.get("milestone"); + if (directReferralIdObj == null || indirectReferredUserIdObj == null || milestoneObj == null) { + return Result.fail("缺少参数"); + } + Long directReferralId = Long.valueOf(directReferralIdObj.toString()); + Long indirectReferredUserId = Long.valueOf(indirectReferredUserIdObj.toString()); + int milestone = Integer.parseInt(milestoneObj.toString()); + return Result.success("领取成功", bonusService.claimIndirectReferralBonus( + userId, directReferralId, indirectReferredUserId, milestone)); } else { return Result.fail("无效的奖励类型"); } diff --git a/src/main/java/com/it/rattan/monisuo/service/BonusService.java b/src/main/java/com/it/rattan/monisuo/service/BonusService.java index 12e24b0..f7a36b7 100644 --- a/src/main/java/com/it/rattan/monisuo/service/BonusService.java +++ b/src/main/java/com/it/rattan/monisuo/service/BonusService.java @@ -22,17 +22,20 @@ import java.util.*; * * 规则: * 1. 首充福利:新用户首次充值完成后可领取100u(一次性) - * 2. 推广奖励:被推广人累计充值每满1000u,推广人领100u(多次触发,最高8次/人) + * 2. 直接推广奖励:被推广人累计充值每满1000u,推广人领100u(最高8次/人) + * 3. 间接推广奖励:被推广人推广的用户充值每满1000u,推广人也领50u(最高8次/人间接上限) */ @Service public class BonusService { private static final BigDecimal BONUS_AMOUNT = new BigDecimal("100"); + private static final BigDecimal INDIRECT_BONUS_AMOUNT = new BigDecimal("50"); private static final BigDecimal MILESTONE_UNIT = new BigDecimal("1000"); private static final int MAX_MILESTONES = 8; private static final String NEW_USER_REMARK = "新人首充福利"; private static final String REFERRAL_REMARK_PREFIX = "邀请奖励-"; + private static final String INDIRECT_REFERRAL_REMARK_PREFIX = "间接推广奖励-"; @Autowired private AccountFundMapper accountFundMapper; @@ -114,15 +117,60 @@ public class BonusService { .count(); referralInfo.put("claimableCount", claimable); + // === 间接推广奖励 === + // 查询 B 推广的所有人(C, D, E...) + LambdaQueryWrapper indirectWrapper = new LambdaQueryWrapper<>(); + indirectWrapper.eq(User::getReferredBy, referred.getId()); + List indirectReferred = userMapper.selectList(indirectWrapper); + referralInfo.put("indirectRefCount", indirectReferred.size()); + + // 计算间接奖励里程碑 + int indirectClaimable = 0; + List> indirectMilestones = new ArrayList<>(); + for (User ir : indirectReferred) { + AccountFund irFund = assetService.getOrCreateFundAccount(ir.getId()); + BigDecimal irTotalDeposit = irFund.getTotalDeposit() != null + ? irFund.getTotalDeposit() : BigDecimal.ZERO; + int irEarned = irTotalDeposit.divide(MILESTONE_UNIT, 0, RoundingMode.DOWN).intValue(); + irEarned = Math.min(irEarned, MAX_MILESTONES); + + Set irClaimed = getIndirectClaimedMilestones(userId, referred.getId(), ir.getId()); + + for (int i = 1; i <= MAX_MILESTONES; i++) { + boolean earned = i <= irEarned; + boolean iClaimed = irClaimed.contains(i); + boolean isClaimable = earned && !iClaimed; + if (isClaimable) indirectClaimable++; + + Map im = new HashMap<>(); + im.put("indirectReferredUserId", ir.getId()); + im.put("indirectUsername", ir.getUsername()); + im.put("milestone", i); + im.put("amount", INDIRECT_BONUS_AMOUNT); + im.put("threshold", MILESTONE_UNIT.multiply(new BigDecimal(i))); + im.put("earned", earned); + im.put("claimed", iClaimed); + im.put("claimable", isClaimable); + indirectMilestones.add(im); + } + } + referralInfo.put("indirectClaimableCount", indirectClaimable); + referralInfo.put("indirectMilestones", indirectMilestones); + referralRewards.add(referralInfo); } result.put("referralRewards", referralRewards); - // 总可领取数量 + // 总可领取数量(直接 + 间接) int totalClaimable = (Boolean.TRUE.equals(newUserBonus.get("eligible")) ? 1 : 0); totalClaimable += referralRewards.stream() - .mapToInt(r -> r.get("claimableCount") instanceof Number - ? ((Number) r.get("claimableCount")).intValue() : 0) + .mapToInt(r -> { + int direct = r.get("claimableCount") instanceof Number + ? ((Number) r.get("claimableCount")).intValue() : 0; + int indirect = r.get("indirectClaimableCount") instanceof Number + ? ((Number) r.get("indirectClaimableCount")).intValue() : 0; + return direct + indirect; + }) .sum(); result.put("totalClaimable", totalClaimable); @@ -205,6 +253,66 @@ public class BonusService { return result; } + /** + * 领取间接推广奖励 + * A 推广 B,B 推广 C → A 领取 C 充值里程碑的间接奖励(50 USDT) + * + * @param referrerId A(领取人) + * @param directReferralId B(A 的直接推广人) + * @param indirectReferredUserId C(B 的推广人) + * @param milestone 里程碑序号 + */ + @Transactional(rollbackFor = Exception.class) + public Map claimIndirectReferralBonus(Long referrerId, Long directReferralId, + Long indirectReferredUserId, int milestone) { + if (milestone < 1 || milestone > MAX_MILESTONES) { + throw new RuntimeException("无效的里程碑"); + } + + // 验证推广链:A→B→C + User directReferral = userMapper.selectById(directReferralId); + if (directReferral == null || !referrerId.equals(directReferral.getReferredBy())) { + throw new RuntimeException("直接推广关系不存在"); + } + + User indirectReferred = userMapper.selectById(indirectReferredUserId); + if (indirectReferred == null || !directReferralId.equals(indirectReferred.getReferredBy())) { + throw new RuntimeException("间接推广关系不存在"); + } + + // 检查里程碑是否已达到 + AccountFund irFund = assetService.getOrCreateFundAccount(indirectReferredUserId); + BigDecimal irTotalDeposit = irFund.getTotalDeposit() != null + ? irFund.getTotalDeposit() : BigDecimal.ZERO; + int earnedMilestones = irTotalDeposit.divide(MILESTONE_UNIT, 0, RoundingMode.DOWN).intValue(); + if (milestone > earnedMilestones) { + throw new RuntimeException("该里程碑尚未达到"); + } + + // 检查是否已领取 + String remark = INDIRECT_REFERRAL_REMARK_PREFIX + directReferralId + "-" + indirectReferredUserId + "-" + milestone; + if (hasClaimedByRemark(referrerId, remark)) { + throw new RuntimeException("该间接奖励已领取"); + } + + // 发放奖励 + AccountFund referrerFund = assetService.getOrCreateFundAccount(referrerId); + BigDecimal balanceBefore = referrerFund.getBalance(); + BigDecimal balanceAfter = balanceBefore.add(INDIRECT_BONUS_AMOUNT); + + updateFundBalance(referrerFund, balanceAfter); + assetService.createFlow(referrerId, 1, INDIRECT_BONUS_AMOUNT, balanceBefore, balanceAfter, + "USDT", null, remark); + + Map result = new HashMap<>(); + result.put("amount", INDIRECT_BONUS_AMOUNT); + result.put("balance", balanceAfter); + result.put("directReferralId", directReferralId); + result.put("indirectReferredUserId", indirectReferredUserId); + result.put("milestone", milestone); + return result; + } + /** * 更新资金账户余额 */ @@ -250,4 +358,28 @@ public class BonusService { } return milestones; } + + /** + * 获取已领取的间接推广里程碑集合 + */ + private Set getIndirectClaimedMilestones(Long referrerId, Long directReferralId, Long indirectReferredUserId) { + String prefix = INDIRECT_REFERRAL_REMARK_PREFIX + directReferralId + "-" + indirectReferredUserId + "-"; + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(AccountFlow::getUserId, referrerId) + .likeRight(AccountFlow::getRemark, prefix); + List flows = accountFlowMapper.selectList(wrapper); + + Set milestones = new HashSet<>(); + for (AccountFlow flow : flows) { + String remark = flow.getRemark(); + if (remark != null && remark.startsWith(prefix)) { + try { + int m = Integer.parseInt(remark.substring(prefix.length())); + milestones.add(m); + } catch (NumberFormatException ignored) { + } + } + } + return milestones; + } }