/** * 时间范围验证器 * 检查当前时间是否在指定的时间范围内(支持工作日限制) */ 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;