@pisell/pisellos 0.0.503 → 0.0.505

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.
@@ -141,10 +141,11 @@ export interface ScanOrderSubmitPayload extends Omit<ScanOrderTempOrder, 'platfo
141
141
  }>;
142
142
  products: ScanOrderSubmitProduct[];
143
143
  }
144
- export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_block' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
144
+ export type ScanOrderAvailabilityMode = 'idle' | 'shop_closed' | 'submit_disabled' | 'resource_busy' | 'additional_order_with_code' | 'additional_order';
145
145
  export interface ScanOrderTableFormRecord {
146
146
  policy?: string | null;
147
147
  partyroom_booking?: string | null;
148
+ capacity?: number | string | null;
148
149
  [key: string]: any;
149
150
  }
150
151
  export interface ScanOrderAvailabilityInfo {
@@ -156,7 +157,7 @@ export interface ScanOrderAvailabilityInfo {
156
157
  errorTips?: string;
157
158
  /** 透传 `availability.closed_behavior`,便于 UI 识别拦截类型(如 show_menu_disabled) */
158
159
  closed_behavior?: string;
159
- /** `/order/dining/table/config` 返回的 `table_form_record` 原样透出 */
160
+ /** `/order/resource/occupy-detail` 返回的 `form_record` 原样透出 */
160
161
  table_form_record?: ScanOrderTableFormRecord | null;
161
162
  policy?: string | null;
162
163
  partyroom_booking?: string | null;
@@ -167,34 +168,36 @@ export interface ScanOrderAvailabilityInfo {
167
168
  /** 首个 `capacity.type === 'custom'` 商品里 `custom[0]` 的 max(人数上限) */
168
169
  requestPaxMax?: number;
169
170
  }
170
- export interface ScanOrderTableSnackConfig {
171
- snack?: boolean | number | string;
172
- table_validate?: boolean | number | string;
171
+ /** `resource_capacity[i].capacity_list[j]` */
172
+ export interface ScanOrderResourceCapacitySlot {
173
+ start_at?: string;
174
+ end_at?: string;
175
+ pax?: number | string;
173
176
  }
174
- export interface ScanOrderOrderNumberPrefixConfig {
175
- table_order?: string;
176
- pos?: string;
177
+ export interface ScanOrderResourceCapacity {
178
+ capacity?: number | string;
179
+ capacity_list?: ScanOrderResourceCapacitySlot[];
177
180
  }
178
- export interface ScanOrderTableConfigApiData {
179
- table_max_number?: number | string | null;
180
- order_count?: number | string | null;
181
+ /** `/order/resource/occupy-detail` 单条 `occupy_details[i]` */
182
+ export interface ScanOrderResourceOccupyDetail {
183
+ form_record_id?: number | string | null;
184
+ form_id?: number | string | null;
181
185
  order_id?: number | string | null;
182
186
  last_order_id?: number | string | null;
183
- relation_id?: number | string | null;
184
- table_form_id?: number | string | null;
185
- table_snack?: ScanOrderTableSnackConfig[] | null;
186
- order_number_prefix?: ScanOrderOrderNumberPrefixConfig[] | null;
187
+ resource_capacity?: ScanOrderResourceCapacity[] | null;
188
+ form_record?: ScanOrderTableFormRecord | null;
187
189
  [key: string]: any;
188
190
  }
189
- export interface ScanOrderTableConfigApiResponse {
191
+ export interface ScanOrderResourceOccupyDetailApiResponse {
190
192
  status?: boolean;
191
193
  code?: number;
192
194
  message?: string;
193
- data?: ScanOrderTableConfigApiData | null;
195
+ data?: {
196
+ occupy_details?: ScanOrderResourceOccupyDetail[] | null;
197
+ } | null;
194
198
  }
199
+ export type ScanOrderResourceSelectType = 'single' | 'multiple' | 'capacity';
195
200
  export interface ScanOrderResourceState extends ScanOrderAvailabilityInfo {
196
- tableMaxNumber: number;
197
- orderCount: number;
198
201
  relationId?: string;
199
202
  tableFormId?: string;
200
203
  currentOrderId?: string;
@@ -203,13 +206,14 @@ export interface ScanOrderResourceState extends ScanOrderAvailabilityInfo {
203
206
  deskmateValid: boolean;
204
207
  isExclusive: boolean;
205
208
  isFull: boolean;
206
- orderNumberPrefix: ScanOrderOrderNumberPrefixConfig[];
207
- raw: ScanOrderTableConfigApiData | null;
209
+ /** 来自首个预约规则商品 product_resource.resources 中与 form_id 匹配的 resource type */
210
+ resourceSelectType?: ScanOrderResourceSelectType;
211
+ raw: ScanOrderResourceOccupyDetail | null;
208
212
  }
209
213
  export interface ScanOrderState {
210
214
  entryContext: ScanOrderEntryContext | null;
211
215
  status: ScanOrderStatus;
212
- config: ScanOrderTableConfigApiData | null;
216
+ config: Record<string, any> | null;
213
217
  resource: ScanOrderResourceState | null;
214
218
  flow: Record<string, any>;
215
219
  error: string | null;
@@ -13,4 +13,8 @@ export var ScanOrderHooks = /*#__PURE__*/function (ScanOrderHooks) {
13
13
  /**
14
14
  * ScanOrder 临时订单(runtime-clean 版本)
15
15
  * 只保留运行时字段,不包含任何 __comment 字段
16
- */
16
+ */
17
+
18
+ /** `resource_capacity[i].capacity_list[j]` */
19
+
20
+ /** `/order/resource/occupy-detail` 单条 `occupy_details[i]` */
@@ -1,4 +1,4 @@
1
- import { ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderSummary, ScanOrderTempOrder } from './types';
1
+ import { ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderResourceCapacitySlot, ScanOrderResourceSelectType, ScanOrderSummary, ScanOrderTempOrder } from './types';
2
2
  import type { CartItemSummary, ItemRuleBusinessData, PaxInfo, QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
3
3
  import type { StrategyConfig } from '../../model/strategy/type';
4
4
  import type { ProductData } from '../../modules/Product/types';
@@ -109,6 +109,18 @@ export declare function collectLinkProductIdsFromReservationRules(rules: unknown
109
109
  export declare function pickFirstDurationMinutesFromProducts(products: ProductData[]): number | undefined;
110
110
  /** 是否存在 capacity.type === 'custom' 的商品 */
111
111
  export declare function hasCustomCapacityProduct(products: ProductData[]): boolean;
112
+ /**
113
+ * 根据预约规则商品的 resource.type 计算桌台是否已被"占满"。
114
+ * - single:只要有 `lastOrderId` 即视为占用
115
+ * - multiple:当前时间落在 `capacity_list[i]` 的 `[start_at, end_at]`(inclusive)内的 pax 之和 > 总容量
116
+ * - 其他('capacity' / undefined):返回 false,不施加限制
117
+ */
118
+ export declare function computeResourceIsFull(params: {
119
+ resourceSelectType?: ScanOrderResourceSelectType;
120
+ lastOrderId?: string;
121
+ capacityList?: ScanOrderResourceCapacitySlot[];
122
+ capacity?: number | string | null;
123
+ }): boolean;
112
124
  /**
113
125
  * 在商品列表中找到第一个 `capacity.type === 'custom'` 的商品,取其 `custom` 数组第一项的 min/max。
114
126
  * 仅返回有限数字字段;若均无法解析则返回 `undefined`。
@@ -11,6 +11,7 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
11
11
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
12
12
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
13
13
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
14
+ import dayjs from 'dayjs';
14
15
  /**
15
16
  * 构建金额全为 0 的空 summary。
16
17
  * 作为尚未计算金额时的兜底默认值,避免下游因 undefined 报错。
@@ -508,16 +509,54 @@ export function hasCustomCapacityProduct(products) {
508
509
  });
509
510
  }
510
511
 
512
+ /**
513
+ * 根据预约规则商品的 resource.type 计算桌台是否已被"占满"。
514
+ * - single:只要有 `lastOrderId` 即视为占用
515
+ * - multiple:当前时间落在 `capacity_list[i]` 的 `[start_at, end_at]`(inclusive)内的 pax 之和 > 总容量
516
+ * - 其他('capacity' / undefined):返回 false,不施加限制
517
+ */
518
+ export function computeResourceIsFull(params) {
519
+ var resourceSelectType = params.resourceSelectType,
520
+ lastOrderId = params.lastOrderId,
521
+ capacityList = params.capacityList,
522
+ capacity = params.capacity;
523
+ if (resourceSelectType === 'single') return Boolean(lastOrderId);
524
+ if (resourceSelectType !== 'multiple') return false;
525
+ var totalCapacity = Number(capacity);
526
+ if (!Number.isFinite(totalCapacity) || totalCapacity <= 0) return false;
527
+ var now = dayjs();
528
+ var occupied = 0;
529
+ var _iterator8 = _createForOfIteratorHelper(capacityList || []),
530
+ _step8;
531
+ try {
532
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
533
+ var slot = _step8.value;
534
+ var start = dayjs(slot === null || slot === void 0 ? void 0 : slot.start_at);
535
+ var end = dayjs(slot === null || slot === void 0 ? void 0 : slot.end_at);
536
+ if (!start.isValid() || !end.isValid()) continue;
537
+ if ((now.isAfter(start) || now.isSame(start)) && (now.isBefore(end) || now.isSame(end))) {
538
+ var pax = Number(slot === null || slot === void 0 ? void 0 : slot.pax);
539
+ if (Number.isFinite(pax) && pax > 0) occupied += pax;
540
+ }
541
+ }
542
+ } catch (err) {
543
+ _iterator8.e(err);
544
+ } finally {
545
+ _iterator8.f();
546
+ }
547
+ return occupied > totalCapacity;
548
+ }
549
+
511
550
  /**
512
551
  * 在商品列表中找到第一个 `capacity.type === 'custom'` 的商品,取其 `custom` 数组第一项的 min/max。
513
552
  * 仅返回有限数字字段;若均无法解析则返回 `undefined`。
514
553
  */
515
554
  export function pickFirstCustomCapacityPaxBounds(products) {
516
- var _iterator8 = _createForOfIteratorHelper(products),
517
- _step8;
555
+ var _iterator9 = _createForOfIteratorHelper(products),
556
+ _step9;
518
557
  try {
519
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
520
- var p = _step8.value;
558
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
559
+ var p = _step9.value;
521
560
  var cap = p === null || p === void 0 ? void 0 : p.capacity;
522
561
  if (!cap || cap.type !== 'custom') continue;
523
562
  if (!Array.isArray(cap.custom) || cap.custom.length === 0) continue;
@@ -536,9 +575,9 @@ export function pickFirstCustomCapacityPaxBounds(products) {
536
575
  if (out.min !== undefined || out.max !== undefined) return out;
537
576
  }
538
577
  } catch (err) {
539
- _iterator8.e(err);
578
+ _iterator9.e(err);
540
579
  } finally {
541
- _iterator8.f();
580
+ _iterator9.f();
542
581
  }
543
582
  return undefined;
544
583
  }
@@ -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
- });
@@ -311,7 +311,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
311
311
  date: string;
312
312
  status: string;
313
313
  week: string;
314
- weekNum: 0 | 1 | 4 | 3 | 2 | 5 | 6;
314
+ weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
315
315
  }[]>;
316
316
  submitTimeSlot(timeSlots: TimeSliceItem): void;
317
317
  private getScheduleDataByIds;
@@ -1,6 +1,6 @@
1
1
  import { Module, ModuleOptions, PisellCore } from '../../types';
2
2
  import { BaseModule } from '../../modules/BaseModule';
3
- import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity, ScanOrderTableConfigApiData } from './types';
3
+ import { ScanOrderAddLogParams, ScanOrderAvailabilityInfo, ScanOrderOrderProduct, ScanOrderOrderProductIdentity } from './types';
4
4
  import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
5
5
  import type { StrategyConfig } from '../../model/strategy/type';
6
6
  export * from './types';
@@ -43,7 +43,7 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
43
43
  refresh(): Promise<void>;
44
44
  getStatus(): import("./types").ScanOrderStatus;
45
45
  getEntryContext(): import("./types").ScanOrderEntryContext | null;
46
- getConfig(): ScanOrderTableConfigApiData;
46
+ getConfig(): Record<string, any>;
47
47
  getItemRuleQuantityLimits(): QuantityLimitResult[];
48
48
  getCartValidationPassed(): boolean | null;
49
49
  getCartValidation(): {
@@ -85,7 +85,8 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
85
85
  private refreshCartValidationPassed;
86
86
  setItemRuleRuntimeConfig(config?: ScanOrderItemRuleRuntimeConfig): Promise<void>;
87
87
  private normalizeResourceState;
88
- private fetchTableConfigByResourceId;
88
+ private resolveResourceSelectType;
89
+ private fetchResourceOccupyDetailByResourceId;
89
90
  checkResourceAvailable(resourceId: string, hasOrderId: boolean): Promise<ScanOrderAvailabilityInfo>;
90
91
  getAdditionalOrderInfo(): Promise<{
91
92
  orderId: string;
@@ -99,6 +100,14 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
99
100
  setOtherParams(params: Record<string, any>, { cover }?: {
100
101
  cover?: boolean;
101
102
  }): Promise<void>;
103
+ private static readonly UI_STATE_KEY_PREFIX;
104
+ private getUIStateBucketKey;
105
+ private readUIStateBucket;
106
+ private writeUIStateBucket;
107
+ setUIState(key: string, value: any): void;
108
+ getUIState<T = any>(key: string): T | undefined;
109
+ deleteUIState(key: string): void;
110
+ clearUIState(): void;
102
111
  setEntryPaxNumber(number: number): Promise<void>;
103
112
  getEntryPaxNumber(): number | null;
104
113
  getFulfillmentModes(): {