已完成用户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,111 @@
// 功能描述用户押金汇总与单瓶押金事实版本1.0.0。
/// 单只气瓶的押金状态,金额单位为分。
class DepositRecord {
const DepositRecord({
required this.identity,
required this.depositNo,
required this.status,
required this.statusName,
required this.amount,
required this.productName,
required this.productCode,
required this.paidAt,
required this.refundedAt,
required this.allowedActions,
this.returnRequestIdentity = '',
this.returnStatusName = '',
});
final String identity, depositNo, statusName, productName, productCode;
final String returnRequestIdentity, returnStatusName;
final int status, amount;
final DateTime paidAt;
final DateTime? refundedAt;
final List<String> allowedActions;
factory DepositRecord.fromJson(Map<String, Object?> data) {
final paidAt = DateTime.tryParse(data['paid_at']?.toString() ?? '');
if (data['identity'] is! String ||
data['deposit_no'] is! String ||
data['deposit_status'] is! int ||
data['amount'] is! int ||
(data['amount'] as int) < 0 ||
paidAt == null) {
throw const FormatException('押金记录数据异常');
}
return DepositRecord(
identity: data['identity'] as String,
depositNo: data['deposit_no'] as String,
status: data['deposit_status'] as int,
statusName: data['status_name'] as String? ?? '处理中',
amount: data['amount'] as int,
productName: data['product_name'] as String? ?? '',
productCode: data['product_code'] as String? ?? '',
paidAt: paidAt.toLocal(),
refundedAt: data['refunded_at'] == null
? null
: DateTime.tryParse(data['refunded_at'].toString())?.toLocal(),
allowedActions: (data['allowed_actions'] as List? ?? []).whereType<String>().toList(),
returnRequestIdentity: data['return_request_identity'] as String? ?? '',
returnStatusName: data['return_status_name'] as String? ?? '',
);
}
}
/// 押金页一次读取的服务端快照。
class DepositSummary {
const DepositSummary({
required this.refundableAmount,
required this.usingCount,
required this.items,
required this.ruleText,
});
final int refundableAmount, usingCount;
final List<DepositRecord> items;
final String ruleText;
factory DepositSummary.fromJson(Map<String, Object?> data) {
if (data['refundable_amount'] is! int ||
data['using_count'] is! int ||
data['items'] is! List) {
throw const FormatException('押金汇总数据异常');
}
return DepositSummary(
refundableAmount: data['refundable_amount'] as int,
usingCount: data['using_count'] as int,
items: (data['items'] as List)
.whereType<Map<Object?, Object?>>()
.map((item) => DepositRecord.fromJson(Map<String, Object?>.from(item)))
.toList(),
ruleText: data['rule_text'] as String? ?? '',
);
}
}
// DepositReturnRequest 表示退瓶申请的可见状态,不暴露内部关联主键。
class DepositReturnRequest {
const DepositReturnRequest({
required this.identity,
required this.status,
required this.statusName,
required this.estimatedAmount,
required this.refundAmount,
});
final String identity, statusName;
final int status, estimatedAmount, refundAmount;
factory DepositReturnRequest.fromJson(Map<String, Object?> data) {
if (data['identity'] is! String || data['return_status'] is! int) {
throw const FormatException('退瓶申请数据不完整');
}
return DepositReturnRequest(
identity: data['identity'] as String,
status: data['return_status'] as int,
statusName: data['status_name'] as String? ?? '处理中',
estimatedAmount: data['estimated_amount'] as int? ?? 0,
refundAmount: data['refund_amount'] as int? ?? 0,
);
}
}