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:
sion
2026-03-22 00:21:21 +08:00
parent 7694a34ade
commit ffac6fc267
67 changed files with 4396 additions and 3097 deletions

View 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,
);
}
}

View 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 ?? '获取订单详情失败');
}
}

View 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 ?? '搜索失败');
}
}

View 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 ?? '获取订单详情失败');
}
}

View 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);
}
}