已完成用户APP首期功能开发
交付用户端首期页面、配套接口、后台资源及测试文档。用户APP构建、静态分析和三个管理后台构建通过;完整测试仍有2项失败,后端模型注释检查未通过,详见交付记录。
This commit is contained in:
93
apps/user_app/lib/domain/models/wallet_account.dart
Normal file
93
apps/user_app/lib/domain/models/wallet_account.dart
Normal file
@@ -0,0 +1,93 @@
|
||||
// 功能描述:银行卡与提现申请的严格领域模型;版本: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')));
|
||||
}
|
||||
Reference in New Issue
Block a user