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