Files
autoAiWorkSys/_doc/搜索列表和投递功能开发规划.md
张成 8fa06435a9 1
2025-12-29 18:35:57 +08:00

765 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Boss直聘搜索列表和投递功能开发规划
## 📋 功能概述
基于Boss直聘Web端职位搜索页面`https://www.zhipin.com/web/geek/jobs`),完善搜索列表获取和职位投递功能,包括服务端任务创建、指令生成和完整流程实现。
## 🎯 目标功能
### 1. 搜索列表功能
- 支持多条件搜索(关键词、城市、薪资、经验、学历等)
- 支持分页获取职位列表
- 自动保存职位到数据库
- 支持职位去重和更新
### 2. 投递功能
- 单个职位投递
- 批量职位投递
- 投递状态跟踪
- 投递记录管理
## 📊 Boss直聘响应数据结构
### 响应格式示例
Boss直聘搜索职位列表的响应数据结构如下
```json
{
"code": 0,
"message": "Success",
"zpData": {
"resCount": 450, // 搜索结果总数
"hasMore": true, // 是否还有更多
"totalCount": 300, // 总职位数
"jobList": [ // 职位列表
{
"encryptJobId": "5ae70dfe114c23ab0nR-2ti-FFpU", // 职位ID投递必需
"encryptBossId": "b55854108ac215180XZ62N-_FlNT", // Boss ID投递必需
"securityId": "HP23zbQfaslvy-c1...", // 安全ID投递必需
"jobName": "全栈软件工程师", // 职位名称
"salaryDesc": "25-50K·19薪", // 薪资描述(需解析)
"jobExperience": "在校/应届", // 工作经验(需解析)
"jobDegree": "学历不限", // 学历要求
"city": 101020100, // 城市代码
"cityName": "上海", // 城市名称
"areaDistrict": "长宁区", // 区域
"businessDistrict": "新华路", // 商圈
"gps": { // 位置信息(优先使用)
"longitude": 121.41902537687392,
"latitude": 31.210308153576566
},
"encryptBrandId": "d283b66de3cefd891H1529q5Flc~", // 公司ID
"brandName": "上海大裂谷智能科技", // 公司名称
"brandScaleName": "100-499人", // 公司规模
"brandIndustry": "人工智能", // 公司行业
"brandStageName": "天使轮", // 融资阶段
"bossName": "杨明雨", // Boss姓名
"bossTitle": "HR", // Boss职位
"bossOnline": true, // Boss是否在线
"jobLabels": ["在校/应届", "学历不限"], // 职位标签
"skills": [], // 技能要求
"welfareList": ["带薪年假", "五险一金"], // 福利列表
"proxyJob": 0, // 是否外包0否1是
"industry": 100028 // 行业代码
}
]
}
}
```
### 关键字段说明
1. **投递必需字段**:
- `encryptJobId`: 职位ID投递时必须
- `encryptBossId`: Boss ID投递时必须
- `securityId`: 安全ID投递时必须每次搜索可能不同
2. **位置信息**:
- `gps.longitude``gps.latitude`: 直接使用无需调用位置服务API
- 如果没有gps字段再使用 `cityName + areaDistrict + businessDistrict + brandName` 调用位置服务
3. **薪资解析**:
- `salaryDesc` 格式多样:`"25-50K·19薪"``"20-30K"``"面议"`
- 需要解析出 `salaryMin``salaryMax`(单位:元)
4. **工作年限解析**:
- `jobExperience` 可能为:`"在校/应届"``"3-5年"``"1-3年"`
- 需要解析出 `experienceMin``experienceMax`
## 📊 功能架构
```
用户/系统触发
创建任务 (task_status)
生成指令序列 (task_commands)
执行指令 (通过MQTT发送到设备)
设备执行并返回结果
保存数据到数据库
更新任务和指令状态
```
## 🔧 技术实现
### 一、搜索列表功能完善
#### 1.1 指令参数扩展
**文件**: `api/middleware/job/jobManager.js`
**方法**: `get_job_list()`
**需要支持的参数**:
```javascript
{
keyword: '全栈工程师', // 搜索关键词
city: '101020100', // 城市代码(上海)
cityName: '上海', // 城市名称
salary: '20-30K', // 薪资范围
experience: '3-5年', // 工作经验
education: '本科', // 学历要求
industry: '互联网', // 公司行业
companySize: '100-499人', // 公司规模
financingStage: 'B轮', // 融资阶段
page: 1, // 页码
pageSize: 20, // 每页数量
pageCount: 3 // 获取页数(用于批量获取)
}
```
#### 1.2 任务创建接口
**文件**: `api/services/pla_account_service.js`
**新增方法**: `createSearchJobListTask()`
```javascript
/**
* 创建搜索职位列表任务
* @param {Object} params - 任务参数
* @param {number} params.id - 账号ID
* @param {string} params.keyword - 搜索关键词
* @param {string} params.city - 城市代码
* @param {Object} params.searchParams - 搜索条件(薪资、经验、学历等)
* @param {number} params.pageCount - 获取页数
* @returns {Promise<Object>} 任务创建结果
*/
async createSearchJobListTask(params) {
// 1. 验证账号和授权
// 2. 创建任务记录
// 3. 生成搜索指令
// 4. 执行指令
// 5. 返回任务ID
}
```
#### 1.3 指令生成逻辑
**文件**: `api/middleware/schedule/taskHandlers.js`
**需要完善**: `handleAutoDeliverTask()` 中的搜索指令生成
**当前实现**:
```javascript
const getJobListCommand = {
command_type: 'getJobList',
command_name: '获取职位列表',
command_params: JSON.stringify({
sn_code: sn_code,
keyword: keyword || accountConfig.keyword || '',
platform: platform || 'boss',
pageCount: pageCount || 3
}),
priority: config.getTaskPriority('search_jobs') || 5
};
```
**需要扩展为**:
```javascript
const getJobListCommand = {
command_type: 'get_job_list', // 统一使用下划线命名
command_name: '获取职位列表',
command_params: JSON.stringify({
sn_code: sn_code,
platform: platform || 'boss',
keyword: keyword || accountConfig.keyword || '',
city: city || accountConfig.city || '101020100', // 默认上海
cityName: cityName || accountConfig.cityName || '上海',
salary: searchParams?.salary || '',
experience: searchParams?.experience || '',
education: searchParams?.education || '',
industry: searchParams?.industry || '',
companySize: searchParams?.companySize || '',
financingStage: searchParams?.financingStage || '',
page: 1,
pageSize: 20,
pageCount: pageCount || 3
}),
priority: config.getTaskPriority('get_job_list') || 5,
sequence: 1
};
```
#### 1.4 职位数据保存优化
**文件**: `api/middleware/job/jobManager.js`
**方法**: `saveJobsToDatabase()`
**需要完善**:
- 支持更多字段映射从Boss直聘响应数据
- 优化位置解析逻辑
- 支持职位状态更新(已投递、已查看等)
- 添加职位匹配度计算
### 二、投递功能完善
#### 2.1 单个职位投递
**文件**: `api/middleware/job/jobManager.js`
**方法**: `applyJob()`
**当前状态**: ✅ 已实现基础功能
**需要完善**:
- 支持更多投递参数(期望薪资、求职信等)
- 优化错误处理
- 添加投递前检查(是否已投递、是否满足条件等)
#### 2.2 批量职位投递任务
**文件**: `api/middleware/schedule/taskHandlers.js`
**方法**: `handleAutoDeliverTask()`
**当前状态**: ✅ 已实现基础功能
**需要完善**:
1. **搜索条件完善**
- 支持城市、薪资、经验、学历等筛选条件
- 从账号配置中读取默认搜索条件
- 支持任务参数覆盖账号配置
2. **职位匹配算法优化**
- 完善距离计算(基于经纬度)
- 完善薪资匹配(解析薪资范围字符串)
- 完善工作年限匹配
- 完善学历匹配
- 完善权重评分系统
3. **投递指令生成**
- 为每个匹配的职位生成投递指令
- 支持批量投递(一次任务投递多个职位)
- 添加投递间隔控制(避免频繁投递)
#### 2.3 投递任务创建接口
**文件**: `api/services/pla_account_service.js`
**新增方法**: `createDeliverTask()`
```javascript
/**
* 创建投递任务
* @param {Object} params - 任务参数
* @param {number} params.id - 账号ID
* @param {string} params.keyword - 搜索关键词
* @param {Object} params.searchParams - 搜索条件
* @param {Object} params.filterRules - 过滤规则
* @param {number} params.maxCount - 最大投递数量
* @returns {Promise<Object>} 任务创建结果
*/
async createDeliverTask(params) {
// 1. 验证账号和授权
// 2. 创建任务记录
// 3. 生成搜索指令(获取职位列表)
// 4. 生成投递指令序列(根据匹配结果)
// 5. 执行任务
// 6. 返回任务ID
}
```
## 📝 具体开发任务
### 任务1: 完善搜索参数支持
**文件**: `api/middleware/job/jobManager.js`
**修改方法**: `get_job_list()`
**任务内容**:
1. 扩展参数支持(城市、薪资、经验、学历等)
2. 构建完整的搜索参数对象
3. 传递给MQTT指令
**代码位置**: 第153-206行
**预计工作量**: 2小时
---
### 任务2: 优化职位数据保存
**文件**: `api/middleware/job/jobManager.js`
**修改方法**: `saveJobsToDatabase()`
**任务内容**:
1. 完善字段映射从Boss直聘响应数据提取更多字段
2. 优化位置解析优先使用响应中的gps字段减少API调用
3. 解析薪资范围从salaryDesc提取min/max
4. 解析工作年限从jobExperience提取min/max
5. 添加职位状态管理
6. 添加职位匹配度字段
**Boss直聘响应数据字段映射表**:
| 响应字段 | 数据库字段 | 说明 | 示例值 |
|---------|-----------|------|--------|
| `encryptJobId` | `jobId` | 职位ID加密 | "5ae70dfe114c23ab0nR-2ti-FFpU" |
| `jobName` | `jobTitle` | 职位名称 | "全栈软件工程师" |
| `encryptBrandId` | `companyId` | 公司ID加密 | "d283b66de3cefd891H1529q5Flc~" |
| `brandName` | `companyName` | 公司名称 | "上海大裂谷智能科技" |
| `brandScaleName` | `companySize` | 公司规模 | "100-499人" |
| `brandIndustry` | `companyIndustry` | 公司行业 | "人工智能" |
| `brandStageName` | `brandStage` | 融资阶段 | "天使轮" |
| `salaryDesc` | `salary` | 薪资描述 | "25-50K·19薪" |
| `salaryDesc` | `salaryMin`, `salaryMax` | 薪资范围(需解析) | 25000, 50000 |
| `jobExperience` | `experience` | 工作经验 | "在校/应届" |
| `jobExperience` | `experienceMin`, `experienceMax` | 工作年限范围(需解析) | - |
| `jobDegree` | `education` | 学历要求 | "学历不限" |
| `jobDegree` | `educationLevel` | 学历等级(需映射) | - |
| `city` | `city` | 城市代码 | 101020100 |
| `cityName` | `cityName` | 城市名称 | "上海" |
| `areaDistrict` | `areaDistrict` | 区域 | "长宁区" |
| `businessDistrict` | `businessDistrict` | 商圈 | "新华路" |
| `gps.longitude` | `longitude` | 经度(优先使用) | 121.41902537687392 |
| `gps.latitude` | `latitude` | 纬度(优先使用) | 31.210308153576566 |
| `encryptBossId` | `encryptBossId` | Boss ID投递需要 | "b55854108ac215180XZ62N-_FlNT" |
| `securityId` | `securityId` | 安全ID投递需要 | "HP23zbQfaslvy-c1..." |
| `bossName` | `bossName` | Boss姓名 | "杨明雨" |
| `bossTitle` | `bossTitle` | Boss职位 | "HR" |
| `bossOnline` | `bossOnline` | Boss是否在线 | true |
| `jobLabels` | `jobLabels` | 职位标签JSON | ["在校/应届", "学历不限"] |
| `skills` | `skills` | 技能要求JSON | ["Java", "MySQL"] |
| `welfareList` | `welfareList` | 福利列表JSON | ["带薪年假", "五险一金"] |
| `proxyJob` | `isOutsourcing` | 是否外包 | 0/1 |
| `industry` | `industry` | 行业代码 | 100028 |
**关键优化点**:
1. **位置信息**: 优先使用响应中的 `gps.longitude``gps.latitude`避免调用位置服务API
- 如果 `gps` 字段存在,直接使用
- 如果不存在,再使用 `cityName + areaDistrict + businessDistrict + brandName` 调用位置服务
2. **薪资解析**: 从 `salaryDesc` 解析薪资范围
- 格式示例:`"25-50K·19薪"` → min: 25000, max: 50000
- 格式示例:`"20-30K"` → min: 20000, max: 30000
- 格式示例:`"面议"` → min: 0, max: 0
- 格式示例:`"15K以上"` → min: 15000, max: 999999
- 需要处理K、W、薪年终奖倍数
3. **工作年限解析**: 从 `jobExperience` 解析年限范围
- `"在校/应届"` → min: 0, max: 0
- `"1-3年"` → min: 1, max: 3
- `"3-5年"` → min: 3, max: 5
- `"5-10年"` → min: 5, max: 10
- `"10年以上"` → min: 10, max: 99
4. **学历映射**: 将学历描述映射为等级
- `"学历不限"``"unlimited"`
- `"高中"``"high_school"`
- `"大专"``"college"`
- `"本科"``"bachelor"`
- `"硕士"``"master"`
- `"博士"``"doctor"`
5. **投递必需字段**: 确保保存 `encryptJobId``encryptBossId``securityId`
- 这些字段在投递时必须使用
- `securityId` 每次搜索可能不同,需要实时保存
**代码位置**: 第215-308行
**预计工作量**: 4小时增加字段解析逻辑
---
### 任务3: 完善自动投递任务搜索条件
**文件**: `api/middleware/schedule/taskHandlers.js`
**修改方法**: `handleAutoDeliverTask()`
**任务内容**:
1. 从账号配置读取默认搜索条件
2. 支持任务参数覆盖
3. 构建完整的搜索参数
4. 传递给搜索指令
**代码位置**: 第220-233行
**预计工作量**: 2小时
---
### 任务4: 优化职位匹配算法
**文件**: `api/middleware/schedule/taskHandlers.js`
**修改方法**: `handleAutoDeliverTask()`
**任务内容**:
1. 完善距离计算(使用经纬度计算实际距离)
2. 完善薪资匹配(解析"20-30K"格式,转换为数值范围)
3. 完善工作年限匹配(解析"3-5年"格式)
4. 完善学历匹配(学历等级映射)
5. 优化权重评分计算
**代码位置**: 第255-400行职位评分和过滤逻辑
**预计工作量**: 4小时
---
### 任务5: 创建搜索任务接口(支持可选投递)
**文件**: `api/services/pla_account_service.js`
**新增方法**: `createSearchJobListTask()`
**方法签名**:
```javascript
/**
* 创建搜索职位列表任务(支持可选投递)
* @param {Object} params - 任务参数
* @param {number} params.id - 账号ID
* @param {string} params.keyword - 搜索关键词
* @param {Object} params.searchParams - 搜索条件(城市、薪资、经验、学历等)
* @param {number} params.pageCount - 获取页数
* @param {boolean} params.autoDeliver - 是否自动投递默认false
* @param {Object} params.filterRules - 过滤规则autoDeliver=true时使用
* @param {number} params.maxCount - 最大投递数量autoDeliver=true时使用
* @returns {Promise<Object>} 任务创建结果 { taskId, message, jobCount, deliveredCount }
*/
async createSearchJobListTask(params) {
// 1. 验证账号和授权
// 2. 创建任务记录 (taskType: 'search_jobs' 或 'auto_deliver')
// 3. 生成搜索指令
// 4. 执行搜索指令
// 5. 等待搜索完成(职位会自动保存到数据库)
// 6. 如果 autoDeliver=true:
// - 从数据库获取刚搜索到的职位列表
// - 根据简历信息和过滤规则匹配职位
// - 生成投递指令序列
// - 执行投递指令(带间隔控制)
// - 保存投递记录
// - 更新职位状态
// 7. 返回任务信息
}
```
**任务内容**:
1. 验证账号和授权
2. 创建任务记录根据autoDeliver参数设置taskType: 'search_jobs' 或 'auto_deliver'
3. 生成搜索指令command_type: 'get_job_list'
4. 执行搜索指令通过MQTT发送到设备
5. 等待搜索完成(职位会自动保存到数据库)
6. 如果 `autoDeliver=true`,继续执行投递流程:
- 从数据库获取刚搜索到的职位列表applyStatus = 'pending'
- 根据简历信息和过滤规则匹配职位(距离、薪资、工作年限、学历等)
- 为每个匹配的职位生成投递指令command_type: 'apply_job'
- 批量执行投递指令(带间隔控制,避免频繁投递)
- 保存投递记录 (apply_records)
- 更新职位状态 (job_postings.applyStatus = 'applied')
7. 返回任务信息(包含搜索到的职位数量和投递数量)
**代码位置**: 在 `runCommand()` 方法后添加
**预计工作量**: 5小时增加投递逻辑
---
---
### 任务6: 完善指令类型映射
**文件**: `api/middleware/schedule/command.js`
**修改位置**: 指令执行逻辑
**任务内容**:
1. 确保 `get_job_list` 指令类型正确映射到 `jobManager.get_job_list()`
2. 确保 `search_jobs` 指令类型正确映射到 `jobManager.search_jobs()`
3. 确保 `apply_job` 指令类型正确映射到 `jobManager.applyJob()`
**代码位置**: 第150-250行指令执行逻辑
**预计工作量**: 1小时
---
### 任务7: 添加搜索条件配置管理
**文件**: `api/model/pla_account.js`
**任务内容**:
1. 添加搜索条件配置字段(如果不存在)
2. 支持在账号配置中保存默认搜索条件
3. 支持在任务参数中覆盖搜索条件
**相关字段**:
- `search_config` (JSON): 搜索条件配置
```json
{
"city": "101020100",
"cityName": "上海",
"defaultSalary": "20-30K",
"defaultExperience": "3-5年",
"defaultEducation": "本科"
}
```
**预计工作量**: 1小时
---
## 🔄 工作流程
### 搜索职位列表流程(支持可选投递)
```
1. 用户/系统调用 createSearchJobListTask()
- 参数: { id, keyword, searchParams, pageCount, autoDeliver: true/false, filterRules, maxCount }
2. 创建任务记录 (task_status)
- taskType: 'search_jobs' 或 'auto_deliver'根据autoDeliver参数
3. 生成搜索指令 (task_commands)
- command_type: 'get_job_list'
- command_params: { keyword, city, salary, experience, education, ... }
4. 执行指令 (通过MQTT发送到设备)
5. 设备执行搜索并返回职位列表
6. 保存职位到数据库 (job_postings)
- 去重处理
- 位置解析优先使用gps字段
- 字段映射
- 状态: applyStatus = 'pending'(待投递)
7. 更新搜索指令状态为完成
8. 如果 autoDeliver=true继续执行投递流程:
8.1 从数据库获取刚搜索到的职位列表
- 筛选条件: applyStatus = 'pending', sn_code = 账号SN码
8.2 根据简历信息和过滤规则匹配职位
- 距离匹配(基于经纬度)
- 薪资匹配解析salaryDesc
- 工作年限匹配解析jobExperience
- 学历匹配解析jobDegree
- 权重评分
8.3 为每个匹配的职位生成投递指令
- command_type: 'apply_job'
- command_params: {
jobId: job.encryptJobId, // 职位ID必需
encryptBossId: job.encryptBossId, // Boss ID必需
securityId: job.securityId, // 安全ID必需从最新搜索结果获取
brandName: job.brandName, // 公司名称(可选)
jobTitle: job.jobName // 职位名称(可选)
}
8.4 批量执行投递指令(带间隔控制,避免频繁投递)
8.5 保存投递记录 (apply_records)
8.6 更新职位状态 (job_postings.applyStatus = 'applied')
9. 更新任务状态为完成
10. 返回任务信息(包含搜索到的职位数量和投递数量)
```
**说明**:
- 此接口支持两种模式:
- `autoDeliver=false`: 仅搜索,不投递。职位保存到数据库,状态为'pending'
- `autoDeliver=true`: 搜索完成后立即投递匹配的职位
- **重要**: 投递必须在搜索完成后立即执行,因为 `securityId` 等字段可能有时效性,前端页面变化后这些字段可能失效
- 不支持从已保存的职位中选择投递,因为职位信息可能已过期
## 📊 数据库字段说明
### job_postings 表需要完善的字段
| 字段名 | 类型 | 说明 | 状态 | 数据来源 |
|--------|------|------|------|----------|
| `city` | VARCHAR | 城市代码 | 待添加 | `job.city` |
| `cityName` | VARCHAR | 城市名称 | 待添加 | `job.cityName` |
| `areaDistrict` | VARCHAR | 区域 | 待添加 | `job.areaDistrict` |
| `businessDistrict` | VARCHAR | 商圈 | 待添加 | `job.businessDistrict` |
| `salaryMin` | INT | 最低薪资(元) | 待添加 | 从 `salaryDesc` 解析 |
| `salaryMax` | INT | 最高薪资(元) | 待添加 | 从 `salaryDesc` 解析 |
| `experienceMin` | INT | 最低工作年限 | 待添加 | 从 `jobExperience` 解析 |
| `experienceMax` | INT | 最高工作年限 | 待添加 | 从 `jobExperience` 解析 |
| `educationLevel` | VARCHAR | 学历等级 | 待添加 | 从 `jobDegree` 映射 |
| `matchScore` | DECIMAL | 匹配度评分 | 待添加 | 计算得出 |
| `encryptBossId` | VARCHAR | Boss ID | 已有 | `job.encryptBossId` |
| `securityId` | VARCHAR | 安全ID | 待添加 | `job.securityId`(投递必需) |
| `bossName` | VARCHAR | Boss姓名 | 待添加 | `job.bossName` |
| `bossTitle` | VARCHAR | Boss职位 | 待添加 | `job.bossTitle` |
| `bossOnline` | TINYINT | Boss是否在线 | 待添加 | `job.bossOnline` |
| `brandStage` | VARCHAR | 融资阶段 | 待添加 | `job.brandStageName` |
| `jobLabels` | JSON | 职位标签 | 待添加 | `job.jobLabels` |
| `skills` | JSON | 技能要求 | 待添加 | `job.skills` |
| `welfareList` | JSON | 福利列表 | 待添加 | `job.welfareList` |
| `isOutsourcing` | TINYINT | 是否外包 | 待添加 | `job.proxyJob` |
| `industry` | INT | 行业代码 | 待添加 | `job.industry` |
### pla_account 表需要添加的字段
| 字段名 | 类型 | 说明 | 状态 |
|--------|------|------|------|
| `search_config` | JSON | 搜索条件配置 | 待添加 |
| `city` | VARCHAR | 默认城市代码 | 待添加 |
| `cityName` | VARCHAR | 默认城市名称 | 待添加 |
## 🧪 测试计划
### 单元测试
1. 测试搜索参数构建
2. 测试职位数据保存
3. 测试职位匹配算法
4. 测试投递指令生成
### 集成测试
1. 测试完整搜索流程
2. 测试完整投递流程
3. 测试任务创建和执行
4. 测试MQTT通信
### 功能测试
1. 测试多条件搜索
2. 测试分页获取
3. 测试批量投递
4. 测试错误处理
## 📅 开发时间估算
| 任务 | 预计时间 | 优先级 |
|------|----------|--------|
| 任务1: 完善搜索参数支持 | 2小时 | 高 |
| 任务2: 优化职位数据保存 | 4小时 | 高 |
| 任务3: 完善自动投递任务搜索条件 | 2小时 | 高 |
| 任务4: 优化职位匹配算法 | 4小时 | 高 |
| 任务5: 创建搜索任务接口(支持可选投递) | 5小时 | 高 |
| 任务6: 完善指令类型映射 | 1小时 | 中 |
| 任务7: 添加搜索条件配置管理 | 1小时 | 低 |
**总计**: 约19小时
## 🚀 开发优先级
### 第一阶段(核心功能)
1. 任务1: 完善搜索参数支持
2. 任务2: 优化职位数据保存
3. 任务3: 完善自动投递任务搜索条件
4. 任务4: 优化职位匹配算法
5. 任务5: 创建搜索任务接口(支持可选投递)
### 第二阶段(接口完善)
6. 任务6: 完善指令类型映射
### 第三阶段(配置管理)
7. 任务7: 添加搜索条件配置管理
## 💡 使用场景说明
### 场景1: 仅搜索职位列表
```javascript
// 只搜索职位,不投递
const result = await plaAccountService.createSearchJobListTask({
id: accountId,
keyword: '全栈工程师',
searchParams: {
city: '101020100',
cityName: '上海',
salary: '20-30K',
experience: '3-5年',
education: '本科'
},
pageCount: 3,
autoDeliver: false // 不自动投递
});
// 返回: { taskId: 123, message: '搜索任务已创建', jobCount: 45 }
// 职位会自动保存到数据库,状态为 'pending'(待投递)
```
### 场景2: 搜索并自动投递(推荐)
```javascript
// 搜索职位并自动投递匹配的职位
const result = await plaAccountService.createSearchJobListTask({
id: accountId,
keyword: '全栈工程师',
searchParams: {
city: '101020100',
cityName: '上海',
salary: '20-30K',
experience: '3-5年',
education: '本科'
},
pageCount: 3,
autoDeliver: true, // 自动投递
filterRules: {
minSalary: 20000,
maxSalary: 30000,
keywords: ['Vue', 'React'],
excludeKeywords: ['外包', '外派']
},
maxCount: 10 // 最多投递10个职位
});
// 返回: { taskId: 123, message: '搜索并投递任务已创建', jobCount: 45, deliveredCount: 8 }
```
**重要说明**:
- **投递必须在搜索完成后立即执行**,因为 `securityId` 等字段可能有时效性
- 前端页面变化后,已保存的职位信息中的 `securityId` 可能失效,无法用于投递
- 因此不支持从已保存的职位中选择投递,必须在搜索后立即投递
- 如果只需要搜索不投递,设置 `autoDeliver: false`
- 如果需要搜索并投递,设置 `autoDeliver: true`,系统会根据匹配规则自动投递
## 📌 注意事项
1. **命名规范**: 统一使用下划线命名(`get_job_list` 而不是 `getJobList`
2. **错误处理**: 所有方法都需要完善的错误处理和日志记录
3. **数据验证**: 所有输入参数都需要验证
4. **性能优化**: 批量操作需要考虑性能,避免阻塞
5. **MQTT通信**: 确保指令参数格式正确,与客户端协议一致
6. **数据库事务**: 批量操作需要使用事务保证数据一致性
7. **投递时机**: 投递必须在搜索完成后立即执行,因为 `securityId` 等字段可能有时效性,前端页面变化后这些字段可能失效
8. **职位状态验证**: 投递前必须验证职位状态applyStatus = 'pending'),避免重复投递
9. **投递必需字段**: 投递时需要 `encryptJobId`、`encryptBossId` 和 `securityId`,这些字段必须从最新搜索结果中获取
10. **位置信息**: 优先使用响应中的 `gps` 字段避免不必要的API调用
11. **接口设计**: 搜索和投递在同一接口中完成,不支持单独的投递接口,因为已保存的职位信息可能已过期
## 🔗 相关文件
- `api/middleware/job/jobManager.js` - 工作管理核心逻辑
- `api/middleware/schedule/taskHandlers.js` - 任务处理器
- `api/middleware/schedule/command.js` - 指令管理器
- `api/services/pla_account_service.js` - 账号服务
- `api/model/job_postings.js` - 职位数据模型
- `api/model/pla_account.js` - 账号数据模型