@pisell/pisellos 2.0.26 → 2.0.27
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.
|
@@ -19,79 +19,63 @@ export function calculateResourceAvailableTime(_ref) {
|
|
|
19
19
|
return dayjs(time.start_at).isSame(dayjs(timeSlots.start_at), 'day');
|
|
20
20
|
});
|
|
21
21
|
if (matchingTimes.length === 0) return 0;
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
// 计算所有时间段与目标时间槽的重叠部分
|
|
24
|
+
var overlaps = [];
|
|
23
25
|
var _iterator = _createForOfIteratorHelper(matchingTimes),
|
|
24
26
|
_step;
|
|
25
27
|
try {
|
|
26
28
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
27
|
-
var _time$event_list;
|
|
28
29
|
var time = _step.value;
|
|
29
30
|
// 计算实际重叠的时间段
|
|
30
31
|
var overlapStart = dayjs(time.start_at).isAfter(dayjs(timeSlots.start_at)) ? dayjs(time.start_at) : dayjs(timeSlots.start_at);
|
|
31
32
|
var overlapEnd = dayjs(time.end_at).isBefore(dayjs(timeSlots.end_at)) ? dayjs(time.end_at) : dayjs(timeSlots.end_at);
|
|
32
33
|
|
|
33
|
-
//
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// 处理时间段内的每个预约事件
|
|
40
|
-
var currentTime = overlapStart;
|
|
41
|
-
var _iterator2 = _createForOfIteratorHelper(time.event_list),
|
|
42
|
-
_step2;
|
|
43
|
-
try {
|
|
44
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
45
|
-
var event = _step2.value;
|
|
46
|
-
var eventStart = dayjs(event.start_at);
|
|
47
|
-
var eventEnd = dayjs(event.end_at);
|
|
48
|
-
|
|
49
|
-
// 如果事件在当前时间之前,跳过
|
|
50
|
-
if (eventEnd.isBefore(currentTime)) continue;
|
|
51
|
-
|
|
52
|
-
// 如果事件开始时间在重叠结束时间之后,可以添加剩余时间
|
|
53
|
-
if (eventStart.isAfter(overlapEnd)) {
|
|
54
|
-
totalAvailableMinutes += overlapEnd.diff(currentTime, 'minute');
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// 如果事件开始时间在当前时间之后,添加事件开始前的时间
|
|
59
|
-
if (eventStart.isAfter(currentTime)) {
|
|
60
|
-
totalAvailableMinutes += eventStart.diff(currentTime, 'minute');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 对于单个预约类型,整个事件时间都是不可用的
|
|
64
|
-
if (resource.resourceType === 'single') {
|
|
65
|
-
currentTime = eventEnd;
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// 对于多个预约类型,检查容量
|
|
70
|
-
if (resource.resourceType === 'multiple') {
|
|
71
|
-
var remainingCapacity = (resource.capacity || 0) - (event.pax || 0);
|
|
72
|
-
if (remainingCapacity >= currentCapacity) {
|
|
73
|
-
// 如果剩余容量足够,这个时间段仍然是可用的
|
|
74
|
-
totalAvailableMinutes += eventEnd.diff(eventStart, 'minute');
|
|
75
|
-
}
|
|
76
|
-
currentTime = eventEnd;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// 添加最后一个事件之后的剩余时间
|
|
81
|
-
} catch (err) {
|
|
82
|
-
_iterator2.e(err);
|
|
83
|
-
} finally {
|
|
84
|
-
_iterator2.f();
|
|
85
|
-
}
|
|
86
|
-
if (currentTime.isBefore(overlapEnd)) {
|
|
87
|
-
totalAvailableMinutes += overlapEnd.diff(currentTime, 'minute');
|
|
34
|
+
// 只有当重叠时间段有效时才添加
|
|
35
|
+
if (overlapStart.isBefore(overlapEnd)) {
|
|
36
|
+
overlaps.push({
|
|
37
|
+
start: overlapStart,
|
|
38
|
+
end: overlapEnd
|
|
39
|
+
});
|
|
88
40
|
}
|
|
89
41
|
}
|
|
42
|
+
|
|
43
|
+
// 合并重叠的时间段,计算并集
|
|
90
44
|
} catch (err) {
|
|
91
45
|
_iterator.e(err);
|
|
92
46
|
} finally {
|
|
93
47
|
_iterator.f();
|
|
94
48
|
}
|
|
49
|
+
if (overlaps.length === 0) return 0;
|
|
50
|
+
|
|
51
|
+
// 按开始时间排序
|
|
52
|
+
overlaps.sort(function (a, b) {
|
|
53
|
+
return a.start.diff(b.start);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// 合并重叠的时间段
|
|
57
|
+
var merged = [];
|
|
58
|
+
var current = overlaps[0];
|
|
59
|
+
for (var i = 1; i < overlaps.length; i++) {
|
|
60
|
+
var next = overlaps[i];
|
|
61
|
+
|
|
62
|
+
// 如果当前时间段与下一个时间段重叠或相邻,则合并
|
|
63
|
+
if (current.end.isSameOrAfter(next.start)) {
|
|
64
|
+
current.end = current.end.isAfter(next.end) ? current.end : next.end;
|
|
65
|
+
} else {
|
|
66
|
+
// 不重叠,添加当前时间段到结果中,开始处理下一个
|
|
67
|
+
merged.push(current);
|
|
68
|
+
current = next;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
merged.push(current);
|
|
72
|
+
|
|
73
|
+
// 计算所有合并后时间段的总时长
|
|
74
|
+
var totalAvailableMinutes = 0;
|
|
75
|
+
for (var _i = 0, _merged = merged; _i < _merged.length; _i++) {
|
|
76
|
+
var segment = _merged[_i];
|
|
77
|
+
totalAvailableMinutes += segment.end.diff(segment.start, 'minute');
|
|
78
|
+
}
|
|
95
79
|
return totalAvailableMinutes;
|
|
96
80
|
}
|
|
97
81
|
|
|
@@ -113,11 +97,11 @@ export function findFastestAvailableResource(_ref2) {
|
|
|
113
97
|
var fastestResources = [];
|
|
114
98
|
|
|
115
99
|
// 遍历所有资源,找到最快可用的时间点
|
|
116
|
-
var
|
|
117
|
-
|
|
100
|
+
var _iterator2 = _createForOfIteratorHelper(resources),
|
|
101
|
+
_step2;
|
|
118
102
|
try {
|
|
119
|
-
for (
|
|
120
|
-
var _resource =
|
|
103
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
104
|
+
var _resource = _step2.value;
|
|
121
105
|
// 获取资源当天的时间段
|
|
122
106
|
var todayTimes = _resource.times.filter(function (time) {
|
|
123
107
|
return dayjs(time.start_at).isSame(currentTime, 'day');
|
|
@@ -130,11 +114,11 @@ export function findFastestAvailableResource(_ref2) {
|
|
|
130
114
|
});
|
|
131
115
|
|
|
132
116
|
// 找到第一个可用的时间段
|
|
133
|
-
var
|
|
134
|
-
|
|
117
|
+
var _iterator3 = _createForOfIteratorHelper(todayTimes),
|
|
118
|
+
_step3;
|
|
135
119
|
try {
|
|
136
120
|
var _loop = function _loop() {
|
|
137
|
-
var time =
|
|
121
|
+
var time = _step3.value;
|
|
138
122
|
var startTime = dayjs(time.start_at);
|
|
139
123
|
|
|
140
124
|
// 如果开始时间在当前时间之前,跳过
|
|
@@ -142,9 +126,9 @@ export function findFastestAvailableResource(_ref2) {
|
|
|
142
126
|
|
|
143
127
|
// 检查这个时间段是否可用
|
|
144
128
|
if (_resource.resourceType === 'single') {
|
|
145
|
-
var _time$
|
|
129
|
+
var _time$event_list;
|
|
146
130
|
// 单个预约类型:检查是否有预约
|
|
147
|
-
var hasBooking = (_time$
|
|
131
|
+
var hasBooking = (_time$event_list = time.event_list) === null || _time$event_list === void 0 ? void 0 : _time$event_list.some(function (event) {
|
|
148
132
|
return dayjs(event.start_at).isSame(startTime);
|
|
149
133
|
});
|
|
150
134
|
if (!hasBooking) {
|
|
@@ -158,10 +142,10 @@ export function findFastestAvailableResource(_ref2) {
|
|
|
158
142
|
return 1; // break
|
|
159
143
|
}
|
|
160
144
|
} else {
|
|
161
|
-
var _time$
|
|
145
|
+
var _time$event_list2;
|
|
162
146
|
// 多个预约类型:检查容量
|
|
163
147
|
var totalCapacity = _resource.capacity || 0;
|
|
164
|
-
var usedCapacity = ((_time$
|
|
148
|
+
var usedCapacity = ((_time$event_list2 = time.event_list) === null || _time$event_list2 === void 0 ? void 0 : _time$event_list2.reduce(function (sum, event) {
|
|
165
149
|
return dayjs(event.start_at).isSame(startTime) ? sum + (event.pax || 0) : sum;
|
|
166
150
|
}, 0)) || 0;
|
|
167
151
|
var remainingCapacity = totalCapacity - usedCapacity;
|
|
@@ -178,23 +162,23 @@ export function findFastestAvailableResource(_ref2) {
|
|
|
178
162
|
}
|
|
179
163
|
},
|
|
180
164
|
_ret;
|
|
181
|
-
for (
|
|
165
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
182
166
|
_ret = _loop();
|
|
183
167
|
if (_ret === 0) continue;
|
|
184
168
|
if (_ret === 1) break;
|
|
185
169
|
}
|
|
186
170
|
} catch (err) {
|
|
187
|
-
|
|
171
|
+
_iterator3.e(err);
|
|
188
172
|
} finally {
|
|
189
|
-
|
|
173
|
+
_iterator3.f();
|
|
190
174
|
}
|
|
191
175
|
}
|
|
192
176
|
|
|
193
177
|
// 如果没有找到可用资源,返回null
|
|
194
178
|
} catch (err) {
|
|
195
|
-
|
|
179
|
+
_iterator2.e(err);
|
|
196
180
|
} finally {
|
|
197
|
-
|
|
181
|
+
_iterator2.f();
|
|
198
182
|
}
|
|
199
183
|
if (!fastestTime || fastestResources.length === 0) return null;
|
|
200
184
|
|
|
@@ -204,8 +188,8 @@ export function findFastestAvailableResource(_ref2) {
|
|
|
204
188
|
// 如果有多个最快可用的资源,比较它们的空闲时间
|
|
205
189
|
var maxIdleTime = 0;
|
|
206
190
|
var selectedResource = null;
|
|
207
|
-
for (var
|
|
208
|
-
var resource = _fastestResources[
|
|
191
|
+
for (var _i2 = 0, _fastestResources = fastestResources; _i2 < _fastestResources.length; _i2++) {
|
|
192
|
+
var resource = _fastestResources[_i2];
|
|
209
193
|
var idleTime = calculateResourceAvailableTime({
|
|
210
194
|
resource: resource,
|
|
211
195
|
timeSlots: {
|
|
@@ -39,49 +39,38 @@ function calculateResourceAvailableTime({
|
|
|
39
39
|
timeSlots,
|
|
40
40
|
currentCapacity = 1
|
|
41
41
|
}) {
|
|
42
|
-
var _a;
|
|
43
42
|
const matchingTimes = resource.times.filter((time) => {
|
|
44
43
|
return (0, import_dayjs.default)(time.start_at).isSame((0, import_dayjs.default)(timeSlots.start_at), "day");
|
|
45
44
|
});
|
|
46
45
|
if (matchingTimes.length === 0)
|
|
47
46
|
return 0;
|
|
48
|
-
|
|
47
|
+
const overlaps = [];
|
|
49
48
|
for (const time of matchingTimes) {
|
|
50
49
|
const overlapStart = (0, import_dayjs.default)(time.start_at).isAfter((0, import_dayjs.default)(timeSlots.start_at)) ? (0, import_dayjs.default)(time.start_at) : (0, import_dayjs.default)(timeSlots.start_at);
|
|
51
50
|
const overlapEnd = (0, import_dayjs.default)(time.end_at).isBefore((0, import_dayjs.default)(timeSlots.end_at)) ? (0, import_dayjs.default)(time.end_at) : (0, import_dayjs.default)(timeSlots.end_at);
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
continue;
|
|
51
|
+
if (overlapStart.isBefore(overlapEnd)) {
|
|
52
|
+
overlaps.push({ start: overlapStart, end: overlapEnd });
|
|
55
53
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (resource.resourceType === "single") {
|
|
70
|
-
currentTime = eventEnd;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (resource.resourceType === "multiple") {
|
|
74
|
-
const remainingCapacity = (resource.capacity || 0) - (event.pax || 0);
|
|
75
|
-
if (remainingCapacity >= currentCapacity) {
|
|
76
|
-
totalAvailableMinutes += eventEnd.diff(eventStart, "minute");
|
|
77
|
-
}
|
|
78
|
-
currentTime = eventEnd;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (currentTime.isBefore(overlapEnd)) {
|
|
82
|
-
totalAvailableMinutes += overlapEnd.diff(currentTime, "minute");
|
|
54
|
+
}
|
|
55
|
+
if (overlaps.length === 0)
|
|
56
|
+
return 0;
|
|
57
|
+
overlaps.sort((a, b) => a.start.diff(b.start));
|
|
58
|
+
const merged = [];
|
|
59
|
+
let current = overlaps[0];
|
|
60
|
+
for (let i = 1; i < overlaps.length; i++) {
|
|
61
|
+
const next = overlaps[i];
|
|
62
|
+
if (current.end.isSameOrAfter(next.start)) {
|
|
63
|
+
current.end = current.end.isAfter(next.end) ? current.end : next.end;
|
|
64
|
+
} else {
|
|
65
|
+
merged.push(current);
|
|
66
|
+
current = next;
|
|
83
67
|
}
|
|
84
68
|
}
|
|
69
|
+
merged.push(current);
|
|
70
|
+
let totalAvailableMinutes = 0;
|
|
71
|
+
for (const segment of merged) {
|
|
72
|
+
totalAvailableMinutes += segment.end.diff(segment.start, "minute");
|
|
73
|
+
}
|
|
85
74
|
return totalAvailableMinutes;
|
|
86
75
|
}
|
|
87
76
|
function findFastestAvailableResource({
|