5
This commit is contained in:
2026-03-23 09:32:39 +08:00
parent 6db9f596c6
commit e643596b60

View File

@ -2201,14 +2201,18 @@ export default function App() {
return hasNonEmptyRuleValue(nodeLike?.startDateRule) || hasNonEmptyRuleValue(nodeLike?.dateAdjustmentRule);
};
// 内部工作时间计算函数
const addInternalBusinessTime = (startDate: Date, businessDays: number, weekendDays: number[] = [], excludedDates: string[] = []): Date => {
const addBusinessTimeWithWindow = (
startDate: Date,
businessDays: number,
weekendDays: number[] = [],
excludedDates: string[] = [],
startHour: number,
endHour: number
): Date => {
const result = new Date(startDate);
if (!businessDays || businessDays === 0) return result;
const isNegative = businessDays < 0;
const absDays = Math.abs(businessDays);
// 处理整数天(仅计入工作日)
const wholeDays = Math.floor(absDays);
let processedDays = 0;
while (processedDays < wholeDays) {
@ -2217,110 +2221,65 @@ export default function App() {
processedDays++;
}
}
// 处理小数部分按9小时工作制
const fractionalDays = absDays - wholeDays;
if (fractionalDays > 0) {
const workingHours = fractionalDays * 9; // 内部按9小时工作制
let currentHour = result.getHours();
let currentMinute = result.getMinutes();
const workMinutes = Math.round(fractionalDays * (endHour - startHour) * 60);
const startMinutes = startHour * 60;
const endMinutes = endHour * 60;
const currentMinutes = result.getHours() * 60 + result.getMinutes();
if (!isNegative) {
// 正向:确保在工作时间内开始
if (currentHour < 9) {
currentHour = 9;
currentMinute = 0;
} else if (currentHour >= 18) {
// 跳到下一个工作日的9:00
let cursor = currentMinutes;
if (cursor < startMinutes) {
cursor = startMinutes;
} else if (cursor >= endMinutes) {
result.setDate(result.getDate() + 1);
while (!isBusinessDay(result, weekendDays, excludedDates)) {
result.setDate(result.getDate() + 1);
}
currentHour = 9;
currentMinute = 0;
cursor = startMinutes;
}
const totalMinutes = currentHour * 60 + currentMinute + workingHours * 60;
const finalHour = Math.floor(totalMinutes / 60);
const finalMinute = totalMinutes % 60;
if (finalHour >= 18) {
const overflowHours = finalHour - 18;
const overflowMinutes = finalMinute;
let total = cursor + workMinutes;
while (total >= endMinutes) {
const overflow = total - endMinutes;
result.setDate(result.getDate() + 1);
while (!isBusinessDay(result, weekendDays, excludedDates)) {
result.setDate(result.getDate() + 1);
}
result.setHours(9 + overflowHours, overflowMinutes, 0, 0);
} else {
result.setHours(finalHour, finalMinute, 0, 0);
total = startMinutes + overflow;
}
result.setHours(Math.floor(total / 60), total % 60, 0, 0);
} else {
// 负向:从当前时间向前回退工作小时,规范到工作时间窗口
if (currentHour > 18) {
// 当天超过18:00先归位到18:00
result.setHours(18, 0, 0, 0);
currentHour = 18;
currentMinute = 0;
} else if (currentHour < 9) {
// 早于9:00跳到前一个工作日的18:00
let cursor = currentMinutes;
if (cursor > endMinutes) {
cursor = endMinutes;
} else if (cursor <= startMinutes) {
result.setDate(result.getDate() - 1);
while (!isBusinessDay(result, weekendDays, excludedDates)) {
result.setDate(result.getDate() - 1);
}
result.setHours(18, 0, 0, 0);
currentHour = 18;
currentMinute = 0;
cursor = endMinutes;
}
const totalMinutes = currentHour * 60 + currentMinute - workingHours * 60;
if (totalMinutes >= 9 * 60) {
const finalHour = Math.floor(totalMinutes / 60);
const finalMinute = totalMinutes % 60;
result.setHours(finalHour, finalMinute, 0, 0);
} else {
// 需要跨到前一个工作日,计算欠缺分钟数
let deficit = 9 * 60 - totalMinutes; // 需要从前一工作日的18:00再退回的分钟数
// 跳到前一个工作日
let total = cursor - workMinutes;
while (total < startMinutes) {
const deficit = startMinutes - total;
result.setDate(result.getDate() - 1);
while (!isBusinessDay(result, weekendDays, excludedDates)) {
result.setDate(result.getDate() - 1);
}
// 从18:00开始退 deficit 分钟
result.setHours(18, 0, 0, 0);
result.setMinutes(result.getMinutes() - deficit);
total = endMinutes - deficit;
}
result.setHours(Math.floor(total / 60), total % 60, 0, 0);
}
}
return result;
};
// 添加工作日 - 使用表格配置的休息日与节点自定义跳过日期
const addInternalBusinessTime = (startDate: Date, businessDays: number, weekendDays: number[] = [], excludedDates: string[] = []): Date => {
return addBusinessTimeWithWindow(startDate, businessDays, weekendDays, excludedDates, 9, 18);
};
const addBusinessDaysWithHolidays = (startDate: Date, businessDays: number, weekendDays: number[] = [], excludedDates: string[] = []): Date => {
const result = new Date(startDate);
if (!businessDays || businessDays === 0) return result;
const isNegative = businessDays < 0;
const absDays = Math.abs(businessDays);
let processedDays = 0;
// 先处理整数工作日
const wholeDays = Math.floor(absDays);
while (processedDays < wholeDays) {
result.setDate(result.getDate() + (isNegative ? -1 : 1));
if (isBusinessDay(result, weekendDays, excludedDates)) {
processedDays++;
}
}
// 再处理小数部分按24小时制
const fractionalDays = absDays - wholeDays;
if (fractionalDays > 0) {
const hours = fractionalDays * 24;
result.setHours(result.getHours() + (isNegative ? -hours : hours));
}
return result;
return addBusinessTimeWithWindow(startDate, businessDays, weekendDays, excludedDates, 0, 24);
};