68 lines
2.3 KiB
Dart
68 lines
2.3 KiB
Dart
|
|
// 功能描述:钱包账单的严格金额与收支语义模型;版本: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<String, Object?> 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<WalletBill> items;
|
|||
|
|
final String nextCursor;
|
|||
|
|
}
|