@pisell/pisellos 0.0.567 → 0.0.568

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