This commit is contained in:
张成
2026-02-27 17:33:39 +08:00
parent c1d812a80e
commit 1a011bcc01
12 changed files with 79 additions and 78 deletions

View File

@@ -4,7 +4,7 @@
*/
const Framework = require("../../framework/node-core-framework.js");
const jobManager = require("../middleware/job/jobManager.js");
const jobManager = require("../middleware/job/index.js");
module.exports = {
/**

View File

@@ -1,5 +1,4 @@
const ai_service_module = require('../../../services/ai_service');
const ai_service = ai_service_module.getInstance();
const ai_service = require('../../../services/ai_service');
/**
* 聊天管理模块

View File

@@ -1,13 +1,10 @@
const aiServiceModule = require('../../../services/ai_service');
const aiService = require('../../../services/ai_service');
const { jobFilterService } = require('../services');
const locationService = require('../../../services/locationService');
const logs = require('../../logProxy');
const db = require('../../dbProxy');
const { v4: uuidv4 } = require('uuid');
// 实例化AI服务
const aiService = aiServiceModule.getInstance();
/**
* 工作管理模块
* 负责简历获取、分析、存储和匹配度计算

View File

@@ -1,12 +1,9 @@
const aiServiceModule = require('../../../services/ai_service');
const aiService = require('../../../services/ai_service');
const { jobFilterService } = require('../services');
const logs = require('../../logProxy');
const db = require('../../dbProxy');
const { v4: uuidv4 } = require('uuid');
// 实例化AI服务
const aiService = aiServiceModule.getInstance();
/**
* 简历管理模块
* 负责简历获取、分析、存储和匹配度计算

View File

@@ -84,10 +84,11 @@ class CommandManager {
const start_time = new Date();
let command_id = null;
let command_record = null;
let task = null;
try {
// 1. 获取任务信息
const task = await db.getModel('task_status').findByPk(task_id);
task = await db.getModel('task_status').findByPk(task_id);
if (!task) {
throw new Error(`任务不存在: ${task_id}`);
}
@@ -191,15 +192,16 @@ class CommandManager {
start_time
);
// 推送指令失败状态
try {
const deviceWorkStatusNotifier = require('../notifiers/deviceWorkStatusNotifier');
const taskQueue = require('./taskQueue');
const summary = await taskQueue.getTaskStatusSummary(task.sn_code);
await deviceWorkStatusNotifier.sendDeviceWorkStatus(task.sn_code, summary);
} catch (pushError) {
// 推送失败不影响错误处理
console.warn(`[指令管理] 推送设备工作状态失败:`, pushError.message);
// 推送指令失败状态(需有 task 或从 DB 取 sn_code
if (task && task.sn_code) {
try {
const deviceWorkStatusNotifier = require('../notifiers/deviceWorkStatusNotifier');
const taskQueue = require('./taskQueue');
const summary = await taskQueue.getTaskStatusSummary(task.sn_code);
await deviceWorkStatusNotifier.sendDeviceWorkStatus(task.sn_code, summary);
} catch (pushError) {
console.warn(`[指令管理] 推送设备工作状态失败:`, pushError.message);
}
}
}
@@ -210,21 +212,18 @@ class CommandManager {
/**
* 执行指令(带超时保护)
* command_type 与 job 层方法名一致,统一使用下划线命名
* @private
*/
async _execute_command_with_timeout(command_id, command_type, command_name, command_params, sn_code, mqttClient, start_time) {
// 获取指令超时时间从配置中获取默认5分钟
const timeout = ScheduleConfig.taskTimeouts[command_type] || 5 * 60 * 1000;
// 构建指令执行 Promise
const command_promise = (async () => {
// 直接使用 command_type 调用 jobManager 的方法,不做映射
// command_type 和 jobManager 的方法名保持一致
if (jobManager[command_type]) {
return await jobManager[command_type](sn_code, mqttClient, command_params);
} else {
const fn = jobManager[command_type];
if (!fn) {
throw new Error(`未知的指令类型: ${command_type}, jobManager 中不存在对应方法`);
}
return await fn(sn_code, mqttClient, command_params);
})();
// 使用超时机制包装

View File

@@ -63,7 +63,7 @@ class ActiveHandler extends BaseHandler {
const actions = activeStrategy.actions || ['view_jobs'];
const activeCommands = actions.map(action => ({
command_type: `active_${action}`,
command_name: `自动活跃 - ${action}`,
command_name: `active_${action}`,
command_params: JSON.stringify({
sn_code,
platform: platform || accountConfig.platform_type || 'boss',

View File

@@ -62,7 +62,7 @@ class ChatHandler extends BaseHandler {
// 4. 创建自动沟通 AI 指令(内部会先获取列表,再获取详情并自动回复)
const chatCommand = {
command_type: 'auto_chat_ai',
command_name: '自动沟通AI回复',
command_name: 'auto_chat_ai',
command_params: {
platform: platform || accountConfig.platform_type || 'boss',
pageCount: chatStrategy.page_count || 3

View File

@@ -201,8 +201,8 @@ class DeliverHandler extends BaseHandler {
try {
await command.executeCommands(taskId, [{
command_type: 'getOnlineResume',
command_name: '获取在线简历',
command_type: 'get_online_resume',
command_name: 'get_online_resume',
command_params: JSON.stringify({ sn_code, platform }),
priority: config.getTaskPriority('get_resume') || 5
}], this.mqttClient);
@@ -241,8 +241,8 @@ class DeliverHandler extends BaseHandler {
*/
async searchJobs(sn_code, platform, keyword, pageCount, taskId) {
const getJobListCommand = {
command_type: 'getJobList',
command_name: '获取职位列表',
command_type: 'get_job_list',
command_name: 'get_job_list',
command_params: JSON.stringify({
sn_code,
keyword,
@@ -389,7 +389,7 @@ class DeliverHandler extends BaseHandler {
createDeliverCommands(jobs, sn_code, platform) {
return jobs.map(job => ({
command_type: 'deliver_resume',
command_name: `投递简历 - ${job.jobTitle} @ ${job.companyName} (评分:${job.matchScore})`,
command_name: 'deliver_resume',
command_params: JSON.stringify({
sn_code,
platform,

View File

@@ -61,8 +61,8 @@ class SearchHandler extends BaseHandler {
// 4. 创建搜索指令
const searchCommand = {
command_type: 'getJobList',
command_name: `自动搜索职位 - ${keyword || accountConfig.keyword}`,
command_type: 'get_job_list',
command_name: 'get_job_list',
command_params: JSON.stringify({
sn_code,
keyword: keyword || accountConfig.keyword || '',

View File

@@ -186,44 +186,33 @@ class DeviceWorkStatusNotifier {
}
/**
* 格式化指令描述
* 格式化指令描述(与前端/后端/下发统一:只用一个名字 command_type不做映射
* @private
*/
_formatCommandDescription(command) {
const params = command.command_params || command.params || {};
let parsedParams = {};
if (typeof params === 'string') {
try {
parsedParams = JSON.parse(params);
} catch (e) {
// 解析失败,忽略
}
} catch (e) {}
} else {
parsedParams = params;
}
// 根据指令类型格式化描述
const commandType = command.command_type || command.type || '';
const commandName = command.command_name || command.name || '';
const command_type = command.command_type || command.type || '';
if (parsedParams.jobTitle && parsedParams.companyName) {
const companyName = parsedParams.companyName.length > 20
? parsedParams.companyName.substring(0, 20) + '...'
const companyName = parsedParams.companyName.length > 20
? parsedParams.companyName.substring(0, 20) + '...'
: parsedParams.companyName;
return `投递职位: ${parsedParams.jobTitle} @ ${companyName}`;
} else if (parsedParams.jobTitle) {
return `投递职位: ${parsedParams.jobTitle}`;
} else if (commandType === 'deliver_resume' || commandName.includes('投递')) {
return '投递简历';
} else if (commandType === 'searchJobs' || commandName.includes('搜索')) {
return `搜索职位: ${parsedParams.keyword || ''}`;
} else if (commandType === 'send_chat_message' || commandType === 'sendChatMessage' || commandName.includes('沟通')) {
return '发送消息';
} else if (commandName) {
return commandName;
return `${command_type}: ${parsedParams.jobTitle} @ ${companyName}`;
}
return '执行指令';
if (parsedParams.jobTitle) {
return `${command_type}: ${parsedParams.jobTitle}`;
}
if (parsedParams.keyword) {
return `${command_type}: ${parsedParams.keyword}`;
}
return command_type || command.command_name || '执行指令';
}
/**

View File

@@ -1,4 +1,4 @@
const Framework = require('node-core-framework');
const Framework = require('../../framework/node-core-framework');
/**
* AI调用记录服务

View File

@@ -5,7 +5,7 @@
const db = require('../middleware/dbProxy');
const scheduleManager = require('../middleware/schedule/index.js');
const locationService = require('./location_service');
const locationService = require('./locationService');
const authorizationService = require('./authorization_service');
const { addRemainingDays, addRemainingDaysToAccounts } = require('../utils/account_utils');
@@ -486,10 +486,10 @@ class PlaAccountService {
finalParams.keyword = account.keyword;
}
// 构建指令对象
// 构建指令对象(与前端/后端/下发统一:只用一个名字 command_type
const command = {
command_type: commandTypeSnake,
command_name: commandName || commandType,
command_name: commandTypeSnake,
command_params: JSON.stringify(finalParams)
};
@@ -497,7 +497,7 @@ class PlaAccountService {
const task = await task_status.create({
sn_code: account.sn_code,
taskType: commandTypeSnake,
taskName: commandName || commandType,
taskName: commandTypeSnake,
taskParams: JSON.stringify(finalParams)
});
@@ -567,10 +567,6 @@ class PlaAccountService {
throw new Error('指令不存在');
}
// 检查指令状态
if (command.status !== 'failed') {
throw new Error('只能重试失败的指令');
}
// 获取任务信息
const task = await task_status.findByPk(command.task_id);
@@ -627,15 +623,39 @@ class PlaAccountService {
command_params: JSON.stringify(commandParams)
};
// 执行指令
const result = await scheduleManager.command.executeCommand(task.id, commandObj, scheduleManager.mqttClient);
// 执行指令并同步更新当前指令记录状态
const start_time = new Date();
try {
const result = await scheduleManager.command.executeCommand(task.id, commandObj, scheduleManager.mqttClient);
const end_time = new Date();
return {
success: true,
message: '指令重试成功',
commandId: command.id,
result: result
};
await command.update({
status: 'completed',
start_time: start_time,
end_time: end_time,
duration: end_time.getTime() - start_time.getTime(),
result: JSON.stringify(result || {})
});
return {
success: true,
message: '指令重试成功',
commandId: command.id,
result: result
};
} catch (error) {
const end_time = new Date();
await command.update({
status: 'failed',
start_time: start_time,
end_time: end_time,
duration: end_time.getTime() - start_time.getTime(),
error_message: error.message || '指令重试失败',
error_stack: error.stack || ''
});
throw error;
}
}
/**