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 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 bizTypeLabels = { 1: '充值返利', 2: '观看收益', 3: '点赞收益', 4: '提现', 5: '提现退回', 6: '返利扣回', 7: '后台调整', }; String get bizTypeLabel => bizTypeLabels[bizType] ?? '其他'; bool get isExpense => changeAmount < 0; factory AssetRecord.fromJson(Map 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 items; factory AssetRecordsPage.fromJson(Map json) => AssetRecordsPage( total: (json['total'] as num?)?.toInt() ?? 0, items: ((json['list'] as List?) ?? const []) .whereType>() .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 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 channelLabels = { 1: '支付宝', 2: '微信', 3: 'USDT', }; String get channelLabel => channelLabels[channel] ?? '未知'; factory WithdrawRecord.fromJson(Map 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 items; factory WithdrawRecordsPage.fromJson(Map json) => WithdrawRecordsPage( total: (json['total'] as num?)?.toInt() ?? 0, items: ((json['list'] as List?) ?? const []) .whereType>() .map(WithdrawRecord.fromJson) .toList(), ); } /// 资产/提现服务(《03-接口文档》第 9 章,均需登录) class AssetService { AssetService._(); /// 9.3 我的资产 static Future fetchAssets() async { final data = await ApiClient.get>(Endpoints.assetsMe); return AssetWallet.fromJson(data); } /// 9.4 资产流水(biz_type 筛选 + 分页) static Future fetchRecords({ int page = 1, int pageSize = 20, int? bizType, }) async { final query = {'page': page, 'page_size': pageSize}; if (bizType != null) query['biz_type'] = bizType; final data = await ApiClient.get>( Endpoints.assetsRecords, queryParameters: query, ); return AssetRecordsPage.fromJson(data); } /// 9.5 申请提现 /// 错误码:2102 资产余额不足,2103 低于最低提现额度,2104 已有审核中的提现申请 static Future applyWithdraw({ required double assets, required int channel, required String account, }) async { final data = await ApiClient.post>( Endpoints.assetsWithdraw, data: {'assets': assets, 'channel': channel, 'account': account}, ); return WithdrawResult.fromJson(data); } /// 9.6 提现记录 static Future fetchWithdrawRecords({ int page = 1, int pageSize = 20, }) async { final data = await ApiClient.get>( Endpoints.withdrawRecords, queryParameters: {'page': page, 'page_size': pageSize}, ); return WithdrawRecordsPage.fromJson(data); } }