import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../domain/entities/price_info.dart'; import '../../domain/entities/market_overview.dart'; import '../../domain/entities/trading_account.dart'; import '../../domain/entities/trade_order.dart'; import '../../domain/entities/kline.dart'; import '../../domain/repositories/trading_repository.dart'; import '../../data/models/trade_order_model.dart'; import '../../core/di/injection.dart'; // Repository Provider final tradingRepositoryProvider = Provider((ref) { return getIt(); }); // 买入功能开关 Provider (2分钟缓存) final buyEnabledProvider = FutureProvider((ref) async { final repository = ref.watch(tradingRepositoryProvider); final result = await repository.getBuyEnabled(); ref.keepAlive(); final timer = Timer(const Duration(minutes: 2), () { ref.invalidateSelf(); }); ref.onDispose(() => timer.cancel()); return result.fold( (failure) => false, // 获取失败时默认关闭 (enabled) => enabled, ); }); // K线周期选择 final selectedKlinePeriodProvider = StateProvider((ref) => '1h'); // 周期字符串映射到API参数 String _periodToApiParam(String period) { const periodMap = { '1分': '1m', '5分': '5m', '15分': '15m', '30分': '30m', '1时': '1h', '4时': '4h', '日': '1d', }; return periodMap[period] ?? '1h'; } // K线数据 Provider (根据选中周期获取) final klinesProvider = FutureProvider>((ref) async { final repository = ref.watch(tradingRepositoryProvider); final selectedPeriod = ref.watch(selectedKlinePeriodProvider); final apiPeriod = _periodToApiParam(selectedPeriod); final result = await repository.getKlines(period: apiPeriod, limit: 100); ref.keepAlive(); final timer = Timer(const Duration(minutes: 1), () { ref.invalidateSelf(); }); ref.onDispose(() => timer.cancel()); return result.fold( (failure) => throw Exception(failure.message), (klines) => klines, ); }); // 当前价格 Provider (15秒缓存 - 交易页面需要快速更新) final currentPriceProvider = FutureProvider((ref) async { final repository = ref.watch(tradingRepositoryProvider); final result = await repository.getCurrentPrice(); ref.keepAlive(); final timer = Timer(const Duration(seconds: 15), () { ref.invalidateSelf(); }); ref.onDispose(() => timer.cancel()); return result.fold( (failure) => throw Exception(failure.message), (priceInfo) => priceInfo, ); }); // 市场概览 Provider (30秒缓存 - 市场数据相对稳定) final marketOverviewProvider = FutureProvider((ref) async { final repository = ref.watch(tradingRepositoryProvider); final result = await repository.getMarketOverview(); ref.keepAlive(); final timer = Timer(const Duration(seconds: 30), () { ref.invalidateSelf(); }); ref.onDispose(() => timer.cancel()); return result.fold( (failure) => throw Exception(failure.message), (overview) => overview, ); }); // 交易账户 Provider (15秒缓存 - 交易后快速更新资产) final tradingAccountProvider = FutureProvider.family( (ref, accountSequence) async { if (accountSequence.isEmpty) return null; final repository = ref.watch(tradingRepositoryProvider); final result = await repository.getTradingAccount(accountSequence); ref.keepAlive(); final timer = Timer(const Duration(seconds: 15), () { ref.invalidateSelf(); }); ref.onDispose(() => timer.cancel()); return result.fold( (failure) => throw Exception(failure.message), (account) => account, ); }, ); // 订单列表 Provider (10秒缓存 - 交易后快速看到结果) final ordersProvider = FutureProvider((ref) async { final repository = ref.watch(tradingRepositoryProvider); final result = await repository.getOrders(page: 1, pageSize: 10); ref.keepAlive(); final timer = Timer(const Duration(seconds: 10), () { ref.invalidateSelf(); }); ref.onDispose(() => timer.cancel()); return result.fold( (failure) => throw Exception(failure.message), (orders) => orders, ); }); // 交易状态 class TradingState { final bool isLoading; final String? error; final Map? lastOrderResult; TradingState({ this.isLoading = false, this.error, this.lastOrderResult, }); TradingState copyWith({ bool? isLoading, String? error, Map? lastOrderResult, }) { return TradingState( isLoading: isLoading ?? this.isLoading, error: error, lastOrderResult: lastOrderResult ?? this.lastOrderResult, ); } } class TradingNotifier extends StateNotifier { final TradingRepository repository; TradingNotifier({required this.repository}) : super(TradingState()); /// 创建买入订单 Future buyShares(String price, String quantity) async { state = state.copyWith(isLoading: true, error: null); final result = await repository.createOrder( type: 'BUY', price: price, quantity: quantity, ); return result.fold( (failure) { state = state.copyWith(isLoading: false, error: failure.message); return false; }, (orderResult) { state = state.copyWith(isLoading: false, lastOrderResult: orderResult); return true; }, ); } /// 创建卖出订单 Future sellShares(String price, String quantity) async { state = state.copyWith(isLoading: true, error: null); final result = await repository.createOrder( type: 'SELL', price: price, quantity: quantity, ); return result.fold( (failure) { state = state.copyWith(isLoading: false, error: failure.message); return false; }, (orderResult) { state = state.copyWith(isLoading: false, lastOrderResult: orderResult); return true; }, ); } /// 取消订单 Future cancelOrder(String orderNo) async { state = state.copyWith(isLoading: true, error: null); final result = await repository.cancelOrder(orderNo); return result.fold( (failure) { state = state.copyWith(isLoading: false, error: failure.message); return false; }, (_) { state = state.copyWith(isLoading: false); return true; }, ); } /// 划入积分股 Future transferIn(String amount) async { state = state.copyWith(isLoading: true, error: null); final result = await repository.transferIn(amount); return result.fold( (failure) { state = state.copyWith(isLoading: false, error: failure.message); return false; }, (_) { state = state.copyWith(isLoading: false); return true; }, ); } /// 划出积分股 Future transferOut(String amount) async { state = state.copyWith(isLoading: true, error: null); final result = await repository.transferOut(amount); return result.fold( (failure) { state = state.copyWith(isLoading: false, error: failure.message); return false; }, (_) { state = state.copyWith(isLoading: false); return true; }, ); } void clearError() { state = state.copyWith(error: null); } } final tradingNotifierProvider = StateNotifierProvider( (ref) => TradingNotifier( repository: ref.watch(tradingRepositoryProvider), ), );