docs(theme): update documentation and clean up deprecated color scheme definitions
Removed outdated compatibility aliases and deprecated methods from AppColorScheme, and updated CLAUDE.md to reflect new theme system requirements with centralized color management and no hard-coded values in UI components.
This commit is contained in:
@@ -64,7 +64,8 @@ deploy/deploy_server.sh backend # 仅部署后端
|
||||
|
||||
### Flutter 应用 (`flutter_monisuo/lib/`)
|
||||
- **状态管理**:Provider(ChangeNotifier)— `providers/` 消费 `data/services/`,底层调用 `core/network/DioClient`。
|
||||
- **UI**:shadcn_ui + 自定义主题系统(`core/theme/`)。深色主题为主,颜色集中管理在 `AppColorScheme`。
|
||||
- **主题样式**:前端禁止硬编码,新设计统一维护到theme目录的定义中,并尽可能复用设计主题。
|
||||
- **UI**:shadcn_ui + 自定义主题系统(`core/theme/`)。颜色集中管理在 `AppColorScheme`。
|
||||
- **数据流**:`data/services/`(API 调用)→ `providers/`(状态)→ `ui/pages/`(视图)。
|
||||
- 页面:auth、home、market、trade、asset、mine、orders、onboarding。
|
||||
|
||||
|
||||
@@ -419,81 +419,21 @@ class AppColorScheme {
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// 兼容性别名(替代 theme/app_colors.dart)
|
||||
// 映射旧名到新系统,避免 breaking change
|
||||
// 兼容性别名 - 仅保留有外部引用的
|
||||
// (buyButtonFill, sellButtonFill, darkCtaGradient, lightCtaGradient,
|
||||
// buyGradient, sellGradient 已在上方定义,此处无需重复)
|
||||
// ============================================
|
||||
|
||||
// 背景色
|
||||
static const Color background = darkBackground;
|
||||
static const Color cardBackground = darkSurfaceContainer;
|
||||
static const Color inputBackground = darkSurfaceContainerHigh;
|
||||
static const Color scaffoldBackground = darkBackground;
|
||||
static const Color modalBackground = darkSurfaceContainerHigh;
|
||||
static const Color hoverBackground = darkSurfaceBright;
|
||||
/// 获取买入按钮渐变(主题感知)- 用于盈利展示
|
||||
|
||||
// 文字色
|
||||
static const Color textPrimary = darkOnSurface;
|
||||
static const Color textSecondary = darkOnSurfaceVariant;
|
||||
static const Color textHint = darkOnSurfaceMuted;
|
||||
static const Color textDisabled = darkInverseSurface;
|
||||
static const Color textLink = darkPrimary;
|
||||
|
||||
// 边框色
|
||||
static const Color border = darkOutlineVariant;
|
||||
static const Color divider = darkSurfaceContainer;
|
||||
static const Color inputBorder = darkOnSurfaceMuted;
|
||||
static const Color inputFocusBorder = darkPrimary;
|
||||
static const Color focusBorder = darkPrimary;
|
||||
|
||||
// 交易类型色
|
||||
static const Color deposit = up;
|
||||
static const Color withdraw = warning;
|
||||
static const Color trade = info;
|
||||
|
||||
// 旧渐变
|
||||
static const List<Color> gradientColors = [darkPrimary, darkPrimaryContainer];
|
||||
static const LinearGradient primaryGradient = LinearGradient(
|
||||
colors: [darkPrimary, darkPrimaryContainer],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
);
|
||||
}
|
||||
|
||||
/// 创建 Shadcn 深色主题
|
||||
ShadThemeData createDarkShadTheme() {
|
||||
return ShadThemeData(
|
||||
brightness: Brightness.dark,
|
||||
colorScheme: AppColorScheme.darkShad,
|
||||
);
|
||||
}
|
||||
|
||||
/// 创建 Shadcn 浅色主题
|
||||
ShadThemeData createLightShadTheme() {
|
||||
return ShadThemeData(
|
||||
brightness: Brightness.light,
|
||||
colorScheme: AppColorScheme.lightShad,
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取涨跌颜色(明暗通用)- 已废弃,请使用带主题感知的版本
|
||||
@Deprecated('Use AppColorScheme.getUpColor(isDark) instead')
|
||||
/// 获取涨跌颜色(明暗通用)
|
||||
Color getChangeColor(bool isUp) => isUp ? AppColorScheme.up : AppColorScheme.down;
|
||||
|
||||
/// 获取涨跌背景色(带透明度)- 已废弃,请使用带主题感知的版本
|
||||
@Deprecated('Use AppColorScheme.getUpBackgroundColor(isDark, opacity: opacity) instead')
|
||||
/// 获取涨跌背景色(带透明度)
|
||||
Color getChangeBackgroundColor(bool isUp, {double opacity = 0.15}) {
|
||||
return isUp
|
||||
? AppColorScheme.up.withValues(alpha: opacity)
|
||||
: AppColorScheme.down.withValues(alpha: opacity);
|
||||
}
|
||||
|
||||
/// 获取涨跌颜色(主题感知)
|
||||
Color getChangeColorThemeAware(bool isUp, bool isDark) =>
|
||||
isUp ? AppColorScheme.getUpColor(isDark) : AppColorScheme.down;
|
||||
|
||||
/// 获取涨跌背景色(主题感知)
|
||||
Color getChangeBackgroundColorThemeAware(bool isUp, bool isDark, {double opacity = 0.15}) {
|
||||
return isUp
|
||||
? AppColorScheme.getUpBackgroundColor(isDark, opacity: opacity)
|
||||
: AppColorScheme.down.withValues(alpha: opacity);
|
||||
}
|
||||
|
||||
|
||||
@@ -81,17 +81,17 @@ class AppRadius {
|
||||
// 基础圆角 (Base Radius)
|
||||
// ============================================
|
||||
|
||||
/// 小圆角 - 4px (标签、小组件)
|
||||
static const double sm = 4.0;
|
||||
/// 小圆角 - 6px (标签、徽章) — 对齐 Pencil $radius-sm
|
||||
static const double sm = 6.0;
|
||||
|
||||
/// 中圆角 - 8px (输入框)
|
||||
static const double md = 8.0;
|
||||
/// 中圆角 - 10px (输入框、标签页) — 对齐 Pencil $radius-md
|
||||
static const double md = 10.0;
|
||||
|
||||
/// 大圆角 - 12px (卡片 - 旧版)
|
||||
static const double lg = 12.0;
|
||||
/// 大圆角 - 14px (卡片、按钮、列表) — 对齐 Pencil $radius-lg
|
||||
static const double lg = 14.0;
|
||||
|
||||
/// 特大圆角 - 16px (大卡片)
|
||||
static const double xl = 16.0;
|
||||
/// 特大圆角 - 20px (大卡片、弹窗) — 对齐 Pencil $radius-xl
|
||||
static const double xl = 20.0;
|
||||
|
||||
/// 超大圆角 - 24px (按钮、模态框、底部抽屉)
|
||||
static const double xxl = 24.0;
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'app_color_scheme.dart';
|
||||
|
||||
/// 文字样式系统
|
||||
///
|
||||
/// 统一管理所有文字样式,确保一致性
|
||||
/// 所有样式默认使用 textPrimary 颜色,保证对比度
|
||||
class AppTextStyles {
|
||||
AppTextStyles._();
|
||||
|
||||
// ============================================
|
||||
// 标题样式 (Headings)
|
||||
// ============================================
|
||||
|
||||
/// H1 - 页面大标题
|
||||
static const TextStyle h1 = TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// H2 - 区块标题
|
||||
static const TextStyle h2 = TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// H3 - 卡片标题
|
||||
static const TextStyle h3 = TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
/// H4 - 小标题
|
||||
static const TextStyle h4 = TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// 正文样式 (Body)
|
||||
// ============================================
|
||||
|
||||
/// Body1 - 主要正文
|
||||
static const TextStyle body1 = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.5,
|
||||
);
|
||||
|
||||
/// Body2 - 次要正文
|
||||
static const TextStyle body2 = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.5,
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// 辅助文字 (Caption & Small)
|
||||
// ============================================
|
||||
|
||||
/// Caption - 说明文字
|
||||
static const TextStyle caption = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: AppColorScheme.textSecondary,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
/// Small - 极小文字
|
||||
static const TextStyle small = TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: AppColorScheme.textSecondary,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// Hint - 提示文字
|
||||
static const TextStyle hint = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: AppColorScheme.textHint,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// 特殊样式 (Special)
|
||||
// ============================================
|
||||
|
||||
/// 金额/价格 - 大号数字
|
||||
static const TextStyle amount = TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.2,
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
);
|
||||
|
||||
/// 价格 - 标准数字
|
||||
static const TextStyle price = TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.3,
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
);
|
||||
|
||||
/// 价格变化 - 涨跌幅
|
||||
static const TextStyle priceChange = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
height: 1.3,
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
);
|
||||
|
||||
/// 按钮文字
|
||||
static const TextStyle button = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColorScheme.textPrimary,
|
||||
height: 1.2,
|
||||
);
|
||||
|
||||
/// 链接文字
|
||||
static const TextStyle link = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColorScheme.textLink,
|
||||
decoration: TextDecoration.underline,
|
||||
height: 1.4,
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// 可复制修改的样式方法
|
||||
// ============================================
|
||||
|
||||
/// 获取带颜色的标题样式
|
||||
static TextStyle headingWithColor(TextStyle style, Color color) {
|
||||
return style.copyWith(color: color);
|
||||
}
|
||||
|
||||
/// 获取带颜色的正文样式
|
||||
static TextStyle bodyWithColor(TextStyle style, Color color) {
|
||||
return style.copyWith(color: color);
|
||||
}
|
||||
|
||||
/// 获取粗体样式
|
||||
static TextStyle bold(TextStyle style) {
|
||||
return style.copyWith(fontWeight: FontWeight.bold);
|
||||
}
|
||||
|
||||
/// 获取半粗体样式
|
||||
static TextStyle semiBold(TextStyle style) {
|
||||
return style.copyWith(fontWeight: FontWeight.w600);
|
||||
}
|
||||
}
|
||||
|
||||
/// 兼容旧代码的别名
|
||||
@Deprecated('Use AppTextStyles instead')
|
||||
class AppText {
|
||||
AppText._();
|
||||
}
|
||||
@@ -69,15 +69,15 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
|
||||
// 按钮 - 渐变 CTA,大圆角
|
||||
// 按钮 - Pencil accent-primary (Gold)
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColorScheme.darkPrimary,
|
||||
foregroundColor: AppColorScheme.darkBackground,
|
||||
minimumSize: const Size(double.infinity, 48),
|
||||
backgroundColor: AppColorScheme.darkSecondary,
|
||||
foregroundColor: AppColorScheme.darkOnSecondary,
|
||||
minimumSize: const Size(double.infinity, 52),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppRadius.xxl),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
elevation: 0,
|
||||
textStyle: GoogleFonts.inter(
|
||||
@@ -89,7 +89,7 @@ class AppTheme {
|
||||
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: AppColorScheme.darkPrimary,
|
||||
foregroundColor: AppColorScheme.darkSecondary,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -174,15 +174,15 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
|
||||
// 按钮 - Plasma 渐变,full 圆角
|
||||
// 按钮 - Pencil accent-primary (dark gray)
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: AppColorScheme.lightPrimary,
|
||||
backgroundColor: const Color(0xFF1F2937),
|
||||
foregroundColor: const Color(0xFFFFFFFF),
|
||||
minimumSize: const Size(double.infinity, 48),
|
||||
minimumSize: const Size(double.infinity, 52),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppRadius.xxl),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
elevation: 0,
|
||||
textStyle: GoogleFonts.inter(
|
||||
@@ -194,7 +194,7 @@ class AppTheme {
|
||||
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: AppColorScheme.lightPrimary,
|
||||
foregroundColor: const Color(0xFF1F2937),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -216,55 +216,56 @@ class AppTheme {
|
||||
}
|
||||
}
|
||||
|
||||
/// "The Kinetic Vault" & "The Ethereal Terminal" 文字样式系统
|
||||
/// Pencil 设计系统字体规范
|
||||
///
|
||||
/// 【优化】统一使用 Inter 字体(专业金融风格,币安同款字体)
|
||||
/// 对齐 Pencil 变量: Inter 字体, 明确的字号/字重层级
|
||||
/// 28px (总资产) → 24px (精选价格) → 22px (页面标题) → 16px (区块标题)
|
||||
/// → 14px (卡片标题/价格) → 13px (正文) → 12px (标签/副标题) → 11px (小文字)
|
||||
class AppTextStyles {
|
||||
AppTextStyles._();
|
||||
|
||||
// ============================================
|
||||
// Display - 核心数字 (价格/余额)
|
||||
// 参考 Binance/OKX 紧凑专业风格
|
||||
// Display - 核心数字
|
||||
// ============================================
|
||||
|
||||
/// D1 - 总资产余额 (22px)
|
||||
/// D1 - 总资产/余额 (28px w700) — Pencil $hero-value
|
||||
static TextStyle displayLarge(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 22,
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.15,
|
||||
letterSpacing: -0.01,
|
||||
letterSpacing: -0.5,
|
||||
);
|
||||
|
||||
/// D2 - 主价格 (20px)
|
||||
/// D2 - 精选价格 (24px w700) — Pencil 行情卡片价格
|
||||
static TextStyle displayMedium(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.15,
|
||||
);
|
||||
|
||||
/// D3 - 页面标题 (22px w700) — Pencil 页面大标题
|
||||
static TextStyle displaySmall(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.2,
|
||||
);
|
||||
|
||||
/// D3 - 次要价格 (18px)
|
||||
static TextStyle displaySmall(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.25,
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// Headline - 标题
|
||||
// ============================================
|
||||
|
||||
/// 区域标题 (15px)
|
||||
/// 区块/导航标题 (16px w600) — Pencil $section-title
|
||||
static TextStyle headlineLarge(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 15,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.3,
|
||||
);
|
||||
|
||||
/// 卡片标题 (14px)
|
||||
/// 卡片标题/价格/标签页 (14px w600) — Pencil $card-title
|
||||
static TextStyle headlineMedium(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
@@ -272,7 +273,7 @@ class AppTextStyles {
|
||||
height: 1.35,
|
||||
);
|
||||
|
||||
/// 副标题 (13px)
|
||||
/// 副标题/持仓价值 (13px w500)
|
||||
static TextStyle headlineSmall(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
@@ -284,7 +285,7 @@ class AppTextStyles {
|
||||
// Body - 正文
|
||||
// ============================================
|
||||
|
||||
/// 主要正文 (13px)
|
||||
/// 主要正文 (13px w400)
|
||||
static TextStyle bodyLarge(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w400,
|
||||
@@ -292,7 +293,7 @@ class AppTextStyles {
|
||||
height: 1.45,
|
||||
);
|
||||
|
||||
/// 次要正文 (12px)
|
||||
/// 次要正文/副标题 (12px w400) — Pencil $subtitle
|
||||
static TextStyle bodyMedium(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
@@ -300,7 +301,7 @@ class AppTextStyles {
|
||||
height: 1.45,
|
||||
);
|
||||
|
||||
/// 辅助文字 (11px)
|
||||
/// 辅助文字/币种全名 (11px w400) — Pencil $small-text
|
||||
static TextStyle bodySmall(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w400,
|
||||
@@ -312,26 +313,26 @@ class AppTextStyles {
|
||||
// Label - 标签
|
||||
// ============================================
|
||||
|
||||
/// 常规标签 (11px)
|
||||
/// 按钮/标签页标签 (12px w500) — Pencil $tab-label
|
||||
static TextStyle labelLarge(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.35,
|
||||
);
|
||||
|
||||
/// 小标签 (10px)
|
||||
/// 涨跌幅标签 (11px w500) — Pencil $change-badge
|
||||
static TextStyle labelMedium(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 10,
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
height: 1.35,
|
||||
);
|
||||
|
||||
/// 极小标签 (9px)
|
||||
/// 涨跌幅标签-粗 (11px w600) — Pencil $change-badge-bold
|
||||
static TextStyle labelSmall(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 9,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
height: 1.35,
|
||||
);
|
||||
@@ -340,108 +341,33 @@ class AppTextStyles {
|
||||
// 数字/金额 - Inter (等宽特性)
|
||||
// ============================================
|
||||
|
||||
/// 大号数字 (22px) - 主价格、总资产
|
||||
/// 大号数字 (28px w700) - 总资产、余额
|
||||
static TextStyle numberLarge(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.15,
|
||||
letterSpacing: -0.5,
|
||||
fontFeatures: const [FontFeature.tabularFigures()],
|
||||
);
|
||||
|
||||
/// 中号数字 (16px) - 次要价格、数量
|
||||
/// 中号数字 (14px w600) - 价格、金额
|
||||
static TextStyle numberMedium(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.25,
|
||||
fontFeatures: const [FontFeature.tabularFigures()],
|
||||
);
|
||||
|
||||
/// 小号数字 (13px) - 涨跌幅、小量
|
||||
/// 小号数字 (12px w500) - 涨跌幅、数量
|
||||
static TextStyle numberSmall(BuildContext context) => GoogleFonts.inter(
|
||||
fontSize: 13,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
height: 1.3,
|
||||
fontFeatures: const [FontFeature.tabularFigures()],
|
||||
);
|
||||
|
||||
// ============================================
|
||||
// 兼容旧代码的静态样式 (已废弃)
|
||||
// ============================================
|
||||
|
||||
@Deprecated('Use displaySmall instead')
|
||||
static const TextStyle heading1 = TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
|
||||
@Deprecated('Use headlineLarge instead')
|
||||
static const TextStyle heading2 = TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
|
||||
@Deprecated('Use headlineMedium instead')
|
||||
static const TextStyle heading3 = TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
|
||||
@Deprecated('Use headlineSmall instead')
|
||||
static const TextStyle heading4 = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
|
||||
@Deprecated('Use bodyLarge instead')
|
||||
static const TextStyle body1 = TextStyle(
|
||||
fontSize: 13,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
|
||||
@Deprecated('Use bodyMedium instead')
|
||||
static const TextStyle body2 = TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
|
||||
@Deprecated('Use labelSmall instead')
|
||||
static const TextStyle caption = TextStyle(
|
||||
fontSize: 11,
|
||||
color: Color(0xFFA1A1AA),
|
||||
);
|
||||
|
||||
@Deprecated('Use labelSmall instead')
|
||||
static const TextStyle hint = TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF71717A),
|
||||
);
|
||||
|
||||
@Deprecated('Use numberMedium instead')
|
||||
static const TextStyle price = TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
|
||||
@Deprecated('Use numberSmall with color instead')
|
||||
static const TextStyle change = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
|
||||
@Deprecated('Use numberSmall instead')
|
||||
static const TextStyle number = TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFFFFFFFF),
|
||||
);
|
||||
}
|
||||
|
||||
/// 动画时长
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/event/app_event_bus.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import 'components/account_tab_switcher.dart';
|
||||
@@ -81,11 +81,7 @@ class _AssetPageState extends State<AssetPage> with AutomaticKeepAliveClientMixi
|
||||
padding: const EdgeInsets.only(top: 16, bottom: 8),
|
||||
child: Text(
|
||||
'资产',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.displaySmall(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
|
||||
/// 账户标签切换器 — .pen node UE6xC
|
||||
@@ -67,12 +67,12 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected
|
||||
? colorScheme.surface
|
||||
: Colors.transparent,
|
||||
: const Color(0x00000000),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
boxShadow: isSelected
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.05),
|
||||
color: colorScheme.shadow.withValues(alpha: 0.05),
|
||||
blurRadius: 3,
|
||||
offset: const Offset(0, 1),
|
||||
),
|
||||
@@ -82,11 +82,12 @@ class AccountTabSwitcher extends StatelessWidget {
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
label,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500,
|
||||
color: isSelected ? colorScheme.onSurface : colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: isSelected
|
||||
? AppTextStyles.headlineMedium(context)
|
||||
: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
|
||||
/// 操作按钮行 — .pen node pIpHe
|
||||
/// gap: 12, three buttons evenly distributed
|
||||
@@ -35,7 +35,7 @@ class ActionButtonsRow extends StatelessWidget {
|
||||
bgColor: bgColor,
|
||||
onTap: onDeposit,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const SizedBox(width: AppSpacing.sm + AppSpacing.xs),
|
||||
ActionButton(
|
||||
icon: LucideIcons.arrowDownLeft,
|
||||
label: '提现',
|
||||
@@ -43,7 +43,7 @@ class ActionButtonsRow extends StatelessWidget {
|
||||
bgColor: bgColor,
|
||||
onTap: onWithdraw,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const SizedBox(width: AppSpacing.sm + AppSpacing.xs),
|
||||
ActionButton(
|
||||
icon: LucideIcons.repeat,
|
||||
label: '划转',
|
||||
@@ -96,12 +96,10 @@ class ActionButton extends StatelessWidget {
|
||||
color: accentColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: AppSpacing.xs + 2),
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/utils/toast_utils.dart';
|
||||
@@ -38,17 +38,14 @@ class InfoRow extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
|
||||
color: colorScheme.onSurface,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontWeight: isBold ? FontWeight.bold : FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -88,9 +85,8 @@ class WalletAddressCard extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Text(
|
||||
address,
|
||||
style: const TextStyle(
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -117,10 +113,7 @@ class WalletAddressCard extends StatelessWidget {
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
'网络: $network',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -141,7 +134,7 @@ void showDepositDialog(BuildContext context) {
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
child: GlassPanel(
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
@@ -157,17 +150,14 @@ void showDepositDialog(BuildContext context) {
|
||||
children: [
|
||||
Text(
|
||||
'充值',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
'Asset: USDT',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -261,7 +251,7 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
child: GlassPanel(
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
@@ -279,10 +269,8 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'充值申请成功',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -294,8 +282,7 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
Text(
|
||||
'请向以下地址转账:',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -318,7 +305,9 @@ void showDepositResultDialog(BuildContext context, Map<String, dynamic> data) {
|
||||
Expanded(
|
||||
child: Text(
|
||||
'转账完成后请点击"已打款"按钮确认',
|
||||
style: GoogleFonts.inter(fontSize: 12, color: AppColorScheme.warning),
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: AppColorScheme.warning,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -372,11 +361,12 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
final contactController = TextEditingController();
|
||||
final formKey = GlobalKey<ShadFormState>();
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
child: GlassPanel(
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
@@ -401,10 +391,8 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'提现',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -412,8 +400,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
const SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
'安全地将您的资产转移到外部钱包地址',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -425,10 +412,10 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColorScheme.up.withValues(alpha: 0.1),
|
||||
color: AppColorScheme.getUpBackgroundColor(isDark),
|
||||
borderRadius: BorderRadius.circular(AppRadius.full),
|
||||
border: Border.all(
|
||||
color: AppColorScheme.up.withValues(alpha: 0.2),
|
||||
color: AppColorScheme.getUpColor(isDark).withValues(alpha: 0.2),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@@ -436,17 +423,15 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
children: [
|
||||
Text(
|
||||
'可用余额: ',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 10,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'$balance USDT',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColorScheme.up,
|
||||
color: AppColorScheme.getUpColor(isDark),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -538,7 +523,7 @@ void showWithdrawDialog(BuildContext context, String? balance) {
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
'End-to-End Encrypted Transaction',
|
||||
style: GoogleFonts.inter(
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontSize: 10,
|
||||
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.5),
|
||||
),
|
||||
@@ -560,7 +545,7 @@ void showResultDialog(BuildContext context, String title, String? message) {
|
||||
showShadDialog(
|
||||
context: context,
|
||||
builder: (ctx) => Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
child: GlassPanel(
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
@@ -569,17 +554,17 @@ void showResultDialog(BuildContext context, String title, String? message) {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
if (message != null) ...[
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
message,
|
||||
style: GoogleFonts.inter(color: colorScheme.onSurfaceVariant),
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../providers/asset_provider.dart';
|
||||
@@ -37,28 +37,22 @@ class BalanceCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'USDT 余额',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
_formatBalance(displayBalance),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.numberLarge(context),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
'\u2248 \$${_formatBalance(displayBalance)} USD',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: isDark ? AppColorScheme.darkOnSurfaceMuted : colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../data/models/account_models.dart';
|
||||
@@ -27,18 +27,13 @@ class HoldingsSection extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'交易账户持仓',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
Text(
|
||||
'查看全部 >',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -50,8 +45,7 @@ class HoldingsSection extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(AppSpacing.xl),
|
||||
child: Text(
|
||||
'暂无持仓',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 13,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -143,8 +137,7 @@ class HoldingRow extends StatelessWidget {
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
coinCode.substring(0, 1),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: accentColor,
|
||||
),
|
||||
@@ -159,18 +152,13 @@ class HoldingRow extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
coinCode,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineMedium(context),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
quantity,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -184,18 +172,14 @@ class HoldingRow extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.inter(
|
||||
style: AppTextStyles.numberMedium(context).copyWith(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
profitRate,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: AppTextStyles.numberSmall(context).copyWith(
|
||||
color: profitColor,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
@@ -30,10 +30,8 @@ class RecordsLinkRow extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'充提记录',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../data/models/account_models.dart';
|
||||
@@ -81,17 +82,6 @@ class _TransferPageState extends State<TransferPage> {
|
||||
|
||||
bool get _isDark => Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
/// 一次性获取所有主题感知颜色
|
||||
_TransferColors get _colors => _TransferColors(_isDark);
|
||||
|
||||
TextStyle _inter({
|
||||
required double fontSize,
|
||||
required FontWeight fontWeight,
|
||||
required Color color,
|
||||
}) {
|
||||
return GoogleFonts.inter(fontSize: fontSize, fontWeight: fontWeight, color: color);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 业务逻辑
|
||||
// ============================================
|
||||
@@ -162,37 +152,37 @@ class _TransferPageState extends State<TransferPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final c = _colors;
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: c.bgSecondary,
|
||||
backgroundColor: colorScheme.surface,
|
||||
appBar: AppBar(
|
||||
backgroundColor: c.surfaceCard,
|
||||
backgroundColor: colorScheme.surfaceContainer,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(LucideIcons.arrowLeft, color: c.textPrimary, size: 20),
|
||||
icon: Icon(LucideIcons.arrowLeft, color: colorScheme.onSurface, size: 20),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
title: Text(
|
||||
'账户划转',
|
||||
style: _inter(fontSize: 16, fontWeight: FontWeight.w600, color: c.textPrimary),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: Consumer<AssetProvider>(
|
||||
builder: (context, provider, _) {
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
|
||||
padding: const EdgeInsets.fromLTRB(AppSpacing.md, AppSpacing.md, AppSpacing.md, AppSpacing.xl),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildTransferDirectionCard(c),
|
||||
const SizedBox(height: 24),
|
||||
_buildAmountSection(c),
|
||||
const SizedBox(height: 24),
|
||||
_buildTipsCard(c),
|
||||
const SizedBox(height: 24),
|
||||
_buildConfirmButton(c),
|
||||
_buildTransferDirectionCard(),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
_buildAmountSection(),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
_buildTipsCard(),
|
||||
const SizedBox(height: AppSpacing.lg),
|
||||
_buildConfirmButton(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -205,14 +195,16 @@ class _TransferPageState extends State<TransferPage> {
|
||||
// Transfer direction card
|
||||
// ============================================
|
||||
|
||||
Widget _buildTransferDirectionCard(_TransferColors c) {
|
||||
Widget _buildTransferDirectionCard() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(AppSpacing.lg),
|
||||
decoration: BoxDecoration(
|
||||
color: c.surfaceCard,
|
||||
color: colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
border: Border.all(color: c.borderDefault.withValues(alpha: 0.6)),
|
||||
border: Border.all(color: colorScheme.outlineVariant.withValues(alpha: 0.6)),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
@@ -224,7 +216,6 @@ class _TransferPageState extends State<TransferPage> {
|
||||
label: '从',
|
||||
accountName: _fromLabel,
|
||||
balance: _fromBalance,
|
||||
c: c,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -234,13 +225,13 @@ class _TransferPageState extends State<TransferPage> {
|
||||
child: Container(
|
||||
width: 36,
|
||||
height: 36,
|
||||
margin: const EdgeInsets.symmetric(vertical: 16),
|
||||
margin: const EdgeInsets.symmetric(vertical: AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: c.accentPrimary,
|
||||
color: colorScheme.secondary,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Center(
|
||||
child: Icon(LucideIcons.arrowUpDown, size: 18, color: c.textInverse),
|
||||
child: Icon(LucideIcons.arrowUpDown, size: 18, color: colorScheme.onSecondary),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -253,7 +244,6 @@ class _TransferPageState extends State<TransferPage> {
|
||||
label: '到',
|
||||
accountName: _toLabel,
|
||||
balance: _toBalance,
|
||||
c: c,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -286,15 +276,16 @@ class _TransferPageState extends State<TransferPage> {
|
||||
required String label,
|
||||
required String accountName,
|
||||
required String balance,
|
||||
required _TransferColors c,
|
||||
}) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(label, style: _inter(fontSize: 11, fontWeight: FontWeight.normal, color: c.textMuted)),
|
||||
const SizedBox(height: 8),
|
||||
Text(label, style: AppTextStyles.bodySmall(context)),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -303,15 +294,15 @@ class _TransferPageState extends State<TransferPage> {
|
||||
Icon(
|
||||
label == '从' ? LucideIcons.wallet : LucideIcons.repeat,
|
||||
size: 18,
|
||||
color: c.textSecondary,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(accountName, style: _inter(fontSize: 14, fontWeight: FontWeight.w600, color: c.textPrimary)),
|
||||
const SizedBox(width: AppSpacing.sm + 2),
|
||||
Text(accountName, style: AppTextStyles.headlineMedium(context)),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'\u00A5 ${_formatBalance(balance)}',
|
||||
style: _inter(fontSize: 14, fontWeight: FontWeight.w600, color: c.textPrimary),
|
||||
style: AppTextStyles.headlineMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -324,7 +315,9 @@ class _TransferPageState extends State<TransferPage> {
|
||||
// Amount input section
|
||||
// ============================================
|
||||
|
||||
Widget _buildAmountSection(_TransferColors c) {
|
||||
Widget _buildAmountSection() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -332,10 +325,13 @@ class _TransferPageState extends State<TransferPage> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('划转金额', style: _inter(fontSize: 14, fontWeight: FontWeight.w500, color: c.textSecondary)),
|
||||
Text('划转金额', style: AppTextStyles.headlineSmall(context).copyWith(color: colorScheme.onSurfaceVariant)),
|
||||
GestureDetector(
|
||||
onTap: () => _setQuickAmount(1.0),
|
||||
child: Text('全部划转', style: _inter(fontSize: 12, fontWeight: FontWeight.w600, color: c.goldAccent)),
|
||||
child: Text('全部划转', style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.secondary,
|
||||
fontWeight: FontWeight.w600,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -347,9 +343,9 @@ class _TransferPageState extends State<TransferPage> {
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 56,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: c.bgTertiary,
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Row(
|
||||
@@ -363,10 +359,12 @@ class _TransferPageState extends State<TransferPage> {
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d{0,8}')),
|
||||
],
|
||||
style: _inter(fontSize: 28, fontWeight: FontWeight.w700, color: c.textPrimary),
|
||||
style: AppTextStyles.numberLarge(context),
|
||||
decoration: InputDecoration(
|
||||
hintText: '0.00',
|
||||
hintStyle: _inter(fontSize: 28, fontWeight: FontWeight.w700, color: c.textMuted),
|
||||
hintStyle: AppTextStyles.numberLarge(context).copyWith(
|
||||
color: AppColorScheme.darkOnSurfaceMuted,
|
||||
),
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
isDense: true,
|
||||
@@ -374,8 +372,11 @@ class _TransferPageState extends State<TransferPage> {
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Text('USDT', style: _inter(fontSize: 14, fontWeight: FontWeight.normal, color: c.textMuted)),
|
||||
padding: const EdgeInsets.only(left: AppSpacing.sm),
|
||||
child: Text('USDT', style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColorScheme.darkOnSurfaceMuted,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -390,8 +391,8 @@ class _TransferPageState extends State<TransferPage> {
|
||||
final percent = entry.value;
|
||||
final label = '${(percent * 100).toInt()}%';
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(left: index > 0 ? 8 : 0),
|
||||
child: _buildPercentButton(label, percent, c),
|
||||
padding: EdgeInsets.only(left: index > 0 ? AppSpacing.sm : 0),
|
||||
child: _buildPercentButton(label, percent),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
@@ -399,18 +400,20 @@ class _TransferPageState extends State<TransferPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPercentButton(String label, double percent, _TransferColors c) {
|
||||
Widget _buildPercentButton(String label, double percent) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: () => _setQuickAmount(percent),
|
||||
child: Container(
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: c.bgTertiary,
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(label, style: _inter(fontSize: 13, fontWeight: FontWeight.w500, color: c.textSecondary)),
|
||||
child: Text(label, style: AppTextStyles.headlineSmall(context)),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -421,22 +424,24 @@ class _TransferPageState extends State<TransferPage> {
|
||||
// Tips card & Confirm button
|
||||
// ============================================
|
||||
|
||||
Widget _buildTipsCard(_TransferColors c) {
|
||||
Widget _buildTipsCard() {
|
||||
final upColor = AppColorScheme.getUpColor(_isDark);
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: c.profitGreenBg,
|
||||
color: AppColorScheme.getUpBackgroundColor(_isDark),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(LucideIcons.info, size: 16, color: c.profitGreen),
|
||||
const SizedBox(width: 8),
|
||||
Icon(LucideIcons.info, size: 16, color: upColor),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'划转即时到账,无需手续费',
|
||||
style: _inter(fontSize: 12, fontWeight: FontWeight.normal, color: c.profitGreen),
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(color: upColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -444,7 +449,9 @@ class _TransferPageState extends State<TransferPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildConfirmButton(_TransferColors c) {
|
||||
Widget _buildConfirmButton() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return SizedBox(
|
||||
width: double.infinity,
|
||||
height: 52,
|
||||
@@ -452,7 +459,7 @@ class _TransferPageState extends State<TransferPage> {
|
||||
onTap: _isLoading ? null : _doTransfer,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: c.accentPrimary,
|
||||
color: colorScheme.secondary,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
),
|
||||
child: Center(
|
||||
@@ -462,12 +469,15 @@ class _TransferPageState extends State<TransferPage> {
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(c.textInverse),
|
||||
valueColor: AlwaysStoppedAnimation<Color>(colorScheme.onSecondary),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'确认划转',
|
||||
style: _inter(fontSize: 16, fontWeight: FontWeight.w700, color: c.textInverse),
|
||||
style: AppTextStyles.displayMedium(context).copyWith(
|
||||
color: colorScheme.onSecondary,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -485,33 +495,3 @@ class _TransferPageState extends State<TransferPage> {
|
||||
return val.toStringAsFixed(2);
|
||||
}
|
||||
}
|
||||
|
||||
/// 主题感知颜色集合,避免在 build() 中重复定义大量局部变量
|
||||
class _TransferColors {
|
||||
final Color bgSecondary;
|
||||
final Color surfaceCard;
|
||||
final Color bgTertiary;
|
||||
final Color borderDefault;
|
||||
final Color textPrimary;
|
||||
final Color textSecondary;
|
||||
final Color textMuted;
|
||||
final Color textInverse;
|
||||
final Color accentPrimary;
|
||||
final Color goldAccent;
|
||||
final Color profitGreen;
|
||||
final Color profitGreenBg;
|
||||
|
||||
_TransferColors(bool isDark)
|
||||
: bgSecondary = isDark ? const Color(0xFF0B1120) : const Color(0xFFF8FAFC),
|
||||
surfaceCard = isDark ? const Color(0xFF0F172A) : const Color(0xFFFFFFFF),
|
||||
bgTertiary = isDark ? const Color(0xFF1E293B) : const Color(0xFFF1F5F9),
|
||||
borderDefault = isDark ? const Color(0xFF334155) : const Color(0xFFE2E8F0),
|
||||
textPrimary = isDark ? const Color(0xFFF8FAFC) : const Color(0xFF0F172A),
|
||||
textSecondary = isDark ? const Color(0xFF94A3B8) : const Color(0xFF475569),
|
||||
textMuted = isDark ? const Color(0xFF64748B) : const Color(0xFF94A3B8),
|
||||
textInverse = isDark ? const Color(0xFF0F172A) : const Color(0xFFFFFFFF),
|
||||
accentPrimary = isDark ? const Color(0xFFD4AF37) : const Color(0xFF1F2937),
|
||||
goldAccent = isDark ? const Color(0xFFD4AF37) : const Color(0xFFF59E0B),
|
||||
profitGreen = isDark ? const Color(0xFF4ADE80) : const Color(0xFF16A34A),
|
||||
profitGreenBg = isDark ? const Color(0xFF052E16) : const Color(0xFFF0FDF4);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
import '../main/main_page.dart';
|
||||
import 'register_page.dart';
|
||||
@@ -26,9 +27,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||
static const _inputHeight = 52.0;
|
||||
static const _buttonHeight = 52.0;
|
||||
|
||||
/// 设计稿 radius-lg = 14
|
||||
static const _designRadiusLg = 14.0;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_usernameController.dispose();
|
||||
@@ -86,18 +84,18 @@ class _LoginPageState extends State<LoginPage> {
|
||||
gradient: const LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xFF1F2937), Color(0xFF374151)],
|
||||
colors: [AppColorScheme.darkSurfaceContainerHigh, AppColorScheme.darkOutline],
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'M',
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.displayLarge(context).copyWith(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
: Colors.white,
|
||||
: AppColorScheme.darkOnPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -105,9 +103,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// 品牌名 "MONISUO"
|
||||
Text(
|
||||
'MONISUO',
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.w800,
|
||||
style: AppTextStyles.displayLarge(context).copyWith(
|
||||
letterSpacing: 3,
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
@@ -119,9 +115,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// 标语
|
||||
Text(
|
||||
'虚拟货币模拟交易平台',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurfaceVariant
|
||||
: AppColorScheme.lightOnSurfaceVariant,
|
||||
@@ -174,11 +168,10 @@ class _LoginPageState extends State<LoginPage> {
|
||||
decoration: ShadDecoration(
|
||||
border: ShadBorder.all(
|
||||
color: borderColor,
|
||||
radius: BorderRadius.circular(_designRadiusLg),
|
||||
radius: AppRadius.radiusLg,
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
: AppColorScheme.lightOnSurface,
|
||||
@@ -218,11 +211,10 @@ class _LoginPageState extends State<LoginPage> {
|
||||
decoration: ShadDecoration(
|
||||
border: ShadBorder.all(
|
||||
color: borderColor,
|
||||
radius: BorderRadius.circular(_designRadiusLg),
|
||||
radius: AppRadius.radiusLg,
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: isDark
|
||||
? AppColorScheme.darkOnSurface
|
||||
: AppColorScheme.lightOnSurface,
|
||||
@@ -235,10 +227,10 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// 设计稿: accent-primary = light:#1F2937 / dark:#D4AF37
|
||||
final buttonColor = isDark
|
||||
? AppColorScheme.darkSecondary
|
||||
: const Color(0xFF1F2937);
|
||||
: AppColorScheme.darkSurfaceContainerHigh;
|
||||
final textColor = isDark
|
||||
? AppColorScheme.darkBackground
|
||||
: Colors.white;
|
||||
: AppColorScheme.darkOnPrimary;
|
||||
|
||||
return Consumer<AuthProvider>(
|
||||
builder: (context, auth, _) {
|
||||
@@ -250,7 +242,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
foregroundColor: textColor,
|
||||
decoration: ShadDecoration(
|
||||
border: ShadBorder.all(
|
||||
radius: BorderRadius.circular(_designRadiusLg),
|
||||
radius: AppRadius.radiusLg,
|
||||
),
|
||||
),
|
||||
child: auth.isLoading
|
||||
@@ -263,8 +255,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
)
|
||||
: Text(
|
||||
'登录',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: textColor,
|
||||
),
|
||||
@@ -283,7 +274,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
// gold-accent: light=#F59E0B / dark=#D4AF37
|
||||
final goldColor = isDark
|
||||
? AppColorScheme.darkSecondary
|
||||
: const Color(0xFFF59E0B);
|
||||
: AppColorScheme.darkSecondaryFixed;
|
||||
final secondaryTextColor = isDark
|
||||
? AppColorScheme.darkOnSurfaceVariant
|
||||
: AppColorScheme.lightOnSurfaceVariant;
|
||||
@@ -295,9 +286,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
children: [
|
||||
Text(
|
||||
'还没有账户?',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: secondaryTextColor,
|
||||
),
|
||||
),
|
||||
@@ -306,8 +295,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
onTap: _navigateToRegister,
|
||||
child: Text(
|
||||
'立即注册',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: goldColor,
|
||||
),
|
||||
|
||||
@@ -2,10 +2,10 @@ import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
import '../../components/neon_glow.dart';
|
||||
@@ -81,7 +81,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.background,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: AppColorScheme.darkBackground.withValues(alpha: 0),
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(LucideIcons.chevronLeft, color: colorScheme.onSurface),
|
||||
@@ -124,7 +124,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
height: 2,
|
||||
color: _currentStep > 0
|
||||
? AppColorScheme.up
|
||||
: colorScheme.outlineVariant.withOpacity(0.2),
|
||||
: colorScheme.outlineVariant.withValues(alpha: 0.2),
|
||||
),
|
||||
),
|
||||
_buildStepCircle(
|
||||
@@ -150,10 +150,10 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
|
||||
if (isComplete) {
|
||||
circleColor = AppColorScheme.up;
|
||||
textColor = Colors.white;
|
||||
textColor = AppColorScheme.darkOnPrimary;
|
||||
} else if (isActive) {
|
||||
circleColor = colorScheme.primary;
|
||||
textColor = Colors.white;
|
||||
textColor = AppColorScheme.darkOnPrimary;
|
||||
} else {
|
||||
circleColor = colorScheme.surfaceContainerHigh;
|
||||
textColor = colorScheme.onSurfaceVariant;
|
||||
@@ -173,19 +173,17 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
? Icon(LucideIcons.check, size: 16, color: textColor)
|
||||
: Text(
|
||||
number,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -204,14 +202,13 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
Center(
|
||||
child: Text(
|
||||
'创建账号',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 18,
|
||||
style: AppTextStyles.displaySmall(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 48),
|
||||
SizedBox(height: AppSpacing.xxl),
|
||||
|
||||
// 用户名
|
||||
TextFormField(
|
||||
@@ -228,7 +225,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
|
||||
// 密码
|
||||
TextFormField(
|
||||
@@ -252,7 +249,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
|
||||
// 确认密码
|
||||
TextFormField(
|
||||
@@ -276,7 +273,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
return null;
|
||||
},
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
|
||||
// 推广码(可选)
|
||||
TextFormField(
|
||||
@@ -287,7 +284,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
prefixIcon: Icon(Icons.card_giftcard, color: colorScheme.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 32),
|
||||
SizedBox(height: AppSpacing.xl),
|
||||
|
||||
// 下一步按钮
|
||||
SizedBox(
|
||||
@@ -304,13 +301,13 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
showGlow: true,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
|
||||
// 登录链接
|
||||
Center(
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('已有账号?立即登录', style: TextStyle(fontSize: 14)),
|
||||
child: Text('已有账号?立即登录', style: AppTextStyles.headlineMedium(context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -334,7 +331,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
Container(
|
||||
padding: EdgeInsets.all(AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.1),
|
||||
color: colorScheme.primary.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
),
|
||||
child: Icon(
|
||||
@@ -349,17 +346,15 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
children: [
|
||||
Text(
|
||||
'身份验证',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
'上传身份证正反面完成注册',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -372,8 +367,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
// 身份证正面
|
||||
Text(
|
||||
'身份证正面(人像面)',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
@@ -391,8 +385,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
// 身份证反面
|
||||
Text(
|
||||
'身份证反面(国徽面)',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
@@ -431,9 +424,9 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
Container(
|
||||
padding: EdgeInsets.all(AppSpacing.md),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColorScheme.up.withOpacity(0.06),
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(color: AppColorScheme.up.withOpacity(0.12)),
|
||||
color: AppColorScheme.up.withValues(alpha: 0.06),
|
||||
borderRadius: AppRadius.radiusLg,
|
||||
border: Border.all(color: AppColorScheme.up.withValues(alpha: 0.12)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
@@ -442,9 +435,8 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
Expanded(
|
||||
child: Text(
|
||||
'您的身份信息将被加密存储,仅用于身份验证',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: AppColorScheme.up.withOpacity(0.8),
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: AppColorScheme.up.withValues(alpha: 0.8),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -472,16 +464,16 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
height: 140,
|
||||
decoration: BoxDecoration(
|
||||
color: hasImage
|
||||
? AppColorScheme.up.withOpacity(0.06)
|
||||
: colorScheme.surfaceContainerHigh.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
? AppColorScheme.up.withValues(alpha: 0.06)
|
||||
: colorScheme.surfaceContainerHigh.withValues(alpha: 0.3),
|
||||
borderRadius: AppRadius.radiusXl,
|
||||
border: Border.all(
|
||||
color: hasImage ? AppColorScheme.up.withOpacity(0.3) : Colors.transparent,
|
||||
color: hasImage ? AppColorScheme.up.withValues(alpha: 0.3) : AppColorScheme.darkBackground.withValues(alpha: 0),
|
||||
),
|
||||
),
|
||||
child: hasImage
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
borderRadius: AppRadius.radiusXl,
|
||||
child: Stack(
|
||||
fit: StackFit.passthrough,
|
||||
children: [
|
||||
@@ -499,7 +491,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Colors.transparent, Colors.black54],
|
||||
colors: [AppColorScheme.darkBackground.withValues(alpha: 0), AppColorScheme.darkSurfaceLowest.withValues(alpha: 0.6)],
|
||||
),
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(AppRadius.xl),
|
||||
@@ -511,10 +503,9 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
children: [
|
||||
Text(
|
||||
'$label已选择',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
@@ -530,12 +521,12 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(4),
|
||||
padding: EdgeInsets.all(AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white24,
|
||||
color: AppColorScheme.darkOnPrimary.withValues(alpha: 0.15),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(LucideIcons.x, size: 14, color: Colors.white),
|
||||
child: Icon(LucideIcons.x, size: 14, color: AppColorScheme.darkOnPrimary),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -547,7 +538,7 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
)
|
||||
: CustomPaint(
|
||||
painter: _DashedBorderPainter(
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.2),
|
||||
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.2),
|
||||
borderRadius: AppRadius.xl,
|
||||
),
|
||||
child: Column(
|
||||
@@ -556,22 +547,20 @@ class _RegisterPageState extends State<RegisterPage> {
|
||||
Icon(
|
||||
LucideIcons.camera,
|
||||
size: 28,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.5),
|
||||
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.5),
|
||||
),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
'点击上传$label',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.6),
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.6),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
'支持 JPG、PNG 格式',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.4),
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant.withValues(alpha: 0.4),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
|
||||
/// 首页顶栏 - Logo + 搜索/通知/头像
|
||||
@@ -14,19 +16,17 @@ class HeaderBar extends StatelessWidget {
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
horizontal: AppSpacing.md,
|
||||
vertical: AppSpacing.sm,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
// Logo
|
||||
Text(
|
||||
'MONISUO',
|
||||
style: GoogleFonts.inter(
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
letterSpacing: 1,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
@@ -36,14 +36,14 @@ class HeaderBar extends StatelessWidget {
|
||||
colorScheme: colorScheme,
|
||||
onTap: () {},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
// Bell button
|
||||
_IconButton(
|
||||
icon: LucideIcons.bell,
|
||||
colorScheme: colorScheme,
|
||||
onTap: () {},
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
// Avatar
|
||||
Consumer<AuthProvider>(
|
||||
builder: (context, auth, _) {
|
||||
@@ -59,10 +59,8 @@ class HeaderBar extends StatelessWidget {
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
initial,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -94,7 +92,7 @@ class _IconButton extends StatelessWidget {
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xl),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:flutter/services.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/utils/toast_utils.dart';
|
||||
@@ -170,19 +170,14 @@ class _HomePageState extends State<HomePage>
|
||||
children: [
|
||||
Text(
|
||||
'充值',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
'资产: USDT',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -289,10 +284,8 @@ class _HomePageState extends State<HomePage>
|
||||
SizedBox(width: AppSpacing.sm),
|
||||
Text(
|
||||
'充值申请成功',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -304,7 +297,7 @@ class _HomePageState extends State<HomePage>
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
Text(
|
||||
'请向以下地址转账:',
|
||||
style: TextStyle(fontSize: 12, color: colorScheme.onSurfaceVariant),
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_WalletAddressCard(address: walletAddress, network: walletNetwork),
|
||||
@@ -323,7 +316,9 @@ class _HomePageState extends State<HomePage>
|
||||
Expanded(
|
||||
child: Text(
|
||||
'转账完成后请点击"已打款"按钮确认',
|
||||
style: TextStyle(fontSize: 12, color: AppColorScheme.warning),
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: AppColorScheme.warning,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -388,15 +383,13 @@ class _HomePageState extends State<HomePage>
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(title,
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
)),
|
||||
if (message != null) ...[
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
Text(message,
|
||||
style: TextStyle(color: colorScheme.onSurfaceVariant),
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
textAlign: TextAlign.center),
|
||||
],
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
@@ -535,7 +528,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final upColor = AppColorScheme.getUpColor(isDark);
|
||||
final downColor = AppColorScheme.down;
|
||||
final downColor = AppColorScheme.getDownColor(isDark);
|
||||
final isProfit = _totalProfit >= 0;
|
||||
final todayProfit = _todayProfit;
|
||||
final isTodayProfit = (todayProfit ?? 0) >= 0;
|
||||
@@ -555,10 +548,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
children: [
|
||||
Text(
|
||||
'预估总资产(USDT)',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontSize: 12,
|
||||
),
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: widget.onDeposit,
|
||||
@@ -576,13 +566,11 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.add, size: 14, color: colorScheme.primary),
|
||||
SizedBox(width: 4),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
'充值',
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.primary,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -596,10 +584,8 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
// 总资产金额
|
||||
Text(
|
||||
displayAsset,
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 22,
|
||||
style: AppTextStyles.displaySmall(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
@@ -651,11 +637,10 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
? colorScheme.primary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
SizedBox(width: 4),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
'盈亏分析',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
style: AppTextStyles.labelMedium(context).copyWith(
|
||||
fontWeight: _calendarExpanded ? FontWeight.w600 : FontWeight.w500,
|
||||
color: _calendarExpanded
|
||||
? colorScheme.primary
|
||||
@@ -739,18 +724,15 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
children: [
|
||||
Text(
|
||||
'${_currentMonth.year}年${_currentMonth.month}月',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
if (!_isLoadingCalendar && _profitData != null)
|
||||
Text(
|
||||
'月度盈亏: ${_monthProfit >= 0 ? '+' : ''}${_monthProfit.toStringAsFixed(2)}',
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: _monthProfit >= 0 ? upColor : downColor,
|
||||
),
|
||||
@@ -787,10 +769,9 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
child: Center(
|
||||
child: Text(
|
||||
d,
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.6),
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -866,7 +847,7 @@ class _AssetCardState extends State<_AssetCard> {
|
||||
children: [
|
||||
Text(
|
||||
'$day',
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontSize: 10,
|
||||
fontWeight: isToday ? FontWeight.bold : FontWeight.w400,
|
||||
color: isToday
|
||||
@@ -969,10 +950,8 @@ class _WelfareCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'福利中心',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
@@ -980,10 +959,7 @@ class _WelfareCard extends StatelessWidget {
|
||||
totalClaimable > 0
|
||||
? '您有 $totalClaimable 个奖励待领取'
|
||||
: '首充奖励 + 推广奖励',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1007,25 +983,24 @@ class _WelfareCard extends StatelessWidget {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.red,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
color: AppColorScheme.darkError,
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
),
|
||||
child: Text(
|
||||
'$totalClaimable',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: totalClaimable > 0 ? 6 : 0),
|
||||
Text(
|
||||
'查看',
|
||||
style: TextStyle(
|
||||
color: isDark ? colorScheme.background : Colors.white,
|
||||
fontSize: 13,
|
||||
style: AppTextStyles.headlineSmall(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: isDark ? colorScheme.background : AppColorScheme.darkOnPrimary,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1055,24 +1030,23 @@ class _HoldingsSection extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'我的持仓',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {},
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: colorScheme.primary,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text('资产详情',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold, fontSize: 13)),
|
||||
const SizedBox(width: 4),
|
||||
style: AppTextStyles.headlineSmall(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
)),
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
Icon(LucideIcons.chevronRight,
|
||||
size: 16, color: colorScheme.primary),
|
||||
],
|
||||
@@ -1109,19 +1083,14 @@ class _EmptyHoldings extends StatelessWidget {
|
||||
SizedBox(height: AppSpacing.md),
|
||||
Text(
|
||||
'暂无持仓',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
'快去交易吧~',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontSize: 13,
|
||||
),
|
||||
style: AppTextStyles.bodyLarge(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1186,7 +1155,7 @@ class _HoldingItem extends StatelessWidget {
|
||||
backgroundColor: colorScheme.primary.withOpacity(0.1),
|
||||
child: Text(
|
||||
holding.coinCode.substring(0, 1),
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -1197,16 +1166,11 @@ class _HoldingItem extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(holding.coinCode,
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
)),
|
||||
Text(holding.quantity,
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontSize: 12,
|
||||
)),
|
||||
style: AppTextStyles.bodyMedium(context)),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -1215,18 +1179,14 @@ class _HoldingItem extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Text('${holding.currentValue} USDT',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface,
|
||||
style: AppTextStyles.headlineSmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 13,
|
||||
)),
|
||||
Text(holding.formattedProfitRate,
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.numberSmall(context).copyWith(
|
||||
color: holding.isProfit
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.down,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
: AppColorScheme.getDownColor(isDark),
|
||||
)),
|
||||
],
|
||||
),
|
||||
@@ -1252,15 +1212,11 @@ class _InfoRow extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
)),
|
||||
style: AppTextStyles.bodyMedium(context)),
|
||||
Text(value,
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontWeight: isBold ? FontWeight.bold : FontWeight.normal,
|
||||
color: colorScheme.onSurface,
|
||||
fontFeatures: isBold ? const [FontFeature.tabularFigures()] : null,
|
||||
)),
|
||||
],
|
||||
);
|
||||
@@ -1293,10 +1249,8 @@ class _WalletAddressCard extends StatelessWidget {
|
||||
Expanded(
|
||||
child: Text(
|
||||
address,
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1320,10 +1274,7 @@ class _WalletAddressCard extends StatelessWidget {
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
'网络: $network',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -1380,10 +1331,9 @@ class _ProfitStatCard extends StatelessWidget {
|
||||
SizedBox(width: 3),
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: color.withOpacity(0.8),
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: color.withOpacity(0.8),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -1393,8 +1343,7 @@ class _ProfitStatCard extends StatelessWidget {
|
||||
hasValue
|
||||
? '${isProfit ? '+' : ''}${value!.toStringAsFixed(2)}'
|
||||
: '--',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.numberMedium(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: color,
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
|
||||
@@ -17,29 +17,22 @@ class HotCoinsSection extends StatelessWidget {
|
||||
children: [
|
||||
// Title row
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
'热门币种',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
Text(
|
||||
'更多',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
// Card
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
@@ -125,10 +118,10 @@ class _CoinRow extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final changeColor = isUp
|
||||
? AppColorScheme.getUpColor(isDark)
|
||||
: AppColorScheme.down;
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 16),
|
||||
padding: const EdgeInsets.symmetric(vertical: 14, horizontal: AppSpacing.md),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -140,31 +133,26 @@ class _CoinRow extends StatelessWidget {
|
||||
backgroundColor: colorScheme.primary.withValues(alpha: 0.1),
|
||||
child: Text(
|
||||
symbol,
|
||||
style: GoogleFonts.inter(
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const SizedBox(width: AppSpacing.sm + AppSpacing.xs),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
pair,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
fullName,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -176,17 +164,11 @@ class _CoinRow extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
price,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.numberMedium(context),
|
||||
),
|
||||
Text(
|
||||
change,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: AppTextStyles.labelMedium(context).copyWith(
|
||||
color: changeColor,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
|
||||
/// 首页快捷操作栏 - 充值/提现/划转/盈亏/账单
|
||||
@@ -25,7 +25,7 @@ class QuickActionsRow extends StatelessWidget {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 8),
|
||||
padding: const EdgeInsets.symmetric(vertical: AppSpacing.md, horizontal: AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainer,
|
||||
border: Border.all(
|
||||
@@ -99,7 +99,7 @@ class _ActionItem extends StatelessWidget {
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
@@ -108,14 +108,10 @@ class _ActionItem extends StatelessWidget {
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: AppSpacing.xs + 2),
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.labelMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../providers/market_provider.dart';
|
||||
import '../home/home_page.dart';
|
||||
@@ -148,7 +150,7 @@ class _BottomNavBar extends StatelessWidget {
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(AppRadius.xxl + AppSpacing.sm)),
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -196,8 +198,8 @@ class _NavItemWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm),
|
||||
decoration: isSelected
|
||||
? BoxDecoration(
|
||||
color: colorScheme.primary.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(AppSpacing.md),
|
||||
color: colorScheme.primary.withValues(alpha: 0.1),
|
||||
borderRadius: AppRadius.radiusMd,
|
||||
)
|
||||
: null,
|
||||
child: Column(
|
||||
@@ -211,9 +213,8 @@ class _NavItemWidget extends StatelessWidget {
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Text(
|
||||
item.label,
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: color,
|
||||
fontSize: 12,
|
||||
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,10 +2,9 @@ import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_spacing.dart' show AppRadius;
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../data/models/coin.dart';
|
||||
import '../../../providers/market_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
@@ -55,20 +54,21 @@ class _MarketPageState extends State<MarketPage>
|
||||
backgroundColor: colorScheme.surfaceContainerHighest,
|
||||
child: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.only(top: 16, left: 16, right: 16, bottom: 32),
|
||||
padding: const EdgeInsets.only(
|
||||
top: AppSpacing.md,
|
||||
left: AppSpacing.md,
|
||||
right: AppSpacing.md,
|
||||
bottom: AppSpacing.xl,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 页面标题 "行情"
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 0, bottom: 8),
|
||||
padding: const EdgeInsets.only(bottom: AppSpacing.sm),
|
||||
child: Text(
|
||||
'行情',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.displaySmall(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
@@ -103,7 +103,7 @@ class _MarketPageState extends State<MarketPage>
|
||||
Expanded(child: _FeaturedCard(coin: btc))
|
||||
else
|
||||
const Expanded(child: SizedBox.shrink()),
|
||||
const SizedBox(width: 12),
|
||||
const SizedBox(width: AppSpacing.sm + AppSpacing.xs),
|
||||
if (eth != null)
|
||||
Expanded(child: _FeaturedCard(coin: eth))
|
||||
else
|
||||
@@ -121,17 +121,11 @@ class _MarketPageState extends State<MarketPage>
|
||||
children: [
|
||||
Text(
|
||||
'全部币种',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
Text(
|
||||
'更多 >',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -157,7 +151,7 @@ class _MarketPageState extends State<MarketPage>
|
||||
color: colorScheme.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
border: Border.all(
|
||||
color: colorScheme.outlineVariant.withOpacity(0.15),
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.15),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
@@ -168,9 +162,9 @@ class _MarketPageState extends State<MarketPage>
|
||||
separatorBuilder: (_, __) => Divider(
|
||||
height: 1,
|
||||
thickness: 1,
|
||||
color: colorScheme.outlineVariant.withOpacity(0.5 * 0.15),
|
||||
indent: 16,
|
||||
endIndent: 16,
|
||||
color: colorScheme.outlineVariant.withValues(alpha: 0.5 * 0.15),
|
||||
indent: AppSpacing.md,
|
||||
endIndent: AppSpacing.md,
|
||||
),
|
||||
itemBuilder: (context, index) => _CoinRow(coin: coins[index]),
|
||||
),
|
||||
@@ -223,7 +217,7 @@ class _FeaturedCard extends StatelessWidget {
|
||||
: AppColorScheme.getDownBackgroundColor(isDark);
|
||||
|
||||
return GlassPanel(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
height: 130,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -235,23 +229,17 @@ class _FeaturedCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'${coin.code}/USDT',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineMedium(context),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xs + 2, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: changeBgColor,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Text(
|
||||
coin.formattedChange,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
style: AppTextStyles.labelSmall(context).copyWith(
|
||||
color: changeColor,
|
||||
),
|
||||
),
|
||||
@@ -261,18 +249,12 @@ class _FeaturedCard extends StatelessWidget {
|
||||
// 第二行:价格
|
||||
Text(
|
||||
'\$${_formatFeaturedPrice(coin)}',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.displayMedium(context),
|
||||
),
|
||||
// 第三行:币种全名
|
||||
Text(
|
||||
coin.name,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -338,7 +320,7 @@ class _MiniBarChart extends StatelessWidget {
|
||||
height: h,
|
||||
decoration: BoxDecoration(
|
||||
color: barColor,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
borderRadius: BorderRadius.circular(AppRadius.xs),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -376,12 +358,12 @@ class _CoinRow extends StatelessWidget {
|
||||
onTap: () => _navigateToTrade(context),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: 14),
|
||||
child: Row(
|
||||
children: [
|
||||
// 头像:圆形字母头像
|
||||
_CoinAvatar(letter: coin.displayIcon, code: coin.code),
|
||||
const SizedBox(width: 10),
|
||||
const SizedBox(width: AppSpacing.sm + AppSpacing.xs),
|
||||
// 币种信息:交易对 + 全名
|
||||
Expanded(
|
||||
child: Column(
|
||||
@@ -390,20 +372,12 @@ class _CoinRow extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'${coin.code}/USDT',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.numberMedium(context),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
coin.name,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -415,24 +389,18 @@ class _CoinRow extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'\$${coin.formattedPrice}',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.numberMedium(context),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.xs + 2, vertical: 2),
|
||||
decoration: BoxDecoration(
|
||||
color: changeBgColor,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Text(
|
||||
coin.formattedChange,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: AppTextStyles.labelMedium(context).copyWith(
|
||||
color: changeColor,
|
||||
),
|
||||
),
|
||||
@@ -464,7 +432,7 @@ class _CoinAvatar extends StatelessWidget {
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
// 从 .pen 设计中的 accent-light 和 accent-primary
|
||||
final bgColor = colorScheme.primary.withOpacity(isDark ? 0.15 : 0.1);
|
||||
final bgColor = colorScheme.primary.withValues(alpha: isDark ? 0.15 : 0.1);
|
||||
final textColor = colorScheme.primary;
|
||||
|
||||
return Container(
|
||||
@@ -477,8 +445,7 @@ class _CoinAvatar extends StatelessWidget {
|
||||
child: Center(
|
||||
child: Text(
|
||||
_getLetter(),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: textColor,
|
||||
),
|
||||
@@ -518,7 +485,7 @@ class _EmptyState extends StatelessWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(icon, size: 48, color: colorScheme.onSurfaceVariant),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
Text(
|
||||
message,
|
||||
style: TextStyle(color: colorScheme.onSurfaceVariant),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import 'avatar_circle.dart';
|
||||
|
||||
/// 用户资料卡片 - 头像 + 用户名 + 徽章 + chevron
|
||||
@@ -42,11 +42,7 @@ class ProfileCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
user?.username ?? '未登录',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
|
||||
@@ -3,10 +3,10 @@ import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
import '../../components/glass_panel.dart';
|
||||
import '../../components/neon_glow.dart';
|
||||
@@ -61,14 +61,11 @@ class _KycPageState extends State<KycPage> {
|
||||
return Scaffold(
|
||||
backgroundColor: colorScheme.background,
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: colorScheme.surface.withOpacity(0.0),
|
||||
elevation: 0,
|
||||
title: Text(
|
||||
'实名认证',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(LucideIcons.chevronLeft, color: colorScheme.onSurface),
|
||||
@@ -111,19 +108,12 @@ class _KycPageState extends State<KycPage> {
|
||||
children: [
|
||||
Text(
|
||||
'身份验证',
|
||||
style: GoogleFonts.spaceGrotesk(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
'上传身份证正反面完成实名认证',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -134,11 +124,7 @@ class _KycPageState extends State<KycPage> {
|
||||
// 身份证正面上传区
|
||||
Text(
|
||||
'身份证正面(人像面)',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineSmall(context),
|
||||
),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_buildUploadZone(
|
||||
@@ -153,11 +139,7 @@ class _KycPageState extends State<KycPage> {
|
||||
// 身份证反面上传区
|
||||
Text(
|
||||
'身份证反面(国徽面)',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineSmall(context),
|
||||
),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
_buildUploadZone(
|
||||
@@ -206,8 +188,7 @@ class _KycPageState extends State<KycPage> {
|
||||
Expanded(
|
||||
child: Text(
|
||||
'您的身份信息将被加密存储,仅用于身份验证',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: AppColorScheme.up.withOpacity(0.8),
|
||||
),
|
||||
),
|
||||
@@ -266,10 +247,10 @@ class _KycPageState extends State<KycPage> {
|
||||
|
||||
if (isDone || isComplete) {
|
||||
circleColor = AppColorScheme.up;
|
||||
textColor = Colors.white;
|
||||
textColor = colorScheme.onPrimary;
|
||||
} else if (isActive) {
|
||||
circleColor = colorScheme.primary;
|
||||
textColor = Colors.white;
|
||||
textColor = colorScheme.onPrimary;
|
||||
} else {
|
||||
circleColor = colorScheme.surfaceContainerHigh;
|
||||
textColor = colorScheme.onSurfaceVariant;
|
||||
@@ -289,9 +270,7 @@ class _KycPageState extends State<KycPage> {
|
||||
? Icon(LucideIcons.check, size: 16, color: textColor)
|
||||
: Text(
|
||||
number,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
@@ -300,10 +279,7 @@ class _KycPageState extends State<KycPage> {
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -332,7 +308,7 @@ class _KycPageState extends State<KycPage> {
|
||||
border: Border.all(
|
||||
color: hasImage
|
||||
? AppColorScheme.up.withOpacity(0.3)
|
||||
: Colors.transparent,
|
||||
: colorScheme.surface.withOpacity(0.0),
|
||||
),
|
||||
),
|
||||
child: hasImage
|
||||
@@ -359,8 +335,8 @@ class _KycPageState extends State<KycPage> {
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.transparent,
|
||||
Colors.black54,
|
||||
const Color(0x00000000),
|
||||
const Color(0x8A000000),
|
||||
],
|
||||
),
|
||||
borderRadius: BorderRadius.only(
|
||||
@@ -373,10 +349,8 @@ class _KycPageState extends State<KycPage> {
|
||||
children: [
|
||||
Text(
|
||||
'$label已选择',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white,
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.onPrimary,
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
@@ -394,13 +368,13 @@ class _KycPageState extends State<KycPage> {
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white24,
|
||||
color: colorScheme.onSurface.withOpacity(0.24),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
LucideIcons.x,
|
||||
size: 14,
|
||||
color: Colors.white,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -427,16 +401,14 @@ class _KycPageState extends State<KycPage> {
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
Text(
|
||||
'点击上传$label',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'支持 JPG、PNG 格式',
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.4),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../providers/auth_provider.dart';
|
||||
import '../auth/login_page.dart';
|
||||
import 'components/about_dialog_helpers.dart';
|
||||
@@ -57,9 +57,7 @@ class _MinePageState extends State<MinePage>
|
||||
SizedBox(height: AppSpacing.md),
|
||||
Text(
|
||||
'System Build v1.0.0',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.5),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/utils/toast_utils.dart';
|
||||
import '../../../core/event/app_event_bus.dart';
|
||||
import '../../../data/services/bonus_service.dart';
|
||||
@@ -63,35 +63,19 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
|
||||
/// 文字静默色 ($text-muted)
|
||||
Color get _textMuted =>
|
||||
_isDark ? const Color(0xFF64748B) : const Color(0xFF94A3B8);
|
||||
_isDark ? AppColorScheme.darkOnSurfaceMuted : AppColorScheme.lightOnSurfaceMuted;
|
||||
|
||||
/// 第三级背景色 ($bg-tertiary)
|
||||
Color get _bgTertiary =>
|
||||
_isDark ? AppColorScheme.darkSurfaceContainerHigh : const Color(0xFFF1F5F9);
|
||||
_isDark ? AppColorScheme.darkSurfaceContainerHigh : AppColorScheme.lightSurfaceContainer;
|
||||
|
||||
/// 卡片表面色 ($surface-card)
|
||||
Color get _surfaceCard =>
|
||||
_isDark ? AppColorScheme.darkSurfaceContainer : Colors.white;
|
||||
_isDark ? AppColorScheme.darkSurfaceContainer : AppColorScheme.lightSurfaceLowest;
|
||||
|
||||
/// 反色文字 ($text-inverse)
|
||||
Color get _textInverse =>
|
||||
_isDark ? const Color(0xFF0F172A) : Colors.white;
|
||||
|
||||
// ============================================
|
||||
// 文本样式辅助
|
||||
// ============================================
|
||||
|
||||
TextStyle _inter({
|
||||
required double fontSize,
|
||||
required FontWeight fontWeight,
|
||||
required Color color,
|
||||
}) {
|
||||
return GoogleFonts.inter(
|
||||
fontSize: fontSize,
|
||||
fontWeight: fontWeight,
|
||||
color: color,
|
||||
);
|
||||
}
|
||||
_isDark ? AppColorScheme.darkInverseSurface : AppColorScheme.lightSurfaceLowest;
|
||||
|
||||
// ============================================
|
||||
// 容器样式辅助
|
||||
@@ -138,7 +122,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: _inter(fontSize: 11, fontWeight: FontWeight.w600, color: textColor),
|
||||
style: AppTextStyles.labelSmall(context).copyWith(color: textColor),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -169,7 +153,10 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
),
|
||||
child: Text(
|
||||
text,
|
||||
style: _inter(fontSize: 14, fontWeight: FontWeight.w700, color: foregroundColor),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: foregroundColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -182,22 +169,18 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
return Scaffold(
|
||||
backgroundColor: _isDark
|
||||
? AppColorScheme.darkBackground
|
||||
: const Color(0xFFF8FAFC),
|
||||
: AppColorScheme.lightBackground,
|
||||
appBar: AppBar(
|
||||
backgroundColor: _isDark
|
||||
? AppColorScheme.darkBackground
|
||||
: Colors.white,
|
||||
: AppColorScheme.lightSurfaceLowest,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
centerTitle: false,
|
||||
titleSpacing: 0,
|
||||
title: Text(
|
||||
'福利中心',
|
||||
style: _inter(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(LucideIcons.arrowLeft, color: colorScheme.onSurface, size: 24),
|
||||
@@ -256,10 +239,8 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
'我的邀请码',
|
||||
style: _inter(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -267,11 +248,11 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
referralCode.isEmpty ? '暂无邀请码' : referralCode,
|
||||
style: _inter(
|
||||
fontSize: 24,
|
||||
style: AppTextStyles.displayMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w800,
|
||||
color: _goldAccent,
|
||||
).copyWith(letterSpacing: 2),
|
||||
letterSpacing: 2,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SizedBox(
|
||||
@@ -295,7 +276,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
),
|
||||
child: Text(
|
||||
'复制邀请码',
|
||||
style: _inter(fontSize: 14, fontWeight: FontWeight.w600, color: _textInverse),
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(color: _textInverse),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -355,10 +336,8 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
children: [
|
||||
Text(
|
||||
'新人福利',
|
||||
style: _inter(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
if (showAvailableBadge)
|
||||
@@ -368,8 +347,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
'+100 USDT',
|
||||
style: _inter(
|
||||
fontSize: 28,
|
||||
style: AppTextStyles.displayLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w800,
|
||||
color: claimed ? colorScheme.onSurfaceVariant : _profitGreen,
|
||||
),
|
||||
@@ -377,9 +355,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
description,
|
||||
style: _inter(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -387,7 +363,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
_fullWidthButton(
|
||||
text: buttonText,
|
||||
backgroundColor: _profitGreen,
|
||||
foregroundColor: Colors.white,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
onPressed: canClaim ? () => _claimNewUserBonus() : null,
|
||||
),
|
||||
],
|
||||
@@ -410,18 +386,12 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
// Section Header
|
||||
Text(
|
||||
'推广奖励',
|
||||
style: _inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'每邀请一位好友充值达标,奖励100 USDT',
|
||||
style: _inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: _textMuted,
|
||||
),
|
||||
),
|
||||
@@ -454,9 +424,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'暂无推广用户',
|
||||
style: _inter(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -505,12 +473,12 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
username,
|
||||
style: _inter(fontSize: 13, fontWeight: FontWeight.w500, color: colorScheme.onSurface),
|
||||
style: AppTextStyles.headlineSmall(context),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(
|
||||
'充值: \u00A5$totalDeposit',
|
||||
style: _inter(fontSize: 11, fontWeight: FontWeight.normal, color: colorScheme.onSurfaceVariant),
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -557,9 +525,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
child: Center(
|
||||
child: Text(
|
||||
username.isNotEmpty ? username[0].toUpperCase() : '?',
|
||||
style: _inter(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: AppTextStyles.headlineSmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -612,7 +578,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
}
|
||||
return Text(
|
||||
'待达标',
|
||||
style: _inter(fontSize: 12, fontWeight: FontWeight.w500, color: _textMuted),
|
||||
style: AppTextStyles.labelLarge(context).copyWith(color: _textMuted),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -635,11 +601,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
children: [
|
||||
Text(
|
||||
'奖励规则',
|
||||
style: _inter(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineSmall(context),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_buildRuleItem('新用户注册完成实名认证奖励 100 USDT'),
|
||||
@@ -658,9 +620,7 @@ class _WelfareCenterPageState extends State<WelfareCenterPage> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 3),
|
||||
child: Text(
|
||||
'\u2022 $text',
|
||||
style: _inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: ruleTextColor,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/storage/local_storage.dart';
|
||||
|
||||
/// 引导页数据模型
|
||||
@@ -39,25 +41,25 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
title: '实时行情',
|
||||
description: '全球市场行情实时更新,把握每一个投资机会',
|
||||
imagePath: 'assets/images/onboarding_1.png', // 替换为你的图片
|
||||
gradientColors: [Color(0xFF6366F1), Color(0xFF8B5CF6)],
|
||||
gradientColors: [AppColorScheme.darkPrimary, AppColorScheme.darkPrimaryContainer],
|
||||
),
|
||||
_OnboardingItem(
|
||||
title: '模拟交易',
|
||||
description: '零风险体验真实交易,学习投资策略',
|
||||
imagePath: 'assets/images/onboarding_2.png', // 替换为你的图片
|
||||
gradientColors: [Color(0xFF10B981), Color(0xFF059669)],
|
||||
gradientColors: [AppColorScheme.darkTertiary, AppColorScheme.darkTertiaryContainer],
|
||||
),
|
||||
_OnboardingItem(
|
||||
title: '资产管理',
|
||||
description: '清晰的资产概览,轻松管理你的投资组合',
|
||||
imagePath: 'assets/images/onboarding_3.png', // 替换为你的图片
|
||||
gradientColors: [Color(0xFFF59E0B), Color(0xFFD97706)],
|
||||
gradientColors: [AppColorScheme.darkSecondary, AppColorScheme.darkSecondaryFixed],
|
||||
),
|
||||
_OnboardingItem(
|
||||
title: '安全可靠',
|
||||
description: '数据加密存储,保护你的隐私安全',
|
||||
imagePath: 'assets/images/onboarding_4.png', // 替换为你的图片
|
||||
gradientColors: [Color(0xFFEC4899), Color(0xFFBE185D)],
|
||||
gradientColors: [AppColorScheme.darkPrimaryFixed, AppColorScheme.darkPrimaryFixedDim],
|
||||
),
|
||||
];
|
||||
|
||||
@@ -110,9 +112,8 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
onPressed: _skip,
|
||||
child: Text(
|
||||
'跳过',
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -169,8 +170,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
),
|
||||
child: Text(
|
||||
_currentPage == _items.length - 1 ? '开始使用' : '下一步',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
@@ -225,7 +225,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
return Icon(
|
||||
item.icon ?? LucideIcons.image,
|
||||
size: 72,
|
||||
color: Colors.white,
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -233,7 +233,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
: Icon(
|
||||
item.icon ?? LucideIcons.star,
|
||||
size: 72,
|
||||
color: Colors.white,
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -241,8 +241,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
// 标题
|
||||
Text(
|
||||
item.title,
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
style: AppTextStyles.displaySmall(context).copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
letterSpacing: -0.5,
|
||||
@@ -253,8 +252,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
Text(
|
||||
item.description,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
height: 1.6,
|
||||
),
|
||||
@@ -275,7 +273,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? colorScheme.primary : colorScheme.outlineVariant,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../data/models/order_models.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
|
||||
@@ -97,20 +98,20 @@ class _FundOrderCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'${isDeposit ? '+' : '-'}${order.amount} USDT',
|
||||
style: theme.textTheme.large.copyWith(
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: statusColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm - AppSpacing.xs, vertical: AppSpacing.xs / 2),
|
||||
decoration: BoxDecoration(
|
||||
color: statusColor.withOpacity(0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
color: statusColor.withValues(alpha: 0.1),
|
||||
borderRadius: AppRadius.radiusMd,
|
||||
),
|
||||
child: Text(
|
||||
_getStatusText(order.status, isDeposit),
|
||||
style: theme.textTheme.small.copyWith(color: statusColor),
|
||||
style: AppTextStyles.labelMedium(context).copyWith(color: statusColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -119,32 +120,32 @@ class _FundOrderCard extends StatelessWidget {
|
||||
if (!isDeposit && order.fee != null) ...[
|
||||
Row(
|
||||
children: [
|
||||
Text('手续费(10%): ', style: theme.textTheme.muted),
|
||||
Text('-${order.fee} USDT', style: theme.textTheme.small),
|
||||
Text('手续费(10%): ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)),
|
||||
Text('-${order.fee} USDT', style: AppTextStyles.bodyMedium(context)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Row(
|
||||
children: [
|
||||
Text('应付款: ', style: theme.textTheme.muted),
|
||||
Text('${order.receivableAmount ?? "0"} USDT', style: theme.textTheme.small.copyWith(fontWeight: FontWeight.bold)),
|
||||
Text('应付款: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)),
|
||||
Text('${order.receivableAmount ?? "0"} USDT', style: AppTextStyles.bodyMedium(context).copyWith(fontWeight: FontWeight.w700)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
],
|
||||
Row(
|
||||
children: [
|
||||
Text('订单号: ', style: theme.textTheme.muted),
|
||||
Text(order.orderNo, style: theme.textTheme.small),
|
||||
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: theme.textTheme.muted),
|
||||
Text('创建时间: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)),
|
||||
Text(
|
||||
order.createTime?.toString() ?? '无',
|
||||
style: theme.textTheme.small,
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -152,11 +153,11 @@ class _FundOrderCard extends StatelessWidget {
|
||||
SizedBox(height: AppSpacing.xs),
|
||||
Row(
|
||||
children: [
|
||||
Text('驳回原因: ', style: theme.textTheme.muted),
|
||||
Text('驳回原因: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)),
|
||||
Expanded(
|
||||
child: Text(
|
||||
order.rejectReason!,
|
||||
style: theme.textTheme.small.copyWith(color: AppColorScheme.error),
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(color: AppColorScheme.error),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -192,7 +193,7 @@ class _FundOrderCard extends StatelessWidget {
|
||||
if (context.mounted) {
|
||||
if (response.success) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: const Text('已确认打款,请等待审核')),
|
||||
const SnackBar(content: Text('已确认打款,请等待审核')),
|
||||
);
|
||||
context.read<AssetProvider>().loadFundOrders();
|
||||
} else {
|
||||
@@ -208,7 +209,7 @@ class _FundOrderCard extends StatelessWidget {
|
||||
if (context.mounted) {
|
||||
if (response.success) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: const Text('订单已取消')),
|
||||
const SnackBar(content: Text('订单已取消')),
|
||||
);
|
||||
context.read<AssetProvider>().loadFundOrders();
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import '../../../data/models/order_models.dart';
|
||||
import 'fund_order_card.dart';
|
||||
@@ -86,34 +88,36 @@ class _FundOrderCardContent extends StatelessWidget {
|
||||
|
||||
const _FundOrderCardContent({required this.order});
|
||||
|
||||
bool get _isDark => true; // 默认深色
|
||||
|
||||
Color _getStatusColor(int status, bool isDeposit) {
|
||||
if (isDeposit) {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return const Color(0xFFFF9800);
|
||||
return AppColorScheme.warning;
|
||||
case 2:
|
||||
return const Color(0xFF2196F3);
|
||||
return AppColorScheme.info;
|
||||
case 3:
|
||||
return const Color(0xFFafffd1);
|
||||
return AppColorScheme.success;
|
||||
case 4:
|
||||
return const Color(0xFFff716c);
|
||||
return AppColorScheme.error;
|
||||
case 5:
|
||||
return const Color(0xFFa9abb3);
|
||||
return AppColorScheme.muted;
|
||||
default:
|
||||
return const Color(0xFFa9abb3);
|
||||
return AppColorScheme.muted;
|
||||
}
|
||||
} else {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return const Color(0xFFFF9800);
|
||||
return AppColorScheme.warning;
|
||||
case 2:
|
||||
return const Color(0xFFafffd1);
|
||||
return AppColorScheme.success;
|
||||
case 3:
|
||||
return const Color(0xFFff716c);
|
||||
return AppColorScheme.error;
|
||||
case 4:
|
||||
return const Color(0xFFa9abb3);
|
||||
return AppColorScheme.muted;
|
||||
default:
|
||||
return const Color(0xFFa9abb3);
|
||||
return AppColorScheme.muted;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,6 +159,8 @@ class _FundOrderCardContent extends StatelessWidget {
|
||||
final theme = ShadTheme.of(context);
|
||||
final isDeposit = order.type == 1;
|
||||
final statusColor = _getStatusColor(order.status, isDeposit);
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final onPrimaryColor = isDark ? AppColorScheme.darkOnSurface : AppColorScheme.lightOnSurface;
|
||||
|
||||
return ShadCard(
|
||||
padding: AppSpacing.cardPadding,
|
||||
@@ -166,20 +172,20 @@ class _FundOrderCardContent extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
'${isDeposit ? '+' : '-'}${order.amount} USDT',
|
||||
style: theme.textTheme.large.copyWith(
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: statusColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm - AppSpacing.xs, vertical: AppSpacing.xs / 2),
|
||||
decoration: BoxDecoration(
|
||||
color: statusColor.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderRadius: AppRadius.radiusMd,
|
||||
),
|
||||
child: Text(
|
||||
_getStatusText(order.status, isDeposit),
|
||||
style: theme.textTheme.small.copyWith(color: statusColor),
|
||||
style: AppTextStyles.labelMedium(context).copyWith(color: statusColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -187,17 +193,17 @@ class _FundOrderCardContent extends StatelessWidget {
|
||||
SizedBox(height: AppSpacing.sm),
|
||||
Row(
|
||||
children: [
|
||||
Text('订单号: ', style: theme.textTheme.muted),
|
||||
Text(order.orderNo, style: theme.textTheme.small),
|
||||
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: theme.textTheme.muted),
|
||||
Text('创建时间: ', style: AppTextStyles.bodyMedium(context).copyWith(color: theme.colorScheme.mutedForeground)),
|
||||
Text(
|
||||
order.createTime?.toString() ?? '无',
|
||||
style: theme.textTheme.small,
|
||||
style: AppTextStyles.bodyMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -206,4 +212,3 @@ class _FundOrderCardContent extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../core/utils/toast_utils.dart';
|
||||
import '../../../core/event/app_event_bus.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
@@ -60,14 +60,6 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
/// 一次性获取所有主题感知颜色
|
||||
_OrderColors get _colors => _OrderColors(_isDark);
|
||||
|
||||
TextStyle _inter({
|
||||
required double fontSize,
|
||||
required FontWeight fontWeight,
|
||||
required Color color,
|
||||
}) {
|
||||
return GoogleFonts.inter(fontSize: fontSize, fontWeight: fontWeight, color: color);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 构建 UI
|
||||
// ============================================
|
||||
@@ -83,7 +75,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
icon: const Icon(LucideIcons.arrowLeft, size: 20),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
title: Text('充提记录', style: _inter(fontSize: 16, fontWeight: FontWeight.w600, color: c.primaryText)),
|
||||
title: Text('充提记录', style: AppTextStyles.headlineLarge(context).copyWith(color: c.primaryText)),
|
||||
backgroundColor: c.background,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
@@ -108,7 +100,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.all(3),
|
||||
padding: const EdgeInsets.all(AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: c.tabBg,
|
||||
borderRadius: AppRadius.radiusMd,
|
||||
@@ -138,17 +130,15 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: isActive ? c.activeTabBg : Colors.transparent,
|
||||
color: isActive ? c.activeTabBg : AppColorScheme.darkSurfaceLowest.withValues(alpha: 0),
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
label,
|
||||
style: _inter(
|
||||
fontSize: 14,
|
||||
fontWeight: isActive ? FontWeight.w600 : FontWeight.w500,
|
||||
color: isActive ? c.activeTabText : c.inactiveTabText,
|
||||
),
|
||||
style: isActive
|
||||
? AppTextStyles.headlineMedium(context).copyWith(color: c.activeTabText)
|
||||
: AppTextStyles.headlineSmall(context).copyWith(color: c.inactiveTabText),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -177,8 +167,8 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(LucideIcons.inbox, size: 64, color: c.mutedText),
|
||||
const SizedBox(height: 16),
|
||||
Text('暂无订单记录', style: _inter(fontSize: 14, fontWeight: FontWeight.normal, color: c.secondaryText)),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
Text('暂无订单记录', style: AppTextStyles.headlineMedium(context).copyWith(color: c.secondaryText)),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -187,9 +177,9 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async => _loadData(),
|
||||
child: ListView.separated(
|
||||
padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
|
||||
padding: const EdgeInsets.fromLTRB(AppSpacing.md, AppSpacing.md, AppSpacing.md, AppSpacing.xl),
|
||||
itemCount: orders.length,
|
||||
separatorBuilder: (_, __) => const SizedBox(height: 12),
|
||||
separatorBuilder: (_, __) => const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
itemBuilder: (context, index) {
|
||||
return _buildOrderCard(orders[index]);
|
||||
},
|
||||
@@ -206,7 +196,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
final c = _colors;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
padding: AppSpacing.cardPadding,
|
||||
decoration: BoxDecoration(
|
||||
color: c.cardBg,
|
||||
borderRadius: AppRadius.radiusLg,
|
||||
@@ -216,20 +206,20 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildCardHeader(order),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
_buildAmountRow(order),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
_buildDetailRows(order),
|
||||
if (order.rejectReason != null) ...[
|
||||
const SizedBox(height: 8),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
_buildRejectionReason(order),
|
||||
],
|
||||
if (order.receivableAmount != null && !order.isDeposit) ...[
|
||||
const SizedBox(height: 8),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
_buildPayableRow(order),
|
||||
],
|
||||
if (order.canCancel || order.canConfirmPay) ...[
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: AppSpacing.sm + AppSpacing.xs),
|
||||
_buildActions(order),
|
||||
],
|
||||
],
|
||||
@@ -262,8 +252,6 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
final downColor = AppColorScheme.getDownColor(_isDark);
|
||||
final upBg = AppColorScheme.getUpBackgroundColor(_isDark, opacity: 0.12);
|
||||
final downBg = AppColorScheme.getDownBackgroundColor(_isDark, opacity: 0.12);
|
||||
const amberColor = Color(0xFFD97706);
|
||||
const amberBg = Color(0xFFFEF3C7);
|
||||
|
||||
Color bgColor;
|
||||
Color textColor;
|
||||
@@ -272,8 +260,8 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
switch (order.status) {
|
||||
case 1: // 待付款
|
||||
case 2: // 待确认
|
||||
bgColor = amberBg;
|
||||
textColor = amberColor;
|
||||
bgColor = AppColorScheme.warning.withValues(alpha: 0.12);
|
||||
textColor = AppColorScheme.warning;
|
||||
break;
|
||||
case 3: // 已完成
|
||||
bgColor = upBg;
|
||||
@@ -287,8 +275,8 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
switch (order.status) {
|
||||
case 1: // 待审批
|
||||
case 5: // 待财务审核
|
||||
bgColor = amberBg;
|
||||
textColor = amberColor;
|
||||
bgColor = AppColorScheme.warning.withValues(alpha: 0.12);
|
||||
textColor = AppColorScheme.warning;
|
||||
break;
|
||||
case 2: // 已完成
|
||||
bgColor = upBg;
|
||||
@@ -305,12 +293,12 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
|
||||
Widget _buildBadge(String text, Color textColor, Color bgColor) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm, vertical: AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
),
|
||||
child: Text(text, style: _inter(fontSize: 11, fontWeight: FontWeight.w600, color: textColor)),
|
||||
child: Text(text, style: AppTextStyles.labelSmall(context).copyWith(color: textColor)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -321,7 +309,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
final c = _colors;
|
||||
return Text(
|
||||
'${order.isDeposit ? '+' : '-'}${order.amount} USDT',
|
||||
style: _inter(fontSize: 18, fontWeight: FontWeight.w700, color: c.primaryText),
|
||||
style: AppTextStyles.displaySmall(context).copyWith(color: c.primaryText, height: 1.3),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -334,14 +322,14 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
return Column(
|
||||
children: [
|
||||
_buildDetailRow('订单号', order.orderNo, c),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
if (order.walletAddress != null) ...[
|
||||
_buildDetailRow(
|
||||
'网络',
|
||||
order.remark.isNotEmpty ? order.remark : '-',
|
||||
c,
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
_buildDetailRow(
|
||||
'地址',
|
||||
_truncateAddress(order.walletAddress!),
|
||||
@@ -354,14 +342,14 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
child: Icon(LucideIcons.copy, size: 14, color: c.mutedText),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
] else if (order.remark.isNotEmpty) ...[
|
||||
_buildDetailRow('网络', order.remark, c),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
],
|
||||
if (order.fee != null && !order.isDeposit) ...[
|
||||
_buildDetailRow('手续费', '${order.fee}%', c),
|
||||
const SizedBox(height: 6),
|
||||
const SizedBox(height: AppSpacing.sm - AppSpacing.xs),
|
||||
],
|
||||
_buildDetailRow(
|
||||
'时间',
|
||||
@@ -378,18 +366,18 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
_OrderColors c, {
|
||||
Widget? trailing,
|
||||
}) {
|
||||
final valueStyle = _inter(fontSize: 12, fontWeight: FontWeight.normal, color: c.primaryText);
|
||||
final valueStyle = AppTextStyles.bodyMedium(context).copyWith(color: c.primaryText);
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label, style: _inter(fontSize: 12, fontWeight: FontWeight.normal, color: c.mutedText)),
|
||||
Text(label, style: AppTextStyles.bodyMedium(context).copyWith(color: c.mutedText)),
|
||||
if (trailing != null)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(value, style: valueStyle),
|
||||
const SizedBox(width: 4),
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
trailing,
|
||||
],
|
||||
)
|
||||
@@ -405,7 +393,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
Widget _buildRejectionReason(OrderFund order) {
|
||||
return Text(
|
||||
'拒绝原因: ${order.rejectReason}',
|
||||
style: _inter(fontSize: 12, fontWeight: FontWeight.normal, color: AppColorScheme.getDownColor(_isDark)),
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(color: AppColorScheme.getDownColor(_isDark)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -416,7 +404,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
final c = _colors;
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.sm + AppSpacing.xs, vertical: AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: c.bgTertiary,
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
@@ -424,8 +412,8 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('应付金额', style: _inter(fontSize: 13, fontWeight: FontWeight.w500, color: c.secondaryText)),
|
||||
Text('${order.receivableAmount} USDT', style: _inter(fontSize: 13, fontWeight: FontWeight.w600, color: c.primaryText)),
|
||||
Text('应付金额', style: AppTextStyles.headlineSmall(context).copyWith(color: c.secondaryText)),
|
||||
Text('${order.receivableAmount} USDT', style: AppTextStyles.headlineMedium(context).copyWith(color: c.primaryText)),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -437,6 +425,7 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
Widget _buildActions(OrderFund order) {
|
||||
final upColor = AppColorScheme.getUpColor(_isDark);
|
||||
final downColor = AppColorScheme.getDownColor(_isDark);
|
||||
final c = _colors;
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
@@ -445,26 +434,26 @@ class _FundOrdersPageState extends State<FundOrdersPage> {
|
||||
GestureDetector(
|
||||
onTap: () => _cancelOrder(order),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
border: Border.all(color: downColor, width: 1),
|
||||
),
|
||||
child: Text('取消订单', style: _inter(fontSize: 13, fontWeight: FontWeight.w500, color: downColor)),
|
||||
child: Text('取消订单', style: AppTextStyles.headlineSmall(context).copyWith(color: downColor)),
|
||||
),
|
||||
),
|
||||
if (order.canCancel && order.canConfirmPay)
|
||||
const SizedBox(width: 12),
|
||||
const SizedBox(width: AppSpacing.sm + AppSpacing.xs),
|
||||
if (order.canConfirmPay)
|
||||
GestureDetector(
|
||||
onTap: () => _confirmPay(order),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md, vertical: AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: upColor,
|
||||
borderRadius: AppRadius.radiusSm,
|
||||
),
|
||||
child: Text('已打款', style: _inter(fontSize: 13, fontWeight: FontWeight.w500, color: Colors.white)),
|
||||
child: Text('已打款', style: AppTextStyles.headlineSmall(context).copyWith(color: c.activeTabText)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -573,7 +562,7 @@ class _OrderColors {
|
||||
: AppColorScheme.lightOnSurfaceVariant,
|
||||
mutedText = isDark ? AppColorScheme.darkOnSurfaceMuted : AppColorScheme.lightOnSurfaceMuted,
|
||||
tabBg = isDark ? AppColorScheme.darkSurfaceContainerHigh : AppColorScheme.lightSurfaceHigh,
|
||||
activeTabBg = isDark ? AppColorScheme.darkOnSurface : Colors.white,
|
||||
activeTabBg = isDark ? AppColorScheme.darkOnSurface : AppColorScheme.lightSurfaceLowest,
|
||||
activeTabText = isDark ? AppColorScheme.darkBackground : AppColorScheme.lightOnSurface,
|
||||
inactiveTabText = isDark ? AppColorScheme.darkOnSurfaceVariant : AppColorScheme.lightOnSurfaceVariant;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:shadcn_ui/shadcn_ui.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../core/theme/app_spacing.dart';
|
||||
import '../../../core/theme/app_theme.dart';
|
||||
import '../../../providers/asset_provider.dart';
|
||||
import 'fund_orders_list.dart';
|
||||
|
||||
@@ -34,6 +35,7 @@ class _OrdersPageState extends State<OrdersPage> with AutomaticKeepAliveClientMi
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final theme = ShadTheme.of(context);
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: theme.colorScheme.background,
|
||||
@@ -82,12 +84,14 @@ class TabSelector extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ShadTheme.of(context);
|
||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
||||
final onPrimaryBg = isDark ? AppColorScheme.darkBackground : AppColorScheme.lightSurfaceLowest;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.all(AppSpacing.xs),
|
||||
padding: const EdgeInsets.all(AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.card,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
borderRadius: AppRadius.radiusLg,
|
||||
),
|
||||
child: Row(
|
||||
children: tabs.asMap().entries.map((entry) {
|
||||
@@ -102,16 +106,20 @@ class TabSelector extends StatelessWidget {
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: EdgeInsets.symmetric(vertical: AppSpacing.sm + AppSpacing.xs),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? theme.colorScheme.primary : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(AppRadius.md),
|
||||
color: isSelected ? theme.colorScheme.primary : AppColorScheme.darkSurfaceLowest.withValues(alpha: 0),
|
||||
borderRadius: AppRadius.radiusMd,
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
color: isSelected ? Colors.white : theme.colorScheme.mutedForeground,
|
||||
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
|
||||
),
|
||||
style: isSelected
|
||||
? AppTextStyles.labelLarge(context).copyWith(
|
||||
color: onPrimaryBg,
|
||||
)
|
||||
: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: theme.colorScheme.mutedForeground,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -132,8 +140,6 @@ class TradeOrdersList extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ShadTheme.of(context);
|
||||
// Trade orders feature not yet implemented in provider
|
||||
// Using tradeAccounts (holdings) as placeholder for now
|
||||
|
||||
return Center(
|
||||
child: Padding(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
|
||||
/// 金额输入框组件(含超额提示)
|
||||
///
|
||||
@@ -70,17 +70,13 @@ class _AmountInputState extends State<AmountInput> {
|
||||
controller: widget.amountController,
|
||||
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
||||
onChanged: (_) => _checkLimit(),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: colorScheme.onSurface,
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
style: AppTextStyles.numberMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
hintText: '请输入金额',
|
||||
hintStyle: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
hintStyle: AppTextStyles.numberMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.5),
|
||||
),
|
||||
border: InputBorder.none,
|
||||
@@ -96,11 +92,10 @@ class _AmountInputState extends State<AmountInput> {
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.error_outline, size: 13, color: warningColor),
|
||||
SizedBox(width: 4),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text(
|
||||
'超出可用USDT余额',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: warningColor,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
|
||||
/// 币种头像组件
|
||||
///
|
||||
@@ -21,10 +22,9 @@ class CoinAvatar extends StatelessWidget {
|
||||
),
|
||||
child: Center(
|
||||
child: Text(icon ?? '?',
|
||||
style: TextStyle(
|
||||
style: AppTextStyles.displaySmall(context).copyWith(
|
||||
fontSize: 20,
|
||||
color: colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
)),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
import 'coin_avatar.dart';
|
||||
|
||||
@@ -54,18 +54,12 @@ class CoinSelector extends StatelessWidget {
|
||||
selectedCoin != null
|
||||
? '${selectedCoin!.code}/USDT'
|
||||
: '选择币种',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
selectedCoin?.name ?? '点击选择交易对',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -86,7 +80,7 @@ class CoinSelector extends StatelessWidget {
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
isScrollControlled: true,
|
||||
builder: (ctx) => Container(
|
||||
height: MediaQuery.of(ctx).size.height * 0.65,
|
||||
@@ -106,7 +100,7 @@ class CoinSelector extends StatelessWidget {
|
||||
height: 4,
|
||||
decoration: BoxDecoration(
|
||||
color: colorScheme.onSurfaceVariant.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
),
|
||||
// 标题栏
|
||||
@@ -116,11 +110,7 @@ class CoinSelector extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('选择币种',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
)),
|
||||
style: AppTextStyles.headlineLarge(context)),
|
||||
GestureDetector(
|
||||
onTap: () => Navigator.of(ctx).pop(),
|
||||
child: Icon(LucideIcons.x,
|
||||
@@ -163,7 +153,7 @@ class CoinSelector extends StatelessWidget {
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: AppSpacing.lg, vertical: AppSpacing.md),
|
||||
color:
|
||||
isSelected ? colorScheme.primary.withOpacity(0.1) : Colors.transparent,
|
||||
isSelected ? colorScheme.primary.withOpacity(0.1) : const Color(0x00000000),
|
||||
child: Row(
|
||||
children: [
|
||||
CoinAvatar(icon: coin.displayIcon),
|
||||
@@ -176,24 +166,15 @@ class CoinSelector extends StatelessWidget {
|
||||
Row(
|
||||
children: [
|
||||
Text(coin.code,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
)),
|
||||
style: AppTextStyles.headlineLarge(context)),
|
||||
SizedBox(width: AppSpacing.xs),
|
||||
Text('/USDT',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
)),
|
||||
const Spacer(),
|
||||
Text('\$${coin.formattedPrice}',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
)),
|
||||
style: AppTextStyles.numberMedium(context)),
|
||||
SizedBox(width: AppSpacing.sm),
|
||||
// 涨跌幅徽章
|
||||
Container(
|
||||
@@ -203,8 +184,7 @@ class CoinSelector extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(AppRadius.sm),
|
||||
),
|
||||
child: Text(coin.formattedChange,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
style: AppTextStyles.labelMedium(context).copyWith(
|
||||
color: changeColor,
|
||||
fontWeight: FontWeight.w600,
|
||||
)),
|
||||
@@ -219,8 +199,7 @@ class CoinSelector extends StatelessWidget {
|
||||
SizedBox(height: 3),
|
||||
// 第二行:币种名称
|
||||
Text(coin.name,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
)),
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../components/glass_panel.dart';
|
||||
import '../../../components/neon_glow.dart';
|
||||
|
||||
@@ -34,7 +34,7 @@ class ConfirmDialog extends StatelessWidget {
|
||||
: AppColorScheme.getDownColor(isDark);
|
||||
|
||||
return Dialog(
|
||||
backgroundColor: Colors.transparent,
|
||||
backgroundColor: const Color(0x00000000),
|
||||
child: GlassPanel(
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
padding: EdgeInsets.all(AppSpacing.lg),
|
||||
@@ -45,11 +45,7 @@ class ConfirmDialog extends StatelessWidget {
|
||||
Center(
|
||||
child: Text(
|
||||
'确认${isBuy ? '买入' : '卖出'}',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
style: AppTextStyles.headlineLarge(context),
|
||||
),
|
||||
),
|
||||
SizedBox(height: AppSpacing.lg),
|
||||
@@ -97,15 +93,12 @@ class ConfirmDialog extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
)),
|
||||
Text(value,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
style: AppTextStyles.numberMedium(context).copyWith(
|
||||
color: valueColor ?? colorScheme.onSurface,
|
||||
)),
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
|
||||
/// 占位卡片组件
|
||||
///
|
||||
@@ -31,9 +31,8 @@ class PlaceholderCard extends StatelessWidget {
|
||||
),
|
||||
child: Center(
|
||||
child: Text(message,
|
||||
style: GoogleFonts.inter(
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
fontSize: 14,
|
||||
)),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
|
||||
/// 价格卡片组件
|
||||
@@ -25,7 +25,7 @@ class PriceCard extends StatelessWidget {
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(AppSpacing.md + AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: isDark
|
||||
? colorScheme.surfaceContainer
|
||||
@@ -43,12 +43,7 @@ class PriceCard extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
coin.formattedPrice,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: colorScheme.onSurface,
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
),
|
||||
style: AppTextStyles.numberLarge(context).copyWith(fontSize: 32),
|
||||
),
|
||||
const SizedBox(width: AppSpacing.sm),
|
||||
// 涨跌幅徽章 - 圆角sm,涨绿背景
|
||||
@@ -61,11 +56,9 @@ class PriceCard extends StatelessWidget {
|
||||
),
|
||||
child: Text(
|
||||
coin.formattedChange,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
style: AppTextStyles.numberSmall(context).copyWith(
|
||||
color: changeColor,
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -75,11 +68,7 @@ class PriceCard extends StatelessWidget {
|
||||
// 副标题
|
||||
Text(
|
||||
'24h 变化',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
style: AppTextStyles.bodySmall(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
|
||||
/// 交易按钮组件
|
||||
///
|
||||
@@ -44,16 +44,14 @@ class TradeButton extends StatelessWidget {
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: Colors.white,
|
||||
color: AppColorScheme.darkOnPrimary,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'${isBuy ? '买入' : '卖出'} ${coinCode ?? ""}',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w700,
|
||||
style: AppTextStyles.headlineLarge(context).copyWith(
|
||||
color: enabled
|
||||
? Colors.white
|
||||
? AppColorScheme.darkOnPrimary
|
||||
: colorScheme.onSurface.withOpacity(0.3),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../../../core/theme/app_color_scheme.dart';
|
||||
import '../../../../core/theme/app_spacing.dart';
|
||||
import '../../../../core/theme/app_theme.dart';
|
||||
import '../../../../data/models/coin.dart';
|
||||
import 'amount_input.dart';
|
||||
|
||||
@@ -51,7 +51,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.all(AppSpacing.md + AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: cardBgColor,
|
||||
borderRadius: BorderRadius.circular(AppRadius.lg),
|
||||
@@ -88,11 +88,9 @@ class TradeFormCard extends StatelessWidget {
|
||||
child: Center(
|
||||
child: Text(
|
||||
'买入',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: isBuy
|
||||
? Colors.white
|
||||
? AppColorScheme.darkOnPrimary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -120,11 +118,9 @@ class TradeFormCard extends StatelessWidget {
|
||||
child: Center(
|
||||
child: Text(
|
||||
'卖出',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
style: AppTextStyles.headlineMedium(context).copyWith(
|
||||
color: !isBuy
|
||||
? Colors.white
|
||||
? AppColorScheme.darkOnPrimary
|
||||
: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -142,17 +138,11 @@ class TradeFormCard extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('交易金额',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
)),
|
||||
Text('USDT',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
)),
|
||||
style: AppTextStyles.labelLarge(context)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppSpacing.sm),
|
||||
@@ -172,9 +162,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
isBuy
|
||||
? '可用: $availableUsdt USDT'
|
||||
: '可用: $availableCoinQty ${selectedCoin?.code ?? ""}',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodySmall(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
@@ -200,19 +188,12 @@ class TradeFormCard extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('交易数量',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
style: AppTextStyles.bodyMedium(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
)),
|
||||
Text(
|
||||
'$calculatedQuantity ${selectedCoin?.code ?? ''}',
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: colorScheme.onSurface,
|
||||
fontFeatures: [FontFeature.tabularFigures()],
|
||||
),
|
||||
style: AppTextStyles.numberMedium(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -234,9 +215,7 @@ class TradeFormCard extends StatelessWidget {
|
||||
),
|
||||
child: Center(
|
||||
child: Text(label,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
style: AppTextStyles.labelLarge(context).copyWith(
|
||||
color: colorScheme.onSurfaceVariant,
|
||||
)),
|
||||
),
|
||||
|
||||
19670
pencil-new.pen
Normal file
19670
pencil-new.pen
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user