feat:对接读写卡器

feat:优化用户下拉框搜索
feat:优化下单卡顿问题
feat:优化商户列表样式
This commit is contained in:
dzc committed 2026-10-13 17:26:11 +08:00
1 parent ceff6c8831
commit ba7e31dbd8
3 files changed
+116 -3

No files matched your search

@@ -488,9 +488,25 @@ mixin OrderMixin {
sqlOrderDetail.serviceUniqueCode = data.orderId;
result = data as T;
} else {
final data = await HardApi.createHardwareOrder(pa);
if (data == null) throw Error();
if (ObjectUtil.isEmpty(data)) throw Error();
String? data;
try {
data = await HardApi.createHardwareOrder(pa);
if (data == null) throw Error();
if (ObjectUtil.isEmpty(data)) throw Error();
} on DioException catch (e) {
// 统一网络层会把服务端业务拒绝(库存不足等)也包装成 DioException 抛出,
// 只有超时/连接类异常才存在"服务端已建单扣款但响应丢失"的可能,需要先对账。
final isTimeoutLike = e.type == DioExceptionType.connectionTimeout ||
e.type == DioExceptionType.sendTimeout ||
e.type == DioExceptionType.receiveTimeout ||
e.type == DioExceptionType.connectionError;
if (!isTimeoutLike) rethrow;
data = await _recoverTimeoutCreateOrder(
serviceId: serviceId!,
order: sqlOrderDetail,
);
if (data == null) rethrow;
}
logger.i("|$_tag||有网络|创建api订单,下单成功res:|$data|");
sqlOrderDetail.status = OrderStatus.PAY;
sqlOrderDetail.serviceUniqueCode = data;
@@ -596,6 +612,47 @@ mixin OrderMixin {
return null;
}
/// 创建订单请求超时后,按终端本地订单号反查服务端订单结果。
///
/// 网络抖动时服务端处理可能长达数十秒,终端 10 秒就超时,但订单可能已建单扣款成功;
/// 此结果必须找回并按成功收尾,否则收银员重试会造成重复下单。服务端已按本地订单号
/// 幂等(重复提交返回原订单),即使对账期间收银员再次点击也不会重复扣款。
/// 最多轮询 3 次(间隔 3 秒)等待服务端长事务提交;查到同号已支付且金额一致的订单时
/// 返回服务端订单号,否则返回 null 由调用方按原失败流程处理。
Future<String?> _recoverTimeoutCreateOrder({
required String serviceId,
required OrderEntity order,
}) async {
final expectedPayPrice = order.price + order.extraPrice;
for (var attempt = 0; attempt < 3; attempt++) {
if (attempt > 0) {
await Future<void>.delayed(const Duration(seconds: 3));
}
try {
final remote = await HardApi.getOrderByAndroidCode(
hardId: serviceId,
androidOrderCode: order.uniqueCode,
);
if (remote == null) continue;
// 状态 5=已支付,且金额与本次结算一致才认定为本次订单。
if (remote.orderStatus == '5' && remote.payPrice == expectedPayPrice) {
logger.i(
"|$_tag|超时对账命中已支付订单,orderId:|${remote.orderId}|attempt:|$attempt|",
);
return remote.orderId;
}
// 已查到订单但状态或金额不符(如已被退款、金额被调整),不再轮询等待。
logger.w(
"|$_tag|超时对账查到订单但状态或金额不符,orderStatus:|${remote.orderStatus}|payPrice:|${remote.payPrice}|expected:|$expectedPayPrice|",
);
return null;
} catch (error) {
logger.w("|$_tag|超时对账查询失败,attempt:|$attempt|error:|$error|");
}
}
return null;
}
/// 支付成功后从 SQLite 重读当前食堂分类,使扣减后的库存立即展示在商品卡片上。
///
/// 页面刷新失败不改变已经确认的支付结果;现有 `productSync` 会在后续空闲周期重新校准