@pisell/pisellos 2.2.278 → 2.2.280

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 (188) hide show
  1. package/dist/modules/BaseModule.d.ts +1 -0
  2. package/dist/modules/BaseModule.js +24 -28
  3. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +7 -3
  4. package/dist/modules/BookingContext/utils/productExtend.js +5 -9
  5. package/dist/modules/BookingContext/utils/timeSlices.js +24 -3
  6. package/dist/modules/Customer/index.d.ts +4 -0
  7. package/dist/modules/Customer/index.js +91 -59
  8. package/dist/modules/Customer/types.d.ts +2 -0
  9. package/dist/modules/Discount/index.d.ts +1 -0
  10. package/dist/modules/Discount/index.js +40 -11
  11. package/dist/modules/Discount/types.d.ts +1 -0
  12. package/dist/modules/Holder/index.d.ts +48 -0
  13. package/dist/modules/Holder/index.js +640 -0
  14. package/dist/modules/Holder/types.d.ts +123 -0
  15. package/dist/modules/Holder/types.js +1 -0
  16. package/dist/modules/Holder/utils.d.ts +13 -0
  17. package/dist/modules/Holder/utils.js +34 -0
  18. package/dist/modules/OpenData/index.js +2 -2
  19. package/dist/modules/Order/index.d.ts +32 -4
  20. package/dist/modules/Order/index.js +868 -675
  21. package/dist/modules/Order/types.d.ts +22 -1
  22. package/dist/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
  23. package/dist/modules/Order/utils/discountProductLineIdentity.js +227 -0
  24. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
  25. package/dist/modules/Order/utils/orderCollectionIdentity.js +75 -0
  26. package/dist/modules/Order/utils.d.ts +10 -0
  27. package/dist/modules/Order/utils.js +71 -34
  28. package/dist/modules/Payment/index.d.ts +4 -0
  29. package/dist/modules/Payment/index.js +14 -4
  30. package/dist/modules/Payment/walletpass.js +21 -7
  31. package/dist/modules/Product/types.d.ts +1 -0
  32. package/dist/modules/ProductList/index.js +33 -13
  33. package/dist/modules/Quotation/index.d.ts +1 -1
  34. package/dist/modules/Quotation/index.js +2 -2
  35. package/dist/modules/ResourcePlanner/index.d.ts +24 -0
  36. package/dist/modules/ResourcePlanner/index.js +181 -0
  37. package/dist/modules/ResourcePlanner/planner.d.ts +14 -0
  38. package/dist/modules/ResourcePlanner/planner.js +1069 -0
  39. package/dist/modules/ResourcePlanner/types.d.ts +227 -0
  40. package/dist/modules/ResourcePlanner/types.js +1 -0
  41. package/dist/modules/Rules/index.js +153 -56
  42. package/dist/modules/SalesSummary/index.js +12 -13
  43. package/dist/modules/ScanOrderLogger/index.d.ts +2 -0
  44. package/dist/modules/ScanOrderLogger/index.js +15 -2
  45. package/dist/modules/ScanOrderLogger/providers/feishu.js +45 -27
  46. package/dist/modules/ScanOrderLogger/types.d.ts +1 -0
  47. package/dist/modules/Schedule/index.d.ts +3 -1
  48. package/dist/modules/Schedule/index.js +21 -16
  49. package/dist/modules/Summary/utils.js +38 -13
  50. package/dist/modules/index.d.ts +2 -0
  51. package/dist/modules/index.js +3 -1
  52. package/dist/plugins/window.d.ts +1 -0
  53. package/dist/server/index.d.ts +20 -0
  54. package/dist/server/index.js +1101 -909
  55. package/dist/server/modules/order/index.d.ts +2 -0
  56. package/dist/server/modules/order/index.js +261 -96
  57. package/dist/server/modules/order/types.d.ts +1 -1
  58. package/dist/solution/BaseSales/index.d.ts +20 -1
  59. package/dist/solution/BaseSales/index.js +989 -881
  60. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -1
  61. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  62. package/dist/solution/BaseSales/utils.js +31 -20
  63. package/dist/solution/BookingByStep/index.d.ts +17 -2
  64. package/dist/solution/BookingByStep/index.js +294 -215
  65. package/dist/solution/BookingByStep/types.d.ts +2 -1
  66. package/dist/solution/BookingByStep/types.js +3 -1
  67. package/dist/solution/BookingByStep/utils/capacity.js +17 -1
  68. package/dist/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  69. package/dist/solution/BookingByStep/utils/timeslots.js +19 -12
  70. package/dist/solution/BookingTicket/index.d.ts +21 -3
  71. package/dist/solution/BookingTicket/index.js +312 -226
  72. package/dist/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  73. package/dist/solution/BookingTicket/utils/scan/handleScan.js +10 -2
  74. package/dist/solution/ScanOrder/index.d.ts +26 -14
  75. package/dist/solution/ScanOrder/index.js +1142 -739
  76. package/dist/solution/ScanOrder/types.d.ts +21 -1
  77. package/dist/solution/ScanOrder/utils.d.ts +8 -0
  78. package/dist/solution/ScanOrder/utils.js +97 -45
  79. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  80. package/dist/solution/ShopDiscount/index.js +125 -87
  81. package/dist/solution/UnifiedBookingSales/index.d.ts +204 -0
  82. package/dist/solution/UnifiedBookingSales/index.js +2211 -0
  83. package/dist/solution/UnifiedBookingSales/types.d.ts +150 -0
  84. package/dist/solution/UnifiedBookingSales/types.js +11 -0
  85. package/dist/solution/VenueBooking/index.d.ts +39 -11
  86. package/dist/solution/VenueBooking/index.js +1167 -841
  87. package/dist/solution/VenueBooking/types.d.ts +3 -0
  88. package/dist/solution/VenueBooking/utils/resource.js +1 -0
  89. package/dist/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  90. package/dist/solution/VenueBooking/utils/slotMerge.js +10 -5
  91. package/dist/solution/index.d.ts +1 -0
  92. package/dist/solution/index.js +2 -1
  93. package/dist/types/index.d.ts +1 -0
  94. package/lib/model/strategy/adapter/promotion/index.js +0 -51
  95. package/lib/modules/BaseModule.d.ts +1 -0
  96. package/lib/modules/BaseModule.js +24 -37
  97. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +3 -0
  98. package/lib/modules/BookingContext/utils/productExtend.js +4 -3
  99. package/lib/modules/BookingContext/utils/timeSlices.js +18 -3
  100. package/lib/modules/Customer/index.d.ts +4 -0
  101. package/lib/modules/Customer/index.js +11 -0
  102. package/lib/modules/Customer/types.d.ts +2 -0
  103. package/lib/modules/Discount/index.d.ts +1 -0
  104. package/lib/modules/Discount/index.js +9 -0
  105. package/lib/modules/Discount/types.d.ts +1 -0
  106. package/lib/modules/Holder/index.d.ts +48 -0
  107. package/lib/modules/Holder/index.js +402 -0
  108. package/lib/modules/Holder/types.d.ts +123 -0
  109. package/lib/modules/Holder/types.js +17 -0
  110. package/lib/modules/Holder/utils.d.ts +13 -0
  111. package/lib/modules/Holder/utils.js +71 -0
  112. package/lib/modules/OpenData/index.js +1 -1
  113. package/lib/modules/Order/index.d.ts +32 -4
  114. package/lib/modules/Order/index.js +372 -156
  115. package/lib/modules/Order/types.d.ts +22 -1
  116. package/lib/modules/Order/utils/discountProductLineIdentity.d.ts +45 -0
  117. package/lib/modules/Order/utils/discountProductLineIdentity.js +170 -0
  118. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +15 -0
  119. package/lib/modules/Order/utils/orderCollectionIdentity.js +70 -0
  120. package/lib/modules/Order/utils.d.ts +10 -0
  121. package/lib/modules/Order/utils.js +39 -6
  122. package/lib/modules/Payment/index.d.ts +4 -0
  123. package/lib/modules/Payment/index.js +7 -0
  124. package/lib/modules/Payment/walletpass.js +12 -0
  125. package/lib/modules/Product/types.d.ts +1 -0
  126. package/lib/modules/ProductList/index.js +49 -31
  127. package/lib/modules/Quotation/index.d.ts +1 -1
  128. package/lib/modules/Quotation/index.js +2 -2
  129. package/lib/modules/ResourcePlanner/index.d.ts +24 -0
  130. package/lib/modules/ResourcePlanner/index.js +148 -0
  131. package/lib/modules/ResourcePlanner/planner.d.ts +14 -0
  132. package/lib/modules/ResourcePlanner/planner.js +933 -0
  133. package/lib/modules/ResourcePlanner/types.d.ts +227 -0
  134. package/lib/modules/ResourcePlanner/types.js +17 -0
  135. package/lib/modules/Rules/index.js +117 -25
  136. package/lib/modules/SalesSummary/index.js +6 -7
  137. package/lib/modules/ScanOrderLogger/index.d.ts +2 -0
  138. package/lib/modules/ScanOrderLogger/index.js +13 -1
  139. package/lib/modules/ScanOrderLogger/providers/feishu.js +15 -6
  140. package/lib/modules/ScanOrderLogger/types.d.ts +1 -0
  141. package/lib/modules/Schedule/index.d.ts +3 -1
  142. package/lib/modules/Schedule/index.js +10 -8
  143. package/lib/modules/Summary/utils.js +21 -1
  144. package/lib/modules/index.d.ts +2 -0
  145. package/lib/modules/index.js +5 -1
  146. package/lib/plugins/window.d.ts +1 -0
  147. package/lib/server/index.d.ts +20 -0
  148. package/lib/server/index.js +124 -19
  149. package/lib/server/modules/order/index.d.ts +2 -0
  150. package/lib/server/modules/order/index.js +75 -5
  151. package/lib/server/modules/order/types.d.ts +1 -1
  152. package/lib/solution/BaseSales/index.d.ts +20 -1
  153. package/lib/solution/BaseSales/index.js +105 -31
  154. package/lib/solution/BaseSales/utils/cartPromotion.js +18 -0
  155. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +1 -0
  156. package/lib/solution/BaseSales/utils.js +29 -18
  157. package/lib/solution/BookingByStep/index.d.ts +17 -2
  158. package/lib/solution/BookingByStep/index.js +60 -18
  159. package/lib/solution/BookingByStep/types.d.ts +2 -1
  160. package/lib/solution/BookingByStep/types.js +5 -0
  161. package/lib/solution/BookingByStep/utils/capacity.js +20 -1
  162. package/lib/solution/BookingByStep/utils/timeslots.d.ts +3 -1
  163. package/lib/solution/BookingByStep/utils/timeslots.js +19 -11
  164. package/lib/solution/BookingTicket/index.d.ts +21 -3
  165. package/lib/solution/BookingTicket/index.js +75 -16
  166. package/lib/solution/BookingTicket/utils/scan/handleScan.d.ts +3 -1
  167. package/lib/solution/BookingTicket/utils/scan/handleScan.js +2 -2
  168. package/lib/solution/ScanOrder/index.d.ts +26 -14
  169. package/lib/solution/ScanOrder/index.js +449 -182
  170. package/lib/solution/ScanOrder/types.d.ts +21 -1
  171. package/lib/solution/ScanOrder/utils.d.ts +8 -0
  172. package/lib/solution/ScanOrder/utils.js +60 -18
  173. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  174. package/lib/solution/ShopDiscount/index.js +14 -0
  175. package/lib/solution/UnifiedBookingSales/index.d.ts +204 -0
  176. package/lib/solution/UnifiedBookingSales/index.js +1273 -0
  177. package/lib/solution/UnifiedBookingSales/types.d.ts +150 -0
  178. package/lib/solution/UnifiedBookingSales/types.js +33 -0
  179. package/lib/solution/VenueBooking/index.d.ts +39 -11
  180. package/lib/solution/VenueBooking/index.js +322 -110
  181. package/lib/solution/VenueBooking/types.d.ts +3 -0
  182. package/lib/solution/VenueBooking/utils/resource.js +1 -0
  183. package/lib/solution/VenueBooking/utils/slotMerge.d.ts +4 -4
  184. package/lib/solution/VenueBooking/utils/slotMerge.js +6 -4
  185. package/lib/solution/index.d.ts +1 -0
  186. package/lib/solution/index.js +3 -1
  187. package/lib/types/index.d.ts +1 -0
  188. package/package.json +1 -1
@@ -89,6 +89,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
89
89
  }
90
90
  const moduleArr = [
91
91
  "accountList",
92
+ "holder",
92
93
  "cart",
93
94
  "schedule",
94
95
  "summary",
@@ -379,6 +380,27 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
379
380
  }
380
381
  return this.store.accountList.fetchHolderAccounts(params);
381
382
  }
383
+ /**
384
+ * 获取 holder 表单 map
385
+ */
386
+ getHolderFormMap() {
387
+ return this.store.holder.getHolderFormMap();
388
+ }
389
+ /**
390
+ * 登录后或外部触发时,按当前 holderMap 批量刷新所有表单的 records
391
+ */
392
+ async refreshAllHolderFormRecords(params) {
393
+ return this.store.holder.refreshAllFormRecords({
394
+ customer_id: params == null ? void 0 : params.customer_id,
395
+ useCache: false
396
+ });
397
+ }
398
+ /**
399
+ * 添加表单记录
400
+ */
401
+ appendFormRecord(params) {
402
+ return this.store.holder.appendFormRecord(params);
403
+ }
382
404
  // 设置日期范围,注入到日期模块中
383
405
  async setDateRange(dateRange) {
384
406
  this.store.date.setDateRange(dateRange);
@@ -486,6 +508,14 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
486
508
  date = (normalProductCartItem == null ? void 0 : normalProductCartItem.start_date) || "";
487
509
  }
488
510
  this.updateQuotationPriceAndCart(date);
511
+ try {
512
+ const customerId = Number(accountInfo.id);
513
+ await this.refreshAllHolderFormRecords({
514
+ customer_id: customerId
515
+ });
516
+ } catch (error) {
517
+ console.error("[BookingByStep] 登录后刷新 holder 表单失败", error);
518
+ }
489
519
  }
490
520
  } else {
491
521
  throw new Error(`没有找到${accountId}账户`);
@@ -512,10 +542,11 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
512
542
  }
513
543
  // 购物车提交订单
514
544
  async submitOrder(extraData) {
545
+ var _a;
515
546
  const cartItems = this.store.cart.getItems();
516
547
  const newCartItems = (0, import_lodash_es.cloneDeep)(cartItems);
517
548
  newCartItems.forEach((item) => {
518
- var _a;
549
+ var _a2;
519
550
  if (item._origin.resources && item._origin.resources.length) {
520
551
  item._origin.resources = item._origin.resources.map((n) => {
521
552
  const newResourcesItem = (0, import_lodash_es.cloneDeep)(n);
@@ -525,7 +556,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
525
556
  return { ...newResourcesItem };
526
557
  });
527
558
  const { currentCapacity, formatCapacity } = (0, import_capacity.getCapacityInfoByCartItem)(item);
528
- if (!((_a = item._origin) == null ? void 0 : _a.metadata)) {
559
+ if (!((_a2 = item._origin) == null ? void 0 : _a2.metadata)) {
529
560
  item._origin.metadata = {};
530
561
  }
531
562
  item._origin.metadata.capacity = formatCapacity;
@@ -543,6 +574,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
543
574
  cartItems: newCartItems,
544
575
  type,
545
576
  platform: this.platform,
577
+ business_code: (_a = this.otherParams) == null ? void 0 : _a.business_code,
546
578
  extraData
547
579
  }
548
580
  });
@@ -628,6 +660,15 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
628
660
  account = activeAccount;
629
661
  }
630
662
  }
663
+ try {
664
+ this.store.holder.ensureFormByProduct({
665
+ product: productData,
666
+ shop_id: (productData == null ? void 0 : productData.shop_id) || "",
667
+ useCache: true
668
+ });
669
+ } catch (error) {
670
+ console.error("[BookingByStep] 加载 holder 表单失败", error);
671
+ }
631
672
  const flag = this.store.cart.mergeCartItemByRowKey({
632
673
  rowKey,
633
674
  quantity,
@@ -1150,7 +1191,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1150
1191
  }
1151
1192
  const totalCapacity = (countMap[n.id] || []).reduce(
1152
1193
  (sum, item) => {
1153
- const hasOverlap = !(0, import_dayjs.default)(item.time.start_at).isAfter((0, import_dayjs.default)(timeSlots.start_at)) && !(0, import_dayjs.default)(item.time.end_at).isBefore((0, import_dayjs.default)(timeSlots.end_at));
1194
+ const hasOverlap = (0, import_dayjs.default)(item.time.start_at).isBefore((0, import_dayjs.default)(timeSlots.end_at)) && (0, import_dayjs.default)(item.time.end_at).isAfter((0, import_dayjs.default)(timeSlots.start_at));
1154
1195
  return hasOverlap ? sum + item.pax : sum;
1155
1196
  },
1156
1197
  0
@@ -1232,9 +1273,10 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1232
1273
  }
1233
1274
  );
1234
1275
  cartItems2.forEach((item, index) => {
1235
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1276
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1236
1277
  const { currentCapacity } = (0, import_capacity.getCapacityInfoByCartItem)(item);
1237
- if (item._origin.start_time && !(timeSlots == null ? void 0 : timeSlots.start_time)) {
1278
+ const hasOriginTimeSlot = Boolean(item._origin.start_time) && Boolean(item._origin.end_time) && !(timeSlots == null ? void 0 : timeSlots.start_time);
1279
+ if (hasOriginTimeSlot) {
1238
1280
  recordTimeSlots = {
1239
1281
  start_time: item._origin.start_time,
1240
1282
  end_time: item._origin.end_time,
@@ -1246,13 +1288,11 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1246
1288
  const currentResourceConfig = (_c = (_b = (_a2 = item._productOrigin) == null ? void 0 : _a2.product_resource) == null ? void 0 : _b.resources) == null ? void 0 : _c.find(
1247
1289
  (n) => n.code === resources_code
1248
1290
  );
1249
- if (index !== 0 && recordTimeSlots && (currentResourceConfig == null ? void 0 : currentResourceConfig.type) === "single" && ((_d = item._productOrigin) == null ? void 0 : _d.duration) && !hasFlexibleProduct) {
1250
- let start_at = (0, import_dayjs.default)(recordTimeSlots.end_time).add(
1251
- ((_f = (_e = item._productOrigin) == null ? void 0 : _e.duration) == null ? void 0 : _f.value) || 10,
1252
- "minutes"
1253
- );
1291
+ if (index !== 0 && recordTimeSlots && (currentResourceConfig == null ? void 0 : currentResourceConfig.type) === "single" && ((_d = item._productOrigin) == null ? void 0 : _d.duration) && !hasFlexibleProduct && !hasOriginTimeSlot) {
1292
+ const recordEndAt = recordTimeSlots.end_at ? (0, import_dayjs.default)(recordTimeSlots.end_at) : (0, import_dayjs.default)(`${item.start_date} ${recordTimeSlots.end_time}`);
1293
+ let start_at = recordEndAt;
1254
1294
  let end_at = start_at.add(
1255
- ((_h = (_g = item._productOrigin) == null ? void 0 : _g.duration) == null ? void 0 : _h.value) || 10,
1295
+ ((_f = (_e = item._productOrigin) == null ? void 0 : _e.duration) == null ? void 0 : _f.value) || 10,
1256
1296
  "minutes"
1257
1297
  );
1258
1298
  recordTimeSlots = {
@@ -1306,7 +1346,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1306
1346
  const allCartItems = (0, import_lodash_es.cloneDeep)(this.store.cart.getItems());
1307
1347
  let selectedResources = [];
1308
1348
  const resources2 = (0, import_lodash_es.cloneDeep)(
1309
- ((_j = (_i = item._productOrigin) == null ? void 0 : _i.product_resource) == null ? void 0 : _j.resources) || []
1349
+ ((_h = (_g = item._productOrigin) == null ? void 0 : _g.product_resource) == null ? void 0 : _h.resources) || []
1310
1350
  );
1311
1351
  const currentResourcesRenderList = [];
1312
1352
  resources2.forEach((n) => {
@@ -1354,11 +1394,11 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1354
1394
  return recordCount >= currentCapacity;
1355
1395
  });
1356
1396
  });
1357
- const targetRenderList = (_k = productResources.find(
1397
+ const targetRenderList = (_i = productResources.find(
1358
1398
  (n) => n.code === resources_code
1359
- )) == null ? void 0 : _k.renderList;
1399
+ )) == null ? void 0 : _i.renderList;
1360
1400
  if (targetRenderList && targetRenderList.length > 0) {
1361
- if ((_l = item._origin.resources) == null ? void 0 : _l.some(
1401
+ if ((_j = item._origin.resources) == null ? void 0 : _j.some(
1362
1402
  (n) => n.form_id === targetRenderList[0].form_id
1363
1403
  )) {
1364
1404
  return;
@@ -1366,7 +1406,9 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1366
1406
  const fastestResource = (0, import_timeslots.findFastestAvailableResource)({
1367
1407
  resources: targetRenderList,
1368
1408
  currentCapacity,
1369
- countMap: selectResourcesMap
1409
+ countMap: selectResourcesMap,
1410
+ targetDate: (_k = dateRange == null ? void 0 : dateRange[0]) == null ? void 0 : _k.date,
1411
+ durationMinutes: ((_l = item == null ? void 0 : item.duration) == null ? void 0 : _l.value) || ((_n = (_m = item == null ? void 0 : item._productOrigin) == null ? void 0 : _m.duration) == null ? void 0 : _n.value) || 10
1370
1412
  });
1371
1413
  const targetResource = fastestResource || targetRenderList[0];
1372
1414
  targetResource.capacity = currentCapacity;
@@ -1403,7 +1445,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1403
1445
  return { errorList };
1404
1446
  }
1405
1447
  // 从购物车中获取已经分配好第一步资源的所有时间片
1406
- getTimeSlotByAllResources(resources_code) {
1448
+ getTimeSlotByAllResources(resources_code, split = 10) {
1407
1449
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1408
1450
  let dateRange = this.store.date.getDateRange();
1409
1451
  const resources = [];
@@ -1561,7 +1603,7 @@ var BookingByStepImpl = class extends import_BaseModule.BaseModule {
1561
1603
  resourcesMap,
1562
1604
  duration,
1563
1605
  currentDate: dateRange[0].date,
1564
- split: 10,
1606
+ split,
1565
1607
  resourcesUseableMap,
1566
1608
  capacity: maxCapacity,
1567
1609
  cut_off_time: maxCutOffTime,
@@ -1,4 +1,4 @@
1
- import { ProductList, CartModule, ProductData, AccountModule, AccountListModule, DateModule, GuestListModule, OrderModule, PaymentModule, ResourceListModule, StepModule, SummaryModule, SalesSummaryModule, ScheduleModule, ScanOrderLoggerModule } from '../../modules';
1
+ import { ProductList, CartModule, ProductData, AccountModule, AccountListModule, DateModule, GuestListModule, OrderModule, PaymentModule, ResourceListModule, StepModule, SummaryModule, SalesSummaryModule, ScheduleModule, ScanOrderLoggerModule, HolderModule } from '../../modules';
2
2
  export interface BookingByStepState {
3
3
  cart: CartModule;
4
4
  summary: SummaryModule;
@@ -16,6 +16,7 @@ export interface BookingByStepState {
16
16
  schedule: ScheduleModule;
17
17
  salesSummary?: SalesSummaryModule;
18
18
  scanOrderLogger?: ScanOrderLoggerModule;
19
+ holder: HolderModule;
19
20
  }
20
21
  export declare function createModule<T extends keyof BookingByStepState>(moduleName: T, solutionName: string, name?: string, version?: string): BookingByStepState[T];
21
22
  export declare enum BookingByStepHooks {
@@ -81,6 +81,11 @@ function createModule(moduleName, solutionName, name, version) {
81
81
  `${solutionName}_${name || moduleName}`,
82
82
  version
83
83
  );
84
+ case "holder":
85
+ return new import_modules.HolderModule(
86
+ `${solutionName}_${name || moduleName}`,
87
+ version
88
+ );
84
89
  default:
85
90
  throw new Error(`Unknown module type: ${moduleName}`);
86
91
  }
@@ -49,8 +49,27 @@ var formatDefaultCapacitys = ({
49
49
  const id = d.bundle_product_id;
50
50
  const variantId = d.bundle_variant_id;
51
51
  const item = ((capacity == null ? void 0 : capacity.package) || []).find(
52
- (item2) => item2.product_id === id || item2.product_id === variantId
52
+ (item2) => item2.product_id == id || item2.product_id == variantId
53
53
  );
54
+ if (!item && (window == null ? void 0 : window.sendWarningLog)) {
55
+ window.sendWarningLog({
56
+ title: "未找到套餐 capacity 配置",
57
+ content: [
58
+ {
59
+ key: "product_id",
60
+ value: id
61
+ },
62
+ {
63
+ key: "variant_id",
64
+ value: variantId
65
+ },
66
+ {
67
+ key: "package",
68
+ value: JSON.stringify((capacity == null ? void 0 : capacity.package) || [])
69
+ }
70
+ ]
71
+ });
72
+ }
54
73
  return {
55
74
  id,
56
75
  value: item ? d.num || 0 : 0,
@@ -19,10 +19,12 @@ export declare function calculateResourceAvailableTime({ resource, timeSlots, cu
19
19
  * @param countMap 已预约数量映射
20
20
  * @returns 最快可用的资源
21
21
  */
22
- export declare function findFastestAvailableResource({ resources, currentCapacity, countMap, }: {
22
+ export declare function findFastestAvailableResource({ resources, currentCapacity, countMap, targetDate, durationMinutes, }: {
23
23
  resources: ResourceItem[];
24
24
  currentCapacity?: number;
25
25
  countMap?: Record<number, number>;
26
+ targetDate?: string | Dayjs;
27
+ durationMinutes?: number;
26
28
  }): ResourceItem | null;
27
29
  /**
28
30
  * 给定一个时间列表,通过开始和结束时间过滤出符合条件的时间段
@@ -77,10 +77,15 @@ function calculateResourceAvailableTime({
77
77
  function findFastestAvailableResource({
78
78
  resources,
79
79
  currentCapacity = 1,
80
- countMap = {}
80
+ countMap = {},
81
+ targetDate,
82
+ durationMinutes = 30
81
83
  }) {
82
84
  var _a, _b, _c;
83
85
  const currentTime = (0, import_dayjs.default)();
86
+ const resolvedDuration = durationMinutes > 0 ? durationMinutes : 30;
87
+ const targetDay = targetDate ? (0, import_dayjs.default)(targetDate) : currentTime;
88
+ const isTargetDayToday = targetDay.isSame(currentTime, "day");
84
89
  let fastestTime = null;
85
90
  let fastestResources = [];
86
91
  console.log("[TimeslotUtils] 查找最快可用资源:", {
@@ -90,19 +95,22 @@ function findFastestAvailableResource({
90
95
  countMap
91
96
  });
92
97
  for (const resource of resources) {
93
- const todayTimes = resource.times.filter((time) => {
94
- const isToday = (0, import_dayjs.default)(time.start_at).isSame(currentTime, "day");
95
- const isStillWorking = (0, import_dayjs.default)(time.end_at).isAfter(currentTime);
96
- return isToday && isStillWorking;
98
+ const targetDayTimes = resource.times.filter((time) => {
99
+ const isSameTargetDay = (0, import_dayjs.default)(time.start_at).isSame(targetDay, "day");
100
+ if (!isSameTargetDay)
101
+ return false;
102
+ if (!isTargetDayToday)
103
+ return true;
104
+ return (0, import_dayjs.default)(time.end_at).isAfter(currentTime);
97
105
  });
98
- if (todayTimes.length === 0) {
106
+ if (targetDayTimes.length === 0) {
99
107
  console.log(`[TimeslotUtils] 资源 ${resource.id}(${resource.main_field}) 今日无可用时间段`);
100
108
  continue;
101
109
  }
102
- for (const time of todayTimes) {
110
+ for (const time of targetDayTimes) {
103
111
  const workStartTime = (0, import_dayjs.default)(time.start_at);
104
112
  const workEndTime = (0, import_dayjs.default)(time.end_at);
105
- let nextAvailableTime = currentTime.isBefore(workStartTime) ? workStartTime : currentTime;
113
+ let nextAvailableTime = isTargetDayToday && currentTime.isAfter(workStartTime) ? currentTime : workStartTime;
106
114
  console.log(`[TimeslotUtils] 检查资源 ${resource.id}(${resource.main_field}):`, {
107
115
  workTime: `${workStartTime.format("HH:mm")}-${workEndTime.format("HH:mm")}`,
108
116
  checkStartTime: nextAvailableTime.format("HH:mm:ss"),
@@ -126,7 +134,7 @@ function findFastestAvailableResource({
126
134
  pax: event.pax || 1
127
135
  });
128
136
  if (resource.resourceType === "single" || (resource.capacity || 1) === 1) {
129
- if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(30, "minute"))) {
137
+ if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(resolvedDuration, "minute"))) {
130
138
  finalAvailableTime = eventEnd;
131
139
  console.log(`[TimeslotUtils] 发现时间冲突,调整到: ${finalAvailableTime.format("HH:mm:ss")}`);
132
140
  }
@@ -134,7 +142,7 @@ function findFastestAvailableResource({
134
142
  const totalCapacity = resource.capacity || 0;
135
143
  const currentUsedCapacity = countMap[resource.id] || 0;
136
144
  const eventUsedCapacity = event.pax || 1;
137
- if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(30, "minute"))) {
145
+ if (finalAvailableTime.isBefore(eventEnd) && eventStart.isBefore(finalAvailableTime.add(resolvedDuration, "minute"))) {
138
146
  const totalRequiredCapacity = currentUsedCapacity + currentCapacity + eventUsedCapacity;
139
147
  if (totalRequiredCapacity > totalCapacity) {
140
148
  finalAvailableTime = eventEnd;
@@ -143,7 +151,7 @@ function findFastestAvailableResource({
143
151
  }
144
152
  }
145
153
  }
146
- if (finalAvailableTime.isAfter(workEndTime)) {
154
+ if (finalAvailableTime.add(resolvedDuration, "minute").isAfter(workEndTime)) {
147
155
  console.log(`[TimeslotUtils] 资源 ${resource.id} 可用时间超出工作时间,跳过`);
148
156
  continue;
149
157
  }
@@ -29,6 +29,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
29
29
  private addTimeProductsCatalog;
30
30
  private orderCustomerDiscountRefreshInFlight;
31
31
  private orderCustomerDiscountRefreshCustomerId;
32
+ private orderCustomerPromotionRefreshInFlight;
32
33
  private loadOpenDataConfigInFlight;
33
34
  /**
34
35
  * 在 BaseSales 默认模块清单(products/order/salesSummary/schedule)基础上追加 customer + bookingContext。
@@ -63,6 +64,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
63
64
  scanPromotionCode(code: string, customerId?: number): Promise<BaseSalesScanCodeResult>;
64
65
  private hydrateOrderCustomerFromScanDiscounts;
65
66
  private getDiscountCustomerId;
67
+ resolveCustomerById(customerId: string | number): Promise<ICustomer | null>;
68
+ /** 兼容既有优惠码扫码逻辑。 */
66
69
  private resolveCustomerByDiscountCustomerId;
67
70
  private findCustomerById;
68
71
  private normalizeCustomer;
@@ -282,7 +285,10 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
282
285
  restoreOrder(): Promise<import("../../modules/Order/types").OrderTempOrder>;
283
286
  /** 内部:基于 OrderModule 当前状态构造一份 OrderCustomerChangePayload。 */
284
287
  private buildOrderCustomerPayload;
285
- private refreshDiscountConfigAfterOrderCustomerChange;
288
+ protected refreshDiscountConfigAfterOrderCustomerChange(customerId: number | null): Promise<void>;
289
+ protected waitForOrderCustomerPromotionRefresh(): Promise<void>;
290
+ protected prepareProductPriceQueryContext(customerId?: number | string): Promise<void>;
291
+ protected preferAuthoritativeProductQueryPrice(): boolean;
286
292
  /**
287
293
  * 获取客户分页信息
288
294
  * @returns 分页信息
@@ -326,7 +332,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
326
332
  * 获取当前的客户搜索条件
327
333
  * @returns 当前搜索条件
328
334
  */
329
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
335
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
330
336
  /**
331
337
  * 获取客户列表状态(包含滚动加载相关状态)
332
338
  * @returns 客户状态
@@ -445,7 +451,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
445
451
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
446
452
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
447
453
  */
448
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
454
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
455
+ action: "reloadCatalog";
456
+ } | {
457
+ action: "add";
458
+ cacheItem: any;
459
+ } | {
460
+ action: "requiresDetail";
461
+ payload: AddProductRequiresDetailPayload;
462
+ } | {
463
+ action: "requiresBookingEdit";
464
+ cacheItem: any;
465
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
466
+ };
449
467
  /** 规格弹窗 callback 后的第二段决策。 */
450
468
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
451
469
  /**
@@ -56,6 +56,7 @@ var import_utils = require("../../modules/Order/utils");
56
56
  __reExport(BookingTicket_exports, require("./types"), module.exports);
57
57
  var OPEN_DATA_SECTION_CODES = ["sale", "reservation", "fulfillment", "menu", "workflow"];
58
58
  var OPEN_DATA_CACHE_TTL = 5 * 60 * 1e3;
59
+ var USER_PLATFORM = ["pc", "h5"];
59
60
  function resolveBookingUidForAddTime(booking) {
60
61
  var _a;
61
62
  const uid = (_a = booking == null ? void 0 : booking.metadata) == null ? void 0 : _a.unique_identification_number;
@@ -135,6 +136,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
135
136
  this.addTimeProductsCatalog = [];
136
137
  this.orderCustomerDiscountRefreshInFlight = null;
137
138
  this.orderCustomerDiscountRefreshCustomerId = null;
139
+ this.orderCustomerPromotionRefreshInFlight = null;
138
140
  this.loadOpenDataConfigInFlight = null;
139
141
  }
140
142
  /**
@@ -240,6 +242,11 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
240
242
  }
241
243
  async configureIdGeneratorFromOpenData() {
242
244
  this.setPaymentNumberDevicePrefix(null);
245
+ const idGenerator = this.getIdGeneratorPlugin();
246
+ if (!(idGenerator == null ? void 0 : idGenerator.configure)) {
247
+ console.warn("[BookingTicket] idGenerator 插件不可用,跳过配置");
248
+ return;
249
+ }
243
250
  let openDataConfig = null;
244
251
  try {
245
252
  openDataConfig = await this.loadOpenDataConfig();
@@ -247,11 +254,6 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
247
254
  console.warn("[BookingTicket] OpenData 配置加载失败,跳过 idGenerator 配置", error);
248
255
  return;
249
256
  }
250
- const idGenerator = this.getIdGeneratorPlugin();
251
- if (!(idGenerator == null ? void 0 : idGenerator.configure)) {
252
- console.warn("[BookingTicket] idGenerator 插件不可用,跳过配置");
253
- return;
254
- }
255
257
  const receiptSequenceLength = this.normalizePositiveInteger(
256
258
  openDataConfig == null ? void 0 : openDataConfig["sale.short_number_digits"],
257
259
  5
@@ -352,7 +354,8 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
352
354
  const scannedList = raw.scannedDiscountList || [];
353
355
  const extractedCustomerId = this.getDiscountCustomerId(scannedList);
354
356
  const hasOrderCustomer = Boolean(this.store.order.getOrderCustomer());
355
- if (!hasOrderCustomer && extractedCustomerId) {
357
+ const isUserPlatform = USER_PLATFORM.includes(this.otherParams.platform);
358
+ if (!hasOrderCustomer && extractedCustomerId && !isUserPlatform) {
356
359
  await this.hydrateOrderCustomerFromScanDiscounts(scannedList);
357
360
  }
358
361
  if (raw.isAvailable) {
@@ -396,7 +399,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
396
399
  }
397
400
  return null;
398
401
  }
399
- async resolveCustomerByDiscountCustomerId(customerId) {
402
+ async resolveCustomerById(customerId) {
400
403
  var _a;
401
404
  const localCustomers = this.store.customer.getCustomers();
402
405
  const localCustomer = this.findCustomerById(localCustomers, customerId);
@@ -410,7 +413,23 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
410
413
  num: 1
411
414
  });
412
415
  const remoteCustomer = this.findCustomerById((result == null ? void 0 : result.list) || [], customerId) || ((_a = result == null ? void 0 : result.list) == null ? void 0 : _a[0]) || null;
413
- return remoteCustomer ? this.normalizeCustomer(remoteCustomer) : null;
416
+ if (remoteCustomer) {
417
+ return this.normalizeCustomer(remoteCustomer);
418
+ }
419
+ try {
420
+ const detailCustomer = await this.store.customer.queryCustomerDetail(customerId);
421
+ return detailCustomer ? this.normalizeCustomer(detailCustomer) : null;
422
+ } catch (error) {
423
+ console.warn(
424
+ "[BookingTicket] resolveCustomerById detail request failed",
425
+ { customerId, error }
426
+ );
427
+ return null;
428
+ }
429
+ }
430
+ /** 兼容既有优惠码扫码逻辑。 */
431
+ resolveCustomerByDiscountCustomerId(customerId) {
432
+ return this.resolveCustomerById(customerId);
414
433
  }
415
434
  findCustomerById(customers = [], customerId) {
416
435
  return customers.find((customer) => {
@@ -899,9 +918,21 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
899
918
  const next = this.buildOrderCustomerPayload();
900
919
  this.core.effects.emit(`${this.name}:onOrderCustomerChange`, next);
901
920
  this.refreshDiscountConfigAfterOrderCustomerChange(patch.customer_id);
902
- void this.store.order.applyPromotion().catch((error) => {
903
- console.error("[BookingTicket] applyPromotion after customer change failed", error);
904
- });
921
+ const promotionRefreshTask = this.store.order.applyPromotion().then(() => void 0);
922
+ this.orderCustomerPromotionRefreshInFlight = promotionRefreshTask;
923
+ void promotionRefreshTask.then(
924
+ () => {
925
+ if (this.orderCustomerPromotionRefreshInFlight !== promotionRefreshTask)
926
+ return;
927
+ this.orderCustomerPromotionRefreshInFlight = null;
928
+ },
929
+ (error) => {
930
+ console.error("[BookingTicket] applyPromotion after customer change failed", error);
931
+ if (this.orderCustomerPromotionRefreshInFlight !== promotionRefreshTask)
932
+ return;
933
+ this.orderCustomerPromotionRefreshInFlight = null;
934
+ }
935
+ );
905
936
  }
906
937
  /**
907
938
  * 读取 tempOrder 上的下单客户协议字段;customer_id 缺失时返回 null。
@@ -971,12 +1002,13 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
971
1002
  }
972
1003
  refreshDiscountConfigAfterOrderCustomerChange(customerId) {
973
1004
  if (!customerId || customerId === 1)
974
- return;
1005
+ return Promise.resolve();
975
1006
  if (this.orderCustomerDiscountRefreshInFlight && this.orderCustomerDiscountRefreshCustomerId === customerId) {
976
- return;
1007
+ return this.orderCustomerDiscountRefreshInFlight;
977
1008
  }
978
1009
  const previousRefresh = this.orderCustomerDiscountRefreshInFlight;
979
1010
  const refreshTask = (async () => {
1011
+ var _a, _b, _c, _d;
980
1012
  if (previousRefresh) {
981
1013
  await previousRefresh.catch(() => void 0);
982
1014
  }
@@ -984,7 +1016,10 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
984
1016
  if (!currentCustomer || Number(currentCustomer.customer_id) !== customerId) {
985
1017
  return;
986
1018
  }
987
- await this.loadDiscountConfig({ customerId });
1019
+ const tempOrder = (_b = (_a = this.store.order).getTempOrder) == null ? void 0 : _b.call(_a);
1020
+ const orderId = (tempOrder == null ? void 0 : tempOrder.order_id) || ((_d = (_c = this.getOrderIdentity) == null ? void 0 : _c.call(this)) == null ? void 0 : _d.orderId);
1021
+ const action = !orderId || String(orderId).startsWith("local_order") ? "create" : "edit";
1022
+ await this.loadDiscountConfig({ customerId, action });
988
1023
  })();
989
1024
  this.orderCustomerDiscountRefreshInFlight = refreshTask;
990
1025
  this.orderCustomerDiscountRefreshCustomerId = customerId;
@@ -996,6 +1031,22 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
996
1031
  this.orderCustomerDiscountRefreshInFlight = null;
997
1032
  this.orderCustomerDiscountRefreshCustomerId = null;
998
1033
  });
1034
+ return refreshTask;
1035
+ }
1036
+ waitForOrderCustomerPromotionRefresh() {
1037
+ return this.orderCustomerPromotionRefreshInFlight || Promise.resolve();
1038
+ }
1039
+ async prepareProductPriceQueryContext(customerId) {
1040
+ await Promise.resolve();
1041
+ const normalizedCustomerId = Number(customerId || 0);
1042
+ const refreshTask = this.orderCustomerDiscountRefreshInFlight;
1043
+ const shouldWait = normalizedCustomerId > 1 && this.orderCustomerDiscountRefreshCustomerId === normalizedCustomerId && Boolean(refreshTask);
1044
+ if (shouldWait && refreshTask) {
1045
+ await refreshTask;
1046
+ }
1047
+ }
1048
+ preferAuthoritativeProductQueryPrice() {
1049
+ return true;
999
1050
  }
1000
1051
  /**
1001
1052
  * 获取客户分页信息
@@ -1093,7 +1144,11 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1093
1144
  */
1094
1145
  scanGlobalListener(callback) {
1095
1146
  const localSearch = (v) => this.store.products.findProductsByCodeOrBarcode(v);
1096
- const scanCallback = (0, import_handleScan.handleGlobalScan)(this.request, localSearch);
1147
+ const scanCallback = (0, import_handleScan.handleGlobalScan)(
1148
+ this.request,
1149
+ localSearch,
1150
+ this.getSubmitOrderSalesChannel()
1151
+ );
1097
1152
  const safeCallback = (d) => {
1098
1153
  try {
1099
1154
  callback(d);
@@ -1422,7 +1477,11 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1422
1477
  }
1423
1478
  try {
1424
1479
  const localSearch = (v) => this.store.products.findProductsByCodeOrBarcode(v);
1425
- const scanCallback = (0, import_handleScan.handleGlobalScan)(this.request, localSearch);
1480
+ const scanCallback = (0, import_handleScan.handleGlobalScan)(
1481
+ this.request,
1482
+ localSearch,
1483
+ this.getSubmitOrderSalesChannel()
1484
+ );
1426
1485
  const raw = await scanCallback({ type: "nativeScanner", value: trimmed });
1427
1486
  const formatted = (0, import_formatGlobalScan.formatGlobalScanResult)(raw, trimmed);
1428
1487
  if (!formatted) {
@@ -2,9 +2,11 @@ import { RequestPlugin } from '../../../../plugins';
2
2
  /**
3
3
  * 处理全局扫码
4
4
  * @param request 请求插件
5
+ * @param localSearch 本地商品搜索
6
+ * @param channel 当前销售渠道
5
7
  * @returns 处理结果
6
8
  */
7
- export declare const handleGlobalScan: (request: RequestPlugin, localSearch: (v: string) => any[]) => (scanResult: {
9
+ export declare const handleGlobalScan: (request: RequestPlugin, localSearch: (v: string) => any[], channel?: string) => (scanResult: {
8
10
  type: string;
9
11
  value: string;
10
12
  }) => Promise<any>;
@@ -102,14 +102,14 @@ var handleScanFn = (getRequestList, localSearch) => {
102
102
  }
103
103
  };
104
104
  };
105
- var handleGlobalScan = (request, localSearch) => {
105
+ var handleGlobalScan = (request, localSearch, channel) => {
106
106
  const getRequestList = (value) => {
107
107
  let requestList = [];
108
108
  if (value.startsWith("WL")) {
109
109
  requestList = [(0, import_cloudSearch.searchWallet)(request, value)];
110
110
  } else {
111
111
  requestList = [
112
- (0, import_cloudSearch.searchOrder)(request, value),
112
+ ...channel === "kiosk" ? [] : [(0, import_cloudSearch.searchOrder)(request, value)],
113
113
  (0, import_cloudSearch.searchWalletPass)(request, value),
114
114
  (0, import_cloudSearch.searchWallet)(request, value),
115
115
  (0, import_cloudSearch.searchProduct)(request, value)