Files
platforms/apps/user_app/lib/domain/models/wallet_bill.dart
czl231 3ef33b531d 已完成用户APP首期功能开发
交付用户端首期页面、配套接口、后台资源及测试文档。用户APP构建、静态分析和三个管理后台构建通过;完整测试仍有2项失败,后端模型注释检查未通过,详见交付记录。
2026-09-13 00:57:32 +08:00

68 lines
2.3 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 功能描述钱包账单的严格金额与收支语义模型版本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;
}