@pisell/pisellos 2.1.124 → 2.1.126

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 (29) hide show
  1. package/dist/model/strategy/adapter/itemRule/adapter.d.ts +8 -0
  2. package/dist/model/strategy/adapter/itemRule/adapter.js +46 -6
  3. package/dist/model/strategy/adapter/itemRule/type.d.ts +11 -1
  4. package/dist/model/strategy/adapter/promotion/index.js +9 -0
  5. package/dist/modules/Order/index.js +2 -2
  6. package/dist/modules/Schedule/utils.d.ts +1 -1
  7. package/dist/solution/BookingByStep/index.d.ts +2 -2
  8. package/dist/solution/ScanOrder/index.js +36 -12
  9. package/dist/solution/ScanOrder/utils.d.ts +1 -0
  10. package/dist/solution/ScanOrder/utils.js +5 -0
  11. package/dist/solution/VenueBooking/index.d.ts +4 -0
  12. package/dist/solution/VenueBooking/index.js +193 -106
  13. package/dist/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  14. package/dist/solution/VenueBooking/utils/dateSummary.js +6 -4
  15. package/lib/model/strategy/adapter/itemRule/adapter.d.ts +8 -0
  16. package/lib/model/strategy/adapter/itemRule/adapter.js +31 -0
  17. package/lib/model/strategy/adapter/itemRule/type.d.ts +11 -1
  18. package/lib/model/strategy/adapter/promotion/index.js +49 -0
  19. package/lib/modules/Order/index.js +2 -2
  20. package/lib/modules/Schedule/utils.d.ts +1 -1
  21. package/lib/solution/BookingByStep/index.d.ts +2 -2
  22. package/lib/solution/ScanOrder/index.js +22 -3
  23. package/lib/solution/ScanOrder/utils.d.ts +1 -0
  24. package/lib/solution/ScanOrder/utils.js +5 -0
  25. package/lib/solution/VenueBooking/index.d.ts +4 -0
  26. package/lib/solution/VenueBooking/index.js +79 -10
  27. package/lib/solution/VenueBooking/utils/dateSummary.d.ts +1 -0
  28. package/lib/solution/VenueBooking/utils/dateSummary.js +13 -4
  29. package/package.json +1 -1
@@ -50,6 +50,14 @@ export declare class ItemRuleAdapter implements BusinessAdapter {
50
50
  * 不适用或无配置时返回 null。
51
51
  */
52
52
  extractQuantityLimits(action: ActionEffect, businessData: ItemRuleBusinessData): QuantityLimitResult | null;
53
+ /**
54
+ * 计算当前提交剩余可选的最大数量。
55
+ *
56
+ * 仅在 scope='cumulative' 且存在 requiredMax 时生效:
57
+ * 用 requiredMax 减去 historicalItems 中目标商品的累计数量,保底 0。
58
+ * 其余场景返回 undefined,保持向后兼容。
59
+ */
60
+ private calculateRemainingMax;
53
61
  private processPrefillCart;
54
62
  /**
55
63
  * 根据 quantityFrom 计算预填数量
@@ -373,18 +373,58 @@ export var ItemRuleAdapter = /*#__PURE__*/function () {
373
373
  } finally {
374
374
  _iterator4.f();
375
375
  }
376
+ var remainingMax = this.calculateRemainingMax(scope, requiredMax, targets, businessData);
376
377
  return {
377
378
  ruleId: action.id,
378
379
  targetType: targetType,
379
380
  targets: targets,
380
381
  requiredMin: requiredMin,
381
382
  requiredMax: requiredMax,
383
+ remainingMax: remainingMax,
382
384
  requiredExact: requiredExact,
383
385
  mustInclude: mustInclude,
384
386
  scope: scope
385
387
  };
386
388
  }
387
389
 
390
+ /**
391
+ * 计算当前提交剩余可选的最大数量。
392
+ *
393
+ * 仅在 scope='cumulative' 且存在 requiredMax 时生效:
394
+ * 用 requiredMax 减去 historicalItems 中目标商品的累计数量,保底 0。
395
+ * 其余场景返回 undefined,保持向后兼容。
396
+ */
397
+ }, {
398
+ key: "calculateRemainingMax",
399
+ value: function calculateRemainingMax(scope, requiredMax, targets, businessData) {
400
+ if (scope !== 'cumulative' || typeof requiredMax !== 'number') {
401
+ return undefined;
402
+ }
403
+ var historicalItems = businessData.historicalItems;
404
+ if (!(historicalItems !== null && historicalItems !== void 0 && historicalItems.length)) {
405
+ return Math.max(0, requiredMax);
406
+ }
407
+ var targetIds = new Set(targets.map(function (t) {
408
+ return t.product_id;
409
+ }));
410
+ var historicalQty = 0;
411
+ var _iterator5 = _createForOfIteratorHelper(historicalItems),
412
+ _step5;
413
+ try {
414
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
415
+ var item = _step5.value;
416
+ if (targetIds.has(item.product_id)) {
417
+ historicalQty += item.quantity;
418
+ }
419
+ }
420
+ } catch (err) {
421
+ _iterator5.e(err);
422
+ } finally {
423
+ _iterator5.f();
424
+ }
425
+ return Math.max(0, requiredMax - historicalQty);
426
+ }
427
+
388
428
  // ============================================
389
429
  // Prefill Cart 处理
390
430
  // ============================================
@@ -394,11 +434,11 @@ export var ItemRuleAdapter = /*#__PURE__*/function () {
394
434
  var config = action.config;
395
435
  if (!(config !== null && config !== void 0 && config.products)) return [];
396
436
  var results = [];
397
- var _iterator5 = _createForOfIteratorHelper(config.products),
398
- _step5;
437
+ var _iterator6 = _createForOfIteratorHelper(config.products),
438
+ _step6;
399
439
  try {
400
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
401
- var prefillProduct = _step5.value;
440
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
441
+ var prefillProduct = _step6.value;
402
442
  var quantity = this.resolvePrefillQuantity(prefillProduct.quantityFrom, prefillProduct.quantity, businessData);
403
443
  if (quantity <= 0) continue;
404
444
  results.push({
@@ -409,9 +449,9 @@ export var ItemRuleAdapter = /*#__PURE__*/function () {
409
449
  });
410
450
  }
411
451
  } catch (err) {
412
- _iterator5.e(err);
452
+ _iterator6.e(err);
413
453
  } finally {
414
- _iterator5.f();
454
+ _iterator6.f();
415
455
  }
416
456
  return results;
417
457
  }
@@ -180,8 +180,18 @@ export interface QuantityLimitResult {
180
180
  targets: TargetItem[];
181
181
  /** 要求的最小数量 */
182
182
  requiredMin?: number;
183
- /** 要求的最大数量 */
183
+ /** 要求的最大数量(规则配置的原始上限,用于 UI 文案展示) */
184
184
  requiredMax?: number;
185
+ /**
186
+ * 当前提交剩余可选的最大数量。
187
+ *
188
+ * 仅在 scope='cumulative' 且存在 requiredMax 时计算:
189
+ * remainingMax = max(0, requiredMax - historicalItems 中目标商品累计数量)
190
+ *
191
+ * 非 cumulative 场景不设置此字段;调用方用于限制加购上限时,
192
+ * 应优先读取本字段,未定义时回退到 requiredMax。
193
+ */
194
+ remainingMax?: number;
185
195
  /** 要求的精确数量 */
186
196
  requiredExact?: number;
187
197
  /** 是否必须包含 */
@@ -0,0 +1,9 @@
1
+ // 导出评估器
2
+ export { PromotionEvaluator } from "./evaluator";
3
+
4
+ // 导出适配器
5
+ export { PromotionAdapter } from "./adapter";
6
+ export { default } from "./adapter";
7
+
8
+ // 导出策略配置示例常量
9
+ export { X_ITEMS_FOR_Y_PRICE_STRATEGY, BUY_X_GET_Y_FREE_STRATEGY } from "./examples";
@@ -1114,8 +1114,8 @@ export var OrderModule = /*#__PURE__*/function (_BaseModule) {
1114
1114
  });
1115
1115
  case 2:
1116
1116
  res = _context15.sent;
1117
- if (res.data.code === 200 && this.store.tempOrder) {
1118
- this.store.tempOrder.lastOrderInfo = res.data.data;
1117
+ if (res.code === 200 && this.store.tempOrder) {
1118
+ this.store.tempOrder.lastOrderInfo = res.data;
1119
1119
  }
1120
1120
  case 4:
1121
1121
  case "end":
@@ -46,7 +46,7 @@ export declare const formatScheduleResult: (schedule: ScheduleItem) => {
46
46
  };
47
47
  export declare const calcScheduleDateRange: (schedule: ScheduleItem) => any[];
48
48
  export declare const calcCalendarDataBySchedules: (schedules: ScheduleItem[]) => unknown[];
49
- export declare const calcMinTimeMaxTimeBySchedules: (schedules: ScheduleItem[], scheduleAllMap?: ScheduleAllMap, selectDate?: string) => {};
49
+ export declare const calcMinTimeMaxTimeBySchedules: (schedules: ScheduleItem[], scheduleAllMap?: ScheduleAllMap, selectDate?: string) => ScheduleAllMap;
50
50
  /**
51
51
  * @title: 格式化日程数据
52
52
  * @description:
@@ -310,7 +310,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
310
310
  date: string;
311
311
  status: string;
312
312
  week: string;
313
- weekNum: 0 | 2 | 1 | 5 | 4 | 3 | 6;
313
+ weekNum: 0 | 1 | 2 | 5 | 4 | 3 | 6;
314
314
  }[]>;
315
315
  submitTimeSlot(timeSlots: TimeSliceItem): void;
316
316
  private getScheduleDataByIds;
@@ -357,7 +357,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
357
357
  };
358
358
  setOtherData(key: string, value: any): void;
359
359
  getOtherData(key: string): any;
360
- getProductTypeById(id: number): Promise<"normal" | "duration" | "session">;
360
+ getProductTypeById(id: number): Promise<"duration" | "session" | "normal">;
361
361
  /**
362
362
  * 提供给 UI 的方法,减轻 UI 层的计算压力,UI 层只需要传递 cartItemId 和 resourceCode 即返回对应的 renderList
363
363
  *
@@ -1327,19 +1327,26 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1327
1327
  key: "applyItemRulePrefill",
1328
1328
  value: function () {
1329
1329
  var _applyItemRulePrefill = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21() {
1330
+ var _this$store$order4, _this$store$order4$ge;
1330
1331
  return _regeneratorRuntime().wrap(function _callee21$(_context21) {
1331
1332
  while (1) switch (_context21.prev = _context21.next) {
1332
1333
  case 0:
1334
+ if (!((_this$store$order4 = this.store.order) !== null && _this$store$order4 !== void 0 && (_this$store$order4$ge = _this$store$order4.getLastOrderInfo) !== null && _this$store$order4$ge !== void 0 && _this$store$order4$ge.call(_this$store$order4))) {
1335
+ _context21.next = 2;
1336
+ break;
1337
+ }
1338
+ return _context21.abrupt("return");
1339
+ case 2:
1333
1340
  this.logMethodStart('applyItemRulePrefill');
1334
- _context21.next = 3;
1335
- return this.applyPrefillByItemRule();
1336
- case 3:
1337
1341
  _context21.next = 5;
1338
- return this.refreshItemRuleQuantityLimits();
1342
+ return this.applyPrefillByItemRule();
1339
1343
  case 5:
1340
1344
  _context21.next = 7;
1341
- return this.refreshCartValidationPassed();
1345
+ return this.refreshItemRuleQuantityLimits();
1342
1346
  case 7:
1347
+ _context21.next = 9;
1348
+ return this.refreshCartValidationPassed();
1349
+ case 9:
1343
1350
  case "end":
1344
1351
  return _context21.stop();
1345
1352
  }
@@ -1654,7 +1661,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1654
1661
  key: "checkResourceAvailable",
1655
1662
  value: function () {
1656
1663
  var _checkResourceAvailable = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee27(resourceId, hasOrderId) {
1657
- var _this$otherParams9, _this$otherParams9$ge, _config$table_form_re, _config$table_form_re2, _this$otherParams10, _this$store$order4, openData, dineInConfig, shopClosedInfo, config, resourceState, availabilityInfo, tempOrder, reservationLinkIds, reservationProductList, scheduleDate, scheduleDatetime, loaded, occupancyMinutes, _this$store$order5;
1664
+ var _this$otherParams9, _this$otherParams9$ge, _config$table_form_re, _config$table_form_re2, _this$otherParams10, _this$store$order5, _this$store$order7, _this$store$order7$ge, openData, dineInConfig, shopClosedInfo, config, resourceState, availabilityInfo, tempOrder, reservationLinkIds, reservationProductList, scheduleDate, scheduleDatetime, loaded, occupancyMinutes, _this$store$order6, lastOrderInfo, historicalItems;
1658
1665
  return _regeneratorRuntime().wrap(function _callee27$(_context27) {
1659
1666
  while (1) switch (_context27.prev = _context27.next) {
1660
1667
  case 0:
@@ -1782,7 +1789,7 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1782
1789
  });
1783
1790
  }
1784
1791
  case 42:
1785
- (_this$store$order4 = this.store.order) === null || _this$store$order4 === void 0 || _this$store$order4.persistTempOrder();
1792
+ (_this$store$order5 = this.store.order) === null || _this$store$order5 === void 0 || _this$store$order5.persistTempOrder();
1786
1793
 
1787
1794
  // 空闲状态下自动准备本地临时订单,供后续“购物车式”商品操作使用
1788
1795
  if (!(availabilityInfo.mode === 'idle')) {
@@ -1801,13 +1808,30 @@ export var ScanOrderImpl = /*#__PURE__*/function (_BaseModule) {
1801
1808
  break;
1802
1809
  }
1803
1810
  _context27.next = 50;
1804
- return (_this$store$order5 = this.store.order) === null || _this$store$order5 === void 0 ? void 0 : _this$store$order5.getOrderInfoByRemote(tempOrder.order_id);
1811
+ return (_this$store$order6 = this.store.order) === null || _this$store$order6 === void 0 ? void 0 : _this$store$order6.getOrderInfoByRemote(tempOrder.order_id);
1805
1812
  case 50:
1806
- _context27.next = 52;
1807
- return this.refreshItemRuleQuantityLimits();
1808
- case 52:
1813
+ lastOrderInfo = (_this$store$order7 = this.store.order) === null || _this$store$order7 === void 0 || (_this$store$order7$ge = _this$store$order7.getLastOrderInfo) === null || _this$store$order7$ge === void 0 ? void 0 : _this$store$order7$ge.call(_this$store$order7);
1814
+ historicalItems = hasOrderId && Array.isArray(lastOrderInfo === null || lastOrderInfo === void 0 ? void 0 : lastOrderInfo.products) ? lastOrderInfo.products.reduce(function (acc, p) {
1815
+ if (typeof (p === null || p === void 0 ? void 0 : p.product_id) !== 'number') return acc;
1816
+ acc.push(_objectSpread({
1817
+ product_id: p.product_id,
1818
+ quantity: Number(p.product_quantity) || 0
1819
+ }, typeof p.product_variant_id === 'number' ? {
1820
+ product_variant_id: p.product_variant_id
1821
+ } : {}));
1822
+ return acc;
1823
+ }, []) : [];
1809
1824
  _context27.next = 54;
1810
- return this.refreshCartValidationPassed();
1825
+ return this.setItemRuleRuntimeConfig({
1826
+ pax: {
1827
+ total: 2,
1828
+ adult: 2,
1829
+ child: 0
1830
+ },
1831
+ serviceType: 'dine-in',
1832
+ submissionIndex: hasOrderId ? 1 : 0,
1833
+ historicalItems: historicalItems
1834
+ });
1811
1835
  case 54:
1812
1836
  this.logMethodSuccess('checkResourceAvailable', {
1813
1837
  resourceId: resourceId,
@@ -59,6 +59,7 @@ export declare function resolveSkuMatchedQuantityLimits(params: {
59
59
  export declare function aggregateItemRuleLimit(matchedLimits: QuantityLimitResult[]): {
60
60
  min: number | undefined;
61
61
  max: number | undefined;
62
+ remainingMax: number | undefined;
62
63
  exact: number | undefined;
63
64
  mustInclude: boolean;
64
65
  } | null;
@@ -216,6 +216,7 @@ export function aggregateItemRuleLimit(matchedLimits) {
216
216
  if (!matchedLimits.length) return null;
217
217
  var min;
218
218
  var max;
219
+ var remainingMax;
219
220
  var exact;
220
221
  var mustInclude = false;
221
222
  var _iterator4 = _createForOfIteratorHelper(matchedLimits),
@@ -229,6 +230,9 @@ export function aggregateItemRuleLimit(matchedLimits) {
229
230
  if (typeof limit.requiredMax === 'number' && Number.isFinite(limit.requiredMax)) {
230
231
  max = max === undefined ? limit.requiredMax : Math.min(max, limit.requiredMax);
231
232
  }
233
+ if (typeof limit.remainingMax === 'number' && Number.isFinite(limit.remainingMax)) {
234
+ remainingMax = remainingMax === undefined ? limit.remainingMax : Math.min(remainingMax, limit.remainingMax);
235
+ }
232
236
  if (typeof limit.requiredExact === 'number' && Number.isFinite(limit.requiredExact)) {
233
237
  exact = limit.requiredExact;
234
238
  }
@@ -246,6 +250,7 @@ export function aggregateItemRuleLimit(matchedLimits) {
246
250
  return {
247
251
  min: min,
248
252
  max: max,
253
+ remainingMax: remainingMax,
249
254
  exact: exact,
250
255
  mustInclude: mustInclude
251
256
  };
@@ -25,6 +25,7 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
25
25
  private cacheId;
26
26
  private window;
27
27
  private request;
28
+ private baseSlotConfig;
28
29
  private itemRuleEvaluator;
29
30
  private itemRuleConfigs;
30
31
  private itemRuleConfigsPromise;
@@ -80,6 +81,9 @@ export declare class VenueBookingImpl extends BaseModule implements Module {
80
81
  startDate: string;
81
82
  endDate: string;
82
83
  }): Promise<void>;
84
+ private getOperatingHoursScheduleIds;
85
+ private resolveSlotConfigForDate;
86
+ private syncOperatingHoursToSlotConfig;
83
87
  getDateRangeSummary(params: {
84
88
  startDate: string;
85
89
  endDate: string;