1
This commit is contained in:
@@ -13,6 +13,19 @@ class JobManager {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备 get_job_list 返回的 response.data:XHR 监听结果数组,每项 data 为接口 JSON(zpData.jobList)
|
||||
*/
|
||||
_jobListFromRecommendMonitorData(responseData) {
|
||||
if (!Array.isArray(responseData)) return [];
|
||||
const jobs = [];
|
||||
for (const item of responseData) {
|
||||
const list = item?.data?.zpData?.jobList;
|
||||
if (Array.isArray(list)) jobs.push(...list);
|
||||
}
|
||||
return jobs;
|
||||
}
|
||||
|
||||
// 启动客户端那个平台 用户信息,心跳机制
|
||||
async set_user_info(sn_code, mqttClient, user_info) {
|
||||
const response = await mqttClient.publishAndWait(sn_code, {
|
||||
@@ -199,19 +212,7 @@ class JobManager {
|
||||
throw new Error('多条件搜索职位失败');
|
||||
}
|
||||
|
||||
// 处理职位列表数据
|
||||
let jobs = [];
|
||||
if (Array.isArray(response.data)) {
|
||||
for (const item of response.data) {
|
||||
if (item.data?.zpData?.jobList && Array.isArray(item.data.zpData.jobList)) {
|
||||
jobs = jobs.concat(item.data.zpData.jobList);
|
||||
}
|
||||
}
|
||||
} else if (response.data?.data?.zpData?.jobList) {
|
||||
jobs = response.data.data.zpData.jobList || [];
|
||||
} else if (response.data?.zpData?.jobList) {
|
||||
jobs = response.data.zpData.jobList || [];
|
||||
}
|
||||
const jobs = this._jobListFromRecommendMonitorData(response.data);
|
||||
|
||||
console.log(`[工作管理] 成功获取岗位数据,共 ${jobs.length} 个岗位`);
|
||||
|
||||
@@ -425,9 +426,8 @@ class JobManager {
|
||||
* @returns {Promise<object>} 岗位列表
|
||||
*/
|
||||
async get_job_list(sn_code, mqttClient, params = {}) {
|
||||
const {
|
||||
keyword: paramKeyword = '',
|
||||
platform = 'boss',
|
||||
const {
|
||||
platform = 'boss',
|
||||
pageCount = 3,
|
||||
city = '',
|
||||
cityName = '',
|
||||
@@ -439,77 +439,29 @@ class JobManager {
|
||||
financingStage = '',
|
||||
page = 1,
|
||||
pageSize = 20,
|
||||
tabLabel,
|
||||
tabIndex,
|
||||
job_type_id
|
||||
tabLabel
|
||||
} = params;
|
||||
|
||||
// 推荐列表实际按期望 tab 拉取,入库 keyword 应与「职位来源」一致:显式 keyword > deliver_tab_label > 空(不再默认「前端」)
|
||||
let keyword = paramKeyword != null && String(paramKeyword).trim() !== ''
|
||||
? String(paramKeyword).trim()
|
||||
: '';
|
||||
if (!keyword && tabLabel != null && String(tabLabel).trim() !== '') {
|
||||
keyword = String(tabLabel).trim();
|
||||
}
|
||||
// 入库用:可与前端一致带 keyword;设备端只收 pageCount + tabLabel(与 Electron get_job_list 一致)
|
||||
const keyword = String(params.keyword || '').trim() || String(tabLabel || '').trim();
|
||||
|
||||
// 仅当调用方显式传入筛选/分页字段时才走多条件分支(避免 page/pageSize 默认值把简单拉列表永远判成「多条件」)
|
||||
const hasMultiParams = Boolean(
|
||||
(params.city != null && params.city !== '') ||
|
||||
(params.cityName != null && params.cityName !== '') ||
|
||||
(params.salary != null && params.salary !== '') ||
|
||||
(params.experience != null && params.experience !== '') ||
|
||||
(params.education != null && params.education !== '') ||
|
||||
(params.industry != null && params.industry !== '') ||
|
||||
(params.companySize != null && params.companySize !== '') ||
|
||||
(params.financingStage != null && params.financingStage !== '') ||
|
||||
params.page !== undefined ||
|
||||
params.pageSize !== undefined
|
||||
);
|
||||
const multiKeys = ['city', 'cityName', 'salary', 'experience', 'education', 'industry', 'companySize', 'financingStage'];
|
||||
const hasMultiParams = multiKeys.some((k) => params[k]) || params.page !== undefined || params.pageSize !== undefined;
|
||||
|
||||
/** 期望 tab 与职位类型需原样带给设备端 get_job_list,否则不会切换 .c-expect-select 标签 */
|
||||
const appendExpectTabToData = (data) => {
|
||||
if (tabLabel != null && String(tabLabel).trim() !== '') {
|
||||
data.tabLabel = String(tabLabel).trim();
|
||||
}
|
||||
if (tabIndex !== undefined && tabIndex !== null && String(tabIndex).trim() !== '') {
|
||||
const ti = Number(tabIndex);
|
||||
if (!Number.isNaN(ti)) {
|
||||
data.tabIndex = ti;
|
||||
}
|
||||
}
|
||||
if (job_type_id != null && job_type_id !== '') {
|
||||
data.job_type_id = job_type_id;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
const devicePayload = () => ({
|
||||
pageCount,
|
||||
...(String(tabLabel || '').trim() ? { tabLabel: String(tabLabel).trim() } : {})
|
||||
});
|
||||
|
||||
if (hasMultiParams) {
|
||||
// 使用多条件搜索逻辑
|
||||
console.log(`[工作管理] 开始多条件搜索设备 ${sn_code} 的职位,关键词: ${keyword}, 城市: ${cityName || city}`);
|
||||
|
||||
// 构建完整的搜索参数对象
|
||||
const searchData = appendExpectTabToData({
|
||||
keyword,
|
||||
pageCount
|
||||
});
|
||||
|
||||
// 添加可选搜索条件
|
||||
if (city) searchData.city = city;
|
||||
if (cityName) searchData.cityName = cityName;
|
||||
if (salary) searchData.salary = salary;
|
||||
if (experience) searchData.experience = experience;
|
||||
if (education) searchData.education = education;
|
||||
if (industry) searchData.industry = industry;
|
||||
if (companySize) searchData.companySize = companySize;
|
||||
if (financingStage) searchData.financingStage = financingStage;
|
||||
if (page) searchData.page = page;
|
||||
if (pageSize) searchData.pageSize = pageSize;
|
||||
|
||||
// 通过MQTT指令获取岗位列表(保持action不变,前端已使用)
|
||||
const response = await mqttClient.publishAndWait(sn_code, {
|
||||
platform,
|
||||
action: "get_job_list", // 保持与原有get_job_list相同的action,前端已使用
|
||||
data: searchData
|
||||
data: devicePayload()
|
||||
});
|
||||
|
||||
if (!response || response.code !== 200) {
|
||||
@@ -517,19 +469,7 @@ class JobManager {
|
||||
throw new Error('多条件搜索职位失败');
|
||||
}
|
||||
|
||||
// 处理职位列表数据
|
||||
let jobs = [];
|
||||
if (Array.isArray(response.data)) {
|
||||
for (const item of response.data) {
|
||||
if (item.data?.zpData?.jobList && Array.isArray(item.data.zpData.jobList)) {
|
||||
jobs = jobs.concat(item.data.zpData.jobList);
|
||||
}
|
||||
}
|
||||
} else if (response.data?.data?.zpData?.jobList) {
|
||||
jobs = response.data.data.zpData.jobList || [];
|
||||
} else if (response.data?.zpData?.jobList) {
|
||||
jobs = response.data.zpData.jobList || [];
|
||||
}
|
||||
const jobs = this._jobListFromRecommendMonitorData(response.data);
|
||||
|
||||
console.log(`[工作管理] 成功获取岗位数据,共 ${jobs.length} 个岗位`);
|
||||
|
||||
@@ -551,11 +491,10 @@ class JobManager {
|
||||
// 简单搜索逻辑(保持原有逻辑)
|
||||
console.log(`[工作管理] 开始获取设备 ${sn_code} 的岗位列表,关键词: ${keyword}`);
|
||||
|
||||
// 通过MQTT指令获取岗位列表(须带上 tabLabel/tabIndex,与 schedule/deliver 下发一致)
|
||||
const response = await mqttClient.publishAndWait(sn_code, {
|
||||
platform,
|
||||
action: "get_job_list",
|
||||
data: appendExpectTabToData({ keyword, pageCount })
|
||||
data: devicePayload()
|
||||
});
|
||||
|
||||
if (!response || response.code !== 200) {
|
||||
@@ -563,25 +502,7 @@ class JobManager {
|
||||
throw new Error('获取岗位列表失败');
|
||||
}
|
||||
|
||||
// 处理职位列表数据:response.data 可能是数组(职位列表.json 格式)或单个对象
|
||||
let jobs = [];
|
||||
|
||||
if (Array.isArray(response.data)) {
|
||||
// 如果是数组格式(职位列表.json),遍历每个元素提取岗位数据
|
||||
for (const item of response.data) {
|
||||
if (item.data?.zpData?.jobList && Array.isArray(item.data.zpData.jobList)) {
|
||||
jobs = jobs.concat(item.data.zpData.jobList);
|
||||
}
|
||||
}
|
||||
console.log(`[工作管理] 从 ${response.data.length} 个响应中提取岗位数据`);
|
||||
} else if (response.data?.data?.zpData?.jobList) {
|
||||
// 如果是单个对象格式,从 data.zpData.jobList 获取
|
||||
jobs = response.data.data.zpData.jobList || [];
|
||||
} else if (response.data?.zpData?.jobList) {
|
||||
// 兼容旧格式:直接从 zpData.jobList 获取
|
||||
jobs = response.data.zpData.jobList || [];
|
||||
}
|
||||
|
||||
const jobs = this._jobListFromRecommendMonitorData(response.data);
|
||||
console.log(`[工作管理] 成功获取岗位数据,共 ${jobs.length} 个岗位`);
|
||||
|
||||
// 保存职位到数据库
|
||||
|
||||
@@ -89,17 +89,9 @@ class DeliverHandler extends BaseHandler {
|
||||
mqttClient: this.mqttClient
|
||||
});
|
||||
|
||||
// 6. 下发 get_job_list 拉取职位列表(tabLabel 切换期望 tab,job_type_id 随指令下发供设备使用)
|
||||
// 6. 下发 get_job_list(与前端一致:command 只带 pageCount + tabLabel,设备端不接收 keyword/job_type_id)
|
||||
const tabLabel = resume.deliver_tab_label || '';
|
||||
await this.getJobList(
|
||||
sn_code,
|
||||
platform,
|
||||
pageCount,
|
||||
task.id,
|
||||
tabLabel,
|
||||
accountConfig.job_type_id,
|
||||
accountConfig.keyword
|
||||
);
|
||||
await this.getJobList(sn_code, platform, pageCount, task.id, tabLabel);
|
||||
|
||||
// 7. 从数据库获取待投递职位
|
||||
const pendingJobs = await this.getPendingJobs(sn_code, platform, actualMaxCount * 3);
|
||||
@@ -114,8 +106,9 @@ class DeliverHandler extends BaseHandler {
|
||||
// 8. 合并过滤配置
|
||||
const filterConfig = this.mergeFilterConfig(deliverConfig, filterRules, jobTypeConfig);
|
||||
|
||||
// 9. 过滤已投递的公司
|
||||
const recentCompanies = await this.getRecentDeliveredCompanies(sn_code, 30);
|
||||
// 9. 过滤已投递的公司(repeat_deliver_days 由投递配置给出,缺省 30,上限 365)
|
||||
const repeatDeliverDays = Math.min(365, Math.max(1, Number(deliverConfig.repeat_deliver_days) || 30));
|
||||
const recentCompanies = await this.getRecentDeliveredCompanies(sn_code, repeatDeliverDays);
|
||||
|
||||
// 10. 过滤 + 评分 + 按 60 分阈值筛(入口在 jobFilterEngine,便于阅读)
|
||||
const filteredJobs = await jobFilterEngine.filterAndScoreJobsForDeliver(
|
||||
@@ -281,28 +274,16 @@ class DeliverHandler extends BaseHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* 下发 get_job_list 命令拉取职位列表
|
||||
* @param {string} tabLabel - 投递用期望标签文案,对应 resume_info.deliver_tab_label,get_job_list 会按此选择 tab
|
||||
* @param {number} jobTypeId - 职位类型 ID,随指令下发供设备使用
|
||||
* 下发 get_job_list 命令拉取职位列表(command_params 与前端约定:pageCount、tabLabel + sn_code、platform)
|
||||
*/
|
||||
async getJobList(sn_code, platform, pageCount, taskId, tabLabel = '', jobTypeId = null, accountKeyword = '') {
|
||||
async getJobList(sn_code, platform, pageCount, taskId, tabLabel = '') {
|
||||
const label = tabLabel != null && String(tabLabel).trim() !== '' ? String(tabLabel).trim() : '';
|
||||
const accKw = accountKeyword != null && String(accountKeyword).trim() !== '' ? String(accountKeyword).trim() : '';
|
||||
// 与 jobManager 一致:优先期望职位文案,其次账户搜索词,用于 job_postings.keyword
|
||||
const keyword = label || accKw;
|
||||
|
||||
const params = {
|
||||
sn_code,
|
||||
platform,
|
||||
pageCount,
|
||||
keyword
|
||||
...(label ? { tabLabel: label } : {})
|
||||
};
|
||||
if (label) {
|
||||
params.tabLabel = label;
|
||||
}
|
||||
if (jobTypeId != null && jobTypeId !== '') {
|
||||
params.job_type_id = jobTypeId;
|
||||
}
|
||||
const getJobListCommand = {
|
||||
command_type: 'get_job_list',
|
||||
command_name: '获取职位列表',
|
||||
|
||||
@@ -77,18 +77,12 @@ class SearchHandler extends BaseHandler {
|
||||
console.warn('[自动搜索] 读取 resume_info.deliver_tab_label 失败:', e.message);
|
||||
}
|
||||
|
||||
let listKeyword = (keyword && String(keyword).trim()) || (accountConfig.keyword && String(accountConfig.keyword).trim()) || '';
|
||||
if (!listKeyword && tabLabel) {
|
||||
listKeyword = tabLabel;
|
||||
}
|
||||
|
||||
const commandParams = {
|
||||
sn_code,
|
||||
keyword: listKeyword,
|
||||
platform: platformType,
|
||||
pageCount: pageCount || searchConfig.page_count || 3
|
||||
pageCount: pageCount || searchConfig.page_count || 3,
|
||||
...(tabLabel ? { tabLabel } : {})
|
||||
};
|
||||
if (tabLabel) commandParams.tabLabel = tabLabel;
|
||||
|
||||
const searchCommand = {
|
||||
command_type: 'get_job_list',
|
||||
|
||||
@@ -43,6 +43,7 @@ class ConfigManager {
|
||||
max_salary: 0, // 最高薪资
|
||||
page_count: 3, // 搜索页数
|
||||
max_deliver: 10, // 最大投递数
|
||||
repeat_deliver_days: 30, // 多少天内已投递过的公司不再投递(与 getRecentDeliveredCompanies 一致)
|
||||
filter_keywords: [], // 过滤关键词
|
||||
exclude_keywords: [], // 排除关键词
|
||||
time_range: null, // 时间范围
|
||||
|
||||
Reference in New Issue
Block a user