| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- 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<CurrencyRate> 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<CurrencyRate>? rates,
- String? selectedCode,
- bool? isLoading,
- }) =>
- CurrencyState(
- rates: rates ?? this.rates,
- selectedCode: selectedCode ?? this.selectedCode,
- isLoading: isLoading ?? this.isLoading,
- );
- }
- // ── Notifier ──────────────────────────────────────────────
- class CurrencyNotifier extends Notifier<CurrencyState> {
- @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<void> _loadRates() async {
- try {
- final dio = ref.read(dioClientProvider);
- final response = await dio.get<Map<String, dynamic>>('contract/currency/rate');
- final list = (response.data?['data'] as List<dynamic>? ?? [])
- .map((e) => CurrencyRate.fromJson(e as Map<String, dynamic>))
- .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, CurrencyState>(
- CurrencyNotifier.new,
- );
|