470 lines
12 KiB
Dart
470 lines
12 KiB
Dart
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<PriceInfoModel> getCurrentPrice();
|
||
|
||
/// 获取市场概览
|
||
Future<MarketOverviewModel> getMarketOverview();
|
||
|
||
/// 获取交易账户信息
|
||
Future<TradingAccountModel> getTradingAccount(String accountSequence);
|
||
|
||
/// 创建订单
|
||
Future<Map<String, dynamic>> createOrder({
|
||
required String type,
|
||
required String price,
|
||
required String quantity,
|
||
});
|
||
|
||
/// 取消订单
|
||
Future<void> cancelOrder(String orderNo);
|
||
|
||
/// 获取用户订单列表
|
||
Future<OrdersPageModel> getOrders({
|
||
int page = 1,
|
||
int pageSize = 50,
|
||
});
|
||
|
||
/// 预估卖出收益
|
||
Future<Map<String, dynamic>> estimateSell(String quantity);
|
||
|
||
/// 划入积分股 (从挖矿账户到交易账户)
|
||
Future<Map<String, dynamic>> transferIn(String amount);
|
||
|
||
/// 划出积分股 (从交易账户到挖矿账户)
|
||
Future<Map<String, dynamic>> transferOut(String amount);
|
||
|
||
/// 获取我的资产显示信息
|
||
Future<AssetDisplayModel> getMyAsset({String? dailyAllocation});
|
||
|
||
/// 获取指定账户资产显示信息
|
||
Future<AssetDisplayModel> getAccountAsset(String accountSequence, {String? dailyAllocation});
|
||
|
||
/// 获取K线数据
|
||
Future<List<KlineModel>> getKlines({String period = '1h', int limit = 100});
|
||
|
||
/// P2P转账 - 发送积分股给其他用户
|
||
Future<P2pTransferModel> p2pTransfer({
|
||
required String toPhone,
|
||
required String amount,
|
||
String? memo,
|
||
});
|
||
|
||
/// 查询账户信息(通过手机号)
|
||
Future<AccountLookupModel> lookupAccount(String phone);
|
||
|
||
/// 获取P2P转账历史
|
||
Future<List<P2pTransferModel>> getP2pTransferHistory(String accountSequence);
|
||
|
||
// ============ C2C交易接口 ============
|
||
|
||
/// 获取C2C订单列表(市场广告)
|
||
Future<C2cOrdersPageModel> getC2cOrders({
|
||
String? type, // BUY/SELL
|
||
int page = 1,
|
||
int pageSize = 20,
|
||
});
|
||
|
||
/// 获取我的C2C订单
|
||
Future<C2cOrdersPageModel> getMyC2cOrders({
|
||
String? status,
|
||
int page = 1,
|
||
int pageSize = 20,
|
||
});
|
||
|
||
/// 创建C2C订单(发布广告)
|
||
Future<C2cOrderModel> createC2cOrder({
|
||
required String type, // BUY/SELL
|
||
required String price,
|
||
required String quantity,
|
||
String? minAmount,
|
||
String? maxAmount,
|
||
String? remark,
|
||
});
|
||
|
||
/// 获取C2C订单详情
|
||
Future<C2cOrderModel> getC2cOrderDetail(String orderNo);
|
||
|
||
/// 接单(吃单)
|
||
Future<C2cOrderModel> takeC2cOrder(String orderNo, {String? quantity});
|
||
|
||
/// 取消C2C订单
|
||
Future<void> cancelC2cOrder(String orderNo);
|
||
|
||
/// 确认付款(买方操作)
|
||
Future<C2cOrderModel> confirmC2cPayment(String orderNo);
|
||
|
||
/// 确认收款(卖方操作)
|
||
Future<C2cOrderModel> confirmC2cReceived(String orderNo);
|
||
}
|
||
|
||
class TradingRemoteDataSourceImpl implements TradingRemoteDataSource {
|
||
final ApiClient client;
|
||
|
||
TradingRemoteDataSourceImpl({required this.client});
|
||
|
||
@override
|
||
Future<PriceInfoModel> getCurrentPrice() async {
|
||
try {
|
||
final response = await client.get(ApiEndpoints.currentPrice);
|
||
return PriceInfoModel.fromJson(response.data);
|
||
} catch (e) {
|
||
throw ServerException(e.toString());
|
||
}
|
||
}
|
||
|
||
@override
|
||
Future<MarketOverviewModel> getMarketOverview() async {
|
||
try {
|
||
final response = await client.get(ApiEndpoints.marketOverview);
|
||
return MarketOverviewModel.fromJson(response.data);
|
||
} catch (e) {
|
||
throw ServerException(e.toString());
|
||
}
|
||
}
|
||
|
||
@override
|
||
Future<TradingAccountModel> 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<Map<String, dynamic>> 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<void> cancelOrder(String orderNo) async {
|
||
try {
|
||
await client.post(ApiEndpoints.cancelOrder(orderNo));
|
||
} catch (e) {
|
||
throw ServerException(e.toString());
|
||
}
|
||
}
|
||
|
||
@override
|
||
Future<OrdersPageModel> 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<Map<String, dynamic>> 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<Map<String, dynamic>> 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<Map<String, dynamic>> 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<AssetDisplayModel> getMyAsset({String? dailyAllocation}) async {
|
||
try {
|
||
final queryParams = <String, dynamic>{};
|
||
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<AssetDisplayModel> getAccountAsset(String accountSequence, {String? dailyAllocation}) async {
|
||
try {
|
||
final queryParams = <String, dynamic>{};
|
||
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<List<KlineModel>> getKlines({String period = '1h', int limit = 100}) async {
|
||
try {
|
||
final response = await client.get(
|
||
ApiEndpoints.priceKlines,
|
||
queryParameters: {'period': period, 'limit': limit},
|
||
);
|
||
final List<dynamic> data = response.data;
|
||
return data.map((json) => KlineModel.fromJson(json)).toList();
|
||
} catch (e) {
|
||
throw ServerException(e.toString());
|
||
}
|
||
}
|
||
|
||
@override
|
||
Future<P2pTransferModel> p2pTransfer({
|
||
required String toPhone,
|
||
required String amount,
|
||
String? memo,
|
||
}) async {
|
||
try {
|
||
final data = <String, dynamic>{
|
||
'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<AccountLookupModel> 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<List<P2pTransferModel>> getP2pTransferHistory(String accountSequence) async {
|
||
try {
|
||
final response = await client.get(
|
||
ApiEndpoints.p2pTransferHistory(accountSequence),
|
||
);
|
||
final List<dynamic> data = response.data;
|
||
return data.map((json) => P2pTransferModel.fromJson(json)).toList();
|
||
} catch (e) {
|
||
throw ServerException(e.toString());
|
||
}
|
||
}
|
||
|
||
// ============ C2C交易实现 ============
|
||
|
||
@override
|
||
Future<C2cOrdersPageModel> getC2cOrders({
|
||
String? type,
|
||
int page = 1,
|
||
int pageSize = 20,
|
||
}) async {
|
||
try {
|
||
final queryParams = <String, dynamic>{
|
||
'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<C2cOrdersPageModel> getMyC2cOrders({
|
||
String? status,
|
||
int page = 1,
|
||
int pageSize = 20,
|
||
}) async {
|
||
try {
|
||
final queryParams = <String, dynamic>{
|
||
'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<C2cOrderModel> createC2cOrder({
|
||
required String type,
|
||
required String price,
|
||
required String quantity,
|
||
String? minAmount,
|
||
String? maxAmount,
|
||
String? remark,
|
||
}) async {
|
||
try {
|
||
final data = <String, dynamic>{
|
||
'type': type,
|
||
'price': price,
|
||
'quantity': quantity,
|
||
};
|
||
if (minAmount != null) data['minAmount'] = minAmount;
|
||
if (maxAmount != null) data['maxAmount'] = maxAmount;
|
||
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<C2cOrderModel> 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<C2cOrderModel> takeC2cOrder(String orderNo, {String? quantity}) async {
|
||
try {
|
||
final data = <String, dynamic>{};
|
||
if (quantity != null) data['quantity'] = quantity;
|
||
|
||
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<void> cancelC2cOrder(String orderNo) async {
|
||
try {
|
||
await client.post(ApiEndpoints.c2cCancelOrder(orderNo));
|
||
} catch (e) {
|
||
throw ServerException(e.toString());
|
||
}
|
||
}
|
||
|
||
@override
|
||
Future<C2cOrderModel> 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<C2cOrderModel> confirmC2cReceived(String orderNo) async {
|
||
try {
|
||
final response = await client.post(
|
||
ApiEndpoints.c2cConfirmReceived(orderNo),
|
||
);
|
||
return C2cOrderModel.fromJson(response.data);
|
||
} catch (e) {
|
||
throw ServerException(e.toString());
|
||
}
|
||
}
|
||
}
|