317 lines
10 KiB
JavaScript
317 lines
10 KiB
JavaScript
const Framework = require("../../framework/node-core-framework.js");
|
||
|
||
/**
|
||
* 任务管理控制器(客户端接口)
|
||
* 提供客户端调用的任务相关接口
|
||
*/
|
||
module.exports = {
|
||
/**
|
||
* @swagger
|
||
* /api/task/current:
|
||
* get:
|
||
* summary: 获取当前执行的任务
|
||
* description: 根据设备SN码获取当前正在执行的任务信息
|
||
* tags: [前端-任务管理]
|
||
* parameters:
|
||
* - in: query
|
||
* name: sn_code
|
||
* required: true
|
||
* schema:
|
||
* type: string
|
||
* description: 设备SN码
|
||
* example: 'GHJU'
|
||
* responses:
|
||
* 200:
|
||
* description: 获取成功
|
||
* content:
|
||
* application/json:
|
||
* schema:
|
||
* type: object
|
||
* properties:
|
||
* code:
|
||
* type: integer
|
||
* description: 状态码,0表示成功
|
||
* example: 0
|
||
* message:
|
||
* type: string
|
||
* description: 响应消息
|
||
* example: 'success'
|
||
* data:
|
||
* type: object
|
||
* nullable: true
|
||
* description: 当前任务信息,null表示没有正在执行的任务
|
||
* properties:
|
||
* taskId:
|
||
* type: integer
|
||
* description: 任务ID
|
||
* taskName:
|
||
* type: string
|
||
* description: 任务名称
|
||
* taskType:
|
||
* type: string
|
||
* description: 任务类型
|
||
* status:
|
||
* type: string
|
||
* description: 任务状态(running-执行中)
|
||
* progress:
|
||
* type: integer
|
||
* description: 任务进度(0-100)
|
||
* currentStep:
|
||
* type: string
|
||
* description: 当前步骤
|
||
* startTime:
|
||
* type: string
|
||
* description: 开始时间
|
||
*/
|
||
'GET /task/current': async (ctx) => {
|
||
try {
|
||
const { sn_code } = ctx.query || {};
|
||
|
||
if (!sn_code) {
|
||
return ctx.fail('请提供设备SN码');
|
||
}
|
||
|
||
const { task_status, op } = await Framework.getModels();
|
||
|
||
// 查询当前正在执行的任务(status = 'running')
|
||
const currentTask = await task_status.findOne({
|
||
where: {
|
||
sn_code: sn_code,
|
||
status: 'running'
|
||
},
|
||
order: [['id', 'DESC']] // 获取最新的任务
|
||
});
|
||
|
||
if (!currentTask) {
|
||
return ctx.success(null, '暂无执行中的任务');
|
||
}
|
||
|
||
const taskData = currentTask.toJSON();
|
||
|
||
return ctx.success({
|
||
taskId: taskData.id,
|
||
taskName: taskData.taskName || taskData.task_name || taskData.taskType || taskData.task_type || '未知任务',
|
||
taskType: taskData.taskType || taskData.task_type,
|
||
status: 'running',
|
||
progress: taskData.progress || 0,
|
||
currentStep: taskData.currentStep || taskData.current_step || '',
|
||
startTime: taskData.startTime || taskData.start_time || taskData.created_time
|
||
});
|
||
} catch (error) {
|
||
console.error('[任务管理] 获取当前任务失败:', error);
|
||
return ctx.fail('获取当前任务失败: ' + (error.message || '未知错误'));
|
||
}
|
||
},
|
||
|
||
/**
|
||
* @swagger
|
||
* /api/task/pending:
|
||
* get:
|
||
* summary: 获取待执行的任务列表
|
||
* description: 根据设备SN码获取待执行的任务列表
|
||
* tags: [前端-任务管理]
|
||
* parameters:
|
||
* - in: query
|
||
* name: sn_code
|
||
* required: true
|
||
* schema:
|
||
* type: string
|
||
* description: 设备SN码
|
||
* example: 'GHJU'
|
||
* - in: query
|
||
* name: limit
|
||
* required: false
|
||
* schema:
|
||
* type: integer
|
||
* default: 10
|
||
* description: 返回数量限制
|
||
* responses:
|
||
* 200:
|
||
* description: 获取成功
|
||
* content:
|
||
* application/json:
|
||
* schema:
|
||
* type: object
|
||
* properties:
|
||
* code:
|
||
* type: integer
|
||
* description: 状态码,0表示成功
|
||
* example: 0
|
||
* message:
|
||
* type: string
|
||
* description: 响应消息
|
||
* example: 'success'
|
||
* data:
|
||
* type: array
|
||
* description: 待执行任务列表
|
||
* items:
|
||
* type: object
|
||
* properties:
|
||
* taskId:
|
||
* type: integer
|
||
* description: 任务ID
|
||
* taskName:
|
||
* type: string
|
||
* description: 任务名称
|
||
* taskType:
|
||
* type: string
|
||
* description: 任务类型
|
||
* status:
|
||
* type: string
|
||
* description: 任务状态(pending-待执行)
|
||
* scheduledTime:
|
||
* type: string
|
||
* description: 计划执行时间
|
||
* priority:
|
||
* type: integer
|
||
* description: 优先级
|
||
*/
|
||
'GET /task/pending': async (ctx) => {
|
||
try {
|
||
const { sn_code, limit = 10 } = ctx.query || {};
|
||
|
||
if (!sn_code) {
|
||
return ctx.fail('请提供设备SN码');
|
||
}
|
||
|
||
const { task_status, op } = await Framework.getModels();
|
||
|
||
// 查询待执行的任务(status = 'pending')
|
||
const pendingTasks = await task_status.findAll({
|
||
where: {
|
||
sn_code: sn_code,
|
||
status: 'pending'
|
||
},
|
||
order: [
|
||
['priority', 'DESC'], // 按优先级降序
|
||
['id', 'ASC'] // 同优先级按ID升序
|
||
],
|
||
limit: parseInt(limit) || 10
|
||
});
|
||
|
||
const taskList = pendingTasks.map(task => {
|
||
const taskData = task.toJSON();
|
||
return {
|
||
taskId: taskData.id,
|
||
taskName: taskData.taskName || taskData.task_name || taskData.taskType || taskData.task_type || '未知任务',
|
||
taskType: taskData.taskType || taskData.task_type,
|
||
status: 'pending',
|
||
scheduledTime: taskData.scheduledTime || taskData.scheduled_time || taskData.created_time,
|
||
priority: taskData.priority || 0
|
||
};
|
||
});
|
||
|
||
return ctx.success(taskList);
|
||
} catch (error) {
|
||
console.error('[任务管理] 获取待执行任务失败:', error);
|
||
return ctx.fail('获取待执行任务失败: ' + (error.message || '未知错误'));
|
||
}
|
||
},
|
||
|
||
/**
|
||
* @swagger
|
||
* /api/task/statistics:
|
||
* get:
|
||
* summary: 获取任务统计
|
||
* description: 根据设备SN码获取任务统计数据(包含今日、本周、本月统计)
|
||
* tags: [前端-任务管理]
|
||
* parameters:
|
||
* - in: query
|
||
* name: sn_code
|
||
* required: true
|
||
* schema:
|
||
* type: string
|
||
* description: 设备SN码
|
||
* responses:
|
||
* 200:
|
||
* description: 获取成功
|
||
*/
|
||
'GET /task/statistics': async (ctx) => {
|
||
try {
|
||
const { sn_code } = ctx.query || {};
|
||
|
||
if (!sn_code) {
|
||
return ctx.fail('请提供设备SN码');
|
||
}
|
||
|
||
const { task_status, op } = await Framework.getModels();
|
||
|
||
// 计算时间范围
|
||
const now = new Date();
|
||
|
||
// 今天的开始时间(00:00:00)
|
||
const todayStart = new Date(now);
|
||
todayStart.setHours(0, 0, 0, 0);
|
||
|
||
// 本周的开始时间(周一00:00:00)
|
||
const weekStart = new Date(now);
|
||
const dayOfWeek = weekStart.getDay();
|
||
const diff = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // 周日算作上周
|
||
weekStart.setDate(weekStart.getDate() - diff);
|
||
weekStart.setHours(0, 0, 0, 0);
|
||
|
||
// 本月的开始时间(1号00:00:00)
|
||
const monthStart = new Date(now.getFullYear(), now.getMonth(), 1);
|
||
monthStart.setHours(0, 0, 0, 0);
|
||
|
||
const [
|
||
totalCount,
|
||
completedCount,
|
||
runningCount,
|
||
pendingCount,
|
||
failedCount,
|
||
todayCount,
|
||
weekCount,
|
||
monthCount
|
||
] = await Promise.all([
|
||
// 总计
|
||
task_status.count({ where: { sn_code: sn_code } }),
|
||
task_status.count({ where: { sn_code: sn_code, status: 'completed' } }),
|
||
task_status.count({ where: { sn_code: sn_code, status: 'running' } }),
|
||
task_status.count({ where: { sn_code: sn_code, status: 'pending' } }),
|
||
task_status.count({ where: { sn_code: sn_code, status: 'failed' } }),
|
||
// 今日完成
|
||
task_status.count({
|
||
where: {
|
||
sn_code: sn_code,
|
||
status: 'completed',
|
||
updated_time: { [op.gte]: todayStart }
|
||
}
|
||
}),
|
||
// 本周完成
|
||
task_status.count({
|
||
where: {
|
||
sn_code: sn_code,
|
||
status: 'completed',
|
||
updated_time: { [op.gte]: weekStart }
|
||
}
|
||
}),
|
||
// 本月完成
|
||
task_status.count({
|
||
where: {
|
||
sn_code: sn_code,
|
||
status: 'completed',
|
||
updated_time: { [op.gte]: monthStart }
|
||
}
|
||
})
|
||
]);
|
||
|
||
return ctx.success({
|
||
totalCount,
|
||
completedCount,
|
||
runningCount,
|
||
pendingCount,
|
||
failedCount,
|
||
todayCount,
|
||
weekCount,
|
||
monthCount,
|
||
completionRate: totalCount > 0 ? ((completedCount / totalCount) * 100).toFixed(2) : 0
|
||
});
|
||
} catch (error) {
|
||
console.error('[任务管理] 获取任务统计失败:', error);
|
||
return ctx.fail('获取任务统计失败: ' + (error.message || '未知错误'));
|
||
}
|
||
}
|
||
};
|
||
|