@pisell/pisellos 0.0.569 → 0.10.2
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 +10 -6
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -3
- package/dist/model/strategy/adapter/promotion/index.js +9 -0
- package/dist/model/strategy/adapter/walletPass/evaluator.js +7 -5
- package/dist/model/strategy/adapter/walletPass/example.js +26 -3
- package/dist/model/strategy/adapter/walletPass/index.js +5 -5
- package/dist/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/dist/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/dist/model/strategy/adapter/walletPass/utils.js +17 -92
- package/dist/model/strategy/strategy-example.js +19 -5
- package/dist/modules/BaseModule.d.ts +1 -1
- package/dist/modules/BaseModule.js +8 -10
- package/dist/modules/Cart/index.js +3 -0
- package/dist/modules/Cart/utils/cartProduct.js +1 -0
- package/dist/modules/Cart/utils/cartResource.js +0 -2
- package/dist/modules/Cart/utils/changePrice.js +9 -16
- package/dist/modules/Date/index.js +5 -1
- package/dist/modules/Discount/index.d.ts +0 -1
- package/dist/modules/Discount/index.js +7 -22
- package/dist/modules/Discount/types.d.ts +0 -1
- package/dist/modules/OpenData/index.js +2 -0
- package/dist/modules/Order/index.js +70 -40
- package/dist/modules/Payment/index.js +162 -97
- package/dist/modules/Payment/types.d.ts +4 -8
- package/dist/modules/Payment/walletpass.d.ts +0 -2
- package/dist/modules/Payment/walletpass.js +5 -4
- package/dist/modules/ProductList/index.d.ts +1 -1
- package/dist/modules/ProductList/index.js +3 -12
- package/dist/modules/ProductList/types.d.ts +0 -1
- package/dist/modules/Rules/index.js +126 -427
- package/dist/modules/SalesSummary/utils.js +1 -2
- package/dist/modules/Schedule/getDateIsInSchedule.js +0 -5
- package/dist/modules/Schedule/index.js +1 -0
- package/dist/modules/Schedule/utils.js +1 -0
- package/dist/modules/Step/index.js +1 -0
- package/dist/modules/Summary/utils.js +22 -43
- package/dist/plugins/request.js +4 -1
- package/dist/plugins/window.js +6 -2
- package/dist/server/index.js +129 -97
- package/dist/server/modules/menu/index.js +41 -32
- package/dist/server/modules/order/index.js +4 -2
- package/dist/server/modules/products/index.js +42 -24
- package/dist/server/modules/quotation/index.js +38 -29
- package/dist/server/modules/resource/index.js +4 -3
- package/dist/server/modules/schedule/index.js +35 -27
- package/dist/server/utils/product.js +1 -0
- package/dist/solution/BaseSales/index.js +41 -38
- package/dist/solution/BookingByStep/index.d.ts +1 -1
- package/dist/solution/BookingByStep/index.js +60 -11
- package/dist/solution/BookingByStep/utils/capacity.js +11 -1
- package/dist/solution/BookingByStep/utils/resources.js +3 -1
- package/dist/solution/BookingByStep/utils/timeslots.js +43 -2
- package/dist/solution/BookingTicket/index.d.ts +1 -1
- package/dist/solution/BookingTicket/index.js +2 -0
- package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +7 -6
- package/dist/solution/BookingTicket/utils/scan/handleScan.js +31 -25
- package/dist/solution/BookingTicket/utils/scan/index.js +10 -6
- package/dist/solution/BuyTickets/index.js +12 -9
- package/dist/solution/Checkout/index.js +252 -177
- package/dist/solution/Checkout/utils/index.js +16 -4
- package/dist/solution/RegisterAndLogin/index.js +76 -30
- package/dist/solution/ScanOrder/index.js +60 -50
- package/dist/solution/ShopDiscount/index.js +14 -15
- package/dist/solution/ShopDiscount/types.d.ts +4 -5
- package/dist/solution/ShopDiscount/utils.d.ts +0 -9
- package/dist/solution/ShopDiscount/utils.js +0 -9
- package/dist/solution/VenueBooking/index.d.ts +3 -31
- package/dist/solution/VenueBooking/index.js +496 -651
- package/dist/solution/VenueBooking/types.d.ts +1 -3
- package/dist/solution/VenueBooking/types.js +0 -1
- package/dist/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/dist/solution/VenueBooking/utils/dateSummary.js +25 -12
- package/dist/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/dist/solution/VenueBooking/utils/timeSlot.js +4 -9
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/task.js +18 -15
- package/dist/utils/watch.js +1 -0
- package/lib/apis/picoding.js +0 -2
- package/lib/core/index.js +132 -130
- package/lib/effects/index.js +57 -46
- package/lib/index.d.ts +0 -1
- package/lib/index.js +50 -92
- package/lib/model/index.js +21 -14
- package/lib/model/strategy/adapter/dataVariant/adapter.js +50 -38
- package/lib/model/strategy/adapter/dataVariant/evaluator.js +236 -162
- package/lib/model/strategy/adapter/dataVariant/examples.js +237 -229
- package/lib/model/strategy/adapter/dataVariant/index.js +34 -39
- package/lib/model/strategy/adapter/dataVariant/type.js +28 -57
- package/lib/model/strategy/adapter/index.js +64 -100
- package/lib/model/strategy/adapter/itemRule/adapter.js +144 -156
- package/lib/model/strategy/adapter/itemRule/evaluator.js +48 -36
- package/lib/model/strategy/adapter/itemRule/examples.js +225 -295
- package/lib/model/strategy/adapter/itemRule/index.js +57 -83
- package/lib/model/strategy/adapter/itemRule/type.js +36 -97
- package/lib/model/strategy/adapter/promotion/adapter.js +63 -84
- package/lib/model/strategy/adapter/promotion/evaluator.js +231 -381
- package/lib/model/strategy/adapter/promotion/examples.js +159 -139
- package/lib/model/strategy/adapter/promotion/index.js +49 -1
- package/lib/model/strategy/adapter/promotion/type.js +35 -199
- package/lib/model/strategy/adapter/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/evaluator.js +152 -180
- package/lib/model/strategy/adapter/walletPass/example.js +190 -217
- package/lib/model/strategy/adapter/walletPass/index.js +51 -75
- package/lib/model/strategy/adapter/walletPass/locales.js +58 -36
- package/lib/model/strategy/adapter/walletPass/type.d.ts +0 -3
- package/lib/model/strategy/adapter/walletPass/type.js +16 -4
- package/lib/model/strategy/adapter/walletPass/utils.d.ts +0 -26
- package/lib/model/strategy/adapter/walletPass/utils.js +383 -678
- package/lib/model/strategy/engine.js +168 -270
- package/lib/model/strategy/index.js +34 -49
- package/lib/model/strategy/strategy-example.js +239 -243
- package/lib/model/strategy/type.js +40 -100
- package/lib/modules/Account/index.js +53 -39
- package/lib/modules/Account/types.js +33 -20
- package/lib/modules/AccountList/index.js +154 -116
- package/lib/modules/AccountList/types.js +31 -30
- package/lib/modules/AccountList/utils.js +30 -18
- package/lib/modules/BaseModule.d.ts +1 -1
- package/lib/modules/BaseModule.js +46 -25
- package/lib/modules/BookingContext/index.js +136 -158
- package/lib/modules/BookingContext/types.js +32 -46
- package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +143 -131
- package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +82 -75
- package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +150 -170
- package/lib/modules/BookingContext/utils/flexible.js +55 -38
- package/lib/modules/BookingContext/utils/formatResourceList.js +34 -19
- package/lib/modules/BookingContext/utils/index.js +41 -124
- package/lib/modules/BookingContext/utils/noResource.js +70 -58
- package/lib/modules/BookingContext/utils/orderLineDisplay.js +41 -14
- package/lib/modules/BookingContext/utils/productExtend.js +155 -202
- package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
- package/lib/modules/BookingContext/utils/resourceSelection.js +41 -19
- package/lib/modules/BookingContext/utils/resources.js +167 -209
- package/lib/modules/BookingContext/utils/serviceTimes.js +116 -115
- package/lib/modules/BookingContext/utils/timeSlices.js +80 -70
- package/lib/modules/Cart/index.js +124 -170
- package/lib/modules/Cart/types.js +51 -46
- package/lib/modules/Cart/utils/cartAccount.js +39 -40
- package/lib/modules/Cart/utils/cartDate.js +61 -56
- package/lib/modules/Cart/utils/cartDiscount.js +33 -28
- package/lib/modules/Cart/utils/cartNote.js +32 -27
- package/lib/modules/Cart/utils/cartProduct.js +251 -321
- package/lib/modules/Cart/utils/cartRelationForms.js +35 -29
- package/lib/modules/Cart/utils/cartResource.js +78 -72
- package/lib/modules/Cart/utils/changePrice.js +50 -28
- package/lib/modules/Cart/utils/index.js +48 -106
- package/lib/modules/Customer/constants.js +34 -13
- package/lib/modules/Customer/index.js +169 -232
- package/lib/modules/Customer/types.js +35 -38
- package/lib/modules/Date/index.js +115 -116
- package/lib/modules/Date/types.js +28 -16
- package/lib/modules/Date/utils.js +123 -174
- package/lib/modules/Discount/index.d.ts +0 -1
- package/lib/modules/Discount/index.js +128 -130
- package/lib/modules/Discount/types.d.ts +0 -1
- package/lib/modules/Discount/types.js +31 -9
- package/lib/modules/Guests/index.js +56 -30
- package/lib/modules/Guests/types.js +33 -23
- package/lib/modules/Holder/index.js +189 -209
- package/lib/modules/Holder/types.js +16 -4
- package/lib/modules/Holder/utils.js +49 -20
- package/lib/modules/OpenData/index.js +76 -69
- package/lib/modules/OpenData/types.js +16 -4
- package/lib/modules/OpenData/utils.js +78 -44
- package/lib/modules/Order/index.js +1909 -1572
- package/lib/modules/Order/types.js +35 -78
- package/lib/modules/Order/utils/bundleDiscountHydration.js +74 -41
- package/lib/modules/Order/utils/manualProductDiscount.js +123 -124
- package/lib/modules/Order/utils/orderCollectionIdentity.js +210 -148
- package/lib/modules/Order/utils.js +634 -799
- package/lib/modules/Payment/cash.js +33 -20
- package/lib/modules/Payment/cashRecommendationAlgorithm.js +76 -145
- package/lib/modules/Payment/eftpos.js +30 -16
- package/lib/modules/Payment/index.js +378 -518
- package/lib/modules/Payment/mx51.js +0 -1
- package/lib/modules/Payment/types.d.ts +4 -8
- package/lib/modules/Payment/types.js +107 -216
- package/lib/modules/Payment/utils.js +48 -51
- package/lib/modules/Payment/walletpass.d.ts +0 -2
- package/lib/modules/Payment/walletpass.js +211 -226
- package/lib/modules/Product/index.js +46 -51
- package/lib/modules/Product/types.js +16 -4
- package/lib/modules/Product/utils.js +33 -32
- package/lib/modules/ProductList/index.d.ts +1 -1
- package/lib/modules/ProductList/index.js +117 -117
- package/lib/modules/ProductList/types.d.ts +0 -1
- package/lib/modules/ProductList/types.js +31 -9
- package/lib/modules/Quotation/index.js +100 -66
- package/lib/modules/Quotation/types.js +16 -4
- package/lib/modules/Resource/index.js +59 -27
- package/lib/modules/Resource/types.js +32 -22
- package/lib/modules/Resource/utils.js +38 -30
- package/lib/modules/ResourcePlanner/index.js +61 -60
- package/lib/modules/ResourcePlanner/planner.js +384 -346
- package/lib/modules/ResourcePlanner/types.js +16 -4
- package/lib/modules/Rules/index.js +903 -1475
- package/lib/modules/Rules/types.js +40 -17
- package/lib/modules/SalesSummary/index.js +90 -85
- package/lib/modules/SalesSummary/types.js +16 -4
- package/lib/modules/SalesSummary/utils.js +427 -351
- package/lib/modules/ScanOrderLogger/index.js +79 -59
- package/lib/modules/ScanOrderLogger/providers/feishu.js +78 -54
- package/lib/modules/ScanOrderLogger/providers/grafana.js +36 -13
- package/lib/modules/ScanOrderLogger/types.js +16 -4
- package/lib/modules/Schedule/getDateIsInSchedule.js +163 -339
- package/lib/modules/Schedule/index.js +114 -100
- package/lib/modules/Schedule/type.js +16 -4
- package/lib/modules/Schedule/types.js +16 -4
- package/lib/modules/Schedule/utils.js +291 -433
- package/lib/modules/Step/index.js +52 -40
- package/lib/modules/Step/tyeps.js +16 -4
- package/lib/modules/Summary/index.js +71 -66
- package/lib/modules/Summary/types.js +16 -4
- package/lib/modules/Summary/utils.js +418 -791
- package/lib/modules/SurchargeList/index.js +60 -46
- package/lib/modules/SurchargeList/types.js +16 -4
- package/lib/modules/index.js +63 -245
- package/lib/plugins/app.js +16 -4
- package/lib/plugins/index.js +25 -36
- package/lib/plugins/request.js +126 -137
- package/lib/plugins/shopStore.js +16 -4
- package/lib/plugins/user.js +16 -4
- package/lib/plugins/window.js +179 -171
- package/lib/server/index.js +2337 -2675
- package/lib/server/modules/floor-plan/index.js +123 -102
- package/lib/server/modules/floor-plan/types.js +30 -15
- package/lib/server/modules/index.js +68 -106
- package/lib/server/modules/menu/index.js +122 -146
- package/lib/server/modules/menu/types.js +31 -18
- package/lib/server/modules/order/index.js +642 -567
- package/lib/server/modules/order/types.js +32 -117
- package/lib/server/modules/order/utils/filterBookings.js +194 -219
- package/lib/server/modules/order/utils/filterOrders.js +92 -118
- package/lib/server/modules/payment/index.js +83 -59
- package/lib/server/modules/payment/types.js +16 -4
- package/lib/server/modules/products/index.js +459 -575
- package/lib/server/modules/products/types.js +34 -44
- package/lib/server/modules/quotation/index.js +172 -137
- package/lib/server/modules/quotation/types.js +31 -21
- package/lib/server/modules/resource/index.js +184 -213
- package/lib/server/modules/resource/types.js +33 -42
- package/lib/server/modules/schedule/index.js +123 -135
- package/lib/server/modules/schedule/types.js +21 -14
- package/lib/server/modules/schedule/utils.js +163 -334
- package/lib/server/types.js +16 -4
- package/lib/server/utils/index.js +23 -25
- package/lib/server/utils/product.js +139 -196
- package/lib/server/utils/schedule.js +41 -34
- package/lib/server/utils/small-ticket.js +456 -478
- package/lib/server/utils/time.js +49 -40
- package/lib/solution/BaseSales/index.js +1016 -850
- package/lib/solution/BaseSales/types.js +37 -41
- package/lib/solution/BaseSales/utils/cartPromotion.js +460 -611
- package/lib/solution/BaseSales/utils/parseSalesResponse.js +105 -85
- package/lib/solution/BaseSales/utils/quotationPrice.js +114 -56
- package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +143 -102
- package/lib/solution/BaseSales/utils.js +140 -155
- package/lib/solution/BookingByStep/index.d.ts +1 -1
- package/lib/solution/BookingByStep/index.js +1340 -1530
- package/lib/solution/BookingByStep/types.js +99 -40
- package/lib/solution/BookingByStep/utils/capacity.js +160 -192
- package/lib/solution/BookingByStep/utils/products.js +52 -42
- package/lib/solution/BookingByStep/utils/resources.js +330 -527
- package/lib/solution/BookingByStep/utils/stock.js +44 -65
- package/lib/solution/BookingByStep/utils/timeslots.js +131 -129
- package/lib/solution/BookingTicket/index.d.ts +1 -1
- package/lib/solution/BookingTicket/index.js +459 -543
- package/lib/solution/BookingTicket/types.js +77 -99
- package/lib/solution/BookingTicket/utils/addProductDecision.js +184 -219
- package/lib/solution/BookingTicket/utils/addTimeAvailability.js +89 -58
- package/lib/solution/BookingTicket/utils/bookingStatus.js +78 -107
- package/lib/solution/BookingTicket/utils/cartView.js +94 -110
- package/lib/solution/BookingTicket/utils/exampleData.js +0 -185
- package/lib/solution/BookingTicket/utils/orderCustomer.js +41 -18
- package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +86 -219
- package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +93 -144
- package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +91 -79
- package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +41 -54
- package/lib/solution/BookingTicket/utils/scan/handleScan.js +81 -84
- package/lib/solution/BookingTicket/utils/scan/index.js +104 -98
- package/lib/solution/BookingTicket/utils/scan/scanCache.js +43 -90
- package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +64 -52
- package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +58 -56
- package/lib/solution/BuyTickets/index.js +70 -67
- package/lib/solution/BuyTickets/types.js +38 -22
- package/lib/solution/Checkout/index.js +1158 -1451
- package/lib/solution/Checkout/types.js +61 -91
- package/lib/solution/Checkout/utils/index.js +156 -228
- package/lib/solution/PlaceOrder/index.js +0 -55
- package/lib/solution/RegisterAndLogin/config.js +460 -493
- package/lib/solution/RegisterAndLogin/index.js +630 -633
- package/lib/solution/RegisterAndLogin/types.js +76 -189
- package/lib/solution/RegisterAndLogin/utils.js +125 -183
- package/lib/solution/Sales/index.js +320 -317
- package/lib/solution/Sales/types.js +33 -27
- package/lib/solution/ScanOrder/index.js +862 -831
- package/lib/solution/ScanOrder/types.js +34 -33
- package/lib/solution/ScanOrder/utils.js +371 -406
- package/lib/solution/ShopDiscount/index.js +233 -235
- package/lib/solution/ShopDiscount/types.d.ts +4 -5
- package/lib/solution/ShopDiscount/types.js +37 -15
- package/lib/solution/ShopDiscount/utils.d.ts +0 -9
- package/lib/solution/ShopDiscount/utils.js +172 -309
- package/lib/solution/UnifiedBookingSales/index.js +405 -379
- package/lib/solution/UnifiedBookingSales/types.js +31 -12
- package/lib/solution/VenueBooking/index.d.ts +3 -31
- package/lib/solution/VenueBooking/index.js +916 -967
- package/lib/solution/VenueBooking/types.d.ts +1 -3
- package/lib/solution/VenueBooking/types.js +39 -20
- package/lib/solution/VenueBooking/utils/dateSummary.d.ts +2 -2
- package/lib/solution/VenueBooking/utils/dateSummary.js +62 -25
- package/lib/solution/VenueBooking/utils/resource.js +54 -31
- package/lib/solution/VenueBooking/utils/slotMerge.js +107 -94
- package/lib/solution/VenueBooking/utils/timeSlot.d.ts +0 -2
- package/lib/solution/VenueBooking/utils/timeSlot.js +133 -138
- package/lib/solution/VenueBooking/utils.js +67 -130
- package/lib/solution/index.js +41 -124
- package/lib/store/createStore.js +29 -32
- package/lib/types/index.d.ts +1 -1
- package/lib/types/index.js +16 -4
- package/lib/utils/task.js +36 -36
- package/lib/utils/watch.js +47 -81
- package/package.json +2 -4
- package/dist/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/dist/solution/VenueBooking/utils/smartPricing.js +0 -233
- package/lib/solution/VenueBooking/utils/smartPricing.d.ts +0 -70
- package/lib/solution/VenueBooking/utils/smartPricing.js +0 -192
|
@@ -1,51 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Object.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var
|
|
7
|
-
|
|
1
|
+
var __create = Object.create;
|
|
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;
|
|
8
18
|
};
|
|
9
|
-
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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);
|
|
29
|
+
|
|
30
|
+
// src/solution/VenueBooking/index.ts
|
|
31
|
+
var VenueBooking_exports = {};
|
|
32
|
+
__export(VenueBooking_exports, {
|
|
33
|
+
VenueBookingImpl: () => VenueBookingImpl
|
|
22
34
|
});
|
|
23
|
-
|
|
24
|
-
var
|
|
25
|
-
var
|
|
26
|
-
var
|
|
27
|
-
var
|
|
28
|
-
var
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
var
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
37
|
-
var
|
|
38
|
-
var
|
|
39
|
-
var
|
|
40
|
-
var
|
|
41
|
-
var
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
module.exports = __toCommonJS(VenueBooking_exports);
|
|
36
|
+
var import_BaseSales = require("../BaseSales");
|
|
37
|
+
var import_types = require("./types");
|
|
38
|
+
var import_utils = require("./utils");
|
|
39
|
+
var import_types2 = require("../BookingByStep/types");
|
|
40
|
+
var import_ProductList = require("../../modules/ProductList");
|
|
41
|
+
var import_Date = require("../../modules/Date");
|
|
42
|
+
var import_Schedule = require("../../modules/Schedule");
|
|
43
|
+
var import_utils2 = require("../../modules/Schedule/utils");
|
|
44
|
+
var import_Quotation = require("../../modules/Quotation");
|
|
45
|
+
var import_OpenData = require("../../modules/OpenData");
|
|
46
|
+
var import_types3 = require("../../modules/Account/types");
|
|
47
|
+
var import_dayjs = __toESM(require("dayjs"));
|
|
48
|
+
var import_itemRule = require("../../model/strategy/adapter/itemRule");
|
|
49
|
+
var import_resource = require("./utils/resource");
|
|
50
|
+
var import_timeSlot = require("./utils/timeSlot");
|
|
51
|
+
var import_dateSummary = require("./utils/dateSummary");
|
|
52
|
+
var import_slotMerge = require("./utils/slotMerge");
|
|
53
|
+
var import_utils3 = require("../../modules/Order/utils");
|
|
54
|
+
var import_Order = require("../../modules/Order");
|
|
55
|
+
var import_types4 = require("../RegisterAndLogin/types");
|
|
56
|
+
var import_decimal = __toESM(require("decimal.js"));
|
|
57
|
+
var import_Holder = require("../../modules/Holder");
|
|
58
|
+
var import_utils4 = require("../../modules/Holder/utils");
|
|
59
|
+
__reExport(VenueBooking_exports, require("./types"), module.exports);
|
|
60
|
+
var OPEN_DATA_SECTION_CODES = [
|
|
61
|
+
"basic",
|
|
62
|
+
"fulfillment",
|
|
63
|
+
"reservation",
|
|
64
|
+
"sale",
|
|
65
|
+
"menu",
|
|
66
|
+
"availability",
|
|
67
|
+
"workflow",
|
|
68
|
+
"checkout"
|
|
69
|
+
];
|
|
47
70
|
function cloneCustomDepositData(customDepositData) {
|
|
48
|
-
if (!customDepositData || typeof customDepositData !==
|
|
71
|
+
if (!customDepositData || typeof customDepositData !== "object")
|
|
72
|
+
return void 0;
|
|
49
73
|
return {
|
|
50
74
|
...customDepositData,
|
|
51
75
|
self_deposit_policy_ids: Array.isArray(customDepositData.self_deposit_policy_ids) ? [...customDepositData.self_deposit_policy_ids] : [],
|
|
@@ -53,74 +77,69 @@ function cloneCustomDepositData(customDepositData) {
|
|
|
53
77
|
deposit_policy_data: Array.isArray(customDepositData.deposit_policy_data) ? [...customDepositData.deposit_policy_data] : []
|
|
54
78
|
};
|
|
55
79
|
}
|
|
56
|
-
class
|
|
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
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
customerLoginRefreshIdInFlight = null;
|
|
93
|
-
/** 最近一次确认登录的客户;登录事件与 user 插件更新之间可能存在时序差。 */
|
|
94
|
-
smartPricingCustomerId;
|
|
95
|
-
loadAllProductsInFlight = null;
|
|
96
|
-
productsLoaded = false;
|
|
97
|
-
loadOpenDataConfigInFlight = null;
|
|
98
|
-
static OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
|
|
99
|
-
/** 按日期缓存 slot 智能定价 Map,避免同周重复 resolveProducts */
|
|
100
|
-
slotPriceMapCache = new Map();
|
|
101
|
-
/** loadProducts 后缓存的全量商品(venue + addon),供分段算价复用 */
|
|
102
|
-
smartPricingProductCatalog = [];
|
|
103
|
-
static PISELL1_LOGIN_SUCCESS = 'pisell1.login.success';
|
|
80
|
+
var _VenueBookingImpl = class extends import_BaseSales.BaseSalesImpl {
|
|
81
|
+
constructor(name, version) {
|
|
82
|
+
super(name, version);
|
|
83
|
+
this.defaultName = "venueBooking";
|
|
84
|
+
this.defaultVersion = "1.0.0";
|
|
85
|
+
this.isSolution = true;
|
|
86
|
+
this.initializeOptions = {};
|
|
87
|
+
this.store = {
|
|
88
|
+
entryContext: null,
|
|
89
|
+
status: "idle",
|
|
90
|
+
flow: {},
|
|
91
|
+
error: null,
|
|
92
|
+
products: void 0,
|
|
93
|
+
rawResourceData: [],
|
|
94
|
+
slotConfig: { ...import_types.DEFAULT_SLOT_CONFIG },
|
|
95
|
+
itemRuleQuantityLimits: [],
|
|
96
|
+
cartValidation: {
|
|
97
|
+
passed: null,
|
|
98
|
+
failures: []
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
this.otherParams = {};
|
|
102
|
+
this.baseSlotConfig = { ...import_types.DEFAULT_SLOT_CONFIG };
|
|
103
|
+
this.itemRuleEvaluator = new import_itemRule.ItemRuleEvaluator();
|
|
104
|
+
this.itemRuleConfigs = [];
|
|
105
|
+
this.itemRuleConfigsPromise = null;
|
|
106
|
+
this.itemRulePrefillApplied = false;
|
|
107
|
+
this.itemRuleRuntimeConfig = {};
|
|
108
|
+
this.resourceProductMap = /* @__PURE__ */ new Map();
|
|
109
|
+
this.loginEffectDisposers = [];
|
|
110
|
+
this.customerLoginRefreshInFlight = null;
|
|
111
|
+
this.customerLoginRefreshIdInFlight = null;
|
|
112
|
+
this.loadAllProductsInFlight = null;
|
|
113
|
+
this.productsLoaded = false;
|
|
114
|
+
this.loadOpenDataConfigInFlight = null;
|
|
115
|
+
}
|
|
104
116
|
getLoggerContext() {
|
|
105
117
|
return {
|
|
106
118
|
cacheId: this.cacheId,
|
|
107
119
|
solutionName: this.name,
|
|
108
|
-
moduleName:
|
|
120
|
+
moduleName: "venueBooking"
|
|
109
121
|
};
|
|
110
122
|
}
|
|
111
123
|
safeStringify(value) {
|
|
112
124
|
try {
|
|
113
125
|
return JSON.stringify(value);
|
|
114
126
|
} catch {
|
|
115
|
-
return
|
|
127
|
+
return void 0;
|
|
116
128
|
}
|
|
117
129
|
}
|
|
118
130
|
pickErrorMessage(error) {
|
|
119
|
-
|
|
131
|
+
var _a, _b, _c, _d;
|
|
132
|
+
const candidates = [
|
|
133
|
+
error.message,
|
|
134
|
+
(_a = error.data) == null ? void 0 : _a.message,
|
|
135
|
+
(_c = (_b = error.response) == null ? void 0 : _b.data) == null ? void 0 : _c.message,
|
|
136
|
+
(_d = error.error) == null ? void 0 : _d.message
|
|
137
|
+
];
|
|
120
138
|
for (const candidate of candidates) {
|
|
121
|
-
if (typeof candidate ===
|
|
139
|
+
if (typeof candidate === "string" && candidate.trim())
|
|
140
|
+
return candidate;
|
|
122
141
|
}
|
|
123
|
-
return
|
|
142
|
+
return void 0;
|
|
124
143
|
}
|
|
125
144
|
serializeError(error) {
|
|
126
145
|
if (error instanceof Error) {
|
|
@@ -130,23 +149,15 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
130
149
|
stack: error.stack
|
|
131
150
|
};
|
|
132
151
|
}
|
|
133
|
-
if (error && typeof error ===
|
|
152
|
+
if (error && typeof error === "object") {
|
|
134
153
|
const raw = error;
|
|
135
154
|
const message = this.pickErrorMessage(raw) || this.safeStringify(raw) || String(error);
|
|
136
155
|
return {
|
|
137
|
-
...
|
|
138
|
-
name: raw.name
|
|
139
|
-
} : {}),
|
|
156
|
+
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
140
157
|
message,
|
|
141
|
-
...
|
|
142
|
-
|
|
143
|
-
} : {}
|
|
144
|
-
...('status' in raw ? {
|
|
145
|
-
status: raw.status
|
|
146
|
-
} : {}),
|
|
147
|
-
...(this.safeStringify(raw) ? {
|
|
148
|
-
raw: this.safeStringify(raw)
|
|
149
|
-
} : {})
|
|
158
|
+
..."code" in raw ? { code: raw.code } : {},
|
|
159
|
+
..."status" in raw ? { status: raw.status } : {},
|
|
160
|
+
...this.safeStringify(raw) ? { raw: this.safeStringify(raw) } : {}
|
|
150
161
|
};
|
|
151
162
|
}
|
|
152
163
|
return {
|
|
@@ -156,19 +167,18 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
156
167
|
async addVenueBookingLog(params) {
|
|
157
168
|
const payload = {
|
|
158
169
|
cacheId: this.cacheId,
|
|
159
|
-
...
|
|
170
|
+
...params.payload || {}
|
|
160
171
|
};
|
|
161
172
|
const extra = {
|
|
162
|
-
...
|
|
173
|
+
...params.extra || {}
|
|
163
174
|
};
|
|
164
175
|
const logger = this.store.scanOrderLogger;
|
|
165
176
|
if (!logger) {
|
|
166
|
-
if ((params.level ||
|
|
167
|
-
console.error(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
} else {}
|
|
177
|
+
if ((params.level || "info") === "error") {
|
|
178
|
+
console.error("[VenueBooking][log-fallback]", params.title, { payload, extra });
|
|
179
|
+
} else {
|
|
180
|
+
console.log("[VenueBooking][log-fallback]", params.title, { payload, extra });
|
|
181
|
+
}
|
|
172
182
|
return;
|
|
173
183
|
}
|
|
174
184
|
await logger.addLog({
|
|
@@ -179,7 +189,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
179
189
|
}
|
|
180
190
|
logMethodStart(method, payload = {}) {
|
|
181
191
|
void this.addVenueBookingLog({
|
|
182
|
-
level:
|
|
192
|
+
level: "info",
|
|
183
193
|
title: `[VenueBooking] ${method} start`,
|
|
184
194
|
payload: {
|
|
185
195
|
method,
|
|
@@ -189,7 +199,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
189
199
|
}
|
|
190
200
|
logMethodSuccess(method, payload = {}) {
|
|
191
201
|
void this.addVenueBookingLog({
|
|
192
|
-
level:
|
|
202
|
+
level: "info",
|
|
193
203
|
title: `[VenueBooking] ${method} success`,
|
|
194
204
|
payload: {
|
|
195
205
|
method,
|
|
@@ -199,7 +209,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
199
209
|
}
|
|
200
210
|
logMethodError(method, error, payload = {}) {
|
|
201
211
|
void this.addVenueBookingLog({
|
|
202
|
-
level:
|
|
212
|
+
level: "error",
|
|
203
213
|
title: `[VenueBooking] ${method} failed`,
|
|
204
214
|
payload: {
|
|
205
215
|
method,
|
|
@@ -212,116 +222,145 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
212
222
|
await this.addVenueBookingLog({
|
|
213
223
|
...params,
|
|
214
224
|
payload: {
|
|
215
|
-
source:
|
|
216
|
-
...
|
|
225
|
+
source: "ui-bridge",
|
|
226
|
+
...params.payload || {}
|
|
217
227
|
}
|
|
218
228
|
});
|
|
219
229
|
}
|
|
220
|
-
constructor(name, version) {
|
|
221
|
-
super(name, version);
|
|
222
|
-
}
|
|
223
230
|
getRegisteredModuleNames() {
|
|
224
|
-
return [
|
|
231
|
+
return [
|
|
232
|
+
"scanOrderLogger",
|
|
233
|
+
"products",
|
|
234
|
+
"order",
|
|
235
|
+
"salesSummary",
|
|
236
|
+
"venueProducts",
|
|
237
|
+
"addonProducts",
|
|
238
|
+
"date",
|
|
239
|
+
"schedule",
|
|
240
|
+
"quotation",
|
|
241
|
+
"openData"
|
|
242
|
+
];
|
|
225
243
|
}
|
|
226
244
|
createSubModule(moduleName) {
|
|
227
245
|
switch (moduleName) {
|
|
228
|
-
case
|
|
229
|
-
return (0,
|
|
230
|
-
case
|
|
231
|
-
return new
|
|
232
|
-
case
|
|
233
|
-
return new
|
|
234
|
-
case
|
|
235
|
-
return new
|
|
236
|
-
case
|
|
237
|
-
return new
|
|
246
|
+
case "scanOrderLogger":
|
|
247
|
+
return (0, import_types2.createModule)("scanOrderLogger", this.name);
|
|
248
|
+
case "venueProducts":
|
|
249
|
+
return new import_ProductList.ProductList(`${this.name}_venueProducts`);
|
|
250
|
+
case "addonProducts":
|
|
251
|
+
return new import_ProductList.ProductList(`${this.name}_addonProducts`);
|
|
252
|
+
case "date":
|
|
253
|
+
return new import_Date.DateModule(`${this.name}_date`);
|
|
254
|
+
case "openData":
|
|
255
|
+
return new import_OpenData.OpenDataModule(`${this.name}_openData`);
|
|
238
256
|
default:
|
|
239
257
|
return super.createSubModule(moduleName);
|
|
240
258
|
}
|
|
241
259
|
}
|
|
242
260
|
attachProductOriginToTempOrder(tempOrder, productUid, origin) {
|
|
243
|
-
|
|
261
|
+
var _a, _b, _c;
|
|
262
|
+
if (!productUid || !origin)
|
|
263
|
+
return;
|
|
244
264
|
tempOrder._extend = {
|
|
245
|
-
...
|
|
265
|
+
...tempOrder._extend || {},
|
|
246
266
|
productsByUid: {
|
|
247
|
-
...(tempOrder._extend
|
|
267
|
+
...((_a = tempOrder._extend) == null ? void 0 : _a.productsByUid) || {},
|
|
248
268
|
[productUid]: {
|
|
249
|
-
...(tempOrder._extend
|
|
269
|
+
...((_c = (_b = tempOrder._extend) == null ? void 0 : _b.productsByUid) == null ? void 0 : _c[productUid]) || {},
|
|
250
270
|
origin
|
|
251
271
|
}
|
|
252
272
|
}
|
|
253
273
|
};
|
|
254
274
|
}
|
|
255
275
|
readProductOriginFromTempOrder(tempOrder, product) {
|
|
256
|
-
|
|
257
|
-
|
|
276
|
+
var _a, _b, _c, _d;
|
|
277
|
+
const uid = ((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) || product.identity_key;
|
|
278
|
+
if (uid && ((_d = (_c = (_b = tempOrder._extend) == null ? void 0 : _b.productsByUid) == null ? void 0 : _c[uid]) == null ? void 0 : _d.origin)) {
|
|
258
279
|
return tempOrder._extend.productsByUid[uid].origin;
|
|
259
280
|
}
|
|
260
281
|
return product._origin;
|
|
261
282
|
}
|
|
262
283
|
normalizeVenueProductTitle(value) {
|
|
263
|
-
if (typeof value ===
|
|
284
|
+
if (typeof value === "string") {
|
|
264
285
|
const text = value.trim();
|
|
265
|
-
return text ? {
|
|
266
|
-
auto: text
|
|
267
|
-
} : undefined;
|
|
286
|
+
return text ? { auto: text } : void 0;
|
|
268
287
|
}
|
|
269
|
-
if (!value || typeof value !==
|
|
288
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
289
|
+
return void 0;
|
|
270
290
|
const source = value;
|
|
271
291
|
const normalized = {};
|
|
272
292
|
Object.entries(source).forEach(([key, text]) => {
|
|
273
|
-
if (typeof text ===
|
|
293
|
+
if (typeof text === "string")
|
|
294
|
+
normalized[key] = text;
|
|
274
295
|
});
|
|
275
296
|
if (!normalized.auto) {
|
|
276
|
-
const fallback = normalized.original || normalized.en || normalized[
|
|
277
|
-
if (fallback)
|
|
297
|
+
const fallback = normalized.original || normalized.en || normalized["zh-CN"] || normalized["zh-HK"];
|
|
298
|
+
if (fallback)
|
|
299
|
+
normalized.auto = fallback;
|
|
278
300
|
}
|
|
279
|
-
return Object.values(normalized).some(text => String(text ||
|
|
301
|
+
return Object.values(normalized).some((text) => String(text || "").trim()) ? normalized : void 0;
|
|
280
302
|
}
|
|
281
303
|
normalizeCustomerId(value) {
|
|
282
304
|
const customerId = Number(value);
|
|
283
|
-
if (!Number.isFinite(customerId) || customerId <= 0)
|
|
305
|
+
if (!Number.isFinite(customerId) || customerId <= 0)
|
|
306
|
+
return null;
|
|
284
307
|
return customerId;
|
|
285
308
|
}
|
|
286
309
|
resolveCustomerIdFromLoginPayload(payload) {
|
|
287
|
-
|
|
310
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
311
|
+
const candidates = [
|
|
312
|
+
payload == null ? void 0 : payload.customerId,
|
|
313
|
+
payload == null ? void 0 : payload.customer_id,
|
|
314
|
+
payload == null ? void 0 : payload.id,
|
|
315
|
+
(_a = payload == null ? void 0 : payload.user) == null ? void 0 : _a.customerId,
|
|
316
|
+
(_b = payload == null ? void 0 : payload.user) == null ? void 0 : _b.customer_id,
|
|
317
|
+
(_c = payload == null ? void 0 : payload.user) == null ? void 0 : _c.id,
|
|
318
|
+
(_e = (_d = payload == null ? void 0 : payload.user) == null ? void 0 : _d._origin) == null ? void 0 : _e.customer_id,
|
|
319
|
+
(_f = payload == null ? void 0 : payload.account) == null ? void 0 : _f.customerId,
|
|
320
|
+
(_g = payload == null ? void 0 : payload.account) == null ? void 0 : _g.customer_id,
|
|
321
|
+
(_h = payload == null ? void 0 : payload.account) == null ? void 0 : _h.id,
|
|
322
|
+
(_i = payload == null ? void 0 : payload._origin) == null ? void 0 : _i.customer_id
|
|
323
|
+
];
|
|
288
324
|
for (const candidate of candidates) {
|
|
289
325
|
const customerId = this.normalizeCustomerId(candidate);
|
|
290
|
-
if (customerId)
|
|
326
|
+
if (customerId)
|
|
327
|
+
return customerId;
|
|
291
328
|
}
|
|
292
329
|
return null;
|
|
293
330
|
}
|
|
294
331
|
resolveHolderCustomerId() {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
332
|
+
var _a, _b;
|
|
333
|
+
const customer = JSON.parse(((_b = (_a = this.window) == null ? void 0 : _a.getLocalStorage) == null ? void 0 : _b.call(_a, "customer")) || "{}");
|
|
334
|
+
if (customer == null ? void 0 : customer.id)
|
|
335
|
+
return Number(customer.id);
|
|
336
|
+
return void 0;
|
|
298
337
|
}
|
|
299
|
-
|
|
300
338
|
/**
|
|
301
339
|
* 按商品 holder_config 预加载表单数据到 holderMap。
|
|
302
340
|
* appointment_booking 在加购时触发;venueBooking 在商品加载后预加载,避免 getHolderFormMap 为空。
|
|
303
341
|
*/
|
|
304
342
|
async preloadHolderForms(products) {
|
|
305
|
-
|
|
306
|
-
|
|
343
|
+
var _a, _b, _c, _d;
|
|
344
|
+
if (!this.store.holder || !products.length)
|
|
345
|
+
return;
|
|
346
|
+
const seenFormIds = /* @__PURE__ */ new Set();
|
|
307
347
|
for (const item of products) {
|
|
308
|
-
const holderConfig = (0,
|
|
309
|
-
if (!holderConfig)
|
|
310
|
-
|
|
311
|
-
|
|
348
|
+
const holderConfig = (0, import_utils4.getProductHolderConfig)((_a = item == null ? void 0 : item._origin) == null ? void 0 : _a.product);
|
|
349
|
+
if (!holderConfig)
|
|
350
|
+
continue;
|
|
351
|
+
const formId = (0, import_utils4.getFormIdFromHolderConfig)(holderConfig);
|
|
352
|
+
if (seenFormIds.has(formId))
|
|
353
|
+
continue;
|
|
312
354
|
seenFormIds.add(formId);
|
|
313
355
|
try {
|
|
314
356
|
await this.store.holder.ensureFormByProduct({
|
|
315
|
-
product: item
|
|
357
|
+
product: ((_b = item == null ? void 0 : item._origin) == null ? void 0 : _b.product) || {},
|
|
316
358
|
customer_id: this.resolveHolderCustomerId(),
|
|
317
|
-
shop_id: item
|
|
359
|
+
shop_id: (_d = (_c = item == null ? void 0 : item._origin) == null ? void 0 : _c.product) == null ? void 0 : _d.shop_id,
|
|
318
360
|
useCache: true
|
|
319
361
|
});
|
|
320
362
|
} catch (error) {
|
|
321
|
-
console.error(
|
|
322
|
-
formId,
|
|
323
|
-
error
|
|
324
|
-
});
|
|
363
|
+
console.error("[VenueBooking] 预加载 holder 表单失败", { formId, error });
|
|
325
364
|
}
|
|
326
365
|
}
|
|
327
366
|
}
|
|
@@ -332,30 +371,35 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
332
371
|
this.loginEffectDisposers = [];
|
|
333
372
|
}
|
|
334
373
|
registerLoginEffect(event, callback) {
|
|
335
|
-
|
|
336
|
-
|
|
374
|
+
var _a;
|
|
375
|
+
const effects = (_a = this.core) == null ? void 0 : _a.effects;
|
|
376
|
+
if (!(effects == null ? void 0 : effects.on))
|
|
377
|
+
return;
|
|
337
378
|
effects.on(event, callback);
|
|
338
379
|
this.loginEffectDisposers.push(() => {
|
|
339
|
-
if (typeof effects.off ===
|
|
380
|
+
if (typeof effects.off === "function") {
|
|
340
381
|
effects.off(event, callback);
|
|
341
382
|
}
|
|
342
383
|
});
|
|
343
384
|
}
|
|
344
385
|
registerCustomerLoginListeners() {
|
|
386
|
+
var _a, _b, _c, _d;
|
|
345
387
|
this.clearLoginEffectListeners();
|
|
346
|
-
const
|
|
388
|
+
const accountModule = (_a = this.core) == null ? void 0 : _a.getModule("account");
|
|
389
|
+
const registerAndLoginModule = (_b = this.core) == null ? void 0 : _b.getModule("registerAndLogin");
|
|
390
|
+
const currentAccount = ((_c = accountModule == null ? void 0 : accountModule.getCurrentAccount) == null ? void 0 : _c.call(accountModule)) || ((_d = accountModule == null ? void 0 : accountModule.getAccount) == null ? void 0 : _d.call(accountModule)) || null;
|
|
391
|
+
const createHandleLogin = (eventName) => async (payload) => {
|
|
347
392
|
const customerId = this.resolveCustomerIdFromLoginPayload(payload);
|
|
348
|
-
if (!customerId)
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
});
|
|
393
|
+
if (!customerId)
|
|
394
|
+
return;
|
|
395
|
+
await this.refreshOrderMarketingAfterLogin({ customerId });
|
|
352
396
|
};
|
|
353
|
-
this.registerLoginEffect(
|
|
354
|
-
this.registerLoginEffect(
|
|
355
|
-
this.registerLoginEffect(_types4.RegisterAndLoginHooks.onLoginSuccess, createHandleLogin());
|
|
397
|
+
this.registerLoginEffect(import_types3.AccountHooks.OnLogin, createHandleLogin(import_types3.AccountHooks.OnLogin));
|
|
398
|
+
this.registerLoginEffect(import_types4.RegisterAndLoginHooks.onLoginSuccess, createHandleLogin(import_types4.RegisterAndLoginHooks.onLoginSuccess));
|
|
356
399
|
}
|
|
357
400
|
async refreshOrderMarketingAfterLogin(params) {
|
|
358
|
-
if (!this.store.order)
|
|
401
|
+
if (!this.store.order)
|
|
402
|
+
throw new Error("order 模块未初始化");
|
|
359
403
|
if (this.customerLoginRefreshInFlight) {
|
|
360
404
|
if (this.customerLoginRefreshIdInFlight === params.customerId) {
|
|
361
405
|
await this.customerLoginRefreshInFlight;
|
|
@@ -365,14 +409,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
365
409
|
}
|
|
366
410
|
this.customerLoginRefreshIdInFlight = params.customerId;
|
|
367
411
|
const refreshTask = (async () => {
|
|
368
|
-
|
|
369
|
-
this.smartPricingCustomerId = params.customerId;
|
|
370
|
-
await this.store.order.loadDiscountConfig({
|
|
371
|
-
customerId: params.customerId
|
|
372
|
-
});
|
|
373
|
-
this.clearSlotPriceMapCache();
|
|
374
|
-
this.recalculateOrderPricesFromSmartPricing();
|
|
375
|
-
// 刷新 holder 表单数据
|
|
412
|
+
var _a;
|
|
376
413
|
if (this.store.holder) {
|
|
377
414
|
await this.store.holder.refreshAllFormRecords({
|
|
378
415
|
customer_id: params.customerId,
|
|
@@ -381,18 +418,17 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
381
418
|
}
|
|
382
419
|
if (this.store.quotation) {
|
|
383
420
|
await this.store.quotation.loadQuotations({
|
|
384
|
-
channel: this.otherParams
|
|
421
|
+
channel: (_a = this.otherParams) == null ? void 0 : _a.channel
|
|
385
422
|
});
|
|
386
423
|
}
|
|
387
|
-
|
|
388
|
-
|
|
424
|
+
this.recalculateOrderPricesFromQuotation();
|
|
425
|
+
await this.store.order.loadDiscountConfig({
|
|
426
|
+
customerId: params.customerId
|
|
389
427
|
});
|
|
428
|
+
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
390
429
|
this.store.order.persistTempOrder();
|
|
391
430
|
await this.refreshItemRuleQuantityLimits();
|
|
392
431
|
await this.refreshCartValidationPassed();
|
|
393
|
-
await this.core?.effects?.emit?.(_types.VenueBookingHooks.onSmartPricingUpdated, {
|
|
394
|
-
customerId: params.customerId
|
|
395
|
-
});
|
|
396
432
|
})();
|
|
397
433
|
this.customerLoginRefreshInFlight = refreshTask;
|
|
398
434
|
try {
|
|
@@ -407,26 +443,21 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
407
443
|
}
|
|
408
444
|
}
|
|
409
445
|
async initialize(core, options = {}) {
|
|
410
|
-
|
|
411
|
-
this.
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
this.smartPricingCustomerId = undefined;
|
|
416
|
-
this.store.entryContext = options.otherParams?.entryContext || this.store.entryContext;
|
|
417
|
-
this.store.status = 'initializing';
|
|
446
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
|
|
447
|
+
this.logMethodStart("initialize");
|
|
448
|
+
this.store = { ...this.store, ...options.store };
|
|
449
|
+
this.store.entryContext = ((_a = options.otherParams) == null ? void 0 : _a.entryContext) || this.store.entryContext;
|
|
450
|
+
this.store.status = "initializing";
|
|
418
451
|
this.store.error = null;
|
|
419
452
|
this.store.rawResourceData = [];
|
|
420
453
|
this.baseSlotConfig = {
|
|
421
|
-
...
|
|
422
|
-
...(options.otherParams
|
|
423
|
-
};
|
|
424
|
-
this.store.slotConfig = {
|
|
425
|
-
...this.baseSlotConfig
|
|
454
|
+
...import_types.DEFAULT_SLOT_CONFIG,
|
|
455
|
+
...((_b = options.otherParams) == null ? void 0 : _b.slotConfig) || {}
|
|
426
456
|
};
|
|
457
|
+
this.store.slotConfig = { ...this.baseSlotConfig };
|
|
427
458
|
this.otherParams = options.otherParams || {};
|
|
428
|
-
this.cacheId = this.otherParams
|
|
429
|
-
this.itemRuleRuntimeConfig = this.otherParams
|
|
459
|
+
this.cacheId = (_c = this.otherParams) == null ? void 0 : _c.cacheId;
|
|
460
|
+
this.itemRuleRuntimeConfig = ((_d = this.otherParams) == null ? void 0 : _d.venueBookingItemRule) || ((_e = this.otherParams) == null ? void 0 : _e.itemRule) || {};
|
|
430
461
|
this.itemRuleConfigs = [];
|
|
431
462
|
this.itemRuleConfigsPromise = null;
|
|
432
463
|
this.itemRulePrefillApplied = false;
|
|
@@ -437,26 +468,35 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
437
468
|
};
|
|
438
469
|
await super.initialize(core, options);
|
|
439
470
|
if (this.store.scanOrderLogger) {
|
|
440
|
-
this.store.scanOrderLogger.setProvider(
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
471
|
+
this.store.scanOrderLogger.setProvider(
|
|
472
|
+
((_f = this.otherParams) == null ? void 0 : _f.loggerProvider) || "feishu"
|
|
473
|
+
);
|
|
474
|
+
this.store.scanOrderLogger.setProviderConfig(
|
|
475
|
+
((_g = this.otherParams) == null ? void 0 : _g.loggerConfig) || {
|
|
476
|
+
feishu: {
|
|
477
|
+
webhook: "https://open.feishu.cn/open-apis/bot/v2/hook/8f069b14-9d39-4728-8f78-b56f393bfde8",
|
|
478
|
+
errorHook: "https://open.feishu.cn/open-apis/bot/v2/hook/bdefae5e-f233-4705-8688-946887d9543d"
|
|
479
|
+
}
|
|
445
480
|
}
|
|
446
|
-
|
|
481
|
+
);
|
|
447
482
|
this.store.scanOrderLogger.setContext(this.getLoggerContext());
|
|
448
483
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
484
|
+
const baseModules = [
|
|
485
|
+
"scanOrderLogger",
|
|
486
|
+
"products",
|
|
487
|
+
"order",
|
|
488
|
+
"salesSummary"
|
|
489
|
+
];
|
|
490
|
+
baseModules.forEach((step) => {
|
|
491
|
+
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
492
|
+
const targetModule = (0, import_types2.createModule)(step, this.name);
|
|
453
493
|
if (targetModule) {
|
|
454
494
|
this.store[step] = targetModule;
|
|
455
|
-
const initialState = step ===
|
|
456
|
-
summary: this.store.order
|
|
495
|
+
const initialState = step === "salesSummary" ? {
|
|
496
|
+
summary: ((_b2 = (_a2 = this.store.order) == null ? void 0 : _a2.getTempOrder()) == null ? void 0 : _b2.summary) || (0, import_utils.createEmptySummary)()
|
|
457
497
|
} : {};
|
|
458
|
-
const loggerProvider = this.otherParams
|
|
459
|
-
const loggerConfig = this.otherParams
|
|
498
|
+
const loggerProvider = ((_c2 = this.otherParams) == null ? void 0 : _c2.loggerProvider) || "feishu";
|
|
499
|
+
const loggerConfig = ((_d2 = this.otherParams) == null ? void 0 : _d2.loggerConfig) || {
|
|
460
500
|
// feishu: {
|
|
461
501
|
// webhook: 'https://open.feishu.cn/open-apis/bot/v2/hook/8f069b14-9d39-4728-8f78-b56f393bfde8',
|
|
462
502
|
// errorHook: 'https://open.feishu.cn/open-apis/bot/v2/hook/bdefae5e-f233-4705-8688-946887d9543d',
|
|
@@ -467,8 +507,8 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
467
507
|
otherParams: {
|
|
468
508
|
...this.otherParams,
|
|
469
509
|
fatherModule: this.name,
|
|
470
|
-
openCache: this.otherParams
|
|
471
|
-
cacheId: this.otherParams
|
|
510
|
+
openCache: ((_e2 = this.otherParams) == null ? void 0 : _e2.cacheId) ? true : false,
|
|
511
|
+
cacheId: (_f2 = this.otherParams) == null ? void 0 : _f2.cacheId,
|
|
472
512
|
salesSummaryModuleName: `${this.name}_salesSummary`,
|
|
473
513
|
provider: loggerProvider,
|
|
474
514
|
providerConfig: loggerConfig,
|
|
@@ -476,13 +516,11 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
476
516
|
}
|
|
477
517
|
});
|
|
478
518
|
} else {
|
|
479
|
-
this.logMethodError(
|
|
519
|
+
this.logMethodError("initialize", `module ${step} missing`);
|
|
480
520
|
throw new Error(`模块 ${step} 不存在`);
|
|
481
521
|
}
|
|
482
522
|
});
|
|
483
|
-
|
|
484
|
-
// 注册场地商品列表模块
|
|
485
|
-
const venueProductsModule = new _ProductList.ProductList(`${this.name}_venueProducts`);
|
|
523
|
+
const venueProductsModule = new import_ProductList.ProductList(`${this.name}_venueProducts`);
|
|
486
524
|
this.store.venueProducts = venueProductsModule;
|
|
487
525
|
this.core.registerModule(venueProductsModule, {
|
|
488
526
|
otherParams: {
|
|
@@ -490,9 +528,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
490
528
|
fatherModule: this.name
|
|
491
529
|
}
|
|
492
530
|
});
|
|
493
|
-
|
|
494
|
-
// 注册附加商品列表模块
|
|
495
|
-
const addonProductsModule = new _ProductList.ProductList(`${this.name}_addonProducts`);
|
|
531
|
+
const addonProductsModule = new import_ProductList.ProductList(`${this.name}_addonProducts`);
|
|
496
532
|
this.store.addonProducts = addonProductsModule;
|
|
497
533
|
this.core.registerModule(addonProductsModule, {
|
|
498
534
|
otherParams: {
|
|
@@ -500,9 +536,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
500
536
|
fatherModule: this.name
|
|
501
537
|
}
|
|
502
538
|
});
|
|
503
|
-
|
|
504
|
-
// 注册日期模块
|
|
505
|
-
const dateModule = new _Date.DateModule(`${this.name}_date`);
|
|
539
|
+
const dateModule = new import_Date.DateModule(`${this.name}_date`);
|
|
506
540
|
this.store.date = dateModule;
|
|
507
541
|
this.core.registerModule(dateModule, {
|
|
508
542
|
otherParams: {
|
|
@@ -511,9 +545,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
511
545
|
cacheId: this.cacheId
|
|
512
546
|
}
|
|
513
547
|
});
|
|
514
|
-
|
|
515
|
-
// 注册日程模块
|
|
516
|
-
const scheduleModule = new _Schedule.ScheduleModule(`${this.name}_schedule`);
|
|
548
|
+
const scheduleModule = new import_Schedule.ScheduleModule(`${this.name}_schedule`);
|
|
517
549
|
this.store.schedule = scheduleModule;
|
|
518
550
|
this.core.registerModule(scheduleModule, {
|
|
519
551
|
otherParams: {
|
|
@@ -521,9 +553,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
521
553
|
fatherModule: this.name
|
|
522
554
|
}
|
|
523
555
|
});
|
|
524
|
-
|
|
525
|
-
// 注册报价单模块
|
|
526
|
-
const quotationModule = new _Quotation.QuotationModule(`${this.name}_quotation`);
|
|
556
|
+
const quotationModule = new import_Quotation.QuotationModule(`${this.name}_quotation`);
|
|
527
557
|
this.store.quotation = quotationModule;
|
|
528
558
|
this.core.registerModule(quotationModule, {
|
|
529
559
|
otherParams: {
|
|
@@ -531,107 +561,109 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
531
561
|
fatherModule: this.name
|
|
532
562
|
}
|
|
533
563
|
});
|
|
534
|
-
|
|
535
|
-
// 注册 OpenData 配置模块
|
|
536
|
-
const openDataModule = new _OpenData.OpenDataModule(`${this.name}_openData`);
|
|
564
|
+
const openDataModule = new import_OpenData.OpenDataModule(`${this.name}_openData`);
|
|
537
565
|
this.store.openData = openDataModule;
|
|
538
566
|
this.core.registerModule(openDataModule, {
|
|
539
567
|
otherParams: {
|
|
540
568
|
...this.otherParams,
|
|
541
569
|
fatherModule: this.name,
|
|
542
|
-
openCache: !!this.otherParams
|
|
543
|
-
cacheId: this.otherParams
|
|
570
|
+
openCache: !!((_h = this.otherParams) == null ? void 0 : _h.cacheId),
|
|
571
|
+
cacheId: (_i = this.otherParams) == null ? void 0 : _i.cacheId
|
|
544
572
|
}
|
|
545
573
|
});
|
|
546
574
|
let holderCacheState;
|
|
547
|
-
if (this.otherParams
|
|
575
|
+
if ((_j = this.otherParams) == null ? void 0 : _j.cacheId) {
|
|
548
576
|
const sessionData = this.window.sessionStorage.getItem(this.name);
|
|
549
577
|
if (sessionData) {
|
|
550
578
|
try {
|
|
551
579
|
const data = JSON.parse(sessionData);
|
|
552
|
-
holderCacheState = data[this.otherParams.cacheId]
|
|
580
|
+
holderCacheState = (_k = data[this.otherParams.cacheId]) == null ? void 0 : _k[`${this.name}_holder`];
|
|
553
581
|
} catch {
|
|
554
|
-
// ignore invalid session cache
|
|
555
582
|
}
|
|
556
583
|
}
|
|
557
584
|
}
|
|
558
|
-
const holderModule = new
|
|
585
|
+
const holderModule = new import_Holder.HolderModule(`${this.name}_holder`);
|
|
559
586
|
this.store.holder = holderModule;
|
|
560
587
|
this.core.registerModule(holderModule, {
|
|
561
588
|
initialState: holderCacheState,
|
|
562
589
|
otherParams: {
|
|
563
590
|
...this.otherParams,
|
|
564
591
|
fatherModule: this.name,
|
|
565
|
-
openCache: !!this.otherParams
|
|
566
|
-
cacheId: this.otherParams
|
|
592
|
+
openCache: !!((_l = this.otherParams) == null ? void 0 : _l.cacheId),
|
|
593
|
+
cacheId: (_m = this.otherParams) == null ? void 0 : _m.cacheId
|
|
567
594
|
}
|
|
568
595
|
});
|
|
569
596
|
this.registerCustomerLoginListeners();
|
|
597
|
+
console.log("[VenueBooking] 初始化开始");
|
|
570
598
|
try {
|
|
571
|
-
await this.store.order
|
|
572
|
-
|
|
573
|
-
});
|
|
574
|
-
this.store.order?.persistTempOrder();
|
|
599
|
+
await ((_n = this.store.order) == null ? void 0 : _n.recalculateSummary({ createIfMissing: false }));
|
|
600
|
+
(_o = this.store.order) == null ? void 0 : _o.persistTempOrder();
|
|
575
601
|
await this.loadRuntimeConfigs();
|
|
576
602
|
if (this.store.schedule) {
|
|
577
603
|
await this.store.schedule.loadAllSchedule();
|
|
604
|
+
this.injectScheduleResolverToQuotation();
|
|
605
|
+
(_q = this.store.quotation) == null ? void 0 : _q.loadQuotations({
|
|
606
|
+
channel: (_p = this.otherParams) == null ? void 0 : _p.channel
|
|
607
|
+
});
|
|
578
608
|
}
|
|
579
609
|
await this.refreshItemRuleQuantityLimits();
|
|
580
|
-
this.store.status =
|
|
581
|
-
|
|
610
|
+
this.store.status = "ready";
|
|
611
|
+
console.log("[VenueBooking] 初始化完成");
|
|
612
|
+
await this.core.effects.emit(import_types.VenueBookingHooks.onInited, {
|
|
582
613
|
status: this.store.status
|
|
583
614
|
});
|
|
584
|
-
this.logMethodSuccess(
|
|
615
|
+
this.logMethodSuccess("initialize", {
|
|
585
616
|
status: this.store.status
|
|
586
617
|
});
|
|
587
618
|
} catch (error) {
|
|
588
|
-
this.store.status =
|
|
589
|
-
this.store.error = error instanceof Error ? error.message :
|
|
590
|
-
console.error(
|
|
591
|
-
this.logMethodError(
|
|
619
|
+
this.store.status = "error";
|
|
620
|
+
this.store.error = error instanceof Error ? error.message : "初始化失败";
|
|
621
|
+
console.error("[VenueBooking] 初始化失败", error);
|
|
622
|
+
this.logMethodError("initialize", error, {
|
|
592
623
|
status: this.store.status
|
|
593
624
|
});
|
|
594
625
|
throw error;
|
|
595
626
|
}
|
|
596
627
|
}
|
|
597
628
|
async destroy() {
|
|
598
|
-
this.logMethodStart(
|
|
629
|
+
this.logMethodStart("destroy");
|
|
599
630
|
this.clearLoginEffectListeners();
|
|
600
|
-
await this.core.effects.emit(
|
|
601
|
-
|
|
631
|
+
await this.core.effects.emit(import_types.VenueBookingHooks.onDestroy, {});
|
|
632
|
+
console.log("[VenueBooking] 已销毁");
|
|
633
|
+
this.logMethodSuccess("destroy");
|
|
602
634
|
}
|
|
603
635
|
async retryInit() {
|
|
604
|
-
this.logMethodStart(
|
|
605
|
-
|
|
636
|
+
this.logMethodStart("retryInit");
|
|
637
|
+
console.log("[VenueBooking] retryInit 调用");
|
|
638
|
+
await this.core.effects.emit(import_types.VenueBookingHooks.onRetryInit, {});
|
|
606
639
|
try {
|
|
607
640
|
await this.initialize(this.core, this.initializeOptions);
|
|
608
|
-
this.logMethodSuccess(
|
|
641
|
+
this.logMethodSuccess("retryInit");
|
|
609
642
|
} catch (error) {
|
|
610
|
-
this.logMethodError(
|
|
643
|
+
this.logMethodError("retryInit", error);
|
|
611
644
|
throw error;
|
|
612
645
|
}
|
|
613
646
|
}
|
|
614
647
|
async refresh() {
|
|
615
|
-
this.logMethodStart(
|
|
648
|
+
this.logMethodStart("refresh");
|
|
649
|
+
console.log("[VenueBooking] refresh 调用");
|
|
616
650
|
try {
|
|
617
|
-
this.store.status =
|
|
651
|
+
this.store.status = "initializing";
|
|
618
652
|
await this.loadRuntimeConfigs();
|
|
619
653
|
await this.refreshItemRuleQuantityLimits();
|
|
620
|
-
this.store.status =
|
|
621
|
-
await this.core.effects.emit(
|
|
654
|
+
this.store.status = "ready";
|
|
655
|
+
await this.core.effects.emit(import_types.VenueBookingHooks.onRefresh, {
|
|
622
656
|
status: this.store.status
|
|
623
657
|
});
|
|
624
|
-
this.logMethodSuccess(
|
|
658
|
+
this.logMethodSuccess("refresh", {
|
|
625
659
|
status: this.store.status
|
|
626
660
|
});
|
|
627
661
|
} catch (error) {
|
|
628
|
-
this.logMethodError(
|
|
662
|
+
this.logMethodError("refresh", error);
|
|
629
663
|
throw error;
|
|
630
664
|
}
|
|
631
665
|
}
|
|
632
|
-
|
|
633
666
|
// ─── 状态查询 ───
|
|
634
|
-
|
|
635
667
|
getStatus() {
|
|
636
668
|
return this.store.status;
|
|
637
669
|
}
|
|
@@ -642,157 +674,65 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
642
674
|
return this.store.itemRuleQuantityLimits || [];
|
|
643
675
|
}
|
|
644
676
|
getCartValidationPassed() {
|
|
645
|
-
|
|
677
|
+
var _a;
|
|
678
|
+
return ((_a = this.store.cartValidation) == null ? void 0 : _a.passed) ?? null;
|
|
646
679
|
}
|
|
647
680
|
getCartValidation() {
|
|
648
|
-
return this.store.cartValidation || {
|
|
649
|
-
passed: null,
|
|
650
|
-
failures: []
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
/** 清除 slot 价格分段缓存(商品重载 / 登录后 customerId 变化时调用) */
|
|
655
|
-
clearSlotPriceMapCache() {
|
|
656
|
-
this.slotPriceMapCache.clear();
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
/** 读取当前登录 customerId */
|
|
660
|
-
resolveCustomerIdForSmartPricing() {
|
|
661
|
-
if (this.smartPricingCustomerId) return this.smartPricingCustomerId;
|
|
662
|
-
try {
|
|
663
|
-
const userPlugin = this.core?.getPlugin('user');
|
|
664
|
-
const customerId = Number(userPlugin?.get?.()?.id);
|
|
665
|
-
return Number.isFinite(customerId) && customerId > 0 ? customerId : undefined;
|
|
666
|
-
} catch {
|
|
667
|
-
return undefined;
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
resolveAvailableWalletIdsForSmartPricing() {
|
|
671
|
-
const orderWalletIds = this.store.order?.getAvailableWalletIds?.();
|
|
672
|
-
const fallbackWalletIds = this.otherParams?.available_wallet_ids || this.otherParams?.availableWalletIds || this.otherParams?.strategy_context?.available_wallet_ids || this.otherParams?.strategy_context?.availableWalletIds;
|
|
673
|
-
const source = Array.isArray(orderWalletIds) && orderWalletIds.length ? orderWalletIds : fallbackWalletIds;
|
|
674
|
-
if (!Array.isArray(source)) return [];
|
|
675
|
-
const ids = source.map(item => Number(item)).filter(item => Number.isFinite(item) && item > 0);
|
|
676
|
-
return Array.from(new Set(ids));
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
/** 读取 schedule 全量列表,供智能定价 schedule_match 使用 */
|
|
680
|
-
getScheduleListForSmartPricing() {
|
|
681
|
-
const scheduleModule = this.store.schedule;
|
|
682
|
-
const list = scheduleModule?.store?.scheduleList;
|
|
683
|
-
return Array.isArray(list) ? list : [];
|
|
681
|
+
return this.store.cartValidation || { passed: null, failures: [] };
|
|
684
682
|
}
|
|
685
|
-
|
|
686
|
-
/** 构建智能定价上下文,对齐 OS Server buildProductFormatterContext */
|
|
687
|
-
buildSmartPricingContext(customerId) {
|
|
688
|
-
const evaluator = this.core?.context?.dataVariantEvaluator;
|
|
689
|
-
return {
|
|
690
|
-
evaluator,
|
|
691
|
-
scheduleList: this.getScheduleListForSmartPricing(),
|
|
692
|
-
menuList: this.otherParams?.menuList || this.otherParams?.openData?.menuList || [],
|
|
693
|
-
customerId: customerId ?? this.resolveCustomerIdForSmartPricing(),
|
|
694
|
-
availableWalletIds: this.resolveAvailableWalletIdsForSmartPricing(),
|
|
695
|
-
channel: this.otherParams?.channel,
|
|
696
|
-
businessCode: this.otherParams?.businessCode,
|
|
697
|
-
orderType: this.otherParams?.orderType || this.otherParams?.type,
|
|
698
|
-
strategy_context: this.otherParams?.strategy_context
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
/** venue + addon 全量商品,供智能定价评估 */
|
|
703
|
-
getAllProductsForSmartPricing() {
|
|
704
|
-
if (this.smartPricingProductCatalog.length) {
|
|
705
|
-
return this.smartPricingProductCatalog;
|
|
706
|
-
}
|
|
707
|
-
const venueList = this.getVenueProducts();
|
|
708
|
-
const addonList = this.getAddonProductsList();
|
|
709
|
-
return [...venueList, ...addonList];
|
|
710
|
-
}
|
|
711
|
-
getSlotPriceMapCacheKey(date, context) {
|
|
712
|
-
return [date, context.customerId ?? '', (context.availableWalletIds || []).join(','), context.channel ?? '', context.businessCode ?? ''].join('|');
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/**
|
|
716
|
-
* 按 schedule 分段构建 slot 价格 Map,带实例级缓存。
|
|
717
|
-
*/
|
|
718
|
-
buildSlotPriceMapForDate(date, config, productIds) {
|
|
719
|
-
const context = this.buildSmartPricingContext();
|
|
720
|
-
const cacheKey = this.getSlotPriceMapCacheKey(date, context);
|
|
721
|
-
const cached = this.slotPriceMapCache.get(cacheKey);
|
|
722
|
-
if (cached) return cached;
|
|
723
|
-
const timeLabels = (0, _timeSlot.generateTimeLabels)(config);
|
|
724
|
-
const slotPriceMap = (0, _smartPricing.buildSlotPriceMapByScheduleSegments)({
|
|
725
|
-
products: this.getAllProductsForSmartPricing(),
|
|
726
|
-
productIds,
|
|
727
|
-
date,
|
|
728
|
-
timeLabels,
|
|
729
|
-
config,
|
|
730
|
-
context
|
|
731
|
-
});
|
|
732
|
-
this.slotPriceMapCache.set(cacheKey, slotPriceMap);
|
|
733
|
-
return slotPriceMap;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
683
|
// ─── 场地商品 & 附加商品 ───
|
|
737
|
-
|
|
738
684
|
async loadAllProducts() {
|
|
739
|
-
if (this.loadAllProductsInFlight)
|
|
685
|
+
if (this.loadAllProductsInFlight)
|
|
686
|
+
return this.loadAllProductsInFlight;
|
|
740
687
|
this.loadAllProductsInFlight = this._doLoadAllProducts().finally(() => {
|
|
741
688
|
this.loadAllProductsInFlight = null;
|
|
742
689
|
});
|
|
743
690
|
return this.loadAllProductsInFlight;
|
|
744
691
|
}
|
|
745
692
|
async _doLoadAllProducts() {
|
|
746
|
-
|
|
693
|
+
var _a, _b, _c, _d, _e;
|
|
694
|
+
this.logMethodStart("loadAllProducts");
|
|
747
695
|
try {
|
|
748
|
-
if (!this.store.venueProducts)
|
|
749
|
-
|
|
696
|
+
if (!this.store.venueProducts)
|
|
697
|
+
throw new Error("venueProducts 模块未初始化");
|
|
698
|
+
if (!this.store.addonProducts)
|
|
699
|
+
throw new Error("addonProducts 模块未初始化");
|
|
750
700
|
await this.loadOpenDataConfig();
|
|
751
|
-
const associatedMenus = this.otherParams
|
|
701
|
+
const associatedMenus = ((_b = (_a = this.otherParams) == null ? void 0 : _a.openData) == null ? void 0 : _b["menu.associated_menus"]) || [];
|
|
752
702
|
if (!associatedMenus.length) {
|
|
753
|
-
this.logMethodError(
|
|
754
|
-
throw new Error(
|
|
703
|
+
this.logMethodError("loadAllProducts", new Error("未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置"));
|
|
704
|
+
throw new Error("未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置");
|
|
755
705
|
}
|
|
756
|
-
const menuListIds = associatedMenus.map(n => Number(n.value));
|
|
706
|
+
const menuListIds = associatedMenus.map((n) => Number(n.value));
|
|
757
707
|
const allProducts = await this.store.venueProducts.loadProducts({
|
|
758
708
|
menu_list_ids: menuListIds,
|
|
759
709
|
cacheId: this.cacheId,
|
|
760
|
-
schedule_date: (0,
|
|
761
|
-
schedule_datetime: (0,
|
|
762
|
-
with_extra: ['dataVariants']
|
|
710
|
+
schedule_date: (0, import_dayjs.default)().format("YYYY-MM-DD"),
|
|
711
|
+
schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
763
712
|
});
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
this.clearSlotPriceMapCache();
|
|
769
|
-
const venueList = list.filter(p => p.duration != null);
|
|
770
|
-
const addonList = list.filter(p => p.duration == null);
|
|
771
|
-
const venueStore = this.store.venueProducts?.store;
|
|
713
|
+
const list = Array.isArray(allProducts) ? allProducts : [];
|
|
714
|
+
const venueList = list.filter((p) => p.duration != null);
|
|
715
|
+
const addonList = list.filter((p) => p.duration == null);
|
|
716
|
+
const venueStore = (_c = this.store.venueProducts) == null ? void 0 : _c.store;
|
|
772
717
|
if (venueStore) {
|
|
773
718
|
venueStore.list = venueList.slice().sort((a, b) => Number(b.sort) - Number(a.sort));
|
|
774
719
|
}
|
|
775
720
|
this.store.addonProducts.addProduct(addonList);
|
|
776
|
-
this.resourceProductMap = (0,
|
|
777
|
-
|
|
778
|
-
// 加载 holder 表单
|
|
721
|
+
this.resourceProductMap = (0, import_resource.buildResourceProductMap)(venueList);
|
|
779
722
|
if (this.store.order) {
|
|
780
|
-
const products = this.store.order
|
|
723
|
+
const products = ((_e = (_d = this.store.order) == null ? void 0 : _d.getOrderProducts) == null ? void 0 : _e.call(_d)) || [];
|
|
781
724
|
await this.preloadHolderForms(products);
|
|
782
725
|
}
|
|
783
726
|
this.productsLoaded = true;
|
|
784
|
-
this.logMethodSuccess(
|
|
727
|
+
this.logMethodSuccess("loadAllProducts", {
|
|
785
728
|
total: list.length,
|
|
786
729
|
venueCount: venueList.length,
|
|
787
730
|
addonCount: addonList.length,
|
|
788
731
|
resourceCount: this.resourceProductMap.size
|
|
789
732
|
});
|
|
790
|
-
return {
|
|
791
|
-
venueProducts: venueList,
|
|
792
|
-
addonProducts: addonList
|
|
793
|
-
};
|
|
733
|
+
return { venueProducts: venueList, addonProducts: addonList };
|
|
794
734
|
} catch (error) {
|
|
795
|
-
this.logMethodError(
|
|
735
|
+
this.logMethodError("loadAllProducts", error);
|
|
796
736
|
throw error;
|
|
797
737
|
}
|
|
798
738
|
}
|
|
@@ -805,55 +745,49 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
805
745
|
return result.addonProducts;
|
|
806
746
|
}
|
|
807
747
|
getVenueProducts() {
|
|
808
|
-
|
|
748
|
+
var _a, _b;
|
|
749
|
+
return ((_b = (_a = this.store.venueProducts) == null ? void 0 : _a.store) == null ? void 0 : _b.list) || [];
|
|
809
750
|
}
|
|
810
751
|
getAddonProductsList() {
|
|
811
|
-
|
|
752
|
+
var _a, _b;
|
|
753
|
+
return ((_b = (_a = this.store.addonProducts) == null ? void 0 : _a.store) == null ? void 0 : _b.list) || [];
|
|
812
754
|
}
|
|
813
|
-
|
|
814
755
|
// ─── 报价单 ───
|
|
815
|
-
|
|
816
756
|
async loadQuotations(params) {
|
|
817
|
-
this.logMethodStart(
|
|
757
|
+
this.logMethodStart("loadQuotations");
|
|
818
758
|
try {
|
|
819
|
-
if (!this.store.quotation)
|
|
759
|
+
if (!this.store.quotation)
|
|
760
|
+
throw new Error("quotation 模块未初始化");
|
|
820
761
|
await this.store.quotation.loadQuotations(params);
|
|
821
|
-
this.logMethodSuccess(
|
|
762
|
+
this.logMethodSuccess("loadQuotations", {
|
|
822
763
|
count: this.store.quotation.getQuotationList().length
|
|
823
764
|
});
|
|
824
765
|
} catch (error) {
|
|
825
|
-
this.logMethodError(
|
|
766
|
+
this.logMethodError("loadQuotations", error);
|
|
826
767
|
throw error;
|
|
827
768
|
}
|
|
828
769
|
}
|
|
829
|
-
|
|
830
770
|
// ─── 资源可用性 ───
|
|
831
|
-
|
|
832
771
|
async fetchResourceAvailability(params) {
|
|
833
|
-
this.logMethodStart(
|
|
772
|
+
this.logMethodStart("fetchResourceAvailability", params);
|
|
834
773
|
try {
|
|
835
774
|
const venueProducts = this.getVenueProducts();
|
|
836
775
|
if (!venueProducts.length) {
|
|
837
776
|
this.store.rawResourceData = [];
|
|
838
|
-
this.logMethodSuccess(
|
|
839
|
-
resourceCount: 0
|
|
840
|
-
});
|
|
777
|
+
this.logMethodSuccess("fetchResourceAvailability", { resourceCount: 0 });
|
|
841
778
|
return;
|
|
842
779
|
}
|
|
843
|
-
const resourceIds = (0,
|
|
780
|
+
const resourceIds = (0, import_resource.extractResourceIds)(venueProducts);
|
|
844
781
|
if (!resourceIds.length) {
|
|
845
782
|
this.store.rawResourceData = [];
|
|
846
|
-
this.logMethodSuccess(
|
|
847
|
-
resourceIds: []
|
|
848
|
-
});
|
|
783
|
+
this.logMethodSuccess("fetchResourceAvailability", { resourceIds: [] });
|
|
849
784
|
return;
|
|
850
785
|
}
|
|
851
|
-
|
|
852
|
-
// 跨天营业时,endDate 扩展一天以覆盖次日凌晨时段
|
|
853
786
|
const config = this.store.slotConfig;
|
|
854
|
-
const crossDay = (0,
|
|
855
|
-
const effectiveEndDate = crossDay ? (0,
|
|
856
|
-
if (!this.store.date)
|
|
787
|
+
const crossDay = (0, import_timeSlot.isBusinessHoursCrossDay)(config);
|
|
788
|
+
const effectiveEndDate = crossDay ? (0, import_dayjs.default)(params.endDate).add(1, "day").format("YYYY-MM-DD") : params.endDate;
|
|
789
|
+
if (!this.store.date)
|
|
790
|
+
throw new Error("date 模块未初始化");
|
|
857
791
|
const res = await this.store.date.fetchResourceDates({
|
|
858
792
|
query: {
|
|
859
793
|
start_date: params.startDate,
|
|
@@ -863,7 +797,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
863
797
|
useCache: false
|
|
864
798
|
});
|
|
865
799
|
const rawData = [];
|
|
866
|
-
if (res
|
|
800
|
+
if ((res == null ? void 0 : res.data) && Array.isArray(res.data)) {
|
|
867
801
|
for (const item of res.data) {
|
|
868
802
|
rawData.push({
|
|
869
803
|
resourceId: item.id,
|
|
@@ -876,49 +810,63 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
876
810
|
this.store.rawResourceData = rawData;
|
|
877
811
|
for (const item of rawData) {
|
|
878
812
|
const mappings = this.resourceProductMap.get(item.resourceId);
|
|
879
|
-
if (!mappings)
|
|
813
|
+
if (!mappings)
|
|
814
|
+
continue;
|
|
880
815
|
for (const mapping of mappings) {
|
|
881
|
-
if (item.main_field)
|
|
882
|
-
|
|
816
|
+
if (item.main_field)
|
|
817
|
+
mapping.resourceName = item.main_field;
|
|
818
|
+
if (item.resource_form_id)
|
|
819
|
+
mapping.formId = item.resource_form_id;
|
|
883
820
|
}
|
|
884
821
|
}
|
|
885
|
-
this.logMethodSuccess(
|
|
822
|
+
this.logMethodSuccess("fetchResourceAvailability", {
|
|
886
823
|
resourceCount: rawData.length,
|
|
887
824
|
totalTimes: rawData.reduce((sum, r) => sum + r.times.length, 0)
|
|
888
825
|
});
|
|
889
826
|
} catch (error) {
|
|
890
827
|
this.store.rawResourceData = [];
|
|
891
|
-
this.logMethodError(
|
|
828
|
+
this.logMethodError("fetchResourceAvailability", error);
|
|
892
829
|
throw error;
|
|
893
830
|
}
|
|
894
831
|
}
|
|
895
|
-
|
|
896
832
|
// ─── 日期概览 & 时间槽矩阵(纯计算,不发请求) ───
|
|
897
|
-
|
|
898
833
|
getOperatingHoursScheduleIds() {
|
|
899
|
-
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
834
|
+
var _a, _b;
|
|
835
|
+
const openData = this.otherParams.openData || ((_b = (_a = this.store.openData) == null ? void 0 : _a.getOpenData) == null ? void 0 : _b.call(_a)) || null;
|
|
836
|
+
const rawIds = openData == null ? void 0 : openData["availability.operating_hours"];
|
|
837
|
+
if (!Array.isArray(rawIds))
|
|
838
|
+
return [];
|
|
839
|
+
return [...new Set(
|
|
840
|
+
rawIds.map((id) => Number(id)).filter((id) => Number.isFinite(id) && id > 0).map((id) => Math.floor(id))
|
|
841
|
+
)];
|
|
903
842
|
}
|
|
904
843
|
resolveSlotConfigForDate(date) {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
844
|
+
var _a;
|
|
845
|
+
const nextSlotConfig = { ...this.baseSlotConfig };
|
|
846
|
+
if (!date || !this.store.schedule)
|
|
847
|
+
return nextSlotConfig;
|
|
909
848
|
const operatingHoursScheduleIds = this.getOperatingHoursScheduleIds();
|
|
910
|
-
if (!operatingHoursScheduleIds.length)
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
849
|
+
if (!operatingHoursScheduleIds.length)
|
|
850
|
+
return nextSlotConfig;
|
|
851
|
+
const scheduleList = this.store.schedule.getScheduleListByIds(
|
|
852
|
+
operatingHoursScheduleIds
|
|
853
|
+
);
|
|
854
|
+
if (!scheduleList.length)
|
|
855
|
+
return nextSlotConfig;
|
|
856
|
+
const timeRangeMap = (0, import_utils2.calcMinTimeMaxTimeBySchedules)(
|
|
857
|
+
scheduleList,
|
|
858
|
+
void 0,
|
|
859
|
+
date
|
|
860
|
+
);
|
|
914
861
|
let earliestStart = null;
|
|
915
862
|
let latestEnd = null;
|
|
916
863
|
for (const schedule of scheduleList) {
|
|
917
|
-
const dateRangeList = timeRangeMap
|
|
864
|
+
const dateRangeList = ((_a = timeRangeMap == null ? void 0 : timeRangeMap[schedule.id]) == null ? void 0 : _a.dateRangeFormat) || [];
|
|
918
865
|
for (const range of dateRangeList) {
|
|
919
|
-
const start = (0,
|
|
920
|
-
const end = (0,
|
|
921
|
-
if (!start.isValid() || !end.isValid())
|
|
866
|
+
const start = (0, import_dayjs.default)(range == null ? void 0 : range.start);
|
|
867
|
+
const end = (0, import_dayjs.default)(range == null ? void 0 : range.end);
|
|
868
|
+
if (!start.isValid() || !end.isValid())
|
|
869
|
+
continue;
|
|
922
870
|
if (!earliestStart || start.isBefore(earliestStart)) {
|
|
923
871
|
earliestStart = start;
|
|
924
872
|
}
|
|
@@ -927,11 +875,12 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
927
875
|
}
|
|
928
876
|
}
|
|
929
877
|
}
|
|
930
|
-
if (!earliestStart || !latestEnd)
|
|
878
|
+
if (!earliestStart || !latestEnd)
|
|
879
|
+
return nextSlotConfig;
|
|
931
880
|
return {
|
|
932
881
|
...nextSlotConfig,
|
|
933
|
-
businessStartTime: earliestStart.format(
|
|
934
|
-
businessEndTime: latestEnd.format(
|
|
882
|
+
businessStartTime: earliestStart.format("HH:mm"),
|
|
883
|
+
businessEndTime: latestEnd.format("HH:mm")
|
|
935
884
|
};
|
|
936
885
|
}
|
|
937
886
|
syncOperatingHoursToSlotConfig(date) {
|
|
@@ -940,31 +889,38 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
940
889
|
return resolvedSlotConfig;
|
|
941
890
|
}
|
|
942
891
|
getDateRangeSummary(params) {
|
|
943
|
-
return (0,
|
|
892
|
+
return (0, import_dateSummary.buildDateRangeSummary)({
|
|
944
893
|
startDate: params.startDate,
|
|
945
894
|
endDate: params.endDate,
|
|
946
895
|
config: this.baseSlotConfig,
|
|
947
896
|
rawResources: this.store.rawResourceData,
|
|
948
897
|
resourceProductMap: this.resourceProductMap,
|
|
949
|
-
|
|
950
|
-
|
|
898
|
+
quotationModule: this.store.quotation,
|
|
899
|
+
resolveConfig: (date) => this.resolveSlotConfigForDate(date)
|
|
951
900
|
});
|
|
952
901
|
}
|
|
953
902
|
getTimeSlotGrid(date) {
|
|
954
903
|
const resolvedSlotConfig = this.syncOperatingHoursToSlotConfig(date);
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
904
|
+
let quotationPriceMap;
|
|
905
|
+
if (this.store.quotation) {
|
|
906
|
+
const productIds = [
|
|
907
|
+
...new Set(
|
|
908
|
+
[...this.resourceProductMap.values()].flat().map((m) => m.productId)
|
|
909
|
+
)
|
|
910
|
+
];
|
|
911
|
+
const timeLabels = (0, import_timeSlot.generateTimeLabels)(resolvedSlotConfig);
|
|
912
|
+
const timePoints = timeLabels.map((label) => `${date} ${label}`);
|
|
913
|
+
quotationPriceMap = this.store.quotation.buildProductPriceMap({ productIds, timePoints });
|
|
914
|
+
}
|
|
915
|
+
return (0, import_timeSlot.buildTimeSlotGrid)({
|
|
958
916
|
date,
|
|
959
917
|
config: resolvedSlotConfig,
|
|
960
918
|
rawResources: this.store.rawResourceData,
|
|
961
919
|
resourceProductMap: this.resourceProductMap,
|
|
962
|
-
|
|
920
|
+
quotationPriceMap
|
|
963
921
|
});
|
|
964
922
|
}
|
|
965
|
-
|
|
966
923
|
// ─── 时间槽订单操作 ───
|
|
967
|
-
|
|
968
924
|
/**
|
|
969
925
|
* 切换单个时段的选中状态(选中/取消)。
|
|
970
926
|
* 内部自动处理连续时段的合并与拆分,订单是唯一真相源。
|
|
@@ -973,7 +929,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
973
929
|
* 同一资源下不同 productId 之间互相隔离,不会相互合并。
|
|
974
930
|
*/
|
|
975
931
|
async toggleSlot(slot) {
|
|
976
|
-
this.logMethodStart(
|
|
932
|
+
this.logMethodStart("toggleSlot", {
|
|
977
933
|
resourceId: slot.resourceId,
|
|
978
934
|
productId: slot.productId,
|
|
979
935
|
startTime: slot.startTime
|
|
@@ -983,73 +939,85 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
983
939
|
if (!mappings || !mappings.length) {
|
|
984
940
|
throw new Error(`未找到资源 ${slot.resourceId} 的商品映射`);
|
|
985
941
|
}
|
|
986
|
-
const mapping = mappings.find(m => m.productId === slot.productId);
|
|
942
|
+
const mapping = mappings.find((m) => m.productId === slot.productId);
|
|
987
943
|
if (!mapping) {
|
|
988
944
|
throw new Error(`资源 ${slot.resourceId} 未关联商品 ${slot.productId}`);
|
|
989
945
|
}
|
|
990
|
-
if (!this.store.order)
|
|
991
|
-
|
|
992
|
-
const
|
|
946
|
+
if (!this.store.order)
|
|
947
|
+
throw new Error("order 模块未初始化");
|
|
948
|
+
const currentSlots = this.getSelectedSlotsForResourceProduct(
|
|
949
|
+
slot.resourceId,
|
|
950
|
+
slot.productId
|
|
951
|
+
);
|
|
952
|
+
const existIndex = currentSlots.findIndex((s) => s.startTime === slot.startTime);
|
|
993
953
|
let nextSlots;
|
|
994
954
|
if (existIndex !== -1) {
|
|
995
955
|
nextSlots = currentSlots.filter((_, i) => i !== existIndex);
|
|
996
956
|
} else {
|
|
997
957
|
nextSlots = [...currentSlots, slot];
|
|
998
958
|
}
|
|
999
|
-
await this.reconcileOrderForResourceProduct(
|
|
959
|
+
await this.reconcileOrderForResourceProduct(
|
|
960
|
+
slot.resourceId,
|
|
961
|
+
slot.productId,
|
|
962
|
+
nextSlots
|
|
963
|
+
);
|
|
1000
964
|
const products = this.store.order.getOrderProducts();
|
|
1001
965
|
await this.refreshItemRuleQuantityLimits();
|
|
1002
966
|
await this.refreshCartValidationPassed();
|
|
1003
|
-
this.logMethodSuccess(
|
|
1004
|
-
action: existIndex !== -1 ?
|
|
967
|
+
this.logMethodSuccess("toggleSlot", {
|
|
968
|
+
action: existIndex !== -1 ? "remove" : "add",
|
|
1005
969
|
resourceId: slot.resourceId,
|
|
1006
970
|
productId: slot.productId,
|
|
1007
971
|
slotCount: nextSlots.length
|
|
1008
972
|
});
|
|
1009
973
|
return products;
|
|
1010
974
|
} catch (error) {
|
|
1011
|
-
this.logMethodError(
|
|
975
|
+
this.logMethodError("toggleSlot", error);
|
|
1012
976
|
throw error;
|
|
1013
977
|
}
|
|
1014
978
|
}
|
|
1015
|
-
|
|
1016
979
|
/**
|
|
1017
980
|
* 获取某资源当前选中的所有独立时段(从订单中解析)。
|
|
1018
981
|
* 不传 productId 时返回该资源下所有商品的选中时段;传了则精确匹配。
|
|
1019
982
|
*/
|
|
1020
983
|
getSelectedSlotsForResource(resourceId, productId) {
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
984
|
+
var _a;
|
|
985
|
+
const tempOrder = (_a = this.store.order) == null ? void 0 : _a.getTempOrder();
|
|
986
|
+
if (!tempOrder)
|
|
987
|
+
return [];
|
|
988
|
+
const venueProducts = tempOrder.products.filter((p) => {
|
|
989
|
+
var _a2, _b;
|
|
990
|
+
if (!((_a2 = p.metadata) == null ? void 0 : _a2.venue_booking))
|
|
991
|
+
return false;
|
|
992
|
+
if (String((_b = p.metadata) == null ? void 0 : _b.resource_id) !== String(resourceId))
|
|
993
|
+
return false;
|
|
994
|
+
if (productId != null && Number(p.product_id) !== Number(productId))
|
|
995
|
+
return false;
|
|
1027
996
|
return true;
|
|
1028
997
|
});
|
|
1029
998
|
const slotDuration = this.store.slotConfig.slotDurationMinutes;
|
|
1030
999
|
const slots = [];
|
|
1031
1000
|
for (const product of venueProducts) {
|
|
1032
|
-
slots.push(
|
|
1033
|
-
...s
|
|
1034
|
-
|
|
1035
|
-
|
|
1001
|
+
slots.push(
|
|
1002
|
+
...(0, import_slotMerge.expandMergedSlotToIndividual)(product, slotDuration).map((s) => ({
|
|
1003
|
+
...s,
|
|
1004
|
+
productId: Number(product.product_id)
|
|
1005
|
+
}))
|
|
1006
|
+
);
|
|
1036
1007
|
}
|
|
1037
1008
|
return slots.sort((a, b) => a.startTime.localeCompare(b.startTime));
|
|
1038
1009
|
}
|
|
1039
|
-
|
|
1040
1010
|
/** getSelectedSlotsForResource 的 (resourceId, productId) 精确版,内部使用。 */
|
|
1041
1011
|
getSelectedSlotsForResourceProduct(resourceId, productId) {
|
|
1042
1012
|
return this.getSelectedSlotsForResource(resourceId, productId);
|
|
1043
1013
|
}
|
|
1044
|
-
|
|
1045
1014
|
/**
|
|
1046
1015
|
* 判断某个时段是否已选中。
|
|
1047
1016
|
* 不传 productId 时:只要该资源下任一商品在 startTime 被选中即返回 true;传了则精确匹配。
|
|
1048
1017
|
*/
|
|
1049
1018
|
isSlotSelected(resourceId, startTime, productId) {
|
|
1050
|
-
return this.getSelectedSlotsForResource(resourceId, productId).some(s => s.startTime === startTime);
|
|
1019
|
+
return this.getSelectedSlotsForResource(resourceId, productId).some((s) => s.startTime === startTime);
|
|
1051
1020
|
}
|
|
1052
|
-
|
|
1053
1021
|
/**
|
|
1054
1022
|
* 判断指定 (resourceId, productId, startTime) 格子是否应因其它已选项而被禁用。
|
|
1055
1023
|
* 规则:
|
|
@@ -1059,27 +1027,21 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1059
1027
|
* 4) 两个组合资源的 child 集合有交集,且对方在该 startTime 被选中 → 禁用
|
|
1060
1028
|
*/
|
|
1061
1029
|
isSlotDisabledBySelection(params) {
|
|
1062
|
-
const {
|
|
1063
|
-
resourceId,
|
|
1064
|
-
productId,
|
|
1065
|
-
startTime
|
|
1066
|
-
} = params;
|
|
1030
|
+
const { resourceId, productId, startTime } = params;
|
|
1067
1031
|
const allSelected = this.getAllSelectedSlots();
|
|
1068
|
-
const getSelectedAt = resId => {
|
|
1032
|
+
const getSelectedAt = (resId) => {
|
|
1069
1033
|
const list = allSelected.get(resId) || [];
|
|
1070
|
-
return list.filter(s => s.startTime === startTime);
|
|
1034
|
+
return list.filter((s) => s.startTime === startTime);
|
|
1071
1035
|
};
|
|
1072
|
-
|
|
1073
|
-
// 规则 1:同场地、不同 productId 的已选
|
|
1074
1036
|
const sameResourceSelections = getSelectedAt(resourceId);
|
|
1075
|
-
if (sameResourceSelections.some(s => Number(s.productId) !== Number(productId))) {
|
|
1037
|
+
if (sameResourceSelections.some((s) => Number(s.productId) !== Number(productId))) {
|
|
1076
1038
|
return true;
|
|
1077
1039
|
}
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
const combined = raw
|
|
1040
|
+
const getCombinedChildIds = (resId) => {
|
|
1041
|
+
const raw = this.store.rawResourceData.find(
|
|
1042
|
+
(r) => String(r.resourceId) === String(resId)
|
|
1043
|
+
);
|
|
1044
|
+
const combined = raw == null ? void 0 : raw.combined_resource;
|
|
1083
1045
|
if (combined && combined.status === 1 && Array.isArray(combined.resource_ids)) {
|
|
1084
1046
|
return combined.resource_ids;
|
|
1085
1047
|
}
|
|
@@ -1087,53 +1049,59 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1087
1049
|
};
|
|
1088
1050
|
const currentChildIds = getCombinedChildIds(resourceId);
|
|
1089
1051
|
const currentIsCombined = currentChildIds.length > 0;
|
|
1090
|
-
|
|
1091
|
-
// 规则 2:当前是组合资源,任一子资源被选 → 禁用
|
|
1092
1052
|
if (currentIsCombined) {
|
|
1093
1053
|
for (const childId of currentChildIds) {
|
|
1094
|
-
if (getSelectedAt(childId).length > 0)
|
|
1054
|
+
if (getSelectedAt(childId).length > 0)
|
|
1055
|
+
return true;
|
|
1095
1056
|
}
|
|
1096
1057
|
}
|
|
1097
|
-
|
|
1098
|
-
// 规则 3 & 4:扫描所有已选的 (resId),若是组合资源,检查其 children 是否包含当前 resourceId 或与当前 child 集合有交集
|
|
1099
1058
|
for (const [selectedResId, slots] of allSelected) {
|
|
1100
|
-
if (!slots.some(s => s.startTime === startTime))
|
|
1101
|
-
|
|
1059
|
+
if (!slots.some((s) => s.startTime === startTime))
|
|
1060
|
+
continue;
|
|
1061
|
+
if (String(selectedResId) === String(resourceId))
|
|
1062
|
+
continue;
|
|
1102
1063
|
const selectedChildIds = getCombinedChildIds(selectedResId);
|
|
1103
|
-
if (selectedChildIds.length === 0)
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
if (selectedChildIds.some(id => String(id) === String(resourceId))) {
|
|
1064
|
+
if (selectedChildIds.length === 0)
|
|
1065
|
+
continue;
|
|
1066
|
+
if (selectedChildIds.some((id) => String(id) === String(resourceId))) {
|
|
1107
1067
|
return true;
|
|
1108
1068
|
}
|
|
1109
|
-
|
|
1110
|
-
// 双方都是组合资源,child 集合有交集(规则 4)
|
|
1111
1069
|
if (currentIsCombined) {
|
|
1112
|
-
const intersect = selectedChildIds.some(
|
|
1113
|
-
|
|
1070
|
+
const intersect = selectedChildIds.some(
|
|
1071
|
+
(id) => currentChildIds.some((cid) => String(cid) === String(id))
|
|
1072
|
+
);
|
|
1073
|
+
if (intersect)
|
|
1074
|
+
return true;
|
|
1114
1075
|
}
|
|
1115
1076
|
}
|
|
1116
1077
|
return false;
|
|
1117
1078
|
}
|
|
1118
|
-
|
|
1119
1079
|
/**
|
|
1120
1080
|
* 获取所有已选时段(按资源分组)。每个 slot 上带 productId,便于 UI 做 per-product 判定。
|
|
1121
1081
|
*/
|
|
1122
1082
|
getAllSelectedSlots() {
|
|
1123
|
-
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1126
|
-
|
|
1083
|
+
var _a, _b;
|
|
1084
|
+
const result = /* @__PURE__ */ new Map();
|
|
1085
|
+
const tempOrder = (_a = this.store.order) == null ? void 0 : _a.getTempOrder();
|
|
1086
|
+
if (!tempOrder)
|
|
1087
|
+
return result;
|
|
1088
|
+
const venueProducts = tempOrder.products.filter((p) => {
|
|
1089
|
+
var _a2;
|
|
1090
|
+
return (_a2 = p.metadata) == null ? void 0 : _a2.venue_booking;
|
|
1091
|
+
});
|
|
1127
1092
|
const slotDuration = this.store.slotConfig.slotDurationMinutes;
|
|
1128
1093
|
for (const product of venueProducts) {
|
|
1129
|
-
const resourceId = product.metadata
|
|
1130
|
-
if (resourceId == null)
|
|
1094
|
+
const resourceId = (_b = product.metadata) == null ? void 0 : _b.resource_id;
|
|
1095
|
+
if (resourceId == null)
|
|
1096
|
+
continue;
|
|
1131
1097
|
const productId = Number(product.product_id);
|
|
1132
1098
|
const existing = result.get(resourceId) || [];
|
|
1133
|
-
existing.push(
|
|
1134
|
-
...s
|
|
1135
|
-
|
|
1136
|
-
|
|
1099
|
+
existing.push(
|
|
1100
|
+
...(0, import_slotMerge.expandMergedSlotToIndividual)(product, slotDuration).map((s) => ({
|
|
1101
|
+
...s,
|
|
1102
|
+
productId
|
|
1103
|
+
}))
|
|
1104
|
+
);
|
|
1137
1105
|
result.set(resourceId, existing);
|
|
1138
1106
|
}
|
|
1139
1107
|
for (const [key, slots] of result) {
|
|
@@ -1141,68 +1109,75 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1141
1109
|
}
|
|
1142
1110
|
return result;
|
|
1143
1111
|
}
|
|
1144
|
-
|
|
1145
1112
|
/**
|
|
1146
1113
|
* 对指定 (resourceId, productId) 的订单商品进行 reconcile:
|
|
1147
1114
|
* 清除旧商品 → 合并连续时段 → 重新写入。
|
|
1148
1115
|
* 同一场地下不同商品互不干扰,各自单独 reconcile。
|
|
1149
1116
|
*/
|
|
1150
1117
|
async reconcileOrderForResourceProduct(resourceId, productId, slots) {
|
|
1118
|
+
var _a, _b;
|
|
1151
1119
|
const mappings = this.resourceProductMap.get(resourceId);
|
|
1152
|
-
if (!mappings || !mappings.length || !this.store.order)
|
|
1153
|
-
|
|
1154
|
-
|
|
1120
|
+
if (!mappings || !mappings.length || !this.store.order)
|
|
1121
|
+
return;
|
|
1122
|
+
const mapping = mappings.find((m) => m.productId === productId);
|
|
1123
|
+
if (!mapping)
|
|
1124
|
+
return;
|
|
1155
1125
|
const tempOrder = this.store.order.ensureTempOrder();
|
|
1156
|
-
const matchesCurrent = (meta, pid) => !!meta
|
|
1157
|
-
tempOrder.products = tempOrder.products.filter(
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1126
|
+
const matchesCurrent = (meta, pid) => !!(meta == null ? void 0 : meta.venue_booking) && String(meta == null ? void 0 : meta.resource_id) === String(resourceId) && Number(pid) === Number(productId);
|
|
1127
|
+
tempOrder.products = tempOrder.products.filter(
|
|
1128
|
+
(p) => !matchesCurrent(p.metadata, p.product_id)
|
|
1129
|
+
);
|
|
1130
|
+
tempOrder.bookings = (tempOrder.bookings || []).filter(
|
|
1131
|
+
(b) => {
|
|
1132
|
+
var _a2, _b2, _c, _d;
|
|
1133
|
+
if (!((_a2 = b.metadata) == null ? void 0 : _a2.venue_booking))
|
|
1134
|
+
return true;
|
|
1135
|
+
if (String((_b2 = b.metadata) == null ? void 0 : _b2.resource_id) !== String(resourceId))
|
|
1136
|
+
return true;
|
|
1137
|
+
const bookingProductId = ((_c = b.metadata) == null ? void 0 : _c.product_id) ?? ((_d = b == null ? void 0 : b.product) == null ? void 0 : _d.product_id);
|
|
1138
|
+
if (bookingProductId == null)
|
|
1139
|
+
return false;
|
|
1140
|
+
return Number(bookingProductId) !== Number(productId);
|
|
1141
|
+
}
|
|
1142
|
+
);
|
|
1165
1143
|
if (!slots.length) {
|
|
1166
1144
|
this.store.order.applyDiscount();
|
|
1167
|
-
await this.store.order.recalculateSummary({
|
|
1168
|
-
createIfMissing: true
|
|
1169
|
-
});
|
|
1145
|
+
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
1170
1146
|
this.store.order.persistTempOrder();
|
|
1171
1147
|
return;
|
|
1172
1148
|
}
|
|
1173
|
-
const merged = (0,
|
|
1174
|
-
const rawResource = this.store.rawResourceData.find(
|
|
1149
|
+
const merged = (0, import_slotMerge.mergeConsecutiveSlots)(slots);
|
|
1150
|
+
const rawResource = this.store.rawResourceData.find(
|
|
1151
|
+
(r) => String(r.resourceId) === String(resourceId)
|
|
1152
|
+
);
|
|
1175
1153
|
const childRawResources = this.getCombinedChildRawResources(rawResource);
|
|
1176
|
-
const venueProduct = this.getVenueProducts().find(p => p.id === mapping.productId);
|
|
1154
|
+
const venueProduct = this.getVenueProducts().find((p) => p.id === mapping.productId);
|
|
1177
1155
|
tempOrder.bookings = tempOrder.bookings || [];
|
|
1178
1156
|
for (let i = 0; i < merged.length; i++) {
|
|
1179
1157
|
const group = merged[i];
|
|
1180
|
-
const identityKey = (0,
|
|
1181
|
-
const bookingUuid = (0,
|
|
1182
|
-
const startMoment = (0,
|
|
1183
|
-
const endMoment = (0,
|
|
1184
|
-
const duration = endMoment.diff(startMoment,
|
|
1185
|
-
const customDepositData = cloneCustomDepositData(venueProduct
|
|
1186
|
-
const productTitle = this.normalizeVenueProductTitle(venueProduct
|
|
1158
|
+
const identityKey = (0, import_slotMerge.buildVenueIdentityKey)(resourceId, i);
|
|
1159
|
+
const bookingUuid = (0, import_utils3.createUuidV4)();
|
|
1160
|
+
const startMoment = (0, import_dayjs.default)(group.startTime, "YYYY-MM-DD HH:mm");
|
|
1161
|
+
const endMoment = (0, import_dayjs.default)(group.endTime, "YYYY-MM-DD HH:mm");
|
|
1162
|
+
const duration = endMoment.diff(startMoment, "minute");
|
|
1163
|
+
const customDepositData = cloneCustomDepositData(venueProduct == null ? void 0 : venueProduct.custom_deposit_data);
|
|
1164
|
+
const productTitle = this.normalizeVenueProductTitle(venueProduct == null ? void 0 : venueProduct.product_title) || this.normalizeVenueProductTitle(venueProduct == null ? void 0 : venueProduct.title) || this.normalizeVenueProductTitle(mapping.productTitle);
|
|
1187
1165
|
const resourceEntry = {
|
|
1188
|
-
relation_type:
|
|
1189
|
-
like_status:
|
|
1166
|
+
relation_type: "form",
|
|
1167
|
+
like_status: "common",
|
|
1190
1168
|
id: resourceId,
|
|
1191
1169
|
main_field: mapping.resourceName,
|
|
1192
|
-
form_id: rawResource
|
|
1170
|
+
form_id: (rawResource == null ? void 0 : rawResource.form_id) ?? mapping.formId,
|
|
1193
1171
|
relation_id: resourceId,
|
|
1194
1172
|
capacity: 1,
|
|
1195
|
-
metadata: (0,
|
|
1196
|
-
mapping,
|
|
1197
|
-
rawResource
|
|
1198
|
-
})
|
|
1173
|
+
metadata: (0, import_slotMerge.buildVenueResourceMetadata)({ mapping, rawResource })
|
|
1199
1174
|
};
|
|
1200
1175
|
if (childRawResources && childRawResources.length) {
|
|
1201
|
-
resourceEntry.children = childRawResources.map(child => ({
|
|
1202
|
-
relation_type:
|
|
1203
|
-
like_status:
|
|
1176
|
+
resourceEntry.children = childRawResources.map((child) => ({
|
|
1177
|
+
relation_type: "form",
|
|
1178
|
+
like_status: "common",
|
|
1204
1179
|
id: child.resourceId,
|
|
1205
|
-
main_field: child.main_field ||
|
|
1180
|
+
main_field: child.main_field || "",
|
|
1206
1181
|
form_id: child.form_id ?? child.formId,
|
|
1207
1182
|
relation_id: child.resourceId,
|
|
1208
1183
|
capacity: child.capacity ?? 1,
|
|
@@ -1212,11 +1187,11 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1212
1187
|
const venueProductOrigin = {
|
|
1213
1188
|
name: mapping.productTitle,
|
|
1214
1189
|
product_title: productTitle,
|
|
1215
|
-
cover: venueProduct
|
|
1190
|
+
cover: (venueProduct == null ? void 0 : venueProduct.cover) || "",
|
|
1216
1191
|
custom_deposit_data: customDepositData,
|
|
1217
1192
|
id: 0,
|
|
1218
1193
|
number: 1,
|
|
1219
|
-
registration_type:
|
|
1194
|
+
registration_type: "all",
|
|
1220
1195
|
relation_products: [],
|
|
1221
1196
|
is_all: false,
|
|
1222
1197
|
product: {
|
|
@@ -1224,42 +1199,38 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1224
1199
|
product_variant_id: 0,
|
|
1225
1200
|
num: 1,
|
|
1226
1201
|
product_bundle: [],
|
|
1227
|
-
product_sku: {
|
|
1228
|
-
option: []
|
|
1229
|
-
},
|
|
1202
|
+
product_sku: { option: [] },
|
|
1230
1203
|
discount_list: [],
|
|
1231
1204
|
custom_deposit_data: customDepositData,
|
|
1232
1205
|
metadata: {}
|
|
1233
1206
|
},
|
|
1234
|
-
sub_type:
|
|
1207
|
+
sub_type: "minutes",
|
|
1235
1208
|
duration,
|
|
1236
|
-
like_status:
|
|
1209
|
+
like_status: "common",
|
|
1237
1210
|
resources: [resourceEntry],
|
|
1238
1211
|
schedule_id: 0,
|
|
1239
|
-
select_date: startMoment.format(
|
|
1240
|
-
start_date: startMoment.format(
|
|
1241
|
-
start_time: startMoment.format(
|
|
1242
|
-
end_date: endMoment.format(
|
|
1243
|
-
end_time: endMoment.format(
|
|
1212
|
+
select_date: startMoment.format("YYYY-MM-DD"),
|
|
1213
|
+
start_date: startMoment.format("YYYY-MM-DD"),
|
|
1214
|
+
start_time: startMoment.format("HH:mm"),
|
|
1215
|
+
end_date: endMoment.format("YYYY-MM-DD"),
|
|
1216
|
+
end_time: endMoment.format("HH:mm"),
|
|
1244
1217
|
metadata: {
|
|
1245
1218
|
venue_booking: true,
|
|
1246
1219
|
slot_count: group.slotCount
|
|
1247
1220
|
},
|
|
1248
1221
|
holder: null
|
|
1249
1222
|
};
|
|
1250
|
-
const normalizedVenueOrderProduct = (0,
|
|
1223
|
+
const normalizedVenueOrderProduct = (0, import_utils.normalizeOrderProduct)({
|
|
1251
1224
|
product_id: mapping.productId,
|
|
1252
1225
|
product_variant_id: 0,
|
|
1253
1226
|
identity_key: identityKey,
|
|
1254
1227
|
num: 1,
|
|
1255
1228
|
selling_price: group.totalPrice,
|
|
1256
1229
|
original_price: group.totalPrice,
|
|
1257
|
-
is_charge_tax: venueProduct
|
|
1230
|
+
is_charge_tax: (venueProduct == null ? void 0 : venueProduct.is_charge_tax) ?? 0,
|
|
1258
1231
|
metadata: {
|
|
1259
1232
|
venue_booking: true,
|
|
1260
|
-
...
|
|
1261
|
-
product_title: productTitle
|
|
1262
|
-
} : {}),
|
|
1233
|
+
...productTitle ? { product_title: productTitle } : {},
|
|
1263
1234
|
resource_id: resourceId,
|
|
1264
1235
|
resource_form_id: mapping.formId,
|
|
1265
1236
|
resource_name: mapping.resourceName,
|
|
@@ -1267,7 +1238,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1267
1238
|
end_time: group.endTime,
|
|
1268
1239
|
slot_count: group.slotCount,
|
|
1269
1240
|
booking_uid: bookingUuid,
|
|
1270
|
-
price_breakdown: (0,
|
|
1241
|
+
price_breakdown: (0, import_slotMerge.buildPriceBreakdown)({
|
|
1271
1242
|
group,
|
|
1272
1243
|
productId: mapping.productId,
|
|
1273
1244
|
quotation: this.store.quotation
|
|
@@ -1275,13 +1246,10 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1275
1246
|
},
|
|
1276
1247
|
_origin: venueProductOrigin
|
|
1277
1248
|
});
|
|
1278
|
-
const venueOrderProduct = productTitle ? {
|
|
1279
|
-
...normalizedVenueOrderProduct,
|
|
1280
|
-
product_title: productTitle
|
|
1281
|
-
} : normalizedVenueOrderProduct;
|
|
1249
|
+
const venueOrderProduct = productTitle ? { ...normalizedVenueOrderProduct, product_title: productTitle } : normalizedVenueOrderProduct;
|
|
1282
1250
|
this.attachProductOriginToTempOrder(tempOrder, identityKey, venueProductOrigin);
|
|
1283
1251
|
tempOrder.products.push(venueOrderProduct);
|
|
1284
|
-
const booking = (0,
|
|
1252
|
+
const booking = (0, import_slotMerge.buildVenueBookingEntry)({
|
|
1285
1253
|
group,
|
|
1286
1254
|
resourceId,
|
|
1287
1255
|
mapping,
|
|
@@ -1292,34 +1260,31 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1292
1260
|
});
|
|
1293
1261
|
tempOrder.bookings.push(booking);
|
|
1294
1262
|
}
|
|
1295
|
-
|
|
1296
|
-
// 获取表单信息
|
|
1297
|
-
const products = this.store.order?.getOrderProducts?.() || [];
|
|
1263
|
+
const products = ((_b = (_a = this.store.order) == null ? void 0 : _a.getOrderProducts) == null ? void 0 : _b.call(_a)) || [];
|
|
1298
1264
|
await this.preloadHolderForms(products);
|
|
1299
1265
|
this.store.order.applyDiscount();
|
|
1300
|
-
await this.store.order.recalculateSummary({
|
|
1301
|
-
createIfMissing: true
|
|
1302
|
-
});
|
|
1266
|
+
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
1303
1267
|
this.store.order.persistTempOrder();
|
|
1304
1268
|
}
|
|
1305
|
-
|
|
1306
1269
|
/** 给定一个父 rawResource,返回其 combined_resource.resource_ids 对应的子 rawResource 列表。 */
|
|
1307
1270
|
getCombinedChildRawResources(rawResource) {
|
|
1308
|
-
if (!rawResource)
|
|
1271
|
+
if (!rawResource)
|
|
1272
|
+
return void 0;
|
|
1309
1273
|
const combined = rawResource.combined_resource;
|
|
1310
1274
|
if (!combined || combined.status !== 1 || !Array.isArray(combined.resource_ids) || !combined.resource_ids.length) {
|
|
1311
|
-
return
|
|
1275
|
+
return void 0;
|
|
1312
1276
|
}
|
|
1313
1277
|
const children = [];
|
|
1314
1278
|
for (const id of combined.resource_ids) {
|
|
1315
|
-
const child = this.store.rawResourceData.find(
|
|
1316
|
-
|
|
1279
|
+
const child = this.store.rawResourceData.find(
|
|
1280
|
+
(r) => String(r.resourceId) === String(id)
|
|
1281
|
+
);
|
|
1282
|
+
if (child)
|
|
1283
|
+
children.push(child);
|
|
1317
1284
|
}
|
|
1318
|
-
return children.length ? children :
|
|
1285
|
+
return children.length ? children : void 0;
|
|
1319
1286
|
}
|
|
1320
|
-
|
|
1321
1287
|
// ─── 配置 ───
|
|
1322
|
-
|
|
1323
1288
|
setSlotConfig(config) {
|
|
1324
1289
|
this.baseSlotConfig = {
|
|
1325
1290
|
...this.baseSlotConfig,
|
|
@@ -1330,189 +1295,187 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1330
1295
|
};
|
|
1331
1296
|
}
|
|
1332
1297
|
getSlotConfig() {
|
|
1333
|
-
return {
|
|
1334
|
-
...this.store.slotConfig
|
|
1335
|
-
};
|
|
1298
|
+
return { ...this.store.slotConfig };
|
|
1336
1299
|
}
|
|
1337
|
-
|
|
1338
1300
|
// ─── 日程 ───
|
|
1339
|
-
|
|
1340
1301
|
async loadSchedules() {
|
|
1341
|
-
this.logMethodStart(
|
|
1302
|
+
this.logMethodStart("loadSchedules");
|
|
1342
1303
|
try {
|
|
1343
|
-
if (!this.store.schedule)
|
|
1304
|
+
if (!this.store.schedule)
|
|
1305
|
+
throw new Error("schedule 模块未初始化");
|
|
1344
1306
|
await this.store.schedule.loadAllSchedule();
|
|
1345
|
-
this.
|
|
1307
|
+
this.injectScheduleResolverToQuotation();
|
|
1308
|
+
this.logMethodSuccess("loadSchedules");
|
|
1346
1309
|
} catch (error) {
|
|
1347
|
-
this.logMethodError(
|
|
1310
|
+
this.logMethodError("loadSchedules", error);
|
|
1348
1311
|
throw error;
|
|
1349
1312
|
}
|
|
1350
1313
|
}
|
|
1314
|
+
injectScheduleResolverToQuotation() {
|
|
1315
|
+
if (this.store.quotation && this.store.schedule) {
|
|
1316
|
+
this.store.quotation.setScheduleResolver(
|
|
1317
|
+
(id) => this.store.schedule.getScheduleListByIds([id])[0]
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1351
1321
|
getScheduleListByIds(ids) {
|
|
1352
|
-
if (!this.store.schedule)
|
|
1322
|
+
if (!this.store.schedule)
|
|
1323
|
+
return [];
|
|
1353
1324
|
return this.store.schedule.getScheduleListByIds(ids);
|
|
1354
1325
|
}
|
|
1355
|
-
|
|
1356
1326
|
// ─── 临时订单操作(保留原有能力) ───
|
|
1357
|
-
|
|
1358
1327
|
getTempOrder() {
|
|
1359
|
-
|
|
1328
|
+
var _a;
|
|
1329
|
+
const result = ((_a = this.store.order) == null ? void 0 : _a.getTempOrder()) || null;
|
|
1360
1330
|
return result;
|
|
1361
1331
|
}
|
|
1362
1332
|
updateTempOrderNote(note, sync = false) {
|
|
1363
|
-
if (!this.store.order)
|
|
1333
|
+
if (!this.store.order)
|
|
1334
|
+
throw new Error("order 模块未初始化");
|
|
1364
1335
|
return this.store.order.updateTempOrderNote(note, sync);
|
|
1365
1336
|
}
|
|
1366
1337
|
updateTempOrderContactsInfo(contactsInfo) {
|
|
1367
|
-
if (!this.store.order)
|
|
1338
|
+
if (!this.store.order)
|
|
1339
|
+
throw new Error("order 模块未初始化");
|
|
1368
1340
|
return this.store.order.updateTempOrderContactsInfo(contactsInfo);
|
|
1369
1341
|
}
|
|
1370
1342
|
ensureVenueTempOrder() {
|
|
1371
|
-
if (!this.store.order)
|
|
1343
|
+
if (!this.store.order)
|
|
1344
|
+
throw new Error("order 模块未初始化");
|
|
1372
1345
|
return this.store.order.ensureTempOrder();
|
|
1373
1346
|
}
|
|
1374
1347
|
async onCustomerLogin(params) {
|
|
1375
|
-
this.logMethodStart(
|
|
1376
|
-
customerId: params.customerId
|
|
1377
|
-
});
|
|
1348
|
+
this.logMethodStart("onCustomerLogin", { customerId: params.customerId });
|
|
1378
1349
|
try {
|
|
1379
1350
|
await this.refreshOrderMarketingAfterLogin({
|
|
1380
1351
|
customerId: params.customerId
|
|
1381
1352
|
});
|
|
1382
|
-
this.logMethodSuccess(
|
|
1383
|
-
customerId: params.customerId
|
|
1384
|
-
});
|
|
1353
|
+
this.logMethodSuccess("onCustomerLogin", { customerId: params.customerId });
|
|
1385
1354
|
} catch (error) {
|
|
1386
|
-
this.logMethodError(
|
|
1355
|
+
this.logMethodError("onCustomerLogin", error);
|
|
1387
1356
|
throw error;
|
|
1388
1357
|
}
|
|
1389
1358
|
}
|
|
1390
|
-
|
|
1391
|
-
|
|
1359
|
+
recalculateOrderPricesFromQuotation() {
|
|
1360
|
+
var _a, _b;
|
|
1361
|
+
if (!this.store.order || !this.store.quotation)
|
|
1362
|
+
return;
|
|
1392
1363
|
const tempOrder = this.store.order.getTempOrder();
|
|
1393
|
-
if (!tempOrder
|
|
1394
|
-
|
|
1395
|
-
const
|
|
1396
|
-
const context = this.buildSmartPricingContext();
|
|
1364
|
+
if (!((_a = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _a.length))
|
|
1365
|
+
return;
|
|
1366
|
+
const now = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
|
|
1397
1367
|
for (const product of tempOrder.products) {
|
|
1398
|
-
if (product.metadata
|
|
1368
|
+
if ((_b = product.metadata) == null ? void 0 : _b.venue_booking) {
|
|
1399
1369
|
const mappings = this.resourceProductMap.get(product.metadata.resource_id);
|
|
1400
|
-
if (!mappings || !mappings.length)
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
const
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
const updatedSlots = slots.map(slot => {
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
...slot,
|
|
1370
|
+
if (!mappings || !mappings.length)
|
|
1371
|
+
continue;
|
|
1372
|
+
const mapping = mappings.find((m) => Number(m.productId) === Number(product.product_id)) || mappings[0];
|
|
1373
|
+
if (!mapping)
|
|
1374
|
+
continue;
|
|
1375
|
+
const slots = (0, import_slotMerge.expandMergedSlotToIndividual)(
|
|
1376
|
+
product,
|
|
1377
|
+
this.store.slotConfig.slotDurationMinutes
|
|
1378
|
+
);
|
|
1379
|
+
const updatedSlots = slots.map((slot) => ({
|
|
1380
|
+
...slot,
|
|
1381
|
+
productId: mapping.productId,
|
|
1382
|
+
price: this.store.quotation.getPriceForProduct({
|
|
1414
1383
|
productId: mapping.productId,
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
fallbackPrice: mapping.price
|
|
1420
|
-
}) : mapping.price
|
|
1421
|
-
};
|
|
1422
|
-
});
|
|
1423
|
-
const merged = (0, _slotMerge.mergeConsecutiveSlots)(updatedSlots);
|
|
1384
|
+
datetime: slot.startTime
|
|
1385
|
+
}) ?? mapping.price
|
|
1386
|
+
}));
|
|
1387
|
+
const merged = (0, import_slotMerge.mergeConsecutiveSlots)(updatedSlots);
|
|
1424
1388
|
if (merged.length === 1) {
|
|
1425
1389
|
product.selling_price = merged[0].totalPrice;
|
|
1426
1390
|
product.original_price = merged[0].totalPrice;
|
|
1427
|
-
product.metadata.price_breakdown = (0,
|
|
1391
|
+
product.metadata.price_breakdown = (0, import_slotMerge.buildPriceBreakdown)({
|
|
1428
1392
|
group: merged[0],
|
|
1429
|
-
productId: mapping.productId
|
|
1393
|
+
productId: mapping.productId,
|
|
1394
|
+
quotation: this.store.quotation
|
|
1430
1395
|
});
|
|
1431
1396
|
}
|
|
1432
1397
|
} else if (product.product_id != null) {
|
|
1433
|
-
const
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
datetime: now,
|
|
1438
|
-
fallbackPrice: product.selling_price
|
|
1398
|
+
const quotationPrice = this.store.quotation.getPriceForProduct({
|
|
1399
|
+
productId: product.product_id,
|
|
1400
|
+
variantId: product.product_variant_id ?? void 0,
|
|
1401
|
+
datetime: now
|
|
1439
1402
|
});
|
|
1440
|
-
|
|
1441
|
-
|
|
1403
|
+
if (quotationPrice !== null) {
|
|
1404
|
+
product.selling_price = quotationPrice;
|
|
1405
|
+
product.original_price = quotationPrice;
|
|
1406
|
+
}
|
|
1442
1407
|
}
|
|
1443
1408
|
}
|
|
1444
1409
|
}
|
|
1445
1410
|
async scanCode(code, customerId) {
|
|
1446
|
-
this.logMethodStart(
|
|
1447
|
-
code
|
|
1448
|
-
});
|
|
1411
|
+
this.logMethodStart("scanCode", { code });
|
|
1449
1412
|
try {
|
|
1450
|
-
if (!this.store.order)
|
|
1413
|
+
if (!this.store.order)
|
|
1414
|
+
throw new Error("order 模块未初始化");
|
|
1451
1415
|
const result = await this.store.order.scanCode(code, customerId);
|
|
1452
1416
|
if (result.isAvailable) {
|
|
1453
|
-
await this.store.order.recalculateSummary({
|
|
1454
|
-
createIfMissing: true
|
|
1455
|
-
});
|
|
1417
|
+
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
1456
1418
|
this.store.order.persistTempOrder();
|
|
1457
1419
|
}
|
|
1458
|
-
this.logMethodSuccess(
|
|
1459
|
-
isAvailable: result.isAvailable
|
|
1460
|
-
});
|
|
1420
|
+
this.logMethodSuccess("scanCode", { isAvailable: result.isAvailable });
|
|
1461
1421
|
return result;
|
|
1462
1422
|
} catch (error) {
|
|
1463
|
-
this.logMethodError(
|
|
1423
|
+
this.logMethodError("scanCode", error);
|
|
1464
1424
|
throw error;
|
|
1465
1425
|
}
|
|
1466
1426
|
}
|
|
1467
|
-
|
|
1468
1427
|
/** 获取当前折扣列表(包装 order.getDiscountList) */
|
|
1469
1428
|
getDiscountList() {
|
|
1470
|
-
if (!this.store.order)
|
|
1429
|
+
if (!this.store.order)
|
|
1430
|
+
return [];
|
|
1471
1431
|
return this.store.order.getDiscountList();
|
|
1472
1432
|
}
|
|
1473
|
-
|
|
1474
1433
|
/** 勾选/取消勾选某张折扣券,重新计算折扣并持久化 */
|
|
1475
1434
|
async setDiscountSelected(params) {
|
|
1476
|
-
|
|
1435
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1436
|
+
this.logMethodStart("setDiscountSelected", params);
|
|
1477
1437
|
try {
|
|
1478
|
-
if (!this.store.order)
|
|
1438
|
+
if (!this.store.order)
|
|
1439
|
+
throw new Error("order 模块未初始化");
|
|
1479
1440
|
const list = this.store.order.getDiscountList();
|
|
1480
|
-
const beforeTarget = list.find(d => d.id === params.discountId) || null;
|
|
1481
|
-
const updated = list.map(
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1441
|
+
const beforeTarget = list.find((d) => d.id === params.discountId) || null;
|
|
1442
|
+
const updated = list.map(
|
|
1443
|
+
(d) => d.id === params.discountId ? {
|
|
1444
|
+
...d,
|
|
1445
|
+
isSelected: params.isSelected,
|
|
1446
|
+
isManualSelect: !params.isSelected
|
|
1447
|
+
} : d
|
|
1448
|
+
);
|
|
1449
|
+
const updatedTarget = updated.find((d) => d.id === params.discountId) || null;
|
|
1487
1450
|
const tempOrder = this.store.order.ensureTempOrder();
|
|
1488
1451
|
const orderStore = this.store.order.store || {};
|
|
1489
1452
|
const discountModule = orderStore.discount;
|
|
1490
1453
|
const rulesModule = orderStore.rules;
|
|
1491
|
-
const holders = tempOrder.holder
|
|
1492
|
-
form_record_id: tempOrder.holder.form_record_id
|
|
1493
|
-
}] : [];
|
|
1454
|
+
const holders = ((_a = tempOrder.holder) == null ? void 0 : _a.form_record_id) ? [{ form_record_id: tempOrder.holder.form_record_id }] : [];
|
|
1494
1455
|
let nextDiscountList = updated;
|
|
1495
|
-
await discountModule
|
|
1456
|
+
await (discountModule == null ? void 0 : discountModule.setDiscountList(updated));
|
|
1496
1457
|
if (rulesModule) {
|
|
1497
|
-
const result = rulesModule.calcDiscount(
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
};
|
|
1509
|
-
if (result
|
|
1458
|
+
const result = rulesModule.calcDiscount(
|
|
1459
|
+
{
|
|
1460
|
+
productList: tempOrder.products,
|
|
1461
|
+
discountList: updated,
|
|
1462
|
+
holders,
|
|
1463
|
+
isFormSubject: !!((_b = tempOrder.holder) == null ? void 0 : _b.type) && tempOrder.holder.type === "form"
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
discountId: params.discountId,
|
|
1467
|
+
isSelected: params.isSelected
|
|
1468
|
+
}
|
|
1469
|
+
) || { productList: tempOrder.products, discountList: updated };
|
|
1470
|
+
if (result == null ? void 0 : result.productList) {
|
|
1510
1471
|
tempOrder.products = result.productList;
|
|
1511
1472
|
}
|
|
1512
|
-
if (result
|
|
1473
|
+
if (result == null ? void 0 : result.discountList) {
|
|
1513
1474
|
nextDiscountList = result.discountList;
|
|
1514
1475
|
if (!params.isSelected) {
|
|
1515
|
-
const beforeSelectedIds = new Set(
|
|
1476
|
+
const beforeSelectedIds = new Set(
|
|
1477
|
+
updated.filter((d) => d.isSelected).map((d) => d.id)
|
|
1478
|
+
);
|
|
1516
1479
|
for (const d of nextDiscountList) {
|
|
1517
1480
|
if (d.isSelected && !beforeSelectedIds.has(d.id)) {
|
|
1518
1481
|
d.isSelected = false;
|
|
@@ -1521,253 +1484,245 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1521
1484
|
}
|
|
1522
1485
|
}
|
|
1523
1486
|
}
|
|
1524
|
-
const selectedResourceIds = new Set(
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
// 目的:避免 unselect 后 selling_price 残留、reselect 时把残留价带进下一轮 Rules 造成双折扣。
|
|
1528
|
-
// 手动改价商品(_origin.isManualDiscount=true)不参与券流程归一化,保留手工价。
|
|
1487
|
+
const selectedResourceIds = new Set(
|
|
1488
|
+
nextDiscountList.filter((d) => d.isSelected).map((d) => d.id)
|
|
1489
|
+
);
|
|
1529
1490
|
for (const product of tempOrder.products) {
|
|
1530
1491
|
const origin = this.readProductOriginFromTempOrder(tempOrder, product);
|
|
1531
|
-
if (origin
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
const rid = pd.discount
|
|
1492
|
+
if (origin == null ? void 0 : origin.isManualDiscount)
|
|
1493
|
+
continue;
|
|
1494
|
+
product.discount_list = (product.discount_list || []).filter((pd) => {
|
|
1495
|
+
var _a2;
|
|
1496
|
+
const rid = ((_a2 = pd.discount) == null ? void 0 : _a2.resource_id) ?? pd.id;
|
|
1536
1497
|
return rid != null && selectedResourceIds.has(rid);
|
|
1537
1498
|
});
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
const optionSum = (0,
|
|
1543
|
-
const sourcePrice = product.metadata
|
|
1544
|
-
const newSourceSellingPrice = new
|
|
1545
|
-
const newMainSellingPrice = new
|
|
1499
|
+
const totalPerUnitDiscount = (product.discount_list || []).reduce(
|
|
1500
|
+
(sum, pd) => sum + (pd.amount || 0),
|
|
1501
|
+
0
|
|
1502
|
+
);
|
|
1503
|
+
const optionSum = (0, import_utils3.sumOptionUnitPrice)((0, import_utils3.getProductSkuOptions)(product));
|
|
1504
|
+
const sourcePrice = ((_c = product.metadata) == null ? void 0 : _c.source_product_price) ?? (((_d = product.metadata) == null ? void 0 : _d.main_product_original_price) != null ? new import_decimal.default(Number(product.metadata.main_product_original_price) || 0).minus(optionSum).toFixed(2) : product.original_price ?? "0");
|
|
1505
|
+
const newSourceSellingPrice = new import_decimal.default(Number(sourcePrice) || 0).minus(totalPerUnitDiscount).toDecimalPlaces(2).toString();
|
|
1506
|
+
const newMainSellingPrice = new import_decimal.default(Number(newSourceSellingPrice) || 0).plus(optionSum).toDecimalPlaces(2).toFixed(2);
|
|
1546
1507
|
if (product.metadata) {
|
|
1547
1508
|
product.metadata.main_product_selling_price = newMainSellingPrice;
|
|
1548
1509
|
product.metadata.price_schema_version = 2;
|
|
1549
1510
|
}
|
|
1550
|
-
product.selling_price = (0,
|
|
1511
|
+
product.selling_price = (0, import_utils3.composeLinePrice)({
|
|
1551
1512
|
mainPrice: newMainSellingPrice,
|
|
1552
1513
|
bundle: product.product_bundle
|
|
1553
1514
|
});
|
|
1554
1515
|
}
|
|
1555
|
-
|
|
1556
|
-
await discountModule
|
|
1557
|
-
tempOrder.discount_list = (nextDiscountList || []).filter(d => d.isSelected);
|
|
1558
|
-
const afterApplyTarget = this.store.order.getDiscountList().find(d => d.id === params.discountId) || null;
|
|
1559
|
-
await this.store.order.recalculateSummary({
|
|
1560
|
-
createIfMissing: true
|
|
1561
|
-
});
|
|
1516
|
+
import_Order.OrderModule.populateSavedAmounts(tempOrder.products, nextDiscountList);
|
|
1517
|
+
await (discountModule == null ? void 0 : discountModule.setDiscountList(nextDiscountList));
|
|
1518
|
+
tempOrder.discount_list = (nextDiscountList || []).filter((d) => d.isSelected);
|
|
1519
|
+
const afterApplyTarget = this.store.order.getDiscountList().find((d) => d.id === params.discountId) || null;
|
|
1520
|
+
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
1562
1521
|
this.store.order.persistTempOrder();
|
|
1563
|
-
const finalSummary = this.store.order.getTempOrder()
|
|
1564
|
-
const finalProduct = this.store.order.getTempOrder()
|
|
1565
|
-
this.logMethodSuccess(
|
|
1566
|
-
const finalTarget = this.store.order.getDiscountList().find(d => d.id === params.discountId) || null;
|
|
1522
|
+
const finalSummary = ((_e = this.store.order.getTempOrder()) == null ? void 0 : _e.summary) || null;
|
|
1523
|
+
const finalProduct = ((_g = (_f = this.store.order.getTempOrder()) == null ? void 0 : _f.products) == null ? void 0 : _g[0]) || null;
|
|
1524
|
+
this.logMethodSuccess("setDiscountSelected", params);
|
|
1525
|
+
const finalTarget = this.store.order.getDiscountList().find((d) => d.id === params.discountId) || null;
|
|
1567
1526
|
return this.store.order.getDiscountList();
|
|
1568
1527
|
} catch (error) {
|
|
1569
|
-
this.logMethodError(
|
|
1528
|
+
this.logMethodError("setDiscountSelected", error);
|
|
1570
1529
|
throw error;
|
|
1571
1530
|
}
|
|
1572
1531
|
}
|
|
1573
1532
|
async addNewOrder() {
|
|
1574
|
-
this.logMethodStart(
|
|
1533
|
+
this.logMethodStart("addNewOrder");
|
|
1575
1534
|
try {
|
|
1576
|
-
if (!this.store.order)
|
|
1535
|
+
if (!this.store.order)
|
|
1536
|
+
throw new Error("order 模块未初始化");
|
|
1577
1537
|
const tempOrder = await this.store.order.addNewOrder();
|
|
1578
|
-
this.logMethodSuccess(
|
|
1538
|
+
this.logMethodSuccess("addNewOrder", {
|
|
1579
1539
|
productCount: tempOrder.products.length
|
|
1580
1540
|
});
|
|
1581
1541
|
return tempOrder;
|
|
1582
1542
|
} catch (error) {
|
|
1583
|
-
this.logMethodError(
|
|
1543
|
+
this.logMethodError("addNewOrder", error);
|
|
1584
1544
|
throw error;
|
|
1585
1545
|
}
|
|
1586
1546
|
}
|
|
1587
1547
|
getOrderProducts() {
|
|
1588
|
-
if (!this.store.order)
|
|
1548
|
+
if (!this.store.order)
|
|
1549
|
+
throw new Error("order 模块未初始化");
|
|
1589
1550
|
const products = this.store.order.getOrderProducts();
|
|
1590
1551
|
return products;
|
|
1591
1552
|
}
|
|
1592
1553
|
async getSummary() {
|
|
1593
|
-
this.logMethodStart(
|
|
1554
|
+
this.logMethodStart("getSummary");
|
|
1594
1555
|
try {
|
|
1595
|
-
if (!this.store.order)
|
|
1556
|
+
if (!this.store.order)
|
|
1557
|
+
throw new Error("order 模块未初始化");
|
|
1596
1558
|
const summary = await this.store.order.getOrderSummary();
|
|
1597
|
-
this.logMethodSuccess(
|
|
1559
|
+
this.logMethodSuccess("getSummary", {
|
|
1598
1560
|
totalAmount: summary.total_amount
|
|
1599
1561
|
});
|
|
1600
1562
|
return summary;
|
|
1601
1563
|
} catch (error) {
|
|
1602
|
-
this.logMethodError(
|
|
1564
|
+
this.logMethodError("getSummary", error);
|
|
1603
1565
|
throw error;
|
|
1604
1566
|
}
|
|
1605
1567
|
}
|
|
1606
1568
|
async submitOrder() {
|
|
1607
|
-
|
|
1569
|
+
var _a, _b, _c, _d, _e;
|
|
1570
|
+
this.logMethodStart("submitOrder");
|
|
1608
1571
|
try {
|
|
1609
1572
|
await this.validateBeforeSubmitByItemRule();
|
|
1610
1573
|
if (!this.store.order) {
|
|
1611
|
-
throw new Error(
|
|
1574
|
+
throw new Error("venueBooking解决方案需要 order 模块支持");
|
|
1612
1575
|
}
|
|
1613
1576
|
const result = await this.store.order.submitTempOrder({
|
|
1614
1577
|
cacheId: this.cacheId,
|
|
1615
|
-
platform: this.otherParams
|
|
1616
|
-
businessCode: this.otherParams
|
|
1617
|
-
channel: this.otherParams
|
|
1618
|
-
type: this.otherParams
|
|
1578
|
+
platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
|
|
1579
|
+
businessCode: (_b = this.otherParams) == null ? void 0 : _b.businessCode,
|
|
1580
|
+
channel: (_c = this.otherParams) == null ? void 0 : _c.channel,
|
|
1581
|
+
type: (_d = this.otherParams) == null ? void 0 : _d.type
|
|
1619
1582
|
});
|
|
1620
1583
|
const tempOrder = this.store.order.getTempOrder();
|
|
1621
|
-
this.logMethodSuccess(
|
|
1622
|
-
productCount: tempOrder
|
|
1584
|
+
this.logMethodSuccess("submitOrder", {
|
|
1585
|
+
productCount: ((_e = tempOrder == null ? void 0 : tempOrder.products) == null ? void 0 : _e.length) || 0
|
|
1623
1586
|
});
|
|
1624
1587
|
return result;
|
|
1625
1588
|
} catch (error) {
|
|
1626
|
-
this.logMethodError(
|
|
1627
|
-
throw error;
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
/**
|
|
1632
|
-
* 0 元订单免费领取(非定金场景)
|
|
1633
|
-
* 与 appointment getFreeProduct 同接口:POST /pay/order/free-pay/:id
|
|
1634
|
-
*/
|
|
1635
|
-
async submitFreeOrder(id) {
|
|
1636
|
-
this.logMethodStart('submitFreeOrder', {
|
|
1637
|
-
id
|
|
1638
|
-
});
|
|
1639
|
-
try {
|
|
1640
|
-
if (!id) {
|
|
1641
|
-
throw new Error('订单 ID 不能为空');
|
|
1642
|
-
}
|
|
1643
|
-
const res = await this.request.post(`/pay/order/free-pay/${id}`);
|
|
1644
|
-
this.logMethodSuccess('submitFreeOrder', {
|
|
1645
|
-
id,
|
|
1646
|
-
status: res?.status
|
|
1647
|
-
});
|
|
1648
|
-
return res;
|
|
1649
|
-
} catch (error) {
|
|
1650
|
-
this.logMethodError('submitFreeOrder', error);
|
|
1589
|
+
this.logMethodError("submitOrder", error);
|
|
1651
1590
|
throw error;
|
|
1652
1591
|
}
|
|
1653
1592
|
}
|
|
1654
1593
|
async addProductToOrder(product) {
|
|
1655
|
-
|
|
1594
|
+
var _a;
|
|
1595
|
+
this.logMethodStart("addProductToOrder", {
|
|
1656
1596
|
product_id: product.product_id,
|
|
1657
1597
|
product_variant_id: product.product_variant_id
|
|
1658
1598
|
});
|
|
1659
1599
|
try {
|
|
1660
|
-
if (!this.store.order)
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
datetime: (0,
|
|
1667
|
-
fallbackPrice: product.selling_price
|
|
1600
|
+
if (!this.store.order)
|
|
1601
|
+
throw new Error("order 模块未初始化");
|
|
1602
|
+
if (!((_a = product.metadata) == null ? void 0 : _a.venue_booking) && this.store.quotation && product.product_id != null) {
|
|
1603
|
+
const quotationPrice = this.store.quotation.getPriceForProduct({
|
|
1604
|
+
productId: product.product_id,
|
|
1605
|
+
variantId: product.product_variant_id ?? void 0,
|
|
1606
|
+
datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
|
|
1668
1607
|
});
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1608
|
+
if (quotationPrice !== null) {
|
|
1609
|
+
product.selling_price = quotationPrice;
|
|
1610
|
+
product.original_price = quotationPrice;
|
|
1611
|
+
} else if (product.selling_price != null) {
|
|
1612
|
+
product.original_price = product.selling_price;
|
|
1613
|
+
}
|
|
1673
1614
|
}
|
|
1674
1615
|
const products = await this.store.order.addProductToOrder(product);
|
|
1675
1616
|
await this.refreshItemRuleQuantityLimits();
|
|
1676
1617
|
await this.refreshCartValidationPassed();
|
|
1677
|
-
this.logMethodSuccess(
|
|
1618
|
+
this.logMethodSuccess("addProductToOrder", {
|
|
1678
1619
|
productCount: products.length
|
|
1679
1620
|
});
|
|
1680
1621
|
return products;
|
|
1681
1622
|
} catch (error) {
|
|
1682
|
-
this.logMethodError(
|
|
1623
|
+
this.logMethodError("addProductToOrder", error);
|
|
1683
1624
|
throw error;
|
|
1684
1625
|
}
|
|
1685
1626
|
}
|
|
1686
1627
|
async updateOrderProduct(params) {
|
|
1687
|
-
this.logMethodStart(
|
|
1628
|
+
this.logMethodStart("updateOrderProduct", {
|
|
1688
1629
|
product_id: params.product_id,
|
|
1689
1630
|
product_variant_id: params.product_variant_id
|
|
1690
1631
|
});
|
|
1691
1632
|
try {
|
|
1692
|
-
if (!this.store.order)
|
|
1633
|
+
if (!this.store.order)
|
|
1634
|
+
throw new Error("order 模块未初始化");
|
|
1693
1635
|
const products = await this.store.order.updateOrderProduct(params);
|
|
1694
1636
|
await this.refreshItemRuleQuantityLimits();
|
|
1695
1637
|
await this.refreshCartValidationPassed();
|
|
1696
|
-
this.logMethodSuccess(
|
|
1638
|
+
this.logMethodSuccess("updateOrderProduct", {
|
|
1697
1639
|
productCount: products.length
|
|
1698
1640
|
});
|
|
1699
1641
|
return products;
|
|
1700
1642
|
} catch (error) {
|
|
1701
|
-
this.logMethodError(
|
|
1643
|
+
this.logMethodError("updateOrderProduct", error);
|
|
1702
1644
|
throw error;
|
|
1703
1645
|
}
|
|
1704
1646
|
}
|
|
1705
1647
|
async removeProductFromOrder(identity) {
|
|
1706
|
-
|
|
1648
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
1649
|
+
this.logMethodStart("removeProductFromOrder", {
|
|
1707
1650
|
product_id: identity.product_id,
|
|
1708
1651
|
product_variant_id: identity.product_variant_id
|
|
1709
1652
|
});
|
|
1710
1653
|
try {
|
|
1711
|
-
if (!this.store.order)
|
|
1712
|
-
|
|
1654
|
+
if (!this.store.order)
|
|
1655
|
+
throw new Error("order 模块未初始化");
|
|
1656
|
+
const tempOrder = ((_b = (_a = this.store.order).getTempOrder) == null ? void 0 : _b.call(_a)) || ((_d = (_c = this.store.order).ensureTempOrder) == null ? void 0 : _d.call(_c));
|
|
1713
1657
|
const products = await this.store.order.removeProductFromOrder(identity);
|
|
1714
|
-
if (tempOrder
|
|
1715
|
-
const venueProductUids = new Set();
|
|
1716
|
-
const venueBookingUids = new Set();
|
|
1658
|
+
if ((_e = tempOrder == null ? void 0 : tempOrder.bookings) == null ? void 0 : _e.length) {
|
|
1659
|
+
const venueProductUids = /* @__PURE__ */ new Set();
|
|
1660
|
+
const venueBookingUids = /* @__PURE__ */ new Set();
|
|
1717
1661
|
for (const product of tempOrder.products || []) {
|
|
1718
|
-
if (!product
|
|
1719
|
-
|
|
1720
|
-
if (product.
|
|
1662
|
+
if (!((_f = product == null ? void 0 : product.metadata) == null ? void 0 : _f.venue_booking))
|
|
1663
|
+
continue;
|
|
1664
|
+
if (product.identity_key)
|
|
1665
|
+
venueProductUids.add(String(product.identity_key));
|
|
1666
|
+
if ((_g = product.metadata) == null ? void 0 : _g.booking_uid) {
|
|
1721
1667
|
venueBookingUids.add(String(product.metadata.booking_uid));
|
|
1722
1668
|
}
|
|
1723
1669
|
}
|
|
1724
|
-
const beforeBookingCount = tempOrder.bookings
|
|
1725
|
-
tempOrder.bookings = (tempOrder.bookings || []).filter(booking => {
|
|
1726
|
-
|
|
1670
|
+
const beforeBookingCount = ((_h = tempOrder.bookings) == null ? void 0 : _h.length) || 0;
|
|
1671
|
+
tempOrder.bookings = (tempOrder.bookings || []).filter((booking) => {
|
|
1672
|
+
var _a2, _b2;
|
|
1673
|
+
if (!((_a2 = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a2.venue_booking))
|
|
1674
|
+
return true;
|
|
1727
1675
|
if (booking.product_uid) {
|
|
1728
1676
|
return venueProductUids.has(String(booking.product_uid));
|
|
1729
1677
|
}
|
|
1730
|
-
const bookingUid = booking.metadata
|
|
1731
|
-
if (bookingUid)
|
|
1678
|
+
const bookingUid = (_b2 = booking.metadata) == null ? void 0 : _b2.unique_identification_number;
|
|
1679
|
+
if (bookingUid)
|
|
1680
|
+
return venueBookingUids.has(String(bookingUid));
|
|
1732
1681
|
return true;
|
|
1733
1682
|
});
|
|
1734
|
-
if ((tempOrder.bookings
|
|
1735
|
-
this.store.order.persistTempOrder
|
|
1683
|
+
if ((((_i = tempOrder.bookings) == null ? void 0 : _i.length) || 0) !== beforeBookingCount) {
|
|
1684
|
+
(_k = (_j = this.store.order).persistTempOrder) == null ? void 0 : _k.call(_j);
|
|
1736
1685
|
}
|
|
1737
1686
|
}
|
|
1738
1687
|
await this.refreshItemRuleQuantityLimits();
|
|
1739
1688
|
await this.refreshCartValidationPassed();
|
|
1740
|
-
this.logMethodSuccess(
|
|
1689
|
+
this.logMethodSuccess("removeProductFromOrder", {
|
|
1741
1690
|
productCount: products.length
|
|
1742
1691
|
});
|
|
1743
1692
|
return products;
|
|
1744
1693
|
} catch (error) {
|
|
1745
|
-
this.logMethodError(
|
|
1694
|
+
this.logMethodError("removeProductFromOrder", error);
|
|
1746
1695
|
throw error;
|
|
1747
1696
|
}
|
|
1748
1697
|
}
|
|
1749
1698
|
async getProductList() {
|
|
1750
1699
|
if (this.productsLoaded) {
|
|
1751
|
-
return (0,
|
|
1700
|
+
return (0, import_utils.attachItemRuleLimitsToTopLevelProducts)(
|
|
1701
|
+
this.getAddonProductsList(),
|
|
1702
|
+
this.store.itemRuleQuantityLimits || []
|
|
1703
|
+
);
|
|
1752
1704
|
}
|
|
1753
1705
|
const result = await this.loadAllProducts();
|
|
1754
|
-
return (0,
|
|
1706
|
+
return (0, import_utils.attachItemRuleLimitsToTopLevelProducts)(
|
|
1707
|
+
result.addonProducts,
|
|
1708
|
+
this.store.itemRuleQuantityLimits || []
|
|
1709
|
+
);
|
|
1755
1710
|
}
|
|
1756
|
-
|
|
1757
1711
|
// ─── ItemRule 引擎 ───
|
|
1758
|
-
|
|
1759
1712
|
async loadOpenDataConfig() {
|
|
1760
|
-
if (!this.store.openData)
|
|
1713
|
+
if (!this.store.openData)
|
|
1714
|
+
throw new Error("openData 模块未初始化");
|
|
1761
1715
|
const lastFetchedAt = this.store.openData.getLastFetchedAt();
|
|
1762
1716
|
const cachedData = this.store.openData.getOpenData();
|
|
1763
|
-
if (cachedData && lastFetchedAt && Date.now() - lastFetchedAt <
|
|
1717
|
+
if (cachedData && lastFetchedAt && Date.now() - lastFetchedAt < _VenueBookingImpl.OPEN_DATA_CACHE_TTL) {
|
|
1764
1718
|
this.otherParams.openData = cachedData;
|
|
1765
1719
|
return cachedData;
|
|
1766
1720
|
}
|
|
1767
|
-
if (this.loadOpenDataConfigInFlight)
|
|
1721
|
+
if (this.loadOpenDataConfigInFlight)
|
|
1722
|
+
return await this.loadOpenDataConfigInFlight;
|
|
1768
1723
|
this.loadOpenDataConfigInFlight = this.store.openData.fetchOpenData({
|
|
1769
|
-
scope:
|
|
1770
|
-
target:
|
|
1724
|
+
scope: "board",
|
|
1725
|
+
target: "venue_booking+online_store",
|
|
1771
1726
|
section_code: [...OPEN_DATA_SECTION_CODES]
|
|
1772
1727
|
});
|
|
1773
1728
|
try {
|
|
@@ -1781,53 +1736,52 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1781
1736
|
async loadRuntimeConfigs() {
|
|
1782
1737
|
await this.loadOpenDataConfig();
|
|
1783
1738
|
const itemRuleConfigs = await this.ensureItemRuleConfigsLoaded();
|
|
1784
|
-
this.logMethodSuccess(
|
|
1739
|
+
this.logMethodSuccess("loadRuntimeConfigs", {
|
|
1785
1740
|
itemRuleCount: itemRuleConfigs.length
|
|
1786
1741
|
});
|
|
1787
|
-
return {
|
|
1788
|
-
itemRuleConfigs
|
|
1789
|
-
};
|
|
1742
|
+
return { itemRuleConfigs };
|
|
1790
1743
|
}
|
|
1791
1744
|
async fetchItemRuleConfigsByModelIds(strategyModelIds) {
|
|
1792
|
-
this.logMethodStart(
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
if (!strategyModelIds.length) return [];
|
|
1745
|
+
this.logMethodStart("fetchItemRuleConfigsByModelIds", { strategyModelIds });
|
|
1746
|
+
if (!strategyModelIds.length)
|
|
1747
|
+
return [];
|
|
1796
1748
|
try {
|
|
1797
|
-
const result = await this.request.get(
|
|
1749
|
+
const result = await this.request.get("/promotion", {
|
|
1798
1750
|
skip: 1,
|
|
1799
1751
|
num: 99,
|
|
1800
|
-
status:
|
|
1752
|
+
status: "active",
|
|
1801
1753
|
ids: strategyModelIds
|
|
1802
1754
|
});
|
|
1803
1755
|
let configs = [];
|
|
1804
1756
|
if (result.code === 200) {
|
|
1805
|
-
configs = result.data.list.map(item => item.metadata);
|
|
1757
|
+
configs = result.data.list.map((item) => item.metadata);
|
|
1806
1758
|
}
|
|
1807
|
-
this.logMethodSuccess(
|
|
1759
|
+
this.logMethodSuccess("fetchItemRuleConfigsByModelIds", {
|
|
1808
1760
|
strategyModelIds,
|
|
1809
1761
|
strategyCount: configs.length
|
|
1810
1762
|
});
|
|
1811
1763
|
return configs;
|
|
1812
1764
|
} catch (error) {
|
|
1813
|
-
this.logMethodError(
|
|
1814
|
-
strategyModelIds
|
|
1815
|
-
});
|
|
1765
|
+
this.logMethodError("fetchItemRuleConfigsByModelIds", error, { strategyModelIds });
|
|
1816
1766
|
return [];
|
|
1817
1767
|
}
|
|
1818
1768
|
}
|
|
1819
1769
|
async buildPrefillProductSourceMap() {
|
|
1820
|
-
const sourceMap = new Map();
|
|
1770
|
+
const sourceMap = /* @__PURE__ */ new Map();
|
|
1821
1771
|
try {
|
|
1822
1772
|
const productList = await this.getProductList();
|
|
1823
|
-
if (!Array.isArray(productList))
|
|
1824
|
-
|
|
1825
|
-
const
|
|
1826
|
-
|
|
1827
|
-
if (
|
|
1773
|
+
if (!Array.isArray(productList))
|
|
1774
|
+
return sourceMap;
|
|
1775
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1776
|
+
const collectFromValue = (value) => {
|
|
1777
|
+
if (!value || typeof value !== "object")
|
|
1778
|
+
return;
|
|
1779
|
+
if (visited.has(value))
|
|
1780
|
+
return;
|
|
1828
1781
|
visited.add(value);
|
|
1829
1782
|
if (Array.isArray(value)) {
|
|
1830
|
-
for (const item of value)
|
|
1783
|
+
for (const item of value)
|
|
1784
|
+
collectFromValue(item);
|
|
1831
1785
|
return;
|
|
1832
1786
|
}
|
|
1833
1787
|
const node = value;
|
|
@@ -1836,16 +1790,18 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1836
1790
|
if (Number.isFinite(productId) && productId > 0) {
|
|
1837
1791
|
const productVariantId = Number(node.product_variant_id ?? node.variant_id ?? 0);
|
|
1838
1792
|
const normalizedVariantId = Number.isNaN(productVariantId) ? 0 : productVariantId;
|
|
1839
|
-
const key = (0,
|
|
1840
|
-
if (!sourceMap.has(key))
|
|
1793
|
+
const key = (0, import_utils.buildProductKey)(productId, normalizedVariantId);
|
|
1794
|
+
if (!sourceMap.has(key))
|
|
1795
|
+
sourceMap.set(key, node);
|
|
1841
1796
|
}
|
|
1842
1797
|
for (const childValue of Object.values(node)) {
|
|
1843
|
-
if (childValue && typeof childValue ===
|
|
1798
|
+
if (childValue && typeof childValue === "object")
|
|
1799
|
+
collectFromValue(childValue);
|
|
1844
1800
|
}
|
|
1845
1801
|
};
|
|
1846
1802
|
collectFromValue(productList);
|
|
1847
1803
|
} catch (error) {
|
|
1848
|
-
this.logMethodError(
|
|
1804
|
+
this.logMethodError("buildPrefillProductSourceMap", error);
|
|
1849
1805
|
}
|
|
1850
1806
|
return sourceMap;
|
|
1851
1807
|
}
|
|
@@ -1853,11 +1809,13 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1853
1809
|
return this.itemRuleRuntimeConfig || {};
|
|
1854
1810
|
}
|
|
1855
1811
|
async ensureItemRuleConfigsLoaded() {
|
|
1856
|
-
if (this.itemRuleConfigs.length > 0)
|
|
1857
|
-
|
|
1812
|
+
if (this.itemRuleConfigs.length > 0)
|
|
1813
|
+
return this.itemRuleConfigs;
|
|
1814
|
+
if (this.itemRuleConfigsPromise)
|
|
1815
|
+
return this.itemRuleConfigsPromise;
|
|
1858
1816
|
this.itemRuleConfigsPromise = (async () => {
|
|
1859
1817
|
const runtimeConfig = this.getItemRuleRuntimeConfig();
|
|
1860
|
-
const staticConfigs = (0,
|
|
1818
|
+
const staticConfigs = (0, import_utils.normalizeItemRuleStrategies)(runtimeConfig.strategyConfigs);
|
|
1861
1819
|
if (staticConfigs.length > 0) {
|
|
1862
1820
|
this.itemRuleConfigs = staticConfigs;
|
|
1863
1821
|
this.itemRuleEvaluator.setStrategyConfigs(staticConfigs);
|
|
@@ -1876,29 +1834,31 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1876
1834
|
this.store.itemRuleQuantityLimits = [];
|
|
1877
1835
|
return [];
|
|
1878
1836
|
}
|
|
1879
|
-
const businessData = (0,
|
|
1837
|
+
const businessData = (0, import_utils.buildItemRuleBusinessData)({
|
|
1880
1838
|
tempOrder: this.ensureVenueTempOrder(),
|
|
1881
1839
|
runtimeConfig: this.getItemRuleRuntimeConfig(),
|
|
1882
1840
|
itemRuleConfigs: this.itemRuleConfigs
|
|
1883
1841
|
});
|
|
1884
1842
|
const limits = this.itemRuleEvaluator.getQuantityLimits(businessData);
|
|
1885
1843
|
this.store.itemRuleQuantityLimits = limits;
|
|
1886
|
-
this.logMethodSuccess(
|
|
1887
|
-
limitCount: limits.length
|
|
1888
|
-
});
|
|
1844
|
+
this.logMethodSuccess("refreshItemRuleQuantityLimits", { limitCount: limits.length });
|
|
1889
1845
|
return limits;
|
|
1890
1846
|
} catch (error) {
|
|
1891
1847
|
this.store.itemRuleQuantityLimits = [];
|
|
1892
|
-
this.logMethodError(
|
|
1848
|
+
this.logMethodError("refreshItemRuleQuantityLimits", error);
|
|
1893
1849
|
return [];
|
|
1894
1850
|
}
|
|
1895
1851
|
}
|
|
1896
1852
|
async applyPrefillByItemRule() {
|
|
1897
|
-
|
|
1898
|
-
if (
|
|
1853
|
+
var _a, _b;
|
|
1854
|
+
if (this.itemRulePrefillApplied)
|
|
1855
|
+
return;
|
|
1856
|
+
if (!this.store.order)
|
|
1857
|
+
return;
|
|
1899
1858
|
const strategyConfigs = await this.ensureItemRuleConfigsLoaded();
|
|
1900
|
-
if (!strategyConfigs.length)
|
|
1901
|
-
|
|
1859
|
+
if (!strategyConfigs.length)
|
|
1860
|
+
return;
|
|
1861
|
+
const businessData = (0, import_utils.buildItemRuleBusinessData)({
|
|
1902
1862
|
tempOrder: this.ensureVenueTempOrder(),
|
|
1903
1863
|
runtimeConfig: this.getItemRuleRuntimeConfig(),
|
|
1904
1864
|
itemRuleConfigs: this.itemRuleConfigs
|
|
@@ -1914,34 +1874,29 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1914
1874
|
for (const prefillItem of prefillItems) {
|
|
1915
1875
|
const productId = Number(prefillItem.product_id);
|
|
1916
1876
|
const productVariantId = Number(prefillItem.product_variant_id ?? 0);
|
|
1917
|
-
const targetQuantity = (0,
|
|
1918
|
-
if (!Number.isFinite(productId) || targetQuantity <= 0)
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1877
|
+
const targetQuantity = (0, import_utils.toNonNegativeInt)(prefillItem.quantity);
|
|
1878
|
+
if (!Number.isFinite(productId) || targetQuantity <= 0)
|
|
1879
|
+
continue;
|
|
1880
|
+
if (Number.isNaN(productVariantId))
|
|
1881
|
+
continue;
|
|
1882
|
+
const sourceItem = productSourceMap.get((0, import_utils.buildProductKey)(productId, productVariantId)) || productSourceMap.get((0, import_utils.buildProductKey)(productId, 0)) || null;
|
|
1883
|
+
const productIndex = (0, import_utils.getProductIdentityIndex)(tempOrder.products, {
|
|
1922
1884
|
product_id: productId,
|
|
1923
1885
|
product_variant_id: productVariantId
|
|
1924
1886
|
});
|
|
1925
1887
|
if (productIndex === -1) {
|
|
1926
|
-
const sellingPrice = (0,
|
|
1927
|
-
const origin = {
|
|
1928
|
-
|
|
1929
|
-
item_rule_prefill: true,
|
|
1930
|
-
item_rule_id: prefillItem.ruleId
|
|
1931
|
-
};
|
|
1932
|
-
const product = (0, _utils.normalizeOrderProduct)({
|
|
1888
|
+
const sellingPrice = (0, import_utils.toPriceString)((sourceItem == null ? void 0 : sourceItem.price) ?? (sourceItem == null ? void 0 : sourceItem.selling_price), "0.00");
|
|
1889
|
+
const origin = { ...sourceItem || {}, item_rule_prefill: true, item_rule_id: prefillItem.ruleId };
|
|
1890
|
+
const product = (0, import_utils.normalizeOrderProduct)({
|
|
1933
1891
|
product_id: productId,
|
|
1934
1892
|
product_variant_id: productVariantId,
|
|
1935
1893
|
num: targetQuantity,
|
|
1936
1894
|
selling_price: sellingPrice,
|
|
1937
1895
|
original_price: sellingPrice,
|
|
1938
|
-
metadata: {
|
|
1939
|
-
item_rule_prefill: true,
|
|
1940
|
-
item_rule_id: prefillItem.ruleId
|
|
1941
|
-
},
|
|
1896
|
+
metadata: { item_rule_prefill: true, item_rule_id: prefillItem.ruleId },
|
|
1942
1897
|
_origin: origin
|
|
1943
1898
|
});
|
|
1944
|
-
const productUid = String(product.metadata
|
|
1899
|
+
const productUid = String(((_a = product.metadata) == null ? void 0 : _a.unique_identification_number) || "");
|
|
1945
1900
|
this.attachProductOriginToTempOrder(tempOrder, productUid, origin);
|
|
1946
1901
|
tempOrder.products.push(product);
|
|
1947
1902
|
hasChanges = true;
|
|
@@ -1949,58 +1904,48 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
1949
1904
|
}
|
|
1950
1905
|
const targetProduct = tempOrder.products[productIndex];
|
|
1951
1906
|
const previousOrigin = this.readProductOriginFromTempOrder(tempOrder, targetProduct);
|
|
1952
|
-
const nextOrigin = sourceItem ? {
|
|
1953
|
-
|
|
1954
|
-
...sourceItem
|
|
1955
|
-
} : previousOrigin;
|
|
1956
|
-
const existedQuantity = (0, _utils.toNonNegativeInt)(targetProduct.num);
|
|
1907
|
+
const nextOrigin = sourceItem ? { ...previousOrigin || {}, ...sourceItem } : previousOrigin;
|
|
1908
|
+
const existedQuantity = (0, import_utils.toNonNegativeInt)(targetProduct.num);
|
|
1957
1909
|
const delta = targetQuantity - existedQuantity;
|
|
1958
1910
|
const nextProduct = {
|
|
1959
1911
|
...targetProduct,
|
|
1960
|
-
...
|
|
1961
|
-
|
|
1962
|
-
} : {}),
|
|
1963
|
-
metadata: {
|
|
1964
|
-
...(targetProduct.metadata || {}),
|
|
1965
|
-
item_rule_prefill: true,
|
|
1966
|
-
item_rule_id: prefillItem.ruleId
|
|
1967
|
-
}
|
|
1912
|
+
...delta > 0 ? { num: (0, import_utils.getSafeProductNum)(existedQuantity + delta) } : {},
|
|
1913
|
+
metadata: { ...targetProduct.metadata || {}, item_rule_prefill: true, item_rule_id: prefillItem.ruleId }
|
|
1968
1914
|
};
|
|
1969
|
-
if (delta > 0 || Boolean(
|
|
1970
|
-
|
|
1915
|
+
if (delta > 0 || Boolean(
|
|
1916
|
+
sourceItem && (!previousOrigin || (previousOrigin == null ? void 0 : previousOrigin.price) !== (sourceItem == null ? void 0 : sourceItem.price))
|
|
1917
|
+
)) {
|
|
1918
|
+
const productUid = String(
|
|
1919
|
+
((_b = nextProduct.metadata) == null ? void 0 : _b.unique_identification_number) || ""
|
|
1920
|
+
);
|
|
1971
1921
|
this.attachProductOriginToTempOrder(tempOrder, productUid, nextOrigin);
|
|
1972
1922
|
tempOrder.products[productIndex] = nextProduct;
|
|
1973
1923
|
hasChanges = true;
|
|
1974
1924
|
}
|
|
1975
1925
|
}
|
|
1976
1926
|
if (hasChanges) {
|
|
1977
|
-
// Prefill 属于 products CRUD 的一种形式:新增后让 Rules 重算,以支持自动应用可用优惠券。
|
|
1978
1927
|
this.store.order.applyDiscount();
|
|
1979
|
-
await this.store.order.recalculateSummary({
|
|
1980
|
-
createIfMissing: true
|
|
1981
|
-
});
|
|
1928
|
+
await this.store.order.recalculateSummary({ createIfMissing: true });
|
|
1982
1929
|
this.store.order.persistTempOrder();
|
|
1983
1930
|
}
|
|
1984
1931
|
await this.refreshItemRuleQuantityLimits();
|
|
1985
1932
|
this.itemRulePrefillApplied = true;
|
|
1986
|
-
this.logMethodSuccess(
|
|
1933
|
+
this.logMethodSuccess("applyPrefillByItemRule", {
|
|
1987
1934
|
prefillCount: prefillItems.length,
|
|
1988
1935
|
hasChanges
|
|
1989
1936
|
});
|
|
1990
1937
|
}
|
|
1991
1938
|
async applyItemRulePrefill() {
|
|
1992
|
-
this.logMethodStart(
|
|
1939
|
+
this.logMethodStart("applyItemRulePrefill");
|
|
1993
1940
|
await this.applyPrefillByItemRule();
|
|
1994
1941
|
await this.refreshItemRuleQuantityLimits();
|
|
1995
1942
|
await this.refreshCartValidationPassed();
|
|
1996
1943
|
}
|
|
1997
1944
|
async evaluateCartValidationByItemRule() {
|
|
1998
1945
|
const strategyConfigs = await this.ensureItemRuleConfigsLoaded();
|
|
1999
|
-
if (!strategyConfigs.length)
|
|
2000
|
-
passed: true,
|
|
2001
|
-
|
|
2002
|
-
};
|
|
2003
|
-
const businessData = (0, _utils.buildItemRuleBusinessData)({
|
|
1946
|
+
if (!strategyConfigs.length)
|
|
1947
|
+
return { passed: true, failures: [] };
|
|
1948
|
+
const businessData = (0, import_utils.buildItemRuleBusinessData)({
|
|
2004
1949
|
tempOrder: this.ensureVenueTempOrder(),
|
|
2005
1950
|
runtimeConfig: this.getItemRuleRuntimeConfig(),
|
|
2006
1951
|
itemRuleConfigs: this.itemRuleConfigs
|
|
@@ -2009,18 +1954,16 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
2009
1954
|
}
|
|
2010
1955
|
async validateBeforeSubmitByItemRule() {
|
|
2011
1956
|
const validationResult = await this.evaluateCartValidationByItemRule();
|
|
2012
|
-
if (validationResult.passed)
|
|
1957
|
+
if (validationResult.passed)
|
|
1958
|
+
return;
|
|
2013
1959
|
const firstFailure = validationResult.failures[0];
|
|
2014
|
-
const errorMessage = firstFailure
|
|
1960
|
+
const errorMessage = (firstFailure == null ? void 0 : firstFailure.validationMessage) || "当前购物车未满足商品规则,请调整后再提交";
|
|
2015
1961
|
const error = new Error(String(errorMessage));
|
|
2016
1962
|
error.failures = validationResult.failures;
|
|
2017
1963
|
throw error;
|
|
2018
1964
|
}
|
|
2019
1965
|
async refreshCartValidationPassed() {
|
|
2020
|
-
const previous = this.store.cartValidation || {
|
|
2021
|
-
passed: null,
|
|
2022
|
-
failures: []
|
|
2023
|
-
};
|
|
1966
|
+
const previous = this.store.cartValidation || { passed: null, failures: [] };
|
|
2024
1967
|
let nextState = {
|
|
2025
1968
|
passed: null,
|
|
2026
1969
|
failures: []
|
|
@@ -2032,15 +1975,12 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
2032
1975
|
failures: validationResult.failures || []
|
|
2033
1976
|
};
|
|
2034
1977
|
} catch {
|
|
2035
|
-
nextState = {
|
|
2036
|
-
passed: false,
|
|
2037
|
-
failures: []
|
|
2038
|
-
};
|
|
1978
|
+
nextState = { passed: false, failures: [] };
|
|
2039
1979
|
}
|
|
2040
1980
|
this.store.cartValidation = nextState;
|
|
2041
1981
|
const changed = previous.passed !== nextState.passed || previous.failures !== nextState.failures;
|
|
2042
1982
|
if (changed) {
|
|
2043
|
-
await this.core.effects.emit(
|
|
1983
|
+
await this.core.effects.emit(import_types.VenueBookingHooks.onCartValidationChanged, {
|
|
2044
1984
|
cartValidation: nextState,
|
|
2045
1985
|
cartValidationPassed: nextState.passed
|
|
2046
1986
|
});
|
|
@@ -2048,20 +1988,15 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
2048
1988
|
return nextState.passed;
|
|
2049
1989
|
}
|
|
2050
1990
|
async setItemRuleRuntimeConfig(config = {}) {
|
|
2051
|
-
|
|
1991
|
+
var _a, _b;
|
|
1992
|
+
this.logMethodStart("setItemRuleRuntimeConfig");
|
|
2052
1993
|
this.itemRuleRuntimeConfig = {
|
|
2053
1994
|
...this.itemRuleRuntimeConfig,
|
|
2054
1995
|
...config,
|
|
2055
|
-
pax: {
|
|
2056
|
-
|
|
2057
|
-
...(config?.pax || {})
|
|
2058
|
-
},
|
|
2059
|
-
custom: {
|
|
2060
|
-
...(this.itemRuleRuntimeConfig?.custom || {}),
|
|
2061
|
-
...(config?.custom || {})
|
|
2062
|
-
}
|
|
1996
|
+
pax: { ...((_a = this.itemRuleRuntimeConfig) == null ? void 0 : _a.pax) || {}, ...(config == null ? void 0 : config.pax) || {} },
|
|
1997
|
+
custom: { ...((_b = this.itemRuleRuntimeConfig) == null ? void 0 : _b.custom) || {}, ...(config == null ? void 0 : config.custom) || {} }
|
|
2063
1998
|
};
|
|
2064
|
-
if (
|
|
1999
|
+
if ("strategyConfigs" in config) {
|
|
2065
2000
|
this.itemRuleConfigs = [];
|
|
2066
2001
|
this.itemRuleConfigsPromise = null;
|
|
2067
2002
|
this.itemRuleEvaluator.setStrategyConfigs([]);
|
|
@@ -2069,54 +2004,54 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
2069
2004
|
this.itemRulePrefillApplied = false;
|
|
2070
2005
|
await this.refreshItemRuleQuantityLimits();
|
|
2071
2006
|
await this.refreshCartValidationPassed();
|
|
2072
|
-
this.logMethodSuccess(
|
|
2007
|
+
this.logMethodSuccess("setItemRuleRuntimeConfig", {
|
|
2073
2008
|
strategyCount: Array.isArray(this.itemRuleRuntimeConfig.strategyConfigs) ? this.itemRuleRuntimeConfig.strategyConfigs.length : 0
|
|
2074
2009
|
});
|
|
2075
2010
|
}
|
|
2076
2011
|
getOtherParams() {
|
|
2077
2012
|
return this.otherParams;
|
|
2078
2013
|
}
|
|
2079
|
-
|
|
2080
|
-
// ─── UI 状态缓存(按 cacheId 分桶,sessionStorage) ───
|
|
2081
|
-
//
|
|
2082
|
-
// 用于物料层持久化 UI 层面的轻量状态(如当前步骤、登录回跳意图等)。
|
|
2083
|
-
// 桶键:pisell.venueBooking.uiState:<cacheId>;内部以 JSON object 形式存储多个字段。
|
|
2084
|
-
// 无 cacheId 时所有方法自动降级为 no-op,上层不用判空。
|
|
2085
|
-
|
|
2086
|
-
static UI_STATE_KEY_PREFIX = 'pisell.venueBooking.uiState:';
|
|
2087
2014
|
getUIStateBucketKey() {
|
|
2088
|
-
if (!this.cacheId)
|
|
2089
|
-
|
|
2015
|
+
if (!this.cacheId)
|
|
2016
|
+
return null;
|
|
2017
|
+
return `${_VenueBookingImpl.UI_STATE_KEY_PREFIX}${this.cacheId}`;
|
|
2090
2018
|
}
|
|
2091
2019
|
readUIStateBucket() {
|
|
2020
|
+
var _a;
|
|
2092
2021
|
const key = this.getUIStateBucketKey();
|
|
2093
|
-
if (!key || !this.window
|
|
2022
|
+
if (!key || !((_a = this.window) == null ? void 0 : _a.sessionStorage))
|
|
2023
|
+
return {};
|
|
2094
2024
|
try {
|
|
2095
|
-
const raw = this.window.sessionStorage.getItem(key) ||
|
|
2025
|
+
const raw = this.window.sessionStorage.getItem(key) || "{}";
|
|
2096
2026
|
const parsed = JSON.parse(raw);
|
|
2097
|
-
return parsed && typeof parsed ===
|
|
2027
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
2098
2028
|
} catch {
|
|
2099
2029
|
return {};
|
|
2100
2030
|
}
|
|
2101
2031
|
}
|
|
2102
2032
|
writeUIStateBucket(bucket) {
|
|
2033
|
+
var _a;
|
|
2103
2034
|
const key = this.getUIStateBucketKey();
|
|
2104
|
-
if (!key || !this.window
|
|
2035
|
+
if (!key || !((_a = this.window) == null ? void 0 : _a.sessionStorage))
|
|
2036
|
+
return;
|
|
2105
2037
|
this.window.sessionStorage.setItem(key, JSON.stringify(bucket));
|
|
2106
2038
|
}
|
|
2107
2039
|
setUIState(key, value) {
|
|
2108
|
-
if (!this.getUIStateBucketKey())
|
|
2040
|
+
if (!this.getUIStateBucketKey())
|
|
2041
|
+
return;
|
|
2109
2042
|
const bucket = this.readUIStateBucket();
|
|
2110
2043
|
bucket[key] = value;
|
|
2111
2044
|
this.writeUIStateBucket(bucket);
|
|
2112
2045
|
}
|
|
2113
2046
|
getUIState(key) {
|
|
2114
|
-
if (!this.getUIStateBucketKey())
|
|
2047
|
+
if (!this.getUIStateBucketKey())
|
|
2048
|
+
return void 0;
|
|
2115
2049
|
const bucket = this.readUIStateBucket();
|
|
2116
2050
|
return bucket[key];
|
|
2117
2051
|
}
|
|
2118
2052
|
deleteUIState(key) {
|
|
2119
|
-
if (!this.getUIStateBucketKey())
|
|
2053
|
+
if (!this.getUIStateBucketKey())
|
|
2054
|
+
return;
|
|
2120
2055
|
const bucket = this.readUIStateBucket();
|
|
2121
2056
|
if (key in bucket) {
|
|
2122
2057
|
delete bucket[key];
|
|
@@ -2124,70 +2059,84 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
|
|
|
2124
2059
|
}
|
|
2125
2060
|
}
|
|
2126
2061
|
setBookingHolder(bookingUid, holder) {
|
|
2127
|
-
|
|
2062
|
+
var _a, _b, _c, _d;
|
|
2063
|
+
if (!this.store.order)
|
|
2064
|
+
return;
|
|
2128
2065
|
const tempOrder = this.store.order.ensureTempOrder();
|
|
2129
|
-
const booking = tempOrder.bookings
|
|
2066
|
+
const booking = (_a = tempOrder.bookings) == null ? void 0 : _a.find(
|
|
2067
|
+
(b) => {
|
|
2068
|
+
var _a2;
|
|
2069
|
+
return ((_a2 = b.metadata) == null ? void 0 : _a2.unique_identification_number) === bookingUid;
|
|
2070
|
+
}
|
|
2071
|
+
);
|
|
2130
2072
|
if (booking) {
|
|
2131
2073
|
booking.holder = holder;
|
|
2132
2074
|
}
|
|
2133
2075
|
for (const product of tempOrder.products) {
|
|
2134
2076
|
const runtimeProduct = product;
|
|
2135
|
-
const productBookingUid = runtimeProduct.metadata
|
|
2136
|
-
if (String(productBookingUid) !== String(bookingUid))
|
|
2137
|
-
|
|
2077
|
+
const productBookingUid = ((_b = runtimeProduct.metadata) == null ? void 0 : _b.booking_uid) ?? ((_d = (_c = runtimeProduct._origin) == null ? void 0 : _c.product) == null ? void 0 : _d.bookingUuid);
|
|
2078
|
+
if (String(productBookingUid) !== String(bookingUid))
|
|
2079
|
+
continue;
|
|
2080
|
+
const origin = runtimeProduct._origin && typeof runtimeProduct._origin === "object" ? runtimeProduct._origin : {};
|
|
2138
2081
|
origin.holder = holder;
|
|
2139
2082
|
runtimeProduct._origin = origin;
|
|
2140
2083
|
}
|
|
2141
2084
|
this.store.order.notifyTempOrderChanged();
|
|
2142
2085
|
}
|
|
2143
|
-
|
|
2144
2086
|
/**
|
|
2145
2087
|
* 获取 holder 表单 map
|
|
2146
2088
|
*/
|
|
2147
2089
|
getHolderFormMap() {
|
|
2148
|
-
if (!this.store.holder)
|
|
2090
|
+
if (!this.store.holder)
|
|
2091
|
+
throw new Error("[VenueBooking] holder 模块未初始化");
|
|
2149
2092
|
return this.store.holder.getHolderFormMap();
|
|
2150
2093
|
}
|
|
2151
|
-
|
|
2152
2094
|
/**
|
|
2153
2095
|
* UI 层触发:按当前 holderMap 批量刷新所有表单的 records
|
|
2154
2096
|
*/
|
|
2155
2097
|
async refreshAllHolderFormRecords(params) {
|
|
2156
|
-
if (!this.store.holder)
|
|
2157
|
-
|
|
2098
|
+
if (!this.store.holder)
|
|
2099
|
+
throw new Error("[VenueBooking] holder 模块未初始化");
|
|
2100
|
+
const customer_id = (params == null ? void 0 : params.customer_id) ?? this.resolveHolderCustomerId();
|
|
2158
2101
|
return this.store.holder.refreshAllFormRecords({
|
|
2159
2102
|
...params,
|
|
2160
2103
|
customer_id,
|
|
2161
|
-
useCache: params
|
|
2104
|
+
useCache: (params == null ? void 0 : params.useCache) ?? false
|
|
2162
2105
|
});
|
|
2163
2106
|
}
|
|
2164
|
-
|
|
2165
2107
|
/**
|
|
2166
2108
|
* 添加表单记录
|
|
2167
2109
|
*/
|
|
2168
2110
|
appendFormRecord(params) {
|
|
2169
|
-
if (!this.store.holder)
|
|
2111
|
+
if (!this.store.holder)
|
|
2112
|
+
throw new Error("[VenueBooking] holder 模块未初始化");
|
|
2170
2113
|
return this.store.holder.appendFormRecord(params);
|
|
2171
2114
|
}
|
|
2172
|
-
|
|
2173
2115
|
// ─── OpenData 可用性 ───
|
|
2174
|
-
|
|
2175
2116
|
async checkOpenDataAvailability() {
|
|
2176
|
-
if (!this.store.openData)
|
|
2117
|
+
if (!this.store.openData)
|
|
2118
|
+
throw new Error("openData 模块未初始化");
|
|
2177
2119
|
await this.loadOpenDataConfig();
|
|
2178
2120
|
return this.store.openData.checkAvailability(this.store.schedule);
|
|
2179
2121
|
}
|
|
2180
|
-
async setOtherParams(params, {
|
|
2181
|
-
cover = false
|
|
2182
|
-
} = {}) {
|
|
2122
|
+
async setOtherParams(params, { cover = false } = {}) {
|
|
2183
2123
|
if (cover) {
|
|
2184
2124
|
this.otherParams = params;
|
|
2185
2125
|
} else {
|
|
2186
|
-
this.otherParams = {
|
|
2187
|
-
...this.otherParams,
|
|
2188
|
-
...params
|
|
2189
|
-
};
|
|
2126
|
+
this.otherParams = { ...this.otherParams, ...params };
|
|
2190
2127
|
}
|
|
2191
2128
|
}
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2129
|
+
};
|
|
2130
|
+
var VenueBookingImpl = _VenueBookingImpl;
|
|
2131
|
+
VenueBookingImpl.OPEN_DATA_CACHE_TTL = 5 * 60 * 1e3;
|
|
2132
|
+
// ─── UI 状态缓存(按 cacheId 分桶,sessionStorage) ───
|
|
2133
|
+
//
|
|
2134
|
+
// 用于物料层持久化 UI 层面的轻量状态(如当前步骤、登录回跳意图等)。
|
|
2135
|
+
// 桶键:pisell.venueBooking.uiState:<cacheId>;内部以 JSON object 形式存储多个字段。
|
|
2136
|
+
// 无 cacheId 时所有方法自动降级为 no-op,上层不用判空。
|
|
2137
|
+
VenueBookingImpl.UI_STATE_KEY_PREFIX = "pisell.venueBooking.uiState:";
|
|
2138
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2139
|
+
0 && (module.exports = {
|
|
2140
|
+
VenueBookingImpl,
|
|
2141
|
+
...require("./types")
|
|
2142
|
+
});
|