5
5
This commit is contained in:
119
src/App.tsx
119
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);
|
||||
total = startMinutes + overflow;
|
||||
}
|
||||
result.setHours(Math.floor(total / 60), total % 60, 0, 0);
|
||||
} else {
|
||||
result.setHours(finalHour, finalMinute, 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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user