// 功能描述:钱包账单的严格金额与收支语义模型;版本:1.0.0。 import 'client_models.dart'; /// 账单是已记账事实,不把未完成订单或提现申请伪装成成功流水。 class WalletBill { const WalletBill({ required this.identity, required this.number, required this.direction, required this.tradeType, required this.amount, required this.fee, required this.balanceAfter, required this.createdAt, required this.channel, }); final String identity, number, direction, tradeType, channel; final int amount, fee, balanceAfter; final DateTime createdAt; bool get income => direction == 'income'; String get signedAmount => '${income ? '+' : '-'}${moneyText(amount)}'; String get title => switch (tradeType) { 'recharge' => '余额充值', 'refund' => '退款入账', 'ec_order' => '商城订单', 'gas_order' => '气瓶订单', 'withdrawal_reserve' => '提现资金冻结', 'withdrawal_release' => '提现资金退回', 'withdrawal_complete' => '提现完成', _ => '其他账单', }; factory WalletBill.fromJson(Map json) { int amount(String key, {bool positive = false}) { final value = json[key]; if (value is! int || value < (positive ? 1 : 0)) { throw const FormatException('账单金额格式异常'); } return value; } final direction = json['direction']; final date = DateTime.tryParse(json['created_at'] as String? ?? ''); if (!['income', 'expense'].contains(direction) || date == null || (json['identity'] as String? ?? '').isEmpty) { throw const FormatException('账单信息不完整'); } return WalletBill( identity: json['identity'] as String, number: json['record_no'] as String? ?? '', direction: direction as String, tradeType: json['trade_type'] as String? ?? '', amount: amount('amount', positive: true), fee: amount('fee'), balanceAfter: amount('balance_after'), createdAt: date.toLocal(), channel: json['pay_channel'] as String? ?? '', ); } } /// 分页游标由服务端提供,不依据客户端条数猜测是否还有数据。 class WalletBillPage { const WalletBillPage(this.items, this.nextCursor); final List items; final String nextCursor; }