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