@pisell/pisellos 0.10.2 → 0.10.4

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 (139) 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 +0 -9
  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/BaseModule.d.ts +1 -0
  14. package/dist/modules/BaseModule.js +24 -28
  15. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +5 -3
  16. package/dist/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +6 -3
  17. package/dist/modules/OpenData/index.d.ts +2 -0
  18. package/dist/modules/OpenData/index.js +8 -0
  19. package/dist/modules/Order/index.d.ts +41 -10
  20. package/dist/modules/Order/index.js +943 -546
  21. package/dist/modules/Order/payment-utils.d.ts +26 -0
  22. package/dist/modules/Order/payment-utils.js +225 -0
  23. package/dist/modules/Order/types.d.ts +43 -2
  24. package/dist/modules/Order/utils/orderCollectionIdentity.js +7 -2
  25. package/dist/modules/Order/utils.js +10 -6
  26. package/dist/modules/Payment/index.d.ts +2 -0
  27. package/dist/modules/Payment/index.js +79 -50
  28. package/dist/modules/Payment/types.d.ts +107 -28
  29. package/dist/modules/Payment/types.js +20 -3
  30. package/dist/modules/Payment/walletpass.d.ts +38 -1
  31. package/dist/modules/Payment/walletpass.js +917 -114
  32. package/dist/modules/ProductList/index.js +1 -1
  33. package/dist/modules/Rules/index.d.ts +3 -0
  34. package/dist/modules/Rules/index.js +130 -99
  35. package/dist/server/index.d.ts +16 -0
  36. package/dist/server/index.js +2084 -1188
  37. package/dist/server/modules/index.d.ts +1 -1
  38. package/dist/server/modules/order/index.d.ts +70 -4
  39. package/dist/server/modules/order/index.js +1816 -728
  40. package/dist/server/modules/order/types.d.ts +25 -3
  41. package/dist/server/modules/order/types.js +7 -1
  42. package/dist/solution/BaseSales/index.d.ts +114 -14
  43. package/dist/solution/BaseSales/index.js +1848 -478
  44. package/dist/solution/BaseSales/types.d.ts +55 -1
  45. package/dist/solution/BaseSales/types.js +2 -1
  46. package/dist/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  47. package/dist/solution/BaseSales/utils/cartPromotion.js +90 -31
  48. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  49. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +6 -3
  50. package/dist/solution/BookingByStep/index.d.ts +1 -1
  51. package/dist/solution/BookingTicket/index.d.ts +8 -16
  52. package/dist/solution/BookingTicket/index.js +138 -52
  53. package/dist/solution/BookingTicket/types.d.ts +1 -0
  54. package/dist/solution/BookingTicket/utils/addProductDecision.js +6 -0
  55. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  56. package/dist/solution/BookingTicket/utils/scan/applyGlobalScan.js +173 -83
  57. package/dist/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  58. package/dist/solution/BookingTicket/utils/weighingProductSku.js +45 -0
  59. package/dist/solution/Sales/index.d.ts +1 -0
  60. package/dist/solution/Sales/index.js +10 -2
  61. package/dist/solution/ScanOrder/index.js +31 -20
  62. package/dist/solution/UnifiedBookingSales/index.d.ts +3 -0
  63. package/dist/solution/UnifiedBookingSales/index.js +392 -304
  64. package/dist/solution/UnifiedBookingSales/types.d.ts +7 -0
  65. package/dist/solution/VenueBooking/index.d.ts +1 -0
  66. package/dist/solution/VenueBooking/index.js +34 -24
  67. package/dist/types/index.d.ts +1 -0
  68. package/dist/utils/payment-number.d.ts +9 -0
  69. package/dist/utils/payment-number.js +69 -0
  70. package/lib/core/index.d.ts +2 -0
  71. package/lib/core/index.js +4 -0
  72. package/lib/model/strategy/adapter/promotion/adapter.d.ts +4 -0
  73. package/lib/model/strategy/adapter/promotion/adapter.js +20 -0
  74. package/lib/model/strategy/adapter/promotion/evaluator.d.ts +17 -0
  75. package/lib/model/strategy/adapter/promotion/evaluator.js +235 -0
  76. package/lib/model/strategy/adapter/promotion/examples.d.ts +86 -0
  77. package/lib/model/strategy/adapter/promotion/examples.js +91 -0
  78. package/lib/model/strategy/adapter/promotion/index.d.ts +1 -1
  79. package/lib/model/strategy/adapter/promotion/index.js +2 -0
  80. package/lib/model/strategy/adapter/promotion/type.d.ts +90 -2
  81. package/lib/model/strategy/adapter/promotion/type.js +2 -0
  82. package/lib/modules/BaseModule.d.ts +1 -0
  83. package/lib/modules/BaseModule.js +24 -37
  84. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +2 -1
  85. package/lib/modules/BookingContext/utils/buildNormalProductCacheItemFromOrderLine.js +2 -1
  86. package/lib/modules/OpenData/index.d.ts +2 -0
  87. package/lib/modules/OpenData/index.js +5 -0
  88. package/lib/modules/Order/index.d.ts +41 -10
  89. package/lib/modules/Order/index.js +322 -86
  90. package/lib/modules/Order/payment-utils.d.ts +26 -0
  91. package/lib/modules/Order/payment-utils.js +224 -0
  92. package/lib/modules/Order/types.d.ts +43 -2
  93. package/lib/modules/Order/utils/orderCollectionIdentity.js +3 -0
  94. package/lib/modules/Order/utils.js +11 -4
  95. package/lib/modules/Payment/index.d.ts +2 -0
  96. package/lib/modules/Payment/index.js +34 -13
  97. package/lib/modules/Payment/types.d.ts +107 -28
  98. package/lib/modules/Payment/types.js +4 -3
  99. package/lib/modules/Payment/walletpass.d.ts +38 -1
  100. package/lib/modules/Payment/walletpass.js +730 -21
  101. package/lib/modules/ProductList/index.js +9 -1
  102. package/lib/modules/Rules/index.d.ts +3 -0
  103. package/lib/modules/Rules/index.js +39 -10
  104. package/lib/server/index.d.ts +16 -0
  105. package/lib/server/index.js +677 -28
  106. package/lib/server/modules/index.d.ts +1 -1
  107. package/lib/server/modules/order/index.d.ts +70 -4
  108. package/lib/server/modules/order/index.js +818 -69
  109. package/lib/server/modules/order/types.d.ts +25 -3
  110. package/lib/server/modules/order/types.js +1 -0
  111. package/lib/solution/BaseSales/index.d.ts +114 -14
  112. package/lib/solution/BaseSales/index.js +907 -58
  113. package/lib/solution/BaseSales/types.d.ts +55 -1
  114. package/lib/solution/BaseSales/types.js +2 -1
  115. package/lib/solution/BaseSales/utils/cartPromotion.d.ts +3 -1
  116. package/lib/solution/BaseSales/utils/cartPromotion.js +63 -12
  117. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +6 -1
  118. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  119. package/lib/solution/BookingByStep/index.d.ts +1 -1
  120. package/lib/solution/BookingTicket/index.d.ts +8 -16
  121. package/lib/solution/BookingTicket/index.js +63 -9
  122. package/lib/solution/BookingTicket/types.d.ts +1 -0
  123. package/lib/solution/BookingTicket/utils/addProductDecision.js +4 -0
  124. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.d.ts +8 -0
  125. package/lib/solution/BookingTicket/utils/scan/applyGlobalScan.js +37 -5
  126. package/lib/solution/BookingTicket/utils/weighingProductSku.d.ts +5 -0
  127. package/lib/solution/BookingTicket/utils/weighingProductSku.js +63 -0
  128. package/lib/solution/Sales/index.d.ts +1 -0
  129. package/lib/solution/Sales/index.js +5 -3
  130. package/lib/solution/ScanOrder/index.js +8 -0
  131. package/lib/solution/UnifiedBookingSales/index.d.ts +3 -0
  132. package/lib/solution/UnifiedBookingSales/index.js +48 -2
  133. package/lib/solution/UnifiedBookingSales/types.d.ts +7 -0
  134. package/lib/solution/VenueBooking/index.d.ts +1 -0
  135. package/lib/solution/VenueBooking/index.js +13 -6
  136. package/lib/types/index.d.ts +1 -0
  137. package/lib/utils/payment-number.d.ts +9 -0
  138. package/lib/utils/payment-number.js +64 -0
  139. package/package.json +1 -1
@@ -136,3 +136,89 @@ export declare const BUY_X_GET_Y_FREE_STRATEGY: {
136
136
  };
137
137
  }[];
138
138
  };
139
+ /**
140
+ * ITEM_REWARD 策略配置示例:儿童票触发婴儿票免费
141
+ *
142
+ * 业务规则:
143
+ * - 条件商品:儿童票(conditions.rules.productIdAndVariantId)
144
+ * - 奖励商品:购物车/订单内已经存在的婴儿票(actions[0].config.rewardTargets)
145
+ * - 本 action 不自动新增婴儿票;每次购物车变更后由统一促销链路重算
146
+ *
147
+ * 字段说明:
148
+ * - type: "ITEM_REWARD" 表示商品奖励 action
149
+ * - target: "product" 表示本期只奖励商品行
150
+ * - config.rewardTargets: 奖励对象数组,支持 { product_id, product_variant_id }
151
+ * - config.targetSelection: "consumer_best" 表示目标商品超额时选择节省金额最高的商品
152
+ * - value.rewardMethod:
153
+ * - "free": 目标商品最终价为 0
154
+ * - "percent_off": 百分比折扣,rewardValue 为 0-100
155
+ * - "amount_off": 每个目标商品固定减免 rewardValue
156
+ * - "fixed_price": 目标商品最终单价为 rewardValue
157
+ * - value.quantityRule:
158
+ * - "per_condition_quantity": 每满足 triggerQuantity 个条件商品,奖励 rewardQuantity 个目标商品
159
+ * - "all_targets": 满足条件后奖励全部目标商品
160
+ * - "max_per_order": 满足条件后每单最多奖励 maxRewardQuantity 个目标商品
161
+ */
162
+ export declare const ITEM_REWARD_STRATEGY: {
163
+ metadata: {
164
+ id: string;
165
+ name: {
166
+ en: string;
167
+ 'zh-CN': string;
168
+ 'zh-HK': string;
169
+ };
170
+ type: string;
171
+ custom: {
172
+ display: {
173
+ product_card: {
174
+ text: {
175
+ en: string;
176
+ 'zh-CN': string;
177
+ 'zh-HK': string;
178
+ };
179
+ type: string;
180
+ };
181
+ };
182
+ };
183
+ };
184
+ conditions: {
185
+ operator: string;
186
+ rules: ({
187
+ type: string;
188
+ field: string;
189
+ value: string;
190
+ operator: string;
191
+ } | {
192
+ type: string;
193
+ field: string;
194
+ value: {
195
+ product_id: number;
196
+ product_variant_id: number;
197
+ }[];
198
+ operator: string;
199
+ })[];
200
+ actionIds: string[];
201
+ };
202
+ actions: {
203
+ id: string;
204
+ type: string;
205
+ value: {
206
+ rewardMethod: string;
207
+ rewardValue: number;
208
+ quantityRule: string;
209
+ triggerQuantity: number;
210
+ rewardQuantity: number;
211
+ maxRewardQuantity: number;
212
+ };
213
+ valueType: string;
214
+ target: string;
215
+ priority: number;
216
+ config: {
217
+ rewardTargets: {
218
+ product_id: number;
219
+ product_variant_id: number;
220
+ }[];
221
+ targetSelection: string;
222
+ };
223
+ }[];
224
+ };
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  var examples_exports = {};
21
21
  __export(examples_exports, {
22
22
  BUY_X_GET_Y_FREE_STRATEGY: () => BUY_X_GET_Y_FREE_STRATEGY,
23
+ ITEM_REWARD_STRATEGY: () => ITEM_REWARD_STRATEGY,
23
24
  X_ITEMS_FOR_Y_PRICE_STRATEGY: () => X_ITEMS_FOR_Y_PRICE_STRATEGY
24
25
  });
25
26
  module.exports = __toCommonJS(examples_exports);
@@ -185,8 +186,98 @@ var BUY_X_GET_Y_FREE_STRATEGY = {
185
186
  }
186
187
  ]
187
188
  };
189
+ var ITEM_REWARD_STRATEGY = {
190
+ metadata: {
191
+ id: "STRATEGY_003",
192
+ name: {
193
+ en: "Infant ticket free with child ticket",
194
+ "zh-CN": "儿童票触发婴儿票免费",
195
+ "zh-HK": "兒童票觸發嬰兒票免費"
196
+ },
197
+ type: "promotion",
198
+ custom: {
199
+ display: {
200
+ product_card: {
201
+ text: {
202
+ en: "Infant ticket free",
203
+ "zh-CN": "婴儿票免费",
204
+ "zh-HK": "嬰兒票免費"
205
+ },
206
+ type: "tag"
207
+ }
208
+ }
209
+ }
210
+ },
211
+ conditions: {
212
+ operator: "and",
213
+ rules: [
214
+ {
215
+ type: "operator",
216
+ field: "currentDateTime",
217
+ value: "2023-01-01 00:00:00",
218
+ operator: ">="
219
+ },
220
+ {
221
+ type: "operator",
222
+ field: "currentDateTime",
223
+ value: "2030-01-01 00:00:00",
224
+ operator: "<="
225
+ },
226
+ {
227
+ type: "operator",
228
+ field: "productIdAndVariantId",
229
+ value: [
230
+ {
231
+ product_id: 1001,
232
+ // 条件商品:儿童票
233
+ product_variant_id: 0
234
+ // 0 = 匹配任意变体
235
+ }
236
+ ],
237
+ operator: "product_match"
238
+ }
239
+ ],
240
+ actionIds: ["1"]
241
+ },
242
+ actions: [
243
+ {
244
+ id: "1",
245
+ type: "ITEM_REWARD",
246
+ value: {
247
+ rewardMethod: "free",
248
+ // free | percent_off | amount_off | fixed_price
249
+ rewardValue: 0,
250
+ // free 可省略;其他 rewardMethod 使用
251
+ quantityRule: "per_condition_quantity",
252
+ // per_condition_quantity | all_targets | max_per_order
253
+ triggerQuantity: 1,
254
+ // N:每满足 N 个条件商品
255
+ rewardQuantity: 1,
256
+ // Y:奖励 Y 个目标商品
257
+ maxRewardQuantity: 1
258
+ // max_per_order 使用;本例保留为配置示意
259
+ },
260
+ valueType: "object",
261
+ target: "product",
262
+ priority: 1,
263
+ config: {
264
+ rewardTargets: [
265
+ {
266
+ product_id: 2001,
267
+ // 奖励对象:婴儿票
268
+ product_variant_id: 0
269
+ // 0 = 匹配任意变体
270
+ }
271
+ ],
272
+ targetSelection: "consumer_best"
273
+ // consumer_best = 按可节省金额从高到低选择
274
+ }
275
+ }
276
+ ]
277
+ };
188
278
  // Annotate the CommonJS export names for ESM import in node:
189
279
  0 && (module.exports = {
190
280
  BUY_X_GET_Y_FREE_STRATEGY,
281
+ ITEM_REWARD_STRATEGY,
191
282
  X_ITEMS_FOR_Y_PRICE_STRATEGY
192
283
  });
@@ -1,4 +1,4 @@
1
1
  export { PromotionEvaluator } from './evaluator';
2
2
  export { PromotionAdapter } from './adapter';
3
3
  export { default } from './adapter';
4
- export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY, } from './examples';
4
+ export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY, ITEM_REWARD_STRATEGY, } from './examples';
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var promotion_exports = {};
31
31
  __export(promotion_exports, {
32
32
  BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
33
+ ITEM_REWARD_STRATEGY: () => import_examples.ITEM_REWARD_STRATEGY,
33
34
  PromotionAdapter: () => import_adapter.PromotionAdapter,
34
35
  PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
35
36
  X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
@@ -43,6 +44,7 @@ var import_examples = require("./examples");
43
44
  // Annotate the CommonJS export names for ESM import in node:
44
45
  0 && (module.exports = {
45
46
  BUY_X_GET_Y_FREE_STRATEGY,
47
+ ITEM_REWARD_STRATEGY,
46
48
  PromotionAdapter,
47
49
  PromotionEvaluator,
48
50
  X_ITEMS_FOR_Y_PRICE_STRATEGY
@@ -12,6 +12,8 @@ export declare const PROMOTION_ACTION_TYPES: {
12
12
  readonly X_ITEMS_FOR_Y_PRICE: "X_ITEMS_FOR_Y_PRICE";
13
13
  /** 买X送Y(买X件送Y件,可累计) */
14
14
  readonly BUY_X_GET_Y_FREE: "BUY_X_GET_Y_FREE";
15
+ /** 商品奖励(满足条件后,订单内指定目标商品享优惠) */
16
+ readonly ITEM_REWARD: "ITEM_REWARD";
15
17
  /** 固定折扣 */
16
18
  readonly DISCOUNT_RATE: "DISCOUNT_RATE";
17
19
  /** 固定减价 */
@@ -66,6 +68,59 @@ export interface BuyXGetYFreeConfig {
66
68
  /** 可选的赠品列表 */
67
69
  giftProducts?: ProductIdentifier[];
68
70
  }
71
+ /**
72
+ * 商品奖励优惠方式
73
+ *
74
+ * - free: 目标商品最终价为 0
75
+ * - percent_off: 目标商品按百分比折扣,rewardValue 为 0-100
76
+ * - amount_off: 每个目标商品固定减免 rewardValue
77
+ * - fixed_price: 目标商品改为固定价 rewardValue
78
+ */
79
+ export type ItemRewardMethod = 'free' | 'percent_off' | 'amount_off' | 'fixed_price';
80
+ /**
81
+ * 商品奖励数量规则
82
+ *
83
+ * - per_condition_quantity: 每满足 N 个条件商品,奖励 Y 个目标商品
84
+ * - all_targets: 满足条件后奖励全部目标商品
85
+ * - max_per_order: 满足条件后每单最多奖励固定数量目标商品
86
+ */
87
+ export type ItemRewardQuantityRule = 'per_condition_quantity' | 'all_targets' | 'max_per_order';
88
+ /** 商品奖励目标选择规则 */
89
+ export type ItemRewardTargetSelection = 'consumer_best';
90
+ /**
91
+ * 商品奖励 - Action Value
92
+ *
93
+ * @example
94
+ * value: {
95
+ * rewardMethod: 'free',
96
+ * quantityRule: 'per_condition_quantity',
97
+ * triggerQuantity: 1,
98
+ * rewardQuantity: 1,
99
+ * }
100
+ */
101
+ export interface ItemRewardValue {
102
+ /** 奖励方式 */
103
+ rewardMethod: ItemRewardMethod;
104
+ /** 奖励值:percent_off/amount_off/fixed_price 使用,free 可省略 */
105
+ rewardValue?: number;
106
+ /** 奖励数量规则 */
107
+ quantityRule: ItemRewardQuantityRule;
108
+ /** 每满足 N 个条件商品;默认 1 */
109
+ triggerQuantity?: number;
110
+ /** 奖励 Y 个目标商品;默认 1 */
111
+ rewardQuantity?: number;
112
+ /** 每单最多奖励 Y 个目标商品;max_per_order 使用 */
113
+ maxRewardQuantity?: number;
114
+ }
115
+ /**
116
+ * 商品奖励 - Action Config
117
+ */
118
+ export interface ItemRewardConfig {
119
+ /** 奖励对象,本期支持指定商品/变体;product_variant_id=0 表示任意变体 */
120
+ rewardTargets?: ProductIdentifier[];
121
+ /** 目标商品超额时的选择规则;本期支持 consumer_best */
122
+ targetSelection?: ItemRewardTargetSelection;
123
+ }
69
124
  /**
70
125
  * 商品标识
71
126
  *
@@ -102,10 +157,19 @@ export interface BuyXGetYFreeAction extends Omit<ActionEffect, 'type' | 'value'
102
157
  valueType: 'object';
103
158
  config?: BuyXGetYFreeConfig;
104
159
  }
160
+ /**
161
+ * 商品奖励 Action
162
+ */
163
+ export interface ItemRewardAction extends Omit<ActionEffect, 'type' | 'value' | 'config'> {
164
+ type: typeof PROMOTION_ACTION_TYPES.ITEM_REWARD;
165
+ value: ItemRewardValue;
166
+ valueType: 'object';
167
+ config?: ItemRewardConfig;
168
+ }
105
169
  /**
106
170
  * 促销活动 Action 联合类型
107
171
  */
108
- export type PromotionAction = XItemsForYPriceAction | BuyXGetYFreeAction;
172
+ export type PromotionAction = XItemsForYPriceAction | BuyXGetYFreeAction | ItemRewardAction;
109
173
  /**
110
174
  * 促销相关运算符
111
175
  */
@@ -170,6 +234,8 @@ export interface PromotionProduct {
170
234
  quantity: number;
171
235
  /** 原价 */
172
236
  original_price?: number;
237
+ /** 内部字段:编辑态订单行只允许参与 ITEM_REWARD,避免旧促销误算历史行 */
238
+ _promotionOnlyForItemReward?: boolean;
173
239
  }
174
240
  /**
175
241
  * 促销活动适配器转换结果
@@ -195,7 +261,7 @@ export interface PromotionTransformResult {
195
261
  /**
196
262
  * Action 详情联合类型
197
263
  */
198
- export type PromotionActionDetail = XItemsForYPriceActionDetail | BuyXGetYFreeActionDetail;
264
+ export type PromotionActionDetail = XItemsForYPriceActionDetail | BuyXGetYFreeActionDetail | ItemRewardActionDetail;
199
265
  /**
200
266
  * X件Y元 Action 详情
201
267
  */
@@ -226,6 +292,28 @@ export interface BuyXGetYFreeActionDetail {
226
292
  /** 可选的赠品列表 */
227
293
  giftProducts: ProductIdentifier[];
228
294
  }
295
+ /**
296
+ * 商品奖励 Action 详情
297
+ */
298
+ export interface ItemRewardActionDetail {
299
+ type: typeof PROMOTION_ACTION_TYPES.ITEM_REWARD;
300
+ /** 奖励方式 */
301
+ rewardMethod: ItemRewardMethod;
302
+ /** 奖励值:percent_off/amount_off/fixed_price 使用,free 为 0 */
303
+ rewardValue: number;
304
+ /** 奖励数量规则 */
305
+ quantityRule: ItemRewardQuantityRule;
306
+ /** 每满足 N 个条件商品;默认 1 */
307
+ triggerQuantity: number;
308
+ /** 奖励 Y 个目标商品;默认 1 */
309
+ rewardQuantity: number;
310
+ /** 每单最多奖励 Y 个目标商品;max_per_order 使用 */
311
+ maxRewardQuantity?: number;
312
+ /** 奖励对象,本期支持指定商品/变体 */
313
+ rewardTargets: ProductIdentifier[];
314
+ /** 目标商品超额时的选择规则 */
315
+ targetSelection: ItemRewardTargetSelection;
316
+ }
229
317
  /**
230
318
  * X件Y元 - 业务层计算结果
231
319
  *
@@ -28,6 +28,8 @@ var PROMOTION_ACTION_TYPES = {
28
28
  X_ITEMS_FOR_Y_PRICE: "X_ITEMS_FOR_Y_PRICE",
29
29
  /** 买X送Y(买X件送Y件,可累计) */
30
30
  BUY_X_GET_Y_FREE: "BUY_X_GET_Y_FREE",
31
+ /** 商品奖励(满足条件后,订单内指定目标商品享优惠) */
32
+ ITEM_REWARD: "ITEM_REWARD",
31
33
  /** 固定折扣 */
32
34
  DISCOUNT_RATE: "DISCOUNT_RATE",
33
35
  /** 固定减价 */
@@ -8,6 +8,7 @@ export declare class BaseModule {
8
8
  protected core: PisellCore;
9
9
  constructor(name?: string, version?: string);
10
10
  destroy(): void;
11
+ private isRecord;
11
12
  checkSaveCache({ cacheId, fatherModule, store, cacheKey, }: {
12
13
  cacheId: string | undefined;
13
14
  fatherModule: string | undefined;
@@ -34,6 +34,9 @@ var BaseModule = class {
34
34
  this.core.effects.offByModuleDestroy(this.name);
35
35
  this.core.unregisterModule(this);
36
36
  }
37
+ isRecord(value) {
38
+ return !!value && typeof value === "object" && !Array.isArray(value);
39
+ }
37
40
  // 提供统一的缓存 module 里的数据的方法
38
41
  checkSaveCache({
39
42
  cacheId,
@@ -41,45 +44,29 @@ var BaseModule = class {
41
44
  store,
42
45
  cacheKey
43
46
  }) {
44
- const window = this.core.getPlugin("window");
45
- if (cacheId) {
47
+ if (!cacheId)
48
+ return;
49
+ try {
50
+ const window = this.core.getPlugin("window");
51
+ const sessionStorage = window == null ? void 0 : window.sessionStorage;
52
+ if (!sessionStorage)
53
+ return;
54
+ const storageKey = fatherModule || cacheId;
55
+ const rawCacheData = sessionStorage.getItem(storageKey);
56
+ const parsedCacheData = rawCacheData ? JSON.parse(rawCacheData) : {};
57
+ if (!this.isRecord(parsedCacheData))
58
+ return;
59
+ const cacheBucket = fatherModule ? this.isRecord(parsedCacheData[cacheId]) ? parsedCacheData[cacheId] : {} : parsedCacheData;
60
+ const moduleBucket = this.isRecord(cacheBucket[this.name]) ? cacheBucket[this.name] : {};
61
+ cacheKey.forEach((key) => {
62
+ moduleBucket[key] = store == null ? void 0 : store[key];
63
+ });
64
+ cacheBucket[this.name] = moduleBucket;
46
65
  if (fatherModule) {
47
- const currentCacheData = window.sessionStorage.getItem(fatherModule);
48
- let currentCacheDataObj = JSON.parse(currentCacheData || "{}");
49
- if (!currentCacheData || !currentCacheDataObj[cacheId]) {
50
- currentCacheDataObj = {
51
- [cacheId]: {
52
- [this.name]: {}
53
- }
54
- };
55
- }
56
- if (!currentCacheDataObj[cacheId][this.name]) {
57
- currentCacheDataObj[cacheId][this.name] = {};
58
- }
59
- cacheKey.forEach((key) => {
60
- currentCacheDataObj[cacheId][this.name][key] = store == null ? void 0 : store[key];
61
- });
62
- window.sessionStorage.setItem(
63
- fatherModule,
64
- JSON.stringify(currentCacheDataObj)
65
- );
66
- } else {
67
- let currentCacheData = window.sessionStorage.getItem(cacheId);
68
- let currentCacheDataObj = JSON.parse(currentCacheData || "{}");
69
- if (!currentCacheDataObj) {
70
- currentCacheDataObj = {};
71
- }
72
- if (!currentCacheDataObj[this.name]) {
73
- currentCacheDataObj[this.name] = {};
74
- }
75
- cacheKey.forEach((key) => {
76
- currentCacheDataObj[this.name][key] = store[key];
77
- });
78
- window.sessionStorage.setItem(
79
- cacheId,
80
- JSON.stringify(currentCacheDataObj)
81
- );
66
+ parsedCacheData[cacheId] = cacheBucket;
82
67
  }
68
+ sessionStorage.setItem(storageKey, JSON.stringify(parsedCacheData));
69
+ } catch {
83
70
  }
84
71
  }
85
72
  effectsOn(eventType, callback) {
@@ -184,7 +184,7 @@ function synthesizeProductResourceFromBooking(booking) {
184
184
  };
185
185
  }
186
186
  function buildCacheItemFromOrderLine(input) {
187
- var _a, _b, _c, _d, _e, _f;
187
+ var _a, _b, _c, _d, _e, _f, _g;
188
188
  const { product, booking, sourceProduct } = input;
189
189
  const resolvedId = product.product_id ?? (sourceProduct == null ? void 0 : sourceProduct.id);
190
190
  const selling = Number(product.selling_price ?? 0);
@@ -259,6 +259,7 @@ function buildCacheItemFromOrderLine(input) {
259
259
  price: (sourceProduct == null ? void 0 : sourceProduct.price) ?? selling,
260
260
  selling_price: product.selling_price,
261
261
  original_price: product.original_price,
262
+ ...Number(((_g = product.product_sku) == null ? void 0 : _g.open_sold_weight) || 0) === 1 ? { product_sku: JSON.parse(JSON.stringify(product.product_sku)) } : {},
262
263
  ...productOptionString ? { product_option_string: productOptionString } : {},
263
264
  _extend: extend,
264
265
  new: 0,
@@ -78,7 +78,7 @@ function mapOrderBundleToOtherBundle(bundle) {
78
78
  });
79
79
  }
80
80
  function buildNormalProductCacheItemFromOrderLine(input) {
81
- var _a, _b, _c, _d, _e;
81
+ var _a, _b, _c, _d, _e, _f;
82
82
  const { product, sourceProduct } = input;
83
83
  const resolvedId = product.product_id ?? (sourceProduct == null ? void 0 : sourceProduct.id);
84
84
  const sourcePrice = resolveSourceProductPrice(product, sourceProduct);
@@ -144,6 +144,7 @@ function buildNormalProductCacheItemFromOrderLine(input) {
144
144
  note: product.note,
145
145
  order_detail_id: product.order_detail_id ?? null,
146
146
  discount_list: discountList,
147
+ ...Number(((_f = product.product_sku) == null ? void 0 : _f.open_sold_weight) || 0) === 1 ? { product_sku: JSON.parse(JSON.stringify(product.product_sku)) } : {},
147
148
  new: 0,
148
149
  autoClose: true,
149
150
  _extend: extend
@@ -27,6 +27,8 @@ export declare class OpenDataModule extends BaseModule implements Module {
27
27
  fetchOpenData(params: OpenDataFetchParams): Promise<OpenDataConfig>;
28
28
  getOpenData(): OpenDataConfig | null;
29
29
  getLastFetchedAt(): number | null;
30
+ /** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
31
+ clearCache(): void;
30
32
  checkAvailability(scheduleModule?: ScheduleModule): OpenDataAvailabilityResult;
31
33
  storeChange(): void;
32
34
  }
@@ -104,6 +104,11 @@ var OpenDataModule = class extends import_BaseModule.BaseModule {
104
104
  getLastFetchedAt() {
105
105
  return this.store.lastFetchedAt ?? null;
106
106
  }
107
+ /** 清除内存与 sessionStorage 镜像中的 OpenData,供宿主切店时调用。 */
108
+ clearCache() {
109
+ this.store.data = null;
110
+ this.store.lastFetchedAt = null;
111
+ }
107
112
  checkAvailability(scheduleModule) {
108
113
  var _a;
109
114
  const scheduleList = scheduleModule ? scheduleModule == null ? void 0 : scheduleModule.getScheduleListByIds(
@@ -3,7 +3,7 @@ import { BaseModule } from '../BaseModule';
3
3
  import { OrderModuleAPI, CommitOrderParams, UpdateOrderBookingParams, UpdateOrderProductParams, UpdateOrderProductQuantityParams, CancelOrderParams, ChangeBookingStatusParams, CheckoutOrderParams } from './types';
4
4
  import { CartItem } from '../Cart/types';
5
5
  import { type SubmitPayloadEnhancer } from './utils';
6
- import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions } from './types';
6
+ import type { OrderAmountSnapshot, AddProductBookingInput, OrderIdentitySnapshot, OrderPaymentSource, OrderSnapshot, OrderSyncState, SyncPaymentsToOrderParams, SyncPaymentsToOrderResult, SubmitSalesOrderParams, OrderProduct, OrderProductIdentity, OrderSummary, OrderTempOrder, OrderPaymentData, OrderPaymentUpdateOptions, OrderPaymentUpdateResult, SendCustomerPayLinkParams, UpdateTempOrderCustomerInput, OrderCustomerPatch, OrderCustomerView, ReplaceTempOrderOptions, OrderPromotionEvaluator, OrderGiftSelectResolver, OrderUnfulfilledPromotion, OrderLastGiftActions } from './types';
7
7
  import type { ICustomer } from '../AccountList/types';
8
8
  import type { Discount } from '../Discount/types';
9
9
  import { UnavailableReason } from '../Rules/types';
@@ -14,7 +14,12 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
14
14
  private request;
15
15
  private logger;
16
16
  private window;
17
+ private appPlugin;
17
18
  private cacheId;
19
+ private fatherModule;
20
+ private openCache;
21
+ private sessionStoragePersistEnabled;
22
+ private sessionStorageRestoreRecord;
18
23
  private salesSummaryModuleName;
19
24
  private rulesHooksOverride?;
20
25
  private moduleHooksOverride?;
@@ -45,6 +50,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
45
50
  static populateSavedAmounts(productList: Array<Record<string, any>>, discountList: Array<Record<string, any>>): void;
46
51
  private applyProductDiscountPrices;
47
52
  constructor(name?: string, version?: string);
53
+ private syncSessionStorageOptions;
48
54
  initialize(core: PisellCore, options: ModuleOptions): Promise<void>;
49
55
  destroy(): Promise<void>;
50
56
  /**
@@ -80,6 +86,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
80
86
  private ensureEditDiscountConfigForProductChange;
81
87
  scanCode(code: string, customerId?: number): Promise<{
82
88
  isAvailable: boolean;
89
+ isAccepted?: boolean;
83
90
  discountList: Discount[];
84
91
  type: 'server' | 'clientCalc';
85
92
  unavailableReason?: UnavailableReason;
@@ -135,7 +142,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
135
142
  }): void;
136
143
  /**
137
144
  * 控制 IndexedDB 草稿(saveDraft)是否写入。
138
- * localStorage tempOrder 持久化已废弃,此方法仅影响 saveDraft。
145
+ * 此开关仅影响 saveDraft;可选 sessionStorage 会话恢复由
146
+ * enableSessionStoragePersist 独立控制。
139
147
  *
140
148
  * @example
141
149
  * order.setEnableTempOrderPersist(false); // BigSale 弹窗:跳过 ~1s 的 dbUpdate
@@ -143,8 +151,12 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
143
151
  setEnableTempOrderPersist(enabled: boolean): void;
144
152
  /** 是否允许 saveDraft 写入 IndexedDB 草稿。 */
145
153
  isTempOrderPersistEnabled(): boolean;
146
- /** @deprecated OrderModule 不再负责 tempOrder localStorage 持久化;草稿保存请使用 IndexedDB saveDraft。 */
154
+ /**
155
+ * 在 UnifiedBookingSales 显式开启会话恢复时,将完整 tempOrder 写入
156
+ * sessionStorage 的 cacheId 分桶。写入失败由 BaseModule 静默降级。
157
+ */
147
158
  persistTempOrder(): void;
159
+ consumeSessionStorageRestore(): Record<string, any> | null;
148
160
  notifyTempOrderChanged(): void;
149
161
  private createDefaultTempOrderInstance;
150
162
  private createExternalSaleNumber;
@@ -177,6 +189,9 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
177
189
  };
178
190
  private calculateDepositPaidAmount;
179
191
  private resolveNextOrderPaymentType;
192
+ private getPaymentNumberAppData;
193
+ private getPaymentNumberDevicePrefixSync;
194
+ private getPaymentNumberDevicePrefixAsync;
180
195
  private normalizePaymentSource;
181
196
  private updateTempOrderPaymentStatus;
182
197
  private shouldKeepPaymentStatusAfterAmountRecalc;
@@ -308,19 +323,20 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
308
323
  * 用一组支付来源覆盖当前订单支付项。
309
324
  *
310
325
  * 入参允许来自 PaymentModule 的 PaymentItem,内部统一映射为 Sales 协议:
311
- * uuid -> metadata.unique_payment_number,id -> custom_payment_id,
326
+ * 新支付来源的 uuid 会作为 payment_number 的唯一号段,id -> custom_payment_id,
312
327
  * isSynced 等运行态字段不会进入 tempOrder.payments。
313
328
  */
314
329
  setOrderPayments(payments: OrderPaymentSource[]): OrderPaymentData[];
315
- /** 追加单个支付项,并立即持久化当前 tempOrder。 */
330
+ /** 同步兼容入口:按调用当下的 device_id 或 LOCAL 生成支付编号。 */
316
331
  addOrderPayment(payment: OrderPaymentSource): OrderPaymentData[];
332
+ /** 异步入口:创建支付项时读取最新 IoT 设备短号。 */
333
+ addOrderPaymentAsync(payment: OrderPaymentSource): Promise<OrderPaymentData[]>;
334
+ private addOrderPaymentWithDevicePrefix;
317
335
  /**
318
- * 按支付唯一号、后端支付 ID、自定义支付方式 ID 或旧 uuid 更新支付项。
319
- *
320
- * 该方法服务 PaymentModal 的 void / 编辑场景;更新 metadata 时会做浅合并,
321
- * 避免覆盖 unique_payment_number、现金实付/找零等已有元数据。
336
+ * 默认按支付唯一号精确更新;仅显式指定 legacy 时兼容历史支付标识。
337
+ * metadata 与 transactions 会分别合并,避免覆盖支付会话号和已有交易记录。
322
338
  */
323
- updateOrderPayment(paymentIdentity: string | number, updates: Partial<OrderPaymentData> & Record<string, any>): OrderPaymentData[];
339
+ updateOrderPayment(paymentIdentity: string | number, updates: Partial<OrderPaymentData> & Record<string, any>, options?: OrderPaymentUpdateOptions): Promise<OrderPaymentUpdateResult>;
324
340
  /** 从当前订单支付项中移除指定支付项。 */
325
341
  deleteOrderPayment(paymentIdentity: string | number): OrderPaymentData[];
326
342
  private confirmPendingVoucherPaymentsInList;
@@ -343,7 +359,11 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
343
359
  */
344
360
  updateVoucherOrderPayments(payments: OrderPaymentSource[], options?: {
345
361
  status?: 'paid' | 'payment_pending';
362
+ devicePrefix?: string;
346
363
  }): OrderPaymentData[];
364
+ updateVoucherOrderPaymentsAsync(payments: OrderPaymentSource[], options?: {
365
+ status?: 'paid' | 'payment_pending';
366
+ }): Promise<OrderPaymentData[]>;
347
367
  private shouldMergeProductToOrder;
348
368
  private hasOrderProductLineNote;
349
369
  /**
@@ -428,6 +448,14 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
428
448
  type?: string;
429
449
  }): import("./types").OrderSubmitPayload;
430
450
  applyLocalPrintOrderNumbers(order?: Record<string, any> | null): Promise<OrderTempOrder>;
451
+ saveTempOrderAsDraft<T = any>(params?: {
452
+ cacheId?: string;
453
+ platform?: string;
454
+ businessCode?: string;
455
+ channel?: string;
456
+ type?: string;
457
+ enhancePayload?: SubmitPayloadEnhancer;
458
+ }): Promise<T>;
431
459
  /**
432
460
  * 提交当前 Sales tempOrder。
433
461
  *
@@ -519,6 +547,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
519
547
  */
520
548
  hydrateTempOrderFromRecord(record: Record<string, any>, options?: {
521
549
  recalcOnHydrate?: boolean;
550
+ source?: 'salesDetail' | 'sessionStorage';
522
551
  }): Promise<OrderTempOrder>;
523
552
  /**
524
553
  * 兼容后端详情将 holder 放在 metadata.holder 的历史形态,统一补到运行时展示路径。
@@ -533,6 +562,8 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
533
562
  */
534
563
  private seedAnonymousBookingUidsFromProducts;
535
564
  private normalizeTempOrderForRuntime;
565
+ private isSyntheticDraftOrderIdForRuntime;
566
+ private withoutSyntheticDraftOrderIdForRuntime;
536
567
  private hydrateLinkedBookingIdentity;
537
568
  private pickHydratedDisplayText;
538
569
  private formatHydratedNamePair;