@pisell/pisellos 2.1.36 → 2.2.1

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 (133) hide show
  1. package/dist/core/index.d.ts +8 -1
  2. package/dist/core/index.js +116 -42
  3. package/dist/effects/index.d.ts +1 -0
  4. package/dist/effects/index.js +29 -6
  5. package/dist/modules/Account/index.js +2 -3
  6. package/dist/modules/BaseModule.d.ts +3 -0
  7. package/dist/modules/BaseModule.js +15 -0
  8. package/dist/modules/Customer/index.js +9 -10
  9. package/dist/modules/Customer/types.d.ts +2 -2
  10. package/dist/modules/Customer/types.js +2 -2
  11. package/dist/modules/Discount/index.js +1 -1
  12. package/dist/modules/Guests/index.js +9 -9
  13. package/dist/modules/Order/index.js +1 -1
  14. package/dist/modules/Payment/index.js +63 -73
  15. package/dist/modules/Payment/walletpass.js +4 -1
  16. package/dist/modules/Product/types.d.ts +19 -0
  17. package/dist/modules/ProductList/index.js +5 -14
  18. package/dist/modules/Resource/index.js +1 -1
  19. package/dist/modules/Rules/index.js +2 -3
  20. package/dist/modules/Schedule/types.d.ts +2 -0
  21. package/dist/plugins/request.d.ts +1 -0
  22. package/dist/server/index.d.ts +152 -0
  23. package/dist/server/index.js +946 -0
  24. package/dist/server/modules/index.d.ts +16 -0
  25. package/dist/server/modules/index.js +21 -0
  26. package/dist/server/modules/menu/index.d.ts +63 -0
  27. package/dist/server/modules/menu/index.js +476 -0
  28. package/dist/server/modules/menu/types.d.ts +68 -0
  29. package/dist/server/modules/menu/types.js +16 -0
  30. package/dist/server/modules/products/index.d.ts +141 -0
  31. package/dist/server/modules/products/index.js +768 -0
  32. package/dist/server/modules/products/types.d.ts +94 -0
  33. package/dist/server/modules/products/types.js +43 -0
  34. package/dist/server/modules/quotation/index.d.ts +47 -0
  35. package/dist/server/modules/quotation/index.js +367 -0
  36. package/dist/server/modules/quotation/types.d.ts +50 -0
  37. package/dist/server/modules/quotation/types.js +20 -0
  38. package/dist/server/modules/schedule/index.d.ts +62 -0
  39. package/dist/server/modules/schedule/index.js +431 -0
  40. package/dist/server/modules/schedule/types.d.ts +1 -0
  41. package/dist/server/modules/schedule/types.js +2 -0
  42. package/dist/server/modules/schedule/utils.d.ts +32 -0
  43. package/dist/server/modules/schedule/utils.js +747 -0
  44. package/dist/server/types.d.ts +64 -0
  45. package/dist/server/types.js +1 -0
  46. package/dist/server/utils/index.d.ts +5 -0
  47. package/dist/server/utils/index.js +6 -0
  48. package/dist/server/utils/product.d.ts +18 -0
  49. package/dist/server/utils/product.js +339 -0
  50. package/dist/server/utils/schedule.d.ts +14 -0
  51. package/dist/server/utils/schedule.js +108 -0
  52. package/dist/server/utils/time.d.ts +18 -0
  53. package/dist/server/utils/time.js +53 -0
  54. package/dist/solution/BookingByStep/index.d.ts +0 -16
  55. package/dist/solution/BookingByStep/index.js +57 -508
  56. package/dist/solution/BookingByStep/utils/capacity.d.ts +2 -7
  57. package/dist/solution/BookingByStep/utils/capacity.js +8 -24
  58. package/dist/solution/BookingTicket/index.d.ts +12 -0
  59. package/dist/solution/BookingTicket/index.js +122 -79
  60. package/dist/solution/BookingTicket/utils/scan/index.d.ts +4 -0
  61. package/dist/solution/BookingTicket/utils/scan/index.js +25 -16
  62. package/dist/solution/BuyTickets/index.js +7 -8
  63. package/dist/solution/Checkout/index.d.ts +1 -46
  64. package/dist/solution/Checkout/index.js +530 -850
  65. package/dist/solution/ShopDiscount/index.js +9 -10
  66. package/dist/types/index.d.ts +27 -0
  67. package/lib/core/index.d.ts +8 -1
  68. package/lib/core/index.js +48 -1
  69. package/lib/effects/index.d.ts +1 -0
  70. package/lib/effects/index.js +13 -0
  71. package/lib/modules/Account/index.js +2 -3
  72. package/lib/modules/BaseModule.d.ts +3 -0
  73. package/lib/modules/BaseModule.js +9 -0
  74. package/lib/modules/Customer/index.js +9 -10
  75. package/lib/modules/Customer/types.d.ts +2 -2
  76. package/lib/modules/Customer/types.js +2 -2
  77. package/lib/modules/Discount/index.js +1 -1
  78. package/lib/modules/Guests/index.js +9 -9
  79. package/lib/modules/Order/index.js +1 -1
  80. package/lib/modules/Payment/index.js +56 -43
  81. package/lib/modules/Payment/walletpass.js +3 -1
  82. package/lib/modules/Product/types.d.ts +19 -0
  83. package/lib/modules/ProductList/index.js +4 -13
  84. package/lib/modules/Resource/index.js +1 -1
  85. package/lib/modules/Rules/index.js +2 -3
  86. package/lib/modules/Schedule/types.d.ts +2 -0
  87. package/lib/plugins/request.d.ts +1 -0
  88. package/lib/server/index.d.ts +152 -0
  89. package/lib/server/index.js +555 -0
  90. package/lib/server/modules/index.d.ts +16 -0
  91. package/lib/server/modules/index.js +47 -0
  92. package/lib/server/modules/menu/index.d.ts +63 -0
  93. package/lib/server/modules/menu/index.js +234 -0
  94. package/lib/server/modules/menu/types.d.ts +68 -0
  95. package/lib/server/modules/menu/types.js +33 -0
  96. package/lib/server/modules/products/index.d.ts +141 -0
  97. package/lib/server/modules/products/index.js +434 -0
  98. package/lib/server/modules/products/types.d.ts +94 -0
  99. package/lib/server/modules/products/types.js +35 -0
  100. package/lib/server/modules/quotation/index.d.ts +47 -0
  101. package/lib/server/modules/quotation/index.js +177 -0
  102. package/lib/server/modules/quotation/types.d.ts +50 -0
  103. package/lib/server/modules/quotation/types.js +33 -0
  104. package/lib/server/modules/schedule/index.d.ts +62 -0
  105. package/lib/server/modules/schedule/index.js +231 -0
  106. package/lib/server/modules/schedule/types.d.ts +1 -0
  107. package/lib/server/modules/schedule/types.js +23 -0
  108. package/lib/server/modules/schedule/utils.d.ts +32 -0
  109. package/lib/server/modules/schedule/utils.js +451 -0
  110. package/lib/server/types.d.ts +64 -0
  111. package/lib/server/types.js +17 -0
  112. package/lib/server/utils/index.d.ts +5 -0
  113. package/lib/server/utils/index.js +25 -0
  114. package/lib/server/utils/product.d.ts +18 -0
  115. package/lib/server/utils/product.js +262 -0
  116. package/lib/server/utils/schedule.d.ts +14 -0
  117. package/lib/server/utils/schedule.js +88 -0
  118. package/lib/server/utils/time.d.ts +18 -0
  119. package/lib/server/utils/time.js +70 -0
  120. package/lib/solution/BookingByStep/index.d.ts +0 -16
  121. package/lib/solution/BookingByStep/index.js +44 -316
  122. package/lib/solution/BookingByStep/utils/capacity.d.ts +2 -7
  123. package/lib/solution/BookingByStep/utils/capacity.js +8 -21
  124. package/lib/solution/BookingTicket/index.d.ts +12 -0
  125. package/lib/solution/BookingTicket/index.js +25 -6
  126. package/lib/solution/BookingTicket/utils/scan/index.d.ts +4 -0
  127. package/lib/solution/BookingTicket/utils/scan/index.js +7 -1
  128. package/lib/solution/BuyTickets/index.js +7 -8
  129. package/lib/solution/Checkout/index.d.ts +1 -46
  130. package/lib/solution/Checkout/index.js +92 -289
  131. package/lib/solution/ShopDiscount/index.js +10 -11
  132. package/lib/types/index.d.ts +27 -0
  133. package/package.json +2 -2
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Server 类型定义
3
+ */
4
+ export type CacheType = 'memory' | 'storage' | 'indexDB';
5
+ export interface CacheProps {
6
+ key?: string;
7
+ type?: CacheType;
8
+ updateCache?: boolean;
9
+ cacheUpdateChange?: (data: any) => void;
10
+ }
11
+ export interface RequestSetting {
12
+ abort?: boolean;
13
+ headers?: any;
14
+ cache?: CacheProps;
15
+ signal?: any;
16
+ token?: string;
17
+ osServer?: boolean;
18
+ [key: string]: any;
19
+ }
20
+ /**
21
+ * 路由处理函数类型
22
+ */
23
+ export type RouteHandler = (params: {
24
+ url: string;
25
+ method: 'get' | 'post' | 'remove' | 'put';
26
+ data?: any;
27
+ config?: RequestSetting;
28
+ }) => Promise<any> | any;
29
+ /**
30
+ * HTTP 方法类型
31
+ */
32
+ export type HttpMethod = 'get' | 'post' | 'remove' | 'put';
33
+ /**
34
+ * 路由定义类型
35
+ */
36
+ export type RouteDefinition = {
37
+ method: HttpMethod;
38
+ path: string;
39
+ handler: RouteHandler;
40
+ };
41
+ /**
42
+ * Router 对象类型
43
+ */
44
+ export interface Router {
45
+ get: Record<string, RouteHandler>;
46
+ post: Record<string, RouteHandler>;
47
+ put: Record<string, RouteHandler>;
48
+ remove: Record<string, RouteHandler>;
49
+ }
50
+ /**
51
+ * 模块注册配置(内部使用)
52
+ */
53
+ export interface ModuleRegistryConfig {
54
+ /** 模块名称 */
55
+ name: string;
56
+ /** 模块类 */
57
+ moduleClass: any;
58
+ /** 模块完整名称(用于注册到 Core) */
59
+ moduleName: string;
60
+ /** 模块版本 */
61
+ version: string;
62
+ /** 默认 store 结构 */
63
+ defaultStore: Record<string, any>;
64
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Server 工具函数集合
3
+ */
4
+ export * from './time';
5
+ export * from './schedule';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Server 工具函数集合
3
+ */
4
+
5
+ export * from "./time";
6
+ export * from "./schedule";
@@ -0,0 +1,18 @@
1
+ import { ProductData } from '../../modules/Product/types';
2
+ import { FormattedProductData, LoadProductsPriceData, ProductFormatterContext } from '../modules/products/types';
3
+ /**
4
+ * 将价格数据应用到商品列表(高性能版本)
5
+ * 通过预构建 Map 索引,将时间复杂度从 O(n×m) 优化到 O(n+m)
6
+ * @param products 商品列表
7
+ * @param priceData 价格数据
8
+ * @returns 应用价格后的商品列表
9
+ */
10
+ export declare function applyPriceDataToProducts(products: ProductData[], priceData: LoadProductsPriceData[]): ProductData[];
11
+ export declare const getIsSessionProduct: (product: ProductData) => boolean;
12
+ /**
13
+ * 将详情值数据应用到商品列表
14
+ * @param products 商品列表
15
+ * @param context 格式化器上下文
16
+ * @returns 应用详情值后的商品列表
17
+ */
18
+ export declare function applyDetailValueToProducts(products: ProductData[], context: ProductFormatterContext): FormattedProductData[];
@@ -0,0 +1,339 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
5
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
9
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10
+ import Decimal from 'decimal.js';
11
+ import { getScheduleStartEndTimePoints } from "../modules/schedule/utils";
12
+ import { getUniqueId } from "../../modules/Cart/utils";
13
+
14
+ /**
15
+ * 构建价格数据的 Map 索引结构
16
+ * 使用三层 Map 实现 O(1) 查询,大幅提升性能
17
+ * @param priceData 价格数据数组
18
+ * @returns 三层 Map 索引:商品、variant、bundle
19
+ */
20
+ function buildPriceIndexMap(priceData) {
21
+ // 1. 商品主价格 Map: productId -> priceInfo
22
+ var priceMap = new Map(priceData.map(function (p) {
23
+ return [p.id, p];
24
+ }));
25
+
26
+ // 2. Variant 价格 Map: productId -> (variantId -> variantPriceInfo)
27
+ var variantMap = new Map();
28
+ priceData.forEach(function (p) {
29
+ if (p.variant && p.variant.length > 0) {
30
+ var variantById = new Map(p.variant.map(function (v) {
31
+ return [v.id, v];
32
+ }));
33
+ variantMap.set(p.id, variantById);
34
+ }
35
+ });
36
+
37
+ // 3. Bundle 价格 Map: productId -> (groupId -> (itemId -> itemPriceInfo))
38
+ var bundleMap = new Map();
39
+ priceData.forEach(function (p) {
40
+ if (p.bundle_group && p.bundle_group.length > 0) {
41
+ var groupMap = new Map();
42
+ p.bundle_group.forEach(function (bg) {
43
+ var itemMap = new Map(bg.bundle_item.map(function (bi) {
44
+ return [bi.id, bi];
45
+ }));
46
+ groupMap.set(bg.id, itemMap);
47
+ });
48
+ bundleMap.set(p.id, groupMap);
49
+ }
50
+ });
51
+ return {
52
+ priceMap: priceMap,
53
+ variantMap: variantMap,
54
+ bundleMap: bundleMap
55
+ };
56
+ }
57
+
58
+ /**
59
+ * 将价格数据应用到商品列表(高性能版本)
60
+ * 通过预构建 Map 索引,将时间复杂度从 O(n×m) 优化到 O(n+m)
61
+ * @param products 商品列表
62
+ * @param priceData 价格数据
63
+ * @returns 应用价格后的商品列表
64
+ */
65
+ export function applyPriceDataToProducts(products, priceData) {
66
+ // 如果没有价格数据,直接返回原商品
67
+ if (!priceData || priceData.length === 0) {
68
+ console.log('[applyPriceDataToProducts] 没有价格数据,返回原商品');
69
+ return products;
70
+ }
71
+
72
+ // 预先构建 Map 索引(O(m) 时间)
73
+ var _buildPriceIndexMap = buildPriceIndexMap(priceData),
74
+ priceMap = _buildPriceIndexMap.priceMap,
75
+ variantMap = _buildPriceIndexMap.variantMap,
76
+ bundleMap = _buildPriceIndexMap.bundleMap;
77
+ console.log("[applyPriceDataToProducts] \u5DF2\u6784\u5EFA\u4EF7\u683C\u7D22\u5F15\uFF0C\u5171 ".concat(priceMap.size, " \u4E2A\u5546\u54C1\u4EF7\u683C"));
78
+
79
+ // 应用价格到商品(O(n) 时间)
80
+ var updatedProducts = products.map(function (product) {
81
+ // O(1) 查询商品价格
82
+ var priceInfo = priceMap.get(product.id);
83
+ if (!priceInfo) {
84
+ return product;
85
+ }
86
+
87
+ // 深拷贝商品对象
88
+ var updatedProduct = _objectSpread({}, product);
89
+
90
+ // 1. 更新主价格(转换为 string 类型)
91
+ updatedProduct.price = priceInfo.price;
92
+ updatedProduct.base_price = priceInfo.base_price;
93
+
94
+ // 2. 更新 variant 价格
95
+ if (updatedProduct.variant && updatedProduct.variant.length > 0) {
96
+ var productVariantMap = variantMap.get(product.id);
97
+ if (productVariantMap) {
98
+ updatedProduct.variant = updatedProduct.variant.map(function (v) {
99
+ var priceVariant = productVariantMap.get(v.id); // O(1)
100
+ if (priceVariant) {
101
+ return _objectSpread(_objectSpread({}, v), {}, {
102
+ price: String(priceVariant.price),
103
+ base_price: String(priceVariant.base_price)
104
+ });
105
+ }
106
+ return v;
107
+ });
108
+ }
109
+ }
110
+
111
+ // 3. 更新 bundle_groups 价格
112
+ if (updatedProduct.bundle_groups && updatedProduct.bundle_groups.length > 0) {
113
+ var productBundleMap = bundleMap.get(product.id);
114
+ if (productBundleMap) {
115
+ updatedProduct.bundle_groups = updatedProduct.bundle_groups.map(function (bg) {
116
+ var groupItemMap = productBundleMap.get(bg.id); // O(1)
117
+ if (!groupItemMap) return bg;
118
+ return _objectSpread(_objectSpread({}, bg), {}, {
119
+ bundle_item: bg.bundle_item.map(function (bi) {
120
+ var priceBi = groupItemMap.get(bi.id); // O(1)
121
+ if (priceBi) {
122
+ // 处理 markdown 类型
123
+ var price = priceBi.price;
124
+ if (priceBi.price_type === 'markdown') {
125
+ price = new Decimal(price || 0).mul(-1).toNumber();
126
+ }
127
+ return _objectSpread(_objectSpread({}, bi), {}, {
128
+ price: String(price),
129
+ base_price: String(priceBi.base_price)
130
+ });
131
+ }
132
+ return bi;
133
+ })
134
+ });
135
+ });
136
+ }
137
+ }
138
+ return updatedProduct;
139
+ });
140
+ console.log("[applyPriceDataToProducts] \u5DF2\u5E94\u7528\u4EF7\u683C\u5230 ".concat(updatedProducts.length, " \u4E2A\u5546\u54C1"));
141
+ return updatedProducts;
142
+ }
143
+ export var getIsSessionProduct = function getIsSessionProduct(product) {
144
+ return ['session_product', 'session_ticket'].includes(product.extension_type);
145
+ };
146
+
147
+ /**
148
+ * 获取是否打开详情弹窗
149
+ * @param product 商品
150
+ * @param context 格式化器上下文
151
+ * @returns 是否打开详情弹窗
152
+ */
153
+ var getIsOpenDetailModal = function getIsOpenDetailModal(product, context) {
154
+ /** 是否为套餐组商品 */
155
+ var isBundleProduct = product.bundle_group_count > 0;
156
+
157
+ /** 是否为选项组商品 */
158
+ var isOptionProduct = product.option_group_count > 0;
159
+
160
+ /** 是否为组合规格商品 */
161
+ var isVariantProduct = product.is_variant > 0;
162
+
163
+ /** 是否为日程商品 */
164
+ var isSessionProduct = getIsSessionProduct(product);
165
+
166
+ // 获取商品关联的日程时间段
167
+ var scheduleTimeSlots = [];
168
+ if (isSessionProduct && product['schedule.ids'] && context.scheduleModule) {
169
+ var scheduleIds = product['schedule.ids'];
170
+ // 从 context 中获取完整的 scheduleList,然后过滤出商品关联的 schedule
171
+ var productSchedules = context.scheduleModule.getScheduleByIds(scheduleIds);
172
+ // 获取当前日期的所有时间段
173
+ scheduleTimeSlots = getScheduleStartEndTimePoints(context.schedule_date, productSchedules);
174
+ }
175
+
176
+ // 是否打开详情弹窗 套餐组、选项组、组合规格、日程商品、日程时间段大于1个 打开详情弹窗
177
+ var isOpenDetailModal = isBundleProduct || isOptionProduct || isVariantProduct || scheduleTimeSlots.length > 1;
178
+ return {
179
+ isOpenDetailModal: isOpenDetailModal,
180
+ scheduleTimeSlots: scheduleTimeSlots
181
+ };
182
+ };
183
+ var formatDataKey = function formatDataKey(data) {
184
+ var _data$option, _data$bundle;
185
+ var _data = _objectSpread({}, data);
186
+ var key = "".concat(_data.product_id);
187
+ var rowKey = key;
188
+
189
+ // 组合规格
190
+ if (_data.product_variant_id) {
191
+ var str = "_".concat(_data.product_variant_id);
192
+ key += str;
193
+ rowKey += str;
194
+ }
195
+
196
+ // 单规格
197
+ if (_data !== null && _data !== void 0 && (_data$option = _data.option) !== null && _data$option !== void 0 && _data$option.length) {
198
+ var _iterator = _createForOfIteratorHelper(_data.option),
199
+ _step;
200
+ try {
201
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
202
+ var item = _step.value;
203
+ var _str = "_".concat(item.option_group_id, "_").concat(item.product_option_item_id);
204
+ key += _str;
205
+ rowKey += "".concat(_str, "_").concat(item.quantity || item.num);
206
+ }
207
+ } catch (err) {
208
+ _iterator.e(err);
209
+ } finally {
210
+ _iterator.f();
211
+ }
212
+ }
213
+
214
+ // 套餐
215
+ if (_data !== null && _data !== void 0 && (_data$bundle = _data.bundle) !== null && _data$bundle !== void 0 && _data$bundle.length) {
216
+ var _iterator2 = _createForOfIteratorHelper(_data.bundle),
217
+ _step2;
218
+ try {
219
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
220
+ var _item = _step2.value;
221
+ var _str2 = "_".concat(_item.group_id, "_").concat(_item.bundle_product_id);
222
+ key += _str2;
223
+ rowKey += "".concat(_str2, "_").concat(_item.quantity || _item.num);
224
+ // 如果有单规格
225
+ if (_item !== null && _item !== void 0 && _item.option) {
226
+ var _iterator3 = _createForOfIteratorHelper(_item.option),
227
+ _step3;
228
+ try {
229
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
230
+ var opt = _step3.value;
231
+ var _str3 = "_".concat(opt.option_group_id, "_").concat(opt.product_option_item_id);
232
+ key += _str3;
233
+ rowKey += "".concat(_str3, "_").concat(opt.quantity || opt.num);
234
+ }
235
+ } catch (err) {
236
+ _iterator3.e(err);
237
+ } finally {
238
+ _iterator3.f();
239
+ }
240
+ }
241
+ }
242
+ } catch (err) {
243
+ _iterator2.e(err);
244
+ } finally {
245
+ _iterator2.f();
246
+ }
247
+ }
248
+
249
+ // session time
250
+ if (_data !== null && _data !== void 0 && _data.session) {
251
+ var _data$session;
252
+ var _str4 = "_".concat(_data === null || _data === void 0 || (_data$session = _data.session) === null || _data$session === void 0 ? void 0 : _data$session.key);
253
+ key += _str4;
254
+ rowKey += _str4;
255
+ }
256
+ if (_data !== null && _data !== void 0 && _data.schedule) {
257
+ var _data$schedule;
258
+ var _str5 = "_".concat(_data === null || _data === void 0 || (_data$schedule = _data.schedule) === null || _data$schedule === void 0 ? void 0 : _data$schedule.key);
259
+ key += _str5;
260
+ rowKey += _str5;
261
+ }
262
+ _data.key = key;
263
+ _data.rowKey = rowKey;
264
+ return _data;
265
+ };
266
+
267
+ /**
268
+ * 生成购物车详情值
269
+ * @param product 商品
270
+ * @param context 格式化器上下文
271
+ * @returns 购物车详情值
272
+ */
273
+ var genCartDetailValue = function genCartDetailValue(product, scheduleTimeSlots) {
274
+ var params = {
275
+ product_id: product === null || product === void 0 ? void 0 : product.id,
276
+ option: [],
277
+ bundle: [],
278
+ product_variant_id: 0,
279
+ quantity: 1,
280
+ unique: getUniqueId(),
281
+ session: null
282
+ };
283
+ if (scheduleTimeSlots.length) {
284
+ params.session = scheduleTimeSlots.map(function (item) {
285
+ return _objectSpread(_objectSpread({}, item), {}, {
286
+ unique: getUniqueId()
287
+ });
288
+ })[0];
289
+ }
290
+ if (product !== null && product !== void 0 && product.service_times) {
291
+ params.service_times = product === null || product === void 0 ? void 0 : product.service_times;
292
+ }
293
+
294
+ // 票务订单需要返回对应的扩展属性
295
+ if (product !== null && product !== void 0 && product.machine_code) {
296
+ params.machine_code = product.machine_code;
297
+ }
298
+ if (product !== null && product !== void 0 && product['schedule.ids']) {
299
+ params.schedule_id = product['schedule.ids'];
300
+ }
301
+
302
+ // 协议id
303
+ if (product !== null && product !== void 0 && product.policy) {
304
+ params.policy_id = product === null || product === void 0 ? void 0 : product.policy;
305
+ }
306
+
307
+ // appointment预约商品
308
+ if (product !== null && product !== void 0 && product.duration) {
309
+ params.duration = product.duration;
310
+ }
311
+ return formatDataKey(params);
312
+ };
313
+
314
+ /**
315
+ * 将详情值数据应用到商品列表
316
+ * @param products 商品列表
317
+ * @param context 格式化器上下文
318
+ * @returns 应用详情值后的商品列表
319
+ */
320
+ export function applyDetailValueToProducts(products, context) {
321
+ var newProducts = products.map(function (product) {
322
+ /** 是否打开详情弹窗 套餐组、选项组、组合规格、日程商品、日程时间段大于1个 打开详情弹窗 */
323
+ var _getIsOpenDetailModal = getIsOpenDetailModal(product, context),
324
+ isOpenDetailModal = _getIsOpenDetailModal.isOpenDetailModal,
325
+ scheduleTimeSlots = _getIsOpenDetailModal.scheduleTimeSlots;
326
+ var cartDetailValue = null;
327
+ if (!isOpenDetailModal) {
328
+ // 生成购物车详情值
329
+ cartDetailValue = genCartDetailValue(product, scheduleTimeSlots);
330
+ }
331
+ return _objectSpread(_objectSpread({}, product), {}, {
332
+ // 是否打开详情弹窗
333
+ isOpenDetailModal: isOpenDetailModal,
334
+ // 购物车详情值
335
+ cartDetailValue: cartDetailValue
336
+ });
337
+ });
338
+ return newProducts;
339
+ }
@@ -0,0 +1,14 @@
1
+ import type { ScheduleItem } from '../../modules/Schedule/types';
2
+ import type { MenuData } from '../modules/menu/types';
3
+ /**
4
+ * 从餐牌列表中提取所有 schedule IDs
5
+ * @param menus 餐牌列表
6
+ * @returns 去重后的日程ID数组
7
+ */
8
+ export declare function extractScheduleIdsFromMenus(menus: MenuData[]): number[];
9
+ /**
10
+ * 从日程列表中提取所有时间点
11
+ * @param schedules 日程列表
12
+ * @returns 排序后的时间点数组,格式为 ["10:00", "12:00", "14:00", "18:00"]
13
+ */
14
+ export declare function extractTimePointsFromSchedules(schedules: ScheduleItem[]): string[];
@@ -0,0 +1,108 @@
1
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
5
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
6
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
7
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
8
+ import { extractTimeFromDateTime, sortTimePoints } from "./time";
9
+ /**
10
+ * 从餐牌列表中提取所有 schedule IDs
11
+ * @param menus 餐牌列表
12
+ * @returns 去重后的日程ID数组
13
+ */
14
+ export function extractScheduleIdsFromMenus(menus) {
15
+ var scheduleIds = menus.reduce(function (ids, menu) {
16
+ if (menu.schedule && Array.isArray(menu.schedule)) {
17
+ return [].concat(_toConsumableArray(ids), _toConsumableArray(menu.schedule));
18
+ }
19
+ return ids;
20
+ }, []);
21
+
22
+ // 去重
23
+ return Array.from(new Set(scheduleIds));
24
+ }
25
+
26
+ /**
27
+ * 从日程列表中提取所有时间点
28
+ * @param schedules 日程列表
29
+ * @returns 排序后的时间点数组,格式为 ["10:00", "12:00", "14:00", "18:00"]
30
+ */
31
+ export function extractTimePointsFromSchedules(schedules) {
32
+ var timePointsSet = new Set();
33
+ var _iterator = _createForOfIteratorHelper(schedules),
34
+ _step;
35
+ try {
36
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
37
+ var schedule = _step.value;
38
+ switch (schedule.type) {
39
+ case 'standard':
40
+ // 标准类型:从 start_time 和 end_time 中提取时间部分
41
+ if (schedule.start_time) {
42
+ var startTime = extractTimeFromDateTime(schedule.start_time);
43
+ if (startTime) timePointsSet.add(startTime);
44
+ }
45
+ if (schedule.end_time) {
46
+ var endTime = extractTimeFromDateTime(schedule.end_time);
47
+ if (endTime) timePointsSet.add(endTime);
48
+ }
49
+ break;
50
+ case 'time-slots':
51
+ // 时间段类型:从 time_slot 数组中提取时间
52
+ if (schedule.time_slot && Array.isArray(schedule.time_slot)) {
53
+ var _iterator2 = _createForOfIteratorHelper(schedule.time_slot),
54
+ _step2;
55
+ try {
56
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
57
+ var slot = _step2.value;
58
+ if (slot.start_time) {
59
+ timePointsSet.add(slot.start_time);
60
+ }
61
+ if (slot.end_time) {
62
+ timePointsSet.add(slot.end_time);
63
+ }
64
+ }
65
+ } catch (err) {
66
+ _iterator2.e(err);
67
+ } finally {
68
+ _iterator2.f();
69
+ }
70
+ }
71
+ break;
72
+ case 'designation':
73
+ // 指定日期类型:从 designation 中提取时间
74
+ if (schedule.designation) {
75
+ var designations = Array.isArray(schedule.designation) ? schedule.designation : [schedule.designation];
76
+ var _iterator3 = _createForOfIteratorHelper(designations),
77
+ _step3;
78
+ try {
79
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
80
+ var des = _step3.value;
81
+ if (des.start_time) {
82
+ timePointsSet.add(des.start_time);
83
+ }
84
+ if (des.end_time) {
85
+ timePointsSet.add(des.end_time);
86
+ }
87
+ }
88
+ } catch (err) {
89
+ _iterator3.e(err);
90
+ } finally {
91
+ _iterator3.f();
92
+ }
93
+ }
94
+ break;
95
+ default:
96
+ console.warn("[ScheduleUtils] \u672A\u77E5\u7684\u65E5\u7A0B\u7C7B\u578B: ".concat(schedule.type));
97
+ }
98
+ }
99
+
100
+ // 转换为数组并排序
101
+ } catch (err) {
102
+ _iterator.e(err);
103
+ } finally {
104
+ _iterator.f();
105
+ }
106
+ var timePoints = Array.from(timePointsSet);
107
+ return sortTimePoints(timePoints);
108
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 从日期时间字符串中提取时间部分
3
+ * @param dateTime 日期时间字符串,格式如 "2024-01-01 10:00:00"
4
+ * @returns 时间字符串,格式如 "10:00"
5
+ */
6
+ export declare function extractTimeFromDateTime(dateTime: string): string | null;
7
+ /**
8
+ * 将时间字符串转换为分钟数(用于排序)
9
+ * @param timeStr 时间字符串,格式如 "10:00" 或 "14:30"
10
+ * @returns 从00:00开始的分钟数
11
+ */
12
+ export declare function timeStringToMinutes(timeStr: string): number;
13
+ /**
14
+ * 对时间点数组进行排序
15
+ * @param timePoints 时间点数组
16
+ * @returns 排序后的时间点数组
17
+ */
18
+ export declare function sortTimePoints(timePoints: string[]): string[];
@@ -0,0 +1,53 @@
1
+ import dayjs from 'dayjs';
2
+
3
+ /**
4
+ * 从日期时间字符串中提取时间部分
5
+ * @param dateTime 日期时间字符串,格式如 "2024-01-01 10:00:00"
6
+ * @returns 时间字符串,格式如 "10:00"
7
+ */
8
+ export function extractTimeFromDateTime(dateTime) {
9
+ if (!dateTime) return null;
10
+
11
+ // 使用 dayjs 解析日期时间
12
+ var date = dayjs(dateTime);
13
+ if (!date.isValid()) {
14
+ console.warn("[TimeUtils] \u65E0\u6548\u7684\u65E5\u671F\u65F6\u95F4\u683C\u5F0F: ".concat(dateTime));
15
+ return null;
16
+ }
17
+
18
+ // 返回 HH:mm 格式的时间
19
+ return date.format('HH:mm');
20
+ }
21
+
22
+ /**
23
+ * 将时间字符串转换为分钟数(用于排序)
24
+ * @param timeStr 时间字符串,格式如 "10:00" 或 "14:30"
25
+ * @returns 从00:00开始的分钟数
26
+ */
27
+ export function timeStringToMinutes(timeStr) {
28
+ if (!timeStr) return 0;
29
+
30
+ // 使用 dayjs 解析时间字符串
31
+ // 由于只有时间没有日期,我们添加一个固定日期来解析
32
+ var date = dayjs("2000-01-01 ".concat(timeStr), 'YYYY-MM-DD HH:mm');
33
+ if (!date.isValid()) {
34
+ console.warn("[TimeUtils] \u65E0\u6548\u7684\u65F6\u95F4\u683C\u5F0F: ".concat(timeStr));
35
+ return 0;
36
+ }
37
+
38
+ // 计算从00:00开始的分钟数
39
+ return date.hour() * 60 + date.minute();
40
+ }
41
+
42
+ /**
43
+ * 对时间点数组进行排序
44
+ * @param timePoints 时间点数组
45
+ * @returns 排序后的时间点数组
46
+ */
47
+ export function sortTimePoints(timePoints) {
48
+ return timePoints.sort(function (a, b) {
49
+ var timeA = timeStringToMinutes(a);
50
+ var timeB = timeStringToMinutes(b);
51
+ return timeA - timeB;
52
+ });
53
+ }
@@ -324,22 +324,6 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
324
324
  success: boolean;
325
325
  minAvailableCount: number;
326
326
  };
327
- /**
328
- * 将 ProductData 转换为 CartItem,但不添加到购物车
329
- * 参考 addProductToCart 方法的实现
330
- */
331
- private convertProductToCartItem;
332
- checkMaxDurationCapacityForDetailNums({ product, date, account, }: {
333
- product: ProductData;
334
- date?: {
335
- startTime: string;
336
- endTime: string;
337
- } | null;
338
- account?: Account | null;
339
- }): {
340
- success: boolean;
341
- minAvailableCount: number;
342
- };
343
327
  setOtherData(key: string, value: any): void;
344
328
  getOtherData(key: string): any;
345
329
  getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;