diff --git a/src/App.tsx b/src/App.tsx index c1b84f5..d533676 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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); };