@pisell/pisellos 0.10.26 → 0.10.28

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.
@@ -533,7 +533,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
533
533
  generateIdempotencyToken(): string;
534
534
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
535
535
  createOrder(params: CommitOrderParams['query']): {
536
- type: "virtual" | "appointment_booking";
536
+ type: "appointment_booking" | "virtual";
537
537
  platform: string;
538
538
  sales_channel: string;
539
539
  order_sales_channel: string;
@@ -851,7 +851,7 @@ export var WalletPassPaymentImpl = /*#__PURE__*/function () {
851
851
  key: "getUserIdentificationCodeListAsync",
852
852
  value: function () {
853
853
  var _getUserIdentificationCodeListAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(params) {
854
- var _newParams$products, _newParams$prepare_pa, _this$walletParams4, newParams, platform, response, sortedData;
854
+ var _newParams$products, _newParams$prepare_pa, _this$walletParams4, newParams, response, sortedData;
855
855
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
856
856
  while (1) switch (_context6.prev = _context6.next) {
857
857
  case 0:
@@ -864,20 +864,19 @@ export var WalletPassPaymentImpl = /*#__PURE__*/function () {
864
864
  this.paymentModule.logInfo('[WalletPass] 商品列表为空,跳过获取用户识别码列表');
865
865
  return _context6.abrupt("return", []);
866
866
  case 5:
867
- platform = this.paymentModule.getPlatform();
868
- if (!(platform === 'pc' || platform === 'h5')) {
869
- _context6.next = 11;
870
- break;
871
- }
872
- this.userIdentificationCodes = [];
873
- this.emitEvent(WalletPassHooks.OnUserIdentificationCodesUpdated, {
874
- userIdentificationCodes: []
875
- });
876
- this.paymentModule.logInfo('[WalletPass] 用户端平台跳过获取用户识别码列表', {
877
- platform: platform
878
- });
879
- return _context6.abrupt("return", []);
880
- case 11:
867
+ // const platform = this.paymentModule.getPlatform();
868
+ // if (platform === 'pc' || platform === 'h5') {
869
+ // this.userIdentificationCodes = [];
870
+ // this.emitEvent(WalletPassHooks.OnUserIdentificationCodesUpdated, {
871
+ // userIdentificationCodes: [],
872
+ // } as OnUserIdentificationCodesUpdatedEventData);
873
+ // this.paymentModule.logInfo(
874
+ // '[WalletPass] 用户端平台跳过获取用户识别码列表',
875
+ // { platform },
876
+ // );
877
+ // return [];
878
+ // }
879
+
881
880
  if (typeof newParams.payment_order_id === 'string' && newParams.payment_order_id.startsWith('LOCAL_')) {
882
881
  newParams.payment_order_id = undefined;
883
882
  }
@@ -888,9 +887,9 @@ export var WalletPassPaymentImpl = /*#__PURE__*/function () {
888
887
  filter_prepare_wallet_pass: newParams.filter_prepare_wallet_pass,
889
888
  payment_order_id: (_this$walletParams4 = this.walletParams) === null || _this$walletParams4 === void 0 ? void 0 : _this$walletParams4.payment_order_id
890
889
  });
891
- _context6.next = 15;
890
+ _context6.next = 9;
892
891
  return this.paymentModule.request.post('/machinecode/prepare/deduction', newParams);
893
- case 15:
892
+ case 9:
894
893
  response = _context6.sent;
895
894
  // 对获取到的数据进行排序,将错误码为 500100、500200、500300 的项目排到最后
896
895
  sortedData = sortUserIdentificationCodeList((response === null || response === void 0 ? void 0 : response.data) || []);
@@ -911,19 +910,19 @@ export var WalletPassPaymentImpl = /*#__PURE__*/function () {
911
910
  })
912
911
  });
913
912
  return _context6.abrupt("return", this.userIdentificationCodes);
914
- case 23:
915
- _context6.prev = 23;
913
+ case 17:
914
+ _context6.prev = 17;
916
915
  _context6.t0 = _context6["catch"](0);
917
916
  this.paymentModule.logError('[WalletPass] 获取用户识别码列表失败', _context6.t0, {
918
917
  customer_id: params.customer_id,
919
918
  available: params.available
920
919
  });
921
920
  return _context6.abrupt("return", []);
922
- case 27:
921
+ case 21:
923
922
  case "end":
924
923
  return _context6.stop();
925
924
  }
926
- }, _callee6, this, [[0, 23]]);
925
+ }, _callee6, this, [[0, 17]]);
927
926
  }));
928
927
  function getUserIdentificationCodeListAsync(_x7) {
929
928
  return _getUserIdentificationCodeListAsync.apply(this, arguments);
@@ -62,13 +62,21 @@ function resolveRequestedDurationMinutes(product, request) {
62
62
  }
63
63
  function resolveRequestedDurationStartTimes(product, request) {
64
64
  var _request$durationStar;
65
- if (product.kind !== 'duration') return [];
65
+ var allowSessionCustomRanges = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
66
+ if (product.kind !== 'duration' && !(product.kind === 'session' && allowSessionCustomRanges)) return [];
66
67
  var values = (_request$durationStar = request.durationStartTimesByProductId) === null || _request$durationStar === void 0 ? void 0 : _request$durationStar[String(product.id)];
67
68
  if (!Array.isArray(values)) return [];
68
69
  return Array.from(new Set(values.filter(function (value) {
69
70
  return typeof value === 'string' && /^([01]\d|2[0-3]):[0-5]\d$/.test(value);
70
71
  })));
71
72
  }
73
+ function resolveRequestedSessionDurationMinutes(product, request, allowSessionCustomRanges) {
74
+ var _request$durationMinu2;
75
+ if (product.kind !== 'session' || !allowSessionCustomRanges) return undefined;
76
+ var override = (_request$durationMinu2 = request.durationMinutesByProductId) === null || _request$durationMinu2 === void 0 ? void 0 : _request$durationMinu2[String(product.id)];
77
+ var normalized = Number(override);
78
+ return Number.isInteger(normalized) && normalized > 0 ? normalized : undefined;
79
+ }
72
80
  function toDateTime(value, _timezoneName) {
73
81
  try {
74
82
  return localDateTimeToScalar(parseLocalDateTime(value));
@@ -1025,12 +1033,23 @@ export function getProductTimeRanges(projection) {
1025
1033
  };
1026
1034
  }
1027
1035
  if (product.kind === 'session' || product.kind === 'venue_slot') {
1036
+ var fixedRanges = getSessionRangesForProduct(projection, product, dateRange);
1037
+ var customRanges = [];
1038
+ var customDurationMinutes = resolveRequestedSessionDurationMinutes(product, request, runtimeOptions.allowSessionCustomRanges === true);
1039
+ var _requestedStartTimes = resolveRequestedDurationStartTimes(product, request, runtimeOptions.allowSessionCustomRanges === true);
1040
+ if (product.kind === 'session' && customDurationMinutes && dateRange.startDate === dateRange.endDate) {
1041
+ _requestedStartTimes.forEach(function (startTime) {
1042
+ var start = toDateTimeInDate(dateRange.startDate, startTime, projection.meta.timezone);
1043
+ if (!Number.isFinite(start)) return;
1044
+ customRanges.push(createDurationTimeRange(product, start, customDurationMinutes, projection, fixedOffsetMinutes));
1045
+ });
1046
+ }
1028
1047
  return {
1029
1048
  productId: product.id,
1030
1049
  title: product.title,
1031
1050
  kind: product.kind,
1032
1051
  slotStepMinutes: slotStepMinutes,
1033
- ranges: getSessionRangesForProduct(projection, product, dateRange)
1052
+ ranges: dedupeProductRanges([].concat(_toConsumableArray(fixedRanges), customRanges))
1034
1053
  };
1035
1054
  }
1036
1055
  var requiredGroups = (product.requirementGroups || []).filter(function (group) {
@@ -243,6 +243,13 @@ export interface GetProductTimeRangesRequest {
243
243
  }
244
244
  export interface GetProductTimeRangesRuntimeOptions {
245
245
  evaluatedAt?: string;
246
+ /**
247
+ * Internal POS capability: allow explicit duration/start overrides to append
248
+ * a custom duration candidate for Session products. Fixed Session ranges are
249
+ * still returned unchanged. Callers outside the POS facade must leave this
250
+ * disabled.
251
+ */
252
+ allowSessionCustomRanges?: boolean;
246
253
  }
247
254
  export interface QueryAvailabilityBaseRequest {
248
255
  productIds?: AvailabilityId[];
@@ -1388,7 +1388,7 @@ export var RulesModule = /*#__PURE__*/function (_BaseModule) {
1388
1388
  // bundle子商品:保存到扁平化Map
1389
1389
  processedFlatItemsMap.set(flatItem._id, [_objectSpread(_objectSpread({}, flatItem), {}, {
1390
1390
  discount_list: isManualDiscount ? _this4.resolveDiscountListForManualOverride(((_flatItem$bundleItem8 = flatItem.bundleItem) === null || _flatItem$bundleItem8 === void 0 ? void 0 : _flatItem$bundleItem8.discount_list) || []) : _this4.filterDiscountListByType(((_flatItem$bundleItem9 = flatItem.bundleItem) === null || _flatItem$bundleItem9 === void 0 ? void 0 : _flatItem$bundleItem9.discount_list) || [], 'promotion'),
1391
- price: isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price,
1391
+ price: flatItem.bundleItem.price,
1392
1392
  bundle_selling_price: (_flatItem$bundleItem$ = flatItem.bundleItem.bundle_selling_price) !== null && _flatItem$bundleItem$ !== void 0 ? _flatItem$bundleItem$ : isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price,
1393
1393
  processed: true
1394
1394
  })]);
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  date: string;
327
327
  status: string;
328
328
  week: string;
329
- weekNum: 0 | 2 | 1 | 6 | 4 | 5 | 3;
329
+ weekNum: 0 | 5 | 3 | 1 | 2 | 4 | 6;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
345
345
  count: number;
346
346
  left: number;
347
347
  summaryCount: number;
348
- status: "lots_of_space" | "filling_up_fast" | "sold_out";
348
+ status: "sold_out" | "lots_of_space" | "filling_up_fast";
349
349
  }[];
350
350
  /**
351
351
  * 找到多个资源的公共可用时间段
@@ -458,7 +458,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
458
458
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
459
459
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
460
460
  */
461
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
461
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
462
+ action: "reloadCatalog";
463
+ } | {
464
+ action: "add";
465
+ cacheItem: any;
466
+ } | {
467
+ action: "requiresDetail";
468
+ payload: AddProductRequiresDetailPayload;
469
+ } | {
470
+ action: "requiresBookingEdit";
471
+ cacheItem: any;
472
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
473
+ };
462
474
  /** 规格弹窗 callback 后的第二段决策。 */
463
475
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
464
476
  /**
@@ -1030,7 +1030,7 @@ function buildBookingFromAvailabilitySelection(params) {
1030
1030
  var timeSlotId = (_candidate$primarySch3 = (_candidate$primarySch4 = candidate.primaryScheduleRef) === null || _candidate$primarySch4 === void 0 ? void 0 : _candidate$primarySch4.timeSlotId) !== null && _candidate$primarySch3 !== void 0 ? _candidate$primarySch3 : (_assignments$find2 = assignments.find(function (assignment) {
1031
1031
  return assignment.timeSlotId != null;
1032
1032
  })) === null || _assignments$find2 === void 0 ? void 0 : _assignments$find2.timeSlotId;
1033
- if (product.kind === 'session' && scheduleId == null) {
1033
+ if (product.kind === 'session' && candidate.source === 'session_schedule' && scheduleId == null) {
1034
1034
  throw new AvailabilityError('REVALIDATION_FAILED', 'session 候选缺少真实 schedule identity', {
1035
1035
  productId: product.id,
1036
1036
  candidateKey: candidate.key,
@@ -1039,15 +1039,16 @@ function buildBookingFromAvailabilitySelection(params) {
1039
1039
  }
1040
1040
  var normalizedHolder = holder && _typeof(holder) === 'object' ? cloneDeep(holder) : undefined;
1041
1041
  var normalizedHolderIds = Array.isArray(holderIds) ? cloneDeep(holderIds) : holderIds;
1042
- return _objectSpread(_objectSpread({
1042
+ return _objectSpread(_objectSpread(_objectSpread({
1043
1043
  start_date: bookingStartAt.slice(0, 10),
1044
1044
  start_time: bookingStartAt.slice(11, 16),
1045
1045
  end_date: bookingEndAt.slice(0, 10),
1046
1046
  end_time: bookingEndAt.slice(11, 16),
1047
1047
  duration: Math.max(1, Math.trunc((endScalar - startScalar) / (60 * 1000))),
1048
- like_status: 'common',
1048
+ like_status: 'common'
1049
+ }, product.kind === 'session' && candidate.source === 'duration_window' ? {} : {
1049
1050
  schedule_id: scheduleId !== null && scheduleId !== void 0 ? scheduleId : 0
1050
- }, normalizedHolder ? {
1051
+ }), normalizedHolder ? {
1051
1052
  holder: normalizedHolder
1052
1053
  } : {}), {}, {
1053
1054
  resources: assignments.map(function (assignment) {
@@ -4272,6 +4273,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4272
4273
  context,
4273
4274
  projectionEntry,
4274
4275
  contextVersion,
4276
+ isPosAvailabilityRequest,
4275
4277
  allowOutsideOperatingHoursForRequestedStartTimes,
4276
4278
  _args37 = arguments;
4277
4279
  return _regeneratorRuntime().wrap(function _callee37$(_context37) {
@@ -4285,13 +4287,15 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4285
4287
  context = _yield$this$ensureAva.context;
4286
4288
  projectionEntry = _yield$this$ensureAva.projectionEntry;
4287
4289
  contextVersion = context.activeVersion;
4288
- allowOutsideOperatingHoursForRequestedStartTimes = String((_this$otherParams$pla = (_this$otherParams19 = this.otherParams) === null || _this$otherParams19 === void 0 ? void 0 : _this$otherParams19.platform) !== null && _this$otherParams$pla !== void 0 ? _this$otherParams$pla : '').trim().toLowerCase() === 'pos' && Object.values(request.durationStartTimesByProductId || {}).some(function (startTimes) {
4290
+ isPosAvailabilityRequest = String((_this$otherParams$pla = (_this$otherParams19 = this.otherParams) === null || _this$otherParams19 === void 0 ? void 0 : _this$otherParams19.platform) !== null && _this$otherParams$pla !== void 0 ? _this$otherParams$pla : '').trim().toLowerCase() === 'pos';
4291
+ allowOutsideOperatingHoursForRequestedStartTimes = isPosAvailabilityRequest && Object.values(request.durationStartTimesByProductId || {}).some(function (startTimes) {
4289
4292
  return Array.isArray(startTimes) && startTimes.length > 0;
4290
4293
  });
4291
4294
  return _context37.abrupt("return", getProjectionProductTimeRanges(projectionEntry.projection, _objectSpread(_objectSpread({}, request), allowOutsideOperatingHoursForRequestedStartTimes ? {
4292
4295
  allowOutsideOperatingHoursForRequestedStartTimes: true
4293
4296
  } : {}), {
4294
- evaluatedAt: this.getAvailabilityRuntimeDateTime()
4297
+ evaluatedAt: this.getAvailabilityRuntimeDateTime(),
4298
+ allowSessionCustomRanges: isPosAvailabilityRequest
4295
4299
  }).map(function (group) {
4296
4300
  return _objectSpread(_objectSpread({}, group), {}, {
4297
4301
  ranges: group.ranges.map(function (candidate) {
@@ -4299,7 +4303,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4299
4303
  })
4300
4304
  });
4301
4305
  }));
4302
- case 9:
4306
+ case 10:
4303
4307
  case "end":
4304
4308
  return _context37.stop();
4305
4309
  }
@@ -4678,7 +4682,9 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4678
4682
  durationStartTimesByProductId: _defineProperty({}, String(params.candidate.productId), [candidateStartTime])
4679
4683
  }, allowPosAvailabilityOverride ? {
4680
4684
  allowOutsideOperatingHoursForRequestedStartTimes: true
4681
- } : {}) : {}) : {})).flatMap(function (group) {
4685
+ } : {}) : {}) : {}), {
4686
+ allowSessionCustomRanges: allowPosAvailabilityOverride
4687
+ }).flatMap(function (group) {
4682
4688
  return group.ranges;
4683
4689
  });
4684
4690
  refreshedCandidateBase = refreshedRanges.find(function (candidate) {
@@ -533,7 +533,7 @@ export declare class OrderModule extends BaseModule implements Module, OrderModu
533
533
  generateIdempotencyToken(): string;
534
534
  syncPaymentsToOrder<T = any>(params: SyncPaymentsToOrderParams): Promise<SyncPaymentsToOrderResult<T>>;
535
535
  createOrder(params: CommitOrderParams['query']): {
536
- type: "virtual" | "appointment_booking";
536
+ type: "appointment_booking" | "virtual";
537
537
  platform: string;
538
538
  sales_channel: string;
539
539
  order_sales_channel: string;
@@ -650,17 +650,20 @@ class WalletPassPaymentImpl {
650
650
  this.paymentModule.logInfo('[WalletPass] 商品列表为空,跳过获取用户识别码列表');
651
651
  return [];
652
652
  }
653
- const platform = this.paymentModule.getPlatform();
654
- if (platform === 'pc' || platform === 'h5') {
655
- this.userIdentificationCodes = [];
656
- this.emitEvent(_types.WalletPassHooks.OnUserIdentificationCodesUpdated, {
657
- userIdentificationCodes: []
658
- });
659
- this.paymentModule.logInfo('[WalletPass] 用户端平台跳过获取用户识别码列表', {
660
- platform
661
- });
662
- return [];
663
- }
653
+
654
+ // const platform = this.paymentModule.getPlatform();
655
+ // if (platform === 'pc' || platform === 'h5') {
656
+ // this.userIdentificationCodes = [];
657
+ // this.emitEvent(WalletPassHooks.OnUserIdentificationCodesUpdated, {
658
+ // userIdentificationCodes: [],
659
+ // } as OnUserIdentificationCodesUpdatedEventData);
660
+ // this.paymentModule.logInfo(
661
+ // '[WalletPass] 用户端平台跳过获取用户识别码列表',
662
+ // { platform },
663
+ // );
664
+ // return [];
665
+ // }
666
+
664
667
  if (typeof newParams.payment_order_id === 'string' && newParams.payment_order_id.startsWith('LOCAL_')) {
665
668
  newParams.payment_order_id = undefined;
666
669
  }
@@ -55,12 +55,18 @@ function resolveRequestedDurationMinutes(product, request) {
55
55
  const normalized = Number(override);
56
56
  return Number.isInteger(normalized) && normalized > 0 ? normalized : configured;
57
57
  }
58
- function resolveRequestedDurationStartTimes(product, request) {
59
- if (product.kind !== 'duration') return [];
58
+ function resolveRequestedDurationStartTimes(product, request, allowSessionCustomRanges = false) {
59
+ if (product.kind !== 'duration' && !(product.kind === 'session' && allowSessionCustomRanges)) return [];
60
60
  const values = request.durationStartTimesByProductId?.[String(product.id)];
61
61
  if (!Array.isArray(values)) return [];
62
62
  return Array.from(new Set(values.filter(value => typeof value === 'string' && /^([01]\d|2[0-3]):[0-5]\d$/.test(value))));
63
63
  }
64
+ function resolveRequestedSessionDurationMinutes(product, request, allowSessionCustomRanges) {
65
+ if (product.kind !== 'session' || !allowSessionCustomRanges) return undefined;
66
+ const override = request.durationMinutesByProductId?.[String(product.id)];
67
+ const normalized = Number(override);
68
+ return Number.isInteger(normalized) && normalized > 0 ? normalized : undefined;
69
+ }
64
70
  function toDateTime(value, _timezoneName) {
65
71
  try {
66
72
  return (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(value));
@@ -919,12 +925,23 @@ function getProductTimeRanges(projection, request = {}, runtimeOptions = {}) {
919
925
  };
920
926
  }
921
927
  if (product.kind === 'session' || product.kind === 'venue_slot') {
928
+ const fixedRanges = getSessionRangesForProduct(projection, product, dateRange);
929
+ const customRanges = [];
930
+ const customDurationMinutes = resolveRequestedSessionDurationMinutes(product, request, runtimeOptions.allowSessionCustomRanges === true);
931
+ const requestedStartTimes = resolveRequestedDurationStartTimes(product, request, runtimeOptions.allowSessionCustomRanges === true);
932
+ if (product.kind === 'session' && customDurationMinutes && dateRange.startDate === dateRange.endDate) {
933
+ requestedStartTimes.forEach(startTime => {
934
+ const start = toDateTimeInDate(dateRange.startDate, startTime, projection.meta.timezone);
935
+ if (!Number.isFinite(start)) return;
936
+ customRanges.push(createDurationTimeRange(product, start, customDurationMinutes, projection, fixedOffsetMinutes));
937
+ });
938
+ }
922
939
  return {
923
940
  productId: product.id,
924
941
  title: product.title,
925
942
  kind: product.kind,
926
943
  slotStepMinutes,
927
- ranges: getSessionRangesForProduct(projection, product, dateRange)
944
+ ranges: dedupeProductRanges([...fixedRanges, ...customRanges])
928
945
  };
929
946
  }
930
947
  const requiredGroups = (product.requirementGroups || []).filter(group => group.required !== false);
@@ -243,6 +243,13 @@ export interface GetProductTimeRangesRequest {
243
243
  }
244
244
  export interface GetProductTimeRangesRuntimeOptions {
245
245
  evaluatedAt?: string;
246
+ /**
247
+ * Internal POS capability: allow explicit duration/start overrides to append
248
+ * a custom duration candidate for Session products. Fixed Session ranges are
249
+ * still returned unchanged. Callers outside the POS facade must leave this
250
+ * disabled.
251
+ */
252
+ allowSessionCustomRanges?: boolean;
246
253
  }
247
254
  export interface QueryAvailabilityBaseRequest {
248
255
  productIds?: AvailabilityId[];
@@ -1128,7 +1128,7 @@ class RulesModule extends _BaseModule.BaseModule {
1128
1128
  processedFlatItemsMap.set(flatItem._id, [{
1129
1129
  ...flatItem,
1130
1130
  discount_list: isManualDiscount ? this.resolveDiscountListForManualOverride(flatItem.bundleItem?.discount_list || []) : this.filterDiscountListByType(flatItem.bundleItem?.discount_list || [], 'promotion'),
1131
- price: isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price,
1131
+ price: flatItem.bundleItem.price,
1132
1132
  bundle_selling_price: flatItem.bundleItem.bundle_selling_price ?? (isManualDiscount ? flatItem.bundleItem.price : flatItem.bundleItem.original_price),
1133
1133
  processed: true
1134
1134
  }]);
@@ -326,7 +326,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
326
326
  date: string;
327
327
  status: string;
328
328
  week: string;
329
- weekNum: 0 | 2 | 1 | 6 | 4 | 5 | 3;
329
+ weekNum: 0 | 5 | 3 | 1 | 2 | 4 | 6;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -345,7 +345,7 @@ export declare class BookingByStepImpl extends BaseModule implements Module {
345
345
  count: number;
346
346
  left: number;
347
347
  summaryCount: number;
348
- status: "lots_of_space" | "filling_up_fast" | "sold_out";
348
+ status: "sold_out" | "lots_of_space" | "filling_up_fast";
349
349
  }[];
350
350
  /**
351
351
  * 找到多个资源的公共可用时间段
@@ -458,7 +458,19 @@ export declare class BookingTicketImpl extends BaseSalesImpl implements Module {
458
458
  * 加车两阶段主决策(规格弹窗 / 资源编辑 / 直接加车)。
459
459
  * 与 ticketBooking `handleSelectProduct` + `handleBooking4Service` 等价。
460
460
  */
461
- decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
461
+ decideAddProduct(item: any, options?: Partial<AddProductDecideContext>): {
462
+ action: "reloadCatalog";
463
+ } | {
464
+ action: "add";
465
+ cacheItem: any;
466
+ } | {
467
+ action: "requiresDetail";
468
+ payload: AddProductRequiresDetailPayload;
469
+ } | {
470
+ action: "requiresBookingEdit";
471
+ cacheItem: any;
472
+ payload: import("./utils/addProductDecision").AddProductRequiresBookingEditPayload;
473
+ };
462
474
  /** 规格弹窗 callback 后的第二段决策。 */
463
475
  decideAfterDetail(cacheItem: any, options?: Partial<AddProductDecideContext>): import("./utils/addProductDecision").AddProductDecision;
464
476
  /**
@@ -946,7 +946,7 @@ function buildBookingFromAvailabilitySelection(params) {
946
946
  const endScalar = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(bookingEndAt));
947
947
  const scheduleId = candidate.primaryScheduleRef?.scheduleId ?? assignments.find(assignment => assignment.scheduleId != null)?.scheduleId;
948
948
  const timeSlotId = candidate.primaryScheduleRef?.timeSlotId ?? assignments.find(assignment => assignment.timeSlotId != null)?.timeSlotId;
949
- if (product.kind === 'session' && scheduleId == null) {
949
+ if (product.kind === 'session' && candidate.source === 'session_schedule' && scheduleId == null) {
950
950
  throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', 'session 候选缺少真实 schedule identity', {
951
951
  productId: product.id,
952
952
  candidateKey: candidate.key,
@@ -962,7 +962,9 @@ function buildBookingFromAvailabilitySelection(params) {
962
962
  end_time: bookingEndAt.slice(11, 16),
963
963
  duration: Math.max(1, Math.trunc((endScalar - startScalar) / (60 * 1000))),
964
964
  like_status: 'common',
965
- schedule_id: scheduleId ?? 0,
965
+ ...(product.kind === 'session' && candidate.source === 'duration_window' ? {} : {
966
+ schedule_id: scheduleId ?? 0
967
+ }),
966
968
  ...(normalizedHolder ? {
967
969
  holder: normalizedHolder
968
970
  } : {}),
@@ -2822,14 +2824,16 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2822
2824
  projectionEntry
2823
2825
  } = await this.ensureAvailabilityContextProjection(contextId, 'get_product_time_ranges');
2824
2826
  const contextVersion = context.activeVersion;
2825
- const allowOutsideOperatingHoursForRequestedStartTimes = String(this.otherParams?.platform ?? '').trim().toLowerCase() === 'pos' && Object.values(request.durationStartTimesByProductId || {}).some(startTimes => Array.isArray(startTimes) && startTimes.length > 0);
2827
+ const isPosAvailabilityRequest = String(this.otherParams?.platform ?? '').trim().toLowerCase() === 'pos';
2828
+ const allowOutsideOperatingHoursForRequestedStartTimes = isPosAvailabilityRequest && Object.values(request.durationStartTimesByProductId || {}).some(startTimes => Array.isArray(startTimes) && startTimes.length > 0);
2826
2829
  return (0, _ResourcePlanner.getProductTimeRanges)(projectionEntry.projection, {
2827
2830
  ...request,
2828
2831
  ...(allowOutsideOperatingHoursForRequestedStartTimes ? {
2829
2832
  allowOutsideOperatingHoursForRequestedStartTimes: true
2830
2833
  } : {})
2831
2834
  }, {
2832
- evaluatedAt: this.getAvailabilityRuntimeDateTime()
2835
+ evaluatedAt: this.getAvailabilityRuntimeDateTime(),
2836
+ allowSessionCustomRanges: isPosAvailabilityRequest
2833
2837
  }).map(group => ({
2834
2838
  ...group,
2835
2839
  ranges: group.ranges.map(candidate => this.decorateAvailabilityCandidate(context.contextId, contextVersion, candidate))
@@ -3100,6 +3104,8 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
3100
3104
  } : {})
3101
3105
  } : {})
3102
3106
  } : {})
3107
+ }, {
3108
+ allowSessionCustomRanges: allowPosAvailabilityOverride
3103
3109
  }).flatMap(group => group.ranges);
3104
3110
  const refreshedCandidateBase = refreshedRanges.find(candidate => candidate.startAt === params.candidate.startAt && candidate.endAt === params.candidate.endAt && candidate.bookingStartAt === params.candidate.bookingStartAt && candidate.bookingEndAt === params.candidate.bookingEndAt);
3105
3111
  if (!refreshedCandidateBase) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "0.10.26",
4
+ "version": "0.10.28",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",