refactor: 将前端从 uni-app x 重构为 Flutter
变更内容: - 删除 uni-app x 项目 (app/ 目录) - 新增 Flutter 项目 (flutter_monisuo/ 目录) - 新增部署脚本 (deploy/ 目录) Flutter 项目功能: - 用户登录/注册 - 首页资产概览 - 行情币种列表 - 交易买卖操作 - 资产账户管理 - 充值/提现/划转 - 深色主题 - JWT Token 认证 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
166
flutter_monisuo/lib/data/models/account_models.dart
Normal file
166
flutter_monisuo/lib/data/models/account_models.dart
Normal file
@@ -0,0 +1,166 @@
|
||||
/// 资产总览模型
|
||||
class AssetOverview {
|
||||
final String totalAsset;
|
||||
final String fundBalance;
|
||||
final String tradeBalance;
|
||||
final String totalProfit;
|
||||
|
||||
AssetOverview({
|
||||
required this.totalAsset,
|
||||
required this.fundBalance,
|
||||
required this.tradeBalance,
|
||||
required this.totalProfit,
|
||||
});
|
||||
|
||||
factory AssetOverview.fromJson(Map<String, dynamic> json) {
|
||||
return AssetOverview(
|
||||
totalAsset: json['totalAsset']?.toString() ?? '0.00',
|
||||
fundBalance: json['fundBalance']?.toString() ?? '0.00',
|
||||
tradeBalance: json['tradeBalance']?.toString() ?? '0.00',
|
||||
totalProfit: json['totalProfit']?.toString() ?? '0.00',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 资金账户模型
|
||||
class AccountFund {
|
||||
final int id;
|
||||
final int userId;
|
||||
final String balance;
|
||||
final String frozenBalance;
|
||||
final DateTime? updateTime;
|
||||
|
||||
AccountFund({
|
||||
required this.id,
|
||||
required this.userId,
|
||||
required this.balance,
|
||||
required this.frozenBalance,
|
||||
this.updateTime,
|
||||
});
|
||||
|
||||
factory AccountFund.fromJson(Map<String, dynamic> json) {
|
||||
return AccountFund(
|
||||
id: json['id'] as int? ?? 0,
|
||||
userId: json['userId'] as int? ?? 0,
|
||||
balance: json['balance']?.toString() ?? '0.00',
|
||||
frozenBalance: json['frozenBalance']?.toString() ?? '0.00',
|
||||
updateTime: json['updateTime'] != null
|
||||
? DateTime.tryParse(json['updateTime'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// 交易账户模型(持仓)
|
||||
class AccountTrade {
|
||||
final int id;
|
||||
final int userId;
|
||||
final String coinCode;
|
||||
final String quantity;
|
||||
final String avgPrice;
|
||||
final String totalCost;
|
||||
final String currentValue;
|
||||
final String profit;
|
||||
final double profitRate;
|
||||
final DateTime? updateTime;
|
||||
|
||||
AccountTrade({
|
||||
required this.id,
|
||||
required this.userId,
|
||||
required this.coinCode,
|
||||
required this.quantity,
|
||||
required this.avgPrice,
|
||||
required this.totalCost,
|
||||
required this.currentValue,
|
||||
required this.profit,
|
||||
required this.profitRate,
|
||||
this.updateTime,
|
||||
});
|
||||
|
||||
factory AccountTrade.fromJson(Map<String, dynamic> json) {
|
||||
return AccountTrade(
|
||||
id: json['id'] as int? ?? 0,
|
||||
userId: json['userId'] as int? ?? 0,
|
||||
coinCode: json['coinCode'] as String? ?? '',
|
||||
quantity: json['quantity']?.toString() ?? '0',
|
||||
avgPrice: json['avgPrice']?.toString() ?? '0.00',
|
||||
totalCost: json['totalCost']?.toString() ?? '0.00',
|
||||
currentValue: json['currentValue']?.toString() ?? '0.00',
|
||||
profit: json['profit']?.toString() ?? '0.00',
|
||||
profitRate: (json['profitRate'] as num?)?.toDouble() ?? 0,
|
||||
updateTime: json['updateTime'] != null
|
||||
? DateTime.tryParse(json['updateTime'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
/// 格式化盈亏率
|
||||
String get formattedProfitRate {
|
||||
final prefix = profitRate >= 0 ? '+' : '';
|
||||
return '$prefix${profitRate.toStringAsFixed(2)}%';
|
||||
}
|
||||
|
||||
/// 是否盈利
|
||||
bool get isProfit => profitRate >= 0;
|
||||
}
|
||||
|
||||
/// 资金流水模型
|
||||
class AccountFlow {
|
||||
final int id;
|
||||
final int userId;
|
||||
final String flowType;
|
||||
final String amount;
|
||||
final String balanceBefore;
|
||||
final String balanceAfter;
|
||||
final String remark;
|
||||
final DateTime? createTime;
|
||||
|
||||
AccountFlow({
|
||||
required this.id,
|
||||
required this.userId,
|
||||
required this.flowType,
|
||||
required this.amount,
|
||||
required this.balanceBefore,
|
||||
required this.balanceAfter,
|
||||
required this.remark,
|
||||
this.createTime,
|
||||
});
|
||||
|
||||
factory AccountFlow.fromJson(Map<String, dynamic> json) {
|
||||
return AccountFlow(
|
||||
id: json['id'] as int? ?? 0,
|
||||
userId: json['userId'] as int? ?? 0,
|
||||
flowType: json['flowType']?.toString() ?? '',
|
||||
amount: json['amount']?.toString() ?? '0.00',
|
||||
balanceBefore: json['balanceBefore']?.toString() ?? '0.00',
|
||||
balanceAfter: json['balanceAfter']?.toString() ?? '0.00',
|
||||
remark: json['remark']?.toString() ?? '',
|
||||
createTime: json['createTime'] != null
|
||||
? DateTime.tryParse(json['createTime'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
/// 流水类型文字
|
||||
String get flowTypeText {
|
||||
switch (flowType) {
|
||||
case '1':
|
||||
return '充值';
|
||||
case '2':
|
||||
return '提现';
|
||||
case '3':
|
||||
return '转入交易账户';
|
||||
case '4':
|
||||
return '从交易账户转出';
|
||||
case '5':
|
||||
return '卖出收入';
|
||||
case '6':
|
||||
return '买入支出';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否为收入
|
||||
bool get isIncome => ['1', '3', '5'].contains(flowType);
|
||||
}
|
||||
106
flutter_monisuo/lib/data/models/coin.dart
Normal file
106
flutter_monisuo/lib/data/models/coin.dart
Normal file
@@ -0,0 +1,106 @@
|
||||
/// 币种模型
|
||||
class Coin {
|
||||
final int id;
|
||||
final String code;
|
||||
final String name;
|
||||
final String? icon;
|
||||
final double price;
|
||||
final double? priceUsd;
|
||||
final double? priceCny;
|
||||
final int priceType; // 1=实时价格, 2=管理员设置
|
||||
final double change24h;
|
||||
final double? high24h;
|
||||
final double? low24h;
|
||||
final double? volume24h;
|
||||
final int status;
|
||||
final int sort;
|
||||
|
||||
Coin({
|
||||
required this.id,
|
||||
required this.code,
|
||||
required this.name,
|
||||
this.icon,
|
||||
required this.price,
|
||||
this.priceUsd,
|
||||
this.priceCny,
|
||||
required this.priceType,
|
||||
required this.change24h,
|
||||
this.high24h,
|
||||
this.low24h,
|
||||
this.volume24h,
|
||||
required this.status,
|
||||
this.sort = 0,
|
||||
});
|
||||
|
||||
factory Coin.fromJson(Map<String, dynamic> json) {
|
||||
return Coin(
|
||||
id: json['id'] as int? ?? 0,
|
||||
code: json['code'] as String? ?? '',
|
||||
name: json['name'] as String? ?? '',
|
||||
icon: json['icon'] as String?,
|
||||
price: (json['price'] as num?)?.toDouble() ?? 0,
|
||||
priceUsd: (json['priceUsd'] as num?)?.toDouble(),
|
||||
priceCny: (json['priceCny'] as num?)?.toDouble(),
|
||||
priceType: json['priceType'] as int? ?? 1,
|
||||
change24h: (json['change24h'] as num?)?.toDouble() ?? 0,
|
||||
high24h: (json['high24h'] as num?)?.toDouble(),
|
||||
low24h: (json['low24h'] as num?)?.toDouble(),
|
||||
volume24h: (json['volume24h'] as num?)?.toDouble(),
|
||||
status: json['status'] as int? ?? 1,
|
||||
sort: json['sort'] as int? ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'code': code,
|
||||
'name': name,
|
||||
'icon': icon,
|
||||
'price': price,
|
||||
'priceUsd': priceUsd,
|
||||
'priceCny': priceCny,
|
||||
'priceType': priceType,
|
||||
'change24h': change24h,
|
||||
'high24h': high24h,
|
||||
'low24h': low24h,
|
||||
'volume24h': volume24h,
|
||||
'status': status,
|
||||
'sort': sort,
|
||||
};
|
||||
}
|
||||
|
||||
/// 显示图标(Unicode 符号)
|
||||
String get displayIcon {
|
||||
const icons = {
|
||||
'BTC': '\u20BF',
|
||||
'ETH': '\u039E',
|
||||
'SOL': '\u25CD',
|
||||
'USDT': '\u20AE',
|
||||
'DOGE': '\uD83D\uDC15',
|
||||
'XRP': '\u2715',
|
||||
'BNB': '\u25B3',
|
||||
'ADA': '\u25C6',
|
||||
};
|
||||
return icons[code] ?? '\u25CF';
|
||||
}
|
||||
|
||||
/// 格式化价格显示
|
||||
String get formattedPrice {
|
||||
if (price >= 1000) return price.toStringAsFixed(2);
|
||||
if (price >= 1) return price.toStringAsFixed(4);
|
||||
return price.toStringAsFixed(6);
|
||||
}
|
||||
|
||||
/// 格式化涨跌幅
|
||||
String get formattedChange {
|
||||
final prefix = change24h >= 0 ? '+' : '';
|
||||
return '$prefix${change24h.toStringAsFixed(2)}%';
|
||||
}
|
||||
|
||||
/// 是否上涨
|
||||
bool get isUp => change24h >= 0;
|
||||
|
||||
/// 是否为实时价格
|
||||
bool get isRealtime => priceType == 1;
|
||||
}
|
||||
139
flutter_monisuo/lib/data/models/order_models.dart
Normal file
139
flutter_monisuo/lib/data/models/order_models.dart
Normal file
@@ -0,0 +1,139 @@
|
||||
/// 交易订单模型
|
||||
class OrderTrade {
|
||||
final int id;
|
||||
final String orderNo;
|
||||
final int userId;
|
||||
final String coinCode;
|
||||
final int direction; // 1=买入, 2=卖出
|
||||
final String price;
|
||||
final String quantity;
|
||||
final String amount;
|
||||
final int status; // 1=待处理, 2=已完成, 3=已取消
|
||||
final DateTime? createTime;
|
||||
final DateTime? updateTime;
|
||||
|
||||
OrderTrade({
|
||||
required this.id,
|
||||
required this.orderNo,
|
||||
required this.userId,
|
||||
required this.coinCode,
|
||||
required this.direction,
|
||||
required this.price,
|
||||
required this.quantity,
|
||||
required this.amount,
|
||||
required this.status,
|
||||
this.createTime,
|
||||
this.updateTime,
|
||||
});
|
||||
|
||||
factory OrderTrade.fromJson(Map<String, dynamic> json) {
|
||||
return OrderTrade(
|
||||
id: json['id'] as int? ?? 0,
|
||||
orderNo: json['orderNo'] as String? ?? '',
|
||||
userId: json['userId'] as int? ?? 0,
|
||||
coinCode: json['coinCode'] as String? ?? '',
|
||||
direction: json['direction'] as int? ?? 1,
|
||||
price: json['price']?.toString() ?? '0.00',
|
||||
quantity: json['quantity']?.toString() ?? '0',
|
||||
amount: json['amount']?.toString() ?? '0.00',
|
||||
status: json['status'] as int? ?? 1,
|
||||
createTime: json['createTime'] != null
|
||||
? DateTime.tryParse(json['createTime'])
|
||||
: null,
|
||||
updateTime: json['updateTime'] != null
|
||||
? DateTime.tryParse(json['updateTime'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
/// 方向文字
|
||||
String get directionText => direction == 1 ? '买入' : '卖出';
|
||||
|
||||
/// 状态文字
|
||||
String get statusText {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return '待处理';
|
||||
case 2:
|
||||
return '已完成';
|
||||
case 3:
|
||||
return '已取消';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否为买入
|
||||
bool get isBuy => direction == 1;
|
||||
}
|
||||
|
||||
/// 充提订单模型
|
||||
class OrderFund {
|
||||
final int id;
|
||||
final String orderNo;
|
||||
final int userId;
|
||||
final int orderType; // 1=充值, 2=提现
|
||||
final String amount;
|
||||
final int status; // 1=待审核, 2=已通过, 3=已拒绝, 4=已取消
|
||||
final String remark;
|
||||
final String? auditRemark;
|
||||
final DateTime? createTime;
|
||||
final DateTime? auditTime;
|
||||
|
||||
OrderFund({
|
||||
required this.id,
|
||||
required this.orderNo,
|
||||
required this.userId,
|
||||
required this.orderType,
|
||||
required this.amount,
|
||||
required this.status,
|
||||
required this.remark,
|
||||
this.auditRemark,
|
||||
this.createTime,
|
||||
this.auditTime,
|
||||
});
|
||||
|
||||
factory OrderFund.fromJson(Map<String, dynamic> json) {
|
||||
return OrderFund(
|
||||
id: json['id'] as int? ?? 0,
|
||||
orderNo: json['orderNo'] as String? ?? '',
|
||||
userId: json['userId'] as int? ?? 0,
|
||||
orderType: json['orderType'] as int? ?? 1,
|
||||
amount: json['amount']?.toString() ?? '0.00',
|
||||
status: json['status'] as int? ?? 1,
|
||||
remark: json['remark']?.toString() ?? '',
|
||||
auditRemark: json['auditRemark']?.toString(),
|
||||
createTime: json['createTime'] != null
|
||||
? DateTime.tryParse(json['createTime'])
|
||||
: null,
|
||||
auditTime: json['auditTime'] != null
|
||||
? DateTime.tryParse(json['auditTime'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
/// 订单类型文字
|
||||
String get orderTypeText => orderType == 1 ? '充值' : '提现';
|
||||
|
||||
/// 状态文字
|
||||
String get statusText {
|
||||
switch (status) {
|
||||
case 1:
|
||||
return '待审核';
|
||||
case 2:
|
||||
return '已通过';
|
||||
case 3:
|
||||
return '已拒绝';
|
||||
case 4:
|
||||
return '已取消';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
/// 是否为充值
|
||||
bool get isDeposit => orderType == 1;
|
||||
|
||||
/// 是否可取消
|
||||
bool get canCancel => status == 1;
|
||||
}
|
||||
80
flutter_monisuo/lib/data/models/user.dart
Normal file
80
flutter_monisuo/lib/data/models/user.dart
Normal file
@@ -0,0 +1,80 @@
|
||||
/// 用户模型
|
||||
class User {
|
||||
final int id;
|
||||
final String username;
|
||||
final String? nickname;
|
||||
final String? avatar;
|
||||
final String? phone;
|
||||
final String? email;
|
||||
final int kycStatus;
|
||||
final int status;
|
||||
final DateTime? lastLoginTime;
|
||||
final DateTime? createTime;
|
||||
|
||||
User({
|
||||
required this.id,
|
||||
required this.username,
|
||||
this.nickname,
|
||||
this.avatar,
|
||||
this.phone,
|
||||
this.email,
|
||||
required this.kycStatus,
|
||||
required this.status,
|
||||
this.lastLoginTime,
|
||||
this.createTime,
|
||||
});
|
||||
|
||||
factory User.fromJson(Map<String, dynamic> json) {
|
||||
return User(
|
||||
id: json['id'] as int? ?? 0,
|
||||
username: json['username'] as String? ?? '',
|
||||
nickname: json['nickname'] as String?,
|
||||
avatar: json['avatar'] as String?,
|
||||
phone: json['phone'] as String?,
|
||||
email: json['email'] as String?,
|
||||
kycStatus: json['kycStatus'] as int? ?? 0,
|
||||
status: json['status'] as int? ?? 1,
|
||||
lastLoginTime: json['lastLoginTime'] != null
|
||||
? DateTime.tryParse(json['lastLoginTime'])
|
||||
: null,
|
||||
createTime: json['createTime'] != null
|
||||
? DateTime.tryParse(json['createTime'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'username': username,
|
||||
'nickname': nickname,
|
||||
'avatar': avatar,
|
||||
'phone': phone,
|
||||
'email': email,
|
||||
'kycStatus': kycStatus,
|
||||
'status': status,
|
||||
'lastLoginTime': lastLoginTime?.toIso8601String(),
|
||||
'createTime': createTime?.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
/// 获取头像显示文字(用户名首字母)
|
||||
String get avatarText =>
|
||||
username.isNotEmpty ? username.substring(0, 1).toUpperCase() : 'U';
|
||||
|
||||
/// KYC 状态文字
|
||||
String get kycStatusText {
|
||||
switch (kycStatus) {
|
||||
case 0:
|
||||
return '未认证';
|
||||
case 1:
|
||||
return '审核中';
|
||||
case 2:
|
||||
return '已认证';
|
||||
case 3:
|
||||
return '认证失败';
|
||||
default:
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
}
|
||||
86
flutter_monisuo/lib/data/services/asset_service.dart
Normal file
86
flutter_monisuo/lib/data/services/asset_service.dart
Normal file
@@ -0,0 +1,86 @@
|
||||
import '../../core/constants/api_endpoints.dart';
|
||||
import '../../core/network/dio_client.dart';
|
||||
import '../models/account_models.dart';
|
||||
|
||||
/// 资产服务
|
||||
class AssetService {
|
||||
final DioClient _client;
|
||||
|
||||
AssetService(this._client);
|
||||
|
||||
/// 获取资产总览
|
||||
Future<ApiResponse<AssetOverview>> getOverview() async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.assetOverview,
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
return ApiResponse.success(
|
||||
AssetOverview.fromJson(response.data!),
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '获取资产总览失败');
|
||||
}
|
||||
|
||||
/// 获取资金账户
|
||||
Future<ApiResponse<AccountFund>> getFundAccount() async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.fundAccount,
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
return ApiResponse.success(
|
||||
AccountFund.fromJson(response.data!),
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '获取资金账户失败');
|
||||
}
|
||||
|
||||
/// 获取交易账户
|
||||
Future<ApiResponse<List<AccountTrade>>> getTradeAccount() async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.tradeAccount,
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
final list = response.data!['list'] as List?;
|
||||
final accounts = list?.map((e) => AccountTrade.fromJson(e as Map<String, dynamic>)).toList() ?? [];
|
||||
return ApiResponse.success(accounts, response.message);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '获取交易账户失败');
|
||||
}
|
||||
|
||||
/// 资金划转
|
||||
Future<ApiResponse<void>> transfer({
|
||||
required int direction,
|
||||
required String amount,
|
||||
}) async {
|
||||
return _client.post<void>(
|
||||
ApiEndpoints.transfer,
|
||||
data: {
|
||||
'direction': direction,
|
||||
'amount': amount,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取资金流水
|
||||
Future<ApiResponse<Map<String, dynamic>>> getFlow({
|
||||
int? flowType,
|
||||
int pageNum = 1,
|
||||
int pageSize = 20,
|
||||
}) async {
|
||||
final params = <String, dynamic>{
|
||||
'pageNum': pageNum,
|
||||
'pageSize': pageSize,
|
||||
};
|
||||
if (flowType != null) params['flowType'] = flowType;
|
||||
|
||||
return _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.assetFlow,
|
||||
queryParameters: params,
|
||||
);
|
||||
}
|
||||
}
|
||||
80
flutter_monisuo/lib/data/services/fund_service.dart
Normal file
80
flutter_monisuo/lib/data/services/fund_service.dart
Normal file
@@ -0,0 +1,80 @@
|
||||
import '../../core/constants/api_endpoints.dart';
|
||||
import '../../core/network/dio_client.dart';
|
||||
import '../models/order_models.dart';
|
||||
|
||||
/// 充提服务
|
||||
class FundService {
|
||||
final DioClient _client;
|
||||
|
||||
FundService(this._client);
|
||||
|
||||
/// 申请充值
|
||||
Future<ApiResponse<Map<String, dynamic>>> deposit({
|
||||
required String amount,
|
||||
String? remark,
|
||||
}) async {
|
||||
return _client.post<Map<String, dynamic>>(
|
||||
ApiEndpoints.deposit,
|
||||
data: {
|
||||
'amount': amount,
|
||||
if (remark != null) 'remark': remark,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 申请提现
|
||||
Future<ApiResponse<Map<String, dynamic>>> withdraw({
|
||||
required String amount,
|
||||
String? remark,
|
||||
}) async {
|
||||
return _client.post<Map<String, dynamic>>(
|
||||
ApiEndpoints.withdraw,
|
||||
data: {
|
||||
'amount': amount,
|
||||
if (remark != null) 'remark': remark,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 取消订单
|
||||
Future<ApiResponse<void>> cancelOrder(String orderNo) async {
|
||||
return _client.post<void>(
|
||||
ApiEndpoints.cancelOrder,
|
||||
data: {'orderNo': orderNo},
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取充提记录
|
||||
Future<ApiResponse<Map<String, dynamic>>> getOrders({
|
||||
int? type,
|
||||
int pageNum = 1,
|
||||
int pageSize = 20,
|
||||
}) async {
|
||||
final params = <String, dynamic>{
|
||||
'pageNum': pageNum,
|
||||
'pageSize': pageSize,
|
||||
};
|
||||
if (type != null) params['type'] = type;
|
||||
|
||||
return _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.fundOrders,
|
||||
queryParameters: params,
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取充提订单详情
|
||||
Future<ApiResponse<OrderFund>> getOrderDetail(String orderNo) async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.fundOrders,
|
||||
queryParameters: {'orderNo': orderNo},
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
return ApiResponse.success(
|
||||
OrderFund.fromJson(response.data!),
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '获取订单详情失败');
|
||||
}
|
||||
}
|
||||
55
flutter_monisuo/lib/data/services/market_service.dart
Normal file
55
flutter_monisuo/lib/data/services/market_service.dart
Normal file
@@ -0,0 +1,55 @@
|
||||
import '../../core/constants/api_endpoints.dart';
|
||||
import '../../core/network/dio_client.dart';
|
||||
import '../models/coin.dart';
|
||||
|
||||
/// 行情服务
|
||||
class MarketService {
|
||||
final DioClient _client;
|
||||
|
||||
MarketService(this._client);
|
||||
|
||||
/// 获取币种列表
|
||||
Future<ApiResponse<List<Coin>>> getCoinList() async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.coinList,
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
final list = response.data!['list'] as List?;
|
||||
final coins = list?.map((e) => Coin.fromJson(e as Map<String, dynamic>)).toList() ?? [];
|
||||
return ApiResponse.success(coins, response.message);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '获取币种列表失败');
|
||||
}
|
||||
|
||||
/// 获取币种详情
|
||||
Future<ApiResponse<Coin>> getCoinDetail(String code) async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.coinDetail,
|
||||
queryParameters: {'code': code},
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
return ApiResponse.success(
|
||||
Coin.fromJson(response.data!),
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '获取币种详情失败');
|
||||
}
|
||||
|
||||
/// 搜索币种
|
||||
Future<ApiResponse<List<Coin>>> searchCoins(String keyword) async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.coinSearch,
|
||||
queryParameters: {'keyword': keyword},
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
final list = response.data!['list'] as List?;
|
||||
final coins = list?.map((e) => Coin.fromJson(e as Map<String, dynamic>)).toList() ?? [];
|
||||
return ApiResponse.success(coins, response.message);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '搜索失败');
|
||||
}
|
||||
}
|
||||
78
flutter_monisuo/lib/data/services/trade_service.dart
Normal file
78
flutter_monisuo/lib/data/services/trade_service.dart
Normal file
@@ -0,0 +1,78 @@
|
||||
import '../../core/constants/api_endpoints.dart';
|
||||
import '../../core/network/dio_client.dart';
|
||||
import '../models/order_models.dart';
|
||||
|
||||
/// 交易服务
|
||||
class TradeService {
|
||||
final DioClient _client;
|
||||
|
||||
TradeService(this._client);
|
||||
|
||||
/// 买入
|
||||
Future<ApiResponse<Map<String, dynamic>>> buy({
|
||||
required String coinCode,
|
||||
required String price,
|
||||
required String quantity,
|
||||
}) async {
|
||||
return _client.post<Map<String, dynamic>>(
|
||||
ApiEndpoints.buy,
|
||||
data: {
|
||||
'coinCode': coinCode,
|
||||
'price': price,
|
||||
'quantity': quantity,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 卖出
|
||||
Future<ApiResponse<Map<String, dynamic>>> sell({
|
||||
required String coinCode,
|
||||
required String price,
|
||||
required String quantity,
|
||||
}) async {
|
||||
return _client.post<Map<String, dynamic>>(
|
||||
ApiEndpoints.sell,
|
||||
data: {
|
||||
'coinCode': coinCode,
|
||||
'price': price,
|
||||
'quantity': quantity,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取交易记录
|
||||
Future<ApiResponse<Map<String, dynamic>>> getOrders({
|
||||
String? coinCode,
|
||||
int? direction,
|
||||
int pageNum = 1,
|
||||
int pageSize = 20,
|
||||
}) async {
|
||||
final params = <String, dynamic>{
|
||||
'pageNum': pageNum,
|
||||
'pageSize': pageSize,
|
||||
};
|
||||
if (coinCode != null) params['coinCode'] = coinCode;
|
||||
if (direction != null) params['direction'] = direction;
|
||||
|
||||
return _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.tradeOrders,
|
||||
queryParameters: params,
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取订单详情
|
||||
Future<ApiResponse<OrderTrade>> getOrderDetail(String orderNo) async {
|
||||
final response = await _client.get<Map<String, dynamic>>(
|
||||
ApiEndpoints.tradeOrderDetail,
|
||||
queryParameters: {'orderNo': orderNo},
|
||||
);
|
||||
|
||||
if (response.success && response.data != null) {
|
||||
return ApiResponse.success(
|
||||
OrderTrade.fromJson(response.data!),
|
||||
response.message,
|
||||
);
|
||||
}
|
||||
return ApiResponse.fail(response.message ?? '获取订单详情失败');
|
||||
}
|
||||
}
|
||||
56
flutter_monisuo/lib/data/services/user_service.dart
Normal file
56
flutter_monisuo/lib/data/services/user_service.dart
Normal file
@@ -0,0 +1,56 @@
|
||||
import '../../core/constants/api_endpoints.dart';
|
||||
import '../../core/network/dio_client.dart';
|
||||
import '../models/user.dart';
|
||||
|
||||
/// 用户服务
|
||||
class UserService {
|
||||
final DioClient _client;
|
||||
|
||||
UserService(this._client);
|
||||
|
||||
/// 用户登录
|
||||
Future<ApiResponse<Map<String, dynamic>>> login(
|
||||
String username,
|
||||
String password,
|
||||
) async {
|
||||
return _client.post<Map<String, dynamic>>(
|
||||
ApiEndpoints.login,
|
||||
data: {'username': username, 'password': password},
|
||||
);
|
||||
}
|
||||
|
||||
/// 用户注册
|
||||
Future<ApiResponse<Map<String, dynamic>>> register(
|
||||
String username,
|
||||
String password,
|
||||
) async {
|
||||
return _client.post<Map<String, dynamic>>(
|
||||
ApiEndpoints.register,
|
||||
data: {'username': username, 'password': password},
|
||||
);
|
||||
}
|
||||
|
||||
/// 获取用户信息
|
||||
Future<ApiResponse<User>> getUserInfo() async {
|
||||
return _client.get<User>(
|
||||
ApiEndpoints.userInfo,
|
||||
fromJson: (data) => User.fromJson(data as Map<String, dynamic>),
|
||||
);
|
||||
}
|
||||
|
||||
/// 上传 KYC 资料
|
||||
Future<ApiResponse<void>> uploadKyc(
|
||||
String idCardFront,
|
||||
String idCardBack,
|
||||
) async {
|
||||
return _client.post<void>(
|
||||
ApiEndpoints.kyc,
|
||||
data: {'idCardFront': idCardFront, 'idCardBack': idCardBack},
|
||||
);
|
||||
}
|
||||
|
||||
/// 退出登录
|
||||
Future<ApiResponse<void>> logout() async {
|
||||
return _client.post<void>(ApiEndpoints.logout);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user