const node_schedule = require("node-schedule"); const config = require('./config.js'); const deviceManager = require('./deviceManager.js'); const command = require('./command.js'); const db = require('../dbProxy'); /** * 定时任务管理器(简化版) * 管理所有定时任务的创建和销毁 */ class ScheduledJobs { constructor(components, taskHandlers) { this.taskQueue = components.taskQueue; this.taskHandlers = taskHandlers; this.jobs = []; } /** * 启动所有定时任务 */ start() { // 每天凌晨重置统计数据 const resetJob = node_schedule.scheduleJob(config.schedules.dailyReset, () => { this.resetDailyStats(); }); this.jobs.push(resetJob); // 启动心跳检查定时任务(每分钟检查一次) const monitoringJob = node_schedule.scheduleJob(config.schedules.monitoringInterval, async () => { await deviceManager.checkHeartbeatStatus().catch(error => { console.error('[定时任务] 检查心跳状态失败:', error); }); }); this.jobs.push(monitoringJob); // 执行自动投递任务 const autoDeliverJob = node_schedule.scheduleJob(config.schedules.autoDeliver, () => { this.autoDeliverTask(); }); this.jobs.push(autoDeliverJob); console.log('[定时任务] 已启动自动投递任务'); } /** * 重置每日统计 */ resetDailyStats() { console.log('[定时任务] 重置每日统计数据'); try { deviceManager.resetAllDailyCounters(); console.log('[定时任务] 每日统计重置完成'); } catch (error) { console.error('[定时任务] 重置统计失败:', error); } } /** * 清理过期数据 */ cleanupCaches() { console.log('[定时任务] 开始清理过期数据'); try { deviceManager.cleanupOfflineDevices(config.monitoring.offlineThreshold); command.cleanupExpiredCommands(30); console.log('[定时任务] 数据清理完成'); } catch (error) { console.error('[定时任务] 数据清理失败:', error); } } /** * 自动投递任务 */ async autoDeliverTask() { const now = new Date(); console.log(`[自动投递] ${now.toLocaleString()} 开始执行自动投递任务`); // 检查是否在工作时间 if (!config.isWorkingHours()) { console.log(`[自动投递] 非工作时间,跳过执行`); return; } try { // 从 device_status 查询所有在线且已登录的设备 const models = db.models; const { device_status, pla_account, op } = models; const onlineDevices = await device_status.findAll({ where: { isOnline: true, isLoggedIn: true }, attributes: ['sn_code', 'accountName', 'platform'] }); if (!onlineDevices || onlineDevices.length === 0) { console.log('[自动投递] 没有在线且已登录的设备'); return; } // 获取这些在线设备对应的账号配置(只获取启用且开启自动投递的账号) const snCodes = onlineDevices.map(device => device.sn_code); const pla_users = await pla_account.findAll({ where: { sn_code: { [op.in]: snCodes }, is_delete: 0, is_enabled: 1, // 只获取启用的账号 auto_deliver: 1 } }); if (!pla_users || pla_users.length === 0) { console.log('[自动投递] 没有启用且开启自动投递的账号'); return; } console.log(`[自动投递] 找到 ${pla_users.length} 个可用账号`); // 为每个设备添加自动投递任务到队列 for (const pl_user of pla_users) { const userData = pl_user.toJSON(); // 检查设备调度策略 const canExecute = deviceManager.canExecuteOperation(userData.sn_code, 'deliver'); if (!canExecute.allowed) { console.log(`[自动投递] 设备 ${userData.sn_code} 不满足执行条件: ${canExecute.reason}`); continue; } // 添加自动投递任务到队列 await this.taskQueue.addTask(userData.sn_code, { taskType: 'auto_deliver', taskName: `自动投递 - ${userData.keyword || '默认关键词'}`, taskParams: { keyword: userData.keyword || '', platform: userData.platform_type || 'boss', pageCount: 3, // 默认值 maxCount: 10, // 默认值 filterRules: { minSalary: userData.min_salary || 0, maxSalary: userData.max_salary || 0, keywords: [], excludeKeywords: [] } }, priority: config.getTaskPriority('auto_deliver') || 6 }); console.log(`[自动投递] 已为设备 ${userData.sn_code} 添加自动投递任务,关键词: ${userData.keyword || '默认'}`); } console.log('[自动投递] 任务添加完成'); } catch (error) { console.error('[自动投递] 执行失败:', error); } } } module.exports = ScheduledJobs;