@pisell/private-materials 6.12.157 → 6.12.158

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/preview.js +1 -1
  6. package/build/lowcode/render/default/view.js +6 -6
  7. package/build/lowcode/view.js +6 -6
  8. package/es/components/checkout/PaymentModal.js +552 -392
  9. package/es/components/checkout/components/PaymentOptionsModule/PaymentMethodItem.js +16 -8
  10. package/es/components/checkout/components/PaymentOptionsModule/index.js +2 -1
  11. package/es/components/checkout/components/SearchAndClientModule/index.js +12 -4
  12. package/es/components/checkout/hooks/useCheckoutPaymentScanActivity.js +80 -0
  13. package/es/components/checkout/hooks/useSharedWalletPass.js +54 -7
  14. package/es/components/checkout/hooks/useWalletPass.js +45 -7
  15. package/es/components/checkout/locales.js +15 -0
  16. package/es/components/checkout/paymentRuntime/PaymentMethodRuntime.js +35 -6
  17. package/es/components/pay/toB/components/EFTPOS/index.js +44 -7
  18. package/es/components/pay/toB/components/MX51/index.js +11 -1
  19. package/es/components/pay/toB/paymentMethods/index.js +31 -17
  20. package/es/plus/salesSdk/demo/hosts/legacyOpenProductDetail.js +1 -7
  21. package/lib/components/checkout/PaymentModal.js +552 -392
  22. package/lib/components/checkout/components/PaymentOptionsModule/PaymentMethodItem.js +16 -8
  23. package/lib/components/checkout/components/PaymentOptionsModule/index.js +2 -1
  24. package/lib/components/checkout/components/SearchAndClientModule/index.js +12 -4
  25. package/lib/components/checkout/hooks/useCheckoutPaymentScanActivity.js +81 -0
  26. package/lib/components/checkout/hooks/useSharedWalletPass.js +54 -7
  27. package/lib/components/checkout/hooks/useWalletPass.js +45 -7
  28. package/lib/components/checkout/locales.js +15 -0
  29. package/lib/components/checkout/paymentRuntime/PaymentMethodRuntime.js +35 -6
  30. package/lib/components/pay/toB/components/EFTPOS/index.js +44 -7
  31. package/lib/components/pay/toB/components/MX51/index.js +11 -1
  32. package/lib/components/pay/toB/paymentMethods/index.js +31 -17
  33. package/lib/plus/salesSdk/demo/hosts/legacyOpenProductDetail.js +1 -7
  34. package/package.json +3 -3
@@ -10,7 +10,7 @@ import { Iconfont } from "@pisell/materials";
10
10
  import classNames from "classnames";
11
11
  import "./index.less";
12
12
  //#region src/components/checkout/components/PaymentOptionsModule/PaymentMethodItem.tsx
13
- const PaymentMethodItem = ({ method, amountSymbol, customAmount, disabled = false, onClick, getText, size = "default", surchargeDisplay, directCustomPayment = false, currentBaseSales }) => {
13
+ const PaymentMethodItem = ({ method, amountSymbol, customAmount, disabled = false, onClick, getText, size = "default", surchargeDisplay, directCustomPayment = false, beginKioskPaymentActivity, currentBaseSales }) => {
14
14
  var _context$appHelper;
15
15
  const context = useEngineContext();
16
16
  const { getData, getApp } = (context === null || context === void 0 || (_context$appHelper = context.appHelper) === null || _context$appHelper === void 0 ? void 0 : _context$appHelper.utils) || {};
@@ -69,17 +69,25 @@ const PaymentMethodItem = ({ method, amountSymbol, customAmount, disabled = fals
69
69
  var _ref = _asyncToGenerator(function* () {
70
70
  if (isEftpos) return;
71
71
  if (paymentChannel === "kiosk") {
72
+ const finishPaymentActivity = beginKioskPaymentActivity === null || beginKioskPaymentActivity === void 0 ? void 0 : beginKioskPaymentActivity(`authorization:${method.code || "unknown"}`);
73
+ if (beginKioskPaymentActivity && !finishPaymentActivity) return;
72
74
  try {
73
75
  var _currentBaseSales$get, _window;
74
76
  const otherParams = (yield Promise.resolve(currentBaseSales === null || currentBaseSales === void 0 || (_currentBaseSales$get = currentBaseSales.getOtherParams) === null || _currentBaseSales$get === void 0 ? void 0 : _currentBaseSales$get.call(currentBaseSales))) || (currentBaseSales === null || currentBaseSales === void 0 ? void 0 : currentBaseSales.otherParams) || {};
75
- (_window = window) === null || _window === void 0 || (_window = _window.app) === null || _window === void 0 || _window.applicationManager.get("global").runFunction("authorizeAction", { params: {
76
- action: "pay",
77
- business_code: otherParams.businessCode || otherParams.business_code,
78
- paymentMethodCode: method.code,
79
- paymentMethodType: method.type,
80
- amount: customAmount
81
- } });
77
+ if (finishPaymentActivity && !finishPaymentActivity.isActive()) return;
78
+ const authorizationResult = yield Promise.resolve((_window = window) === null || _window === void 0 || (_window = _window.app) === null || _window === void 0 ? void 0 : _window.applicationManager.get("global").runFunction("authorizeAction", {
79
+ onClose: finishPaymentActivity,
80
+ params: {
81
+ action: "pay",
82
+ business_code: otherParams.businessCode || otherParams.business_code,
83
+ paymentMethodCode: method.code,
84
+ paymentMethodType: method.type,
85
+ amount: customAmount
86
+ }
87
+ }));
88
+ if (String((authorizationResult === null || authorizationResult === void 0 ? void 0 : authorizationResult.status) || "").toLowerCase() !== "success") finishPaymentActivity === null || finishPaymentActivity === void 0 || finishPaymentActivity();
82
89
  } catch (error) {
90
+ finishPaymentActivity === null || finishPaymentActivity === void 0 || finishPaymentActivity();
83
91
  console.error("[PaymentMethodItem] request payment authorization failed", error);
84
92
  }
85
93
  return;
@@ -10,7 +10,7 @@ import classNames from "classnames";
10
10
  import { useDebounceFn } from "ahooks";
11
11
  import "./index.less";
12
12
  //#region src/components/checkout/components/PaymentOptionsModule/index.tsx
13
- function PaymentOptionsModule({ amountSymbol, orderInfo, onClick, paymentMethods = [], customAmount, title, disabled = false, showCashPayment = false, channel = "pos", columnCount, sciSurchargeDisplayMap = {}, directCustomPayment = false, isModalOpen = false, paymentMethodsReady = false, autoTriggerSinglePaymentOption = false, currentBaseSales }) {
13
+ function PaymentOptionsModule({ amountSymbol, orderInfo, onClick, paymentMethods = [], customAmount, title, disabled = false, showCashPayment = false, channel = "pos", columnCount, sciSurchargeDisplayMap = {}, directCustomPayment = false, isModalOpen = false, paymentMethodsReady = false, autoTriggerSinglePaymentOption = false, beginKioskPaymentActivity, currentBaseSales }) {
14
14
  var _context$appHelper, _context$appHelper$ge, _context$appHelper$ge2, _context$appHelper$ut;
15
15
  const context = useEngineContext();
16
16
  locales.init(locales_default, ((_context$appHelper = context.appHelper) === null || _context$appHelper === void 0 || (_context$appHelper = _context$appHelper.utils) === null || _context$appHelper === void 0 || (_context$appHelper$ge = _context$appHelper.getApp) === null || _context$appHelper$ge === void 0 || (_context$appHelper$ge = _context$appHelper$ge.call(_context$appHelper)) === null || _context$appHelper$ge === void 0 || (_context$appHelper$ge = _context$appHelper$ge.locales) === null || _context$appHelper$ge === void 0 || (_context$appHelper$ge2 = _context$appHelper$ge.getLocale) === null || _context$appHelper$ge2 === void 0 ? void 0 : _context$appHelper$ge2.call(_context$appHelper$ge)) || ((_context$appHelper$ut = context.appHelper.utils) === null || _context$appHelper$ut === void 0 || (_context$appHelper$ut = _context$appHelper$ut.storage) === null || _context$appHelper$ut === void 0 ? void 0 : _context$appHelper$ut.get("umi_locale")) || "en");
@@ -86,6 +86,7 @@ function PaymentOptionsModule({ amountSymbol, orderInfo, onClick, paymentMethods
86
86
  getText,
87
87
  surchargeDisplay: sciSurchargeDisplayMap[String(method.id)],
88
88
  directCustomPayment,
89
+ beginKioskPaymentActivity,
89
90
  currentBaseSales
90
91
  })))));
91
92
  }
@@ -71,7 +71,7 @@ function extractContactsInfo(customer) {
71
71
  }
72
72
  const SearchAndClientModule = (props) => {
73
73
  var _context$appHelper2, _baseSales$getBooking, _baseSales$getBooking2, _bookingConfig$config, _context$appHelper4;
74
- const { disabledSwitch, clientInfo, onSearch, onClientChange, baseSales: propBaseSales, baseSalesModuleName, enableScanner = true, showCustomerSelect = true } = props;
74
+ const { disabledSwitch, clientInfo, onSearch, beginScanActivity, onClientChange, baseSales: propBaseSales, baseSalesModuleName, enableScanner = true, showCustomerSelect = true } = props;
75
75
  const [loading, setLoading] = useState(false);
76
76
  const [customerLoading, setCustomerLoading] = useState(false);
77
77
  const [customerLoadingMore, setCustomerLoadingMore] = useState(false);
@@ -111,9 +111,15 @@ const SearchAndClientModule = (props) => {
111
111
  const handleFindSearch = useCallback(function() {
112
112
  var _ref2 = _asyncToGenerator(function* (keyword) {
113
113
  if (!(keyword === null || keyword === void 0 ? void 0 : keyword.trim())) return;
114
+ const finishScanActivity = beginScanActivity === null || beginScanActivity === void 0 ? void 0 : beginScanActivity();
115
+ if (beginScanActivity && !finishScanActivity) {
116
+ var _findRef$current;
117
+ (_findRef$current = findRef.current) === null || _findRef$current === void 0 || _findRef$current.setKeyword("");
118
+ return;
119
+ }
114
120
  setLoading(true);
115
121
  try {
116
- var _findRef$current;
122
+ var _findRef$current2;
117
123
  const res = yield onSearch === null || onSearch === void 0 ? void 0 : onSearch(keyword);
118
124
  const sharedAsset = res === null || res === void 0 ? void 0 : res.asset;
119
125
  if (!(Boolean(sharedAsset) || (Array.isArray(res === null || res === void 0 ? void 0 : res.data) ? res.data.length > 0 : Boolean(res === null || res === void 0 ? void 0 : res.data)))) {
@@ -135,11 +141,12 @@ const SearchAndClientModule = (props) => {
135
141
  return;
136
142
  }
137
143
  const _customer = _objectSpread2(_objectSpread2({}, customer), {}, { latest_wallet_detail: rest });
138
- (_clientSelectorRef$cu = clientSelectorRef.current) === null || _clientSelectorRef$cu === void 0 || (_clientSelectorRef$cu2 = _clientSelectorRef$cu.handleSetClient) === null || _clientSelectorRef$cu2 === void 0 || _clientSelectorRef$cu2.call(_clientSelectorRef$cu, _customer, { sameClientTip: locales.getText("pisell2.checkout.client-card.tip.same-client") });
144
+ yield (_clientSelectorRef$cu = clientSelectorRef.current) === null || _clientSelectorRef$cu === void 0 || (_clientSelectorRef$cu2 = _clientSelectorRef$cu.handleSetClient) === null || _clientSelectorRef$cu2 === void 0 ? void 0 : _clientSelectorRef$cu2.call(_clientSelectorRef$cu, _customer, { sameClientTip: locales.getText("pisell2.checkout.client-card.tip.same-client") });
139
145
  }
140
- (_findRef$current = findRef.current) === null || _findRef$current === void 0 || _findRef$current.setKeyword("");
146
+ (_findRef$current2 = findRef.current) === null || _findRef$current2 === void 0 || _findRef$current2.setKeyword("");
141
147
  } catch (error) {} finally {
142
148
  setLoading(false);
149
+ finishScanActivity === null || finishScanActivity === void 0 || finishScanActivity();
143
150
  }
144
151
  });
145
152
  return function(_x) {
@@ -147,6 +154,7 @@ const SearchAndClientModule = (props) => {
147
154
  };
148
155
  }(), [
149
156
  Toast,
157
+ beginScanActivity,
150
158
  disabledSwitch,
151
159
  onSearch
152
160
  ]);
@@ -0,0 +1,80 @@
1
+ import { useEffect, useMemo, useRef, useState } from "react";
2
+ import { useMemoizedFn } from "ahooks";
3
+ //#region src/components/checkout/hooks/useCheckoutPaymentScanActivity.ts
4
+ const NOOP_RELEASE = () => void 0;
5
+ /**
6
+ * Checkout 内部的支付/扫码双向活动锁。
7
+ *
8
+ * 同步 ref 用于事件回调的竞态判断,React state 只用于驱动禁用态。
9
+ * 同一时刻只允许一个活动成功占锁,避免扫码和支付在 React rerender 前同时进入。
10
+ */
11
+ function useCheckoutPaymentScanActivity(enabled) {
12
+ const activeActivityRef = useRef();
13
+ const mountedRef = useRef(true);
14
+ const [isPaymentProcessing, setIsPaymentProcessing] = useState(false);
15
+ const [isScanProcessing, setIsScanProcessing] = useState(false);
16
+ const tryBeginActivity = useMemoizedFn((type) => {
17
+ if (!enabled) return NOOP_RELEASE;
18
+ if (activeActivityRef.current) return null;
19
+ const token = Symbol(type);
20
+ activeActivityRef.current = {
21
+ token,
22
+ type
23
+ };
24
+ if (mountedRef.current) {
25
+ setIsPaymentProcessing(type === "payment");
26
+ setIsScanProcessing(type === "scan");
27
+ }
28
+ let released = false;
29
+ return () => {
30
+ var _activeActivityRef$cu;
31
+ if (released) return;
32
+ released = true;
33
+ if (((_activeActivityRef$cu = activeActivityRef.current) === null || _activeActivityRef$cu === void 0 ? void 0 : _activeActivityRef$cu.token) !== token) return;
34
+ activeActivityRef.current = void 0;
35
+ if (mountedRef.current) {
36
+ setIsPaymentProcessing(false);
37
+ setIsScanProcessing(false);
38
+ }
39
+ };
40
+ });
41
+ const tryBeginPayment = useMemoizedFn(() => tryBeginActivity("payment"));
42
+ const tryBeginScan = useMemoizedFn(() => tryBeginActivity("scan"));
43
+ const getIsPaymentProcessing = useMemoizedFn(() => {
44
+ var _activeActivityRef$cu2;
45
+ return enabled && ((_activeActivityRef$cu2 = activeActivityRef.current) === null || _activeActivityRef$cu2 === void 0 ? void 0 : _activeActivityRef$cu2.type) === "payment";
46
+ });
47
+ const getIsScanProcessing = useMemoizedFn(() => {
48
+ var _activeActivityRef$cu3;
49
+ return enabled && ((_activeActivityRef$cu3 = activeActivityRef.current) === null || _activeActivityRef$cu3 === void 0 ? void 0 : _activeActivityRef$cu3.type) === "scan";
50
+ });
51
+ useEffect(() => {
52
+ mountedRef.current = true;
53
+ return () => {
54
+ mountedRef.current = false;
55
+ };
56
+ }, []);
57
+ useEffect(() => {
58
+ if (enabled) return;
59
+ activeActivityRef.current = void 0;
60
+ setIsPaymentProcessing(false);
61
+ setIsScanProcessing(false);
62
+ }, [enabled]);
63
+ return useMemo(() => ({
64
+ tryBeginPayment,
65
+ tryBeginScan,
66
+ getIsPaymentProcessing,
67
+ getIsScanProcessing,
68
+ isPaymentProcessing,
69
+ isScanProcessing
70
+ }), [
71
+ tryBeginPayment,
72
+ tryBeginScan,
73
+ getIsPaymentProcessing,
74
+ getIsScanProcessing,
75
+ isPaymentProcessing,
76
+ isScanProcessing
77
+ ]);
78
+ }
79
+ //#endregion
80
+ export { useCheckoutPaymentScanActivity as default };
@@ -63,6 +63,8 @@ function useSharedWalletPass(props) {
63
63
  const [loadingAction, setLoadingAction] = useState(false);
64
64
  const deferWalletStateRef = useRef(false);
65
65
  const deferredWalletStateRef = useRef(null);
66
+ const pendingSearchApplyRef = useRef(null);
67
+ const pendingSearchApplyAttachedRef = useRef(false);
66
68
  useEffect(() => {
67
69
  var _baseSales$getWalletA2, _baseSales$getDiscoun2;
68
70
  const current = baseSales === null || baseSales === void 0 || (_baseSales$getWalletA2 = baseSales.getWalletAssetsState) === null || _baseSales$getWalletA2 === void 0 ? void 0 : _baseSales$getWalletA2.call(baseSales);
@@ -93,8 +95,35 @@ function useSharedWalletPass(props) {
93
95
  };
94
96
  }, [baseSales]);
95
97
  useEffect(() => {
96
- onSelectChange === null || onSelectChange === void 0 || onSelectChange(toSelection(state));
98
+ let notification;
99
+ try {
100
+ notification = onSelectChange === null || onSelectChange === void 0 ? void 0 : onSelectChange(toSelection(state));
101
+ } catch (error) {
102
+ var _pendingSearchApplyRe;
103
+ (_pendingSearchApplyRe = pendingSearchApplyRef.current) === null || _pendingSearchApplyRe === void 0 || _pendingSearchApplyRe.call(pendingSearchApplyRef);
104
+ pendingSearchApplyRef.current = null;
105
+ pendingSearchApplyAttachedRef.current = false;
106
+ throw error;
107
+ }
108
+ const resolvePendingSearch = pendingSearchApplyRef.current;
109
+ if (resolvePendingSearch && !pendingSearchApplyAttachedRef.current) {
110
+ pendingSearchApplyAttachedRef.current = true;
111
+ const finishPendingSearch = () => {
112
+ if (pendingSearchApplyRef.current === resolvePendingSearch) {
113
+ pendingSearchApplyRef.current = null;
114
+ pendingSearchApplyAttachedRef.current = false;
115
+ }
116
+ resolvePendingSearch();
117
+ };
118
+ Promise.resolve(notification).then(finishPendingSearch, finishPendingSearch);
119
+ }
97
120
  }, [onSelectChange, state.revision]);
121
+ useEffect(() => () => {
122
+ var _pendingSearchApplyRe2;
123
+ (_pendingSearchApplyRe2 = pendingSearchApplyRef.current) === null || _pendingSearchApplyRe2 === void 0 || _pendingSearchApplyRe2.call(pendingSearchApplyRef);
124
+ pendingSearchApplyRef.current = null;
125
+ pendingSearchApplyAttachedRef.current = false;
126
+ }, []);
98
127
  const selectedWalletIds = useMemo(() => [...state.selectedIds || [], ...state.committedIds || []], [state.committedIds, state.selectedIds]);
99
128
  const committedKeys = useMemo(() => new Set((state.committedIds || []).map((id) => String(id))), [state.committedIds]);
100
129
  const selectedItemByKey = useMemo(() => new Map((state.selectedItems || []).map((asset) => {
@@ -179,14 +208,17 @@ function useSharedWalletPass(props) {
179
208
  }
180
209
  }));
181
210
  const handleSearchIdentificationCode = useMemoizedFn(function() {
182
- var _ref7 = _asyncToGenerator(function* (code) {
211
+ var _ref7 = _asyncToGenerator(function* (code, options) {
183
212
  if (!(baseSales === null || baseSales === void 0 ? void 0 : baseSales.scanWalletAsset)) return null;
184
213
  setLoadingAction(true);
185
214
  deferWalletStateRef.current = true;
186
215
  deferredWalletStateRef.current = null;
216
+ let searchCompleted = false;
217
+ const initialRevision = state.revision;
187
218
  try {
188
219
  var _asset$customer_id, _asset$holder, _baseSales$getOrderCu, _ref6, _currentCustomer$id;
189
220
  const result = yield baseSales.scanWalletAsset(code);
221
+ searchCompleted = true;
190
222
  const asset = result === null || result === void 0 ? void 0 : result.asset;
191
223
  const customerId = Number((_asset$customer_id = asset === null || asset === void 0 ? void 0 : asset.customer_id) !== null && _asset$customer_id !== void 0 ? _asset$customer_id : asset === null || asset === void 0 || (_asset$holder = asset.holder) === null || _asset$holder === void 0 ? void 0 : _asset$holder.customer_id);
192
224
  const currentCustomer = baseSales === null || baseSales === void 0 || (_baseSales$getOrderCu = baseSales.getOrderCustomerSnapshot) === null || _baseSales$getOrderCu === void 0 ? void 0 : _baseSales$getOrderCu.call(baseSales);
@@ -206,11 +238,26 @@ function useSharedWalletPass(props) {
206
238
  deferWalletStateRef.current = false;
207
239
  const finalState = (baseSales === null || baseSales === void 0 || (_baseSales$getWalletA3 = baseSales.getWalletAssetsState) === null || _baseSales$getWalletA3 === void 0 ? void 0 : _baseSales$getWalletA3.call(baseSales)) || deferredWalletStateRef.current;
208
240
  deferredWalletStateRef.current = null;
209
- if (finalState) setState(finalState);
210
- setLoadingAction(false);
241
+ let waitForApply;
242
+ try {
243
+ if (finalState) {
244
+ if ((options === null || options === void 0 ? void 0 : options.waitForApply) && searchCompleted && !Object.is(finalState.revision, initialRevision)) {
245
+ var _pendingSearchApplyRe3;
246
+ (_pendingSearchApplyRe3 = pendingSearchApplyRef.current) === null || _pendingSearchApplyRe3 === void 0 || _pendingSearchApplyRe3.call(pendingSearchApplyRef);
247
+ pendingSearchApplyAttachedRef.current = false;
248
+ waitForApply = new Promise((resolve) => {
249
+ pendingSearchApplyRef.current = resolve;
250
+ });
251
+ }
252
+ setState(finalState);
253
+ }
254
+ yield waitForApply;
255
+ } finally {
256
+ setLoadingAction(false);
257
+ }
211
258
  }
212
259
  });
213
- return function(_x2) {
260
+ return function(_x2, _x3) {
214
261
  return _ref7.apply(this, arguments);
215
262
  };
216
263
  }());
@@ -239,7 +286,7 @@ function useSharedWalletPass(props) {
239
286
  setLoadingAction(false);
240
287
  }
241
288
  });
242
- return function(_x3) {
289
+ return function(_x4) {
243
290
  return _ref8.apply(this, arguments);
244
291
  };
245
292
  }());
@@ -282,7 +329,7 @@ function useSharedWalletPass(props) {
282
329
  setLoadingAction(false);
283
330
  }
284
331
  });
285
- return function(_x4, _x5, _x6) {
332
+ return function(_x5, _x6, _x7) {
286
333
  return _ref9.apply(this, arguments);
287
334
  };
288
335
  }());
@@ -119,6 +119,8 @@ const useWalletPass = (props) => {
119
119
  const historyDiscountIdsRef = useRef(/* @__PURE__ */ new Set());
120
120
  const historyDiscountOrderKeyRef = useRef("");
121
121
  const activeClientKeyRef = useRef("");
122
+ const pendingSearchApplyRef = useRef(null);
123
+ const pendingSearchApplyAttachedRef = useRef(false);
122
124
  const [searchIdentificationCodeList, setSearchIdentificationCodeList] = useState([]);
123
125
  const [orderInfo, setOrderInfo] = useState({});
124
126
  const [selectedWallet, setSelectedWallet] = useState([]);
@@ -452,10 +454,37 @@ const useWalletPass = (props) => {
452
454
  baseSales
453
455
  ]);
454
456
  useDebounceEffect(() => {
455
- notifySelectChange(selectedWithDetails);
457
+ let notification;
458
+ try {
459
+ notification = notifySelectChange(selectedWithDetails);
460
+ } catch (error) {
461
+ var _pendingSearchApplyRe;
462
+ (_pendingSearchApplyRe = pendingSearchApplyRef.current) === null || _pendingSearchApplyRe === void 0 || _pendingSearchApplyRe.call(pendingSearchApplyRef);
463
+ pendingSearchApplyRef.current = null;
464
+ pendingSearchApplyAttachedRef.current = false;
465
+ throw error;
466
+ }
456
467
  setWalletSelect(selectedWithDetails);
457
468
  setLoading(false);
469
+ const resolvePendingSearch = pendingSearchApplyRef.current;
470
+ if (resolvePendingSearch && !pendingSearchApplyAttachedRef.current) {
471
+ pendingSearchApplyAttachedRef.current = true;
472
+ const finishPendingSearch = () => {
473
+ if (pendingSearchApplyRef.current === resolvePendingSearch) {
474
+ pendingSearchApplyRef.current = null;
475
+ pendingSearchApplyAttachedRef.current = false;
476
+ }
477
+ resolvePendingSearch();
478
+ };
479
+ Promise.resolve(notification).then(finishPendingSearch, finishPendingSearch);
480
+ }
458
481
  }, [selectedWithDetails], { wait: 200 });
482
+ useEffect(() => () => {
483
+ var _pendingSearchApplyRe2;
484
+ (_pendingSearchApplyRe2 = pendingSearchApplyRef.current) === null || _pendingSearchApplyRe2 === void 0 || _pendingSearchApplyRe2.call(pendingSearchApplyRef);
485
+ pendingSearchApplyRef.current = null;
486
+ pendingSearchApplyAttachedRef.current = false;
487
+ }, []);
459
488
  const data = useMemo(() => {
460
489
  return formatMachineCodeServer2CardList(uniqueByKey(mergeDataWithInitialOrder([
461
490
  ...selectedWithDetails,
@@ -587,6 +616,7 @@ const useWalletPass = (props) => {
587
616
  setNoApplicableVoucher(allDisabledData);
588
617
  setWalletSelect(newValues);
589
618
  setSelectedVoucherIds(newValues.map((item) => item.id));
619
+ return isAvailableData.length === 1;
590
620
  });
591
621
  const applyWalletInitResult = useMemoizedFn((result) => {
592
622
  var _baseSales$getOrderSn5, _walletApi$getStoredW;
@@ -759,23 +789,31 @@ const useWalletPass = (props) => {
759
789
  select
760
790
  }
761
791
  });
762
- onSelectChange === null || onSelectChange === void 0 || onSelectChange(select);
792
+ return onSelectChange === null || onSelectChange === void 0 ? void 0 : onSelectChange(select);
763
793
  });
764
794
  const handleSearchIdentificationCode = useMemoizedFn(function() {
765
- var _ref12 = _asyncToGenerator(function* (value) {
795
+ var _ref12 = _asyncToGenerator(function* (value, options) {
766
796
  var _walletApi$formatWall3;
767
797
  if (!(walletApi === null || walletApi === void 0 ? void 0 : walletApi.searchIdentificationCodeAsync)) return null;
768
798
  const result = yield walletApi.searchIdentificationCodeAsync({
769
799
  code: value,
770
800
  prepare_payments: ((_walletApi$formatWall3 = walletApi.formatWalletPassList2PreparePayments) === null || _walletApi$formatWall3 === void 0 ? void 0 : _walletApi$formatWall3.call(walletApi, selectedWithDetails)) || []
771
801
  });
772
- handleSearchIdentificationCodeCompleted({
802
+ const willApplySelection = handleSearchIdentificationCodeCompleted({
773
803
  currentSearchResults: (result === null || result === void 0 ? void 0 : result.data) || [],
774
804
  cachedSearchResults: searchIdentificationCodeList
775
805
  });
806
+ if ((options === null || options === void 0 ? void 0 : options.waitForApply) && willApplySelection) {
807
+ var _pendingSearchApplyRe3;
808
+ (_pendingSearchApplyRe3 = pendingSearchApplyRef.current) === null || _pendingSearchApplyRe3 === void 0 || _pendingSearchApplyRe3.call(pendingSearchApplyRef);
809
+ pendingSearchApplyAttachedRef.current = false;
810
+ yield new Promise((resolve) => {
811
+ pendingSearchApplyRef.current = resolve;
812
+ });
813
+ }
776
814
  return result;
777
815
  });
778
- return function(_x3) {
816
+ return function(_x3, _x4) {
779
817
  return _ref12.apply(this, arguments);
780
818
  };
781
819
  }());
@@ -925,7 +963,7 @@ const useWalletPass = (props) => {
925
963
  setLoading(false);
926
964
  }
927
965
  });
928
- return function(_x4, _x5) {
966
+ return function(_x5, _x6) {
929
967
  return _ref13.apply(this, arguments);
930
968
  };
931
969
  }());
@@ -981,7 +1019,7 @@ const useWalletPass = (props) => {
981
1019
  var _ref14 = _asyncToGenerator(function* (value, index, data) {
982
1020
  return true;
983
1021
  });
984
- return function(_x6, _x7, _x8) {
1022
+ return function(_x7, _x8, _x9) {
985
1023
  return _ref14.apply(this, arguments);
986
1024
  };
987
1025
  }()),
@@ -45,6 +45,9 @@ var locales_default = {
45
45
  "payment.failed": "Payment Failed",
46
46
  "payment.cancelled": "Payment Cancelled",
47
47
  "payment.processing": "Processing Payment",
48
+ "pisell2.checkout.scan-blocked-by-payment": "Payment is processing. This scan was not applied. Please scan again after payment is complete.",
49
+ "pisell2.checkout.payment-blocked-by-scan": "A wallet pass is being applied. Please wait before starting payment.",
50
+ "pisell2.checkout.wallet-scan-processing": "A wallet pass is being applied. Please wait before scanning again.",
48
51
  "close": "Close",
49
52
  "cancel": "Cancel",
50
53
  "confirm": "Confirm",
@@ -245,6 +248,9 @@ var locales_default = {
245
248
  "payment.failed": "支付失败",
246
249
  "payment.cancelled": "支付取消",
247
250
  "payment.processing": "支付处理中",
251
+ "pisell2.checkout.scan-blocked-by-payment": "支付处理中,本次扫码未生效,请在支付完成后重新扫码",
252
+ "pisell2.checkout.payment-blocked-by-scan": "卡券处理中,请稍后再支付",
253
+ "pisell2.checkout.wallet-scan-processing": "卡券处理中,请稍后再扫码",
248
254
  "close": "关闭",
249
255
  "cancel": "取消",
250
256
  "confirm": "确认",
@@ -447,6 +453,9 @@ var locales_default = {
447
453
  "payment.failed": "支付失敗",
448
454
  "payment.cancelled": "支付取消",
449
455
  "payment.processing": "支付處理中",
456
+ "pisell2.checkout.scan-blocked-by-payment": "支付處理中,本次掃碼未生效,請在支付完成後重新掃碼",
457
+ "pisell2.checkout.payment-blocked-by-scan": "卡券處理中,請稍後再支付",
458
+ "pisell2.checkout.wallet-scan-processing": "卡券處理中,請稍後再掃碼",
450
459
  "close": "關閉",
451
460
  "cancel": "取消",
452
461
  "confirm": "確認",
@@ -649,6 +658,9 @@ var locales_default = {
649
658
  "payment.failed": "支払い失敗",
650
659
  "payment.cancelled": "支払いキャンセル",
651
660
  "payment.processing": "支払い処理中",
661
+ "pisell2.checkout.scan-blocked-by-payment": "支払い処理中のため、このスキャンは適用されませんでした。支払い完了後にもう一度スキャンしてください。",
662
+ "pisell2.checkout.payment-blocked-by-scan": "ウォレットパスを処理中です。処理完了後に支払いを開始してください。",
663
+ "pisell2.checkout.wallet-scan-processing": "ウォレットパスを処理中です。処理完了後にもう一度スキャンしてください。",
652
664
  "close": "閉じる",
653
665
  "cancel": "キャンセル",
654
666
  "confirm": "確認",
@@ -848,6 +860,9 @@ var locales_default = {
848
860
  "payment.failed": "Pagamento Falhou",
849
861
  "payment.cancelled": "Pagamento Cancelado",
850
862
  "payment.processing": "Processando Pagamento",
863
+ "pisell2.checkout.scan-blocked-by-payment": "O pagamento está sendo processado. Esta leitura não foi aplicada. Leia novamente após a conclusão do pagamento.",
864
+ "pisell2.checkout.payment-blocked-by-scan": "Um passe da carteira está sendo aplicado. Aguarde antes de iniciar o pagamento.",
865
+ "pisell2.checkout.wallet-scan-processing": "Um passe da carteira está sendo aplicado. Aguarde antes de ler novamente.",
851
866
  "close": "Fechar",
852
867
  "cancel": "Cancelar",
853
868
  "confirm": "Confirmar",
@@ -69,8 +69,8 @@ var PaymentMethodRuntime_default = memo(forwardRef(function PaymentMethodRuntime
69
69
  };
70
70
  useImperativeHandle(ref, () => ({
71
71
  onPay: (type, params) => {
72
- var _paymentMethodsRef$cu;
73
- return (_paymentMethodsRef$cu = paymentMethodsRef.current) === null || _paymentMethodsRef$cu === void 0 ? void 0 : _paymentMethodsRef$cu.onPay(type, params);
72
+ var _paymentMethodsRef$cu, _paymentMethodsRef$cu2;
73
+ return (_paymentMethodsRef$cu = (_paymentMethodsRef$cu2 = paymentMethodsRef.current) === null || _paymentMethodsRef$cu2 === void 0 ? void 0 : _paymentMethodsRef$cu2.onPay(type, params)) !== null && _paymentMethodsRef$cu !== void 0 ? _paymentMethodsRef$cu : Promise.resolve(false);
74
74
  },
75
75
  openPi: (options) => {
76
76
  var _piPaymentRef$current;
@@ -110,8 +110,17 @@ var PaymentMethodRuntime_default = memo(forwardRef(function PaymentMethodRuntime
110
110
  const configuredSurcharge = calculateSurcharge(method, amount);
111
111
  const formattedSurcharge = String(formatAmount(configuredSurcharge, 2));
112
112
  if (SPI_PAYMENT_CODES.includes(code)) return new Promise((resolve) => {
113
- var _paymentMethodsRef$cu2, _baseSales$getOrderId3;
114
- (_paymentMethodsRef$cu2 = paymentMethodsRef.current) === null || _paymentMethodsRef$cu2 === void 0 || _paymentMethodsRef$cu2.onPay("mx51", {
113
+ var _baseSales$getOrderId3;
114
+ const paymentMethods = paymentMethodsRef.current;
115
+ if (!paymentMethods) {
116
+ resolve({
117
+ status: "failed",
118
+ amount,
119
+ message: "Payment method is unavailable."
120
+ });
121
+ return;
122
+ }
123
+ paymentMethods.onPay("mx51", {
115
124
  source: "normal",
116
125
  data: {
117
126
  payMethod: method,
@@ -163,6 +172,12 @@ var PaymentMethodRuntime_default = memo(forwardRef(function PaymentMethodRuntime
163
172
  raw: data
164
173
  });
165
174
  }
175
+ }).then((opened) => {
176
+ if (!opened) resolve({
177
+ status: "failed",
178
+ amount,
179
+ message: "Payment method is unavailable."
180
+ });
166
181
  });
167
182
  });
168
183
  const usePiPayment = !!(context === null || context === void 0 || (_context$appHelper2 = context.appHelper) === null || _context$appHelper2 === void 0 || (_context$appHelper2 = _context$appHelper2.utils) === null || _context$appHelper2 === void 0 || (_context$appHelper2 = _context$appHelper2.businessUtils) === null || _context$appHelper2 === void 0 || (_context$appHelper2$i = _context$appHelper2.isPiPaymentEnabled) === null || _context$appHelper2$i === void 0 ? void 0 : _context$appHelper2$i.call(_context$appHelper2));
@@ -273,8 +288,16 @@ var PaymentMethodRuntime_default = memo(forwardRef(function PaymentMethodRuntime
273
288
  }
274
289
  const orderId = yield ensureRemoteOrderId(baseSales);
275
290
  return new Promise((resolve) => {
276
- var _paymentMethodsRef$cu3;
277
- (_paymentMethodsRef$cu3 = paymentMethodsRef.current) === null || _paymentMethodsRef$cu3 === void 0 || _paymentMethodsRef$cu3.onPay("eftpos", {
291
+ const paymentMethods = paymentMethodsRef.current;
292
+ if (!paymentMethods) {
293
+ resolve({
294
+ status: "failed",
295
+ amount,
296
+ message: "Payment method is unavailable."
297
+ });
298
+ return;
299
+ }
300
+ paymentMethods.onPay("eftpos", {
278
301
  source: "normal",
279
302
  data: {
280
303
  payMethod: method,
@@ -322,6 +345,12 @@ var PaymentMethodRuntime_default = memo(forwardRef(function PaymentMethodRuntime
322
345
  raw: data
323
346
  });
324
347
  }
348
+ }).then((opened) => {
349
+ if (!opened) resolve({
350
+ status: "failed",
351
+ amount,
352
+ message: "Payment method is unavailable."
353
+ });
325
354
  });
326
355
  });
327
356
  });
@@ -18,12 +18,14 @@ const updateTransactionReceiveStatus = function() {
18
18
  }();
19
19
  const EFTPOS = (props, ref) => {
20
20
  var _context$appHelper;
21
- const { interaction } = ((_context$appHelper = useEngineContext().appHelper) === null || _context$appHelper === void 0 ? void 0 : _context$appHelper.utils) || {};
21
+ const { interaction, getData } = ((_context$appHelper = useEngineContext().appHelper) === null || _context$appHelper === void 0 ? void 0 : _context$appHelper.utils) || {};
22
+ const paymentChannel = String((getData === null || getData === void 0 ? void 0 : getData("channel")) || "pos").trim().toLowerCase();
22
23
  const logger = useLogger();
23
24
  const network = useNetwork();
24
25
  const [visible, setVisible] = useState(false);
25
26
  const eftposRef = useRef(null);
26
27
  const payCallbackRef = useRef(null);
28
+ const openResultResolveRef = useRef(null);
27
29
  const eftposHandlingRef = useRef(false);
28
30
  const eftposOpenParamsRef = useRef(null);
29
31
  const eftposInitDataRef = useRef(null);
@@ -34,11 +36,23 @@ const EFTPOS = (props, ref) => {
34
36
  (_eftposRef$current = eftposRef.current) === null || _eftposRef$current === void 0 || (_eftposRef$current$up = _eftposRef$current.updateNetwork) === null || _eftposRef$current$up === void 0 || _eftposRef$current$up.call(_eftposRef$current, { network: network.online });
35
37
  }
36
38
  }, [network.online]);
39
+ const settleOpenResult = (accepted) => {
40
+ const resolve = openResultResolveRef.current;
41
+ if (!resolve) return;
42
+ openResultResolveRef.current = null;
43
+ resolve(accepted);
44
+ };
37
45
  const closeModal = () => {
46
+ settleOpenResult(false);
38
47
  setIsEftposLoading(false);
39
48
  eftposHandlingRef.current = false;
40
49
  setVisible(false);
41
50
  };
51
+ useEffect(() => () => {
52
+ const resolve = openResultResolveRef.current;
53
+ openResultResolveRef.current = null;
54
+ resolve === null || resolve === void 0 || resolve(false);
55
+ }, []);
42
56
  /**
43
57
  * @title: 打开支付弹窗
44
58
  * @param {ToBPayParams} data 支付参数
@@ -46,26 +60,45 @@ const EFTPOS = (props, ref) => {
46
60
  * @param {string} source 支付来源(正常支付、恢复支付)
47
61
  */
48
62
  const onOpen = function() {
49
- var _ref2 = _asyncToGenerator(function* ({ source, data, payCallback }) {
63
+ var _ref2 = _asyncToGenerator(function* ({ source, data, payCallback, isActive }) {
50
64
  if (eftposHandlingRef.current || visible) {
51
65
  logger === null || logger === void 0 || logger.addLog({
52
66
  type: "info",
53
67
  title: "ToB_EFTPOS_onOpen 重复触发被拦截",
54
68
  metadata: { data }
55
69
  });
56
- return;
70
+ return false;
57
71
  }
58
72
  eftposHandlingRef.current = true;
59
- let device_number = "";
60
- try {
73
+ const openResult = new Promise((resolve) => {
74
+ openResultResolveRef.current = resolve;
75
+ });
76
+ const initializationResult = yield Promise.race([Promise.resolve().then(() => {
61
77
  var _interaction$utils, _interaction$utils$as;
62
- device_number = yield interaction === null || interaction === void 0 || (_interaction$utils = interaction.utils) === null || _interaction$utils === void 0 || (_interaction$utils$as = _interaction$utils.asyncDataManager) === null || _interaction$utils$as === void 0 ? void 0 : _interaction$utils$as.call(_interaction$utils, {
78
+ return interaction === null || interaction === void 0 || (_interaction$utils = interaction.utils) === null || _interaction$utils === void 0 || (_interaction$utils$as = _interaction$utils.asyncDataManager) === null || _interaction$utils$as === void 0 ? void 0 : _interaction$utils$as.call(_interaction$utils, {
63
79
  module: "get",
64
80
  key: "device_number"
65
81
  });
66
- } catch (error) {
82
+ }).then((deviceNumber) => ({
83
+ status: "ready",
84
+ deviceNumber: deviceNumber || ""
85
+ })).catch((error) => {
67
86
  console.error("获取设备编号失败", error);
87
+ return {
88
+ status: "ready",
89
+ deviceNumber: ""
90
+ };
91
+ }), openResult.then((accepted) => ({
92
+ status: "settled",
93
+ accepted
94
+ }))]);
95
+ if (initializationResult.status === "settled") return initializationResult.accepted;
96
+ if (isActive && !isActive()) {
97
+ eftposHandlingRef.current = false;
98
+ settleOpenResult(false);
99
+ return false;
68
100
  }
101
+ const device_number = initializationResult.deviceNumber;
69
102
  const { type, payMethod, params, mode } = data;
70
103
  const newData = {
71
104
  type,
@@ -108,6 +141,7 @@ const EFTPOS = (props, ref) => {
108
141
  };
109
142
  setVisible(true);
110
143
  setIsEftposLoading(true);
144
+ return openResult;
111
145
  });
112
146
  return function onOpen(_x2) {
113
147
  return _ref2.apply(this, arguments);
@@ -120,6 +154,7 @@ const EFTPOS = (props, ref) => {
120
154
  metadata: { status }
121
155
  });
122
156
  setIsEftposLoading(false);
157
+ settleOpenResult(status);
123
158
  if (!status) closeModal();
124
159
  };
125
160
  const onAfterOpenChange = (v) => {
@@ -160,6 +195,7 @@ const EFTPOS = (props, ref) => {
160
195
  params
161
196
  }
162
197
  });
198
+ if (status === "success" || status === "fail") settleOpenResult(true);
163
199
  handleResult(status, params);
164
200
  if (status === "success" || status === "fail") {
165
201
  var _payCallbackRef$curre;
@@ -177,6 +213,7 @@ const EFTPOS = (props, ref) => {
177
213
  return /* @__PURE__ */ React.createElement(Modal, {
178
214
  open: visible,
179
215
  onCancel: closeModal,
216
+ keyboard: paymentChannel !== "kiosk",
180
217
  footer: null,
181
218
  closable: false,
182
219
  width: "fit-content",