import 'package:flutter/material.dart'; import '../theme/app_colors.dart'; /// 显示 WS 原始价格字符串:整数部分加千分符,小数部分去掉尾零 /// 例: "79126.31000000" → "79,126.31" | "0.384200" → "0.3842" String formatRawPrice(String priceStr) { if (priceStr.isEmpty) return '--'; final parts = priceStr.split('.'); final intPart = parts[0].replaceAllMapped( RegExp(r'(\d)(?=(\d{3})+$)'), (m) => '${m[1]},', ); if (parts.length > 1) { final decimal = parts[1].replaceAll(RegExp(r'0+$'), ''); if (decimal.isEmpty) return intPart; return '$intPart.$decimal'; } return intPart; } /// 价格格式化 — 自动判断小数位 /// BTC: 67,234.56 | DOGE: 0.123456 String formatPrice(double price, {int? decimalPlaces}) { if (price == 0) return '0.00'; final decimals = decimalPlaces ?? _autoDecimals(price); final parts = price.toStringAsFixed(decimals).split('.'); final intPart = parts[0].replaceAllMapped( RegExp(r'(\d)(?=(\d{3})+$)'), (m) => '${m[1]},', ); return parts.length > 1 ? '$intPart.${parts[1]}' : intPart; } int _autoDecimals(double price) { if (price >= 1000) return 2; if (price >= 1) return 4; return 6; } /// 涨跌幅格式化 /// +2.34% | -1.20% | 0.00% String formatChange(double change) { final sign = change >= 0 ? '+' : ''; return '$sign${change.toStringAsFixed(2)}%'; } double _pow10(int n) { double r = 1; for (var i = 0; i < n; i++) { r *= 10; } return r; } /// 数量/金额格式化:截断到 [decimals] 位小数(不四舍五入),带千分符 String formatAmount(double v, {int decimals = 2}) { if (v == 0) return decimals > 0 ? '0.${'0' * decimals}' : '0'; final factor = _pow10(decimals); final truncated = (v * factor).truncateToDouble() / factor; final fixed = truncated.toStringAsFixed(decimals); final parts = fixed.split('.'); final intPart = parts[0].replaceAllMapped( RegExp(r'(\d)(?=(\d{3})+$)'), (m) => '${m[1]},', ); return parts.length > 1 ? '$intPart.${parts[1]}' : intPart; } /// 数量原样格式化:不截断精度,仅去除尾零 /// 0.001 → "0.001" | 1.0 → "1" | 0.10 → "0.1" String formatQuantity(double v) { if (v == v.truncateToDouble()) return v.toInt().toString(); // toStringAsFixed(8) 覆盖 8 位小数精度,再剥离尾零和多余小数点 final s = v.toStringAsFixed(8); return s.replaceAll(RegExp(r'0+$'), '').replaceAll(RegExp(r'\.$'), ''); } /// 成交量格式化(亿/万) String formatVolume(double volume) { if (volume >= 1e8) return '${(volume / 1e8).toStringAsFixed(2)}亿'; if (volume >= 1e4) return '${(volume / 1e4).toStringAsFixed(2)}万'; return volume.toStringAsFixed(2); } // ── 法币估值 ───────────────────────────────────────────────── /// 当前法币汇率(USDT → 目标法币),默认 1:1(USD) /// 后续切换法币时修改此值和符号即可全局生效 double _fiatRate = 1.0; String _fiatSymbol = '\$'; /// 设置法币汇率与符号(如 CNY: rate=7.25, symbol='¥') void setFiatCurrency({required double rate, required String symbol}) { _fiatRate = rate; _fiatSymbol = symbol; } /// 获取当前法币符号 String get fiatSymbol => _fiatSymbol; /// 获取当前法币汇率 double get fiatRate => _fiatRate; /// 将 USDT 价格转换为法币估值字符串 /// 例: formatFiatPrice(0.31478, pricePrecision: 5) → "≈$0.31478" /// 例: formatFiatPrice(465.97, pricePrecision: 2) → "≈$466" String formatFiatPrice(double usdtPrice, {int? pricePrecision}) { final fiatValue = usdtPrice * _fiatRate; final decimals = pricePrecision ?? _autoDecimals(fiatValue); return '≈$_fiatSymbol${formatPrice(fiatValue, decimalPlaces: decimals)}'; } /// 根据涨跌幅返回颜色 Color changeColor(double change, BuildContext context) { if (change > 0) return AppColors.rise; if (change < 0) return AppColors.fall; return Theme.of(context).colorScheme.onSurface.withAlpha(128); }