@pisell/pisellos 0.0.508 → 0.0.509

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.
@@ -25,7 +25,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
25
25
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
26
26
  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); }
27
27
  import { BaseModule } from "../BaseModule";
28
- import { generateDuration, getAllDiscountList, mergeRelationForms, buildSubmitPayload, createDefaultTempOrder, createDefaultOrderRulesHooks, createEmptySummary, formatDateTime, formatV1Product, isTempOrder } from "./utils";
28
+ import { generateDuration, getAllDiscountList, mergeRelationForms, buildSubmitPayload, createDefaultTempOrder, createDefaultOrderRulesHooks, createEmptySummary, formatDateTime, filterProductsForScanOrderMore, formatV1Product, isTempOrder } from "./utils";
29
29
  import { isNormalProduct } from "../Product/utils";
30
30
  import dayjs from 'dayjs';
31
31
  import { getProductIdentityIndex, getSafeProductNum, isIdentityMatch, normalizeOrderProduct } from "../../solution/ScanOrder/utils";
@@ -737,7 +737,7 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
737
737
  _context10.next = 12;
738
738
  break;
739
739
  }
740
- products = formatV1Product(payload.products);
740
+ products = formatV1Product(filterProductsForScanOrderMore(payload.products));
741
741
  _context10.next = 8;
742
742
  return this.scanOrderMore({
743
743
  query: {
@@ -72,6 +72,8 @@ export declare function buildSubmitPayload(params: {
72
72
  type?: string;
73
73
  enhance?: SubmitPayloadEnhancer;
74
74
  }): ScanOrderSubmitPayload;
75
+ /** 加单(scanOrderMore)不应提交 booking 关联的虚拟规则商品行 */
76
+ export declare function filterProductsForScanOrderMore(products: ScanOrderSubmitProduct[]): ScanOrderSubmitProduct[];
75
77
  export declare function formatV1Product(products: ScanOrderSubmitProduct[]): {
76
78
  bundle: any[];
77
79
  key: number | null;
@@ -390,6 +390,14 @@ export function buildSubmitPayload(params) {
390
390
  now: now
391
391
  }) : payload;
392
392
  }
393
+
394
+ /** 加单(scanOrderMore)不应提交 booking 关联的虚拟规则商品行 */
395
+ export function filterProductsForScanOrderMore(products) {
396
+ return (products || []).filter(function (p) {
397
+ var _p$metadata;
398
+ return ((_p$metadata = p.metadata) === null || _p$metadata === void 0 ? void 0 : _p$metadata.is_rule) !== true;
399
+ });
400
+ }
393
401
  export function formatV1Product(products) {
394
402
  return products.map(function (product) {
395
403
  return {
@@ -30,7 +30,7 @@ import { OrderModule } from "../../modules/Order";
30
30
  import { AccountHooks } from "../../modules/Account/types";
31
31
  import { RegisterAndLoginHooks } from "../RegisterAndLogin/types";
32
32
  import Decimal from 'decimal.js';
33
- import { attachItemRuleLimitsToTopLevelProducts, buildProductKey, buildItemRuleBusinessData, collectLinkProductIdsFromReservationRules, computeResourceIsFull, createEmptySummary, getProductIdentityIndex, getSafeProductNum, hasCustomCapacityProduct, pickFirstCustomCapacityPaxBounds, normalizeEnabledItemRuleIds, normalizeOrderProduct, normalizeItemRuleStrategies, pickFirstDurationMinutesFromProducts, toNonNegativeInt, toPriceString, toBoolean, toPositiveString } from "./utils";
33
+ import { attachItemRuleLimitsToTopLevelProducts, buildProductKey, buildItemRuleBusinessData, collectLinkProductIdsFromReservationRules, computeResourceIsFull, createEmptySummary, getProductIdentityIndex, getSafeProductNum, hasCustomCapacityProduct, pickFirstCustomCapacityDimensionId, pickFirstCustomCapacityPaxBounds, normalizeEnabledItemRuleIds, normalizeOrderProduct, normalizeItemRuleStrategies, pickFirstDurationMinutesFromProducts, toNonNegativeInt, toPriceString, toBoolean, toPositiveString } from "./utils";
34
34
  import { createModule } from "../BookingByStep/types";
35
35
  import { ProductList } from "../../modules/ProductList";
36
36
  import { ScheduleModule } from "../../modules/Schedule";
@@ -1195,6 +1195,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1195
1195
  }, {
1196
1196
  key: "buildSubmitPayloadEnhancer",
1197
1197
  value: function buildSubmitPayloadEnhancer() {
1198
+ var _this5 = this;
1198
1199
  var ruleProduct = this.enabledReservationRuleProducts[0];
1199
1200
  var resourceState = this.store.resource;
1200
1201
  var resourceSelectType = resourceState === null || resourceState === void 0 ? void 0 : resourceState.resourceSelectType;
@@ -1211,7 +1212,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1211
1212
  return 1;
1212
1213
  };
1213
1214
  return function (payload, _ref3) {
1214
- var _tempOrder$resource_i, _ref4, _pickOriginal, _resourceState$table_2, _resourceState$relati;
1215
+ var _tempOrder$resource_i, _ref4, _pickOriginal, _resourceState$table_2, _resourceState$relati, _tempOrder$metadata, _pickFirstCustomCapac;
1215
1216
  var bookingUuid = _ref3.bookingUuid,
1216
1217
  tempOrder = _ref3.tempOrder;
1217
1218
  var resourceId = (_tempOrder$resource_i = tempOrder.resource_id) !== null && _tempOrder$resource_i !== void 0 ? _tempOrder$resource_i : resourceState === null || resourceState === void 0 ? void 0 : resourceState.relationId;
@@ -1234,7 +1235,11 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1234
1235
  metadata: {}
1235
1236
  } : undefined;
1236
1237
  var ruleProductUid = ruleProduct ? createUuidV4() : undefined;
1237
- var bookingCapacityValue = resolveResourceCapacity();
1238
+ // 默认 resolveResourceCapacity(single 为桌台容量,其余多为 1);有 collect_pax 时 value 优先用人数
1239
+ var rawCollectPax = (_tempOrder$metadata = tempOrder.metadata) === null || _tempOrder$metadata === void 0 ? void 0 : _tempOrder$metadata.collect_pax;
1240
+ var hasCollectPaxForCapacity = rawCollectPax !== null && rawCollectPax !== undefined && rawCollectPax !== '';
1241
+ var bookingCapacityValue = hasCollectPaxForCapacity ? normalizeSubmitCollectPaxValue(rawCollectPax) : resolveResourceCapacity();
1242
+ var bookingCapacityDimensionId = (_pickFirstCustomCapac = pickFirstCustomCapacityDimensionId(_this5.enabledReservationRuleProducts)) !== null && _pickFirstCustomCapac !== void 0 ? _pickFirstCustomCapac : 0;
1238
1243
  var nextBookings = (payload.bookings || []).map(function (booking, idx) {
1239
1244
  return _objectSpread(_objectSpread(_objectSpread({}, booking), {}, {
1240
1245
  appointment_status: 'started',
@@ -1242,7 +1247,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1242
1247
  resource_select_type: resourceSelectType
1243
1248
  } : {}), resourceSelectType ? {
1244
1249
  capacity: [{
1245
- id: 0,
1250
+ id: bookingCapacityDimensionId,
1246
1251
  value: bookingCapacityValue,
1247
1252
  name: ''
1248
1253
  }]
@@ -1254,7 +1259,8 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1254
1259
  } : {});
1255
1260
  });
1256
1261
  var nextProducts = _toConsumableArray(payload.products || []);
1257
- if (ruleProduct && ruleProductUid) {
1262
+ // 加餐(已有 order_id)走 scanOrderMore,原单已含 booking 规则行,勿再追加虚拟规则商品
1263
+ if (ruleProduct && ruleProductUid && !tempOrder.order_id) {
1258
1264
  var _ruleProduct$price, _ref5, _ruleProduct$original, _ruleProduct$is_gst;
1259
1265
  var sellingPrice = String((_ruleProduct$price = ruleProduct.price) !== null && _ruleProduct$price !== void 0 ? _ruleProduct$price : '0.00');
1260
1266
  var originalPrice = String((_ref5 = (_ruleProduct$original = ruleProduct.original_price) !== null && _ruleProduct$original !== void 0 ? _ruleProduct$original : ruleProduct.price) !== null && _ref5 !== void 0 ? _ref5 : '0.00');
@@ -1719,7 +1725,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1719
1725
  key: "ensureItemRuleConfigsLoaded",
1720
1726
  value: function () {
1721
1727
  var _ensureItemRuleConfigsLoaded = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee25() {
1722
- var _this5 = this;
1728
+ var _this6 = this;
1723
1729
  var loadedConfigs;
1724
1730
  return _regeneratorRuntime().wrap(function _callee25$(_context25) {
1725
1731
  while (1) switch (_context25.prev = _context25.next) {
@@ -1741,19 +1747,19 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1741
1747
  return _regeneratorRuntime().wrap(function _callee24$(_context24) {
1742
1748
  while (1) switch (_context24.prev = _context24.next) {
1743
1749
  case 0:
1744
- runtimeConfig = _this5.getItemRuleRuntimeConfig();
1750
+ runtimeConfig = _this6.getItemRuleRuntimeConfig();
1745
1751
  staticConfigs = normalizeItemRuleStrategies(runtimeConfig.strategyConfigs);
1746
1752
  if (!(staticConfigs.length > 0)) {
1747
1753
  _context24.next = 6;
1748
1754
  break;
1749
1755
  }
1750
- _this5.itemRuleConfigs = staticConfigs;
1751
- _this5.itemRuleEvaluator.setStrategyConfigs(staticConfigs);
1752
- return _context24.abrupt("return", _this5.itemRuleConfigs);
1756
+ _this6.itemRuleConfigs = staticConfigs;
1757
+ _this6.itemRuleEvaluator.setStrategyConfigs(staticConfigs);
1758
+ return _context24.abrupt("return", _this6.itemRuleConfigs);
1753
1759
  case 6:
1754
- _this5.itemRuleConfigs = [];
1755
- _this5.itemRuleEvaluator.setStrategyConfigs([]);
1756
- return _context24.abrupt("return", _this5.itemRuleConfigs);
1760
+ _this6.itemRuleConfigs = [];
1761
+ _this6.itemRuleEvaluator.setStrategyConfigs([]);
1762
+ return _context24.abrupt("return", _this6.itemRuleConfigs);
1757
1763
  case 9:
1758
1764
  case "end":
1759
1765
  return _context24.stop();
@@ -2207,7 +2213,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2207
2213
  var tableFormId = toPositiveString(detail === null || detail === void 0 ? void 0 : detail.form_id);
2208
2214
  var formRecord = (_detail$form_record = detail === null || detail === void 0 ? void 0 : detail.form_record) !== null && _detail$form_record !== void 0 ? _detail$form_record : null;
2209
2215
  // 是否允许加餐
2210
- var allowSnack = ((_this$otherParams8 = this.otherParams) === null || _this$otherParams8 === void 0 || (_this$otherParams8 = _this$otherParams8.dineInConfig) === null || _this$otherParams8 === void 0 ? void 0 : _this$otherParams8['workflow.allow_add_items']) || false;
2216
+ var allowSnack = ((_this$otherParams8 = this.otherParams) === null || _this$otherParams8 === void 0 || (_this$otherParams8 = _this$otherParams8.dineInConfig) === null || _this$otherParams8 === void 0 ? void 0 : _this$otherParams8['sale.allow_add_items']) || false;
2211
2217
  // 开启同桌验证 - 本期没有这个配置,默认关掉
2212
2218
  var deskmateValid = false;
2213
2219
  var isExclusive = resourceSelectType === 'single';
@@ -2723,11 +2729,18 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2723
2729
  return _setOtherParams.apply(this, arguments);
2724
2730
  }
2725
2731
  return setOtherParams;
2726
- }() // ─── UI 状态缓存(按 cacheId 分桶,sessionStorage) ───
2732
+ }() // ─── UI 状态缓存(按 cacheId 分桶,localStorage) ───
2727
2733
  //
2728
2734
  // 用于物料层持久化 UI 层面的轻量状态(如当前步骤、gate 标记、登录回跳意图等)。
2729
2735
  // 桶键:pisell.scanOrder.uiState:<cacheId>;内部以 JSON object 形式存储多个字段。
2730
2736
  // 无 cacheId 时所有方法自动降级为 no-op,上层不用判空。
2737
+ //
2738
+ // 之所以用 localStorage 而不是 sessionStorage:
2739
+ // 1. 与 Order 模块 openCache 下的 tempOrder 同栈,购物车在 / UIState 在,行为对齐;
2740
+ // 2. pisell1.login 整页 OAuth 跳转在 H5 壳 / iOS Safari 场景下可能丢 sessionStorage,
2741
+ // 导致登录回跳后 gate 标记失效、pax 弹窗重开、落点错误;localStorage 稳定不受影响。
2742
+ // 3. 失效由上层显式控制:提交成功 clearStepCache / entryContext 不一致 clearUIState /
2743
+ // pendingStep 登录回调 deleteUIState,足够约束生命周期。
2731
2744
  }, {
2732
2745
  key: "getUIStateBucketKey",
2733
2746
  value: function getUIStateBucketKey() {
@@ -2739,9 +2752,9 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2739
2752
  value: function readUIStateBucket() {
2740
2753
  var _this$window;
2741
2754
  var key = this.getUIStateBucketKey();
2742
- if (!key || !((_this$window = this.window) !== null && _this$window !== void 0 && _this$window.sessionStorage)) return {};
2755
+ if (!key || !((_this$window = this.window) !== null && _this$window !== void 0 && _this$window.localStorage)) return {};
2743
2756
  try {
2744
- var raw = this.window.sessionStorage.getItem(key) || '{}';
2757
+ var raw = this.window.localStorage.getItem(key) || '{}';
2745
2758
  var parsed = JSON.parse(raw);
2746
2759
  return parsed && _typeof(parsed) === 'object' ? parsed : {};
2747
2760
  } catch (_unused) {
@@ -2753,9 +2766,9 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2753
2766
  value: function writeUIStateBucket(bucket) {
2754
2767
  var _this$window2;
2755
2768
  var key = this.getUIStateBucketKey();
2756
- if (!key || !((_this$window2 = this.window) !== null && _this$window2 !== void 0 && _this$window2.sessionStorage)) return;
2769
+ if (!key || !((_this$window2 = this.window) !== null && _this$window2 !== void 0 && _this$window2.localStorage)) return;
2757
2770
  try {
2758
- this.window.sessionStorage.setItem(key, JSON.stringify(bucket));
2771
+ this.window.localStorage.setItem(key, JSON.stringify(bucket));
2759
2772
  } catch (error) {
2760
2773
  console.warn('[ScanOrder] writeUIStateBucket failed', error);
2761
2774
  }
@@ -2792,9 +2805,9 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2792
2805
  value: function clearUIState() {
2793
2806
  var _this$window3;
2794
2807
  var key = this.getUIStateBucketKey();
2795
- if (!key || !((_this$window3 = this.window) !== null && _this$window3 !== void 0 && _this$window3.sessionStorage)) return;
2808
+ if (!key || !((_this$window3 = this.window) !== null && _this$window3 !== void 0 && _this$window3.localStorage)) return;
2796
2809
  try {
2797
- this.window.sessionStorage.removeItem(key);
2810
+ this.window.localStorage.removeItem(key);
2798
2811
  } catch (error) {
2799
2812
  console.warn('[ScanOrder] clearUIState failed', error);
2800
2813
  }
@@ -129,3 +129,8 @@ export declare function pickFirstCustomCapacityPaxBounds(products: ProductData[]
129
129
  min?: number;
130
130
  max?: number;
131
131
  } | undefined;
132
+ /**
133
+ * 第一个 `capacity.type === 'custom'` 的商品,取其 `custom[0].id`(提交 booking metadata.capacity 维度 id)。
134
+ * 无匹配时返回 `undefined`,调用方应回退为 `0`。
135
+ */
136
+ export declare function pickFirstCustomCapacityDimensionId(products: ProductData[]): string | number | undefined;
@@ -580,4 +580,36 @@ export function pickFirstCustomCapacityPaxBounds(products) {
580
580
  _iterator9.f();
581
581
  }
582
582
  return undefined;
583
+ }
584
+
585
+ /**
586
+ * 第一个 `capacity.type === 'custom'` 的商品,取其 `custom[0].id`(提交 booking metadata.capacity 维度 id)。
587
+ * 无匹配时返回 `undefined`,调用方应回退为 `0`。
588
+ */
589
+ export function pickFirstCustomCapacityDimensionId(products) {
590
+ var _iterator10 = _createForOfIteratorHelper(products),
591
+ _step10;
592
+ try {
593
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
594
+ var p = _step10.value;
595
+ var cap = p === null || p === void 0 ? void 0 : p.capacity;
596
+ if (!cap || cap.type !== 'custom') continue;
597
+ if (!Array.isArray(cap.custom) || cap.custom.length === 0) continue;
598
+ var row = cap.custom[0];
599
+ if (!row || _typeof(row) !== 'object') continue;
600
+ var id = row.id;
601
+ if (id === null || id === undefined || id === '') continue;
602
+ if (typeof id === 'number' && Number.isFinite(id)) return id;
603
+ if (typeof id === 'string') {
604
+ var trimmed = id.trim();
605
+ if (!trimmed) continue;
606
+ return trimmed;
607
+ }
608
+ }
609
+ } catch (err) {
610
+ _iterator10.e(err);
611
+ } finally {
612
+ _iterator10.f();
613
+ }
614
+ return undefined;
583
615
  }
@@ -1,49 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
-
29
- // src/model/strategy/adapter/promotion/index.ts
30
- var promotion_exports = {};
31
- __export(promotion_exports, {
32
- BUY_X_GET_Y_FREE_STRATEGY: () => import_examples.BUY_X_GET_Y_FREE_STRATEGY,
33
- PromotionAdapter: () => import_adapter.PromotionAdapter,
34
- PromotionEvaluator: () => import_evaluator.PromotionEvaluator,
35
- X_ITEMS_FOR_Y_PRICE_STRATEGY: () => import_examples.X_ITEMS_FOR_Y_PRICE_STRATEGY,
36
- default: () => import_adapter2.default
37
- });
38
- module.exports = __toCommonJS(promotion_exports);
39
- var import_evaluator = require("./evaluator");
40
- var import_adapter = require("./adapter");
41
- var import_adapter2 = __toESM(require("./adapter"));
42
- var import_examples = require("./examples");
43
- // Annotate the CommonJS export names for ESM import in node:
44
- 0 && (module.exports = {
45
- BUY_X_GET_Y_FREE_STRATEGY,
46
- PromotionAdapter,
47
- PromotionEvaluator,
48
- X_ITEMS_FOR_Y_PRICE_STRATEGY
49
- });
@@ -477,7 +477,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
477
477
  });
478
478
  let result;
479
479
  if (tempOrder.order_id) {
480
- const products = (0, import_utils.formatV1Product)(payload.products);
480
+ let products = (0, import_utils.formatV1Product)(
481
+ (0, import_utils.filterProductsForScanOrderMore)(payload.products)
482
+ );
481
483
  const moreResult = await this.scanOrderMore({
482
484
  query: {
483
485
  order_id: tempOrder.order_id,
@@ -72,6 +72,8 @@ export declare function buildSubmitPayload(params: {
72
72
  type?: string;
73
73
  enhance?: SubmitPayloadEnhancer;
74
74
  }): ScanOrderSubmitPayload;
75
+ /** 加单(scanOrderMore)不应提交 booking 关联的虚拟规则商品行 */
76
+ export declare function filterProductsForScanOrderMore(products: ScanOrderSubmitProduct[]): ScanOrderSubmitProduct[];
75
77
  export declare function formatV1Product(products: ScanOrderSubmitProduct[]): {
76
78
  bundle: any[];
77
79
  key: number | null;
@@ -34,6 +34,7 @@ __export(utils_exports, {
34
34
  createDefaultTempOrder: () => createDefaultTempOrder,
35
35
  createEmptySummary: () => import_utils2.createEmptySummary,
36
36
  createUuidV4: () => createUuidV4,
37
+ filterProductsForScanOrderMore: () => filterProductsForScanOrderMore,
37
38
  formatDateTime: () => formatDateTime,
38
39
  formatV1Product: () => formatV1Product,
39
40
  generateDuration: () => generateDuration,
@@ -366,6 +367,12 @@ function buildSubmitPayload(params) {
366
367
  };
367
368
  return enhance ? enhance(payload, { tempOrder, bookingUuid, now }) : payload;
368
369
  }
370
+ function filterProductsForScanOrderMore(products) {
371
+ return (products || []).filter((p) => {
372
+ var _a;
373
+ return ((_a = p.metadata) == null ? void 0 : _a.is_rule) !== true;
374
+ });
375
+ }
369
376
  function formatV1Product(products) {
370
377
  return products.map((product) => {
371
378
  return {
@@ -388,6 +395,7 @@ function formatV1Product(products) {
388
395
  createDefaultTempOrder,
389
396
  createEmptySummary,
390
397
  createUuidV4,
398
+ filterProductsForScanOrderMore,
391
399
  formatDateTime,
392
400
  formatV1Product,
393
401
  generateDuration,
@@ -741,7 +741,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
741
741
  return 1;
742
742
  };
743
743
  return (payload, { bookingUuid, tempOrder }) => {
744
- var _a;
744
+ var _a, _b;
745
745
  const resourceId = tempOrder.resource_id ?? (resourceState == null ? void 0 : resourceState.relationId);
746
746
  const pickOriginal = (value) => {
747
747
  if (value && typeof value === "object" && !Array.isArray(value)) {
@@ -762,20 +762,31 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
762
762
  metadata: {}
763
763
  } : void 0;
764
764
  const ruleProductUid = ruleProduct ? (0, import_utils2.createUuidV4)() : void 0;
765
- const bookingCapacityValue = resolveResourceCapacity();
765
+ const rawCollectPax = (_b = tempOrder.metadata) == null ? void 0 : _b.collect_pax;
766
+ const hasCollectPaxForCapacity = rawCollectPax !== null && rawCollectPax !== void 0 && rawCollectPax !== "";
767
+ const bookingCapacityValue = hasCollectPaxForCapacity ? (0, import_utils2.normalizeSubmitCollectPaxValue)(rawCollectPax) : resolveResourceCapacity();
768
+ const bookingCapacityDimensionId = (0, import_utils.pickFirstCustomCapacityDimensionId)(this.enabledReservationRuleProducts) ?? 0;
766
769
  const nextBookings = (payload.bookings || []).map((booking, idx) => ({
767
770
  ...booking,
768
771
  appointment_status: "started",
769
772
  metadata: {
770
773
  ...booking.metadata || {},
771
774
  ...resourceSelectType ? { resource_select_type: resourceSelectType } : {},
772
- ...resourceSelectType ? { capacity: [{ id: 0, value: bookingCapacityValue, name: "" }] } : {}
775
+ ...resourceSelectType ? {
776
+ capacity: [
777
+ {
778
+ id: bookingCapacityDimensionId,
779
+ value: bookingCapacityValue,
780
+ name: ""
781
+ }
782
+ ]
783
+ } : {}
773
784
  },
774
785
  ...idx === 0 && resourceEntry ? { resources: [resourceEntry] } : {},
775
786
  ...idx === 0 && ruleProductUid ? { product_uid: ruleProductUid } : {}
776
787
  }));
777
788
  const nextProducts = [...payload.products || []];
778
- if (ruleProduct && ruleProductUid) {
789
+ if (ruleProduct && ruleProductUid && !tempOrder.order_id) {
779
790
  const sellingPrice = String(ruleProduct.price ?? "0.00");
780
791
  const originalPrice = String(
781
792
  ruleProduct.original_price ?? ruleProduct.price ?? "0.00"
@@ -1261,7 +1272,7 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1261
1272
  const relationId = (0, import_utils.toPositiveString)(detail == null ? void 0 : detail.form_record_id);
1262
1273
  const tableFormId = (0, import_utils.toPositiveString)(detail == null ? void 0 : detail.form_id);
1263
1274
  const formRecord = (detail == null ? void 0 : detail.form_record) ?? null;
1264
- const allowSnack = ((_b = (_a = this.otherParams) == null ? void 0 : _a.dineInConfig) == null ? void 0 : _b["workflow.allow_add_items"]) || false;
1275
+ const allowSnack = ((_b = (_a = this.otherParams) == null ? void 0 : _a.dineInConfig) == null ? void 0 : _b["sale.allow_add_items"]) || false;
1265
1276
  const deskmateValid = false;
1266
1277
  const isExclusive = resourceSelectType === "single";
1267
1278
  const isFull = (0, import_utils.computeResourceIsFull)({
@@ -1620,10 +1631,10 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1620
1631
  readUIStateBucket() {
1621
1632
  var _a;
1622
1633
  const key = this.getUIStateBucketKey();
1623
- if (!key || !((_a = this.window) == null ? void 0 : _a.sessionStorage))
1634
+ if (!key || !((_a = this.window) == null ? void 0 : _a.localStorage))
1624
1635
  return {};
1625
1636
  try {
1626
- const raw = this.window.sessionStorage.getItem(key) || "{}";
1637
+ const raw = this.window.localStorage.getItem(key) || "{}";
1627
1638
  const parsed = JSON.parse(raw);
1628
1639
  return parsed && typeof parsed === "object" ? parsed : {};
1629
1640
  } catch {
@@ -1633,10 +1644,10 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1633
1644
  writeUIStateBucket(bucket) {
1634
1645
  var _a;
1635
1646
  const key = this.getUIStateBucketKey();
1636
- if (!key || !((_a = this.window) == null ? void 0 : _a.sessionStorage))
1647
+ if (!key || !((_a = this.window) == null ? void 0 : _a.localStorage))
1637
1648
  return;
1638
1649
  try {
1639
- this.window.sessionStorage.setItem(key, JSON.stringify(bucket));
1650
+ this.window.localStorage.setItem(key, JSON.stringify(bucket));
1640
1651
  } catch (error) {
1641
1652
  console.warn("[ScanOrder] writeUIStateBucket failed", error);
1642
1653
  }
@@ -1667,10 +1678,10 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1667
1678
  clearUIState() {
1668
1679
  var _a;
1669
1680
  const key = this.getUIStateBucketKey();
1670
- if (!key || !((_a = this.window) == null ? void 0 : _a.sessionStorage))
1681
+ if (!key || !((_a = this.window) == null ? void 0 : _a.localStorage))
1671
1682
  return;
1672
1683
  try {
1673
- this.window.sessionStorage.removeItem(key);
1684
+ this.window.localStorage.removeItem(key);
1674
1685
  } catch (error) {
1675
1686
  console.warn("[ScanOrder] clearUIState failed", error);
1676
1687
  }
@@ -1726,11 +1737,18 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1726
1737
  };
1727
1738
  var ScanOrderImpl = _ScanOrderImpl;
1728
1739
  ScanOrderImpl.PISELL1_LOGIN_SUCCESS = "pisell1.login.success";
1729
- // ─── UI 状态缓存(按 cacheId 分桶,sessionStorage) ───
1740
+ // ─── UI 状态缓存(按 cacheId 分桶,localStorage) ───
1730
1741
  //
1731
1742
  // 用于物料层持久化 UI 层面的轻量状态(如当前步骤、gate 标记、登录回跳意图等)。
1732
1743
  // 桶键:pisell.scanOrder.uiState:<cacheId>;内部以 JSON object 形式存储多个字段。
1733
1744
  // 无 cacheId 时所有方法自动降级为 no-op,上层不用判空。
1745
+ //
1746
+ // 之所以用 localStorage 而不是 sessionStorage:
1747
+ // 1. 与 Order 模块 openCache 下的 tempOrder 同栈,购物车在 / UIState 在,行为对齐;
1748
+ // 2. pisell1.login 整页 OAuth 跳转在 H5 壳 / iOS Safari 场景下可能丢 sessionStorage,
1749
+ // 导致登录回跳后 gate 标记失效、pax 弹窗重开、落点错误;localStorage 稳定不受影响。
1750
+ // 3. 失效由上层显式控制:提交成功 clearStepCache / entryContext 不一致 clearUIState /
1751
+ // pendingStep 登录回调 deleteUIState,足够约束生命周期。
1734
1752
  ScanOrderImpl.UI_STATE_KEY_PREFIX = "pisell.scanOrder.uiState:";
1735
1753
  // Annotate the CommonJS export names for ESM import in node:
1736
1754
  0 && (module.exports = {
@@ -129,3 +129,8 @@ export declare function pickFirstCustomCapacityPaxBounds(products: ProductData[]
129
129
  min?: number;
130
130
  max?: number;
131
131
  } | undefined;
132
+ /**
133
+ * 第一个 `capacity.type === 'custom'` 的商品,取其 `custom[0].id`(提交 booking metadata.capacity 维度 id)。
134
+ * 无匹配时返回 `undefined`,调用方应回退为 `0`。
135
+ */
136
+ export declare function pickFirstCustomCapacityDimensionId(products: ProductData[]): string | number | undefined;
@@ -47,6 +47,7 @@ __export(utils_exports, {
47
47
  normalizeEnabledItemRuleIds: () => normalizeEnabledItemRuleIds,
48
48
  normalizeItemRuleStrategies: () => normalizeItemRuleStrategies,
49
49
  normalizeOrderProduct: () => normalizeOrderProduct,
50
+ pickFirstCustomCapacityDimensionId: () => pickFirstCustomCapacityDimensionId,
50
51
  pickFirstCustomCapacityPaxBounds: () => pickFirstCustomCapacityPaxBounds,
51
52
  pickFirstDurationMinutesFromProducts: () => pickFirstDurationMinutesFromProducts,
52
53
  resolveSkuMatchedQuantityLimits: () => resolveSkuMatchedQuantityLimits,
@@ -474,6 +475,30 @@ function pickFirstCustomCapacityPaxBounds(products) {
474
475
  }
475
476
  return void 0;
476
477
  }
478
+ function pickFirstCustomCapacityDimensionId(products) {
479
+ for (const p of products) {
480
+ const cap = p == null ? void 0 : p.capacity;
481
+ if (!cap || cap.type !== "custom")
482
+ continue;
483
+ if (!Array.isArray(cap.custom) || cap.custom.length === 0)
484
+ continue;
485
+ const row = cap.custom[0];
486
+ if (!row || typeof row !== "object")
487
+ continue;
488
+ const id = row.id;
489
+ if (id === null || id === void 0 || id === "")
490
+ continue;
491
+ if (typeof id === "number" && Number.isFinite(id))
492
+ return id;
493
+ if (typeof id === "string") {
494
+ const trimmed = id.trim();
495
+ if (!trimmed)
496
+ continue;
497
+ return trimmed;
498
+ }
499
+ }
500
+ return void 0;
501
+ }
477
502
  // Annotate the CommonJS export names for ESM import in node:
478
503
  0 && (module.exports = {
479
504
  aggregateItemRuleLimit,
@@ -494,6 +519,7 @@ function pickFirstCustomCapacityPaxBounds(products) {
494
519
  normalizeEnabledItemRuleIds,
495
520
  normalizeItemRuleStrategies,
496
521
  normalizeOrderProduct,
522
+ pickFirstCustomCapacityDimensionId,
497
523
  pickFirstCustomCapacityPaxBounds,
498
524
  pickFirstDurationMinutesFromProducts,
499
525
  resolveSkuMatchedQuantityLimits,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.0.508",
4
+ "version": "0.0.509",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",