@pisell/pisellos 2.2.274 → 2.2.276

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 (117) hide show
  1. package/dist/core/index.d.ts +2 -0
  2. package/dist/core/index.js +7 -0
  3. package/dist/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  4. package/dist/model/strategy/adapter/promotion/adapter.js +23 -0
  5. package/dist/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  6. package/dist/model/strategy/adapter/promotion/evaluator.js +279 -6
  7. package/dist/model/strategy/adapter/promotion/examples.d.ts +86 -0
  8. package/dist/model/strategy/adapter/promotion/examples.js +99 -0
  9. package/dist/model/strategy/adapter/promotion/index.d.ts +1 -1
  10. package/dist/model/strategy/adapter/promotion/index.js +1 -1
  11. package/dist/model/strategy/adapter/promotion/type.d.ts +90 -2
  12. package/dist/model/strategy/adapter/promotion/type.js +45 -0
  13. package/dist/modules/OpenData/index.d.ts +2 -0
  14. package/dist/modules/OpenData/index.js +8 -0
  15. package/dist/modules/Order/index.d.ts +28 -8
  16. package/dist/modules/Order/index.js +907 -588
  17. package/dist/modules/Order/payment-utils.d.ts +26 -0
  18. package/dist/modules/Order/payment-utils.js +225 -0
  19. package/dist/modules/Order/types.d.ts +35 -1
  20. package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
  21. package/dist/modules/Order/utils.js +10 -6
  22. package/dist/modules/Payment/index.d.ts +2 -0
  23. package/dist/modules/Payment/index.js +78 -49
  24. package/dist/modules/Payment/types.d.ts +104 -25
  25. package/dist/modules/Payment/types.js +17 -0
  26. package/dist/modules/Payment/walletpass.d.ts +38 -1
  27. package/dist/modules/Payment/walletpass.js +917 -114
  28. package/dist/modules/Rules/index.d.ts +3 -0
  29. package/dist/modules/Rules/index.js +100 -70
  30. package/dist/server/index.d.ts +25 -0
  31. package/dist/server/index.js +1993 -1061
  32. package/dist/server/modules/index.d.ts +1 -1
  33. package/dist/server/modules/order/index.d.ts +70 -4
  34. package/dist/server/modules/order/index.js +1816 -728
  35. package/dist/server/modules/order/types.d.ts +25 -3
  36. package/dist/server/modules/order/types.js +7 -1
  37. package/dist/solution/BaseSales/index.d.ts +104 -5
  38. package/dist/solution/BaseSales/index.js +1767 -436
  39. package/dist/solution/BaseSales/types.d.ts +55 -1
  40. package/dist/solution/BaseSales/types.js +2 -1
  41. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  42. package/dist/solution/BaseSales/utils/cartPromotion.js +94 -32
  43. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  44. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +7 -4
  45. package/dist/solution/BookingByStep/index.d.ts +1 -1
  46. package/dist/solution/BookingTicket/index.d.ts +21 -5
  47. package/dist/solution/BookingTicket/index.js +139 -56
  48. package/dist/solution/BookingTicket/types.d.ts +1 -0
  49. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  50. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +173 -83
  51. package/dist/solution/Sales/index.d.ts +2 -0
  52. package/dist/solution/Sales/index.js +26 -4
  53. package/dist/solution/ScanOrder/index.js +31 -20
  54. package/dist/solution/VenueBooking/index.d.ts +1 -0
  55. package/dist/solution/VenueBooking/index.js +30 -19
  56. package/dist/types/index.d.ts +1 -0
  57. package/dist/utils/payment-number.d.ts +9 -0
  58. package/dist/utils/payment-number.js +69 -0
  59. package/lib/core/index.d.ts +2 -0
  60. package/lib/core/index.js +4 -0
  61. package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  62. package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
  63. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  64. package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
  65. package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
  66. package/lib/model/strategy/adapter/promotion/examples.js +91 -0
  67. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  68. package/lib/model/strategy/adapter/promotion/index.js +2 -0
  69. package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
  70. package/lib/model/strategy/adapter/promotion/type.js +2 -0
  71. package/lib/modules/OpenData/index.d.ts +2 -0
  72. package/lib/modules/OpenData/index.js +5 -0
  73. package/lib/modules/Order/index.d.ts +28 -8
  74. package/lib/modules/Order/index.js +252 -84
  75. package/lib/modules/Order/payment-utils.d.ts +26 -0
  76. package/lib/modules/Order/payment-utils.js +224 -0
  77. package/lib/modules/Order/types.d.ts +35 -1
  78. package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
  79. package/lib/modules/Order/utils.js +11 -4
  80. package/lib/modules/Payment/index.d.ts +2 -0
  81. package/lib/modules/Payment/index.js +33 -12
  82. package/lib/modules/Payment/types.d.ts +104 -25
  83. package/lib/modules/Payment/types.js +1 -0
  84. package/lib/modules/Payment/walletpass.d.ts +38 -1
  85. package/lib/modules/Payment/walletpass.js +730 -21
  86. package/lib/modules/Rules/index.d.ts +3 -0
  87. package/lib/modules/Rules/index.js +38 -9
  88. package/lib/server/index.d.ts +25 -0
  89. package/lib/server/index.js +726 -31
  90. package/lib/server/modules/index.d.ts +1 -1
  91. package/lib/server/modules/order/index.d.ts +70 -4
  92. package/lib/server/modules/order/index.js +818 -69
  93. package/lib/server/modules/order/types.d.ts +25 -3
  94. package/lib/server/modules/order/types.js +1 -0
  95. package/lib/solution/BaseSales/index.d.ts +104 -5
  96. package/lib/solution/BaseSales/index.js +858 -27
  97. package/lib/solution/BaseSales/types.d.ts +55 -1
  98. package/lib/solution/BaseSales/types.js +2 -1
  99. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  100. package/lib/solution/BaseSales/utils/cartPromotion.js +66 -12
  101. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  102. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +4 -3
  103. package/lib/solution/BookingByStep/index.d.ts +1 -1
  104. package/lib/solution/BookingTicket/index.d.ts +21 -5
  105. package/lib/solution/BookingTicket/index.js +64 -13
  106. package/lib/solution/BookingTicket/types.d.ts +1 -0
  107. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  108. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +37 -5
  109. package/lib/solution/Sales/index.d.ts +2 -0
  110. package/lib/solution/Sales/index.js +20 -6
  111. package/lib/solution/ScanOrder/index.js +8 -0
  112. package/lib/solution/VenueBooking/index.d.ts +1 -0
  113. package/lib/solution/VenueBooking/index.js +8 -0
  114. package/lib/types/index.d.ts +1 -0
  115. package/lib/utils/payment-number.d.ts +9 -0
  116. package/lib/utils/payment-number.js +64 -0
  117. package/package.json +1 -1
@@ -3,6 +3,7 @@ import { OrderModule, ProductList, QuotationModule, SalesSummaryModule, ScanOrde
3
3
  import type { ScanOrderLogInput as BaseSalesLogInput, ScanOrderLoggerProviderConfig as BaseSalesLoggerProviderConfig, ScanOrderLoggerProviderType as BaseSalesLoggerProviderType } from '../../modules/ScanOrderLogger/types';
4
4
  import type { QuantityCheckResult, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
5
5
  import type { QuotationCustomerScopeInfo } from '../../modules/Quotation/types';
6
+ import type { PaymentMethod } from '../../modules/Payment/types';
6
7
  /**
7
8
  * BaseSales 流程 hook 后缀。
8
9
  * 完整事件名应由当前模块名动态拼接,避免多个实例共享固定事件 key。
@@ -16,11 +17,62 @@ export declare const BaseSalesHookNames: {
16
17
  readonly onPaymentSyncStart: "onPaymentSyncStart";
17
18
  readonly onPaymentSyncEnd: "onPaymentSyncEnd";
18
19
  readonly onDepositPaymentSyncEnd: "onDepositPaymentSyncEnd";
20
+ readonly onWalletAssetsStateChanged: "onWalletAssetsStateChanged";
19
21
  };
20
22
  export type BaseSalesHookName = typeof BaseSalesHookNames[keyof typeof BaseSalesHookNames];
21
23
  export declare function createBaseSalesHook(moduleName: string, hookName: BaseSalesHookName): string;
22
24
  export type BaseSalesStatus = 'idle' | 'initializing' | 'ready' | 'error';
23
25
  export type BaseSalesPaymentStatus = 'paid' | 'partially_paid' | 'unpaid' | 'payment_processing' | string;
26
+ export interface BaseSalesCashPaymentConfig {
27
+ available: boolean;
28
+ paymentMethod?: PaymentMethod;
29
+ amountDue: number;
30
+ recommendedAmounts: number[];
31
+ }
32
+ export interface BaseSalesPayCashParams {
33
+ /** 实际计入订单的现金支付金额(部分支付时小于待付金额)。 */
34
+ amount: number;
35
+ /** 顾客实际交付现金;可大于 amount。 */
36
+ actualPaidAmount?: number;
37
+ changeAmount?: number;
38
+ roundingAmount?: number;
39
+ }
40
+ export interface BaseSalesPayCashResult {
41
+ payment: Record<string, any>;
42
+ payments: Record<string, any>[];
43
+ syncResult: Record<string, any>;
44
+ isOrderFullyPaid: boolean;
45
+ }
46
+ export interface BaseSalesCommitPaymentMethodParams {
47
+ /** 支付方式 id;与 paymentMethodCode 至少传一个。 */
48
+ paymentMethodId?: number | string;
49
+ /** 支付方式 code,大小写不敏感。 */
50
+ paymentMethodCode?: string;
51
+ /** 本次计入订单的支付金额。 */
52
+ amount: number;
53
+ /** 支付设备返回的原始金额;缺省时与 amount 相同。 */
54
+ originAmount?: number;
55
+ /** 支付设备返回的实际手续费配置。 */
56
+ serviceCharge?: {
57
+ amount?: string | number;
58
+ percentage?: string | number;
59
+ } | null;
60
+ /** 支付设备返回的唯一流水号等扩展信息。 */
61
+ metadata?: Record<string, any>;
62
+ /** 少数支付方式需要透传的额外 payment 字段。 */
63
+ paymentData?: Record<string, any>;
64
+ }
65
+ export interface BaseSalesCommitPaymentMethodResult {
66
+ payment: Record<string, any>;
67
+ payments: Record<string, any>[];
68
+ syncResult: Record<string, any>;
69
+ isOrderFullyPaid: boolean;
70
+ }
71
+ export interface BaseSalesConfirmWalletPaymentResult<T = Record<string, any>> {
72
+ submitResult: T;
73
+ payments: Record<string, any>[];
74
+ isOrderFullyPaid: boolean;
75
+ }
24
76
  export interface BaseSalesEntryContext {
25
77
  biz: string;
26
78
  mode: 'scan' | 'append';
@@ -387,8 +439,10 @@ export interface BaseSalesAddLogParams extends BaseSalesLogInput {
387
439
  /** BaseSales.scanPromotionCode 对外的轻量结果(UI 可用 getDiscountList 或 scannedDiscountList 补 Holder) */
388
440
  export interface BaseSalesScanCodeResult {
389
441
  isAvailable: boolean;
442
+ /** 卡券已加入 Promotion;false 时可能是无效、过期或已使用。 */
443
+ isAccepted?: boolean;
390
444
  type?: 'server' | string;
391
445
  unavailableReason?: 'time_limit' | string;
392
- /** batchSearch 原始结果;isAvailable=false 时 discountList 可能未写入 store,Holder 补全需读此字段 */
446
+ /** batchSearch 原始结果;Holder 补全等流程可从这里读取原始卡券。 */
393
447
  scannedDiscountList?: Discount[];
394
448
  }
@@ -10,7 +10,8 @@ export var BaseSalesHookNames = {
10
10
  onCartValidationChanged: 'onCartValidationChanged',
11
11
  onPaymentSyncStart: 'onPaymentSyncStart',
12
12
  onPaymentSyncEnd: 'onPaymentSyncEnd',
13
- onDepositPaymentSyncEnd: 'onDepositPaymentSyncEnd'
13
+ onDepositPaymentSyncEnd: 'onDepositPaymentSyncEnd',
14
+ onWalletAssetsStateChanged: 'onWalletAssetsStateChanged'
14
15
  };
15
16
  export function createBaseSalesHook(moduleName, hookName) {
16
17
  return "".concat(moduleName, ":").concat(hookName);
@@ -78,6 +78,7 @@ export interface CartPromotionEvaluator {
78
78
  }>;
79
79
  hasApplicableStrategy: boolean;
80
80
  }>;
81
+ getStrategyConfigs?: () => unknown[];
81
82
  }
82
83
  /** 单个赠品减量项 */
83
84
  export interface GiftReduceItem {
@@ -267,7 +268,8 @@ export declare function appendPromotionTags<T extends Record<string, any>>(produ
267
268
  * 处理购物车的促销计算与赠品差异化。
268
269
  *
269
270
  * 流程:
270
- * 1. 分离 main / gift / edit-product 三类(带 `booking_id` 的编辑态商品不参与促销)
271
+ * 1. 分离 main / gift / edit-product 三类(普通促销下带 `booking_id` 的编辑态商品不参与;
272
+ * 配置 ITEM_REWARD 时,编辑态商品也参与商品奖励重算)
271
273
  * 2. 转 PromotionProduct 喂评估器 → 拿到 `evaluateCartWithPricing` 与 `getProductsApplicableStrategies`
272
274
  * 3. 把 PricedProduct 映射回 OrderProduct 形态:
273
275
  * - 参与促销的,写 `metadata._promotion` + 调整 `selling_price` / `main_product_selling_price`
@@ -1,17 +1,17 @@
1
1
  var _excluded = ["_promotionTags"];
2
2
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
3
3
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
4
- 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; }
5
- 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; }
6
- 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; }
7
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
8
- 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); }
9
4
  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); }
10
5
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
11
6
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
12
7
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
13
8
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
14
9
  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; } } }; }
10
+ 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; }
11
+ 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; }
12
+ 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; }
13
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
14
+ 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); }
15
15
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
16
16
  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."); }
17
17
  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); }
@@ -116,24 +116,50 @@ export function getOrderProductOriginalPriceForPromotion(product) {
116
116
  }
117
117
  return getOrderProductBasePrice(product);
118
118
  }
119
+ var X_ITEMS_FOR_Y_PRICE = 'X_ITEMS_FOR_Y_PRICE';
120
+ var BUY_X_GET_Y_FREE = 'BUY_X_GET_Y_FREE';
121
+ var ITEM_REWARD = 'ITEM_REWARD';
122
+ function isItemRewardPromotionDiscountItem(item) {
123
+ var _item$metadata, _item$metadata2;
124
+ return (item === null || item === void 0 ? void 0 : item.type) === 'product' && (item === null || item === void 0 || (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.source) === 'promotion' && (item === null || item === void 0 || (_item$metadata2 = item.metadata) === null || _item$metadata2 === void 0 ? void 0 : _item$metadata2.actionType) === ITEM_REWARD;
125
+ }
126
+ function isManagedPromotionDiscountItem(item) {
127
+ if ((item === null || item === void 0 ? void 0 : item.type) === 'promotion') return true;
128
+ return isItemRewardPromotionDiscountItem(item);
129
+ }
130
+
131
+ /**
132
+ * 判断商品行在本轮评估前是否已享受促销。
133
+ *
134
+ * `_promotion` 仅存在于当前运行时;订单保存后会被裁剪,因此编辑态需通过
135
+ * ITEM_REWARD 写入的受管商品折扣恢复上一轮状态。
136
+ */
137
+ function wasInPromotionBeforeEvaluation(item) {
138
+ var _item$metadata3;
139
+ if ((item === null || item === void 0 || (_item$metadata3 = item.metadata) === null || _item$metadata3 === void 0 || (_item$metadata3 = _item$metadata3._promotion) === null || _item$metadata3 === void 0 ? void 0 : _item$metadata3.inPromotion) === true) return true;
140
+ return Array.isArray(item === null || item === void 0 ? void 0 : item.discount_list) && item.discount_list.some(isItemRewardPromotionDiscountItem);
141
+ }
119
142
 
120
143
  /**
121
- * 写入/清除促销 discount_list(type=promotion)。
144
+ * 写入/清除促销 discount_list
122
145
  *
123
146
  * applyDiscount → applyProductDiscountPrices 会从 source_product_price 减去 discount_list 合计
124
147
  * 重算 main_product_selling_price;保留券前 source 时必须同步写入促销差额,否则会还原成原价。
125
148
  *
149
+ * ITEM_REWARD 使用 type=product,复用商品级折扣排他规则,避免客户折扣继续叠加到奖励商品行。
150
+ *
126
151
  * @example
127
152
  * updatePromotionDiscountList(line, { title: '2 items for $10', amount: '17.00', original_amount: '22.00', fixed_amount: '17.00' });
128
153
  */
129
- function updatePromotionDiscountList(item, promotionDiscount) {
154
+ function updatePromotionDiscountList(item, promotionDiscount, options) {
130
155
  var discountList = Array.isArray(item.discount_list) ? _toConsumableArray(item.discount_list) : [];
131
156
  discountList = discountList.filter(function (d) {
132
- return (d === null || d === void 0 ? void 0 : d.type) !== 'promotion';
157
+ return !isManagedPromotionDiscountItem(d);
133
158
  });
134
159
  if (promotionDiscount) {
135
- discountList.push({
136
- type: 'promotion',
160
+ var discountType = (options === null || options === void 0 ? void 0 : options.discountType) || 'promotion';
161
+ discountList.push(_objectSpread({
162
+ type: discountType,
137
163
  amount: promotionDiscount.amount,
138
164
  discount: {
139
165
  original_amount: promotionDiscount.original_amount,
@@ -141,7 +167,12 @@ function updatePromotionDiscountList(item, promotionDiscount) {
141
167
  title: promotionDiscount.title,
142
168
  resource_id: ''
143
169
  }
144
- });
170
+ }, discountType === 'product' ? {
171
+ metadata: {
172
+ source: 'promotion',
173
+ actionType: (options === null || options === void 0 ? void 0 : options.actionType) || ITEM_REWARD
174
+ }
175
+ } : {}));
145
176
  }
146
177
  if (discountList.length > 0) {
147
178
  item.discount_list = discountList;
@@ -149,11 +180,19 @@ function updatePromotionDiscountList(item, promotionDiscount) {
149
180
  delete item.discount_list;
150
181
  }
151
182
  }
152
- var X_ITEMS_FOR_Y_PRICE = 'X_ITEMS_FOR_Y_PRICE';
153
- var BUY_X_GET_Y_FREE = 'BUY_X_GET_Y_FREE';
183
+ function evaluatorHasActionType(evaluator, actionType) {
184
+ var _evaluator$getStrateg;
185
+ var configs = evaluator === null || evaluator === void 0 || (_evaluator$getStrateg = evaluator.getStrategyConfigs) === null || _evaluator$getStrateg === void 0 ? void 0 : _evaluator$getStrateg.call(evaluator);
186
+ if (!Array.isArray(configs)) return false;
187
+ return configs.some(function (config) {
188
+ return ((config === null || config === void 0 ? void 0 : config.actions) || []).some(function (action) {
189
+ return (action === null || action === void 0 ? void 0 : action.type) === actionType;
190
+ });
191
+ });
192
+ }
154
193
 
155
194
  /**
156
- * 将促销单价写入 OrderProduct(含 metadata 三字段 + promotion discount_list)。
195
+ * 将促销单价写入 OrderProduct(含 metadata 三字段 + 行内折扣)。
157
196
  *
158
197
  * @example
159
198
  * applyPromoUnitPriceToLine(newItem, { promoUnitPrice: '5.00', originalBasePrice: 1, strategyTitle: '2 for 10' });
@@ -184,6 +223,9 @@ function applyPromoUnitPriceToLine(item, input) {
184
223
  amount: discountAmount,
185
224
  original_amount: catalogSource,
186
225
  fixed_amount: discountAmount
226
+ }, {
227
+ actionType: input.actionType,
228
+ discountType: input.actionType === ITEM_REWARD ? 'product' : 'promotion'
187
229
  });
188
230
  } else {
189
231
  updatePromotionDiscountList(item, null);
@@ -426,10 +468,13 @@ function getProductLineNoteSignature(product) {
426
468
  }
427
469
 
428
470
  /**
429
- * 称重行以及编辑订单历史行都有各自的促销合并边界。
471
+ * 自定义商品、称重行以及编辑订单历史行都有各自的促销合并边界。
430
472
  */
431
473
  function getPromotionLineMergeBoundary(product) {
432
474
  var _product$product_sku, _product$metadata3;
475
+ if ((product === null || product === void 0 ? void 0 : product.product_id) === undefined || (product === null || product === void 0 ? void 0 : product.product_id) === null) {
476
+ return "custom:".concat(getOrderProductUid(product));
477
+ }
433
478
  if (Number((product === null || product === void 0 || (_product$product_sku = product.product_sku) === null || _product$product_sku === void 0 ? void 0 : _product$product_sku.open_sold_weight) || 0) === 1) {
434
479
  return "weighing:".concat(getOrderProductUid(product));
435
480
  }
@@ -473,11 +518,11 @@ function getProductBundleForEvaluator(product) {
473
518
  * // => 单行 num=4,清除 _promotion 后重新评估
474
519
  */
475
520
  export function buildConsolidateKeyForPromotion(item) {
476
- var _item$booking_uid, _item$metadata, _item$order_detail_id, _item$product_variant3;
521
+ var _item$booking_uid, _item$metadata4, _item$order_detail_id, _item$product_variant3;
477
522
  var fingerprint = buildProductLineFingerprint(getProductSkuOptions(item), item.product_bundle);
478
523
  var noteSignature = getProductLineNoteSignature(item);
479
524
  var lineMergeBoundary = getPromotionLineMergeBoundary(item);
480
- var bookingUid = (_item$booking_uid = item === null || item === void 0 ? void 0 : item.booking_uid) !== null && _item$booking_uid !== void 0 ? _item$booking_uid : item === null || item === void 0 || (_item$metadata = item.metadata) === null || _item$metadata === void 0 ? void 0 : _item$metadata.booking_uid;
525
+ var bookingUid = (_item$booking_uid = item === null || item === void 0 ? void 0 : item.booking_uid) !== null && _item$booking_uid !== void 0 ? _item$booking_uid : item === null || item === void 0 || (_item$metadata4 = item.metadata) === null || _item$metadata4 === void 0 ? void 0 : _item$metadata4.booking_uid;
481
526
  var orderDetailId = (_item$order_detail_id = item === null || item === void 0 ? void 0 : item.order_detail_id) !== null && _item$order_detail_id !== void 0 ? _item$order_detail_id : item === null || item === void 0 ? void 0 : item.orderDetailId;
482
527
  if (orderDetailId !== undefined && orderDetailId !== null && orderDetailId !== '') {
483
528
  var _item$product_variant;
@@ -498,12 +543,11 @@ function consolidateMainProductsForPromotion(entries) {
498
543
  _step5;
499
544
  try {
500
545
  for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
501
- var _item$metadata2;
502
546
  var _step5$value = _step5.value,
503
547
  item = _step5$value.item,
504
548
  originalListIndex = _step5$value.originalListIndex;
505
549
  var key = buildConsolidateKeyForPromotion(item);
506
- var wasInPromotion = (item === null || item === void 0 || (_item$metadata2 = item.metadata) === null || _item$metadata2 === void 0 || (_item$metadata2 = _item$metadata2._promotion) === null || _item$metadata2 === void 0 ? void 0 : _item$metadata2.inPromotion) === true;
550
+ var wasInPromotion = wasInPromotionBeforeEvaluation(item);
507
551
  var existing = groups.get(key);
508
552
  if (!existing) {
509
553
  var mergedItem = cloneDeep(item);
@@ -600,6 +644,9 @@ function splitXItemsPromoLinesByGroup(lines, strategyActionMap) {
600
644
  function generateNumericId() {
601
645
  return Math.floor(Math.random() * 1000000000) + Date.now();
602
646
  }
647
+ function isBookingEditProductLine(product) {
648
+ return (product === null || product === void 0 ? void 0 : product.booking_id) !== undefined && (product === null || product === void 0 ? void 0 : product.booking_id) !== null && product.booking_id !== 0 && product.booking_id !== '0';
649
+ }
603
650
 
604
651
  /**
605
652
  * 把 OrderProduct 转成 evaluator 的 PromotionProduct(仅评估期使用)。
@@ -620,6 +667,7 @@ function convertToPromotionProduct(product, index) {
620
667
  price: getOrderProductOriginalPriceForPromotion(product),
621
668
  quantity: Number((_product$num = product === null || product === void 0 ? void 0 : product.num) !== null && _product$num !== void 0 ? _product$num : 1) || 1,
622
669
  bundle: getProductBundleForEvaluator(product),
670
+ _promotionOnlyForItemReward: isBookingEditProductLine(product),
623
671
  _originalItem: originalItem,
624
672
  _originalId: getOrderProductUid(product),
625
673
  _originalIndex: index
@@ -827,6 +875,9 @@ export function resolveStrategyRequiredQuantity(matched) {
827
875
  if (matched.actionType === 'BUY_X_GET_Y_FREE') {
828
876
  return Number(detail.buyQuantity) || 1;
829
877
  }
878
+ if (matched.actionType === 'ITEM_REWARD') {
879
+ return Number(detail.triggerQuantity) || 1;
880
+ }
830
881
  return 1;
831
882
  }
832
883
 
@@ -986,7 +1037,8 @@ export function appendPromotionTags(products, evaluator) {
986
1037
  * 处理购物车的促销计算与赠品差异化。
987
1038
  *
988
1039
  * 流程:
989
- * 1. 分离 main / gift / edit-product 三类(带 `booking_id` 的编辑态商品不参与促销)
1040
+ * 1. 分离 main / gift / edit-product 三类(普通促销下带 `booking_id` 的编辑态商品不参与;
1041
+ * 配置 ITEM_REWARD 时,编辑态商品也参与商品奖励重算)
990
1042
  * 2. 转 PromotionProduct 喂评估器 → 拿到 `evaluateCartWithPricing` 与 `getProductsApplicableStrategies`
991
1043
  * 3. 把 PricedProduct 映射回 OrderProduct 形态:
992
1044
  * - 参与促销的,写 `metadata._promotion` + 调整 `selling_price` / `main_product_selling_price`
@@ -1016,6 +1068,7 @@ export function processCartPromotion(list, evaluator, options) {
1016
1068
  if (!list || list.length === 0 || !evaluator) return empty;
1017
1069
 
1018
1070
  // 0. 分类
1071
+ var shouldIncludeEditProductsForItemReward = evaluatorHasActionType(evaluator, ITEM_REWARD);
1019
1072
  var mainProductsWithIndex = [];
1020
1073
  var existingGiftsWithIndex = [];
1021
1074
  var editProductsWithIndex = [];
@@ -1032,11 +1085,18 @@ export function processCartPromotion(list, evaluator, options) {
1032
1085
  item: item,
1033
1086
  originalListIndex: i
1034
1087
  });
1035
- } else if ((item === null || item === void 0 ? void 0 : item.booking_id) !== undefined && (item === null || item === void 0 ? void 0 : item.booking_id) !== null && item.booking_id !== 0 && item.booking_id !== '0') {
1036
- editProductsWithIndex.push({
1037
- item: item,
1038
- originalListIndex: i
1039
- });
1088
+ } else if (isBookingEditProductLine(item)) {
1089
+ if (shouldIncludeEditProductsForItemReward) {
1090
+ mainProductsWithIndex.push({
1091
+ item: item,
1092
+ originalListIndex: i
1093
+ });
1094
+ } else {
1095
+ editProductsWithIndex.push({
1096
+ item: item,
1097
+ originalListIndex: i
1098
+ });
1099
+ }
1040
1100
  } else {
1041
1101
  mainProductsWithIndex.push({
1042
1102
  item: item,
@@ -1091,16 +1151,17 @@ export function processCartPromotion(list, evaluator, options) {
1091
1151
  var promotionProducts = [];
1092
1152
  var originalItemMap = new Map();
1093
1153
  var productsForStrategies = consolidatedMainProductsWithIndex.map(function (_ref16, i) {
1094
- var _item$product_id, _item$product_variant5, _item$metadata3, _item$num;
1154
+ var _item$product_id, _item$product_variant5, _item$metadata5, _item$num;
1095
1155
  var item = _ref16.item;
1096
1156
  return {
1097
1157
  id: i,
1098
1158
  product_id: Number((_item$product_id = item === null || item === void 0 ? void 0 : item.product_id) !== null && _item$product_id !== void 0 ? _item$product_id : 0) || 0,
1099
1159
  product_variant_id: Number((_item$product_variant5 = item === null || item === void 0 ? void 0 : item.product_variant_id) !== null && _item$product_variant5 !== void 0 ? _item$product_variant5 : 0) || 0,
1100
- name: (item === null || item === void 0 || (_item$metadata3 = item.metadata) === null || _item$metadata3 === void 0 ? void 0 : _item$metadata3.product_name) || (item === null || item === void 0 ? void 0 : item.title) || '',
1160
+ name: (item === null || item === void 0 || (_item$metadata5 = item.metadata) === null || _item$metadata5 === void 0 ? void 0 : _item$metadata5.product_name) || (item === null || item === void 0 ? void 0 : item.title) || '',
1101
1161
  price: getOrderProductBasePrice(item),
1102
1162
  quantity: Number((_item$num = item === null || item === void 0 ? void 0 : item.num) !== null && _item$num !== void 0 ? _item$num : 1) || 1,
1103
- bundle: getProductBundleForEvaluator(item)
1163
+ bundle: getProductBundleForEvaluator(item),
1164
+ _promotionOnlyForItemReward: isBookingEditProductLine(item)
1104
1165
  };
1105
1166
  });
1106
1167
  for (var _i = 0; _i < consolidatedMainProductsWithIndex.length; _i++) {
@@ -1208,7 +1269,7 @@ export function processCartPromotion(list, evaluator, options) {
1208
1269
  _step20;
1209
1270
  try {
1210
1271
  for (_iterator20.s(); !(_step20 = _iterator20.n()).done;) {
1211
- var _priced$originalId2, _priced$product_id, _originalItem$product, _metadata$_promotion2;
1272
+ var _priced$originalId2, _priced$product_id, _originalItem$product;
1212
1273
  var _priced = _step20.value;
1213
1274
  var rawSourceId = (_priced$originalId2 = _priced.originalId) !== null && _priced$originalId2 !== void 0 ? _priced$originalId2 : _priced.id;
1214
1275
  var _sourceId = Number(rawSourceId);
@@ -1227,7 +1288,7 @@ export function processCartPromotion(list, evaluator, options) {
1227
1288
  newItem._sourceCartNum = sourceCartNum;
1228
1289
 
1229
1290
  // 清掉历史促销字段
1230
- var wasInPromotion = ((_metadata$_promotion2 = metadata._promotion) === null || _metadata$_promotion2 === void 0 ? void 0 : _metadata$_promotion2.inPromotion) === true || originalItem._wasInPromotionBeforeConsolidate === true;
1291
+ var wasInPromotion = wasInPromotionBeforeEvaluation(originalItem) || originalItem._wasInPromotionBeforeConsolidate === true;
1231
1292
  delete metadata._promotion;
1232
1293
  if (Array.isArray(newItem.product_bundle)) {
1233
1294
  var _iterator23 = _createForOfIteratorHelper(newItem.product_bundle),
@@ -1248,12 +1309,13 @@ export function processCartPromotion(list, evaluator, options) {
1248
1309
  var priceUnchangedPromo = _priced.inPromotion && Number(_priced.finalPrice) === Number(originalBasePrice);
1249
1310
  if (shouldModifyPrice) {
1250
1311
  if (_priced.inPromotion && !priceUnchangedPromo) {
1251
- var _priced$strategyMetad;
1312
+ var _priced$strategyMetad, _strategyActionMap$ge;
1252
1313
  var promoUnitPrice = new Decimal(_priced.finalPrice).toDecimalPlaces(2).toFixed(2);
1253
1314
  applyPromoUnitPriceToLine(newItem, {
1254
1315
  promoUnitPrice: promoUnitPrice,
1255
1316
  originalBasePrice: originalBasePrice,
1256
- strategyTitle: (_priced$strategyMetad = _priced.strategyMetadata) === null || _priced$strategyMetad === void 0 ? void 0 : _priced$strategyMetad.name
1317
+ strategyTitle: (_priced$strategyMetad = _priced.strategyMetadata) === null || _priced$strategyMetad === void 0 ? void 0 : _priced$strategyMetad.name,
1318
+ actionType: _priced.strategyId ? (_strategyActionMap$ge = strategyActionMap.get(_priced.strategyId)) === null || _strategyActionMap$ge === void 0 ? void 0 : _strategyActionMap$ge.actionType : undefined
1257
1319
  });
1258
1320
  } else {
1259
1321
  // 撤销上一轮促销:还原 selling_price 到 main_product_original_price 派生值
@@ -82,8 +82,13 @@ export interface ISalesBooking {
82
82
  metadata?: Record<string, any> | null;
83
83
  [key: string]: any;
84
84
  }
85
+ export interface ISalesPaymentMetadata extends Record<string, any> {
86
+ /** 刷卡机设备快照;OS 不解析内部字段 */
87
+ card_reader_snapshot?: Record<string, unknown>;
88
+ }
85
89
  export interface ISalesPayment {
86
90
  order_payment_id?: number | null;
91
+ payment_number?: string;
87
92
  custom_payment_id?: number;
88
93
  code?: string;
89
94
  name?: string;
@@ -95,7 +100,7 @@ export interface ISalesPayment {
95
100
  status?: string;
96
101
  payment_time?: string | null;
97
102
  service_charge?: Record<string, any> | null;
98
- metadata?: Record<string, any> | null;
103
+ metadata?: ISalesPaymentMetadata | null;
99
104
  [key: string]: any;
100
105
  }
101
106
  export interface ISalesSurcharge {
@@ -104,7 +104,7 @@ function findVariantById(origin, variantId) {
104
104
  * 注意:这里不生成 identity,缺省时由 OrderModule 自动补齐。
105
105
  */
106
106
  export function transformBaseProductToOrderProduct(params) {
107
- var _ref10, _ref11, _ref12, _payload$product_id, _ref13, _ref14, _payload$product_vari, _payload$_origin, _payload$_origin2, _ref15, _findVariantById, _ref16, _ref17, _ref18, _ref19, _ref20, _ref21, _ref22, _payload$price, _ref23, _payload$line_total, _payload$_extend, _ref24, _ref25, _payload$product_sku$, _payload$product_sku, _payload$bundle, _payload$quantity, _payload$_extend2, _extend, _extend2, _ref26, _ref27, _origin$base_price, _ref28, _ref29, _payload$line_total2, _payload$_extend3, _payload$_extend4, _extend3, _payload$_extend5, _payload$_extend6, _ref30, _ref31, _payload$tax_fee, _ref32, _ref33, _payload$is_charge_ta;
107
+ var _ref10, _ref11, _ref12, _payload$product_id, _ref13, _ref14, _payload$product_vari, _payload$_origin, _payload$_origin2, _ref15, _findVariantById, _ref16, _ref17, _ref18, _ref19, _ref20, _matchedVariant$price, _ref21, _ref22, _payload$price, _ref23, _payload$line_total, _payload$_extend, _ref24, _ref25, _payload$product_sku$, _payload$product_sku, _payload$bundle, _payload$quantity, _payload$_extend2, _extend, _extend2, _ref26, _ref27, _origin$base_price, _ref28, _ref29, _payload$line_total2, _payload$_extend3, _payload$_extend4, _extend3, _payload$_extend5, _payload$_extend6, _ref30, _ref31, _payload$tax_fee, _ref32, _ref33, _payload$is_charge_ta;
108
108
  var payload = params.payload,
109
109
  _params$fallbackProdu = params.fallbackProductId,
110
110
  fallbackProductId = _params$fallbackProdu === void 0 ? null : _params$fallbackProdu;
@@ -116,11 +116,14 @@ export function transformBaseProductToOrderProduct(params) {
116
116
  var callbackOrigin = payload.origin || ((_payload$_origin = payload._origin) === null || _payload$_origin === void 0 ? void 0 : _payload$_origin.sourceProduct) || ((_payload$_origin2 = payload._origin) === null || _payload$_origin2 === void 0 ? void 0 : _payload$_origin2.sourceItem) || payload._origin || {};
117
117
  var origin = _objectSpread(_objectSpread({}, sourceProduct || {}), callbackOrigin || {});
118
118
  var matchedVariant = (_ref15 = (_findVariantById = findVariantById(callbackOrigin, productVariantId)) !== null && _findVariantById !== void 0 ? _findVariantById : findVariantById(sourceProduct, productVariantId)) !== null && _ref15 !== void 0 ? _ref15 : findVariantById(origin, productVariantId);
119
- var sourceProductPrice = toPriceString((_ref16 = (_ref17 = (_ref18 = (_ref19 = (_ref20 = (_ref21 = (_ref22 = (_payload$price = payload.price) !== null && _payload$price !== void 0 ? _payload$price : payload.selling_price) !== null && _ref22 !== void 0 ? _ref22 : matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.price) !== null && _ref21 !== void 0 ? _ref21 : matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.base_price) !== null && _ref20 !== void 0 ? _ref20 : origin === null || origin === void 0 ? void 0 : origin.price) !== null && _ref19 !== void 0 ? _ref19 : origin === null || origin === void 0 ? void 0 : origin.base_price) !== null && _ref18 !== void 0 ? _ref18 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.price) !== null && _ref17 !== void 0 ? _ref17 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.selling_price) !== null && _ref16 !== void 0 ? _ref16 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.base_price, '0.00');
119
+ var hasPriceOverride = payload.price_override !== undefined && payload.price_override !== null && payload.price_override !== '';
120
+ // 手动改价后 payload.price 是分摊后的主商品售价,不能再作为券前 source。
121
+ // 此时优先从商品/variant 快照读取目录价;售价仍由 line_total - bundle 推导。
122
+ var catalogSourcePrice = (_ref16 = (_ref17 = (_ref18 = (_ref19 = (_ref20 = (_matchedVariant$price = matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.price) !== null && _matchedVariant$price !== void 0 ? _matchedVariant$price : matchedVariant === null || matchedVariant === void 0 ? void 0 : matchedVariant.base_price) !== null && _ref20 !== void 0 ? _ref20 : origin === null || origin === void 0 ? void 0 : origin.price) !== null && _ref19 !== void 0 ? _ref19 : origin === null || origin === void 0 ? void 0 : origin.base_price) !== null && _ref18 !== void 0 ? _ref18 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.price) !== null && _ref17 !== void 0 ? _ref17 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.selling_price) !== null && _ref16 !== void 0 ? _ref16 : sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.base_price;
123
+ var sourceProductPrice = toPriceString(hasPriceOverride ? (_ref21 = catalogSourcePrice !== null && catalogSourcePrice !== void 0 ? catalogSourcePrice : payload.price) !== null && _ref21 !== void 0 ? _ref21 : payload.selling_price : (_ref22 = (_payload$price = payload.price) !== null && _payload$price !== void 0 ? _payload$price : payload.selling_price) !== null && _ref22 !== void 0 ? _ref22 : catalogSourcePrice, '0.00');
120
124
  var explicitLineTotal = (_ref23 = (_payload$line_total = payload.line_total) !== null && _payload$line_total !== void 0 ? _payload$line_total : payload.total) !== null && _ref23 !== void 0 ? _ref23 : (_payload$_extend = payload._extend) === null || _payload$_extend === void 0 ? void 0 : _payload$_extend.total;
121
125
  var hasExplicitLineTotal = Number.isFinite(Number(explicitLineTotal));
122
126
  var lineCompositeTotal = toPriceString(explicitLineTotal, sourceProductPrice);
123
- var hasPriceOverride = payload.price_override !== undefined && payload.price_override !== null && payload.price_override !== '';
124
127
  var productOptionItem = normalizeProductSkuOptions(normalizeOptionItems((_ref24 = (_ref25 = (_payload$product_sku$ = (_payload$product_sku = payload.product_sku) === null || _payload$product_sku === void 0 ? void 0 : _payload$product_sku.option) !== null && _payload$product_sku$ !== void 0 ? _payload$product_sku$ : payload.option) !== null && _ref25 !== void 0 ? _ref25 : payload.options) !== null && _ref24 !== void 0 ? _ref24 : payload.product_option_item));
125
128
  var productBundle = normalizeBundleItems((_payload$bundle = payload.bundle) !== null && _payload$bundle !== void 0 ? _payload$bundle : payload.product_bundle, hasPriceOverride);
126
129
  // `payload.unique` 是业务侧商品/票务标识,可能在连续加同一商品时重复;
@@ -190,7 +193,7 @@ export function transformBaseProductToOrderProduct(params) {
190
193
  }
191
194
  // 从源头补充商品多语言标题
192
195
  var productTitle = _objectSpread(_objectSpread({}, (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title_i18n) || {}), {}, {
193
- original: (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title) || ''
196
+ original: (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.original_title) || (sourceProduct === null || sourceProduct === void 0 ? void 0 : sourceProduct.title) || ''
194
197
  });
195
198
  return {
196
199
  product_id: productId,
@@ -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 | 6 | 4 | 3 | 5;
314
+ weekNum: 0 | 1 | 2 | 3 | 6 | 4 | 5;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -46,6 +46,8 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
46
46
  private getIdGeneratorPlugin;
47
47
  private loadOpenDataConfig;
48
48
  getOpenData(): Promise<OpenDataConfig | null>;
49
+ /** 清除店铺级 OpenData;下一次 getOpenData 时会重新拉取。 */
50
+ clearOpenDataCache(): void;
49
51
  private getShortNumberOrDeviceId;
50
52
  private configureIdGeneratorFromOpenData;
51
53
  private normalizePositiveInteger;
@@ -189,10 +191,12 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
189
191
  */
190
192
  getCustomer(): ICustomer | null;
191
193
  /**
192
- * 通过 ids 获取商品列表(不加载到模块中)
193
- * @returns 商品列表
194
+ * 通过 ids 获取商品列表;默认只读取内存,显式开启 loadMissing 时按当前订单上下文补查缺失商品。
195
+ * 补查直接写入 ProductList,不更新 BookingTicket.productCatalog,避免当前商品列表被查询子集覆盖。
194
196
  */
195
- getProductByIds(ids: number[]): Promise<ProductData[] | undefined>;
197
+ getProductByIds(ids: number[], options?: {
198
+ loadMissing?: boolean;
199
+ }): Promise<ProductData[]>;
196
200
  /**
197
201
  * 获取日程时间段点
198
202
  * @param params 参数
@@ -322,7 +326,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
322
326
  * 获取当前的客户搜索条件
323
327
  * @returns 当前搜索条件
324
328
  */
325
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
329
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
326
330
  /**
327
331
  * 获取客户列表状态(包含滚动加载相关状态)
328
332
  * @returns 客户状态
@@ -441,7 +445,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
441
445
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
442
446
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
443
447
  */
444
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
448
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
449
+ action: "reloadCatalog";
450
+ } | {
451
+ action: "add";
452
+ cacheItem: any;
453
+ } | {
454
+ action: "requiresDetail";
455
+ payload: AddProductRequiresDetailPayload;
456
+ } | {
457
+ action: "requiresBookingEdit";
458
+ cacheItem: any;
459
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
460
+ };
445
461
  /** 规格弹窗 callback 后的第二段决策。 */
446
462
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
447
463
  /**