| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 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);
- }
|