@pisell/pisellos 0.0.567 → 0.0.568

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/dist/core/index.js +6 -9
  2. package/dist/model/strategy/adapter/walletPass/evaluator.js +0 -2
  3. package/dist/model/strategy/adapter/walletPass/example.js +3 -26
  4. package/dist/model/strategy/adapter/walletPass/utils.js +0 -3
  5. package/dist/model/strategy/strategy-example.js +5 -19
  6. package/dist/modules/Cart/index.js +0 -3
  7. package/dist/modules/Cart/utils/cartProduct.js +0 -1
  8. package/dist/modules/Date/index.js +1 -5
  9. package/dist/modules/Discount/index.js +1 -4
  10. package/dist/modules/OpenData/index.js +0 -2
  11. package/dist/modules/Order/index.d.ts +1 -1
  12. package/dist/modules/Order/index.js +14 -41
  13. package/dist/modules/Payment/index.js +142 -270
  14. package/dist/modules/Payment/walletpass.js +4 -5
  15. package/dist/modules/Rules/index.js +0 -7
  16. package/dist/modules/Schedule/utils.js +0 -1
  17. package/dist/modules/Step/index.js +0 -1
  18. package/dist/plugins/request.js +1 -4
  19. package/dist/plugins/window.js +2 -6
  20. package/dist/server/index.js +88 -121
  21. package/dist/server/modules/menu/index.js +32 -41
  22. package/dist/server/modules/products/index.js +29 -49
  23. package/dist/server/modules/quotation/index.js +29 -38
  24. package/dist/server/modules/resource/index.js +3 -4
  25. package/dist/server/modules/schedule/index.js +32 -40
  26. package/dist/server/utils/product.js +0 -1
  27. package/dist/solution/BookingByStep/index.d.ts +1 -1
  28. package/dist/solution/BookingByStep/index.js +7 -59
  29. package/dist/solution/BookingByStep/utils/capacity.js +1 -11
  30. package/dist/solution/BookingByStep/utils/resources.js +1 -3
  31. package/dist/solution/BookingByStep/utils/timeslots.js +2 -43
  32. package/dist/solution/BookingTicket/index.d.ts +1 -1
  33. package/dist/solution/BookingTicket/index.js +5 -7
  34. package/dist/solution/BookingTicket/utils/scan/handleScan.js +25 -31
  35. package/dist/solution/BookingTicket/utils/scan/index.js +6 -10
  36. package/dist/solution/BuyTickets/index.js +9 -12
  37. package/dist/solution/Checkout/index.js +177 -246
  38. package/dist/solution/Checkout/utils/index.js +4 -16
  39. package/dist/solution/RegisterAndLogin/index.js +30 -76
  40. package/dist/solution/ScanOrder/index.js +50 -60
  41. package/dist/solution/ShopDiscount/index.js +2 -7
  42. package/dist/solution/VenueBooking/index.d.ts +5 -0
  43. package/dist/solution/VenueBooking/index.js +364 -327
  44. package/dist/utils/task.js +15 -18
  45. package/dist/utils/watch.js +0 -1
  46. package/lib/apis/picoding.js +2 -0
  47. package/lib/core/index.js +130 -131
  48. package/lib/effects/index.js +46 -57
  49. package/lib/index.js +92 -53
  50. package/lib/model/index.js +14 -21
  51. package/lib/model/strategy/adapter/dataVariant/adapter.js +38 -50
  52. package/lib/model/strategy/adapter/dataVariant/evaluator.js +162 -236
  53. package/lib/model/strategy/adapter/dataVariant/examples.js +229 -237
  54. package/lib/model/strategy/adapter/dataVariant/index.js +39 -34
  55. package/lib/model/strategy/adapter/dataVariant/type.js +57 -28
  56. package/lib/model/strategy/adapter/index.js +100 -64
  57. package/lib/model/strategy/adapter/itemRule/adapter.js +156 -144
  58. package/lib/model/strategy/adapter/itemRule/evaluator.js +36 -48
  59. package/lib/model/strategy/adapter/itemRule/examples.js +295 -225
  60. package/lib/model/strategy/adapter/itemRule/index.js +83 -57
  61. package/lib/model/strategy/adapter/itemRule/type.js +97 -36
  62. package/lib/model/strategy/adapter/promotion/adapter.js +84 -63
  63. package/lib/model/strategy/adapter/promotion/evaluator.js +381 -231
  64. package/lib/model/strategy/adapter/promotion/examples.js +139 -159
  65. package/lib/model/strategy/adapter/promotion/index.js +1 -49
  66. package/lib/model/strategy/adapter/promotion/type.js +199 -35
  67. package/lib/model/strategy/adapter/type.js +4 -16
  68. package/lib/model/strategy/adapter/walletPass/evaluator.js +180 -152
  69. package/lib/model/strategy/adapter/walletPass/example.js +217 -190
  70. package/lib/model/strategy/adapter/walletPass/index.js +75 -51
  71. package/lib/model/strategy/adapter/walletPass/locales.js +36 -58
  72. package/lib/model/strategy/adapter/walletPass/type.js +4 -16
  73. package/lib/model/strategy/adapter/walletPass/utils.js +652 -402
  74. package/lib/model/strategy/engine.js +270 -168
  75. package/lib/model/strategy/index.js +49 -34
  76. package/lib/model/strategy/strategy-example.js +243 -239
  77. package/lib/model/strategy/type.js +100 -40
  78. package/lib/modules/Account/index.js +39 -53
  79. package/lib/modules/Account/types.js +20 -33
  80. package/lib/modules/AccountList/index.js +116 -154
  81. package/lib/modules/AccountList/types.js +30 -31
  82. package/lib/modules/AccountList/utils.js +18 -30
  83. package/lib/modules/BaseModule.js +22 -45
  84. package/lib/modules/Cart/index.js +170 -124
  85. package/lib/modules/Cart/types.js +46 -51
  86. package/lib/modules/Cart/utils/cartAccount.js +40 -39
  87. package/lib/modules/Cart/utils/cartDate.js +56 -61
  88. package/lib/modules/Cart/utils/cartDiscount.js +28 -33
  89. package/lib/modules/Cart/utils/cartNote.js +27 -32
  90. package/lib/modules/Cart/utils/cartProduct.js +306 -241
  91. package/lib/modules/Cart/utils/cartRelationForms.js +29 -35
  92. package/lib/modules/Cart/utils/cartResource.js +72 -78
  93. package/lib/modules/Cart/utils/changePrice.js +26 -62
  94. package/lib/modules/Cart/utils/index.js +106 -48
  95. package/lib/modules/Customer/constants.js +13 -34
  96. package/lib/modules/Customer/index.js +216 -153
  97. package/lib/modules/Customer/types.js +38 -35
  98. package/lib/modules/Date/index.js +116 -115
  99. package/lib/modules/Date/types.js +16 -28
  100. package/lib/modules/Date/utils.js +174 -123
  101. package/lib/modules/Discount/index.js +117 -113
  102. package/lib/modules/Discount/types.js +9 -31
  103. package/lib/modules/Guests/index.js +30 -56
  104. package/lib/modules/Guests/types.js +23 -33
  105. package/lib/modules/Holder/index.js +209 -189
  106. package/lib/modules/Holder/types.js +4 -16
  107. package/lib/modules/Holder/utils.js +20 -49
  108. package/lib/modules/OpenData/index.js +63 -74
  109. package/lib/modules/OpenData/types.js +4 -16
  110. package/lib/modules/OpenData/utils.js +44 -78
  111. package/lib/modules/Order/index.d.ts +1 -1
  112. package/lib/modules/Order/index.js +332 -320
  113. package/lib/modules/Order/types.js +24 -33
  114. package/lib/modules/Order/utils.js +350 -284
  115. package/lib/modules/Payment/cash.js +20 -33
  116. package/lib/modules/Payment/cashRecommendationAlgorithm.js +145 -76
  117. package/lib/modules/Payment/eftpos.js +16 -30
  118. package/lib/modules/Payment/index.js +566 -432
  119. package/lib/modules/Payment/mx51.js +1 -0
  120. package/lib/modules/Payment/types.js +216 -107
  121. package/lib/modules/Payment/utils.js +50 -47
  122. package/lib/modules/Payment/walletpass.js +221 -203
  123. package/lib/modules/Product/index.js +51 -46
  124. package/lib/modules/Product/types.js +4 -16
  125. package/lib/modules/Product/utils.js +32 -33
  126. package/lib/modules/ProductList/index.js +111 -110
  127. package/lib/modules/ProductList/types.js +9 -31
  128. package/lib/modules/Quotation/index.js +60 -82
  129. package/lib/modules/Quotation/types.js +4 -16
  130. package/lib/modules/Resource/index.js +27 -59
  131. package/lib/modules/Resource/types.js +22 -32
  132. package/lib/modules/Resource/utils.js +30 -38
  133. package/lib/modules/Rules/index.js +1172 -872
  134. package/lib/modules/Rules/types.js +17 -40
  135. package/lib/modules/SalesSummary/index.js +59 -68
  136. package/lib/modules/SalesSummary/types.js +4 -16
  137. package/lib/modules/SalesSummary/utils.js +176 -193
  138. package/lib/modules/ScanOrderLogger/index.js +59 -79
  139. package/lib/modules/ScanOrderLogger/providers/feishu.js +54 -78
  140. package/lib/modules/ScanOrderLogger/providers/grafana.js +13 -36
  141. package/lib/modules/ScanOrderLogger/types.js +4 -16
  142. package/lib/modules/Schedule/getDateIsInSchedule.js +334 -167
  143. package/lib/modules/Schedule/index.js +97 -107
  144. package/lib/modules/Schedule/type.js +4 -16
  145. package/lib/modules/Schedule/types.js +4 -16
  146. package/lib/modules/Schedule/utils.js +433 -291
  147. package/lib/modules/Step/index.js +40 -52
  148. package/lib/modules/Step/tyeps.js +4 -16
  149. package/lib/modules/Summary/index.js +66 -70
  150. package/lib/modules/Summary/types.js +4 -16
  151. package/lib/modules/Summary/utils.js +782 -429
  152. package/lib/modules/index.js +212 -57
  153. package/lib/plugins/app.js +4 -16
  154. package/lib/plugins/index.js +36 -25
  155. package/lib/plugins/request.js +137 -126
  156. package/lib/plugins/shopStore.js +4 -16
  157. package/lib/plugins/user.js +4 -16
  158. package/lib/plugins/window.js +171 -179
  159. package/lib/server/index.js +882 -623
  160. package/lib/server/modules/index.js +85 -59
  161. package/lib/server/modules/menu/index.js +146 -122
  162. package/lib/server/modules/menu/types.js +18 -31
  163. package/lib/server/modules/order/index.js +195 -231
  164. package/lib/server/modules/order/types.js +107 -32
  165. package/lib/server/modules/order/utils/filterBookings.js +174 -140
  166. package/lib/server/modules/order/utils/filterOrders.js +89 -60
  167. package/lib/server/modules/products/index.js +430 -335
  168. package/lib/server/modules/products/types.js +41 -34
  169. package/lib/server/modules/quotation/index.js +76 -77
  170. package/lib/server/modules/quotation/types.js +21 -31
  171. package/lib/server/modules/resource/index.js +216 -187
  172. package/lib/server/modules/resource/types.js +42 -33
  173. package/lib/server/modules/schedule/index.js +134 -119
  174. package/lib/server/modules/schedule/types.js +14 -21
  175. package/lib/server/modules/schedule/utils.js +334 -163
  176. package/lib/server/types.js +4 -16
  177. package/lib/server/utils/index.js +25 -23
  178. package/lib/server/utils/product.js +196 -139
  179. package/lib/server/utils/schedule.js +34 -41
  180. package/lib/server/utils/time.js +40 -49
  181. package/lib/solution/BookingByStep/index.d.ts +1 -1
  182. package/lib/solution/BookingByStep/index.js +1530 -1343
  183. package/lib/solution/BookingByStep/types.js +40 -99
  184. package/lib/solution/BookingByStep/utils/capacity.js +192 -160
  185. package/lib/solution/BookingByStep/utils/products.js +42 -52
  186. package/lib/solution/BookingByStep/utils/resources.js +527 -330
  187. package/lib/solution/BookingByStep/utils/stock.js +65 -44
  188. package/lib/solution/BookingByStep/utils/timeslots.js +129 -131
  189. package/lib/solution/BookingTicket/index.d.ts +1 -1
  190. package/lib/solution/BookingTicket/index.js +147 -122
  191. package/lib/solution/BookingTicket/types.js +38 -64
  192. package/lib/solution/BookingTicket/utils/scan/cloudSearch.js +64 -80
  193. package/lib/solution/BookingTicket/utils/scan/handleScan.js +82 -80
  194. package/lib/solution/BookingTicket/utils/scan/index.js +90 -94
  195. package/lib/solution/BookingTicket/utils/scan/scanCache.js +90 -43
  196. package/lib/solution/BuyTickets/index.js +67 -70
  197. package/lib/solution/BuyTickets/types.js +22 -38
  198. package/lib/solution/Checkout/index.js +1451 -1158
  199. package/lib/solution/Checkout/types.js +91 -61
  200. package/lib/solution/Checkout/utils/index.js +227 -158
  201. package/lib/solution/PlaceOrder/index.js +55 -0
  202. package/lib/solution/RegisterAndLogin/config.js +493 -460
  203. package/lib/solution/RegisterAndLogin/index.js +633 -630
  204. package/lib/solution/RegisterAndLogin/types.js +189 -76
  205. package/lib/solution/RegisterAndLogin/utils.js +183 -125
  206. package/lib/solution/Sales/index.js +218 -200
  207. package/lib/solution/Sales/types.js +27 -33
  208. package/lib/solution/ScanOrder/index.js +803 -840
  209. package/lib/solution/ScanOrder/types.js +34 -34
  210. package/lib/solution/ScanOrder/utils.js +372 -331
  211. package/lib/solution/ShopDiscount/index.js +230 -236
  212. package/lib/solution/ShopDiscount/types.js +15 -37
  213. package/lib/solution/ShopDiscount/utils.js +309 -172
  214. package/lib/solution/VenueBooking/index.d.ts +5 -0
  215. package/lib/solution/VenueBooking/index.js +886 -929
  216. package/lib/solution/VenueBooking/types.js +20 -40
  217. package/lib/solution/VenueBooking/utils/dateSummary.js +22 -54
  218. package/lib/solution/VenueBooking/utils/resource.js +31 -54
  219. package/lib/solution/VenueBooking/utils/slotMerge.js +88 -106
  220. package/lib/solution/VenueBooking/utils/smartPricing.js +112 -100
  221. package/lib/solution/VenueBooking/utils/timeSlot.js +133 -132
  222. package/lib/solution/VenueBooking/utils.js +130 -67
  223. package/lib/solution/index.js +102 -37
  224. package/lib/store/createStore.js +32 -29
  225. package/lib/types/index.js +4 -16
  226. package/lib/utils/task.js +36 -36
  227. package/lib/utils/watch.js +81 -47
  228. package/package.json +2 -1
@@ -1,34 +1,109 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ "use strict";
18
2
 
19
- // src/server/modules/order/types.ts
20
- var types_exports = {};
21
- __export(types_exports, {
22
- OrderHooks: () => OrderHooks
23
- });
24
- module.exports = __toCommonJS(types_exports);
25
- var OrderHooks = /* @__PURE__ */ ((OrderHooks2) => {
26
- OrderHooks2["onOrdersLoaded"] = "order:onOrdersLoaded";
27
- OrderHooks2["onOrdersChanged"] = "order:onOrdersChanged";
28
- OrderHooks2["onOrdersSyncCompleted"] = "order:onOrdersSyncCompleted";
29
- return OrderHooks2;
30
- })(OrderHooks || {});
31
- // Annotate the CommonJS export names for ESM import in node:
32
- 0 && (module.exports = {
33
- OrderHooks
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
34
5
  });
6
+ exports.OrderHooks = void 0;
7
+ /**
8
+ * Order 模块主键类型(对齐标准 Sales 协议的 order_id)
9
+ */
10
+ /**
11
+ * 协议中金额类字段多为 string 快照(交易时价格不可从基准商品重算)
12
+ */
13
+ // ─────────────────────────────────────────────────────────────────
14
+ // 订单类型 / 平台 / 渠道(Sales 协议枚举,保留 string 并置常用字面量)
15
+ // ─────────────────────────────────────────────────────────────────
16
+ /** 订单类型。文档:appointment_booking / ticket / virtual。来源:Order.type */
17
+ /**
18
+ * 来源平台。文档:shop / pos / kiosk / h5 / app / mini-program。
19
+ * 来源:Order.platform
20
+ */
21
+ /** 订单状态(仅输出)。文档:open / completed / cancelled。来源:Order.status */
22
+ /** 支付状态。来源:Order.payment_status */
23
+ /** 发货状态(仅输出)。来源:Order.shipping_status */
24
+ /**
25
+ * 预约子事件状态(仅输出)。
26
+ * 文档:new / confirmed / arrived / started / completed / cancelled。
27
+ * 来源:ScheduleEvent.appointment_status
28
+ */
29
+ /** 折扣类型:shop(整单)/ product(商品)。来源:Discount.type */
30
+ /** 支付记录状态:paid / voided / payment_pending 等。来源:OrderPayment.status */
31
+ /** 附加费类型。来源:OrderSurcharge.type */
32
+ // ─────────────────────────────────────────────────────────────────
33
+ // 3.3 products / 3.3.1 discount_list / 3.3.2 product_bundle
34
+ // ─────────────────────────────────────────────────────────────────
35
+ /** 商品折扣 metadata,常含 unique_identification_number */
36
+ /**
37
+ * 商品折扣项(3.3.1 discount_list)
38
+ */
39
+ /**
40
+ * 套餐子商品(3.3.2 product_bundle)
41
+ */
42
+ /** 商品行 metadata,常含 unique_identification_number */
43
+ /**
44
+ * 订单级商品行(3.3 products)。
45
+ * 订单级别的非预约关联商品;预约关联商品在 bookings 内。
46
+ * product_id 为关联 ID,展示信息从本地基准数据取;价格为交易快照须保留在 Sales 数据中。
47
+ */
48
+ // ─────────────────────────────────────────────────────────────────
49
+ // 3.4 bookings
50
+ // ─────────────────────────────────────────────────────────────────
51
+ /** 预约条目 metadata,常含 unique_identification_number */
52
+ /**
53
+ * 单条预约(子 schedule_event,parent_id != 0)。
54
+ * product 结构同 products 单项;relation_products 结构同 products 数组。
55
+ */
56
+ // ─────────────────────────────────────────────────────────────────
57
+ // 3.5 payments
58
+ // ─────────────────────────────────────────────────────────────────
59
+ /** 支付记录 metadata,常含 unique_payment_number */
60
+ /**
61
+ * 支付记录(3.5 payments)
62
+ */
63
+ // ─────────────────────────────────────────────────────────────────
64
+ // 3.6 surcharges
65
+ // ─────────────────────────────────────────────────────────────────
66
+ /**
67
+ * 订单附加费(3.6 surcharges)
68
+ */
69
+ // ─────────────────────────────────────────────────────────────────
70
+ // 3.7 summary(仅输出,由 OrderV2Service::computeOrderSummaryData 计算)
71
+ // ─────────────────────────────────────────────────────────────────
72
+ /**
73
+ * 订单数据结构(Server 侧对齐《统一 Sales 数据协议》)
74
+ */
75
+ /** 去掉 bookings 后的订单快照;展开预约行时挂在 {@link BookingData.order} 上 */
76
+ /**
77
+ * 展开后的单条预约视图:协议 {@link OrderBookingItem} 平铺字段 + 所属订单(不含 bookings)
78
+ */
79
+ /**
80
+ * 订单列表筛选条件(与 order.ts getFilterButtonList 等 UI 对齐)
81
+ */
82
+ /**
83
+ * 预约展开列表筛选条件(订单级条件匹配 booking.order.*,预约级匹配 booking 自身)
84
+ */
85
+ /** 分页筛选结果通用结构 */
86
+ /**
87
+ * SSE 同步配置
88
+ */
89
+ /**
90
+ * Ably 事件类型
91
+ */
92
+ /**
93
+ * Ably 事件载荷
94
+ */
95
+ /**
96
+ * OrderSyncMessage - pubsub 同步消息结构
97
+ */
98
+ /**
99
+ * Order 模块状态
100
+ */
101
+ /**
102
+ * Order 模块钩子
103
+ */
104
+ let OrderHooks = exports.OrderHooks = /*#__PURE__*/function (OrderHooks) {
105
+ OrderHooks["onOrdersLoaded"] = "order:onOrdersLoaded";
106
+ OrderHooks["onOrdersChanged"] = "order:onOrdersChanged";
107
+ OrderHooks["onOrdersSyncCompleted"] = "order:onOrdersSyncCompleted";
108
+ return OrderHooks;
109
+ }({});
@@ -1,78 +1,70 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __export = (target, all) => {
6
- for (var name in all)
7
- __defProp(target, name, { get: all[name], enumerable: true });
8
- };
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ "use strict";
18
2
 
19
- // src/server/modules/order/utils/filterBookings.ts
20
- var filterBookings_exports = {};
21
- __export(filterBookings_exports, {
22
- filterBookings: () => filterBookings,
23
- filterBookingsFromOrders: () => filterBookingsFromOrders,
24
- flattenOrdersToBookings: () => flattenOrdersToBookings,
25
- sortBookings: () => sortBookings
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
26
5
  });
27
- module.exports = __toCommonJS(filterBookings_exports);
6
+ exports.filterBookings = filterBookings;
7
+ exports.filterBookingsFromOrders = filterBookingsFromOrders;
8
+ exports.flattenOrdersToBookings = flattenOrdersToBookings;
9
+ exports.sortBookings = sortBookings;
10
+ /** 预约状态:协议 appointment_status 优先,兼容历史 status */
28
11
  function getBookingAppointmentStatus(booking) {
29
- return String(booking.appointment_status ?? booking.status ?? "");
12
+ return String(booking.appointment_status ?? booking.status ?? '');
30
13
  }
14
+
15
+ // ─────────────────────────────────────────────────────────────────
16
+ // 时间戳 / 范围解析
17
+ // ─────────────────────────────────────────────────────────────────
18
+
31
19
  function toTimestamp(value) {
32
- if (value === void 0 || value === null || value === "")
33
- return 0;
34
- if (typeof value === "number")
35
- return value;
20
+ if (value === undefined || value === null || value === '') return 0;
21
+ if (typeof value === 'number') return value;
36
22
  return new Date(value).getTime();
37
23
  }
24
+
25
+ /**
26
+ * 将 start_date / start_time(或 end_*)拼成可被 Date 稳定解析的字符串。
27
+ * 时间字段协议为 H:i(如 15:00)时补全为 H:i:00,避免部分环境对「无秒」非 ISO 串(空格分隔)解析不一致。
28
+ */
38
29
  function bookingDateTimeString(datePart, timePart) {
39
- const d = (datePart ?? "").trim();
40
- let t = (timePart ?? "").trim();
30
+ const d = (datePart ?? '').trim();
31
+ let t = (timePart ?? '').trim();
41
32
  if (t && /^\d{1,2}:\d{2}$/.test(t)) {
42
33
  t = `${t}:00`;
43
34
  }
44
35
  return `${d} ${t}`.trim();
45
36
  }
46
37
  function parseDateRange(range) {
47
- if (!Array.isArray(range) || range.length < 2)
48
- return null;
38
+ if (!Array.isArray(range) || range.length < 2) return null;
49
39
  const start = toTimestamp(range[0]);
50
40
  const end = toTimestamp(range[1]);
51
- if (!start && !end)
52
- return null;
41
+ if (!start && !end) return null;
53
42
  return [start, end];
54
43
  }
55
44
  function parseNumberRange(range) {
56
- if (!Array.isArray(range) || range.length < 2)
57
- return null;
45
+ if (!Array.isArray(range) || range.length < 2) return null;
58
46
  const min = Number(range[0]);
59
47
  const max = Number(range[1]);
60
- if (isNaN(min) || isNaN(max))
61
- return null;
48
+ if (isNaN(min) || isNaN(max)) return null;
62
49
  return [min, max];
63
50
  }
51
+
52
+ // ─────────────────────────────────────────────────────────────────
53
+ // 预编译过滤上下文:将 filters 一次性解析为高效的 Set / Range,
54
+ // 供 matchOrder、matchBooking 复用,避免重复计算
55
+ // ─────────────────────────────────────────────────────────────────
56
+
64
57
  function prepareFilters(f) {
65
- var _a, _b, _c, _d, _e, _f;
66
- const hasCustomerId = f.customer_id !== void 0 && f.customer_id !== null;
58
+ const hasCustomerId = f.customer_id !== undefined && f.customer_id !== null;
67
59
  return {
68
- orderPaymentStatusSet: ((_a = f.order_payment_status) == null ? void 0 : _a.length) ? new Set(f.order_payment_status) : null,
69
- orderStatusSet: ((_b = f.order_status) == null ? void 0 : _b.length) ? new Set(f.order_status) : null,
70
- orderSalesChannelSet: ((_c = f.order_sales_channel) == null ? void 0 : _c.length) ? new Set(f.order_sales_channel) : null,
71
- paymentMethodSet: ((_d = f.payment_method) == null ? void 0 : _d.length) ? new Set(f.payment_method) : null,
72
- appointmentStatusSet: ((_e = f.appointment_status) == null ? void 0 : _e.length) ? new Set(f.appointment_status) : null,
73
- formRecordIdSet: ((_f = f.form_record_ids) == null ? void 0 : _f.length) ? new Set(f.form_record_ids) : null,
60
+ orderPaymentStatusSet: f.order_payment_status?.length ? new Set(f.order_payment_status) : null,
61
+ orderStatusSet: f.order_status?.length ? new Set(f.order_status) : null,
62
+ orderSalesChannelSet: f.order_sales_channel?.length ? new Set(f.order_sales_channel) : null,
63
+ paymentMethodSet: f.payment_method?.length ? new Set(f.payment_method) : null,
64
+ appointmentStatusSet: f.appointment_status?.length ? new Set(f.appointment_status) : null,
65
+ formRecordIdSet: f.form_record_ids?.length ? new Set(f.form_record_ids) : null,
74
66
  hasCustomerId,
75
- customerIdStr: hasCustomerId ? String(f.customer_id) : "",
67
+ customerIdStr: hasCustomerId ? String(f.customer_id) : '',
76
68
  hasBusinessCode: !!f.business_code,
77
69
  businessCode: f.business_code,
78
70
  bookingTimeRange: parseDateRange(f.sales_time_between),
@@ -80,33 +72,30 @@ function prepareFilters(f) {
80
72
  updatedAtRange: parseDateRange(f.updated_at_between),
81
73
  numberRange: parseNumberRange(f.number_between),
82
74
  totalAmountRange: Array.isArray(f.total_amount_between) && f.total_amount_between.length === 2 ? f.total_amount_between : null,
83
- keywordLower: f.keyword ? f.keyword.toLowerCase() : "",
75
+ keywordLower: f.keyword ? f.keyword.toLowerCase() : '',
84
76
  afterExecutionTimeMs: (() => {
85
77
  const raw = f.after_execution_time;
86
- if (raw === void 0 || raw === null || raw === "")
87
- return null;
78
+ if (raw === undefined || raw === null || raw === '') return null;
88
79
  const ms = toTimestamp(raw);
89
80
  return Number.isFinite(ms) ? ms : null;
90
81
  })(),
91
82
  enableChildBookingFilter: f.child_booking === 1
92
83
  };
93
84
  }
85
+
86
+ // ─────────────────────────────────────────────────────────────────
87
+ // 订单级匹配:不通过则整个 order 下所有 bookings 跳过
88
+ // ─────────────────────────────────────────────────────────────────
89
+
94
90
  function matchOrder(order, ctx) {
95
- var _a;
96
- if (ctx.hasBusinessCode && order.business_code !== ctx.businessCode)
97
- return false;
98
- if (ctx.hasCustomerId && String(order.customer_id) !== ctx.customerIdStr)
99
- return false;
100
- if (ctx.orderPaymentStatusSet && !ctx.orderPaymentStatusSet.has(order.payment_status))
101
- return false;
102
- if (ctx.orderStatusSet && !ctx.orderStatusSet.has(order.status))
103
- return false;
104
- if (ctx.orderSalesChannelSet && !ctx.orderSalesChannelSet.has(order.order_sales_channel))
105
- return false;
91
+ if (ctx.hasBusinessCode && order.business_code !== ctx.businessCode) return false;
92
+ if (ctx.hasCustomerId && String(order.customer_id) !== ctx.customerIdStr) return false;
93
+ if (ctx.orderPaymentStatusSet && !ctx.orderPaymentStatusSet.has(order.payment_status)) return false;
94
+ if (ctx.orderStatusSet && !ctx.orderStatusSet.has(order.status)) return false;
95
+ if (ctx.orderSalesChannelSet && !ctx.orderSalesChannelSet.has(order.order_sales_channel)) return false;
106
96
  if (ctx.paymentMethodSet) {
107
97
  const pm = order.payments;
108
- if (!Array.isArray(pm) || pm.length === 0)
109
- return false;
98
+ if (!Array.isArray(pm) || pm.length === 0) return false;
110
99
  let matched = false;
111
100
  for (let k = 0; k < pm.length; k++) {
112
101
  if (ctx.paymentMethodSet.has(pm[k].code)) {
@@ -114,101 +103,121 @@ function matchOrder(order, ctx) {
114
103
  break;
115
104
  }
116
105
  }
117
- if (!matched)
118
- return false;
106
+ if (!matched) return false;
119
107
  }
120
108
  if (ctx.createdAtRange) {
121
109
  const ts = toTimestamp(order.created_at);
122
- if (ts < ctx.createdAtRange[0] || ts > ctx.createdAtRange[1])
123
- return false;
110
+ if (ts < ctx.createdAtRange[0] || ts > ctx.createdAtRange[1]) return false;
124
111
  }
125
112
  if (ctx.updatedAtRange) {
126
113
  const ts = toTimestamp(order.updated_at);
127
- if (ts < ctx.updatedAtRange[0] || ts > ctx.updatedAtRange[1])
128
- return false;
114
+ if (ts < ctx.updatedAtRange[0] || ts > ctx.updatedAtRange[1]) return false;
129
115
  }
130
116
  if (ctx.totalAmountRange) {
131
- const raw = ((_a = order.summary) == null ? void 0 : _a.total_amount) ?? order.total_amount;
117
+ const raw = order.summary?.total_amount ?? order.total_amount;
132
118
  const amt = Number(raw);
133
- if (isNaN(amt))
134
- return false;
135
- if (ctx.totalAmountRange[0] != null && amt < ctx.totalAmountRange[0])
136
- return false;
137
- if (ctx.totalAmountRange[1] != null && amt > ctx.totalAmountRange[1])
138
- return false;
119
+ if (isNaN(amt)) return false;
120
+ if (ctx.totalAmountRange[0] != null && amt < ctx.totalAmountRange[0]) return false;
121
+ if (ctx.totalAmountRange[1] != null && amt > ctx.totalAmountRange[1]) return false;
139
122
  }
140
123
  return true;
141
124
  }
125
+
126
+ // ─────────────────────────────────────────────────────────────────
127
+ // Booking 级匹配:在订单通过之后逐条检查每个 booking
128
+ // orderInfo 用于 keyword 搜索时的 JSON 序列化
129
+ // ─────────────────────────────────────────────────────────────────
130
+
142
131
  function matchBooking(booking, orderInfo, ctx) {
143
132
  if (ctx.enableChildBookingFilter) {
144
133
  const parentId = Number(booking.parent_id ?? 0);
145
- const itemType = String(booking.item_type ?? "");
146
- const isMatched = parentId !== 0 && itemType !== "recurring_booking" || parentId === 0 && itemType === "recurring_booking";
147
- if (!isMatched)
148
- return false;
134
+ const itemType = String(booking.item_type ?? '');
135
+ const isMatched = parentId !== 0 && itemType !== 'recurring_booking' || parentId === 0 && itemType === 'recurring_booking';
136
+ if (!isMatched) return false;
149
137
  }
150
- if (ctx.appointmentStatusSet && !ctx.appointmentStatusSet.has(getBookingAppointmentStatus(booking)))
151
- return false;
138
+ if (ctx.appointmentStatusSet && !ctx.appointmentStatusSet.has(getBookingAppointmentStatus(booking))) return false;
152
139
  if (ctx.bookingTimeRange) {
153
140
  const ts = toTimestamp(booking.start_date);
154
- if (ts < ctx.bookingTimeRange[0] || ts > ctx.bookingTimeRange[1])
155
- return false;
141
+ if (ts < ctx.bookingTimeRange[0] || ts > ctx.bookingTimeRange[1]) return false;
156
142
  }
157
143
  if (ctx.afterExecutionTimeMs != null) {
158
144
  const bookingStartMs = toTimestamp(bookingDateTimeString(booking.start_date, booking.start_time));
159
- if (!Number.isFinite(bookingStartMs) || bookingStartMs < ctx.afterExecutionTimeMs)
160
- return false;
145
+ if (!Number.isFinite(bookingStartMs) || bookingStartMs < ctx.afterExecutionTimeMs) return false;
161
146
  }
162
147
  if (ctx.numberRange) {
163
148
  const num = Number(booking.number);
164
- if (isNaN(num) || num < ctx.numberRange[0] || num > ctx.numberRange[1])
165
- return false;
149
+ if (isNaN(num) || num < ctx.numberRange[0] || num > ctx.numberRange[1]) return false;
166
150
  }
167
151
  if (ctx.formRecordIdSet) {
168
152
  let formMatched = false;
169
153
  const resources = booking.resources;
170
154
  if (Array.isArray(resources)) {
171
155
  for (let r = 0; r < resources.length; r++) {
172
- if (resources[r].relation_type === "form" && ctx.formRecordIdSet.has(resources[r].relation_id)) {
156
+ if (resources[r].relation_type === 'form' && ctx.formRecordIdSet.has(resources[r].relation_id)) {
173
157
  formMatched = true;
174
158
  break;
175
159
  }
176
160
  }
177
161
  }
178
- if (!formMatched && booking.relation_type === "form" && booking.relation_id && booking.relation_id > 0) {
162
+ if (!formMatched && booking.relation_type === 'form' && booking.relation_id && booking.relation_id > 0) {
179
163
  formMatched = ctx.formRecordIdSet.has(booking.relation_id);
180
164
  }
181
- if (!formMatched)
182
- return false;
165
+ if (!formMatched) return false;
183
166
  }
184
167
  if (ctx.keywordLower) {
185
- const target = orderInfo ? { ...booking, order: orderInfo } : booking;
168
+ const target = orderInfo ? {
169
+ ...booking,
170
+ order: orderInfo
171
+ } : booking;
186
172
  const str = JSON.stringify(target).toLowerCase();
187
- if (!str.includes(ctx.keywordLower))
188
- return false;
173
+ if (!str.includes(ctx.keywordLower)) return false;
189
174
  }
190
175
  return true;
191
176
  }
177
+
178
+ // ─────────────────────────────────────────────────────────────────
179
+ // 转换:OrderData[] → BookingData[](独立导出,供其他场景使用)
180
+ // ─────────────────────────────────────────────────────────────────
181
+
192
182
  function flattenOrdersToBookings(orders) {
193
- if (!orders || !Array.isArray(orders))
194
- return [];
183
+ if (!orders || !Array.isArray(orders)) return [];
195
184
  const result = [];
196
185
  for (let i = 0, len = orders.length; i < len; i++) {
197
186
  const order = orders[i];
198
187
  const bookings = order.bookings;
199
- if (!Array.isArray(bookings) || bookings.length === 0)
200
- continue;
201
- const { bookings: _omit, ...orderInfo } = order;
188
+ if (!Array.isArray(bookings) || bookings.length === 0) continue;
189
+ const {
190
+ bookings: _omit,
191
+ ...orderInfo
192
+ } = order;
202
193
  for (let j = 0, bLen = bookings.length; j < bLen; j++) {
203
- result.push({ ...bookings[j], order: orderInfo });
194
+ result.push({
195
+ ...bookings[j],
196
+ order: orderInfo
197
+ });
204
198
  }
205
199
  }
206
200
  return result;
207
201
  }
202
+
203
+ // ─────────────────────────────────────────────────────────────────
204
+ // 核心:单遍扫描 — 展开 + 过滤 + 分页
205
+ //
206
+ // 性能策略:
207
+ // 1. 订单级条件在外层循环 matchOrder 预判,不匹配则整组 bookings 跳过
208
+ // 2. orderInfo 延迟到有命中 booking 时才创建,同一 order 只创建一次
209
+ // 3. 只对最终命中的 booking 做 object spread
210
+ // ─────────────────────────────────────────────────────────────────
211
+
208
212
  function filterBookingsFromOrders(orders, filters) {
209
213
  const f = filters || {};
210
214
  if (!orders || !Array.isArray(orders)) {
211
- return { list: [], count: 0, size: 0, skip: 0 };
215
+ return {
216
+ list: [],
217
+ count: 0,
218
+ size: 0,
219
+ skip: 0
220
+ };
212
221
  }
213
222
  const size = f.num || 20;
214
223
  const page = f.skip || 1;
@@ -219,25 +228,39 @@ function filterBookingsFromOrders(orders, filters) {
219
228
  for (let i = 0, oLen = orders.length; i < oLen; i++) {
220
229
  const order = orders[i];
221
230
  const bookings = order.bookings;
222
- if (!Array.isArray(bookings) || bookings.length === 0)
223
- continue;
224
- if (!matchOrder(order, ctx))
225
- continue;
231
+ if (!Array.isArray(bookings) || bookings.length === 0) continue;
232
+
233
+ // 订单级预过滤
234
+ if (!matchOrder(order, ctx)) continue;
235
+
236
+ // 订单通过,遍历其 bookings;orderInfo 延迟创建
226
237
  let orderInfo = null;
227
238
  for (let j = 0, bLen = bookings.length; j < bLen; j++) {
228
239
  const booking = bookings[j];
240
+
241
+ // keyword 匹配需要 orderInfo,提前创建
229
242
  if (ctx.keywordLower && !orderInfo) {
230
- const { bookings: _omit, ...rest } = order;
243
+ const {
244
+ bookings: _omit,
245
+ ...rest
246
+ } = order;
231
247
  orderInfo = rest;
232
248
  }
233
- if (!matchBooking(booking, orderInfo, ctx))
234
- continue;
249
+ if (!matchBooking(booking, orderInfo, ctx)) continue;
250
+
251
+ // 命中:收集到分页窗口内
235
252
  if (totalCount >= startIndex && paginatedList.length < size) {
236
253
  if (!orderInfo) {
237
- const { bookings: _omit, ...rest } = order;
254
+ const {
255
+ bookings: _omit,
256
+ ...rest
257
+ } = order;
238
258
  orderInfo = rest;
239
259
  }
240
- paginatedList.push({ ...booking, order: orderInfo });
260
+ paginatedList.push({
261
+ ...booking,
262
+ order: orderInfo
263
+ });
241
264
  }
242
265
  totalCount++;
243
266
  }
@@ -249,28 +272,32 @@ function filterBookingsFromOrders(orders, filters) {
249
272
  skip: page
250
273
  };
251
274
  }
275
+
276
+ // ─────────────────────────────────────────────────────────────────
277
+ // 排序预约列表
278
+ // order_by 格式:"field:direction",如 "start_at:desc"
279
+ // 不带方向后缀则不排序
280
+ // ─────────────────────────────────────────────────────────────────
281
+
252
282
  function sortBookings(result, filters) {
253
283
  const f = filters || {};
254
284
  const orderBy = f.order_by;
255
- if (!orderBy)
256
- return result;
257
- const separatorIdx = orderBy.lastIndexOf(":");
258
- if (separatorIdx === -1)
259
- return result;
285
+ if (!orderBy) return result;
286
+ const separatorIdx = orderBy.lastIndexOf(':');
287
+ if (separatorIdx === -1) return result;
260
288
  const field = orderBy.slice(0, separatorIdx);
261
289
  const direction = orderBy.slice(separatorIdx + 1);
262
- if (direction !== "asc" && direction !== "desc")
263
- return result;
264
- const multiplier = direction === "asc" ? 1 : -1;
265
- const getTimestamp = (booking) => {
290
+ if (direction !== 'asc' && direction !== 'desc') return result;
291
+ const multiplier = direction === 'asc' ? 1 : -1;
292
+ const getTimestamp = booking => {
266
293
  switch (field) {
267
- case "start_at":
294
+ case 'start_at':
268
295
  return toTimestamp(bookingDateTimeString(booking.start_date, booking.start_time));
269
- case "end_at":
296
+ case 'end_at':
270
297
  return toTimestamp(bookingDateTimeString(booking.end_date, booking.end_time));
271
- case "created_at":
298
+ case 'created_at':
272
299
  return toTimestamp(booking.order.created_at);
273
- case "updated_at":
300
+ case 'updated_at':
274
301
  return toTimestamp(booking.order.updated_at);
275
302
  default:
276
303
  return 0;
@@ -279,12 +306,26 @@ function sortBookings(result, filters) {
279
306
  const sorted = result.list.slice().sort((a, b) => {
280
307
  return (getTimestamp(a) - getTimestamp(b)) * multiplier;
281
308
  });
282
- return { ...result, list: sorted };
309
+ return {
310
+ ...result,
311
+ list: sorted
312
+ };
283
313
  }
314
+
315
+ // ─────────────────────────────────────────────────────────────────
316
+ // 兼容独立调用:对已展开的 BookingData[] 做筛选
317
+ // 复用 matchOrder + matchBooking,仅负责迭代与分页
318
+ // ─────────────────────────────────────────────────────────────────
319
+
284
320
  function filterBookings(bookings, filters) {
285
321
  const f = filters || {};
286
322
  if (!bookings || !Array.isArray(bookings)) {
287
- return { list: [], count: 0, size: 0, skip: 0 };
323
+ return {
324
+ list: [],
325
+ count: 0,
326
+ size: 0,
327
+ skip: 0
328
+ };
288
329
  }
289
330
  const size = f.num || 20;
290
331
  const page = f.skip || 1;
@@ -295,10 +336,10 @@ function filterBookings(bookings, filters) {
295
336
  for (let i = 0, len = bookings.length; i < len; i++) {
296
337
  const booking = bookings[i];
297
338
  const order = booking.order;
298
- if (!matchOrder(order, ctx))
299
- continue;
300
- if (!matchBooking(booking, order, ctx))
301
- continue;
339
+
340
+ // 订单级 + booking 级统一匹配
341
+ if (!matchOrder(order, ctx)) continue;
342
+ if (!matchBooking(booking, order, ctx)) continue;
302
343
  if (totalCount >= startIndex && paginatedList.length < size) {
303
344
  paginatedList.push(booking);
304
345
  }
@@ -310,11 +351,4 @@ function filterBookings(bookings, filters) {
310
351
  size,
311
352
  skip: page
312
353
  };
313
- }
314
- // Annotate the CommonJS export names for ESM import in node:
315
- 0 && (module.exports = {
316
- filterBookings,
317
- filterBookingsFromOrders,
318
- flattenOrdersToBookings,
319
- sortBookings
320
- });
354
+ }