import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/network/dio_client.dart'; import '../core/utils/number_format.dart'; import '../data/models/currency_rate.dart'; import 'app_provider.dart'; const _kCurrencyCode = 'currency_code'; const _kCurrencyRate = 'currency_rate'; const _kCurrencySymbol = 'currency_symbol'; // ── State ───────────────────────────────────────────────── class CurrencyState { final List rates; final String selectedCode; final bool isLoading; const CurrencyState({ required this.rates, required this.selectedCode, this.isLoading = false, }); CurrencyRate? get selected { if (rates.isEmpty) return null; try { return rates.firstWhere((r) => r.currency == selectedCode); } catch (_) { return rates.first; } } CurrencyState copyWith({ List? rates, String? selectedCode, bool? isLoading, }) => CurrencyState( rates: rates ?? this.rates, selectedCode: selectedCode ?? this.selectedCode, isLoading: isLoading ?? this.isLoading, ); } // ── Notifier ────────────────────────────────────────────── class CurrencyNotifier extends Notifier { @override CurrencyState build() { final prefs = ref.read(sharedPreferencesProvider); final savedCode = prefs.getString(_kCurrencyCode) ?? 'USD'; final savedRate = prefs.getDouble(_kCurrencyRate) ?? 1.0; final savedSymbol = prefs.getString(_kCurrencySymbol) ?? '\$'; // 立即应用上次保存的汇率,避免启动时显示错误 setFiatCurrency(rate: savedRate, symbol: savedSymbol); Future.microtask(_loadRates); return CurrencyState(rates: const [], selectedCode: savedCode, isLoading: true); } Future _loadRates() async { try { final dio = ref.read(dioClientProvider); final response = await dio.get>('contract/currency/rate'); final list = (response.data?['data'] as List? ?? []) .map((e) => CurrencyRate.fromJson(e as Map)) .toList(); state = state.copyWith(rates: list, isLoading: false); // 用最新汇率更新全局法币设置 final current = state.selected; if (current != null) { _applyAndPersist(current); } } catch (_) { // 接口失败时继续使用上次保存的汇率 state = state.copyWith(isLoading: false); } } void selectCurrency(CurrencyRate rate) { state = state.copyWith(selectedCode: rate.currency); _applyAndPersist(rate); } void _applyAndPersist(CurrencyRate rate) { setFiatCurrency(rate: rate.rate, symbol: rate.symbol); final prefs = ref.read(sharedPreferencesProvider); prefs.setString(_kCurrencyCode, rate.currency); prefs.setDouble(_kCurrencyRate, rate.rate); prefs.setString(_kCurrencySymbol, rate.symbol); } } // ── Provider ────────────────────────────────────────────── final currencyProvider = NotifierProvider( CurrencyNotifier.new, );