@pisell/pisellos 2.3.24 → 2.3.25

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 (69) hide show
  1. package/dist/model/strategy/adapter/index.d.ts +0 -4
  2. package/dist/model/strategy/adapter/index.js +1 -5
  3. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  4. package/dist/modules/Discount/index.d.ts +2 -5
  5. package/dist/modules/Discount/index.js +7 -30
  6. package/dist/modules/Discount/types.d.ts +0 -4
  7. package/dist/modules/Order/index.d.ts +1 -1
  8. package/dist/modules/Order/index.js +616 -568
  9. package/dist/modules/Order/types.d.ts +0 -2
  10. package/dist/modules/Product/types.d.ts +0 -22
  11. package/dist/modules/ProductList/index.d.ts +1 -1
  12. package/dist/modules/ProductList/index.js +2 -4
  13. package/dist/modules/ProductList/types.d.ts +0 -2
  14. package/dist/server/index.d.ts +0 -50
  15. package/dist/server/index.js +749 -995
  16. package/dist/server/modules/products/index.d.ts +7 -26
  17. package/dist/server/modules/products/index.js +76 -167
  18. package/dist/server/modules/products/types.d.ts +0 -14
  19. package/dist/solution/BaseSales/index.d.ts +0 -2
  20. package/dist/solution/BaseSales/index.js +50 -36
  21. package/dist/solution/BookingByStep/index.d.ts +1 -1
  22. package/dist/solution/BookingTicket/index.js +21 -5
  23. package/dist/solution/BookingTicket/types.d.ts +0 -2
  24. package/dist/solution/ShopDiscount/index.js +14 -15
  25. package/lib/model/strategy/adapter/index.d.ts +0 -4
  26. package/lib/model/strategy/adapter/index.js +2 -13
  27. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  28. package/lib/modules/Discount/index.d.ts +2 -5
  29. package/lib/modules/Discount/index.js +3 -23
  30. package/lib/modules/Discount/types.d.ts +0 -4
  31. package/lib/modules/Order/index.d.ts +1 -1
  32. package/lib/modules/Order/index.js +36 -20
  33. package/lib/modules/Order/types.d.ts +0 -2
  34. package/lib/modules/Product/types.d.ts +0 -22
  35. package/lib/modules/ProductList/index.d.ts +1 -1
  36. package/lib/modules/ProductList/index.js +2 -4
  37. package/lib/modules/ProductList/types.d.ts +0 -2
  38. package/lib/server/index.d.ts +0 -50
  39. package/lib/server/index.js +29 -206
  40. package/lib/server/modules/products/index.d.ts +7 -26
  41. package/lib/server/modules/products/index.js +35 -114
  42. package/lib/server/modules/products/types.d.ts +0 -14
  43. package/lib/solution/BaseSales/index.d.ts +0 -2
  44. package/lib/solution/BaseSales/index.js +22 -12
  45. package/lib/solution/BookingByStep/index.d.ts +1 -1
  46. package/lib/solution/BookingTicket/index.js +18 -1
  47. package/lib/solution/BookingTicket/types.d.ts +0 -2
  48. package/lib/solution/ShopDiscount/index.js +1 -2
  49. package/package.json +1 -1
  50. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
  51. package/dist/model/strategy/adapter/dataVariant/adapter.js +0 -167
  52. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
  53. package/dist/model/strategy/adapter/dataVariant/evaluator.js +0 -780
  54. package/dist/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
  55. package/dist/model/strategy/adapter/dataVariant/examples.js +0 -277
  56. package/dist/model/strategy/adapter/dataVariant/index.d.ts +0 -4
  57. package/dist/model/strategy/adapter/dataVariant/index.js +0 -4
  58. package/dist/model/strategy/adapter/dataVariant/type.d.ts +0 -148
  59. package/dist/model/strategy/adapter/dataVariant/type.js +0 -54
  60. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +0 -50
  61. package/lib/model/strategy/adapter/dataVariant/adapter.js +0 -149
  62. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +0 -89
  63. package/lib/model/strategy/adapter/dataVariant/evaluator.js +0 -583
  64. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +0 -39
  65. package/lib/model/strategy/adapter/dataVariant/examples.js +0 -293
  66. package/lib/model/strategy/adapter/dataVariant/index.d.ts +0 -4
  67. package/lib/model/strategy/adapter/dataVariant/index.js +0 -38
  68. package/lib/model/strategy/adapter/dataVariant/type.d.ts +0 -148
  69. package/lib/model/strategy/adapter/dataVariant/type.js +0 -31
@@ -308,9 +308,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
308
308
  if (!this.store.summary) {
309
309
  this.store.summary = (0, import_utils.createEmptySummary)();
310
310
  }
311
- if (!Array.isArray(this.store.availableWalletIds)) {
312
- this.store.availableWalletIds = [];
313
- }
314
311
  this.request = this.core.getPlugin("request");
315
312
  const appPlugin = this.core.getPlugin("app");
316
313
  if (!appPlugin) {
@@ -438,19 +435,15 @@ var OrderModule = class extends import_BaseModule.BaseModule {
438
435
  async loadDiscountConfig(params) {
439
436
  var _a, _b, _c, _d, _e, _f, _g;
440
437
  const orderId = params.orderId || ((_a = this.store.tempOrder) == null ? void 0 : _a.order_id) || void 0;
441
- const prepareConfigResult = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
438
+ const discountList = await ((_b = this.store.discount) == null ? void 0 : _b.loadPrepareConfig({
442
439
  customer_id: params.customerId,
443
440
  action: params.action || (orderId ? "edit" : "create"),
444
441
  with_good_pass: 1,
445
442
  with_discount_card: 1,
446
443
  with_wallet_pass_holder: 1,
447
- with_available_wallet_flag: 1,
448
- with_available_wallet_pass_flag: 1,
449
444
  request_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
450
445
  ...orderId ? { order_id: orderId } : {}
451
446
  }));
452
- const discountList = prepareConfigResult == null ? void 0 : prepareConfigResult.discountList;
453
- this.store.availableWalletIds = (prepareConfigResult == null ? void 0 : prepareConfigResult.availableWalletIds) || [];
454
447
  if (discountList) {
455
448
  const currentDiscountList = ((_c = this.store.discount) == null ? void 0 : _c.getDiscountList()) || [];
456
449
  const currentEditDiscounts = currentDiscountList.filter((discount) => discount == null ? void 0 : discount.isEditMode);
@@ -484,8 +477,18 @@ var OrderModule = class extends import_BaseModule.BaseModule {
484
477
  var _a;
485
478
  return ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList()) || [];
486
479
  }
487
- getAvailableWalletIds() {
488
- return Array.isArray(this.store.availableWalletIds) ? [...this.store.availableWalletIds] : [];
480
+ async syncScannedDiscountsToOriginalDiscountList(discountList) {
481
+ var _a, _b, _c, _d;
482
+ const scanDiscounts = (discountList || []).filter((discount) => discount == null ? void 0 : discount.isScan);
483
+ if (!scanDiscounts.length)
484
+ return;
485
+ const scanDiscountIds = new Set(scanDiscounts.map((discount) => discount == null ? void 0 : discount.id));
486
+ const originalDiscounts = ((_b = (_a = this.store.discount) == null ? void 0 : _a.getOriginalDiscountList) == null ? void 0 : _b.call(_a)) || [];
487
+ const nextOriginalDiscounts = [
488
+ ...scanDiscounts,
489
+ ...originalDiscounts.filter((discount) => !scanDiscountIds.has(discount == null ? void 0 : discount.id))
490
+ ];
491
+ await ((_d = (_c = this.store.discount) == null ? void 0 : _c.setOriginalDiscountList) == null ? void 0 : _d.call(_c, nextOriginalDiscounts));
489
492
  }
490
493
  async ensureEditDiscountConfigForProductChange(tempOrder) {
491
494
  var _a, _b, _c, _d, _e, _f;
@@ -535,6 +538,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
535
538
  }));
536
539
  const currentSelected = this.getDiscountList().filter((n) => n.isSelected);
537
540
  if (currentSelected.length && currentSelected.some((n) => withScanList.some((m) => m.id === n.id))) {
541
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
538
542
  return {
539
543
  type: "clientCalc",
540
544
  isAvailable: true,
@@ -555,6 +559,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
555
559
  if (isAvailable && newDiscountList) {
556
560
  (_d = this.store.discount) == null ? void 0 : _d.setDiscountList(newDiscountList);
557
561
  this.applyDiscount();
562
+ await this.syncScannedDiscountsToOriginalDiscountList(this.getDiscountList());
558
563
  }
559
564
  return {
560
565
  type: "clientCalc",
@@ -2366,7 +2371,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2366
2371
  }
2367
2372
  const nextCustomerId = tempOrder.customer_id ?? null;
2368
2373
  if (String(previousCustomerId ?? "") !== String(nextCustomerId ?? "")) {
2369
- this.store.availableWalletIds = [];
2370
2374
  (0, import_utils.clearTempOrderHolderAssignments)(tempOrder);
2371
2375
  this.clearCustomerBoundDiscounts(tempOrder);
2372
2376
  this.applyDiscount();
@@ -2406,7 +2410,6 @@ var OrderModule = class extends import_BaseModule.BaseModule {
2406
2410
  tempOrder.customer = null;
2407
2411
  if (tempOrder._extend)
2408
2412
  delete tempOrder._extend.customerSnapshot;
2409
- this.store.availableWalletIds = [];
2410
2413
  this.clearCustomerBoundDiscounts(tempOrder);
2411
2414
  this.persistTempOrder();
2412
2415
  this.saveDraftInBackground();
@@ -3998,7 +4001,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
3998
4001
  async hydrateTempOrderFromRecord(record, options) {
3999
4002
  var _a, _b, _c;
4000
4003
  const raw = record && typeof record === "object" && record.data && record.order_id == null ? record.data : record || {};
4001
- const nextTempOrder = this.normalizeTempOrderForRuntime(raw);
4004
+ const nextTempOrder = this.normalizeTempOrderForRuntime(raw, { makeEditMark: true });
4002
4005
  const rawSummary = raw.summary && typeof raw.summary === "object" ? raw.summary : {};
4003
4006
  const summarySurcharges = Array.isArray(rawSummary.surcharges) ? rawSummary.surcharges.map((s) => ({ ...s || {} })) : (0, import_lodash_es.cloneDeep)(nextTempOrder.surcharges || []);
4004
4007
  this.store.tempOrder = nextTempOrder;
@@ -4021,14 +4024,25 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4021
4024
  this.store.lastOrderInfo = raw.lastOrderInfo || raw;
4022
4025
  const hydratedEditDiscounts = this.collectHydratedEditDiscounts(nextTempOrder.products);
4023
4026
  const currentDiscounts = typeof ((_a = this.store.discount) == null ? void 0 : _a.getDiscountList) === "function" ? this.store.discount.getDiscountList() || [] : [];
4024
- const shouldSkipEmptyDiscountSync = hydratedEditDiscounts.length === 0 && currentDiscounts.length === 0;
4027
+ const currentScanDiscounts = currentDiscounts.filter((discount) => discount == null ? void 0 : discount.isScan);
4028
+ const hydratedDiscountIds = new Set(
4029
+ hydratedEditDiscounts.map((discount) => discount == null ? void 0 : discount.id)
4030
+ );
4031
+ const retainedScanDiscounts = currentScanDiscounts.filter(
4032
+ (discount) => !hydratedDiscountIds.has(discount == null ? void 0 : discount.id)
4033
+ );
4034
+ const nextDiscounts = [
4035
+ ...hydratedEditDiscounts,
4036
+ ...retainedScanDiscounts
4037
+ ];
4038
+ const shouldSkipEmptyDiscountSync = nextDiscounts.length === 0 && currentDiscounts.length === 0;
4025
4039
  if (!shouldSkipEmptyDiscountSync) {
4026
4040
  OrderModule.populateSavedAmounts(
4027
4041
  nextTempOrder.products,
4028
- hydratedEditDiscounts
4042
+ nextDiscounts
4029
4043
  );
4030
- await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(hydratedEditDiscounts));
4031
- await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(hydratedEditDiscounts));
4044
+ await ((_b = this.store.discount) == null ? void 0 : _b.setOriginalDiscountList(nextDiscounts));
4045
+ await ((_c = this.store.discount) == null ? void 0 : _c.setDiscountList(nextDiscounts));
4032
4046
  }
4033
4047
  if (options == null ? void 0 : options.recalcOnHydrate) {
4034
4048
  await this.recalculateSummary({ createIfMissing: false });
@@ -4085,7 +4099,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4085
4099
  nextTempOrder.metadata = raw.metadata && typeof raw.metadata === "object" ? { ...raw.metadata } : {};
4086
4100
  nextTempOrder.holder = raw.holder && typeof raw.holder === "object" ? { ...raw.holder } : null;
4087
4101
  const rawProducts = Array.isArray(raw.products) ? raw.products : [];
4088
- nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p)) : [];
4102
+ nextTempOrder.products = rawProducts.length > 0 ? rawProducts.map((p) => this.normalizeHydratedOrderProduct(p, { makeEditMark: options == null ? void 0 : options.makeEditMark })) : [];
4089
4103
  nextTempOrder.bookings = Array.isArray(raw.bookings) ? raw.bookings.map((b) => {
4090
4104
  const booking = this.normalizeHydratedBookingHolder(b || {});
4091
4105
  return {
@@ -4231,7 +4245,7 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4231
4245
  normalized.id = optionItem.id;
4232
4246
  return normalized;
4233
4247
  }
4234
- normalizeHydratedOrderProduct(product) {
4248
+ normalizeHydratedOrderProduct(product, options) {
4235
4249
  let row = { ...product || {} };
4236
4250
  if (row.num === void 0 && row.product_quantity !== void 0) {
4237
4251
  row.num = row.product_quantity;
@@ -4258,7 +4272,9 @@ var OrderModule = class extends import_BaseModule.BaseModule {
4258
4272
  if (!existingIdentity) {
4259
4273
  row.metadata.unique_identification_number = (0, import_utils.createUuidV4)();
4260
4274
  }
4261
- row.metadata.is_edit_for_runtime = true;
4275
+ if (options == null ? void 0 : options.makeEditMark) {
4276
+ row.metadata.is_edit_for_runtime = true;
4277
+ }
4262
4278
  const normalized = (0, import_utils3.normalizeOrderProduct)(row);
4263
4279
  normalized.discount_list = (0, import_utils.normalizeOrderProductDiscountList)(
4264
4280
  normalized.discount_list
@@ -309,7 +309,6 @@ export interface OrderState {
309
309
  lastOrderInfo?: Record<string, any>;
310
310
  syncState?: OrderSyncState;
311
311
  discountList: any[];
312
- availableWalletIds?: number[];
313
312
  discount: DiscountModule | null;
314
313
  rules: RulesModule | null;
315
314
  }
@@ -776,7 +775,6 @@ export interface OrderModuleAPI {
776
775
  apply?: boolean;
777
776
  }) => Promise<Discount[]>;
778
777
  getDiscountList: () => Discount[];
779
- getAvailableWalletIds: () => number[];
780
778
  applyDiscount: () => void;
781
779
  /**
782
780
  * 注入促销评估器。
@@ -9,26 +9,6 @@ export interface ProductCollection {
9
9
  /** 商品集合封面 */
10
10
  cover: string;
11
11
  }
12
- /**
13
- * 商品 Data Variant 记录,结构与后端 data_variant 表对齐。
14
- */
15
- export interface ProductDataVariant {
16
- /** 变体记录 id */
17
- id: number;
18
- /** 店铺 id */
19
- shop_id: number;
20
- /** 所属模块,商品场景固定为 product */
21
- module: string;
22
- /** 模块数据 id,商品场景对应 product.id */
23
- module_data_id: number;
24
- /** 关联 data_variant_rule.id */
25
- data_variant_rule_id: number;
26
- /** 命中策略后覆盖到商品上的字段 */
27
- data: Record<string, any>;
28
- created_at: string | null;
29
- updated_at: string | null;
30
- deleted_at: string | null;
31
- }
32
12
  /**
33
13
  * 商品基本信息接口
34
14
  */
@@ -234,8 +214,6 @@ export interface ProductData {
234
214
  bundle_group_count: number;
235
215
  /** 选项组数量 */
236
216
  option_group_count: number;
237
- /** 智能定价变体列表,/product/query with dataVariants 返回 */
238
- data_variants?: ProductDataVariant[];
239
217
  /** 服务时长 */
240
218
  service_times?: any;
241
219
  }
@@ -26,7 +26,7 @@ export declare class ProductList extends BaseModule implements Module {
26
26
  * const products = await productList.getAddTimeProducts({ schedule_date: '2026-06-16' });
27
27
  */
28
28
  getAddTimeProducts(params?: ProductListLoadProductsParams): Promise<any>;
29
- 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?: {
29
+ loadProducts({ category_ids, product_ids, collection, menu_list_ids, customer_id: paramsCustomerId, with_count, schedule_datetime, schedule_date, cacheId, with_schedule, extension_type, status, }?: ProductListLoadProductsParams, options?: {
30
30
  callback?: (result: any) => void;
31
31
  subscriberId?: string;
32
32
  }): Promise<any>;
@@ -95,8 +95,7 @@ var ProductList = class extends import_BaseModule.BaseModule {
95
95
  cacheId,
96
96
  with_schedule,
97
97
  extension_type,
98
- status = "published",
99
- strategy_context
98
+ status = "published"
100
99
  } = {}, options) {
101
100
  var _a, _b;
102
101
  let userPlugin = this.core.getPlugin("user");
@@ -136,8 +135,7 @@ var ProductList = class extends import_BaseModule.BaseModule {
136
135
  is_eject: 1,
137
136
  with_schedule,
138
137
  schedule_datetime,
139
- extension_type,
140
- strategy_context
138
+ extension_type
141
139
  },
142
140
  { osServer: true, callback: options == null ? void 0 : options.callback, subscriberId: options == null ? void 0 : options.subscriberId, customToast: () => {
143
141
  } }
@@ -12,8 +12,6 @@ export interface ProductListLoadProductsParams {
12
12
  with_schedule?: number;
13
13
  extension_type?: string[];
14
14
  status?: string;
15
- /** 智能定价条件上下文,仅影响策略命中,不参与商品集合筛选 */
16
- strategy_context?: Record<string, any>;
17
15
  }
18
16
  export interface ProductListData {
19
17
  list: ProductData[];
@@ -47,8 +47,6 @@ declare class Server {
47
47
  private prefixRouterGet;
48
48
  router: Router;
49
49
  private productQuerySubscribers;
50
- /** subscriberId → 智能定价变价时间点定时器句柄(与 subscriber 分离存储,便于 clear) */
51
- private productQueryScheduleTimers;
52
50
  private orderQuerySubscribers;
53
51
  private bookingQuerySubscribers;
54
52
  private bookingRemoteQuerySubscribers;
@@ -212,48 +210,6 @@ declare class Server {
212
210
  * 根据 subscriberId 移除商品查询订阅者
213
211
  */
214
212
  removeProductQuerySubscriber(subscriberId?: string): void;
215
- /**
216
- * 构建商品 query 响应 data 段,附带智能定价 schedule_time_points 元数据。
217
- */
218
- private buildProductQueryResultPayload;
219
- /**
220
- * 是否启用商品 query 订阅的 schedule 时间点定时重算。
221
- * strategy_context.enable_schedule_reload === false 时关闭。
222
- */
223
- private shouldScheduleProductQueryReload;
224
- /**
225
- * 清除指定 subscriber 的全部 schedule 定时器,防止重复 query 或 unsubscribe 后泄漏。
226
- */
227
- private clearSubscriberScheduleTimers;
228
- /**
229
- * 从 productQueryScheduleTimers 移除已触发的 timer 引用。
230
- */
231
- private removeScheduleTimerRef;
232
- /**
233
- * 计算 schedule 变价时间点到当前时刻的延迟(ms)。已过期返回 -1。
234
- */
235
- private computeScheduleTimePointDelayMs;
236
- /**
237
- * 定时重算前刷新 subscriber schedule 上下文:使用执行瞬间时间,禁止沿用首次 query 的 schedule_datetime。
238
- */
239
- private refreshSubscriberScheduleAtExecution;
240
- /**
241
- * 为 subscriber 注册智能定价 scheduleTimePoints 定时重算。
242
- * 必须先 clearSubscriberScheduleTimers,再调用本方法。
243
- */
244
- private scheduleSubscriberTimePointReloads;
245
- /**
246
- * schedule 变价时间点定时器触发:刷新 schedule_datetime 后重算并 callback。
247
- */
248
- private onScheduleTimePointTimerFire;
249
- /**
250
- * 对单个商品 query 订阅者重算并推送(定时路径;不新建 schedule timer)。
251
- */
252
- private recomputeAndNotifySubscriber;
253
- /**
254
- * query 完成后为 subscriber 同步 schedule 定时器(先 clear 再 schedule)。
255
- */
256
- private syncProductQueryScheduleTimers;
257
213
  /**
258
214
  * 处理商品查询请求
259
215
  * 存储订阅者信息,便于数据变更时推送最新结果
@@ -614,12 +570,6 @@ declare class Server {
614
570
  * @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
615
571
  */
616
572
  private computeProductQueryResult;
617
- /**
618
- * 构建商品格式化上下文。
619
- *
620
- * 智能定价条件使用全量 menuList/scheduleList;Product Query 顶层参数只保留筛选商品集合所需字段。
621
- */
622
- private buildProductFormatterContext;
623
573
  /**
624
574
  * 数据变更后,遍历所有订阅者重新计算查询结果并通过 callback 推送
625
575
  * 由 ProductsModule 的 onProductsSyncCompleted 事件触发
@@ -76,8 +76,6 @@ var Server = class {
76
76
  };
77
77
  // ---- 商品查询订阅者 ----
78
78
  this.productQuerySubscribers = /* @__PURE__ */ new Map();
79
- /** subscriberId → 智能定价变价时间点定时器句柄(与 subscriber 分离存储,便于 clear) */
80
- this.productQueryScheduleTimers = /* @__PURE__ */ new Map();
81
79
  // ---- 订单 / 预约列表查询订阅者 ----
82
80
  this.orderQuerySubscribers = /* @__PURE__ */ new Map();
83
81
  this.bookingQuerySubscribers = /* @__PURE__ */ new Map();
@@ -210,7 +208,7 @@ var Server = class {
210
208
  */
211
209
  this.handleProductQuery = async ({ url, method, data, config }) => {
212
210
  console.log("[Server] handleProductQuery:", url, method, data, config);
213
- const { menu_list_ids, schedule_datetime, schedule_date, customer_id, ids, extension_type, strategy_context } = data;
211
+ const { menu_list_ids, schedule_datetime, schedule_date, customer_id, ids, extension_type } = data;
214
212
  const { callback, subscriberId } = config || {};
215
213
  this.logInfo("handleProductQuery: 开始处理商品查询请求", {
216
214
  menu_list_ids,
@@ -218,32 +216,19 @@ var Server = class {
218
216
  schedule_datetime,
219
217
  schedule_date,
220
218
  customer_id,
221
- extension_type,
222
- strategyContextKeys: strategy_context ? Object.keys(strategy_context) : []
219
+ extension_type
223
220
  });
224
221
  if (subscriberId && typeof callback === "function") {
225
222
  this.productQuerySubscribers.set(subscriberId, {
226
223
  callback,
227
- context: { menu_list_ids, ids, schedule_date, schedule_datetime, customer_id, extension_type, strategy_context }
224
+ context: { menu_list_ids, ids, schedule_date, schedule_datetime, customer_id, extension_type }
228
225
  });
229
226
  this.logInfo("handleProductQuery: 已注册订阅者", {
230
227
  subscriberId,
231
228
  totalSubscribers: this.productQuerySubscribers.size
232
229
  });
233
230
  }
234
- const result = await this.computeProductQueryResult({
235
- menu_list_ids,
236
- ids,
237
- schedule_date,
238
- schedule_datetime,
239
- customer_id,
240
- extension_type,
241
- strategy_context
242
- });
243
- if (subscriberId && typeof callback === "function") {
244
- this.syncProductQueryScheduleTimers(subscriberId, strategy_context);
245
- }
246
- return result;
231
+ return this.computeProductQueryResult({ menu_list_ids, ids, schedule_date, schedule_datetime, customer_id, extension_type });
247
232
  };
248
233
  /**
249
234
  * 按商品 id 查询单条(GET /shop/product/query/:productId)
@@ -1926,7 +1911,6 @@ var Server = class {
1926
1911
  */
1927
1912
  removeProductQuerySubscriber(subscriberId) {
1928
1913
  if (subscriberId) {
1929
- this.clearSubscriberScheduleTimers(subscriberId);
1930
1914
  this.productQuerySubscribers.delete(subscriberId);
1931
1915
  this.logInfo("removeProductQuerySubscriber: 已移除订阅者", {
1932
1916
  subscriberId,
@@ -1934,156 +1918,6 @@ var Server = class {
1934
1918
  });
1935
1919
  }
1936
1920
  }
1937
- /**
1938
- * 构建商品 query 响应 data 段,附带智能定价 schedule_time_points 元数据。
1939
- */
1940
- buildProductQueryResultPayload(list, count) {
1941
- var _a, _b;
1942
- return {
1943
- list,
1944
- count: count ?? list.length,
1945
- schedule_time_points: ((_b = (_a = this.products) == null ? void 0 : _a.getLastScheduleTimePoints) == null ? void 0 : _b.call(_a)) ?? []
1946
- };
1947
- }
1948
- /**
1949
- * 是否启用商品 query 订阅的 schedule 时间点定时重算。
1950
- * strategy_context.enable_schedule_reload === false 时关闭。
1951
- */
1952
- shouldScheduleProductQueryReload(strategy_context) {
1953
- return (strategy_context == null ? void 0 : strategy_context.enable_schedule_reload) !== false;
1954
- }
1955
- /**
1956
- * 清除指定 subscriber 的全部 schedule 定时器,防止重复 query 或 unsubscribe 后泄漏。
1957
- */
1958
- clearSubscriberScheduleTimers(subscriberId) {
1959
- const timers = this.productQueryScheduleTimers.get(subscriberId);
1960
- if (timers == null ? void 0 : timers.length) {
1961
- timers.forEach((timerId) => clearTimeout(timerId));
1962
- }
1963
- this.productQueryScheduleTimers.delete(subscriberId);
1964
- const subscriber = this.productQuerySubscribers.get(subscriberId);
1965
- if (subscriber) {
1966
- subscriber.scheduleTimerIds = [];
1967
- }
1968
- }
1969
- /**
1970
- * 从 productQueryScheduleTimers 移除已触发的 timer 引用。
1971
- */
1972
- removeScheduleTimerRef(subscriberId, timerId) {
1973
- const timers = this.productQueryScheduleTimers.get(subscriberId);
1974
- if (!(timers == null ? void 0 : timers.length))
1975
- return;
1976
- const next = timers.filter((id) => id !== timerId);
1977
- if (next.length === 0) {
1978
- this.productQueryScheduleTimers.delete(subscriberId);
1979
- } else {
1980
- this.productQueryScheduleTimers.set(subscriberId, next);
1981
- }
1982
- const subscriber = this.productQuerySubscribers.get(subscriberId);
1983
- if (subscriber) {
1984
- subscriber.scheduleTimerIds = next;
1985
- }
1986
- }
1987
- /**
1988
- * 计算 schedule 变价时间点到当前时刻的延迟(ms)。已过期返回 -1。
1989
- */
1990
- computeScheduleTimePointDelayMs(scheduleDate, timePoint) {
1991
- const parts = timePoint.split(":");
1992
- if (parts.length < 2)
1993
- return -1;
1994
- const hours = parseInt(parts[0], 10);
1995
- const minutes = parseInt(parts[1], 10);
1996
- if (!Number.isFinite(hours) || !Number.isFinite(minutes))
1997
- return -1;
1998
- const target = (0, import_dayjs.default)(scheduleDate).hour(hours).minute(minutes).second(4).millisecond(0);
1999
- const delayMs = target.diff((0, import_dayjs.default)());
2000
- return delayMs >= 0 ? delayMs : -1;
2001
- }
2002
- /**
2003
- * 定时重算前刷新 subscriber schedule 上下文:使用执行瞬间时间,禁止沿用首次 query 的 schedule_datetime。
2004
- */
2005
- refreshSubscriberScheduleAtExecution(subscriber) {
2006
- const executedAt = (0, import_dayjs.default)();
2007
- const bookingDate = subscriber.context.schedule_date || executedAt.format("YYYY-MM-DD");
2008
- subscriber.context.schedule_date = bookingDate;
2009
- subscriber.context.schedule_datetime = `${bookingDate} ${executedAt.format("HH:mm:ss")}`;
2010
- }
2011
- /**
2012
- * 为 subscriber 注册智能定价 scheduleTimePoints 定时重算。
2013
- * 必须先 clearSubscriberScheduleTimers,再调用本方法。
2014
- */
2015
- scheduleSubscriberTimePointReloads(subscriberId, timePoints) {
2016
- const subscriber = this.productQuerySubscribers.get(subscriberId);
2017
- if (!subscriber || !timePoints.length)
2018
- return;
2019
- const scheduleDate = subscriber.context.schedule_date || (0, import_dayjs.default)().format("YYYY-MM-DD");
2020
- const timerIds = [];
2021
- for (const timePoint of timePoints) {
2022
- const delayMs = this.computeScheduleTimePointDelayMs(scheduleDate, timePoint);
2023
- if (delayMs < 0)
2024
- continue;
2025
- const timerId = setTimeout(() => {
2026
- void this.onScheduleTimePointTimerFire(subscriberId, timerId);
2027
- }, delayMs);
2028
- timerIds.push(timerId);
2029
- }
2030
- if (timerIds.length > 0) {
2031
- this.productQueryScheduleTimers.set(subscriberId, timerIds);
2032
- subscriber.scheduleTimerIds = timerIds;
2033
- this.logInfo("scheduleSubscriberTimePointReloads: 已注册定时器", {
2034
- subscriberId,
2035
- timerCount: timerIds.length,
2036
- timePoints
2037
- });
2038
- }
2039
- }
2040
- /**
2041
- * schedule 变价时间点定时器触发:刷新 schedule_datetime 后重算并 callback。
2042
- */
2043
- async onScheduleTimePointTimerFire(subscriberId, timerId) {
2044
- this.removeScheduleTimerRef(subscriberId, timerId);
2045
- if (!this.productQuerySubscribers.has(subscriberId))
2046
- return;
2047
- const subscriber = this.productQuerySubscribers.get(subscriberId);
2048
- this.refreshSubscriberScheduleAtExecution(subscriber);
2049
- await this.recomputeAndNotifySubscriber(subscriberId);
2050
- }
2051
- /**
2052
- * 对单个商品 query 订阅者重算并推送(定时路径;不新建 schedule timer)。
2053
- */
2054
- async recomputeAndNotifySubscriber(subscriberId) {
2055
- const subscriber = this.productQuerySubscribers.get(subscriberId);
2056
- if (!subscriber)
2057
- return;
2058
- try {
2059
- const result = await this.computeProductQueryResult(subscriber.context);
2060
- subscriber.callback(result);
2061
- this.logInfo("recomputeAndNotifySubscriber: 已推送", {
2062
- subscriberId,
2063
- schedule_datetime: subscriber.context.schedule_datetime
2064
- });
2065
- } catch (error) {
2066
- const errorMessage = error instanceof Error ? error.message : String(error);
2067
- this.logError("recomputeAndNotifySubscriber: 推送失败", {
2068
- subscriberId,
2069
- error: errorMessage
2070
- });
2071
- }
2072
- }
2073
- /**
2074
- * query 完成后为 subscriber 同步 schedule 定时器(先 clear 再 schedule)。
2075
- */
2076
- syncProductQueryScheduleTimers(subscriberId, strategy_context) {
2077
- var _a, _b;
2078
- this.clearSubscriberScheduleTimers(subscriberId);
2079
- if (!this.shouldScheduleProductQueryReload(strategy_context)) {
2080
- return;
2081
- }
2082
- const timePoints = ((_b = (_a = this.products) == null ? void 0 : _a.getLastScheduleTimePoints) == null ? void 0 : _b.call(_a)) ?? [];
2083
- if (timePoints.length > 0) {
2084
- this.scheduleSubscriberTimePointReloads(subscriberId, timePoints);
2085
- }
2086
- }
2087
1921
  /**
2088
1922
  * 执行 sales 搜索并登记可见订单号。
2089
1923
  * 搜索参数完全透传后端,OS 不做过滤、筛选、排序。
@@ -4277,14 +4111,8 @@ var Server = class {
4277
4111
  */
4278
4112
  async computeProductQueryResult(context, options) {
4279
4113
  const tTotal = performance.now();
4280
- const { menu_list_ids, ids, schedule_date, schedule_datetime, customer_id, extension_type, product_id, strategy_context } = context;
4114
+ const { menu_list_ids, ids, schedule_date, schedule_datetime, customer_id, extension_type, product_id } = context;
4281
4115
  const queryIds = Array.isArray(ids) ? ids.map((id) => Number(id)).filter((id) => Number.isFinite(id)) : [];
4282
- const formatterContext = this.buildProductFormatterContext({
4283
- schedule_date,
4284
- schedule_datetime,
4285
- customer_id,
4286
- strategy_context
4287
- });
4288
4116
  this.logInfo("computeProductQueryResult 开始", {
4289
4117
  menuListIdsCount: (menu_list_ids == null ? void 0 : menu_list_ids.length) ?? 0,
4290
4118
  ids: queryIds,
@@ -4293,17 +4121,20 @@ var Server = class {
4293
4121
  customer_id,
4294
4122
  extension_type,
4295
4123
  product_id,
4296
- strategyContextKeys: strategy_context ? Object.keys(strategy_context) : [],
4297
4124
  changedIds: options == null ? void 0 : options.changedIds
4298
4125
  });
4299
4126
  if (!this.products) {
4300
4127
  this.logError("computeProductQueryResult: Products 模块未注册");
4301
- return { message: "Products 模块未注册", data: this.buildProductQueryResultPayload([], 0) };
4128
+ return { message: "Products 模块未注册", data: { list: [], count: 0 } };
4302
4129
  }
4303
4130
  if (queryIds.length > 0) {
4304
4131
  const uniqueIds = Array.from(new Set(queryIds));
4305
4132
  const tPrice2 = performance.now();
4306
- const productsWithPrice = await this.products.getProductsWithPrice(schedule_date, formatterContext, {
4133
+ const productsWithPrice = await this.products.getProductsWithPrice(schedule_date, {
4134
+ scheduleModule: this.getSchedule(),
4135
+ schedule_datetime,
4136
+ customer_id
4137
+ }, {
4307
4138
  changedIds: options == null ? void 0 : options.changedIds,
4308
4139
  productIds: uniqueIds
4309
4140
  });
@@ -4324,7 +4155,7 @@ var Server = class {
4324
4155
  });
4325
4156
  return {
4326
4157
  code: 200,
4327
- data: this.buildProductQueryResultPayload(extensionFilteredProducts),
4158
+ data: { list: extensionFilteredProducts, count: extensionFilteredProducts.length },
4328
4159
  message: "",
4329
4160
  status: true
4330
4161
  };
@@ -4332,7 +4163,9 @@ var Server = class {
4332
4163
  if (product_id != null && Number.isFinite(Number(product_id))) {
4333
4164
  const pid = Number(product_id);
4334
4165
  const tPrice2 = performance.now();
4335
- const allProductsWithPrice = await this.products.getProductsWithPrice(schedule_date, formatterContext, {
4166
+ const allProductsWithPrice = await this.products.getProductsWithPrice(schedule_date, {
4167
+ scheduleModule: this.getSchedule()
4168
+ }, {
4336
4169
  changedIds: options == null ? void 0 : options.changedIds
4337
4170
  });
4338
4171
  (0, import_product.perfMark)("computeQuery.getProductsWithPrice(single)", performance.now() - tPrice2, {
@@ -4362,7 +4195,11 @@ var Server = class {
4362
4195
  }
4363
4196
  if (this.shouldQueryProductsByExtensionTypes(extension_type)) {
4364
4197
  const tPrice2 = performance.now();
4365
- let filteredProducts2 = await this.products.getProductsWithPrice(schedule_date, formatterContext, {
4198
+ let filteredProducts2 = await this.products.getProductsWithPrice(schedule_date, {
4199
+ scheduleModule: this.getSchedule(),
4200
+ schedule_datetime,
4201
+ customer_id
4202
+ }, {
4366
4203
  changedIds: options == null ? void 0 : options.changedIds
4367
4204
  });
4368
4205
  (0, import_product.perfMark)("computeQuery.getProductsWithPrice(extensionType)", performance.now() - tPrice2, {
@@ -4402,18 +4239,18 @@ var Server = class {
4402
4239
  });
4403
4240
  return {
4404
4241
  code: 200,
4405
- data: this.buildProductQueryResultPayload(filteredProducts2),
4242
+ data: { list: filteredProducts2, count: filteredProducts2.length },
4406
4243
  message: "",
4407
4244
  status: true
4408
4245
  };
4409
4246
  }
4410
4247
  if (!this.menu) {
4411
4248
  this.logError("computeProductQueryResult: Menu 模块未注册");
4412
- return { message: "Menu 模块未注册", data: this.buildProductQueryResultPayload([], 0) };
4249
+ return { message: "Menu 模块未注册", data: { list: [], count: 0 } };
4413
4250
  }
4414
4251
  if (!this.schedule) {
4415
4252
  this.logError("computeProductQueryResult: Schedule 模块未注册");
4416
- return { message: "Schedule 模块未注册", data: this.buildProductQueryResultPayload([], 0) };
4253
+ return { message: "Schedule 模块未注册", data: { list: [], count: 0 } };
4417
4254
  }
4418
4255
  let activeMenuList = [];
4419
4256
  if (menu_list_ids && Array.isArray(menu_list_ids) && menu_list_ids.length > 0) {
@@ -4437,7 +4274,11 @@ var Server = class {
4437
4274
  isAllProducts: !!productScope.isAllProducts
4438
4275
  });
4439
4276
  const tPrice = performance.now();
4440
- let filteredProducts = scopedProductIds.length > 0 ? await this.products.getProductsWithPrice(schedule_date, formatterContext, {
4277
+ let filteredProducts = scopedProductIds.length > 0 ? await this.products.getProductsWithPrice(schedule_date, {
4278
+ scheduleModule: this.getSchedule(),
4279
+ schedule_datetime,
4280
+ customer_id
4281
+ }, {
4441
4282
  changedIds: options == null ? void 0 : options.changedIds,
4442
4283
  productIds: productScope.isAllProducts ? void 0 : scopedProductIds
4443
4284
  }) : [];
@@ -4480,29 +4321,11 @@ var Server = class {
4480
4321
  });
4481
4322
  return {
4482
4323
  code: 200,
4483
- data: this.buildProductQueryResultPayload(filteredProducts),
4324
+ data: { list: filteredProducts, count: filteredProducts.length },
4484
4325
  message: "",
4485
4326
  status: true
4486
4327
  };
4487
4328
  }
4488
- /**
4489
- * 构建商品格式化上下文。
4490
- *
4491
- * 智能定价条件使用全量 menuList/scheduleList;Product Query 顶层参数只保留筛选商品集合所需字段。
4492
- */
4493
- buildProductFormatterContext(context) {
4494
- var _a, _b, _c, _d;
4495
- const scheduleModule = this.getSchedule();
4496
- return {
4497
- scheduleModule,
4498
- schedule_datetime: context.schedule_datetime,
4499
- customer_id: context.customer_id,
4500
- strategy_context: context.strategy_context,
4501
- menuList: ((_b = (_a = this.menu) == null ? void 0 : _a.getMenuList) == null ? void 0 : _b.call(_a)) || [],
4502
- scheduleList: ((_c = scheduleModule == null ? void 0 : scheduleModule.getScheduleList) == null ? void 0 : _c.call(scheduleModule)) || [],
4503
- dataVariantEvaluator: (_d = this.core.context) == null ? void 0 : _d.dataVariantEvaluator
4504
- };
4505
- }
4506
4329
  /**
4507
4330
  * 数据变更后,遍历所有订阅者重新计算查询结果并通过 callback 推送
4508
4331
  * 由 ProductsModule 的 onProductsSyncCompleted 事件触发