import '../../models/trade_order_model.dart'; import '../../models/price_info_model.dart'; import '../../models/trading_account_model.dart'; import '../../models/market_overview_model.dart'; import '../../models/asset_display_model.dart'; import '../../models/kline_model.dart'; import '../../models/p2p_transfer_model.dart'; import '../../models/c2c_order_model.dart'; import '../../../core/network/api_client.dart'; import '../../../core/network/api_endpoints.dart'; import '../../../core/error/exceptions.dart'; abstract class TradingRemoteDataSource { /// 获取买入功能开关状态 Future getBuyEnabled(); /// 获取当前价格信息 Future getCurrentPrice(); /// 获取市场概览 Future getMarketOverview(); /// 获取交易账户信息 Future getTradingAccount(String accountSequence); /// 创建订单 Future> createOrder({ required String type, required String price, required String quantity, }); /// 取消订单 Future cancelOrder(String orderNo); /// 获取用户订单列表 Future getOrders({ int page = 1, int pageSize = 50, }); /// 获取用户成交记录(含手续费明细) Future getTrades({ int page = 1, int pageSize = 50, }); /// 预估卖出收益 Future> estimateSell(String quantity); /// 划入积分股 (从挖矿账户到交易账户) Future> transferIn(String amount); /// 划出积分股 (从交易账户到挖矿账户) Future> transferOut(String amount); /// 获取划转历史记录 Future> getTransferHistory({int page = 1, int pageSize = 50}); /// 获取我的资产显示信息 Future getMyAsset({String? dailyAllocation}); /// 获取指定账户资产显示信息 Future getAccountAsset(String accountSequence, {String? dailyAllocation}); /// 获取K线数据 /// [before] 获取此时间之前的K线数据(用于加载更多历史) Future> getKlines({String period = '1h', int limit = 100, DateTime? before}); /// P2P转账 - 发送积分股给其他用户 Future p2pTransfer({ required String toPhone, required String amount, String? memo, }); /// 查询账户信息(通过手机号) Future lookupAccount(String phone); /// 获取P2P转账历史 Future> getP2pTransferHistory(String accountSequence); // ============ C2C交易接口 ============ /// 获取C2C订单列表(市场广告) Future getC2cOrders({ String? type, // BUY/SELL int page = 1, int pageSize = 20, }); /// 获取我的C2C订单 Future getMyC2cOrders({ String? status, int page = 1, int pageSize = 20, }); /// 创建C2C订单(发布广告) Future createC2cOrder({ required String type, // BUY/SELL required String price, required String quantity, String? minAmount, String? maxAmount, // 收款信息(卖单必填) String? paymentMethod, String? paymentAccount, String? paymentQrCode, String? paymentRealName, String? systemId, // 1.0系统ID(绿积分支付必填) String? remark, }); /// 获取C2C订单详情 Future getC2cOrderDetail(String orderNo); /// 接单(吃单) Future takeC2cOrder( String orderNo, { String? quantity, // 收款信息(接买单时由taker提供) String? paymentMethod, String? paymentAccount, String? paymentQrCode, String? paymentRealName, }); /// 取消C2C订单 Future cancelC2cOrder(String orderNo); /// 确认付款(买方操作) Future confirmC2cPayment(String orderNo); /// 确认收款(卖方操作) Future confirmC2cReceived(String orderNo); } class TradingRemoteDataSourceImpl implements TradingRemoteDataSource { final ApiClient client; TradingRemoteDataSourceImpl({required this.client}); @override Future getBuyEnabled() async { try { final response = await client.get(ApiEndpoints.buyEnabled); return response.data['enabled'] ?? false; } catch (e) { // 如果获取失败,默认返回false(关闭状态) return false; } } @override Future getCurrentPrice() async { try { final response = await client.get(ApiEndpoints.currentPrice); return PriceInfoModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getMarketOverview() async { try { final response = await client.get(ApiEndpoints.marketOverview); return MarketOverviewModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getTradingAccount(String accountSequence) async { try { final response = await client.get(ApiEndpoints.tradingAccount(accountSequence)); return TradingAccountModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future> createOrder({ required String type, required String price, required String quantity, }) async { try { final response = await client.post( ApiEndpoints.createOrder, data: { 'type': type, 'price': price, 'quantity': quantity, }, ); return response.data; } catch (e) { throw ServerException(e.toString()); } } @override Future cancelOrder(String orderNo) async { try { await client.post(ApiEndpoints.cancelOrder(orderNo)); } catch (e) { throw ServerException(e.toString()); } } @override Future getOrders({ int page = 1, int pageSize = 50, }) async { try { final response = await client.get( ApiEndpoints.orders, queryParameters: {'page': page, 'pageSize': pageSize}, ); return OrdersPageModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getTrades({ int page = 1, int pageSize = 50, }) async { try { final response = await client.get( ApiEndpoints.trades, queryParameters: {'page': page, 'pageSize': pageSize}, ); return TradesPageModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future> estimateSell(String quantity) async { try { final response = await client.get( ApiEndpoints.estimateSell, queryParameters: {'quantity': quantity}, ); return response.data; } catch (e) { throw ServerException(e.toString()); } } @override Future> transferIn(String amount) async { try { final response = await client.post( ApiEndpoints.transferIn, data: {'amount': amount}, ); return response.data; } catch (e) { throw ServerException(e.toString()); } } @override Future> transferOut(String amount) async { try { final response = await client.post( ApiEndpoints.transferOut, data: {'amount': amount}, ); return response.data; } catch (e) { throw ServerException(e.toString()); } } @override Future> getTransferHistory({int page = 1, int pageSize = 50}) async { try { final response = await client.get( ApiEndpoints.transferHistory, queryParameters: {'page': page, 'pageSize': pageSize}, ); return response.data['data'] ?? []; } catch (e) { throw ServerException(e.toString()); } } @override Future getMyAsset({String? dailyAllocation}) async { try { final queryParams = {}; if (dailyAllocation != null) { queryParams['dailyAllocation'] = dailyAllocation; } final response = await client.get( ApiEndpoints.myAsset, queryParameters: queryParams.isNotEmpty ? queryParams : null, ); return AssetDisplayModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getAccountAsset(String accountSequence, {String? dailyAllocation}) async { try { final queryParams = {}; if (dailyAllocation != null) { queryParams['dailyAllocation'] = dailyAllocation; } final response = await client.get( ApiEndpoints.accountAsset(accountSequence), queryParameters: queryParams.isNotEmpty ? queryParams : null, ); return AssetDisplayModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future> getKlines({ String period = '1h', int limit = 100, DateTime? before, }) async { try { final queryParams = { 'period': period, 'limit': limit, }; if (before != null) { queryParams['before'] = before.toUtc().toIso8601String(); } final response = await client.get( ApiEndpoints.priceKlines, queryParameters: queryParams, ); final List data = response.data; return data.map((json) => KlineModel.fromJson(json)).toList(); } catch (e) { throw ServerException(e.toString()); } } @override Future p2pTransfer({ required String toPhone, required String amount, String? memo, }) async { try { final data = { 'toPhone': toPhone, 'amount': amount, }; if (memo != null && memo.isNotEmpty) { data['memo'] = memo; } final response = await client.post( ApiEndpoints.p2pTransfer, data: data, ); return P2pTransferModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future lookupAccount(String phone) async { try { final response = await client.get( ApiEndpoints.lookupAccount, queryParameters: {'phone': phone}, ); return AccountLookupModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future> getP2pTransferHistory(String accountSequence) async { try { final response = await client.get( ApiEndpoints.p2pTransferHistory(accountSequence), ); final List data = response.data; return data.map((json) => P2pTransferModel.fromJson(json)).toList(); } catch (e) { throw ServerException(e.toString()); } } // ============ C2C交易实现 ============ @override Future getC2cOrders({ String? type, int page = 1, int pageSize = 20, }) async { try { final queryParams = { 'page': page, 'pageSize': pageSize, }; if (type != null) { queryParams['type'] = type; } final response = await client.get( ApiEndpoints.c2cOrders, queryParameters: queryParams, ); return C2cOrdersPageModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getMyC2cOrders({ String? status, int page = 1, int pageSize = 20, }) async { try { final queryParams = { 'page': page, 'pageSize': pageSize, }; if (status != null) { queryParams['status'] = status; } final response = await client.get( ApiEndpoints.c2cMyOrders, queryParameters: queryParams, ); return C2cOrdersPageModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future createC2cOrder({ required String type, required String price, required String quantity, String? minAmount, String? maxAmount, // 收款信息(卖单必填) String? paymentMethod, String? paymentAccount, String? paymentQrCode, String? paymentRealName, String? systemId, // 1.0系统ID(绿积分支付必填) String? remark, }) async { try { final data = { 'type': type, 'price': price, 'quantity': quantity, }; if (minAmount != null) data['minAmount'] = minAmount; if (maxAmount != null) data['maxAmount'] = maxAmount; // 收款信息 if (paymentMethod != null) data['paymentMethod'] = paymentMethod; if (paymentAccount != null) data['paymentAccount'] = paymentAccount; if (paymentQrCode != null) data['paymentQrCode'] = paymentQrCode; if (paymentRealName != null) data['paymentRealName'] = paymentRealName; if (systemId != null && systemId.isNotEmpty) data['systemId'] = systemId; if (remark != null && remark.isNotEmpty) data['remark'] = remark; final response = await client.post( ApiEndpoints.c2cOrders, data: data, ); return C2cOrderModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future getC2cOrderDetail(String orderNo) async { try { final response = await client.get( ApiEndpoints.c2cOrderDetail(orderNo), ); return C2cOrderModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future takeC2cOrder( String orderNo, { String? quantity, // 收款信息(接买单时由taker提供) String? paymentMethod, String? paymentAccount, String? paymentQrCode, String? paymentRealName, }) async { try { final data = {}; if (quantity != null) data['quantity'] = quantity; // 收款信息 if (paymentMethod != null) data['paymentMethod'] = paymentMethod; if (paymentAccount != null) data['paymentAccount'] = paymentAccount; if (paymentQrCode != null) data['paymentQrCode'] = paymentQrCode; if (paymentRealName != null) data['paymentRealName'] = paymentRealName; final response = await client.post( ApiEndpoints.c2cTakeOrder(orderNo), data: data.isNotEmpty ? data : null, ); return C2cOrderModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future cancelC2cOrder(String orderNo) async { try { await client.post(ApiEndpoints.c2cCancelOrder(orderNo)); } catch (e) { throw ServerException(e.toString()); } } @override Future confirmC2cPayment(String orderNo) async { try { final response = await client.post( ApiEndpoints.c2cConfirmPayment(orderNo), ); return C2cOrderModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } @override Future confirmC2cReceived(String orderNo) async { try { final response = await client.post( ApiEndpoints.c2cConfirmReceived(orderNo), ); return C2cOrderModel.fromJson(response.data); } catch (e) { throw ServerException(e.toString()); } } }