111
This commit is contained in:
1 parent
7c20242ad7
commit
382b8d660f
8 files changed
+802
-21
No files matched your search
@@ -3,11 +3,13 @@ import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:common_utils/common_utils.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_subscreen_plugin/flutter_subscreen_plugin.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:pj_supermarket_cloud/common/index.dart';
|
||||
import 'package:pj_supermarket_cloud/common/utils/order/terminal_order_recovery.dart';
|
||||
|
||||
mixin OrderMixin {
|
||||
static const _tag = "OrderMixin";
|
||||
@@ -15,6 +17,9 @@ mixin OrderMixin {
|
||||
/// 下单参数日志保留的最大字符数,与 HttpManage 请求日志的截断口径一致。
|
||||
static const _maxOrderParamLogLength = 2000;
|
||||
|
||||
/// 覆盖参数准备、下单、超时对账和本地收尾,避免多种硬件回调同时提交本次订单。
|
||||
bool _creatingApiOrder = false;
|
||||
|
||||
/// 当前收银弹框成功的人脸证据结果,只有人脸支付下单时才会消费并绑定订单号。
|
||||
Rxn<FaceStream> pendingFaceRecognition = Rxn<FaceStream>();
|
||||
|
||||
@@ -227,8 +232,8 @@ mixin OrderMixin {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 更新本地订单
|
||||
Future<bool> updateSqlOrder() async {
|
||||
/// 更新结算快照;只有已由扫码轮询确认支付时才提前写为 PAY,普通下单等待服务端确认。
|
||||
Future<bool> updateSqlOrder({bool paymentConfirmed = false}) async {
|
||||
if (ObjectUtil.isEmpty(sqlOrderId)) {
|
||||
logger.e("|$_tag|更新本地订单,失败本地订单id不存在");
|
||||
return false;
|
||||
@@ -253,7 +258,7 @@ mixin OrderMixin {
|
||||
sqlOrderDetail.hourType = hourType.value.code;
|
||||
sqlOrderDetail.type = orderType;
|
||||
sqlOrderDetail.payType = orderPayType.value!;
|
||||
sqlOrderDetail.status = OrderStatus.PAY;
|
||||
if (paymentConfirmed) sqlOrderDetail.status = OrderStatus.PAY;
|
||||
await orderDao.edit(sqlOrderDetail);
|
||||
logger.i("|$_tag|更新本地订单,成功orderId:|$sqlOrderId|;");
|
||||
await createSqlChildCar(sqlOrderDetail);
|
||||
@@ -294,8 +299,19 @@ mixin OrderMixin {
|
||||
return OrderApiPrepare(order: sqlOrderDetail!, setting: appSetting);
|
||||
}
|
||||
|
||||
// |接口|创建api订单
|
||||
/// 同一次结算只允许一个在途请求,重试始终沿用本地持久化的订单号。
|
||||
Future<T?> createApiOrder<T>() async {
|
||||
if (_creatingApiOrder) return null;
|
||||
_creatingApiOrder = true;
|
||||
try {
|
||||
return await _createApiOrder<T>();
|
||||
} finally {
|
||||
_creatingApiOrder = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 准备并提交原协议订单;网络响应丢失时先只读对账,确认后统一完成本地状态。
|
||||
Future<T?> _createApiOrder<T>() async {
|
||||
final prepare = await createApiOrderValidate();
|
||||
if (prepare == null) return null;
|
||||
|
||||
@@ -306,6 +322,11 @@ mixin OrderMixin {
|
||||
|
||||
final orderDao = appC.dataBase.getOrderDao;
|
||||
|
||||
// 固定本次请求的支付方式,异步网络处理期间不读取可能被硬件回调更新的选择状态。
|
||||
final submittedPayType = orderPayType.value!;
|
||||
final submittedDisplayType = orderPayDisplayType.value!;
|
||||
final anonymousPayment = OrderPayDisplayType.isOffline(submittedDisplayType);
|
||||
|
||||
// 获取下单商品
|
||||
List<Map<String, dynamic>> shopList = [];
|
||||
if (_sysType == SysType.CANTEEN) {
|
||||
@@ -332,7 +353,7 @@ mixin OrderMixin {
|
||||
final isNetwork = AppNetworkTool.isAutoNetwork();
|
||||
// 人脸支付订单在发起请求前把识别会话绑定到终端订单号;离线单同样绑定,
|
||||
// 联网同步并由服务端确认支付后,后台补传任务按订单号对账上传证据。
|
||||
final isFacePayment = orderPayType.value == OrderPayType.FACE;
|
||||
final isFacePayment = submittedPayType == OrderPayType.FACE;
|
||||
final faceSessionId = pendingFaceRecognition.value?.sessionId?.trim();
|
||||
var evidenceMetadataList = const <Map<String, dynamic>>[];
|
||||
String? evidenceAppVersion;
|
||||
@@ -355,19 +376,18 @@ mixin OrderMixin {
|
||||
"merchantId": serviceMerchantId!,
|
||||
"orderType": orderType.name,
|
||||
"orderSourceTypeId": getOrderSourceTypeId(),
|
||||
"orderPayType": orderPayType.value?.name,
|
||||
"orderPayType": submittedPayType.name,
|
||||
"list": shopList,
|
||||
"extraPrice": amountMealPrice.value,
|
||||
if (evidenceMetadataList.isNotEmpty)
|
||||
"evidenceMetadataList": evidenceMetadataList,
|
||||
if (evidenceAppVersion != null) "appVersion": evidenceAppVersion,
|
||||
};
|
||||
if (orderPayType.value != null &&
|
||||
appSetting.sysType == SysType.CANTEEN &&
|
||||
(orderPayType.value == OrderPayType.WALLET_QR_CODE)) {
|
||||
if (appSetting.sysType == SysType.CANTEEN &&
|
||||
(submittedPayType == OrderPayType.WALLET_QR_CODE)) {
|
||||
pa["walletId"] = globalQrCode?.id;
|
||||
} else if (OrderPayDisplayType.isSelectWalletPayType(
|
||||
orderPayDisplayType.value!)) {
|
||||
submittedDisplayType)) {
|
||||
if (payUser.value?.walletId != null) {
|
||||
pa["walletId"] = payUser.value?.walletId;
|
||||
}
|
||||
@@ -382,7 +402,7 @@ mixin OrderMixin {
|
||||
T? result;
|
||||
try {
|
||||
if (isNetwork) {
|
||||
if (orderPayType.value == OrderPayType.WALLET_QR_CODE_SCAN) {
|
||||
if (submittedPayType == OrderPayType.WALLET_QR_CODE_SCAN) {
|
||||
final data = await HardApi.createHardQrCodeScanOrder(pa);
|
||||
if (data == null) throw Error();
|
||||
if (ObjectUtil.isEmpty(data)) throw Error();
|
||||
@@ -391,7 +411,28 @@ mixin OrderMixin {
|
||||
sqlOrderDetail.serviceUniqueCode = data.orderId;
|
||||
result = data as T;
|
||||
} else {
|
||||
final data = await HardApi.createHardwareOrder(pa);
|
||||
String? data;
|
||||
try {
|
||||
data = await HardApi.createHardwareOrder(pa);
|
||||
} on DioException catch (error) {
|
||||
if (!TerminalOrderRecovery.shouldQuery(error)) rethrow;
|
||||
data = await TerminalOrderRecovery.recover(
|
||||
lookup: () => HardApi.getOrderByAndroidCode(
|
||||
hardId: serviceId!,
|
||||
androidOrderCode: sqlOrderDetail.uniqueCode,
|
||||
),
|
||||
// 旧 Flutter 枚举的消费卡 code 与人民医院重复;线上请求按名称编码,
|
||||
// 对账使用后端既有消费卡编码 14,不改动本地历史枚举和存储协议。
|
||||
payType: submittedPayType == OrderPayType.CSXFK
|
||||
? '14'
|
||||
: submittedPayType.code,
|
||||
userId: anonymousPayment ? null : pa['userId']?.toString(),
|
||||
totalPrice: sqlOrderDetail.price,
|
||||
extraPrice: sqlOrderDetail.extraPrice,
|
||||
);
|
||||
if (data == null) rethrow;
|
||||
logger.i('|$_tag|超时对账确认订单已支付|orderId:$data|');
|
||||
}
|
||||
if (data == null) throw Error();
|
||||
if (ObjectUtil.isEmpty(data)) throw Error();
|
||||
logger.i("|$_tag||有网络|创建api订单,下单成功res:|$data|");
|
||||
@@ -437,7 +478,7 @@ mixin OrderMixin {
|
||||
);
|
||||
}
|
||||
}
|
||||
if (orderPayType.value != OrderPayType.WALLET_QR_CODE_SCAN) {
|
||||
if (submittedPayType != OrderPayType.WALLET_QR_CODE_SCAN) {
|
||||
// 支付结果已落库,副屏通知只能尽力发送,不能等待其回执阻塞主屏订单收尾。
|
||||
unawaited(sendSubScreenPaySuccess());
|
||||
if (sqlOrderDetail.payPrice != 0) {
|
||||
|
||||
Reference in new issue
Block a user