@pisell/pisellos 2.3.74 → 2.3.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/core/index.js +6 -10
  2. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  3. package/dist/model/strategy/adapter/walletPass/example.js +3 -26
  4. package/dist/model/strategy/strategy-example.js +5 -19
  5. package/dist/modules/Cart/index.js +0 -3
  6. package/dist/modules/Cart/utils/cartProduct.js +0 -1
  7. package/dist/modules/Date/index.js +1 -5
  8. package/dist/modules/Discount/index.js +2 -4
  9. package/dist/modules/OpenData/index.js +0 -2
  10. package/dist/modules/Order/index.d.ts +1 -1
  11. package/dist/modules/Order/index.js +75 -91
  12. package/dist/modules/Order/types.d.ts +3 -1
  13. package/dist/modules/Payment/index.js +97 -162
  14. package/dist/modules/Rules/index.js +1 -4
  15. package/dist/modules/Schedule/index.js +0 -1
  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 +97 -129
  21. package/dist/server/modules/menu/index.js +32 -41
  22. package/dist/server/modules/order/index.js +2 -4
  23. package/dist/server/modules/products/index.js +24 -42
  24. package/dist/server/modules/quotation/index.js +29 -38
  25. package/dist/server/modules/resource/index.js +3 -4
  26. package/dist/server/modules/schedule/index.js +27 -35
  27. package/dist/server/utils/product.js +0 -1
  28. package/dist/solution/BaseSales/index.js +100 -72
  29. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
  30. package/dist/solution/BaseSales/utils/cartPromotion.js +15 -6
  31. package/dist/solution/BookingByStep/index.js +7 -59
  32. package/dist/solution/BookingByStep/utils/capacity.js +1 -11
  33. package/dist/solution/BookingByStep/utils/resources.js +1 -3
  34. package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
  35. package/dist/solution/BookingTicket/index.js +0 -2
  36. package/dist/solution/BookingTicket/utils/scan/cloudSearch.js +6 -7
  37. package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
  38. package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
  39. package/dist/solution/BuyTickets/index.js +9 -12
  40. package/dist/solution/Checkout/index.js +177 -252
  41. package/dist/solution/Checkout/utils/index.js +4 -16
  42. package/dist/solution/RegisterAndLogin/index.js +30 -76
  43. package/dist/solution/ScanOrder/index.js +50 -60
  44. package/dist/solution/ShopDiscount/index.js +2 -7
  45. package/dist/solution/VenueBooking/index.js +45 -55
  46. package/dist/utils/task.js +15 -18
  47. package/dist/utils/watch.js +0 -1
  48. package/lib/apis/picoding.js +2 -0
  49. package/lib/core/index.js +134 -134
  50. package/lib/effects/index.js +46 -57
  51. package/lib/index.js +82 -49
  52. package/lib/model/index.js +14 -21
  53. package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
  54. package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
  55. package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
  56. package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
  57. package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
  58. package/lib/model/strategy/adapter/index.js +100 -64
  59. package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
  60. package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
  61. package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
  62. package/lib/model/strategy/adapter/itemRule/index.js +83 -57
  63. package/lib/model/strategy/adapter/itemRule/type.js +97 -36
  64. package/lib/model/strategy/adapter/promotion/adapter.js +91 -69
  65. package/lib/model/strategy/adapter/promotion/evaluator.js +444 -310
  66. package/lib/model/strategy/adapter/promotion/examples.js +222 -234
  67. package/lib/model/strategy/adapter/promotion/index.js +1 -0
  68. package/lib/model/strategy/adapter/promotion/type.js +243 -36
  69. package/lib/model/strategy/adapter/type.js +4 -16
  70. package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -150
  71. package/lib/model/strategy/adapter/walletPass/example.js +217 -190
  72. package/lib/model/strategy/adapter/walletPass/index.js +75 -51
  73. package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
  74. package/lib/model/strategy/adapter/walletPass/type.js +4 -16
  75. package/lib/model/strategy/adapter/walletPass/utils.js +588 -378
  76. package/lib/model/strategy/engine.js +270 -168
  77. package/lib/model/strategy/index.js +49 -34
  78. package/lib/model/strategy/strategy-example.js +243 -239
  79. package/lib/model/strategy/type.js +100 -40
  80. package/lib/modules/Account/index.js +39 -53
  81. package/lib/modules/Account/types.js +20 -33
  82. package/lib/modules/AccountList/index.js +116 -154
  83. package/lib/modules/AccountList/types.js +30 -31
  84. package/lib/modules/AccountList/utils.js +18 -30
  85. package/lib/modules/BaseModule.js +23 -42
  86. package/lib/modules/BookingContext/index.js +158 -136
  87. package/lib/modules/BookingContext/types.js +46 -32
  88. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +138 -146
  89. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +78 -83
  90. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +170 -150
  91. package/lib/modules/BookingContext/utils/flexible.js +38 -55
  92. package/lib/modules/BookingContext/utils/formatResourceList.js +19 -34
  93. package/lib/modules/BookingContext/utils/index.js +124 -41
  94. package/lib/modules/BookingContext/utils/noResource.js +58 -70
  95. package/lib/modules/BookingContext/utils/orderLineDisplay.js +14 -41
  96. package/lib/modules/BookingContext/utils/productExtend.js +202 -155
  97. package/lib/modules/BookingContext/utils/resourceErrors.js +53 -53
  98. package/lib/modules/BookingContext/utils/resourceSelection.js +19 -41
  99. package/lib/modules/BookingContext/utils/resources.js +209 -167
  100. package/lib/modules/BookingContext/utils/serviceTimes.js +115 -116
  101. package/lib/modules/BookingContext/utils/timeSlices.js +76 -86
  102. package/lib/modules/Cart/index.js +170 -124
  103. package/lib/modules/Cart/types.js +46 -51
  104. package/lib/modules/Cart/utils/cartAccount.js +40 -39
  105. package/lib/modules/Cart/utils/cartDate.js +56 -61
  106. package/lib/modules/Cart/utils/cartDiscount.js +28 -33
  107. package/lib/modules/Cart/utils/cartNote.js +27 -32
  108. package/lib/modules/Cart/utils/cartProduct.js +321 -251
  109. package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
  110. package/lib/modules/Cart/utils/cartResource.js +70 -78
  111. package/lib/modules/Cart/utils/changePrice.js +22 -50
  112. package/lib/modules/Cart/utils/index.js +106 -48
  113. package/lib/modules/Customer/constants.js +13 -34
  114. package/lib/modules/Customer/index.js +235 -172
  115. package/lib/modules/Customer/types.js +38 -35
  116. package/lib/modules/Date/index.js +116 -115
  117. package/lib/modules/Date/types.js +16 -28
  118. package/lib/modules/Date/utils.js +174 -123
  119. package/lib/modules/Discount/index.js +122 -127
  120. package/lib/modules/Discount/types.js +9 -31
  121. package/lib/modules/Guests/index.js +30 -56
  122. package/lib/modules/Guests/types.js +23 -33
  123. package/lib/modules/Holder/index.js +209 -189
  124. package/lib/modules/Holder/types.js +4 -16
  125. package/lib/modules/Holder/utils.js +20 -49
  126. package/lib/modules/OpenData/index.js +70 -76
  127. package/lib/modules/OpenData/types.js +4 -16
  128. package/lib/modules/OpenData/utils.js +44 -78
  129. package/lib/modules/Order/index.d.ts +1 -1
  130. package/lib/modules/Order/index.js +1733 -2121
  131. package/lib/modules/Order/payment-utils.js +77 -120
  132. package/lib/modules/Order/types.d.ts +3 -1
  133. package/lib/modules/Order/types.js +88 -35
  134. package/lib/modules/Order/utils/bundleDiscountHydration.js +41 -74
  135. package/lib/modules/Order/utils/discountProductLineIdentity.js +142 -100
  136. package/lib/modules/Order/utils/manualProductDiscount.js +124 -123
  137. package/lib/modules/Order/utils/orderCollectionIdentity.js +184 -244
  138. package/lib/modules/Order/utils.js +814 -647
  139. package/lib/modules/Payment/cash.js +20 -33
  140. package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
  141. package/lib/modules/Payment/eftpos.js +16 -30
  142. package/lib/modules/Payment/index.js +532 -399
  143. package/lib/modules/Payment/mx51.js +1 -0
  144. package/lib/modules/Payment/types.js +230 -108
  145. package/lib/modules/Payment/utils.js +52 -51
  146. package/lib/modules/Payment/walletpass.js +485 -660
  147. package/lib/modules/Product/index.js +51 -46
  148. package/lib/modules/Product/types.js +4 -16
  149. package/lib/modules/Product/utils.js +32 -33
  150. package/lib/modules/ProductList/index.js +113 -123
  151. package/lib/modules/ProductList/types.js +9 -31
  152. package/lib/modules/Quotation/index.js +81 -118
  153. package/lib/modules/Quotation/types.js +4 -16
  154. package/lib/modules/Resource/index.js +27 -59
  155. package/lib/modules/Resource/types.js +22 -32
  156. package/lib/modules/Resource/utils.js +30 -38
  157. package/lib/modules/ResourcePlanner/index.js +25 -23
  158. package/lib/modules/ResourcePlanner/localClock.js +54 -119
  159. package/lib/modules/ResourcePlanner/planner.js +589 -770
  160. package/lib/modules/ResourcePlanner/types.js +10 -29
  161. package/lib/modules/Rules/index.js +1218 -959
  162. package/lib/modules/Rules/types.js +17 -40
  163. package/lib/modules/SalesSummary/index.js +85 -90
  164. package/lib/modules/SalesSummary/types.js +4 -16
  165. package/lib/modules/SalesSummary/utils.js +355 -430
  166. package/lib/modules/ScanOrderLogger/index.js +59 -79
  167. package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
  168. package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
  169. package/lib/modules/ScanOrderLogger/types.js +4 -16
  170. package/lib/modules/Schedule/getDateIsInSchedule.js +334 -163
  171. package/lib/modules/Schedule/index.js +100 -114
  172. package/lib/modules/Schedule/type.js +4 -16
  173. package/lib/modules/Schedule/types.js +4 -16
  174. package/lib/modules/Schedule/utils.js +433 -291
  175. package/lib/modules/Step/index.js +40 -52
  176. package/lib/modules/Step/tyeps.js +4 -16
  177. package/lib/modules/Summary/index.js +66 -71
  178. package/lib/modules/Summary/types.js +4 -16
  179. package/lib/modules/Summary/utils.js +773 -418
  180. package/lib/modules/SurchargeList/index.js +46 -60
  181. package/lib/modules/SurchargeList/types.js +4 -16
  182. package/lib/modules/index.js +245 -63
  183. package/lib/plugins/app.js +4 -16
  184. package/lib/plugins/index.js +36 -25
  185. package/lib/plugins/request.js +137 -126
  186. package/lib/plugins/shopStore.js +4 -16
  187. package/lib/plugins/user.js +4 -16
  188. package/lib/plugins/window.js +171 -179
  189. package/lib/server/index.js +3050 -2665
  190. package/lib/server/modules/floor-plan/index.js +118 -134
  191. package/lib/server/modules/floor-plan/types.js +15 -30
  192. package/lib/server/modules/index.js +106 -68
  193. package/lib/server/modules/menu/index.js +142 -122
  194. package/lib/server/modules/menu/types.js +18 -31
  195. package/lib/server/modules/order/index.js +784 -1002
  196. package/lib/server/modules/order/types.js +122 -33
  197. package/lib/server/modules/order/utils/filterBookings.js +219 -194
  198. package/lib/server/modules/order/utils/filterOrders.js +118 -92
  199. package/lib/server/modules/payment/index.js +59 -83
  200. package/lib/server/modules/payment/types.js +4 -16
  201. package/lib/server/modules/products/index.js +583 -471
  202. package/lib/server/modules/products/types.js +44 -34
  203. package/lib/server/modules/quotation/index.js +137 -172
  204. package/lib/server/modules/quotation/types.js +21 -31
  205. package/lib/server/modules/resource/index.js +220 -186
  206. package/lib/server/modules/resource/types.js +42 -33
  207. package/lib/server/modules/schedule/index.js +135 -123
  208. package/lib/server/modules/schedule/types.js +14 -21
  209. package/lib/server/modules/schedule/utils.js +334 -163
  210. package/lib/server/types.js +4 -16
  211. package/lib/server/utils/index.js +25 -23
  212. package/lib/server/utils/product.js +196 -139
  213. package/lib/server/utils/schedule.js +34 -41
  214. package/lib/server/utils/small-ticket.js +479 -456
  215. package/lib/server/utils/time.js +40 -49
  216. package/lib/solution/BaseSales/index.js +1220 -1412
  217. package/lib/solution/BaseSales/types.js +42 -38
  218. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +5 -0
  219. package/lib/solution/BaseSales/utils/cartPromotion.js +652 -498
  220. package/lib/solution/BaseSales/utils/parseSalesResponse.js +85 -105
  221. package/lib/solution/BaseSales/utils/quotationPrice.js +56 -114
  222. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +108 -145
  223. package/lib/solution/BaseSales/utils.js +158 -143
  224. package/lib/solution/BookingByStep/index.js +1527 -1340
  225. package/lib/solution/BookingByStep/types.js +40 -99
  226. package/lib/solution/BookingByStep/utils/capacity.js +192 -160
  227. package/lib/solution/BookingByStep/utils/products.js +42 -52
  228. package/lib/solution/BookingByStep/utils/resources.js +527 -330
  229. package/lib/solution/BookingByStep/utils/stock.js +65 -44
  230. package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
  231. package/lib/solution/BookingTicket/index.js +607 -522
  232. package/lib/solution/BookingTicket/types.js +99 -77
  233. package/lib/solution/BookingTicket/utils/addProductDecision.js +226 -189
  234. package/lib/solution/BookingTicket/utils/addTimeAvailability.js +58 -89
  235. package/lib/solution/BookingTicket/utils/bookingStatus.js +107 -78
  236. package/lib/solution/BookingTicket/utils/cartView.js +114 -99
  237. package/lib/solution/BookingTicket/utils/exampleData.js +185 -0
  238. package/lib/solution/BookingTicket/utils/orderCustomer.js +18 -41
  239. package/lib/solution/BookingTicket/utils/resolveBestAddTimePlan.js +219 -86
  240. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +168 -116
  241. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +79 -91
  242. package/lib/solution/BookingTicket/utils/scan/formatGlobalScan.js +54 -41
  243. package/lib/solution/BookingTicket/utils/scan/handleScan.js +84 -81
  244. package/lib/solution/BookingTicket/utils/scan/index.js +98 -104
  245. package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
  246. package/lib/solution/BookingTicket/utils/scan/scanProductValues.js +52 -64
  247. package/lib/solution/BookingTicket/utils/sessionCatalogStale.js +56 -58
  248. package/lib/solution/BookingTicket/utils/weighingProductSku.js +34 -48
  249. package/lib/solution/BuyTickets/index.js +67 -70
  250. package/lib/solution/BuyTickets/types.js +22 -38
  251. package/lib/solution/Checkout/index.js +1451 -1158
  252. package/lib/solution/Checkout/types.js +91 -61
  253. package/lib/solution/Checkout/utils/index.js +228 -156
  254. package/lib/solution/PlaceOrder/index.js +55 -0
  255. package/lib/solution/RegisterAndLogin/config.js +493 -460
  256. package/lib/solution/RegisterAndLogin/index.js +633 -630
  257. package/lib/solution/RegisterAndLogin/types.js +189 -76
  258. package/lib/solution/RegisterAndLogin/utils.js +183 -125
  259. package/lib/solution/Sales/index.js +328 -324
  260. package/lib/solution/Sales/types.js +27 -33
  261. package/lib/solution/ScanOrder/index.js +832 -864
  262. package/lib/solution/ScanOrder/types.js +33 -34
  263. package/lib/solution/ScanOrder/utils.js +409 -374
  264. package/lib/solution/ShopDiscount/index.js +226 -232
  265. package/lib/solution/ShopDiscount/types.js +15 -37
  266. package/lib/solution/ShopDiscount/utils.js +300 -172
  267. package/lib/solution/UnifiedBookingSales/index.js +1035 -1201
  268. package/lib/solution/UnifiedBookingSales/remoteOccupancyCache.js +99 -159
  269. package/lib/solution/UnifiedBookingSales/types.js +10 -32
  270. package/lib/solution/VenueBooking/index.js +811 -879
  271. package/lib/solution/VenueBooking/types.js +19 -39
  272. package/lib/solution/VenueBooking/utils/dateSummary.js +27 -56
  273. package/lib/solution/VenueBooking/utils/resource.js +31 -54
  274. package/lib/solution/VenueBooking/utils/slotMerge.js +94 -107
  275. package/lib/solution/VenueBooking/utils/timeSlot.js +132 -132
  276. package/lib/solution/VenueBooking/utils.js +130 -67
  277. package/lib/solution/index.js +124 -41
  278. package/lib/store/createStore.js +32 -29
  279. package/lib/types/index.js +4 -16
  280. package/lib/utils/payment-number.js +26 -46
  281. package/lib/utils/task.js +36 -36
  282. package/lib/utils/watch.js +81 -47
  283. package/package.json +2 -1
@@ -1,107 +1,143 @@
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
-
29
- // src/solution/BookingByStep/utils/resources.ts
30
- var resources_exports = {};
31
- __export(resources_exports, {
32
- checkSessionProductLeadTime: () => checkSessionProductLeadTime,
33
- checkTwoResourcesIntersection: () => checkTwoResourcesIntersection,
34
- filterResourcesByFormItem: () => filterResourcesByFormItem,
35
- filterScheduleByDateRange: () => filterScheduleByDateRange,
36
- formatResources: () => formatResources,
37
- getIsUsableByTimeItem: () => getIsUsableByTimeItem,
38
- getOthersCartSelectedResources: () => getOthersCartSelectedResources,
39
- getOthersSelectedResources: () => getOthersSelectedResources,
40
- getResourcesByIds: () => getResourcesByIds,
41
- getResourcesByProduct: () => getResourcesByProduct,
42
- getResourcesIdsByProduct: () => getResourcesIdsByProduct,
43
- getTimeSlicesByResource: () => getTimeSlicesByResource,
44
- getTimeSlicesByResources: () => getTimeSlicesByResources,
45
- getTimesIntersection: () => getTimesIntersection,
46
- isConflict: () => isConflict,
47
- mergeSubResourcesTimeSlices: () => mergeSubResourcesTimeSlices,
48
- sortCombinedResources: () => sortCombinedResources
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
49
5
  });
50
- module.exports = __toCommonJS(resources_exports);
51
- var import_dayjs = __toESM(require("dayjs"));
52
- var getUseableEventCount = (eventList, current) => {
6
+ exports.checkSessionProductLeadTime = checkSessionProductLeadTime;
7
+ exports.checkTwoResourcesIntersection = checkTwoResourcesIntersection;
8
+ exports.filterResourcesByFormItem = filterResourcesByFormItem;
9
+ exports.filterScheduleByDateRange = filterScheduleByDateRange;
10
+ exports.getResourcesByProduct = exports.getResourcesByIds = exports.getOthersSelectedResources = exports.getOthersCartSelectedResources = exports.getIsUsableByTimeItem = exports.formatResources = void 0;
11
+ exports.getResourcesIdsByProduct = getResourcesIdsByProduct;
12
+ exports.mergeSubResourcesTimeSlices = exports.isConflict = exports.getTimesIntersection = exports.getTimeSlicesByResources = exports.getTimeSlicesByResource = void 0;
13
+ exports.sortCombinedResources = sortCombinedResources;
14
+ var _dayjs = _interopRequireDefault(require("dayjs"));
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+ /**
17
+ * 1. 获取资源列表
18
+ * 2. 根据当前选择的商品过滤出来对应的资源列表 getResourcesByProduct
19
+ * 3. 格式化资源相关 格式化资源列表 --> 格式化资源 --> 获取时间切片列表 --> 判断单个时间切片是否可用 formatResources
20
+ *
21
+ */
22
+
23
+ /**
24
+ * @title: 获取重叠剩余量
25
+ * @description:
26
+ * @param {any} eventList
27
+ * @param {number} current
28
+ * @return {*}
29
+ * @Author: zhiwei.Wang
30
+ */
31
+ const getUseableEventCount = (eventList, current) => {
53
32
  return (eventList || []).reduce((pre, event) => {
54
33
  return pre - event.pax;
55
34
  }, current || 0);
56
35
  };
57
- var isConflict = (event, current) => {
58
- const eventStart = (0, import_dayjs.default)(event.start_at);
59
- const eventEnd = (0, import_dayjs.default)(event.end_at);
60
- const currentStart = (0, import_dayjs.default)(current.start_at);
36
+
37
+ /**
38
+ * @title: 判断两个时间段是否有重叠
39
+ * @description:
40
+ * @param {object} event
41
+ * @param {object} current
42
+ * @return {*}
43
+ * @Author: zhiwei.Wang
44
+ */
45
+ const isConflict = (event, current) => {
46
+ const eventStart = (0, _dayjs.default)(event.start_at);
47
+ const eventEnd = (0, _dayjs.default)(event.end_at);
48
+ const currentStart = (0, _dayjs.default)(current.start_at);
61
49
  const _isBefore = currentStart.isBefore(eventEnd);
62
50
  let _isAfter = true;
51
+
52
+ // 如果传递结束时间,则比对结束时间
63
53
  if (current.end_at) {
64
- const currentEnd = (0, import_dayjs.default)(current.end_at);
54
+ const currentEnd = (0, _dayjs.default)(current.end_at);
65
55
  _isAfter = currentEnd.isAfter(eventStart);
66
56
  }
57
+
58
+ // 检查是否有重叠
67
59
  return _isBefore && _isAfter;
68
60
  };
69
- var checkAfterToDay = (date, today = (0, import_dayjs.default)()) => {
70
- return (0, import_dayjs.default)(date).isAfter((0, import_dayjs.default)(today));
61
+
62
+ /**
63
+ * @title: 判断传入日期是否在当前日期之后
64
+ * @description:
65
+ * @param {any} date
66
+ * @param {any} today
67
+ * @return {*}
68
+ * @Author: zhiwei.Wang
69
+ */
70
+ exports.isConflict = isConflict;
71
+ const checkAfterToDay = (date, today = (0, _dayjs.default)()) => {
72
+ return (0, _dayjs.default)(date).isAfter((0, _dayjs.default)(today));
71
73
  };
72
- var formatResource = (resourceItem, booking) => {
73
- let _resourceItem = { ...resourceItem };
74
+
75
+ /**
76
+ * @title: 格式化资源, 添加自定义参数
77
+ * @description:
78
+ * @param {any} resourceItem
79
+ * @return {*}
80
+ * @Author: zhiwei.Wang
81
+ * @Date: 2024-01-09 13:40
82
+ */
83
+ const formatResource = (resourceItem, booking) => {
84
+ // 当前资源
85
+ let _resourceItem = {
86
+ ...resourceItem
87
+ };
88
+
89
+ // 格式化times里面的数据
74
90
  _resourceItem.timeSlices = getTimeSlicesByResource({
75
91
  resource: _resourceItem,
76
92
  duration: booking.duration,
77
93
  split: 10,
78
- currentDate: (0, import_dayjs.default)().format("YYYY-MM-DD")
94
+ currentDate: (0, _dayjs.default)().format('YYYY-MM-DD')
79
95
  });
96
+
97
+ // 格式化label
80
98
  _resourceItem.labelText = _resourceItem.main_field;
81
99
  return _resourceItem;
82
100
  };
83
- var checkCapacity = ({
101
+
102
+ /**
103
+ * @title: 判断资源容量是否可用
104
+ * @description:
105
+ * @param {object} param1
106
+ * @return {*}
107
+ * @Author: zhiwei.Wang
108
+ */
109
+ const checkCapacity = ({
84
110
  event_list,
85
111
  timeSlice,
86
112
  resource,
87
113
  currentCount = 1
88
114
  }) => {
89
- const isMultipleBooking = resource.resourceType === "multiple";
115
+ // 单个预约:如果当前资源容量不足以满足需求的容量,且当前资源是没有被占用的,返回资源不可用标记,但在外部运算会通过 reason=capacityOnly 来处理组合资源可用
116
+ // 多个预约:只需判断容量是否足够
117
+ const isMultipleBooking = resource.resourceType === 'multiple';
90
118
  if (currentCount > resource.capacity && (isMultipleBooking || !isMultipleBooking && event_list.length === 0)) {
91
119
  return {
92
120
  status: false,
93
121
  capacity: resource.capacity,
94
- reason: "capacityOnly"
122
+ reason: 'capacityOnly'
95
123
  };
96
124
  }
97
- let conflict = (event_list || []).filter((d) => {
98
- return isConflict(
99
- { start_at: d.start_at, end_at: d.end_at },
100
- { start_at: timeSlice.start_at, end_at: timeSlice.end_at }
101
- );
125
+ let conflict = (event_list || []).filter(d => {
126
+ return isConflict({
127
+ start_at: d.start_at,
128
+ end_at: d.end_at
129
+ }, {
130
+ start_at: timeSlice.start_at,
131
+ end_at: timeSlice.end_at
132
+ });
102
133
  });
134
+
135
+ // 减去重叠的总量
103
136
  let conflictCount = getUseableEventCount(conflict, resource.capacity);
104
- if (resource.resourceType === "single") {
137
+
138
+ // 同一时间段内只能进行一个预约,无论容量是否已满。
139
+ if (resource.resourceType === 'single') {
140
+ // 0代表着不重叠,则满足条件
105
141
  if (conflict.length === 0) {
106
142
  return {
107
143
  status: true,
@@ -114,6 +150,7 @@ var checkCapacity = ({
114
150
  };
115
151
  }
116
152
  } else {
153
+ // 当前预约量 <= 总剩余容量
117
154
  if (currentCount <= conflictCount) {
118
155
  return {
119
156
  status: true,
@@ -127,7 +164,15 @@ var checkCapacity = ({
127
164
  }
128
165
  }
129
166
  };
130
- var getIsUsableByTimeItem = ({
167
+
168
+ /**
169
+ * @title: 获取时间切片是否可用
170
+ * @description: 根据时间切片、资源、当前预约量判断时间切片是否可用
171
+ * @param {any} param1
172
+ * @return {*}
173
+ * @Author: zhiwei.Wang
174
+ */
175
+ const getIsUsableByTimeItem = ({
131
176
  timeSlice,
132
177
  time,
133
178
  resource,
@@ -135,26 +180,34 @@ var getIsUsableByTimeItem = ({
135
180
  resourcesUseableMap = {},
136
181
  cut_off_time
137
182
  }) => {
138
- var _a;
139
183
  let status = {
140
184
  afterToDay: false,
141
185
  capacity: false,
142
186
  usable: false,
143
187
  remainingCapacity: 0,
144
188
  // 剩余容量
145
- reason: ""
189
+ reason: ''
146
190
  };
147
- let earliest = (0, import_dayjs.default)();
191
+ // 最早可预约时间为 当前日期之后并且提前量之后
192
+ let earliest = (0, _dayjs.default)();
148
193
  let canBookingForOngoing = false;
149
- const { unit, unit_type, type, ongoing } = cut_off_time || {};
150
- if (type === "ongoing" && (ongoing == null ? void 0 : ongoing.type) === "after_start") {
151
- if ((0, import_dayjs.default)(timeSlice.start_at).isBefore((0, import_dayjs.default)())) {
152
- if (earliest.isBefore((0, import_dayjs.default)(timeSlice.start_at).add(ongoing.unit, "minute"))) {
194
+ const {
195
+ unit,
196
+ unit_type,
197
+ type,
198
+ ongoing
199
+ } = cut_off_time || {};
200
+ // 允许购买已开始的活动
201
+ if (type === 'ongoing' && ongoing?.type === 'after_start') {
202
+ // 如果timeSlice.start_at 小于当前时间,判断当前时间是否在如果timeSlice.start_at+ongoing.unit之间
203
+ // 即,如果现在是15:30,timeSlice.start_at是15:00,ongoing.unit是60分钟,则允许预约
204
+ if ((0, _dayjs.default)(timeSlice.start_at).isBefore((0, _dayjs.default)())) {
205
+ if (earliest.isBefore((0, _dayjs.default)(timeSlice.start_at).add(ongoing.unit, 'minute'))) {
153
206
  canBookingForOngoing = true;
154
207
  }
155
208
  }
156
- } else if (type === "ongoing" && (ongoing == null ? void 0 : ongoing.type) === "before_end") {
157
- if ((0, import_dayjs.default)(timeSlice.end_at).isAfter(earliest)) {
209
+ } else if (type === 'ongoing' && ongoing?.type === 'before_end') {
210
+ if ((0, _dayjs.default)(timeSlice.end_at).isAfter(earliest)) {
158
211
  canBookingForOngoing = true;
159
212
  }
160
213
  } else {
@@ -162,25 +215,28 @@ var getIsUsableByTimeItem = ({
162
215
  earliest = earliest.add(unit, unit_type);
163
216
  }
164
217
  }
218
+ // 不可预约提前量时间之前的
165
219
  if (!checkAfterToDay(timeSlice.start_at, earliest) && !canBookingForOngoing) {
166
220
  return status;
167
221
  }
168
222
  status.afterToDay = true;
169
223
  const checkCapacityResult = checkCapacity({
170
- event_list: time == null ? void 0 : time.event_list,
224
+ event_list: time?.event_list,
171
225
  timeSlice,
172
226
  resource,
173
227
  currentCount
174
228
  });
175
- if ((_a = resource.combined_resource) == null ? void 0 : _a.status) {
229
+ if (resource.combined_resource?.status) {
230
+ // 组合资源中子资源是否可用
176
231
  const resourceIds = resource.combined_resource.resource_ids;
177
- resourceIds.forEach((id) => {
178
- if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[id]) === false) {
232
+ resourceIds.forEach(id => {
233
+ // 只要有一个子资源不可用,整个组合资源都不可用
234
+ if (resourcesUseableMap?.[id] === false) {
179
235
  checkCapacityResult.status = false;
180
236
  }
181
237
  });
182
238
  }
183
- status.reason = checkCapacityResult.reason || "";
239
+ status.reason = checkCapacityResult.reason || '';
184
240
  if (!checkCapacityResult.status) {
185
241
  return status;
186
242
  }
@@ -189,116 +245,113 @@ var getIsUsableByTimeItem = ({
189
245
  status.usable = true;
190
246
  return status;
191
247
  };
192
- var getResourcesByProduct = (resourcesMap, resources, selectedResources, capacity = 1) => {
248
+
249
+ /**
250
+ * @title: 获取商品下绑定的资源列表
251
+ * @description:
252
+ * @param {any} resourcesMap
253
+ * @param {any} product
254
+ * @return {*}
255
+ * @Author: zhiwei.Wang
256
+ */
257
+ exports.getIsUsableByTimeItem = getIsUsableByTimeItem;
258
+ const getResourcesByProduct = (resourcesMap, resources, selectedResources, capacity = 1) => {
193
259
  return (resources || []).reduce((acc, item) => {
194
- if ((item == null ? void 0 : item.status) == 1) {
260
+ if (item?.status == 1) {
195
261
  const form_id = item.id;
196
- item.optional_resource = (item.optional_resource || []).filter(
197
- (d) => item.default_resource.indexOf(d) == -1
198
- );
199
- let optional_resource = item.optional_resource.reduce(
200
- (childAcc, d) => {
201
- var _a;
202
- const isSelectSingleResources = ((_a = resourcesMap[d]) == null ? void 0 : _a.resourceType) === "single" && selectedResources.includes(resourcesMap[d].id);
203
- if (resourcesMap[d] && !isSelectSingleResources) {
204
- const combiningResources = [];
205
- if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) {
206
- resourcesMap[d].combined_resource.resource_ids.forEach(
207
- (id) => {
208
- if (resourcesMap[id]) {
209
- combiningResources.push(resourcesMap[id]);
210
- childAcc.push(
211
- Object.assign({}, resourcesMap[id], {
212
- form_id,
213
- resourceType: item.type,
214
- children: combiningResources,
215
- onlyComputed: true,
216
- // 是否是只用来计算用,组合资源里,假设商品只关联了组合资源没关联子资源,需要通过这个计算来在后面从 renderList 里删除这个资源
217
- metadata: {
218
- ...resourcesMap[id].metadata,
219
- combined_resource: resourcesMap[id].combined_resource,
220
- form_name: item.title,
221
- resource_name: resourcesMap[id].main_field
222
- }
223
- })
224
- );
262
+ // 去重 可选资源和必选资源可能会有重复的
263
+ item.optional_resource = (item.optional_resource || []).filter(d => item.default_resource.indexOf(d) == -1);
264
+ let optional_resource = item.optional_resource.reduce((childAcc, d) => {
265
+ // 如果其他资源选择过,并且这个资源是单个预约,则不可以选中此资源
266
+ // TODO: 如果容量超了这里怎么处理?
267
+ const isSelectSingleResources = resourcesMap[d]?.resourceType === 'single' && selectedResources.includes(resourcesMap[d].id);
268
+ if (resourcesMap[d] && !isSelectSingleResources) {
269
+ // 拼装组合资源的数据
270
+ const combiningResources = [];
271
+ if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) {
272
+ resourcesMap[d].combined_resource.resource_ids.forEach(id => {
273
+ if (resourcesMap[id]) {
274
+ combiningResources.push(resourcesMap[id]);
275
+ childAcc.push(Object.assign({}, resourcesMap[id], {
276
+ form_id: form_id,
277
+ resourceType: item.type,
278
+ children: combiningResources,
279
+ onlyComputed: true,
280
+ // 是否是只用来计算用,组合资源里,假设商品只关联了组合资源没关联子资源,需要通过这个计算来在后面从 renderList 里删除这个资源
281
+ metadata: {
282
+ ...resourcesMap[id].metadata,
283
+ combined_resource: resourcesMap[id].combined_resource,
284
+ form_name: item.title,
285
+ resource_name: resourcesMap[id].main_field
225
286
  }
226
- }
227
- );
228
- }
229
- childAcc.push(
230
- Object.assign({}, resourcesMap[d], {
231
- form_id,
232
- resourceType: item.type,
233
- children: combiningResources,
234
- metadata: {
235
- ...resourcesMap[d].metadata,
236
- combined_resource: resourcesMap[d].combined_resource,
237
- form_name: item.title,
238
- resource_name: resourcesMap[d].main_field
239
- }
240
- })
241
- );
287
+ }));
288
+ }
289
+ });
242
290
  }
243
- return childAcc;
244
- },
245
- []
246
- );
247
- let default_resource = item.default_resource.reduce(
248
- (childAcc, d) => {
249
- var _a;
250
- const isSelectSingleResources = ((_a = resourcesMap[d]) == null ? void 0 : _a.resourceType) === "single" && selectedResources.includes(resourcesMap[d].id);
251
- if (resourcesMap[d] && !isSelectSingleResources) {
252
- const combiningResources = [];
253
- if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) {
254
- resourcesMap[d].combined_resource.resource_ids.forEach(
255
- (id) => {
256
- if (resourcesMap[id]) {
257
- combiningResources.push(resourcesMap[id]);
258
- childAcc.push(
259
- Object.assign({}, resourcesMap[id], {
260
- form_id,
261
- resourceType: item.type,
262
- children: combiningResources,
263
- onlyComputed: true,
264
- // 是否是只用来计算用,组合资源里,假设商品只关联了组合资源没关联子资源,需要通过这个计算来在后面从 renderList 里删除这个资源
265
- metadata: {
266
- ...resourcesMap[id].metadata,
267
- combined_resource: resourcesMap[id].combined_resource,
268
- form_name: item.title,
269
- resource_name: resourcesMap[id].main_field
270
- }
271
- })
272
- );
273
- }
274
- }
275
- );
291
+ childAcc.push(Object.assign({}, resourcesMap[d], {
292
+ form_id: form_id,
293
+ resourceType: item.type,
294
+ children: combiningResources,
295
+ metadata: {
296
+ ...resourcesMap[d].metadata,
297
+ combined_resource: resourcesMap[d].combined_resource,
298
+ form_name: item.title,
299
+ resource_name: resourcesMap[d].main_field
276
300
  }
277
- childAcc.push(
278
- Object.assign({}, resourcesMap[d], {
279
- form_id,
280
- resourceType: item.type,
281
- is_default: 1,
282
- children: combiningResources,
283
- metadata: {
284
- ...resourcesMap[d].metadata,
285
- combined_resource: resourcesMap[d].combined_resource,
286
- form_name: item.title,
287
- resource_name: resourcesMap[d].main_field
288
- }
289
- })
290
- );
301
+ }));
302
+ }
303
+ return childAcc;
304
+ }, []);
305
+ let default_resource = item.default_resource.reduce((childAcc, d) => {
306
+ const isSelectSingleResources = resourcesMap[d]?.resourceType === 'single' && selectedResources.includes(resourcesMap[d].id);
307
+ if (resourcesMap[d] && !isSelectSingleResources) {
308
+ // 拼装组合资源的数据
309
+ const combiningResources = [];
310
+ if (resourcesMap[d].combined_resource && resourcesMap[d].combined_resource.status === 1) {
311
+ resourcesMap[d].combined_resource.resource_ids.forEach(id => {
312
+ if (resourcesMap[id]) {
313
+ combiningResources.push(resourcesMap[id]);
314
+ childAcc.push(Object.assign({}, resourcesMap[id], {
315
+ form_id: form_id,
316
+ resourceType: item.type,
317
+ children: combiningResources,
318
+ onlyComputed: true,
319
+ // 是否是只用来计算用,组合资源里,假设商品只关联了组合资源没关联子资源,需要通过这个计算来在后面从 renderList 里删除这个资源
320
+ metadata: {
321
+ ...resourcesMap[id].metadata,
322
+ combined_resource: resourcesMap[id].combined_resource,
323
+ form_name: item.title,
324
+ resource_name: resourcesMap[id].main_field
325
+ }
326
+ }));
327
+ }
328
+ });
291
329
  }
292
- return childAcc;
293
- },
294
- []
295
- );
330
+ childAcc.push(Object.assign({}, resourcesMap[d], {
331
+ form_id: form_id,
332
+ resourceType: item.type,
333
+ is_default: 1,
334
+ children: combiningResources,
335
+ metadata: {
336
+ ...resourcesMap[d].metadata,
337
+ combined_resource: resourcesMap[d].combined_resource,
338
+ form_name: item.title,
339
+ resource_name: resourcesMap[d].main_field
340
+ }
341
+ }));
342
+ }
343
+ return childAcc;
344
+ }, []);
345
+ // 合并渲染
296
346
  item.renderList = optional_resource.concat(default_resource);
297
- item.renderList = item.renderList.filter((d) => {
347
+ // renderList times 的每一项需要匹配一下当前时间,如果 times 里最小的end_at小于当前时间,则这个资源应该从 renderList 删除
348
+ item.renderList = item.renderList.filter(d => {
298
349
  const latestTime = d.times.reduce((latest, current) => {
299
- return (0, import_dayjs.default)(current.end_at).isAfter((0, import_dayjs.default)(latest.end_at)) ? current : latest;
350
+ return (0, _dayjs.default)(current.end_at).isAfter((0, _dayjs.default)(latest.end_at)) ? current : latest;
300
351
  }, d.times[0]);
301
- return (0, import_dayjs.default)(latestTime.end_at).isAfter((0, import_dayjs.default)()) && d.capacity >= capacity;
352
+ // TODO,在这拉时间切片出来,如果可用 timeSlots.length > 1 才可以被选择
353
+ // 当前资源的配置容量需要大于当前需求的 capacity
354
+ return (0, _dayjs.default)(latestTime.end_at).isAfter((0, _dayjs.default)()) && d.capacity >= capacity;
302
355
  });
303
356
  item.form_id = form_id;
304
357
  acc.push(item);
@@ -306,7 +359,16 @@ var getResourcesByProduct = (resourcesMap, resources, selectedResources, capacit
306
359
  return acc;
307
360
  }, []);
308
361
  };
309
- var formatResources = ({
362
+
363
+ /**
364
+ * @title: 获取资源列表
365
+ * @description:
366
+ * @return {*}
367
+ * @Author: zhiwei.Wang
368
+ * @Date: 2024-01-09 13:38
369
+ */
370
+ exports.getResourcesByProduct = getResourcesByProduct;
371
+ const formatResources = ({
310
372
  booking,
311
373
  resources
312
374
  }) => {
@@ -315,30 +377,39 @@ var formatResources = ({
315
377
  let maps = {};
316
378
  for (let item of _list) {
317
379
  let renderListMaps = {};
318
- item.renderList = item.renderList.map((d) => {
380
+ item.renderList = item.renderList.map(d => {
319
381
  let res = formatResource(d, booking);
320
382
  renderListMaps[res.id] = res;
321
383
  return res;
322
384
  });
323
385
  maps[item.form_id] = {
324
386
  ...item,
325
- renderListMaps
387
+ renderListMaps: renderListMaps
326
388
  };
327
389
  }
328
- return { list: _list, maps };
329
- } catch (err) {
330
- console.log("formatResourcesErr", err);
331
- }
390
+ return {
391
+ list: _list,
392
+ maps: maps
393
+ };
394
+ } catch (err) {}
332
395
  return {
333
396
  list: [],
334
397
  maps: {}
335
398
  };
336
399
  };
337
- var getTimeSlicesByResource = ({
400
+
401
+ /**
402
+ * @title: 获取资源的时间切片列表
403
+ * @description:
404
+ * @return {*}
405
+ * @Author: zhiwei.Wang
406
+ */
407
+ exports.formatResources = formatResources;
408
+ const getTimeSlicesByResource = ({
338
409
  resource,
339
410
  duration,
340
411
  split = 10,
341
- currentDate = (0, import_dayjs.default)(),
412
+ currentDate = (0, _dayjs.default)(),
342
413
  capacity,
343
414
  resourcesUseableMap = {},
344
415
  cut_off_time,
@@ -346,26 +417,45 @@ var getTimeSlicesByResource = ({
346
417
  operating_day_boundary,
347
418
  maxBlockThreshold
348
419
  }) => {
349
- let { times } = resource;
420
+ let {
421
+ times
422
+ } = resource;
423
+
424
+ // 存储所有时间切片
350
425
  const timeSlices = [];
426
+ // times 先以开始时间为准做个排序,时间早的先循环
351
427
  times.sort((a, b) => {
352
- return (0, import_dayjs.default)(a.start_at).diff((0, import_dayjs.default)(b.start_at), "minute");
428
+ return (0, _dayjs.default)(a.start_at).diff((0, _dayjs.default)(b.start_at), 'minute');
353
429
  });
354
- times.forEach((time) => {
355
- const startTime = (0, import_dayjs.default)(`${time.start_at}`);
356
- let endTime = (0, import_dayjs.default)(`${time.end_at}`);
357
- if (endTime.isAfter((0, import_dayjs.default)(currentDate).endOf("day"))) {
358
- endTime = (0, import_dayjs.default)(currentDate).endOf("day");
430
+
431
+ // 处理每个时间范围
432
+ times.forEach(time => {
433
+ // 创建今天的日期字符串,用于构建完整的日期时间
434
+ // const today = dayjs(currentDate).format('YYYY-MM-DD');
435
+
436
+ // 解析开始和结束时间
437
+ const startTime = (0, _dayjs.default)(`${time.start_at}`);
438
+ let endTime = (0, _dayjs.default)(`${time.end_at}`);
439
+ // 结束时间要做修复,如果time.end_at 是超过了 currentDate 的那一天,则把 end_at 设置为 currentDate 那一天的 23:59:59
440
+ if (endTime.isAfter((0, _dayjs.default)(currentDate).endOf('day'))) {
441
+ endTime = (0, _dayjs.default)(currentDate).endOf('day');
359
442
  }
443
+
444
+ // 当前切片的开始时间
360
445
  let currentStart = startTime;
446
+
447
+ // 生成时间切片
361
448
  while (true) {
362
- const currentEnd = currentStart.add(duration, "minute");
449
+ // 计算当前切片的结束时间
450
+ const currentEnd = currentStart.add(duration, 'minute');
451
+
452
+ // 如果结束时间超过了时间范围的结束时间,则停止
363
453
  if (currentEnd.isAfter(endTime)) {
364
454
  break;
365
455
  }
366
456
  const timeSlice = {
367
- start_time: currentStart.format("HH:mm"),
368
- end_time: currentEnd.format("HH:mm"),
457
+ start_time: currentStart.format('HH:mm'),
458
+ end_time: currentEnd.format('HH:mm'),
369
459
  start_at: currentStart,
370
460
  end_at: currentEnd
371
461
  };
@@ -374,39 +464,54 @@ var getTimeSlicesByResource = ({
374
464
  time,
375
465
  resource,
376
466
  currentCount: capacity || 1,
377
- resourcesUseableMap,
467
+ resourcesUseableMap: resourcesUseableMap,
378
468
  cut_off_time
379
469
  });
380
- if ((resourcesUseableMap == null ? void 0 : resourcesUseableMap[resource.id]) !== false) {
470
+ if (resourcesUseableMap?.[resource.id] !== false) {
381
471
  resourcesUseableMap[resource.id] = _status.usable;
382
472
  }
383
473
  if (_status.usable) {
384
- const operatingBoundaryDateTime = (operating_day_boundary == null ? void 0 : operating_day_boundary.type) === "start_time" ? "23:59" : operating_day_boundary == null ? void 0 : operating_day_boundary.time;
385
- if (hasFlexibleDuration && operating_day_boundary && timeSlice.start_time >= (operatingBoundaryDateTime || "23:59")) {
474
+ // 如果有hasFlexibleDuration,且timeSlice.start_at 大于等于operating_day_boundary,则不添加时间切片
475
+ const operatingBoundaryDateTime = operating_day_boundary?.type === 'start_time' ? '23:59' : operating_day_boundary?.time;
476
+ if (hasFlexibleDuration && operating_day_boundary && timeSlice.start_time >= (operatingBoundaryDateTime || '23:59')) {
386
477
  break;
387
478
  }
388
- const operatingBoundaryDateTimeObj = (0, import_dayjs.default)(`${endTime.format("YYYY-MM-DD")} ${operatingBoundaryDateTime}`);
479
+ // 如果有配置了最低禁止购买时长,则需要判断时间切片是否在最低禁止购买时长内
480
+ // 看一下endTime和operatingBoundaryDateTime哪个早,哪个早用哪个去比较
481
+ const operatingBoundaryDateTimeObj = (0, _dayjs.default)(`${endTime.format('YYYY-MM-DD')} ${operatingBoundaryDateTime}`);
389
482
  const earlyTime = endTime.isBefore(operatingBoundaryDateTimeObj) ? endTime : operatingBoundaryDateTimeObj;
390
- if (hasFlexibleDuration && operating_day_boundary && maxBlockThreshold && timeSlice.start_at.add(maxBlockThreshold || 0, "minutes").isAfter(earlyTime)) {
483
+ if (hasFlexibleDuration && operating_day_boundary && maxBlockThreshold && timeSlice.start_at.add(maxBlockThreshold || 0, 'minutes').isAfter(earlyTime)) {
391
484
  break;
392
485
  }
486
+ // 添加时间切片 09:00 ~ 10:00 09:20 ~ 10:20 09:00 ~ 10:00 09:20 ~ 10:20 11:00 ~ 12:00 11:20 ~ 12:20
393
487
  timeSlices.push({
394
488
  ...timeSlice,
395
489
  // 这里需要补充这个时间段内是否可预约
396
- _status
490
+ _status: _status
397
491
  });
398
492
  }
399
- currentStart = currentStart.add(split, "minute");
493
+ // 移动到下一个开始时间(增加10分钟)
494
+ currentStart = currentStart.add(split, 'minute');
400
495
  }
401
496
  });
402
497
  return timeSlices;
403
498
  };
404
- var getTimesIntersection = (times, count) => {
499
+
500
+ /**
501
+ * @title: 获取时间切片列表的交集
502
+ * @description: 注意: 需要将多个时间切片列表合并在一起,然后判断交集
503
+ * @param {TimeSliceItem} times 多个时间切片
504
+ * @param {number} count 交集次数, 符合此次数的会返回
505
+ * @return {*}
506
+ * @Author: zhiwei.Wang
507
+ */
508
+ exports.getTimeSlicesByResource = getTimeSlicesByResource;
509
+ const getTimesIntersection = (times, count) => {
405
510
  let obj = times.reduce((acc, item) => {
406
511
  let _key = `${item.start_time}-${item.end_time}`;
407
512
  if (!acc[_key]) {
408
513
  acc[_key] = {
409
- item,
514
+ item: item,
410
515
  count: 1
411
516
  };
412
517
  } else {
@@ -414,24 +519,44 @@ var getTimesIntersection = (times, count) => {
414
519
  }
415
520
  return acc;
416
521
  }, {});
417
- return Object.values(obj).filter((d) => d.count >= count).map((d) => d.item);
522
+
523
+ // 过滤出符合交集次数的
524
+ return Object.values(obj).filter(d => d.count >= count).map(d => d.item);
418
525
  };
419
- var getResourcesByIds = (resourcesMap, ids) => {
420
- return (ids || []).map((id) => resourcesMap[id]);
526
+
527
+ /**
528
+ * @title: 根据ids筛选资源列表
529
+ * @description:
530
+ * @param {any} resourcesMap
531
+ * @param {any} ids
532
+ * @return {*}
533
+ * @Author: zhiwei.Wang
534
+ * @Date: 2024-09-19 20:23
535
+ */
536
+ exports.getTimesIntersection = getTimesIntersection;
537
+ const getResourcesByIds = (resourcesMap, ids) => {
538
+ return (ids || []).map(id => resourcesMap[id]);
421
539
  };
422
- var mergeSubResourcesTimeSlices = (resources, resourcesMap) => {
423
- return resources.forEach((item) => {
424
- var _a, _b;
425
- if (((_a = item == null ? void 0 : item.combined_resource) == null ? void 0 : _a.status) === 1) {
426
- (_b = item == null ? void 0 : item.combined_resource) == null ? void 0 : _b.resource_ids.forEach((id) => {
540
+
541
+ /**
542
+ * @title: 合并子资源的时间切片至组合资源
543
+ * @description:
544
+ * @param {ResourceItem[]} resources
545
+ * @param {Record<string, ResourceItem>} resourcesMap
546
+ * @return {*}
547
+ * @Author: zhiwei.Wang
548
+ */
549
+ exports.getResourcesByIds = getResourcesByIds;
550
+ const mergeSubResourcesTimeSlices = (resources, resourcesMap) => {
551
+ return resources.forEach(item => {
552
+ if (item?.combined_resource?.status === 1) {
553
+ item?.combined_resource?.resource_ids.forEach(id => {
427
554
  const subResource = resourcesMap[id];
428
555
  if (subResource) {
429
- subResource.times.forEach((time) => {
430
- const fatherResourcesTime = item.times.find(
431
- (n) => n.start_at === time.start_at && n.end_at === time.end_at
432
- );
556
+ subResource.times.forEach(time => {
557
+ const fatherResourcesTime = item.times.find(n => n.start_at === time.start_at && n.end_at === time.end_at);
433
558
  if (fatherResourcesTime) {
434
- fatherResourcesTime.event_list.push(...time.event_list || []);
559
+ fatherResourcesTime.event_list.push(...(time.event_list || []));
435
560
  }
436
561
  });
437
562
  }
@@ -439,7 +564,17 @@ var mergeSubResourcesTimeSlices = (resources, resourcesMap) => {
439
564
  }
440
565
  });
441
566
  };
442
- var getTimeSlicesByResources = ({
567
+
568
+ /**
569
+ * @title: 根据资源id列表获取时间切片
570
+ * @description: 传入一个技师id列表, 找出技师列表中公共的时间切片
571
+ * @param {ResourceItem} resources
572
+ * @param {CartItem} cart
573
+ * @return {*}
574
+ * @Author: zhiwei.Wang
575
+ */
576
+ exports.mergeSubResourcesTimeSlices = mergeSubResourcesTimeSlices;
577
+ const getTimeSlicesByResources = ({
443
578
  resourceIds,
444
579
  resourcesMap,
445
580
  duration,
@@ -452,129 +587,181 @@ var getTimeSlicesByResources = ({
452
587
  operating_day_boundary,
453
588
  maxBlockThreshold
454
589
  }) => {
590
+ // 获取资源列表
455
591
  let resources = getResourcesByIds(resourcesMap, resourceIds);
456
592
  mergeSubResourcesTimeSlices(resources, resourcesMap);
593
+ // 资源排下序,把单个资源靠前,组合资源排在后面
457
594
  resources.sort((a, b) => {
458
- var _a, _b, _c, _d;
459
- const aIsCombined = ((_b = (_a = a.metadata) == null ? void 0 : _a.combined_resource) == null ? void 0 : _b.status) === 1;
460
- const bIsCombined = ((_d = (_c = b.metadata) == null ? void 0 : _c.combined_resource) == null ? void 0 : _d.status) === 1;
461
- if (aIsCombined && !bIsCombined)
462
- return 1;
463
- if (!aIsCombined && bIsCombined)
464
- return -1;
595
+ const aIsCombined = a.metadata?.combined_resource?.status === 1;
596
+ const bIsCombined = b.metadata?.combined_resource?.status === 1;
597
+ if (aIsCombined && !bIsCombined) return 1;
598
+ if (!aIsCombined && bIsCombined) return -1;
465
599
  return 0;
466
600
  });
467
- let timeSliceList = resources.reduce(
468
- (acc, item) => {
469
- return acc.concat(
470
- getTimeSlicesByResource({
471
- resource: item,
472
- duration,
473
- split,
474
- currentDate,
475
- capacity,
476
- resourcesUseableMap,
477
- cut_off_time,
478
- hasFlexibleDuration,
479
- operating_day_boundary,
480
- maxBlockThreshold
481
- })
482
- );
483
- },
484
- []
485
- );
601
+
602
+ // 获取资源列表中所有的时间切片
603
+ let timeSliceList = resources.reduce((acc, item) => {
604
+ return acc.concat(getTimeSlicesByResource({
605
+ resource: item,
606
+ duration: duration,
607
+ split: split,
608
+ currentDate: currentDate,
609
+ capacity: capacity,
610
+ resourcesUseableMap: resourcesUseableMap,
611
+ cut_off_time: cut_off_time,
612
+ hasFlexibleDuration,
613
+ operating_day_boundary,
614
+ maxBlockThreshold
615
+ }));
616
+ }, []);
617
+
618
+ // 获取时间切片列表的交集
486
619
  let intersection = getTimesIntersection(timeSliceList, resources.length);
487
620
  return intersection;
488
621
  };
489
- var getOthersSelectedResources = (cartItems, accountId, resourcesMap) => {
622
+
623
+ /**
624
+ * @title: 获取其他人的已选资源
625
+ * @description:
626
+ * @param {CartItem[]} cartItems
627
+ * @param {number | string} accountId
628
+ * @return {*}
629
+ * @Author: jinglin.tan
630
+ */
631
+ exports.getTimeSlicesByResources = getTimeSlicesByResources;
632
+ const getOthersSelectedResources = (cartItems, accountId, resourcesMap) => {
490
633
  return cartItems.reduce((acc, d) => {
491
- var _a;
492
634
  if (d.holder_id !== accountId) {
493
- if ((_a = d._origin) == null ? void 0 : _a.resources) {
494
- d._origin.resources.forEach((n) => {
635
+ if (d._origin?.resources) {
636
+ d._origin.resources.forEach(n => {
637
+ // 如果是组合资源,还需要检查组合资源里子资源是否被占用过
495
638
  if (n.metadata.combined_resource && n.metadata.combined_resource.status === 1) {
496
- if (n.metadata.combined_resource.resource_ids.some(
497
- (m) => acc.includes(m)
498
- )) {
639
+ // 如果组合资源里子资源被占用过,则这个资源不可以进待选列表了
640
+ if (n.metadata.combined_resource.resource_ids.some(m => acc.includes(m))) {
499
641
  return acc;
500
642
  }
501
643
  acc.push(...n.metadata.combined_resource.resource_ids);
644
+ // n.metadata.combined_resource.resource_ids.forEach((m: number) => {
645
+ // if (resourcesMap[m]) resourcesMap[m].capacity -= d.num || 0;
646
+ // });
502
647
  } else {
503
- Object.values(resourcesMap).forEach((m) => {
648
+ // 如果当前选中的不是组合资源,但是是别的组合资源里的子资源,则还需要把别的组合资源也加进来
649
+ // 去 resourcesMap 里找一下 n.id 是不是别的组合资源里的子资源,是的话把别的组合资源也加进来
650
+ Object.values(resourcesMap).forEach(m => {
504
651
  if (m.combined_resource && m.combined_resource.status === 1) {
505
652
  if (m.combined_resource.resource_ids.includes(n.id)) {
506
653
  acc.push(m.id);
654
+ // if (resourcesMap[m.id]) resourcesMap[m.id].capacity -= d.num || 0;
507
655
  }
508
656
  }
509
657
  });
510
658
  }
511
659
  acc.push(n.id);
660
+ // if (resourcesMap[n.id]) resourcesMap[n.id].capacity -= currentCapacity || 0;
512
661
  });
513
662
  }
514
663
  }
515
664
  return acc;
516
665
  }, []);
517
666
  };
518
- var getOthersCartSelectedResources = (cartItems, cartItemId, resourcesMap) => {
667
+
668
+ /**
669
+ * @title: 获取其他购物车内商品的已选资源
670
+ * @description:
671
+ * @param {CartItem[]} cartItems
672
+ * @param {number | string} accountId
673
+ * @return {*}
674
+ * @Author: jinglin.tan
675
+ */
676
+ exports.getOthersSelectedResources = getOthersSelectedResources;
677
+ const getOthersCartSelectedResources = (cartItems, cartItemId, resourcesMap) => {
519
678
  return cartItems.reduce((acc, d) => {
520
- var _a;
521
679
  if (d._id !== cartItemId) {
522
- if ((_a = d._origin) == null ? void 0 : _a.resources) {
523
- d._origin.resources.forEach((n) => {
680
+ if (d._origin?.resources) {
681
+ d._origin.resources.forEach(n => {
682
+ // 如果是组合资源,还需要检查组合资源里子资源是否被占用过
524
683
  if (n.metadata.combined_resource && n.metadata.combined_resource.status === 1) {
525
- if (n.metadata.combined_resource.resource_ids.some(
526
- (m) => acc.includes(m)
527
- )) {
684
+ // 如果组合资源里子资源被占用过,则这个资源不可以进待选列表了
685
+ if (n.metadata.combined_resource.resource_ids.some(m => acc.includes(m))) {
528
686
  return acc;
529
687
  }
530
688
  acc.push(...n.metadata.combined_resource.resource_ids);
689
+ // n.metadata.combined_resource.resource_ids.forEach((m: number) => {
690
+ // resourcesMap[m].capacity -= n.num;
691
+ // });
531
692
  } else {
532
- Object.values(resourcesMap).forEach((m) => {
693
+ // 如果当前选中的不是组合资源,但是是别的组合资源里的子资源,则还需要把别的组合资源也加进来
694
+ // 去 resourcesMap 里找一下 n.id 是不是别的组合资源里的子资源,是的话把别的组合资源也加进来
695
+ Object.values(resourcesMap).forEach(m => {
533
696
  if (m.combined_resource && m.combined_resource.status === 1) {
534
697
  if (m.combined_resource.resource_ids.includes(n.id)) {
535
698
  acc.push(m.id);
699
+ // resourcesMap[m.id].capacity -= n.num;
536
700
  }
537
701
  }
538
702
  });
539
703
  }
540
704
  acc.push(n.id);
705
+ // push 完以后,把 resourceMap 的 capacity 减掉当前的商品数量
706
+ // resourcesMap[n.id].capacity -= currentCapacity || 0;
541
707
  });
542
708
  }
543
709
  }
544
710
  return acc;
545
711
  }, []);
546
712
  };
713
+ exports.getOthersCartSelectedResources = getOthersCartSelectedResources;
714
+ /**
715
+ * @title: 根据日期范围过滤日程
716
+ *
717
+ * @export
718
+ * @param {any[]} schedule
719
+ * @param {string} startDate
720
+ * @param {string} endDate
721
+ * @return {*}
722
+ */
547
723
  function filterScheduleByDateRange(schedule, startDate, endDate) {
548
- if (!(schedule == null ? void 0 : schedule.length))
549
- return [];
724
+ if (!schedule?.length) return [];
550
725
  const start = new Date(startDate);
551
726
  const end = new Date(endDate);
552
- return schedule.filter((item) => {
727
+ return schedule.filter(item => {
553
728
  const itemDate = new Date(item.date);
554
729
  return itemDate >= start && itemDate <= end;
555
730
  });
556
731
  }
732
+
733
+ /**
734
+ * 传入商品数据,返回基于商品配置的提前量的最早开始日期和最晚结束日期
735
+ *
736
+ * @export
737
+ * @param {ProductData} product
738
+ * @return {*}
739
+ */
557
740
  function checkSessionProductLeadTime(product) {
558
- let latestStartDate = "";
559
- let earliestEndDate = "";
560
- const { future_day, unit, unit_type } = product.cut_off_time;
741
+ let latestStartDate = ''; // 最晚开始日期
742
+ let earliestEndDate = ''; // 最早结束日期
743
+ const {
744
+ future_day,
745
+ unit,
746
+ unit_type
747
+ } = product.cut_off_time;
748
+ // 预定天数存在,则开始计算从当前时间开始往后推预定天数作为结束时间
561
749
  if (future_day) {
562
- const endDate = (0, import_dayjs.default)().add(future_day, "day");
563
- if (!earliestEndDate || endDate.isBefore((0, import_dayjs.default)(earliestEndDate), "day")) {
564
- earliestEndDate = endDate.format("YYYY-MM-DD");
750
+ const endDate = (0, _dayjs.default)().add(future_day, 'day');
751
+ if (!earliestEndDate || endDate.isBefore((0, _dayjs.default)(earliestEndDate), 'day')) {
752
+ earliestEndDate = endDate.format('YYYY-MM-DD');
565
753
  }
566
754
  } else if (future_day === 0) {
567
- const endDate = (0, import_dayjs.default)();
568
- if (!earliestEndDate || endDate.isBefore((0, import_dayjs.default)(earliestEndDate), "day")) {
569
- earliestEndDate = endDate.format("YYYY-MM-DD");
755
+ const endDate = (0, _dayjs.default)();
756
+ if (!earliestEndDate || endDate.isBefore((0, _dayjs.default)(earliestEndDate), 'day')) {
757
+ earliestEndDate = endDate.format('YYYY-MM-DD');
570
758
  }
571
759
  }
760
+ // 如果存在提前预约时间,则开始计算从当前时间开始往后推提前预约时间作为开始时间
572
761
  if (unit && unit_type) {
573
- const startDate = (0, import_dayjs.default)(
574
- (0, import_dayjs.default)().add(unit, unit_type).format("YYYY-MM-DD")
575
- );
576
- if (!latestStartDate || startDate.isAfter((0, import_dayjs.default)(latestStartDate), "day")) {
577
- latestStartDate = startDate.format("YYYY-MM-DD");
762
+ const startDate = (0, _dayjs.default)((0, _dayjs.default)().add(unit, unit_type).format('YYYY-MM-DD'));
763
+ if (!latestStartDate || startDate.isAfter((0, _dayjs.default)(latestStartDate), 'day')) {
764
+ latestStartDate = startDate.format('YYYY-MM-DD');
578
765
  }
579
766
  }
580
767
  return {
@@ -582,65 +769,75 @@ function checkSessionProductLeadTime(product) {
582
769
  earliestEndDate
583
770
  };
584
771
  }
772
+
773
+ /**
774
+ * 基于商品的 resources 配置,返回可选择的资源的 id 列表
775
+ *
776
+ * @export
777
+ * @param {ProductData} product
778
+ * @return {*}
779
+ */
585
780
  function getResourcesIdsByProduct(product) {
586
- var _a, _b, _c;
587
781
  const tempResourceIds = [];
588
- (_c = (_b = (_a = product == null ? void 0 : product.product_resource) == null ? void 0 : _a.resources) == null ? void 0 : _b.forEach) == null ? void 0 : _c.call(_b, (resource) => {
589
- var _a2, _b2;
590
- if ((resource == null ? void 0 : resource.status) == 1) {
591
- if ((_a2 = resource == null ? void 0 : resource.default_resource) == null ? void 0 : _a2.length) {
592
- tempResourceIds.push(...resource == null ? void 0 : resource.default_resource);
593
- } else if ((_b2 = resource == null ? void 0 : resource.optional_resource) == null ? void 0 : _b2.length) {
594
- tempResourceIds.push(...resource == null ? void 0 : resource.optional_resource);
782
+ product?.product_resource?.resources?.forEach?.(resource => {
783
+ if (resource?.status == 1) {
784
+ if (resource?.default_resource?.length) {
785
+ tempResourceIds.push(...resource?.default_resource);
786
+ } else if (resource?.optional_resource?.length) {
787
+ tempResourceIds.push(...resource?.optional_resource);
595
788
  }
596
789
  }
597
790
  });
598
791
  return tempResourceIds;
599
792
  }
793
+
794
+ /**
795
+ * 资源排序,把单个资源靠前,组合资源排在后面
796
+ *
797
+ * @export
798
+ * @param {ResourceItem[]} resourcesList
799
+ * @return {*}
800
+ */
600
801
  function sortCombinedResources(resourcesList) {
601
802
  const newResourcesList = [...resourcesList];
602
803
  newResourcesList.sort((a, b) => {
603
- var _a, _b, _c, _d;
604
- const aIsCombined = ((_b = (_a = a.metadata) == null ? void 0 : _a.combined_resource) == null ? void 0 : _b.status) === 1;
605
- const bIsCombined = ((_d = (_c = b.metadata) == null ? void 0 : _c.combined_resource) == null ? void 0 : _d.status) === 1;
804
+ const aIsCombined = a.metadata?.combined_resource?.status === 1;
805
+ const bIsCombined = b.metadata?.combined_resource?.status === 1;
606
806
  return aIsCombined === bIsCombined ? 0 : aIsCombined ? 1 : -1;
607
807
  });
608
808
  return newResourcesList;
609
809
  }
810
+
811
+ /**
812
+ * 传入一个资源组,根据 formid筛出相同类型的资源
813
+ *
814
+ * @export
815
+ * @param {ResourceItem[]} resources
816
+ * @param {string} form_id
817
+ * @return {*}
818
+ */
610
819
  function filterResourcesByFormItem(resources, form_id) {
611
- return resources.filter((n) => n.form_id === form_id);
820
+ return resources.filter(n => n.form_id === form_id);
612
821
  }
822
+
823
+ /**
824
+ * 传入两个资源,确认这两个资源是否有交集(包括组合资源)
825
+ *
826
+ * @export
827
+ * @param {ResourceItem} resource1
828
+ * @param {ResourceItem} resource2
829
+ * @return {*}
830
+ */
613
831
  function checkTwoResourcesIntersection(resource1, resource2) {
614
- var _a, _b;
615
- if (resource1.id === resource2.id)
616
- return true;
617
- if (((_a = resource1.metadata.combined_resource) == null ? void 0 : _a.status) === 1 && // 如果现在选择的是组合资源,需要判断
832
+ // 检查主资源ID是否匹配
833
+ if (resource1.id === resource2.id) return true;
834
+ // 检查组合资源的情况
835
+ if (resource1.metadata.combined_resource?.status === 1 && (
836
+ // 如果现在选择的是组合资源,需要判断
618
837
  // 1、当前其他购物车里是否选了当前组合资源的子资源
619
838
  // 2、如果其他购物车里的商品也是组合资源,出了组合资源本身的 id 需要判断,还需要判断子资源的 id 是否有交集
620
- (resource1.metadata.combined_resource.resource_ids.includes(resource2.id) || resource1.metadata.combined_resource.resource_ids.some((n) => {
839
+ resource1.metadata.combined_resource.resource_ids.includes(resource2.id) || resource1.metadata.combined_resource.resource_ids.some(n => {
621
840
  return resource2.metadata.combined_resource.resource_ids.includes(n);
622
- })))
623
- return true;
624
- if (((_b = resource2.metadata.combined_resource) == null ? void 0 : _b.status) === 1 && resource2.metadata.combined_resource.resource_ids.includes(resource2.id))
625
- return true;
626
- }
627
- // Annotate the CommonJS export names for ESM import in node:
628
- 0 && (module.exports = {
629
- checkSessionProductLeadTime,
630
- checkTwoResourcesIntersection,
631
- filterResourcesByFormItem,
632
- filterScheduleByDateRange,
633
- formatResources,
634
- getIsUsableByTimeItem,
635
- getOthersCartSelectedResources,
636
- getOthersSelectedResources,
637
- getResourcesByIds,
638
- getResourcesByProduct,
639
- getResourcesIdsByProduct,
640
- getTimeSlicesByResource,
641
- getTimeSlicesByResources,
642
- getTimesIntersection,
643
- isConflict,
644
- mergeSubResourcesTimeSlices,
645
- sortCombinedResources
646
- });
841
+ }))) return true;
842
+ if (resource2.metadata.combined_resource?.status === 1 && resource2.metadata.combined_resource.resource_ids.includes(resource2.id)) return true;
843
+ }