// 全局任务超时服务 import http from '../api/http'; // 任务超时服务类 class TaskTimeoutService { constructor() { this.taskStatusMap = {}; // 存储任务状态开始时间 this.taskTimeoutMinutes = 10; // 任务超时时间,单位为分钟,调整为10分钟便于测试 this.checkTaskStatusTimer = null; this.apiTaskData = []; // 存储通过API获取的任务数据 this.apiRefreshTimer = null; // API数据刷新定时器 this.apiRefreshInterval = 10000; // API数据刷新间隔,调整为10秒便于测试 } // 初始化任务超时服务 init(app) { // 设置定时器,每10秒检查一次,调整为便于测试的频率 this.checkTaskStatusTimer = setInterval(() => { this.checkTaskStatus(); }, 10000); // 设置API数据刷新定时器,每10秒刷新一次任务数据 this.apiRefreshTimer = setInterval(() => { this.refreshTaskDataFromApi(); }, this.apiRefreshInterval); // 初始刷新一次任务数据 this.refreshTaskDataFromApi(); // 保存定时器引用,方便后续清理 if (app && app.config) { app.config.globalProperties.$global.taskTimeoutTimer = this.checkTaskStatusTimer; app.config.globalProperties.$global.taskTimeoutApiTimer = this.apiRefreshTimer; } // 方便手动测试,将check方法挂载到window对象 window.testTaskTimeout = () => { this.checkTaskStatus(); }; } // 从API刷新任务数据 async refreshTaskDataFromApi() { try { // 构建查询参数,获取所有任务,不限制状态,在后续处理中过滤 const requestData = { Page: 1, Rows: 9999, Filter: [], Wheres: '', Sort: 'CreateDate', Order: 'desc' }; // 调用API获取任务数据 const apiData = await http.post('/api/Task/GetPageData', requestData); if (apiData && apiData.rows) { this.apiTaskData = apiData.rows; } else { this.apiTaskData = []; } } catch (error) { console.error('从API获取任务数据失败:', error); this.apiTaskData = []; } } // 检查任务状态 checkTaskStatus() { // 直接使用从API获取的数据 const allTaskData = this.apiTaskData || []; // 去重,确保每个任务只处理一次 const uniqueTaskData = []; const taskNumSet = new Set(); allTaskData.forEach(task => { if (task && task.taskNum && !taskNumSet.has(task.taskNum)) { uniqueTaskData.push(task); taskNumSet.add(task.taskNum); } }); if (uniqueTaskData.length === 0) { return; } const now = new Date(); // 获取全局对象 const globalObj = window.$global || {}; // 处理消息删除逻辑,重置对应任务的定时器 const deletedMessages = [...(globalObj.messageDeleted || [])]; if (deletedMessages.length > 0) { // 清空已处理的删除消息列表,避免重复处理 globalObj.messageDeleted = []; // 遍历被删除的消息ID,重置对应任务的定时器 deletedMessages.forEach(deletedId => { // 不需要从messageList中查找,因为消息已经被删除 // 直接处理任务状态重置 // 这里不做任何操作,因为消息删除是用户主动行为 // 我们只需要清空messageDeleted数组即可 }); } // 获取当前所有任务号和状态 const currentTaskStatuses = {}; uniqueTaskData.forEach(task => { currentTaskStatuses[task.taskNum] = task.taskStatus; }); // 检查任务状态 uniqueTaskData.forEach(task => { if (task.taskStatus === 210) { // 堆垛机执行中状态 if (!this.taskStatusMap[task.taskNum]) { this.taskStatusMap[task.taskNum] = now; } else { // 计算持续时间(分钟) const duration = (now - this.taskStatusMap[task.taskNum]) / 60000; if (duration >= this.taskTimeoutMinutes) { this.sendTaskWarningMessage(task, duration); delete this.taskStatusMap[task.taskNum]; } } } else { // 任务状态已改变,清除记录 delete this.taskStatusMap[task.taskNum]; } }); // 清除已解决的任务超时消息 this.clearResolvedTaskMessages(currentTaskStatuses); } // 清除已解决的任务超时消息 clearResolvedTaskMessages(currentTaskStatuses) { // 获取全局对象 const globalObj = window.$global || {}; // 获取全局消息列表 const globalMessageList = [...(globalObj.messageList || [])]; // 找出需要清除的任务超时消息 const taskTimeoutMessages = globalMessageList.filter(msg => msg.businessType === 'task_timeout'); // 遍历所有任务超时消息 taskTimeoutMessages.forEach(msg => { const taskNum = msg.taskNum; // 检查条件: // 1. 任务不在当前任务列表中(已完成或被移除) // 2. 任务在当前任务列表中,但状态已不再是堆垛机执行中 if (taskNum && (!currentTaskStatuses[taskNum] || currentTaskStatuses[taskNum] !== 210)) { // 任务已完成或状态已改变,清除该消息 // 但要确保只在消息仍然存在时才删除 if (globalObj.messageList && Array.isArray(globalObj.messageList)) { const index = globalObj.messageList.findIndex(m => m.id === msg.id); if (index !== -1) { globalObj.messageList.splice(index, 1); } } } }); } // 发送任务警告消息 sendTaskWarningMessage(task, duration) { // 创建唯一的消息ID const messageId = Date.now() + Math.random().toString(36).substr(2, 9); // 创建警告消息 const warningMessage = { id: messageId, title: '任务异常警告', message: `任务号 ${task.taskNum} 已在堆垛机执行中状态超过${Math.round(duration)}分钟,请及时处理!`, type: 'warning', businessType: 'task_timeout', taskNum: task.taskNum, createTime: new Date().toLocaleString() }; // 获取全局对象 const globalObj = window.$global || {}; // 检查是否已经存在相同的任务超时警告 const globalMessageList = globalObj.messageList || []; const hasExistingWarning = globalMessageList.some(msg => msg.businessType === 'task_timeout' && msg.taskNum === task.taskNum ); if (hasExistingWarning) return; // 发送消息到全局消息列表 try { if (globalObj.messageList) { globalObj.messageList.push(warningMessage); } } catch (error) { // 出错时使用浏览器原生alert作为最终备选 try { alert(`任务异常警告: 任务号 ${task.taskNum} 已在堆垛机执行中状态超过${Math.round(duration)}分钟,请及时处理!`); } catch (e) { // 忽略所有错误 } } } // 手动检查任务状态(用于外部调用) manualCheckTaskStatus() { this.checkTaskStatus(); } // 设置任务超时时间 setTaskTimeoutMinutes(minutes) { if (typeof minutes === 'number' && minutes > 0) { this.taskTimeoutMinutes = minutes; } } // 获取当前任务超时时间 getTaskTimeoutMinutes() { return this.taskTimeoutMinutes; } // 清理资源 cleanup() { if (this.checkTaskStatusTimer) { clearInterval(this.checkTaskStatusTimer); this.checkTaskStatusTimer = null; } if (this.apiRefreshTimer) { clearInterval(this.apiRefreshTimer); this.apiRefreshTimer = null; } this.taskStatusMap = {}; this.apiTaskData = []; delete window.testTaskTimeout; } } // 创建单例实例 const taskTimeoutService = new TaskTimeoutService(); export default taskTimeoutService;