@pisell/pisellos
Version:
一个可扩展的前端模块化SDK框架,支持插件系统
167 lines (165 loc) • 6.61 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/solution/BookingByStep/utils/timeslots.ts
var timeslots_exports = {};
__export(timeslots_exports, {
calculateResourceAvailableTime: () => calculateResourceAvailableTime,
filterConditionTimeSlots: () => filterConditionTimeSlots,
findFastestAvailableResource: () => findFastestAvailableResource
});
module.exports = __toCommonJS(timeslots_exports);
var import_dayjs = __toESM(require("dayjs"));
function calculateResourceAvailableTime({
resource,
timeSlots,
currentCapacity = 1
}) {
const matchingTimes = resource.times.filter((time) => {
return (0, import_dayjs.default)(time.start_at).isSame((0, import_dayjs.default)(timeSlots.start_at), "day");
});
if (matchingTimes.length === 0)
return 0;
const overlaps = [];
for (const time of matchingTimes) {
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);
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);
if (overlapStart.isBefore(overlapEnd)) {
overlaps.push({ start: overlapStart, end: overlapEnd });
}
}
if (overlaps.length === 0)
return 0;
overlaps.sort((a, b) => a.start.diff(b.start));
const merged = [];
let current = overlaps[0];
for (let i = 1; i < overlaps.length; i++) {
const next = overlaps[i];
if (current.end.isSameOrAfter(next.start)) {
current.end = current.end.isAfter(next.end) ? current.end : next.end;
} else {
merged.push(current);
current = next;
}
}
merged.push(current);
let totalAvailableMinutes = 0;
for (const segment of merged) {
totalAvailableMinutes += segment.end.diff(segment.start, "minute");
}
return totalAvailableMinutes;
}
function findFastestAvailableResource({
resources,
currentCapacity = 1,
countMap = {}
}) {
var _a, _b;
const currentTime = (0, import_dayjs.default)();
let fastestTime = null;
let fastestResources = [];
for (const resource of resources) {
const todayTimes = resource.times.filter((time) => {
return (0, import_dayjs.default)(time.start_at).isSame(currentTime, "day");
});
if (todayTimes.length === 0)
continue;
todayTimes.sort((a, b) => {
return (0, import_dayjs.default)(a.start_at).diff((0, import_dayjs.default)(b.start_at));
});
for (const time of todayTimes) {
const startTime = (0, import_dayjs.default)(time.start_at);
if (startTime.isBefore(currentTime))
continue;
if (resource.resourceType === "single") {
const hasBooking = (_a = time.event_list) == null ? void 0 : _a.some((event) => {
return (0, import_dayjs.default)(event.start_at).isSame(startTime);
});
if (!hasBooking) {
if (!fastestTime || startTime.isSame(fastestTime)) {
fastestTime = startTime;
fastestResources.push(resource);
} else if (startTime.isBefore(fastestTime)) {
fastestTime = startTime;
fastestResources = [resource];
}
break;
}
} else {
const totalCapacity = resource.capacity || 0;
const usedCapacity = ((_b = time.event_list) == null ? void 0 : _b.reduce((sum, event) => {
return (0, import_dayjs.default)(event.start_at).isSame(startTime) ? sum + (event.pax || 0) : sum;
}, 0)) || 0;
const remainingCapacity = totalCapacity - usedCapacity;
if (remainingCapacity >= (countMap[resource.id] || 0) + currentCapacity) {
if (!fastestTime || startTime.isSame(fastestTime)) {
fastestTime = startTime;
fastestResources.push(resource);
} else if (startTime.isBefore(fastestTime)) {
fastestTime = startTime;
fastestResources = [resource];
}
break;
}
}
}
}
if (!fastestTime || fastestResources.length === 0)
return null;
if (fastestResources.length === 1)
return fastestResources[0];
let maxIdleTime = 0;
let selectedResource = null;
for (const resource of fastestResources) {
const idleTime = calculateResourceAvailableTime({
resource,
timeSlots: {
start_time: fastestTime.format("HH:mm"),
end_time: fastestTime.format("HH:mm"),
start_at: fastestTime,
end_at: fastestTime
},
currentCapacity: (countMap[resource.id] || 0) + currentCapacity
});
if (idleTime > maxIdleTime) {
maxIdleTime = idleTime;
selectedResource = resource;
}
}
return selectedResource;
}
function filterConditionTimeSlots(times, startTime, endTime) {
return times.filter((n) => {
return !(0, import_dayjs.default)(n.start_at).isAfter((0, import_dayjs.default)(startTime)) && !(0, import_dayjs.default)(n.end_at).isBefore((0, import_dayjs.default)(endTime));
});
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
calculateResourceAvailableTime,
filterConditionTimeSlots,
findFastestAvailableResource
});