@pisell/pisellos 2.2.97 → 2.2.99

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 (44) hide show
  1. package/dist/model/strategy/adapter/walletPass/type.d.ts +2 -2
  2. package/dist/model/strategy/adapter/walletPass/utils.js +70 -57
  3. package/dist/modules/Order/index.d.ts +1 -1
  4. package/dist/server/index.d.ts +30 -0
  5. package/dist/server/index.js +660 -330
  6. package/dist/server/modules/floor-plan/index.d.ts +39 -0
  7. package/dist/server/modules/floor-plan/index.js +595 -0
  8. package/dist/server/modules/floor-plan/types.d.ts +43 -0
  9. package/dist/server/modules/floor-plan/types.js +13 -0
  10. package/dist/server/modules/index.d.ts +3 -0
  11. package/dist/server/modules/index.js +4 -0
  12. package/dist/server/modules/order/types.d.ts +13 -1
  13. package/dist/server/modules/order/types.js +2 -1
  14. package/dist/server/modules/order/utils/filterBookings.d.ts +7 -1
  15. package/dist/server/modules/order/utils/filterBookings.js +64 -4
  16. package/dist/server/modules/resource/index.d.ts +0 -5
  17. package/dist/server/modules/resource/index.js +186 -269
  18. package/dist/server/types.d.ts +2 -0
  19. package/dist/solution/BookingByStep/index.d.ts +1 -1
  20. package/dist/solution/Sales/index.d.ts +2 -1
  21. package/dist/solution/Sales/index.js +23 -10
  22. package/dist/solution/Sales/types.d.ts +1 -1
  23. package/lib/model/strategy/adapter/walletPass/type.d.ts +2 -2
  24. package/lib/model/strategy/adapter/walletPass/utils.js +58 -51
  25. package/lib/modules/Order/index.d.ts +1 -1
  26. package/lib/server/index.d.ts +30 -0
  27. package/lib/server/index.js +202 -9
  28. package/lib/server/modules/floor-plan/index.d.ts +39 -0
  29. package/lib/server/modules/floor-plan/index.js +327 -0
  30. package/lib/server/modules/floor-plan/types.d.ts +43 -0
  31. package/lib/server/modules/floor-plan/types.js +34 -0
  32. package/lib/server/modules/index.d.ts +3 -0
  33. package/lib/server/modules/index.js +6 -0
  34. package/lib/server/modules/order/types.d.ts +13 -1
  35. package/lib/server/modules/order/utils/filterBookings.d.ts +7 -1
  36. package/lib/server/modules/order/utils/filterBookings.js +69 -3
  37. package/lib/server/modules/resource/index.d.ts +0 -5
  38. package/lib/server/modules/resource/index.js +60 -73
  39. package/lib/server/types.d.ts +2 -0
  40. package/lib/solution/BookingByStep/index.d.ts +1 -1
  41. package/lib/solution/Sales/index.d.ts +2 -1
  42. package/lib/solution/Sales/index.js +11 -4
  43. package/lib/solution/Sales/types.d.ts +1 -1
  44. package/package.json +1 -1
@@ -0,0 +1,43 @@
1
+ /**
2
+ * 平面图(floor-plan)Server 模块类型
3
+ * 与 GET /shop/schedule/floor-plan 系列接口数据结构对齐
4
+ */
5
+ export interface FloorPlanItem {
6
+ id: number;
7
+ shop_id?: number;
8
+ code: string;
9
+ name: string | Record<string, string>;
10
+ layout: unknown[];
11
+ canvas_width: number;
12
+ canvas_height: number;
13
+ sort: number;
14
+ status: number;
15
+ created_at?: string;
16
+ updated_at?: string;
17
+ }
18
+ export interface FloorPlanState {
19
+ list: FloorPlanItem[];
20
+ map: Map<string, FloorPlanItem>;
21
+ codeMap: Map<string, FloorPlanItem>;
22
+ }
23
+ /** pubsub / Ably 推送消息(与《平面图编辑器API文档》Socket 一节一致) */
24
+ export interface FloorPlanSyncMessage {
25
+ module?: string;
26
+ action?: string;
27
+ operation?: string;
28
+ id?: number;
29
+ ids?: number[];
30
+ body?: Partial<FloorPlanItem> & {
31
+ id?: number;
32
+ };
33
+ message_uuid?: string;
34
+ timestamp?: string;
35
+ _channelKey?: string;
36
+ }
37
+ export declare const FloorPlanHooks: {
38
+ /** 本地列表变更(预加载、合并、删除后) */
39
+ readonly onFloorPlansChanged: "server_floor_plan:onFloorPlansChanged";
40
+ /** pubsub 同步处理完成,供 Server 向订阅者推送最新查询结果 */
41
+ readonly onFloorPlanSyncCompleted: "server_floor_plan:onFloorPlanSyncCompleted";
42
+ };
43
+ export type FloorPlanHooksType = (typeof FloorPlanHooks)[keyof typeof FloorPlanHooks];
@@ -0,0 +1,34 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/server/modules/floor-plan/types.ts
20
+ var types_exports = {};
21
+ __export(types_exports, {
22
+ FloorPlanHooks: () => FloorPlanHooks
23
+ });
24
+ module.exports = __toCommonJS(types_exports);
25
+ var FloorPlanHooks = {
26
+ /** 本地列表变更(预加载、合并、删除后) */
27
+ onFloorPlansChanged: "server_floor_plan:onFloorPlansChanged",
28
+ /** pubsub 同步处理完成,供 Server 向订阅者推送最新查询结果 */
29
+ onFloorPlanSyncCompleted: "server_floor_plan:onFloorPlanSyncCompleted"
30
+ };
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ FloorPlanHooks
34
+ });
@@ -16,6 +16,9 @@ export type { ScheduleState, ScheduleItem } from './schedule/types';
16
16
  export { OrderModule } from './order';
17
17
  export type { OrderState, OrderData, OrderId, OrderSummary, OrderBookingItem, OrderProductLineItem, OrderPaymentItem, OrderSurchargeItem, OrderProductDiscountItem, OrderWithoutBookings, BookingData, OrderFilters, BookingFilters, OrderFilterResult, BookingFilterResult, OrderModulePagedResult, } from './order/types';
18
18
  export { OrderHooks } from './order/types';
19
+ export { FloorPlanModule } from './floor-plan';
20
+ export type { FloorPlanItem, FloorPlanState, FloorPlanSyncMessage } from './floor-plan/types';
21
+ export { FloorPlanHooks } from './floor-plan/types';
19
22
  export { ResourceModule, resourceModule } from './resource';
20
23
  export type { ResourceState, ResourceData, ResourceId, ResourceBooking, ResourcePageQuery, ResourcePageResult, QueryOptions, ScheduleEventResource, } from './resource';
21
24
  export { ResourceHooks } from './resource';
@@ -19,6 +19,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/server/modules/index.ts
20
20
  var modules_exports = {};
21
21
  __export(modules_exports, {
22
+ FloorPlanHooks: () => import_types5.FloorPlanHooks,
23
+ FloorPlanModule: () => import_floor_plan.FloorPlanModule,
22
24
  MenuHooks: () => import_types2.MenuHooks,
23
25
  MenuModule: () => import_menu.MenuModule,
24
26
  OrderHooks: () => import_types4.OrderHooks,
@@ -42,10 +44,14 @@ var import_types3 = require("./quotation/types");
42
44
  var import_schedule = require("./schedule");
43
45
  var import_order = require("./order");
44
46
  var import_types4 = require("./order/types");
47
+ var import_floor_plan = require("./floor-plan");
48
+ var import_types5 = require("./floor-plan/types");
45
49
  var import_resource = require("./resource");
46
50
  var import_resource2 = require("./resource");
47
51
  // Annotate the CommonJS export names for ESM import in node:
48
52
  0 && (module.exports = {
53
+ FloorPlanHooks,
54
+ FloorPlanModule,
49
55
  MenuHooks,
50
56
  MenuModule,
51
57
  OrderHooks,
@@ -121,6 +121,8 @@ export interface OrderProductLineItem {
121
121
  product_bundle?: OrderProductBundleItem[];
122
122
  /** 元数据;含 unique_identification_number。来源:Detail.metadata */
123
123
  metadata?: OrderProductMetadata | null;
124
+ /** 关联子预约 ID(仅输出,预约订单场景)。来源:Detail.schedule_event_id */
125
+ schedule_event_id?: number | null;
124
126
  }
125
127
  /** 预约条目 metadata,常含 unique_identification_number */
126
128
  export interface OrderBookingMetadata {
@@ -188,6 +190,14 @@ export interface OrderBookingItem {
188
190
  holder?: Record<string, unknown> | null;
189
191
  /** 元数据;含 unique_identification_number。来源:ScheduleEvent.metadata */
190
192
  metadata?: OrderBookingMetadata | null;
193
+ /**
194
+ * 与订单明细等资源的关联(如 resource_type 为订单 Detail 时 resource_id 对应 order_detail_id)。
195
+ * 来源:服务端 ScheduleEvent 关联表。
196
+ */
197
+ relation_items?: {
198
+ resource_id?: number | null;
199
+ [key: string]: unknown;
200
+ }[];
191
201
  }
192
202
  /** 支付记录 metadata,常含 unique_payment_number */
193
203
  export interface OrderPaymentMetadata {
@@ -391,10 +401,12 @@ export interface OrderData {
391
401
  /** 去掉 bookings 后的订单快照;展开预约行时挂在 {@link BookingData.order} 上 */
392
402
  export type OrderWithoutBookings = Omit<OrderData, 'bookings'>;
393
403
  /**
394
- * 展开后的单条预约视图:协议 {@link OrderBookingItem} 平铺字段 + 所属订单(不含 bookings
404
+ * 展开后的单条预约视图:协议 {@link OrderBookingItem} 平铺字段 + 所属订单(不含 bookings)+
405
+ * 当前预约归属的商品行(由订单 products 按 schedule_event_id / relation_items 归集,不修改 order)
395
406
  */
396
407
  export type BookingData = OrderBookingItem & {
397
408
  order: OrderWithoutBookings;
409
+ products: OrderProductLineItem[];
398
410
  };
399
411
  /**
400
412
  * 订单列表筛选条件(与 order.ts getFilterButtonList 等 UI 对齐)
@@ -1,5 +1,11 @@
1
- import type { BookingData, BookingFilters, BookingFilterResult, OrderData } from '../types';
1
+ import type { BookingData, BookingFilters, BookingFilterResult, OrderBookingItem, OrderData, OrderProductLineItem } from '../types';
2
2
  export type { BookingData, BookingFilters, BookingFilterResult } from '../types';
3
+ /**
4
+ * 从整单 `order.products` 中归集属于指定 `booking` 的明细行。
5
+ * - 第一遍:`product.schedule_event_id === booking.schedule_event_id`(保持 products 原顺序)
6
+ * - 第二遍:按 `relation_items` 顺序追加 `resource_id` 与 `order_detail_id` 匹配且尚未收录的行
7
+ */
8
+ export declare function productsForBooking(order: OrderData, booking: OrderBookingItem): OrderProductLineItem[];
3
9
  export declare function flattenOrdersToBookings(orders: OrderData[]): BookingData[];
4
10
  export declare function filterBookingsFromOrders(orders: OrderData[], filters: BookingFilters): BookingFilterResult;
5
11
  export declare function sortBookings(result: BookingFilterResult, filters: BookingFilters): BookingFilterResult;
@@ -22,6 +22,7 @@ __export(filterBookings_exports, {
22
22
  filterBookings: () => filterBookings,
23
23
  filterBookingsFromOrders: () => filterBookingsFromOrders,
24
24
  flattenOrdersToBookings: () => flattenOrdersToBookings,
25
+ productsForBooking: () => productsForBooking,
25
26
  sortBookings: () => sortBookings
26
27
  });
27
28
  module.exports = __toCommonJS(filterBookings_exports);
@@ -189,6 +190,58 @@ function matchBooking(booking, orderInfo, ctx) {
189
190
  }
190
191
  return true;
191
192
  }
193
+ function productsForBooking(order, booking) {
194
+ var _a;
195
+ const products = order.products;
196
+ if (!Array.isArray(products) || products.length === 0)
197
+ return [];
198
+ const bookingEventId = booking.schedule_event_id;
199
+ const byDetailId = /* @__PURE__ */ new Map();
200
+ for (let i = 0, len = products.length; i < len; i++) {
201
+ const p = products[i];
202
+ const oid = p.order_detail_id;
203
+ if (oid === void 0 || oid === null)
204
+ continue;
205
+ const detailId = Number(oid);
206
+ if (Number.isNaN(detailId))
207
+ continue;
208
+ byDetailId.set(detailId, p);
209
+ }
210
+ const seen = /* @__PURE__ */ new Set();
211
+ const out = [];
212
+ for (let i = 0, len = products.length; i < len; i++) {
213
+ const p = products[i];
214
+ const oid = p.order_detail_id;
215
+ if (oid === void 0 || oid === null)
216
+ continue;
217
+ const detailId = Number(oid);
218
+ if (Number.isNaN(detailId))
219
+ continue;
220
+ if (bookingEventId !== void 0 && bookingEventId !== null && p.schedule_event_id !== void 0 && p.schedule_event_id !== null && Number(p.schedule_event_id) === Number(bookingEventId)) {
221
+ if (!seen.has(detailId)) {
222
+ seen.add(detailId);
223
+ out.push(p);
224
+ }
225
+ }
226
+ }
227
+ const relationItems = booking.relation_items;
228
+ if (Array.isArray(relationItems) && relationItems.length > 0) {
229
+ for (let r = 0, rLen = relationItems.length; r < rLen; r++) {
230
+ const rid = (_a = relationItems[r]) == null ? void 0 : _a.resource_id;
231
+ if (rid === void 0 || rid === null)
232
+ continue;
233
+ const detailId = Number(rid);
234
+ if (Number.isNaN(detailId) || seen.has(detailId))
235
+ continue;
236
+ const line = byDetailId.get(detailId);
237
+ if (line) {
238
+ seen.add(detailId);
239
+ out.push(line);
240
+ }
241
+ }
242
+ }
243
+ return out;
244
+ }
192
245
  function flattenOrdersToBookings(orders) {
193
246
  if (!orders || !Array.isArray(orders))
194
247
  return [];
@@ -200,7 +253,12 @@ function flattenOrdersToBookings(orders) {
200
253
  continue;
201
254
  const { bookings: _omit, ...orderInfo } = order;
202
255
  for (let j = 0, bLen = bookings.length; j < bLen; j++) {
203
- result.push({ ...bookings[j], order: orderInfo });
256
+ const booking = bookings[j];
257
+ result.push({
258
+ ...booking,
259
+ order: orderInfo,
260
+ products: productsForBooking(order, booking)
261
+ });
204
262
  }
205
263
  }
206
264
  return result;
@@ -237,7 +295,11 @@ function filterBookingsFromOrders(orders, filters) {
237
295
  const { bookings: _omit, ...rest } = order;
238
296
  orderInfo = rest;
239
297
  }
240
- paginatedList.push({ ...booking, order: orderInfo });
298
+ paginatedList.push({
299
+ ...booking,
300
+ order: orderInfo,
301
+ products: productsForBooking(order, booking)
302
+ });
241
303
  }
242
304
  totalCount++;
243
305
  }
@@ -300,7 +362,10 @@ function filterBookings(bookings, filters) {
300
362
  if (!matchBooking(booking, order, ctx))
301
363
  continue;
302
364
  if (totalCount >= startIndex && paginatedList.length < size) {
303
- paginatedList.push(booking);
365
+ paginatedList.push({
366
+ ...booking,
367
+ products: productsForBooking(booking.order, booking)
368
+ });
304
369
  }
305
370
  totalCount++;
306
371
  }
@@ -316,5 +381,6 @@ function filterBookings(bookings, filters) {
316
381
  filterBookings,
317
382
  filterBookingsFromOrders,
318
383
  flattenOrdersToBookings,
384
+ productsForBooking,
319
385
  sortBookings
320
386
  });
@@ -50,15 +50,12 @@ export declare class ResourceModule extends BaseModule implements Module {
50
50
  /**
51
51
  * 创建预订
52
52
  */
53
- createBooking(booking: Partial<ResourceBooking>): ResourceBooking;
54
53
  /**
55
54
  * 更新预订
56
55
  */
57
- updateBooking(id: ResourceId, data: Partial<ResourceBooking>): ResourceBooking | undefined;
58
56
  /**
59
57
  * 删除预订
60
58
  */
61
- deleteBooking(id: ResourceId): boolean;
62
59
  /**
63
60
  * 清空缓存
64
61
  */
@@ -73,8 +70,6 @@ export declare class ResourceModule extends BaseModule implements Module {
73
70
  private loadResourcesByServer;
74
71
  private loadResourcesFromSQLite;
75
72
  private saveResourcesToSQLite;
76
- private loadBookingsFromSQLite;
77
- private saveBookingsToSQLite;
78
73
  private initResourceDataSource;
79
74
  private setupResourceSync;
80
75
  private processSyncMessages;
@@ -29,7 +29,6 @@ var import_BaseModule = require("../../../modules/BaseModule");
29
29
  var import_types = require("./types");
30
30
  var import_types2 = require("./types");
31
31
  var RESOURCE_STORE_NAME = "resources";
32
- var BOOKING_STORE_NAME = "resource_bookings";
33
32
  var DEFAULT_PAGE_SIZE = 999;
34
33
  var RESOURCE_SYNC_DEBOUNCE_MS = 1e4;
35
34
  var ResourceModule = class extends import_BaseModule.BaseModule {
@@ -103,11 +102,6 @@ var ResourceModule = class extends import_BaseModule.BaseModule {
103
102
  await this.safeEmit(import_types.ResourceHooks.onResourcesChanged, this.store.list);
104
103
  }
105
104
  }
106
- const cachedBookings = await this.loadBookingsFromSQLite();
107
- if (cachedBookings.length > 0) {
108
- this.store.bookings = (0, import_lodash_es.cloneDeep)(cachedBookings);
109
- this.syncBookingsIndex();
110
- }
111
105
  }
112
106
  getRoutes() {
113
107
  return [];
@@ -205,54 +199,49 @@ var ResourceModule = class extends import_BaseModule.BaseModule {
205
199
  /**
206
200
  * 创建预订
207
201
  */
208
- createBooking(booking) {
209
- const id = (booking == null ? void 0 : booking.id) ?? Date.now();
210
- const normalized = {
211
- id,
212
- ...booking
213
- };
214
- this.store.bookings.push(normalized);
215
- const rid = normalized.resource_id ?? normalized.resourceId;
216
- if (rid !== void 0) {
217
- const existing = this.resourceIdIndex.get(rid) || [];
218
- existing.push(normalized);
219
- this.resourceIdIndex.set(rid, existing);
220
- }
221
- this.saveBookingsToSQLite(this.store.bookings).catch(() => {
222
- });
223
- this.safeEmit(import_types.ResourceHooks.onBookingsChanged, this.store.bookings);
224
- return normalized;
225
- }
202
+ // createBooking(booking: Partial<ResourceBooking>): ResourceBooking {
203
+ // const id = booking?.id ?? Date.now()
204
+ // const normalized: ResourceBooking = {
205
+ // id,
206
+ // ...booking,
207
+ // } as ResourceBooking
208
+ // this.store.bookings.push(normalized)
209
+ // const rid = normalized.resource_id ?? normalized.resourceId
210
+ // if (rid !== undefined) {
211
+ // const existing = this.resourceIdIndex.get(rid) || []
212
+ // existing.push(normalized)
213
+ // this.resourceIdIndex.set(rid, existing)
214
+ // }
215
+ // this.saveBookingsToSQLite(this.store.bookings).catch(() => {})
216
+ // this.safeEmit(ResourceHooks.onBookingsChanged, this.store.bookings)
217
+ // return normalized
218
+ // }
226
219
  /**
227
220
  * 更新预订
228
221
  */
229
- updateBooking(id, data) {
230
- const index = this.store.bookings.findIndex((b) => this.getIdKey(b.id) === this.getIdKey(id));
231
- if (index === -1)
232
- return void 0;
233
- const old = this.store.bookings[index];
234
- const updated = { ...old, ...data, id: old.id };
235
- this.store.bookings[index] = updated;
236
- this.rebuildBookingsIndex();
237
- this.saveBookingsToSQLite(this.store.bookings).catch(() => {
238
- });
239
- this.safeEmit(import_types.ResourceHooks.onBookingsChanged, this.store.bookings);
240
- return updated;
241
- }
222
+ // updateBooking(id: ResourceId, data: Partial<ResourceBooking>): ResourceBooking | undefined {
223
+ // const index = this.store.bookings.findIndex(b => this.getIdKey(b.id) === this.getIdKey(id))
224
+ // if (index === -1) return undefined
225
+ // const old = this.store.bookings[index]
226
+ // const updated: ResourceBooking = { ...old, ...data, id: old.id } as ResourceBooking
227
+ // this.store.bookings[index] = updated
228
+ // this.rebuildBookingsIndex()
229
+ // this.saveBookingsToSQLite(this.store.bookings).catch(() => {})
230
+ // this.safeEmit(ResourceHooks.onBookingsChanged, this.store.bookings)
231
+ // return updated
232
+ // }
242
233
  /**
243
234
  * 删除预订
244
235
  */
245
- deleteBooking(id) {
246
- const index = this.store.bookings.findIndex((b) => this.getIdKey(b.id) === this.getIdKey(id));
247
- if (index === -1)
248
- return false;
249
- this.store.bookings.splice(index, 1);
250
- this.rebuildBookingsIndex();
251
- this.saveBookingsToSQLite(this.store.bookings).catch(() => {
252
- });
253
- this.safeEmit(import_types.ResourceHooks.onBookingsChanged, this.store.bookings);
254
- return true;
255
- }
236
+ // deleteBooking(id: ResourceId): boolean {
237
+ // const index = this.store.bookings.findIndex(b => this.getIdKey(b.id) === this.getIdKey(id))
238
+ // if (index === -1) return false
239
+ // this.store.bookings.splice(index, 1)
240
+ // this.rebuildBookingsIndex()
241
+ // this.saveBookingsToSQLite(this.store.bookings).catch(() => {})
242
+ // this.safeEmit(ResourceHooks.onBookingsChanged, this.store.bookings)
243
+ // return true
244
+ // }
256
245
  /**
257
246
  * 清空缓存
258
247
  */
@@ -396,31 +385,29 @@ var ResourceModule = class extends import_BaseModule.BaseModule {
396
385
  });
397
386
  }
398
387
  }
399
- async loadBookingsFromSQLite() {
400
- if (!this.dbManager)
401
- return [];
402
- try {
403
- const bookings = await this.dbManager.getAll(BOOKING_STORE_NAME);
404
- return bookings || [];
405
- } catch {
406
- return [];
407
- }
408
- }
409
- async saveBookingsToSQLite(bookings) {
410
- if (!this.dbManager)
411
- return;
412
- try {
413
- await this.dbManager.clear(BOOKING_STORE_NAME);
414
- if (bookings.length === 0)
415
- return;
416
- if (this.dbManager.bulkAdd) {
417
- await this.dbManager.bulkAdd(BOOKING_STORE_NAME, bookings);
418
- return;
419
- }
420
- await Promise.all(bookings.map((b) => this.dbManager.add(BOOKING_STORE_NAME, b)));
421
- } catch {
422
- }
423
- }
388
+ // private async loadBookingsFromSQLite(): Promise<ResourceBooking[]> {
389
+ // if (!this.dbManager) return []
390
+ // try {
391
+ // const bookings = await this.dbManager.getAll(BOOKING_STORE_NAME)
392
+ // return bookings || []
393
+ // } catch {
394
+ // return []
395
+ // }
396
+ // }
397
+ // private async saveBookingsToSQLite(bookings: ResourceBooking[]): Promise<void> {
398
+ // if (!this.dbManager) return
399
+ // try {
400
+ // await this.dbManager.clear(BOOKING_STORE_NAME)
401
+ // if (bookings.length === 0) return
402
+ // if (this.dbManager.bulkAdd) {
403
+ // await this.dbManager.bulkAdd(BOOKING_STORE_NAME, bookings)
404
+ // return
405
+ // }
406
+ // await Promise.all(bookings.map(b => this.dbManager.add(BOOKING_STORE_NAME, b)))
407
+ // } catch {
408
+ // // 忽略 SQLite 异常
409
+ // }
410
+ // }
424
411
  // ─────────────────────────────────────────────────────────────────
425
412
  // pubsub 同步
426
413
  // ─────────────────────────────────────────────────────────────────
@@ -25,6 +25,8 @@ export type RouteHandler = (params: {
25
25
  method: 'get' | 'post' | 'remove' | 'put';
26
26
  data?: any;
27
27
  config?: RequestSetting;
28
+ /** 路由路径(前缀匹配时由 handleRoute 注入,便于 handler 解析动态段) */
29
+ path?: string;
28
30
  }) => Promise<any> | any;
29
31
  /**
30
32
  * HTTP 方法类型
@@ -344,7 +344,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
344
344
  };
345
345
  setOtherData(key: string, value: any): void;
346
346
  getOtherData(key: string): any;
347
- getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
347
+ getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
348
348
  /**
349
349
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
350
350
  *
@@ -87,10 +87,11 @@ export declare class SalesImpl extends BaseModule implements Module, SalesModule
87
87
  /**
88
88
  * 标准化单条 booking:
89
89
  * - 过滤终态(rejected/cancelled/completed)
90
+ * - 当 deviceTime 早于 currentTime 时,过滤 end_time 早于 currentTime 的历史数据
90
91
  * - 注入 status / isTimeout / reserved_status
91
92
  */
92
93
  private normalizeMatchedBooking;
93
- getResourceBookingList(currentTime: string, bookingList?: BookingData[]): Promise<SalesResourceBookingItem[]>;
94
+ getResourceBookingList(currentTime: string, bookingList?: BookingData[], deviceTime?: string): Promise<SalesResourceBookingItem[]>;
94
95
  }
95
96
  export { SalesImpl as Sales };
96
97
  export default SalesImpl;
@@ -312,15 +312,19 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
312
312
  /**
313
313
  * 标准化单条 booking:
314
314
  * - 过滤终态(rejected/cancelled/completed)
315
+ * - 当 deviceTime 早于 currentTime 时,过滤 end_time 早于 currentTime 的历史数据
315
316
  * - 注入 status / isTimeout / reserved_status
316
317
  */
317
- normalizeMatchedBooking(current, booking) {
318
+ normalizeMatchedBooking(current, deviceCurrent, booking) {
318
319
  const appointmentStatus = String(booking.appointment_status ?? booking.status ?? "");
319
320
  if (appointmentStatus === "rejected" || appointmentStatus === "cancelled" || appointmentStatus === "completed") {
320
321
  return null;
321
322
  }
322
- const bookingStatus = this.getBookingStatus(appointmentStatus);
323
323
  const endAt = this.toBookingDateTime(booking.end_date, booking.end_time);
324
+ const shouldFilterHistoryByCurrent = deviceCurrent.isBefore(current);
325
+ if (shouldFilterHistoryByCurrent && endAt.isValid() && endAt.isBefore(current))
326
+ return null;
327
+ const bookingStatus = this.getBookingStatus(appointmentStatus);
324
328
  const startAt = this.toBookingDateTime(booking.start_date, booking.start_time);
325
329
  const isTimeout = bookingStatus === "occupied" && endAt.isValid() && current.isAfter(endAt);
326
330
  const timeoutTime = isTimeout ? current.diff(endAt, "minute") : void 0;
@@ -362,11 +366,14 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
362
366
  remainingReserveTime
363
367
  };
364
368
  }
365
- async getResourceBookingList(currentTime, bookingList = []) {
369
+ async getResourceBookingList(currentTime, bookingList = [], deviceTime = currentTime) {
366
370
  var _a;
367
371
  const current = (0, import_dayjs.default)(currentTime);
368
372
  if (!current.isValid())
369
373
  return [];
374
+ const deviceCurrent = (0, import_dayjs.default)(deviceTime);
375
+ if (!deviceCurrent.isValid())
376
+ return [];
370
377
  const resourceResponse = await this.request.get(
371
378
  "/shop/form/resource/page",
372
379
  { skip: 1, num: 999 },
@@ -376,7 +383,7 @@ var SalesImpl = class extends import_BaseModule.BaseModule {
376
383
  const resourceList = ((_a = resourceResponse == null ? void 0 : resourceResponse.data) == null ? void 0 : _a.list) ?? [];
377
384
  if (!Array.isArray(resourceList) || resourceList.length === 0)
378
385
  return [];
379
- const normalizedBookings = bookingList.map((booking) => this.normalizeMatchedBooking(current, booking)).filter((booking) => Boolean(booking)).sort((left, right) => {
386
+ const normalizedBookings = bookingList.map((booking) => this.normalizeMatchedBooking(current, deviceCurrent, booking)).filter((booking) => Boolean(booking)).sort((left, right) => {
380
387
  const leftStartAt = this.toBookingDateTime(left.start_date, left.start_time).valueOf();
381
388
  const rightStartAt = this.toBookingDateTime(right.start_date, right.start_time).valueOf();
382
389
  return leftStartAt - rightStartAt;
@@ -61,7 +61,7 @@ export interface SalesModuleAPI {
61
61
  /** 重置预约列表为空 */
62
62
  resetReservationList: () => Reservation[];
63
63
  /** 获取资源维度的预约占用列表 */
64
- getResourceBookingList: (currentTime: string, bookingList: BookingData[]) => Promise<SalesResourceBookingItem[]>;
64
+ getResourceBookingList: (currentTime: string, bookingList: BookingData[], deviceTime?: string) => Promise<SalesResourceBookingItem[]>;
65
65
  /** 获取时间轴每个时间片的预约数量 */
66
66
  getTimelineHighlights: (bookingList: BookingData[], startDateTime?: string, endDateTime?: string) => SalesTimelineHighlights;
67
67
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.97",
4
+ "version": "2.2.99",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",