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