1
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const Framework = require("../../framework/node-core-framework.js");
|
const Framework = require("../../framework/node-core-framework.js");
|
||||||
const jobManager = require("../middleware/job/jobManager.js");
|
const jobManager = require("../middleware/job/index.js");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
const ai_service_module = require('../../../services/ai_service');
|
const ai_service = require('../../../services/ai_service');
|
||||||
const ai_service = ai_service_module.getInstance();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 聊天管理模块
|
* 聊天管理模块
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
const aiServiceModule = require('../../../services/ai_service');
|
const aiService = require('../../../services/ai_service');
|
||||||
const { jobFilterService } = require('../services');
|
const { jobFilterService } = require('../services');
|
||||||
const locationService = require('../../../services/locationService');
|
const locationService = require('../../../services/locationService');
|
||||||
const logs = require('../../logProxy');
|
const logs = require('../../logProxy');
|
||||||
const db = require('../../dbProxy');
|
const db = require('../../dbProxy');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
// 实例化AI服务
|
|
||||||
const aiService = aiServiceModule.getInstance();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 工作管理模块
|
* 工作管理模块
|
||||||
* 负责简历获取、分析、存储和匹配度计算
|
* 负责简历获取、分析、存储和匹配度计算
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
const aiServiceModule = require('../../../services/ai_service');
|
const aiService = require('../../../services/ai_service');
|
||||||
const { jobFilterService } = require('../services');
|
const { jobFilterService } = require('../services');
|
||||||
const logs = require('../../logProxy');
|
const logs = require('../../logProxy');
|
||||||
const db = require('../../dbProxy');
|
const db = require('../../dbProxy');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
// 实例化AI服务
|
|
||||||
const aiService = aiServiceModule.getInstance();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 简历管理模块
|
* 简历管理模块
|
||||||
* 负责简历获取、分析、存储和匹配度计算
|
* 负责简历获取、分析、存储和匹配度计算
|
||||||
|
|||||||
@@ -84,10 +84,11 @@ class CommandManager {
|
|||||||
const start_time = new Date();
|
const start_time = new Date();
|
||||||
let command_id = null;
|
let command_id = null;
|
||||||
let command_record = null;
|
let command_record = null;
|
||||||
|
let task = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 获取任务信息
|
// 1. 获取任务信息
|
||||||
const task = await db.getModel('task_status').findByPk(task_id);
|
task = await db.getModel('task_status').findByPk(task_id);
|
||||||
if (!task) {
|
if (!task) {
|
||||||
throw new Error(`任务不存在: ${task_id}`);
|
throw new Error(`任务不存在: ${task_id}`);
|
||||||
}
|
}
|
||||||
@@ -191,15 +192,16 @@ class CommandManager {
|
|||||||
start_time
|
start_time
|
||||||
);
|
);
|
||||||
|
|
||||||
// 推送指令失败状态
|
// 推送指令失败状态(需有 task 或从 DB 取 sn_code)
|
||||||
try {
|
if (task && task.sn_code) {
|
||||||
const deviceWorkStatusNotifier = require('../notifiers/deviceWorkStatusNotifier');
|
try {
|
||||||
const taskQueue = require('./taskQueue');
|
const deviceWorkStatusNotifier = require('../notifiers/deviceWorkStatusNotifier');
|
||||||
const summary = await taskQueue.getTaskStatusSummary(task.sn_code);
|
const taskQueue = require('./taskQueue');
|
||||||
await deviceWorkStatusNotifier.sendDeviceWorkStatus(task.sn_code, summary);
|
const summary = await taskQueue.getTaskStatusSummary(task.sn_code);
|
||||||
} catch (pushError) {
|
await deviceWorkStatusNotifier.sendDeviceWorkStatus(task.sn_code, summary);
|
||||||
// 推送失败不影响错误处理
|
} catch (pushError) {
|
||||||
console.warn(`[指令管理] 推送设备工作状态失败:`, pushError.message);
|
console.warn(`[指令管理] 推送设备工作状态失败:`, pushError.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,21 +212,18 @@ class CommandManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行指令(带超时保护)
|
* 执行指令(带超时保护)
|
||||||
|
* command_type 与 job 层方法名一致,统一使用下划线命名
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
async _execute_command_with_timeout(command_id, command_type, command_name, command_params, sn_code, mqttClient, start_time) {
|
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;
|
const timeout = ScheduleConfig.taskTimeouts[command_type] || 5 * 60 * 1000;
|
||||||
|
|
||||||
// 构建指令执行 Promise
|
|
||||||
const command_promise = (async () => {
|
const command_promise = (async () => {
|
||||||
// 直接使用 command_type 调用 jobManager 的方法,不做映射
|
const fn = jobManager[command_type];
|
||||||
// command_type 和 jobManager 的方法名保持一致
|
if (!fn) {
|
||||||
if (jobManager[command_type]) {
|
|
||||||
return await jobManager[command_type](sn_code, mqttClient, command_params);
|
|
||||||
} else {
|
|
||||||
throw new Error(`未知的指令类型: ${command_type}, jobManager 中不存在对应方法`);
|
throw new Error(`未知的指令类型: ${command_type}, jobManager 中不存在对应方法`);
|
||||||
}
|
}
|
||||||
|
return await fn(sn_code, mqttClient, command_params);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// 使用超时机制包装
|
// 使用超时机制包装
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class ActiveHandler extends BaseHandler {
|
|||||||
const actions = activeStrategy.actions || ['view_jobs'];
|
const actions = activeStrategy.actions || ['view_jobs'];
|
||||||
const activeCommands = actions.map(action => ({
|
const activeCommands = actions.map(action => ({
|
||||||
command_type: `active_${action}`,
|
command_type: `active_${action}`,
|
||||||
command_name: `自动活跃 - ${action}`,
|
command_name: `active_${action}`,
|
||||||
command_params: JSON.stringify({
|
command_params: JSON.stringify({
|
||||||
sn_code,
|
sn_code,
|
||||||
platform: platform || accountConfig.platform_type || 'boss',
|
platform: platform || accountConfig.platform_type || 'boss',
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class ChatHandler extends BaseHandler {
|
|||||||
// 4. 创建自动沟通 AI 指令(内部会先获取列表,再获取详情并自动回复)
|
// 4. 创建自动沟通 AI 指令(内部会先获取列表,再获取详情并自动回复)
|
||||||
const chatCommand = {
|
const chatCommand = {
|
||||||
command_type: 'auto_chat_ai',
|
command_type: 'auto_chat_ai',
|
||||||
command_name: '自动沟通AI回复',
|
command_name: 'auto_chat_ai',
|
||||||
command_params: {
|
command_params: {
|
||||||
platform: platform || accountConfig.platform_type || 'boss',
|
platform: platform || accountConfig.platform_type || 'boss',
|
||||||
pageCount: chatStrategy.page_count || 3
|
pageCount: chatStrategy.page_count || 3
|
||||||
|
|||||||
@@ -201,8 +201,8 @@ class DeliverHandler extends BaseHandler {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await command.executeCommands(taskId, [{
|
await command.executeCommands(taskId, [{
|
||||||
command_type: 'getOnlineResume',
|
command_type: 'get_online_resume',
|
||||||
command_name: '获取在线简历',
|
command_name: 'get_online_resume',
|
||||||
command_params: JSON.stringify({ sn_code, platform }),
|
command_params: JSON.stringify({ sn_code, platform }),
|
||||||
priority: config.getTaskPriority('get_resume') || 5
|
priority: config.getTaskPriority('get_resume') || 5
|
||||||
}], this.mqttClient);
|
}], this.mqttClient);
|
||||||
@@ -241,8 +241,8 @@ class DeliverHandler extends BaseHandler {
|
|||||||
*/
|
*/
|
||||||
async searchJobs(sn_code, platform, keyword, pageCount, taskId) {
|
async searchJobs(sn_code, platform, keyword, pageCount, taskId) {
|
||||||
const getJobListCommand = {
|
const getJobListCommand = {
|
||||||
command_type: 'getJobList',
|
command_type: 'get_job_list',
|
||||||
command_name: '获取职位列表',
|
command_name: 'get_job_list',
|
||||||
command_params: JSON.stringify({
|
command_params: JSON.stringify({
|
||||||
sn_code,
|
sn_code,
|
||||||
keyword,
|
keyword,
|
||||||
@@ -389,7 +389,7 @@ class DeliverHandler extends BaseHandler {
|
|||||||
createDeliverCommands(jobs, sn_code, platform) {
|
createDeliverCommands(jobs, sn_code, platform) {
|
||||||
return jobs.map(job => ({
|
return jobs.map(job => ({
|
||||||
command_type: 'deliver_resume',
|
command_type: 'deliver_resume',
|
||||||
command_name: `投递简历 - ${job.jobTitle} @ ${job.companyName} (评分:${job.matchScore})`,
|
command_name: 'deliver_resume',
|
||||||
command_params: JSON.stringify({
|
command_params: JSON.stringify({
|
||||||
sn_code,
|
sn_code,
|
||||||
platform,
|
platform,
|
||||||
|
|||||||
@@ -61,8 +61,8 @@ class SearchHandler extends BaseHandler {
|
|||||||
|
|
||||||
// 4. 创建搜索指令
|
// 4. 创建搜索指令
|
||||||
const searchCommand = {
|
const searchCommand = {
|
||||||
command_type: 'getJobList',
|
command_type: 'get_job_list',
|
||||||
command_name: `自动搜索职位 - ${keyword || accountConfig.keyword}`,
|
command_name: 'get_job_list',
|
||||||
command_params: JSON.stringify({
|
command_params: JSON.stringify({
|
||||||
sn_code,
|
sn_code,
|
||||||
keyword: keyword || accountConfig.keyword || '',
|
keyword: keyword || accountConfig.keyword || '',
|
||||||
|
|||||||
@@ -186,44 +186,33 @@ class DeviceWorkStatusNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化指令描述
|
* 格式化指令描述(与前端/后端/下发统一:只用一个名字 command_type,不做映射)
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_formatCommandDescription(command) {
|
_formatCommandDescription(command) {
|
||||||
const params = command.command_params || command.params || {};
|
const params = command.command_params || command.params || {};
|
||||||
let parsedParams = {};
|
let parsedParams = {};
|
||||||
|
|
||||||
if (typeof params === 'string') {
|
if (typeof params === 'string') {
|
||||||
try {
|
try {
|
||||||
parsedParams = JSON.parse(params);
|
parsedParams = JSON.parse(params);
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
// 解析失败,忽略
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
parsedParams = params;
|
parsedParams = params;
|
||||||
}
|
}
|
||||||
|
const command_type = command.command_type || command.type || '';
|
||||||
// 根据指令类型格式化描述
|
|
||||||
const commandType = command.command_type || command.type || '';
|
|
||||||
const commandName = command.command_name || command.name || '';
|
|
||||||
|
|
||||||
if (parsedParams.jobTitle && parsedParams.companyName) {
|
if (parsedParams.jobTitle && parsedParams.companyName) {
|
||||||
const companyName = parsedParams.companyName.length > 20
|
const companyName = parsedParams.companyName.length > 20
|
||||||
? parsedParams.companyName.substring(0, 20) + '...'
|
? parsedParams.companyName.substring(0, 20) + '...'
|
||||||
: parsedParams.companyName;
|
: parsedParams.companyName;
|
||||||
return `投递职位: ${parsedParams.jobTitle} @ ${companyName}`;
|
return `${command_type}: ${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 '执行指令';
|
if (parsedParams.jobTitle) {
|
||||||
|
return `${command_type}: ${parsedParams.jobTitle}`;
|
||||||
|
}
|
||||||
|
if (parsedParams.keyword) {
|
||||||
|
return `${command_type}: ${parsedParams.keyword}`;
|
||||||
|
}
|
||||||
|
return command_type || command.command_name || '执行指令';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const Framework = require('node-core-framework');
|
const Framework = require('../../framework/node-core-framework');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AI调用记录服务
|
* AI调用记录服务
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
const db = require('../middleware/dbProxy');
|
const db = require('../middleware/dbProxy');
|
||||||
const scheduleManager = require('../middleware/schedule/index.js');
|
const scheduleManager = require('../middleware/schedule/index.js');
|
||||||
const locationService = require('./location_service');
|
const locationService = require('./locationService');
|
||||||
const authorizationService = require('./authorization_service');
|
const authorizationService = require('./authorization_service');
|
||||||
const { addRemainingDays, addRemainingDaysToAccounts } = require('../utils/account_utils');
|
const { addRemainingDays, addRemainingDaysToAccounts } = require('../utils/account_utils');
|
||||||
|
|
||||||
@@ -486,10 +486,10 @@ class PlaAccountService {
|
|||||||
finalParams.keyword = account.keyword;
|
finalParams.keyword = account.keyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建指令对象
|
// 构建指令对象(与前端/后端/下发统一:只用一个名字 command_type)
|
||||||
const command = {
|
const command = {
|
||||||
command_type: commandTypeSnake,
|
command_type: commandTypeSnake,
|
||||||
command_name: commandName || commandType,
|
command_name: commandTypeSnake,
|
||||||
command_params: JSON.stringify(finalParams)
|
command_params: JSON.stringify(finalParams)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -497,7 +497,7 @@ class PlaAccountService {
|
|||||||
const task = await task_status.create({
|
const task = await task_status.create({
|
||||||
sn_code: account.sn_code,
|
sn_code: account.sn_code,
|
||||||
taskType: commandTypeSnake,
|
taskType: commandTypeSnake,
|
||||||
taskName: commandName || commandType,
|
taskName: commandTypeSnake,
|
||||||
taskParams: JSON.stringify(finalParams)
|
taskParams: JSON.stringify(finalParams)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -567,10 +567,6 @@ class PlaAccountService {
|
|||||||
throw new Error('指令不存在');
|
throw new Error('指令不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查指令状态
|
|
||||||
if (command.status !== 'failed') {
|
|
||||||
throw new Error('只能重试失败的指令');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取任务信息
|
// 获取任务信息
|
||||||
const task = await task_status.findByPk(command.task_id);
|
const task = await task_status.findByPk(command.task_id);
|
||||||
@@ -627,15 +623,39 @@ class PlaAccountService {
|
|||||||
command_params: JSON.stringify(commandParams)
|
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 {
|
await command.update({
|
||||||
success: true,
|
status: 'completed',
|
||||||
message: '指令重试成功',
|
start_time: start_time,
|
||||||
commandId: command.id,
|
end_time: end_time,
|
||||||
result: result
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user