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);
|
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user