@pisell/pisellos 0.0.567 → 0.0.568
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.
- package/dist/core/index.js +6 -9
- package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -2
- package/dist/model/strategy/adapter/walletPass/example.js +3 -26
- package/dist/model/strategy/adapter/walletPass/utils.js +0 -3
- package/dist/model/strategy/strategy-example.js +5 -19
- package/dist/modules/Cart/index.js +0 -3
- package/dist/modules/Cart/utils/cartProduct.js +0 -1
- package/dist/modules/Date/index.js +1 -5
- package/dist/modules/Discount/index.js +1 -4
- package/dist/modules/OpenData/index.js +0 -2
- package/dist/modules/Order/index.d.ts +1 -1
- package/dist/modules/Order/index.js +14 -41
- package/dist/modules/Payment/index.js +142 -270
- package/dist/modules/Payment/walletpass.js +4 -5
- package/dist/modules/Rules/index.js +0 -7
- package/dist/modules/Schedule/utils.js +0 -1
- package/dist/modules/Step/index.js +0 -1
- package/dist/plugins/request.js +1 -4
- package/dist/plugins/window.js +2 -6
- package/dist/server/index.js +88 -121
- package/dist/server/modules/menu/index.js +32 -41
- package/dist/server/modules/products/index.js +29 -49
- package/dist/server/modules/quotation/index.js +29 -38
- package/dist/server/modules/resource/index.js +3 -4
- package/dist/server/modules/schedule/index.js +32 -40
- package/dist/server/utils/product.js +0 -1
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingByStep/index.js +7 -59
- package/dist/solution/BookingByStep/utils/capacity.js +1 -11
- package/dist/solution/BookingByStep/utils/resources.js +1 -3
- package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +5 -7
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
- package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
- package/dist/solution/BuyTickets/index.js +9 -12
- package/dist/solution/Checkout/index.js +177 -246
- package/dist/solution/Checkout/utils/index.js +4 -16
- package/dist/solution/RegisterAndLogin/index.js +30 -76
- package/dist/solution/ScanOrder/index.js +50 -60
- package/dist/solution/ShopDiscount/index.js +2 -7
- package/dist/solution/VenueBooking/index.d.ts +5 -0
- package/dist/solution/VenueBooking/index.js +364 -327
- package/dist/utils/task.js +15 -18
- package/dist/utils/watch.js +0 -1
- package/lib/apis/picoding.js +2 -0
- package/lib/core/index.js +130 -131
- package/lib/effects/index.js +46 -57
- package/lib/index.js +92 -53
- package/lib/model/index.js +14 -21
- package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
- package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
- package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
- package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
- package/lib/model/strategy/adapter/index.js +100 -64
- package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
- package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
- package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
- package/lib/model/strategy/adapter/itemRule/index.js +83 -57
- package/lib/model/strategy/adapter/itemRule/type.js +97 -36
- package/lib/model/strategy/adapter/promotion/adapter.js +84 -63
- package/lib/model/strategy/adapter/promotion/evaluator.js +381 -231
- package/lib/model/strategy/adapter/promotion/examples.js +139 -159
- package/lib/model/strategy/adapter/promotion/index.js +1 -49
- package/lib/model/strategy/adapter/promotion/type.js +199 -35
- package/lib/model/strategy/adapter/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -152
- package/lib/model/strategy/adapter/walletPass/example.js +217 -190
- package/lib/model/strategy/adapter/walletPass/index.js +75 -51
- package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
- package/lib/model/strategy/adapter/walletPass/type.js +4 -16
- package/lib/model/strategy/adapter/walletPass/utils.js +652 -402
- package/lib/model/strategy/engine.js +270 -168
- package/lib/model/strategy/index.js +49 -34
- package/lib/model/strategy/strategy-example.js +243 -239
- package/lib/model/strategy/type.js +100 -40
- package/lib/modules/Account/index.js +39 -53
- package/lib/modules/Account/types.js +20 -33
- package/lib/modules/AccountList/index.js +116 -154
- package/lib/modules/AccountList/types.js +30 -31
- package/lib/modules/AccountList/utils.js +18 -30
- package/lib/modules/BaseModule.js +22 -45
- package/lib/modules/Cart/index.js +170 -124
- package/lib/modules/Cart/types.js +46 -51
- package/lib/modules/Cart/utils/cartAccount.js +40 -39
- package/lib/modules/Cart/utils/cartDate.js +56 -61
- package/lib/modules/Cart/utils/cartDiscount.js +28 -33
- package/lib/modules/Cart/utils/cartNote.js +27 -32
- package/lib/modules/Cart/utils/cartProduct.js +306 -241
- package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
- package/lib/modules/Cart/utils/cartResource.js +72 -78
- package/lib/modules/Cart/utils/changePrice.js +26 -62
- package/lib/modules/Cart/utils/index.js +106 -48
- package/lib/modules/Customer/constants.js +13 -34
- package/lib/modules/Customer/index.js +216 -153
- package/lib/modules/Customer/types.js +38 -35
- package/lib/modules/Date/index.js +116 -115
- package/lib/modules/Date/types.js +16 -28
- package/lib/modules/Date/utils.js +174 -123
- package/lib/modules/Discount/index.js +117 -113
- package/lib/modules/Discount/types.js +9 -31
- package/lib/modules/Guests/index.js +30 -56
- package/lib/modules/Guests/types.js +23 -33
- package/lib/modules/Holder/index.js +209 -189
- package/lib/modules/Holder/types.js +4 -16
- package/lib/modules/Holder/utils.js +20 -49
- package/lib/modules/OpenData/index.js +63 -74
- package/lib/modules/OpenData/types.js +4 -16
- package/lib/modules/OpenData/utils.js +44 -78
- package/lib/modules/Order/index.d.ts +1 -1
- package/lib/modules/Order/index.js +332 -320
- package/lib/modules/Order/types.js +24 -33
- package/lib/modules/Order/utils.js +350 -284
- package/lib/modules/Payment/cash.js +20 -33
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
- package/lib/modules/Payment/eftpos.js +16 -30
- package/lib/modules/Payment/index.js +566 -432
- package/lib/modules/Payment/mx51.js +1 -0
- package/lib/modules/Payment/types.js +216 -107
- package/lib/modules/Payment/utils.js +50 -47
- package/lib/modules/Payment/walletpass.js +221 -203
- package/lib/modules/Product/index.js +51 -46
- package/lib/modules/Product/types.js +4 -16
- package/lib/modules/Product/utils.js +32 -33
- package/lib/modules/ProductList/index.js +111 -110
- package/lib/modules/ProductList/types.js +9 -31
- package/lib/modules/Quotation/index.js +60 -82
- package/lib/modules/Quotation/types.js +4 -16
- package/lib/modules/Resource/index.js +27 -59
- package/lib/modules/Resource/types.js +22 -32
- package/lib/modules/Resource/utils.js +30 -38
- package/lib/modules/Rules/index.js +1172 -872
- package/lib/modules/Rules/types.js +17 -40
- package/lib/modules/SalesSummary/index.js +59 -68
- package/lib/modules/SalesSummary/types.js +4 -16
- package/lib/modules/SalesSummary/utils.js +176 -193
- package/lib/modules/ScanOrderLogger/index.js +59 -79
- package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
- package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
- package/lib/modules/ScanOrderLogger/types.js +4 -16
- package/lib/modules/Schedule/getDateIsInSchedule.js +334 -167
- package/lib/modules/Schedule/index.js +97 -107
- package/lib/modules/Schedule/type.js +4 -16
- package/lib/modules/Schedule/types.js +4 -16
- package/lib/modules/Schedule/utils.js +433 -291
- package/lib/modules/Step/index.js +40 -52
- package/lib/modules/Step/tyeps.js +4 -16
- package/lib/modules/Summary/index.js +66 -70
- package/lib/modules/Summary/types.js +4 -16
- package/lib/modules/Summary/utils.js +782 -429
- package/lib/modules/index.js +212 -57
- package/lib/plugins/app.js +4 -16
- package/lib/plugins/index.js +36 -25
- package/lib/plugins/request.js +137 -126
- package/lib/plugins/shopStore.js +4 -16
- package/lib/plugins/user.js +4 -16
- package/lib/plugins/window.js +171 -179
- package/lib/server/index.js +882 -623
- package/lib/server/modules/index.js +85 -59
- package/lib/server/modules/menu/index.js +146 -122
- package/lib/server/modules/menu/types.js +18 -31
- package/lib/server/modules/order/index.js +195 -231
- package/lib/server/modules/order/types.js +107 -32
- package/lib/server/modules/order/utils/filterBookings.js +174 -140
- package/lib/server/modules/order/utils/filterOrders.js +89 -60
- package/lib/server/modules/products/index.js +430 -335
- package/lib/server/modules/products/types.js +41 -34
- package/lib/server/modules/quotation/index.js +76 -77
- package/lib/server/modules/quotation/types.js +21 -31
- package/lib/server/modules/resource/index.js +216 -187
- package/lib/server/modules/resource/types.js +42 -33
- package/lib/server/modules/schedule/index.js +134 -119
- package/lib/server/modules/schedule/types.js +14 -21
- package/lib/server/modules/schedule/utils.js +334 -163
- package/lib/server/types.js +4 -16
- package/lib/server/utils/index.js +25 -23
- package/lib/server/utils/product.js +196 -139
- package/lib/server/utils/schedule.js +34 -41
- package/lib/server/utils/time.js +40 -49
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingByStep/index.js +1530 -1343
- package/lib/solution/BookingByStep/types.js +40 -99
- package/lib/solution/BookingByStep/utils/capacity.js +192 -160
- package/lib/solution/BookingByStep/utils/products.js +42 -52
- package/lib/solution/BookingByStep/utils/resources.js +527 -330
- package/lib/solution/BookingByStep/utils/stock.js +65 -44
- package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +147 -122
- package/lib/solution/BookingTicket/types.js +38 -64
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +64 -80
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +82 -80
- package/lib/solution/BookingTicket/utils/scan/index.js +90 -94
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
- package/lib/solution/BuyTickets/index.js +67 -70
- package/lib/solution/BuyTickets/types.js +22 -38
- package/lib/solution/Checkout/index.js +1451 -1158
- package/lib/solution/Checkout/types.js +91 -61
- package/lib/solution/Checkout/utils/index.js +227 -158
- package/lib/solution/PlaceOrder/index.js +55 -0
- package/lib/solution/RegisterAndLogin/config.js +493 -460
- package/lib/solution/RegisterAndLogin/index.js +633 -630
- package/lib/solution/RegisterAndLogin/types.js +189 -76
- package/lib/solution/RegisterAndLogin/utils.js +183 -125
- package/lib/solution/Sales/index.js +218 -200
- package/lib/solution/Sales/types.js +27 -33
- package/lib/solution/ScanOrder/index.js +803 -840
- package/lib/solution/ScanOrder/types.js +34 -34
- package/lib/solution/ScanOrder/utils.js +372 -331
- package/lib/solution/ShopDiscount/index.js +230 -236
- package/lib/solution/ShopDiscount/types.js +15 -37
- package/lib/solution/ShopDiscount/utils.js +309 -172
- package/lib/solution/VenueBooking/index.d.ts +5 -0
- package/lib/solution/VenueBooking/index.js +886 -929
- package/lib/solution/VenueBooking/types.js +20 -40
- package/lib/solution/VenueBooking/utils/dateSummary.js +22 -54
- package/lib/solution/VenueBooking/utils/resource.js +31 -54
- package/lib/solution/VenueBooking/utils/slotMerge.js +88 -106
- package/lib/solution/VenueBooking/utils/smartPricing.js +112 -100
- package/lib/solution/VenueBooking/utils/timeSlot.js +133 -132
- package/lib/solution/VenueBooking/utils.js +130 -67
- package/lib/solution/index.js +102 -37
- package/lib/store/createStore.js +32 -29
- package/lib/types/index.js +4 -16
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +81 -47
- package/package.json +2 -1
|
@@ -1,114 +1,93 @@
|
|
|
1
|
-
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
"use strict";
|
|
29
2
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
__export(ScanOrder_exports, {
|
|
33
|
-
ScanOrderImpl: () => ScanOrderImpl
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
34
5
|
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
ScanOrderImpl: true
|
|
8
|
+
};
|
|
9
|
+
exports.ScanOrderImpl = void 0;
|
|
10
|
+
var _BaseModule = require("../../modules/BaseModule");
|
|
11
|
+
var _types = require("./types");
|
|
12
|
+
Object.keys(_types).forEach(function (key) {
|
|
13
|
+
if (key === "default" || key === "__esModule") return;
|
|
14
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
15
|
+
if (key in exports && exports[key] === _types[key]) return;
|
|
16
|
+
Object.defineProperty(exports, key, {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () {
|
|
19
|
+
return _types[key];
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
var _Order = require("../../modules/Order");
|
|
24
|
+
var _types2 = require("../../modules/Account/types");
|
|
25
|
+
var _types3 = require("../RegisterAndLogin/types");
|
|
26
|
+
var _decimal = _interopRequireDefault(require("decimal.js"));
|
|
27
|
+
var _utils = require("./utils");
|
|
28
|
+
var _types4 = require("../BookingByStep/types");
|
|
29
|
+
var _ProductList = require("../../modules/ProductList");
|
|
30
|
+
var _Schedule = require("../../modules/Schedule");
|
|
31
|
+
var _getDateIsInSchedule = require("../../modules/Schedule/getDateIsInSchedule");
|
|
32
|
+
var _utils2 = require("../../modules/Order/utils");
|
|
33
|
+
var _dayjs = _interopRequireDefault(require("dayjs"));
|
|
34
|
+
var _itemRule = require("../../model/strategy/adapter/itemRule");
|
|
35
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
36
|
+
class ScanOrderImpl extends _BaseModule.BaseModule {
|
|
37
|
+
defaultName = 'scanOrder';
|
|
38
|
+
defaultVersion = '1.0.0';
|
|
39
|
+
isSolution = true;
|
|
40
|
+
initializeOptions = {};
|
|
41
|
+
store = {
|
|
42
|
+
entryContext: null,
|
|
43
|
+
status: 'idle',
|
|
44
|
+
config: null,
|
|
45
|
+
resource: null,
|
|
46
|
+
flow: {},
|
|
47
|
+
error: null,
|
|
48
|
+
products: undefined,
|
|
49
|
+
itemRuleQuantityLimits: [],
|
|
50
|
+
cartValidation: {
|
|
51
|
+
passed: null,
|
|
52
|
+
failures: []
|
|
53
|
+
},
|
|
54
|
+
entryPaxNumber: 1
|
|
55
|
+
};
|
|
56
|
+
otherParams = {};
|
|
57
|
+
cacheId;
|
|
58
|
+
window;
|
|
59
|
+
request;
|
|
60
|
+
itemRuleEvaluator = new _itemRule.ItemRuleEvaluator();
|
|
61
|
+
itemRuleConfigs = [];
|
|
62
|
+
itemRuleConfigsPromise = null;
|
|
63
|
+
itemRulePrefillApplied = false;
|
|
64
|
+
itemRuleRuntimeConfig = {};
|
|
65
|
+
/** 最近一次 checkResourceAvailable 从预约规则 link 拉取的商品快照 */
|
|
66
|
+
enabledReservationRuleProducts = [];
|
|
67
|
+
loginEffectDisposers = [];
|
|
68
|
+
customerLoginRefreshInFlight = null;
|
|
69
|
+
customerLoginRefreshIdInFlight = null;
|
|
70
|
+
static PISELL1_LOGIN_SUCCESS = 'pisell1.login.success';
|
|
85
71
|
getScanOrderLoggerContext() {
|
|
86
72
|
return {
|
|
87
73
|
cacheId: this.cacheId,
|
|
88
74
|
solutionName: this.name,
|
|
89
|
-
moduleName:
|
|
75
|
+
moduleName: 'scanOrder'
|
|
90
76
|
};
|
|
91
77
|
}
|
|
92
78
|
safeStringify(value) {
|
|
93
79
|
try {
|
|
94
80
|
return JSON.stringify(value);
|
|
95
81
|
} catch {
|
|
96
|
-
return
|
|
82
|
+
return undefined;
|
|
97
83
|
}
|
|
98
84
|
}
|
|
99
85
|
pickErrorMessage(error) {
|
|
100
|
-
|
|
101
|
-
const candidates = [
|
|
102
|
-
error.message,
|
|
103
|
-
(_a = error.data) == null ? void 0 : _a.message,
|
|
104
|
-
(_c = (_b = error.response) == null ? void 0 : _b.data) == null ? void 0 : _c.message,
|
|
105
|
-
(_d = error.error) == null ? void 0 : _d.message
|
|
106
|
-
];
|
|
86
|
+
const candidates = [error.message, error.data?.message, error.response?.data?.message, error.error?.message];
|
|
107
87
|
for (const candidate of candidates) {
|
|
108
|
-
if (typeof candidate ===
|
|
109
|
-
return candidate;
|
|
88
|
+
if (typeof candidate === 'string' && candidate.trim()) return candidate;
|
|
110
89
|
}
|
|
111
|
-
return
|
|
90
|
+
return undefined;
|
|
112
91
|
}
|
|
113
92
|
serializeError(error) {
|
|
114
93
|
if (error instanceof Error) {
|
|
@@ -118,15 +97,23 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
118
97
|
stack: error.stack
|
|
119
98
|
};
|
|
120
99
|
}
|
|
121
|
-
if (error && typeof error ===
|
|
100
|
+
if (error && typeof error === 'object') {
|
|
122
101
|
const raw = error;
|
|
123
102
|
const message = this.pickErrorMessage(raw) || this.safeStringify(raw) || String(error);
|
|
124
103
|
return {
|
|
125
|
-
...typeof raw.name ===
|
|
104
|
+
...(typeof raw.name === 'string' ? {
|
|
105
|
+
name: raw.name
|
|
106
|
+
} : {}),
|
|
126
107
|
message,
|
|
127
|
-
...
|
|
128
|
-
|
|
129
|
-
|
|
108
|
+
...('code' in raw ? {
|
|
109
|
+
code: raw.code
|
|
110
|
+
} : {}),
|
|
111
|
+
...('status' in raw ? {
|
|
112
|
+
status: raw.status
|
|
113
|
+
} : {}),
|
|
114
|
+
...(this.safeStringify(raw) ? {
|
|
115
|
+
raw: this.safeStringify(raw)
|
|
116
|
+
} : {})
|
|
130
117
|
};
|
|
131
118
|
}
|
|
132
119
|
return {
|
|
@@ -136,18 +123,19 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
136
123
|
async addScanOrderLog(params) {
|
|
137
124
|
const payload = {
|
|
138
125
|
cacheId: this.cacheId,
|
|
139
|
-
...params.payload || {}
|
|
126
|
+
...(params.payload || {})
|
|
140
127
|
};
|
|
141
128
|
const extra = {
|
|
142
|
-
...params.extra || {}
|
|
129
|
+
...(params.extra || {})
|
|
143
130
|
};
|
|
144
131
|
const logger = this.store.scanOrderLogger;
|
|
145
132
|
if (!logger) {
|
|
146
|
-
if ((params.level ||
|
|
147
|
-
console.error(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
133
|
+
if ((params.level || 'info') === 'error') {
|
|
134
|
+
console.error('[ScanOrder][log-fallback]', params.title, {
|
|
135
|
+
payload,
|
|
136
|
+
extra
|
|
137
|
+
});
|
|
138
|
+
} else {}
|
|
151
139
|
return;
|
|
152
140
|
}
|
|
153
141
|
await logger.addLog({
|
|
@@ -158,7 +146,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
158
146
|
}
|
|
159
147
|
logMethodStart(method, payload = {}) {
|
|
160
148
|
void this.addScanOrderLog({
|
|
161
|
-
level:
|
|
149
|
+
level: 'info',
|
|
162
150
|
title: `[ScanOrder] ${method} start`,
|
|
163
151
|
payload: {
|
|
164
152
|
method,
|
|
@@ -168,7 +156,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
168
156
|
}
|
|
169
157
|
logMethodSuccess(method, payload = {}) {
|
|
170
158
|
void this.addScanOrderLog({
|
|
171
|
-
level:
|
|
159
|
+
level: 'info',
|
|
172
160
|
title: `[ScanOrder] ${method} success`,
|
|
173
161
|
payload: {
|
|
174
162
|
method,
|
|
@@ -178,7 +166,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
178
166
|
}
|
|
179
167
|
logMethodError(method, error, payload = {}) {
|
|
180
168
|
void this.addScanOrderLog({
|
|
181
|
-
level:
|
|
169
|
+
level: 'error',
|
|
182
170
|
title: `[ScanOrder] ${method} failed`,
|
|
183
171
|
payload: {
|
|
184
172
|
method,
|
|
@@ -188,9 +176,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
188
176
|
});
|
|
189
177
|
}
|
|
190
178
|
assertProductListLoaded(method, result, payload = {}) {
|
|
191
|
-
if (Array.isArray(result))
|
|
192
|
-
|
|
193
|
-
const error = result instanceof Error ? result : new Error("商品列表接口返回异常");
|
|
179
|
+
if (Array.isArray(result)) return result;
|
|
180
|
+
const error = result instanceof Error ? result : new Error('商品列表接口返回异常');
|
|
194
181
|
this.logMethodError(method, error, payload);
|
|
195
182
|
error.__scanOrderLogged = true;
|
|
196
183
|
throw error;
|
|
@@ -199,36 +186,21 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
199
186
|
await this.addScanOrderLog({
|
|
200
187
|
...params,
|
|
201
188
|
payload: {
|
|
202
|
-
source:
|
|
203
|
-
...params.payload || {}
|
|
189
|
+
source: 'ui-bridge',
|
|
190
|
+
...(params.payload || {})
|
|
204
191
|
}
|
|
205
192
|
});
|
|
206
193
|
}
|
|
207
194
|
normalizeCustomerId(value) {
|
|
208
195
|
const customerId = Number(value);
|
|
209
|
-
if (!Number.isFinite(customerId) || customerId <= 0)
|
|
210
|
-
return null;
|
|
196
|
+
if (!Number.isFinite(customerId) || customerId <= 0) return null;
|
|
211
197
|
return customerId;
|
|
212
198
|
}
|
|
213
199
|
resolveCustomerIdFromLoginPayload(payload) {
|
|
214
|
-
|
|
215
|
-
const candidates = [
|
|
216
|
-
payload == null ? void 0 : payload.customerId,
|
|
217
|
-
payload == null ? void 0 : payload.customer_id,
|
|
218
|
-
payload == null ? void 0 : payload.id,
|
|
219
|
-
(_a = payload == null ? void 0 : payload.user) == null ? void 0 : _a.customerId,
|
|
220
|
-
(_b = payload == null ? void 0 : payload.user) == null ? void 0 : _b.customer_id,
|
|
221
|
-
(_c = payload == null ? void 0 : payload.user) == null ? void 0 : _c.id,
|
|
222
|
-
(_e = (_d = payload == null ? void 0 : payload.user) == null ? void 0 : _d._origin) == null ? void 0 : _e.customer_id,
|
|
223
|
-
(_f = payload == null ? void 0 : payload.account) == null ? void 0 : _f.customerId,
|
|
224
|
-
(_g = payload == null ? void 0 : payload.account) == null ? void 0 : _g.customer_id,
|
|
225
|
-
(_h = payload == null ? void 0 : payload.account) == null ? void 0 : _h.id,
|
|
226
|
-
(_i = payload == null ? void 0 : payload._origin) == null ? void 0 : _i.customer_id
|
|
227
|
-
];
|
|
200
|
+
const candidates = [payload?.customerId, payload?.customer_id, payload?.id, payload?.user?.customerId, payload?.user?.customer_id, payload?.user?.id, payload?.user?._origin?.customer_id, payload?.account?.customerId, payload?.account?.customer_id, payload?.account?.id, payload?._origin?.customer_id];
|
|
228
201
|
for (const candidate of candidates) {
|
|
229
202
|
const customerId = this.normalizeCustomerId(candidate);
|
|
230
|
-
if (customerId)
|
|
231
|
-
return customerId;
|
|
203
|
+
if (customerId) return customerId;
|
|
232
204
|
}
|
|
233
205
|
return null;
|
|
234
206
|
}
|
|
@@ -239,38 +211,30 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
239
211
|
this.loginEffectDisposers = [];
|
|
240
212
|
}
|
|
241
213
|
registerLoginEffect(event, callback) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (!(effects == null ? void 0 : effects.on))
|
|
245
|
-
return;
|
|
214
|
+
const effects = this.core?.effects;
|
|
215
|
+
if (!effects?.on) return;
|
|
246
216
|
effects.on(event, callback);
|
|
247
217
|
this.loginEffectDisposers.push(() => {
|
|
248
|
-
if (typeof effects.off ===
|
|
218
|
+
if (typeof effects.off === 'function') {
|
|
249
219
|
effects.off(event, callback);
|
|
250
220
|
}
|
|
251
221
|
});
|
|
252
222
|
}
|
|
253
223
|
registerCustomerLoginListeners() {
|
|
254
224
|
this.clearLoginEffectListeners();
|
|
255
|
-
const createHandleLogin = () => async
|
|
225
|
+
const createHandleLogin = () => async payload => {
|
|
256
226
|
const customerId = this.resolveCustomerIdFromLoginPayload(payload);
|
|
257
|
-
if (!customerId)
|
|
258
|
-
|
|
259
|
-
|
|
227
|
+
if (!customerId) return;
|
|
228
|
+
await this.refreshOrderMarketingAfterLogin({
|
|
229
|
+
customerId
|
|
230
|
+
});
|
|
260
231
|
};
|
|
261
|
-
this.registerLoginEffect(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
);
|
|
265
|
-
this.registerLoginEffect(import_types2.AccountHooks.OnLogin, createHandleLogin());
|
|
266
|
-
this.registerLoginEffect(
|
|
267
|
-
import_types3.RegisterAndLoginHooks.onLoginSuccess,
|
|
268
|
-
createHandleLogin()
|
|
269
|
-
);
|
|
232
|
+
this.registerLoginEffect(ScanOrderImpl.PISELL1_LOGIN_SUCCESS, createHandleLogin());
|
|
233
|
+
this.registerLoginEffect(_types2.AccountHooks.OnLogin, createHandleLogin());
|
|
234
|
+
this.registerLoginEffect(_types3.RegisterAndLoginHooks.onLoginSuccess, createHandleLogin());
|
|
270
235
|
}
|
|
271
236
|
async refreshOrderMarketingAfterLogin(params) {
|
|
272
|
-
if (!this.store.order)
|
|
273
|
-
throw new Error("order 模块未初始化");
|
|
237
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
274
238
|
if (this.customerLoginRefreshInFlight) {
|
|
275
239
|
if (this.customerLoginRefreshIdInFlight === params.customerId) {
|
|
276
240
|
await this.customerLoginRefreshInFlight;
|
|
@@ -283,7 +247,9 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
283
247
|
await this.store.order.loadDiscountConfig({
|
|
284
248
|
customerId: params.customerId
|
|
285
249
|
});
|
|
286
|
-
await this.store.order.recalculateSummary({
|
|
250
|
+
await this.store.order.recalculateSummary({
|
|
251
|
+
createIfMissing: true
|
|
252
|
+
});
|
|
287
253
|
this.store.order.persistTempOrder();
|
|
288
254
|
await this.refreshItemRuleQuantityLimits();
|
|
289
255
|
await this.refreshCartValidationPassed();
|
|
@@ -300,35 +266,34 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
300
266
|
}
|
|
301
267
|
}
|
|
302
268
|
}
|
|
269
|
+
constructor(name, version) {
|
|
270
|
+
super(name, version);
|
|
271
|
+
}
|
|
272
|
+
|
|
303
273
|
/** 与 `otherParams.cacheId` 一致,供宿主在 URL 变化时判断是否需要重新注册模块 */
|
|
304
274
|
getCacheId() {
|
|
305
275
|
return this.cacheId;
|
|
306
276
|
}
|
|
307
277
|
async destroyRegisteredChildModules() {
|
|
308
|
-
const modules = [
|
|
309
|
-
this.store.schedule,
|
|
310
|
-
this.store.salesSummary,
|
|
311
|
-
this.store.order,
|
|
312
|
-
this.store.products,
|
|
313
|
-
this.store.scanOrderLogger
|
|
314
|
-
];
|
|
278
|
+
const modules = [this.store.schedule, this.store.salesSummary, this.store.order, this.store.products, this.store.scanOrderLogger];
|
|
315
279
|
for (const mod of modules) {
|
|
316
|
-
if (mod && typeof mod.destroy ===
|
|
317
|
-
await Promise.resolve(mod.destroy());
|
|
280
|
+
if (mod && typeof mod.destroy === 'function') await Promise.resolve(mod.destroy());
|
|
318
281
|
}
|
|
319
282
|
}
|
|
320
283
|
async initialize(core, options = {}) {
|
|
321
|
-
|
|
322
|
-
this.logMethodStart("initialize");
|
|
284
|
+
this.logMethodStart('initialize');
|
|
323
285
|
this.core = core;
|
|
324
286
|
this.initializeOptions = options || {};
|
|
325
|
-
this.store = {
|
|
326
|
-
|
|
327
|
-
|
|
287
|
+
this.store = {
|
|
288
|
+
...this.store,
|
|
289
|
+
...options.store
|
|
290
|
+
};
|
|
291
|
+
this.store.entryContext = options.otherParams?.entryContext || this.store.entryContext;
|
|
292
|
+
this.store.status = 'initializing';
|
|
328
293
|
this.store.error = null;
|
|
329
294
|
this.otherParams = options.otherParams || {};
|
|
330
|
-
this.cacheId =
|
|
331
|
-
this.itemRuleRuntimeConfig =
|
|
295
|
+
this.cacheId = this.otherParams?.cacheId;
|
|
296
|
+
this.itemRuleRuntimeConfig = this.otherParams?.scanOrderItemRule || this.otherParams?.itemRule || {};
|
|
332
297
|
this.itemRuleConfigs = [];
|
|
333
298
|
this.itemRuleConfigsPromise = null;
|
|
334
299
|
this.itemRulePrefillApplied = false;
|
|
@@ -337,35 +302,29 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
337
302
|
passed: null,
|
|
338
303
|
failures: []
|
|
339
304
|
};
|
|
340
|
-
this.window = core.getPlugin(
|
|
341
|
-
this.request = core.getPlugin(
|
|
305
|
+
this.window = core.getPlugin('window');
|
|
306
|
+
this.request = core.getPlugin('request');
|
|
342
307
|
if (!this.window) {
|
|
343
|
-
this.logMethodError(
|
|
344
|
-
throw new Error(
|
|
308
|
+
this.logMethodError('initialize', 'window plugin missing');
|
|
309
|
+
throw new Error('scanOrder解决方案需要 window 插件支持');
|
|
345
310
|
}
|
|
346
311
|
if (!this.request) {
|
|
347
|
-
this.logMethodError(
|
|
348
|
-
throw new Error(
|
|
349
|
-
}
|
|
350
|
-
const moduleArr = [
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
"order",
|
|
354
|
-
"salesSummary"
|
|
355
|
-
];
|
|
356
|
-
moduleArr.forEach((step) => {
|
|
357
|
-
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
358
|
-
const targetModule = (0, import_types4.createModule)(step, this.name);
|
|
312
|
+
this.logMethodError('initialize', 'request plugin missing');
|
|
313
|
+
throw new Error('scanOrder解决方案需要 request 插件支持');
|
|
314
|
+
}
|
|
315
|
+
const moduleArr = ['scanOrderLogger', 'products', 'order', 'salesSummary'];
|
|
316
|
+
moduleArr.forEach(step => {
|
|
317
|
+
const targetModule = (0, _types4.createModule)(step, this.name);
|
|
359
318
|
if (targetModule) {
|
|
360
319
|
this.store[step] = targetModule;
|
|
361
|
-
const initialState = step ===
|
|
362
|
-
summary:
|
|
320
|
+
const initialState = step === 'salesSummary' ? {
|
|
321
|
+
summary: this.store.order?.getTempOrder()?.summary || (0, _utils.createEmptySummary)()
|
|
363
322
|
} : {};
|
|
364
|
-
const loggerProvider =
|
|
365
|
-
const loggerConfig =
|
|
323
|
+
const loggerProvider = this.otherParams?.scanOrderLoggerProvider || 'feishu';
|
|
324
|
+
const loggerConfig = this.otherParams?.scanOrderLoggerConfig || {
|
|
366
325
|
feishu: {
|
|
367
|
-
webhook:
|
|
368
|
-
errorHook:
|
|
326
|
+
webhook: 'https://open.feishu.cn/open-apis/bot/v2/hook/216b3fe6-af98-424e-8706-f0471241a7ed',
|
|
327
|
+
errorHook: 'https://open.feishu.cn/open-apis/bot/v2/hook/015b7c2a-dd3c-4c30-9898-ef0f5253111f'
|
|
369
328
|
}
|
|
370
329
|
};
|
|
371
330
|
this.core.registerModule(targetModule, {
|
|
@@ -373,8 +332,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
373
332
|
otherParams: {
|
|
374
333
|
...this.otherParams,
|
|
375
334
|
fatherModule: this.name,
|
|
376
|
-
openCache:
|
|
377
|
-
cacheId:
|
|
335
|
+
openCache: this.otherParams?.cacheId ? true : false,
|
|
336
|
+
cacheId: this.otherParams?.cacheId,
|
|
378
337
|
salesSummaryModuleName: `${this.name}_salesSummary`,
|
|
379
338
|
provider: loggerProvider,
|
|
380
339
|
providerConfig: loggerConfig,
|
|
@@ -382,14 +341,14 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
382
341
|
}
|
|
383
342
|
});
|
|
384
343
|
} else {
|
|
385
|
-
this.logMethodError(
|
|
344
|
+
this.logMethodError('initialize', `module ${step} missing`);
|
|
386
345
|
throw new Error(`模块 ${step} 不存在`);
|
|
387
346
|
}
|
|
388
347
|
});
|
|
389
348
|
if (this.store.scanOrderLogger) {
|
|
390
349
|
this.store.scanOrderLogger.setContext(this.getScanOrderLoggerContext());
|
|
391
350
|
}
|
|
392
|
-
const scheduleModule = new
|
|
351
|
+
const scheduleModule = new _Schedule.ScheduleModule(`${this.name}_schedule`);
|
|
393
352
|
this.store.schedule = scheduleModule;
|
|
394
353
|
this.core.registerModule(scheduleModule, {
|
|
395
354
|
otherParams: {
|
|
@@ -398,337 +357,336 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
398
357
|
}
|
|
399
358
|
});
|
|
400
359
|
this.registerCustomerLoginListeners();
|
|
401
|
-
console.log("[ScanOrder] 初始化开始");
|
|
402
360
|
try {
|
|
403
|
-
await
|
|
404
|
-
|
|
361
|
+
await this.store.order?.recalculateSummary({
|
|
362
|
+
createIfMissing: false
|
|
363
|
+
});
|
|
364
|
+
this.store.order?.persistTempOrder();
|
|
405
365
|
await this.loadRuntimeConfigs();
|
|
406
366
|
if (this.store.schedule) {
|
|
407
367
|
try {
|
|
408
368
|
await this.store.schedule.loadAllSchedule();
|
|
409
369
|
} catch (scheduleError) {
|
|
410
|
-
console.warn(
|
|
370
|
+
console.warn('[ScanOrder] loadAllSchedule 失败,operating_hours 判定将跳过', scheduleError);
|
|
411
371
|
}
|
|
412
372
|
}
|
|
413
373
|
await this.refreshItemRuleQuantityLimits();
|
|
414
|
-
this.store.status =
|
|
415
|
-
|
|
416
|
-
await this.core.effects.emit(import_types.ScanOrderHooks.onInited, {
|
|
374
|
+
this.store.status = 'ready';
|
|
375
|
+
await this.core.effects.emit(_types.ScanOrderHooks.onInited, {
|
|
417
376
|
status: this.store.status
|
|
418
377
|
});
|
|
419
|
-
this.logMethodSuccess(
|
|
378
|
+
this.logMethodSuccess('initialize', {
|
|
420
379
|
status: this.store.status
|
|
421
380
|
});
|
|
422
381
|
} catch (error) {
|
|
423
|
-
this.store.status =
|
|
424
|
-
this.store.error = error instanceof Error ? error.message :
|
|
425
|
-
console.error(
|
|
426
|
-
this.logMethodError(
|
|
382
|
+
this.store.status = 'error';
|
|
383
|
+
this.store.error = error instanceof Error ? error.message : '初始化失败';
|
|
384
|
+
console.error('[ScanOrder] 初始化失败', error);
|
|
385
|
+
this.logMethodError('initialize', error, {
|
|
427
386
|
status: this.store.status
|
|
428
387
|
});
|
|
429
388
|
throw error;
|
|
430
389
|
}
|
|
431
390
|
}
|
|
432
391
|
async destroy() {
|
|
433
|
-
this.logMethodStart(
|
|
392
|
+
this.logMethodStart('destroy');
|
|
434
393
|
this.clearLoginEffectListeners();
|
|
435
|
-
await this.core.effects.emit(
|
|
394
|
+
await this.core.effects.emit(_types.ScanOrderHooks.onDestroy, {});
|
|
436
395
|
await this.destroyRegisteredChildModules();
|
|
437
396
|
super.destroy();
|
|
438
|
-
|
|
439
|
-
this.logMethodSuccess("destroy");
|
|
397
|
+
this.logMethodSuccess('destroy');
|
|
440
398
|
}
|
|
441
399
|
async retryInit() {
|
|
442
|
-
this.logMethodStart(
|
|
443
|
-
|
|
444
|
-
|
|
400
|
+
this.logMethodStart('retryInit');
|
|
401
|
+
// TODO: 细化重试策略(指数退避、最大重试次数)后替换当前实现
|
|
402
|
+
|
|
403
|
+
await this.core.effects.emit(_types.ScanOrderHooks.onRetryInit, {});
|
|
445
404
|
try {
|
|
446
405
|
await this.initialize(this.core, this.initializeOptions);
|
|
447
|
-
this.logMethodSuccess(
|
|
406
|
+
this.logMethodSuccess('retryInit');
|
|
448
407
|
} catch (error) {
|
|
449
|
-
this.logMethodError(
|
|
408
|
+
this.logMethodError('retryInit', error);
|
|
450
409
|
throw error;
|
|
451
410
|
}
|
|
452
411
|
}
|
|
453
412
|
async refresh() {
|
|
454
|
-
this.logMethodStart(
|
|
455
|
-
|
|
413
|
+
this.logMethodStart('refresh');
|
|
414
|
+
// TODO: 接入真实刷新逻辑(资源重拉取、流程重建)后替换当前实现
|
|
415
|
+
|
|
456
416
|
try {
|
|
457
|
-
this.store.status =
|
|
417
|
+
this.store.status = 'initializing';
|
|
458
418
|
await this.loadRuntimeConfigs();
|
|
459
419
|
await this.refreshItemRuleQuantityLimits();
|
|
460
|
-
this.store.status =
|
|
461
|
-
await this.core.effects.emit(
|
|
420
|
+
this.store.status = 'ready';
|
|
421
|
+
await this.core.effects.emit(_types.ScanOrderHooks.onRefresh, {
|
|
462
422
|
status: this.store.status
|
|
463
423
|
});
|
|
464
|
-
this.logMethodSuccess(
|
|
424
|
+
this.logMethodSuccess('refresh', {
|
|
465
425
|
status: this.store.status
|
|
466
426
|
});
|
|
467
427
|
} catch (error) {
|
|
468
|
-
this.logMethodError(
|
|
428
|
+
this.logMethodError('refresh', error);
|
|
469
429
|
throw error;
|
|
470
430
|
}
|
|
471
431
|
}
|
|
472
432
|
getStatus() {
|
|
473
|
-
this.logMethodStart(
|
|
433
|
+
this.logMethodStart('getStatus');
|
|
474
434
|
const result = this.store.status;
|
|
475
|
-
this.logMethodSuccess(
|
|
435
|
+
this.logMethodSuccess('getStatus', {
|
|
476
436
|
status: result
|
|
477
437
|
});
|
|
478
438
|
return result;
|
|
479
439
|
}
|
|
480
440
|
getEntryContext() {
|
|
481
|
-
this.logMethodStart(
|
|
441
|
+
this.logMethodStart('getEntryContext');
|
|
482
442
|
const result = this.store.entryContext;
|
|
483
|
-
this.logMethodSuccess(
|
|
443
|
+
this.logMethodSuccess('getEntryContext', {
|
|
484
444
|
hasEntryContext: Boolean(result)
|
|
485
445
|
});
|
|
486
446
|
return result;
|
|
487
447
|
}
|
|
488
448
|
getConfig() {
|
|
489
|
-
this.logMethodStart(
|
|
449
|
+
this.logMethodStart('getConfig');
|
|
490
450
|
const result = this.store.config || {};
|
|
491
|
-
this.logMethodSuccess(
|
|
451
|
+
this.logMethodSuccess('getConfig', {
|
|
492
452
|
configKeys: Object.keys(result || {})
|
|
493
453
|
});
|
|
494
454
|
return result;
|
|
495
455
|
}
|
|
496
456
|
getItemRuleQuantityLimits() {
|
|
497
|
-
this.logMethodStart(
|
|
457
|
+
this.logMethodStart('getItemRuleQuantityLimits');
|
|
498
458
|
const result = this.store.itemRuleQuantityLimits || [];
|
|
499
|
-
this.logMethodSuccess(
|
|
459
|
+
this.logMethodSuccess('getItemRuleQuantityLimits', {
|
|
500
460
|
limitCount: result.length
|
|
501
461
|
});
|
|
502
462
|
return result;
|
|
503
463
|
}
|
|
504
464
|
getCartValidationPassed() {
|
|
505
|
-
|
|
506
|
-
this.
|
|
507
|
-
|
|
508
|
-
this.logMethodSuccess("getCartValidationPassed", {
|
|
465
|
+
this.logMethodStart('getCartValidationPassed');
|
|
466
|
+
const result = this.store.cartValidation?.passed ?? null;
|
|
467
|
+
this.logMethodSuccess('getCartValidationPassed', {
|
|
509
468
|
cartValidationPassed: result
|
|
510
469
|
});
|
|
511
470
|
return result;
|
|
512
471
|
}
|
|
513
472
|
getCartValidation() {
|
|
514
|
-
this.logMethodStart(
|
|
473
|
+
this.logMethodStart('getCartValidation');
|
|
515
474
|
const result = this.store.cartValidation || {
|
|
516
475
|
passed: null,
|
|
517
476
|
failures: []
|
|
518
477
|
};
|
|
519
|
-
this.logMethodSuccess(
|
|
478
|
+
this.logMethodSuccess('getCartValidation', {
|
|
520
479
|
cartValidationPassed: result.passed,
|
|
521
480
|
failureCount: Array.isArray(result.failures) ? result.failures.length : 0
|
|
522
481
|
});
|
|
523
482
|
return result;
|
|
524
483
|
}
|
|
525
484
|
getTempOrder() {
|
|
526
|
-
|
|
527
|
-
this.
|
|
528
|
-
|
|
529
|
-
this.logMethodSuccess("getTempOrder", {
|
|
485
|
+
this.logMethodStart('getTempOrder');
|
|
486
|
+
const result = this.store.order?.getTempOrder() || null;
|
|
487
|
+
this.logMethodSuccess('getTempOrder', {
|
|
530
488
|
hasTempOrder: Boolean(result),
|
|
531
|
-
productCount:
|
|
532
|
-
noteLength:
|
|
489
|
+
productCount: result?.products?.length || 0,
|
|
490
|
+
noteLength: result?.note?.length || 0
|
|
533
491
|
});
|
|
534
492
|
return result;
|
|
535
493
|
}
|
|
536
494
|
updateTempOrderNote(note) {
|
|
537
|
-
this.logMethodStart(
|
|
538
|
-
noteLength: String(note ||
|
|
495
|
+
this.logMethodStart('updateTempOrderNote', {
|
|
496
|
+
noteLength: String(note || '').length
|
|
539
497
|
});
|
|
540
498
|
try {
|
|
541
|
-
if (!this.store.order)
|
|
542
|
-
throw new Error("order 模块未初始化");
|
|
499
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
543
500
|
const result = this.store.order.updateTempOrderNote(note);
|
|
544
|
-
this.logMethodSuccess(
|
|
501
|
+
this.logMethodSuccess('updateTempOrderNote', {
|
|
545
502
|
noteLength: result.length
|
|
546
503
|
});
|
|
547
504
|
return result;
|
|
548
505
|
} catch (error) {
|
|
549
|
-
this.logMethodError(
|
|
506
|
+
this.logMethodError('updateTempOrderNote', error);
|
|
550
507
|
throw error;
|
|
551
508
|
}
|
|
552
509
|
}
|
|
510
|
+
|
|
553
511
|
// 存储 UI 层选择的取餐方式到 tempOrder.metadata.shop_service_data
|
|
554
512
|
// service_type 在扫码点餐场景固定为 dine_in
|
|
555
513
|
setPickupReferenceMode(mode) {
|
|
556
|
-
|
|
557
|
-
|
|
514
|
+
this.logMethodStart('setPickupReferenceMode', {
|
|
515
|
+
mode
|
|
516
|
+
});
|
|
558
517
|
try {
|
|
559
|
-
if (!this.store.order)
|
|
560
|
-
throw new Error("order 模块未初始化");
|
|
518
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
561
519
|
const tempOrder = this.store.order.ensureTempOrder();
|
|
562
520
|
tempOrder.metadata = {
|
|
563
|
-
...tempOrder.metadata || {},
|
|
521
|
+
...(tempOrder.metadata || {}),
|
|
564
522
|
shop_service_data: {
|
|
565
|
-
...(tempOrder.metadata || {}).shop_service_data || {},
|
|
566
|
-
service_type:
|
|
523
|
+
...((tempOrder.metadata || {}).shop_service_data || {}),
|
|
524
|
+
service_type: this.otherParams?.businessCode === 'dine_in' ? 'dine_in' : '',
|
|
567
525
|
pickup_reference_mode: mode
|
|
568
526
|
}
|
|
569
527
|
};
|
|
570
528
|
this.store.order.persistTempOrder();
|
|
571
|
-
this.logMethodSuccess(
|
|
529
|
+
this.logMethodSuccess('setPickupReferenceMode', {
|
|
572
530
|
mode
|
|
573
531
|
});
|
|
574
532
|
return tempOrder.metadata.shop_service_data;
|
|
575
533
|
} catch (error) {
|
|
576
|
-
this.logMethodError(
|
|
534
|
+
this.logMethodError('setPickupReferenceMode', error, {
|
|
535
|
+
mode
|
|
536
|
+
});
|
|
577
537
|
throw error;
|
|
578
538
|
}
|
|
579
539
|
}
|
|
540
|
+
|
|
580
541
|
// 存储用户自定义取餐标识到 tempOrder.buzzer
|
|
581
542
|
setPickupRef(buzzer) {
|
|
582
|
-
this.logMethodStart(
|
|
583
|
-
buzzerLength: String(buzzer ||
|
|
543
|
+
this.logMethodStart('setPickupRef', {
|
|
544
|
+
buzzerLength: String(buzzer || '').length
|
|
584
545
|
});
|
|
585
546
|
try {
|
|
586
|
-
if (!this.store.order)
|
|
587
|
-
throw new Error("order 模块未初始化");
|
|
547
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
588
548
|
const result = this.store.order.updateTempOrderBuzzer(buzzer);
|
|
589
|
-
this.logMethodSuccess(
|
|
549
|
+
this.logMethodSuccess('setPickupRef', {
|
|
590
550
|
buzzerLength: result.length
|
|
591
551
|
});
|
|
592
552
|
return result;
|
|
593
553
|
} catch (error) {
|
|
594
|
-
this.logMethodError(
|
|
554
|
+
this.logMethodError('setPickupRef', error);
|
|
595
555
|
throw error;
|
|
596
556
|
}
|
|
597
557
|
}
|
|
598
558
|
ensureTempOrder() {
|
|
599
|
-
if (!this.store.order)
|
|
600
|
-
throw new Error("order 模块未初始化");
|
|
559
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
601
560
|
return this.store.order.ensureTempOrder();
|
|
602
561
|
}
|
|
562
|
+
|
|
603
563
|
// 主动创建临时订单;若已存在则直接返回已有订单
|
|
604
564
|
async addNewOrder() {
|
|
605
|
-
this.logMethodStart(
|
|
565
|
+
this.logMethodStart('addNewOrder');
|
|
606
566
|
try {
|
|
607
|
-
if (!this.store.order)
|
|
608
|
-
throw new Error("order 模块未初始化");
|
|
567
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
609
568
|
const tempOrder = await this.store.order.addNewOrder();
|
|
610
|
-
this.logMethodSuccess(
|
|
569
|
+
this.logMethodSuccess('addNewOrder', {
|
|
611
570
|
productCount: tempOrder.products.length
|
|
612
571
|
});
|
|
613
572
|
return tempOrder;
|
|
614
573
|
} catch (error) {
|
|
615
|
-
this.logMethodError(
|
|
574
|
+
this.logMethodError('addNewOrder', error);
|
|
616
575
|
throw error;
|
|
617
576
|
}
|
|
618
577
|
}
|
|
578
|
+
|
|
619
579
|
// 重置 tempOrder 与与上一单强相关的运行态(resource/entryPaxNumber/enabledReservationRuleProducts),
|
|
620
580
|
// 适用于从支付页通过 react-router 跳回继续下单时清理残留数据
|
|
621
581
|
async restoreOrder() {
|
|
622
|
-
this.logMethodStart(
|
|
582
|
+
this.logMethodStart('restoreOrder');
|
|
623
583
|
try {
|
|
624
584
|
if (!this.store.order) {
|
|
625
|
-
throw new Error(
|
|
585
|
+
throw new Error('scanOrder 解决方案需要 order 模块支持');
|
|
626
586
|
}
|
|
627
587
|
this.store.resource = null;
|
|
628
588
|
this.store.entryPaxNumber = 1;
|
|
629
589
|
this.enabledReservationRuleProducts = [];
|
|
630
590
|
const tempOrder = this.store.order.restoreOrder();
|
|
631
|
-
this.logMethodSuccess(
|
|
591
|
+
this.logMethodSuccess('restoreOrder');
|
|
632
592
|
return tempOrder;
|
|
633
593
|
} catch (error) {
|
|
634
|
-
this.logMethodError(
|
|
594
|
+
this.logMethodError('restoreOrder', error);
|
|
635
595
|
throw error;
|
|
636
596
|
}
|
|
637
597
|
}
|
|
638
598
|
getOrderProducts() {
|
|
639
|
-
this.logMethodStart(
|
|
640
|
-
if (!this.store.order)
|
|
641
|
-
throw new Error("order 模块未初始化");
|
|
599
|
+
this.logMethodStart('getOrderProducts');
|
|
600
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
642
601
|
const products = this.store.order.getOrderProducts();
|
|
643
|
-
this.logMethodSuccess(
|
|
602
|
+
this.logMethodSuccess('getOrderProducts', {
|
|
644
603
|
productCount: products.length
|
|
645
604
|
});
|
|
646
605
|
return products;
|
|
647
606
|
}
|
|
648
607
|
async getSummary() {
|
|
649
|
-
this.logMethodStart(
|
|
608
|
+
this.logMethodStart('getSummary');
|
|
650
609
|
try {
|
|
651
|
-
if (!this.store.order)
|
|
652
|
-
throw new Error("order 模块未初始化");
|
|
610
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
653
611
|
const summary = await this.store.order.getScanOrderSummary();
|
|
654
|
-
this.logMethodSuccess(
|
|
612
|
+
this.logMethodSuccess('getSummary', {
|
|
655
613
|
totalAmount: summary.total_amount
|
|
656
614
|
});
|
|
657
615
|
return summary;
|
|
658
616
|
} catch (error) {
|
|
659
|
-
this.logMethodError(
|
|
617
|
+
this.logMethodError('getSummary', error);
|
|
660
618
|
throw error;
|
|
661
619
|
}
|
|
662
620
|
}
|
|
663
621
|
getDiscountList() {
|
|
664
|
-
if (!this.store.order)
|
|
665
|
-
return [];
|
|
622
|
+
if (!this.store.order) return [];
|
|
666
623
|
return this.store.order.getDiscountList();
|
|
667
624
|
}
|
|
668
625
|
async scanCode(code, customerId) {
|
|
669
|
-
this.logMethodStart(
|
|
626
|
+
this.logMethodStart('scanCode', {
|
|
627
|
+
code
|
|
628
|
+
});
|
|
670
629
|
try {
|
|
671
|
-
if (!this.store.order)
|
|
672
|
-
throw new Error("order 模块未初始化");
|
|
630
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
673
631
|
const raw = await this.store.order.scanCode(code, customerId);
|
|
674
632
|
if (raw.isAvailable) {
|
|
675
|
-
await this.store.order.recalculateSummary({
|
|
633
|
+
await this.store.order.recalculateSummary({
|
|
634
|
+
createIfMissing: true
|
|
635
|
+
});
|
|
676
636
|
this.store.order.persistTempOrder();
|
|
677
637
|
}
|
|
678
|
-
this.logMethodSuccess(
|
|
638
|
+
this.logMethodSuccess('scanCode', {
|
|
639
|
+
isAvailable: raw.isAvailable
|
|
640
|
+
});
|
|
679
641
|
return {
|
|
680
642
|
isAvailable: raw.isAvailable,
|
|
681
643
|
type: raw.type,
|
|
682
644
|
unavailableReason: raw.unavailableReason
|
|
683
645
|
};
|
|
684
646
|
} catch (error) {
|
|
685
|
-
this.logMethodError(
|
|
647
|
+
this.logMethodError('scanCode', error);
|
|
686
648
|
throw error;
|
|
687
649
|
}
|
|
688
650
|
}
|
|
689
651
|
async setDiscountSelected(params) {
|
|
690
|
-
|
|
691
|
-
this.logMethodStart("setDiscountSelected", params);
|
|
652
|
+
this.logMethodStart('setDiscountSelected', params);
|
|
692
653
|
try {
|
|
693
|
-
if (!this.store.order)
|
|
694
|
-
throw new Error("order 模块未初始化");
|
|
654
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
695
655
|
const list = this.store.order.getDiscountList();
|
|
696
|
-
const updated = list.map(
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
} : d
|
|
702
|
-
);
|
|
656
|
+
const updated = list.map(d => d.id === params.discountId ? {
|
|
657
|
+
...d,
|
|
658
|
+
isSelected: params.isSelected,
|
|
659
|
+
isManualSelect: !params.isSelected
|
|
660
|
+
} : d);
|
|
703
661
|
const tempOrder = this.store.order.ensureTempOrder();
|
|
704
662
|
const orderStore = this.store.order.store || {};
|
|
705
663
|
const discountModule = orderStore.discount;
|
|
706
664
|
const rulesModule = orderStore.rules;
|
|
707
|
-
const holders =
|
|
665
|
+
const holders = tempOrder.holder?.form_record_id ? [{
|
|
666
|
+
form_record_id: tempOrder.holder.form_record_id
|
|
667
|
+
}] : [];
|
|
708
668
|
let nextDiscountList = updated;
|
|
709
|
-
await
|
|
669
|
+
await discountModule?.setDiscountList(updated);
|
|
710
670
|
if (rulesModule) {
|
|
711
|
-
const result = rulesModule.calcDiscount(
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
if (result
|
|
671
|
+
const result = rulesModule.calcDiscount({
|
|
672
|
+
productList: tempOrder.products,
|
|
673
|
+
discountList: updated,
|
|
674
|
+
holders,
|
|
675
|
+
isFormSubject: !!tempOrder.holder?.type && tempOrder.holder.type === 'form'
|
|
676
|
+
}, {
|
|
677
|
+
discountId: params.discountId,
|
|
678
|
+
isSelected: params.isSelected
|
|
679
|
+
}) || {
|
|
680
|
+
productList: tempOrder.products,
|
|
681
|
+
discountList: updated
|
|
682
|
+
};
|
|
683
|
+
if (result?.productList) {
|
|
724
684
|
tempOrder.products = result.productList;
|
|
725
685
|
}
|
|
726
|
-
if (result
|
|
686
|
+
if (result?.discountList) {
|
|
727
687
|
nextDiscountList = result.discountList;
|
|
728
688
|
if (!params.isSelected) {
|
|
729
|
-
const beforeSelectedIds = new Set(
|
|
730
|
-
updated.filter((d) => d.isSelected).map((d) => d.id)
|
|
731
|
-
);
|
|
689
|
+
const beforeSelectedIds = new Set(updated.filter(d => d.isSelected).map(d => d.id));
|
|
732
690
|
for (const d of nextDiscountList) {
|
|
733
691
|
if (d.isSelected && !beforeSelectedIds.has(d.id)) {
|
|
734
692
|
d.isSelected = false;
|
|
@@ -737,88 +695,92 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
737
695
|
}
|
|
738
696
|
}
|
|
739
697
|
}
|
|
740
|
-
const selectedResourceIds = new Set(
|
|
741
|
-
nextDiscountList.filter((d) => d.isSelected).map((d) => d.id)
|
|
742
|
-
);
|
|
698
|
+
const selectedResourceIds = new Set(nextDiscountList.filter(d => d.isSelected).map(d => d.id));
|
|
743
699
|
for (const product of tempOrder.products) {
|
|
744
|
-
if (
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
var _a2;
|
|
748
|
-
const rid = ((_a2 = pd.discount) == null ? void 0 : _a2.resource_id) ?? pd.id;
|
|
700
|
+
if (product._origin?.isManualDiscount) continue;
|
|
701
|
+
product.discount_list = (product.discount_list || []).filter(pd => {
|
|
702
|
+
const rid = pd.discount?.resource_id ?? pd.id;
|
|
749
703
|
return rid != null && selectedResourceIds.has(rid);
|
|
750
704
|
});
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
);
|
|
755
|
-
const optionSum = (0,
|
|
756
|
-
const sourcePrice =
|
|
757
|
-
const newSourceSellingPrice = new
|
|
758
|
-
const newMainSellingPrice = new
|
|
705
|
+
|
|
706
|
+
// 券作用于 source(不含 option、不含 bundle);算出新 source 折后价后补回 options
|
|
707
|
+
// 写入含 option 的 main_product_selling_price,再合成 composite 回写 selling_price。
|
|
708
|
+
const totalPerUnitDiscount = (product.discount_list || []).reduce((sum, pd) => sum + (pd.amount || 0), 0);
|
|
709
|
+
const optionSum = (0, _utils2.sumOptionUnitPrice)(product.product_option_item);
|
|
710
|
+
const sourcePrice = product.metadata?.source_product_price ?? (product.metadata?.main_product_original_price != null ? new _decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? '0');
|
|
711
|
+
const newSourceSellingPrice = new _decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
|
|
712
|
+
const newMainSellingPrice = new _decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
759
713
|
if (product.metadata) {
|
|
760
714
|
product.metadata.main_product_selling_price = newMainSellingPrice;
|
|
761
715
|
product.metadata.price_schema_version = 2;
|
|
762
716
|
}
|
|
763
|
-
product.selling_price = (0,
|
|
717
|
+
product.selling_price = (0, _utils2.composeLinePrice)({
|
|
764
718
|
mainPrice: newMainSellingPrice,
|
|
765
719
|
bundle: product.product_bundle
|
|
766
720
|
});
|
|
767
721
|
}
|
|
768
|
-
|
|
769
|
-
await
|
|
770
|
-
tempOrder.discount_list = (nextDiscountList || []).filter(
|
|
771
|
-
await this.store.order.recalculateSummary({
|
|
722
|
+
_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
|
|
723
|
+
await discountModule?.setDiscountList(nextDiscountList);
|
|
724
|
+
tempOrder.discount_list = (nextDiscountList || []).filter(d => d.isSelected);
|
|
725
|
+
await this.store.order.recalculateSummary({
|
|
726
|
+
createIfMissing: true
|
|
727
|
+
});
|
|
772
728
|
this.store.order.persistTempOrder();
|
|
773
|
-
this.logMethodSuccess(
|
|
729
|
+
this.logMethodSuccess('setDiscountSelected', params);
|
|
774
730
|
} catch (error) {
|
|
775
|
-
this.logMethodError(
|
|
731
|
+
this.logMethodError('setDiscountSelected', error);
|
|
776
732
|
throw error;
|
|
777
733
|
}
|
|
778
734
|
}
|
|
779
735
|
async onCustomerLogin(params) {
|
|
780
|
-
this.logMethodStart(
|
|
736
|
+
this.logMethodStart('onCustomerLogin', {
|
|
737
|
+
customerId: params.customerId
|
|
738
|
+
});
|
|
781
739
|
try {
|
|
782
740
|
await this.refreshOrderMarketingAfterLogin({
|
|
783
741
|
customerId: params.customerId
|
|
784
742
|
});
|
|
785
|
-
this.logMethodSuccess(
|
|
743
|
+
this.logMethodSuccess('onCustomerLogin', {
|
|
744
|
+
customerId: params.customerId
|
|
745
|
+
});
|
|
786
746
|
} catch (error) {
|
|
787
|
-
this.logMethodError(
|
|
747
|
+
this.logMethodError('onCustomerLogin', error);
|
|
788
748
|
throw error;
|
|
789
749
|
}
|
|
790
750
|
}
|
|
791
751
|
findReservationRuleResource(formId) {
|
|
792
|
-
|
|
793
|
-
if (formId == null)
|
|
794
|
-
return void 0;
|
|
752
|
+
if (formId == null) return undefined;
|
|
795
753
|
const numericFormId = Number(formId);
|
|
796
|
-
if (!Number.isFinite(numericFormId) || numericFormId <= 0)
|
|
797
|
-
return void 0;
|
|
754
|
+
if (!Number.isFinite(numericFormId) || numericFormId <= 0) return undefined;
|
|
798
755
|
for (const product of this.enabledReservationRuleProducts) {
|
|
799
|
-
const resources =
|
|
800
|
-
if (!Array.isArray(resources))
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (matched)
|
|
804
|
-
return matched;
|
|
756
|
+
const resources = product?.product_resource?.resources;
|
|
757
|
+
if (!Array.isArray(resources)) continue;
|
|
758
|
+
const matched = resources.find(resource => Number(resource?.id) === numericFormId);
|
|
759
|
+
if (matched) return matched;
|
|
805
760
|
}
|
|
806
|
-
return
|
|
761
|
+
return undefined;
|
|
807
762
|
}
|
|
808
763
|
buildScanOrderResourceMetadata(params) {
|
|
809
|
-
const {
|
|
764
|
+
const {
|
|
765
|
+
resourceState,
|
|
766
|
+
resourceName
|
|
767
|
+
} = params;
|
|
810
768
|
const ruleResource = this.findReservationRuleResource(resourceState.tableFormId);
|
|
811
|
-
const combined = ruleResource
|
|
769
|
+
const combined = ruleResource?.combined_resource;
|
|
812
770
|
const isCombined = !!(combined && combined.status === 1 && Array.isArray(combined.resource_ids));
|
|
813
771
|
return {
|
|
814
|
-
form_name:
|
|
772
|
+
form_name: ruleResource?.title ?? '',
|
|
815
773
|
resource_name: resourceName,
|
|
816
774
|
combined_resource: isCombined ? combined : null
|
|
817
775
|
};
|
|
818
776
|
}
|
|
819
777
|
async prepareRetailAvailability(params) {
|
|
820
|
-
|
|
821
|
-
|
|
778
|
+
const {
|
|
779
|
+
tempOrder,
|
|
780
|
+
hasOrderId,
|
|
781
|
+
resourceId,
|
|
782
|
+
reason
|
|
783
|
+
} = params;
|
|
822
784
|
this.enabledReservationRuleProducts = [];
|
|
823
785
|
tempOrder.bookings = [];
|
|
824
786
|
tempOrder.order_id = null;
|
|
@@ -826,10 +788,12 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
826
788
|
delete tempOrder.table_form_id;
|
|
827
789
|
delete tempOrder.resource_id;
|
|
828
790
|
delete tempOrder.table_number;
|
|
829
|
-
tempOrder.metadata = {
|
|
791
|
+
tempOrder.metadata = {
|
|
792
|
+
...(tempOrder.metadata || {})
|
|
793
|
+
};
|
|
830
794
|
delete tempOrder.metadata.table_occupancy_duration;
|
|
831
795
|
const resourceState = {
|
|
832
|
-
mode:
|
|
796
|
+
mode: 'idle',
|
|
833
797
|
deskmate_valid: false,
|
|
834
798
|
allowSnack: false,
|
|
835
799
|
deskmateValid: false,
|
|
@@ -838,18 +802,18 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
838
802
|
raw: null
|
|
839
803
|
};
|
|
840
804
|
this.store.resource = resourceState;
|
|
841
|
-
|
|
805
|
+
this.store.order?.persistTempOrder();
|
|
842
806
|
await this.addNewOrder();
|
|
843
807
|
await this.setItemRuleRuntimeConfig({
|
|
844
|
-
serviceType:
|
|
808
|
+
serviceType: this.otherParams?.businessCode,
|
|
845
809
|
submissionIndex: hasOrderId ? 1 : 0,
|
|
846
810
|
historicalItems: []
|
|
847
811
|
});
|
|
848
812
|
const availabilityInfo = {
|
|
849
|
-
mode:
|
|
813
|
+
mode: 'idle',
|
|
850
814
|
deskmate_valid: false
|
|
851
815
|
};
|
|
852
|
-
this.logMethodSuccess(
|
|
816
|
+
this.logMethodSuccess('checkResourceAvailable', {
|
|
853
817
|
resourceId,
|
|
854
818
|
mode: availabilityInfo.mode,
|
|
855
819
|
retailMode: true,
|
|
@@ -859,6 +823,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
859
823
|
});
|
|
860
824
|
return availabilityInfo;
|
|
861
825
|
}
|
|
826
|
+
|
|
862
827
|
// ScanOrder 提交 payload enhancer:
|
|
863
828
|
// - 给所有 booking 注入 appointment_status: 'started'(扫码点餐语义)
|
|
864
829
|
// - 给所有 booking 的 metadata 注入 resource_select_type(来自预约规则商品的 resource.type)
|
|
@@ -867,45 +832,45 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
867
832
|
buildSubmitPayloadEnhancer() {
|
|
868
833
|
const ruleProduct = this.enabledReservationRuleProducts[0];
|
|
869
834
|
const resourceState = this.store.resource;
|
|
870
|
-
const resourceSelectType = resourceState
|
|
835
|
+
const resourceSelectType = resourceState?.resourceSelectType;
|
|
836
|
+
|
|
837
|
+
// ScanOrder 的 booking 容量只由预约规则决定:single 占用整张桌台,multiple 占用 1 个容量位。
|
|
871
838
|
const resolveBookingCapacityValue = () => {
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
const raw = (_a = resourceState == null ? void 0 : resourceState.table_form_record) == null ? void 0 : _a.capacity;
|
|
839
|
+
if (resourceSelectType === 'single') {
|
|
840
|
+
const raw = resourceState?.table_form_record?.capacity;
|
|
875
841
|
const num = Number(raw);
|
|
876
|
-
if (Number.isFinite(num) && num > 0)
|
|
877
|
-
return Math.max(1, Math.floor(num));
|
|
842
|
+
if (Number.isFinite(num) && num > 0) return Math.max(1, Math.floor(num));
|
|
878
843
|
return 1;
|
|
879
844
|
}
|
|
880
845
|
return 1;
|
|
881
846
|
};
|
|
882
|
-
return (payload, {
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
);
|
|
847
|
+
return (payload, {
|
|
848
|
+
bookingUuid,
|
|
849
|
+
tempOrder
|
|
850
|
+
}) => {
|
|
851
|
+
const resourceId = String(tempOrder.resource_id ?? resourceState?.relationId ?? '').trim();
|
|
852
|
+
const hasReservationBookingContext = Boolean(ruleProduct && resourceState && resourceId && (tempOrder.relation_id || resourceState.relationId) && (tempOrder.table_form_id || resourceState.tableFormId));
|
|
888
853
|
if (!hasReservationBookingContext) {
|
|
889
854
|
return {
|
|
890
855
|
...payload,
|
|
891
856
|
bookings: [],
|
|
892
|
-
products: [...payload.products || []]
|
|
857
|
+
products: [...(payload.products || [])]
|
|
893
858
|
};
|
|
894
859
|
}
|
|
895
|
-
const rawCollectPax =
|
|
896
|
-
const hasExplicitCollectPax = rawCollectPax !== null && rawCollectPax !==
|
|
860
|
+
const rawCollectPax = tempOrder.metadata?.collect_pax;
|
|
861
|
+
const hasExplicitCollectPax = rawCollectPax !== null && rawCollectPax !== undefined && rawCollectPax !== '';
|
|
897
862
|
const bookingCapacityValue = resolveBookingCapacityValue();
|
|
898
|
-
const pickOriginal =
|
|
899
|
-
if (value && typeof value ===
|
|
863
|
+
const pickOriginal = value => {
|
|
864
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
900
865
|
const original = value.original;
|
|
901
|
-
return typeof original ===
|
|
866
|
+
return typeof original === 'string' && original.length > 0 ? original : undefined;
|
|
902
867
|
}
|
|
903
|
-
return
|
|
868
|
+
return undefined;
|
|
904
869
|
};
|
|
905
|
-
const mainField = pickOriginal(tempOrder.table_number) ?? pickOriginal(
|
|
870
|
+
const mainField = pickOriginal(tempOrder.table_number) ?? pickOriginal(resourceState?.table_form_record?.name) ?? '';
|
|
906
871
|
const resourceEntry = resourceState && resourceId ? {
|
|
907
|
-
relation_type:
|
|
908
|
-
like_status:
|
|
872
|
+
relation_type: 'form',
|
|
873
|
+
like_status: 'common',
|
|
909
874
|
id: Number(resourceId),
|
|
910
875
|
main_field: mainField,
|
|
911
876
|
form_id: resourceState.tableFormId,
|
|
@@ -915,43 +880,48 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
915
880
|
resourceState,
|
|
916
881
|
resourceName: mainField
|
|
917
882
|
})
|
|
918
|
-
} :
|
|
919
|
-
const ruleProductUid = ruleProduct ? (0,
|
|
920
|
-
const bookingCapacityDimensionId = (0,
|
|
883
|
+
} : undefined;
|
|
884
|
+
const ruleProductUid = ruleProduct ? (0, _utils2.createUuidV4)() : undefined;
|
|
885
|
+
const bookingCapacityDimensionId = (0, _utils.pickFirstCustomCapacityDimensionId)(this.enabledReservationRuleProducts) ?? 0;
|
|
921
886
|
const nextBookings = (payload.bookings || []).map((booking, idx) => {
|
|
922
|
-
const metadata = {
|
|
887
|
+
const metadata = {
|
|
888
|
+
...(booking.metadata || {})
|
|
889
|
+
};
|
|
923
890
|
if (hasExplicitCollectPax) {
|
|
924
|
-
metadata.collect_pax = (0,
|
|
891
|
+
metadata.collect_pax = (0, _utils2.normalizeSubmitCollectPaxValue)(rawCollectPax);
|
|
925
892
|
} else {
|
|
926
893
|
delete metadata.collect_pax;
|
|
927
894
|
}
|
|
928
895
|
return {
|
|
929
896
|
...booking,
|
|
930
897
|
number: bookingCapacityValue,
|
|
931
|
-
appointment_status:
|
|
898
|
+
appointment_status: 'started',
|
|
932
899
|
metadata: {
|
|
933
900
|
...metadata,
|
|
934
|
-
...resourceSelectType ? {
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
]
|
|
943
|
-
} : {}
|
|
901
|
+
...(resourceSelectType ? {
|
|
902
|
+
resource_select_type: resourceSelectType
|
|
903
|
+
} : {}),
|
|
904
|
+
...(resourceSelectType ? {
|
|
905
|
+
capacity: [{
|
|
906
|
+
id: bookingCapacityDimensionId,
|
|
907
|
+
value: bookingCapacityValue,
|
|
908
|
+
name: ''
|
|
909
|
+
}]
|
|
910
|
+
} : {})
|
|
944
911
|
},
|
|
945
|
-
...idx === 0 && resourceEntry ? {
|
|
946
|
-
|
|
912
|
+
...(idx === 0 && resourceEntry ? {
|
|
913
|
+
resources: [resourceEntry]
|
|
914
|
+
} : {}),
|
|
915
|
+
...(idx === 0 && ruleProductUid ? {
|
|
916
|
+
product_uid: ruleProductUid
|
|
917
|
+
} : {})
|
|
947
918
|
};
|
|
948
919
|
});
|
|
949
|
-
const nextProducts = [...payload.products || []];
|
|
920
|
+
const nextProducts = [...(payload.products || [])];
|
|
921
|
+
// 加餐(已有 order_id)走 scanOrderMore,原单已含 booking 规则行,勿再追加虚拟规则商品
|
|
950
922
|
if (ruleProduct && ruleProductUid && !tempOrder.order_id) {
|
|
951
|
-
const sellingPrice = String(ruleProduct.price ??
|
|
952
|
-
const originalPrice = String(
|
|
953
|
-
ruleProduct.original_price ?? ruleProduct.price ?? "0.00"
|
|
954
|
-
);
|
|
923
|
+
const sellingPrice = String(ruleProduct.price ?? '0.00');
|
|
924
|
+
const originalPrice = String(ruleProduct.original_price ?? ruleProduct.price ?? '0.00');
|
|
955
925
|
nextProducts.push({
|
|
956
926
|
product_id: ruleProduct.id,
|
|
957
927
|
product_variant_id: 0,
|
|
@@ -971,21 +941,24 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
971
941
|
}
|
|
972
942
|
});
|
|
973
943
|
}
|
|
974
|
-
return {
|
|
944
|
+
return {
|
|
945
|
+
...payload,
|
|
946
|
+
bookings: nextBookings,
|
|
947
|
+
products: nextProducts
|
|
948
|
+
};
|
|
975
949
|
};
|
|
976
950
|
}
|
|
977
951
|
async submitScanOrder() {
|
|
978
|
-
|
|
979
|
-
this.logMethodStart("submitScanOrder");
|
|
952
|
+
this.logMethodStart('submitScanOrder');
|
|
980
953
|
try {
|
|
981
954
|
await this.validateBeforeSubmitByItemRule();
|
|
982
955
|
if (!this.store.order) {
|
|
983
|
-
throw new Error(
|
|
956
|
+
throw new Error('scanOrder解决方案需要 order 模块支持');
|
|
984
957
|
}
|
|
985
958
|
const tempOrderForSubmit = this.store.order.ensureTempOrder();
|
|
986
|
-
tempOrderForSubmit.delivery_type =
|
|
987
|
-
const resourceTableName =
|
|
988
|
-
if (resourceTableName && typeof resourceTableName ===
|
|
959
|
+
tempOrderForSubmit.delivery_type = 'shop_service';
|
|
960
|
+
const resourceTableName = this.store.resource?.table_form_record?.name;
|
|
961
|
+
if (resourceTableName && typeof resourceTableName === 'object') {
|
|
989
962
|
tempOrderForSubmit.table_number = resourceTableName;
|
|
990
963
|
} else {
|
|
991
964
|
delete tempOrderForSubmit.table_number;
|
|
@@ -994,68 +967,67 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
994
967
|
const enhancePayload = this.buildSubmitPayloadEnhancer();
|
|
995
968
|
const result = await this.store.order.submitTempOrder({
|
|
996
969
|
cacheId: this.cacheId,
|
|
997
|
-
platform:
|
|
998
|
-
businessCode:
|
|
999
|
-
channel:
|
|
1000
|
-
type:
|
|
970
|
+
platform: this.otherParams?.platform,
|
|
971
|
+
businessCode: this.otherParams?.businessCode,
|
|
972
|
+
channel: this.otherParams?.channel,
|
|
973
|
+
type: this.otherParams?.type,
|
|
1001
974
|
enhancePayload
|
|
1002
975
|
});
|
|
1003
976
|
const tempOrder = this.store.order.getTempOrder();
|
|
1004
|
-
this.logMethodSuccess(
|
|
1005
|
-
productCount:
|
|
977
|
+
this.logMethodSuccess('submitScanOrder', {
|
|
978
|
+
productCount: tempOrder?.products?.length || 0
|
|
1006
979
|
});
|
|
1007
980
|
return result;
|
|
1008
981
|
} catch (error) {
|
|
1009
|
-
this.logMethodError(
|
|
982
|
+
this.logMethodError('submitScanOrder', error);
|
|
1010
983
|
throw error;
|
|
1011
984
|
}
|
|
1012
985
|
}
|
|
1013
986
|
async addProductToOrder(product) {
|
|
1014
|
-
this.logMethodStart(
|
|
987
|
+
this.logMethodStart('addProductToOrder', {
|
|
1015
988
|
product_id: product.product_id,
|
|
1016
989
|
product_variant_id: product.product_variant_id
|
|
1017
990
|
});
|
|
1018
991
|
try {
|
|
1019
|
-
if (!this.store.order)
|
|
1020
|
-
throw new Error("order 模块未初始化");
|
|
992
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1021
993
|
const products = await this.store.order.addProductToOrder(product);
|
|
1022
994
|
await this.refreshItemRuleQuantityLimits();
|
|
1023
995
|
await this.refreshCartValidationPassed();
|
|
1024
|
-
this.logMethodSuccess(
|
|
996
|
+
this.logMethodSuccess('addProductToOrder', {
|
|
1025
997
|
productCount: products.length
|
|
1026
998
|
});
|
|
1027
999
|
return products;
|
|
1028
1000
|
} catch (error) {
|
|
1029
|
-
this.logMethodError(
|
|
1001
|
+
this.logMethodError('addProductToOrder', error);
|
|
1030
1002
|
throw error;
|
|
1031
1003
|
}
|
|
1032
1004
|
}
|
|
1033
1005
|
async updateProductInOrder(params) {
|
|
1034
|
-
this.logMethodStart(
|
|
1006
|
+
this.logMethodStart('updateProductInOrder', {
|
|
1035
1007
|
product_id: params.product_id,
|
|
1036
1008
|
product_variant_id: params.product_variant_id
|
|
1037
1009
|
});
|
|
1038
1010
|
try {
|
|
1039
|
-
if (!this.store.order)
|
|
1040
|
-
throw new Error("order 模块未初始化");
|
|
1011
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1041
1012
|
const products = await this.store.order.updateProductInOrder(params);
|
|
1042
1013
|
await this.refreshItemRuleQuantityLimits();
|
|
1043
1014
|
await this.refreshCartValidationPassed();
|
|
1044
|
-
this.logMethodSuccess(
|
|
1015
|
+
this.logMethodSuccess('updateProductInOrder', {
|
|
1045
1016
|
productCount: products.length
|
|
1046
1017
|
});
|
|
1047
1018
|
return products;
|
|
1048
1019
|
} catch (error) {
|
|
1049
|
-
this.logMethodError(
|
|
1020
|
+
this.logMethodError('updateProductInOrder', error);
|
|
1050
1021
|
throw error;
|
|
1051
1022
|
}
|
|
1052
1023
|
}
|
|
1024
|
+
|
|
1053
1025
|
/**
|
|
1054
1026
|
* 设置单行商品备注(与整单 `updateTempOrderNote` 区分)。
|
|
1055
1027
|
* 多行同 SKU 时必须传入与删除/更新一致的 identity(如 `identity_key`)。
|
|
1056
1028
|
*/
|
|
1057
1029
|
async setOrderProductLineNote(identity, note) {
|
|
1058
|
-
this.logMethodStart(
|
|
1030
|
+
this.logMethodStart('setOrderProductLineNote', {
|
|
1059
1031
|
product_id: identity.product_id,
|
|
1060
1032
|
product_variant_id: identity.product_variant_id
|
|
1061
1033
|
});
|
|
@@ -1063,46 +1035,47 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1063
1035
|
const params = {
|
|
1064
1036
|
product_id: identity.product_id,
|
|
1065
1037
|
product_variant_id: identity.product_variant_id,
|
|
1066
|
-
updates: {
|
|
1038
|
+
updates: {
|
|
1039
|
+
note: String(note || '')
|
|
1040
|
+
}
|
|
1067
1041
|
};
|
|
1068
|
-
if (identity.identity_key !==
|
|
1069
|
-
|
|
1070
|
-
if (identity.product_option_item !== void 0) {
|
|
1042
|
+
if (identity.identity_key !== undefined) params.identity_key = identity.identity_key;
|
|
1043
|
+
if (identity.product_option_item !== undefined) {
|
|
1071
1044
|
params.product_option_item = identity.product_option_item;
|
|
1072
1045
|
}
|
|
1073
|
-
if (identity.product_bundle !==
|
|
1074
|
-
params.product_bundle = identity.product_bundle;
|
|
1046
|
+
if (identity.product_bundle !== undefined) params.product_bundle = identity.product_bundle;
|
|
1075
1047
|
const products = await this.updateProductInOrder(params);
|
|
1076
|
-
this.logMethodSuccess(
|
|
1048
|
+
this.logMethodSuccess('setOrderProductLineNote', {
|
|
1049
|
+
productCount: products.length
|
|
1050
|
+
});
|
|
1077
1051
|
return products;
|
|
1078
1052
|
} catch (error) {
|
|
1079
|
-
this.logMethodError(
|
|
1053
|
+
this.logMethodError('setOrderProductLineNote', error);
|
|
1080
1054
|
throw error;
|
|
1081
1055
|
}
|
|
1082
1056
|
}
|
|
1083
1057
|
async removeProductFromOrder(identity) {
|
|
1084
|
-
this.logMethodStart(
|
|
1058
|
+
this.logMethodStart('removeProductFromOrder', {
|
|
1085
1059
|
product_id: identity.product_id,
|
|
1086
1060
|
product_variant_id: identity.product_variant_id
|
|
1087
1061
|
});
|
|
1088
1062
|
try {
|
|
1089
|
-
if (!this.store.order)
|
|
1090
|
-
throw new Error("order 模块未初始化");
|
|
1063
|
+
if (!this.store.order) throw new Error('order 模块未初始化');
|
|
1091
1064
|
const products = await this.store.order.removeProductFromOrder(identity);
|
|
1092
1065
|
await this.refreshItemRuleQuantityLimits();
|
|
1093
1066
|
await this.refreshCartValidationPassed();
|
|
1094
|
-
this.logMethodSuccess(
|
|
1067
|
+
this.logMethodSuccess('removeProductFromOrder', {
|
|
1095
1068
|
productCount: products.length
|
|
1096
1069
|
});
|
|
1097
1070
|
return products;
|
|
1098
1071
|
} catch (error) {
|
|
1099
|
-
this.logMethodError(
|
|
1072
|
+
this.logMethodError('removeProductFromOrder', error);
|
|
1100
1073
|
throw error;
|
|
1101
1074
|
}
|
|
1102
1075
|
}
|
|
1103
1076
|
async loadRuntimeConfigs() {
|
|
1104
1077
|
const itemRuleConfigs = await this.ensureItemRuleConfigsLoaded();
|
|
1105
|
-
this.logMethodSuccess(
|
|
1078
|
+
this.logMethodSuccess('loadRuntimeConfigs', {
|
|
1106
1079
|
itemRuleCount: itemRuleConfigs.length
|
|
1107
1080
|
});
|
|
1108
1081
|
return {
|
|
@@ -1110,28 +1083,24 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1110
1083
|
};
|
|
1111
1084
|
}
|
|
1112
1085
|
async syncItemRuleConfigsFromDineInConfig(dineInConfig) {
|
|
1113
|
-
const enableItemRules = (0,
|
|
1114
|
-
const strategyModelIds = (0,
|
|
1115
|
-
dineInConfig == null ? void 0 : dineInConfig["sale.enabled_item_rules"]
|
|
1116
|
-
);
|
|
1086
|
+
const enableItemRules = (0, _utils.toBoolean)(dineInConfig?.['sale.enable_item_rules']);
|
|
1087
|
+
const strategyModelIds = (0, _utils.normalizeEnabledItemRuleIds)(dineInConfig?.['sale.enabled_item_rules']);
|
|
1117
1088
|
if (!enableItemRules || !strategyModelIds.length) {
|
|
1118
1089
|
this.itemRuleConfigs = [];
|
|
1119
1090
|
this.itemRuleConfigsPromise = Promise.resolve([]);
|
|
1120
1091
|
this.itemRuleEvaluator.setStrategyConfigs([]);
|
|
1121
|
-
this.logMethodSuccess(
|
|
1092
|
+
this.logMethodSuccess('syncItemRuleConfigsFromDineInConfig', {
|
|
1122
1093
|
enabled: enableItemRules,
|
|
1123
1094
|
strategyModelIds: [],
|
|
1124
1095
|
itemRuleCount: 0
|
|
1125
1096
|
});
|
|
1126
1097
|
return [];
|
|
1127
1098
|
}
|
|
1128
|
-
const itemRuleConfigs = await this.fetchItemRuleConfigsByModelIds(
|
|
1129
|
-
strategyModelIds
|
|
1130
|
-
);
|
|
1099
|
+
const itemRuleConfigs = await this.fetchItemRuleConfigsByModelIds(strategyModelIds);
|
|
1131
1100
|
this.itemRuleConfigs = itemRuleConfigs;
|
|
1132
1101
|
this.itemRuleConfigsPromise = Promise.resolve(itemRuleConfigs);
|
|
1133
1102
|
this.itemRuleEvaluator.setStrategyConfigs(itemRuleConfigs);
|
|
1134
|
-
this.logMethodSuccess(
|
|
1103
|
+
this.logMethodSuccess('syncItemRuleConfigsFromDineInConfig', {
|
|
1135
1104
|
enabled: enableItemRules,
|
|
1136
1105
|
strategyModelIds,
|
|
1137
1106
|
itemRuleCount: itemRuleConfigs.length
|
|
@@ -1139,76 +1108,70 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1139
1108
|
return itemRuleConfigs;
|
|
1140
1109
|
}
|
|
1141
1110
|
async fetchItemRuleConfigsByModelIds(strategyModelIds) {
|
|
1142
|
-
this.logMethodStart(
|
|
1111
|
+
this.logMethodStart('fetchItemRuleConfigsByModelIds', {
|
|
1143
1112
|
strategyModelIds
|
|
1144
1113
|
});
|
|
1145
|
-
if (!strategyModelIds.length)
|
|
1146
|
-
return [];
|
|
1114
|
+
if (!strategyModelIds.length) return [];
|
|
1147
1115
|
try {
|
|
1148
|
-
const result = await this.request.get(
|
|
1116
|
+
const result = await this.request.get('/promotion', {
|
|
1149
1117
|
skip: 1,
|
|
1150
1118
|
num: 99,
|
|
1151
|
-
status:
|
|
1119
|
+
status: 'active',
|
|
1152
1120
|
ids: strategyModelIds
|
|
1153
1121
|
});
|
|
1154
1122
|
let configs = [];
|
|
1155
1123
|
if (result.code === 200) {
|
|
1156
|
-
configs = result.data.list.map(
|
|
1124
|
+
configs = result.data.list.map(item => {
|
|
1157
1125
|
return item.metadata;
|
|
1158
1126
|
});
|
|
1159
1127
|
}
|
|
1160
|
-
this.logMethodSuccess(
|
|
1128
|
+
this.logMethodSuccess('fetchItemRuleConfigsByModelIds', {
|
|
1161
1129
|
strategyModelIds,
|
|
1162
1130
|
strategyCount: configs.length
|
|
1163
1131
|
});
|
|
1164
1132
|
return configs;
|
|
1165
1133
|
} catch (error) {
|
|
1166
|
-
this.logMethodError(
|
|
1134
|
+
this.logMethodError('fetchItemRuleConfigsByModelIds', error, {
|
|
1167
1135
|
strategyModelIds
|
|
1168
1136
|
});
|
|
1137
|
+
// A:策略加载失败时不阻塞下单
|
|
1169
1138
|
return [];
|
|
1170
1139
|
}
|
|
1171
1140
|
}
|
|
1172
1141
|
async buildPrefillProductSourceMap() {
|
|
1173
|
-
const sourceMap =
|
|
1142
|
+
const sourceMap = new Map();
|
|
1174
1143
|
try {
|
|
1175
1144
|
const productList = await this.getProductList();
|
|
1176
|
-
if (!Array.isArray(productList))
|
|
1177
|
-
|
|
1178
|
-
const
|
|
1179
|
-
|
|
1180
|
-
if (
|
|
1181
|
-
return;
|
|
1182
|
-
if (visited.has(value))
|
|
1183
|
-
return;
|
|
1145
|
+
if (!Array.isArray(productList)) return sourceMap;
|
|
1146
|
+
const visited = new Set();
|
|
1147
|
+
const collectFromValue = value => {
|
|
1148
|
+
if (!value || typeof value !== 'object') return;
|
|
1149
|
+
if (visited.has(value)) return;
|
|
1184
1150
|
visited.add(value);
|
|
1185
1151
|
if (Array.isArray(value)) {
|
|
1186
|
-
for (const item of value)
|
|
1187
|
-
collectFromValue(item);
|
|
1152
|
+
for (const item of value) collectFromValue(item);
|
|
1188
1153
|
return;
|
|
1189
1154
|
}
|
|
1190
1155
|
const node = value;
|
|
1191
1156
|
const rawProductId = node.product_id ?? node.id;
|
|
1192
1157
|
const productId = Number(rawProductId);
|
|
1193
1158
|
if (Number.isFinite(productId) && productId > 0) {
|
|
1194
|
-
const productVariantId = Number(
|
|
1195
|
-
node.product_variant_id ?? node.variant_id ?? 0
|
|
1196
|
-
);
|
|
1159
|
+
const productVariantId = Number(node.product_variant_id ?? node.variant_id ?? 0);
|
|
1197
1160
|
const normalizedVariantId = Number.isNaN(productVariantId) ? 0 : productVariantId;
|
|
1198
|
-
const key = (0,
|
|
1161
|
+
const key = (0, _utils.buildProductKey)(productId, normalizedVariantId);
|
|
1199
1162
|
if (!sourceMap.has(key)) {
|
|
1200
1163
|
sourceMap.set(key, node);
|
|
1201
1164
|
}
|
|
1202
1165
|
}
|
|
1203
1166
|
for (const childValue of Object.values(node)) {
|
|
1204
|
-
if (childValue && typeof childValue ===
|
|
1167
|
+
if (childValue && typeof childValue === 'object') {
|
|
1205
1168
|
collectFromValue(childValue);
|
|
1206
1169
|
}
|
|
1207
1170
|
}
|
|
1208
1171
|
};
|
|
1209
1172
|
collectFromValue(productList);
|
|
1210
1173
|
} catch (error) {
|
|
1211
|
-
this.logMethodError(
|
|
1174
|
+
this.logMethodError('buildPrefillProductSourceMap', error);
|
|
1212
1175
|
}
|
|
1213
1176
|
return sourceMap;
|
|
1214
1177
|
}
|
|
@@ -1216,13 +1179,11 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1216
1179
|
return this.itemRuleRuntimeConfig || {};
|
|
1217
1180
|
}
|
|
1218
1181
|
async ensureItemRuleConfigsLoaded() {
|
|
1219
|
-
if (this.itemRuleConfigs.length > 0)
|
|
1220
|
-
|
|
1221
|
-
if (this.itemRuleConfigsPromise)
|
|
1222
|
-
return this.itemRuleConfigsPromise;
|
|
1182
|
+
if (this.itemRuleConfigs.length > 0) return this.itemRuleConfigs;
|
|
1183
|
+
if (this.itemRuleConfigsPromise) return this.itemRuleConfigsPromise;
|
|
1223
1184
|
this.itemRuleConfigsPromise = (async () => {
|
|
1224
1185
|
const runtimeConfig = this.getItemRuleRuntimeConfig();
|
|
1225
|
-
const staticConfigs = (0,
|
|
1186
|
+
const staticConfigs = (0, _utils.normalizeItemRuleStrategies)(runtimeConfig.strategyConfigs);
|
|
1226
1187
|
if (staticConfigs.length > 0) {
|
|
1227
1188
|
this.itemRuleConfigs = staticConfigs;
|
|
1228
1189
|
this.itemRuleEvaluator.setStrategyConfigs(staticConfigs);
|
|
@@ -1242,33 +1203,29 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1242
1203
|
this.store.itemRuleQuantityLimits = [];
|
|
1243
1204
|
return [];
|
|
1244
1205
|
}
|
|
1245
|
-
const businessData = (0,
|
|
1206
|
+
const businessData = (0, _utils.buildItemRuleBusinessData)({
|
|
1246
1207
|
tempOrder: this.ensureTempOrder(),
|
|
1247
1208
|
runtimeConfig: this.getItemRuleRuntimeConfig(),
|
|
1248
1209
|
itemRuleConfigs: this.itemRuleConfigs
|
|
1249
1210
|
});
|
|
1250
1211
|
const limits = this.itemRuleEvaluator.getQuantityLimits(businessData);
|
|
1251
1212
|
this.store.itemRuleQuantityLimits = limits;
|
|
1252
|
-
this.logMethodSuccess(
|
|
1213
|
+
this.logMethodSuccess('refreshItemRuleQuantityLimits', {
|
|
1253
1214
|
limitCount: limits.length
|
|
1254
1215
|
});
|
|
1255
1216
|
return limits;
|
|
1256
1217
|
} catch (error) {
|
|
1257
1218
|
this.store.itemRuleQuantityLimits = [];
|
|
1258
|
-
this.logMethodError(
|
|
1219
|
+
this.logMethodError('refreshItemRuleQuantityLimits', error);
|
|
1259
1220
|
return [];
|
|
1260
1221
|
}
|
|
1261
1222
|
}
|
|
1262
1223
|
async applyPrefillByItemRule() {
|
|
1263
|
-
|
|
1264
|
-
if (this.
|
|
1265
|
-
return;
|
|
1266
|
-
if (!this.store.order)
|
|
1267
|
-
return;
|
|
1224
|
+
if (this.itemRulePrefillApplied) return;
|
|
1225
|
+
if (!this.store.order) return;
|
|
1268
1226
|
const strategyConfigs = await this.ensureItemRuleConfigsLoaded();
|
|
1269
|
-
if (!strategyConfigs.length)
|
|
1270
|
-
|
|
1271
|
-
const businessData = (0, import_utils.buildItemRuleBusinessData)({
|
|
1227
|
+
if (!strategyConfigs.length) return;
|
|
1228
|
+
const businessData = (0, _utils.buildItemRuleBusinessData)({
|
|
1272
1229
|
tempOrder: this.ensureTempOrder(),
|
|
1273
1230
|
runtimeConfig: this.getItemRuleRuntimeConfig(),
|
|
1274
1231
|
itemRuleConfigs: this.itemRuleConfigs
|
|
@@ -1284,88 +1241,81 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1284
1241
|
for (const prefillItem of prefillItems) {
|
|
1285
1242
|
const productId = Number(prefillItem.product_id);
|
|
1286
1243
|
const productVariantId = Number(prefillItem.product_variant_id ?? 0);
|
|
1287
|
-
const targetQuantity = (0,
|
|
1288
|
-
if (!Number.isFinite(productId) || targetQuantity <= 0)
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
const sourceItem = productSourceMap.get(
|
|
1293
|
-
(0, import_utils.buildProductKey)(productId, productVariantId)
|
|
1294
|
-
) || productSourceMap.get((0, import_utils.buildProductKey)(productId, 0)) || null;
|
|
1295
|
-
const productIndex = (0, import_utils.getProductIdentityIndex)(tempOrder.products, {
|
|
1244
|
+
const targetQuantity = (0, _utils.toNonNegativeInt)(prefillItem.quantity);
|
|
1245
|
+
if (!Number.isFinite(productId) || targetQuantity <= 0) continue;
|
|
1246
|
+
if (Number.isNaN(productVariantId)) continue;
|
|
1247
|
+
const sourceItem = productSourceMap.get((0, _utils.buildProductKey)(productId, productVariantId)) || productSourceMap.get((0, _utils.buildProductKey)(productId, 0)) || null;
|
|
1248
|
+
const productIndex = (0, _utils.getProductIdentityIndex)(tempOrder.products, {
|
|
1296
1249
|
product_id: productId,
|
|
1297
1250
|
product_variant_id: productVariantId
|
|
1298
1251
|
});
|
|
1299
1252
|
if (productIndex === -1) {
|
|
1300
|
-
const sellingPrice = (0,
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
item_rule_prefill: true,
|
|
1319
|
-
item_rule_id: prefillItem.ruleId
|
|
1320
|
-
}
|
|
1321
|
-
})
|
|
1322
|
-
);
|
|
1253
|
+
const sellingPrice = (0, _utils.toPriceString)(sourceItem?.price ?? sourceItem?.selling_price, '0.00');
|
|
1254
|
+
tempOrder.products.push((0, _utils.normalizeOrderProduct)({
|
|
1255
|
+
...sourceItem,
|
|
1256
|
+
product_id: productId,
|
|
1257
|
+
product_variant_id: productVariantId,
|
|
1258
|
+
num: targetQuantity,
|
|
1259
|
+
selling_price: sellingPrice,
|
|
1260
|
+
original_price: sellingPrice,
|
|
1261
|
+
metadata: {
|
|
1262
|
+
item_rule_prefill: true,
|
|
1263
|
+
item_rule_id: prefillItem.ruleId
|
|
1264
|
+
},
|
|
1265
|
+
_origin: {
|
|
1266
|
+
...(sourceItem || {}),
|
|
1267
|
+
item_rule_prefill: true,
|
|
1268
|
+
item_rule_id: prefillItem.ruleId
|
|
1269
|
+
}
|
|
1270
|
+
}));
|
|
1323
1271
|
hasChanges = true;
|
|
1324
1272
|
continue;
|
|
1325
1273
|
}
|
|
1326
1274
|
const targetProduct = tempOrder.products[productIndex];
|
|
1327
|
-
const existedQuantity = (0,
|
|
1275
|
+
const existedQuantity = (0, _utils.toNonNegativeInt)(targetProduct.num);
|
|
1328
1276
|
const delta = targetQuantity - existedQuantity;
|
|
1329
1277
|
const nextProduct = {
|
|
1330
1278
|
...targetProduct,
|
|
1331
|
-
...delta > 0 ? {
|
|
1279
|
+
...(delta > 0 ? {
|
|
1280
|
+
num: (0, _utils.getSafeProductNum)(existedQuantity + delta)
|
|
1281
|
+
} : {}),
|
|
1332
1282
|
metadata: {
|
|
1333
|
-
...targetProduct.metadata || {},
|
|
1283
|
+
...(targetProduct.metadata || {}),
|
|
1334
1284
|
item_rule_prefill: true,
|
|
1335
1285
|
item_rule_id: prefillItem.ruleId
|
|
1336
1286
|
},
|
|
1337
1287
|
_origin: sourceItem ? {
|
|
1338
|
-
...targetProduct._origin || {},
|
|
1288
|
+
...(targetProduct._origin || {}),
|
|
1339
1289
|
...sourceItem
|
|
1340
1290
|
} : targetProduct._origin
|
|
1341
1291
|
};
|
|
1342
1292
|
const hasQuantityChanged = delta > 0;
|
|
1343
|
-
const hasOriginChanged = Boolean(
|
|
1344
|
-
sourceItem && (!targetProduct._origin || ((_a = targetProduct._origin) == null ? void 0 : _a.name) !== (sourceItem == null ? void 0 : sourceItem.name) || ((_b = targetProduct._origin) == null ? void 0 : _b.title) !== (sourceItem == null ? void 0 : sourceItem.title) || ((_c = targetProduct._origin) == null ? void 0 : _c.price) !== (sourceItem == null ? void 0 : sourceItem.price))
|
|
1345
|
-
);
|
|
1293
|
+
const hasOriginChanged = Boolean(sourceItem && (!targetProduct._origin || targetProduct._origin?.name !== sourceItem?.name || targetProduct._origin?.title !== sourceItem?.title || targetProduct._origin?.price !== sourceItem?.price));
|
|
1346
1294
|
if (hasQuantityChanged || hasOriginChanged) {
|
|
1347
1295
|
tempOrder.products[productIndex] = nextProduct;
|
|
1348
1296
|
hasChanges = true;
|
|
1349
1297
|
}
|
|
1350
1298
|
}
|
|
1351
1299
|
if (hasChanges) {
|
|
1300
|
+
// Prefill 属于 products CRUD 的一种形式:新增后让 Rules 重算,以支持自动应用可用优惠券。
|
|
1352
1301
|
this.store.order.applyDiscount();
|
|
1353
|
-
await this.store.order.recalculateSummary({
|
|
1302
|
+
await this.store.order.recalculateSummary({
|
|
1303
|
+
createIfMissing: true
|
|
1304
|
+
});
|
|
1354
1305
|
this.store.order.persistTempOrder();
|
|
1355
1306
|
}
|
|
1356
1307
|
await this.refreshItemRuleQuantityLimits();
|
|
1357
1308
|
this.itemRulePrefillApplied = true;
|
|
1358
|
-
this.logMethodSuccess(
|
|
1309
|
+
this.logMethodSuccess('applyPrefillByItemRule', {
|
|
1359
1310
|
prefillCount: prefillItems.length,
|
|
1360
1311
|
hasChanges
|
|
1361
1312
|
});
|
|
1362
1313
|
}
|
|
1363
1314
|
async applyItemRulePrefill() {
|
|
1364
|
-
|
|
1365
|
-
if ((_b = (_a = this.store.order) == null ? void 0 : _a.getLastOrderInfo) == null ? void 0 : _b.call(_a)) {
|
|
1315
|
+
if (this.store.order?.getLastOrderInfo?.()) {
|
|
1366
1316
|
return;
|
|
1367
1317
|
}
|
|
1368
|
-
this.logMethodStart(
|
|
1318
|
+
this.logMethodStart('applyItemRulePrefill');
|
|
1369
1319
|
await this.applyPrefillByItemRule();
|
|
1370
1320
|
await this.refreshItemRuleQuantityLimits();
|
|
1371
1321
|
await this.refreshCartValidationPassed();
|
|
@@ -1378,7 +1328,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1378
1328
|
failures: []
|
|
1379
1329
|
};
|
|
1380
1330
|
}
|
|
1381
|
-
const businessData = (0,
|
|
1331
|
+
const businessData = (0, _utils.buildItemRuleBusinessData)({
|
|
1382
1332
|
tempOrder: this.ensureTempOrder(),
|
|
1383
1333
|
runtimeConfig: this.getItemRuleRuntimeConfig(),
|
|
1384
1334
|
itemRuleConfigs: this.itemRuleConfigs
|
|
@@ -1387,10 +1337,9 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1387
1337
|
}
|
|
1388
1338
|
async validateBeforeSubmitByItemRule() {
|
|
1389
1339
|
const validationResult = await this.evaluateCartValidationByItemRule();
|
|
1390
|
-
if (validationResult.passed)
|
|
1391
|
-
return;
|
|
1340
|
+
if (validationResult.passed) return;
|
|
1392
1341
|
const firstFailure = validationResult.failures[0];
|
|
1393
|
-
const errorMessage =
|
|
1342
|
+
const errorMessage = firstFailure?.validationMessage || '当前购物车未满足商品规则,请调整后再提交';
|
|
1394
1343
|
const error = new Error(String(errorMessage));
|
|
1395
1344
|
error.failures = validationResult.failures;
|
|
1396
1345
|
throw error;
|
|
@@ -1419,7 +1368,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1419
1368
|
this.store.cartValidation = nextState;
|
|
1420
1369
|
const changed = previous.passed !== nextState.passed || previous.failures !== nextState.failures;
|
|
1421
1370
|
if (changed) {
|
|
1422
|
-
await this.core.effects.emit(
|
|
1371
|
+
await this.core.effects.emit(_types.ScanOrderHooks.onCartValidationChanged, {
|
|
1423
1372
|
cartValidation: nextState,
|
|
1424
1373
|
cartValidationPassed: nextState.passed
|
|
1425
1374
|
});
|
|
@@ -1427,21 +1376,20 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1427
1376
|
return nextState.passed;
|
|
1428
1377
|
}
|
|
1429
1378
|
async setItemRuleRuntimeConfig(config = {}) {
|
|
1430
|
-
|
|
1431
|
-
this.logMethodStart("setItemRuleRuntimeConfig");
|
|
1379
|
+
this.logMethodStart('setItemRuleRuntimeConfig');
|
|
1432
1380
|
this.itemRuleRuntimeConfig = {
|
|
1433
1381
|
...this.itemRuleRuntimeConfig,
|
|
1434
1382
|
...config,
|
|
1435
1383
|
pax: {
|
|
1436
|
-
...(
|
|
1437
|
-
...(config
|
|
1384
|
+
...(this.itemRuleRuntimeConfig?.pax || {}),
|
|
1385
|
+
...(config?.pax || {})
|
|
1438
1386
|
},
|
|
1439
1387
|
custom: {
|
|
1440
|
-
...(
|
|
1441
|
-
...(config
|
|
1388
|
+
...(this.itemRuleRuntimeConfig?.custom || {}),
|
|
1389
|
+
...(config?.custom || {})
|
|
1442
1390
|
}
|
|
1443
1391
|
};
|
|
1444
|
-
if (
|
|
1392
|
+
if ('strategyConfigs' in config) {
|
|
1445
1393
|
this.itemRuleConfigs = [];
|
|
1446
1394
|
this.itemRuleConfigsPromise = null;
|
|
1447
1395
|
this.itemRuleEvaluator.setStrategyConfigs([]);
|
|
@@ -1449,42 +1397,47 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1449
1397
|
this.itemRulePrefillApplied = false;
|
|
1450
1398
|
await this.refreshItemRuleQuantityLimits();
|
|
1451
1399
|
await this.refreshCartValidationPassed();
|
|
1452
|
-
this.logMethodSuccess(
|
|
1400
|
+
this.logMethodSuccess('setItemRuleRuntimeConfig', {
|
|
1453
1401
|
strategyCount: Array.isArray(this.itemRuleRuntimeConfig.strategyConfigs) ? this.itemRuleRuntimeConfig.strategyConfigs.length : 0
|
|
1454
1402
|
});
|
|
1455
1403
|
}
|
|
1456
1404
|
normalizeResourceState(detail, resourceSelectType, hasOrderId) {
|
|
1457
|
-
|
|
1458
|
-
const
|
|
1459
|
-
const
|
|
1460
|
-
const
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1463
|
-
const allowSnack =
|
|
1405
|
+
const currentOrderId = (0, _utils.toPositiveString)(detail?.order_id);
|
|
1406
|
+
const lastOrderId = (0, _utils.toPositiveString)(detail?.last_order_id);
|
|
1407
|
+
const relationId = (0, _utils.toPositiveString)(detail?.form_record_id);
|
|
1408
|
+
const tableFormId = (0, _utils.toPositiveString)(detail?.form_id);
|
|
1409
|
+
const formRecord = detail?.form_record ?? null;
|
|
1410
|
+
// 是否允许加餐
|
|
1411
|
+
const allowSnack = this.otherParams?.dineInConfig?.['sale.allow_add_items'] || false;
|
|
1412
|
+
// 开启同桌验证 - 本期没有这个配置,默认关掉
|
|
1464
1413
|
const deskmateValid = false;
|
|
1465
|
-
const isExclusive = resourceSelectType ===
|
|
1466
|
-
const isFull = (0,
|
|
1414
|
+
const isExclusive = resourceSelectType === 'single';
|
|
1415
|
+
const isFull = (0, _utils.computeResourceIsFull)({
|
|
1467
1416
|
resourceSelectType,
|
|
1468
1417
|
lastOrderId,
|
|
1469
|
-
capacityList:
|
|
1470
|
-
capacity: formRecord
|
|
1418
|
+
capacityList: detail?.resource_capacity?.[0]?.capacity_list ?? [],
|
|
1419
|
+
capacity: formRecord?.capacity
|
|
1471
1420
|
});
|
|
1472
1421
|
let availabilityInfo = {
|
|
1473
|
-
mode:
|
|
1422
|
+
mode: 'idle',
|
|
1474
1423
|
deskmate_valid: deskmateValid
|
|
1475
1424
|
};
|
|
1425
|
+
|
|
1426
|
+
// 有currentOrderId代表是我点的单
|
|
1427
|
+
// 如果 url 上没有 hasOrderId,则跳转到订单详情,通过返回 resource_busy 实现
|
|
1476
1428
|
if (currentOrderId) {
|
|
1477
1429
|
if (!hasOrderId) {
|
|
1478
1430
|
availabilityInfo = {
|
|
1479
|
-
mode:
|
|
1431
|
+
mode: 'resource_busy',
|
|
1480
1432
|
order_id: currentOrderId,
|
|
1481
1433
|
relation_id: relationId,
|
|
1482
1434
|
table_form_id: tableFormId,
|
|
1483
1435
|
deskmate_valid: deskmateValid
|
|
1484
1436
|
};
|
|
1485
1437
|
} else {
|
|
1438
|
+
// 如果有 hasOrderId,需要检测是否允许加餐,如果允许则返回additional_order,否则也是 resource_busy
|
|
1486
1439
|
availabilityInfo = {
|
|
1487
|
-
mode: allowSnack ?
|
|
1440
|
+
mode: allowSnack ? 'additional_order' : 'resource_busy',
|
|
1488
1441
|
order_id: currentOrderId,
|
|
1489
1442
|
relation_id: relationId,
|
|
1490
1443
|
table_form_id: tableFormId,
|
|
@@ -1492,11 +1445,13 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1492
1445
|
};
|
|
1493
1446
|
}
|
|
1494
1447
|
} else if (lastOrderId) {
|
|
1495
|
-
|
|
1448
|
+
// 如果有其他人点的单
|
|
1449
|
+
// multiple 预约且容量仍有剩余时,其他人的单不影响当前用户下单,保持 idle 走正常下单流程
|
|
1450
|
+
const canFallthroughToIdle = resourceSelectType === 'multiple' && !isFull;
|
|
1496
1451
|
if (!canFallthroughToIdle) {
|
|
1497
1452
|
availabilityInfo = {
|
|
1498
|
-
mode:
|
|
1499
|
-
order_id:
|
|
1453
|
+
mode: 'resource_busy',
|
|
1454
|
+
order_id: '0',
|
|
1500
1455
|
relation_id: relationId,
|
|
1501
1456
|
table_form_id: tableFormId,
|
|
1502
1457
|
deskmate_valid: deskmateValid
|
|
@@ -1518,67 +1473,62 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1518
1473
|
table_form_record: formRecord
|
|
1519
1474
|
};
|
|
1520
1475
|
}
|
|
1476
|
+
|
|
1521
1477
|
// 从首个预约规则商品的 product_resource.resources 中,按 form_id 匹配返回 type
|
|
1522
1478
|
resolveResourceSelectType(formId) {
|
|
1523
|
-
var _a;
|
|
1524
1479
|
const firstProduct = this.enabledReservationRuleProducts[0];
|
|
1525
|
-
const resources =
|
|
1480
|
+
const resources = firstProduct?.product_resource?.resources || [];
|
|
1526
1481
|
const numericFormId = Number(formId);
|
|
1527
|
-
if (!Number.isFinite(numericFormId) || numericFormId <= 0)
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
return matched == null ? void 0 : matched.type;
|
|
1482
|
+
if (!Number.isFinite(numericFormId) || numericFormId <= 0) return undefined;
|
|
1483
|
+
const matched = resources.find(r => Number(r?.id) === numericFormId);
|
|
1484
|
+
return matched?.type;
|
|
1531
1485
|
}
|
|
1532
1486
|
async fetchResourceOccupyDetailsByResourceId(resourceId) {
|
|
1533
|
-
var _a, _b, _c;
|
|
1534
1487
|
const formRecordId = Number(resourceId);
|
|
1535
1488
|
if (!Number.isFinite(formRecordId) || formRecordId <= 0) {
|
|
1536
1489
|
throw new Error(`[ScanOrder] 非法桌台 resourceId: ${resourceId}`);
|
|
1537
1490
|
}
|
|
1538
|
-
const shopId =
|
|
1491
|
+
const shopId = this.otherParams?.getStateData?.('shop_id');
|
|
1539
1492
|
if (!shopId) {
|
|
1540
|
-
throw new Error(
|
|
1541
|
-
}
|
|
1542
|
-
const response = await this.request.get(
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
);
|
|
1552
|
-
if (!(response == null ? void 0 : response.status)) {
|
|
1553
|
-
throw new Error((response == null ? void 0 : response.message) || "获取资源占用详情失败");
|
|
1493
|
+
throw new Error('[ScanOrder] 无法获取 shop_id');
|
|
1494
|
+
}
|
|
1495
|
+
const response = await this.request.get('/order/resource/occupy-detail', {
|
|
1496
|
+
shop_id: shopId,
|
|
1497
|
+
'form_record_ids[]': formRecordId,
|
|
1498
|
+
with_resource_capacity_info: 1,
|
|
1499
|
+
with_resource_order_info: 1,
|
|
1500
|
+
with_resource_form_info: 1
|
|
1501
|
+
});
|
|
1502
|
+
if (!response?.status) {
|
|
1503
|
+
throw new Error(response?.message || '获取资源占用详情失败');
|
|
1554
1504
|
}
|
|
1555
|
-
return
|
|
1505
|
+
return response?.data?.occupy_details ?? [];
|
|
1556
1506
|
}
|
|
1557
1507
|
resolveAdditionalOrderFromOccupyDetail(detail, resourceSelectType, allowAddItems) {
|
|
1558
|
-
const currentOrderId = (0,
|
|
1508
|
+
const currentOrderId = (0, _utils.toPositiveString)(detail?.order_id);
|
|
1559
1509
|
if (currentOrderId) {
|
|
1560
1510
|
return {
|
|
1561
1511
|
matched: true,
|
|
1562
1512
|
order_id: currentOrderId
|
|
1563
1513
|
};
|
|
1564
1514
|
}
|
|
1565
|
-
const orderListIds = (Array.isArray(detail
|
|
1566
|
-
if (resourceSelectType !==
|
|
1515
|
+
const orderListIds = (Array.isArray(detail?.order_list) ? detail?.order_list || [] : []).map(order => (0, _utils.toPositiveString)(order?.id)).filter(Boolean);
|
|
1516
|
+
if (resourceSelectType !== 'single') {
|
|
1567
1517
|
return {
|
|
1568
1518
|
matched: false,
|
|
1569
|
-
reason:
|
|
1519
|
+
reason: 'no_order'
|
|
1570
1520
|
};
|
|
1571
1521
|
}
|
|
1572
1522
|
if (!orderListIds.length) {
|
|
1573
1523
|
return {
|
|
1574
1524
|
matched: false,
|
|
1575
|
-
reason:
|
|
1525
|
+
reason: 'no_order'
|
|
1576
1526
|
};
|
|
1577
1527
|
}
|
|
1578
1528
|
if (!allowAddItems) {
|
|
1579
1529
|
return {
|
|
1580
1530
|
matched: false,
|
|
1581
|
-
reason:
|
|
1531
|
+
reason: 'add_items_disabled'
|
|
1582
1532
|
};
|
|
1583
1533
|
}
|
|
1584
1534
|
if (orderListIds.length === 1) {
|
|
@@ -1590,94 +1540,103 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1590
1540
|
if (orderListIds.length > 1) {
|
|
1591
1541
|
return {
|
|
1592
1542
|
matched: false,
|
|
1593
|
-
reason:
|
|
1543
|
+
reason: 'multiple_orders'
|
|
1594
1544
|
};
|
|
1595
1545
|
}
|
|
1596
1546
|
return {
|
|
1597
1547
|
matched: false,
|
|
1598
|
-
reason:
|
|
1548
|
+
reason: 'no_order'
|
|
1599
1549
|
};
|
|
1600
1550
|
}
|
|
1551
|
+
|
|
1601
1552
|
// 检测当前链接是否可用
|
|
1602
1553
|
// 通过 resource_id + 店铺配置
|
|
1603
1554
|
// hasOrderId 表示 url 上是否有 orderid,如果是的话,后续的流程会走加单
|
|
1604
1555
|
async checkResourceAvailable(resourceId, hasOrderId = false) {
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
this.logMethodStart("checkResourceAvailable", {
|
|
1556
|
+
const normalizedResourceId = String(resourceId ?? '').trim();
|
|
1557
|
+
this.logMethodStart('checkResourceAvailable', {
|
|
1608
1558
|
resourceId: normalizedResourceId
|
|
1609
1559
|
});
|
|
1610
1560
|
try {
|
|
1611
|
-
const businessCode = String(
|
|
1612
|
-
const channel = String(
|
|
1613
|
-
const openDataTarget = businessCode && channel ? `${businessCode}+${channel}` :
|
|
1614
|
-
const openData = await
|
|
1615
|
-
scope:
|
|
1561
|
+
const businessCode = String(this.otherParams?.businessCode ?? '').trim();
|
|
1562
|
+
const channel = String(this.otherParams?.channel ?? '').trim();
|
|
1563
|
+
const openDataTarget = businessCode && channel ? `${businessCode}+${channel}` : 'dine_in+scan_to_order';
|
|
1564
|
+
const openData = await this.otherParams?.getOpenData?.({
|
|
1565
|
+
scope: 'board',
|
|
1616
1566
|
target: openDataTarget,
|
|
1617
|
-
section_code: [
|
|
1618
|
-
})
|
|
1619
|
-
if (
|
|
1620
|
-
throw new Error(
|
|
1567
|
+
section_code: ['basic', 'fulfillment', 'reservation', 'sale', 'menu', 'availability', 'workflow']
|
|
1568
|
+
});
|
|
1569
|
+
if (openData?.status === false) {
|
|
1570
|
+
throw new Error(openData?.message || '获取店铺配置失败');
|
|
1621
1571
|
}
|
|
1622
|
-
const dineInConfig =
|
|
1572
|
+
const dineInConfig = openData?.data || {};
|
|
1623
1573
|
this.otherParams.dineInConfig = dineInConfig;
|
|
1624
1574
|
await this.syncItemRuleConfigsFromDineInConfig(dineInConfig);
|
|
1625
|
-
const closedBehaviorValue = dineInConfig
|
|
1626
|
-
const closedMessage =
|
|
1627
|
-
const basicUnavailableMessage =
|
|
1628
|
-
const pauseMessage =
|
|
1575
|
+
const closedBehaviorValue = dineInConfig?.['availability.closed_behavior'];
|
|
1576
|
+
const closedMessage = dineInConfig?.['availability.closed_message'] || dineInConfig?.['availability.message'] || dineInConfig?.['basic.closed_message'];
|
|
1577
|
+
const basicUnavailableMessage = dineInConfig?.['basic.unavailable_message'] || closedMessage;
|
|
1578
|
+
const pauseMessage = dineInConfig?.['availability.pause_message'] || closedMessage;
|
|
1629
1579
|
const makeShopClosed = (errorTips, closed_behavior) => ({
|
|
1630
|
-
mode:
|
|
1631
|
-
order_id:
|
|
1632
|
-
relation_id:
|
|
1633
|
-
table_form_id:
|
|
1580
|
+
mode: 'shop_closed',
|
|
1581
|
+
order_id: undefined,
|
|
1582
|
+
relation_id: undefined,
|
|
1583
|
+
table_form_id: undefined,
|
|
1634
1584
|
deskmate_valid: false,
|
|
1635
1585
|
errorTips,
|
|
1636
1586
|
closed_behavior
|
|
1637
1587
|
});
|
|
1638
|
-
|
|
1588
|
+
|
|
1589
|
+
// 1. 基础开关 basic.enable 关闭
|
|
1590
|
+
if (dineInConfig?.['basic.enable'] === false) {
|
|
1639
1591
|
return makeShopClosed(basicUnavailableMessage);
|
|
1640
1592
|
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1593
|
+
|
|
1594
|
+
// 2. 暂停营业(保留原有逻辑:仅 hide_all 才阻止进入)
|
|
1595
|
+
if ((0, _utils.toBoolean)(dineInConfig?.['availability.paused'])) {
|
|
1596
|
+
if (dineInConfig?.['availability.pause_behavior'] === 'hide_all') {
|
|
1643
1597
|
return makeShopClosed(pauseMessage);
|
|
1644
1598
|
}
|
|
1645
1599
|
}
|
|
1646
|
-
|
|
1600
|
+
|
|
1601
|
+
// 3. 营业时间 operating_hours 闸门
|
|
1602
|
+
const operatingHourIds = Array.isArray(dineInConfig?.['availability.operating_hours']) ? dineInConfig['availability.operating_hours'].map(id => Number(id)).filter(id => Number.isFinite(id) && id > 0) : [];
|
|
1647
1603
|
let outsideOperatingHours = false;
|
|
1648
1604
|
if (operatingHourIds.length && this.store.schedule) {
|
|
1649
1605
|
const scheduleList = this.store.schedule.getScheduleListByIds(operatingHourIds);
|
|
1650
1606
|
if (scheduleList.length) {
|
|
1651
|
-
const now = (0,
|
|
1652
|
-
outsideOperatingHours = !(0,
|
|
1607
|
+
const now = (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss');
|
|
1608
|
+
outsideOperatingHours = !(0, _getDateIsInSchedule.getDateIsInSchedule)(now, scheduleList);
|
|
1653
1609
|
}
|
|
1654
1610
|
}
|
|
1655
|
-
if (outsideOperatingHours && closedBehaviorValue !==
|
|
1611
|
+
if (outsideOperatingHours && closedBehaviorValue !== 'show_menu_disabled') {
|
|
1656
1612
|
return makeShopClosed(closedMessage, closedBehaviorValue);
|
|
1657
1613
|
}
|
|
1614
|
+
|
|
1615
|
+
// Step1: 先加载预约规则商品,拿到 enabledReservationRuleProducts 与容量附加信息
|
|
1616
|
+
// (resourceSelectType 需要基于这些商品 + 占用接口的 form_id 计算,故必须前置)
|
|
1658
1617
|
const tempOrder = this.ensureTempOrder();
|
|
1659
|
-
const reservationLinkIds = (0,
|
|
1660
|
-
dineInConfig["fulfillment.enabled_resource_rules"]
|
|
1661
|
-
);
|
|
1618
|
+
const reservationLinkIds = (0, _utils.collectLinkProductIdsFromReservationRules)(dineInConfig['fulfillment.enabled_resource_rules']);
|
|
1662
1619
|
if (!normalizedResourceId || reservationLinkIds.length === 0) {
|
|
1663
1620
|
return await this.prepareRetailAvailability({
|
|
1664
1621
|
tempOrder,
|
|
1665
1622
|
hasOrderId,
|
|
1666
1623
|
resourceId: normalizedResourceId,
|
|
1667
|
-
reason: !normalizedResourceId ?
|
|
1624
|
+
reason: !normalizedResourceId ? 'missing_resource_id' : 'missing_enabled_resource_rules'
|
|
1668
1625
|
});
|
|
1669
1626
|
}
|
|
1670
1627
|
let pendingRequestEntryPax;
|
|
1671
1628
|
let pendingRequestPaxMin;
|
|
1672
1629
|
let pendingRequestPaxMax;
|
|
1673
|
-
tempOrder.metadata = {
|
|
1630
|
+
tempOrder.metadata = {
|
|
1631
|
+
...(tempOrder.metadata || {})
|
|
1632
|
+
};
|
|
1674
1633
|
delete tempOrder.metadata.table_occupancy_duration;
|
|
1675
|
-
const reservationProductList = new
|
|
1676
|
-
`${this.name}_reservationEnabledRules`,
|
|
1677
|
-
this.defaultVersion
|
|
1678
|
-
);
|
|
1634
|
+
const reservationProductList = new _ProductList.ProductList(`${this.name}_reservationEnabledRules`, this.defaultVersion);
|
|
1679
1635
|
await reservationProductList.initialize(this.core, {
|
|
1680
|
-
store: {
|
|
1636
|
+
store: {
|
|
1637
|
+
list: [],
|
|
1638
|
+
selectProducts: []
|
|
1639
|
+
},
|
|
1681
1640
|
otherParams: {
|
|
1682
1641
|
...this.otherParams,
|
|
1683
1642
|
fatherModule: this.name,
|
|
@@ -1685,8 +1644,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1685
1644
|
cacheId: this.cacheId
|
|
1686
1645
|
}
|
|
1687
1646
|
});
|
|
1688
|
-
const scheduleDate = (0,
|
|
1689
|
-
const scheduleDatetime = (0,
|
|
1647
|
+
const scheduleDate = (0, _dayjs.default)().format('YYYY-MM-DD');
|
|
1648
|
+
const scheduleDatetime = (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss');
|
|
1690
1649
|
const loaded = await reservationProductList.loadProducts({
|
|
1691
1650
|
product_ids: reservationLinkIds,
|
|
1692
1651
|
schedule_date: scheduleDate,
|
|
@@ -1694,28 +1653,23 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1694
1653
|
cacheId: this.cacheId
|
|
1695
1654
|
});
|
|
1696
1655
|
if (Array.isArray(loaded)) {
|
|
1697
|
-
const matchedRuleProduct = (0,
|
|
1698
|
-
loaded,
|
|
1699
|
-
normalizedResourceId
|
|
1700
|
-
);
|
|
1656
|
+
const matchedRuleProduct = (0, _utils.findReservationRuleProductByResourceId)(loaded, normalizedResourceId);
|
|
1701
1657
|
const ruleProductsForResource = matchedRuleProduct ? [matchedRuleProduct] : [];
|
|
1702
1658
|
this.enabledReservationRuleProducts = ruleProductsForResource;
|
|
1703
|
-
const occupancyMinutes = (0,
|
|
1704
|
-
if (occupancyMinutes !==
|
|
1659
|
+
const occupancyMinutes = (0, _utils.pickFirstDurationMinutesFromProducts)(ruleProductsForResource);
|
|
1660
|
+
if (occupancyMinutes !== undefined) {
|
|
1705
1661
|
tempOrder.metadata.table_occupancy_duration = occupancyMinutes;
|
|
1706
1662
|
}
|
|
1707
|
-
if ((0,
|
|
1663
|
+
if ((0, _utils.hasCustomCapacityProduct)(ruleProductsForResource)) {
|
|
1708
1664
|
pendingRequestEntryPax = 1;
|
|
1709
|
-
const paxBounds = (0,
|
|
1710
|
-
if (
|
|
1711
|
-
|
|
1712
|
-
if ((paxBounds == null ? void 0 : paxBounds.max) !== void 0)
|
|
1713
|
-
pendingRequestPaxMax = paxBounds.max;
|
|
1665
|
+
const paxBounds = (0, _utils.pickFirstCustomCapacityPaxBounds)(ruleProductsForResource);
|
|
1666
|
+
if (paxBounds?.min !== undefined) pendingRequestPaxMin = paxBounds.min;
|
|
1667
|
+
if (paxBounds?.max !== undefined) pendingRequestPaxMax = paxBounds.max;
|
|
1714
1668
|
}
|
|
1715
1669
|
} else {
|
|
1716
1670
|
this.enabledReservationRuleProducts = [];
|
|
1717
|
-
const error = loaded instanceof Error ? loaded : new Error(
|
|
1718
|
-
this.logMethodError(
|
|
1671
|
+
const error = loaded instanceof Error ? loaded : new Error('预约规则商品列表接口返回异常');
|
|
1672
|
+
this.logMethodError('loadReservationRuleProducts', error, {
|
|
1719
1673
|
resourceId: normalizedResourceId,
|
|
1720
1674
|
reservationLinkIds,
|
|
1721
1675
|
scheduleDate,
|
|
@@ -1723,62 +1677,61 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1723
1677
|
cacheId: this.cacheId
|
|
1724
1678
|
});
|
|
1725
1679
|
}
|
|
1680
|
+
|
|
1681
|
+
// Step2: 请求新的资源占用详情接口。occupy_details 第一维是资源,不是订单。
|
|
1726
1682
|
const occupyDetails = await this.fetchResourceOccupyDetailsByResourceId(normalizedResourceId);
|
|
1727
1683
|
const occupyDetail = occupyDetails[0] ?? null;
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
const
|
|
1732
|
-
const
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
allowAddItems
|
|
1736
|
-
);
|
|
1737
|
-
if (additionalOrderResult.reason === "multiple_orders") {
|
|
1684
|
+
|
|
1685
|
+
// Step3: 结合预约规则商品的 product_resource.resources 与占用接口返回的 form_id,
|
|
1686
|
+
// 计算当前桌台的 resourceSelectType(single/multiple/capacity)
|
|
1687
|
+
const resourceSelectType = this.resolveResourceSelectType((0, _utils.toPositiveString)(occupyDetail?.form_id));
|
|
1688
|
+
const allowAddItems = (0, _utils.toBoolean)(dineInConfig?.['sale.allow_add_items']);
|
|
1689
|
+
const additionalOrderResult = this.resolveAdditionalOrderFromOccupyDetail(occupyDetail, resourceSelectType, allowAddItems);
|
|
1690
|
+
if (additionalOrderResult.reason === 'multiple_orders') {
|
|
1738
1691
|
const multipleOrdersState = {
|
|
1739
1692
|
...this.normalizeResourceState(occupyDetail, resourceSelectType, hasOrderId),
|
|
1740
|
-
mode:
|
|
1693
|
+
mode: 'multiple_orders'
|
|
1741
1694
|
};
|
|
1742
1695
|
this.store.resource = multipleOrdersState;
|
|
1743
|
-
const
|
|
1744
|
-
mode:
|
|
1696
|
+
const availabilityInfo = {
|
|
1697
|
+
mode: 'multiple_orders',
|
|
1745
1698
|
deskmate_valid: multipleOrdersState.deskmate_valid,
|
|
1746
1699
|
relation_id: multipleOrdersState.relationId,
|
|
1747
1700
|
table_form_id: multipleOrdersState.tableFormId,
|
|
1748
1701
|
table_form_record: multipleOrdersState.table_form_record
|
|
1749
1702
|
};
|
|
1750
|
-
this.logMethodSuccess(
|
|
1703
|
+
this.logMethodSuccess('checkResourceAvailable', {
|
|
1751
1704
|
resourceId: normalizedResourceId,
|
|
1752
|
-
mode:
|
|
1753
|
-
orderListCount:
|
|
1705
|
+
mode: availabilityInfo.mode,
|
|
1706
|
+
orderListCount: occupyDetail?.order_list?.length || 0,
|
|
1754
1707
|
resourceSelectType
|
|
1755
1708
|
});
|
|
1756
|
-
return
|
|
1709
|
+
return availabilityInfo;
|
|
1757
1710
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
hasOrderId
|
|
1762
|
-
);
|
|
1711
|
+
|
|
1712
|
+
// Step4: 用 occupyDetail + resourceSelectType 规整为 resourceState
|
|
1713
|
+
const resourceState = this.normalizeResourceState(occupyDetail, resourceSelectType, hasOrderId);
|
|
1763
1714
|
const additionalOrderId = additionalOrderResult.order_id;
|
|
1764
1715
|
if (additionalOrderId) {
|
|
1765
|
-
resourceState.mode =
|
|
1716
|
+
resourceState.mode = 'additional_order';
|
|
1766
1717
|
resourceState.order_id = additionalOrderId;
|
|
1767
|
-
} else if (additionalOrderResult.reason ===
|
|
1768
|
-
resourceState.mode =
|
|
1769
|
-
resourceState.order_id =
|
|
1770
|
-
} else if (resourceSelectType ===
|
|
1771
|
-
resourceState.mode =
|
|
1772
|
-
resourceState.order_id =
|
|
1718
|
+
} else if (additionalOrderResult.reason === 'add_items_disabled') {
|
|
1719
|
+
resourceState.mode = 'resource_busy';
|
|
1720
|
+
resourceState.order_id = '0';
|
|
1721
|
+
} else if (resourceSelectType === 'multiple' && resourceState.isFull) {
|
|
1722
|
+
resourceState.mode = 'resource_busy';
|
|
1723
|
+
resourceState.order_id = '0';
|
|
1773
1724
|
}
|
|
1774
1725
|
this.store.resource = resourceState;
|
|
1775
|
-
|
|
1726
|
+
|
|
1727
|
+
// Step5: 把预约规则商品阶段暂存的 requestEntryPax 等注入 store.resource
|
|
1728
|
+
if (pendingRequestEntryPax !== undefined) {
|
|
1776
1729
|
this.store.resource.requestEntryPax = pendingRequestEntryPax;
|
|
1777
1730
|
}
|
|
1778
|
-
if (pendingRequestPaxMin !==
|
|
1731
|
+
if (pendingRequestPaxMin !== undefined) {
|
|
1779
1732
|
this.store.resource.requestPaxMin = pendingRequestPaxMin;
|
|
1780
1733
|
}
|
|
1781
|
-
if (pendingRequestPaxMax !==
|
|
1734
|
+
if (pendingRequestPaxMax !== undefined) {
|
|
1782
1735
|
this.store.resource.requestPaxMax = pendingRequestPaxMax;
|
|
1783
1736
|
}
|
|
1784
1737
|
const availabilityInfo = {
|
|
@@ -1788,45 +1741,60 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1788
1741
|
table_form_id: resourceState.tableFormId,
|
|
1789
1742
|
deskmate_valid: resourceState.deskmate_valid,
|
|
1790
1743
|
table_form_record: resourceState.table_form_record,
|
|
1791
|
-
policy:
|
|
1792
|
-
partyroom_booking:
|
|
1793
|
-
...this.store.resource.requestEntryPax !==
|
|
1794
|
-
|
|
1795
|
-
|
|
1744
|
+
policy: occupyDetail?.form_record?.policy,
|
|
1745
|
+
partyroom_booking: occupyDetail?.form_record?.partyroom_booking,
|
|
1746
|
+
...(this.store.resource.requestEntryPax !== undefined ? {
|
|
1747
|
+
requestEntryPax: this.store.resource.requestEntryPax
|
|
1748
|
+
} : {}),
|
|
1749
|
+
...(this.store.resource.requestPaxMin !== undefined ? {
|
|
1750
|
+
requestPaxMin: this.store.resource.requestPaxMin
|
|
1751
|
+
} : {}),
|
|
1752
|
+
...(this.store.resource.requestPaxMax !== undefined ? {
|
|
1753
|
+
requestPaxMax: this.store.resource.requestPaxMax
|
|
1754
|
+
} : {})
|
|
1796
1755
|
};
|
|
1797
|
-
tempOrder.relation_id = normalizedResourceId ||
|
|
1756
|
+
tempOrder.relation_id = normalizedResourceId || this.otherParams?.relation_id;
|
|
1798
1757
|
tempOrder.table_form_id = resourceState.tableFormId;
|
|
1799
1758
|
tempOrder.resource_id = normalizedResourceId;
|
|
1800
|
-
|
|
1801
|
-
|
|
1759
|
+
this.store.order?.persistTempOrder();
|
|
1760
|
+
|
|
1761
|
+
// 空闲状态下自动准备本地临时订单,供后续“购物车式”商品操作使用
|
|
1762
|
+
if (availabilityInfo.mode === 'idle') {
|
|
1802
1763
|
await this.addNewOrder();
|
|
1803
1764
|
}
|
|
1804
|
-
const isAdditionalOrderMode = availabilityInfo.mode ===
|
|
1765
|
+
const isAdditionalOrderMode = availabilityInfo.mode === 'additional_order' || availabilityInfo.mode === 'additional_order_with_code';
|
|
1766
|
+
// 如果是加单模式,tempOrder 里需要记录目标订单 id,提交的时候走加单接口
|
|
1805
1767
|
if (isAdditionalOrderMode) {
|
|
1806
1768
|
tempOrder.order_id = additionalOrderId;
|
|
1807
1769
|
}
|
|
1808
|
-
const lastOrderInfo =
|
|
1809
|
-
const historicalItems = isAdditionalOrderMode && Array.isArray(lastOrderInfo
|
|
1810
|
-
if (typeof
|
|
1811
|
-
return acc;
|
|
1770
|
+
const lastOrderInfo = this.store.order?.getLastOrderInfo?.();
|
|
1771
|
+
const historicalItems = isAdditionalOrderMode && Array.isArray(lastOrderInfo?.products) ? lastOrderInfo.products.reduce((acc, p) => {
|
|
1772
|
+
if (typeof p?.product_id !== 'number') return acc;
|
|
1812
1773
|
acc.push({
|
|
1813
1774
|
product_id: p.product_id,
|
|
1814
1775
|
quantity: Number(p.product_quantity) || 0,
|
|
1815
|
-
...typeof p.product_variant_id ===
|
|
1776
|
+
...(typeof p.product_variant_id === 'number' ? {
|
|
1777
|
+
product_variant_id: p.product_variant_id
|
|
1778
|
+
} : {})
|
|
1816
1779
|
});
|
|
1817
1780
|
return acc;
|
|
1818
1781
|
}, []) : [];
|
|
1782
|
+
|
|
1783
|
+
// pax 由 setEntryPaxNumber 负责写入 itemRuleRuntimeConfig.pax
|
|
1819
1784
|
await this.setItemRuleRuntimeConfig({
|
|
1820
|
-
serviceType:
|
|
1785
|
+
serviceType: this.otherParams?.businessCode,
|
|
1821
1786
|
submissionIndex: isAdditionalOrderMode ? 1 : 0,
|
|
1822
1787
|
historicalItems
|
|
1823
1788
|
});
|
|
1824
|
-
|
|
1825
|
-
|
|
1789
|
+
|
|
1790
|
+
// operating_hours 超出营业时段 + closed_behavior=show_menu_disabled:
|
|
1791
|
+
// 允许浏览商品但 UI 层需拦截“下一步”,这里覆盖最终 mode 并回传错误提示
|
|
1792
|
+
if (outsideOperatingHours && closedBehaviorValue === 'show_menu_disabled') {
|
|
1793
|
+
availabilityInfo.mode = 'submit_disabled';
|
|
1826
1794
|
availabilityInfo.errorTips = closedMessage;
|
|
1827
1795
|
availabilityInfo.closed_behavior = closedBehaviorValue;
|
|
1828
1796
|
}
|
|
1829
|
-
this.logMethodSuccess(
|
|
1797
|
+
this.logMethodSuccess('checkResourceAvailable', {
|
|
1830
1798
|
resourceId: normalizedResourceId,
|
|
1831
1799
|
mode: availabilityInfo.mode,
|
|
1832
1800
|
orderId: availabilityInfo.order_id,
|
|
@@ -1841,72 +1809,68 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1841
1809
|
});
|
|
1842
1810
|
return availabilityInfo;
|
|
1843
1811
|
} catch (error) {
|
|
1844
|
-
this.logMethodError(
|
|
1812
|
+
this.logMethodError('checkResourceAvailable', error.message, {
|
|
1845
1813
|
resourceId: normalizedResourceId
|
|
1846
1814
|
});
|
|
1847
1815
|
throw error;
|
|
1848
1816
|
}
|
|
1849
1817
|
}
|
|
1818
|
+
|
|
1850
1819
|
// 恢复之前订单的数据,读取 entrypax
|
|
1851
1820
|
async restorePreviousOrderData() {
|
|
1852
|
-
var _a, _b, _c, _d, _e;
|
|
1853
1821
|
const tempOrder = this.ensureTempOrder();
|
|
1854
1822
|
if (tempOrder.order_id) {
|
|
1855
|
-
const res = await
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
return (_a2 = p.metadata) == null ? void 0 : _a2.collect_pax;
|
|
1859
|
-
})) == null ? void 0 : _d.metadata) == null ? void 0 : _e.collect_pax;
|
|
1823
|
+
const res = await this.store.order?.getOrderInfoByRemote(tempOrder.order_id);
|
|
1824
|
+
// 找到下单的时候输入的 entryPaxNumber
|
|
1825
|
+
const entryPaxNumber = res?.data?.bookings?.find(p => p.metadata?.collect_pax)?.metadata?.collect_pax;
|
|
1860
1826
|
if (entryPaxNumber) {
|
|
1861
1827
|
await this.setEntryPaxNumber(entryPaxNumber);
|
|
1862
1828
|
}
|
|
1863
1829
|
}
|
|
1864
1830
|
}
|
|
1831
|
+
|
|
1865
1832
|
// 如果是加单的情况,提供返回当前订单相关信息的能力
|
|
1866
1833
|
async getAdditionalOrderInfo() {
|
|
1867
|
-
this.logMethodStart(
|
|
1834
|
+
this.logMethodStart('getAdditionalOrderInfo');
|
|
1868
1835
|
const result = {
|
|
1869
|
-
orderId:
|
|
1870
|
-
orderStatus:
|
|
1871
|
-
orderTime:
|
|
1836
|
+
orderId: '123567890',
|
|
1837
|
+
orderStatus: 'pending',
|
|
1838
|
+
orderTime: '2026-03-31 10:00:00',
|
|
1872
1839
|
orderAmount: 100,
|
|
1873
1840
|
orderItems: []
|
|
1874
1841
|
};
|
|
1875
|
-
this.logMethodSuccess(
|
|
1842
|
+
this.logMethodSuccess('getAdditionalOrderInfo', {
|
|
1876
1843
|
orderId: result.orderId,
|
|
1877
1844
|
orderStatus: result.orderStatus
|
|
1878
1845
|
});
|
|
1879
1846
|
return result;
|
|
1880
1847
|
}
|
|
1848
|
+
|
|
1881
1849
|
// 获取商品列表
|
|
1882
1850
|
async getProductList() {
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
const menu_list_ids =
|
|
1851
|
+
this.logMethodStart('getProductList');
|
|
1852
|
+
// 可以直接通过配置里的 menu 读取
|
|
1853
|
+
const menu_list_ids = this.otherParams?.dineInConfig?.['menu.associated_menus'].map(n => Number(n.value)) || [];
|
|
1886
1854
|
try {
|
|
1887
|
-
if (!this.store.products)
|
|
1888
|
-
throw new Error("products 模块未初始化");
|
|
1855
|
+
if (!this.store.products) throw new Error('products 模块未初始化');
|
|
1889
1856
|
const res = await this.store.products.loadProducts({
|
|
1890
1857
|
menu_list_ids,
|
|
1891
1858
|
cacheId: this.cacheId,
|
|
1892
|
-
schedule_date: (0,
|
|
1893
|
-
schedule_datetime: (0,
|
|
1859
|
+
schedule_date: (0, _dayjs.default)().format('YYYY-MM-DD'),
|
|
1860
|
+
schedule_datetime: (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss')
|
|
1894
1861
|
});
|
|
1895
|
-
const productList = this.assertProductListLoaded(
|
|
1862
|
+
const productList = this.assertProductListLoaded('getProductList', res, {
|
|
1896
1863
|
menu_list_ids,
|
|
1897
1864
|
cacheId: this.cacheId
|
|
1898
1865
|
});
|
|
1899
|
-
const formattedRes = (0,
|
|
1900
|
-
|
|
1901
|
-
this.store.itemRuleQuantityLimits || []
|
|
1902
|
-
);
|
|
1903
|
-
this.logMethodSuccess("getProductList", {
|
|
1866
|
+
const formattedRes = (0, _utils.attachItemRuleLimitsToTopLevelProducts)(productList, this.store.itemRuleQuantityLimits || []);
|
|
1867
|
+
this.logMethodSuccess('getProductList', {
|
|
1904
1868
|
menuCount: menu_list_ids.length
|
|
1905
1869
|
});
|
|
1906
1870
|
return formattedRes;
|
|
1907
1871
|
} catch (error) {
|
|
1908
|
-
if (!
|
|
1909
|
-
this.logMethodError(
|
|
1872
|
+
if (!error?.__scanOrderLogged) {
|
|
1873
|
+
this.logMethodError('getProductList', error, {
|
|
1910
1874
|
menu_list_ids,
|
|
1911
1875
|
cacheId: this.cacheId
|
|
1912
1876
|
});
|
|
@@ -1917,87 +1881,107 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
1917
1881
|
getOtherParams() {
|
|
1918
1882
|
return this.otherParams;
|
|
1919
1883
|
}
|
|
1920
|
-
async setOtherParams(params, {
|
|
1884
|
+
async setOtherParams(params, {
|
|
1885
|
+
cover = false
|
|
1886
|
+
} = {}) {
|
|
1921
1887
|
if (cover) {
|
|
1922
1888
|
this.otherParams = params;
|
|
1923
1889
|
} else {
|
|
1924
|
-
this.otherParams = {
|
|
1890
|
+
this.otherParams = {
|
|
1891
|
+
...this.otherParams,
|
|
1892
|
+
...params
|
|
1893
|
+
};
|
|
1925
1894
|
}
|
|
1926
1895
|
}
|
|
1896
|
+
|
|
1897
|
+
// ─── UI 状态缓存(按 cacheId 分桶,localStorage) ───
|
|
1898
|
+
//
|
|
1899
|
+
// 用于物料层持久化 UI 层面的轻量状态(如当前步骤、gate 标记、登录回跳意图等)。
|
|
1900
|
+
// 桶键:pisell.scanOrder.uiState:<cacheId>;内部以 JSON object 形式存储多个字段。
|
|
1901
|
+
// 无 cacheId 时所有方法自动降级为 no-op,上层不用判空。
|
|
1902
|
+
//
|
|
1903
|
+
// 之所以用 localStorage 而不是 sessionStorage:
|
|
1904
|
+
// 1. 与 Order 模块 openCache 下的 tempOrder 同栈,购物车在 / UIState 在,行为对齐;
|
|
1905
|
+
// 2. pisell1.login 整页 OAuth 跳转在 H5 壳 / iOS Safari 场景下可能丢 sessionStorage,
|
|
1906
|
+
// 导致登录回跳后 gate 标记失效、pax 弹窗重开、落点错误;localStorage 稳定不受影响。
|
|
1907
|
+
// 3. 失效由上层显式控制:提交成功 clearStepCache / entryContext 不一致 clearUIState /
|
|
1908
|
+
// pendingStep 登录回调 deleteUIState,足够约束生命周期。
|
|
1909
|
+
|
|
1910
|
+
static UI_STATE_KEY_PREFIX = 'pisell.scanOrder.uiState:';
|
|
1927
1911
|
getUIStateBucketKey() {
|
|
1928
|
-
if (!this.cacheId)
|
|
1929
|
-
|
|
1930
|
-
return `${_ScanOrderImpl.UI_STATE_KEY_PREFIX}${this.cacheId}`;
|
|
1912
|
+
if (!this.cacheId) return null;
|
|
1913
|
+
return `${ScanOrderImpl.UI_STATE_KEY_PREFIX}${this.cacheId}`;
|
|
1931
1914
|
}
|
|
1932
1915
|
readUIStateBucket() {
|
|
1933
|
-
var _a;
|
|
1934
1916
|
const key = this.getUIStateBucketKey();
|
|
1935
|
-
if (!key || !
|
|
1936
|
-
return {};
|
|
1917
|
+
if (!key || !this.window?.localStorage) return {};
|
|
1937
1918
|
try {
|
|
1938
|
-
const raw = this.window.localStorage.getItem(key) ||
|
|
1919
|
+
const raw = this.window.localStorage.getItem(key) || '{}';
|
|
1939
1920
|
const parsed = JSON.parse(raw);
|
|
1940
|
-
return parsed && typeof parsed ===
|
|
1921
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
1941
1922
|
} catch {
|
|
1942
1923
|
return {};
|
|
1943
1924
|
}
|
|
1944
1925
|
}
|
|
1945
1926
|
writeUIStateBucket(bucket) {
|
|
1946
|
-
var _a;
|
|
1947
1927
|
const key = this.getUIStateBucketKey();
|
|
1948
|
-
if (!key || !
|
|
1949
|
-
return;
|
|
1928
|
+
if (!key || !this.window?.localStorage) return;
|
|
1950
1929
|
try {
|
|
1951
1930
|
this.window.localStorage.setItem(key, JSON.stringify(bucket));
|
|
1952
1931
|
} catch (error) {
|
|
1953
|
-
console.warn(
|
|
1932
|
+
console.warn('[ScanOrder] writeUIStateBucket failed', error);
|
|
1954
1933
|
}
|
|
1955
1934
|
}
|
|
1956
1935
|
setUIState(key, value) {
|
|
1957
|
-
if (!this.getUIStateBucketKey())
|
|
1958
|
-
return;
|
|
1936
|
+
if (!this.getUIStateBucketKey()) return;
|
|
1959
1937
|
const bucket = this.readUIStateBucket();
|
|
1960
1938
|
bucket[key] = value;
|
|
1961
1939
|
this.writeUIStateBucket(bucket);
|
|
1962
1940
|
}
|
|
1963
1941
|
getUIState(key) {
|
|
1964
|
-
if (!this.getUIStateBucketKey())
|
|
1965
|
-
return void 0;
|
|
1942
|
+
if (!this.getUIStateBucketKey()) return undefined;
|
|
1966
1943
|
const bucket = this.readUIStateBucket();
|
|
1967
1944
|
return bucket[key];
|
|
1968
1945
|
}
|
|
1969
1946
|
deleteUIState(key) {
|
|
1970
|
-
if (!this.getUIStateBucketKey())
|
|
1971
|
-
return;
|
|
1947
|
+
if (!this.getUIStateBucketKey()) return;
|
|
1972
1948
|
const bucket = this.readUIStateBucket();
|
|
1973
1949
|
if (key in bucket) {
|
|
1974
1950
|
delete bucket[key];
|
|
1975
1951
|
this.writeUIStateBucket(bucket);
|
|
1976
1952
|
}
|
|
1977
1953
|
}
|
|
1954
|
+
|
|
1978
1955
|
// 整桶清空(用于扫新桌、提交成功、restoreOrder 等场景)
|
|
1979
1956
|
clearUIState() {
|
|
1980
|
-
var _a;
|
|
1981
1957
|
const key = this.getUIStateBucketKey();
|
|
1982
|
-
if (!key || !
|
|
1983
|
-
return;
|
|
1958
|
+
if (!key || !this.window?.localStorage) return;
|
|
1984
1959
|
try {
|
|
1985
1960
|
this.window.localStorage.removeItem(key);
|
|
1986
1961
|
} catch (error) {
|
|
1987
|
-
console.warn(
|
|
1962
|
+
console.warn('[ScanOrder] clearUIState failed', error);
|
|
1988
1963
|
}
|
|
1989
1964
|
}
|
|
1990
1965
|
async setEntryPaxNumber(number) {
|
|
1991
|
-
const pax = (0,
|
|
1966
|
+
const pax = (0, _utils2.normalizeSubmitCollectPaxValue)(number);
|
|
1992
1967
|
this.store.entryPaxNumber = pax;
|
|
1993
1968
|
if (this.store.order) {
|
|
1994
1969
|
const t = this.store.order.ensureTempOrder();
|
|
1995
|
-
t.metadata = {
|
|
1970
|
+
t.metadata = {
|
|
1971
|
+
...t.metadata,
|
|
1972
|
+
collect_pax: pax
|
|
1973
|
+
};
|
|
1996
1974
|
this.store.order.persistTempOrder();
|
|
1997
1975
|
}
|
|
1976
|
+
|
|
1977
|
+
// pax 变化后同步到 itemRuleRuntimeConfig,并刷新限购 / 校验
|
|
1998
1978
|
this.itemRuleRuntimeConfig = {
|
|
1999
1979
|
...this.itemRuleRuntimeConfig,
|
|
2000
|
-
pax: {
|
|
1980
|
+
pax: {
|
|
1981
|
+
total: pax,
|
|
1982
|
+
adult: 0,
|
|
1983
|
+
child: 0
|
|
1984
|
+
}
|
|
2001
1985
|
};
|
|
2002
1986
|
this.itemRulePrefillApplied = false;
|
|
2003
1987
|
await this.refreshItemRuleQuantityLimits();
|
|
@@ -2007,35 +1991,26 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
2007
1991
|
return this.store.entryPaxNumber;
|
|
2008
1992
|
}
|
|
2009
1993
|
async syncAdditionalOrderFromResource(resourceId) {
|
|
2010
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2011
1994
|
const tempOrder = this.ensureTempOrder();
|
|
2012
|
-
const normalizedResourceId = String(
|
|
2013
|
-
|
|
2014
|
-
).trim();
|
|
2015
|
-
this.logMethodStart("syncAdditionalOrderFromResource", {
|
|
1995
|
+
const normalizedResourceId = String(resourceId ?? tempOrder.resource_id ?? this.store.resource?.relationId ?? this.store.resource?.relation_id ?? '').trim();
|
|
1996
|
+
this.logMethodStart('syncAdditionalOrderFromResource', {
|
|
2016
1997
|
resourceId: normalizedResourceId
|
|
2017
1998
|
});
|
|
2018
1999
|
if (!normalizedResourceId) {
|
|
2019
|
-
const
|
|
2000
|
+
const result = {
|
|
2020
2001
|
matched: false,
|
|
2021
|
-
reason:
|
|
2002
|
+
reason: 'missing_resource_id'
|
|
2022
2003
|
};
|
|
2023
|
-
this.logMethodSuccess(
|
|
2024
|
-
return
|
|
2004
|
+
this.logMethodSuccess('syncAdditionalOrderFromResource', result);
|
|
2005
|
+
return result;
|
|
2025
2006
|
}
|
|
2026
2007
|
const occupyDetails = await this.fetchResourceOccupyDetailsByResourceId(normalizedResourceId);
|
|
2027
2008
|
const occupyDetail = occupyDetails[0] ?? null;
|
|
2028
|
-
const resourceSelectType =
|
|
2029
|
-
const allowAddItems = (0,
|
|
2030
|
-
|
|
2031
|
-
);
|
|
2032
|
-
const result = this.resolveAdditionalOrderFromOccupyDetail(
|
|
2033
|
-
occupyDetail,
|
|
2034
|
-
resourceSelectType,
|
|
2035
|
-
allowAddItems
|
|
2036
|
-
);
|
|
2009
|
+
const resourceSelectType = this.store.resource?.resourceSelectType || this.resolveResourceSelectType((0, _utils.toPositiveString)(occupyDetail?.form_id));
|
|
2010
|
+
const allowAddItems = (0, _utils.toBoolean)(this.otherParams?.dineInConfig?.['sale.allow_add_items']);
|
|
2011
|
+
const result = this.resolveAdditionalOrderFromOccupyDetail(occupyDetail, resourceSelectType, allowAddItems);
|
|
2037
2012
|
if (!result.matched || !result.order_id) {
|
|
2038
|
-
this.logMethodSuccess(
|
|
2013
|
+
this.logMethodSuccess('syncAdditionalOrderFromResource', {
|
|
2039
2014
|
...result,
|
|
2040
2015
|
resourceId: normalizedResourceId,
|
|
2041
2016
|
resourceSelectType,
|
|
@@ -2045,10 +2020,10 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
2045
2020
|
}
|
|
2046
2021
|
tempOrder.order_id = result.order_id;
|
|
2047
2022
|
tempOrder.resource_id = normalizedResourceId;
|
|
2048
|
-
tempOrder.relation_id = (0,
|
|
2049
|
-
tempOrder.table_form_id = (0,
|
|
2050
|
-
|
|
2051
|
-
this.logMethodSuccess(
|
|
2023
|
+
tempOrder.relation_id = (0, _utils.toPositiveString)(occupyDetail?.form_record_id) || normalizedResourceId || tempOrder.relation_id;
|
|
2024
|
+
tempOrder.table_form_id = (0, _utils.toPositiveString)(occupyDetail?.form_id) || tempOrder.table_form_id;
|
|
2025
|
+
this.store.order?.persistTempOrder();
|
|
2026
|
+
this.logMethodSuccess('syncAdditionalOrderFromResource', {
|
|
2052
2027
|
...result,
|
|
2053
2028
|
resourceId: normalizedResourceId,
|
|
2054
2029
|
resourceSelectType,
|
|
@@ -2056,80 +2031,68 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
|
|
|
2056
2031
|
});
|
|
2057
2032
|
return result;
|
|
2058
2033
|
}
|
|
2034
|
+
|
|
2059
2035
|
// 读取预约规则商品的资源选择类型:single=单个预约,multiple=多个预约,capacity=容量型预约
|
|
2060
2036
|
// 依赖 checkResourceAvailable 已根据预约规则商品与 occupy-detail 的 form_id 计算并缓存 store.resource
|
|
2061
2037
|
getReservationResourceSelectType() {
|
|
2062
|
-
|
|
2063
|
-
this.
|
|
2064
|
-
const resourceSelectType = (_a = this.store.resource) == null ? void 0 : _a.resourceSelectType;
|
|
2038
|
+
this.logMethodStart('getReservationResourceSelectType');
|
|
2039
|
+
const resourceSelectType = this.store.resource?.resourceSelectType;
|
|
2065
2040
|
const result = {
|
|
2066
|
-
...resourceSelectType ? {
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2041
|
+
...(resourceSelectType ? {
|
|
2042
|
+
resourceSelectType
|
|
2043
|
+
} : {}),
|
|
2044
|
+
isSingleReservation: resourceSelectType === 'single',
|
|
2045
|
+
isMultipleReservation: resourceSelectType === 'multiple',
|
|
2046
|
+
isCapacityReservation: resourceSelectType === 'capacity'
|
|
2070
2047
|
};
|
|
2071
|
-
this.logMethodSuccess(
|
|
2048
|
+
this.logMethodSuccess('getReservationResourceSelectType', result);
|
|
2072
2049
|
return result;
|
|
2073
2050
|
}
|
|
2051
|
+
|
|
2074
2052
|
// 判定后台是否开启允许加餐
|
|
2075
2053
|
// 依赖 checkResourceAvailable 已缓存的 dineInConfig
|
|
2076
2054
|
checkAllowAddItems() {
|
|
2077
|
-
|
|
2078
|
-
this.
|
|
2079
|
-
const dineInConfig = ((_a = this.otherParams) == null ? void 0 : _a.dineInConfig) || {};
|
|
2055
|
+
this.logMethodStart('checkAllowAddItems');
|
|
2056
|
+
const dineInConfig = this.otherParams?.dineInConfig || {};
|
|
2080
2057
|
const result = {
|
|
2081
|
-
enabled: (0,
|
|
2058
|
+
enabled: (0, _utils.toBoolean)(dineInConfig['sale.allow_add_items'])
|
|
2082
2059
|
};
|
|
2083
|
-
this.logMethodSuccess(
|
|
2060
|
+
this.logMethodSuccess('checkAllowAddItems', result);
|
|
2084
2061
|
return result;
|
|
2085
2062
|
}
|
|
2063
|
+
|
|
2086
2064
|
// 读取取餐/送餐开关
|
|
2087
2065
|
// 依赖 checkResourceAvailable 已缓存的 dineInConfig
|
|
2088
2066
|
getFulfillmentModes() {
|
|
2089
|
-
|
|
2090
|
-
this.
|
|
2091
|
-
const dineInConfig = ((_a = this.otherParams) == null ? void 0 : _a.dineInConfig) || {};
|
|
2067
|
+
this.logMethodStart('getFulfillmentModes');
|
|
2068
|
+
const dineInConfig = this.otherParams?.dineInConfig || {};
|
|
2092
2069
|
const result = {
|
|
2093
|
-
enablePickup: Boolean(dineInConfig[
|
|
2094
|
-
enableTableService: Boolean(dineInConfig[
|
|
2070
|
+
enablePickup: Boolean(dineInConfig['fulfillment.enable_pickup']),
|
|
2071
|
+
enableTableService: Boolean(dineInConfig['fulfillment.enable_table_service'])
|
|
2095
2072
|
};
|
|
2096
|
-
this.logMethodSuccess(
|
|
2073
|
+
this.logMethodSuccess('getFulfillmentModes', result);
|
|
2097
2074
|
return result;
|
|
2098
2075
|
}
|
|
2076
|
+
|
|
2099
2077
|
// 判定后台是否开启客户自定义取餐标识
|
|
2100
2078
|
// 依赖 checkResourceAvailable 已缓存的 dineInConfig
|
|
2101
2079
|
checkManualPickupRef() {
|
|
2102
|
-
|
|
2103
|
-
this.
|
|
2104
|
-
const
|
|
2105
|
-
const
|
|
2106
|
-
const
|
|
2107
|
-
const
|
|
2108
|
-
|
|
2109
|
-
|
|
2080
|
+
this.logMethodStart('checkManualPickupRef');
|
|
2081
|
+
const dineInConfig = this.otherParams?.dineInConfig || {};
|
|
2082
|
+
const refMode = dineInConfig['fulfillment.fulfillment_ref_mode'];
|
|
2083
|
+
const manualInputType = dineInConfig['fulfillment.manual_input_type'];
|
|
2084
|
+
const enabled = refMode === 'manual_input';
|
|
2085
|
+
const result = enabled ? {
|
|
2086
|
+
enabled: true,
|
|
2087
|
+
manualInputType
|
|
2088
|
+
} : {
|
|
2089
|
+
enabled: false
|
|
2090
|
+
};
|
|
2091
|
+
this.logMethodSuccess('checkManualPickupRef', {
|
|
2110
2092
|
enabled,
|
|
2111
|
-
manualInputType: enabled ? manualInputType :
|
|
2093
|
+
manualInputType: enabled ? manualInputType : undefined
|
|
2112
2094
|
});
|
|
2113
2095
|
return result;
|
|
2114
2096
|
}
|
|
2115
|
-
}
|
|
2116
|
-
|
|
2117
|
-
ScanOrderImpl.PISELL1_LOGIN_SUCCESS = "pisell1.login.success";
|
|
2118
|
-
// ─── UI 状态缓存(按 cacheId 分桶,localStorage) ───
|
|
2119
|
-
//
|
|
2120
|
-
// 用于物料层持久化 UI 层面的轻量状态(如当前步骤、gate 标记、登录回跳意图等)。
|
|
2121
|
-
// 桶键:pisell.scanOrder.uiState:<cacheId>;内部以 JSON object 形式存储多个字段。
|
|
2122
|
-
// 无 cacheId 时所有方法自动降级为 no-op,上层不用判空。
|
|
2123
|
-
//
|
|
2124
|
-
// 之所以用 localStorage 而不是 sessionStorage:
|
|
2125
|
-
// 1. 与 Order 模块 openCache 下的 tempOrder 同栈,购物车在 / UIState 在,行为对齐;
|
|
2126
|
-
// 2. pisell1.login 整页 OAuth 跳转在 H5 壳 / iOS Safari 场景下可能丢 sessionStorage,
|
|
2127
|
-
// 导致登录回跳后 gate 标记失效、pax 弹窗重开、落点错误;localStorage 稳定不受影响。
|
|
2128
|
-
// 3. 失效由上层显式控制:提交成功 clearStepCache / entryContext 不一致 clearUIState /
|
|
2129
|
-
// pendingStep 登录回调 deleteUIState,足够约束生命周期。
|
|
2130
|
-
ScanOrderImpl.UI_STATE_KEY_PREFIX = "pisell.scanOrder.uiState:";
|
|
2131
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
2132
|
-
0 && (module.exports = {
|
|
2133
|
-
ScanOrderImpl,
|
|
2134
|
-
...require("./types")
|
|
2135
|
-
});
|
|
2097
|
+
}
|
|
2098
|
+
exports.ScanOrderImpl = ScanOrderImpl;
|