@pisell/pisellos 2.2.223 → 2.2.225

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 (62) hide show
  1. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  2. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -0
  3. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +3 -0
  4. package/dist/modules/Customer/index.d.ts +7 -0
  5. package/dist/modules/Customer/index.js +16 -0
  6. package/dist/modules/OpenData/index.d.ts +7 -0
  7. package/dist/modules/OpenData/index.js +15 -0
  8. package/dist/modules/Order/index.d.ts +44 -0
  9. package/dist/modules/Order/index.js +306 -113
  10. package/dist/modules/Order/types.d.ts +16 -0
  11. package/dist/modules/Order/utils.js +7 -4
  12. package/dist/modules/Payment/index.d.ts +7 -0
  13. package/dist/modules/Payment/index.js +12 -0
  14. package/dist/modules/ProductList/index.d.ts +7 -0
  15. package/dist/modules/ProductList/index.js +11 -0
  16. package/dist/modules/SalesSummary/index.d.ts +7 -0
  17. package/dist/modules/SalesSummary/index.js +58 -23
  18. package/dist/modules/Schedule/index.d.ts +7 -0
  19. package/dist/modules/Schedule/index.js +16 -0
  20. package/dist/server/index.d.ts +6 -0
  21. package/dist/server/index.js +519 -355
  22. package/dist/server/modules/order/types.d.ts +2 -0
  23. package/dist/server/modules/order/utils/filterBookings.js +25 -2
  24. package/dist/server/utils/small-ticket.js +160 -30
  25. package/dist/solution/BaseSales/index.d.ts +17 -0
  26. package/dist/solution/BaseSales/index.js +524 -439
  27. package/dist/solution/BaseSales/utils/cartPromotion.js +26 -7
  28. package/dist/solution/BookingByStep/index.d.ts +1 -1
  29. package/dist/solution/BookingTicket/index.d.ts +1 -9
  30. package/dist/solution/BookingTicket/index.js +42 -76
  31. package/dist/types/index.d.ts +10 -0
  32. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -0
  33. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +3 -0
  34. package/lib/modules/Customer/index.d.ts +7 -0
  35. package/lib/modules/Customer/index.js +12 -0
  36. package/lib/modules/OpenData/index.d.ts +7 -0
  37. package/lib/modules/OpenData/index.js +12 -0
  38. package/lib/modules/Order/index.d.ts +44 -0
  39. package/lib/modules/Order/index.js +150 -3
  40. package/lib/modules/Order/types.d.ts +16 -0
  41. package/lib/modules/Order/utils.js +6 -2
  42. package/lib/modules/Payment/index.d.ts +7 -0
  43. package/lib/modules/Payment/index.js +9 -0
  44. package/lib/modules/ProductList/index.d.ts +7 -0
  45. package/lib/modules/ProductList/index.js +9 -0
  46. package/lib/modules/SalesSummary/index.d.ts +7 -0
  47. package/lib/modules/SalesSummary/index.js +13 -0
  48. package/lib/modules/Schedule/index.d.ts +7 -0
  49. package/lib/modules/Schedule/index.js +12 -0
  50. package/lib/server/index.d.ts +6 -0
  51. package/lib/server/index.js +136 -3
  52. package/lib/server/modules/order/types.d.ts +2 -0
  53. package/lib/server/modules/order/utils/filterBookings.js +17 -2
  54. package/lib/server/utils/small-ticket.js +141 -32
  55. package/lib/solution/BaseSales/index.d.ts +17 -0
  56. package/lib/solution/BaseSales/index.js +48 -10
  57. package/lib/solution/BaseSales/utils/cartPromotion.js +31 -2
  58. package/lib/solution/BookingByStep/index.d.ts +1 -1
  59. package/lib/solution/BookingTicket/index.d.ts +1 -9
  60. package/lib/solution/BookingTicket/index.js +1 -13
  61. package/lib/types/index.d.ts +10 -0
  62. package/package.json +1 -1
@@ -168,13 +168,20 @@ function buildProducts(order, locale, productMap) {
168
168
  const originalPrice = product.original_price ?? product.selling_price ?? product.payment_price ?? product.price ?? 0;
169
169
  const sellingPrice = product.selling_price ?? product.payment_price ?? product.price ?? originalPrice;
170
170
  const productTitle = resolveProductTitle({ product, productMap, locale });
171
+ const parentProduct = resolveProductFromMap(product.product_id ?? product.id, productMap);
171
172
  const currencySymbol = getCurrencySymbol(order, null);
172
- const options = normalizeProductOptions({ product, locale, currencySymbol });
173
+ const options = normalizeProductOptions({
174
+ product,
175
+ locale,
176
+ currencySymbol,
177
+ parentProduct
178
+ });
173
179
  const combinations = normalizeProductCombinations({
174
180
  product,
175
181
  productMap,
176
182
  locale,
177
- currencySymbol
183
+ currencySymbol,
184
+ parentProduct
178
185
  });
179
186
  return {
180
187
  product_title: productTitle,
@@ -190,32 +197,24 @@ function buildProducts(order, locale, productMap) {
190
197
  });
191
198
  }
192
199
  function resolveProductTitle(params) {
193
- var _a, _b;
194
200
  const { product, productMap, locale } = params;
195
- const ownTitle = getLocalizedValue(
196
- product.product_title || product.title || product.name || ((_a = product.product) == null ? void 0 : _a.title),
197
- locale
198
- );
199
- if (ownTitle)
200
- return ownTitle;
201
+ const ownTitle = getProductTitleSource(product, locale);
201
202
  const productId = product.product_id ?? product.id;
202
- const fallbackProduct = productId !== void 0 && productId !== null ? productMap[productId] || productMap[String(productId)] : null;
203
+ const fallbackProduct = resolveProductFromMap(productId, productMap);
203
204
  if (!fallbackProduct)
204
- return "";
205
- return getLocalizedValue(
206
- fallbackProduct.product_title || fallbackProduct.title || fallbackProduct.name || fallbackProduct.format_title || ((_b = fallbackProduct.product) == null ? void 0 : _b.title),
207
- locale
208
- );
205
+ return ownTitle || "";
206
+ return getProductTitleSource(fallbackProduct, locale);
209
207
  }
210
208
  function normalizeProductOptions(params) {
211
209
  var _a;
212
- const { product, locale, currencySymbol } = params;
210
+ const { product, locale, currencySymbol, parentProduct } = params;
213
211
  const rawOptions = Array.isArray(params.options) ? params.options : Array.isArray(product.options) ? product.options : Array.isArray((_a = product.product_sku) == null ? void 0 : _a.option) ? product.product_sku.option : [];
214
212
  return rawOptions.map((option) => {
215
213
  const price = option.original_price ?? option.add_price ?? option.price;
216
214
  const value = option.value ?? option.option ?? option.item;
215
+ const name = getProductTitleSource(option, locale) || resolveOptionTitleFromParentProduct({ option, parentProduct, locale });
217
216
  return {
218
- name: getLocalizedValue(option.name || option.title, locale),
217
+ name,
219
218
  ...option.num !== void 0 || option.quantity !== void 0 ? { num: toNumber(option.num ?? option.quantity, 1) } : {},
220
219
  ...price !== void 0 && price !== null && price !== "" ? { price: formatMoney(price, currencySymbol) } : {},
221
220
  ...value !== void 0 && value !== null && value !== "" ? { value: getLocalizedValue(value, locale) } : {}
@@ -223,16 +222,22 @@ function normalizeProductOptions(params) {
223
222
  });
224
223
  }
225
224
  function normalizeProductCombinations(params) {
226
- const { product, productMap, locale, currencySymbol } = params;
225
+ const { product, productMap, locale, currencySymbol, parentProduct } = params;
227
226
  const bundles = Array.isArray(product.product_bundle) ? product.product_bundle : [];
228
227
  return bundles.map((bundle) => {
229
228
  const combinationsOptions = normalizeProductOptions({
230
229
  product: {},
231
230
  locale,
232
231
  currencySymbol,
233
- options: Array.isArray(bundle.option) ? bundle.option : []
232
+ options: Array.isArray(bundle.option) ? bundle.option : [],
233
+ parentProduct
234
+ });
235
+ const baseTitle = resolveBundleProductTitle({
236
+ bundle,
237
+ productMap,
238
+ locale,
239
+ parentProduct
234
240
  });
235
- const baseTitle = resolveBundleProductTitle({ bundle, productMap, locale });
236
241
  const optionTitle = buildOptionTitleSuffix(combinationsOptions);
237
242
  return {
238
243
  product_title: `${baseTitle}${optionTitle}`,
@@ -243,22 +248,126 @@ function normalizeProductCombinations(params) {
243
248
  });
244
249
  }
245
250
  function resolveBundleProductTitle(params) {
246
- var _a, _b;
247
- const { bundle, productMap, locale } = params;
248
- const ownTitle = getLocalizedValue(
249
- bundle.product_title || bundle.title || bundle.name || ((_a = bundle.product) == null ? void 0 : _a.title),
250
- locale
251
- );
251
+ const { bundle, productMap, locale, parentProduct } = params;
252
+ const ownTitle = getProductTitleSource(bundle, locale);
252
253
  if (ownTitle)
253
254
  return ownTitle;
255
+ const parentBundleItem = resolveBundleItemFromParentProduct({ bundle, parentProduct });
256
+ const parentBundleTitle = parentBundleItem ? getProductTitleSource(parentBundleItem, locale) : "";
257
+ if (parentBundleTitle)
258
+ return parentBundleTitle;
254
259
  const productId = bundle.bundle_product_id ?? bundle._bundle_product_id ?? bundle.product_id ?? bundle.id;
255
- const fallbackProduct = productId !== void 0 && productId !== null ? productMap[productId] || productMap[String(productId)] : null;
260
+ const fallbackProduct = resolveProductFromMap(productId, productMap);
256
261
  if (!fallbackProduct)
257
262
  return "";
258
- return getLocalizedValue(
259
- fallbackProduct.product_title || fallbackProduct.title || fallbackProduct.name || fallbackProduct.format_title || ((_b = fallbackProduct.product) == null ? void 0 : _b.title),
260
- locale
261
- );
263
+ return getProductTitleSource(fallbackProduct, locale);
264
+ }
265
+ function resolveProductFromMap(productId, productMap) {
266
+ if (productId === void 0 || productId === null || productId === "")
267
+ return null;
268
+ return productMap[productId] || productMap[String(productId)] || null;
269
+ }
270
+ function getProductTitleSource(source, locale) {
271
+ if (!source || typeof source !== "object")
272
+ return "";
273
+ return resolveTitleValue(source.product_title, locale) || resolveTitleValue(source.title, locale) || resolveTitleValue(source.name, locale);
274
+ }
275
+ function resolveTitleValue(value, locale) {
276
+ if (value === void 0 || value === null)
277
+ return "";
278
+ if (typeof value !== "object")
279
+ return stringify(value);
280
+ const dashedLocale = locale.replace("_", "-");
281
+ const underscoredLocale = locale.replace("-", "_");
282
+ return stringify(value[locale] ?? value[dashedLocale] ?? value[underscoredLocale] ?? "");
283
+ }
284
+ function resolveOptionTitleFromParentProduct(params) {
285
+ const { option, parentProduct, locale } = params;
286
+ if (!parentProduct)
287
+ return "";
288
+ const optionItems = flattenOptionItems(parentProduct);
289
+ const matchedOption = optionItems.find((item) => isOptionItemMatch(option, item));
290
+ return getProductTitleSource(matchedOption, locale);
291
+ }
292
+ function flattenOptionItems(parentProduct) {
293
+ const optionGroups = Array.isArray(parentProduct.option_group) ? parentProduct.option_group : [];
294
+ return optionGroups.flatMap((group) => {
295
+ const items = normalizeArray(
296
+ group.option_item || group.option_items || group.option || group.options || group.items || group.children || group.product_option_item
297
+ );
298
+ return items.map((item) => ({
299
+ ...item,
300
+ option_group_id: item.option_group_id ?? group.id ?? group.option_group_id
301
+ }));
302
+ });
303
+ }
304
+ function isOptionItemMatch(option, item) {
305
+ const optionItemId = option.option_group_item_id ?? option.product_option_item_id ?? option.id;
306
+ const itemId = item.option_group_item_id ?? item.product_option_item_id ?? item.id;
307
+ if (!isSameId(optionItemId, itemId))
308
+ return false;
309
+ const optionGroupId = option.option_group_id ?? option.group_id;
310
+ const itemGroupId = item.option_group_id ?? item.group_id;
311
+ if (isPresentId(optionGroupId) && isPresentId(itemGroupId)) {
312
+ return isSameId(optionGroupId, itemGroupId);
313
+ }
314
+ return true;
315
+ }
316
+ function resolveBundleItemFromParentProduct(params) {
317
+ const { bundle, parentProduct } = params;
318
+ if (!parentProduct)
319
+ return null;
320
+ const bundleItems = flattenBundleItems(parentProduct);
321
+ const bundleVariantId = bundle.bundle_variant_id ?? bundle.variant_id ?? bundle.product_variant_id;
322
+ if (isNonZeroId(bundleVariantId)) {
323
+ const matchedByVariant = bundleItems.find(
324
+ (item) => isSameId(item.bundle_variant_id ?? item.variant_id ?? item.product_variant_id, bundleVariantId)
325
+ );
326
+ if (matchedByVariant)
327
+ return matchedByVariant;
328
+ }
329
+ const bundleId = bundle.bundle_id ?? bundle.id;
330
+ if (isPresentId(bundleId)) {
331
+ const matchedByBundleId = bundleItems.find((item) => isSameId(item.id ?? item.bundle_id, bundleId));
332
+ if (matchedByBundleId)
333
+ return matchedByBundleId;
334
+ }
335
+ const bundleGroupId = bundle.bundle_group_id ?? bundle.group_id;
336
+ const bundleProductId = bundle.bundle_product_id ?? bundle._bundle_product_id ?? bundle.product_id;
337
+ if (isPresentId(bundleGroupId) && isPresentId(bundleProductId)) {
338
+ const matchedByGroupAndProduct = bundleItems.find(
339
+ (item) => isSameId(item.group_id ?? item.bundle_group_id, bundleGroupId) && isSameId(item.bundle_product_id ?? item._bundle_product_id ?? item.product_id, bundleProductId)
340
+ );
341
+ if (matchedByGroupAndProduct)
342
+ return matchedByGroupAndProduct;
343
+ }
344
+ if (isPresentId(bundleProductId)) {
345
+ return bundleItems.find(
346
+ (item) => isSameId(item.bundle_product_id ?? item._bundle_product_id ?? item.product_id, bundleProductId)
347
+ ) || null;
348
+ }
349
+ return null;
350
+ }
351
+ function flattenBundleItems(parentProduct) {
352
+ const bundleGroups = Array.isArray(parentProduct.bundle_group) ? parentProduct.bundle_group : [];
353
+ return bundleGroups.flatMap((group) => {
354
+ const items = Array.isArray(group.bundle_item) ? group.bundle_item : [];
355
+ return items.map((item) => ({
356
+ ...item,
357
+ group_id: item.group_id ?? group.id ?? group.group_id
358
+ }));
359
+ });
360
+ }
361
+ function isNonZeroId(value) {
362
+ return isPresentId(value) && String(value) !== "0";
363
+ }
364
+ function isPresentId(value) {
365
+ return value !== void 0 && value !== null && value !== "";
366
+ }
367
+ function isSameId(left, right) {
368
+ if (!isPresentId(left) || !isPresentId(right))
369
+ return false;
370
+ return String(left) === String(right);
262
371
  }
263
372
  function buildOptionTitleSuffix(options) {
264
373
  const text = options.map((option) => {
@@ -523,7 +632,7 @@ function getLocalizedValue(value, locale) {
523
632
  return stringify(value);
524
633
  const dashedLocale = locale.replace("_", "-");
525
634
  return stringify(
526
- value[locale] ?? value[dashedLocale] ?? value.default ?? value.en ?? value.zh_CN ?? value["zh-CN"] ?? Object.values(value).find((item) => typeof item === "string" || typeof item === "number") ?? ""
635
+ value[locale] ?? value[dashedLocale] ?? value.default ?? value.en ?? ""
527
636
  );
528
637
  }
529
638
  function buildShopAddress(shopInfo) {
@@ -83,6 +83,23 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
83
83
  */
84
84
  protected createSubModule(moduleName: string): Module | null;
85
85
  protected getSubModuleHooks(moduleName: string): any;
86
+ /**
87
+ * 构造传给 BaseSales 子模块的完整运行态参数,保证初始化和后续同步语义一致。
88
+ *
89
+ * @example
90
+ * const params = this.buildSubModuleOtherParams();
91
+ * this.core.registerModule(orderModule, { otherParams: params });
92
+ */
93
+ protected buildSubModuleOtherParams(): Record<string, any>;
94
+ /**
95
+ * 将父级 otherParams 的变更显式同步给已注册的子模块。
96
+ *
97
+ * @example
98
+ * await this.syncOtherParamsToSubModules({ channel: 'pos' });
99
+ */
100
+ protected syncOtherParamsToSubModules(changedParams: Record<string, any>, { cover }?: {
101
+ cover?: boolean;
102
+ }): Promise<void>;
86
103
  /**
87
104
  * 读取 sessionStorage[this.name][cacheId],作为子模块 initialState 的来源。
88
105
  * sessionStorage 损坏时静默忽略,按空状态注册。
@@ -425,6 +425,43 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
425
425
  }
426
426
  return optionHooks[moduleName] || ((_b = this.otherParams[moduleName]) == null ? void 0 : _b.hooks) || otherHooks[moduleName];
427
427
  }
428
+ /**
429
+ * 构造传给 BaseSales 子模块的完整运行态参数,保证初始化和后续同步语义一致。
430
+ *
431
+ * @example
432
+ * const params = this.buildSubModuleOtherParams();
433
+ * this.core.registerModule(orderModule, { otherParams: params });
434
+ */
435
+ buildSubModuleOtherParams() {
436
+ return {
437
+ ...this.otherParams,
438
+ salesSummaryModuleName: `${this.name}_salesSummary`,
439
+ fatherModule: this.name,
440
+ openCache: this.cacheId ? true : false,
441
+ cacheId: this.cacheId
442
+ };
443
+ }
444
+ /**
445
+ * 将父级 otherParams 的变更显式同步给已注册的子模块。
446
+ *
447
+ * @example
448
+ * await this.syncOtherParamsToSubModules({ channel: 'pos' });
449
+ */
450
+ async syncOtherParamsToSubModules(changedParams, { cover = false } = {}) {
451
+ const nextSubModuleOtherParams = this.buildSubModuleOtherParams();
452
+ await Promise.all(
453
+ Object.values(this.store).map(async (subModule) => {
454
+ const targetModule = subModule;
455
+ if (!targetModule || typeof targetModule.updateOtherParams !== "function") {
456
+ return;
457
+ }
458
+ await targetModule.updateOtherParams(nextSubModuleOtherParams, {
459
+ changedParams,
460
+ cover
461
+ });
462
+ })
463
+ );
464
+ }
428
465
  /**
429
466
  * 读取 sessionStorage[this.name][cacheId],作为子模块 initialState 的来源。
430
467
  * sessionStorage 损坏时静默忽略,按空状态注册。
@@ -513,13 +550,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
513
550
  this.core.registerModule(targetModule, {
514
551
  initialState: (targetCacheData == null ? void 0 : targetCacheData[targetModule.name]) || {},
515
552
  ...hooks ? { hooks } : {},
516
- otherParams: {
517
- ...this.otherParams,
518
- salesSummaryModuleName: `${this.name}_salesSummary`,
519
- fatherModule: this.name,
520
- openCache: this.cacheId ? true : false,
521
- cacheId: this.cacheId
522
- }
553
+ otherParams: this.buildSubModuleOtherParams()
523
554
  });
524
555
  });
525
556
  if (this.store.schedule) {
@@ -1248,6 +1279,7 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1248
1279
  throw new Error("BaseSales 解决方案需要 order 模块支持");
1249
1280
  }
1250
1281
  const inferredPaymentStatus = this.getSubmitPaymentStatus(params == null ? void 0 : params.paymentStatus);
1282
+ debugger;
1251
1283
  const submitParams = {
1252
1284
  cacheId: this.cacheId,
1253
1285
  platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
@@ -1391,11 +1423,14 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1391
1423
  if (!metadata.unique_payment_number) {
1392
1424
  metadata.unique_payment_number = (0, import_utils.createUuidV4)();
1393
1425
  }
1394
- const paymentTime = paymentRecord.payment_time ?? (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
1426
+ const paymentTimestamp = (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss");
1427
+ const paymentTime = paymentRecord.payment_time ?? paymentTimestamp;
1428
+ const createdAt = paymentRecord.created_at ?? paymentTimestamp;
1395
1429
  const payments = this.store.order.addOrderPayment({
1396
1430
  ...paymentRecord,
1397
1431
  metadata,
1398
- payment_time: paymentTime
1432
+ payment_time: paymentTime,
1433
+ created_at: createdAt
1399
1434
  });
1400
1435
  const amountSnapshot = this.store.order.getOrderAmountSnapshot();
1401
1436
  const syncState = this.store.order.getOrderSyncState();
@@ -1793,11 +1828,14 @@ var BaseSalesImpl = class extends import_BaseModule.BaseModule {
1793
1828
  return this.otherParams;
1794
1829
  }
1795
1830
  async setOtherParams(params, { cover = false } = {}) {
1831
+ var _a;
1796
1832
  if (cover) {
1797
- this.otherParams = params;
1833
+ this.otherParams = { ...params };
1798
1834
  } else {
1799
1835
  this.otherParams = { ...this.otherParams, ...params };
1800
1836
  }
1837
+ this.cacheId = (_a = this.otherParams) == null ? void 0 : _a.cacheId;
1838
+ await this.syncOtherParamsToSubModules(params, { cover });
1801
1839
  }
1802
1840
  };
1803
1841
  // Annotate the CommonJS export names for ESM import in node:
@@ -178,12 +178,14 @@ function mergeIdenticalPromotionCartLines(products) {
178
178
  const promoUnitPrice = String(
179
179
  promotion.finalPrice ?? ((_c = line.metadata) == null ? void 0 : _c.main_product_selling_price) ?? ""
180
180
  );
181
+ const noteSignature = getProductLineNoteSignature(line);
181
182
  const bookingUid = (line == null ? void 0 : line.booking_uid) ?? ((_d = line == null ? void 0 : line.metadata) == null ? void 0 : _d.booking_uid);
182
183
  const orderDetailId = (line == null ? void 0 : line.order_detail_id) ?? (line == null ? void 0 : line.orderDetailId);
183
184
  const mergeKey = [
184
185
  line.product_id,
185
186
  line.product_variant_id ?? 0,
186
187
  fingerprint,
188
+ noteSignature,
187
189
  bookingUid ? String(bookingUid) : "",
188
190
  orderDetailId !== void 0 && orderDetailId !== null && orderDetailId !== "" ? String(orderDetailId) : "",
189
191
  promotion.strategyId,
@@ -317,6 +319,16 @@ function getGiftInfo(product) {
317
319
  var _a;
318
320
  return ((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a._giftInfo) || (product == null ? void 0 : product._giftInfo) || null;
319
321
  }
322
+ function getProductLineNoteSignature(product) {
323
+ const note = product == null ? void 0 : product.note;
324
+ if (typeof note !== "string")
325
+ return "";
326
+ const normalizedNote = note.trim();
327
+ if (!normalizedNote)
328
+ return "";
329
+ const uid = getOrderProductUid(product);
330
+ return uid ? `note:${uid}` : `note:${normalizedNote}`;
331
+ }
320
332
  function isPersistedGeneratedVoucher(product) {
321
333
  const orderDetailId = (product == null ? void 0 : product.order_detail_id) ?? (product == null ? void 0 : product.orderDetailId);
322
334
  if (orderDetailId === void 0 || orderDetailId === null || orderDetailId === "") {
@@ -343,6 +355,7 @@ function buildConsolidateKeyForPromotion(item) {
343
355
  (0, import_utils.getProductSkuOptions)(item),
344
356
  item.product_bundle
345
357
  );
358
+ const noteSignature = getProductLineNoteSignature(item);
346
359
  const bookingUid = (item == null ? void 0 : item.booking_uid) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.booking_uid);
347
360
  const orderDetailId = (item == null ? void 0 : item.order_detail_id) ?? (item == null ? void 0 : item.orderDetailId);
348
361
  if (orderDetailId !== void 0 && orderDetailId !== null && orderDetailId !== "") {
@@ -350,6 +363,7 @@ function buildConsolidateKeyForPromotion(item) {
350
363
  item.product_id,
351
364
  item.product_variant_id ?? 0,
352
365
  fingerprint,
366
+ noteSignature,
353
367
  String(orderDetailId)
354
368
  ].join("#");
355
369
  }
@@ -358,18 +372,26 @@ function buildConsolidateKeyForPromotion(item) {
358
372
  item.product_id,
359
373
  item.product_variant_id ?? 0,
360
374
  fingerprint,
375
+ noteSignature,
361
376
  String(bookingUid)
362
377
  ].join("#");
363
378
  }
364
- return [item.product_id, item.product_variant_id ?? 0, fingerprint].join("#");
379
+ return [
380
+ item.product_id,
381
+ item.product_variant_id ?? 0,
382
+ fingerprint,
383
+ noteSignature
384
+ ].join("#");
365
385
  }
366
386
  function consolidateMainProductsForPromotion(entries) {
387
+ var _a, _b;
367
388
  if (!Array.isArray(entries) || entries.length <= 1) {
368
389
  return [...entries || []];
369
390
  }
370
391
  const groups = /* @__PURE__ */ new Map();
371
392
  for (const { item, originalListIndex } of entries) {
372
393
  const key = buildConsolidateKeyForPromotion(item);
394
+ const wasInPromotion = ((_b = (_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a._promotion) == null ? void 0 : _b.inPromotion) === true;
373
395
  const existing = groups.get(key);
374
396
  if (!existing) {
375
397
  const mergedItem = (0, import_lodash_es.cloneDeep)(item);
@@ -382,12 +404,18 @@ function consolidateMainProductsForPromotion(entries) {
382
404
  delete bundle._promotion;
383
405
  }
384
406
  }
407
+ if (wasInPromotion) {
408
+ mergedItem._wasInPromotionBeforeConsolidate = true;
409
+ }
385
410
  groups.set(key, { item: mergedItem, originalListIndex });
386
411
  continue;
387
412
  }
388
413
  existing.item.num = (0, import_utils2.getSafeProductNum)(
389
414
  Number(existing.item.num || 0) + Number(item.num || 0)
390
415
  );
416
+ if (wasInPromotion) {
417
+ existing.item._wasInPromotionBeforeConsolidate = true;
418
+ }
391
419
  }
392
420
  return Array.from(groups.values());
393
421
  }
@@ -775,7 +803,7 @@ function processCartPromotion(list, evaluator, options) {
775
803
  const metadata = newItem.metadata || {};
776
804
  const sourceCartNum = (0, import_utils2.getSafeProductNum)(originalItem.num);
777
805
  newItem._sourceCartNum = sourceCartNum;
778
- const wasInPromotion = ((_a = metadata._promotion) == null ? void 0 : _a.inPromotion) === true;
806
+ const wasInPromotion = ((_a = metadata._promotion) == null ? void 0 : _a.inPromotion) === true || originalItem._wasInPromotionBeforeConsolidate === true;
779
807
  delete metadata._promotion;
780
808
  if (Array.isArray(newItem.product_bundle)) {
781
809
  for (const b of newItem.product_bundle) {
@@ -938,6 +966,7 @@ function processCartPromotion(list, evaluator, options) {
938
966
  delete product._sortSubIndex;
939
967
  delete product._originalProductUid;
940
968
  delete product._sourceCartNum;
969
+ delete product._wasInPromotionBeforeConsolidate;
941
970
  }
942
971
  return {
943
972
  products: processedProducts,
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 2 | 3 | 5 | 4 | 6;
314
+ weekNum: 0 | 2 | 1 | 3 | 6 | 4 | 5;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -312,7 +312,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
312
312
  * 获取当前的客户搜索条件
313
313
  * @returns 当前搜索条件
314
314
  */
315
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
315
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
316
316
  /**
317
317
  * 获取客户列表状态(包含滚动加载相关状态)
318
318
  * @returns 客户状态
@@ -359,14 +359,6 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
359
359
  * 清空所有扫描监听对应的任务执行队列
360
360
  */
361
361
  clearAllScanListenersTaskQueue(): void;
362
- /**
363
- * 设置其他参数
364
- * @param params 参数
365
- * @param options 选项
366
- */
367
- setOtherParams(params: Record<string, any>, { cover }?: {
368
- cover?: boolean;
369
- }): Promise<void>;
370
362
  /**
371
363
  * 获取其他参数
372
364
  * @returns 其他参数
@@ -185,7 +185,7 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
185
185
  }
186
186
  const receiptSequenceLength = this.normalizePositiveInteger(
187
187
  openDataConfig == null ? void 0 : openDataConfig["sale.short_number_digits"],
188
- 2
188
+ 5
189
189
  );
190
190
  const receiptSequenceStart = this.normalizePositiveInteger(
191
191
  openDataConfig == null ? void 0 : openDataConfig["sale.short_number_start_number"],
@@ -1003,18 +1003,6 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1003
1003
  clearAllScanListenersTaskQueue() {
1004
1004
  this.scan.clearTaskQueue();
1005
1005
  }
1006
- /**
1007
- * 设置其他参数
1008
- * @param params 参数
1009
- * @param options 选项
1010
- */
1011
- async setOtherParams(params, { cover = false } = {}) {
1012
- if (cover) {
1013
- this.otherParams = params;
1014
- } else {
1015
- this.otherParams = { ...this.otherParams, ...params };
1016
- }
1017
- }
1018
1006
  /**
1019
1007
  * 获取其他参数
1020
1008
  * @returns 其他参数
@@ -14,6 +14,16 @@ export interface Module {
14
14
  name: string;
15
15
  version: string;
16
16
  initialize: (core: PisellCore, options: ModuleOptions) => Promise<void> | void;
17
+ /**
18
+ * 父级解决方案运行时更新 otherParams 后,显式通知子模块刷新自己的运行态参数。
19
+ *
20
+ * @example
21
+ * await module.updateOtherParams?.({ channel: 'pos' }, { changedParams: { channel: 'pos' } });
22
+ */
23
+ updateOtherParams?: (params: Record<string, any>, meta?: {
24
+ changedParams?: Record<string, any>;
25
+ cover?: boolean;
26
+ }) => Promise<void> | void;
17
27
  destroy?: () => Promise<void> | void;
18
28
  exports?: Record<string, any>;
19
29
  isSolution?: boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.223",
4
+ "version": "2.2.225",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",