@pisell/pisellos 2.2.297 → 2.2.299

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.
@@ -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));
@@ -1029,18 +1037,32 @@ export function getProductTimeRanges(projection) {
1029
1037
  };
1030
1038
  }
1031
1039
  if (product.kind === 'session' || product.kind === 'venue_slot') {
1040
+ var fixedRanges = getSessionRangesForProduct(projection, product, dateRange);
1041
+ var customRanges = [];
1042
+ var customDurationMinutes = resolveRequestedSessionDurationMinutes(product, request, runtimeOptions.allowSessionCustomRanges === true);
1043
+ var _requestedStartTimes = resolveRequestedDurationStartTimes(product, request, runtimeOptions.allowSessionCustomRanges === true);
1044
+ if (product.kind === 'session' && customDurationMinutes && dateRange.startDate === dateRange.endDate) {
1045
+ _requestedStartTimes.forEach(function (startTime) {
1046
+ var start = toDateTimeInDate(dateRange.startDate, startTime, projection.meta.timezone);
1047
+ if (!Number.isFinite(start)) return;
1048
+ customRanges.push(createDurationTimeRange(product, start, customDurationMinutes, projection, fixedOffsetMinutes));
1049
+ });
1050
+ }
1032
1051
  return {
1033
1052
  productId: product.id,
1034
1053
  title: product.title,
1035
1054
  kind: product.kind,
1036
1055
  slotStepMinutes: slotStepMinutes,
1037
- ranges: getSessionRangesForProduct(projection, product, dateRange)
1056
+ ranges: dedupeProductRanges([].concat(_toConsumableArray(fixedRanges), customRanges))
1038
1057
  };
1039
1058
  }
1040
1059
  var requiredGroups = (product.requirementGroups || []).filter(function (group) {
1041
1060
  return group.required !== false;
1042
1061
  });
1043
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;
1044
1066
  var resourceRanges = requiredGroups.length ? requiredGroups.map(function (group) {
1045
1067
  return buildGroupWorkingRanges({
1046
1068
  projection: projection,
@@ -1108,13 +1130,16 @@ export function getProductTimeRanges(projection) {
1108
1130
  ranges.push(createDurationTimeRange(product, start, durationMinutes, projection, fixedOffsetMinutes));
1109
1131
  });
1110
1132
  }
1111
- return {
1133
+ return _objectSpread(_objectSpread({
1112
1134
  productId: product.id,
1113
1135
  title: product.title,
1114
1136
  kind: product.kind,
1115
- slotStepMinutes: slotStepMinutes,
1137
+ slotStepMinutes: slotStepMinutes
1138
+ }, operatingEndAt ? {
1139
+ operatingEndAt: operatingEndAt
1140
+ } : {}), {}, {
1116
1141
  ranges: dedupeProductRanges(ranges)
1117
- };
1142
+ });
1118
1143
  });
1119
1144
  }
1120
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 {
@@ -243,6 +245,13 @@ export interface GetProductTimeRangesRequest {
243
245
  }
244
246
  export interface GetProductTimeRangesRuntimeOptions {
245
247
  evaluatedAt?: string;
248
+ /**
249
+ * Internal POS capability: allow explicit duration/start overrides to append
250
+ * a custom duration candidate for Session products. Fixed Session ranges are
251
+ * still returned unchanged. Callers outside the POS facade must leave this
252
+ * disabled.
253
+ */
254
+ allowSessionCustomRanges?: boolean;
246
255
  }
247
256
  export interface QueryAvailabilityBaseRequest {
248
257
  productIds?: AvailabilityId[];
@@ -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 | 3 | 5;
329
+ weekNum: 0 | 2 | 3 | 1 | 5 | 6 | 4;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -1029,7 +1029,7 @@ function buildBookingFromAvailabilitySelection(params) {
1029
1029
  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) {
1030
1030
  return assignment.timeSlotId != null;
1031
1031
  })) === null || _assignments$find2 === void 0 ? void 0 : _assignments$find2.timeSlotId;
1032
- if (product.kind === 'session' && scheduleId == null) {
1032
+ if (product.kind === 'session' && candidate.source === 'session_schedule' && scheduleId == null) {
1033
1033
  throw new AvailabilityError('REVALIDATION_FAILED', 'session 候选缺少真实 schedule identity', {
1034
1034
  productId: product.id,
1035
1035
  candidateKey: candidate.key,
@@ -1038,15 +1038,16 @@ function buildBookingFromAvailabilitySelection(params) {
1038
1038
  }
1039
1039
  var normalizedHolder = holder && _typeof(holder) === 'object' ? cloneDeep(holder) : undefined;
1040
1040
  var normalizedHolderIds = Array.isArray(holderIds) ? cloneDeep(holderIds) : holderIds;
1041
- return _objectSpread(_objectSpread({
1041
+ return _objectSpread(_objectSpread(_objectSpread({
1042
1042
  start_date: bookingStartAt.slice(0, 10),
1043
1043
  start_time: bookingStartAt.slice(11, 16),
1044
1044
  end_date: bookingEndAt.slice(0, 10),
1045
1045
  end_time: bookingEndAt.slice(11, 16),
1046
1046
  duration: Math.max(1, Math.trunc((endScalar - startScalar) / (60 * 1000))),
1047
- like_status: 'common',
1047
+ like_status: 'common'
1048
+ }, product.kind === 'session' && candidate.source === 'duration_window' ? {} : {
1048
1049
  schedule_id: scheduleId !== null && scheduleId !== void 0 ? scheduleId : 0
1049
- }, normalizedHolder ? {
1050
+ }), normalizedHolder ? {
1050
1051
  holder: normalizedHolder
1051
1052
  } : {}), {}, {
1052
1053
  resources: assignments.map(function (assignment) {
@@ -4209,6 +4210,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4209
4210
  context,
4210
4211
  projectionEntry,
4211
4212
  contextVersion,
4213
+ isPosAvailabilityRequest,
4212
4214
  allowOutsideOperatingHoursForRequestedStartTimes,
4213
4215
  _args35 = arguments;
4214
4216
  return _regeneratorRuntime().wrap(function _callee35$(_context35) {
@@ -4222,13 +4224,15 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4222
4224
  context = _yield$this$ensureAva.context;
4223
4225
  projectionEntry = _yield$this$ensureAva.projectionEntry;
4224
4226
  contextVersion = context.activeVersion;
4225
- allowOutsideOperatingHoursForRequestedStartTimes = String((_this$otherParams$pla = (_this$otherParams18 = this.otherParams) === null || _this$otherParams18 === void 0 ? void 0 : _this$otherParams18.platform) !== null && _this$otherParams$pla !== void 0 ? _this$otherParams$pla : '').trim().toLowerCase() === 'pos' && Object.values(request.durationStartTimesByProductId || {}).some(function (startTimes) {
4227
+ isPosAvailabilityRequest = String((_this$otherParams$pla = (_this$otherParams18 = this.otherParams) === null || _this$otherParams18 === void 0 ? void 0 : _this$otherParams18.platform) !== null && _this$otherParams$pla !== void 0 ? _this$otherParams$pla : '').trim().toLowerCase() === 'pos';
4228
+ allowOutsideOperatingHoursForRequestedStartTimes = isPosAvailabilityRequest && Object.values(request.durationStartTimesByProductId || {}).some(function (startTimes) {
4226
4229
  return Array.isArray(startTimes) && startTimes.length > 0;
4227
4230
  });
4228
4231
  return _context35.abrupt("return", getProjectionProductTimeRanges(projectionEntry.projection, _objectSpread(_objectSpread({}, request), allowOutsideOperatingHoursForRequestedStartTimes ? {
4229
4232
  allowOutsideOperatingHoursForRequestedStartTimes: true
4230
4233
  } : {}), {
4231
- evaluatedAt: this.getAvailabilityRuntimeDateTime()
4234
+ evaluatedAt: this.getAvailabilityRuntimeDateTime(),
4235
+ allowSessionCustomRanges: isPosAvailabilityRequest
4232
4236
  }).map(function (group) {
4233
4237
  return _objectSpread(_objectSpread({}, group), {}, {
4234
4238
  ranges: group.ranges.map(function (candidate) {
@@ -4236,7 +4240,7 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4236
4240
  })
4237
4241
  });
4238
4242
  }));
4239
- case 9:
4243
+ case 10:
4240
4244
  case "end":
4241
4245
  return _context35.stop();
4242
4246
  }
@@ -4615,7 +4619,9 @@ export var UnifiedBookingSalesImpl = /*#__PURE__*/function (_BookingTicket) {
4615
4619
  durationStartTimesByProductId: _defineProperty({}, String(params.candidate.productId), [candidateStartTime])
4616
4620
  }, allowPosAvailabilityOverride ? {
4617
4621
  allowOutsideOperatingHoursForRequestedStartTimes: true
4618
- } : {}) : {}) : {})).flatMap(function (group) {
4622
+ } : {}) : {}) : {}), {
4623
+ allowSessionCustomRanges: allowPosAvailabilityOverride
4624
+ }).flatMap(function (group) {
4619
4625
  return group.ranges;
4620
4626
  });
4621
4627
  refreshedCandidateBase = refreshedRanges.find(function (candidate) {
@@ -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));
@@ -923,16 +929,28 @@ function getProductTimeRanges(projection, request = {}, runtimeOptions = {}) {
923
929
  };
924
930
  }
925
931
  if (product.kind === 'session' || product.kind === 'venue_slot') {
932
+ const fixedRanges = getSessionRangesForProduct(projection, product, dateRange);
933
+ const customRanges = [];
934
+ const customDurationMinutes = resolveRequestedSessionDurationMinutes(product, request, runtimeOptions.allowSessionCustomRanges === true);
935
+ const requestedStartTimes = resolveRequestedDurationStartTimes(product, request, runtimeOptions.allowSessionCustomRanges === true);
936
+ if (product.kind === 'session' && customDurationMinutes && dateRange.startDate === dateRange.endDate) {
937
+ requestedStartTimes.forEach(startTime => {
938
+ const start = toDateTimeInDate(dateRange.startDate, startTime, projection.meta.timezone);
939
+ if (!Number.isFinite(start)) return;
940
+ customRanges.push(createDurationTimeRange(product, start, customDurationMinutes, projection, fixedOffsetMinutes));
941
+ });
942
+ }
926
943
  return {
927
944
  productId: product.id,
928
945
  title: product.title,
929
946
  kind: product.kind,
930
947
  slotStepMinutes,
931
- ranges: getSessionRangesForProduct(projection, product, dateRange)
948
+ ranges: dedupeProductRanges([...fixedRanges, ...customRanges])
932
949
  };
933
950
  }
934
951
  const requiredGroups = (product.requirementGroups || []).filter(group => group.required !== false);
935
952
  const operatingRanges = buildOperatingRanges(projection, dateRange);
953
+ const operatingEndAt = dateRange.startDate === dateRange.endDate && operatingRanges.length > 0 ? formatDateTime(Math.max(...operatingRanges.map(range => range.end)), projection.meta.timezone, fixedOffsetMinutes) : undefined;
936
954
  const resourceRanges = requiredGroups.length ? requiredGroups.map(group => buildGroupWorkingRanges({
937
955
  projection,
938
956
  product,
@@ -999,6 +1017,9 @@ function getProductTimeRanges(projection, request = {}, runtimeOptions = {}) {
999
1017
  title: product.title,
1000
1018
  kind: product.kind,
1001
1019
  slotStepMinutes,
1020
+ ...(operatingEndAt ? {
1021
+ operatingEndAt
1022
+ } : {}),
1002
1023
  ranges: dedupeProductRanges(ranges)
1003
1024
  };
1004
1025
  });
@@ -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 {
@@ -243,6 +245,13 @@ export interface GetProductTimeRangesRequest {
243
245
  }
244
246
  export interface GetProductTimeRangesRuntimeOptions {
245
247
  evaluatedAt?: string;
248
+ /**
249
+ * Internal POS capability: allow explicit duration/start overrides to append
250
+ * a custom duration candidate for Session products. Fixed Session ranges are
251
+ * still returned unchanged. Callers outside the POS facade must leave this
252
+ * disabled.
253
+ */
254
+ allowSessionCustomRanges?: boolean;
246
255
  }
247
256
  export interface QueryAvailabilityBaseRequest {
248
257
  productIds?: AvailabilityId[];
@@ -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 | 3 | 5;
329
+ weekNum: 0 | 2 | 3 | 1 | 5 | 6 | 4;
330
330
  }[]>;
331
331
  submitTimeSlot(timeSlots: TimeSliceItem): void;
332
332
  private getScheduleDataByIds;
@@ -945,7 +945,7 @@ function buildBookingFromAvailabilitySelection(params) {
945
945
  const endScalar = (0, _localClock.localDateTimeToScalar)((0, _localClock.parseLocalDateTime)(bookingEndAt));
946
946
  const scheduleId = candidate.primaryScheduleRef?.scheduleId ?? assignments.find(assignment => assignment.scheduleId != null)?.scheduleId;
947
947
  const timeSlotId = candidate.primaryScheduleRef?.timeSlotId ?? assignments.find(assignment => assignment.timeSlotId != null)?.timeSlotId;
948
- if (product.kind === 'session' && scheduleId == null) {
948
+ if (product.kind === 'session' && candidate.source === 'session_schedule' && scheduleId == null) {
949
949
  throw new _ResourcePlanner.AvailabilityError('REVALIDATION_FAILED', 'session 候选缺少真实 schedule identity', {
950
950
  productId: product.id,
951
951
  candidateKey: candidate.key,
@@ -961,7 +961,9 @@ function buildBookingFromAvailabilitySelection(params) {
961
961
  end_time: bookingEndAt.slice(11, 16),
962
962
  duration: Math.max(1, Math.trunc((endScalar - startScalar) / (60 * 1000))),
963
963
  like_status: 'common',
964
- schedule_id: scheduleId ?? 0,
964
+ ...(product.kind === 'session' && candidate.source === 'duration_window' ? {} : {
965
+ schedule_id: scheduleId ?? 0
966
+ }),
965
967
  ...(normalizedHolder ? {
966
968
  holder: normalizedHolder
967
969
  } : {}),
@@ -2809,14 +2811,16 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
2809
2811
  projectionEntry
2810
2812
  } = await this.ensureAvailabilityContextProjection(contextId, 'get_product_time_ranges');
2811
2813
  const contextVersion = context.activeVersion;
2812
- const allowOutsideOperatingHoursForRequestedStartTimes = String(this.otherParams?.platform ?? '').trim().toLowerCase() === 'pos' && Object.values(request.durationStartTimesByProductId || {}).some(startTimes => Array.isArray(startTimes) && startTimes.length > 0);
2814
+ const isPosAvailabilityRequest = String(this.otherParams?.platform ?? '').trim().toLowerCase() === 'pos';
2815
+ const allowOutsideOperatingHoursForRequestedStartTimes = isPosAvailabilityRequest && Object.values(request.durationStartTimesByProductId || {}).some(startTimes => Array.isArray(startTimes) && startTimes.length > 0);
2813
2816
  return (0, _ResourcePlanner.getProductTimeRanges)(projectionEntry.projection, {
2814
2817
  ...request,
2815
2818
  ...(allowOutsideOperatingHoursForRequestedStartTimes ? {
2816
2819
  allowOutsideOperatingHoursForRequestedStartTimes: true
2817
2820
  } : {})
2818
2821
  }, {
2819
- evaluatedAt: this.getAvailabilityRuntimeDateTime()
2822
+ evaluatedAt: this.getAvailabilityRuntimeDateTime(),
2823
+ allowSessionCustomRanges: isPosAvailabilityRequest
2820
2824
  }).map(group => ({
2821
2825
  ...group,
2822
2826
  ranges: group.ranges.map(candidate => this.decorateAvailabilityCandidate(context.contextId, contextVersion, candidate))
@@ -3087,6 +3091,8 @@ class UnifiedBookingSalesImpl extends _BookingTicket.BookingTicket {
3087
3091
  } : {})
3088
3092
  } : {})
3089
3093
  } : {})
3094
+ }, {
3095
+ allowSessionCustomRanges: allowPosAvailabilityOverride
3090
3096
  }).flatMap(group => group.ranges);
3091
3097
  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);
3092
3098
  if (!refreshedCandidateBase) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "private": false,
3
3
  "name": "@pisell/pisellos",
4
- "version": "2.2.297",
4
+ "version": "2.2.299",
5
5
  "description": "一个可扩展的前端模块化SDK框架,支持插件系统",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",