Files
autoAiWorkSys/api/middleware/schedule/services/timeRangeValidator.js
张成 65833dd32d 11
2025-12-30 15:46:18 +08:00

159 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 时间范围验证器
* 检查当前时间是否在指定的时间范围内(支持工作日限制)
*/
class TimeRangeValidator {
/**
* 检查当前时间是否在指定的时间范围内
* @param {object} timeRange - 时间范围配置 {start_time: '09:00', end_time: '18:00', workdays_only: 1}
* @returns {{allowed: boolean, reason: string}} 检查结果
*/
static checkTimeRange(timeRange) {
if (!timeRange || !timeRange.start_time || !timeRange.end_time) {
return { allowed: true, reason: '未配置时间范围' };
}
const now = new Date();
const currentHour = now.getHours();
const currentMinute = now.getMinutes();
const currentTime = currentHour * 60 + currentMinute; // 转换为分钟数
// 解析开始时间和结束时间
const [startHour, startMinute] = timeRange.start_time.split(':').map(Number);
const [endHour, endMinute] = timeRange.end_time.split(':').map(Number);
const startTime = startHour * 60 + startMinute;
const endTime = endHour * 60 + endMinute;
// 检查是否仅工作日(使用宽松比较,兼容字符串和数字)
if (timeRange.workdays_only == 1) {
const dayOfWeek = now.getDay(); // 0=周日, 1=周一, ..., 6=周六
if (dayOfWeek === 0 || dayOfWeek === 6) {
return { allowed: false, reason: '当前是周末,不在允许的时间范围内' };
}
}
// 检查当前时间是否在时间范围内
if (startTime <= endTime) {
// 正常情况09:00 - 18:00
if (currentTime < startTime || currentTime >= endTime) {
const currentTimeStr = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
return {
allowed: false,
reason: `当前时间 ${currentTimeStr} 不在允许的时间范围内 (${timeRange.start_time} - ${timeRange.end_time})`
};
}
} else {
// 跨天情况22:00 - 06:00
if (currentTime < startTime && currentTime >= endTime) {
const currentTimeStr = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
return {
allowed: false,
reason: `当前时间 ${currentTimeStr} 不在允许的时间范围内 (${timeRange.start_time} - ${timeRange.end_time})`
};
}
}
return { allowed: true, reason: '在允许的时间范围内' };
}
/**
* 检查是否在工作时间内
* @param {string} startTime - 开始时间 '09:00'
* @param {string} endTime - 结束时间 '18:00'
* @returns {boolean}
*/
static isWithinWorkingHours(startTime = '09:00', endTime = '18:00') {
const result = this.checkTimeRange({
start_time: startTime,
end_time: endTime,
workdays_only: 0
});
return result.allowed;
}
/**
* 检查是否是工作日
* @returns {boolean}
*/
static isWorkingDay() {
const dayOfWeek = new Date().getDay();
return dayOfWeek !== 0 && dayOfWeek !== 6; // 非周六周日
}
/**
* 获取下一个可操作时间
* @param {object} timeRange - 时间范围配置
* @returns {Date|null} 下一个可操作时间,如果当前可操作则返回 null
*/
static getNextAvailableTime(timeRange) {
const check = this.checkTimeRange(timeRange);
if (check.allowed) {
return null; // 当前可操作
}
if (!timeRange || !timeRange.start_time) {
return null;
}
const now = new Date();
const [startHour, startMinute] = timeRange.start_time.split(':').map(Number);
// 如果是工作日限制且当前是周末
if (timeRange.workdays_only == 1) {
const dayOfWeek = now.getDay();
if (dayOfWeek === 0) {
// 周日,下一个可操作时间是周一
const nextTime = new Date(now);
nextTime.setDate(now.getDate() + 1);
nextTime.setHours(startHour, startMinute, 0, 0);
return nextTime;
} else if (dayOfWeek === 6) {
// 周六,下一个可操作时间是下周一
const nextTime = new Date(now);
nextTime.setDate(now.getDate() + 2);
nextTime.setHours(startHour, startMinute, 0, 0);
return nextTime;
}
}
// 计算下一个开始时间
const nextTime = new Date(now);
nextTime.setHours(startHour, startMinute, 0, 0);
// 如果已经过了今天的开始时间,则设置为明天
if (nextTime <= now) {
nextTime.setDate(now.getDate() + 1);
}
return nextTime;
}
/**
* 格式化剩余时间
* @param {object} timeRange - 时间范围配置
* @returns {string} 剩余时间描述
*/
static formatRemainingTime(timeRange) {
const nextTime = this.getNextAvailableTime(timeRange);
if (!nextTime) {
return '当前可操作';
}
const now = Date.now();
const diff = nextTime.getTime() - now;
const hours = Math.floor(diff / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
if (hours > 24) {
const days = Math.floor(hours / 24);
return `需要等待 ${days}${hours % 24} 小时`;
} else if (hours > 0) {
return `需要等待 ${hours} 小时 ${minutes} 分钟`;
} else {
return `需要等待 ${minutes} 分钟`;
}
}
}
module.exports = TimeRangeValidator;