@pisell/pisellos 2.3.78 → 2.3.80

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.
@@ -18,6 +18,19 @@ export declare class ProductList extends BaseModule implements Module {
18
18
  * productList.updateOtherParams({ channel: 'pos' });
19
19
  */
20
20
  updateOtherParams(params: Record<string, any>): void;
21
+ /**
22
+ * 判断当前商品查询是否会被本地 OS Server 接管。
23
+ *
24
+ * 不能只看请求参数中的 osServer=true:H5 RequestPlugin 会透传该参数,但仍然直接请求远端接口。
25
+ * 这里按 RequestPlugin 实际使用的 baseUrl 检查已注册路由,避免 OS Server 与客户端重复执行
26
+ * Data Variant 评估。
27
+ */
28
+ private isProductQueryHandledByOsServer;
29
+ /**
30
+ * 未启用商品 OS 路由时,在客户端补做 Data Variant 解析。
31
+ * OS Server 已接管时直接信任服务端结果,确保同一批商品只评估一次。
32
+ */
33
+ private resolveClientDataVariants;
21
34
  storeChange(path?: string, value?: any): Promise<void>;
22
35
  /**
23
36
  * 获取加时商品列表。
@@ -25,11 +38,11 @@ export declare class ProductList extends BaseModule implements Module {
25
38
  * @example
26
39
  * const products = await productList.getAddTimeProducts({ schedule_date: '2026-06-16' });
27
40
  */
28
- getAddTimeProducts(params?: ProductListLoadProductsParams): Promise<any>;
41
+ getAddTimeProducts(params?: ProductListLoadProductsParams): Promise<ProductData[]>;
29
42
  loadProducts({ category_ids, product_ids, collection, menu_list_ids, customer_id: paramsCustomerId, with_count, schedule_datetime, schedule_date, cacheId, with_schedule, extension_type, status, strategy_context, }?: ProductListLoadProductsParams, options?: {
30
43
  callback?: (result: any) => void;
31
44
  subscriberId?: string;
32
- }): Promise<any>;
45
+ }): Promise<ProductData[]>;
33
46
  loadProductsPrice({ ids, customer_id, schedule_date, channel, }: {
34
47
  ids?: number[];
35
48
  customer_id?: number;
@@ -55,6 +55,58 @@ class ProductList extends _BaseModule.BaseModule {
55
55
  updateOtherParams(params) {
56
56
  this.otherParams = params || {};
57
57
  }
58
+
59
+ /**
60
+ * 判断当前商品查询是否会被本地 OS Server 接管。
61
+ *
62
+ * 不能只看请求参数中的 osServer=true:H5 RequestPlugin 会透传该参数,但仍然直接请求远端接口。
63
+ * 这里按 RequestPlugin 实际使用的 baseUrl 检查已注册路由,避免 OS Server 与客户端重复执行
64
+ * Data Variant 评估。
65
+ */
66
+ isProductQueryHandledByOsServer() {
67
+ const server = this.core?.server;
68
+ if (!server || typeof server.hasRoute !== 'function') return false;
69
+ const requestBaseUrl = String(this.request?.baseUrl || '/shop').replace(/\/+$/, '');
70
+ const routePath = `${requestBaseUrl}/product/query`;
71
+ return server.hasRoute('post', routePath) === true;
72
+ }
73
+
74
+ /**
75
+ * 未启用商品 OS 路由时,在客户端补做 Data Variant 解析。
76
+ * OS Server 已接管时直接信任服务端结果,确保同一批商品只评估一次。
77
+ */
78
+ resolveClientDataVariants(products, queryPayload, handledByOsServer) {
79
+ if (handledByOsServer || products.length === 0) return products;
80
+ const evaluator = this.core?.context?.dataVariantEvaluator;
81
+ if (!evaluator || typeof evaluator.resolveProducts !== 'function') {
82
+ return products;
83
+ }
84
+ const strategyContext = queryPayload.strategy_context && typeof queryPayload.strategy_context === 'object' ? queryPayload.strategy_context : {};
85
+ const fatherModule = String(this.otherParams?.fatherModule || '').trim();
86
+ const scheduleModule = (fatherModule ? this.core.getModule(`${fatherModule}_schedule`) : null) || this.core.getModule('schedule');
87
+ const scheduleList = scheduleModule?.getScheduleList?.();
88
+ const contextScheduleList = this.core?.context?.scheduleList;
89
+ const contextMenuList = this.core?.context?.menuList;
90
+ const businessData = {
91
+ products,
92
+ scheduleDateTime: queryPayload.schedule_datetime || queryPayload.schedule_date,
93
+ scheduleList: Array.isArray(scheduleList) ? scheduleList : Array.isArray(contextScheduleList) ? contextScheduleList : [],
94
+ menuList: Array.isArray(this.otherParams?.menuList) ? this.otherParams.menuList : Array.isArray(contextMenuList) ? contextMenuList : [],
95
+ customerId: queryPayload.customer_id,
96
+ channel: strategyContext.channel,
97
+ orderType: strategyContext.orderType || strategyContext.order_type,
98
+ businessCode: strategyContext.business_code ?? strategyContext.businessCode,
99
+ availableWalletIds: strategyContext.available_wallet_ids,
100
+ custom: strategyContext
101
+ };
102
+ try {
103
+ const result = evaluator.resolveProducts(businessData);
104
+ return Array.isArray(result?.products) ? result.products : products;
105
+ } catch (error) {
106
+ console.error('[ProductList] Data Variant 客户端解析失败', error);
107
+ return products;
108
+ }
109
+ }
58
110
  async storeChange(path, value) {
59
111
  // No longer needed - products are stored as plain objects instead of Product instances
60
112
  }
@@ -149,13 +201,32 @@ class ProductList extends _BaseModule.BaseModule {
149
201
  extension_type,
150
202
  strategy_context
151
203
  };
204
+ const handledByOsServer = this.isProductQueryHandledByOsServer();
205
+ const originalCallback = options?.callback;
206
+ const subscriptionCallback = typeof originalCallback === 'function' ? async result => {
207
+ const callbackList = result?.data?.list;
208
+ if (!Array.isArray(callbackList)) {
209
+ originalCallback(result);
210
+ return;
211
+ }
212
+ const products = this.resolveClientDataVariants(callbackList, queryPayload, handledByOsServer);
213
+ await this.addProduct(products);
214
+ originalCallback(handledByOsServer ? result : {
215
+ ...result,
216
+ data: {
217
+ ...result.data,
218
+ list: products
219
+ }
220
+ });
221
+ } : undefined;
152
222
  const productsData = await this.request.post(`/product/query`, queryPayload, {
153
223
  osServer: true,
154
- callback: options?.callback,
224
+ callback: subscriptionCallback,
155
225
  subscriberId: options?.subscriberId,
156
226
  customToast: () => {}
157
227
  });
158
- const sortedList = (productsData.data.list || []).slice().sort((a, b) => Number(b.sort) - Number(a.sort));
228
+ const resolvedList = this.resolveClientDataVariants(productsData.data.list || [], queryPayload, handledByOsServer);
229
+ const sortedList = resolvedList.slice().sort((a, b) => Number(b.sort) - Number(a.sort));
159
230
  // if (sortedList.length) {
160
231
  // sortedList.forEach((n: any) => {
161
232
  // if (n.is_eject !== 1 && n['schedule.ids'] && n['schedule.ids'].length) {
@@ -495,7 +495,7 @@ export declare class BaseSalesImpl extends BaseModule implements Module {
495
495
  getUnfulfilledPromotions(): OrderUnfulfilledPromotion[];
496
496
  /** 最近一次促销计算输出的赠品操作 diff。 */
497
497
  getLastGiftActions(): OrderLastGiftActions | null;
498
- getProductList(): Promise<any>;
498
+ getProductList(): Promise<import("../..").ProductData[] | undefined>;
499
499
  getOtherParams(): Record<string, any>;
500
500
  setOtherParams(params: Record<string, any>, { cover }?: {
501
501
  cover?: boolean;
@@ -67,7 +67,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
67
67
  product_ids?: number[];
68
68
  collection?: number | string[];
69
69
  schedule_date?: string;
70
- }): Promise<any>;
70
+ }): Promise<ProductData[]>;
71
71
  /**
72
72
  * 通过 schedule 来读取商品,适用于 session 类商品
73
73
  *
@@ -87,7 +87,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
87
87
  date: string;
88
88
  product_ids?: number[];
89
89
  category_ids?: number[];
90
- }): Promise<any>;
90
+ }): Promise<ProductData[]>;
91
91
  /**
92
92
  * 更新完商品数据、切换日期、或者在较后的流程里登录了,检测当前购物车里是否有商品,如果有,则需要更新购物车里的商品价格
93
93
  *
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  date: string;
327
327
  status: string;
328
328
  week: string;
329
- weekNum: 0 | 1 | 2 | 5 | 4 | 3 | 6;
329
+ weekNum: 0 | 1 | 5 | 2 | 3 | 4 | 6;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
345
345
  count: number;
346
346
  left: number;
347
347
  summaryCount: number;
348
- status: "sold_out" | "lots_of_space" | "filling_up_fast";
348
+ status: "lots_of_space" | "filling_up_fast" | "sold_out";
349
349
  }[];
350
350
  /**
351
351
  * 找到多个资源的公共可用时间段
@@ -128,7 +128,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
128
128
  loadProducts(params?: ILoadProductsParams, options?: {
129
129
  callback?: (result: any) => void;
130
130
  subscriberId?: string;
131
- }): Promise<any>;
131
+ }): Promise<ProductData[]>;
132
132
  /**
133
133
  * 获取加时商品列表。
134
134
  *
@@ -334,7 +334,7 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
334
334
  * 获取当前的客户搜索条件
335
335
  * @returns 当前搜索条件
336
336
  */
337
- getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "skip" | "num">;
337
+ getCurrentCustomerSearchParams(): Omit<import("../../modules").ShopGetCustomerListParams, "num" | "skip">;
338
338
  /**
339
339
  * 获取客户列表状态(包含滚动加载相关状态)
340
340
  * @returns 客户状态
@@ -453,7 +453,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
453
453
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
454
454
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
455
455
  */
456
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
456
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
457
+ action: "reloadCatalog";
458
+ } | {
459
+ action: "add";
460
+ cacheItem: any;
461
+ } | {
462
+ action: "requiresDetail";
463
+ payload: AddProductRequiresDetailPayload;
464
+ } | {
465
+ action: "requiresBookingEdit";
466
+ cacheItem: any;
467
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
468
+ };
457
469
  /** 规格弹窗 callback 后的第二段决策。 */
458
470
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
459
471
  /**
@@ -980,6 +980,125 @@ function buildBookingFromAvailabilitySelection(params) {
980
980
  }
981
981
  };
982
982
  }
983
+ const POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES = new Set(['past', 'booking_cutoff', 'resource_full', 'resource_unavailable', 'resource_capacity_exceeded',
984
+ // A required group whose selected resource is outside its window is surfaced
985
+ // as missing_resource at group level. Structural validation below still
986
+ // rejects a genuinely missing selection.
987
+ 'missing_resource']);
988
+ function matchesForcedSelectionGroup(selection, group) {
989
+ const hasGroupId = typeof selection.requirementGroupId === 'string' && selection.requirementGroupId.trim().length > 0;
990
+ const hasFormId = selection.formId !== undefined && selection.formId !== null;
991
+ if (!hasGroupId && !hasFormId) return false;
992
+ if (hasGroupId && selection.requirementGroupId !== group.id) return false;
993
+ if (hasFormId && !sameAvailabilityId(selection.formId, group.formId)) return false;
994
+ return true;
995
+ }
996
+
997
+ /**
998
+ * POS may intentionally overbook a configured time/resource. Rebuild the
999
+ * assignments from the submitted, structurally valid resource identities so
1000
+ * a full/unavailable option is not silently dropped by normal availability
1001
+ * evaluation. This deliberately ignores capacity, occupancy and resource
1002
+ * windows, while retaining product/group/resource identity and selection
1003
+ * cardinality checks.
1004
+ */
1005
+ function buildPosForcedAvailabilityAssignments(params) {
1006
+ const {
1007
+ product,
1008
+ resources,
1009
+ candidate,
1010
+ requirementSelections,
1011
+ partySize
1012
+ } = params;
1013
+ const groups = product.requirementGroups || [];
1014
+ const conflicts = [];
1015
+ const assignments = [];
1016
+ const selectionsByGroup = new Map();
1017
+ const addConflict = (code, message, details = {}) => conflicts.push({
1018
+ code,
1019
+ message,
1020
+ productId: candidate.productId,
1021
+ candidateKey: candidate.key,
1022
+ ...details
1023
+ });
1024
+ requirementSelections.forEach(selection => {
1025
+ const matchedGroups = groups.filter(group => matchesForcedSelectionGroup(selection, group));
1026
+ if (matchedGroups.length !== 1) {
1027
+ addConflict('invalid_requirement_group', '选择的资源组不属于当前商品', {
1028
+ requirementGroupId: selection.requirementGroupId,
1029
+ formId: selection.formId
1030
+ });
1031
+ return;
1032
+ }
1033
+ const group = matchedGroups[0];
1034
+ if (selectionsByGroup.has(group.id)) {
1035
+ addConflict('invalid_selection_count', `资源组 ${group.id} 被重复提交`, {
1036
+ requirementGroupId: group.id,
1037
+ formId: group.formId
1038
+ });
1039
+ return;
1040
+ }
1041
+ selectionsByGroup.set(group.id, selection);
1042
+ if (!Array.isArray(selection.resourceIds)) {
1043
+ addConflict('invalid_selection_count', `资源组 ${group.id} 的资源选择必须是数组`, {
1044
+ requirementGroupId: group.id,
1045
+ formId: group.formId
1046
+ });
1047
+ return;
1048
+ }
1049
+ const selectedResourceIds = Array.from(new Map(selection.resourceIds.map(resourceId => [String(resourceId), resourceId])).values());
1050
+ const required = group.required !== false;
1051
+ const min = Math.max(required ? 1 : 0, Number(group.min ?? (required ? 1 : 0)) || 0);
1052
+ const max = Math.max(min, Number(group.max ?? Math.max(min, 1)) || Math.max(min, 1));
1053
+ if (selectedResourceIds.length < min) {
1054
+ addConflict('missing_resource', `资源组 ${group.id} 缺少已选资源`, {
1055
+ requirementGroupId: group.id,
1056
+ formId: group.formId
1057
+ });
1058
+ return;
1059
+ }
1060
+ if (selectedResourceIds.length > max) {
1061
+ addConflict('invalid_selection_count', `资源组 ${group.id} 已选资源数量超出上限`, {
1062
+ requirementGroupId: group.id,
1063
+ formId: group.formId
1064
+ });
1065
+ return;
1066
+ }
1067
+ selectedResourceIds.forEach(resourceId => {
1068
+ const resource = resources.find(item => sameAvailabilityId(item.id, resourceId));
1069
+ const belongsToGroup = Boolean(resource && !(group.formId !== undefined && resource.formId !== undefined && !sameAvailabilityId(group.formId, resource.formId)) && !(group.resourceIds?.length && !group.resourceIds.some(id => sameAvailabilityId(id, resourceId))));
1070
+ if (!resource || !belongsToGroup) {
1071
+ addConflict('resource_unavailable', `资源 ${String(resourceId)} 不属于当前商品资源组`, {
1072
+ requirementGroupId: group.id,
1073
+ formId: group.formId,
1074
+ resourceId
1075
+ });
1076
+ return;
1077
+ }
1078
+ assignments.push({
1079
+ productId: product.id,
1080
+ resourceId,
1081
+ formId: group.formId ?? resource.formId,
1082
+ startAt: candidate.bookingStartAt || candidate.startAt,
1083
+ endAt: candidate.bookingEndAt || candidate.endAt,
1084
+ capacityRequired: Math.max(1, partySize),
1085
+ scheduleId: candidate.primaryScheduleRef?.scheduleId,
1086
+ timeSlotId: candidate.primaryScheduleRef?.timeSlotId
1087
+ });
1088
+ });
1089
+ });
1090
+ groups.filter(group => group.required !== false).forEach(group => {
1091
+ if (selectionsByGroup.has(group.id)) return;
1092
+ addConflict('missing_resource', `资源组 ${group.id} 缺少已选资源`, {
1093
+ requirementGroupId: group.id,
1094
+ formId: group.formId
1095
+ });
1096
+ });
1097
+ return {
1098
+ assignments,
1099
+ conflicts
1100
+ };
1101
+ }
983
1102
  class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
984
1103
  defaultName = 'unifiedBookingSales';
985
1104
  defaultVersion = '1.0.0';
@@ -1529,7 +1648,11 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1529
1648
  if (!normalizedPolicyId) {
1530
1649
  throw new Error('[UnifiedBookingSales] getProtocol 需要 policyId');
1531
1650
  }
1532
- return this.request.get(`/shop-policy/${encodeURIComponent(normalizedPolicyId)}`);
1651
+ let policyUrl = 'shop-policy';
1652
+ if (this.otherParams.platform === 'kiosk' || this.otherParams.platform === 'pos' || this.otherParams.platform === 'shop') {
1653
+ policyUrl = 'policy';
1654
+ }
1655
+ return this.request.get(`/${policyUrl}/${encodeURIComponent(normalizedPolicyId)}`);
1533
1656
  }
1534
1657
 
1535
1658
  /**
@@ -1721,6 +1844,7 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1721
1844
  }
1722
1845
  buildUnifiedOrderProduct(sourceProduct, ownershipKey, product) {
1723
1846
  const normalizedProductRaw = product?.raw || {};
1847
+ const quotationShelfId = sourceProduct._extend?.quotation_shelf_id ?? sourceProduct.quotation_shelf_id ?? sourceProduct.metadata?.quotation_shelf_id;
1724
1848
  const orderProduct = this.transformBaseProductToOrderProduct({
1725
1849
  payload: {
1726
1850
  ...sourceProduct,
@@ -1737,11 +1861,14 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
1737
1861
  sourceProduct
1738
1862
  });
1739
1863
  if (orderProduct && typeof orderProduct === 'object') {
1740
- // BaseSales may rebuild metadata from its price source. Stamp ownership after that transform
1741
- // so each UnifiedBookingSales entry point can replace only its own temporary lines.
1864
+ // BaseSales may rebuild metadata from its price source. Stamp ownership and the selected
1865
+ // quotation shelf after that transform so neither booking adds nor edits lose quote identity.
1742
1866
  orderProduct.metadata = {
1743
1867
  ...(orderProduct.metadata || {}),
1744
- [ownershipKey]: true
1868
+ [ownershipKey]: true,
1869
+ ...(quotationShelfId !== undefined ? {
1870
+ quotation_shelf_id: quotationShelfId
1871
+ } : {})
1745
1872
  };
1746
1873
  }
1747
1874
  return orderProduct;
@@ -2901,12 +3028,39 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2901
3028
  refreshedSnapshotId: refreshedProjection.meta.snapshotId
2902
3029
  });
2903
3030
  }
2904
- const validation = (0, _ResourcePlanner.validateAvailabilitySelection)(refreshedProjection, {
3031
+ const product = refreshedProjection.products.find(item => sameAvailabilityId(item.id, refreshedCandidateBase.productId));
3032
+ if (!product) {
3033
+ throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', '缓存重校验后商品不在 projection 中', {
3034
+ productId: refreshedCandidateBase.productId
3035
+ });
3036
+ }
3037
+ let validation = (0, _ResourcePlanner.validateAvailabilitySelection)(refreshedProjection, {
2905
3038
  candidate: refreshedCandidateBase,
2906
3039
  requirementSelections: params.requirementSelections,
2907
3040
  partySize,
2908
3041
  bookingCount
2909
3042
  });
3043
+ const allowPosAvailabilityOverride = String(this.otherParams?.platform ?? '').trim().toLowerCase() === 'pos';
3044
+ if (allowPosAvailabilityOverride && !validation.ok && validation.conflicts.every(conflict => POS_OVERRIDABLE_AVAILABILITY_CONFLICT_CODES.has(conflict.code))) {
3045
+ const forced = buildPosForcedAvailabilityAssignments({
3046
+ product,
3047
+ resources: refreshedProjection.resources,
3048
+ candidate: refreshedCandidateBase,
3049
+ requirementSelections: params.requirementSelections,
3050
+ partySize
3051
+ });
3052
+ validation = forced.conflicts.length > 0 ? {
3053
+ ...validation,
3054
+ assignments: [],
3055
+ conflicts: forced.conflicts
3056
+ } : {
3057
+ ...validation,
3058
+ ok: true,
3059
+ status: validation.availability.status,
3060
+ assignments: forced.assignments,
3061
+ conflicts: []
3062
+ };
3063
+ }
2910
3064
  if (!validation.ok) {
2911
3065
  const capacityConflict = validation.conflicts.find(conflict => conflict.code === 'resource_capacity_exceeded');
2912
3066
  throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', capacityConflict?.message || '缓存重校验后资源已不可提交', {
@@ -2944,12 +3098,6 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2944
3098
  expectedOrderRevision: revalidationEntry.orderRevision
2945
3099
  };
2946
3100
  const refreshedCandidate = this.decorateAvailabilityCandidate(normalizedContextId, revalidatedContext.activeVersion, refreshedCandidateBase);
2947
- const product = refreshedProjection.products.find(item => sameAvailabilityId(item.id, refreshedCandidate.productId));
2948
- if (!product) {
2949
- throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', '缓存重校验后商品不在 projection 中', {
2950
- productId: refreshedCandidate.productId
2951
- });
2952
- }
2953
3101
  const existingBooking = editingLine ? this.findLinkedBooking(editingLine) : undefined;
2954
3102
  const existingBookingUid = existingBooking ? getBookingUid(existingBooking) : '';
2955
3103
  if (params.mode === 'edit' && !existingBookingUid) {
@@ -3004,7 +3152,13 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
3004
3152
  product_variant_id: transformed.product_variant_id ?? editingLine.product_variant_id ?? 0,
3005
3153
  unique_identification_number: params.productLineUid,
3006
3154
  updates: transformed,
3007
- booking
3155
+ booking,
3156
+ ...(params.allowBookingReprice !== undefined ? {
3157
+ allow_booking_reprice: params.allowBookingReprice
3158
+ } : {}),
3159
+ ...(params.allowBookingDiscountReapply !== undefined ? {
3160
+ allow_booking_discount_reapply: params.allowBookingDiscountReapply
3161
+ } : {})
3008
3162
  });
3009
3163
  productLineUid = params.productLineUid;
3010
3164
  bookingUid = existingBookingUid;
@@ -151,6 +151,10 @@ export interface ContextualCommitAvailabilitySelectionParams {
151
151
  requirementSelections: AvailabilityRequirementSelection[];
152
152
  partySize: number;
153
153
  bookingCount?: number;
154
+ /** 编辑预约时,允许本次显式报价覆盖已落库订单行的历史价格。 */
155
+ allowBookingReprice?: boolean;
156
+ /** 编辑预约重报价后,允许订单模块重新应用已选编辑态折扣。 */
157
+ allowBookingDiscountReapply?: boolean;
154
158
  }
155
159
  export type UnifiedBookingSalesCommitAvailabilitySelectionParams = ContextualCommitAvailabilitySelectionParams;
156
160
  export interface UnifiedBookingSalesCommitAvailabilitySelectionResult {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.3.78",
4
+ "version": "2.3.80",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",