@pisell/pisellos 2.2.258 → 2.2.260

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 (90) hide show
  1. package/dist/model/strategy/adapter/dataVariant/adapter.d.ts +49 -0
  2. package/dist/model/strategy/adapter/dataVariant/adapter.js +152 -0
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.d.ts +87 -0
  4. package/dist/model/strategy/adapter/dataVariant/evaluator.js +755 -0
  5. package/dist/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  6. package/dist/model/strategy/adapter/dataVariant/examples.js +282 -0
  7. package/dist/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  8. package/dist/model/strategy/adapter/dataVariant/index.js +4 -0
  9. package/dist/model/strategy/adapter/dataVariant/type.d.ts +146 -0
  10. package/dist/model/strategy/adapter/dataVariant/type.js +54 -0
  11. package/dist/model/strategy/adapter/index.d.ts +4 -0
  12. package/dist/model/strategy/adapter/index.js +5 -1
  13. package/dist/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +13 -17
  14. package/dist/modules/Order/index.d.ts +2 -30
  15. package/dist/modules/Order/index.js +241 -508
  16. package/dist/modules/Order/types.d.ts +2 -20
  17. package/dist/modules/Order/utils.d.ts +0 -4
  18. package/dist/modules/Order/utils.js +28 -114
  19. package/dist/modules/Product/index.d.ts +1 -1
  20. package/dist/modules/Product/types.d.ts +22 -0
  21. package/dist/modules/ProductList/index.d.ts +1 -1
  22. package/dist/modules/ProductList/index.js +4 -2
  23. package/dist/modules/ProductList/types.d.ts +2 -0
  24. package/dist/modules/Rules/index.d.ts +3 -3
  25. package/dist/modules/Rules/index.js +3 -8
  26. package/dist/modules/Rules/types.d.ts +1 -2
  27. package/dist/server/index.d.ts +50 -3
  28. package/dist/server/index.js +958 -1000
  29. package/dist/server/modules/order/index.d.ts +3 -22
  30. package/dist/server/modules/order/index.js +314 -397
  31. package/dist/server/modules/products/index.d.ts +26 -7
  32. package/dist/server/modules/products/index.js +166 -76
  33. package/dist/server/modules/products/types.d.ts +14 -0
  34. package/dist/solution/BaseSales/index.d.ts +2 -16
  35. package/dist/solution/BaseSales/index.js +314 -484
  36. package/dist/solution/BaseSales/types.d.ts +0 -1
  37. package/dist/solution/BaseSales/types.js +1 -2
  38. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +2 -4
  39. package/dist/solution/BookingByStep/index.d.ts +1 -1
  40. package/dist/solution/BookingTicket/index.d.ts +1 -9
  41. package/dist/solution/BookingTicket/index.js +6 -162
  42. package/dist/solution/BookingTicket/types.d.ts +2 -0
  43. package/lib/model/strategy/adapter/dataVariant/adapter.d.ts +49 -0
  44. package/lib/model/strategy/adapter/dataVariant/adapter.js +139 -0
  45. package/lib/model/strategy/adapter/dataVariant/evaluator.d.ts +87 -0
  46. package/lib/model/strategy/adapter/dataVariant/evaluator.js +564 -0
  47. package/lib/model/strategy/adapter/dataVariant/examples.d.ts +39 -0
  48. package/lib/model/strategy/adapter/dataVariant/examples.js +295 -0
  49. package/lib/model/strategy/adapter/dataVariant/index.d.ts +4 -0
  50. package/lib/model/strategy/adapter/dataVariant/index.js +38 -0
  51. package/lib/model/strategy/adapter/dataVariant/type.d.ts +146 -0
  52. package/lib/model/strategy/adapter/dataVariant/type.js +31 -0
  53. package/lib/model/strategy/adapter/index.d.ts +4 -0
  54. package/lib/model/strategy/adapter/index.js +13 -2
  55. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  56. package/lib/modules/BookingContext/utils/buildCacheItemFromOrderLine.js +1 -11
  57. package/lib/modules/Order/index.d.ts +2 -30
  58. package/lib/modules/Order/index.js +57 -340
  59. package/lib/modules/Order/types.d.ts +2 -20
  60. package/lib/modules/Order/utils.d.ts +0 -4
  61. package/lib/modules/Order/utils.js +2 -84
  62. package/lib/modules/Product/index.d.ts +1 -1
  63. package/lib/modules/Product/types.d.ts +22 -0
  64. package/lib/modules/ProductList/index.d.ts +1 -1
  65. package/lib/modules/ProductList/index.js +4 -2
  66. package/lib/modules/ProductList/types.d.ts +2 -0
  67. package/lib/modules/Rules/index.d.ts +3 -3
  68. package/lib/modules/Rules/index.js +3 -4
  69. package/lib/modules/Rules/types.d.ts +1 -2
  70. package/lib/server/index.d.ts +50 -3
  71. package/lib/server/index.js +215 -230
  72. package/lib/server/modules/order/index.d.ts +3 -22
  73. package/lib/server/modules/order/index.js +51 -102
  74. package/lib/server/modules/products/index.d.ts +26 -7
  75. package/lib/server/modules/products/index.js +113 -35
  76. package/lib/server/modules/products/types.d.ts +14 -0
  77. package/lib/solution/BaseSales/index.d.ts +2 -16
  78. package/lib/solution/BaseSales/index.js +31 -143
  79. package/lib/solution/BaseSales/types.d.ts +0 -1
  80. package/lib/solution/BaseSales/types.js +1 -2
  81. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +5 -4
  82. package/lib/solution/BookingByStep/index.d.ts +1 -1
  83. package/lib/solution/BookingTicket/index.d.ts +1 -9
  84. package/lib/solution/BookingTicket/index.js +0 -112
  85. package/lib/solution/BookingTicket/types.d.ts +2 -0
  86. package/package.json +1 -1
  87. package/dist/modules/Order/utils/bundleDiscountHydration.d.ts +0 -5
  88. package/dist/modules/Order/utils/bundleDiscountHydration.js +0 -144
  89. package/lib/modules/Order/utils/bundleDiscountHydration.d.ts +0 -5
  90. package/lib/modules/Order/utils/bundleDiscountHydration.js +0 -139
@@ -18,7 +18,8 @@ export declare class ProductsModule extends BaseModule implements Module {
18
18
  private productsPriceCache;
19
19
  private readonly CACHE_MAX_DAYS;
20
20
  private formatters;
21
- private isPriceFormatterRegistered;
21
+ private isBuiltinFormatterRegistered;
22
+ private isLegacyPriceFormatterEnabled;
22
23
  private quotationPriceBridge?;
23
24
  private quotationBridgeChannel?;
24
25
  private quotationBridgeLoadedKey?;
@@ -36,6 +37,8 @@ export declare class ProductsModule extends BaseModule implements Module {
36
37
  private lastPreloadCompletedAtMs;
37
38
  /** IndexDB 写入串行队列,避免快照与 patch 并发交错 */
38
39
  private productIndexDBSaveQueue;
40
+ /** 最近一次智能定价评估提取的 schedule 变价时间点(HH:mm),供 Server 订阅定时刷新使用 */
41
+ private lastScheduleTimePoints;
39
42
  constructor(name?: string, version?: string);
40
43
  initialize(core: PisellCore, options: any): Promise<void>;
41
44
  /**
@@ -108,6 +111,10 @@ export declare class ProductsModule extends BaseModule implements Module {
108
111
  */
109
112
  private prepareProductsWithPrice;
110
113
  private getProductsPriceCacheKey;
114
+ /**
115
+ * 稳定序列化策略上下文,避免对象 key 顺序不同导致缓存 key 抖动。
116
+ */
117
+ private stringifyStable;
111
118
  private normalizeProductIds;
112
119
  /**
113
120
  * 按轻量范围返回商品 ID,不做 structuredClone。
@@ -122,14 +129,26 @@ export declare class ProductsModule extends BaseModule implements Module {
122
129
  */
123
130
  private applyFormatters;
124
131
  /**
125
- * 注册内置的价格格式化器
126
- * 这个格式化器负责将价格数据应用到商品上
132
+ * 注册内置商品格式化器。
133
+ *
134
+ * 智能定价默认替代报价单逻辑;报价单 formatter 仅在 enableLegacyPriceFormatter=true 时启用。
127
135
  * @private
128
136
  */
129
- private registerBuiltinPriceFormatter;
137
+ private registerBuiltinProductFormatters;
138
+ /**
139
+ * 是否启用旧报价单价格 formatter。
140
+ *
141
+ * 默认关闭,避免报价单逻辑覆盖智能定价结果。
142
+ */
143
+ private shouldEnableLegacyPriceFormatter;
144
+ /**
145
+ * 返回最近一次 prepareProductsWithPrice / DataVariant 评估提取的变价时间点(HH:mm)。
146
+ * 供 OS Server 商品 query 订阅定时刷新使用。
147
+ */
148
+ getLastScheduleTimePoints(): string[];
130
149
  /**
131
150
  * 注册商品格式化器
132
- * 格式化器会按注册顺序依次执行(内置价格格式化器始终是第一个)
151
+ * 格式化器会按注册顺序依次执行;legacy 启用时先兜底报价,再由智能定价覆盖。
133
152
  * @param formatter 格式化函数
134
153
  * @param prepend 是否插入到队列开头(默认 false,追加到末尾)
135
154
  * @example
@@ -144,8 +163,8 @@ export declare class ProductsModule extends BaseModule implements Module {
144
163
  */
145
164
  registerFormatter(formatter: ProductFormatter, prepend?: boolean): void;
146
165
  /**
147
- * 清空所有格式化器(包括内置价格格式化器)
148
- * @param keepBuiltin 是否保留内置价格格式化器(默认 true)
166
+ * 清空所有格式化器(包括内置智能定价格式化器)
167
+ * @param keepBuiltin 是否保留内置智能定价格式化器(默认 true)
149
168
  */
150
169
  clearFormatters(keepBuiltin?: boolean): void;
151
170
  /**
@@ -1,12 +1,12 @@
1
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
1
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
7
2
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
3
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
9
4
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
5
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
6
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
7
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
8
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
9
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
10
10
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
11
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
12
  function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
@@ -32,7 +32,6 @@ import { BaseModule } from "../../../modules/BaseModule";
32
32
  import { QuotationModule as ClientQuotationModule } from "../../../modules/Quotation";
33
33
  import { ProductsHooks } from "./types";
34
34
  import { applyDetailValueToProducts, applyPriceDataToProducts, applyI18nToProducts, perfMark } from "../../utils/product";
35
-
36
35
  /**
37
36
  * IndexDB 存储名称
38
37
  */
@@ -69,8 +68,10 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
69
68
  // 最多缓存7天
70
69
  // 商品格式化器列表
71
70
  _defineProperty(_assertThisInitialized(_this), "formatters", []);
72
- // 是否已注册内置价格格式化器
73
- _defineProperty(_assertThisInitialized(_this), "isPriceFormatterRegistered", false);
71
+ // 是否已注册内置商品格式化器
72
+ _defineProperty(_assertThisInitialized(_this), "isBuiltinFormatterRegistered", false);
73
+ // 旧报价单格式化器默认关闭,仅显式开启时作为兼容兜底注册
74
+ _defineProperty(_assertThisInitialized(_this), "isLegacyPriceFormatterEnabled", false);
74
75
  // 普通层 QuotationModule 桥接器:本地计算报价单价格,替代 /product/query/price
75
76
  _defineProperty(_assertThisInitialized(_this), "quotationPriceBridge", void 0);
76
77
  _defineProperty(_assertThisInitialized(_this), "quotationBridgeChannel", void 0);
@@ -90,6 +91,8 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
90
91
  _defineProperty(_assertThisInitialized(_this), "lastPreloadCompletedAtMs", 0);
91
92
  /** IndexDB 写入串行队列,避免快照与 patch 并发交错 */
92
93
  _defineProperty(_assertThisInitialized(_this), "productIndexDBSaveQueue", Promise.resolve());
94
+ /** 最近一次智能定价评估提取的 schedule 变价时间点(HH:mm),供 Server 订阅定时刷新使用 */
95
+ _defineProperty(_assertThisInitialized(_this), "lastScheduleTimePoints", []);
93
96
  return _this;
94
97
  }
95
98
  _createClass(ProductsModule, [{
@@ -128,8 +131,8 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
128
131
  }
129
132
  }
130
133
 
131
- // 注册内置的价格格式化器(作为第一个格式化器)
132
- this.registerBuiltinPriceFormatter();
134
+ // 注册内置商品格式化器;智能定价默认替代报价单价格逻辑
135
+ this.registerBuiltinProductFormatters();
133
136
 
134
137
  // 初始化 ProductDataSource 实例
135
138
  this.initProductDataSource();
@@ -743,7 +746,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
743
746
  key: "prepareProductsWithPrice",
744
747
  value: (function () {
745
748
  var _prepareProductsWithPrice = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(schedule_date, extraContext, options) {
746
- var tTotal, targetIds, isIncremental, _priceData$length, _this$core, products, ids, tIds, i, tPrice, priceData, context, tFormat, processedProducts, errorMessage;
749
+ var tTotal, targetIds, isIncremental, _this$core, _this$core2, products, ids, tIds, i, priceData, _priceData$length, _priceData, tPrice, context, tFormat, processedProducts, errorMessage;
747
750
  return _regeneratorRuntime().wrap(function _callee7$(_context7) {
748
751
  while (1) switch (_context7.prev = _context7.next) {
749
752
  case 0:
@@ -778,34 +781,44 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
778
781
  productCount: products.length
779
782
  });
780
783
 
781
- // 2. 获取价格数据(网络请求)
784
+ // 2. 仅在 legacy 报价单 formatter 启用时加载报价单价格;默认由智能定价覆盖商品价格。
785
+ priceData = [];
786
+ if (!this.isLegacyPriceFormatterEnabled) {
787
+ _context7.next = 15;
788
+ break;
789
+ }
782
790
  tPrice = performance.now();
783
- _context7.next = 10;
791
+ _context7.next = 12;
784
792
  return this.loadProductsPrice({
785
793
  ids: ids,
786
794
  schedule_date: schedule_date,
787
795
  schedule_datetime: extraContext === null || extraContext === void 0 ? void 0 : extraContext.schedule_datetime,
788
796
  customer_id: extraContext === null || extraContext === void 0 ? void 0 : extraContext.customer_id
789
797
  });
790
- case 10:
798
+ case 12:
791
799
  priceData = _context7.sent;
792
800
  perfMark('prepareProducts.loadPrice', performance.now() - tPrice, {
793
801
  count: ids.length
794
802
  });
795
803
  this.logInfo('获取商品报价单价格成功', {
796
- priceDataCount: (_priceData$length = priceData === null || priceData === void 0 ? void 0 : priceData.length) !== null && _priceData$length !== void 0 ? _priceData$length : 0
804
+ priceDataCount: (_priceData$length = (_priceData = priceData) === null || _priceData === void 0 ? void 0 : _priceData.length) !== null && _priceData$length !== void 0 ? _priceData$length : 0
797
805
  });
806
+ case 15:
798
807
  context = _objectSpread({
799
808
  schedule_date: schedule_date,
800
809
  schedule_datetime: extraContext === null || extraContext === void 0 ? void 0 : extraContext.schedule_datetime,
801
810
  customer_id: extraContext === null || extraContext === void 0 ? void 0 : extraContext.customer_id,
802
811
  priceData: priceData,
803
- locale: (_this$core = this.core) === null || _this$core === void 0 || (_this$core = _this$core.context) === null || _this$core === void 0 ? void 0 : _this$core.locale
812
+ locale: (_this$core = this.core) === null || _this$core === void 0 || (_this$core = _this$core.context) === null || _this$core === void 0 ? void 0 : _this$core.locale,
813
+ dataVariantEvaluator: (extraContext === null || extraContext === void 0 ? void 0 : extraContext.dataVariantEvaluator) || ((_this$core2 = this.core) === null || _this$core2 === void 0 || (_this$core2 = _this$core2.context) === null || _this$core2 === void 0 ? void 0 : _this$core2.dataVariantEvaluator),
814
+ menuList: (extraContext === null || extraContext === void 0 ? void 0 : extraContext.menuList) || [],
815
+ scheduleList: (extraContext === null || extraContext === void 0 ? void 0 : extraContext.scheduleList) || [],
816
+ strategy_context: extraContext === null || extraContext === void 0 ? void 0 : extraContext.strategy_context
804
817
  }, extraContext); // 3. 通过格式化器流程处理商品
805
818
  tFormat = performance.now();
806
- _context7.next = 17;
819
+ _context7.next = 19;
807
820
  return this.applyFormatters(products, context);
808
- case 17:
821
+ case 19:
809
822
  processedProducts = _context7.sent;
810
823
  perfMark('prepareProducts.applyFormatters', performance.now() - tFormat, {
811
824
  count: products.length,
@@ -818,20 +831,20 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
818
831
  formatterCount: this.formatters.length
819
832
  });
820
833
  if (isIncremental) {
821
- _context7.next = 23;
834
+ _context7.next = 25;
822
835
  break;
823
836
  }
824
- _context7.next = 23;
837
+ _context7.next = 25;
825
838
  return this.core.effects.emit(ProductsHooks.onProductsPriceApplied, processedProducts);
826
- case 23:
839
+ case 25:
827
840
  perfMark('prepareProductsWithPrice', performance.now() - tTotal, {
828
841
  productCount: products.length,
829
842
  formatterCount: this.formatters.length,
830
843
  mode: isIncremental ? 'incremental' : 'full'
831
844
  });
832
845
  return _context7.abrupt("return", processedProducts);
833
- case 27:
834
- _context7.prev = 27;
846
+ case 29:
847
+ _context7.prev = 29;
835
848
  _context7.t0 = _context7["catch"](4);
836
849
  errorMessage = _context7.t0 instanceof Error ? _context7.t0.message : String(_context7.t0);
837
850
  console.log("[ProductsModule] \uD83C\uDF10 ERROR", _context7.t0);
@@ -839,13 +852,13 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
839
852
  schedule_date: schedule_date,
840
853
  error: errorMessage
841
854
  });
842
- case 32:
855
+ case 34:
843
856
  return _context7.abrupt("return", []);
844
- case 33:
857
+ case 35:
845
858
  case "end":
846
859
  return _context7.stop();
847
860
  }
848
- }, _callee7, this, [[4, 27]]);
861
+ }, _callee7, this, [[4, 29]]);
849
862
  }));
850
863
  function prepareProductsWithPrice(_x10, _x11, _x12) {
851
864
  return _prepareProductsWithPrice.apply(this, arguments);
@@ -858,7 +871,27 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
858
871
  var _extraContext$custome;
859
872
  var datetime = (extraContext === null || extraContext === void 0 ? void 0 : extraContext.schedule_datetime) || schedule_date;
860
873
  var productScope = productIds ? ":products:".concat(productIds.join(',')) : '';
861
- return "".concat(datetime, ":customer:").concat((_extraContext$custome = extraContext === null || extraContext === void 0 ? void 0 : extraContext.customer_id) !== null && _extraContext$custome !== void 0 ? _extraContext$custome : '').concat(productScope);
874
+ var strategyScope = this.stringifyStable((extraContext === null || extraContext === void 0 ? void 0 : extraContext.strategy_context) || {});
875
+ return "".concat(datetime, ":customer:").concat((_extraContext$custome = extraContext === null || extraContext === void 0 ? void 0 : extraContext.customer_id) !== null && _extraContext$custome !== void 0 ? _extraContext$custome : '', ":strategy:").concat(strategyScope).concat(productScope);
876
+ }
877
+
878
+ /**
879
+ * 稳定序列化策略上下文,避免对象 key 顺序不同导致缓存 key 抖动。
880
+ */
881
+ }, {
882
+ key: "stringifyStable",
883
+ value: function stringifyStable(value) {
884
+ var _this7 = this;
885
+ if (value == null) return '';
886
+ if (Array.isArray(value)) return "[".concat(value.map(function (item) {
887
+ return _this7.stringifyStable(item);
888
+ }).join(','), "]");
889
+ if (_typeof(value) === 'object') {
890
+ return "{".concat(Object.keys(value).sort().map(function (key) {
891
+ return "".concat(key, ":").concat(_this7.stringifyStable(value[key]));
892
+ }).join(','), "}");
893
+ }
894
+ return String(value);
862
895
  }
863
896
  }, {
864
897
  key: "normalizeProductIds",
@@ -1004,26 +1037,55 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1004
1037
  return applyFormatters;
1005
1038
  }()
1006
1039
  /**
1007
- * 注册内置的价格格式化器
1008
- * 这个格式化器负责将价格数据应用到商品上
1040
+ * 注册内置商品格式化器。
1041
+ *
1042
+ * 智能定价默认替代报价单逻辑;报价单 formatter 仅在 enableLegacyPriceFormatter=true 时启用。
1009
1043
  * @private
1010
1044
  */
1011
1045
  )
1012
1046
  }, {
1013
- key: "registerBuiltinPriceFormatter",
1014
- value: function registerBuiltinPriceFormatter() {
1015
- if (this.isPriceFormatterRegistered) {
1016
- console.warn('[ProductsModule] 内置价格格式化器已注册,跳过');
1047
+ key: "registerBuiltinProductFormatters",
1048
+ value: function registerBuiltinProductFormatters() {
1049
+ var _this8 = this;
1050
+ if (this.isBuiltinFormatterRegistered) {
1051
+ console.warn('[ProductsModule] 内置商品格式化器已注册,跳过');
1017
1052
  return;
1018
1053
  }
1054
+ this.isLegacyPriceFormatterEnabled = this.shouldEnableLegacyPriceFormatter();
1055
+ var dataVariantFormatter = function dataVariantFormatter(products, context) {
1056
+ var _this8$core, _strategyContext$busi;
1057
+ var evaluator = context.dataVariantEvaluator || ((_this8$core = _this8.core) === null || _this8$core === void 0 || (_this8$core = _this8$core.context) === null || _this8$core === void 0 ? void 0 : _this8$core.dataVariantEvaluator);
1058
+ if (!evaluator || typeof evaluator.resolveProducts !== 'function') {
1059
+ _this8.lastScheduleTimePoints = [];
1060
+ _this8.logWarning('智能定价评估器未注入,跳过 DataVariant 格式化', {
1061
+ productCount: products.length
1062
+ });
1063
+ return products;
1064
+ }
1065
+ var strategyContext = context.strategy_context || {};
1066
+ var businessData = {
1067
+ products: products,
1068
+ scheduleDateTime: context.schedule_datetime || context.schedule_date,
1069
+ scheduleList: context.scheduleList || [],
1070
+ menuList: context.menuList || [],
1071
+ customerId: context.customer_id,
1072
+ channel: strategyContext.channel,
1073
+ orderType: strategyContext.orderType || strategyContext.order_type,
1074
+ businessCode: (_strategyContext$busi = strategyContext.business_code) !== null && _strategyContext$busi !== void 0 ? _strategyContext$busi : strategyContext.businessCode,
1075
+ custom: strategyContext
1076
+ };
1077
+ var result = evaluator.resolveProducts(businessData);
1078
+ _this8.lastScheduleTimePoints = Array.isArray(result === null || result === void 0 ? void 0 : result.scheduleTimePoints) ? _toConsumableArray(result.scheduleTimePoints) : [];
1079
+ return Array.isArray(result === null || result === void 0 ? void 0 : result.products) ? result.products : products;
1080
+ };
1019
1081
 
1020
- // 创建价格格式化器
1021
- var priceFormatter = function priceFormatter(products, context) {
1082
+ // 创建 legacy 报价单格式化器
1083
+ var legacyPriceFormatter = function legacyPriceFormatter(products, context) {
1022
1084
  if (!context.priceData || context.priceData.length === 0) {
1023
- console.log('[ProductsModule] 💰 没有价格数据,跳过价格应用');
1085
+ console.log('[ProductsModule] 💰 没有价格数据,跳过 legacy 报价单价格应用');
1024
1086
  return products;
1025
1087
  }
1026
- console.log("[ProductsModule] \uD83D\uDCB0 \u5E94\u7528\u4EF7\u683C\u6570\u636E\u5230 ".concat(products.length, " \u4E2A\u5546\u54C1"));
1088
+ console.log("[ProductsModule] \uD83D\uDCB0 \u5E94\u7528 legacy \u62A5\u4EF7\u5355\u4EF7\u683C\u5230 ".concat(products.length, " \u4E2A\u5546\u54C1"));
1027
1089
  return applyPriceDataToProducts(products, context.priceData);
1028
1090
  };
1029
1091
  var i18nFormatter = function i18nFormatter(products, context) {
@@ -1032,18 +1094,41 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1032
1094
  var detailValueFormatter = function detailValueFormatter(products, context) {
1033
1095
  return applyDetailValueToProducts(products, context);
1034
1096
  };
1035
-
1036
- // 将价格格式化器注册为第一个格式化器
1037
- this.formatters.unshift(priceFormatter);
1097
+ if (this.isLegacyPriceFormatterEnabled) {
1098
+ this.formatters.push(legacyPriceFormatter);
1099
+ }
1100
+ this.formatters.push(dataVariantFormatter);
1038
1101
  this.formatters.push(i18nFormatter);
1039
1102
  this.formatters.push(detailValueFormatter);
1040
- this.isPriceFormatterRegistered = true;
1041
- console.log('[ProductsModule] ✅ 内置价格格式化器已注册(第 1 个)');
1103
+ this.isBuiltinFormatterRegistered = true;
1104
+ console.log('[ProductsModule] ✅ 内置商品格式化器已注册(智能定价优先)');
1105
+ }
1106
+
1107
+ /**
1108
+ * 是否启用旧报价单价格 formatter。
1109
+ *
1110
+ * 默认关闭,避免报价单逻辑覆盖智能定价结果。
1111
+ */
1112
+ }, {
1113
+ key: "shouldEnableLegacyPriceFormatter",
1114
+ value: function shouldEnableLegacyPriceFormatter() {
1115
+ var _this$otherParams3, _this$core3;
1116
+ return ((_this$otherParams3 = this.otherParams) === null || _this$otherParams3 === void 0 ? void 0 : _this$otherParams3.enableLegacyPriceFormatter) === true || ((_this$core3 = this.core) === null || _this$core3 === void 0 || (_this$core3 = _this$core3.context) === null || _this$core3 === void 0 ? void 0 : _this$core3.enableLegacyPriceFormatter) === true;
1117
+ }
1118
+
1119
+ /**
1120
+ * 返回最近一次 prepareProductsWithPrice / DataVariant 评估提取的变价时间点(HH:mm)。
1121
+ * 供 OS Server 商品 query 订阅定时刷新使用。
1122
+ */
1123
+ }, {
1124
+ key: "getLastScheduleTimePoints",
1125
+ value: function getLastScheduleTimePoints() {
1126
+ return _toConsumableArray(this.lastScheduleTimePoints);
1042
1127
  }
1043
1128
 
1044
1129
  /**
1045
1130
  * 注册商品格式化器
1046
- * 格式化器会按注册顺序依次执行(内置价格格式化器始终是第一个)
1131
+ * 格式化器会按注册顺序依次执行;legacy 启用时先兜底报价,再由智能定价覆盖。
1047
1132
  * @param formatter 格式化函数
1048
1133
  * @param prepend 是否插入到队列开头(默认 false,追加到末尾)
1049
1134
  * @example
@@ -1061,8 +1146,8 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1061
1146
  value: function registerFormatter(formatter) {
1062
1147
  var prepend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1063
1148
  if (prepend) {
1064
- // 插入到价格格式化器之后(索引 1 的位置)
1065
- var insertIndex = this.isPriceFormatterRegistered ? 1 : 0;
1149
+ // 插入到内置智能定价格式化器之后;legacy 报价单启用时需跳过它。
1150
+ var insertIndex = this.isBuiltinFormatterRegistered ? this.isLegacyPriceFormatterEnabled ? 2 : 1 : 0;
1066
1151
  this.formatters.splice(insertIndex, 0, formatter);
1067
1152
  console.log("[ProductsModule] \uD83D\uDCCC \u5DF2\u5728\u4F4D\u7F6E ".concat(insertIndex + 1, " \u63D2\u5165\u683C\u5F0F\u5316\u5668\uFF0C\u5F53\u524D\u5171 ").concat(this.formatters.length, " \u4E2A"));
1068
1153
  } else {
@@ -1073,20 +1158,21 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1073
1158
  }
1074
1159
 
1075
1160
  /**
1076
- * 清空所有格式化器(包括内置价格格式化器)
1077
- * @param keepBuiltin 是否保留内置价格格式化器(默认 true)
1161
+ * 清空所有格式化器(包括内置智能定价格式化器)
1162
+ * @param keepBuiltin 是否保留内置智能定价格式化器(默认 true)
1078
1163
  */
1079
1164
  }, {
1080
1165
  key: "clearFormatters",
1081
1166
  value: function clearFormatters() {
1082
1167
  var keepBuiltin = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1083
- if (keepBuiltin && this.isPriceFormatterRegistered) {
1084
- // 只保留第一个格式化器(内置价格格式化器)
1085
- this.formatters = [this.formatters[0]];
1086
- console.log('[ProductsModule] 🧹 已清空自定义格式化器,保留内置价格格式化器');
1168
+ if (keepBuiltin && this.isBuiltinFormatterRegistered) {
1169
+ // 保留 legacy 兜底(如果启用)和智能定价格式化器。
1170
+ var builtinCount = this.isLegacyPriceFormatterEnabled ? 2 : 1;
1171
+ this.formatters = this.formatters.slice(0, builtinCount);
1172
+ console.log('[ProductsModule] 🧹 已清空自定义格式化器,保留内置智能定价格式化器');
1087
1173
  } else {
1088
1174
  this.formatters = [];
1089
- this.isPriceFormatterRegistered = false;
1175
+ this.isBuiltinFormatterRegistered = false;
1090
1176
  console.log('[ProductsModule] 🧹 已清空所有格式化器');
1091
1177
  }
1092
1178
  }
@@ -1197,7 +1283,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1197
1283
  key: "fetchProductsByHttp",
1198
1284
  value: (function () {
1199
1285
  var _fetchProductsByHttp = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(params) {
1200
- var _ref13, _ref13$category_ids, category_ids, _ref13$product_ids, product_ids, _ref13$collection, collection, customer_id, cacheId, startTime, _this$otherParams3, _productsData$data, productsData, productList, duration, _duration2, errorMessage;
1286
+ var _ref13, _ref13$category_ids, category_ids, _ref13$product_ids, product_ids, _ref13$collection, collection, customer_id, cacheId, startTime, _this$otherParams4, _productsData$data, productsData, productList, duration, _duration2, errorMessage;
1201
1287
  return _regeneratorRuntime().wrap(function _callee10$(_context10) {
1202
1288
  while (1) switch (_context10.prev = _context10.next) {
1203
1289
  case 0:
@@ -1215,7 +1301,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1215
1301
  open_bundle: 1,
1216
1302
  exclude_extension_type: ['product_party', 'product_event', 'product_series_event', 'product_package_ticket', 'ticket', 'event_item'],
1217
1303
  force_ignore_cache_flag: 1,
1218
- with: ['category', 'collection', 'resourceRelation', 'bundleGroup.bundleItem', 'optionGroup.optionItem', 'variantGroup.variantItem'],
1304
+ with: ['category', 'collection', 'resourceRelation', 'bundleGroup.bundleItem', 'optionGroup.optionItem', 'variantGroup.variantItem', 'dataVariants'],
1219
1305
  open_deposit: 1,
1220
1306
  is_append_product_description: 1,
1221
1307
  with_count: ['bundleGroup', 'optionGroup'],
@@ -1227,7 +1313,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1227
1313
  ids: product_ids,
1228
1314
  collection: collection,
1229
1315
  front_end_cache_id: cacheId,
1230
- application_code: (_this$otherParams3 = this.otherParams) === null || _this$otherParams3 === void 0 ? void 0 : _this$otherParams3.channel
1316
+ application_code: (_this$otherParams4 = this.otherParams) === null || _this$otherParams4 === void 0 ? void 0 : _this$otherParams4.channel
1231
1317
  }, {
1232
1318
  cache: undefined
1233
1319
  });
@@ -1691,7 +1777,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1691
1777
  key: "replaceProductsSnapshotInIndexDB",
1692
1778
  value: (function () {
1693
1779
  var _replaceProductsSnapshotInIndexDB = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee20(products, source) {
1694
- var _this7 = this;
1780
+ var _this9 = this;
1695
1781
  var errorMessage;
1696
1782
  return _regeneratorRuntime().wrap(function _callee20$(_context20) {
1697
1783
  while (1) switch (_context20.prev = _context20.next) {
@@ -1710,25 +1796,25 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1710
1796
  return _regeneratorRuntime().wrap(function _callee19$(_context19) {
1711
1797
  while (1) switch (_context19.prev = _context19.next) {
1712
1798
  case 0:
1713
- _this7.logInfo('replaceProductsSnapshotInIndexDB 开始', {
1799
+ _this9.logInfo('replaceProductsSnapshotInIndexDB 开始', {
1714
1800
  source: source,
1715
1801
  productCount: products.length
1716
1802
  });
1717
1803
  t0 = performance.now();
1718
1804
  _context19.next = 4;
1719
- return _this7.dbManager.clear(INDEXDB_STORE_NAME);
1805
+ return _this9.dbManager.clear(INDEXDB_STORE_NAME);
1720
1806
  case 4:
1721
1807
  if (!(products.length > 0)) {
1722
1808
  _context19.next = 7;
1723
1809
  break;
1724
1810
  }
1725
1811
  _context19.next = 7;
1726
- return _this7.dbManager.bulkUpdate(INDEXDB_STORE_NAME, products);
1812
+ return _this9.dbManager.bulkUpdate(INDEXDB_STORE_NAME, products);
1727
1813
  case 7:
1728
1814
  perfMark('replaceProductsSnapshotInIndexDB', performance.now() - t0, {
1729
1815
  count: products.length
1730
1816
  });
1731
- _this7.logInfo('replaceProductsSnapshotInIndexDB 完成', {
1817
+ _this9.logInfo('replaceProductsSnapshotInIndexDB 完成', {
1732
1818
  source: source,
1733
1819
  productCount: products.length
1734
1820
  });
@@ -1772,7 +1858,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1772
1858
  key: "patchProductsInIndexDB",
1773
1859
  value: (function () {
1774
1860
  var _patchProductsInIndexDB = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee22(products, source) {
1775
- var _this8 = this;
1861
+ var _this10 = this;
1776
1862
  var mergeActions,
1777
1863
  validProducts,
1778
1864
  errorMessage,
@@ -1803,22 +1889,22 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1803
1889
  return _regeneratorRuntime().wrap(function _callee21$(_context21) {
1804
1890
  while (1) switch (_context21.prev = _context21.next) {
1805
1891
  case 0:
1806
- _this8.logInfo('patchProductsInIndexDB 开始', {
1892
+ _this10.logInfo('patchProductsInIndexDB 开始', {
1807
1893
  source: source,
1808
1894
  count: validProducts.length
1809
1895
  });
1810
1896
  t0 = performance.now();
1811
- if (!(typeof _this8.dbManager.bulkUpdate === 'function')) {
1897
+ if (!(typeof _this10.dbManager.bulkUpdate === 'function')) {
1812
1898
  _context21.next = 7;
1813
1899
  break;
1814
1900
  }
1815
1901
  _context21.next = 5;
1816
- return _this8.dbManager.bulkUpdate(INDEXDB_STORE_NAME, validProducts);
1902
+ return _this10.dbManager.bulkUpdate(INDEXDB_STORE_NAME, validProducts);
1817
1903
  case 5:
1818
1904
  _context21.next = 25;
1819
1905
  break;
1820
1906
  case 7:
1821
- if (!(typeof _this8.dbManager.update === 'function')) {
1907
+ if (!(typeof _this10.dbManager.update === 'function')) {
1822
1908
  _context21.next = 25;
1823
1909
  break;
1824
1910
  }
@@ -1832,7 +1918,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1832
1918
  }
1833
1919
  product = _step10.value;
1834
1920
  _context21.next = 15;
1835
- return _this8.dbManager.update(INDEXDB_STORE_NAME, product);
1921
+ return _this10.dbManager.update(INDEXDB_STORE_NAME, product);
1836
1922
  case 15:
1837
1923
  _context21.next = 11;
1838
1924
  break;
@@ -1851,7 +1937,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1851
1937
  perfMark('patchProductsInIndexDB', performance.now() - t0, {
1852
1938
  count: validProducts.length
1853
1939
  });
1854
- _this8.logInfo('patchProductsInIndexDB 完成', {
1940
+ _this10.logInfo('patchProductsInIndexDB 完成', {
1855
1941
  source: source,
1856
1942
  count: validProducts.length
1857
1943
  });
@@ -2049,7 +2135,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2049
2135
  }, {
2050
2136
  key: "setupProductSync",
2051
2137
  value: function setupProductSync() {
2052
- var _this9 = this;
2138
+ var _this11 = this;
2053
2139
  if (!this.productDataSource) {
2054
2140
  this.logWarning('setupProductSync: ProductDataSource 不可用,跳过同步初始化');
2055
2141
  return;
@@ -2059,20 +2145,20 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2059
2145
  var data = (message === null || message === void 0 ? void 0 : message.data) || message;
2060
2146
  if (!data) return;
2061
2147
  console.log("[ProductsModule] \u6536\u5230\u540C\u6B65\u6D88\u606F [".concat(channelKey, "]:"), data);
2062
- _this9.logInfo('收到同步消息', {
2148
+ _this11.logInfo('收到同步消息', {
2063
2149
  channelKey: channelKey,
2064
2150
  action: data.action,
2065
2151
  id: data.id,
2066
2152
  action_filed: data.action_filed
2067
2153
  });
2068
- _this9.pendingSyncMessages.push(_objectSpread(_objectSpread({}, data), {}, {
2154
+ _this11.pendingSyncMessages.push(_objectSpread(_objectSpread({}, data), {}, {
2069
2155
  _channelKey: channelKey
2070
2156
  }));
2071
- if (_this9.syncTimer) {
2072
- clearTimeout(_this9.syncTimer);
2157
+ if (_this11.syncTimer) {
2158
+ clearTimeout(_this11.syncTimer);
2073
2159
  }
2074
- _this9.syncTimer = setTimeout(function () {
2075
- _this9.processProductSyncMessages();
2160
+ _this11.syncTimer = setTimeout(function () {
2161
+ _this11.processProductSyncMessages();
2076
2162
  }, PRODUCT_SYNC_DEBOUNCE_MS);
2077
2163
  };
2078
2164
  };
@@ -2090,7 +2176,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2090
2176
  }
2091
2177
  }
2092
2178
  }).catch(function (err) {
2093
- _this9.logError('setupProductSync: DataSource run 出错', {
2179
+ _this11.logError('setupProductSync: DataSource run 出错', {
2094
2180
  error: err instanceof Error ? err.message : String(err)
2095
2181
  });
2096
2182
  });
@@ -2119,7 +2205,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2119
2205
  key: "processProductSyncMessages",
2120
2206
  value: (function () {
2121
2207
  var _processProductSyncMessages = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee24() {
2122
- var messages, deleteIds, bodyUpdates, sseRefreshIds, priceRefreshIds, shouldClearPriceCache, _iterator12, _step12, msg, channelKey, _msg$relation_product, _msg$change_types, _msg$ids2, _msg$ids, ids, bodyId, _bodyId, _msg$relation_product2, _msg$relation_product3, uniqueDeleteIds, uniqueSSEIds, uniquePriceIds, patchProductMap, patchMergeActions, storeMutated, bodyResult, _iterator13, _step13, product, freshProducts, mergeResult, _iterator14, _step14, _product, patchProducts, allChangedIds, hasChanges, errorMessage;
2208
+ var messages, deleteIds, bodyUpdates, sseRefreshIds, priceRefreshIds, shouldClearPriceCache, _iterator12, _step12, msg, channelKey, _msg$relation_product, _msg$change_types, _msg$ids2, _msg$ids, ids, bodyId, _bodyId, _msg$relation_product2, _msg$relation_product3, _msg$product_ids, uniqueDeleteIds, uniqueSSEIds, uniquePriceIds, patchProductMap, patchMergeActions, storeMutated, bodyResult, _iterator13, _step13, product, freshProducts, mergeResult, _iterator14, _step14, _product, patchProducts, allChangedIds, hasChanges, errorMessage;
2123
2209
  return _regeneratorRuntime().wrap(function _callee24$(_context24) {
2124
2210
  while (1) switch (_context24.prev = _context24.next) {
2125
2211
  case 0:
@@ -2203,6 +2289,10 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
2203
2289
  if ((_msg$relation_product3 = msg.relation_product_ids) !== null && _msg$relation_product3 !== void 0 && _msg$relation_product3.length) {
2204
2290
  sseRefreshIds.push.apply(sseRefreshIds, _toConsumableArray(msg.relation_product_ids));
2205
2291
  }
2292
+ } else if (['product_data_variant'].includes(channelKey)) {
2293
+ if ((_msg$product_ids = msg.product_ids) !== null && _msg$product_ids !== void 0 && _msg$product_ids.length) {
2294
+ sseRefreshIds.push.apply(sseRefreshIds, _toConsumableArray(msg.product_ids));
2295
+ }
2206
2296
  }
2207
2297
  case 34:
2208
2298
  _context24.next = 13;
@@ -110,6 +110,8 @@ export interface ProductSyncMessage {
110
110
  change_types?: string[];
111
111
  /** 关联商品 ID(product_collection / product_category / product_quotation 变更时携带) */
112
112
  relation_product_ids?: number[];
113
+ /** 关联商品 ID(product_data_variant 变更时携带) */
114
+ product_ids?: number[];
113
115
  message_uuid?: string;
114
116
  timestamp?: string;
115
117
  /** 内部标记:来源频道 key */
@@ -124,6 +126,18 @@ export interface ProductFormatterContext {
124
126
  customer_id?: number | string;
125
127
  priceData?: LoadProductsPriceData[];
126
128
  scheduleModule?: any;
129
+ /** 全量餐牌列表,供智能定价 menu_match 等条件判断使用 */
130
+ menuList?: any[];
131
+ /** 全量日程列表,供智能定价 schedule_match 等条件判断使用 */
132
+ scheduleList?: any[];
133
+ /** 外部传入的策略上下文,仅承载定价条件,不参与商品集合筛选 */
134
+ strategy_context?: Record<string, any>;
135
+ /** 智能定价评估器,由宿主统一注入到 PisellOS context */
136
+ dataVariantEvaluator?: {
137
+ resolveProducts: (businessData: any) => {
138
+ products: ProductData[];
139
+ };
140
+ };
127
141
  locale?: string;
128
142
  }
129
143
  /**