94 lines
2.8 KiB
Dart
94 lines
2.8 KiB
Dart
|
|
// 功能描述:银行卡与提现申请的严格领域模型;版本:1.0.0。
|
|||
|
|
|
|||
|
|
/// 本人已绑定银行卡只保留服务端返回的脱敏字段。
|
|||
|
|
class WalletBank {
|
|||
|
|
const WalletBank({
|
|||
|
|
required this.identity,
|
|||
|
|
required this.maskedNumber,
|
|||
|
|
required this.bankName,
|
|||
|
|
required this.owner,
|
|||
|
|
required this.type,
|
|||
|
|
required this.isDefault,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
final String identity, maskedNumber, bankName, owner, type;
|
|||
|
|
final bool isDefault;
|
|||
|
|
|
|||
|
|
factory WalletBank.fromJson(Map<String, Object?> json) {
|
|||
|
|
final identity = json['identity'], number = json['card_no_masked'];
|
|||
|
|
if (identity is! String || identity.isEmpty || number is! String || number.isEmpty) {
|
|||
|
|
throw const FormatException('银行卡数据不完整');
|
|||
|
|
}
|
|||
|
|
return WalletBank(
|
|||
|
|
identity: identity,
|
|||
|
|
maskedNumber: number,
|
|||
|
|
bankName: json['bank_name'] as String? ?? '银行卡',
|
|||
|
|
owner: json['card_owner'] as String? ?? '',
|
|||
|
|
type: json['bank_type'] as String? ?? '',
|
|||
|
|
isDefault: json['is_default'] == true,
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
String get typeName => switch (type) {
|
|||
|
|
'debit' || 'saving' => '储蓄卡',
|
|||
|
|
'credit' => '信用卡',
|
|||
|
|
_ => type,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 提现状态必须来自服务端,申请成功只表示进入审核流程。
|
|||
|
|
class WalletWithdrawal {
|
|||
|
|
const WalletWithdrawal({
|
|||
|
|
required this.identity,
|
|||
|
|
required this.number,
|
|||
|
|
required this.amount,
|
|||
|
|
required this.fee,
|
|||
|
|
required this.status,
|
|||
|
|
required this.createdAt,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
final String identity, number;
|
|||
|
|
final int amount, fee, status;
|
|||
|
|
final DateTime createdAt;
|
|||
|
|
|
|||
|
|
factory WalletWithdrawal.fromJson(Map<String, Object?> json) {
|
|||
|
|
final identity = json['identity'], amount = json['amount'], fee = json['fee'];
|
|||
|
|
final createdAt = DateTime.tryParse(json['created_at'] as String? ?? '');
|
|||
|
|
if (identity is! String ||
|
|||
|
|
identity.isEmpty ||
|
|||
|
|
amount is! int ||
|
|||
|
|
amount <= 0 ||
|
|||
|
|
fee is! int ||
|
|||
|
|
fee < 0 ||
|
|||
|
|
json['apply_status'] is! int ||
|
|||
|
|
createdAt == null) {
|
|||
|
|
throw const FormatException('提现记录数据不完整');
|
|||
|
|
}
|
|||
|
|
return WalletWithdrawal(
|
|||
|
|
identity: identity,
|
|||
|
|
number: json['cash_no'] as String? ?? '',
|
|||
|
|
amount: amount,
|
|||
|
|
fee: fee,
|
|||
|
|
status: json['apply_status'] as int,
|
|||
|
|
createdAt: createdAt.toLocal(),
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
String get statusName => switch (status) {
|
|||
|
|
10 => '待审核',
|
|||
|
|
18 => '处理中',
|
|||
|
|
23 => '已到账',
|
|||
|
|
30 => '已拒绝',
|
|||
|
|
31 => '已退回',
|
|||
|
|
_ => '状态待确认',
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 金额文本直接转整数分,禁止浮点舍入和指数格式。
|
|||
|
|
int? parseWithdrawalAmount(String value) {
|
|||
|
|
final text = value.trim();
|
|||
|
|
if (!RegExp(r'^\d{1,9}(\.\d{1,2})?$').hasMatch(text)) return null;
|
|||
|
|
final parts = text.split('.');
|
|||
|
|
return int.parse(parts[0]) * 100 + (parts.length == 1 ? 0 : int.parse(parts[1].padRight(2, '0')));
|
|||
|
|
}
|