@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,87 @@
1
+ import { Module, ModuleOptions, PisellCore } from '../../../types';
2
+ import { BaseModule } from '../../../modules/BaseModule';
3
+ import type { RouteDefinition } from '../../types';
4
+ import { OrderData, OrderId } from './types';
5
+ /**
6
+ * Order 模块 - 基础框架
7
+ */
8
+ export declare class OrderModule extends BaseModule implements Module {
9
+ protected defaultName: string;
10
+ protected defaultVersion: string;
11
+ private store;
12
+ private dbManager;
13
+ private orderDataSource;
14
+ private pendingSyncMessages;
15
+ private syncTimer?;
16
+ private readonly ORDER_SYNC_DEBOUNCE_MS;
17
+ private resourceIdIndex;
18
+ private logger;
19
+ private storage;
20
+ constructor(name?: string, version?: string);
21
+ initialize(core: PisellCore, options?: ModuleOptions): Promise<void>;
22
+ /**
23
+ * 记录信息日志
24
+ * @param title 日志标题
25
+ * @param metadata 日志元数据
26
+ */
27
+ private logInfo;
28
+ /**
29
+ * 记录错误日志
30
+ * @param title 日志标题
31
+ * @param metadata 日志元数据
32
+ */
33
+ private logError;
34
+ preload(): Promise<void>;
35
+ getOrders(): OrderData[];
36
+ getOrderById(id: OrderId): OrderData | undefined;
37
+ /** 按 order_id 查询(推荐) */
38
+ getOrderByOrderId(orderId: OrderId): OrderData | undefined;
39
+ loadOrdersByServer(): Promise<OrderData[]>;
40
+ getOrdersByResourceId(resourceId: string | number): OrderData[];
41
+ getRoutes(): RouteDefinition[];
42
+ destroy(): void;
43
+ private syncOrdersMap;
44
+ private extractResourceIds;
45
+ private getOrderDateKey;
46
+ /**
47
+ * 初始化 OrderDataSource 实例
48
+ */
49
+ private initOrderDataSource;
50
+ /**
51
+ * 初始化 pubsub 订阅,监听订单变更
52
+ */
53
+ private setupOrderSync;
54
+ /**
55
+ * 处理防抖后的同步消息批次
56
+ *
57
+ * 后端统一发送 change 消息,不再区分新增/编辑/删除。
58
+ * - 单条(id/order_id):若携带 body/data 则直接 upsert 到本地
59
+ * - 批量(ids):通过 HTTP 按 ids 增量拉取,再 merge 到本地
60
+ */
61
+ private processOrderSyncMessages;
62
+ /**
63
+ * 通过 HTTP 按 ids 增量拉取订单
64
+ */
65
+ private fetchOrdersByHttp;
66
+ /**
67
+ * 将增量订单合并到 store
68
+ */
69
+ private mergeOrdersToStore;
70
+ private normalizeOrderSyncMessage;
71
+ private normalizeOrderSyncPayload;
72
+ private uniqueOrderIds;
73
+ private getIdKey;
74
+ /**
75
+ * 当前订单拉取窗口:
76
+ * - 优先使用 createdAtQuery.sales_time_between(已按营业日边界初始化)
77
+ * - 无法解析时退化为自然日窗口
78
+ */
79
+ private getCurrentPullWindow;
80
+ private hasPulledOrdersToday;
81
+ private markOrderPulledAtNow;
82
+ private getStorageItem;
83
+ private setStorageItem;
84
+ private loadOrdersFromSQLite;
85
+ private saveOrdersToSQLite;
86
+ clear(): Promise<void>;
87
+ }
@@ -0,0 +1,543 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+
29
+ // src/server/modules/order/index.ts
30
+ var order_exports = {};
31
+ __export(order_exports, {
32
+ OrderModule: () => OrderModule
33
+ });
34
+ module.exports = __toCommonJS(order_exports);
35
+ var import_lodash_es = require("lodash-es");
36
+ var import_dayjs = __toESM(require("dayjs"));
37
+ var import_BaseModule = require("../../../modules/BaseModule");
38
+ var import_types = require("./types");
39
+ var INDEXDB_STORE_NAME = "orders";
40
+ var ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY = "server_order_last_full_fetch_at";
41
+ var OrderModule = class extends import_BaseModule.BaseModule {
42
+ constructor(name, version) {
43
+ super(name, version);
44
+ this.defaultName = "order";
45
+ this.defaultVersion = "1.0.0";
46
+ this.pendingSyncMessages = [];
47
+ this.ORDER_SYNC_DEBOUNCE_MS = 1e4;
48
+ // Map<resource_id, OrderId[]> 资源到订单的倒排索引
49
+ this.resourceIdIndex = /* @__PURE__ */ new Map();
50
+ }
51
+ async initialize(core, options) {
52
+ var _a, _b;
53
+ this.core = core;
54
+ this.store = options == null ? void 0 : options.store;
55
+ if (!this.store.map)
56
+ this.store.map = /* @__PURE__ */ new Map();
57
+ const appPlugin = core.getPlugin("app");
58
+ const app = appPlugin == null ? void 0 : appPlugin.getApp();
59
+ if (app) {
60
+ this.dbManager = app.sqlite;
61
+ this.logger = app.logger;
62
+ this.storage = app.storage;
63
+ const coreData = app.data.store.getStore().getDataByModel("core");
64
+ if (!((_a = this.store.createdAtQuery) == null ? void 0 : _a.sales_time_between) && (coreData == null ? void 0 : coreData.core)) {
65
+ const today = (0, import_dayjs.default)();
66
+ if (coreData == null ? void 0 : coreData.core.operating_day_boundary) {
67
+ const operatingDayBoundary = coreData.core.operating_day_boundary;
68
+ if (operatingDayBoundary.type === "start_time") {
69
+ const boundaryTime = String(operatingDayBoundary.time || "").trim();
70
+ const boundaryStart = (0, import_dayjs.default)(`${today.format("YYYY-MM-DD")} ${boundaryTime}`);
71
+ const boundaryEnd = boundaryStart.add(1, "day");
72
+ if (boundaryStart.isValid()) {
73
+ this.store.createdAtQuery = {
74
+ sales_time_between: [
75
+ boundaryStart.format("YYYY-MM-DD HH:mm:ss"),
76
+ boundaryEnd.format("YYYY-MM-DD HH:mm:ss")
77
+ ]
78
+ };
79
+ } else {
80
+ this.store.createdAtQuery = {
81
+ sales_time_between: [
82
+ today.startOf("day").format("YYYY-MM-DD HH:mm:ss"),
83
+ today.endOf("day").format("YYYY-MM-DD HH:mm:ss")
84
+ ]
85
+ };
86
+ }
87
+ } else {
88
+ this.store.createdAtQuery = {
89
+ sales_time_between: [
90
+ today.startOf("day").format("YYYY-MM-DD HH:mm:ss"),
91
+ today.endOf("day").format("YYYY-MM-DD HH:mm:ss")
92
+ ]
93
+ };
94
+ }
95
+ } else {
96
+ this.store.createdAtQuery = {
97
+ sales_time_between: [today.startOf("day").format("YYYY-MM-DD HH:mm:ss"), today.endOf("day").format("YYYY-MM-DD HH:mm:ss")]
98
+ };
99
+ }
100
+ }
101
+ }
102
+ if (Array.isArray((_b = options == null ? void 0 : options.initialState) == null ? void 0 : _b.list)) {
103
+ this.store.list = options.initialState.list;
104
+ this.syncOrdersMap();
105
+ this.core.effects.emit(import_types.OrderHooks.onOrdersChanged, this.store.list);
106
+ } else {
107
+ this.store.list = [];
108
+ this.store.map = /* @__PURE__ */ new Map();
109
+ }
110
+ this.initOrderDataSource();
111
+ this.setupOrderSync();
112
+ this.logInfo("OrderServer模块初始化完成", {
113
+ hasDbManager: !!this.dbManager,
114
+ hasLogger: !!this.logger,
115
+ initialOrderCount: this.store.list.length
116
+ });
117
+ }
118
+ /**
119
+ * 记录信息日志
120
+ * @param title 日志标题
121
+ * @param metadata 日志元数据
122
+ */
123
+ logInfo(title, metadata) {
124
+ try {
125
+ if (this.logger) {
126
+ this.logger.addLog({
127
+ type: "info",
128
+ title: `[OrderServerModule] ${title}`,
129
+ metadata: metadata || {}
130
+ });
131
+ }
132
+ } catch {
133
+ }
134
+ }
135
+ /**
136
+ * 记录错误日志
137
+ * @param title 日志标题
138
+ * @param metadata 日志元数据
139
+ */
140
+ logError(title, metadata) {
141
+ try {
142
+ if (this.logger) {
143
+ this.logger.addLog({
144
+ type: "error",
145
+ title: `[OrderServerModule] ${title}`,
146
+ metadata: metadata || {}
147
+ });
148
+ }
149
+ } catch {
150
+ }
151
+ }
152
+ async preload() {
153
+ const orders = await this.loadOrdersByServer();
154
+ if (orders.length === 0)
155
+ return;
156
+ this.store.list = (0, import_lodash_es.cloneDeep)(orders);
157
+ this.syncOrdersMap();
158
+ this.core.effects.emit(import_types.OrderHooks.onOrdersChanged, this.store.list);
159
+ }
160
+ getOrders() {
161
+ return this.store.list;
162
+ }
163
+ getOrderById(id) {
164
+ return this.store.map.get(this.getIdKey(id));
165
+ }
166
+ /** 按 order_id 查询(推荐) */
167
+ getOrderByOrderId(orderId) {
168
+ return this.store.map.get(this.getIdKey(orderId));
169
+ }
170
+ async loadOrdersByServer() {
171
+ let orderList = [];
172
+ if (this.orderDataSource) {
173
+ try {
174
+ const data = await this.orderDataSource.run({
175
+ http: {
176
+ query: this.store.createdAtQuery
177
+ }
178
+ });
179
+ orderList = data || [];
180
+ this.markOrderPulledAtNow();
181
+ } catch {
182
+ orderList = [];
183
+ }
184
+ }
185
+ await this.saveOrdersToSQLite(orderList);
186
+ await this.core.effects.emit(import_types.OrderHooks.onOrdersLoaded, orderList);
187
+ return orderList;
188
+ }
189
+ getOrdersByResourceId(resourceId) {
190
+ const ids = this.resourceIdIndex.get(String(resourceId)) || [];
191
+ return ids.map((id) => this.store.map.get(id)).filter((order) => !!order);
192
+ }
193
+ getRoutes() {
194
+ return [];
195
+ }
196
+ destroy() {
197
+ var _a;
198
+ if (this.syncTimer) {
199
+ clearTimeout(this.syncTimer);
200
+ this.syncTimer = void 0;
201
+ }
202
+ this.pendingSyncMessages = [];
203
+ if ((_a = this.orderDataSource) == null ? void 0 : _a.destroy)
204
+ this.orderDataSource.destroy();
205
+ super.destroy();
206
+ }
207
+ syncOrdersMap() {
208
+ this.store.map.clear();
209
+ this.resourceIdIndex.clear();
210
+ for (const order of this.store.list) {
211
+ const id = order.order_id;
212
+ if (id === void 0 || id === null)
213
+ continue;
214
+ this.store.map.set(this.getIdKey(id), order);
215
+ const resourceIds = this.extractResourceIds(order);
216
+ for (const resourceId of resourceIds) {
217
+ const key = String(resourceId);
218
+ const existing = this.resourceIdIndex.get(key) || [];
219
+ if (existing.some((eid) => this.getIdKey(eid) === this.getIdKey(id)))
220
+ continue;
221
+ existing.push(id);
222
+ this.resourceIdIndex.set(key, existing);
223
+ }
224
+ }
225
+ }
226
+ extractResourceIds(order) {
227
+ const ids = /* @__PURE__ */ new Set();
228
+ const visitResources = (resources) => {
229
+ if (!Array.isArray(resources))
230
+ return;
231
+ resources.forEach((resource) => {
232
+ const rid = resource == null ? void 0 : resource.relation_id;
233
+ if (rid !== void 0 && rid !== null && rid !== "")
234
+ ids.add(String(rid));
235
+ if (Array.isArray(resource == null ? void 0 : resource.children))
236
+ visitResources(resource.children);
237
+ });
238
+ };
239
+ if (Array.isArray(order == null ? void 0 : order.bookings)) {
240
+ order.bookings.forEach((booking) => visitResources((booking == null ? void 0 : booking.resources) || []));
241
+ }
242
+ return [...ids];
243
+ }
244
+ getOrderDateKey(order) {
245
+ var _a, _b, _c, _d;
246
+ const candidates = [
247
+ order == null ? void 0 : order.schedule_date,
248
+ order == null ? void 0 : order.create_date,
249
+ order == null ? void 0 : order.created_at,
250
+ (_b = (_a = order == null ? void 0 : order.bookings) == null ? void 0 : _a[0]) == null ? void 0 : _b.start_date,
251
+ (_d = (_c = order == null ? void 0 : order.bookings) == null ? void 0 : _c[0]) == null ? void 0 : _d.select_date
252
+ ];
253
+ for (const v of candidates) {
254
+ if (!v)
255
+ continue;
256
+ const text = String(v);
257
+ if (!text)
258
+ continue;
259
+ return text.split("T")[0].split(" ")[0];
260
+ }
261
+ return void 0;
262
+ }
263
+ /**
264
+ * 初始化 OrderDataSource 实例
265
+ */
266
+ initOrderDataSource() {
267
+ var _a, _b;
268
+ const OrderDataSourceClass = (_b = (_a = this.core.serverOptions) == null ? void 0 : _a.All_DATA_SOURCES) == null ? void 0 : _b.OrderDataSource;
269
+ if (!OrderDataSourceClass)
270
+ return;
271
+ this.orderDataSource = new OrderDataSourceClass();
272
+ }
273
+ /**
274
+ * 初始化 pubsub 订阅,监听订单变更
275
+ */
276
+ setupOrderSync() {
277
+ if (!this.orderDataSource)
278
+ return;
279
+ const shouldSkipHttpPull = this.hasPulledOrdersToday();
280
+ const syncPayload = {
281
+ pubsub: {
282
+ callback: (res) => {
283
+ const message = this.normalizeOrderSyncMessage(res);
284
+ if (!message)
285
+ return;
286
+ this.pendingSyncMessages.push(message);
287
+ if (this.syncTimer)
288
+ clearTimeout(this.syncTimer);
289
+ this.syncTimer = setTimeout(() => {
290
+ this.processOrderSyncMessages();
291
+ }, this.ORDER_SYNC_DEBOUNCE_MS);
292
+ }
293
+ }
294
+ };
295
+ syncPayload.http = {
296
+ query: this.store.createdAtQuery,
297
+ skipHttp: shouldSkipHttpPull
298
+ };
299
+ this.orderDataSource.run(syncPayload).then(() => {
300
+ if (!shouldSkipHttpPull)
301
+ this.markOrderPulledAtNow();
302
+ }).catch(() => {
303
+ });
304
+ }
305
+ /**
306
+ * 处理防抖后的同步消息批次
307
+ *
308
+ * 后端统一发送 change 消息,不再区分新增/编辑/删除。
309
+ * - 单条(id/order_id):若携带 body/data 则直接 upsert 到本地
310
+ * - 批量(ids):通过 HTTP 按 ids 增量拉取,再 merge 到本地
311
+ */
312
+ async processOrderSyncMessages() {
313
+ var _a;
314
+ const messages = [...this.pendingSyncMessages];
315
+ this.pendingSyncMessages = [];
316
+ if (messages.length === 0)
317
+ return;
318
+ const upsertOrders = /* @__PURE__ */ new Map();
319
+ const refreshIds = [];
320
+ for (const msg of messages) {
321
+ const hasBatchIds = Array.isArray(msg.ids) && msg.ids.length > 0;
322
+ const singleId = msg.id ?? msg.order_id;
323
+ const hasSingleId = !hasBatchIds && singleId !== void 0 && singleId !== null;
324
+ const rawBody = msg.body || msg.data;
325
+ const normalizedBody = this.normalizeOrderSyncPayload(rawBody);
326
+ if (hasSingleId && normalizedBody) {
327
+ upsertOrders.set(this.getIdKey(normalizedBody.order_id), normalizedBody);
328
+ continue;
329
+ }
330
+ if (hasBatchIds)
331
+ refreshIds.push(...msg.ids);
332
+ else if (hasSingleId)
333
+ refreshIds.push(singleId);
334
+ else if ((_a = msg.relation_order_ids) == null ? void 0 : _a.length)
335
+ refreshIds.push(...msg.relation_order_ids);
336
+ }
337
+ const uniqueRefreshIds = this.uniqueOrderIds(refreshIds);
338
+ const upsertList = [...upsertOrders.values()];
339
+ if (upsertList.length > 0)
340
+ await this.mergeOrdersToStore(upsertList);
341
+ if (uniqueRefreshIds.length > 0) {
342
+ const freshOrders = await this.fetchOrdersByHttp(uniqueRefreshIds);
343
+ if (freshOrders.length > 0)
344
+ await this.mergeOrdersToStore(freshOrders);
345
+ }
346
+ if (upsertList.length === 0 && uniqueRefreshIds.length === 0)
347
+ return;
348
+ await this.core.effects.emit(import_types.OrderHooks.onOrdersSyncCompleted, null);
349
+ }
350
+ /**
351
+ * 通过 HTTP 按 ids 增量拉取订单
352
+ */
353
+ async fetchOrdersByHttp(ids) {
354
+ if (!this.orderDataSource || ids.length === 0)
355
+ return [];
356
+ try {
357
+ if (typeof this.orderDataSource.fetchOrdersByIds === "function") {
358
+ const orderList2 = await this.orderDataSource.fetchOrdersByIds(ids);
359
+ return orderList2 || [];
360
+ }
361
+ const orderList = await this.orderDataSource.run({
362
+ http: {
363
+ query: { ids }
364
+ }
365
+ });
366
+ return orderList || [];
367
+ } catch {
368
+ return [];
369
+ }
370
+ }
371
+ /**
372
+ * 将增量订单合并到 store
373
+ */
374
+ async mergeOrdersToStore(freshOrders) {
375
+ const freshMap = /* @__PURE__ */ new Map();
376
+ for (const order of freshOrders) {
377
+ const id = order == null ? void 0 : order.order_id;
378
+ if (id === void 0 || id === null)
379
+ continue;
380
+ freshMap.set(this.getIdKey(id), order);
381
+ }
382
+ const updatedList = this.store.list.map((order) => {
383
+ const id = order.order_id;
384
+ if (id === void 0 || id === null)
385
+ return order;
386
+ const key = this.getIdKey(id);
387
+ if (!freshMap.has(key))
388
+ return order;
389
+ const fresh = freshMap.get(key);
390
+ freshMap.delete(key);
391
+ return fresh;
392
+ });
393
+ for (const order of freshMap.values()) {
394
+ updatedList.push(order);
395
+ }
396
+ this.store.list = updatedList;
397
+ this.syncOrdersMap();
398
+ await this.saveOrdersToSQLite(this.store.list);
399
+ this.core.effects.emit(import_types.OrderHooks.onOrdersChanged, this.store.list);
400
+ }
401
+ normalizeOrderSyncMessage(res) {
402
+ const data = (res == null ? void 0 : res.data) || res;
403
+ if (!data)
404
+ return null;
405
+ const payload = (data == null ? void 0 : data.data) && typeof data.data === "object" ? data.data : void 0;
406
+ const normalized = {
407
+ ...data,
408
+ _channelKey: data.module || "sales_sync"
409
+ };
410
+ if (!normalized.type && typeof data.event === "string")
411
+ normalized.type = data.event;
412
+ if (!normalized.id && data.id !== void 0)
413
+ normalized.id = data.id;
414
+ if (!normalized.id && data.order_id !== void 0)
415
+ normalized.id = data.order_id;
416
+ if (!normalized.order_id && data.order_id !== void 0)
417
+ normalized.order_id = data.order_id;
418
+ if (!normalized.order_id && (payload == null ? void 0 : payload.order_id) !== void 0)
419
+ normalized.order_id = payload.order_id;
420
+ if (!normalized.body && (payload == null ? void 0 : payload.order_id) !== void 0)
421
+ normalized.body = payload;
422
+ if (!normalized.data && (payload == null ? void 0 : payload.order_id) !== void 0)
423
+ normalized.data = payload;
424
+ return normalized;
425
+ }
426
+ normalizeOrderSyncPayload(payload) {
427
+ if (!payload)
428
+ return null;
429
+ const orderId = payload.order_id;
430
+ if (orderId === void 0 || orderId === null)
431
+ return null;
432
+ return { ...payload, order_id: orderId };
433
+ }
434
+ uniqueOrderIds(ids) {
435
+ const idMap = /* @__PURE__ */ new Map();
436
+ for (const id of ids) {
437
+ idMap.set(this.getIdKey(id), id);
438
+ }
439
+ return [...idMap.values()];
440
+ }
441
+ getIdKey(id) {
442
+ return String(id);
443
+ }
444
+ /**
445
+ * 当前订单拉取窗口:
446
+ * - 优先使用 createdAtQuery.sales_time_between(已按营业日边界初始化)
447
+ * - 无法解析时退化为自然日窗口
448
+ */
449
+ getCurrentPullWindow() {
450
+ var _a, _b;
451
+ const now = (0, import_dayjs.default)();
452
+ const range = (_b = (_a = this.store) == null ? void 0 : _a.createdAtQuery) == null ? void 0 : _b.sales_time_between;
453
+ if (Array.isArray(range) && range.length >= 2) {
454
+ const startAt2 = (0, import_dayjs.default)(range[0]);
455
+ const endExclusiveAt = (0, import_dayjs.default)(range[1]);
456
+ if (startAt2.isValid() && endExclusiveAt.isValid() && endExclusiveAt.isAfter(startAt2)) {
457
+ return { startAt: startAt2, endExclusiveAt };
458
+ }
459
+ }
460
+ const startAt = now.startOf("day");
461
+ return { startAt, endExclusiveAt: startAt.add(1, "day") };
462
+ }
463
+ hasPulledOrdersToday() {
464
+ const lastFullFetchAt = this.getStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY);
465
+ if (!lastFullFetchAt)
466
+ return false;
467
+ const parsed = (0, import_dayjs.default)(lastFullFetchAt);
468
+ if (!parsed.isValid())
469
+ return false;
470
+ const { startAt, endExclusiveAt } = this.getCurrentPullWindow();
471
+ return (parsed.isAfter(startAt) || parsed.isSame(startAt)) && parsed.isBefore(endExclusiveAt);
472
+ }
473
+ markOrderPulledAtNow() {
474
+ this.setStorageItem(
475
+ ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY,
476
+ (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss")
477
+ );
478
+ }
479
+ getStorageItem(key) {
480
+ var _a;
481
+ try {
482
+ if ((_a = this.storage) == null ? void 0 : _a.getStorage)
483
+ return this.storage.getStorage(key);
484
+ if (typeof globalThis !== "undefined" && (globalThis == null ? void 0 : globalThis.localStorage)) {
485
+ return globalThis.localStorage.getItem(key);
486
+ }
487
+ } catch {
488
+ }
489
+ return null;
490
+ }
491
+ setStorageItem(key, value) {
492
+ var _a;
493
+ try {
494
+ if ((_a = this.storage) == null ? void 0 : _a.setStorage) {
495
+ this.storage.setStorage(key, value);
496
+ return;
497
+ }
498
+ if (typeof globalThis !== "undefined" && (globalThis == null ? void 0 : globalThis.localStorage)) {
499
+ globalThis.localStorage.setItem(key, value);
500
+ }
501
+ } catch {
502
+ }
503
+ }
504
+ async loadOrdersFromSQLite() {
505
+ if (!this.dbManager)
506
+ return [];
507
+ try {
508
+ const orders = await this.dbManager.getAll(INDEXDB_STORE_NAME);
509
+ return orders || [];
510
+ } catch {
511
+ return [];
512
+ }
513
+ }
514
+ async saveOrdersToSQLite(orderList) {
515
+ if (!this.dbManager)
516
+ return;
517
+ try {
518
+ await this.dbManager.clear(INDEXDB_STORE_NAME);
519
+ if (orderList.length === 0)
520
+ return;
521
+ await this.dbManager.bulkAdd(INDEXDB_STORE_NAME, orderList);
522
+ } catch (error) {
523
+ this.logError("保存订单到 SQLite 失败", {
524
+ error: error instanceof Error ? error.message : String(error),
525
+ orderList: orderList.length
526
+ });
527
+ }
528
+ }
529
+ async clear() {
530
+ this.store.list = [];
531
+ this.store.map = /* @__PURE__ */ new Map();
532
+ this.resourceIdIndex.clear();
533
+ if (this.dbManager) {
534
+ await this.dbManager.clear(INDEXDB_STORE_NAME);
535
+ }
536
+ this.setStorageItem(ORDER_LAST_FULL_FETCH_AT_STORAGE_KEY, "");
537
+ this.core.effects.emit(import_types.OrderHooks.onOrdersChanged, this.store.list);
538
+ }
539
+ };
540
+ // Annotate the CommonJS export names for ESM import in node:
541
+ 0 && (module.exports = {
542
+ OrderModule
543
+ });