Files
monisuo/flutter_monisuo/lib/providers/trade_provider.dart
2026-04-21 08:12:17 +08:00

93 lines
2.6 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import '../data/models/coin.dart';
import '../data/models/order_book.dart';
import '../data/services/market_service.dart';
import '../data/services/trade_service.dart';
/// 交易頁狀態管理 — 輪詢價格 + 訂單簿
class TradeProvider extends ChangeNotifier {
final MarketService _marketService;
// ignore: unused_field
final TradeService _tradeService;
TradeProvider(this._marketService, this._tradeService);
Coin? _selectedCoin;
OrderBookDepth _depth = const OrderBookDepth(asks: [], bids: [], spread: 0, spreadPercent: 0);
bool _isLoadingDepth = false;
String? _error;
Timer? _pollTimer;
static const _pollInterval = Duration(seconds: 5);
Coin? get selectedCoin => _selectedCoin;
OrderBookDepth get depth => _depth;
bool get isLoadingDepth => _isLoadingDepth;
String? get error => _error;
/// 实时模拟价格(从 depth 轮询获取)
double get currentPrice => _depth.currentPrice;
double get change24h => _depth.change24h;
double get high24h => _depth.high24h;
double get low24h => _depth.low24h;
double get volume24h => _depth.volume24h;
/// 交易时段状态
String get tradingStatus => _depth.tradingStatus;
double? get targetLow => _depth.targetLow;
double? get targetHigh => _depth.targetHigh;
double? get targetClose => _depth.targetClose;
bool get isTradable => tradingStatus == 'trading';
void selectCoin(Coin coin) {
if (_selectedCoin?.code == coin.code) return;
_selectedCoin = coin;
_depth = const OrderBookDepth(asks: [], bids: [], spread: 0, spreadPercent: 0);
_error = null;
notifyListeners();
startPolling();
}
void clearSelection() {
_selectedCoin = null;
_depth = const OrderBookDepth(asks: [], bids: [], spread: 0, spreadPercent: 0);
stopPolling();
notifyListeners();
}
void startPolling() {
stopPolling();
_fetchDepth();
_pollTimer = Timer.periodic(_pollInterval, (_) => _fetchDepth());
}
void stopPolling() {
_pollTimer?.cancel();
_pollTimer = null;
}
Future<void> _fetchDepth() async {
if (_selectedCoin == null) return;
final response = await _marketService.getDepth(_selectedCoin!.code);
if (!response.success || response.data == null) return;
_depth = OrderBookDepth.fromJson(response.data!);
notifyListeners();
}
/// 刷新幣種價格(從 MarketProvider 的列表中找到最新價)
void updateCoinPrice(Coin updatedCoin) {
if (_selectedCoin?.code == updatedCoin.code) {
_selectedCoin = updatedCoin;
notifyListeners();
}
}
@override
void dispose() {
stopPolling();
super.dispose();
}
}