1
This commit is contained in:
235
api/middleware/schedule/tasks/autoSearchTask.js
Normal file
235
api/middleware/schedule/tasks/autoSearchTask.js
Normal file
@@ -0,0 +1,235 @@
|
||||
const BaseTask = require('./baseTask');
|
||||
const db = require('../../dbProxy');
|
||||
const config = require('../config');
|
||||
|
||||
/**
|
||||
* 自动搜索职位任务
|
||||
* 定期搜索符合条件的职位并保存到数据库
|
||||
*/
|
||||
class AutoSearchTask extends BaseTask {
|
||||
constructor() {
|
||||
super('auto_search', {
|
||||
defaultInterval: 60, // 默认60分钟
|
||||
defaultPriority: 8, // 高优先级(比投递高,先搜索后投递)
|
||||
requiresLogin: true, // 需要登录
|
||||
conflictsWith: [ // 与这些任务冲突
|
||||
'auto_deliver', // 投递任务
|
||||
'auto_active_account' // 活跃账号任务
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证任务参数
|
||||
*/
|
||||
validateParams(params) {
|
||||
if (!params.keyword && !params.jobType) {
|
||||
return {
|
||||
valid: false,
|
||||
reason: '缺少必要参数: keyword 或 jobType'
|
||||
};
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务名称
|
||||
*/
|
||||
getTaskName(params) {
|
||||
return `自动搜索 - ${params.keyword || params.jobType || '默认'}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行自动搜索任务
|
||||
*/
|
||||
async execute(sn_code, params) {
|
||||
console.log(`[自动搜索] 设备 ${sn_code} 开始执行搜索任务`);
|
||||
|
||||
// 1. 获取账号信息
|
||||
const account = await this.getAccountInfo(sn_code);
|
||||
if (!account) {
|
||||
throw new Error(`账号 ${sn_code} 不存在`);
|
||||
}
|
||||
|
||||
// 2. 获取搜索配置
|
||||
const searchConfig = this.parseSearchConfig(account.search_config);
|
||||
|
||||
// 3. 检查日搜索限制
|
||||
const dailyLimit = config.dailyLimits.maxSearch || 20;
|
||||
const todaySearched = await this.getTodaySearchCount(sn_code);
|
||||
|
||||
if (todaySearched >= dailyLimit) {
|
||||
throw new Error(`今日搜索已达上限 (${todaySearched}/${dailyLimit})`);
|
||||
}
|
||||
|
||||
// 4. 执行搜索(这里需要调用实际的搜索逻辑)
|
||||
const searchResult = {
|
||||
success: true,
|
||||
keyword: params.keyword || account.keyword,
|
||||
pageCount: searchConfig.page_count || 3,
|
||||
jobsFound: 0, // 实际搜索到的职位数
|
||||
jobsSaved: 0 // 保存到数据库的职位数
|
||||
};
|
||||
|
||||
console.log(`[自动搜索] 设备 ${sn_code} 搜索完成,找到 ${searchResult.jobsFound} 个职位`);
|
||||
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账号信息
|
||||
*/
|
||||
async getAccountInfo(sn_code) {
|
||||
const { pla_account } = db.models;
|
||||
const account = await pla_account.findOne({
|
||||
where: {
|
||||
sn_code: sn_code,
|
||||
is_delete: 0,
|
||||
is_enabled: 1
|
||||
}
|
||||
});
|
||||
|
||||
return account ? account.toJSON() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析搜索配置
|
||||
*/
|
||||
parseSearchConfig(search_config) {
|
||||
if (typeof search_config === 'string') {
|
||||
try {
|
||||
search_config = JSON.parse(search_config);
|
||||
} catch (e) {
|
||||
search_config = {};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
search_interval: search_config?.search_interval || 60,
|
||||
page_count: search_config?.page_count || 3,
|
||||
city: search_config?.city || '',
|
||||
salary_range: search_config?.salary_range || '',
|
||||
experience: search_config?.experience || '',
|
||||
education: search_config?.education || '',
|
||||
time_range: search_config?.time_range || null
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今日已搜索数量
|
||||
*/
|
||||
async getTodaySearchCount(sn_code) {
|
||||
const { task_status } = db.models;
|
||||
const Sequelize = require('sequelize');
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const count = await task_status.count({
|
||||
where: {
|
||||
sn_code: sn_code,
|
||||
taskType: 'auto_search',
|
||||
status: 'completed',
|
||||
endTime: {
|
||||
[Sequelize.Op.gte]: today
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加搜索任务到队列
|
||||
*/
|
||||
async addToQueue(sn_code, taskQueue, customParams = {}) {
|
||||
const now = new Date();
|
||||
console.log(`[自动搜索] ${now.toLocaleString()} 尝试为设备 ${sn_code} 添加任务`);
|
||||
|
||||
try {
|
||||
// 1. 获取账号信息
|
||||
const account = await this.getAccountInfo(sn_code);
|
||||
if (!account) {
|
||||
console.log(`[自动搜索] 账号 ${sn_code} 不存在或未启用`);
|
||||
return { success: false, reason: '账号不存在或未启用' };
|
||||
}
|
||||
|
||||
// 2. 检查是否开启了自动搜索
|
||||
if (!account.auto_search) {
|
||||
console.log(`[自动搜索] 设备 ${sn_code} 未开启自动搜索`);
|
||||
return { success: false, reason: '未开启自动搜索' };
|
||||
}
|
||||
|
||||
// 3. 获取搜索配置
|
||||
const searchConfig = this.parseSearchConfig(account.search_config);
|
||||
|
||||
// 4. 检查时间范围
|
||||
if (searchConfig.time_range) {
|
||||
const timeCheck = this.checkTimeRange(searchConfig.time_range);
|
||||
if (!timeCheck.allowed) {
|
||||
console.log(`[自动搜索] 设备 ${sn_code} ${timeCheck.reason}`);
|
||||
return { success: false, reason: timeCheck.reason };
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 执行所有层级的冲突检查
|
||||
const conflictCheck = await this.canExecuteTask(sn_code, taskQueue);
|
||||
if (!conflictCheck.allowed) {
|
||||
console.log(`[自动搜索] 设备 ${sn_code} 冲突检查未通过: ${conflictCheck.reason}`);
|
||||
return { success: false, reason: conflictCheck.reason };
|
||||
}
|
||||
|
||||
// 6. 检查搜索间隔
|
||||
const intervalCheck = await this.checkExecutionInterval(
|
||||
sn_code,
|
||||
searchConfig.search_interval
|
||||
);
|
||||
|
||||
if (!intervalCheck.allowed) {
|
||||
console.log(`[自动搜索] 设备 ${sn_code} ${intervalCheck.reason}`);
|
||||
return { success: false, reason: intervalCheck.reason };
|
||||
}
|
||||
|
||||
// 7. 构建任务参数
|
||||
const taskParams = {
|
||||
keyword: account.keyword || '',
|
||||
jobType: account.job_type || '',
|
||||
platform: account.platform_type || 'boss',
|
||||
pageCount: searchConfig.page_count || 3,
|
||||
city: searchConfig.city || '',
|
||||
salaryRange: searchConfig.salary_range || '',
|
||||
...customParams
|
||||
};
|
||||
|
||||
// 8. 验证参数
|
||||
const validation = this.validateParams(taskParams);
|
||||
if (!validation.valid) {
|
||||
return { success: false, reason: validation.reason };
|
||||
}
|
||||
|
||||
// 9. 添加任务到队列
|
||||
await taskQueue.addTask(sn_code, {
|
||||
taskType: this.taskType,
|
||||
taskName: this.getTaskName(taskParams),
|
||||
taskParams: taskParams,
|
||||
priority: this.config.defaultPriority
|
||||
});
|
||||
|
||||
console.log(`[自动搜索] 已为设备 ${sn_code} 添加搜索任务,间隔: ${searchConfig.search_interval} 分钟`);
|
||||
|
||||
// 10. 释放任务锁
|
||||
this.releaseTaskLock(sn_code);
|
||||
|
||||
return { success: true };
|
||||
|
||||
} catch (error) {
|
||||
console.error(`[自动搜索] 添加任务失败:`, error);
|
||||
this.releaseTaskLock(sn_code);
|
||||
return { success: false, reason: error.message };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例
|
||||
module.exports = new AutoSearchTask();
|
||||
Reference in New Issue
Block a user