This commit is contained in:
张成
2026-04-08 14:09:26 +08:00
parent e3d14dd637
commit 21fe005c19
7 changed files with 62 additions and 151 deletions

View File

@@ -13,6 +13,19 @@ class JobManager {
constructor() {
}
/**
* 设备 get_job_list 返回的 response.dataXHR 监听结果数组,每项 data 为接口 JSONzpData.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} 个岗位`);
// 保存职位到数据库

View File

@@ -89,17 +89,9 @@ class DeliverHandler extends BaseHandler {
mqttClient: this.mqttClient
});
// 6. 下发 get_job_list 拉取职位列表tabLabel 切换期望 tabjob_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_labelget_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: '获取职位列表',

View File

@@ -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',

View File

@@ -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, // 时间范围