import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import '../../../core/network/api_response.dart'; import '../models/market/funding_rate.dart'; /// 资金费率接口 class FundingRateService { const FundingRateService(this._dio); final Dio _dio; static bool _isNoData(DioException e) => e.response?.statusCode == 404 || e.error is ApiException; /// 当前资金费率 /// GET /swap/funding-rate/current?contractCoinId=1 Future getCurrent(int contractCoinId) async { try { final response = await _dio.get>( 'swap/funding-rate/current', queryParameters: {'contractCoinId': contractCoinId}, ); final data = response.data?['data']; if (data is Map) { return FundingRateCurrent.fromJson(data); } return null; } on DioException catch (e) { if (_isNoData(e)) { debugPrint('[FundingRate] getCurrent no-data: ${e.error}'); return null; } rethrow; } } /// 拉取单页历史记录 Future> _fetchPage( int contractCoinId, int pageNo, int pageSize) async { final response = await _dio.get>( 'swap/funding-rate/history', queryParameters: { 'contractCoinId': contractCoinId, 'pageNo': pageNo, 'pageSize': pageSize, }, ); final data = response.data?['data'] ?? response.data; List? raw; if (data is Map) { raw = data['content'] as List?; } else if (data is List) { raw = data; } return (raw ?? []) .whereType>() .map((e) => FundingRateHistoryItem.fromJson(e)) .toList(); } /// 资金费率历史——多页拉取,直到覆盖最近 [days] 天或服务端无更多数据 /// GET /swap/funding-rate/history?contractCoinId=1&pageNo=N&pageSize=N Future> getHistory({ required int contractCoinId, int pageSize = 20, int days = 7, }) async { try { final cutoff = DateTime.now().subtract(Duration(days: days)); final result = []; int pageNo = 1; // 最多拉 10 页,防止死循环 const maxPages = 10; while (pageNo <= maxPages) { final page = await _fetchPage(contractCoinId, pageNo, pageSize); result.addAll(page); // 服务端返回不足一页 → 已无更多数据 if (page.length < pageSize) break; // 最早一条已早于 cutoff → 足够了 final oldest = page .map((e) => e.fundingTime) .reduce((a, b) => a.isBefore(b) ? a : b); if (oldest.isBefore(cutoff)) break; pageNo++; } return result; } on DioException catch (e) { if (_isNoData(e)) { debugPrint('[FundingRate] getHistory no-data: ${e.error}'); return []; } rethrow; } } }