已完成用户APP首期功能开发

交付用户端首期页面、配套接口、后台资源及测试文档。用户APP构建、静态分析和三个管理后台构建通过;完整测试仍有2项失败,后端模型注释检查未通过,详见交付记录。
This commit is contained in:
czl231
2026-09-13 00:57:32 +08:00
parent a0a4bb1218
commit 3ef33b531d
793 changed files with 40959 additions and 1204 deletions

View 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')));
}