@pisell/pisellos 2.2.260 → 2.2.262

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 (107) hide show
  1. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +1 -0
  2. package/dist/model/strategy/adapter/dataVariant/adapter.js +15 -0
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +2 -0
  4. package/dist/model/strategy/adapter/dataVariant/evaluator.js +25 -0
  5. package/dist/model/strategy/adapter/dataVariant/examples.js +1 -6
  6. package/dist/model/strategy/adapter/dataVariant/type.d.ts +2 -0
  7. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  8. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +23 -13
  9. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  10. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  11. package/dist/modules/BookingContext/utils/cacheItemToBookingInput.js +32 -1
  12. package/dist/modules/Discount/index.d.ts +5 -2
  13. package/dist/modules/Discount/index.js +30 -7
  14. package/dist/modules/Discount/types.d.ts +4 -0
  15. package/dist/modules/Order/index.d.ts +45 -2
  16. package/dist/modules/Order/index.js +1552 -926
  17. package/dist/modules/Order/types.d.ts +36 -2
  18. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  19. package/dist/modules/Order/utils/bundleDiscountHydration.js +144 -0
  20. package/dist/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  21. package/dist/modules/Order/utils/orderCollectionIdentity.js +405 -0
  22. package/dist/modules/Order/utils.d.ts +8 -3
  23. package/dist/modules/Order/utils.js +136 -56
  24. package/dist/modules/Rules/index.d.ts +4 -10
  25. package/dist/modules/Rules/index.js +63 -12
  26. package/dist/modules/Rules/types.d.ts +12 -2
  27. package/dist/modules/SalesSummary/index.d.ts +7 -3
  28. package/dist/modules/SalesSummary/index.js +67 -39
  29. package/dist/modules/SalesSummary/types.d.ts +1 -0
  30. package/dist/modules/SalesSummary/utils.js +2 -1
  31. package/dist/modules/SurchargeList/index.d.ts +6 -4
  32. package/dist/modules/SurchargeList/index.js +62 -39
  33. package/dist/modules/SurchargeList/types.d.ts +6 -2
  34. package/dist/server/index.d.ts +8 -0
  35. package/dist/server/index.js +1365 -911
  36. package/dist/server/modules/order/index.d.ts +32 -7
  37. package/dist/server/modules/order/index.js +551 -464
  38. package/dist/server/modules/order/types.d.ts +4 -0
  39. package/dist/server/modules/products/index.d.ts +5 -1
  40. package/dist/server/modules/products/index.js +384 -315
  41. package/dist/server/modules/products/types.d.ts +4 -0
  42. package/dist/solution/BaseSales/index.d.ts +42 -2
  43. package/dist/solution/BaseSales/index.js +1416 -775
  44. package/dist/solution/BaseSales/types.d.ts +7 -1
  45. package/dist/solution/BaseSales/types.js +3 -2
  46. package/dist/solution/BaseSales/utils/cartPromotion.js +19 -7
  47. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
  48. package/dist/solution/BaseSales/utils/parseSalesResponse.js +6 -8
  49. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +20 -4
  50. package/dist/solution/BookingByStep/index.d.ts +1 -1
  51. package/dist/solution/BookingTicket/index.d.ts +8 -0
  52. package/dist/solution/BookingTicket/index.js +212 -31
  53. package/dist/solution/ShopDiscount/index.js +15 -14
  54. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +1 -0
  55. package/lib/model/strategy/adapter/dataVariant/adapter.js +10 -0
  56. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +2 -0
  57. package/lib/model/strategy/adapter/dataVariant/evaluator.js +20 -1
  58. package/lib/model/strategy/adapter/dataVariant/examples.js +0 -2
  59. package/lib/model/strategy/adapter/dataVariant/type.d.ts +2 -0
  60. package/lib/model/strategy/adapter/promotion/index.js +0 -49
  61. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +16 -1
  62. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +1 -0
  63. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.d.ts +1 -1
  64. package/lib/modules/BookingContext/utils/cacheItemToBookingInput.js +23 -2
  65. package/lib/modules/Discount/index.d.ts +5 -2
  66. package/lib/modules/Discount/index.js +23 -3
  67. package/lib/modules/Discount/types.d.ts +4 -0
  68. package/lib/modules/Order/index.d.ts +45 -2
  69. package/lib/modules/Order/index.js +720 -116
  70. package/lib/modules/Order/types.d.ts +36 -2
  71. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +5 -0
  72. package/lib/modules/Order/utils/bundleDiscountHydration.js +139 -0
  73. package/lib/modules/Order/utils/orderCollectionIdentity.d.ts +53 -0
  74. package/lib/modules/Order/utils/orderCollectionIdentity.js +415 -0
  75. package/lib/modules/Order/utils.d.ts +8 -3
  76. package/lib/modules/Order/utils.js +104 -18
  77. package/lib/modules/Rules/index.d.ts +4 -10
  78. package/lib/modules/Rules/index.js +61 -9
  79. package/lib/modules/Rules/types.d.ts +12 -2
  80. package/lib/modules/SalesSummary/index.d.ts +7 -3
  81. package/lib/modules/SalesSummary/index.js +28 -11
  82. package/lib/modules/SalesSummary/types.d.ts +1 -0
  83. package/lib/modules/SalesSummary/utils.js +2 -0
  84. package/lib/modules/SurchargeList/index.d.ts +6 -4
  85. package/lib/modules/SurchargeList/index.js +41 -21
  86. package/lib/modules/SurchargeList/types.d.ts +6 -2
  87. package/lib/server/index.d.ts +8 -0
  88. package/lib/server/index.js +336 -11
  89. package/lib/server/modules/order/index.d.ts +32 -7
  90. package/lib/server/modules/order/index.js +298 -189
  91. package/lib/server/modules/order/types.d.ts +4 -0
  92. package/lib/server/modules/products/index.d.ts +5 -1
  93. package/lib/server/modules/products/index.js +21 -0
  94. package/lib/server/modules/products/types.d.ts +4 -0
  95. package/lib/solution/BaseSales/index.d.ts +42 -2
  96. package/lib/solution/BaseSales/index.js +535 -108
  97. package/lib/solution/BaseSales/types.d.ts +7 -1
  98. package/lib/solution/BaseSales/types.js +2 -1
  99. package/lib/solution/BaseSales/utils/cartPromotion.js +13 -1
  100. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +3 -3
  101. package/lib/solution/BaseSales/utils/parseSalesResponse.js +4 -5
  102. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +14 -6
  103. package/lib/solution/BookingByStep/index.d.ts +1 -1
  104. package/lib/solution/BookingTicket/index.d.ts +8 -0
  105. package/lib/solution/BookingTicket/index.js +134 -8
  106. package/lib/solution/ShopDiscount/index.js +2 -1
  107. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import type { Discount } from '../../modules/Discount/types';
1
2
  import { OrderModule, ProductList, QuotationModule, SalesSummaryModule, ScanOrderLoggerModule as BaseSalesLoggerModule, ScheduleModule } from '../../modules';
2
3
  import type { ScanOrderLogInput as BaseSalesLogInput, ScanOrderLoggerProviderConfig as BaseSalesLoggerProviderConfig, ScanOrderLoggerProviderType as BaseSalesLoggerProviderType } from '../../modules/ScanOrderLogger/types';
3
4
  import type { QuantityCheckResult, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
@@ -14,6 +15,7 @@ export declare const BaseSalesHookNames: {
14
15
  readonly onCartValidationChanged: "onCartValidationChanged";
15
16
  readonly onPaymentSyncStart: "onPaymentSyncStart";
16
17
  readonly onPaymentSyncEnd: "onPaymentSyncEnd";
18
+ readonly onDepositPaymentSyncEnd: "onDepositPaymentSyncEnd";
17
19
  };
18
20
  export type BaseSalesHookName = typeof BaseSalesHookNames[keyof typeof BaseSalesHookNames];
19
21
  export declare function createBaseSalesHook(moduleName: string, hookName: BaseSalesHookName): string;
@@ -84,6 +86,8 @@ export interface BaseSalesOrderProduct extends BaseSalesOrderProductIdentity {
84
86
  booking_uid?: string;
85
87
  /** 多语言商品标题快照,随 tempOrder 提交到 checkout。 */
86
88
  product_title?: BaseSalesLocalizedText;
89
+ /** 商品封面图快照,随 tempOrder 提交到 checkout。 */
90
+ product_cover?: string;
87
91
  /**
88
92
  * 行级扩展 metadata。价格相关的权威字段:
89
93
  *
@@ -380,9 +384,11 @@ export interface BaseSalesLoggerRuntimeConfig {
380
384
  }
381
385
  export interface BaseSalesAddLogParams extends BaseSalesLogInput {
382
386
  }
383
- /** BaseSales.scanPromotionCode 对外的轻量结果(不含 discountList,UI resolve 后调 getDiscountList) */
387
+ /** BaseSales.scanPromotionCode 对外的轻量结果(UI 可用 getDiscountList scannedDiscountList 补 Holder) */
384
388
  export interface BaseSalesScanCodeResult {
385
389
  isAvailable: boolean;
386
390
  type?: 'server' | string;
387
391
  unavailableReason?: 'time_limit' | string;
392
+ /** batchSearch 原始结果;isAvailable=false 时 discountList 可能未写入 store,Holder 补全需读此字段 */
393
+ scannedDiscountList?: Discount[];
388
394
  }
@@ -30,7 +30,8 @@ var BaseSalesHookNames = {
30
30
  onRefresh: "onRefresh",
31
31
  onCartValidationChanged: "onCartValidationChanged",
32
32
  onPaymentSyncStart: "onPaymentSyncStart",
33
- onPaymentSyncEnd: "onPaymentSyncEnd"
33
+ onPaymentSyncEnd: "onPaymentSyncEnd",
34
+ onDepositPaymentSyncEnd: "onDepositPaymentSyncEnd"
34
35
  };
35
36
  function createBaseSalesHook(moduleName, hookName) {
36
37
  return `${moduleName}:${hookName}`;
@@ -179,6 +179,7 @@ function mergeIdenticalPromotionCartLines(products) {
179
179
  promotion.finalPrice ?? ((_c = line.metadata) == null ? void 0 : _c.main_product_selling_price) ?? ""
180
180
  );
181
181
  const noteSignature = getProductLineNoteSignature(line);
182
+ const lineMergeBoundary = getPromotionLineMergeBoundary(line);
182
183
  const bookingUid = (line == null ? void 0 : line.booking_uid) ?? ((_d = line == null ? void 0 : line.metadata) == null ? void 0 : _d.booking_uid);
183
184
  const orderDetailId = (line == null ? void 0 : line.order_detail_id) ?? (line == null ? void 0 : line.orderDetailId);
184
185
  const mergeKey = [
@@ -186,6 +187,7 @@ function mergeIdenticalPromotionCartLines(products) {
186
187
  line.product_variant_id ?? 0,
187
188
  fingerprint,
188
189
  noteSignature,
190
+ lineMergeBoundary,
189
191
  bookingUid ? String(bookingUid) : "",
190
192
  orderDetailId !== void 0 && orderDetailId !== null && orderDetailId !== "" ? String(orderDetailId) : "",
191
193
  promotion.strategyId,
@@ -329,6 +331,12 @@ function getProductLineNoteSignature(product) {
329
331
  const uid = getOrderProductUid(product);
330
332
  return uid ? `note:${uid}` : `note:${normalizedNote}`;
331
333
  }
334
+ function getPromotionLineMergeBoundary(product) {
335
+ var _a;
336
+ if (((_a = product == null ? void 0 : product.metadata) == null ? void 0 : _a.is_edit_for_runtime) !== true)
337
+ return "";
338
+ return `edit:${getOrderProductUid(product)}`;
339
+ }
332
340
  function isPersistedGeneratedVoucher(product) {
333
341
  const orderDetailId = (product == null ? void 0 : product.order_detail_id) ?? (product == null ? void 0 : product.orderDetailId);
334
342
  if (orderDetailId === void 0 || orderDetailId === null || orderDetailId === "") {
@@ -356,6 +364,7 @@ function buildConsolidateKeyForPromotion(item) {
356
364
  item.product_bundle
357
365
  );
358
366
  const noteSignature = getProductLineNoteSignature(item);
367
+ const lineMergeBoundary = getPromotionLineMergeBoundary(item);
359
368
  const bookingUid = (item == null ? void 0 : item.booking_uid) ?? ((_a = item == null ? void 0 : item.metadata) == null ? void 0 : _a.booking_uid);
360
369
  const orderDetailId = (item == null ? void 0 : item.order_detail_id) ?? (item == null ? void 0 : item.orderDetailId);
361
370
  if (orderDetailId !== void 0 && orderDetailId !== null && orderDetailId !== "") {
@@ -364,6 +373,7 @@ function buildConsolidateKeyForPromotion(item) {
364
373
  item.product_variant_id ?? 0,
365
374
  fingerprint,
366
375
  noteSignature,
376
+ lineMergeBoundary,
367
377
  String(orderDetailId)
368
378
  ].join("#");
369
379
  }
@@ -373,6 +383,7 @@ function buildConsolidateKeyForPromotion(item) {
373
383
  item.product_variant_id ?? 0,
374
384
  fingerprint,
375
385
  noteSignature,
386
+ lineMergeBoundary,
376
387
  String(bookingUid)
377
388
  ].join("#");
378
389
  }
@@ -380,7 +391,8 @@ function buildConsolidateKeyForPromotion(item) {
380
391
  item.product_id,
381
392
  item.product_variant_id ?? 0,
382
393
  fingerprint,
383
- noteSignature
394
+ noteSignature,
395
+ lineMergeBoundary
384
396
  ].join("#");
385
397
  }
386
398
  function consolidateMainProductsForPromotion(entries) {
@@ -2,7 +2,7 @@
2
2
  * 把 `/order/sales/{id}` 响应(OrderData)解析为 ISalesDetail。
3
3
  *
4
4
  * - 纯函数:不依赖任何运行时模块/插件,便于单测与 view-model 适配
5
- * - products 保留 tempOrder / 后端详情原字段,仅做浅拷贝,避免丢失 product_sku 等协议字段
5
+ * - products 保留 tempOrder / 后端详情原字段,仅规范化集合身份并浅拷贝,避免丢失 product_sku 等协议字段
6
6
  * - bookings 平铺保留服务端原顺序,同时输出 byProductUid 反查表与 rootBooking
7
7
  * - header 收敛"非数组顶层字段",便于 ticketBooking view-model 直接消费
8
8
  *
@@ -130,7 +130,7 @@ export interface ISalesDetail {
130
130
  customer: ISalesDetailCustomer | null;
131
131
  /** 服务端 summary(仅输出) */
132
132
  summary: Record<string, any>;
133
- /** 原始响应快照,方便 UI 兜底使用 */
133
+ /** 规范化后的响应快照,方便 UI 兜底使用 */
134
134
  raw: Record<string, any>;
135
135
  }
136
136
  /**
@@ -138,7 +138,7 @@ export interface ISalesDetail {
138
138
  *
139
139
  * 注意:
140
140
  * - 入参允许是 `{ data: OrderData }` 或直接 `OrderData`,自动识别。
141
- * - products 保留原字段;字段补齐由 OrderModule hydrate 负责。
141
+ * - products/bookings/payments 在此补齐集合身份;其余 runtime 字段由 OrderModule hydrate 负责。
142
142
  * - 不做远程请求;不修改入参;返回新对象。
143
143
  */
144
144
  export declare function parseSalesResponse(input: Record<string, any> | null | undefined): ISalesDetail;
@@ -22,6 +22,7 @@ __export(parseSalesResponse_exports, {
22
22
  parseSalesResponse: () => parseSalesResponse
23
23
  });
24
24
  module.exports = __toCommonJS(parseSalesResponse_exports);
25
+ var import_orderCollectionIdentity = require("../../../modules/Order/utils/orderCollectionIdentity");
25
26
  var HEADER_KEYS = [
26
27
  "order_id",
27
28
  "order_number",
@@ -121,14 +122,12 @@ function indexBookingsByProductUid(bookings) {
121
122
  return result;
122
123
  }
123
124
  function parseSalesResponse(input) {
124
- const raw = input && typeof input === "object" && input.data && input.order_id == null ? input.data : input || {};
125
+ const sourceRaw = input && typeof input === "object" && input.data && input.order_id == null ? input.data : input || {};
126
+ const raw = (0, import_orderCollectionIdentity.normalizeOrderCollections)(sourceRaw).order;
125
127
  const productsRaw = Array.isArray(raw == null ? void 0 : raw.products) ? raw.products : [];
126
- const products = productsRaw.map((p, index) => {
128
+ const products = productsRaw.map((p) => {
127
129
  const row = { ...p || {} };
128
130
  const metadata = row.metadata && typeof row.metadata === "object" ? { ...row.metadata } : {};
129
- if (!metadata.unique_identification_number) {
130
- metadata.unique_identification_number = `sales-product-${row.product_id ?? "unknown"}-${row.product_variant_id ?? 0}-${index}`;
131
- }
132
131
  delete metadata.price_schema_version;
133
132
  delete row.identity_key;
134
133
  return { ...row, metadata };
@@ -50,6 +50,12 @@ function toPriceString(value, fallback = "0.00") {
50
50
  return fallback;
51
51
  return parsedValue.toFixed(2);
52
52
  }
53
+ function isBlankValue(value) {
54
+ return value === void 0 || value === null || typeof value === "string" && value.trim() === "";
55
+ }
56
+ function firstNonBlank(...values) {
57
+ return values.find((value) => !isBlankValue(value));
58
+ }
53
59
  function normalizeOptionItems(optionItems) {
54
60
  if (!Array.isArray(optionItems))
55
61
  return [];
@@ -88,7 +94,8 @@ function normalizeBundleItems(bundleItems, preferPriceField = false) {
88
94
  price: bundleItem.price ?? unitStr,
89
95
  bundle_selling_price: unitStr,
90
96
  original_price: bundleItem.original_price ?? bundleItem.product_price ?? bundleItem.price ?? unitStr,
91
- option: normalizeOptionItems(bundleItem == null ? void 0 : bundleItem.option)
97
+ option: normalizeOptionItems(bundleItem == null ? void 0 : bundleItem.option),
98
+ discount_list: preferPriceField ? [] : bundleItem.discount_list
92
99
  };
93
100
  normalizedItem.bundle_selling_price = (0, import_utils.getBundleSellingMagnitude)(magnitudeSource).toFixed(2);
94
101
  if ((normalizedItem.price_type ?? normalizedItem.custom_price_type) === "markdown" && (normalizedItem.price_type_ext === "" || normalizedItem.price_type_ext === void 0 || normalizedItem.price_type_ext === null)) {
@@ -129,10 +136,9 @@ function transformBaseProductToOrderProduct(params) {
129
136
  payload.price ?? payload.selling_price ?? (matchedVariant == null ? void 0 : matchedVariant.price) ?? (matchedVariant == null ? void 0 : matchedVariant.base_price) ?? (origin == null ? void 0 : origin.price) ?? (origin == null ? void 0 : origin.base_price) ?? (sourceProduct == null ? void 0 : sourceProduct.price) ?? (sourceProduct == null ? void 0 : sourceProduct.selling_price) ?? (sourceProduct == null ? void 0 : sourceProduct.base_price),
130
137
  "0.00"
131
138
  );
132
- const lineCompositeTotal = toPriceString(
133
- payload.line_total ?? payload.total ?? ((_c = payload._extend) == null ? void 0 : _c.total),
134
- sourceProductPrice
135
- );
139
+ const explicitLineTotal = payload.line_total ?? payload.total ?? ((_c = payload._extend) == null ? void 0 : _c.total);
140
+ const hasExplicitLineTotal = Number.isFinite(Number(explicitLineTotal));
141
+ const lineCompositeTotal = toPriceString(explicitLineTotal, sourceProductPrice);
136
142
  const hasPriceOverride = payload.price_override !== void 0 && payload.price_override !== null && payload.price_override !== "";
137
143
  const productOptionItem = (0, import_utils.normalizeProductSkuOptions)(
138
144
  normalizeOptionItems(
@@ -180,7 +186,7 @@ function transformBaseProductToOrderProduct(params) {
180
186
  const optionSum = (0, import_utils.sumOptionUnitPrice)(productOptionItem).toNumber();
181
187
  const mainProductOriginalPrice = toPriceString(Number(sourceProductPrice) + optionSum);
182
188
  const bundleOnlyComposite = (0, import_utils.composeLinePrice)({ mainPrice: 0, bundle: productBundle });
183
- const derivedMainSelling = Number(lineCompositeTotal) - Number(bundleOnlyComposite);
189
+ const derivedMainSelling = hasExplicitLineTotal ? Number(lineCompositeTotal) - Number(bundleOnlyComposite) : Number(mainProductOriginalPrice);
184
190
  const mainProductSellingPrice = toPriceString(
185
191
  Number.isFinite(derivedMainSelling) && derivedMainSelling >= 0 ? derivedMainSelling : Number(mainProductOriginalPrice)
186
192
  );
@@ -198,6 +204,7 @@ function transformBaseProductToOrderProduct(params) {
198
204
  main_product_selling_price: mainProductSellingPrice,
199
205
  main_product_original_price: mainProductOriginalPrice,
200
206
  price_schema_version: 2,
207
+ holder_config: sourceProduct == null ? void 0 : sourceProduct.holder_config,
201
208
  ...hasPriceOverride ? {
202
209
  price_override: String(payload.price_override),
203
210
  is_manual_discount: 1
@@ -236,6 +243,7 @@ function transformBaseProductToOrderProduct(params) {
236
243
  metadata,
237
244
  note: payload.note != null ? String(payload.note) : "",
238
245
  product_title: productTitle,
246
+ product_cover: firstNonBlank(matchedVariant == null ? void 0 : matchedVariant.cover, sourceProduct == null ? void 0 : sourceProduct.cover),
239
247
  _origin: {
240
248
  ...sourceProduct || {},
241
249
  callbackData: payload
@@ -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 | 5 | 4 | 3 | 6;
314
+ weekNum: 0 | 2 | 1 | 6 | 4 | 3 | 5;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -551,6 +551,14 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
551
551
  setOtherParams(params: Record<string, any>, { cover }?: {
552
552
  cover?: boolean;
553
553
  }): Promise<void>;
554
+ private getDeviceTaskPlugin;
555
+ handlePrintWristband(params: {
556
+ voucher_ids: number[];
557
+ }): Promise<void>;
558
+ handleRedeem(params: {
559
+ voucher_ids: number[];
560
+ is_checkin: boolean;
561
+ }): Promise<any>;
554
562
  /**
555
563
  * 销毁模块:先调用父类(销毁所有 store 内子模块 + emit destroy + super.destroy()),
556
564
  * 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
@@ -52,6 +52,7 @@ var import_buildNormalProductCacheItemFromOrderLine = require("../../modules/Boo
52
52
  var import_orderLineDisplay = require("../../modules/BookingContext/utils/orderLineDisplay");
53
53
  var import_bookingStatus = require("./utils/bookingStatus");
54
54
  var import_resolveBestAddTimePlan = require("./utils/resolveBestAddTimePlan");
55
+ var import_utils = require("../../modules/Order/utils");
55
56
  __reExport(BookingTicket_exports, require("./types"), module.exports);
56
57
  var OPEN_DATA_SECTION_CODES = ["sale", "reservation", "fulfillment", "menu", "workflow"];
57
58
  var OPEN_DATA_CACHE_TTL = 5 * 60 * 1e3;
@@ -340,15 +341,28 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
340
341
  if (!this.store.order)
341
342
  throw new Error("order 模块未初始化");
342
343
  const raw = await this.store.order.scanCode(code, customerId);
344
+ const scannedList = raw.scannedDiscountList || [];
345
+ const extractedCustomerId = this.getDiscountCustomerId(scannedList);
346
+ const hasOrderCustomer = Boolean(this.store.order.getOrderCustomer());
347
+ if (!hasOrderCustomer && extractedCustomerId) {
348
+ await this.hydrateOrderCustomerFromScanDiscounts(scannedList);
349
+ }
343
350
  if (raw.isAvailable) {
344
- await this.hydrateOrderCustomerFromScanDiscounts(raw.scannedDiscountList || []);
345
351
  await this.store.order.recalculateSummary({ createIfMissing: true });
346
352
  this.store.order.persistTempOrder();
353
+ const tempOrder = this.store.order.ensureTempOrder();
354
+ await this.effectsEmit("onDiscountApplied", {
355
+ productList: tempOrder.products || [],
356
+ discountList: this.store.order.getDiscountList(),
357
+ selectedDiscountList: tempOrder.discount_list || [],
358
+ tempOrder
359
+ });
347
360
  }
348
361
  return {
349
362
  isAvailable: raw.isAvailable,
350
363
  type: raw.type,
351
- unavailableReason: raw.unavailableReason
364
+ unavailableReason: raw.unavailableReason,
365
+ scannedDiscountList: raw.scannedDiscountList
352
366
  };
353
367
  }
354
368
  async hydrateOrderCustomerFromScanDiscounts(discounts) {
@@ -365,11 +379,13 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
365
379
  this.setOrderCustomer(customer);
366
380
  }
367
381
  getDiscountCustomerId(discounts) {
368
- const discount = discounts.find((item) => item.customer_id != null);
369
- const customerId = Number(discount == null ? void 0 : discount.customer_id);
370
- if (!Number.isFinite(customerId) || customerId <= 0)
371
- return null;
372
- return customerId;
382
+ for (const item of discounts) {
383
+ const topLevelId = Number(item.customer_id);
384
+ if (Number.isFinite(topLevelId) && topLevelId > 0) {
385
+ return topLevelId;
386
+ }
387
+ }
388
+ return null;
373
389
  }
374
390
  async resolveCustomerByDiscountCustomerId(customerId) {
375
391
  var _a;
@@ -861,7 +877,17 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
861
877
  void ((_a = discountModule == null ? void 0 : discountModule.setOriginalDiscountList) == null ? void 0 : _a.call(discountModule, []));
862
878
  void ((_b = discountModule == null ? void 0 : discountModule.setDiscountList) == null ? void 0 : _b.call(discountModule, []));
863
879
  this.store.order.applyDiscount();
864
- void this.store.order.recalculateSummary({ createIfMissing: true }).then(() => this.store.order.persistTempOrder()).catch((error) => {
880
+ void this.store.order.recalculateSummary({ createIfMissing: true }).then(() => {
881
+ var _a2;
882
+ const tempOrder = this.store.order.ensureTempOrder();
883
+ this.store.order.persistTempOrder();
884
+ return this.effectsEmit("onDiscountApplied", {
885
+ productList: tempOrder.products || [],
886
+ discountList: ((_a2 = discountModule == null ? void 0 : discountModule.getDiscountList) == null ? void 0 : _a2.call(discountModule)) || [],
887
+ selectedDiscountList: tempOrder.discount_list || [],
888
+ tempOrder
889
+ });
890
+ }).catch((error) => {
865
891
  console.error("Failed to recalculate summary after clearing customer:", error);
866
892
  });
867
893
  this.core.effects.emit(`${this.name}:onOrderCustomerChange`, null);
@@ -1505,6 +1531,106 @@ var BookingTicketImpl = class extends import_BaseSales.BaseSalesImpl {
1505
1531
  await this.configureIdGeneratorFromOpenData();
1506
1532
  }
1507
1533
  }
1534
+ getDeviceTaskPlugin() {
1535
+ var _a;
1536
+ const app = this.core.getPlugin("app");
1537
+ return ((_a = app == null ? void 0 : app.getApp()) == null ? void 0 : _a.getPlugin("deviceTask")) || null;
1538
+ }
1539
+ // 打印手环,单个或批量都可以
1540
+ async handlePrintWristband(params) {
1541
+ var _a;
1542
+ const deviceTask = this.getDeviceTaskPlugin();
1543
+ if (!(deviceTask == null ? void 0 : deviceTask.dispatch)) {
1544
+ this.logger.addLog({
1545
+ type: "info",
1546
+ title: "[BookingTicket] handlePrintWristband: deviceTask.dispatch 不可用",
1547
+ metadata: {
1548
+ voucher_ids: Array.isArray(params.voucher_ids) ? params.voucher_ids : [params.voucher_ids]
1549
+ }
1550
+ });
1551
+ return;
1552
+ }
1553
+ this.logger.addLog({
1554
+ type: "info",
1555
+ title: "[BookingTicket] handlePrintWristband",
1556
+ metadata: {
1557
+ voucher_ids: Array.isArray(params.voucher_ids) ? params.voucher_ids : [params.voucher_ids]
1558
+ }
1559
+ });
1560
+ const deviceId = await this.getShortNumberOrDeviceId();
1561
+ const idempotencyKey = (0, import_utils.createUuidV4)();
1562
+ deviceTask.dispatch({
1563
+ action: "print_all",
1564
+ device_id: deviceId,
1565
+ payload: {
1566
+ type: "WRISTBAND",
1567
+ data: {
1568
+ order_id: (_a = this.getOrderIdentity()) == null ? void 0 : _a.orderId,
1569
+ voucher_ids: Array.isArray(params.voucher_ids) ? params.voucher_ids : [params.voucher_ids]
1570
+ }
1571
+ },
1572
+ idempotency_key: idempotencyKey,
1573
+ name: "PRINT_WRISTBAND",
1574
+ source: "bookingTicket",
1575
+ source_type: "handlePrintWristband",
1576
+ source_id: idempotencyKey
1577
+ });
1578
+ }
1579
+ // 触发核销
1580
+ async handleRedeem(params) {
1581
+ var _a, _b, _c;
1582
+ const voucherIds = Array.isArray(params.voucher_ids) ? params.voucher_ids : [];
1583
+ const status = params.is_checkin ? "used" : "unused";
1584
+ this.logger.addLog({
1585
+ type: "info",
1586
+ title: "[BookingTicket] handleRedeem",
1587
+ metadata: {
1588
+ voucher_ids: voucherIds,
1589
+ status
1590
+ }
1591
+ });
1592
+ const voucherIdSet = new Set(voucherIds);
1593
+ const tempOrder = (_b = (_a = this.store.order) == null ? void 0 : _a.getTempOrder) == null ? void 0 : _b.call(_a);
1594
+ const vouchers = (tempOrder == null ? void 0 : tempOrder.vouchers) || ((_c = this.store.order) == null ? void 0 : _c.getVouchers()) || [];
1595
+ let hasUpdatedVoucher = false;
1596
+ const nextVouchers = vouchers.map((voucher) => {
1597
+ if (!voucherIdSet.has(voucher.voucher_id))
1598
+ return voucher;
1599
+ hasUpdatedVoucher = true;
1600
+ return {
1601
+ ...voucher,
1602
+ status
1603
+ };
1604
+ });
1605
+ if (tempOrder && hasUpdatedVoucher) {
1606
+ await this.replaceTempOrder({
1607
+ ...tempOrder,
1608
+ vouchers: nextVouchers
1609
+ });
1610
+ }
1611
+ this.core.effects.emit(`${this.name}:onVouchersChange`, {});
1612
+ if (voucherIds.length === 0) {
1613
+ return {
1614
+ code: 200,
1615
+ status: true,
1616
+ message: "",
1617
+ data: []
1618
+ };
1619
+ }
1620
+ const identity = this.getOrderIdentity();
1621
+ const externalSaleNumber = (tempOrder == null ? void 0 : tempOrder.external_sale_number) || (identity == null ? void 0 : identity.externalSaleNumber) || void 0;
1622
+ const orderId = (tempOrder == null ? void 0 : tempOrder.order_id) ?? (identity == null ? void 0 : identity.orderId) ?? void 0;
1623
+ const orderLookup = externalSaleNumber || orderId || (identity == null ? void 0 : identity.orderNumber) || (identity == null ? void 0 : identity.shopOrderNumber) || (identity == null ? void 0 : identity.shopFullOrderNumber) || void 0;
1624
+ return this.request.post("/machinecode/batch", {
1625
+ ids: voucherIds,
1626
+ status,
1627
+ order_lookup: orderLookup,
1628
+ order_id: orderId,
1629
+ external_sale_number: externalSaleNumber
1630
+ }, {
1631
+ osServer: true
1632
+ });
1633
+ }
1508
1634
  /**
1509
1635
  * 销毁模块:先调用父类(销毁所有 store 内子模块 + emit destroy + super.destroy()),
1510
1636
  * 再清理 BookingTicket 自有资源(scan 监听 + scan 内存缓存)。
@@ -505,7 +505,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
505
505
  try {
506
506
  const orderId = this.store.orderId;
507
507
  const customerId = params.customerId || ((_a = this.getCustomer()) == null ? void 0 : _a.id);
508
- const goodPassList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
508
+ const prepareConfigResult = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
509
509
  customer_id: customerId,
510
510
  action: orderId ? "edit" : "create",
511
511
  with_good_pass: 1,
@@ -514,6 +514,7 @@ var ShopDiscountImpl = class extends import_BaseModule.BaseModule {
514
514
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
515
515
  ...orderId ? { order_id: orderId } : {}
516
516
  }));
517
+ const goodPassList = (prepareConfigResult == null ? void 0 : prepareConfigResult.discountList) || [];
517
518
  const scanDiscount = (_c = this.getDiscountList()) == null ? void 0 : _c.filter(
518
519
  (item) => item.isScan
519
520
  );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.260",
4
+ "version": "2.2.262",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",