@pisell/pisellos 2.2.93 → 2.2.95

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 (53) hide show
  1. package/dist/modules/Order/index.d.ts +1 -1
  2. package/dist/plugins/app-types/app/app.d.ts +1 -0
  3. package/dist/server/index.d.ts +55 -0
  4. package/dist/server/index.js +826 -207
  5. package/dist/server/modules/index.d.ts +6 -0
  6. package/dist/server/modules/index.js +7 -0
  7. package/dist/server/modules/order/index.d.ts +87 -0
  8. package/dist/server/modules/order/index.js +916 -0
  9. package/dist/server/modules/order/types.d.ts +530 -0
  10. package/dist/server/modules/order/types.js +141 -0
  11. package/dist/server/modules/order/utils/filterBookings.d.ts +6 -0
  12. package/dist/server/modules/order/utils/filterBookings.js +350 -0
  13. package/dist/server/modules/order/utils/filterOrders.d.ts +15 -0
  14. package/dist/server/modules/order/utils/filterOrders.js +226 -0
  15. package/dist/server/modules/resource/index.d.ts +88 -0
  16. package/dist/server/modules/resource/index.js +1202 -0
  17. package/dist/server/modules/resource/types.d.ts +121 -0
  18. package/dist/server/modules/resource/types.js +47 -0
  19. package/dist/solution/BookingByStep/index.d.ts +1 -1
  20. package/dist/solution/BookingTicket/index.d.ts +1 -1
  21. package/dist/solution/Sales/index.d.ts +96 -0
  22. package/dist/solution/Sales/index.js +562 -0
  23. package/dist/solution/Sales/types.d.ts +66 -0
  24. package/dist/solution/Sales/types.js +26 -0
  25. package/dist/solution/index.d.ts +1 -0
  26. package/dist/solution/index.js +2 -1
  27. package/lib/modules/Order/index.d.ts +1 -1
  28. package/lib/plugins/app-types/app/app.d.ts +1 -0
  29. package/lib/server/index.d.ts +55 -0
  30. package/lib/server/index.js +343 -1
  31. package/lib/server/modules/index.d.ts +6 -0
  32. package/lib/server/modules/index.js +16 -2
  33. package/lib/server/modules/order/index.d.ts +87 -0
  34. package/lib/server/modules/order/index.js +543 -0
  35. package/lib/server/modules/order/types.d.ts +530 -0
  36. package/lib/server/modules/order/types.js +34 -0
  37. package/lib/server/modules/order/utils/filterBookings.d.ts +6 -0
  38. package/lib/server/modules/order/utils/filterBookings.js +320 -0
  39. package/lib/server/modules/order/utils/filterOrders.d.ts +15 -0
  40. package/lib/server/modules/order/utils/filterOrders.js +197 -0
  41. package/lib/server/modules/resource/index.d.ts +88 -0
  42. package/lib/server/modules/resource/index.js +571 -0
  43. package/lib/server/modules/resource/types.d.ts +121 -0
  44. package/lib/server/modules/resource/types.js +35 -0
  45. package/lib/solution/BookingByStep/index.d.ts +1 -1
  46. package/lib/solution/BookingTicket/index.d.ts +1 -1
  47. package/lib/solution/Sales/index.d.ts +96 -0
  48. package/lib/solution/Sales/index.js +413 -0
  49. package/lib/solution/Sales/types.d.ts +66 -0
  50. package/lib/solution/Sales/types.js +35 -0
  51. package/lib/solution/index.d.ts +1 -0
  52. package/lib/solution/index.js +3 -1
  53. package/package.json +1 -1
@@ -0,0 +1,26 @@
1
+ export var SalesHooks = /*#__PURE__*/function (SalesHooks) {
2
+ SalesHooks["onInited"] = "sales:onInited";
3
+ SalesHooks["onDestroy"] = "sales:onDestroy";
4
+ SalesHooks["onCurrentDayChanged"] = "sales:onCurrentDayChanged";
5
+ SalesHooks["onReservationListChanged"] = "sales:onReservationListChanged";
6
+ return SalesHooks;
7
+ }({});
8
+
9
+ /**
10
+ * 预订记录类型(暂用 OrderData 占位)
11
+ *
12
+ * TODO(Rolo): 等领导提供 reservationList 的目标结构后,
13
+ * 将 Server/Order 原始数据转换为真正的 Reservation DTO,
14
+ * 当前不要直接把 OrderData 当作最终 UI 数据结构。
15
+ */
16
+
17
+ /**
18
+ * Sales 解决方案状态
19
+ *
20
+ * - currentDay: 当前选择的日期,默认当天 00:00:00
21
+ * - reservationList: currentDay 对应的预约列表(数据来源于 Server/Order,转换逻辑待补)
22
+ */
23
+
24
+ /**
25
+ * Sales 解决方案最小 API 面
26
+ */
@@ -4,3 +4,4 @@ export * from './BookingTicket';
4
4
  export * from './ShopDiscount';
5
5
  export * from './RegisterAndLogin';
6
6
  export * from './Checkout';
7
+ export * from './Sales';
@@ -3,4 +3,5 @@ export * from "./BookingByStep";
3
3
  export * from "./BookingTicket";
4
4
  export * from "./ShopDiscount";
5
5
  export * from "./RegisterAndLogin";
6
- export * from "./Checkout";
6
+ export * from "./Checkout";
7
+ export * from "./Sales";
@@ -23,7 +23,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
23
23
  */
24
24
  private logError;
25
25
  createOrder(params: CommitOrderParams['query']): {
26
- type: "virtual" | "appointment_booking";
26
+ type: "appointment_booking" | "virtual";
27
27
  platform: string;
28
28
  sales_channel: string;
29
29
  order_sales_channel: string;
@@ -63,6 +63,7 @@ declare class App {
63
63
  pubsub: import("../pubsub").PubSub;
64
64
  tasksManager: TasksManager;
65
65
  dbManager: IndexDBManager | null;
66
+ sqlite: any;
66
67
  constants: {
67
68
  channel: string;
68
69
  [key: string]: string;
@@ -2,8 +2,10 @@ import { ProductsModule } from './modules/products';
2
2
  import { MenuModule } from './modules/menu';
3
3
  import { QuotationModule } from './modules/quotation';
4
4
  import { ScheduleModuleEx } from './modules/schedule';
5
+ import { ResourceModule } from './modules/resource';
5
6
  import { PisellCore, ServerModuleConfig, InitializeServerOptions } from '../types';
6
7
  import type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, RequestSetting } from './types';
8
+ import { OrderModule } from './modules/order';
7
9
  export type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, };
8
10
  /**
9
11
  * Server 类
@@ -17,8 +19,12 @@ declare class Server {
17
19
  menu?: MenuModule;
18
20
  quotation?: QuotationModule;
19
21
  schedule?: ScheduleModuleEx;
22
+ resource?: ResourceModule;
23
+ order?: OrderModule;
20
24
  router: Router;
21
25
  private productQuerySubscribers;
26
+ private orderQuerySubscribers;
27
+ private bookingQuerySubscribers;
22
28
  private moduleRegistry;
23
29
  constructor(core: PisellCore);
24
30
  /**
@@ -151,6 +157,47 @@ declare class Server {
151
157
  * 取消商品查询订阅(HTTP 路由入口)
152
158
  */
153
159
  private handleUnsubscribeProductQuery;
160
+ /**
161
+ * 处理订单列表查询
162
+ * 存储订阅者信息,本地计算结果;数据变更时通过 callback 推送
163
+ */
164
+ private handleOrderList;
165
+ /**
166
+ * 取消订单列表查询订阅(HTTP 路由入口)
167
+ */
168
+ private handleUnsubscribeOrderQuery;
169
+ /**
170
+ * 判断预约查询的 sales_time_between 起始日期是否为今天
171
+ */
172
+ private isBookingQueryForToday;
173
+ /**
174
+ * 非今天的预约查询:通过真实 API 获取数据,再做 flattenOrdersToBookings 拆分
175
+ */
176
+ private fetchBookingListFromAPI;
177
+ /**
178
+ * 处理预约列表查询
179
+ * 今天:注册订阅者 + 本地数据筛选;非今天:清理订阅者 + 走真实 API
180
+ */
181
+ private handleBookingList;
182
+ /**
183
+ * 处理资源列表查询
184
+ * 转发到资源模块去
185
+ */
186
+ private handleResourceList;
187
+ /**
188
+ * 取消预约列表查询订阅(HTTP 路由入口)
189
+ */
190
+ private handleUnsubscribeBookingQuery;
191
+ /**
192
+ * 订单列表本地计算(编排 Order 模块)
193
+ * filter 逻辑暂为 mock,仅记录参数
194
+ */
195
+ private computeOrderQueryResult;
196
+ /**
197
+ * 预约列表本地计算(编排 Order 模块)
198
+ * 从订单中展开 bookings,再按条件筛选 + 分页
199
+ */
200
+ private computeBookingQueryResult;
154
201
  /**
155
202
  * 商品查询的核心计算逻辑(编排 Products、Menu、Schedule 模块)
156
203
  * 供 handleProductQuery 首次返回及 pubsub 变更推送复用
@@ -166,6 +213,14 @@ declare class Server {
166
213
  * @param options.changedIds 变更的商品 IDs,用于增量更新价格缓存
167
214
  */
168
215
  private recomputeAndNotifyProductQuery;
216
+ /**
217
+ * 订单数据变更后,遍历订阅者重新计算并通过 callback 推送
218
+ */
219
+ private recomputeAndNotifyOrderQuery;
220
+ /**
221
+ * 预约数据变更后,遍历订阅者重新计算并通过 callback 推送
222
+ */
223
+ private recomputeAndNotifyBookingQuery;
169
224
  /**
170
225
  * 根据餐牌配置过滤商品
171
226
  * @param products 所有商品列表
@@ -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,13 +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");
31
43
  var import_types = require("./modules/products/types");
32
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");
33
49
  __reExport(server_exports, require("./modules"), module.exports);
34
50
  var Server = class {
35
51
  constructor(core) {
@@ -42,6 +58,9 @@ var Server = class {
42
58
  };
43
59
  // ---- 商品查询订阅者 ----
44
60
  this.productQuerySubscribers = /* @__PURE__ */ new Map();
61
+ // ---- 订单 / 预约列表查询订阅者 ----
62
+ this.orderQuerySubscribers = /* @__PURE__ */ new Map();
63
+ this.bookingQuerySubscribers = /* @__PURE__ */ new Map();
45
64
  // 模块注册表 - 定义所有可用的模块配置
46
65
  this.moduleRegistry = {
47
66
  products: {
@@ -82,6 +101,26 @@ var Server = class {
82
101
  availabilityDateList: [],
83
102
  otherProductsIds: []
84
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
+ }
85
124
  }
86
125
  };
87
126
  /**
@@ -117,6 +156,109 @@ var Server = class {
117
156
  this.removeProductQuerySubscriber(subscriberId);
118
157
  return { code: 200, message: "ok", status: true };
119
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
+ });
177
+ }
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
190
+ });
191
+ }
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
206
+ });
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
+ });
226
+ }
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
240
+ });
241
+ return {
242
+ code: 200,
243
+ data: { list, count: (list == null ? void 0 : list.length) || 0 },
244
+ message: "",
245
+ status: true
246
+ };
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
+ };
120
262
  /**
121
263
  * 处理获取日程时间段点的请求
122
264
  * 通过餐牌ID列表获取所有相关日程的时间段点
@@ -420,6 +562,10 @@ var Server = class {
420
562
  changedIds: payload == null ? void 0 : payload.changedIds
421
563
  });
422
564
  });
565
+ this.core.effects.on(import_types2.OrderHooks.onOrdersChanged, () => {
566
+ this.recomputeAndNotifyOrderQuery();
567
+ this.recomputeAndNotifyBookingQuery();
568
+ });
423
569
  const duration = Date.now() - startTime;
424
570
  this.logInfo("Server 初始化完成", {
425
571
  duration: `${duration}ms`,
@@ -464,6 +610,10 @@ var Server = class {
464
610
  modules.push("quotation");
465
611
  if (this.schedule)
466
612
  modules.push("schedule");
613
+ if (this.resource)
614
+ modules.push("resource");
615
+ if (this.order)
616
+ modules.push("order");
467
617
  return modules;
468
618
  }
469
619
  /**
@@ -517,6 +667,14 @@ var Server = class {
517
667
  clearTasks.push(this.schedule.clear());
518
668
  moduleNames.push("Schedule");
519
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
+ }
520
678
  if (clearTasks.length === 0) {
521
679
  console.warn("[Server] 没有找到已注册的模块,无需清空");
522
680
  this.logWarning("没有找到已注册的模块,无需清空 IndexedDB");
@@ -567,7 +725,6 @@ var Server = class {
567
725
  */
568
726
  async handleRoute(method, path, params) {
569
727
  const startTime = Date.now();
570
- console.log(method, path, params, "method, path, params");
571
728
  this.logInfo(`路由请求开始: ${method.toUpperCase()} ${path}`, {
572
729
  method: method.toUpperCase(),
573
730
  path,
@@ -638,6 +795,31 @@ var Server = class {
638
795
  method: "post",
639
796
  path: "/shop/menu/schedule-time-points",
640
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)
641
823
  }
642
824
  ]);
643
825
  }
@@ -653,6 +835,120 @@ var Server = class {
653
835
  });
654
836
  }
655
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
+ }
656
952
  /**
657
953
  * 商品查询的核心计算逻辑(编排 Products、Menu、Schedule 模块)
658
954
  * 供 handleProductQuery 首次返回及 pubsub 变更推送复用
@@ -770,6 +1066,52 @@ var Server = class {
770
1066
  }
771
1067
  }
772
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
+ }
773
1115
  /**
774
1116
  * 根据餐牌配置过滤商品
775
1117
  * @param products 所有商品列表
@@ -13,4 +13,10 @@ export type { QuotationState, QuotationData, QuotationProductPrice } from './quo
13
13
  export { QuotationHooks } from './quotation/types';
14
14
  export { ScheduleModuleEx } from './schedule';
15
15
  export type { ScheduleState, ScheduleItem } from './schedule/types';
16
+ export { OrderModule } from './order';
17
+ export type { OrderState, OrderData, OrderId, OrderSummary, OrderBookingItem, OrderProductLineItem, OrderPaymentItem, OrderSurchargeItem, OrderProductDiscountItem, OrderWithoutBookings, BookingData, OrderFilters, BookingFilters, OrderFilterResult, BookingFilterResult, OrderModulePagedResult, } from './order/types';
18
+ export { OrderHooks } from './order/types';
19
+ export { ResourceModule, resourceModule } from './resource';
20
+ export type { ResourceState, ResourceData, ResourceId, ResourceBooking, ResourcePageQuery, ResourcePageResult, QueryOptions, ScheduleEventResource, } from './resource';
21
+ export { ResourceHooks } from './resource';
16
22
  export type { RouteHandler, HttpMethod, RouteDefinition, Router, ModuleRegistryConfig, } from '../types';
@@ -21,11 +21,16 @@ var modules_exports = {};
21
21
  __export(modules_exports, {
22
22
  MenuHooks: () => import_types2.MenuHooks,
23
23
  MenuModule: () => import_menu.MenuModule,
24
+ OrderHooks: () => import_types4.OrderHooks,
25
+ OrderModule: () => import_order.OrderModule,
24
26
  ProductsHooks: () => import_types.ProductsHooks,
25
27
  ProductsModule: () => import_products.ProductsModule,
26
28
  QuotationHooks: () => import_types3.QuotationHooks,
27
29
  QuotationModule: () => import_quotation.QuotationModule,
28
- ScheduleModuleEx: () => import_schedule.ScheduleModuleEx
30
+ ResourceHooks: () => import_resource2.ResourceHooks,
31
+ ResourceModule: () => import_resource.ResourceModule,
32
+ ScheduleModuleEx: () => import_schedule.ScheduleModuleEx,
33
+ resourceModule: () => import_resource.resourceModule
29
34
  });
30
35
  module.exports = __toCommonJS(modules_exports);
31
36
  var import_products = require("./products");
@@ -35,13 +40,22 @@ var import_types2 = require("./menu/types");
35
40
  var import_quotation = require("./quotation");
36
41
  var import_types3 = require("./quotation/types");
37
42
  var import_schedule = require("./schedule");
43
+ var import_order = require("./order");
44
+ var import_types4 = require("./order/types");
45
+ var import_resource = require("./resource");
46
+ var import_resource2 = require("./resource");
38
47
  // Annotate the CommonJS export names for ESM import in node:
39
48
  0 && (module.exports = {
40
49
  MenuHooks,
41
50
  MenuModule,
51
+ OrderHooks,
52
+ OrderModule,
42
53
  ProductsHooks,
43
54
  ProductsModule,
44
55
  QuotationHooks,
45
56
  QuotationModule,
46
- ScheduleModuleEx
57
+ ResourceHooks,
58
+ ResourceModule,
59
+ ScheduleModuleEx,
60
+ resourceModule
47
61
  });