@pisell/pisellos 2.1.126 → 2.1.127

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 (39) hide show
  1. package/dist/model/strategy/adapter/itemRule/adapter.js +6 -2
  2. package/dist/model/strategy/adapter/itemRule/examples.d.ts +15 -0
  3. package/dist/model/strategy/adapter/itemRule/examples.js +68 -1
  4. package/dist/model/strategy/adapter/itemRule/index.d.ts +1 -1
  5. package/dist/model/strategy/adapter/itemRule/index.js +1 -1
  6. package/dist/model/strategy/adapter/itemRule/type.d.ts +9 -0
  7. package/dist/modules/Order/index.d.ts +1 -1
  8. package/dist/modules/Order/index.js +4 -38
  9. package/dist/modules/Order/utils.d.ts +24 -0
  10. package/dist/modules/Order/utils.js +87 -11
  11. package/dist/modules/SalesSummary/types.d.ts +2 -1
  12. package/dist/modules/SalesSummary/utils.js +10 -10
  13. package/dist/solution/BookingByStep/index.d.ts +2 -2
  14. package/dist/solution/ScanOrder/index.d.ts +5 -0
  15. package/dist/solution/ScanOrder/index.js +177 -60
  16. package/dist/solution/ScanOrder/types.d.ts +19 -5
  17. package/dist/solution/ScanOrder/utils.d.ts +14 -0
  18. package/dist/solution/ScanOrder/utils.js +138 -63
  19. package/dist/solution/VenueBooking/index.js +40 -44
  20. package/lib/model/strategy/adapter/itemRule/adapter.js +10 -2
  21. package/lib/model/strategy/adapter/itemRule/examples.d.ts +15 -0
  22. package/lib/model/strategy/adapter/itemRule/examples.js +47 -0
  23. package/lib/model/strategy/adapter/itemRule/index.d.ts +1 -1
  24. package/lib/model/strategy/adapter/itemRule/index.js +2 -0
  25. package/lib/model/strategy/adapter/itemRule/type.d.ts +9 -0
  26. package/lib/modules/Order/index.d.ts +1 -1
  27. package/lib/modules/Order/index.js +2 -35
  28. package/lib/modules/Order/utils.d.ts +24 -0
  29. package/lib/modules/Order/utils.js +65 -4
  30. package/lib/modules/SalesSummary/types.d.ts +2 -1
  31. package/lib/modules/SalesSummary/utils.js +2 -2
  32. package/lib/solution/BookingByStep/index.d.ts +2 -2
  33. package/lib/solution/ScanOrder/index.d.ts +5 -0
  34. package/lib/solution/ScanOrder/index.js +76 -19
  35. package/lib/solution/ScanOrder/types.d.ts +19 -5
  36. package/lib/solution/ScanOrder/utils.d.ts +14 -0
  37. package/lib/solution/ScanOrder/utils.js +82 -20
  38. package/lib/solution/VenueBooking/index.js +10 -16
  39. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  export { ItemRuleEvaluator } from './evaluator';
2
2
  export { ItemRuleAdapter } from './adapter';
3
3
  export { default } from './adapter';
4
- export { MIN_CONDIMENT_PER_PERSON_STRATEGY, MAX_BUNS_PER_TABLE_STRATEGY, HOTPOT_BASE_REQUIRED_STRATEGY, quickUseItemRuleEvaluator, runItemRuleEvaluatorDemo, } from './examples';
4
+ export { MIN_CONDIMENT_PER_PERSON_STRATEGY, MAX_BUNS_PER_TABLE_STRATEGY, HOTPOT_BASE_REQUIRED_STRATEGY, HOTPOT_BASE_PICK_ONE_STRATEGY, quickUseItemRuleEvaluator, runItemRuleEvaluatorDemo, } from './examples';
5
5
  export * from './type';
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/model/strategy/adapter/itemRule/index.ts
31
31
  var itemRule_exports = {};
32
32
  __export(itemRule_exports, {
33
+ HOTPOT_BASE_PICK_ONE_STRATEGY: () => import_examples.HOTPOT_BASE_PICK_ONE_STRATEGY,
33
34
  HOTPOT_BASE_REQUIRED_STRATEGY: () => import_examples.HOTPOT_BASE_REQUIRED_STRATEGY,
34
35
  ItemRuleAdapter: () => import_adapter.ItemRuleAdapter,
35
36
  ItemRuleEvaluator: () => import_evaluator.ItemRuleEvaluator,
@@ -47,6 +48,7 @@ var import_examples = require("./examples");
47
48
  __reExport(itemRule_exports, require("./type"), module.exports);
48
49
  // Annotate the CommonJS export names for ESM import in node:
49
50
  0 && (module.exports = {
51
+ HOTPOT_BASE_PICK_ONE_STRATEGY,
50
52
  HOTPOT_BASE_REQUIRED_STRATEGY,
51
53
  ItemRuleAdapter,
52
54
  ItemRuleEvaluator,
@@ -198,6 +198,15 @@ export interface QuantityLimitResult {
198
198
  mustInclude?: boolean;
199
199
  /** 作用范围 */
200
200
  scope: RuleScope;
201
+ /**
202
+ * 校验失败时的提示语(已做 {min}/{max}/{exact} 占位符替换)。
203
+ * 当 rawValidationMessage 为多语言对象时,后端不做 locale 选择,
204
+ * 默认按 en → Object.values()[0] 的顺序兜底,前端可再根据自身 locale
205
+ * 读取 rawValidationMessage 做精确匹配。
206
+ */
207
+ validationMessage?: string;
208
+ /** 原始多语言模板,前端可根据自身 locale 做二次选择 */
209
+ rawValidationMessage?: string | Record<string, string>;
201
210
  }
202
211
  /**
203
212
  * ItemRule 评估器的完整输出结果
@@ -112,6 +112,6 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
112
112
  createOrderByCheckout(params: CheckoutOrderParams): Promise<any>;
113
113
  submitScanOrder<T = any>(params: SubmitScanOrderParams): Promise<T>;
114
114
  scanOrderMore<T = any>(params: ScanOrderMoreParams): Promise<T>;
115
- getOrderInfoByRemote(order_id: number): Promise<void>;
115
+ getOrderInfoByRemote(order_id: number): Promise<any>;
116
116
  getLastOrderInfo(): Record<string, any> | undefined;
117
117
  }
@@ -158,41 +158,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
158
158
  this.store.rules = rules;
159
159
  }
160
160
  createDefaultRulesHooks() {
161
- return {
162
- getProduct: (product) => {
163
- var _a, _b, _c, _d;
164
- return {
165
- id: product.product_id,
166
- _id: product.identity_key ? `${product.product_id}_${product.product_variant_id}_${product.identity_key}` : `${product.product_id}_${product.product_variant_id}`,
167
- price: product.selling_price,
168
- total: new import_decimal.default(product.payment_price || product.selling_price || 0).times(product.num || 1).toNumber(),
169
- origin_total: new import_decimal.default(product.original_price || product.selling_price || 0).times(product.num || 1).toNumber(),
170
- original_price: product.original_price,
171
- quantity: product.num || 1,
172
- num: product.num || 1,
173
- discount_list: product.discount_list || [],
174
- bundle: product.product_bundle || [],
175
- booking_id: ((_a = product._origin) == null ? void 0 : _a.booking_id) || null,
176
- isClient: false,
177
- isManualDiscount: ((_b = product._origin) == null ? void 0 : _b.isManualDiscount) || false,
178
- holder_id: (_c = product._origin) == null ? void 0 : _c.holder_id,
179
- startDate: (_d = product._origin) == null ? void 0 : _d.startDate
180
- };
181
- },
182
- setProduct: (product, values) => ({
183
- ...product,
184
- selling_price: values.price !== void 0 ? String(values.price) : product.selling_price,
185
- payment_price: values.total !== void 0 ? String(values.total) : product.payment_price,
186
- original_price: values.original_price !== void 0 ? String(values.original_price) : product.original_price,
187
- discount_list: values.discount_list ?? product.discount_list,
188
- num: values.quantity ?? product.num,
189
- product_bundle: values.bundle ?? product.product_bundle,
190
- metadata: {
191
- ...product.metadata || {},
192
- ...values.main_product_selling_price !== void 0 ? { main_product_selling_price: String(values.main_product_selling_price) } : {}
193
- }
194
- })
195
- };
161
+ return (0, import_utils.createDefaultOrderRulesHooks)();
196
162
  }
197
163
  // ─── Discount: 公共 API ───
198
164
  async loadDiscountConfig(params) {
@@ -740,6 +706,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
740
706
  if (res.code === 200 && this.store.tempOrder) {
741
707
  this.store.tempOrder.lastOrderInfo = res.data;
742
708
  }
709
+ return res;
743
710
  }
744
711
  getLastOrderInfo() {
745
712
  var _a, _b;
@@ -1,5 +1,25 @@
1
1
  import { CartItem } from "../Cart";
2
2
  import type { ScanOrderSubmitPayload, ScanOrderSubmitProduct, ScanOrderSummary, ScanOrderTempOrder } from '../../solution/ScanOrder/types';
3
+ import type { RulesParamsHooks } from '../Rules/types';
4
+ /**
5
+ * OrderModule 默认 Rules 钩子工厂。
6
+ *
7
+ * 价格语义约定(订单域):
8
+ * - `selling_price`:券后单品单价(实际成交单价)。初次加购 = `original_price`;券应用后由 Rules 引擎更新。
9
+ * - `original_price`:券前单品单价(店铺售价)。不承载后台划线价语义。
10
+ * - `payment_price`:已从内部字段移除;只在出站 payload 中由 `selling_price` 派生以兼容后端。
11
+ *
12
+ * Rules 钩子契约:
13
+ * - `getProduct.total` = `selling_price × num`(当前成交总价)
14
+ * - `getProduct.origin_total` = `original_price × num`(券前总价)
15
+ * - `setProduct` 写回 `selling_price` 的优先级:
16
+ * 1. `values.main_product_selling_price`(券应用分支,per-unit 券后主价)
17
+ * 2. `values.price`(还原分支 `restoredPrice`、good_pass 归零)
18
+ * 3. `values.total / num`(仅当 Rules 只给出总价时的兜底)
19
+ *
20
+ * 导出为纯函数方便单测直接驱动钩子,不依赖 OrderModule 实例。
21
+ */
22
+ export declare function createDefaultOrderRulesHooks(): RulesParamsHooks;
3
23
  /**
4
24
  * 通过 session 类商品的开始时间结束时间生成商品的时长
5
25
  * @param {CartItem} cartItem
@@ -28,6 +48,10 @@ export declare function formatDateTime(date: Date): string;
28
48
  export declare function normalizeSubmitBooking<T extends {
29
49
  metadata?: Record<string, any>;
30
50
  }>(booking: T): T;
51
+ /** 提交用人数:有限且为正则向下取整,否则为 1 */
52
+ export declare function normalizeSubmitCollectPaxValue(value: unknown): number;
53
+ /** 从临时订单 metadata 解析合成 booking 的 collect_pax */
54
+ export declare function resolveSubmitCollectPax(tempOrder: ScanOrderTempOrder): number;
31
55
  export declare function createDefaultTempOrder(params: {
32
56
  now: string;
33
57
  summary?: ScanOrderSummary;
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var utils_exports = {};
31
31
  __export(utils_exports, {
32
32
  buildSubmitPayload: () => buildSubmitPayload,
33
+ createDefaultOrderRulesHooks: () => createDefaultOrderRulesHooks,
33
34
  createDefaultTempOrder: () => createDefaultTempOrder,
34
35
  createEmptySummary: () => import_utils2.createEmptySummary,
35
36
  createUuidV4: () => createUuidV4,
@@ -39,12 +40,59 @@ __export(utils_exports, {
39
40
  getAllDiscountList: () => getAllDiscountList,
40
41
  isTempOrder: () => isTempOrder,
41
42
  mergeRelationForms: () => mergeRelationForms,
42
- normalizeSubmitBooking: () => normalizeSubmitBooking
43
+ normalizeSubmitBooking: () => normalizeSubmitBooking,
44
+ normalizeSubmitCollectPaxValue: () => normalizeSubmitCollectPaxValue,
45
+ resolveSubmitCollectPax: () => resolveSubmitCollectPax
43
46
  });
44
47
  module.exports = __toCommonJS(utils_exports);
45
48
  var import_dayjs = __toESM(require("dayjs"));
49
+ var import_decimal = __toESM(require("decimal.js"));
46
50
  var import_utils = require("../../solution/ScanOrder/utils");
47
51
  var import_utils2 = require("../../solution/ScanOrder/utils");
52
+ function createDefaultOrderRulesHooks() {
53
+ const toUnitPriceString = (totalLike, num) => {
54
+ const effectiveNum = Number(num) > 0 ? Number(num) : 1;
55
+ return new import_decimal.default(Number(totalLike) || 0).dividedBy(effectiveNum).toDecimalPlaces(2).toString();
56
+ };
57
+ return {
58
+ getProduct: (product) => {
59
+ var _a, _b, _c, _d;
60
+ return {
61
+ id: product.product_id,
62
+ _id: product.identity_key ? `${product.product_id}_${product.product_variant_id}_${product.identity_key}` : `${product.product_id}_${product.product_variant_id}`,
63
+ price: product.selling_price,
64
+ total: new import_decimal.default(product.selling_price || 0).times(product.num || 1).toNumber(),
65
+ origin_total: new import_decimal.default(product.original_price || product.selling_price || 0).times(product.num || 1).toNumber(),
66
+ original_price: product.original_price,
67
+ quantity: product.num || 1,
68
+ num: product.num || 1,
69
+ discount_list: product.discount_list || [],
70
+ bundle: product.product_bundle || [],
71
+ booking_id: ((_a = product._origin) == null ? void 0 : _a.booking_id) || null,
72
+ isClient: false,
73
+ isManualDiscount: ((_b = product._origin) == null ? void 0 : _b.isManualDiscount) || false,
74
+ holder_id: (_c = product._origin) == null ? void 0 : _c.holder_id,
75
+ startDate: (_d = product._origin) == null ? void 0 : _d.startDate
76
+ };
77
+ },
78
+ setProduct: (product, values) => {
79
+ const nextNum = Number(values.quantity ?? product.num ?? 1) || 1;
80
+ const nextSellingPrice = values.main_product_selling_price !== void 0 ? String(values.main_product_selling_price) : values.price !== void 0 ? String(values.price) : values.total !== void 0 ? toUnitPriceString(values.total, nextNum) : product.selling_price;
81
+ return {
82
+ ...product,
83
+ selling_price: nextSellingPrice,
84
+ original_price: values.original_price !== void 0 ? String(values.original_price) : product.original_price,
85
+ discount_list: values.discount_list ?? product.discount_list,
86
+ num: values.quantity ?? product.num,
87
+ product_bundle: values.bundle ?? product.product_bundle,
88
+ metadata: {
89
+ ...product.metadata || {},
90
+ ...values.main_product_selling_price !== void 0 ? { main_product_selling_price: String(values.main_product_selling_price) } : {}
91
+ }
92
+ };
93
+ }
94
+ };
95
+ }
48
96
  var generateDuration = (cartItem) => {
49
97
  const startDate = (0, import_dayjs.default)(`${cartItem.start_date} ${cartItem.start_time}`);
50
98
  const endDate = (0, import_dayjs.default)(`${cartItem.end_date} ${cartItem.end_time}`);
@@ -130,7 +178,9 @@ function normalizeSubmitProduct(product) {
130
178
  product_option_item: submitProduct.product_option_item || [],
131
179
  discount_list: submitProduct.discount_list || [],
132
180
  product_bundle: submitProduct.product_bundle || [],
133
- metadata: cleanMetadata
181
+ metadata: cleanMetadata,
182
+ // 出站兼容:后端仍消费 payment_price 字段,从 selling_price(券后单价)派生。
183
+ payment_price: submitProduct.selling_price
134
184
  };
135
185
  }
136
186
  var SUBMIT_BOOKING_METADATA_WHITELIST = [
@@ -172,6 +222,14 @@ function resolveTableOccupancyDuration(tempOrder) {
172
222
  }
173
223
  return DEFAULT_TABLE_OCCUPANCY_DURATION;
174
224
  }
225
+ function normalizeSubmitCollectPaxValue(value) {
226
+ const n = Number(value);
227
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) : 1;
228
+ }
229
+ function resolveSubmitCollectPax(tempOrder) {
230
+ var _a;
231
+ return normalizeSubmitCollectPaxValue((_a = tempOrder.metadata) == null ? void 0 : _a.collect_pax);
232
+ }
175
233
  function createDefaultTempOrder(params) {
176
234
  const summary = params.summary || (0, import_utils.createEmptySummary)();
177
235
  return {
@@ -248,7 +306,7 @@ function buildSubmitPayload(params) {
248
306
  duration: bookingDuration,
249
307
  metadata: {
250
308
  unique_identification_number: bookingUuid,
251
- collect_pax: 1
309
+ collect_pax: resolveSubmitCollectPax(tempOrder)
252
310
  },
253
311
  select_date: bookingStart.format("YYYY-MM-DD"),
254
312
  is_all: false,
@@ -316,6 +374,7 @@ function formatV1Product(products) {
316
374
  // Annotate the CommonJS export names for ESM import in node:
317
375
  0 && (module.exports = {
318
376
  buildSubmitPayload,
377
+ createDefaultOrderRulesHooks,
319
378
  createDefaultTempOrder,
320
379
  createEmptySummary,
321
380
  createUuidV4,
@@ -325,5 +384,7 @@ function formatV1Product(products) {
325
384
  getAllDiscountList,
326
385
  isTempOrder,
327
386
  mergeRelationForms,
328
- normalizeSubmitBooking
387
+ normalizeSubmitBooking,
388
+ normalizeSubmitCollectPaxValue,
389
+ resolveSubmitCollectPax
329
390
  });
@@ -2,9 +2,10 @@ export interface SalesSummaryProduct {
2
2
  product_id: number | null;
3
3
  product_variant_id: number;
4
4
  num: number;
5
+ /** 券后单品单价(订单域成交单价),由 OrderModule 维护。 */
5
6
  selling_price: string;
7
+ /** 券前单品单价(店铺售价)。 */
6
8
  original_price: string;
7
- payment_price: string;
8
9
  tax_fee: string;
9
10
  is_charge_tax?: number;
10
11
  product_option_item?: any[];
@@ -82,7 +82,7 @@ function getBundleUnitPrice(product, useOriginal = false) {
82
82
  }
83
83
  function getUnitPaymentTotal(product) {
84
84
  const variantPrice = getVariantPrice(product);
85
- const basePrice = variantPrice || toDecimal(product.selling_price || product.payment_price);
85
+ const basePrice = variantPrice || toDecimal(product.selling_price);
86
86
  return basePrice.plus(getOptionUnitPrice(product)).plus(getBundleUnitPrice(product));
87
87
  }
88
88
  function getUnitOriginalTotal(product) {
@@ -231,7 +231,7 @@ function calculateSingleItemTax(params) {
231
231
  function getMainProductPaymentTotal(product) {
232
232
  var _a, _b, _c, _d;
233
233
  const variantPrice = getVariantPrice(product);
234
- let total = variantPrice || toDecimal(((_a = product.metadata) == null ? void 0 : _a.main_product_selling_price) ?? product.selling_price ?? product.payment_price);
234
+ let total = variantPrice || toDecimal(((_a = product.metadata) == null ? void 0 : _a.main_product_selling_price) ?? product.selling_price);
235
235
  const mainDiscountList = ((_c = (_b = product._origin) == null ? void 0 : _b.product) == null ? void 0 : _c.discount_list) || ((_d = product._origin) == null ? void 0 : _d.discount_list) || [];
236
236
  const mainDiscountAmount = getDiscountListAmount(
237
237
  mainDiscountList.filter((d) => {
@@ -310,7 +310,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
310
310
  date: string;
311
311
  status: string;
312
312
  week: string;
313
- weekNum: 0 | 1 | 2 | 5 | 4 | 3 | 6;
313
+ weekNum: 0 | 2 | 1 | 5 | 4 | 3 | 6;
314
314
  }[]>;
315
315
  submitTimeSlot(timeSlots: TimeSliceItem): void;
316
316
  private getScheduleDataByIds;
@@ -357,7 +357,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
357
357
  };
358
358
  setOtherData(key: string, value: any): void;
359
359
  getOtherData(key: string): any;
360
- getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
360
+ getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
361
361
  /**
362
362
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
363
363
  *
@@ -89,4 +89,9 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
89
89
  }>;
90
90
  getProductList(): Promise<any>;
91
91
  getOtherParams(): Record<string, any>;
92
+ setOtherParams(params: Record<string, any>, { cover }?: {
93
+ cover?: boolean;
94
+ }): Promise<void>;
95
+ setEntryPaxNumber(number: number): Promise<void>;
96
+ getEntryPaxNumber(): number | null;
92
97
  }
@@ -38,6 +38,7 @@ var import_types = require("./types");
38
38
  var import_utils = require("./utils");
39
39
  var import_types2 = require("../BookingByStep/types");
40
40
  var import_ProductList = require("../../modules/ProductList");
41
+ var import_utils2 = require("../../modules/Order/utils");
41
42
  var import_dayjs = __toESM(require("dayjs"));
42
43
  var import_itemRule = require("../../model/strategy/adapter/itemRule");
43
44
  __reExport(ScanOrder_exports, require("./types"), module.exports);
@@ -60,7 +61,8 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
60
61
  cartValidation: {
61
62
  passed: null,
62
63
  failures: []
63
- }
64
+ },
65
+ entryPaxNumber: 1
64
66
  };
65
67
  this.otherParams = {};
66
68
  this.itemRuleEvaluator = new import_itemRule.ItemRuleEvaluator();
@@ -420,6 +422,11 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
420
422
  if (!this.store.order) {
421
423
  throw new Error("scanOrder解决方案需要 order 模块支持");
422
424
  }
425
+ const pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(this.store.entryPaxNumber);
426
+ this.store.entryPaxNumber = pax;
427
+ const tempOrderForSubmit = this.store.order.ensureTempOrder();
428
+ tempOrderForSubmit.metadata = { ...tempOrderForSubmit.metadata, collect_pax: pax };
429
+ this.store.order.persistTempOrder();
423
430
  const result = await this.store.order.submitTempOrder({
424
431
  cacheId: this.cacheId,
425
432
  platform: (_a = this.otherParams) == null ? void 0 : _a.platform,
@@ -698,22 +705,13 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
698
705
  (sourceItem == null ? void 0 : sourceItem.price) ?? (sourceItem == null ? void 0 : sourceItem.selling_price),
699
706
  "0.00"
700
707
  );
701
- const originalPrice = (0, import_utils.toPriceString)(
702
- (sourceItem == null ? void 0 : sourceItem.original_price) ?? (sourceItem == null ? void 0 : sourceItem.price) ?? sellingPrice,
703
- sellingPrice
704
- );
705
- const paymentPrice = (0, import_utils.toPriceString)(
706
- (sourceItem == null ? void 0 : sourceItem.payment_price) ?? (sourceItem == null ? void 0 : sourceItem.price) ?? sellingPrice,
707
- sellingPrice
708
- );
709
708
  tempOrder.products.push(
710
709
  (0, import_utils.normalizeOrderProduct)({
711
710
  product_id: productId,
712
711
  product_variant_id: productVariantId,
713
712
  num: targetQuantity,
714
713
  selling_price: sellingPrice,
715
- original_price: originalPrice,
716
- payment_price: paymentPrice,
714
+ original_price: sellingPrice,
717
715
  metadata: {
718
716
  item_rule_prefill: true,
719
717
  item_rule_id: prefillItem.ruleId
@@ -930,7 +928,8 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
930
928
  isExclusive,
931
929
  isFull,
932
930
  orderNumberPrefix,
933
- raw: config
931
+ raw: config,
932
+ table_form_record: (config == null ? void 0 : config.table_form_record) ?? null
934
933
  };
935
934
  }
936
935
  async fetchTableConfigByResourceId(resourceId) {
@@ -954,7 +953,7 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
954
953
  // 通过 resource_id + 店铺配置
955
954
  // hasOrderId 表示 url 上是否有 orderid,如果是的话,后续的流程会走加单
956
955
  async checkResourceAvailable(resourceId, hasOrderId) {
957
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
956
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
958
957
  this.logMethodStart("checkResourceAvailable", {
959
958
  resourceId
960
959
  });
@@ -992,6 +991,7 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
992
991
  relation_id: resourceState.relationId,
993
992
  table_form_id: resourceState.tableFormId,
994
993
  deskmate_valid: resourceState.deskmate_valid,
994
+ table_form_record: resourceState.table_form_record,
995
995
  policy: (_c = config == null ? void 0 : config.table_form_record) == null ? void 0 : _c.policy,
996
996
  partyroom_booking: (_d = config == null ? void 0 : config.table_form_record) == null ? void 0 : _d.partyroom_booking
997
997
  };
@@ -1004,8 +1004,11 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
1004
1004
  );
1005
1005
  if (reservationLinkIds.length === 0) {
1006
1006
  this.enabledReservationRuleProducts = [];
1007
- if (this.store.resource)
1007
+ if (this.store.resource) {
1008
1008
  delete this.store.resource.requestEntryPax;
1009
+ delete this.store.resource.requestPaxMin;
1010
+ delete this.store.resource.requestPaxMax;
1011
+ }
1009
1012
  } else {
1010
1013
  tempOrder.metadata = { ...tempOrder.metadata || {} };
1011
1014
  delete tempOrder.metadata.table_occupancy_duration;
@@ -1040,13 +1043,35 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
1040
1043
  availabilityInfo.requestEntryPax = 1;
1041
1044
  if (this.store.resource)
1042
1045
  this.store.resource.requestEntryPax = 1;
1046
+ delete availabilityInfo.requestPaxMin;
1047
+ delete availabilityInfo.requestPaxMax;
1048
+ if (this.store.resource) {
1049
+ delete this.store.resource.requestPaxMin;
1050
+ delete this.store.resource.requestPaxMax;
1051
+ }
1052
+ const paxBounds = (0, import_utils.pickFirstCustomCapacityPaxBounds)(loaded);
1053
+ if ((paxBounds == null ? void 0 : paxBounds.min) !== void 0) {
1054
+ availabilityInfo.requestPaxMin = paxBounds.min;
1055
+ if (this.store.resource)
1056
+ this.store.resource.requestPaxMin = paxBounds.min;
1057
+ }
1058
+ if ((paxBounds == null ? void 0 : paxBounds.max) !== void 0) {
1059
+ availabilityInfo.requestPaxMax = paxBounds.max;
1060
+ if (this.store.resource)
1061
+ this.store.resource.requestPaxMax = paxBounds.max;
1062
+ }
1043
1063
  } else if (this.store.resource) {
1044
1064
  delete this.store.resource.requestEntryPax;
1065
+ delete this.store.resource.requestPaxMin;
1066
+ delete this.store.resource.requestPaxMax;
1045
1067
  }
1046
1068
  } else {
1047
1069
  this.enabledReservationRuleProducts = [];
1048
- if (this.store.resource)
1070
+ if (this.store.resource) {
1049
1071
  delete this.store.resource.requestEntryPax;
1072
+ delete this.store.resource.requestPaxMin;
1073
+ delete this.store.resource.requestPaxMax;
1074
+ }
1050
1075
  void this.addScanOrderLog({
1051
1076
  level: "error",
1052
1077
  title: "[ScanOrder] enabled_reservation_rules product query failed",
@@ -1065,9 +1090,16 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
1065
1090
  tempOrder.order_id = resourceState.lastOrderId;
1066
1091
  }
1067
1092
  if (tempOrder.order_id) {
1068
- await ((_g = this.store.order) == null ? void 0 : _g.getOrderInfoByRemote(tempOrder.order_id));
1093
+ const res = await ((_g = this.store.order) == null ? void 0 : _g.getOrderInfoByRemote(tempOrder.order_id));
1094
+ const entryPaxNumber = (_k = (_j = (_i = (_h = res == null ? void 0 : res.data) == null ? void 0 : _h.bookings) == null ? void 0 : _i.find((p) => {
1095
+ var _a2;
1096
+ return (_a2 = p.metadata) == null ? void 0 : _a2.collect_pax;
1097
+ })) == null ? void 0 : _j.metadata) == null ? void 0 : _k.collect_pax;
1098
+ if (entryPaxNumber) {
1099
+ await this.setEntryPaxNumber(entryPaxNumber);
1100
+ }
1069
1101
  }
1070
- const lastOrderInfo = (_i = (_h = this.store.order) == null ? void 0 : _h.getLastOrderInfo) == null ? void 0 : _i.call(_h);
1102
+ const lastOrderInfo = (_m = (_l = this.store.order) == null ? void 0 : _l.getLastOrderInfo) == null ? void 0 : _m.call(_l);
1071
1103
  const historicalItems = hasOrderId && Array.isArray(lastOrderInfo == null ? void 0 : lastOrderInfo.products) ? lastOrderInfo.products.reduce((acc, p) => {
1072
1104
  if (typeof (p == null ? void 0 : p.product_id) !== "number")
1073
1105
  return acc;
@@ -1079,8 +1111,7 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
1079
1111
  return acc;
1080
1112
  }, []) : [];
1081
1113
  await this.setItemRuleRuntimeConfig({
1082
- pax: { total: 2, adult: 2, child: 0 },
1083
- serviceType: "dine-in",
1114
+ serviceType: (_n = this.otherParams) == null ? void 0 : _n.businessCode,
1084
1115
  submissionIndex: hasOrderId ? 1 : 0,
1085
1116
  historicalItems
1086
1117
  });
@@ -1150,6 +1181,32 @@ var ScanOrderImpl = class extends import_BaseModule.BaseModule {
1150
1181
  getOtherParams() {
1151
1182
  return this.otherParams;
1152
1183
  }
1184
+ async setOtherParams(params, { cover = false } = {}) {
1185
+ if (cover) {
1186
+ this.otherParams = params;
1187
+ } else {
1188
+ this.otherParams = { ...this.otherParams, ...params };
1189
+ }
1190
+ }
1191
+ async setEntryPaxNumber(number) {
1192
+ const pax = (0, import_utils2.normalizeSubmitCollectPaxValue)(number);
1193
+ this.store.entryPaxNumber = pax;
1194
+ if (this.store.order) {
1195
+ const t = this.store.order.ensureTempOrder();
1196
+ t.metadata = { ...t.metadata, collect_pax: pax };
1197
+ this.store.order.persistTempOrder();
1198
+ }
1199
+ this.itemRuleRuntimeConfig = {
1200
+ ...this.itemRuleRuntimeConfig,
1201
+ pax: { total: pax, adult: 0, child: 0 }
1202
+ };
1203
+ this.itemRulePrefillApplied = false;
1204
+ await this.refreshItemRuleQuantityLimits();
1205
+ await this.refreshCartValidationPassed();
1206
+ }
1207
+ getEntryPaxNumber() {
1208
+ return this.store.entryPaxNumber;
1209
+ }
1153
1210
  };
1154
1211
  // Annotate the CommonJS export names for ESM import in node:
1155
1212
  0 && (module.exports = {
@@ -36,9 +36,10 @@ export interface ScanOrderOrderProduct extends ScanOrderOrderProductIdentity {
36
36
  order_detail_id: number | null;
37
37
  num: number;
38
38
  product_option_item: any[];
39
+ /** 券后单品单价(= 订单域实际成交单价)。未应用券时等同 original_price。 */
39
40
  selling_price: string;
41
+ /** 券前单品单价(= 店铺售价),不承载后台划线价语义。 */
40
42
  original_price: string;
41
- payment_price: string;
42
43
  tax_fee: string;
43
44
  is_charge_tax: number;
44
45
  discount_list: any[];
@@ -47,6 +48,11 @@ export interface ScanOrderOrderProduct extends ScanOrderOrderProductIdentity {
47
48
  _origin?: Record<string, any>;
48
49
  }
49
50
  export interface ScanOrderSubmitProduct extends Omit<ScanOrderOrderProduct, '_origin' | 'identity_key'> {
51
+ /**
52
+ * 出站兼容字段:SDK 内部不再消费 payment_price,
53
+ * 仅在提交后端时由 selling_price 派生,保持原有后端契约。
54
+ */
55
+ payment_price: string;
50
56
  }
51
57
  export interface ScanOrderSummary {
52
58
  product_quantity: number;
@@ -133,6 +139,11 @@ export interface ScanOrderSubmitPayload extends Omit<ScanOrderTempOrder, 'platfo
133
139
  products: ScanOrderSubmitProduct[];
134
140
  }
135
141
  export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'resource_block' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
142
+ export interface ScanOrderTableFormRecord {
143
+ policy?: string | null;
144
+ partyroom_booking?: string | null;
145
+ [key: string]: any;
146
+ }
136
147
  export interface ScanOrderAvailabilityInfo {
137
148
  mode: ScanOrderAvailabilityMode;
138
149
  order_id?: string;
@@ -140,10 +151,16 @@ export interface ScanOrderAvailabilityInfo {
140
151
  table_form_id?: string;
141
152
  deskmate_valid?: boolean;
142
153
  errorTips?: string;
154
+ /** `/order/dining/table/config` 返回的 `table_form_record` 原样透出 */
155
+ table_form_record?: ScanOrderTableFormRecord | null;
143
156
  policy?: string | null;
144
157
  partyroom_booking?: string | null;
145
158
  /** 预约规则关联商品存在 custom 容量时,由 checkResourceAvailable 置为 1 */
146
159
  requestEntryPax?: number;
160
+ /** 首个 `capacity.type === 'custom'` 商品里 `custom[0]` 的 min(人数下限) */
161
+ requestPaxMin?: number;
162
+ /** 首个 `capacity.type === 'custom'` 商品里 `custom[0]` 的 max(人数上限) */
163
+ requestPaxMax?: number;
147
164
  }
148
165
  export interface ScanOrderTableSnackConfig {
149
166
  snack?: boolean | number | string;
@@ -153,9 +170,6 @@ export interface ScanOrderOrderNumberPrefixConfig {
153
170
  table_order?: string;
154
171
  pos?: string;
155
172
  }
156
- export interface ScanOrderTableFormRecord {
157
- policy?: string | null;
158
- }
159
173
  export interface ScanOrderTableConfigApiData {
160
174
  table_max_number?: number | string | null;
161
175
  order_count?: number | string | null;
@@ -186,7 +200,6 @@ export interface ScanOrderResourceState extends ScanOrderAvailabilityInfo {
186
200
  isFull: boolean;
187
201
  orderNumberPrefix: ScanOrderOrderNumberPrefixConfig[];
188
202
  raw: ScanOrderTableConfigApiData | null;
189
- table_form_record?: ScanOrderTableFormRecord | null;
190
203
  }
191
204
  export interface ScanOrderState {
192
205
  entryContext: ScanOrderEntryContext | null;
@@ -204,6 +217,7 @@ export interface ScanOrderState {
204
217
  passed: boolean | null;
205
218
  failures: QuantityCheckResult[];
206
219
  };
220
+ entryPaxNumber: number | null;
207
221
  }
208
222
  export interface ScanOrderLoggerRuntimeConfig {
209
223
  provider?: ScanOrderLoggerProviderType;
@@ -62,6 +62,12 @@ export declare function aggregateItemRuleLimit(matchedLimits: QuantityLimitResul
62
62
  remainingMax: number | undefined;
63
63
  exact: number | undefined;
64
64
  mustInclude: boolean;
65
+ validationMessage: string | undefined;
66
+ rawValidationMessage: string | Record<string, string> | undefined;
67
+ maxValidationMessage: string | undefined;
68
+ rawMaxValidationMessage: string | Record<string, string> | undefined;
69
+ minValidationMessage: string | undefined;
70
+ rawMinValidationMessage: string | Record<string, string> | undefined;
65
71
  } | null;
66
72
  export declare function buildItemRuleBusinessData(params: {
67
73
  tempOrder: ScanOrderTempOrder;
@@ -103,3 +109,11 @@ export declare function collectLinkProductIdsFromReservationRules(rules: unknown
103
109
  export declare function pickFirstDurationMinutesFromProducts(products: ProductData[]): number | undefined;
104
110
  /** 是否存在 capacity.type === 'custom' 的商品 */
105
111
  export declare function hasCustomCapacityProduct(products: ProductData[]): boolean;
112
+ /**
113
+ * 在商品列表中找到第一个 `capacity.type === 'custom'` 的商品,取其 `custom` 数组第一项的 min/max。
114
+ * 仅返回有限数字字段;若均无法解析则返回 `undefined`。
115
+ */
116
+ export declare function pickFirstCustomCapacityPaxBounds(products: ProductData[]): {
117
+ min?: number;
118
+ max?: number;
119
+ } | undefined;