@pisell/pisellos 0.0.479 → 0.0.481

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 (147) hide show
  1. package/dist/core/index.d.ts +3 -2
  2. package/dist/core/index.js +7 -0
  3. package/dist/effects/index.d.ts +2 -2
  4. package/dist/effects/index.js +34 -81
  5. package/dist/model/strategy/adapter/promotion/evaluator.js +99 -26
  6. package/dist/model/strategy/adapter/walletPass/type.d.ts +9 -2
  7. package/dist/model/strategy/adapter/walletPass/utils.d.ts +6 -6
  8. package/dist/model/strategy/adapter/walletPass/utils.js +111 -72
  9. package/dist/modules/Customer/index.js +1 -1
  10. package/dist/modules/Discount/index.d.ts +6 -2
  11. package/dist/modules/Discount/index.js +14 -8
  12. package/dist/modules/Order/index.d.ts +1 -1
  13. package/dist/modules/Order/index.js +18 -13
  14. package/dist/modules/Payment/index.d.ts +4 -0
  15. package/dist/modules/Payment/index.js +774 -649
  16. package/dist/modules/Payment/walletpass.js +44 -17
  17. package/dist/modules/Product/index.d.ts +1 -1
  18. package/dist/modules/Product/types.d.ts +2 -0
  19. package/dist/modules/ProductList/index.d.ts +3 -0
  20. package/dist/modules/ProductList/index.js +9 -7
  21. package/dist/modules/Rules/index.d.ts +2 -2
  22. package/dist/modules/Rules/index.js +37 -31
  23. package/dist/modules/Rules/types.d.ts +2 -2
  24. package/dist/modules/Schedule/index.d.ts +9 -0
  25. package/dist/modules/Schedule/index.js +15 -2
  26. package/dist/plugins/app-types/app/app.d.ts +1 -0
  27. package/dist/plugins/request.d.ts +2 -0
  28. package/dist/server/index.d.ts +107 -2
  29. package/dist/server/index.js +1507 -279
  30. package/dist/server/modules/index.d.ts +6 -0
  31. package/dist/server/modules/index.js +7 -0
  32. package/dist/server/modules/menu/index.d.ts +19 -0
  33. package/dist/server/modules/menu/index.js +221 -71
  34. package/dist/server/modules/order/index.d.ts +87 -0
  35. package/dist/server/modules/order/index.js +916 -0
  36. package/dist/server/modules/order/types.d.ts +530 -0
  37. package/dist/server/modules/order/types.js +141 -0
  38. package/dist/server/modules/order/utils/filterBookings.d.ts +6 -0
  39. package/dist/server/modules/order/utils/filterBookings.js +350 -0
  40. package/dist/server/modules/order/utils/filterOrders.d.ts +15 -0
  41. package/dist/server/modules/order/utils/filterOrders.js +226 -0
  42. package/dist/server/modules/products/index.d.ts +117 -5
  43. package/dist/server/modules/products/index.js +1450 -240
  44. package/dist/server/modules/products/types.d.ts +25 -1
  45. package/dist/server/modules/products/types.js +3 -0
  46. package/dist/server/modules/resource/index.d.ts +86 -0
  47. package/dist/server/modules/resource/index.js +1128 -0
  48. package/dist/server/modules/resource/types.d.ts +121 -0
  49. package/dist/server/modules/resource/types.js +47 -0
  50. package/dist/server/modules/schedule/index.d.ts +19 -0
  51. package/dist/server/modules/schedule/index.js +229 -68
  52. package/dist/server/utils/product.d.ts +5 -0
  53. package/dist/server/utils/product.js +71 -31
  54. package/dist/solution/BookingTicket/index.d.ts +10 -2
  55. package/dist/solution/BookingTicket/index.js +41 -28
  56. package/dist/solution/BookingTicket/utils/scan/index.js +1 -1
  57. package/dist/solution/Checkout/index.d.ts +1 -0
  58. package/dist/solution/Checkout/index.js +286 -188
  59. package/dist/solution/Checkout/utils/index.d.ts +2 -1
  60. package/dist/solution/Checkout/utils/index.js +6 -4
  61. package/dist/solution/RegisterAndLogin/config.js +340 -1
  62. package/dist/solution/Sales/index.d.ts +96 -0
  63. package/dist/solution/Sales/index.js +566 -0
  64. package/dist/solution/Sales/types.d.ts +67 -0
  65. package/dist/solution/Sales/types.js +26 -0
  66. package/dist/solution/ShopDiscount/index.d.ts +1 -0
  67. package/dist/solution/ShopDiscount/index.js +35 -22
  68. package/dist/solution/ShopDiscount/types.d.ts +6 -0
  69. package/dist/solution/ShopDiscount/utils.d.ts +9 -0
  70. package/dist/solution/ShopDiscount/utils.js +21 -27
  71. package/dist/solution/index.d.ts +2 -1
  72. package/dist/solution/index.js +2 -1
  73. package/dist/types/index.d.ts +5 -0
  74. package/lib/core/index.d.ts +3 -2
  75. package/lib/core/index.js +4 -0
  76. package/lib/effects/index.d.ts +2 -2
  77. package/lib/effects/index.js +22 -31
  78. package/lib/model/strategy/adapter/promotion/evaluator.js +57 -8
  79. package/lib/model/strategy/adapter/walletPass/type.d.ts +9 -2
  80. package/lib/model/strategy/adapter/walletPass/utils.d.ts +6 -6
  81. package/lib/model/strategy/adapter/walletPass/utils.js +115 -48
  82. package/lib/modules/Customer/index.js +1 -1
  83. package/lib/modules/Discount/index.d.ts +6 -2
  84. package/lib/modules/Discount/index.js +3 -1
  85. package/lib/modules/Order/index.d.ts +1 -1
  86. package/lib/modules/Order/index.js +20 -18
  87. package/lib/modules/Payment/index.d.ts +4 -0
  88. package/lib/modules/Payment/index.js +134 -66
  89. package/lib/modules/Payment/walletpass.js +23 -4
  90. package/lib/modules/Product/index.d.ts +1 -1
  91. package/lib/modules/Product/types.d.ts +2 -0
  92. package/lib/modules/ProductList/index.d.ts +3 -0
  93. package/lib/modules/ProductList/index.js +2 -2
  94. package/lib/modules/Rules/index.d.ts +2 -2
  95. package/lib/modules/Rules/index.js +69 -73
  96. package/lib/modules/Rules/types.d.ts +2 -2
  97. package/lib/modules/Schedule/index.d.ts +9 -0
  98. package/lib/modules/Schedule/index.js +11 -0
  99. package/lib/plugins/app-types/app/app.d.ts +1 -0
  100. package/lib/plugins/request.d.ts +2 -0
  101. package/lib/server/index.d.ts +107 -2
  102. package/lib/server/index.js +773 -51
  103. package/lib/server/modules/index.d.ts +6 -0
  104. package/lib/server/modules/index.js +16 -2
  105. package/lib/server/modules/menu/index.d.ts +19 -0
  106. package/lib/server/modules/menu/index.js +121 -2
  107. package/lib/server/modules/order/index.d.ts +87 -0
  108. package/lib/server/modules/order/index.js +543 -0
  109. package/lib/server/modules/order/types.d.ts +530 -0
  110. package/lib/server/modules/order/types.js +34 -0
  111. package/lib/server/modules/order/utils/filterBookings.d.ts +6 -0
  112. package/lib/server/modules/order/utils/filterBookings.js +320 -0
  113. package/lib/server/modules/order/utils/filterOrders.d.ts +15 -0
  114. package/lib/server/modules/order/utils/filterOrders.js +197 -0
  115. package/lib/server/modules/products/index.d.ts +117 -5
  116. package/lib/server/modules/products/index.js +799 -62
  117. package/lib/server/modules/products/types.d.ts +25 -1
  118. package/lib/server/modules/products/types.js +1 -0
  119. package/lib/server/modules/resource/index.d.ts +86 -0
  120. package/lib/server/modules/resource/index.js +557 -0
  121. package/lib/server/modules/resource/types.d.ts +121 -0
  122. package/lib/server/modules/resource/types.js +35 -0
  123. package/lib/server/modules/schedule/index.d.ts +19 -0
  124. package/lib/server/modules/schedule/index.js +141 -12
  125. package/lib/server/utils/product.d.ts +5 -0
  126. package/lib/server/utils/product.js +56 -27
  127. package/lib/solution/BookingTicket/index.d.ts +10 -2
  128. package/lib/solution/BookingTicket/index.js +10 -2
  129. package/lib/solution/BookingTicket/utils/scan/index.js +0 -1
  130. package/lib/solution/Checkout/index.d.ts +1 -0
  131. package/lib/solution/Checkout/index.js +399 -331
  132. package/lib/solution/Checkout/utils/index.d.ts +2 -1
  133. package/lib/solution/Checkout/utils/index.js +6 -4
  134. package/lib/solution/RegisterAndLogin/config.js +266 -1
  135. package/lib/solution/Sales/index.d.ts +96 -0
  136. package/lib/solution/Sales/index.js +416 -0
  137. package/lib/solution/Sales/types.d.ts +67 -0
  138. package/lib/solution/Sales/types.js +35 -0
  139. package/lib/solution/ShopDiscount/index.d.ts +1 -0
  140. package/lib/solution/ShopDiscount/index.js +14 -6
  141. package/lib/solution/ShopDiscount/types.d.ts +6 -0
  142. package/lib/solution/ShopDiscount/utils.d.ts +9 -0
  143. package/lib/solution/ShopDiscount/utils.js +6 -10
  144. package/lib/solution/index.d.ts +2 -1
  145. package/lib/solution/index.js +4 -2
  146. package/lib/types/index.d.ts +5 -0
  147. package/package.json +1 -1
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __export = (target, all) => {
6
8
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  return to;
16
18
  };
17
19
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/server/index.ts
@@ -23,11 +33,19 @@ __export(server_exports, {
23
33
  default: () => server_default
24
34
  });
25
35
  module.exports = __toCommonJS(server_exports);
36
+ var import_dayjs = __toESM(require("dayjs"));
26
37
  var import_products = require("./modules/products");
27
38
  var import_menu = require("./modules/menu");
28
39
  var import_quotation = require("./modules/quotation");
29
40
  var import_schedule = require("./modules/schedule");
41
+ var import_resource = require("./modules/resource");
30
42
  var import_schedule2 = require("./utils/schedule");
43
+ var import_types = require("./modules/products/types");
44
+ var import_product = require("./utils/product");
45
+ var import_order = require("./modules/order");
46
+ var import_types2 = require("./modules/order/types");
47
+ var import_filterOrders = require("./modules/order/utils/filterOrders");
48
+ var import_filterBookings = require("./modules/order/utils/filterBookings");
31
49
  __reExport(server_exports, require("./modules"), module.exports);
32
50
  var Server = class {
33
51
  constructor(core) {
@@ -38,6 +56,11 @@ var Server = class {
38
56
  put: {},
39
57
  remove: {}
40
58
  };
59
+ // ---- 商品查询订阅者 ----
60
+ this.productQuerySubscribers = /* @__PURE__ */ new Map();
61
+ // ---- 订单 / 预约列表查询订阅者 ----
62
+ this.orderQuerySubscribers = /* @__PURE__ */ new Map();
63
+ this.bookingQuerySubscribers = /* @__PURE__ */ new Map();
41
64
  // 模块注册表 - 定义所有可用的模块配置
42
65
  this.moduleRegistry = {
43
66
  products: {
@@ -78,71 +101,164 @@ var Server = class {
78
101
  availabilityDateList: [],
79
102
  otherProductsIds: []
80
103
  }
104
+ },
105
+ order: {
106
+ name: "order",
107
+ moduleClass: import_order.OrderModule,
108
+ moduleName: "server_order",
109
+ version: "1.0.0",
110
+ defaultStore: {
111
+ list: []
112
+ }
113
+ },
114
+ resource: {
115
+ name: "resource",
116
+ moduleClass: import_resource.ResourceModule,
117
+ moduleName: "server_resource",
118
+ version: "1.0.0",
119
+ defaultStore: {
120
+ list: [],
121
+ map: /* @__PURE__ */ new Map(),
122
+ bookings: []
123
+ }
81
124
  }
82
125
  };
83
126
  /**
84
- * 处理商品查询请求(编排 Products、Menu、Schedule 模块)
85
- * 这是一个业务编排方法,协调多个模块完成复杂的业务需求
127
+ * 处理商品查询请求
128
+ * 存储订阅者信息,便于数据变更时推送最新结果
86
129
  */
87
130
  this.handleProductQuery = async ({ url, method, data, config }) => {
88
131
  console.log("[Server] handleProductQuery:", url, method, data, config);
89
132
  const { menu_list_ids, schedule_datetime, schedule_date } = data;
90
- if (!this.products) {
91
- console.error("[Server] Products 模块未注册");
92
- return {
93
- message: "Products 模块未注册",
94
- data: { list: [], count: 0 }
95
- };
96
- }
97
- if (!this.menu) {
98
- console.error("[Server] Menu 模块未注册");
99
- return {
100
- message: "Menu 模块未注册",
101
- data: { list: [], count: 0 }
102
- };
133
+ const { callback, subscriberId } = config || {};
134
+ this.logInfo("handleProductQuery: 开始处理商品查询请求", {
135
+ menu_list_ids,
136
+ schedule_datetime,
137
+ schedule_date
138
+ });
139
+ if (subscriberId && typeof callback === "function") {
140
+ this.productQuerySubscribers.set(subscriberId, {
141
+ callback,
142
+ context: { menu_list_ids, schedule_date, schedule_datetime }
143
+ });
144
+ this.logInfo("handleProductQuery: 已注册订阅者", {
145
+ subscriberId,
146
+ totalSubscribers: this.productQuerySubscribers.size
147
+ });
103
148
  }
104
- if (!this.schedule) {
105
- console.error("[Server] Schedule 模块未注册");
106
- return {
107
- message: "Schedule 模块未注册",
108
- data: { list: [], count: 0 }
109
- };
149
+ return this.computeProductQueryResult({ menu_list_ids, schedule_date, schedule_datetime });
150
+ };
151
+ /**
152
+ * 取消商品查询订阅(HTTP 路由入口)
153
+ */
154
+ this.handleUnsubscribeProductQuery = async ({ data }) => {
155
+ const { subscriberId } = data || {};
156
+ this.removeProductQuerySubscriber(subscriberId);
157
+ return { code: 200, message: "ok", status: true };
158
+ };
159
+ /**
160
+ * 处理订单列表查询
161
+ * 存储订阅者信息,本地计算结果;数据变更时通过 callback 推送
162
+ */
163
+ this.handleOrderList = async ({ url, method, data, config }) => {
164
+ console.log("[Server] handleOrderList:", url, method, data, config);
165
+ const queryPayload = data && typeof data === "object" ? { ...data } : {};
166
+ const { callback, subscriberId } = config || {};
167
+ this.logInfo("handleOrderList: 开始处理订单列表请求", { data: queryPayload });
168
+ if (subscriberId && typeof callback === "function") {
169
+ this.orderQuerySubscribers.set(subscriberId, {
170
+ callback,
171
+ context: queryPayload
172
+ });
173
+ this.logInfo("handleOrderList: 已注册订阅者", {
174
+ subscriberId,
175
+ totalSubscribers: this.orderQuerySubscribers.size
176
+ });
110
177
  }
111
- let activeMenuList = [];
112
- if (menu_list_ids && Array.isArray(menu_list_ids) && menu_list_ids.length > 0) {
113
- console.log("[Server] 获取餐牌详情,IDs:", menu_list_ids);
114
- const menuList = this.menu.getMenuByIds(menu_list_ids);
115
- activeMenuList = menuList.filter((menu) => {
116
- var _a;
117
- return ((_a = this.schedule) == null ? void 0 : _a.getDateIsInSchedule(schedule_datetime, menu.schedule)) || false;
178
+ return this.computeOrderQueryResult(queryPayload);
179
+ };
180
+ /**
181
+ * 取消订单列表查询订阅(HTTP 路由入口)
182
+ */
183
+ this.handleUnsubscribeOrderQuery = async ({ data }) => {
184
+ const { subscriberId } = data || {};
185
+ if (subscriberId) {
186
+ this.orderQuerySubscribers.delete(subscriberId);
187
+ this.logInfo("handleUnsubscribeOrderQuery: 已移除订阅者", {
188
+ subscriberId,
189
+ remaining: this.orderQuerySubscribers.size
118
190
  });
119
191
  }
120
- console.log(activeMenuList, "activeMenuList");
121
- const allProductsWithPrice = await this.products.getProductsWithPrice(data.schedule_date, {
122
- scheduleModule: this.getSchedule()
192
+ return { code: 200, message: "ok", status: true };
193
+ };
194
+ /**
195
+ * 处理预约列表查询
196
+ * 今天:注册订阅者 + 本地数据筛选;非今天:清理订阅者 + 走真实 API
197
+ */
198
+ this.handleBookingList = async ({ url, method, data, config }) => {
199
+ console.log("[Server] handleBookingList:", url, method, data, config);
200
+ const queryPayload = data && typeof data === "object" ? { ...data } : {};
201
+ const { callback, subscriberId } = config || {};
202
+ const isToday = this.isBookingQueryForToday(queryPayload);
203
+ this.logInfo("handleBookingList: 开始处理预约列表请求", {
204
+ data: queryPayload,
205
+ isToday
123
206
  });
124
- console.log(allProductsWithPrice, "allProductsWithPrice");
125
- let filteredProducts = this.filterProductsByMenuConfig(allProductsWithPrice, activeMenuList);
126
- filteredProducts = filteredProducts.sort((a, b) => {
127
- const sortDiff = Number(b.sort) - Number(a.sort);
128
- if (sortDiff !== 0) {
129
- return sortDiff;
207
+ if (isToday) {
208
+ if (subscriberId && typeof callback === "function") {
209
+ this.bookingQuerySubscribers.set(subscriberId, {
210
+ callback,
211
+ context: queryPayload
212
+ });
213
+ this.logInfo("handleBookingList: 已注册订阅者(今天)", {
214
+ subscriberId,
215
+ totalSubscribers: this.bookingQuerySubscribers.size
216
+ });
217
+ }
218
+ return this.computeBookingQueryResult(queryPayload);
219
+ } else {
220
+ if (subscriberId) {
221
+ this.bookingQuerySubscribers.delete(subscriberId);
222
+ this.logInfo("handleBookingList: 已清理订阅者(非今天)", {
223
+ subscriberId,
224
+ remaining: this.bookingQuerySubscribers.size
225
+ });
130
226
  }
131
- return (a.title || "").localeCompare(b.title || "");
227
+ return this.fetchBookingListFromAPI(queryPayload);
228
+ }
229
+ };
230
+ /**
231
+ * 处理资源列表查询
232
+ * 转发到资源模块去
233
+ */
234
+ this.handleResourceList = async ({ url, method, data, config }) => {
235
+ var _a;
236
+ console.log("[Server] handleResourceList:", url, method, data, config);
237
+ const list = (_a = this.resource) == null ? void 0 : _a.getResources({
238
+ skip: (data == null ? void 0 : data.skip) || 1,
239
+ num: (data == null ? void 0 : data.num) || 10
132
240
  });
133
- console.log("[Server] 原始商品数量:", allProductsWithPrice.length);
134
- console.log("[Server] 过滤后商品数量:", filteredProducts.length);
135
- console.log(filteredProducts, "filteredProducts");
136
241
  return {
137
242
  code: 200,
138
- data: {
139
- list: filteredProducts,
140
- count: filteredProducts.length
141
- },
243
+ data: { list, count: (list == null ? void 0 : list.length) || 0 },
142
244
  message: "",
143
245
  status: true
144
246
  };
145
247
  };
248
+ /**
249
+ * 取消预约列表查询订阅(HTTP 路由入口)
250
+ */
251
+ this.handleUnsubscribeBookingQuery = async ({ data }) => {
252
+ const { subscriberId } = data || {};
253
+ if (subscriberId) {
254
+ this.bookingQuerySubscribers.delete(subscriberId);
255
+ this.logInfo("handleUnsubscribeBookingQuery: 已移除订阅者", {
256
+ subscriberId,
257
+ remaining: this.bookingQuerySubscribers.size
258
+ });
259
+ }
260
+ return { code: 200, message: "ok", status: true };
261
+ };
146
262
  /**
147
263
  * 处理获取日程时间段点的请求
148
264
  * 通过餐牌ID列表获取所有相关日程的时间段点
@@ -150,8 +266,10 @@ var Server = class {
150
266
  this.handleGetScheduleTimePoints = async ({ url, method, data, config }) => {
151
267
  console.log("[Server] handleGetScheduleTimePoints:", url, method, data, config);
152
268
  const { menu_list_ids } = data;
269
+ this.logInfo("handleGetScheduleTimePoints 开始处理", { menuListIdsCount: (menu_list_ids == null ? void 0 : menu_list_ids.length) ?? 0, menu_list_ids });
153
270
  if (!this.menu) {
154
271
  console.error("[Server] Menu 模块未注册");
272
+ this.logError("handleGetScheduleTimePoints: Menu 模块未注册");
155
273
  return {
156
274
  code: 500,
157
275
  message: "Menu 模块未注册",
@@ -161,6 +279,7 @@ var Server = class {
161
279
  }
162
280
  if (!this.schedule) {
163
281
  console.error("[Server] Schedule 模块未注册");
282
+ this.logError("handleGetScheduleTimePoints: Schedule 模块未注册");
164
283
  return {
165
284
  code: 500,
166
285
  message: "Schedule 模块未注册",
@@ -170,6 +289,7 @@ var Server = class {
170
289
  }
171
290
  if (!menu_list_ids || !Array.isArray(menu_list_ids) || menu_list_ids.length === 0) {
172
291
  console.error("[Server] menu_list_ids 参数无效");
292
+ this.logWarning("handleGetScheduleTimePoints: menu_list_ids 参数无效", { menuListIdsCount: (menu_list_ids == null ? void 0 : menu_list_ids.length) ?? 0, menu_list_ids });
173
293
  return {
174
294
  code: 400,
175
295
  message: "menu_list_ids 参数无效",
@@ -180,9 +300,19 @@ var Server = class {
180
300
  try {
181
301
  const menuList = this.menu.getMenuByIds(menu_list_ids);
182
302
  console.log(`[Server] 找到 ${menuList.length} 个餐牌`);
303
+ this.logInfo("handleGetScheduleTimePoints: 获取到餐牌列表", {
304
+ requestedCount: menu_list_ids.length,
305
+ foundCount: menuList.length,
306
+ menu_list_ids,
307
+ menuList
308
+ });
183
309
  const scheduleIds = (0, import_schedule2.extractScheduleIdsFromMenus)(menuList);
184
310
  console.log(`[Server] 提取到 ${scheduleIds.length} 个日程ID:`, scheduleIds);
311
+ this.logInfo("handleGetScheduleTimePoints: 提取到日程 IDs", {
312
+ scheduleCount: scheduleIds.length
313
+ });
185
314
  if (scheduleIds.length === 0) {
315
+ this.logInfo("handleGetScheduleTimePoints: 没有找到相关日程", { menuListIdsCount: menu_list_ids.length });
186
316
  return {
187
317
  code: 200,
188
318
  message: "没有找到相关日程",
@@ -192,8 +322,18 @@ var Server = class {
192
322
  }
193
323
  const scheduleList = this.schedule.getScheduleByIds(scheduleIds);
194
324
  console.log(`[Server] 找到 ${scheduleList.length} 个日程`);
325
+ this.logInfo("handleGetScheduleTimePoints: 获取到日程详情", {
326
+ requestedCount: scheduleIds.length,
327
+ foundCount: scheduleList.length
328
+ });
195
329
  const timePoints = (0, import_schedule2.extractTimePointsFromSchedules)(scheduleList);
196
330
  console.log(`[Server] 提取到 ${timePoints.length} 个时间点:`, timePoints);
331
+ this.logInfo("handleGetScheduleTimePoints 处理完成", {
332
+ menuListIdsCount: menu_list_ids.length,
333
+ menuCount: menuList.length,
334
+ scheduleCount: scheduleList.length,
335
+ timePointCount: timePoints.length
336
+ });
197
337
  return {
198
338
  code: 200,
199
339
  message: "获取成功",
@@ -201,17 +341,30 @@ var Server = class {
201
341
  status: true
202
342
  };
203
343
  } catch (error) {
344
+ const errorMessage = error instanceof Error ? error.message : "未知错误";
204
345
  console.error("[Server] 获取日程时间点失败:", error);
346
+ this.logError("handleGetScheduleTimePoints: 获取日程时间点失败", {
347
+ menuListIdsCount: menu_list_ids.length,
348
+ error: errorMessage
349
+ });
205
350
  return {
206
351
  code: 500,
207
- message: `获取失败: ${error instanceof Error ? error.message : "未知错误"}`,
352
+ message: `获取失败: ${errorMessage}`,
208
353
  data: [],
209
354
  status: false
210
355
  };
211
356
  }
212
357
  };
358
+ var _a;
213
359
  this.core = core;
214
- console.log("[Server] Server 初始化");
360
+ const appPlugin = core.getPlugin("app");
361
+ this.app = (appPlugin == null ? void 0 : appPlugin.getApp()) || null;
362
+ this.logger = ((_a = this.app) == null ? void 0 : _a.logger) || null;
363
+ console.log("[Server] Server 初始化", this.core);
364
+ this.logInfo("Server 初始化", {
365
+ hasApp: !!this.app,
366
+ hasLogger: !!this.logger
367
+ });
215
368
  }
216
369
  /**
217
370
  * 注册路由
@@ -222,13 +375,16 @@ var Server = class {
222
375
  const { method, path, handler } = route;
223
376
  if (!this.router[method]) {
224
377
  console.warn(`[Server] 不支持的 HTTP 方法: ${method}`);
378
+ this.logWarning(`不支持的 HTTP 方法`, { method, path });
225
379
  return;
226
380
  }
227
381
  if (this.router[method][path]) {
228
382
  console.warn(`[Server] 路由已存在,将被覆盖: ${method.toUpperCase()} ${path}`);
383
+ this.logWarning(`路由已存在,将被覆盖`, { method, path });
229
384
  }
230
385
  this.router[method][path] = handler;
231
386
  console.log(`[Server] 📝 注册路由: ${method.toUpperCase()} ${path}`);
387
+ this.logInfo(`注册路由`, { method: method.toUpperCase(), path });
232
388
  });
233
389
  }
234
390
  /**
@@ -238,12 +394,15 @@ var Server = class {
238
394
  * @param moduleName 模块名称(用于日志)
239
395
  */
240
396
  async registerModuleWithRoutes(module2, options, moduleName) {
397
+ this.logInfo(`开始注册模块: ${moduleName}`, { moduleName, options });
241
398
  await this.core.registerModule(module2, options);
242
399
  console.log(`[Server] ✅ ${moduleName} 模块已注册`);
400
+ this.logInfo(`模块注册成功: ${moduleName}`, { moduleName });
243
401
  if (typeof module2.getRoutes === "function") {
244
402
  const routes = module2.getRoutes();
245
403
  if (routes && routes.length > 0) {
246
404
  this.registerRoutes(routes);
405
+ this.logInfo(`模块路由已注册: ${moduleName}`, { moduleName, routesCount: routes.length });
247
406
  }
248
407
  }
249
408
  }
@@ -255,8 +414,14 @@ var Server = class {
255
414
  const moduleName = typeof moduleConfig === "string" ? moduleConfig : moduleConfig.name;
256
415
  const shouldPreload = typeof moduleConfig === "object" ? moduleConfig.preload !== false : true;
257
416
  const customConfig = typeof moduleConfig === "object" ? moduleConfig.config : {};
417
+ this.logInfo(`解析模块配置: ${moduleName}`, {
418
+ moduleName,
419
+ shouldPreload,
420
+ customConfig
421
+ });
258
422
  const registryConfig = this.moduleRegistry[moduleName];
259
423
  if (!registryConfig) {
424
+ this.logError(`未找到模块配置: ${moduleName}`, { moduleName });
260
425
  throw new Error(`[Server] 未找到模块配置: ${moduleName}`);
261
426
  }
262
427
  const ModuleClass = registryConfig.moduleClass;
@@ -271,6 +436,11 @@ var Server = class {
271
436
  moduleName.charAt(0).toUpperCase() + moduleName.slice(1)
272
437
  );
273
438
  this[moduleName] = moduleInstance;
439
+ this.logInfo(`模块注册完成: ${moduleName}`, {
440
+ moduleName,
441
+ shouldPreload,
442
+ version: registryConfig.version
443
+ });
274
444
  return { module: moduleInstance, config: registryConfig, shouldPreload };
275
445
  }
276
446
  /**
@@ -280,17 +450,34 @@ var Server = class {
280
450
  async registerModules(moduleConfigs) {
281
451
  console.log("[Server] 开始注册模块...");
282
452
  const configs = moduleConfigs || Object.keys(this.moduleRegistry);
453
+ this.logInfo("开始批量注册模块", {
454
+ moduleConfigs: configs,
455
+ totalCount: configs.length
456
+ });
283
457
  const registeredModules = [];
284
458
  for (const config of configs) {
459
+ const configName = typeof config === "string" ? config : config.name;
285
460
  try {
286
461
  const result = await this.registerModuleByName(config);
287
462
  registeredModules.push(result);
288
463
  } catch (error) {
464
+ const errorMessage = error instanceof Error ? error.message : String(error);
465
+ this.logError(`模块注册失败: ${configName}`, {
466
+ moduleName: configName,
467
+ error: errorMessage
468
+ });
289
469
  console.error(`[Server] 模块注册失败:`, error);
290
470
  throw error;
291
471
  }
292
472
  }
293
473
  console.log("[Server] ✅ 所有模块注册完成");
474
+ this.logInfo("所有模块注册完成", {
475
+ registeredCount: registeredModules.length,
476
+ moduleNames: registeredModules.map((m) => {
477
+ var _a;
478
+ return (_a = m == null ? void 0 : m.config) == null ? void 0 : _a.name;
479
+ })
480
+ });
294
481
  return registeredModules;
295
482
  }
296
483
  /**
@@ -300,25 +487,56 @@ var Server = class {
300
487
  async preloadModulesData(registeredModules, options) {
301
488
  var _a, _b;
302
489
  console.log("[Server] 开始预加载模块数据...");
490
+ const modulesToPreload = registeredModules.filter((m) => m.shouldPreload);
491
+ this.logInfo("开始预加载模块数据", {
492
+ totalModules: registeredModules.length,
493
+ preloadCount: modulesToPreload.length,
494
+ modulesToPreload
495
+ });
496
+ const preloadResults = [];
303
497
  for (const { module: module2, config, shouldPreload } of registeredModules) {
304
498
  if (!shouldPreload) {
305
499
  console.log(`[Server] ⏭️ 跳过 ${config.name} 模块预加载`);
500
+ this.logInfo(`跳过模块预加载: ${config.name}`, { moduleName: config.name, reason: "shouldPreload=false" });
306
501
  continue;
307
502
  }
308
503
  if (typeof module2.preload === "function") {
504
+ const startTime = Date.now();
309
505
  try {
506
+ this.logInfo(`开始预加载模块: ${config.name}`, { moduleName: config.name });
310
507
  (_a = options == null ? void 0 : options.onModuleLoad) == null ? void 0 : _a.call(options, config.name);
311
508
  await module2.preload();
312
509
  (_b = options == null ? void 0 : options.onModuleLoadComplete) == null ? void 0 : _b.call(options, config.name);
510
+ const duration = Date.now() - startTime;
313
511
  console.log(`[Server] ✅ ${config.name} 模块数据已预加载`);
512
+ this.logInfo(`模块预加载成功: ${config.name}`, {
513
+ moduleName: config.name,
514
+ duration: `${duration}ms`
515
+ });
516
+ preloadResults.push({ name: config.name, success: true });
314
517
  } catch (error) {
518
+ const duration = Date.now() - startTime;
519
+ const errorMessage = error instanceof Error ? error.message : String(error);
315
520
  console.error(`[Server] ❌ ${config.name} 模块预加载失败:`, error);
521
+ this.logError(`模块预加载失败: ${config.name}`, {
522
+ moduleName: config.name,
523
+ duration: `${duration}ms`,
524
+ error: errorMessage
525
+ });
526
+ preloadResults.push({ name: config.name, success: false, error: errorMessage });
316
527
  }
317
528
  } else {
318
529
  console.log(`[Server] ⚠️ ${config.name} 模块未实现 preload() 方法`);
530
+ this.logWarning(`模块未实现 preload 方法: ${config.name}`, { moduleName: config.name });
319
531
  }
320
532
  }
533
+ const successCount = preloadResults.filter((r) => r.success).length;
534
+ const failCount = preloadResults.filter((r) => !r.success).length;
321
535
  console.log("[Server] ✅ 所有模块数据预加载完成");
536
+ this.logInfo("所有模块预加载完成", {
537
+ successCount,
538
+ failCount
539
+ });
322
540
  }
323
541
  /**
324
542
  * 初始化 Server(注册模块并预加载数据)
@@ -326,11 +544,33 @@ var Server = class {
326
544
  * @param autoPreload 是否自动预加载数据
327
545
  */
328
546
  async initialize(moduleConfigs, autoPreload = true, options) {
547
+ const startTime = Date.now();
548
+ this.logInfo("Server 初始化开始", {
549
+ moduleConfigCount: (moduleConfigs == null ? void 0 : moduleConfigs.length) ?? "all",
550
+ autoPreload,
551
+ moduleConfigs
552
+ });
329
553
  this.registerServerRoutes();
330
554
  const registeredModules = await this.registerModules(moduleConfigs);
331
555
  if (autoPreload) {
332
556
  await this.preloadModulesData(registeredModules, options);
557
+ } else {
558
+ this.logInfo("跳过自动预加载", { autoPreload });
333
559
  }
560
+ this.core.effects.on(import_types.ProductsHooks.onProductsSyncCompleted, (payload) => {
561
+ this.recomputeAndNotifyProductQuery({
562
+ changedIds: payload == null ? void 0 : payload.changedIds
563
+ });
564
+ });
565
+ this.core.effects.on(import_types2.OrderHooks.onOrdersChanged, () => {
566
+ this.recomputeAndNotifyOrderQuery();
567
+ this.recomputeAndNotifyBookingQuery();
568
+ });
569
+ const duration = Date.now() - startTime;
570
+ this.logInfo("Server 初始化完成", {
571
+ duration: `${duration}ms`,
572
+ registeredModuleCount: registeredModules.length
573
+ });
334
574
  return registeredModules;
335
575
  }
336
576
  /**
@@ -370,14 +610,45 @@ var Server = class {
370
610
  modules.push("quotation");
371
611
  if (this.schedule)
372
612
  modules.push("schedule");
613
+ if (this.resource)
614
+ modules.push("resource");
615
+ if (this.order)
616
+ modules.push("order");
373
617
  return modules;
374
618
  }
619
+ /**
620
+ * 后台静默刷新商品数据
621
+ * 重新拉取全量 SSE 接口,更新本地数据后触发 onProductsSyncCompleted
622
+ * 不影响当前界面展示,适用于切回前台、定时刷新等场景
623
+ */
624
+ async refreshProductsInBackground() {
625
+ if (!this.products) {
626
+ this.logWarning("refreshProductsInBackground: Products 模块未注册");
627
+ return;
628
+ }
629
+ this.logInfo("refreshProductsInBackground 开始");
630
+ const startTime = Date.now();
631
+ try {
632
+ await this.products.silentRefresh();
633
+ const duration = Date.now() - startTime;
634
+ this.logInfo("refreshProductsInBackground 完成", { duration: `${duration}ms` });
635
+ } catch (error) {
636
+ const duration = Date.now() - startTime;
637
+ const errorMessage = error instanceof Error ? error.message : String(error);
638
+ console.error("[Server] refreshProductsInBackground 失败:", error);
639
+ this.logError("refreshProductsInBackground 失败", {
640
+ duration: `${duration}ms`,
641
+ error: errorMessage
642
+ });
643
+ }
644
+ }
375
645
  /**
376
646
  * 清空所有server模块的IndexedDB缓存
377
647
  * @returns Promise<void>
378
648
  */
379
649
  async clearAllIndexDB() {
380
650
  console.log("[Server] 开始清空所有模块的IndexedDB缓存...");
651
+ this.logInfo("开始清空所有模块的 IndexedDB 缓存");
381
652
  const clearTasks = [];
382
653
  const moduleNames = [];
383
654
  if (this.products) {
@@ -396,15 +667,28 @@ var Server = class {
396
667
  clearTasks.push(this.schedule.clear());
397
668
  moduleNames.push("Schedule");
398
669
  }
670
+ if (this.resource) {
671
+ clearTasks.push(this.resource.clear());
672
+ moduleNames.push("Resource");
673
+ }
674
+ if (this.order) {
675
+ clearTasks.push(this.order.clear());
676
+ moduleNames.push("Order");
677
+ }
399
678
  if (clearTasks.length === 0) {
400
679
  console.warn("[Server] 没有找到已注册的模块,无需清空");
680
+ this.logWarning("没有找到已注册的模块,无需清空 IndexedDB");
401
681
  return;
402
682
  }
683
+ this.logInfo("准备清空模块缓存", { moduleNames });
403
684
  try {
404
685
  await Promise.all(clearTasks);
405
686
  console.log(`[Server] ✅ 已成功清空所有模块的IndexedDB缓存: ${moduleNames.join(", ")}`);
687
+ this.logInfo("成功清空所有模块的 IndexedDB 缓存", { moduleNames });
406
688
  } catch (error) {
689
+ const errorMessage = error instanceof Error ? error.message : String(error);
407
690
  console.error("[Server] ❌ 清空IndexedDB缓存时发生错误:", error);
691
+ this.logError("清空 IndexedDB 缓存时发生错误", { moduleNames, error: errorMessage });
408
692
  throw error;
409
693
  }
410
694
  }
@@ -440,14 +724,39 @@ var Server = class {
440
724
  * @param params 请求参数
441
725
  */
442
726
  async handleRoute(method, path, params) {
443
- console.log(method, path, params, "method, path, params");
727
+ const startTime = Date.now();
728
+ this.logInfo(`路由请求开始: ${method.toUpperCase()} ${path}`, {
729
+ method: method.toUpperCase(),
730
+ path,
731
+ url: params.url,
732
+ data: params.data
733
+ });
444
734
  const handler = this.getRouteHandler(method, path);
445
735
  if (!handler) {
736
+ this.logError(`路由未找到: ${method.toUpperCase()} ${path}`, { method, path });
446
737
  throw new Error(`Route not found: ${method.toUpperCase()} ${path}`);
447
738
  }
448
739
  try {
449
- return await handler(params);
740
+ const result = await handler(params);
741
+ const duration = Date.now() - startTime;
742
+ this.logInfo(`路由请求完成: ${method.toUpperCase()} ${path}`, {
743
+ method: method.toUpperCase(),
744
+ path,
745
+ duration: `${duration}ms`,
746
+ resultCode: result == null ? void 0 : result.code,
747
+ resultStatus: result == null ? void 0 : result.status
748
+ });
749
+ return result;
450
750
  } catch (error) {
751
+ const duration = Date.now() - startTime;
752
+ const errorMessage = error instanceof Error ? error.message : String(error);
753
+ this.logError(`路由处理错误: ${method.toUpperCase()} ${path}`, {
754
+ method: method.toUpperCase(),
755
+ path,
756
+ duration: `${duration}ms`,
757
+ error: errorMessage,
758
+ data: params.data
759
+ });
451
760
  console.error(`[Server] 路由处理错误: ${method.toUpperCase()} ${path}`, error);
452
761
  throw error;
453
762
  }
@@ -477,13 +786,332 @@ var Server = class {
477
786
  path: "/shop/product/query",
478
787
  handler: this.handleProductQuery.bind(this)
479
788
  },
789
+ {
790
+ method: "post",
791
+ path: "/shop/product/query/unsubscribe",
792
+ handler: this.handleUnsubscribeProductQuery.bind(this)
793
+ },
480
794
  {
481
795
  method: "post",
482
796
  path: "/shop/menu/schedule-time-points",
483
797
  handler: this.handleGetScheduleTimePoints.bind(this)
798
+ },
799
+ {
800
+ method: "post",
801
+ path: "/shop/order/v2/list",
802
+ handler: this.handleOrderList.bind(this)
803
+ },
804
+ {
805
+ method: "post",
806
+ path: "/shop/order/v2/list/unsubscribe",
807
+ handler: this.handleUnsubscribeOrderQuery.bind(this)
808
+ },
809
+ {
810
+ method: "get",
811
+ path: "/shop/schedule/booking",
812
+ handler: this.handleBookingList.bind(this)
813
+ },
814
+ {
815
+ method: "get",
816
+ path: "/shop/schedule/booking/unsubscribe",
817
+ handler: this.handleUnsubscribeBookingQuery.bind(this)
818
+ },
819
+ {
820
+ method: "get",
821
+ path: "/shop/form/resource/page",
822
+ handler: this.handleResourceList.bind(this)
484
823
  }
485
824
  ]);
486
825
  }
826
+ /**
827
+ * 根据 subscriberId 移除商品查询订阅者
828
+ */
829
+ removeProductQuerySubscriber(subscriberId) {
830
+ if (subscriberId) {
831
+ this.productQuerySubscribers.delete(subscriberId);
832
+ this.logInfo("removeProductQuerySubscriber: 已移除订阅者", {
833
+ subscriberId,
834
+ remaining: this.productQuerySubscribers.size
835
+ });
836
+ }
837
+ }
838
+ /**
839
+ * 判断预约查询的 sales_time_between 起始日期是否为今天
840
+ */
841
+ isBookingQueryForToday(data) {
842
+ const range = data == null ? void 0 : data.sales_time_between;
843
+ if (!Array.isArray(range) || range.length < 1)
844
+ return true;
845
+ const startDateStr = String(range[0]).split("T")[0].split(" ")[0];
846
+ const todayStr = (0, import_dayjs.default)().format("YYYY-MM-DD");
847
+ return startDateStr === todayStr;
848
+ }
849
+ /**
850
+ * 非今天的预约查询:通过真实 API 获取数据,再做 flattenOrdersToBookings 拆分
851
+ */
852
+ async fetchBookingListFromAPI(data) {
853
+ var _a, _b;
854
+ if (!((_a = this.app) == null ? void 0 : _a.request)) {
855
+ this.logError("fetchBookingListFromAPI: app.request 不可用");
856
+ return {
857
+ code: 500,
858
+ message: "app.request 不可用",
859
+ data: { list: [], count: 0 },
860
+ status: false
861
+ };
862
+ }
863
+ try {
864
+ const response = await this.app.request.get("/shop/order/sales", { ...data, form_record_ids: void 0, with: ["all"] }, {
865
+ isShopApi: true
866
+ });
867
+ const rawList = ((_b = response == null ? void 0 : response.data) == null ? void 0 : _b.list) ?? (response == null ? void 0 : response.list) ?? [];
868
+ const list = (0, import_filterBookings.filterBookingsFromOrders)(rawList, data);
869
+ this.logInfo("fetchBookingListFromAPI: API 返回并拆分完成", {
870
+ rawCount: rawList.length,
871
+ flattenedCount: list.count
872
+ });
873
+ return {
874
+ code: 200,
875
+ data: { ...response.data, list: (list == null ? void 0 : list.list) || [] },
876
+ message: "",
877
+ status: true
878
+ };
879
+ } catch (error) {
880
+ const errorMessage = error instanceof Error ? error.message : String(error);
881
+ this.logError("fetchBookingListFromAPI: 请求失败", { error: errorMessage });
882
+ return {
883
+ code: 500,
884
+ message: errorMessage,
885
+ data: { list: [], count: 0 },
886
+ status: false
887
+ };
888
+ }
889
+ }
890
+ /**
891
+ * 订单列表本地计算(编排 Order 模块)
892
+ * filter 逻辑暂为 mock,仅记录参数
893
+ */
894
+ async computeOrderQueryResult(data) {
895
+ this.logInfo("computeOrderQueryResult: 开始过滤", { data });
896
+ console.log("[Server] computeOrderQueryResult", data);
897
+ if (!this.order) {
898
+ this.logError("computeOrderQueryResult: Order 模块未注册");
899
+ return {
900
+ code: 500,
901
+ message: "Order 模块未注册",
902
+ data: { list: [], count: 0 },
903
+ status: false
904
+ };
905
+ }
906
+ const rawList = this.order.getOrders();
907
+ this.logInfo("computeOrderQueryResult: 本地订单数量", { rawCount: rawList.length });
908
+ const result = (0, import_filterOrders.filterOrders)(rawList, data);
909
+ this.logInfo("computeOrderQueryResult: 过滤结果", {
910
+ rawCount: rawList.length,
911
+ filteredCount: result.count,
912
+ size: result.size,
913
+ skip: result.skip
914
+ });
915
+ return {
916
+ code: 200,
917
+ data: result,
918
+ message: "",
919
+ status: true
920
+ };
921
+ }
922
+ /**
923
+ * 预约列表本地计算(编排 Order 模块)
924
+ * 从订单中展开 bookings,再按条件筛选 + 分页
925
+ */
926
+ async computeBookingQueryResult(data) {
927
+ if (!this.order) {
928
+ this.logError("computeBookingQueryResult: Order 模块未注册");
929
+ return {
930
+ code: 500,
931
+ message: "Order 模块未注册",
932
+ data: { list: [], count: 0 },
933
+ status: false
934
+ };
935
+ }
936
+ const rawOrders = this.order.getOrders();
937
+ let result = (0, import_filterBookings.filterBookingsFromOrders)(rawOrders, data);
938
+ result = (0, import_filterBookings.sortBookings)(result, data);
939
+ this.logInfo("computeBookingQueryResult: 过滤结果", {
940
+ orderCount: rawOrders.length,
941
+ filteredCount: result.count,
942
+ size: result.size,
943
+ skip: result.skip
944
+ });
945
+ return {
946
+ code: 200,
947
+ data: result,
948
+ message: "",
949
+ status: true
950
+ };
951
+ }
952
+ /**
953
+ * 商品查询的核心计算逻辑(编排 Products、Menu、Schedule 模块)
954
+ * 供 handleProductQuery 首次返回及 pubsub 变更推送复用
955
+ * @param context 查询上下文
956
+ * @param options 可选参数
957
+ * @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
958
+ */
959
+ async computeProductQueryResult(context, options) {
960
+ const tTotal = performance.now();
961
+ const { menu_list_ids, schedule_date, schedule_datetime } = context;
962
+ this.logInfo("computeProductQueryResult 开始", {
963
+ menuListIdsCount: (menu_list_ids == null ? void 0 : menu_list_ids.length) ?? 0,
964
+ schedule_datetime,
965
+ schedule_date,
966
+ changedIds: options == null ? void 0 : options.changedIds
967
+ });
968
+ if (!this.products) {
969
+ this.logError("computeProductQueryResult: Products 模块未注册");
970
+ return { message: "Products 模块未注册", data: { list: [], count: 0 } };
971
+ }
972
+ if (!this.menu) {
973
+ this.logError("computeProductQueryResult: Menu 模块未注册");
974
+ return { message: "Menu 模块未注册", data: { list: [], count: 0 } };
975
+ }
976
+ if (!this.schedule) {
977
+ this.logError("computeProductQueryResult: Schedule 模块未注册");
978
+ return { message: "Schedule 模块未注册", data: { list: [], count: 0 } };
979
+ }
980
+ let activeMenuList = [];
981
+ if (menu_list_ids && Array.isArray(menu_list_ids) && menu_list_ids.length > 0) {
982
+ const tMenu = performance.now();
983
+ const menuList = this.menu.getMenuByIds(menu_list_ids);
984
+ activeMenuList = menuList.filter((menu) => {
985
+ var _a;
986
+ return ((_a = this.schedule) == null ? void 0 : _a.getDateIsInSchedule(schedule_datetime, menu.schedule)) || false;
987
+ });
988
+ (0, import_product.perfMark)("computeQuery.filterActiveMenu", performance.now() - tMenu, {
989
+ totalMenu: menuList.length,
990
+ activeMenu: activeMenuList.length
991
+ });
992
+ }
993
+ const tPrice = performance.now();
994
+ const allProductsWithPrice = await this.products.getProductsWithPrice(schedule_date, {
995
+ scheduleModule: this.getSchedule()
996
+ }, {
997
+ changedIds: options == null ? void 0 : options.changedIds
998
+ });
999
+ (0, import_product.perfMark)("computeQuery.getProductsWithPrice", performance.now() - tPrice, {
1000
+ count: allProductsWithPrice.length
1001
+ });
1002
+ const tFilter = performance.now();
1003
+ let filteredProducts = this.filterProductsByMenuConfig(allProductsWithPrice, activeMenuList);
1004
+ (0, import_product.perfMark)("computeQuery.filterByMenu", performance.now() - tFilter, {
1005
+ before: allProductsWithPrice.length,
1006
+ after: filteredProducts.length
1007
+ });
1008
+ const tStatus = performance.now();
1009
+ const beforeStatusCount = filteredProducts.length;
1010
+ filteredProducts = filteredProducts.filter((p) => ((p == null ? void 0 : p.status) || "published") === "published");
1011
+ (0, import_product.perfMark)("computeQuery.filterByStatus", performance.now() - tStatus, {
1012
+ before: beforeStatusCount,
1013
+ after: filteredProducts.length
1014
+ });
1015
+ const tSort = performance.now();
1016
+ filteredProducts = filteredProducts.sort((a, b) => {
1017
+ const sortDiff = Number(b.sort) - Number(a.sort);
1018
+ if (sortDiff !== 0)
1019
+ return sortDiff;
1020
+ return (a.title || "").localeCompare(b.title || "");
1021
+ });
1022
+ (0, import_product.perfMark)("computeQuery.sort", performance.now() - tSort, { count: filteredProducts.length });
1023
+ (0, import_product.perfMark)("computeProductQueryResult", performance.now() - tTotal, {
1024
+ originalCount: allProductsWithPrice.length,
1025
+ filteredCount: filteredProducts.length,
1026
+ activeMenuCount: activeMenuList.length
1027
+ });
1028
+ this.logInfo("computeProductQueryResult 完成", {
1029
+ originalCount: allProductsWithPrice.length,
1030
+ filteredCount: filteredProducts.length,
1031
+ activeMenuCount: activeMenuList.length
1032
+ });
1033
+ return {
1034
+ code: 200,
1035
+ data: { list: filteredProducts, count: filteredProducts.length },
1036
+ message: "",
1037
+ status: true
1038
+ };
1039
+ }
1040
+ /**
1041
+ * 数据变更后,遍历所有订阅者重新计算查询结果并通过 callback 推送
1042
+ * 由 ProductsModule 的 onProductsSyncCompleted 事件触发
1043
+ * @param options 可选参数
1044
+ * @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
1045
+ */
1046
+ async recomputeAndNotifyProductQuery(options) {
1047
+ if (this.productQuerySubscribers.size === 0)
1048
+ return;
1049
+ this.logInfo("recomputeAndNotifyProductQuery: 开始推送", {
1050
+ subscriberCount: this.productQuerySubscribers.size,
1051
+ changedIds: options == null ? void 0 : options.changedIds
1052
+ });
1053
+ for (const [subscriberId, subscriber] of this.productQuerySubscribers.entries()) {
1054
+ try {
1055
+ const result = await this.computeProductQueryResult(subscriber.context, {
1056
+ changedIds: options == null ? void 0 : options.changedIds
1057
+ });
1058
+ subscriber.callback(result);
1059
+ this.logInfo("recomputeAndNotifyProductQuery: 已推送", { subscriberId });
1060
+ } catch (error) {
1061
+ const errorMessage = error instanceof Error ? error.message : String(error);
1062
+ this.logError("recomputeAndNotifyProductQuery: 推送失败", {
1063
+ subscriberId,
1064
+ error: errorMessage
1065
+ });
1066
+ }
1067
+ }
1068
+ }
1069
+ /**
1070
+ * 订单数据变更后,遍历订阅者重新计算并通过 callback 推送
1071
+ */
1072
+ async recomputeAndNotifyOrderQuery() {
1073
+ if (this.orderQuerySubscribers.size === 0)
1074
+ return;
1075
+ this.logInfo("recomputeAndNotifyOrderQuery: 开始推送", {
1076
+ subscriberCount: this.orderQuerySubscribers.size
1077
+ });
1078
+ for (const [subscriberId, subscriber] of this.orderQuerySubscribers.entries()) {
1079
+ try {
1080
+ const result = await this.computeOrderQueryResult(subscriber.context);
1081
+ subscriber.callback(result);
1082
+ this.logInfo("recomputeAndNotifyOrderQuery: 已推送", { subscriberId });
1083
+ } catch (error) {
1084
+ const errorMessage = error instanceof Error ? error.message : String(error);
1085
+ this.logError("recomputeAndNotifyOrderQuery: 推送失败", {
1086
+ subscriberId,
1087
+ error: errorMessage
1088
+ });
1089
+ }
1090
+ }
1091
+ }
1092
+ /**
1093
+ * 预约数据变更后,遍历订阅者重新计算并通过 callback 推送
1094
+ */
1095
+ async recomputeAndNotifyBookingQuery() {
1096
+ if (this.bookingQuerySubscribers.size === 0)
1097
+ return;
1098
+ this.logInfo("recomputeAndNotifyBookingQuery: 开始推送", {
1099
+ subscriberCount: this.bookingQuerySubscribers.size
1100
+ });
1101
+ for (const [subscriberId, subscriber] of this.bookingQuerySubscribers.entries()) {
1102
+ try {
1103
+ const result = await this.computeBookingQueryResult(subscriber.context);
1104
+ subscriber.callback(result);
1105
+ this.logInfo("recomputeAndNotifyBookingQuery: 已推送", { subscriberId });
1106
+ } catch (error) {
1107
+ const errorMessage = error instanceof Error ? error.message : String(error);
1108
+ this.logError("recomputeAndNotifyBookingQuery: 推送失败", {
1109
+ subscriberId,
1110
+ error: errorMessage
1111
+ });
1112
+ }
1113
+ }
1114
+ }
487
1115
  /**
488
1116
  * 根据餐牌配置过滤商品
489
1117
  * @param products 所有商品列表
@@ -494,6 +1122,10 @@ var Server = class {
494
1122
  filterProductsByMenuConfig(products, activeMenuList) {
495
1123
  if (!activeMenuList || activeMenuList.length === 0) {
496
1124
  console.log("[Server] 没有生效的餐牌,返回空数组");
1125
+ this.logInfo("filterProductsByMenuConfig: 没有生效的餐牌,返回空数组", {
1126
+ productCount: products.length,
1127
+ activeMenuCount: 0
1128
+ });
497
1129
  return [];
498
1130
  }
499
1131
  let allowedProductIds = /* @__PURE__ */ new Set();
@@ -503,10 +1135,19 @@ var Server = class {
503
1135
  const config = menu.partyroom_package;
504
1136
  if (!config) {
505
1137
  console.warn("[Server] 餐牌缺少 partyroom_package 配置:", menu);
1138
+ this.logWarning("filterProductsByMenuConfig: 餐牌缺少 partyroom_package 配置", {
1139
+ menuId: menu.form_record_id,
1140
+ menuName: menu.name
1141
+ });
506
1142
  continue;
507
1143
  }
508
1144
  if (config.type === "product_all") {
509
1145
  console.log("[Server] 餐牌允许所有商品:", menu.name);
1146
+ this.logInfo("filterProductsByMenuConfig: 餐牌允许所有商品", {
1147
+ menuId: menu.form_record_id,
1148
+ menuName: menu.name,
1149
+ configType: config.type
1150
+ });
510
1151
  hasProductAll = true;
511
1152
  break;
512
1153
  }
@@ -514,22 +1155,47 @@ var Server = class {
514
1155
  const productIds = config.products.map((item) => item.product_id);
515
1156
  productIds.forEach((id) => id && allowedProductIds.add(id));
516
1157
  console.log("[Server] 餐牌允许指定商品 (product_ids):", menu.name, productIds);
1158
+ this.logInfo("filterProductsByMenuConfig: 餐牌允许指定商品", {
1159
+ menuId: menu.form_record_id,
1160
+ menuName: menu.name,
1161
+ configType: config.type,
1162
+ productIdsCount: productIds.length
1163
+ });
517
1164
  }
518
1165
  if (config.type === "product_collection" && Array.isArray(config.products)) {
519
1166
  const collectionIds = config.products.map((item) => item.product_collection_id);
520
1167
  collectionIds.forEach((id) => id && allowedCollectionIds.add(id));
521
1168
  console.log("[Server] 餐牌允许商品集合 (product_collection):", menu.name, collectionIds);
1169
+ this.logInfo("filterProductsByMenuConfig: 餐牌允许商品集合", {
1170
+ menuId: menu.form_record_id,
1171
+ menuName: menu.name,
1172
+ configType: config.type,
1173
+ collectionIdsCount: collectionIds.length
1174
+ });
522
1175
  }
523
1176
  }
524
1177
  if (hasProductAll) {
1178
+ this.logInfo("filterProductsByMenuConfig: 返回所有商品(product_all)", {
1179
+ productCount: products.length
1180
+ });
525
1181
  return products;
526
1182
  }
527
1183
  if (allowedProductIds.size === 0 && allowedCollectionIds.size === 0) {
528
1184
  console.log("[Server] 没有允许的商品和集合");
1185
+ this.logWarning("filterProductsByMenuConfig: 没有允许的商品和集合", {
1186
+ productCount: products.length,
1187
+ activeMenuCount: activeMenuList.length
1188
+ });
529
1189
  return [];
530
1190
  }
531
- console.log("[Server] 允许的商品 IDs:", Array.from(allowedProductIds));
532
- console.log("[Server] 允许的集合 IDs:", Array.from(allowedCollectionIds));
1191
+ const allowedProductIdsArray = Array.from(allowedProductIds);
1192
+ const allowedCollectionIdsArray = Array.from(allowedCollectionIds);
1193
+ console.log("[Server] 允许的商品 IDs:", allowedProductIdsArray);
1194
+ console.log("[Server] 允许的集合 IDs:", allowedCollectionIdsArray);
1195
+ this.logInfo("filterProductsByMenuConfig: 收集到的允许规则", {
1196
+ allowedProductCount: allowedProductIds.size,
1197
+ allowedCollectionCount: allowedCollectionIds.size
1198
+ });
533
1199
  const filteredProducts = products.filter((product) => {
534
1200
  if (allowedProductIds.has(product.id)) {
535
1201
  return true;
@@ -545,8 +1211,64 @@ var Server = class {
545
1211
  return false;
546
1212
  });
547
1213
  console.log("[Server] 过滤结果: 原始 %d 个,过滤后 %d 个", products.length, filteredProducts.length);
1214
+ this.logInfo("filterProductsByMenuConfig: 过滤完成", {
1215
+ originalCount: products.length,
1216
+ filteredCount: filteredProducts.length,
1217
+ removedCount: products.length - filteredProducts.length
1218
+ });
548
1219
  return filteredProducts;
549
1220
  }
1221
+ /**
1222
+ * 记录信息日志
1223
+ * @param title 日志标题
1224
+ * @param metadata 日志元数据
1225
+ */
1226
+ logInfo(title, metadata) {
1227
+ try {
1228
+ if (this.logger) {
1229
+ this.logger.addLog({
1230
+ type: "info",
1231
+ title: `[Server] ${title}`,
1232
+ metadata: metadata || {}
1233
+ });
1234
+ }
1235
+ } catch {
1236
+ }
1237
+ }
1238
+ /**
1239
+ * 记录警告日志
1240
+ * @param title 日志标题
1241
+ * @param metadata 日志元数据
1242
+ */
1243
+ logWarning(title, metadata) {
1244
+ try {
1245
+ if (this.logger) {
1246
+ this.logger.addLog({
1247
+ type: "warning",
1248
+ title: `[Server] ${title}`,
1249
+ metadata: metadata || {}
1250
+ });
1251
+ }
1252
+ } catch {
1253
+ }
1254
+ }
1255
+ /**
1256
+ * 记录错误日志
1257
+ * @param title 日志标题
1258
+ * @param metadata 日志元数据
1259
+ */
1260
+ logError(title, metadata) {
1261
+ try {
1262
+ if (this.logger) {
1263
+ this.logger.addLog({
1264
+ type: "error",
1265
+ title: `[Server] ${title}`,
1266
+ metadata: metadata || {}
1267
+ });
1268
+ }
1269
+ } catch {
1270
+ }
1271
+ }
550
1272
  };
551
1273
  var server_default = Server;
552
1274
  // Annotate the CommonJS export names for ESM import in node: