Files
video/app/lib/services/asset_service.dart
2026-10-15 20:36:59 +08:00

241 lines
7.0 KiB
Dart

import '../core/network/api_client.dart';
import '../core/network/endpoints.dart';
/// 资产钱包(《03-接口文档》9.3,10 资产 = 1 元)
class AssetWallet {
const AssetWallet({
this.assets = 0,
this.assetsValueYuan = 0,
this.totalEarned = 0,
this.totalWithdrawn = 0,
this.minWithdrawAssets = 100,
this.hasPendingWithdraw = false,
});
/// 资产余额
final double assets;
/// 折合人民币(元)
final double assetsValueYuan;
final double totalEarned;
final double totalWithdrawn;
/// 最低提现资产
final int minWithdrawAssets;
/// 是否有审核中的提现申请
final bool hasPendingWithdraw;
factory AssetWallet.fromJson(Map<String, dynamic> json) => AssetWallet(
assets: (json['assets'] as num?)?.toDouble() ?? 0,
assetsValueYuan: (json['assets_value_yuan'] as num?)?.toDouble() ?? 0,
totalEarned: (json['total_earned'] as num?)?.toDouble() ?? 0,
totalWithdrawn: (json['total_withdrawn'] as num?)?.toDouble() ?? 0,
minWithdrawAssets:
(json['min_withdraw_assets'] as num?)?.toInt() ?? 100,
hasPendingWithdraw: json['has_pending_withdraw'] as bool? ?? false,
);
}
/// 资产流水(《03-接口文档》9.4)
class AssetRecord {
const AssetRecord({
required this.id,
required this.changeAmount,
required this.balanceAfter,
required this.bizType,
this.remark = '',
this.createdAt = '',
});
final int id;
/// 正=收入,负=支出
final double changeAmount;
final double balanceAfter;
/// 1充值返利 2完整观看收益 3点赞收益 4提现 5提现退回 6返利扣回 7后台调整
final int bizType;
final String remark;
final String createdAt;
static const Map<int, String> bizTypeLabels = {
1: '充值返利',
2: '观看收益',
3: '点赞收益',
4: '提现',
5: '提现退回',
6: '返利扣回',
7: '后台调整',
};
String get bizTypeLabel => bizTypeLabels[bizType] ?? '其他';
bool get isExpense => changeAmount < 0;
factory AssetRecord.fromJson(Map<String, dynamic> json) => AssetRecord(
id: (json['id'] as num).toInt(),
changeAmount: (json['change_amount'] as num?)?.toDouble() ?? 0,
balanceAfter: (json['balance_after'] as num?)?.toDouble() ?? 0,
bizType: (json['biz_type'] as num?)?.toInt() ?? 0,
remark: (json['remark'] as String?) ?? '',
createdAt: (json['created_at'] as String?) ?? '',
);
}
/// 资产流水分页
class AssetRecordsPage {
const AssetRecordsPage({required this.total, required this.items});
final int total;
final List<AssetRecord> items;
factory AssetRecordsPage.fromJson(Map<String, dynamic> json) =>
AssetRecordsPage(
total: (json['total'] as num?)?.toInt() ?? 0,
items: ((json['list'] as List?) ?? const [])
.whereType<Map<String, dynamic>>()
.map(AssetRecord.fromJson)
.toList(),
);
}
/// 提现申请结果(《03-接口文档》9.5)
class WithdrawResult {
const WithdrawResult({
required this.withdrawNo,
required this.assets,
required this.amountYuan,
required this.status,
this.statusText = '',
});
final String withdrawNo;
final double assets;
final double amountYuan;
final int status;
final String statusText;
factory WithdrawResult.fromJson(Map<String, dynamic> json) =>
WithdrawResult(
withdrawNo: (json['withdraw_no'] as String?) ?? '',
assets: (json['assets'] as num?)?.toDouble() ?? 0,
amountYuan: (json['amount_yuan'] as num?)?.toDouble() ?? 0,
status: (json['status'] as num?)?.toInt() ?? 0,
statusText: (json['status_text'] as String?) ?? '',
);
}
/// 提现记录(《03-接口文档》9.6)
class WithdrawRecord {
const WithdrawRecord({
required this.withdrawNo,
required this.assets,
required this.amountYuan,
required this.channel,
required this.status,
this.statusText = '',
this.createdAt = '',
});
final String withdrawNo;
final double assets;
final double amountYuan;
/// 1支付宝 2微信 3USDT
final int channel;
/// 0待审核 1已打款 2已拒绝
final int status;
final String statusText;
final String createdAt;
static const Map<int, String> channelLabels = {
1: '支付宝',
2: '微信',
3: 'USDT',
};
String get channelLabel => channelLabels[channel] ?? '未知';
factory WithdrawRecord.fromJson(Map<String, dynamic> json) =>
WithdrawRecord(
withdrawNo: (json['withdraw_no'] as String?) ?? '',
assets: (json['assets'] as num?)?.toDouble() ?? 0,
amountYuan: (json['amount_yuan'] as num?)?.toDouble() ?? 0,
channel: (json['channel'] as num?)?.toInt() ?? 1,
status: (json['status'] as num?)?.toInt() ?? 0,
statusText: (json['status_text'] as String?) ?? '',
createdAt: (json['created_at'] as String?) ?? '',
);
}
/// 提现记录分页
class WithdrawRecordsPage {
const WithdrawRecordsPage({required this.total, required this.items});
final int total;
final List<WithdrawRecord> items;
factory WithdrawRecordsPage.fromJson(Map<String, dynamic> json) =>
WithdrawRecordsPage(
total: (json['total'] as num?)?.toInt() ?? 0,
items: ((json['list'] as List?) ?? const [])
.whereType<Map<String, dynamic>>()
.map(WithdrawRecord.fromJson)
.toList(),
);
}
/// 资产/提现服务(《03-接口文档》第 9 章,均需登录)
class AssetService {
AssetService._();
/// 9.3 我的资产
static Future<AssetWallet> fetchAssets() async {
final data =
await ApiClient.get<Map<String, dynamic>>(Endpoints.assetsMe);
return AssetWallet.fromJson(data);
}
/// 9.4 资产流水(biz_type 筛选 + 分页)
static Future<AssetRecordsPage> fetchRecords({
int page = 1,
int pageSize = 20,
int? bizType,
}) async {
final query = <String, dynamic>{'page': page, 'page_size': pageSize};
if (bizType != null) query['biz_type'] = bizType;
final data = await ApiClient.get<Map<String, dynamic>>(
Endpoints.assetsRecords,
queryParameters: query,
);
return AssetRecordsPage.fromJson(data);
}
/// 9.5 申请提现
/// 错误码:2102 资产余额不足,2103 低于最低提现额度,2104 已有审核中的提现申请
static Future<WithdrawResult> applyWithdraw({
required double assets,
required int channel,
required String account,
}) async {
final data = await ApiClient.post<Map<String, dynamic>>(
Endpoints.assetsWithdraw,
data: {'assets': assets, 'channel': channel, 'account': account},
);
return WithdrawResult.fromJson(data);
}
/// 9.6 提现记录
static Future<WithdrawRecordsPage> fetchWithdrawRecords({
int page = 1,
int pageSize = 20,
}) async {
final data = await ApiClient.get<Map<String, dynamic>>(
Endpoints.withdrawRecords,
queryParameters: {'page': page, 'page_size': pageSize},
);
return WithdrawRecordsPage.fromJson(data);
}
}