This commit is contained in:
dzc committed 2026-10-22 19:08:46 +08:00
1 parent 7c20242ad7
commit 382b8d660f
8 files changed
+802 -21

No files matched your search

@@ -0,0 +1,51 @@
import 'package:dio/dio.dart';
import 'package:pj_supermarket_cloud/common/models/api/hard_api_models.dart';
/// 处理下单响应丢失后的只读对账;调用方继续使用原本地订单号,不自动重放扣款请求。
abstract class TerminalOrderRecovery {
/// 网络超时、断连及网关服务错误可能丢失已成功响应,明确业务拒绝无需轮询。
static bool shouldQuery(DioException error) {
return error.type == DioExceptionType.connectionTimeout ||
error.type == DioExceptionType.sendTimeout ||
error.type == DioExceptionType.receiveTimeout ||
error.type == DioExceptionType.connectionError ||
(error.type == DioExceptionType.badResponse &&
(error.response?.statusCode ?? 0) >= 500);
}
/// 有限次读取原订单,只有状态、支付方式、金额及必要的人员均吻合才恢复成功。
///
/// 现金/第三方核销的实付值沿用后端旧约定,金额比对使用商品额与餐费,避免误判。
/// 查询异常(包括后端尚未部署新接口的 404)只会消耗本次尝试,不会触发再次扣款。
static Future<String?> recover({
required Future<ServiceOrderByAndroidCode?> Function() lookup,
required String payType,
required String? userId,
required int totalPrice,
required int extraPrice,
int attempts = 5,
Duration interval = const Duration(seconds: 2),
}) async {
for (var attempt = 0; attempt < attempts; attempt++) {
if (attempt > 0) await Future<void>.delayed(interval);
ServiceOrderByAndroidCode? order;
try {
order = await lookup();
} catch (_) {
continue;
}
if (order == null) continue;
if (order.orderId.isEmpty ||
order.orderStatus != '5' ||
order.payType != payType ||
order.totalPrice != totalPrice ||
order.extraPrice != extraPrice ||
(userId != null && order.userId != userId)) {
return null;
}
return order.orderId;
}
return null;
}
}