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

75 lines
3.0 KiB
Dart
Raw 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 '../repositories/client_repository.dart';
import '../../domain/models/recharge.dart';
import 'recharge_draft_store.dart';
import 'api_client.dart';
/// 单个页面使用一个实例;所有网络写入前确认存储所属账号。
class RechargeFlow {
RechargeFlow(this.repository, this.store);
final ClientRepository repository;
final RechargeDraftStore store;
bool _busy = false;
Future<Map<String, Object?>> create(PendingRecharge draft) async {
if (_busy) throw StateError('充值正在处理中');
_busy = true;
try {
final owner = await repository.rechargeDraftOwner();
final previous = await store.read(owner);
if (previous != null &&
(previous.request != draft.request ||
previous.amount != draft.amount ||
previous.channel != draft.channel ||
previous.payType != draft.payType)) {
throw StateError('请先查询待确认充值');
}
if (previous != null) {
// 重试先读取入账事实,避免到账后再次拉起原支付参数。
try {
final result = await repository.rechargeResult(previous.request);
if (result.amount != previous.amount || result.channel != previous.channel) {
throw StateError('充值结果与原请求不一致');
}
if (await repository.rechargeDraftOwner() != owner) throw StateError('充值账户已切换');
if (result.credited) return {'recharge_status': 23};
} on ApiException catch (error) {
// 明确不存在才允许使用相同请求重发,网络异常不能推断订单不存在。
if (error.code != 1112) rethrow;
}
}
await store.write(owner, draft);
if (await repository.rechargeDraftOwner() != owner) throw StateError('充值账户已切换');
return await repository.createRecharge(
request: draft.request,
amount: draft.amount,
channel: draft.channel,
payType: draft.payType,
);
} finally {
_busy = false;
}
}
/// 未到账、查询失败或业务关联异常均保留原请求,方便再次核对。
Future<RechargeRecord?> recover() async {
if (_busy) throw StateError('充值正在处理中');
_busy = true;
try {
final owner = await repository.rechargeDraftOwner();
final draft = await store.read(owner);
if (draft == null) return null;
if (await repository.rechargeDraftOwner() != owner) throw StateError('充值账户已切换');
final result = await repository.rechargeResult(draft.request);
if (result.amount != draft.amount || result.channel != draft.channel) {
throw StateError('充值结果与原请求不一致');
}
if (await repository.rechargeDraftOwner() != owner) throw StateError('充值账户已切换');
if (result.credited) await store.delete(owner);
return result;
} finally {
_busy = false;
}
}
}