@pisell/pisellos 2.2.90 → 2.2.92

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.
@@ -29,6 +29,7 @@ declare class PisellOSCore implements PisellCore {
29
29
  getModuleExports<T = any>(name: string): T | null;
30
30
  hasModule(name: string): boolean;
31
31
  destroy(): Promise<void>;
32
+ setContext(ctx: Partial<BusinessContext>): void;
32
33
  /**
33
34
  * 验证上下文参数
34
35
  */
@@ -403,6 +403,13 @@ var PisellOSCore = /*#__PURE__*/function () {
403
403
  }
404
404
  return destroy;
405
405
  }()
406
+ }, {
407
+ key: "setContext",
408
+ value: function setContext(ctx) {
409
+ this.context = _objectSpread(_objectSpread({}, this.context), ctx);
410
+ this.log("\u4E0A\u4E0B\u6587\u5DF2\u66F4\u65B0: ".concat(JSON.stringify(Object.keys(ctx))));
411
+ }
412
+
406
413
  /**
407
414
  * 验证上下文参数
408
415
  */
@@ -1,9 +0,0 @@
1
- // 导出评估器
2
- export { PromotionEvaluator } from "./evaluator";
3
-
4
- // 导出适配器
5
- export { PromotionAdapter } from "./adapter";
6
- export { default } from "./adapter";
7
-
8
- // 导出策略配置示例常量
9
- export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY } from "./examples";
@@ -31,7 +31,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
31
31
  import { BaseModule } from "../../../modules/BaseModule";
32
32
  import { RequestModeENUM } from "../../../plugins";
33
33
  import { ProductsHooks } from "./types";
34
- import { applyDetailValueToProducts, applyPriceDataToProducts, perfMark } from "../../utils/product";
34
+ import { applyDetailValueToProducts, applyPriceDataToProducts, applyI18nToProducts, perfMark } from "../../utils/product";
35
35
 
36
36
  /**
37
37
  * IndexDB 存储名称
@@ -426,7 +426,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
426
426
  key: "prepareProductsWithPrice",
427
427
  value: (function () {
428
428
  var _prepareProductsWithPrice = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(schedule_date, extraContext, options) {
429
- var tTotal, targetIds, isIncremental, _priceData$length, products, ids, idSet, tIds, i, tPrice, priceData, context, tFormat, processedProducts, errorMessage;
429
+ var tTotal, targetIds, isIncremental, _priceData$length, _this$core, products, ids, idSet, tIds, i, tPrice, priceData, context, tFormat, processedProducts, errorMessage;
430
430
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
431
431
  while (1) switch (_context4.prev = _context4.next) {
432
432
  case 0:
@@ -481,7 +481,8 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
481
481
  });
482
482
  context = _objectSpread({
483
483
  schedule_date: schedule_date,
484
- priceData: priceData
484
+ priceData: priceData,
485
+ 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
485
486
  }, extraContext); // 3. 通过格式化器流程处理商品
486
487
  tFormat = performance.now();
487
488
  _context4.next = 17;
@@ -638,12 +639,16 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
638
639
  console.log("[ProductsModule] \uD83D\uDCB0 \u5E94\u7528\u4EF7\u683C\u6570\u636E\u5230 ".concat(products.length, " \u4E2A\u5546\u54C1"));
639
640
  return applyPriceDataToProducts(products, context.priceData);
640
641
  };
642
+ var i18nFormatter = function i18nFormatter(products, context) {
643
+ return applyI18nToProducts(products, context.locale);
644
+ };
641
645
  var detailValueFormatter = function detailValueFormatter(products, context) {
642
646
  return applyDetailValueToProducts(products, context);
643
647
  };
644
648
 
645
649
  // 将价格格式化器注册为第一个格式化器
646
650
  this.formatters.unshift(priceFormatter);
651
+ this.formatters.push(i18nFormatter);
647
652
  this.formatters.push(detailValueFormatter);
648
653
  this.isPriceFormatterRegistered = true;
649
654
  console.log('[ProductsModule] ✅ 内置价格格式化器已注册(第 1 个)');
@@ -1521,7 +1526,7 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1521
1526
  key: "processProductSyncMessages",
1522
1527
  value: (function () {
1523
1528
  var _processProductSyncMessages = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee17() {
1524
- var messages, deleteIds, bodyUpdates, sseRefreshIds, priceRefreshIds, shouldClearPriceCache, _iterator7, _step7, msg, channelKey, _msg$relation_product, _msg$change_types, _msg$ids2, _msg$ids, ids, bodyId, _msg$relation_product2, _msg$relation_product3, uniqueDeleteIds, uniqueSSEIds, uniquePriceIds, freshProducts, allChangedIds, hasChanges;
1529
+ var messages, deleteIds, bodyUpdates, sseRefreshIds, priceRefreshIds, shouldClearPriceCache, _iterator7, _step7, msg, channelKey, _msg$relation_product, _msg$change_types, _msg$ids2, _msg$ids, ids, bodyId, _bodyId, _msg$relation_product2, _msg$relation_product3, uniqueDeleteIds, uniqueSSEIds, uniquePriceIds, freshProducts, allChangedIds, hasChanges;
1525
1530
  return _regeneratorRuntime().wrap(function _callee17$(_context17) {
1526
1531
  while (1) switch (_context17.prev = _context17.next) {
1527
1532
  case 0:
@@ -1546,13 +1551,13 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1546
1551
  _iterator7.s();
1547
1552
  case 13:
1548
1553
  if ((_step7 = _iterator7.n()).done) {
1549
- _context17.next = 35;
1554
+ _context17.next = 36;
1550
1555
  break;
1551
1556
  }
1552
1557
  msg = _step7.value;
1553
1558
  channelKey = msg._channelKey || msg.module || 'product';
1554
1559
  if (!(channelKey === 'product')) {
1555
- _context17.next = 32;
1560
+ _context17.next = 33;
1556
1561
  break;
1557
1562
  }
1558
1563
  if ((_msg$relation_product = msg.relation_product_ids) !== null && _msg$relation_product !== void 0 && _msg$relation_product.length) {
@@ -1564,33 +1569,37 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1564
1569
  break;
1565
1570
  }
1566
1571
  if ((_msg$ids = msg.ids) !== null && _msg$ids !== void 0 && _msg$ids.length) deleteIds.push.apply(deleteIds, _toConsumableArray(msg.ids));else if (msg.id) deleteIds.push(msg.id);
1567
- return _context17.abrupt("continue", 33);
1572
+ return _context17.abrupt("continue", 34);
1568
1573
  case 21:
1569
1574
  if (!((_msg$change_types = msg.change_types) !== null && _msg$change_types !== void 0 && _msg$change_types.includes('price'))) {
1570
- _context17.next = 25;
1575
+ _context17.next = 26;
1571
1576
  break;
1572
1577
  }
1573
1578
  ids = msg.ids || (msg.id ? [msg.id] : []);
1574
1579
  priceRefreshIds.push.apply(priceRefreshIds, _toConsumableArray(ids));
1575
- return _context17.abrupt("continue", 33);
1576
- case 25:
1580
+ if (msg.body) {
1581
+ bodyId = msg.body.id;
1582
+ if (bodyId) bodyUpdates.set(bodyId, msg.body);
1583
+ }
1584
+ return _context17.abrupt("continue", 34);
1585
+ case 26:
1577
1586
  if (!msg.body) {
1578
- _context17.next = 29;
1587
+ _context17.next = 30;
1579
1588
  break;
1580
1589
  }
1581
- bodyId = msg.body.id || msg.id;
1582
- if (bodyId) bodyUpdates.set(bodyId, msg.body);
1583
- return _context17.abrupt("continue", 33);
1584
- case 29:
1590
+ _bodyId = msg.body.id || msg.id;
1591
+ if (_bodyId) bodyUpdates.set(_bodyId, msg.body);
1592
+ return _context17.abrupt("continue", 34);
1593
+ case 30:
1585
1594
  // 4. 其他情况(有 ids 无 body 无 change_types)→ SSE 拉取
1586
1595
  if ((_msg$ids2 = msg.ids) !== null && _msg$ids2 !== void 0 && _msg$ids2.length) {
1587
1596
  sseRefreshIds.push.apply(sseRefreshIds, _toConsumableArray(msg.ids));
1588
1597
  } else if (msg.id) {
1589
1598
  sseRefreshIds.push(msg.id);
1590
1599
  }
1591
- _context17.next = 33;
1600
+ _context17.next = 34;
1592
1601
  break;
1593
- case 32:
1602
+ case 33:
1594
1603
  if (channelKey === 'product_quotation') {
1595
1604
  // 报价单变更影响范围大,标记清除全量价格缓存
1596
1605
  shouldClearPriceCache = true;
@@ -1602,61 +1611,61 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1602
1611
  sseRefreshIds.push.apply(sseRefreshIds, _toConsumableArray(msg.relation_product_ids));
1603
1612
  }
1604
1613
  }
1605
- case 33:
1614
+ case 34:
1606
1615
  _context17.next = 13;
1607
1616
  break;
1608
- case 35:
1609
- _context17.next = 40;
1617
+ case 36:
1618
+ _context17.next = 41;
1610
1619
  break;
1611
- case 37:
1612
- _context17.prev = 37;
1620
+ case 38:
1621
+ _context17.prev = 38;
1613
1622
  _context17.t0 = _context17["catch"](11);
1614
1623
  _iterator7.e(_context17.t0);
1615
- case 40:
1616
- _context17.prev = 40;
1624
+ case 41:
1625
+ _context17.prev = 41;
1617
1626
  _iterator7.f();
1618
- return _context17.finish(40);
1619
- case 43:
1627
+ return _context17.finish(41);
1628
+ case 44:
1620
1629
  uniqueDeleteIds = _toConsumableArray(new Set(deleteIds));
1621
1630
  uniqueSSEIds = _toConsumableArray(new Set(sseRefreshIds));
1622
1631
  uniquePriceIds = _toConsumableArray(new Set(priceRefreshIds)); // 1. 处理删除
1623
1632
  if (!(uniqueDeleteIds.length > 0)) {
1624
- _context17.next = 49;
1633
+ _context17.next = 50;
1625
1634
  break;
1626
1635
  }
1627
- _context17.next = 49;
1636
+ _context17.next = 50;
1628
1637
  return this.removeProductsByIds(uniqueDeleteIds);
1629
- case 49:
1638
+ case 50:
1630
1639
  if (!(bodyUpdates.size > 0)) {
1631
- _context17.next = 52;
1640
+ _context17.next = 53;
1632
1641
  break;
1633
1642
  }
1634
- _context17.next = 52;
1643
+ _context17.next = 53;
1635
1644
  return this.applyBodyUpdatesToStore(bodyUpdates);
1636
- case 52:
1645
+ case 53:
1637
1646
  if (!(uniqueSSEIds.length > 0)) {
1638
- _context17.next = 60;
1647
+ _context17.next = 61;
1639
1648
  break;
1640
1649
  }
1641
- _context17.next = 55;
1650
+ _context17.next = 56;
1642
1651
  return this.fetchProductsBySSE(uniqueSSEIds);
1643
- case 55:
1652
+ case 56:
1644
1653
  freshProducts = _context17.sent;
1645
1654
  if (!(freshProducts.length > 0)) {
1646
- _context17.next = 59;
1655
+ _context17.next = 60;
1647
1656
  break;
1648
1657
  }
1649
- _context17.next = 59;
1658
+ _context17.next = 60;
1650
1659
  return this.mergeProductsToStore(freshProducts);
1651
- case 59:
1652
- this.logInfo('processProductSyncMessages: SSE 增量更新完成', {
1660
+ case 60:
1661
+ this.logInfo('processProductSyncMessages: SSE 增量更新完成123', {
1653
1662
  requestedCount: uniqueSSEIds.length,
1654
1663
  receivedCount: freshProducts.length
1655
1664
  });
1656
- case 60:
1665
+ case 61:
1657
1666
  // 收集所有非 delete 的变更 IDs(body + SSE + price),用于增量更新价格缓存
1658
1667
  allChangedIds = _toConsumableArray(new Set([].concat(_toConsumableArray(Array.from(bodyUpdates.keys())), _toConsumableArray(uniqueSSEIds), _toConsumableArray(uniquePriceIds))));
1659
- this.logInfo('processProductSyncMessages: 处理完成', {
1668
+ this.logInfo('processProductSyncMessages: 处理完成123', {
1660
1669
  deleteCount: uniqueDeleteIds.length,
1661
1670
  bodyUpdateCount: bodyUpdates.size,
1662
1671
  sseRefreshCount: uniqueSSEIds.length,
@@ -1666,25 +1675,25 @@ export var ProductsModule = /*#__PURE__*/function (_BaseModule) {
1666
1675
  });
1667
1676
  hasChanges = uniqueDeleteIds.length > 0 || allChangedIds.length > 0 || shouldClearPriceCache;
1668
1677
  if (hasChanges) {
1669
- _context17.next = 66;
1678
+ _context17.next = 67;
1670
1679
  break;
1671
1680
  }
1672
1681
  this.logInfo('processProductSyncMessages: 没有变更,不触发 onProductsSyncCompleted');
1673
1682
  return _context17.abrupt("return");
1674
- case 66:
1683
+ case 67:
1675
1684
  // 报价单变更 → 清除全量价格缓存,后续走全量重建
1676
1685
  if (shouldClearPriceCache) {
1677
1686
  this.clearPriceCache();
1678
1687
  }
1679
- _context17.next = 69;
1688
+ _context17.next = 70;
1680
1689
  return this.core.effects.emit(ProductsHooks.onProductsSyncCompleted, {
1681
1690
  changedIds: allChangedIds
1682
1691
  });
1683
- case 69:
1692
+ case 70:
1684
1693
  case "end":
1685
1694
  return _context17.stop();
1686
1695
  }
1687
- }, _callee17, this, [[11, 37, 40, 43]]);
1696
+ }, _callee17, this, [[11, 38, 41, 44]]);
1688
1697
  }));
1689
1698
  function processProductSyncMessages() {
1690
1699
  return _processProductSyncMessages.apply(this, arguments);
@@ -109,6 +109,7 @@ export interface ProductFormatterContext {
109
109
  schedule_date: string;
110
110
  priceData?: LoadProductsPriceData[];
111
111
  scheduleModule?: any;
112
+ locale?: string;
112
113
  }
113
114
  /**
114
115
  * 商品格式化器类型
@@ -10,6 +10,10 @@ export declare function perfMark(label: string, durationMs: number, meta?: Recor
10
10
  */
11
11
  export declare function applyPriceDataToProducts(products: ProductData[], priceData: LoadProductsPriceData[]): ProductData[];
12
12
  export declare const getIsSessionProduct: (product: ProductData) => boolean;
13
+ /**
14
+ * 根据 locale 将商品的 i18n 字段覆盖到对应原始字段
15
+ */
16
+ export declare function applyI18nToProducts(products: ProductData[], locale?: string): ProductData[];
13
17
  /**
14
18
  * 将详情值数据应用到商品列表
15
19
  * @param products 商品列表
@@ -1,7 +1,11 @@
1
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
2
  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; } } }; }
3
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
+ 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."); }
3
5
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
6
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
+ 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; } }
8
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
5
9
  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; }
6
10
  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; }
7
11
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -186,6 +190,36 @@ var getIsOpenDetailModal = function getIsOpenDetailModal(product, context) {
186
190
  scheduleTimeSlots: scheduleTimeSlots
187
191
  };
188
192
  };
193
+ var I18N_FIELD_MAP = {
194
+ title_i18n: 'title',
195
+ subtitle_i18n: 'subtitle',
196
+ description_i18n: 'description',
197
+ cover_i18n: 'cover'
198
+ };
199
+
200
+ /**
201
+ * 根据 locale 将商品的 i18n 字段覆盖到对应原始字段
202
+ */
203
+ export function applyI18nToProducts(products, locale) {
204
+ if (!locale) return products;
205
+ return products.map(function (product) {
206
+ var _patched;
207
+ var patched = null;
208
+ for (var _i = 0, _Object$entries = Object.entries(I18N_FIELD_MAP); _i < _Object$entries.length; _i++) {
209
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
210
+ i18nKey = _Object$entries$_i[0],
211
+ originalKey = _Object$entries$_i[1];
212
+ var i18nDict = product[i18nKey];
213
+ if (!i18nDict) continue;
214
+ var localizedValue = i18nDict[locale];
215
+ if (localizedValue) {
216
+ if (!patched) patched = _objectSpread({}, product);
217
+ patched[originalKey] = localizedValue;
218
+ }
219
+ }
220
+ return (_patched = patched) !== null && _patched !== void 0 ? _patched : product;
221
+ });
222
+ }
189
223
  var formatDataKey = function formatDataKey(data) {
190
224
  var _data$option, _data$bundle;
191
225
  var _data = _objectSpread({}, data);
@@ -52,6 +52,7 @@ export interface PisellCore {
52
52
  validateContext: (config: ModuleContextConfig) => boolean;
53
53
  serverOptions?: ServerOptions;
54
54
  server?: any;
55
+ setContext: (ctx: Partial<BusinessContext>) => void;
55
56
  }
56
57
  /**
57
58
  * 业务上下文接口
@@ -59,6 +60,7 @@ export interface PisellCore {
59
60
  export interface BusinessContext {
60
61
  userId?: string;
61
62
  companyId?: string;
63
+ locale?: string;
62
64
  [key: string]: any;
63
65
  }
64
66
  /**
@@ -29,6 +29,7 @@ declare class PisellOSCore implements PisellCore {
29
29
  getModuleExports<T = any>(name: string): T | null;
30
30
  hasModule(name: string): boolean;
31
31
  destroy(): Promise<void>;
32
+ setContext(ctx: Partial<BusinessContext>): void;
32
33
  /**
33
34
  * 验证上下文参数
34
35
  */
package/lib/core/index.js CHANGED
@@ -235,6 +235,10 @@ var PisellOSCore = class {
235
235
  this.plugins.clear();
236
236
  this.log("PisellOS 核心已销毁");
237
237
  }
238
+ setContext(ctx) {
239
+ this.context = { ...this.context, ...ctx };
240
+ this.log(`上下文已更新: ${JSON.stringify(Object.keys(ctx))}`);
241
+ }
238
242
  /**
239
243
  * 验证上下文参数
240
244
  */
@@ -284,6 +284,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
284
284
  * @private
285
285
  */
286
286
  async prepareProductsWithPrice(schedule_date, extraContext, options) {
287
+ var _a, _b;
287
288
  const tTotal = performance.now();
288
289
  const targetIds = options == null ? void 0 : options.productIds;
289
290
  const isIncremental = targetIds && targetIds.length > 0;
@@ -319,6 +320,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
319
320
  const context = {
320
321
  schedule_date,
321
322
  priceData,
323
+ locale: (_b = (_a = this.core) == null ? void 0 : _a.context) == null ? void 0 : _b.locale,
322
324
  ...extraContext
323
325
  };
324
326
  const tFormat = performance.now();
@@ -417,10 +419,14 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
417
419
  console.log(`[ProductsModule] 💰 应用价格数据到 ${products.length} 个商品`);
418
420
  return (0, import_product.applyPriceDataToProducts)(products, context.priceData);
419
421
  };
422
+ const i18nFormatter = (products, context) => {
423
+ return (0, import_product.applyI18nToProducts)(products, context.locale);
424
+ };
420
425
  const detailValueFormatter = (products, context) => {
421
426
  return (0, import_product.applyDetailValueToProducts)(products, context);
422
427
  };
423
428
  this.formatters.unshift(priceFormatter);
429
+ this.formatters.push(i18nFormatter);
424
430
  this.formatters.push(detailValueFormatter);
425
431
  this.isPriceFormatterRegistered = true;
426
432
  console.log("[ProductsModule] ✅ 内置价格格式化器已注册(第 1 个)");
@@ -948,6 +954,11 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
948
954
  if ((_c = msg.change_types) == null ? void 0 : _c.includes("price")) {
949
955
  const ids = msg.ids || (msg.id ? [msg.id] : []);
950
956
  priceRefreshIds.push(...ids);
957
+ if (msg.body) {
958
+ const bodyId = msg.body.id;
959
+ if (bodyId)
960
+ bodyUpdates.set(bodyId, msg.body);
961
+ }
951
962
  continue;
952
963
  }
953
964
  if (msg.body) {
@@ -986,7 +997,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
986
997
  if (freshProducts.length > 0) {
987
998
  await this.mergeProductsToStore(freshProducts);
988
999
  }
989
- this.logInfo("processProductSyncMessages: SSE 增量更新完成", {
1000
+ this.logInfo("processProductSyncMessages: SSE 增量更新完成123", {
990
1001
  requestedCount: uniqueSSEIds.length,
991
1002
  receivedCount: freshProducts.length
992
1003
  });
@@ -996,7 +1007,7 @@ var ProductsModule = class extends import_BaseModule.BaseModule {
996
1007
  ...uniqueSSEIds,
997
1008
  ...uniquePriceIds
998
1009
  ])];
999
- this.logInfo("processProductSyncMessages: 处理完成", {
1010
+ this.logInfo("processProductSyncMessages: 处理完成123", {
1000
1011
  deleteCount: uniqueDeleteIds.length,
1001
1012
  bodyUpdateCount: bodyUpdates.size,
1002
1013
  sseRefreshCount: uniqueSSEIds.length,
@@ -109,6 +109,7 @@ export interface ProductFormatterContext {
109
109
  schedule_date: string;
110
110
  priceData?: LoadProductsPriceData[];
111
111
  scheduleModule?: any;
112
+ locale?: string;
112
113
  }
113
114
  /**
114
115
  * 商品格式化器类型
@@ -10,6 +10,10 @@ export declare function perfMark(label: string, durationMs: number, meta?: Recor
10
10
  */
11
11
  export declare function applyPriceDataToProducts(products: ProductData[], priceData: LoadProductsPriceData[]): ProductData[];
12
12
  export declare const getIsSessionProduct: (product: ProductData) => boolean;
13
+ /**
14
+ * 根据 locale 将商品的 i18n 字段覆盖到对应原始字段
15
+ */
16
+ export declare function applyI18nToProducts(products: ProductData[], locale?: string): ProductData[];
13
17
  /**
14
18
  * 将详情值数据应用到商品列表
15
19
  * @param products 商品列表
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  var product_exports = {};
21
21
  __export(product_exports, {
22
22
  applyDetailValueToProducts: () => applyDetailValueToProducts,
23
+ applyI18nToProducts: () => applyI18nToProducts,
23
24
  applyPriceDataToProducts: () => applyPriceDataToProducts,
24
25
  getIsSessionProduct: () => getIsSessionProduct,
25
26
  perfMark: () => perfMark
@@ -155,6 +156,31 @@ var getIsOpenDetailModal = (product, context) => {
155
156
  scheduleTimeSlots
156
157
  };
157
158
  };
159
+ var I18N_FIELD_MAP = {
160
+ title_i18n: "title",
161
+ subtitle_i18n: "subtitle",
162
+ description_i18n: "description",
163
+ cover_i18n: "cover"
164
+ };
165
+ function applyI18nToProducts(products, locale) {
166
+ if (!locale)
167
+ return products;
168
+ return products.map((product) => {
169
+ let patched = null;
170
+ for (const [i18nKey, originalKey] of Object.entries(I18N_FIELD_MAP)) {
171
+ const i18nDict = product[i18nKey];
172
+ if (!i18nDict)
173
+ continue;
174
+ const localizedValue = i18nDict[locale];
175
+ if (localizedValue) {
176
+ if (!patched)
177
+ patched = { ...product };
178
+ patched[originalKey] = localizedValue;
179
+ }
180
+ }
181
+ return patched ?? product;
182
+ });
183
+ }
158
184
  var formatDataKey = (data) => {
159
185
  var _a, _b, _c, _d;
160
186
  const _data = {
@@ -258,6 +284,7 @@ function applyDetailValueToProducts(products, context) {
258
284
  // Annotate the CommonJS export names for ESM import in node:
259
285
  0 && (module.exports = {
260
286
  applyDetailValueToProducts,
287
+ applyI18nToProducts,
261
288
  applyPriceDataToProducts,
262
289
  getIsSessionProduct,
263
290
  perfMark
@@ -52,6 +52,7 @@ export interface PisellCore {
52
52
  validateContext: (config: ModuleContextConfig) => boolean;
53
53
  serverOptions?: ServerOptions;
54
54
  server?: any;
55
+ setContext: (ctx: Partial<BusinessContext>) => void;
55
56
  }
56
57
  /**
57
58
  * 业务上下文接口
@@ -59,6 +60,7 @@ export interface PisellCore {
59
60
  export interface BusinessContext {
60
61
  userId?: string;
61
62
  companyId?: string;
63
+ locale?: string;
62
64
  [key: string]: any;
63
65
  }
64
66
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.90",
4
+ "version": "2.2.92",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",