@pisell/pisellos 2.1.139 → 2.1.141

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.
@@ -11,10 +11,12 @@ export declare class ScanOrderLoggerModule extends BaseModule implements Module,
11
11
  protected defaultName: string;
12
12
  protected defaultVersion: string;
13
13
  private store;
14
+ private window?;
14
15
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
15
16
  setContext(context: ScanOrderLoggerContext): void;
16
17
  setProvider(provider: ScanOrderLoggerProviderType): void;
17
18
  setProviderConfig(providerConfig: ScanOrderLoggerProviderConfig): void;
19
+ private getCurrentHost;
18
20
  private buildRecord;
19
21
  addLog(params: ScanOrderLogInput): Promise<void>;
20
22
  }
@@ -46,6 +46,7 @@ export var ScanOrderLoggerModule = /*#__PURE__*/function (_BaseModule) {
46
46
  _defineProperty(_assertThisInitialized(_this), "defaultName", 'scanOrderLogger');
47
47
  _defineProperty(_assertThisInitialized(_this), "defaultVersion", '1.0.0');
48
48
  _defineProperty(_assertThisInitialized(_this), "store", void 0);
49
+ _defineProperty(_assertThisInitialized(_this), "window", void 0);
49
50
  return _this;
50
51
  }
51
52
  _createClass(ScanOrderLoggerModule, [{
@@ -64,6 +65,7 @@ export var ScanOrderLoggerModule = /*#__PURE__*/function (_BaseModule) {
64
65
  options = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
65
66
  this.core = core;
66
67
  this.store = options.store;
68
+ this.window = core.getPlugin('window') || undefined;
67
69
  provider = ((_options$otherParams = options.otherParams) === null || _options$otherParams === void 0 ? void 0 : _options$otherParams.provider) || 'feishu';
68
70
  providerConfig = ((_options$otherParams2 = options.otherParams) === null || _options$otherParams2 === void 0 ? void 0 : _options$otherParams2.providerConfig) || {};
69
71
  context = ((_options$otherParams3 = options.otherParams) === null || _options$otherParams3 === void 0 ? void 0 : _options$otherParams3.context) || {};
@@ -73,7 +75,7 @@ export var ScanOrderLoggerModule = /*#__PURE__*/function (_BaseModule) {
73
75
  grafana: _objectSpread(_objectSpread({}, defaultProviderConfig.grafana), providerConfig.grafana || {})
74
76
  });
75
77
  this.store.context = context;
76
- case 9:
78
+ case 10:
77
79
  case "end":
78
80
  return _context.stop();
79
81
  }
@@ -102,16 +104,27 @@ export var ScanOrderLoggerModule = /*#__PURE__*/function (_BaseModule) {
102
104
  grafana: _objectSpread(_objectSpread({}, this.store.providerConfig.grafana || {}), providerConfig.grafana || {})
103
105
  });
104
106
  }
107
+ }, {
108
+ key: "getCurrentHost",
109
+ value: function getCurrentHost() {
110
+ var _this$window;
111
+ var host = (_this$window = this.window) === null || _this$window === void 0 || (_this$window = _this$window.location) === null || _this$window === void 0 ? void 0 : _this$window.host;
112
+ if (typeof host === 'string' && host.length > 0) return host;
113
+ return undefined;
114
+ }
105
115
  }, {
106
116
  key: "buildRecord",
107
117
  value: function buildRecord(params) {
118
+ var host = this.getCurrentHost();
108
119
  return {
109
120
  level: params.level || 'info',
110
121
  title: params.title,
111
122
  timestamp: params.timestamp || dayjs().format('YYYY-MM-DD HH:mm:ss'),
112
123
  payload: params.payload || {},
113
124
  extra: params.extra || {},
114
- context: this.store.context || {}
125
+ context: _objectSpread(_objectSpread({}, this.store.context || {}), host ? {
126
+ host: host
127
+ } : {})
115
128
  };
116
129
  }
117
130
  }, {
@@ -142,62 +142,80 @@ function _flushQueue() {
142
142
  export var feishuLoggerProvider = {
143
143
  send: function send(payload) {
144
144
  return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
145
- var _payload$providerConf, _payload$providerConf2, _payload$providerConf3;
146
- var webhook, throttleMs;
145
+ var _payload$providerConf, _payload$providerConf2, _payload$providerConf3, _payload$providerConf4;
146
+ var webhook, errorHook, throttleMs;
147
147
  return _regeneratorRuntime().wrap(function _callee$(_context) {
148
148
  while (1) switch (_context.prev = _context.next) {
149
149
  case 0:
150
150
  cachedProviderConfig = payload.providerConfig;
151
151
  webhook = (_payload$providerConf = payload.providerConfig) === null || _payload$providerConf === void 0 || (_payload$providerConf = _payload$providerConf.feishu) === null || _payload$providerConf === void 0 ? void 0 : _payload$providerConf.webhook;
152
- if (webhook) {
153
- _context.next = 5;
152
+ errorHook = (_payload$providerConf2 = payload.providerConfig) === null || _payload$providerConf2 === void 0 || (_payload$providerConf2 = _payload$providerConf2.feishu) === null || _payload$providerConf2 === void 0 ? void 0 : _payload$providerConf2.errorHook;
153
+ if (!(typeof fetch !== 'function')) {
154
+ _context.next = 6;
154
155
  break;
155
156
  }
156
- console.warn('[ScanOrderLogger] Feishu webhook 未配置,跳过日志上报');
157
+ console.warn('[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志上报');
157
158
  return _context.abrupt("return");
158
- case 5:
159
- if (isWebhookUsable(webhook)) {
160
- _context.next = 7;
159
+ case 6:
160
+ if (!(payload.record.level === 'error' && isWebhookUsable(errorHook))) {
161
+ _context.next = 16;
161
162
  break;
162
163
  }
164
+ _context.prev = 7;
165
+ _context.next = 10;
166
+ return postToFeishu(errorHook, buildFeishuBody([payload.record]));
167
+ case 10:
168
+ _context.next = 15;
169
+ break;
170
+ case 12:
171
+ _context.prev = 12;
172
+ _context.t0 = _context["catch"](7);
173
+ console.warn('[ScanOrderLogger] Feishu errorHook 上报失败', _context.t0);
174
+ case 15:
163
175
  return _context.abrupt("return");
164
- case 7:
165
- if (!(typeof fetch !== 'function')) {
166
- _context.next = 10;
176
+ case 16:
177
+ if (webhook) {
178
+ _context.next = 19;
167
179
  break;
168
180
  }
169
- console.warn('[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志上报');
181
+ console.warn('[ScanOrderLogger] Feishu webhook 未配置,跳过日志上报');
170
182
  return _context.abrupt("return");
171
- case 10:
172
- throttleMs = (_payload$providerConf2 = (_payload$providerConf3 = payload.providerConfig) === null || _payload$providerConf3 === void 0 || (_payload$providerConf3 = _payload$providerConf3.feishu) === null || _payload$providerConf3 === void 0 ? void 0 : _payload$providerConf3.throttleMs) !== null && _payload$providerConf2 !== void 0 ? _payload$providerConf2 : DEFAULT_THROTTLE_MS;
173
- if (!(throttleMs <= 0)) {
183
+ case 19:
184
+ if (isWebhookUsable(webhook)) {
174
185
  _context.next = 21;
175
186
  break;
176
187
  }
177
- _context.prev = 12;
178
- _context.next = 15;
188
+ return _context.abrupt("return");
189
+ case 21:
190
+ throttleMs = (_payload$providerConf3 = (_payload$providerConf4 = payload.providerConfig) === null || _payload$providerConf4 === void 0 || (_payload$providerConf4 = _payload$providerConf4.feishu) === null || _payload$providerConf4 === void 0 ? void 0 : _payload$providerConf4.throttleMs) !== null && _payload$providerConf3 !== void 0 ? _payload$providerConf3 : DEFAULT_THROTTLE_MS;
191
+ if (!(throttleMs <= 0)) {
192
+ _context.next = 32;
193
+ break;
194
+ }
195
+ _context.prev = 23;
196
+ _context.next = 26;
179
197
  return postToFeishu(webhook, buildFeishuBody([payload.record]));
180
- case 15:
181
- _context.next = 20;
198
+ case 26:
199
+ _context.next = 31;
182
200
  break;
183
- case 17:
184
- _context.prev = 17;
185
- _context.t0 = _context["catch"](12);
186
- console.warn('[ScanOrderLogger] Feishu 日志上报失败', _context.t0);
187
- case 20:
201
+ case 28:
202
+ _context.prev = 28;
203
+ _context.t1 = _context["catch"](23);
204
+ console.warn('[ScanOrderLogger] Feishu 日志上报失败', _context.t1);
205
+ case 31:
188
206
  return _context.abrupt("return");
189
- case 21:
207
+ case 32:
190
208
  pendingQueue.push(payload.record);
191
209
  if (!flushTimer) {
192
210
  flushTimer = setTimeout(function () {
193
211
  void flushQueue();
194
212
  }, throttleMs);
195
213
  }
196
- case 23:
214
+ case 34:
197
215
  case "end":
198
216
  return _context.stop();
199
217
  }
200
- }, _callee, null, [[12, 17]]);
218
+ }, _callee, null, [[7, 12], [23, 28]]);
201
219
  }))();
202
220
  }
203
221
  };
@@ -2,6 +2,7 @@ export type ScanOrderLogLevel = 'info' | 'warning' | 'error' | 'debug';
2
2
  export type ScanOrderLoggerProviderType = 'feishu' | 'grafana';
3
3
  export interface ScanOrderLoggerProviderFeishuConfig {
4
4
  webhook?: string;
5
+ errorHook?: string;
5
6
  /**
6
7
  * 节流窗口毫秒数,默认 3000ms
7
8
  * - >0:首条日志进入队列并启动定时器,窗口结束后合并成一条 Feishu post 统一发送
@@ -310,7 +310,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
310
310
  date: string;
311
311
  status: string;
312
312
  week: string;
313
- weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
313
+ weekNum: 0 | 1 | 4 | 2 | 3 | 5 | 6;
314
314
  }[]>;
315
315
  submitTimeSlot(timeSlots: TimeSliceItem): void;
316
316
  private getScheduleDataByIds;
@@ -357,7 +357,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
357
357
  };
358
358
  setOtherData(key: string, value: any): void;
359
359
  getOtherData(key: string): any;
360
- getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
360
+ getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
361
361
  /**
362
362
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
363
363
  *
@@ -5,6 +5,7 @@ import type { UpdateProductInOrderParams } from '../../modules/Order/types';
5
5
  import type { Discount } from '../../modules/Discount/types';
6
6
  import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
7
7
  import type { StrategyConfig } from '../../model/strategy/type';
8
+ import type { ProductData } from '../../modules/Product/types';
8
9
  export * from './types';
9
10
  interface ScanOrderItemRuleRuntimeConfig {
10
11
  strategyConfigs?: StrategyConfig[];
@@ -41,6 +42,7 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
41
42
  private logMethodStart;
42
43
  private logMethodSuccess;
43
44
  private logMethodError;
45
+ private assertProductListLoaded;
44
46
  addLog(params: ScanOrderAddLogParams): Promise<void>;
45
47
  private normalizeCustomerId;
46
48
  private resolveCustomerIdFromLoginPayload;
@@ -122,7 +124,7 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
122
124
  orderAmount: number;
123
125
  orderItems: any[];
124
126
  }>;
125
- getProductList(): Promise<any>;
127
+ getProductList(): Promise<ProductData[]>;
126
128
  getOtherParams(): Record<string, any>;
127
129
  setOtherParams(params: Record<string, any>, { cover }?: {
128
130
  cover?: boolean;
@@ -192,6 +192,16 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
192
192
  })
193
193
  });
194
194
  }
195
+ }, {
196
+ key: "assertProductListLoaded",
197
+ value: function assertProductListLoaded(method, result) {
198
+ var payload = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
199
+ if (Array.isArray(result)) return result;
200
+ var error = result instanceof Error ? result : new Error('商品列表接口返回异常');
201
+ this.logMethodError(method, error, payload);
202
+ error.__scanOrderLogged = true;
203
+ throw error;
204
+ }
195
205
  }, {
196
206
  key: "addLog",
197
207
  value: function () {
@@ -497,7 +507,8 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
497
507
  var loggerProvider = ((_this4$otherParams = _this4.otherParams) === null || _this4$otherParams === void 0 ? void 0 : _this4$otherParams.scanOrderLoggerProvider) || 'feishu';
498
508
  var loggerConfig = ((_this4$otherParams2 = _this4.otherParams) === null || _this4$otherParams2 === void 0 ? void 0 : _this4$otherParams2.scanOrderLoggerConfig) || {
499
509
  feishu: {
500
- webhook: 'https://open.feishu.cn/open-apis/bot/v2/hook/216b3fe6-af98-424e-8706-f0471241a7ed'
510
+ webhook: 'https://open.feishu.cn/open-apis/bot/v2/hook/216b3fe6-af98-424e-8706-f0471241a7ed',
511
+ errorHook: 'https://open.feishu.cn/open-apis/bot/v2/hook/015b7c2a-dd3c-4c30-9898-ef0f5253111f'
501
512
  }
502
513
  };
503
514
  _this4.core.registerModule(targetModule, {
@@ -2508,7 +2519,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2508
2519
  key: "checkResourceAvailable",
2509
2520
  value: function () {
2510
2521
  var _checkResourceAvailable = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee36(resourceId, hasOrderId) {
2511
- var _this$otherParams$bus, _this$otherParams10, _this$otherParams$cha, _this$otherParams11, _this$otherParams12, _this$otherParams12$g, _occupyDetail$form_re, _occupyDetail$form_re2, _this$otherParams13, _this$store$order5, _this$store$order7, _this$store$order7$ge, _this$otherParams14, businessCode, channel, openDataTarget, openData, dineInConfig, closedBehaviorValue, closedMessage, basicUnavailableMessage, pauseMessage, makeShopClosed, operatingHourIds, outsideOperatingHours, scheduleList, now, tempOrder, reservationLinkIds, pendingRequestEntryPax, pendingRequestPaxMin, pendingRequestPaxMax, reservationProductList, scheduleDate, scheduleDatetime, loaded, occupancyMinutes, paxBounds, occupyDetail, resourceSelectType, resourceState, availabilityInfo, _this$store$order6, _res$data, res, entryPaxNumber, lastOrderInfo, historicalItems;
2522
+ var _this$otherParams$bus, _this$otherParams10, _this$otherParams$cha, _this$otherParams11, _this$otherParams12, _this$otherParams12$g, _occupyDetail$form_re, _occupyDetail$form_re2, _this$otherParams13, _this$store$order5, _this$store$order7, _this$store$order7$ge, _this$otherParams14, businessCode, channel, openDataTarget, openData, dineInConfig, closedBehaviorValue, closedMessage, basicUnavailableMessage, pauseMessage, makeShopClosed, operatingHourIds, outsideOperatingHours, scheduleList, now, tempOrder, reservationLinkIds, pendingRequestEntryPax, pendingRequestPaxMin, pendingRequestPaxMax, reservationProductList, scheduleDate, scheduleDatetime, loaded, occupancyMinutes, paxBounds, error, occupyDetail, resourceSelectType, resourceState, availabilityInfo, _this$store$order6, _res$data, res, entryPaxNumber, lastOrderInfo, historicalItems;
2512
2523
  return _regeneratorRuntime().wrap(function _callee36$(_context36) {
2513
2524
  while (1) switch (_context36.prev = _context36.next) {
2514
2525
  case 0:
@@ -2642,13 +2653,13 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2642
2653
  }
2643
2654
  } else {
2644
2655
  this.enabledReservationRuleProducts = [];
2645
- void this.addScanOrderLog({
2646
- level: 'error',
2647
- title: '[ScanOrder] enabled_reservation_rules product query failed',
2648
- payload: {
2649
- linkIds: reservationLinkIds,
2650
- error: this.serializeError(loaded)
2651
- }
2656
+ error = loaded instanceof Error ? loaded : new Error('预约规则商品列表接口返回异常');
2657
+ this.logMethodError('loadReservationRuleProducts', error, {
2658
+ resourceId: resourceId,
2659
+ reservationLinkIds: reservationLinkIds,
2660
+ scheduleDate: scheduleDate,
2661
+ scheduleDatetime: scheduleDatetime,
2662
+ cacheId: this.cacheId
2652
2663
  });
2653
2664
  }
2654
2665
  case 46:
@@ -2819,7 +2830,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2819
2830
  value: function () {
2820
2831
  var _getProductList = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee38() {
2821
2832
  var _this$otherParams15;
2822
- var menu_list_ids, _this$store$products, res, formattedRes;
2833
+ var menu_list_ids, res, productList, formattedRes;
2823
2834
  return _regeneratorRuntime().wrap(function _callee38$(_context38) {
2824
2835
  while (1) switch (_context38.prev = _context38.next) {
2825
2836
  case 0:
@@ -2829,30 +2840,45 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
2829
2840
  return Number(n.value);
2830
2841
  })) || [];
2831
2842
  _context38.prev = 2;
2832
- _context38.next = 5;
2833
- return (_this$store$products = this.store.products) === null || _this$store$products === void 0 ? void 0 : _this$store$products.loadProducts({
2843
+ if (this.store.products) {
2844
+ _context38.next = 5;
2845
+ break;
2846
+ }
2847
+ throw new Error('products 模块未初始化');
2848
+ case 5:
2849
+ _context38.next = 7;
2850
+ return this.store.products.loadProducts({
2834
2851
  menu_list_ids: menu_list_ids,
2835
2852
  cacheId: this.cacheId,
2836
2853
  schedule_date: dayjs().format('YYYY-MM-DD'),
2837
2854
  schedule_datetime: dayjs().format('YYYY-MM-DD HH:mm:ss')
2838
2855
  });
2839
- case 5:
2856
+ case 7:
2840
2857
  res = _context38.sent;
2841
- formattedRes = attachItemRuleLimitsToTopLevelProducts(res, this.store.itemRuleQuantityLimits || []);
2858
+ productList = this.assertProductListLoaded('getProductList', res, {
2859
+ menu_list_ids: menu_list_ids,
2860
+ cacheId: this.cacheId
2861
+ });
2862
+ formattedRes = attachItemRuleLimitsToTopLevelProducts(productList, this.store.itemRuleQuantityLimits || []);
2842
2863
  this.logMethodSuccess('getProductList', {
2843
2864
  menuCount: menu_list_ids.length
2844
2865
  });
2845
2866
  return _context38.abrupt("return", formattedRes);
2846
- case 11:
2847
- _context38.prev = 11;
2867
+ case 14:
2868
+ _context38.prev = 14;
2848
2869
  _context38.t0 = _context38["catch"](2);
2849
- this.logMethodError('getProductList', _context38.t0.message);
2870
+ if (!(_context38.t0 !== null && _context38.t0 !== void 0 && _context38.t0.__scanOrderLogged)) {
2871
+ this.logMethodError('getProductList', _context38.t0, {
2872
+ menu_list_ids: menu_list_ids,
2873
+ cacheId: this.cacheId
2874
+ });
2875
+ }
2850
2876
  throw _context38.t0;
2851
- case 15:
2877
+ case 18:
2852
2878
  case "end":
2853
2879
  return _context38.stop();
2854
2880
  }
2855
- }, _callee38, this, [[2, 11]]);
2881
+ }, _callee38, this, [[2, 14]]);
2856
2882
  }));
2857
2883
  function getProductList() {
2858
2884
  return _getProductList.apply(this, arguments);
@@ -503,7 +503,10 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
503
503
  } : {};
504
504
  var loggerProvider = ((_this4$otherParams = _this4.otherParams) === null || _this4$otherParams === void 0 ? void 0 : _this4$otherParams.loggerProvider) || 'feishu';
505
505
  var loggerConfig = ((_this4$otherParams2 = _this4.otherParams) === null || _this4$otherParams2 === void 0 ? void 0 : _this4$otherParams2.loggerConfig) || {
506
- feishu: {}
506
+ feishu: {
507
+ webhook: 'https://open.feishu.cn/open-apis/bot/v2/hook/8f069b14-9d39-4728-8f78-b56f393bfde8',
508
+ errorHook: 'https://open.feishu.cn/open-apis/bot/v2/hook/bdefae5e-f233-4705-8688-946887d9543d'
509
+ }
507
510
  };
508
511
  _this4.core.registerModule(targetModule, {
509
512
  initialState: initialState,
@@ -833,22 +836,23 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
833
836
  case 8:
834
837
  associatedMenus = ((_this$otherParams7 = this.otherParams) === null || _this$otherParams7 === void 0 || (_this$otherParams7 = _this$otherParams7.openData) === null || _this$otherParams7 === void 0 ? void 0 : _this$otherParams7['menu.associated_menus']) || [];
835
838
  if (associatedMenus.length) {
836
- _context11.next = 11;
839
+ _context11.next = 12;
837
840
  break;
838
841
  }
842
+ this.logMethodError('loadAllProducts', new Error('未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置'));
839
843
  throw new Error('未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置');
840
- case 11:
844
+ case 12:
841
845
  menuListIds = associatedMenus.map(function (n) {
842
846
  return Number(n.value);
843
847
  });
844
- _context11.next = 14;
848
+ _context11.next = 15;
845
849
  return this.store.venueProducts.loadProducts({
846
850
  menu_list_ids: menuListIds,
847
851
  cacheId: this.cacheId,
848
852
  schedule_date: dayjs().format('YYYY-MM-DD'),
849
853
  schedule_datetime: dayjs().format('YYYY-MM-DD HH:mm:ss')
850
854
  });
851
- case 14:
855
+ case 15:
852
856
  allProducts = _context11.sent;
853
857
  list = Array.isArray(allProducts) ? allProducts : [];
854
858
  venueList = list.filter(function (p) {
@@ -876,16 +880,16 @@ export var VenueBookingImpl = /*#__PURE__*/function (_BaseModule) {
876
880
  venueProducts: venueList,
877
881
  addonProducts: addonList
878
882
  });
879
- case 27:
880
- _context11.prev = 27;
883
+ case 28:
884
+ _context11.prev = 28;
881
885
  _context11.t0 = _context11["catch"](1);
882
886
  this.logMethodError('loadAllProducts', _context11.t0);
883
887
  throw _context11.t0;
884
- case 31:
888
+ case 32:
885
889
  case "end":
886
890
  return _context11.stop();
887
891
  }
888
- }, _callee11, this, [[1, 27]]);
892
+ }, _callee11, this, [[1, 28]]);
889
893
  }));
890
894
  function _doLoadAllProducts() {
891
895
  return _doLoadAllProducts2.apply(this, arguments);
@@ -11,10 +11,12 @@ export declare class ScanOrderLoggerModule extends BaseModule implements Module,
11
11
  protected defaultName: string;
12
12
  protected defaultVersion: string;
13
13
  private store;
14
+ private window?;
14
15
  initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
15
16
  setContext(context: ScanOrderLoggerContext): void;
16
17
  setProvider(provider: ScanOrderLoggerProviderType): void;
17
18
  setProviderConfig(providerConfig: ScanOrderLoggerProviderConfig): void;
19
+ private getCurrentHost;
18
20
  private buildRecord;
19
21
  addLog(params: ScanOrderLogInput): Promise<void>;
20
22
  }
@@ -60,6 +60,7 @@ var ScanOrderLoggerModule = class extends import_BaseModule.BaseModule {
60
60
  var _a, _b, _c;
61
61
  this.core = core;
62
62
  this.store = options.store;
63
+ this.window = core.getPlugin("window") || void 0;
63
64
  const provider = ((_a = options.otherParams) == null ? void 0 : _a.provider) || "feishu";
64
65
  const providerConfig = ((_b = options.otherParams) == null ? void 0 : _b.providerConfig) || {};
65
66
  const context = ((_c = options.otherParams) == null ? void 0 : _c.context) || {};
@@ -101,14 +102,25 @@ var ScanOrderLoggerModule = class extends import_BaseModule.BaseModule {
101
102
  }
102
103
  };
103
104
  }
105
+ getCurrentHost() {
106
+ var _a, _b;
107
+ const host = (_b = (_a = this.window) == null ? void 0 : _a.location) == null ? void 0 : _b.host;
108
+ if (typeof host === "string" && host.length > 0)
109
+ return host;
110
+ return void 0;
111
+ }
104
112
  buildRecord(params) {
113
+ const host = this.getCurrentHost();
105
114
  return {
106
115
  level: params.level || "info",
107
116
  title: params.title,
108
117
  timestamp: params.timestamp || (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
109
118
  payload: params.payload || {},
110
119
  extra: params.extra || {},
111
- context: this.store.context || {}
120
+ context: {
121
+ ...this.store.context || {},
122
+ ...host ? { host } : {}
123
+ }
112
124
  };
113
125
  }
114
126
  async addLog(params) {
@@ -112,20 +112,29 @@ async function flushQueue() {
112
112
  }
113
113
  var feishuLoggerProvider = {
114
114
  async send(payload) {
115
- var _a, _b, _c, _d;
115
+ var _a, _b, _c, _d, _e, _f;
116
116
  cachedProviderConfig = payload.providerConfig;
117
117
  const webhook = (_b = (_a = payload.providerConfig) == null ? void 0 : _a.feishu) == null ? void 0 : _b.webhook;
118
+ const errorHook = (_d = (_c = payload.providerConfig) == null ? void 0 : _c.feishu) == null ? void 0 : _d.errorHook;
119
+ if (typeof fetch !== "function") {
120
+ console.warn("[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志上报");
121
+ return;
122
+ }
123
+ if (payload.record.level === "error" && isWebhookUsable(errorHook)) {
124
+ try {
125
+ await postToFeishu(errorHook, buildFeishuBody([payload.record]));
126
+ } catch (error) {
127
+ console.warn("[ScanOrderLogger] Feishu errorHook 上报失败", error);
128
+ }
129
+ return;
130
+ }
118
131
  if (!webhook) {
119
132
  console.warn("[ScanOrderLogger] Feishu webhook 未配置,跳过日志上报");
120
133
  return;
121
134
  }
122
135
  if (!isWebhookUsable(webhook))
123
136
  return;
124
- if (typeof fetch !== "function") {
125
- console.warn("[ScanOrderLogger] 当前环境不支持 fetch,跳过 Feishu 日志上报");
126
- return;
127
- }
128
- const throttleMs = ((_d = (_c = payload.providerConfig) == null ? void 0 : _c.feishu) == null ? void 0 : _d.throttleMs) ?? DEFAULT_THROTTLE_MS;
137
+ const throttleMs = ((_f = (_e = payload.providerConfig) == null ? void 0 : _e.feishu) == null ? void 0 : _f.throttleMs) ?? DEFAULT_THROTTLE_MS;
129
138
  if (throttleMs <= 0) {
130
139
  try {
131
140
  await postToFeishu(webhook, buildFeishuBody([payload.record]));
@@ -2,6 +2,7 @@ export type ScanOrderLogLevel = 'info' | 'warning' | 'error' | 'debug';
2
2
  export type ScanOrderLoggerProviderType = 'feishu' | 'grafana';
3
3
  export interface ScanOrderLoggerProviderFeishuConfig {
4
4
  webhook?: string;
5
+ errorHook?: string;
5
6
  /**
6
7
  * 节流窗口毫秒数,默认 3000ms
7
8
  * - >0:首条日志进入队列并启动定时器,窗口结束后合并成一条 Feishu post 统一发送
@@ -310,7 +310,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
310
310
  date: string;
311
311
  status: string;
312
312
  week: string;
313
- weekNum: 0 | 1 | 2 | 3 | 4 | 5 | 6;
313
+ weekNum: 0 | 1 | 4 | 2 | 3 | 5 | 6;
314
314
  }[]>;
315
315
  submitTimeSlot(timeSlots: TimeSliceItem): void;
316
316
  private getScheduleDataByIds;
@@ -357,7 +357,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
357
357
  };
358
358
  setOtherData(key: string, value: any): void;
359
359
  getOtherData(key: string): any;
360
- getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
360
+ getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
361
361
  /**
362
362
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
363
363
  *
@@ -5,6 +5,7 @@ import type { UpdateProductInOrderParams } from '../../modules/Order/types';
5
5
  import type { Discount } from '../../modules/Discount/types';
6
6
  import { type CartItemSummary, type PaxInfo, type QuantityCheckResult, type QuantityLimitResult } from '../../model/strategy/adapter/itemRule';
7
7
  import type { StrategyConfig } from '../../model/strategy/type';
8
+ import type { ProductData } from '../../modules/Product/types';
8
9
  export * from './types';
9
10
  interface ScanOrderItemRuleRuntimeConfig {
10
11
  strategyConfigs?: StrategyConfig[];
@@ -41,6 +42,7 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
41
42
  private logMethodStart;
42
43
  private logMethodSuccess;
43
44
  private logMethodError;
45
+ private assertProductListLoaded;
44
46
  addLog(params: ScanOrderAddLogParams): Promise<void>;
45
47
  private normalizeCustomerId;
46
48
  private resolveCustomerIdFromLoginPayload;
@@ -122,7 +124,7 @@ export declare class ScanOrderImpl extends BaseModule implements Module {
122
124
  orderAmount: number;
123
125
  orderItems: any[];
124
126
  }>;
125
- getProductList(): Promise<any>;
127
+ getProductList(): Promise<ProductData[]>;
126
128
  getOtherParams(): Record<string, any>;
127
129
  setOtherParams(params: Record<string, any>, { cover }?: {
128
130
  cover?: boolean;
@@ -155,6 +155,14 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
155
155
  }
156
156
  });
157
157
  }
158
+ assertProductListLoaded(method, result, payload = {}) {
159
+ if (Array.isArray(result))
160
+ return result;
161
+ const error = result instanceof Error ? result : new Error("商品列表接口返回异常");
162
+ this.logMethodError(method, error, payload);
163
+ error.__scanOrderLogged = true;
164
+ throw error;
165
+ }
158
166
  async addLog(params) {
159
167
  await this.addScanOrderLog({
160
168
  ...params,
@@ -324,7 +332,8 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
324
332
  const loggerProvider = ((_c2 = this.otherParams) == null ? void 0 : _c2.scanOrderLoggerProvider) || "feishu";
325
333
  const loggerConfig = ((_d2 = this.otherParams) == null ? void 0 : _d2.scanOrderLoggerConfig) || {
326
334
  feishu: {
327
- webhook: "https://open.feishu.cn/open-apis/bot/v2/hook/216b3fe6-af98-424e-8706-f0471241a7ed"
335
+ webhook: "https://open.feishu.cn/open-apis/bot/v2/hook/216b3fe6-af98-424e-8706-f0471241a7ed",
336
+ errorHook: "https://open.feishu.cn/open-apis/bot/v2/hook/015b7c2a-dd3c-4c30-9898-ef0f5253111f"
328
337
  }
329
338
  };
330
339
  this.core.registerModule(targetModule, {
@@ -1558,13 +1567,13 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1558
1567
  }
1559
1568
  } else {
1560
1569
  this.enabledReservationRuleProducts = [];
1561
- void this.addScanOrderLog({
1562
- level: "error",
1563
- title: "[ScanOrder] enabled_reservation_rules product query failed",
1564
- payload: {
1565
- linkIds: reservationLinkIds,
1566
- error: this.serializeError(loaded)
1567
- }
1570
+ const error = loaded instanceof Error ? loaded : new Error("预约规则商品列表接口返回异常");
1571
+ this.logMethodError("loadReservationRuleProducts", error, {
1572
+ resourceId,
1573
+ reservationLinkIds,
1574
+ scheduleDate,
1575
+ scheduleDatetime,
1576
+ cacheId: this.cacheId
1568
1577
  });
1569
1578
  }
1570
1579
  }
@@ -1680,18 +1689,24 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1680
1689
  }
1681
1690
  // 获取商品列表
1682
1691
  async getProductList() {
1683
- var _a, _b, _c;
1692
+ var _a, _b;
1684
1693
  this.logMethodStart("getProductList");
1685
1694
  const menu_list_ids = ((_b = (_a = this.otherParams) == null ? void 0 : _a.dineInConfig) == null ? void 0 : _b["menu.associated_menus"].map((n) => Number(n.value))) || [];
1686
1695
  try {
1687
- const res = await ((_c = this.store.products) == null ? void 0 : _c.loadProducts({
1696
+ if (!this.store.products)
1697
+ throw new Error("products 模块未初始化");
1698
+ const res = await this.store.products.loadProducts({
1688
1699
  menu_list_ids,
1689
1700
  cacheId: this.cacheId,
1690
1701
  schedule_date: (0, import_dayjs.default)().format("YYYY-MM-DD"),
1691
1702
  schedule_datetime: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
1692
- }));
1703
+ });
1704
+ const productList = this.assertProductListLoaded("getProductList", res, {
1705
+ menu_list_ids,
1706
+ cacheId: this.cacheId
1707
+ });
1693
1708
  const formattedRes = (0, import_utils.attachItemRuleLimitsToTopLevelProducts)(
1694
- res,
1709
+ productList,
1695
1710
  this.store.itemRuleQuantityLimits || []
1696
1711
  );
1697
1712
  this.logMethodSuccess("getProductList", {
@@ -1699,7 +1714,12 @@ var _ScanOrderImpl = class extends import_BaseModule.BaseModule {
1699
1714
  });
1700
1715
  return formattedRes;
1701
1716
  } catch (error) {
1702
- this.logMethodError("getProductList", error.message);
1717
+ if (!(error == null ? void 0 : error.__scanOrderLogged)) {
1718
+ this.logMethodError("getProductList", error, {
1719
+ menu_list_ids,
1720
+ cacheId: this.cacheId
1721
+ });
1722
+ }
1703
1723
  throw error;
1704
1724
  }
1705
1725
  }
@@ -345,7 +345,10 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
345
345
  } : {};
346
346
  const loggerProvider = ((_c2 = this.otherParams) == null ? void 0 : _c2.loggerProvider) || "feishu";
347
347
  const loggerConfig = ((_d2 = this.otherParams) == null ? void 0 : _d2.loggerConfig) || {
348
- feishu: {}
348
+ feishu: {
349
+ webhook: "https://open.feishu.cn/open-apis/bot/v2/hook/8f069b14-9d39-4728-8f78-b56f393bfde8",
350
+ errorHook: "https://open.feishu.cn/open-apis/bot/v2/hook/bdefae5e-f233-4705-8688-946887d9543d"
351
+ }
349
352
  };
350
353
  this.core.registerModule(targetModule, {
351
354
  initialState,
@@ -526,6 +529,7 @@ var _VenueBookingImpl = class extends import_BaseModule.BaseModule {
526
529
  await this.loadOpenDataConfig();
527
530
  const associatedMenus = ((_b = (_a = this.otherParams) == null ? void 0 : _a.openData) == null ? void 0 : _b["menu.associated_menus"]) || [];
528
531
  if (!associatedMenus.length) {
532
+ this.logMethodError("loadAllProducts", new Error("未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置"));
529
533
  throw new Error("未获取到餐牌配置(menu.associated_menus),请检查 OpenData 配置");
530
534
  }
531
535
  const menuListIds = associatedMenus.map((n) => Number(n.value));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.1.139",
4
+ "version": "2.1.141",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",