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