@pisell/pisellos 2.2.313 → 2.2.315

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 (215) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.js +3 -1
  3. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
  4. package/dist/model/strategy/adapter/itemRule/adapter.js +74 -7
  5. package/dist/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
  6. package/dist/model/strategy/adapter/itemRule/evaluator.js +13 -0
  7. package/dist/model/strategy/adapter/itemRule/type.d.ts +40 -1
  8. package/dist/model/strategy/adapter/itemRule/type.js +10 -0
  9. package/dist/modules/BookingContext/utils/productExtend.d.ts +7 -0
  10. package/dist/modules/BookingContext/utils/productExtend.js +62 -18
  11. package/dist/modules/BookingContext/utils/resources.js +1 -1
  12. package/dist/modules/BusinessAvailability/index.d.ts +30 -0
  13. package/dist/modules/BusinessAvailability/index.js +204 -0
  14. package/dist/modules/Cart/index.js +4 -3
  15. package/dist/modules/Cart/types.d.ts +2 -0
  16. package/dist/modules/Cart/utils/cartProduct.d.ts +3 -1
  17. package/dist/modules/Cart/utils/cartProduct.js +59 -32
  18. package/dist/modules/FulfillmentTiming/index.d.ts +11 -0
  19. package/dist/modules/FulfillmentTiming/index.js +407 -0
  20. package/dist/modules/FulfillmentTiming/types.d.ts +67 -0
  21. package/dist/modules/FulfillmentTiming/types.js +1 -0
  22. package/dist/modules/OpenData/types.d.ts +14 -0
  23. package/dist/modules/Order/index.d.ts +14 -2
  24. package/dist/modules/Order/index.js +856 -486
  25. package/dist/modules/Order/localEftposState.d.ts +13 -0
  26. package/dist/modules/Order/localEftposState.js +39 -0
  27. package/dist/modules/Order/pickupTiming.d.ts +46 -0
  28. package/dist/modules/Order/pickupTiming.js +53 -0
  29. package/dist/modules/Order/types.d.ts +30 -2
  30. package/dist/modules/Order/utils.js +25 -7
  31. package/dist/modules/Payment/index.js +9 -10
  32. package/dist/modules/Product/types.d.ts +11 -0
  33. package/dist/modules/ProductList/index.js +1 -1
  34. package/dist/modules/ResourcePlanner/planner.d.ts +2 -0
  35. package/dist/modules/ResourcePlanner/planner.js +332 -23
  36. package/dist/modules/ResourcePlanner/types.d.ts +29 -0
  37. package/dist/modules/Schedule/index.d.ts +8 -0
  38. package/dist/modules/Schedule/index.js +141 -39
  39. package/dist/modules/index.d.ts +1 -0
  40. package/dist/modules/index.js +1 -0
  41. package/dist/plugins/request.d.ts +7 -0
  42. package/dist/server/index.d.ts +1 -0
  43. package/dist/server/index.js +1536 -1309
  44. package/dist/server/modules/form/index.d.ts +19 -0
  45. package/dist/server/modules/form/index.js +205 -0
  46. package/dist/server/modules/form/types.d.ts +13 -0
  47. package/dist/server/modules/form/types.js +3 -0
  48. package/dist/server/modules/index.d.ts +3 -0
  49. package/dist/server/modules/index.js +4 -0
  50. package/dist/server/modules/order/index.d.ts +15 -0
  51. package/dist/server/modules/order/index.js +920 -688
  52. package/dist/server/modules/order/types.d.ts +1 -0
  53. package/dist/server/test.json +1 -1
  54. package/dist/server/utils/small-ticket.d.ts +1 -85
  55. package/dist/server/utils/small-ticket.js +2 -2542
  56. package/dist/shared/payment/loadPaymentMethods.d.ts +9 -0
  57. package/dist/shared/payment/loadPaymentMethods.js +66 -0
  58. package/dist/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  59. package/dist/shared/receipt/customerInvoiceLanguages.js +60 -0
  60. package/dist/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  61. package/dist/shared/receipt/loadCustomerInvoiceLayout.js +184 -0
  62. package/dist/shared/receipt/small-ticket.d.ts +96 -0
  63. package/dist/shared/receipt/small-ticket.js +2751 -0
  64. package/dist/shared/receipt/templateVisibility.d.ts +23 -0
  65. package/dist/shared/receipt/templateVisibility.js +64 -0
  66. package/dist/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  67. package/dist/shared/sales/loadSalesOrderSnapshot.js +21 -0
  68. package/dist/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  69. package/dist/solution/BaseSales/fulfillmentItemRules.js +750 -0
  70. package/dist/solution/BaseSales/index.d.ts +39 -16
  71. package/dist/solution/BaseSales/index.js +1754 -1154
  72. package/dist/solution/BaseSales/pickupTiming.d.ts +47 -0
  73. package/dist/solution/BaseSales/pickupTiming.js +616 -0
  74. package/dist/solution/BaseSales/types.d.ts +11 -0
  75. package/dist/solution/BaseSales/utils/parseSalesResponse.js +3 -0
  76. package/dist/solution/BookingByStep/index.d.ts +4 -2
  77. package/dist/solution/BookingByStep/index.js +8 -3
  78. package/dist/solution/BookingTicket/index.d.ts +8 -2
  79. package/dist/solution/BookingTicket/index.js +513 -436
  80. package/dist/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  81. package/dist/solution/BookingTicket/utils/addProductDecision.js +1 -1
  82. package/dist/solution/BookingTicket/utils/cartView.js +3 -1
  83. package/dist/solution/OrderInvoicePreview/index.d.ts +66 -0
  84. package/dist/solution/OrderInvoicePreview/index.js +340 -0
  85. package/dist/solution/RegisterAndLogin/config.js +54 -11
  86. package/dist/solution/RegisterAndLogin/index.d.ts +2 -0
  87. package/dist/solution/RegisterAndLogin/index.js +1 -1
  88. package/dist/solution/RegisterAndLogin/utils.d.ts +12 -4
  89. package/dist/solution/RegisterAndLogin/utils.js +36 -16
  90. package/dist/solution/Sales/index.js +1 -1
  91. package/dist/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  92. package/dist/solution/UnifiedBookingSales/businessAvailability.js +292 -0
  93. package/dist/solution/UnifiedBookingSales/index.d.ts +36 -4
  94. package/dist/solution/UnifiedBookingSales/index.js +1714 -905
  95. package/dist/solution/UnifiedBookingSales/types.d.ts +16 -2
  96. package/dist/solution/VenueBooking/index.d.ts +15 -2
  97. package/dist/solution/VenueBooking/index.js +1062 -785
  98. package/dist/solution/VenueBooking/types.d.ts +2 -1
  99. package/dist/solution/VenueBooking/types.js +1 -0
  100. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  101. package/dist/solution/VenueBooking/utils/dateSummary.js +7 -4
  102. package/dist/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  103. package/dist/solution/VenueBooking/utils/smartPricing.js +273 -0
  104. package/dist/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  105. package/dist/solution/VenueBooking/utils/timeSlot.js +6 -3
  106. package/dist/solution/index.d.ts +1 -0
  107. package/dist/solution/index.js +2 -1
  108. package/lib/index.d.ts +2 -0
  109. package/lib/index.js +21 -1
  110. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +3 -1
  111. package/lib/model/strategy/adapter/itemRule/adapter.js +54 -4
  112. package/lib/model/strategy/adapter/itemRule/evaluator.d.ts +3 -1
  113. package/lib/model/strategy/adapter/itemRule/evaluator.js +9 -0
  114. package/lib/model/strategy/adapter/itemRule/type.d.ts +40 -1
  115. package/lib/model/strategy/adapter/itemRule/type.js +10 -0
  116. package/lib/modules/BookingContext/utils/productExtend.d.ts +7 -0
  117. package/lib/modules/BookingContext/utils/productExtend.js +45 -2
  118. package/lib/modules/BookingContext/utils/resources.js +1 -1
  119. package/lib/modules/BusinessAvailability/index.d.ts +30 -0
  120. package/lib/modules/BusinessAvailability/index.js +146 -0
  121. package/lib/modules/Cart/index.js +4 -2
  122. package/lib/modules/Cart/types.d.ts +2 -0
  123. package/lib/modules/Cart/utils/cartProduct.d.ts +3 -1
  124. package/lib/modules/Cart/utils/cartProduct.js +39 -20
  125. package/lib/modules/FulfillmentTiming/index.d.ts +11 -0
  126. package/lib/modules/FulfillmentTiming/index.js +359 -0
  127. package/lib/modules/FulfillmentTiming/types.d.ts +67 -0
  128. package/lib/modules/FulfillmentTiming/types.js +5 -0
  129. package/lib/modules/OpenData/types.d.ts +14 -0
  130. package/lib/modules/Order/index.d.ts +14 -2
  131. package/lib/modules/Order/index.js +240 -38
  132. package/lib/modules/Order/localEftposState.d.ts +13 -0
  133. package/lib/modules/Order/localEftposState.js +44 -0
  134. package/lib/modules/Order/pickupTiming.d.ts +46 -0
  135. package/lib/modules/Order/pickupTiming.js +61 -0
  136. package/lib/modules/Order/types.d.ts +30 -2
  137. package/lib/modules/Order/utils.js +21 -5
  138. package/lib/modules/Payment/index.js +3 -4
  139. package/lib/modules/Product/types.d.ts +11 -0
  140. package/lib/modules/ProductList/index.js +1 -1
  141. package/lib/modules/ResourcePlanner/planner.d.ts +2 -0
  142. package/lib/modules/ResourcePlanner/planner.js +252 -8
  143. package/lib/modules/ResourcePlanner/types.d.ts +29 -0
  144. package/lib/modules/Schedule/index.d.ts +8 -0
  145. package/lib/modules/Schedule/index.js +68 -12
  146. package/lib/modules/index.d.ts +1 -0
  147. package/lib/modules/index.js +11 -0
  148. package/lib/plugins/request.d.ts +7 -0
  149. package/lib/server/index.d.ts +1 -0
  150. package/lib/server/index.js +158 -37
  151. package/lib/server/modules/form/index.d.ts +19 -0
  152. package/lib/server/modules/form/index.js +73 -0
  153. package/lib/server/modules/form/types.d.ts +13 -0
  154. package/lib/server/modules/form/types.js +9 -0
  155. package/lib/server/modules/index.d.ts +3 -0
  156. package/lib/server/modules/index.js +15 -1
  157. package/lib/server/modules/order/index.d.ts +15 -0
  158. package/lib/server/modules/order/index.js +114 -3
  159. package/lib/server/modules/order/types.d.ts +1 -0
  160. package/lib/server/test.json +1 -1
  161. package/lib/server/utils/small-ticket.d.ts +1 -85
  162. package/lib/server/utils/small-ticket.js +9 -2305
  163. package/lib/shared/payment/loadPaymentMethods.d.ts +9 -0
  164. package/lib/shared/payment/loadPaymentMethods.js +40 -0
  165. package/lib/shared/receipt/customerInvoiceLanguages.d.ts +8 -0
  166. package/lib/shared/receipt/customerInvoiceLanguages.js +58 -0
  167. package/lib/shared/receipt/loadCustomerInvoiceLayout.d.ts +27 -0
  168. package/lib/shared/receipt/loadCustomerInvoiceLayout.js +124 -0
  169. package/lib/shared/receipt/small-ticket.d.ts +96 -0
  170. package/lib/shared/receipt/small-ticket.js +2546 -0
  171. package/lib/shared/receipt/templateVisibility.d.ts +23 -0
  172. package/lib/shared/receipt/templateVisibility.js +63 -0
  173. package/lib/shared/sales/loadSalesOrderSnapshot.d.ts +9 -0
  174. package/lib/shared/sales/loadSalesOrderSnapshot.js +22 -0
  175. package/lib/solution/BaseSales/fulfillmentItemRules.d.ts +27 -0
  176. package/lib/solution/BaseSales/fulfillmentItemRules.js +259 -0
  177. package/lib/solution/BaseSales/index.d.ts +39 -16
  178. package/lib/solution/BaseSales/index.js +333 -31
  179. package/lib/solution/BaseSales/pickupTiming.d.ts +47 -0
  180. package/lib/solution/BaseSales/pickupTiming.js +290 -0
  181. package/lib/solution/BaseSales/types.d.ts +11 -0
  182. package/lib/solution/BaseSales/utils/parseSalesResponse.js +3 -0
  183. package/lib/solution/BookingByStep/index.d.ts +4 -2
  184. package/lib/solution/BookingByStep/index.js +7 -3
  185. package/lib/solution/BookingTicket/index.d.ts +8 -2
  186. package/lib/solution/BookingTicket/index.js +65 -6
  187. package/lib/solution/BookingTicket/utils/addProductDecision.d.ts +0 -1
  188. package/lib/solution/BookingTicket/utils/addProductDecision.js +1 -1
  189. package/lib/solution/BookingTicket/utils/cartView.js +3 -1
  190. package/lib/solution/OrderInvoicePreview/index.d.ts +66 -0
  191. package/lib/solution/OrderInvoicePreview/index.js +246 -0
  192. package/lib/solution/RegisterAndLogin/config.js +57 -11
  193. package/lib/solution/RegisterAndLogin/index.d.ts +2 -0
  194. package/lib/solution/RegisterAndLogin/index.js +9 -1
  195. package/lib/solution/RegisterAndLogin/utils.d.ts +12 -4
  196. package/lib/solution/RegisterAndLogin/utils.js +24 -17
  197. package/lib/solution/Sales/index.js +1 -1
  198. package/lib/solution/UnifiedBookingSales/businessAvailability.d.ts +27 -0
  199. package/lib/solution/UnifiedBookingSales/businessAvailability.js +138 -0
  200. package/lib/solution/UnifiedBookingSales/index.d.ts +36 -4
  201. package/lib/solution/UnifiedBookingSales/index.js +561 -74
  202. package/lib/solution/UnifiedBookingSales/types.d.ts +16 -2
  203. package/lib/solution/VenueBooking/index.d.ts +15 -2
  204. package/lib/solution/VenueBooking/index.js +243 -96
  205. package/lib/solution/VenueBooking/types.d.ts +2 -1
  206. package/lib/solution/VenueBooking/types.js +1 -0
  207. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  208. package/lib/solution/VenueBooking/utils/dateSummary.js +7 -4
  209. package/lib/solution/VenueBooking/utils/smartPricing.d.ts +71 -0
  210. package/lib/solution/VenueBooking/utils/smartPricing.js +224 -0
  211. package/lib/solution/VenueBooking/utils/timeSlot.d.ts +1 -0
  212. package/lib/solution/VenueBooking/utils/timeSlot.js +5 -2
  213. package/lib/solution/index.d.ts +1 -0
  214. package/lib/solution/index.js +11 -0
  215. package/package.json +1 -1
@@ -72,6 +72,11 @@ export interface UnifiedBookingSalesPrepareAvailabilityProjectionParams {
72
72
  }
73
73
  export interface AvailabilityContextRef {
74
74
  contextId: string;
75
+ /** POS/Kiosk duration protocol capability and business-day default. */
76
+ durationTimeSelection?: {
77
+ version: 1;
78
+ currentBusinessDate: string;
79
+ };
75
80
  }
76
81
  export interface ContextualProductTimeRange extends ProductTimeRange {
77
82
  availabilityContextId: string;
@@ -80,7 +85,7 @@ export interface ContextualProductTimeRange extends ProductTimeRange {
80
85
  export interface ContextualProductTimeRangeGroup extends Omit<ProductTimeRangeGroup, 'ranges'> {
81
86
  ranges: ContextualProductTimeRange[];
82
87
  }
83
- export type ContextualAvailabilityQuery = Omit<Extract<AvailabilityQuery, {
88
+ export type ContextualAvailabilityQuery = (Omit<Extract<AvailabilityQuery, {
84
89
  target: 'product';
85
90
  }>, never> | Omit<Extract<AvailabilityQuery, {
86
91
  target: 'date';
@@ -92,7 +97,10 @@ export type ContextualAvailabilityQuery = Omit<Extract<AvailabilityQuery, {
92
97
  target: 'resource';
93
98
  }>, 'selectedRanges'> & {
94
99
  selectedRanges: ContextualProductTimeRange[];
95
- });
100
+ })) & {
101
+ /** Automatic remembered selection must not inherit POS manual exceptions. */
102
+ selectionIntent?: 'remembered' | 'manual';
103
+ };
96
104
  export type ContextualTimeAvailabilityItem = Omit<TimeAvailabilityItem, keyof ProductTimeRange> & ContextualProductTimeRange;
97
105
  export interface ContextualTimeAvailabilityGroup extends Omit<TimeAvailabilityGroup, 'times'> {
98
106
  times: ContextualTimeAvailabilityItem[];
@@ -155,6 +163,10 @@ export interface UnifiedBookingSalesAddRetailProductParams {
155
163
  }
156
164
  export interface ContextualCommitAvailabilitySelectionParams {
157
165
  mode: 'add' | 'edit';
166
+ /** Only POS duration add supports automatic remembered-time commits. */
167
+ selectionIntent?: 'remembered' | 'manual';
168
+ /** Local UI intent guard, checked again immediately before the Order mutation. */
169
+ availabilityCommitGuard?: () => void;
158
170
  productLineUid?: string;
159
171
  orderProduct: Record<string, any>;
160
172
  candidate: ContextualProductTimeRange;
@@ -216,6 +228,8 @@ export interface UnifiedBookingSalesDiscountResult {
216
228
  summaryAfter?: unknown;
217
229
  }
218
230
  export interface UnifiedBookingSalesApi {
231
+ /** Uses cached business settings and evaluates the current store-local clock. */
232
+ getBusinessAvailability: () => Promise<import('../../modules/BusinessAvailability').BusinessAvailability>;
219
233
  loadOpenData: (params: UnifiedBookingSalesLoadOpenDataParams) => Promise<OpenDataConfig>;
220
234
  /** Returns the latest OpenData payload cached by this solution instance. */
221
235
  getOpenData: () => Promise<OpenDataConfig | null>;
@@ -41,6 +41,11 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
41
41
  private customerLoginRefreshIdInFlight;
42
42
  private loadAllProductsInFlight;
43
43
  private productsLoaded;
44
+ private smartPricingCustomerId;
45
+ private smartPricingProductCatalog;
46
+ private slotPriceMapCache;
47
+ private slotPriceStrategyConfigs;
48
+ private slotPriceScheduleList;
44
49
  private loadOpenDataConfigInFlight;
45
50
  private static readonly OPEN_DATA_CACHE_TTL;
46
51
  private getLoggerContext;
@@ -69,7 +74,7 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
69
74
  private clearLoginEffectListeners;
70
75
  private registerLoginEffect;
71
76
  private registerCustomerLoginListeners;
72
- private refreshOrderMarketingAfterLogin;
77
+ private refreshOrderMarketingForCustomer;
73
78
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
74
79
  destroy(): Promise<void>;
75
80
  retryInit(): Promise<void>;
@@ -82,6 +87,11 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
82
87
  passed: boolean | null;
83
88
  failures: QuantityCheckResult[];
84
89
  };
90
+ private resolveCustomerIdForSmartPricing;
91
+ private buildSmartPricingContext;
92
+ private buildSlotPriceMapForDate;
93
+ /** 规则或客户上下文更新后,同步商品展示、已选时段和订单汇总。 */
94
+ refreshSmartPricing(): Promise<void>;
85
95
  loadAllProducts(): Promise<{
86
96
  venueProducts: ProductData[];
87
97
  addonProducts: ProductData[];
@@ -167,7 +177,10 @@ export declare class VenueBookingImpl extends BaseSalesImpl implements Module {
167
177
  onCustomerLogin(params: {
168
178
  customerId: number;
169
179
  }): Promise<void>;
170
- private recalculateOrderPricesFromQuotation;
180
+ /** 宿主退出登录或以匿名身份重新进入时,清理客户资产并恢复匿名价格。 */
181
+ onCustomerLogout(): Promise<void>;
182
+ private recalculateOrderPricesFromSmartPricing;
183
+ private resetProductPriceForSmartPricing;
171
184
  scanCode(code: string, customerId?: number): Promise<{
172
185
  isAvailable: boolean;
173
186
  isAccepted?: boolean | undefined;
@@ -34,6 +34,7 @@ var _itemRule = require("../../model/strategy/adapter/itemRule");
34
34
  var _resource = require("./utils/resource");
35
35
  var _timeSlot = require("./utils/timeSlot");
36
36
  var _dateSummary = require("./utils/dateSummary");
37
+ var _smartPricing = require("./utils/smartPricing");
37
38
  var _slotMerge = require("./utils/slotMerge");
38
39
  var _utils3 = require("../../modules/Order/utils");
39
40
  var _Order = require("../../modules/Order");
@@ -94,6 +95,12 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
94
95
  customerLoginRefreshIdInFlight = null;
95
96
  loadAllProductsInFlight = null;
96
97
  productsLoaded = false;
98
+ // undefined 尚未同步宿主身份;null 表示已明确退出,禁止回退到旧用户插件。
99
+ smartPricingCustomerId;
100
+ smartPricingProductCatalog = [];
101
+ slotPriceMapCache = new Map();
102
+ slotPriceStrategyConfigs;
103
+ slotPriceScheduleList = undefined;
97
104
  loadOpenDataConfigInFlight = null;
98
105
  static OPEN_DATA_CACHE_TTL = 5 * 60 * 1000;
99
106
  getLoggerContext() {
@@ -248,7 +255,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
248
255
  };
249
256
  }
250
257
  readProductOriginFromTempOrder(tempOrder, product) {
251
- const uid = product.metadata?.unique_identification_number || product.identity_key;
258
+ const uid = (0, _utils3.getOrderProductLineUid)(product);
252
259
  if (uid && tempOrder._extend?.productsByUid?.[uid]?.origin) {
253
260
  return tempOrder._extend.productsByUid[uid].origin;
254
261
  }
@@ -287,6 +294,9 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
287
294
  return null;
288
295
  }
289
296
  resolveHolderCustomerId() {
297
+ if (this.smartPricingCustomerId !== undefined) {
298
+ return this.smartPricingCustomerId ?? undefined;
299
+ }
290
300
  const customer = JSON.parse(this.window?.getLocalStorage?.('customer') || '{}');
291
301
  if (customer?.id) return Number(customer.id);
292
302
  return undefined;
@@ -338,52 +348,65 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
338
348
  }
339
349
  registerCustomerLoginListeners() {
340
350
  this.clearLoginEffectListeners();
341
- const accountModule = this.core?.getModule('account');
342
- const registerAndLoginModule = this.core?.getModule('registerAndLogin');
343
- const currentAccount = accountModule?.getCurrentAccount?.() || accountModule?.getAccount?.() || null;
344
- const createHandleLogin = eventName => async payload => {
351
+ const handleLogin = async payload => {
345
352
  const customerId = this.resolveCustomerIdFromLoginPayload(payload);
346
353
  if (!customerId) return;
347
- await this.refreshOrderMarketingAfterLogin({
354
+ await this.refreshOrderMarketingForCustomer({
348
355
  customerId
349
356
  });
350
357
  };
351
- this.registerLoginEffect(_types3.AccountHooks.OnLogin, createHandleLogin(_types3.AccountHooks.OnLogin));
352
- this.registerLoginEffect(_types4.RegisterAndLoginHooks.onLoginSuccess, createHandleLogin(_types4.RegisterAndLoginHooks.onLoginSuccess));
358
+ this.registerLoginEffect(_types3.AccountHooks.OnLogin, handleLogin);
359
+ this.registerLoginEffect(_types4.RegisterAndLoginHooks.onLoginSuccess, handleLogin);
360
+ this.registerLoginEffect(_types3.AccountHooks.OnLogout, () => this.onCustomerLogout());
353
361
  }
354
- async refreshOrderMarketingAfterLogin(params) {
362
+ async refreshOrderMarketingForCustomer(params) {
355
363
  if (!this.store.order) throw new Error('order 模块未初始化');
356
- if (this.customerLoginRefreshInFlight) {
357
- if (this.customerLoginRefreshIdInFlight === params.customerId) {
358
- await this.customerLoginRefreshInFlight;
359
- return;
360
- }
364
+ if (this.customerLoginRefreshInFlight && this.customerLoginRefreshIdInFlight === params.customerId) {
361
365
  await this.customerLoginRefreshInFlight;
366
+ return;
362
367
  }
368
+ const previousRefresh = this.customerLoginRefreshInFlight;
363
369
  this.customerLoginRefreshIdInFlight = params.customerId;
364
370
  const refreshTask = (async () => {
365
- // 刷新 holder 表单数据
366
- if (this.store.holder) {
367
- await this.store.holder.refreshAllFormRecords({
368
- customer_id: params.customerId,
369
- useCache: false
370
- });
371
- }
372
- if (this.store.quotation) {
373
- await this.ensureQuotationsLoaded({
374
- channel: this.otherParams?.channel
371
+ // 身份切换按调用顺序执行;上一请求失败也不能阻止退出清理。
372
+ if (previousRefresh) await previousRefresh.catch(() => undefined);
373
+ this.smartPricingCustomerId = params.customerId;
374
+ const order = this.store.order;
375
+ if (params.customerId === null) {
376
+ order.clearOrderCustomer();
377
+ // 清除客户记录,保留表单定义供下次登录刷新。
378
+ const holder = this.store.holder;
379
+ for (const formId of Object.keys(holder?.getHolderFormMap() || {})) {
380
+ holder?.setFormData(formId, {
381
+ records: []
382
+ });
383
+ }
384
+ } else {
385
+ const tempOrder = order.ensureTempOrder();
386
+ if (Number(tempOrder.customer_id) !== params.customerId) {
387
+ const user = this.core.getPlugin('user')?.get?.();
388
+ order.updateTempOrderCustomer({
389
+ ...(Number(user?.id) === params.customerId ? user : {}),
390
+ customer_id: params.customerId
391
+ });
392
+ }
393
+ // 先获取新客户的钱包/优惠资产,再按该上下文计算智能价。
394
+ await order.loadDiscountConfig({
395
+ customerId: params.customerId,
396
+ apply: false
375
397
  });
398
+ if (this.store.holder) {
399
+ await this.store.holder.refreshAllFormRecords({
400
+ customer_id: params.customerId,
401
+ useCache: false
402
+ });
403
+ }
376
404
  }
377
- this.recalculateOrderPricesFromQuotation();
378
- await this.store.order.loadDiscountConfig({
379
- customerId: params.customerId
380
- });
381
- await this.store.order.recalculateSummary({
382
- createIfMissing: true
383
- });
384
- this.store.order.persistTempOrder();
385
- await this.refreshItemRuleQuantityLimits();
386
- await this.refreshCartValidationPassed();
405
+
406
+ // 不复用身份切换前尚未返回的商品请求,避免旧客户的结果覆盖新价格。
407
+ if (this.loadAllProductsInFlight) await this.loadAllProductsInFlight;
408
+ if (this.productsLoaded) await this.loadAllProducts();
409
+ await this.refreshSmartPricing();
387
410
  })();
388
411
  this.customerLoginRefreshInFlight = refreshTask;
389
412
  try {
@@ -407,6 +430,12 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
407
430
  this.store.status = 'initializing';
408
431
  this.store.error = null;
409
432
  this.store.rawResourceData = [];
433
+ this.smartPricingCustomerId = undefined;
434
+ this.smartPricingProductCatalog = [];
435
+ this.productsLoaded = false;
436
+ this.slotPriceStrategyConfigs = undefined;
437
+ this.slotPriceScheduleList = undefined;
438
+ this.slotPriceMapCache.clear();
410
439
  this.baseSlotConfig = {
411
440
  ..._types.DEFAULT_SLOT_CONFIG,
412
441
  ...(options.otherParams?.slotConfig || {})
@@ -644,6 +673,80 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
644
673
  failures: []
645
674
  };
646
675
  }
676
+ resolveCustomerIdForSmartPricing() {
677
+ if (this.smartPricingCustomerId !== undefined) return this.smartPricingCustomerId ?? undefined;
678
+ try {
679
+ const user = this.core?.getPlugin('user');
680
+ const customerId = Number(user?.get?.()?.id);
681
+ return Number.isFinite(customerId) && customerId > 0 ? customerId : undefined;
682
+ } catch {
683
+ return undefined;
684
+ }
685
+ }
686
+ buildSmartPricingContext() {
687
+ const strategyContext = this.otherParams?.strategy_context || {};
688
+ const orderWalletIds = this.store.order?.getAvailableWalletIds?.();
689
+ const fallbackWalletIds = this.otherParams?.available_wallet_ids ?? this.otherParams?.availableWalletIds ?? strategyContext.available_wallet_ids ?? strategyContext.availableWalletIds;
690
+ const walletIds = this.smartPricingCustomerId === null ? [] : orderWalletIds?.length ? orderWalletIds : fallbackWalletIds;
691
+ return {
692
+ evaluator: this.core?.context?.dataVariantEvaluator,
693
+ scheduleList: this.store.schedule?.getScheduleList?.() || [],
694
+ menuList: this.otherParams?.menuList || this.otherParams?.openData?.menuList || this.core?.context?.menuList || [],
695
+ customerId: this.resolveCustomerIdForSmartPricing(),
696
+ availableWalletIds: Array.isArray(walletIds) ? walletIds : [],
697
+ channel: this.otherParams?.channel ?? strategyContext.channel,
698
+ businessCode: this.otherParams?.businessCode ?? strategyContext.business_code ?? strategyContext.businessCode,
699
+ orderType: this.otherParams?.orderType || this.otherParams?.type || strategyContext.orderType || strategyContext.order_type,
700
+ strategy_context: strategyContext
701
+ };
702
+ }
703
+ buildSlotPriceMapForDate(date, config, productIds) {
704
+ const context = this.buildSmartPricingContext();
705
+ const strategyConfigs = context.evaluator?.getStrategyConfigs?.();
706
+ if (strategyConfigs !== this.slotPriceStrategyConfigs) {
707
+ this.slotPriceMapCache.clear();
708
+ this.slotPriceStrategyConfigs = strategyConfigs;
709
+ }
710
+ if (context.scheduleList !== this.slotPriceScheduleList) {
711
+ this.slotPriceMapCache.clear();
712
+ this.slotPriceScheduleList = context.scheduleList;
713
+ }
714
+ const cacheKey = JSON.stringify([date, config, productIds, context.customerId, context.availableWalletIds, context.channel, context.businessCode, context.orderType]);
715
+ const cached = this.slotPriceMapCache.get(cacheKey);
716
+ if (cached) return cached;
717
+ const priceMap = (0, _smartPricing.buildSlotPriceMapByScheduleSegments)({
718
+ products: this.smartPricingProductCatalog,
719
+ productIds,
720
+ date,
721
+ timeLabels: (0, _timeSlot.generateTimeLabels)(config),
722
+ config,
723
+ context
724
+ });
725
+ this.slotPriceMapCache.set(cacheKey, priceMap);
726
+ return priceMap;
727
+ }
728
+
729
+ /** 规则或客户上下文更新后,同步商品展示、已选时段和订单汇总。 */
730
+ async refreshSmartPricing() {
731
+ if (this.loadAllProductsInFlight) await this.loadAllProductsInFlight;
732
+ this.slotPriceMapCache.clear();
733
+ if (!this.productsLoaded || !this.store.order) return;
734
+ await this.store.schedule?.loadAllSchedule();
735
+ const products = (0, _smartPricing.formatProductsWithDataVariant)(this.smartPricingProductCatalog, this.buildSmartPricingContext());
736
+ this.store.venueProducts?.addProduct(products.filter(product => product.duration != null));
737
+ this.store.addonProducts?.addProduct(products.filter(product => product.duration == null));
738
+ this.recalculateOrderPricesFromSmartPricing();
739
+ this.store.order.applyDiscount();
740
+ await this.store.order.recalculateSummary({
741
+ createIfMissing: false
742
+ });
743
+ this.store.order.persistTempOrder();
744
+ await this.refreshItemRuleQuantityLimits();
745
+ await this.refreshCartValidationPassed();
746
+ await this.core.effects.emit(_types.VenueBookingHooks.onSmartPricingUpdated, {
747
+ customerId: this.resolveCustomerIdForSmartPricing()
748
+ });
749
+ }
647
750
 
648
751
  // ─── 场地商品 & 附加商品 ───
649
752
 
@@ -660,19 +763,34 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
660
763
  if (!this.store.venueProducts) throw new Error('venueProducts 模块未初始化');
661
764
  if (!this.store.addonProducts) throw new Error('addonProducts 模块未初始化');
662
765
  await this.loadOpenDataConfig();
766
+ if (!this.store.schedule) throw new Error('schedule 模块未初始化');
767
+ await this.store.schedule.loadAllSchedule();
663
768
  const associatedMenus = this.otherParams?.openData?.['menu.associated_menus'] || [];
664
769
  if (!associatedMenus.length) {
665
770
  this.logMethodError('loadAllProducts', new Error('未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置'));
666
771
  throw new Error('未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置');
667
772
  }
668
773
  const menuListIds = associatedMenus.map(n => Number(n.value));
774
+ const pricingContext = this.buildSmartPricingContext();
669
775
  const allProducts = await this.store.venueProducts.loadProducts({
670
776
  menu_list_ids: menuListIds,
671
777
  cacheId: this.cacheId,
672
778
  schedule_date: (0, _dayjs.default)().format('YYYY-MM-DD'),
673
- schedule_datetime: (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss')
779
+ schedule_datetime: (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss'),
780
+ customer_id: this.resolveCustomerIdForSmartPricing(),
781
+ strategy_context: {
782
+ ...pricingContext.strategy_context,
783
+ channel: pricingContext.channel,
784
+ business_code: pricingContext.businessCode,
785
+ order_type: pricingContext.orderType,
786
+ available_wallet_ids: pricingContext.availableWalletIds
787
+ }
674
788
  });
675
- const list = Array.isArray(allProducts) ? allProducts : [];
789
+ const loadedList = Array.isArray(allProducts) ? allProducts : [];
790
+ const rawProducts = this.store.venueProducts.getRawProductPriceSources(loadedList.map(product => product.id));
791
+ this.smartPricingProductCatalog = await Promise.all(loadedList.map(async product => rawProducts.get(product.id) ?? (await this.core.server?.getProducts?.()?.getProductById(product.id)) ?? product));
792
+ const list = (0, _smartPricing.formatProductsWithDataVariant)(this.smartPricingProductCatalog, this.buildSmartPricingContext());
793
+ this.slotPriceMapCache.clear();
676
794
  const venueList = list.filter(p => p.duration != null);
677
795
  const addonList = list.filter(p => p.duration == null);
678
796
  const venueStore = this.store.venueProducts?.store;
@@ -680,7 +798,9 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
680
798
  venueStore.list = venueList.slice().sort((a, b) => Number(b.sort) - Number(a.sort));
681
799
  }
682
800
  this.store.addonProducts.addProduct(addonList);
683
- this.resourceProductMap = (0, _resource.buildResourceProductMap)(venueList);
801
+
802
+ // 无规则命中时仍应回到原始商品价,不能回退到加载时刻的智能价。
803
+ this.resourceProductMap = (0, _resource.buildResourceProductMap)(this.smartPricingProductCatalog.filter(product => product.duration != null));
684
804
 
685
805
  // 加载 holder 表单
686
806
  if (this.store.order) {
@@ -704,8 +824,10 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
704
824
  }
705
825
  }
706
826
  async loadVenueProducts() {
707
- const result = await this.loadAllProducts();
708
- return result.venueProducts;
827
+ await this.loadAllProducts();
828
+ // 同步会话中已选的时段,避免新网格价格与恢复的购物车价格不一致。
829
+ await this.refreshSmartPricing();
830
+ return this.getVenueProducts();
709
831
  }
710
832
  async loadAddonProducts() {
711
833
  const result = await this.loadAllProducts();
@@ -866,31 +988,22 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
866
988
  config: this.baseSlotConfig,
867
989
  rawResources: this.store.rawResourceData,
868
990
  resourceProductMap: this.resourceProductMap,
869
- quotationModule: this.store.quotation,
870
- channel: this.otherParams?.channel,
871
- resolveConfig: date => this.resolveSlotConfigForDate(date)
991
+ resolveConfig: date => this.resolveSlotConfigForDate(date),
992
+ buildSlotPriceMap: (date, config, productIds) => this.buildSlotPriceMapForDate(date, config, productIds)
872
993
  });
873
994
  }
874
995
  getTimeSlotGrid(date) {
875
996
  const resolvedSlotConfig = this.syncOperatingHoursToSlotConfig(date);
876
- let quotationPriceMap;
877
- if (this.store.quotation) {
878
- const productIds = [...new Set([...this.resourceProductMap.values()].flat().map(m => m.productId))];
879
- const timeLabels = (0, _timeSlot.generateTimeLabels)(resolvedSlotConfig);
880
- const timePoints = timeLabels.map(label => `${date} ${label}`);
881
- quotationPriceMap = this.store.quotation.buildProductPriceMap({
882
- productIds,
883
- timePoints,
884
- channel: this.otherParams?.channel
885
- });
886
- }
887
- return (0, _timeSlot.buildTimeSlotGrid)({
997
+ const productIds = [...new Set([...this.resourceProductMap.values()].flat().map(mapping => mapping.productId))];
998
+ const slotPriceMap = this.buildSlotPriceMapForDate(date, resolvedSlotConfig, productIds);
999
+ const grid = (0, _timeSlot.buildTimeSlotGrid)({
888
1000
  date,
889
1001
  config: resolvedSlotConfig,
890
1002
  rawResources: this.store.rawResourceData,
891
1003
  resourceProductMap: this.resourceProductMap,
892
- quotationPriceMap
1004
+ slotPriceMap
893
1005
  });
1006
+ return grid;
894
1007
  }
895
1008
 
896
1009
  // ─── 时间槽订单操作 ───
@@ -1107,7 +1220,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1107
1220
  tempOrder.bookings = tempOrder.bookings || [];
1108
1221
  for (let i = 0; i < merged.length; i++) {
1109
1222
  const group = merged[i];
1110
- const identityKey = (0, _slotMerge.buildVenueIdentityKey)(resourceId, i);
1223
+ const productUid = (0, _slotMerge.buildVenueIdentityKey)(resourceId, i);
1111
1224
  const bookingUuid = (0, _utils3.createUuidV4)();
1112
1225
  const startMoment = (0, _dayjs.default)(group.startTime, 'YYYY-MM-DD HH:mm');
1113
1226
  const endMoment = (0, _dayjs.default)(group.endTime, 'YYYY-MM-DD HH:mm');
@@ -1180,12 +1293,12 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1180
1293
  const normalizedVenueOrderProduct = (0, _utils.normalizeOrderProduct)({
1181
1294
  product_id: mapping.productId,
1182
1295
  product_variant_id: 0,
1183
- identity_key: identityKey,
1184
1296
  num: 1,
1185
1297
  selling_price: group.totalPrice,
1186
1298
  original_price: group.totalPrice,
1187
1299
  is_charge_tax: venueProduct?.is_charge_tax ?? 0,
1188
1300
  metadata: {
1301
+ unique_identification_number: productUid,
1189
1302
  venue_booking: true,
1190
1303
  ...(productTitle ? {
1191
1304
  product_title: productTitle
@@ -1199,9 +1312,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1199
1312
  booking_uid: bookingUuid,
1200
1313
  price_breakdown: (0, _slotMerge.buildPriceBreakdown)({
1201
1314
  group,
1202
- productId: mapping.productId,
1203
- quotation: this.store.quotation,
1204
- channel: this.otherParams?.channel
1315
+ productId: mapping.productId
1205
1316
  })
1206
1317
  },
1207
1318
  _origin: venueProductOrigin
@@ -1210,7 +1321,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1210
1321
  ...normalizedVenueOrderProduct,
1211
1322
  product_title: productTitle
1212
1323
  } : normalizedVenueOrderProduct;
1213
- this.attachProductOriginToTempOrder(tempOrder, identityKey, venueProductOrigin);
1324
+ this.attachProductOriginToTempOrder(tempOrder, productUid, venueProductOrigin);
1214
1325
  tempOrder.products.push(venueOrderProduct);
1215
1326
  const booking = (0, _slotMerge.buildVenueBookingEntry)({
1216
1327
  group,
@@ -1218,7 +1329,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1218
1329
  mapping,
1219
1330
  rawResource,
1220
1331
  bookingUuid,
1221
- productUid: identityKey,
1332
+ productUid,
1222
1333
  childResources: childRawResources
1223
1334
  });
1224
1335
  tempOrder.bookings.push(booking);
@@ -1252,6 +1363,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1252
1363
  // ─── 配置 ───
1253
1364
 
1254
1365
  setSlotConfig(config) {
1366
+ this.slotPriceMapCache.clear();
1255
1367
  this.baseSlotConfig = {
1256
1368
  ...this.baseSlotConfig,
1257
1369
  ...config
@@ -1274,6 +1386,8 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1274
1386
  if (!this.store.schedule) throw new Error('schedule 模块未初始化');
1275
1387
  await this.store.schedule.loadAllSchedule();
1276
1388
  this.injectScheduleResolverToQuotation();
1389
+ this.slotPriceMapCache.clear();
1390
+ await this.refreshSmartPricing();
1277
1391
  this.logMethodSuccess('loadSchedules');
1278
1392
  } catch (error) {
1279
1393
  this.logMethodError('loadSchedules', error);
@@ -1313,7 +1427,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1313
1427
  customerId: params.customerId
1314
1428
  });
1315
1429
  try {
1316
- await this.refreshOrderMarketingAfterLogin({
1430
+ await this.refreshOrderMarketingForCustomer({
1317
1431
  customerId: params.customerId
1318
1432
  });
1319
1433
  this.logMethodSuccess('onCustomerLogin', {
@@ -1324,8 +1438,15 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1324
1438
  throw error;
1325
1439
  }
1326
1440
  }
1327
- recalculateOrderPricesFromQuotation() {
1328
- if (!this.store.order || !this.store.quotation) return;
1441
+
1442
+ /** 宿主退出登录或以匿名身份重新进入时,清理客户资产并恢复匿名价格。 */
1443
+ async onCustomerLogout() {
1444
+ await this.refreshOrderMarketingForCustomer({
1445
+ customerId: null
1446
+ });
1447
+ }
1448
+ recalculateOrderPricesFromSmartPricing() {
1449
+ if (!this.store.order) return;
1329
1450
  const tempOrder = this.store.order.getTempOrder();
1330
1451
  if (!tempOrder?.products?.length) return;
1331
1452
  const now = (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss');
@@ -1336,40 +1457,67 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1336
1457
  const mapping = mappings.find(m => Number(m.productId) === Number(product.product_id)) || mappings[0];
1337
1458
  if (!mapping) continue;
1338
1459
  const slots = (0, _slotMerge.expandMergedSlotToIndividual)(product, this.store.slotConfig.slotDurationMinutes);
1339
- const updatedSlots = slots.map(slot => ({
1340
- ...slot,
1341
- productId: mapping.productId,
1342
- price: this.store.quotation.getPriceForProduct({
1460
+ const updatedSlots = slots.map(slot => {
1461
+ const slotStart = (0, _dayjs.default)(slot.startTime);
1462
+ let date = slotStart.format('YYYY-MM-DD');
1463
+ const previousDate = slotStart.subtract(1, 'day').format('YYYY-MM-DD');
1464
+ const previousConfig = this.resolveSlotConfigForDate(previousDate);
1465
+ if ((0, _timeSlot.isBusinessHoursCrossDay)(previousConfig) && slotStart.format('HH:mm') < previousConfig.businessStartTime) {
1466
+ date = previousDate;
1467
+ }
1468
+ const slotPriceMap = this.buildSlotPriceMapForDate(date, this.resolveSlotConfigForDate(date), [mapping.productId]);
1469
+ return {
1470
+ ...slot,
1343
1471
  productId: mapping.productId,
1344
- datetime: slot.startTime,
1345
- channel: this.otherParams?.channel
1346
- }) ?? mapping.price
1347
- }));
1472
+ price: (0, _smartPricing.getSlotPriceFromMap)({
1473
+ slotPriceMap,
1474
+ productId: mapping.productId,
1475
+ slotStartTime: slot.startTime,
1476
+ fallbackPrice: mapping.price
1477
+ })
1478
+ };
1479
+ });
1348
1480
  const merged = (0, _slotMerge.mergeConsecutiveSlots)(updatedSlots);
1349
1481
  if (merged.length === 1) {
1350
- product.selling_price = merged[0].totalPrice;
1351
- product.original_price = merged[0].totalPrice;
1482
+ this.resetProductPriceForSmartPricing(product, merged[0].totalPrice);
1352
1483
  product.metadata.price_breakdown = (0, _slotMerge.buildPriceBreakdown)({
1353
1484
  group: merged[0],
1354
- productId: mapping.productId,
1355
- quotation: this.store.quotation,
1356
- channel: this.otherParams?.channel
1485
+ productId: mapping.productId
1357
1486
  });
1358
1487
  }
1359
1488
  } else if (product.product_id != null) {
1360
- const quotationPrice = this.store.quotation.getPriceForProduct({
1489
+ const price = (0, _smartPricing.getPriceForProductAtDatetime)({
1490
+ products: this.smartPricingProductCatalog,
1491
+ context: this.buildSmartPricingContext(),
1361
1492
  productId: product.product_id,
1362
1493
  variantId: product.product_variant_id ?? undefined,
1363
1494
  datetime: now,
1364
- channel: this.otherParams?.channel
1495
+ fallbackPrice: product.metadata?.source_product_price ?? product.original_price
1365
1496
  });
1366
- if (quotationPrice !== null) {
1367
- product.selling_price = quotationPrice;
1368
- product.original_price = quotationPrice;
1369
- }
1497
+ this.resetProductPriceForSmartPricing(product, price);
1370
1498
  }
1371
1499
  }
1372
1500
  }
1501
+ resetProductPriceForSmartPricing(product, price) {
1502
+ const mainPrice = new _decimal.default(price).plus((0, _utils3.sumOptionUnitPrice)((0, _utils3.getProductSkuOptions)(product))).toFixed(2);
1503
+ product.metadata = {
1504
+ ...product.metadata,
1505
+ source_product_price: price,
1506
+ main_product_original_price: mainPrice,
1507
+ main_product_selling_price: mainPrice,
1508
+ price_schema_version: 2
1509
+ };
1510
+ product.discount_list = [];
1511
+ product.selling_price = (0, _utils3.composeLinePrice)({
1512
+ mainPrice,
1513
+ bundle: product.product_bundle
1514
+ });
1515
+ product.original_price = (0, _utils3.composeLinePrice)({
1516
+ mainPrice,
1517
+ bundle: product.product_bundle,
1518
+ useOriginalBundle: true
1519
+ });
1520
+ }
1373
1521
  async scanCode(code, customerId) {
1374
1522
  this.logMethodStart('scanCode', {
1375
1523
  code
@@ -1565,19 +1713,16 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1565
1713
  });
1566
1714
  try {
1567
1715
  if (!this.store.order) throw new Error('order 模块未初始化');
1568
- if (!product.metadata?.venue_booking && this.store.quotation && product.product_id != null) {
1569
- const quotationPrice = this.store.quotation.getPriceForProduct({
1716
+ if (!product.metadata?.venue_booking && product.product_id != null) {
1717
+ const price = (0, _smartPricing.getPriceForProductAtDatetime)({
1718
+ products: this.smartPricingProductCatalog,
1719
+ context: this.buildSmartPricingContext(),
1570
1720
  productId: product.product_id,
1571
1721
  variantId: product.product_variant_id ?? undefined,
1572
1722
  datetime: (0, _dayjs.default)().format('YYYY-MM-DD HH:mm:ss'),
1573
- channel: this.otherParams?.channel
1723
+ fallbackPrice: product.metadata?.source_product_price ?? product.selling_price
1574
1724
  });
1575
- if (quotationPrice !== null) {
1576
- product.selling_price = quotationPrice;
1577
- product.original_price = quotationPrice;
1578
- } else if (product.selling_price != null) {
1579
- product.original_price = product.selling_price;
1580
- }
1725
+ this.resetProductPriceForSmartPricing(product, price);
1581
1726
  }
1582
1727
  const products = await this.store.order.addProductToOrder(product);
1583
1728
  await this.refreshItemRuleQuantityLimits();
@@ -1624,7 +1769,8 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1624
1769
  const venueBookingUids = new Set();
1625
1770
  for (const product of tempOrder.products || []) {
1626
1771
  if (!product?.metadata?.venue_booking) continue;
1627
- if (product.identity_key) venueProductUids.add(String(product.identity_key));
1772
+ const productUid = (0, _utils3.getOrderProductLineUid)(product);
1773
+ if (productUid) venueProductUids.add(productUid);
1628
1774
  if (product.metadata?.booking_uid) {
1629
1775
  venueBookingUids.add(String(product.metadata.booking_uid));
1630
1776
  }
@@ -1853,7 +1999,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1853
1999
  },
1854
2000
  _origin: origin
1855
2001
  });
1856
- const productUid = String(product.metadata?.unique_identification_number || '');
2002
+ const productUid = (0, _utils3.getOrderProductLineUid)(product) || '';
1857
2003
  this.attachProductOriginToTempOrder(tempOrder, productUid, origin);
1858
2004
  tempOrder.products.push(product);
1859
2005
  hasChanges = true;
@@ -1879,7 +2025,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
1879
2025
  }
1880
2026
  };
1881
2027
  if (delta > 0 || Boolean(sourceItem && (!previousOrigin || previousOrigin?.price !== sourceItem?.price))) {
1882
- const productUid = String(nextProduct.metadata?.unique_identification_number || '');
2028
+ const productUid = (0, _utils3.getOrderProductLineUid)(nextProduct) || '';
1883
2029
  this.attachProductOriginToTempOrder(tempOrder, productUid, nextOrigin);
1884
2030
  tempOrder.products[productIndex] = nextProduct;
1885
2031
  hasChanges = true;
@@ -2092,6 +2238,7 @@ class VenueBookingImpl extends _BaseSales.BaseSalesImpl {
2092
2238
  async setOtherParams(params, {
2093
2239
  cover = false
2094
2240
  } = {}) {
2241
+ this.slotPriceMapCache.clear();
2095
2242
  if (cover) {
2096
2243
  this.otherParams = params;
2097
2244
  } else {