@pisell/pisellos 0.10.28 → 0.10.30

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 (85) hide show
  1. package/dist/core/index.d.ts +7 -0
  2. package/dist/core/index.js +108 -65
  3. package/dist/model/strategy/adapter/dataVariant/evaluator.js +13 -2
  4. package/dist/model/strategy/adapter/promotion/index.js +0 -9
  5. package/dist/modules/Discount/index.js +4 -1
  6. package/dist/modules/Discount/types.d.ts +14 -4
  7. package/dist/modules/Order/index.d.ts +3 -1
  8. package/dist/modules/Order/index.js +89 -16
  9. package/dist/modules/Order/types.d.ts +13 -0
  10. package/dist/modules/Order/utils.d.ts +17 -2
  11. package/dist/modules/Order/utils.js +133 -27
  12. package/dist/modules/Quotation/index.d.ts +6 -0
  13. package/dist/modules/Quotation/index.js +77 -25
  14. package/dist/modules/ResourcePlanner/planner.js +14 -4
  15. package/dist/modules/ResourcePlanner/types.d.ts +2 -0
  16. package/dist/plugins/request.d.ts +1 -0
  17. package/dist/server/index.d.ts +13 -2
  18. package/dist/server/index.js +1531 -1230
  19. package/dist/server/modules/floor-plan/index.d.ts +4 -0
  20. package/dist/server/modules/floor-plan/index.js +240 -98
  21. package/dist/server/modules/menu/index.js +48 -23
  22. package/dist/server/modules/order/index.d.ts +17 -7
  23. package/dist/server/modules/order/index.js +419 -207
  24. package/dist/server/modules/order/types.d.ts +50 -0
  25. package/dist/server/modules/order/types.js +2 -0
  26. package/dist/server/modules/products/index.d.ts +10 -4
  27. package/dist/server/modules/products/index.js +177 -84
  28. package/dist/server/modules/resource/index.js +21 -13
  29. package/dist/server/utils/product.d.ts +1 -1
  30. package/dist/server/utils/product.js +186 -22
  31. package/dist/server/utils/small-ticket.d.ts +4 -1
  32. package/dist/server/utils/small-ticket.js +543 -101
  33. package/dist/solution/BaseSales/index.d.ts +3 -3
  34. package/dist/solution/BaseSales/index.js +171 -198
  35. package/dist/solution/BaseSales/utils/parseSalesResponse.d.ts +2 -0
  36. package/dist/solution/BaseSales/utils/parseSalesResponse.js +1 -1
  37. package/dist/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  38. package/dist/solution/BookingByStep/index.d.ts +2 -2
  39. package/dist/solution/Sales/index.d.ts +7 -0
  40. package/dist/solution/Sales/index.js +87 -31
  41. package/dist/solution/UnifiedBookingSales/index.d.ts +2 -2
  42. package/dist/solution/UnifiedBookingSales/index.js +38 -21
  43. package/lib/core/index.d.ts +7 -0
  44. package/lib/core/index.js +20 -2
  45. package/lib/model/strategy/adapter/dataVariant/evaluator.js +12 -2
  46. package/lib/model/strategy/adapter/promotion/index.js +46 -1
  47. package/lib/modules/Discount/index.js +4 -1
  48. package/lib/modules/Discount/types.d.ts +14 -4
  49. package/lib/modules/Order/index.d.ts +3 -1
  50. package/lib/modules/Order/index.js +69 -1
  51. package/lib/modules/Order/types.d.ts +13 -0
  52. package/lib/modules/Order/utils.d.ts +17 -2
  53. package/lib/modules/Order/utils.js +131 -18
  54. package/lib/modules/Quotation/index.d.ts +6 -0
  55. package/lib/modules/Quotation/index.js +52 -8
  56. package/lib/modules/ResourcePlanner/planner.js +9 -1
  57. package/lib/modules/ResourcePlanner/types.d.ts +2 -0
  58. package/lib/plugins/request.d.ts +1 -0
  59. package/lib/server/index.d.ts +13 -2
  60. package/lib/server/index.js +210 -19
  61. package/lib/server/modules/floor-plan/index.d.ts +4 -0
  62. package/lib/server/modules/floor-plan/index.js +60 -7
  63. package/lib/server/modules/menu/index.js +26 -4
  64. package/lib/server/modules/order/index.d.ts +17 -7
  65. package/lib/server/modules/order/index.js +194 -57
  66. package/lib/server/modules/order/types.d.ts +50 -0
  67. package/lib/server/modules/order/types.js +1 -0
  68. package/lib/server/modules/products/index.d.ts +10 -4
  69. package/lib/server/modules/products/index.js +93 -23
  70. package/lib/server/modules/resource/index.js +12 -2
  71. package/lib/server/utils/product.d.ts +1 -1
  72. package/lib/server/utils/product.js +163 -3
  73. package/lib/server/utils/small-ticket.d.ts +4 -1
  74. package/lib/server/utils/small-ticket.js +507 -75
  75. package/lib/solution/BaseSales/index.d.ts +3 -3
  76. package/lib/solution/BaseSales/index.js +9 -14
  77. package/lib/solution/BaseSales/utils/parseSalesResponse.d.ts +2 -0
  78. package/lib/solution/BaseSales/utils/parseSalesResponse.js +1 -1
  79. package/lib/solution/BaseSales/utils/transformBaseProductToOrderProduct.js +3 -2
  80. package/lib/solution/BookingByStep/index.d.ts +2 -2
  81. package/lib/solution/Sales/index.d.ts +7 -0
  82. package/lib/solution/Sales/index.js +48 -3
  83. package/lib/solution/UnifiedBookingSales/index.d.ts +2 -2
  84. package/lib/solution/UnifiedBookingSales/index.js +19 -3
  85. package/package.json +1 -1
@@ -40,6 +40,8 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
40
40
  list: []
41
41
  });
42
42
  _defineProperty(_assertThisInitialized(_this), "scheduleResolver", void 0);
43
+ _defineProperty(_assertThisInitialized(_this), "app", void 0);
44
+ _defineProperty(_assertThisInitialized(_this), "quotationListUpdatedListener", void 0);
43
45
  _defineProperty(_assertThisInitialized(_this), "quotationCache", new Map());
44
46
  _defineProperty(_assertThisInitialized(_this), "quotationLoadPromises", new Map());
45
47
  _defineProperty(_assertThisInitialized(_this), "quotationCacheVersions", new Map());
@@ -51,6 +53,7 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
51
53
  key: "initialize",
52
54
  value: function () {
53
55
  var _initialize = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(core, options) {
56
+ var _core$getPlugin, _core$getPlugin$getAp;
54
57
  return _regeneratorRuntime().wrap(function _callee$(_context) {
55
58
  while (1) switch (_context.prev = _context.next) {
56
59
  case 0:
@@ -62,6 +65,7 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
62
65
  }
63
66
  throw new Error('QuotationModule 需要 request 插件支持');
64
67
  case 4:
68
+ this.app = (_core$getPlugin = core.getPlugin('app')) === null || _core$getPlugin === void 0 || (_core$getPlugin$getAp = _core$getPlugin.getApp) === null || _core$getPlugin$getAp === void 0 ? void 0 : _core$getPlugin$getAp.call(_core$getPlugin);
65
69
  this.store = {
66
70
  list: []
67
71
  };
@@ -70,7 +74,7 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
70
74
  this.quotationCacheVersions.clear();
71
75
  this.activeChannelKey = '';
72
76
  this.lifecycleGeneration += 1;
73
- case 10:
77
+ case 11:
74
78
  case "end":
75
79
  return _context.stop();
76
80
  }
@@ -254,32 +258,34 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
254
258
  key: "fetchQuotations",
255
259
  value: function () {
256
260
  var _fetchQuotations = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(params) {
257
- var _data;
258
- var query, res, list;
261
+ var _this3 = this;
262
+ var query, initialResultApplied, applyRemoteUpdate, res;
259
263
  return _regeneratorRuntime().wrap(function _callee4$(_context4) {
260
264
  while (1) switch (_context4.prev = _context4.next) {
261
265
  case 0:
262
266
  query = {};
263
267
  if (params.channelKey) query.channel = params.channelKey;
264
- _context4.next = 4;
268
+ initialResultApplied = false;
269
+ applyRemoteUpdate = function applyRemoteUpdate(response) {
270
+ var applied = _this3.applyQuotationResponse(response, params);
271
+ if (applied && initialResultApplied && _this3.activeChannelKey === params.channelKey) {
272
+ _this3.notifyQuotationListUpdated();
273
+ }
274
+ };
275
+ _context4.next = 6;
265
276
  return this.request.get('/quotation/available', query, {
266
- useCache: false,
267
- osServer: true
277
+ cache: {
278
+ type: 'indexDB',
279
+ updateCache: true,
280
+ cacheKeyData: this.getQuotationCacheKeyData(query)
281
+ },
282
+ cacheUpdateChange: applyRemoteUpdate
268
283
  });
269
- case 4:
284
+ case 6:
270
285
  res = _context4.sent;
271
- list = _toConsumableArray((res === null || res === void 0 || (_data = res.data) === null || _data === void 0 ? void 0 : _data.list) || (res === null || res === void 0 ? void 0 : res.list) || []).sort(function (a, b) {
272
- return b.sort - a.sort;
273
- });
274
- if (!(this.lifecycleGeneration !== params.lifecycleGeneration || this.getQuotationCacheVersion(params.channelKey) !== params.cacheVersion)) {
275
- _context4.next = 8;
276
- break;
277
- }
278
- return _context4.abrupt("return");
279
- case 8:
280
- this.quotationCache.set(params.channelKey, list);
281
- if (this.activeChannelKey === params.channelKey) this.store.list = list;
282
- case 10:
286
+ this.applyQuotationResponse(res, params);
287
+ initialResultApplied = true;
288
+ case 9:
283
289
  case "end":
284
290
  return _context4.stop();
285
291
  }
@@ -295,10 +301,15 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
295
301
  value: function getQuotationList() {
296
302
  return this.store.list;
297
303
  }
304
+ }, {
305
+ key: "setQuotationListUpdatedListener",
306
+ value: function setQuotationListUpdatedListener(listener) {
307
+ this.quotationListUpdatedListener = listener;
308
+ }
298
309
  }, {
299
310
  key: "getQuotationCustomerScopeInfo",
300
311
  value: function getQuotationCustomerScopeInfo() {
301
- var _this3 = this;
312
+ var _this4 = this;
302
313
  var customerById = new Map();
303
314
  var quotationScopes = this.store.list.filter(function (quotation) {
304
315
  return Array.isArray(quotation.customer) && quotation.customer.length > 0;
@@ -308,7 +319,7 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
308
319
  var localSeen = new Set();
309
320
  var quotationCustomers = quotation.customer || [];
310
321
  quotationCustomers.forEach(function (customer) {
311
- var customerId = _this3.normalizeCustomerId(customer === null || customer === void 0 ? void 0 : customer.id);
322
+ var customerId = _this4.normalizeCustomerId(customer === null || customer === void 0 ? void 0 : customer.id);
312
323
  if (!customerId || localSeen.has(customerId)) return;
313
324
  localSeen.add(customerId);
314
325
  customerIds.push(customerId);
@@ -436,6 +447,47 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
436
447
  value: function setScheduleResolver(resolver) {
437
448
  this.scheduleResolver = resolver;
438
449
  }
450
+ }, {
451
+ key: "applyQuotationResponse",
452
+ value: function applyQuotationResponse(response, params) {
453
+ var _data;
454
+ var source = (response === null || response === void 0 || (_data = response.data) === null || _data === void 0 ? void 0 : _data.list) || (response === null || response === void 0 ? void 0 : response.list) || [];
455
+ var list = _toConsumableArray(source).sort(function (a, b) {
456
+ return Number(b.sort || 0) - Number(a.sort || 0);
457
+ });
458
+ if (this.lifecycleGeneration !== params.lifecycleGeneration || this.getQuotationCacheVersion(params.channelKey) !== params.cacheVersion) {
459
+ return false;
460
+ }
461
+ this.quotationCache.set(params.channelKey, list);
462
+ if (this.activeChannelKey === params.channelKey) this.store.list = list;
463
+ return true;
464
+ }
465
+ }, {
466
+ key: "notifyQuotationListUpdated",
467
+ value: function notifyQuotationListUpdated() {
468
+ try {
469
+ var _this$quotationListUp;
470
+ (_this$quotationListUp = this.quotationListUpdatedListener) === null || _this$quotationListUp === void 0 || _this$quotationListUp.call(this);
471
+ } catch (error) {
472
+ console.warn('[QuotationModule] 报价单后台更新回调失败', error);
473
+ }
474
+ }
475
+ }, {
476
+ key: "getQuotationCacheKeyData",
477
+ value: function getQuotationCacheKeyData(query) {
478
+ var shopId = '';
479
+ try {
480
+ var _this$app, _this$app$getStorage;
481
+ var storedCore = (_this$app = this.app) === null || _this$app === void 0 || (_this$app = _this$app.storage) === null || _this$app === void 0 || (_this$app$getStorage = _this$app.getStorage) === null || _this$app$getStorage === void 0 ? void 0 : _this$app$getStorage.call(_this$app, 'core');
482
+ var coreInfo = typeof storedCore === 'string' ? JSON.parse(storedCore || '{}') : storedCore || {};
483
+ shopId = String((coreInfo === null || coreInfo === void 0 ? void 0 : coreInfo.id) || '');
484
+ } catch (_unused) {
485
+ // 缓存隔离信息读取失败时仍按请求参数缓存。
486
+ }
487
+ return _objectSpread(_objectSpread({}, query), {}, {
488
+ shop_id: shopId
489
+ });
490
+ }
439
491
  }, {
440
492
  key: "normalizeChannel",
441
493
  value: function normalizeChannel(channel) {
@@ -486,17 +538,17 @@ export var QuotationModule = /*#__PURE__*/function (_BaseModule) {
486
538
  key: "isQuotationActiveAt",
487
539
  value: function isQuotationActiveAt(quotation, datetime) {
488
540
  var _quotation$schedule,
489
- _this4 = this;
541
+ _this5 = this;
490
542
  if (!((_quotation$schedule = quotation.schedule) !== null && _quotation$schedule !== void 0 && _quotation$schedule.length)) return false;
491
543
  var scheduleItems = [];
492
544
  quotation.schedule.forEach(function (s) {
493
- var _this4$scheduleResolv;
494
- var full = (_this4$scheduleResolv = _this4.scheduleResolver) === null || _this4$scheduleResolv === void 0 ? void 0 : _this4$scheduleResolv.call(_this4, s.id);
545
+ var _this5$scheduleResolv;
546
+ var full = (_this5$scheduleResolv = _this5.scheduleResolver) === null || _this5$scheduleResolv === void 0 ? void 0 : _this5$scheduleResolv.call(_this5, s.id);
495
547
  if (full) {
496
548
  scheduleItems.push(full);
497
549
  return;
498
550
  }
499
- if (_this4.scheduleResolver) {
551
+ if (_this5.scheduleResolver) {
500
552
  return;
501
553
  }
502
554
  var fallbackSchedule = _objectSpread(_objectSpread({}, s), {}, {
@@ -220,7 +220,11 @@ function evaluateCandidateTimeGate(params) {
220
220
  };
221
221
  }
222
222
  if (policy.type === 'before_start') {
223
- if (now < candidateRange.start) return null;
223
+ // Flexible-duration candidates start at minute precision. Keep the current
224
+ // minute selectable instead of treating the freshly generated candidate as
225
+ // already started because the query clock still contains seconds.
226
+ var hasNotReachedStart = product.isFlexibleDuration ? floorToMinute(now) <= candidateRange.start : now < candidateRange.start;
227
+ if (hasNotReachedStart) return null;
224
228
  return {
225
229
  status: 'unavailable',
226
230
  reasonCodes: ['booking_cutoff_before_start'],
@@ -1056,6 +1060,9 @@ export function getProductTimeRanges(projection) {
1056
1060
  return group.required !== false;
1057
1061
  });
1058
1062
  var operatingRanges = buildOperatingRanges(projection, dateRange);
1063
+ var operatingEndAt = dateRange.startDate === dateRange.endDate && operatingRanges.length > 0 ? formatDateTime(Math.max.apply(Math, _toConsumableArray(operatingRanges.map(function (range) {
1064
+ return range.end;
1065
+ }))), projection.meta.timezone, fixedOffsetMinutes) : undefined;
1059
1066
  var resourceRanges = requiredGroups.length ? requiredGroups.map(function (group) {
1060
1067
  return buildGroupWorkingRanges({
1061
1068
  projection: projection,
@@ -1123,13 +1130,16 @@ export function getProductTimeRanges(projection) {
1123
1130
  ranges.push(createDurationTimeRange(product, start, durationMinutes, projection, fixedOffsetMinutes));
1124
1131
  });
1125
1132
  }
1126
- return {
1133
+ return _objectSpread(_objectSpread({
1127
1134
  productId: product.id,
1128
1135
  title: product.title,
1129
1136
  kind: product.kind,
1130
- slotStepMinutes: slotStepMinutes,
1137
+ slotStepMinutes: slotStepMinutes
1138
+ }, operatingEndAt ? {
1139
+ operatingEndAt: operatingEndAt
1140
+ } : {}), {}, {
1131
1141
  ranges: dedupeProductRanges(ranges)
1132
- };
1142
+ });
1133
1143
  });
1134
1144
  }
1135
1145
  function aggregateMatchedCells(productId, requirementGroupId, resourceId, candidateRange, indexedCells) {
@@ -213,6 +213,8 @@ export interface ProductTimeRangeGroup {
213
213
  title?: string;
214
214
  kind: AvailabilityProductKind;
215
215
  slotStepMinutes?: number;
216
+ /** 单日查询对应营业窗口的最终结束时刻,不受资源排班是否为空影响。 */
217
+ operatingEndAt?: string;
216
218
  ranges: ProductTimeRange[];
217
219
  }
218
220
  export interface AvailabilityAssignment extends AvailabilityAbsoluteRange {
@@ -68,6 +68,7 @@ export interface RequestOptions {
68
68
  useCache?: boolean;
69
69
  customToast?: () => void;
70
70
  cache?: CacheProps;
71
+ cacheUpdateChange?: (data: any) => void;
71
72
  osServer?: boolean;
72
73
  isNocobase?: boolean;
73
74
  prefix?: boolean;
@@ -51,6 +51,8 @@ declare class Server {
51
51
  private productQueryScheduleTimers;
52
52
  /** 餐牌筛选为空时才触发的菜单/日程缓存自愈,避免每次商品查询都请求远端。 */
53
53
  private menuScheduleRefreshInFlight;
54
+ /** 启动阶段模块预加载任务;预渲染商品查询复用该任务,避免缓存尚未 ready 时误触发远端自愈。 */
55
+ private startupModulePreloadInFlight;
54
56
  private lastMenuScheduleRefreshAt;
55
57
  private readonly MENU_SCHEDULE_REFRESH_COOLDOWN_MS;
56
58
  private orderQuerySubscribers;
@@ -126,6 +128,9 @@ declare class Server {
126
128
  private runCheckoutSync;
127
129
  private omitCheckoutSyncMode;
128
130
  private buildRemoteCheckoutData;
131
+ private buildCheckoutDeviceHeaders;
132
+ private applyKioskCheckoutOperator;
133
+ private resolveKioskCheckoutOperatorId;
129
134
  private mergeCheckoutSyncPayments;
130
135
  private persistSyncedCheckoutOrder;
131
136
  /**
@@ -157,13 +162,17 @@ declare class Server {
157
162
  * 重新拉取全量 SSE 接口,更新本地数据后触发 onProductsSyncCompleted
158
163
  * 不影响当前界面展示,适用于切回前台、定时刷新等场景
159
164
  */
160
- refreshProductsInBackground(): Promise<void>;
165
+ refreshProductsInBackground(options?: {
166
+ trigger?: string;
167
+ }): Promise<void>;
161
168
  /**
162
169
  * 后台静默刷新订单数据
163
170
  * 重新拉取全量 SSE 接口,更新本地数据后触发 onOrdersSyncCompleted
164
171
  * 不影响当前界面展示,适用于切回前台、定时刷新等场景
165
172
  */
166
- refreshOrdersInBackground(): Promise<void>;
173
+ refreshOrdersInBackground(options?: {
174
+ trigger?: string;
175
+ }): Promise<void>;
167
176
  /**
168
177
  * 编辑正式订单时强制查询 Server 最新快照并覆盖本地缓存。
169
178
  * 商品成员增删由 OrderModule 在 SQLite/Store 更新完成后广播,
@@ -524,6 +533,8 @@ declare class Server {
524
533
  private getLocalPrintOrderLookup;
525
534
  private mergeLocalPrintOrderInput;
526
535
  private handleLocalPrintOrder;
536
+ private normalizeRequestedReceiptLocales;
537
+ private handleLocalOrderReceiptSnapshot;
527
538
  private handleMachinecodeBatchMeta;
528
539
  private resolveMachinecodeBatchMetadataLookup;
529
540
  private syncMachinecodeRedeemStatusToLocalOrder;