From dfd31191633d9efc4bc1a09275c4dc0272bdd283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=88=90?= Date: Sat, 28 Feb 2026 10:38:28 +0800 Subject: [PATCH] 1 --- _doc/AI禁用说明.md | 140 - _doc/MQTT指令列表.md | 968 ---- _doc/主流程.md | 20 - _doc/任务与指令的区别说明.md | 354 -- _doc/功能规划文档.md | 874 ---- _doc/发布的接口文档.md | 574 --- _doc/命名规范统一方案.md | 100 - _doc/命名规范统一进度.md | 68 - _doc/在线简历响应文本.json | 860 ---- _doc/客户端待开发功能.md | 1174 ----- _doc/已删除文件清单.md | 47 - _doc/指令列表.md | 0 _doc/指令和任务模式适配检查报告.md | 123 - _doc/搜索列表和投递功能开发规划.md | 764 ---- _doc/数据库表同步指南.md | 210 - _doc/文件清理总结.md | 57 - _doc/服务合并完成说明.md | 54 - _doc/服务端升级功能逻辑说明.md | 320 -- _doc/目录整理执行计划.md | 26 - _doc/目录结构整理方案.md | 60 - _doc/简历功能使用前置条件.md | 239 - _doc/简历功能实现总结.md | 238 - _doc/简历功能快速参考.md | 251 - _doc/简历存储和分析功能说明.md | 169 - _doc/聊天列表功能说明.md | 281 -- _doc/聊天功能快速开始.md | 151 - _doc/职位列表.json | 4020 ----------------- _doc/调度架构分析与优化建议.md | 299 -- _doc/重构完成说明.md | 255 -- _doc/项目功能总结.md | 387 -- admin/src/api/task/task_status_server.js | 8 +- .../src/views/account/pla_account_detail.vue | 105 +- api/controller_admin/chat_records.js | 9 +- api/controller_admin/dashboard.js | 2 +- api/controller_admin/statistics.js | 29 +- api/controller_admin/task_status.js | 4 +- api/controller_front/user.js | 77 + api/middleware/job/managers/chatManager.js | 149 +- api/middleware/job/managers/jobManager.js | 16 +- api/middleware/schedule/core/scheduledJobs.js | 46 +- .../schedule/handlers/chatHandler.js | 159 +- .../schedule/handlers/deliverHandler.js | 16 +- .../schedule/infrastructure/config.js | 2 +- api/model/chat_records.js | 299 +- 44 files changed, 449 insertions(+), 13555 deletions(-) delete mode 100644 _doc/AI禁用说明.md delete mode 100644 _doc/MQTT指令列表.md delete mode 100644 _doc/主流程.md delete mode 100644 _doc/任务与指令的区别说明.md delete mode 100644 _doc/功能规划文档.md delete mode 100644 _doc/发布的接口文档.md delete mode 100644 _doc/命名规范统一方案.md delete mode 100644 _doc/命名规范统一进度.md delete mode 100644 _doc/在线简历响应文本.json delete mode 100644 _doc/客户端待开发功能.md delete mode 100644 _doc/已删除文件清单.md delete mode 100644 _doc/指令列表.md delete mode 100644 _doc/指令和任务模式适配检查报告.md delete mode 100644 _doc/搜索列表和投递功能开发规划.md delete mode 100644 _doc/数据库表同步指南.md delete mode 100644 _doc/文件清理总结.md delete mode 100644 _doc/服务合并完成说明.md delete mode 100644 _doc/服务端升级功能逻辑说明.md delete mode 100644 _doc/目录整理执行计划.md delete mode 100644 _doc/目录结构整理方案.md delete mode 100644 _doc/简历功能使用前置条件.md delete mode 100644 _doc/简历功能实现总结.md delete mode 100644 _doc/简历功能快速参考.md delete mode 100644 _doc/简历存储和分析功能说明.md delete mode 100644 _doc/聊天列表功能说明.md delete mode 100644 _doc/聊天功能快速开始.md delete mode 100644 _doc/职位列表.json delete mode 100644 _doc/调度架构分析与优化建议.md delete mode 100644 _doc/重构完成说明.md delete mode 100644 _doc/项目功能总结.md diff --git a/_doc/AI禁用说明.md b/_doc/AI禁用说明.md deleted file mode 100644 index 6a847da..0000000 --- a/_doc/AI禁用说明.md +++ /dev/null @@ -1,140 +0,0 @@ -# AI 功能禁用说明 - -## 📋 概述 - -根据需求,AI 接入功能暂时禁用,作为二期规划。当前使用简单的文本匹配来实现职位过滤功能。 - - - -## ✅ 已完成的修改 - -### 1. 创建文本匹配过滤服务 -- ✅ 创建了 `api/middleware/job/job_filter_service.js` - - 实现基于文本匹配的职位分析 - - 支持技能匹配、经验匹配、薪资匹配 - - 支持外包检测和关键词过滤 - -### 2. 禁用 AI 服务调用 - -#### 2.1 jobManager.js -- ✅ 注释掉 `aiService` 引用 -- ✅ 禁用 `analyzeResumeWithAI()` 调用 -- ✅ 修改 `analyzeResume()` 使用文本匹配 - -#### 2.2 resumeManager.js -- ✅ 注释掉 `aiService` 引用 -- ✅ 修改 `analyzeResume()` 使用文本匹配 -- ✅ 修改 `calculateMatchScore()` 使用 `jobFilterService.analyzeJobMatch()` - -#### 2.3 chatManager.js -- ✅ 注释掉 `aiService` 引用 -- ✅ 修改 `generateChatContent()` 使用默认模板 -- ✅ 修改 `generateInterviewInvitation()` 使用默认模板 -- ✅ 添加 `generateDefaultChatContent()` 方法 -- ✅ 添加 `generateDefaultInterviewInvitation()` 方法 - -## 🔧 文本匹配过滤功能 - -### 功能特性 - -1. **技能匹配度计算** - - 从职位描述中提取技能关键词 - - 与简历技能进行匹配 - - 计算匹配百分比(0-100分) - -2. **经验匹配度计算** - - 从职位描述中提取经验要求 - - 与简历工作经验进行匹配 - - 计算匹配分数 - -3. **薪资合理性计算** - - 解析职位薪资范围 - - 与期望薪资进行对比 - - 计算匹配分数 - -4. **外包检测** - - 检测职位描述中的外包关键词 - - 标记是否为外包岗位 - -5. **关键词过滤** - - 支持包含关键词过滤 - - 支持排除关键词过滤 - - 支持自定义排除关键词列表 - -### 使用示例 - -```javascript -const jobFilterService = require('./job_filter_service'); - -// 分析职位匹配度 -const analysis = jobFilterService.analyzeJobMatch(jobInfo, resumeInfo); -console.log('综合分数:', analysis.overallScore); -console.log('技能匹配:', analysis.skillMatch); -console.log('是否为外包:', analysis.isOutsourcing); - -// 过滤职位列表 -const filteredJobs = jobFilterService.filterJobs(jobs, { - minScore: 60, // 最低匹配分数 - excludeOutsourcing: true, // 排除外包 - excludeKeywords: ['销售', '客服'] // 排除关键词 -}, resumeInfo); -``` - -## 📝 默认模板 - -### 聊天内容模板 -- **greeting**: "您好,我对这个岗位很感兴趣,希望能进一步了解。" -- **interview**: "感谢您的回复,我很期待与您进一步沟通。" -- **followup**: "您好,想了解一下这个岗位的最新进展。" - -### 面试邀约模板 -- "感谢您的邀请,我很期待与您面谈。请问方便的时间是什么时候?" - -## ⚠️ 注意事项 - -1. **AI 服务文件保留** - - `api/middleware/job/aiService.js` 文件保留,但不再被调用 - - 二期规划时可以重新启用 - - - -3. **日志提示** - - 所有禁用 AI 的地方都有日志提示 - - 明确标注"AI分析已禁用(二期规划)" - -## 🔄 二期规划恢复步骤 - -当需要恢复 AI 功能时: - -1. 取消注释所有 `aiService` 引用 -2. 恢复 AI 方法调用 -3. 移除或注释文本匹配的替代代码 -4. 测试 AI 服务连接和功能 - -## 📊 当前功能对比 - -| 功能 | AI 版本 | 文本匹配版本 | -|------|---------|-------------| -| 简历分析 | AI 智能分析 | 技能关键词提取 | -| 职位匹配 | AI 深度分析 | 文本匹配评分 | -| 聊天生成 | AI 个性化生成 | 固定模板 | -| 面试邀约 | AI 个性化生成 | 固定模板 | -| 外包检测 | AI 判断 | 关键词匹配 | - -## 🎯 后续优化建议 - -1. **增强文本匹配** - - 添加更多技能关键词 - - 优化匹配算法 - - 支持同义词匹配 - -2. **规则配置化** - - 将过滤规则配置化 - - 支持用户自定义规则 - - 支持规则优先级 - -3. **匹配度优化** - - 优化评分算法 - - 添加更多匹配维度 - - 支持权重配置 - diff --git a/_doc/MQTT指令列表.md b/_doc/MQTT指令列表.md deleted file mode 100644 index 28597de..0000000 --- a/_doc/MQTT指令列表.md +++ /dev/null @@ -1,968 +0,0 @@ -# 自动找工作系统 - MQTT指令列表 - -> 版本: v1.0 | 更新日期: 2025-12-25 - -## 文档说明 - -本文档定义了服务端通过MQTT向客户端下发的所有指令格式和规范。所有操作都通过任务和指令的方式异步执行。 - ---- - -## 一、MQTT通信架构 - -### 1.1 通信流程 - -``` -┌──────────────┐ ┌──────────────┐ -│ 服务端 │ │ 客户端 │ -│ (Node.js) │ │ (设备端) │ -└──────┬───────┘ └──────┬───────┘ - │ │ - │ ① 创建任务(task_status表) │ - │ ② 生成指令(task_commands表) │ - │ │ - │ ③ MQTT Publish │ - │ Topic: {sn_code}/command │ - │ ─────────────────────────────> │ - │ │ - │ ④ 执行指令 │ - │ ⑤ 生成结果 │ - │ │ - │ ⑥ MQTT Publish │ - │ Topic: response │ - │ <───────────────────────────── │ - │ │ - │ ⑦ 更新指令状态(task_commands) │ - │ ⑧ 更新任务状态(task_status) │ - │ │ -``` - -### 1.2 MQTT配置 - -- **Broker地址**: `mqtt://192.144.167.231:1883` -- **订阅主题**: - - `heartbeat` - 设备心跳信息 - - `response` - 设备响应信息 -- **发布主题**: - - `{sn_code}/command` - 向指定设备发送指令 - -### 1.3 消息格式 - -**服务端 → 客户端 (指令)** -```json -{ - "commandId": "uuid", - "taskId": "uuid", - "platform": "boss", - "action": "search_jobs", - "data": { - "keyword": "全栈工程师", - "city": "101020100", - "page": 1 - } -} -``` - -**客户端 → 服务端 (响应)** -```json -{ - "commandId": "uuid", - "taskId": "uuid", - "code": 200, - "message": "执行成功", - "data": { - // 返回数据 - } -} -``` - -**客户端 → 服务端 (心跳)** -```json -{ - "sn_code": "device001", - "platform": "boss", - "timestamp": 1672531200000, - "status": "online", - "version": "1.0.0" -} -``` - ---- - -## 二、已实现指令列表 - -### 2.1 用户登录指令 - -#### get_login_qr_code - 获取登录二维码 - -**指令格式** -```json -{ - "action": "get_login_qr_code", - "platform": "boss", - "data": {} -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "二维码获取成功", - "data": { - "qrCode": "https://example.com/qrcode.png", - "qr_code_url": "https://example.com/qrcode.png", - "expire_time": 300 - } -} -``` - -**说明**: 获取登录二维码,用户扫码登录后客户端需要保存cookies/token - ---- - -#### get_user_info - 获取用户信息 - -**指令格式** -```json -{ - "action": "get_user_info", - "platform": "boss", - "data": {} -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "获取成功", - "data": { - "userId": "123456", - "userName": "张三", - "phone": "138****5678", - "isLoggedIn": true - } -} -``` - -**说明**: 获取当前登录用户的基本信息,验证登录状态 - ---- - -### 2.2 简历管理指令 - -#### get_online_resume - 获取在线简历 - -**指令格式** -```json -{ - "action": "get_online_resume", - "platform": "boss", - "data": {} -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "获取成功", - "data": { - "baseInfo": { - "name": "张三", - "gender": 1, - "age": 28, - "account": "138****5678", - "emailBlur": "zhang***@qq.com", - "workYears": 5, - "workYearDesc": "5年", - "degreeCategory": "本科" - }, - "expectList": [{ - "positionName": "全栈工程师", - "locationName": "上海", - "salaryDesc": "20-30K", - "industryDesc": "互联网" - }], - "workExpList": [{ - "companyName": "XX科技公司", - "positionName": "高级前端工程师", - "startDate": "2020-01", - "endDate": "2023-12", - "workContent": "负责前端架构设计和开发..." - }], - "projectExpList": [{ - "name": "电商平台项目", - "roleName": "技术负责人", - "startDate": "2022-01", - "endDate": "2023-06", - "projectDesc": "项目描述...", - "performance": "项目成果..." - }], - "educationExpList": [{ - "school": "XX大学", - "major": "计算机科学与技术", - "degreeName": "本科", - "endYear": 2018 - }], - "userDesc": "熟悉Vue、React、Node.js等技术栈...", - "certificationList": [] - } -} -``` - -**说明**: 获取用户在招聘平台上的完整简历信息 - ---- - -### 2.3 岗位搜索指令 - -#### search_jobs - 搜索岗位 (已实现但需完善) - -**指令格式** -```json -{ - "action": "search_jobs", - "platform": "boss", - "data": { - "keyword": "全栈工程师", - "city": "101020100", - "page": 1 - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "搜索成功", - "data": { - "total": 150, - "page": 1, - "jobList": [{ - "jobId": "job123456", - "jobTitle": "全栈工程师", - "companyName": "XX科技公司", - "companySize": "100-499人", - "salary": "20-30K", - "location": "上海·浦东新区", - "experience": "3-5年", - "education": "本科", - "jobRequirements": "1. 熟悉Vue/React...", - "jobDescription": "岗位职责...", - "bossName": "张经理", - "bossTitle": "技术总监" - }] - } -} -``` - -**说明**: 当前实现基础,需要扩展支持更多搜索条件 - ---- - -#### get_job_list - 获取岗位列表 - -**指令格式** -```json -{ - "action": "get_job_list", - "platform": "boss", - "data": { - "page": 1, - "pageSize": 20 - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "获取成功", - "data": { - "total": 50, - "page": 1, - "jobList": [ - // 同 search_jobs 的 jobList 格式 - ] - } -} -``` - -**说明**: 获取推荐岗位列表 - ---- - -### 2.4 投递管理指令 - -#### apply_job - 投递岗位 (基础实现) - -**指令格式** -```json -{ - "action": "apply_job", - "platform": "boss", - "data": { - "jobId": "job123456", - "expectSalary": "20-30K" - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "投递成功", - "data": { - "applyId": "apply123456", - "jobId": "job123456", - "applyTime": "2025-12-25 10:30:00", - "status": "success" - } -} -``` - -**错误码** -- `400` - 参数错误 -- `403` - 已投递过该岗位 -- `429` - 投递次数达到上限 -- `500` - 投递失败 - -**说明**: 向指定岗位投递简历 - ---- - -### 2.5 聊天管理指令 - -#### get_chat_list - 获取聊天列表 - -**指令格式** -```json -{ - "action": "get_chat_list", - "platform": "boss", - "data": { - "page": 1, - "pageSize": 20 - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "获取成功", - "data": { - "total": 15, - "chatList": [{ - "conversationId": "conv123456", - "jobId": "job123456", - "jobTitle": "全栈工程师", - "companyName": "XX科技", - "bossName": "张经理", - "lastMessage": "您好,请问...", - "lastMessageTime": "2025-12-25 10:30:00", - "unreadCount": 2, - "hasInterview": false - }] - } -} -``` - -**说明**: 获取与HR的聊天会话列表 - ---- - -#### send_chat_message - 发送聊天消息 - -**指令格式** -```json -{ - "action": "send_chat_message", - "platform": "boss", - "data": { - "conversationId": "conv123456", - "jobId": "job123456", - "content": "您好,我对这个岗位很感兴趣..." - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "发送成功", - "data": { - "messageId": "msg123456", - "sendTime": "2025-12-25 10:30:00" - } -} -``` - -**说明**: 向HR发送聊天消息 - ---- - -### 2.6 测试和调试指令 - -#### open_bot_detection - 打开测试页 - -**指令格式** -```json -{ - "action": "open_bot_detection", - "platform": "boss", - "data": {} -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "测试页已打开", - "data": {} -} -``` - -**说明**: 打开测试页面,用于调试 - ---- - -## 三、待开发指令列表 - -### 3.1 搜索投递增强指令 (优先级: HIGH) - -#### search_jobs_enhanced - 增强搜索岗位 ⭐⭐⭐⭐⭐ - -**指令格式** -```json -{ - "action": "search_jobs_enhanced", - "platform": "boss", - "data": { - "keyword": "全栈工程师", - "city": "101020100", - "page": 1, - "pageSize": 20, - - // 新增搜索条件 - "experience": "3", - "degree": "203", - "salary": "406", - "scale": "303", - "stage": "807", - "position": "100109", - - // 滚动加载方式 - "scrollLoadType": "auto", - "maxScrollPages": 5 - } -} -``` - -**参数说明** -| 参数 | 说明 | 示例值 | -|------|------|--------| -| keyword | 搜索关键词 | "全栈工程师" | -| city | 城市代码 | "101020100" (上海) | -| page | 页码 | 1 | -| pageSize | 每页数量 | 20 | -| experience | 工作经验 | "1"=1年以下, "3"=1-3年, "4"=3-5年, "5"=5-10年, "6"=10年以上 | -| degree | 学历要求 | "202"=不限, "203"=大专, "204"=本科, "205"=硕士, "206"=博士 | -| salary | 薪资范围 | "402"=3-5K, "403"=5-10K, "404"=10-15K, "405"=15-20K, "406"=20-30K, "407"=30-50K, "408"=50K以上 | -| scale | 公司规模 | "302"=0-20人, "303"=20-99人, "304"=100-499人, "305"=500-999人, "306"=1000人以上 | -| stage | 融资阶段 | "801"=未融资, "802"=天使轮, "803"=A轮, "804"=B轮, "805"=C轮, "806"=D轮及以上, "807"=已上市, "808"=不需要融资 | -| position | 职位类型 | "100109"=全栈, "100110"=前端, "100111"=后端, "100112"=移动端 | -| scrollLoadType | 加载方式 | "auto"=自动滚动, "manual"=手动翻页 | -| maxScrollPages | 最大滚动页数 | 5 | - -**返回格式** -```json -{ - "code": 200, - "message": "搜索成功", - "data": { - "total": 150, - "page": 1, - "hasMore": true, - "jobList": [{ - "jobId": "job123456", - "jobTitle": "全栈工程师", - "companyName": "XX科技公司", - "companySize": "100-499人", - "companyIndustry": "互联网", - "companyStage": "已上市", - "salary": "20-30K", - "salaryMonth": "14薪", - "location": "上海·浦东新区", - "longitude": 121.5273, - "latitude": 31.2172, - "experience": "3-5年", - "education": "本科", - "skills": ["Vue", "React", "Node.js"], - "jobRequirements": "1. 熟悉Vue/React...", - "jobDescription": "岗位职责...", - "welfare": ["五险一金", "带薪年假", "弹性工作"], - "bossName": "张经理", - "bossTitle": "技术总监", - "bossActiveStatus": "刚刚活跃", - "publishTime": "2025-12-25", - "viewCount": 150, - "applyCount": 30, - "isOutsourcing": false, - "jobLink": "https://www.zhipin.com/job_detail/xxx" - }] - } -} -``` - -**说明**: -- 支持Boss直聘完整的搜索筛选条件 -- 支持自动滚动加载更多岗位 -- 返回更详细的岗位信息 - ---- - -#### search_by_url - 通过URL搜索岗位 ⭐⭐⭐⭐⭐ - -**指令格式** -```json -{ - "action": "search_by_url", - "platform": "boss", - "data": { - "url": "https://www.zhipin.com/web/geek/jobs?city=101020100&query=%E5%85%A8%E6%A0%88%E5%B7%A5%E7%A8%8B%E5%B8%88", - "scrollLoadType": "auto", - "maxScrollPages": 5 - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "搜索成功", - "data": { - // 同 search_jobs_enhanced 返回格式 - } -} -``` - -**说明**: -- 直接使用Boss直聘的搜索URL -- 自动解析URL参数 -- 支持所有筛选条件 - ---- - -### 3.2 批量投递指令 (优先级: HIGH) - -#### batch_apply_jobs - 批量投递岗位 ⭐⭐⭐⭐⭐ - -**指令格式** -```json -{ - "action": "batch_apply_jobs", - "platform": "boss", - "data": { - "jobIds": ["job001", "job002", "job003"], - "expectSalary": "20-30K", - "applyInterval": 30, - "maxApplyCount": 10 - } -} -``` - -**参数说明** -| 参数 | 说明 | 示例值 | -|------|------|--------| -| jobIds | 岗位ID数组 | ["job001", "job002"] | -| expectSalary | 期望薪资 | "20-30K" | -| applyInterval | 投递间隔(秒) | 30 | -| maxApplyCount | 最大投递数量 | 10 | - -**返回格式** -```json -{ - "code": 200, - "message": "批量投递完成", - "data": { - "total": 10, - "success": 8, - "failed": 2, - "results": [{ - "jobId": "job001", - "status": "success", - "applyId": "apply001", - "message": "投递成功" - }, { - "jobId": "job002", - "status": "failed", - "message": "已投递过该岗位" - }] - } -} -``` - -**说明**: -- 批量投递多个岗位 -- 控制投递间隔避免被限制 -- 返回每个岗位的投递结果 - ---- - -### 3.3 简历刷新指令 (优先级: HIGH) - -#### refresh_resume - 刷新简历 ⭐⭐⭐⭐ - -**指令格式** -```json -{ - "action": "refresh_resume", - "platform": "boss", - "data": {} -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "简历刷新成功", - "data": { - "refreshTime": "2025-12-25 10:30:00", - "nextRefreshTime": "2025-12-25 12:30:00" - } -} -``` - -**说明**: -- 刷新简历提升排名 -- 每2小时可刷新一次 - ---- - -### 3.4 账号保活指令 (优先级: HIGH) - -#### auto_active - 自动活跃账号 ⭐⭐⭐⭐ - -**指令格式** -```json -{ - "action": "auto_active", - "platform": "boss", - "data": { - "actionType": "random", - "actions": ["browse_jobs", "view_company", "search_keyword", "update_visibility"] - } -} -``` - -**参数说明** -| 参数 | 说明 | 可选值 | -|------|------|--------| -| actionType | 动作类型 | "random"=随机, "sequence"=顺序 | -| actions | 动作列表 | ["browse_jobs", "view_company", "search_keyword", "update_visibility"] | - -**动作说明** -- `browse_jobs` - 浏览岗位(随机点击5-10个岗位) -- `view_company` - 查看公司主页 -- `search_keyword` - 搜索关键词(随机关键词) -- `update_visibility` - 修改简历可见性 - -**返回格式** -```json -{ - "code": 200, - "message": "活跃操作完成", - "data": { - "executedActions": ["browse_jobs", "view_company"], - "duration": 120, - "timestamp": "2025-12-25 10:30:00" - } -} -``` - -**说明**: -- 模拟真实用户行为 -- 随机时间间隔 -- 避免账号被标记为机器人 - ---- - -### 3.5 聊天增强指令 (优先级: MEDIUM) - -#### get_chat_detail - 获取聊天详情 ⭐⭐⭐ - -**指令格式** -```json -{ - "action": "get_chat_detail", - "platform": "boss", - "data": { - "conversationId": "conv123456", - "page": 1, - "pageSize": 50 - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "获取成功", - "data": { - "conversationId": "conv123456", - "jobId": "job123456", - "messages": [{ - "messageId": "msg001", - "senderId": "boss123", - "senderType": "boss", - "content": "您好,请问什么时候方便面试?", - "sendTime": "2025-12-25 10:30:00", - "isRead": true, - "messageType": "text", - "isInterviewInvitation": true - }] - } -} -``` - -**说明**: 获取完整的聊天历史记录 - ---- - -#### send_greeting - 发送打招呼 ⭐⭐⭐ - -**指令格式** -```json -{ - "action": "send_greeting", - "platform": "boss", - "data": { - "jobId": "job123456", - "content": "您好,我对这个岗位很感兴趣,期待能有机会详聊。" - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "打招呼成功", - "data": { - "conversationId": "conv123456", - "messageId": "msg001", - "sendTime": "2025-12-25 10:30:00" - } -} -``` - -**说明**: 主动向HR发起沟通 - ---- - -### 3.6 数据采集指令 (优先级: MEDIUM) - -#### get_job_detail - 获取岗位详情 ⭐⭐⭐ - -**指令格式** -```json -{ - "action": "get_job_detail", - "platform": "boss", - "data": { - "jobId": "job123456" - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "获取成功", - "data": { - "jobId": "job123456", - // 完整的岗位详情(同search_jobs_enhanced中的jobList项) - "companyDetail": { - "companyId": "company123", - "companyName": "XX科技公司", - "companyLogo": "https://...", - "companySize": "100-499人", - "companyIndustry": "互联网", - "companyStage": "已上市", - "companyAddress": "上海市浦东新区...", - "companyDesc": "公司介绍..." - } - } -} -``` - -**说明**: 获取岗位的完整详情信息 - ---- - -#### get_company_info - 获取公司信息 ⭐⭐⭐ - -**指令格式** -```json -{ - "action": "get_company_info", - "platform": "boss", - "data": { - "companyId": "company123" - } -} -``` - -**返回格式** -```json -{ - "code": 200, - "message": "获取成功", - "data": { - "companyId": "company123", - "companyName": "XX科技公司", - "companyLogo": "https://...", - "companySize": "100-499人", - "companyIndustry": "互联网", - "companyStage": "已上市", - "companyAddress": "上海市浦东新区...", - "companyDesc": "公司介绍...", - "companyBenefit": ["五险一金", "带薪年假"], - "companyPhotos": ["https://...", "https://..."], - "jobCount": 50, - "isVerified": true - } -} -``` - -**说明**: 获取公司的详细信息 - ---- - -## 四、指令执行规范 - -### 4.1 指令生命周期 - -``` -1. 创建 (pending) - ↓ -2. 下发 (sent) - ↓ -3. 执行中 (executing) - ↓ -4. 完成 (completed) / 失败 (failed) / 超时 (timeout) -``` - -### 4.2 超时设置 - -| 指令类型 | 超时时间 | 重试次数 | -|---------|----------|----------| -| 登录类指令 | 60秒 | 1次 | -| 简历获取 | 30秒 | 2次 | -| 岗位搜索 | 60秒 | 2次 | -| 岗位投递 | 30秒 | 1次 | -| 聊天消息 | 30秒 | 2次 | -| 保活操作 | 120秒 | 0次 | - -### 4.3 错误码规范 - -| 错误码 | 说明 | 处理方式 | -|--------|------|----------| -| 200 | 成功 | - | -| 400 | 参数错误 | 不重试 | -| 401 | 未登录 | 触发重新登录 | -| 403 | 无权限/已操作 | 不重试 | -| 429 | 请求过于频繁 | 延迟后重试 | -| 500 | 服务器错误 | 重试 | -| 503 | 服务不可用 | 延迟后重试 | -| 600 | 网络超时 | 重试 | -| 700 | 客户端错误 | 记录日志,不重试 | - -### 4.4 重试策略 - -- **指数退避**: `delay = min(1000 * 2^(retryCount-1), 30000ms)` -- **最大重试次数**: 根据指令类型决定(见4.2表格) -- **可重试错误**: 429, 500, 503, 600 -- **不可重试错误**: 400, 401, 403, 700 - ---- - -## 五、客户端实现要求 - -### 5.1 MQTT客户端 - -- **连接保持**: 断线自动重连 -- **心跳间隔**: 10秒 -- **订阅主题**: `{sn_code}/command` -- **发布主题**: `response`, `heartbeat` - -### 5.2 指令处理 - -1. **接收指令** - - 解析JSON格式 - - 验证必需字段 - - 记录指令日志 - -2. **执行指令** - - 根据action分发到对应处理器 - - 更新执行状态 - - 捕获异常错误 - -3. **返回响应** - - 统一响应格式 - - 包含commandId用于追踪 - - 返回详细的执行结果 - -### 5.3 异常处理 - -- **网络异常**: 自动重试 -- **登录过期**: 通知服务端重新登录 -- **页面加载失败**: 刷新页面重试 -- **元素定位失败**: 记录截图,返回错误 - -### 5.4 日志记录 - -- **请求日志**: 记录所有接收到的指令 -- **响应日志**: 记录所有返回的响应 -- **错误日志**: 记录所有异常和错误 -- **操作日志**: 记录关键操作步骤 - ---- - -## 六、开发优先级 - -### P0 - 立即开发 (投递核心功能) - -1. ✅ `search_jobs_enhanced` - 增强搜索 -2. ✅ `search_by_url` - URL搜索 -3. ✅ `batch_apply_jobs` - 批量投递 -4. ✅ `refresh_resume` - 简历刷新 - -### P1 - 短期开发 (保活和聊天) - -5. ✅ `auto_active` - 账号保活 -6. ✅ `send_greeting` - 发送打招呼 -7. ✅ `get_chat_detail` - 聊天详情 - -### P2 - 中期开发 (数据采集) - -8. ⭐ `get_job_detail` - 岗位详情 -9. ⭐ `get_company_info` - 公司信息 - ---- - -**文档维护**: 开发团队 -**最后更新**: 2025-12-25 diff --git a/_doc/主流程.md b/_doc/主流程.md deleted file mode 100644 index 6d3ee5d..0000000 --- a/_doc/主流程.md +++ /dev/null @@ -1,20 +0,0 @@ - - - # handleAutoDeliverTask ,自动投递岗位 - - - 1. 如果 2 小时之内没有获取在线简历 ,则重新获取一下在线简历,没有创建,有则更新 - - 2. 获取职位列表, 按照用户 简历的信息resume_info 中的 skills expectedLocation ,expectedSalary ,expectedPosition ,workYears ,education location 和 职位类型 job_types 中的 年龄,薪资,距离职位的位置,commonSkills,excludeKeywords , - user_longitude, - user_longitude - - job_postings和 经纬度 做距离匹配 ,按照 用户中可以配置 is_salary_priority 优先级 按照权重 占比 过滤 - defaultValue: [ { "key": "distance", "weight": 50 }, { "key": "salary", "weight": 20 }, { "key": "work_years", "weight": 10 }, { "key": "education", "weight": 20} ] - - 3.投递合适匹配的岗位 - - - - - diff --git a/_doc/任务与指令的区别说明.md b/_doc/任务与指令的区别说明.md deleted file mode 100644 index 6030bae..0000000 --- a/_doc/任务与指令的区别说明.md +++ /dev/null @@ -1,354 +0,0 @@ -# 任务与指令的区别说明 - -## 📋 概述 - -在调度系统中,**任务(Task)** 和 **指令(Command)** 是两个不同层次的概念,它们的关系是:**一个任务可以包含多个指令**。 - -### ⚠️ 重要说明 - -**当前系统实际情况**: -- **真正的任务**:目前只有 `auto_deliver`(自动投递任务)是真正的任务,它包含多个步骤和指令 -- **伪任务**:虽然代码中有 `get_resume`、`get_job_list`、`send_chat`、`apply_job` 等任务处理器,但它们实际上只是包装了单个指令,本质上就是直接执行指令 - -**为什么会有伪任务**: -1. 统一的任务追踪和日志记录 -2. 保持接口的一致性 -3. 未来可能扩展为真正的任务(包含多个步骤) - -## 🔄 层级关系 - -``` -任务(Task) - ├── 指令1(Command) - ├── 指令2(Command) - └── 指令3(Command) -``` - -## 📊 详细对比 - -| 维度 | 任务(Task) | 指令(Command) | -|------|------------|----------------| -| **概念层级** | 业务层 | 执行层 | -| **数据库表** | `task_status` | `task_commands` | -| **管理模块** | TaskQueue(任务队列) | CommandManager(指令管理器) | -| **处理模块** | TaskHandlers(任务处理器) | jobManager(业务管理器) | -| **粒度** | 粗粒度(业务流程) | 细粒度(具体操作) | -| **包含关系** | 包含多个指令 | 属于某个任务 | -| **执行方式** | 由任务队列调度 | 由指令管理器执行 | -| **通信方式** | 内部调度 | 通过 MQTT 发送到客户端 | - -## 🎯 任务(Task) - -### 定义 -任务是业务层面的概念,代表一个完整的业务流程或工作单元。 - -### 特点 -- **业务导向**:代表一个完整的业务目标 -- **可包含多个步骤**:一个任务可以包含多个指令 -- **有生命周期**:pending → running → completed/failed -- **有优先级**:可以设置任务优先级 -- **有超时机制**:任务级别有超时保护 - -### 任务类型示例 - -**真正的任务(包含多个步骤)**: -- `auto_deliver` - 自动投递任务(包含多个子操作:获取简历、获取岗位列表、筛选职位、批量投递) -- `auto_chat` - 自动沟通任务(待实现:自动与HR进行沟通,回复消息等) -- `auto_active_account` - 自动活跃账号任务(待实现:自动执行操作保持账号活跃度) - -**注意**:目前系统中只有 `auto_deliver` 是已实现的真正任务,`auto_chat` 和 `auto_active_account` 是待实现的任务框架。 - -### 任务表结构(task_status) -```javascript -{ - id: 1, - sn_code: 'GHJU', - taskType: 'auto_deliver', - taskName: '自动投递 - 前端开发', - status: 'running', - priority: 7, - taskParams: { keyword: '前端', platform: 'boss' }, - result: {}, - startTime: '2024-01-01 10:00:00', - endTime: null, - duration: 0 -} -``` - -### 任务执行流程 -```javascript -// 1. 添加任务到队列 -await taskQueue.addTask(sn_code, { - taskType: 'auto_deliver', - taskName: '自动投递', - taskParams: { keyword: '前端' } -}); - -// 2. 任务队列调度执行 -// 3. 任务处理器处理任务 -// 4. 任务处理器创建并执行指令 -``` - -## ⚙️ 指令(Command) - -### 定义 -指令是执行层面的概念,代表一个具体的操作,通过 MQTT 发送到客户端执行。 - -### 特点 -- **执行导向**:代表一个具体的操作 -- **原子性**:一个指令是一个不可分割的操作 -- **有执行顺序**:指令可以按顺序执行 -- **有超时机制**:指令级别有超时保护 -- **MQTT 通信**:通过 MQTT 发送到客户端 - -### 指令类型示例 -- `getOnlineResume` - 获取在线简历 -- `getJobList` - 获取岗位列表 -- `applyJob` - 投递简历 -- `sendChatMessage` - 发送聊天消息 -- `getLoginQrCode` - 获取登录二维码 - -### 指令表结构(task_commands) -```javascript -{ - id: 1, - task_id: 100, // 关联的任务ID - command_type: 'getOnlineResume', - command_name: '获取在线简历', - command_params: '{"sn_code":"GHJU"}', - status: 'completed', - sequence: 1, - priority: 9, - start_time: '2024-01-01 10:00:00', - end_time: '2024-01-01 10:00:30', - duration: 30000 -} -``` - -### 指令执行流程 -```javascript -// 1. 任务处理器创建指令 -const commands = [{ - command_type: 'getOnlineResume', - command_name: '获取在线简历', - command_params: JSON.stringify({ sn_code }) -}]; - -// 2. 指令管理器执行指令 -await command.executeCommands(taskId, commands, mqttClient); - -// 3. 通过 MQTT 发送到客户端 -// 4. 客户端执行并返回结果 -``` - -## 🔗 关系示例 - -### 示例1:自动投递任务 - -**任务**:`auto_deliver`(自动投递任务) - -**包含的指令**: -1. `getOnlineResume` - 获取在线简历 -2. `getJobList` - 获取岗位列表 -3. `applyJob` - 投递简历(可能多个) - -```javascript -// 任务处理器创建多个指令 -async handleAutoDeliverTask(task) { - // 1. 获取简历指令 - const getResumeCommand = { - command_type: 'getOnlineResume', - command_name: '获取在线简历', - ... - }; - - // 2. 获取岗位列表指令 - const getJobListCommand = { - command_type: 'getJobList', - command_name: '获取岗位列表', - ... - }; - - // 3. 投递指令(可能多个) - const applyCommands = jobs.map(job => ({ - command_type: 'applyJob', - command_name: `投递简历 - ${job.jobTitle}`, - ... - })); - - // 执行所有指令 - await command.executeCommands(task.id, [ - getResumeCommand, - getJobListCommand, - ...applyCommands - ], mqttClient); -} -``` - -### 示例2:获取简历(伪任务,实际是指令) - -**说明**:虽然代码中有 `get_resume` 任务处理器,但它实际上只是包装了单个指令,本质上就是直接执行指令。 - -**任务**:`get_resume`(获取简历任务) - -**包含的指令**: -1. `getOnlineResume` - 获取在线简历 - -```javascript -async handleGetResumeTask(task) { - // 实际上只是创建一个指令并执行 - const commands = [{ - command_type: 'getOnlineResume', - command_name: '获取在线简历', - command_params: JSON.stringify({ sn_code: task.sn_code }) - }]; - - await command.executeCommands(task.id, commands, this.mqttClient); -} -``` - -**注意**:这种"任务"实际上可以直接作为指令执行,不需要通过任务队列。它们存在的原因可能是为了: -1. 统一的任务追踪和日志记录 -2. 未来可能扩展为真正的任务(包含多个步骤) -3. 保持接口的一致性 - -## 📈 执行流程图 - -``` -┌─────────────────┐ -│ 任务队列 │ -│ (TaskQueue) │ -└────────┬────────┘ - │ 调度任务 - ↓ -┌─────────────────┐ -│ 任务处理器 │ -│ (TaskHandlers) │ -└────────┬────────┘ - │ 创建指令 - ↓ -┌─────────────────┐ -│ 指令管理器 │ -│ (CommandManager)│ -└────────┬────────┘ - │ 执行指令 - ↓ -┌─────────────────┐ -│ 业务管理器 │ -│ (jobManager) │ -└────────┬────────┘ - │ MQTT 发送 - ↓ -┌─────────────────┐ -│ 客户端设备 │ -│ (Python Client)│ -└─────────────────┘ -``` - -## 🎨 设计优势 - -### 1. **职责分离** -- **任务层**:负责业务逻辑和流程编排 -- **指令层**:负责具体操作和 MQTT 通信 - -### 2. **灵活性** -- 一个任务可以包含不同数量的指令 -- 可以根据业务需求动态创建指令 - -### 3. **可追踪性** -- 任务级别:可以追踪整个业务流程 -- 指令级别:可以追踪每个具体操作 - -### 4. **错误处理** -- 任务级别:处理业务逻辑错误 -- 指令级别:处理执行错误和超时 - -## 📝 代码示例 - -### 任务处理器创建指令 - -```javascript -// api/middleware/schedule/taskHandlers.js -async handleAutoDeliverTask(task) { - const { sn_code, taskParams } = task; - - // 1. 创建获取简历指令 - const getResumeCommand = { - command_type: 'getOnlineResume', - command_name: '获取在线简历', - command_params: JSON.stringify({ sn_code, platform: 'boss' }) - }; - - // 2. 创建获取岗位列表指令 - const getJobListCommand = { - command_type: 'getJobList', - command_name: '获取岗位列表', - command_params: JSON.stringify({ - sn_code, - keyword: taskParams.keyword, - platform: 'boss' - }) - }; - - // 3. 执行指令序列 - const result = await command.executeCommands( - task.id, - [getResumeCommand, getJobListCommand], - this.mqttClient - ); - - return result; -} -``` - -### 指令管理器执行指令 - -```javascript -// api/middleware/schedule/command.js -async executeCommand(taskId, command, mqttClient) { - // 1. 创建指令记录 - const commandRecord = await db.getModel('task_commands').create({ - task_id: taskId, - command_type: command.command_type, - command_name: command.command_name, - status: 'pending' - }); - - // 2. 调用业务管理器执行 - const result = await jobManager[commandType]( - sn_code, - mqttClient, - commandParams - ); - - // 3. 更新指令状态 - await this.updateCommandStatus(commandId, 'completed', result); - - return result; -} -``` - -## 🔍 总结 - -- **任务(Task)**:业务层面的工作单元,代表一个完整的业务流程 - - **真正的任务**:包含多个步骤/指令,如 `auto_deliver` - - **伪任务**:虽然叫任务,但实际只是包装了单个指令,如 `get_resume`、`get_job_list` 等 - -- **指令(Command)**:执行层面的操作单元,代表一个具体的操作 - - 通过 MQTT 发送到客户端执行 - - 如:`getOnlineResume`、`getJobList`、`applyJob` 等 - -- **关系**: - - 真正的任务包含多个指令,指令按顺序执行 - - 伪任务只是指令的包装,本质上就是直接执行指令 - -- **管理**:任务由任务队列管理,指令由指令管理器管理 - -- **通信**:任务在服务端内部调度,指令通过 MQTT 发送到客户端 - -- **当前状态**: - - 目前系统中只有 `auto_deliver` 是真正的任务(包含多个步骤) - - 其他如 `get_resume`、`get_job_list`、`send_chat`、`apply_job` 虽然叫任务,但实际只是指令的包装 - -这种设计实现了业务逻辑和执行逻辑的分离,提高了系统的灵活性和可维护性。伪任务的存在可能是为了统一的任务追踪和未来扩展。 - diff --git a/_doc/功能规划文档.md b/_doc/功能规划文档.md deleted file mode 100644 index 183412b..0000000 --- a/_doc/功能规划文档.md +++ /dev/null @@ -1,874 +0,0 @@ -# 自动找工作系统 - 功能规划文档 - -> 版本: v1.0 | 规划日期: 2025-12-25 | 状态: 待开发 - -## 文档说明 - -本文档规划了自动找工作系统的未开发功能,按优先级分为4个方向共20项功能。每项功能包含现状分析、待开发内容和预期价值,可直接转化为开发任务。 - -## 优先级说明 - -- **HIGH**: 核心功能,对系统价值提升明显,建议优先开发 -- **MEDIUM**: 重要优化,提升用户体验和系统性能,可分阶段实施 -- **LOW**: 未来规划,可根据实际需求决定是否开发 - ---- - -## 第一部分: 功能完善和补充 - -**优先级: HIGH** | **预计工期: 4-6周** - -### 1.1 自动聊天功能完善 ⭐⭐⭐⭐⭐ - -**现状分析** -- ✅ 聊天记录表结构完整 (`chat_records`) -- ✅ AI聊天内容生成基础框架 (`aiService.generateChatContent`) -- ✅ 聊天类型分类 (greeting/followup/interview/reply) -- ❌ AI生成器未完整实现 -- ❌ 聊天时机判断逻辑缺失 -- ❌ 多轮对话上下文管理未实现 - -**待开发内容** -1. **AI聊天内容生成器完整实现** - - 完善 Prompt 模板(不同场景) - - 集成简历信息和岗位描述 - - 个性化内容生成(根据HR回复调整策略) - - 长度和语气控制 - -2. **聊天时机智能判断** - - HR查看后多久发消息(规则+AI预测) - - 避免过于频繁或过晚联系 - - 根据不同平台特性调整策略 - - 工作时间优先发送 - -3. **多轮对话上下文管理** - - 记录对话历史 - - 上下文理解(避免重复询问) - - 话题延续和自然过渡 - - 面试邀约智能识别和响应 - -4. **情感分析和回复策略调整** - - 分析HR回复的情感倾向 - - 根据情感调整后续策略 - - 识别拒绝信号(及时停止沟通) - - 识别兴趣信号(加大沟通力度) - -**技术实现** -- 文件路径: `api/middleware/job/chatManager.js` -- 依赖: `aiService.js`, `chat_records表` -- 预计工期: 2周 - -**预期价值** -- 📈 HR回复率提升 30%+ -- 📈 面试邀约率提升 20%+ -- 💡 减少人工沟通成本 80%+ -- ✨ 提供24小时自动化沟通能力 - ---- - -### 1.2 账号保活任务 ⭐⭐⭐⭐⭐ - -**现状分析** -- ✅ 配置项已有 (`pla_account.auto_active`, `active_interval`, `active_actions_json`) -- ✅ 任务类型定义 (`auto_active_account`) -- ❌ 执行逻辑未实现 -- ❌ 行为模拟策略缺失 - -**待开发内容** -1. **定时浏览岗位模拟真实用户** - - 随机浏览岗位详情 - - 模拟点击、滚动行为 - - 页面停留时间随机化(10-60秒) - - 每日浏览次数控制(5-20次) - -2. **随机时间间隔访问** - - 避免固定时间访问(容易被识别) - - 工作时间随机分布 - - 模拟午休和下班后的访问 - - 周末降低活跃频率 - -3. **多样化操作行为** - - 搜索岗位(随机关键词) - - 查看推荐岗位 - - 浏览公司主页 - - 修改简历可见性 - - 更新最后活跃时间 - -4. **避免账号被标记为机器人** - - 行为模式随机化 - - 添加鼠标轨迹模拟 - - 操作速度人性化(不要太快) - - 避免连续大量操作 - -**技术实现** -- 文件路径: `api/middleware/schedule/taskHandlers.js` (新增 `handleAutoActiveTask`) -- MQTT指令: 新增 `auto_active` 操作类型 -- 预计工期: 1周 - -**预期价值** -- 📉 账号封禁风险降低 70%+ -- 📈 简历曝光率提升 40%+ -- 🔒 账号在线状态保持稳定 -- ✨ 自动维护账号活跃度 - ---- - -### 1.3 简历自动更新 ⭐⭐⭐⭐ - -**现状分析** -- ✅ 简历同步功能完整 -- ✅ 简历信息存储完善 -- ❌ 简历刷新逻辑未实现 -- ❌ 简历优化建议缺失 - -**待开发内容** -1. **定时刷新简历排名** - - 每天自动刷新简历(提升排名) - - 最佳刷新时间智能选择(如早上9点) - - 通过MQTT下发刷新指令 - - 记录刷新历史和效果 - -2. **简历内容优化建议** - - AI分析当前简历不足 - - 给出具体优化建议(哪些技能需要补充) - - 对比同类岗位的简历特征 - - 建议调整项目经验描述 - -3. **A/B测试不同简历版本效果** - - 支持多个简历版本 - - 自动切换测试 - - 统计不同版本的查看率和回复率 - - 推荐最优版本 - -**技术实现** -- 文件路径: `api/middleware/job/resumeManager.js` (新增刷新方法) -- MQTT指令: 新增 `refresh_resume` 操作 -- 数据库: `resume_info` 新增 `last_refresh_time` 字段 -- 预计工期: 1周 - -**预期价值** -- 📈 简历曝光率提升 50%+ -- 📈 查看率提升 30%+ -- 💡 简历质量持续优化 -- ✨ 自动维护简历新鲜度 - ---- - -### 1.4 岗位黑名单和收藏 ⭐⭐⭐⭐ - -**现状分析** -- ❌ 黑名单功能未实现 -- ❌ 收藏功能未实现 -- ❌ 岗位对比功能缺失 - -**待开发内容** -1. **公司黑名单** - - 不再投递某公司的岗位 - - 黑名单原因记录(薪资虚标、工作内容不符等) - - 支持批量添加 - - 黑名单导入导出 - -2. **岗位类型黑名单** - - 不再投递某类岗位(如外包、销售) - - 支持自定义黑名单关键词 - - 黑名单优先级高于匹配规则 - -3. **收藏感兴趣岗位** - - 标记收藏岗位 - - 收藏原因备注 - - 收藏夹分类管理 - - 收藏岗位状态跟踪(是否还在招聘) - -4. **岗位对比功能** - - 多个岗位并排对比 - - 对比维度: 薪资、技能要求、公司、地点、福利 - - AI给出推荐意见 - - 导出对比报告 - -**技术实现** -- 数据库: 新增 `job_blacklist`, `job_favorites` 表 -- 文件路径: `api/controller_admin/` 新增相关API -- 前端: `admin/src/views/work/` 新增黑名单和收藏页面 -- 预计工期: 1周 - -**预期价值** -- 📈 投递精准度提升 40%+ -- 📉 无效投递减少 60%+ -- 💡 提供个性化岗位管理 -- ✨ 提高求职效率 - ---- - -### 1.5 多轮面试跟踪 ⭐⭐⭐⭐ - -**现状分析** -- ✅ `apply_records` 表有 `hasInterview` 字段 -- ❌ 只记录是否有面试,未细分轮次 -- ❌ Offer管理功能缺失 -- ❌ 入职状态未追踪 - -**待开发内容** -1. **一面/二面/三面状态追踪** - - 新增面试轮次字段 (`interview_round`) - - 每轮面试时间、地点、面试官记录 - - 面试类型(电话、视频、现场) - - 面试状态(待面试、已面试、通过、淘汰) - -2. **面试反馈记录** - - 面试官反馈内容 - - 面试问题记录 - - 自我评价 - - 改进建议 - -3. **Offer管理** - - Offer详情(薪资、福利、入职时间) - - 接受/拒绝/谈薪状态 - - 谈薪记录(几轮谈判,最终结果) - - Offer对比(如有多个Offer) - -4. **入职状态追踪** - - 入职日期 - - 试用期状态 - - 转正时间 - - 离职时间(如有) - -**技术实现** -- 数据库: `apply_records` 新增字段或新增 `interview_records`, `offer_records` 表 -- 文件路径: `api/controller_admin/apply_records.js` 扩展 -- 前端: `admin/src/views/work/apply_records.vue` 新增详情面板 -- 预计工期: 1.5周 - -**预期价值** -- 📊 完整的求职生命周期管理 -- 📈 面试准备更充分 -- 💡 Offer决策更科学 -- ✨ 提供长期职业数据积累 - ---- - -## 第二部分: AI能力增强 - -**优先级: HIGH** | **预计工期: 5-7周** - -### 2.1 简历智能优化 ⭐⭐⭐⭐⭐ - -**现状分析** -- ✅ 简历AI分析基础功能 (`aiService.analyzeResume`) -- ✅ 竞争力评分、技能提取、优劣势分析 -- ❌ 优化建议深度不足 -- ❌ 针对性改进方案缺失 - -**待开发内容** -1. **AI简历分析深度提升** - - 细粒度分析(每个项目、每段经历) - - 识别简历中的弱项和亮点 - - 对比行业优秀简历 - - 生成详细分析报告 - -2. **简历改进建议(针对性)** - - 针对目标岗位给出定制化建议 - - 建议补充哪些技能关键词 - - 建议如何重写工作描述 - - 建议哪些内容需要精简 - -3. **技能关键词优化建议** - - 分析热门技能关键词 - - 建议替换为更专业的术语 - - 建议技能顺序排列 - - 建议补充相关技能 - -4. **项目经验描述优化** - - 使用STAR法则重写项目描述 - - 量化项目成果(如提升XX%性能) - - 突出个人贡献和技术难点 - - 精简冗长描述 - -**技术实现** -- 文件路径: `api/middleware/job/aiService.js` 新增 `optimizeResume` 方法 -- Prompt工程: 设计专业的简历优化Prompt -- 前端: `resume_info_detail.vue` 新增优化建议面板 -- 预计工期: 2周 - -**预期价值** -- 📈 简历竞争力提升 20%+ -- 📈 查看率提升 35%+ -- 📈 回复率提升 25%+ -- 💡 简历质量专业化 - ---- - -### 2.2 面试问题预测 ⭐⭐⭐⭐ - -**待开发内容** -1. **基于岗位描述预测面试问题** - - 分析岗位职责和要求 - - 预测技术问题(如React性能优化、数据库索引等) - - 预测行为问题(如团队合作、项目经验) - - 预测HR问题(如离职原因、职业规划) - -2. **提供参考答案** - - 给出专业、结构化的答案 - - 提供多种回答思路 - - 标注答案亮点和注意事项 - - 面试官可能的追问 - -3. **根据简历生成个性化回答** - - 结合简历中的项目经验 - - 使用简历中的真实案例 - - 避免空洞的回答 - - 突出个人优势 - -**技术实现** -- 文件路径: `api/middleware/job/aiService.js` 新增 `predictInterviewQuestions` 方法 -- 数据来源: `job_postings.jobDescription`, `resume_info` -- 前端: 新增 `interview_prep.vue` 面试准备页面 -- 预计工期: 1.5周 - -**预期价值** -- 📈 面试通过率提升 30%+ -- ⏱️ 面试准备时间减少 70%+ -- 💡 回答更专业、更自信 -- ✨ 提供全方位面试辅导 - ---- - -### 2.3 薪资谈判策略 ⭐⭐⭐⭐ - -**待开发内容** -1. **AI分析岗位薪资合理范围** - - 根据岗位要求和地区计算合理薪资 - - 参考行业薪资数据(如拉勾、Boss薪资报告) - - 考虑公司规模和融资阶段 - - 给出薪资范围建议(如18-22K) - -2. **给出谈薪建议和话术** - - 什么时候开始谈薪(面试哪个阶段) - - 如何提薪资要求(不卑不亢) - - 谈判策略(如先等对方报价) - - 具体话术模板 - -3. **根据市场行情评估Offer价值** - - 对比市场平均薪资 - - 综合评估(薪资+福利+发展空间) - - 识别低于市场价的Offer - - 给出接受/拒绝建议 - -**技术实现** -- 文件路径: `api/middleware/job/aiService.js` 新增 `analyzeSalary` 方法 -- 数据源: 岗位描述、地区、公司、市场数据 -- 前端: `offer_analysis.vue` Offer分析页面 -- 预计工期: 1周 - -**预期价值** -- 💰 薪资平均提升 10-15% -- 📈 谈判成功率提升 40%+ -- 💡 避免接受低薪Offer -- ✨ 提供科学的薪资决策 - ---- - -### 2.4 公司背景调查 ⭐⭐⭐⭐ - -**待开发内容** -1. **整合企查查/天眼查数据** - - 调用企查查API获取公司信息 - - 公司基本信息(注册资本、成立时间、法人) - - 融资情况(融资轮次、投资方) - - 诉讼记录、欠薪记录 - -2. **AI分析公司发展前景** - - 根据融资情况评估发展阶段 - - 根据招聘规模判断业务状态 - - 根据行业趋势预测前景 - - 给出公司评级(A/B/C/D) - -3. **风险预警** - - 识别高风险公司(如多次欠薪、频繁裁员) - - 识别虚假招聘(如招聘周期异常长) - - 识别外包公司(尽管岗位描述未标注) - - 给出风险提示和建议 - -**技术实现** -- 文件路径: `api/services/company_background_service.js` -- 数据源: 企查查API、`company_info` 表 -- 前端: `job_postings.vue` 新增公司背调入口 -- 预计工期: 1.5周 - -**预期价值** -- 📉 入职风险降低 80%+ -- 💡 避免进入高风险公司 -- ✨ 提供全面的公司情报 -- 🔍 识别隐藏的问题公司 - ---- - -### 2.5 职业发展路径 ⭐⭐⭐ - -**待开发内容** -1. **基于简历和目标生成职业规划** - - 分析当前职业阶段(初级/中级/高级) - - 根据目标岗位生成发展路径 - - 列出需要补充的技能和经验 - - 给出时间线规划(1年/3年/5年) - -2. **技能提升建议** - - 推荐学习资源(课程、书籍、开源项目) - - 建议考取的证书 - - 建议参加的技术社区 - - 建议做的练手项目 - -3. **转行可行性分析** - - 评估转行难度 - - 分析已有技能的可迁移性 - - 给出转行路径建议 - - 预测转行后的薪资变化 - -**技术实现** -- 文件路径: `api/middleware/job/aiService.js` 新增 `generateCareerPath` 方法 -- 数据源: `resume_info`, 目标岗位描述 -- 前端: 新增 `career_plan.vue` 职业规划页面 -- 预计工期: 1.5周 - -**预期价值** -- 📊 提供长期职业指导 -- 💡 明确发展方向和目标 -- 📈 技能提升更有针对性 -- ✨ 降低职业迷茫感 - ---- - -## 第三部分: 用户体验优化 - -**优先级: MEDIUM** | **预计工期: 4-5周** - -### 3.1 数据可视化增强 ⭐⭐⭐⭐ - -**待开发内容** -1. **投递转化漏斗图** - - 投递数 → 查看数 → 回复数 → 面试数 → Offer数 - - 每个环节的转化率 - - 识别漏斗中的薄弱环节 - - 对比不同平台的漏斗差异 - -2. **面试成功率趋势** - - 按时间展示面试通过率变化 - - 分析成功率提升/下降原因 - - 识别面试表现最好的时间段 - - 给出改进建议 - -3. **薪资分布统计** - - 投递岗位的薪资分布 - - Offer薪资分布 - - 对比期望薪资和实际薪资 - - 不同技能栈的薪资对比 - -4. **不同平台效果对比** - - Boss、猎聘等平台的效果对比 - - 投递量、回复率、面试率对比 - - 平台特点分析 - - 推荐最优平台 - -**技术实现** -- 前端: `admin/src/views/statistics/` 新增统计页面 -- ECharts图表: 漏斗图、折线图、柱状图、饼图 -- API: `statistics_server.js` 新增统计接口 -- 预计工期: 1周 - -**预期价值** -- 📊 数据洞察更直观 -- 💡 快速发现问题环节 -- 📈 数据驱动优化决策 -- ✨ 提供专业的数据分析 - ---- - -### 3.2 实时通知系统 ⭐⭐⭐⭐ - -**待开发内容** -1. **浏览器通知** - - 面试邀约即时通知 - - Offer通知 - - 重要聊天消息通知 - - 任务执行状态通知 - -2. **邮件通知** - - 每日投递报告 - - 面试提醒(提前1天) - - 重要事件邮件 - - 周报月报 - -3. **企业微信/钉钉集成** - - 通过企业微信机器人推送 - - 支持快捷操作(如快速回复) - - 群组通知 - - @指定人员 - -4. **关键事件提醒** - - 面试邀约(立即通知) - - Offer(立即通知) - - 简历被查看(可配置) - - 任务执行失败(立即通知) - -**技术实现** -- 文件路径: `api/services/notification_service.js` -- 浏览器通知: Web Notification API -- 邮件: nodemailer -- 企业微信: 企业微信Webhook -- 预计工期: 1.5周 - -**预期价值** -- ⏱️ 响应时间缩短 90%+ -- 📲 不错过任何重要消息 -- 💡 多渠道及时触达 -- ✨ 提供主动式消息推送 - ---- - -### 3.3 批量操作功能 ⭐⭐⭐ - -**待开发内容** -1. **批量启用/禁用账号** - - 勾选多个账号 - - 一键启用/禁用 - - 批量设置自动化开关 - - 操作日志记录 - -2. **批量设置投递策略** - - 批量修改投递时间范围 - - 批量修改每日上限 - - 批量设置关键词过滤 - - 应用模板到多个账号 - -3. **批量导出数据** - - 勾选导出字段 - - 导出为CSV/Excel - - 定时导出任务 - - 导出历史管理 - -**技术实现** -- 前端: 各列表页面新增批量操作工具栏 -- API: 各模块新增批量操作接口 -- 预计工期: 1周 - -**预期价值** -- ⏱️ 管理效率提升 80%+ -- 💡 降低重复操作 -- ✨ 提供便捷的批量工具 - ---- - -### 3.4 移动端适配 ⭐⭐⭐ - -**待开发内容** -1. **响应式布局优化** - - 适配手机、平板屏幕 - - 菜单改为抽屉式 - - 表格改为卡片式 - - 图表自适应尺寸 - -2. **移动端专属操作界面** - - 大图标按钮 - - 手势操作(滑动、长按) - - 底部操作栏 - - 快捷入口 - -3. **快捷操作入口** - - 快捷查看今日统计 - - 快捷查看任务状态 - - 快捷回复聊天 - - 快捷查看面试安排 - -**技术实现** -- 前端: 响应式CSS -- 使用 iView 的响应式组件 -- 新增移动端专属组件 -- 预计工期: 1.5周 - -**预期价值** -- 📱 随时随地管理 -- 💡 提升移动端体验 -- ✨ 扩大使用场景 - ---- - -### 3.5 智能推荐 ⭐⭐⭐ - -**待开发内容** -1. **推荐最适合的岗位** - - 基于简历和历史投递记录 - - AI预测岗位匹配度 - - 推荐优先投递的岗位 - - 推荐理由说明 - -2. **推荐最佳投递时间** - - 分析不同时间投递的效果 - - 推荐最佳投递时段 - - 避开竞争激烈的时段 - - 根据平台特性调整 - -3. **推荐优化策略** - - 分析数据找出问题 - - 推荐具体改进措施 - - 预测改进后的效果 - - 跟踪改进效果 - -**技术实现** -- 文件路径: `api/middleware/job/recommendService.js` -- AI模型: 基于历史数据训练 -- 前端: 首页新增推荐面板 -- 预计工期: 1周 - -**预期价值** -- 📈 投递效果提升 25%+ -- 💡 降低决策成本 -- ✨ 提供智能化建议 - ---- - -## 第四部分: 系统性能提升 - -**优先级: MEDIUM** | **预计工期: 3-4周** - -### 4.1 缓存策略优化 ⭐⭐⭐⭐ - -**待开发内容** -1. **Redis缓存热点数据** - - 缓存职位类型配置(5分钟→实时) - - 缓存统计数据(避免重复计算) - - 缓存简历信息(减少数据库查询) - - 缓存设备状态 - -2. **职位类型配置缓存** - - 当前5分钟缓存改为即时失效 - - 配置更新时清除缓存 - - 预加载常用配置 - -3. **简历信息缓存** - - 缓存最近查询的简历 - - LRU淘汰策略 - - 简历更新时清除缓存 - -**技术实现** -- Redis集成: `ioredis` -- 文件路径: `api/middleware/cache/cacheManager.js` -- 缓存策略: LRU, TTL -- 预计工期: 1周 - -**预期价值** -- 📈 响应速度提升 50%+ -- 📉 数据库压力降低 60%+ -- 💡 提升系统吞吐量 -- ✨ 提供更快的用户体验 - ---- - -### 4.2 数据库查询优化 ⭐⭐⭐⭐ - -**待开发内容** -1. **慢查询分析和优化** - - 开启MySQL慢查询日志 - - 分析TOP 10慢查询 - - 优化SQL语句 - - 添加必要索引 - -2. **索引优化** - - 分析现有索引使用情况 - - 添加复合索引 - - 删除冗余索引 - - 定期索引维护 - -3. **分表分库策略** - - 大表分表(如 `chat_records` 按月分表) - - 历史数据归档 - - 读写分离(可选) - -**技术实现** -- 使用 `EXPLAIN` 分析查询 -- Sequelize 索引配置优化 -- 数据库迁移脚本 -- 预计工期: 1周 - -**预期价值** -- 📈 查询性能提升 3-5倍 -- 📉 慢查询数量减少 80%+ -- 💡 数据库可支撑更大数据量 -- ✨ 提升系统稳定性 - ---- - -### 4.3 任务队列扩展 ⭐⭐⭐ - -**待开发内容** -1. **支持更多任务类型** - - 定时报告生成 - - 数据清理任务 - - 批量操作任务 - - 自定义任务 - -2. **任务优先级动态调整** - - 根据紧急程度调整优先级 - - VIP用户任务优先执行 - - 失败任务降低优先级 - - 长时间等待的任务提升优先级 - -3. **任务失败自动重试优化** - - 更智能的重试策略 - - 不同错误类型不同重试间隔 - - 重试次数动态调整 - - 重试失败后的降级处理 - -**技术实现** -- 文件路径: `api/middleware/schedule/taskQueue.js` 优化 -- 新增任务类型处理器 -- 优化优先级算法 -- 预计工期: 1周 - -**预期价值** -- 📈 任务处理更稳定 -- 💡 支持更复杂的任务场景 -- ✨ 提供更灵活的任务管理 - ---- - -### 4.4 并发控制优化 ⭐⭐⭐ - -**待开发内容** -1. **增加并发设备数** - - 当前最多5个设备 - - 支持动态配置并发数 - - 根据服务器性能自动调整 - - 支持分布式部署 - -2. **更精细的限流策略** - - 不同任务类型不同限流 - - 不同平台不同限流 - - 根据时间段动态调整 - - API请求限流 - -3. **分布式锁机制** - - 避免多实例冲突 - - Redis分布式锁 - - 锁超时自动释放 - - 死锁检测 - -**技术实现** -- Redis分布式锁: `redlock` -- 配置动态化 -- 负载均衡策略 -- 预计工期: 1周 - -**预期价值** -- 📈 系统吞吐量提升 2-3倍 -- 💡 支持更大规模部署 -- ✨ 提供企业级并发控制 - ---- - -### 4.5 日志和监控 ⭐⭐⭐⭐ - -**待开发内容** -1. **完善日志记录** - - 统一日志格式(JSON) - - 日志级别分级(DEBUG/INFO/WARN/ERROR) - - 敏感信息脱敏 - - 日志文件按日期切割 - -2. **性能监控面板** - - API响应时间监控 - - 数据库查询时间监控 - - 任务执行时间监控 - - 内存和CPU监控 - -3. **异常告警机制** - - 错误率超过阈值告警 - - 任务失败立即告警 - - 系统资源不足告警 - - 钉钉/企业微信告警 - -4. **操作审计日志** - - 记录所有关键操作 - - 操作人、操作时间、操作内容 - - 敏感操作二次确认 - - 审计日志导出 - -**技术实现** -- 日志库: `winston` -- 监控: `prometheus` + `grafana` (可选) -- 告警: `api/services/alert_service.js` -- 预计工期: 1.5周 - -**预期价值** -- 🔍 问题定位效率提升 80%+ -- 📊 系统运行状态可视化 -- 🚨 及时发现和处理异常 -- ✨ 提供运维级别的监控 - ---- - -## 附录: 开发优先级建议 - -### 短期(1-2个月) -**优先开发高价值、低成本功能** - -| 功能 | 优先级 | 预计工期 | 价值 | -|------|--------|----------|------| -| 自动聊天功能完善 | ⭐⭐⭐⭐⭐ | 2周 | HR回复率+30% | -| 账号保活任务 | ⭐⭐⭐⭐⭐ | 1周 | 封禁风险-70% | -| 简历智能优化 | ⭐⭐⭐⭐⭐ | 2周 | 竞争力+20% | -| 缓存策略优化 | ⭐⭐⭐⭐ | 1周 | 响应速度+50% | - -**预计总工期: 6周** - -### 中期(3-4个月) -**完善核心功能和AI能力** - -| 功能 | 优先级 | 预计工期 | 价值 | -|------|--------|----------|------| -| 简历自动更新 | ⭐⭐⭐⭐ | 1周 | 曝光率+50% | -| 岗位黑名单和收藏 | ⭐⭐⭐⭐ | 1周 | 精准度+40% | -| 多轮面试跟踪 | ⭐⭐⭐⭐ | 1.5周 | 完整生命周期 | -| 面试问题预测 | ⭐⭐⭐⭐ | 1.5周 | 通过率+30% | -| 数据可视化增强 | ⭐⭐⭐⭐ | 1周 | 数据洞察更直观 | - -**预计总工期: 6周** - -### 长期(5-6个月) -**提升体验和系统性能** - -| 功能 | 优先级 | 预计工期 | 价值 | -|------|--------|----------|------| -| 薪资谈判策略 | ⭐⭐⭐⭐ | 1周 | 薪资+10-15% | -| 公司背景调查 | ⭐⭐⭐⭐ | 1.5周 | 风险-80% | -| 实时通知系统 | ⭐⭐⭐⭐ | 1.5周 | 响应时间-90% | -| 日志和监控 | ⭐⭐⭐⭐ | 1.5周 | 定位效率+80% | -| 数据库查询优化 | ⭐⭐⭐⭐ | 1周 | 性能+3-5倍 | - -**预计总工期: 6.5周** - ---- - -## 总结 - -本规划文档共列出 **20项待开发功能**,分为4个优先级方向: - -- **功能完善和补充** (5项, HIGH): 完善核心业务流程 -- **AI能力增强** (5项, HIGH): 提升智能化水平 -- **用户体验优化** (5项, MEDIUM): 改善交互和便捷性 -- **系统性能提升** (5项, MEDIUM): 优化性能和稳定性 - -**预期开发周期**: -- 短期(1-2月): 6周 -- 中期(3-4月): 6周 -- 长期(5-6月): 6.5周 -- **总计**: 约4.5个月 - -**预期收益**: -- 📈 整体求职成功率提升 **50%+** -- 📈 用户使用效率提升 **80%+** -- 📈 系统性能提升 **3-5倍** -- 💰 用户平均薪资提升 **10-15%** - ---- - -**文档维护**: 开发团队 -**最后更新**: 2025-12-25 diff --git a/_doc/发布的接口文档.md b/_doc/发布的接口文档.md deleted file mode 100644 index 51b6eb7..0000000 --- a/_doc/发布的接口文档.md +++ /dev/null @@ -1,574 +0,0 @@ -# 发布脚本使用说明 - -## 📋 概述 - -发布脚本 (`scripts/publish.js`) 用于自动化应用的构建和发布流程,包括: -1. 清理构建目录 -2. 构建应用(NSIS 或便携版) -3. 调用接口创建版本记录 -4. 上传压缩包到 OSS - -## 🚀 快速开始 - -### 安装依赖 - -确保已安装 `form-data` 依赖: - -```bash -npm install form-data --save-dev -``` - -### 基本使用 - -```bash -# 发布 NSIS 安装包(默认) -npm run publish - -# 或直接运行脚本 -node scripts/publish.js -``` - -## 📝 命令选项 - -### 构建类型 - -```bash -# 发布 NSIS 安装包 -npm run publish:nsis -# 或 -node scripts/publish.js --type nsis - -# 发布便携版 -npm run publish:portable -# 或 -node scripts/publish.js --type portable -``` - -### 发布说明 - -```bash -node scripts/publish.js --notes "修复了若干bug,优化了性能" -``` - -### 强制更新 - -```bash -node scripts/publish.js --force -``` - -### 跳过步骤 - -```bash -# 仅上传已构建的文件(跳过构建) -node scripts/publish.js --skip-build - -# 仅构建不上传 -node scripts/publish.js --skip-upload -``` - -### 查看帮助 - -```bash -node scripts/publish.js --help -``` - -## 🔧 配置要求 - -### 1. 配置文件 - -确保 `config/appConfig.js` 中包含有效的配置: - -```javascript -module.exports = { - api_urls: { - dev: "http://work.light120.com/api", - prod: "http://work.light120.com/api" - }, - token: "your-token-here", // 必须配置有效的 token - // ... -}; -``` - -### 2. API 接口 - -脚本需要以下 API 接口: - -#### 接口 1:创建版本记录 - -- **接口地址**: `POST /api/version/create` -- **请求头**: - ``` - Content-Type: application/json - Authorization: ${token} - ``` -- **请求参数**: - ```json - { - "version": "1.0.0", // 必填:版本号(x.y.z 格式) - "platform": "win32", // 必填:平台类型(win32/darwin/linux) - "arch": "x64", // 必填:架构类型(x64/ia32/arm64) - "download_url": "https://...", // 必填:下载地址(上传后更新) - "file_path": "/path/to/file", // 必填:服务器文件路径 - "file_size": 12345678, // 可选:文件大小(字节),不提供会自动计算 - "file_hash": "sha256-hash", // 可选:SHA256 哈希值,不提供会自动计算 - "release_notes": "发布说明", // 可选:更新日志 - "force_update": 0, // 可选:是否强制更新(1:是 0:否),默认 0 - "status": 1 // 可选:状态(1:启用 0:禁用),默认 1 - } - ``` -- **响应示例**: - ```json - { - "code": 0, - "message": "版本创建成功", - "data": { - "id": 123, - "version": "1.0.0", - "platform": "win32", - "arch": "x64", - "download_url": "https://oss.example.com/path/to/file.exe", - "file_path": "/path/to/file.exe", - "file_size": 12345678, - "file_hash": "sha256-hash-value", - "release_notes": "发布说明", - "force_update": 0, - "status": 1, - "create_time": "2024-01-01 12:00:00" - } - } - ``` -- **错误响应**: - ```json - { - "code": 400, - "message": "版本号不能为空" // 或其他错误信息 - } - ``` -- **注意事项**: - - 版本号格式必须为 `x.y.z`(如:1.0.0) - - 平台类型必须为:`win32`、`darwin` 或 `linux` - - 架构类型必须为:`x64`、`ia32` 或 `arm64` - - 如果版本已存在(相同 version + platform + arch),会返回错误 - - 如果提供了 `file_path` 但未提供 `file_size` 或 `file_hash`,接口会自动计算 - -#### 接口 2:上传文件到 OSS - -- **接口地址**: `POST /api/file/upload_version` -- **请求头**: - ``` - Content-Type: multipart/form-data - Authorization: ${token} - ``` -- **请求参数**(Form Data): - | 参数名 | 类型 | 必填 | 说明 | - |--------|------|------|------| - | `file` | File | 是 | 文件内容(二进制) | - | `version` | String | 是 | 版本号(如:1.0.0) | - | `platform` | String | 是 | 平台类型(win32/darwin/linux) | - | `arch` | String | 是 | 架构类型(x64/ia32/arm64) | - | `file_hash` | String | 是 | SHA256 哈希值 | - | `file_size` | Number | 是 | 文件大小(字节) | - | `version_id` | Number | 否 | 版本记录 ID(如果已创建版本记录) | - | `build_type` | String | 否 | 构建类型(nsis/portable) | -- **请求示例**(使用 form-data): - ```javascript - const FormData = require('form-data'); - const fs = require('fs'); - - const form = new FormData(); - form.append('file', fs.createReadStream('./dist/app.exe')); - form.append('version', '1.0.0'); - form.append('platform', 'win32'); - form.append('arch', 'x64'); - form.append('file_hash', 'sha256-hash-value'); - form.append('file_size', 12345678); - form.append('version_id', 123); // 可选 - - // 发送请求 - form.submit('http://api.example.com/api/file/upload_version', { - headers: { - 'Authorization': `${token}` - } - }, callback); - ``` -- **响应示例**: - ```json - { - "code": 0, - "message": "文件上传成功", - "data": { - "download_url": "https://oss.example.com/versions/win32/x64/app-1.0.0.exe", - "file_path": "versions/win32/x64/app-1.0.0.exe", - "oss_path": "https://oss.example.com/versions/win32/x64/app-1.0.0.exe", - "file_size": 12345678, - "file_hash": "sha256-hash-value" - } - } - ``` -- **错误响应**: - ```json - { - "code": 400, - "message": "文件上传失败:文件大小不匹配" // 或其他错误信息 - } - ``` -- **注意事项**: - - 文件会按照 `versions/{platform}/{arch}/{filename}` 的路径结构上传到 OSS - - 上传前会验证文件哈希值,确保文件完整性 - - 上传成功后,建议调用 `/version/update` 接口更新版本记录的下载地址 - - 大文件上传建议设置较长的超时时间(建议 10 分钟以上) - -#### 接口 3:更新版本下载地址(可选) - -- **接口地址**: `POST /api/version/update` -- **请求头**: - ``` - Content-Type: application/json - Authorization: ${token} - ``` -- **请求参数**: - ```json - { - "id": 123, // 必填:版本记录 ID - "download_url": "https://...", // 可选:下载地址 - "file_path": "/path/to/file", // 可选:文件路径 - "file_hash": "sha256-hash", // 可选:文件哈希值 - "file_size": 12345678, // 可选:文件大小 - "release_notes": "更新说明", // 可选:更新日志 - "force_update": 1, // 可选:是否强制更新 - "status": 1 // 可选:状态 - } - ``` -- **响应示例**: - ```json - { - "code": 0, - "message": "版本更新成功", - "data": { - "id": 123, - "version": "1.0.0", - "download_url": "https://oss.example.com/path/to/file.exe", - // ... 其他字段 - } - } - ``` -- **使用场景**: - - 文件上传成功后,更新版本记录的下载地址 - - 修改版本的发布说明或强制更新标志 - - 启用或禁用某个版本 - -## 📦 发布流程 - -1. **清理构建目录** - - 删除 `dist` 目录及其所有内容 - -2. **构建应用** - - 根据构建类型执行 `electron-builder` - - NSIS: `electron-builder --win nsis` - - Portable: `electron-builder --win portable` - -3. **查找构建产物** - - 在 `dist` 目录中查找 `.exe` 文件 - - 按文件大小排序,优先处理主安装包 - -4. **创建版本记录** - - 调用 `POST /api/version/create` 接口 - - 传递版本信息、平台、架构等 - - 获取版本记录 ID(用于后续更新) - -5. **上传文件到 OSS** - - 计算文件 SHA256 哈希值 - - 使用 `multipart/form-data` 格式调用 `POST /api/file/upload_version` 接口 - - 传递文件、版本信息、哈希值等参数 - - 获取上传后的下载地址 - -6. **更新版本记录** - - 使用获取到的下载地址调用 `POST /api/version/update` 接口 - - 更新版本记录的 `download_url` 和 `file_path` 字段 - -## ⚠️ 注意事项 - -1. **Token 配置** - - 确保 `config/appConfig.js` 中有有效的 `token` - - Token 用于 API 认证,格式为 `${token}` - - 所有接口请求都需要在请求头中包含 `Authorization: ${token}` - -2. **接口路径** - - 所有接口路径前缀为 `/api` - - 完整路径示例: - - 创建版本:`POST http://api.example.com/api/version/create` - - 上传文件:`POST http://api.example.com/api/file/upload_version` - - 更新版本:`POST http://api.example.com/api/version/update` - -3. **文件大小** - - 大文件上传可能需要较长时间 - - 脚本默认超时时间为 10 分钟(600000ms) - - 建议大文件(>100MB)增加超时时间到 30 分钟 - -4. **网络连接** - - 确保能够访问 API 服务器和 OSS - - 上传大文件时建议使用稳定的网络连接 - - 建议在网络稳定的环境下执行发布流程 - -5. **版本号** - - 版本号从 `package.json` 的 `version` 字段读取 - - 发布前确保版本号已更新 - - 版本号格式必须符合 `x.y.z` 格式(如:1.0.0) - -6. **构建产物** - - 脚本会自动查找 `dist` 目录中的 `.exe` 文件 - - 排除 `builder` 和 `helper` 相关的辅助文件 - - 确保构建产物文件名清晰,便于识别 - -7. **文件哈希验证** - - 上传前必须计算文件的 SHA256 哈希值 - - 上传接口会验证文件哈希,确保文件完整性 - - 哈希值不匹配会导致上传失败 - -8. **接口调用顺序** - - 建议先创建版本记录(获取 version_id) - - 然后上传文件(可传递 version_id) - - 最后更新版本记录的下载地址 - - 也可以先上传文件,再创建版本记录并更新下载地址 - -## 🔍 故障排查 - -### 问题:上传失败 - -**可能原因**: -- Token 无效或过期 -- API 接口地址不正确 -- 网络连接问题 -- 文件过大,超时 - -**解决方法**: -1. 检查 `config/appConfig.js` 中的 `token` 是否有效 -2. 检查 API 地址是否正确 -3. 检查网络连接 -4. 如果文件很大,可以增加超时时间 - -### 问题:构建失败 - -**可能原因**: -- 缺少依赖 -- electron-builder 配置错误 -- 磁盘空间不足 - -**解决方法**: -1. 运行 `npm install` 安装所有依赖 -2. 检查 `package.json` 中的 `build` 配置 -3. 确保有足够的磁盘空间 - -### 问题:找不到构建产物 - -**可能原因**: -- 构建未成功完成 -- 构建产物在其他位置 - -**解决方法**: -1. 检查构建日志,确认构建成功 -2. 手动检查 `dist` 目录 -3. 使用 `--skip-build` 选项,手动指定文件路径(需要修改脚本) - -## 📝 示例 - -### 完整发布流程 - -```bash -# 1. 更新版本号(在 package.json 中) -# "version": "1.0.1" - -# 2. 发布 -npm run publish -- --notes "新功能:支持自动投递简历" --force -``` - -### 仅上传已构建的文件 - -```bash -# 1. 手动构建 -npm run build:nsis - -# 2. 仅上传 -node scripts/publish.js --skip-build -``` - -### 测试发布(不上传) - -```bash -# 构建并创建版本记录,但不上传文件 -node scripts/publish.js --skip-upload -``` - -## 💻 接口调用示例 - -### Node.js 示例代码 - -#### 1. 创建版本记录 - -```javascript -const axios = require('axios'); -const crypto = require('crypto'); -const fs = require('fs'); - -async function createVersion() { - const filePath = './dist/app-1.0.0.exe'; - const stats = fs.statSync(filePath); - const fileSize = stats.size; - - // 计算文件哈希 - const fileBuffer = fs.readFileSync(filePath); - const fileHash = crypto.createHash('sha256').update(fileBuffer).digest('hex'); - - const response = await axios.post('http://api.example.com/api/version/create', { - version: '1.0.0', - platform: 'win32', - arch: 'x64', - download_url: '', // 上传后更新 - file_path: filePath, - file_size: fileSize, - file_hash: fileHash, - release_notes: '修复了若干bug,优化了性能', - force_update: 0, - status: 1 - }, { - headers: { - 'Authorization': `${token}`, - 'Content-Type': 'application/json' - } - }); - - return response.data.data; // 返回版本记录,包含 id -} -``` - -#### 2. 上传文件到 OSS - -```javascript -const FormData = require('form-data'); -const axios = require('axios'); -const fs = require('fs'); -const crypto = require('crypto'); - -async function uploadVersionFile(versionId) { - const filePath = './dist/app-1.0.0.exe'; - const stats = fs.statSync(filePath); - const fileSize = stats.size; - - // 计算文件哈希 - const fileBuffer = fs.readFileSync(filePath); - const fileHash = crypto.createHash('sha256').update(fileBuffer).digest('hex'); - - // 创建 FormData - const form = new FormData(); - form.append('file', fs.createReadStream(filePath)); - form.append('version', '1.0.0'); - form.append('platform', 'win32'); - form.append('arch', 'x64'); - form.append('file_hash', fileHash); - form.append('file_size', fileSize); - if (versionId) { - form.append('version_id', versionId); - } - - const response = await axios.post('http://api.example.com/api/file/upload_version', form, { - headers: { - 'Authorization': `${token}`, - ...form.getHeaders() - }, - maxContentLength: Infinity, - maxBodyLength: Infinity, - timeout: 600000 // 10 分钟超时 - }); - - return response.data.data; // 返回上传结果,包含 download_url -} -``` - -#### 3. 更新版本下载地址 - -```javascript -async function updateVersionDownloadUrl(versionId, downloadUrl, fileHash) { - const response = await axios.post('http://api.example.com/api/version/update', { - id: versionId, - download_url: downloadUrl, - file_hash: fileHash - }, { - headers: { - 'Authorization': `${token}`, - 'Content-Type': 'application/json' - } - }); - - return response.data.data; -} -``` - -#### 4. 完整发布流程示例 - -```javascript -async function publishVersion() { - try { - // 1. 创建版本记录 - console.log('创建版本记录...'); - const version = await createVersion(); - console.log('版本记录创建成功,ID:', version.id); - - // 2. 上传文件 - console.log('上传文件到 OSS...'); - const uploadResult = await uploadVersionFile(version.id); - console.log('文件上传成功,下载地址:', uploadResult.download_url); - - // 3. 更新版本下载地址 - console.log('更新版本下载地址...'); - await updateVersionDownloadUrl(version.id, uploadResult.download_url, uploadResult.file_hash); - console.log('版本发布完成!'); - - } catch (error) { - console.error('发布失败:', error.response?.data || error.message); - throw error; - } -} -``` - -### cURL 示例 - -#### 创建版本记录 - -```bash -curl -X POST http://api.example.com/api/version/create \ - -H "Authorization: your-token-here" \ - -H "Content-Type: application/json" \ - -d '{ - "version": "1.0.0", - "platform": "win32", - "arch": "x64", - "download_url": "", - "file_path": "/path/to/file.exe", - "file_size": 12345678, - "file_hash": "sha256-hash-value", - "release_notes": "发布说明", - "force_update": 0, - "status": 1 - }' -``` - -#### 上传文件 - -```bash -curl -X POST http://api.example.com/api/file/upload_version \ - -H "Authorization: your-token-here" \ - -F "file=@./dist/app-1.0.0.exe" \ - -F "version=1.0.0" \ - -F "platform=win32" \ - -F "arch=x64" \ - -F "file_hash=sha256-hash-value" \ - -F "file_size=12345678" \ - -F "version_id=123" -``` - -## 🔗 相关文档 - -- [API 配置说明](./API_CONFIG.md) -- [打包说明](./BUILD.md) -- [更新逻辑检查报告](./更新逻辑检查报告.md) - diff --git a/_doc/命名规范统一方案.md b/_doc/命名规范统一方案.md deleted file mode 100644 index b7b4bb5..0000000 --- a/_doc/命名规范统一方案.md +++ /dev/null @@ -1,100 +0,0 @@ -# 命名规范统一方案 - -## 📋 命名规范标准 - -### 1. 文件命名规范 -**统一使用下划线命名(snake_case)** -- ✅ `ai_service.js` -- ✅ `job_service.js` -- ✅ `pla_account_service.js` -- ✅ `job_manager_service.js` -- ✅ `chat_manager_service.js` -- ✅ `resume_manager_service.js` -- ❌ `aiService.js` → `ai_service.js` -- ❌ `jobManager.js` → `job_manager_service.js` -- ❌ `chatManager.js` → `chat_manager_service.js` -- ❌ `resumeManager.js` → `resume_manager_service.js` - -### 2. 类命名规范 -**统一使用大驼峰命名(PascalCase)** -- ✅ `AIService` -- ✅ `JobService` -- ✅ `JobManagerService` -- ✅ `ChatManagerService` -- ✅ `ResumeManagerService` -- ❌ `aiService` → `AIService` -- ❌ `JobManager` → `JobManagerService` - -### 3. 目录命名规范 -**统一使用小写+下划线(snake_case)** -- ✅ `services/` - 业务服务层 -- ✅ `middleware/` - 中间件层 -- ✅ `middleware/schedule/` - 调度系统 -- ✅ `middleware/mqtt/` - MQTT通信 -- ❌ `middleware/job/` → 移到 `services/` 并重命名 - -### 4. 服务文件命名规范 -**所有服务文件统一以 `_service.js` 结尾** -- ✅ `ai_service.js` -- ✅ `job_service.js` -- ✅ `job_manager_service.js` -- ✅ `chat_manager_service.js` -- ✅ `resume_manager_service.js` -- ✅ `pla_account_service.js` -- ✅ `oss_tool_service.js` (重命名 `ossTool.js`) - -## 🔄 需要重命名的文件 - -### services/ 目录 -1. `ossTool.js` → `oss_tool_service.js` -2. `task_scheduler.js` → 标记为废弃或删除 - -### middleware/job/ 目录(移到 services/) -1. `jobManager.js` → `services/job_manager_service.js` -2. `chatManager.js` → `services/chat_manager_service.js` -3. `resumeManager.js` → `services/resume_manager_service.js` -4. `aiService.js` → 合并到 `services/ai_service.js` 后删除 - -## 📁 整理后的目录结构 - -``` -api/ -├── services/ # 业务服务层 -│ ├── index.js # 服务管理器 -│ ├── ai_service.js # AI服务(合并后) -│ ├── job_service.js # 职位服务 -│ ├── job_manager_service.js # 工作管理服务 -│ ├── chat_manager_service.js # 聊天管理服务 -│ ├── resume_manager_service.js # 简历管理服务 -│ ├── pla_account_service.js # 账号服务 -│ └── oss_tool_service.js # OSS服务 -│ -└── middleware/ # 中间件层 - ├── schedule/ # 调度系统 - ├── mqtt/ # MQTT通信 - ├── dbProxy.js # 数据库代理 - └── logProxy.js # 日志代理 -``` - -## 🎯 执行步骤 - -1. **重命名现有文件** - - `ossTool.js` → `oss_tool_service.js` - -2. **移动并重命名业务服务** - - `middleware/job/jobManager.js` → `services/job_manager_service.js` - - `middleware/job/chatManager.js` → `services/chat_manager_service.js` - - `middleware/job/resumeManager.js` → `services/resume_manager_service.js` - -3. **合并AI服务** - - 将 `middleware/job/aiService.js` 的功能合并到 `services/ai_service.js` - - 删除 `middleware/job/aiService.js` - -4. **更新所有引用** - - 更新 `command.js` 中的引用 - - 更新其他文件中的引用 - -5. **统一类命名** - - 确保所有类都使用 PascalCase - - 确保所有服务类都以 Service 结尾 - diff --git a/_doc/命名规范统一进度.md b/_doc/命名规范统一进度.md deleted file mode 100644 index 371d3f5..0000000 --- a/_doc/命名规范统一进度.md +++ /dev/null @@ -1,68 +0,0 @@ -# 命名规范统一进度 - -## ✅ 已完成 - -### 1. OSS服务重命名 -- ✅ `ossTool.js` → `oss_tool_service.js` -- ✅ `OSSTool` → `OSSToolService` -- ✅ 更新引用:`api/controller_front/file.js` - -## 📋 待完成 - -### 2. 移动并重命名业务服务(middleware/job/ → services/) -- ⏳ `jobManager.js` → `services/job_manager_service.js` - - 类名:`JobManager` → `JobManagerService` - - 更新引用:`api/middleware/schedule/command.js` - -- ⏳ `chatManager.js` → `services/chat_manager_service.js` - - 类名:`ChatManager` → `ChatManagerService` - - 更新引用:`api/middleware/schedule/command.js` - -- ⏳ `resumeManager.js` → `services/resume_manager_service.js` - - 类名:`ResumeManager` → `ResumeManagerService` - -### 3. 合并AI服务 -- ⏳ 将 `middleware/job/aiService.js` 的功能合并到 `services/ai_service.js` -- ⏳ 统一类名为 `AIService` -- ⏳ 删除 `middleware/job/aiService.js` -- ⏳ 更新所有引用 - -### 4. 处理废弃文件 -- ⏳ `services/task_scheduler.js` - 添加废弃标记或删除 - -## 📝 命名规范总结 - -### 文件命名规范 -- ✅ 统一使用 `snake_case` + `_service.js` 后缀 -- ✅ 示例:`oss_tool_service.js`, `job_manager_service.js` - -### 类命名规范 -- ✅ 统一使用 `PascalCase` + `Service` 后缀 -- ✅ 示例:`OSSToolService`, `JobManagerService` - -### 目录结构 -``` -api/ -├── services/ # 业务服务层 -│ ├── ai_service.js -│ ├── job_service.js -│ ├── job_manager_service.js # 待移动 -│ ├── chat_manager_service.js # 待移动 -│ ├── resume_manager_service.js # 待移动 -│ ├── pla_account_service.js -│ └── oss_tool_service.js # ✅ 已完成 -│ -└── middleware/ # 中间件层 - ├── schedule/ - ├── mqtt/ - └── job/ # 待删除(文件移到services后) -``` - -## 🔄 下一步操作 - -1. 移动并重命名 `middleware/job/` 下的文件 -2. 合并AI服务 -3. 更新所有引用 -4. 统一导出方式 -5. 删除废弃文件 - diff --git a/_doc/在线简历响应文本.json b/_doc/在线简历响应文本.json deleted file mode 100644 index 458943a..0000000 --- a/_doc/在线简历响应文本.json +++ /dev/null @@ -1,860 +0,0 @@ -{ - "baseInfo": { - "name": "张成", - "nickName": "张成", - "tiny": "https://img.bosszhipin.com/beijin/upload/avatar/20250211/607f1f3d68754fd006d510844c0273d99b737108b9d73a664006f977785f3a6a694eb527b0e564d8_s.png.webp", - "birthday": "19930612", - "age": "32岁", - "gender": 1, - "degree": 203, - "degreeCategory": "本科", - "account": "193******69", - "emailBlur": "978****03@qq.com", - "weixinBlur": "z56***01", - "freshGraduate": 0, - "workYears": 11, - "nameShowType": 0, - "bossCert": 0, - "userCert": 2, - "certGender": true, - "certBirth": true, - "startWorkDate": 20141201, - "applyStatus": 0, - "workYearDesc": "10年以上经验", - "resumeStatus": 0, - "resumeCount": 0, - "complete": false, - "weiXinSecurityUid": null, - "garbageFieldList": null, - "hometown": 0, - "hometownName": null, - "studyAbroadCertPass": 0, - "highestEduExp": null, - "showF3Optimize": 0, - "startWorkDateDesc": "2014-12", - "birthdayDesc": "1993-06" - }, - "userDesc": "拥有10年深厚行业经验的资深前端架构师,专注前沿技术与业务融合,推动数字化产品创新升级。\n \n1. 技术栈与架构:熟练运用Vue、React等主流框架,搭配Webpack、Vite等构建工具进行高效开发。精通TypeScript,优化代码结构与维护性。擅长使用Redux、MobX管理复杂应用状态,搭建稳定架构。\n \n2. 跨端与组件化:掌握Flutter、React Native等跨端技术,实现多平台无缝运行。主导设计高复用组件库,利用Storybook管理组件,使组件复用率达70%,开发周期缩短40%。\n \n3. AI集成:积极探索AI与前端融合,集成GPT等大模型实现智能客服、内容生成,引入机器学习算法实现用户行为分析、个性化推荐,大幅提升用户参与度。\n \n4. 音视频处理:具备音视频处理能力,使用WebRTC实现实时通信,结合FFmpeg进行格式转换、剪辑。利用Media Source Extensions实现自适应码率播放,优化视频加载与播放体验。\n\n 5. 后端及多元开发:擅长使用Node.js搭配Express、Koa框架搭建高性能后端服务,优化接口响应速度。熟练运用Python进行数据处理、自动化脚本编写,结合Django、Flask框架开发后端应用,在数据挖掘与分析领域成果显著。掌握C#语言,基于.NET平台进行Windows桌面应用开发,具备丰富的Windows Forms、WPF项目经验,实现全栈技术链路的打通。", - "applyStatus": 0, - "lastlast_modify_time": "2025.11.05 13:41", - "workEduDesc": "宝尊电子商务·架构师", - "expectList": [ - { - "id": "dfc1777a2703c9071nVz3d-0GVpYxA~~", - "expectType": 0, - "position": 100123, - "positionName": "全栈工程师", - "customPositionId": "", - "positionType": 0, - "location": 101020100, - "locationName": "上海", - "subLocation": 0, - "subLocationName": null, - "lowSalary": 20, - "highSalary": 30, - "salaryDesc": "20-30K", - "salaryDescNew": "20-30K", - "industryList": [], - "industryDesc": "行业不限", - "suggestPosition": "", - "applyStatus": 0, - "freshGraduate": 0, - "doneWorkPositionList": null, - "garbageFieldList": null, - "interestPositionList": null, - "interestLocationList": null, - "industryExpect": false, - "tagName": null - } - ], - "workExpList": [ - { - "id": "9bd3116c0333c52d1nJ_09y-EldZx465V_-X", - "companyName": "上海宝尊电子商务有限公司", - "industry": { - "code": 100020, - "name": "互联网" - }, - "department": "", - "customPositionName": "架构师", - "position": 100704, - "positionName": "架构师", - "positionLv2": 100700, - "startDate": "2019.06", - "startDateStr": "2019.06", - "endDate": "2024.12", - "endDateStr": "2024.12", - "emphasis": [], - "workContent": "智能视频剪辑系统(2021.07-2024.12)\n技术栈:Vue2+Element UI+WebAssembly+Canvas+Konva.js+WebSocket+GSAP\n核心功能:\n1.视频处理:基于WebAssembly解析视频信息,实现大文件分片上传,支持200G+视频处理\n2.创意编辑:使用Konva.js开发多层级编辑器,实现图片分层、文字动画、贴片特效\n3.动画系统:基于GSAP开发文字特效、Logo动画,支持动态片头片尾制作\n4.预览系统:使用Canvas实现视频片段预览,支持时间轴精确定位\n5.任务管理:基于WebSocket实现批量任务进度实时通知\n项目成果:视频处理效率提升300%|日均处理1000+视频|压缩率达97%|任务效率提升200%|降低\n人工成本60%", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - }, - { - "id": "283b1abcae6041e41nJ_0969ElpVy423Vvic", - "companyName": "上海航天动力科技工程有限公司", - "industry": { - "code": 100021, - "name": "计算机软件" - }, - "department": "", - "customPositionName": "架构师", - "position": 100704, - "positionName": "架构师", - "positionLv2": 100700, - "startDate": "2018.06", - "startDateStr": "2018.06", - "endDate": "2019.06", - "endDateStr": "2019.06", - "emphasis": [], - "workContent": "技术栈:Vue2+iView+OpenLayers+Cesium+WebSocket+Less\n核心功能:\n1.GIS可视化:基于OpenLayers实现管网GIS展示,支持多图层管理\n2.实时监控:使用WebSocket推送报警信息,实现管道水流方向动画\n3.数据分析:集成ECharts开发运营分析、报表统计功能\n4.空间分析:使用Turf.js实现等差线绘制,可视化爆管位置\n项目成果:地图加载提升200%|漏损检测准确率95%|节省成本300万+|服务10+水务公司|覆盖管\n网1000km+", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - }, - { - "id": "d18fc7f74a6479ee1nJ_0969ElpVy423Vvid", - "companyName": "上海开澜软件有限公司", - "industry": { - "code": 100021, - "name": "计算机软件" - }, - "department": "", - "customPositionName": ".NET", - "position": 100107, - "positionName": ".NET", - "positionLv2": 100100, - "startDate": "2016.06", - "startDateStr": "2016.06", - "endDate": "2018.06", - "endDateStr": "2018.06", - "emphasis": [ - "HTML" - ], - "workContent": "滩涂造地BIM管理系统(2017.01-2018.05)\n技术栈:jQuery+EasyUI+BIMViz+百度图+WebAppOffice\n核心功能:\n1.BIM可视化:集成BIMViz实现模型在线预览,支持构件查询和联动\n2.地图集成:基于百度地图API实现工程位置展示和空间分析\n3.文档管理:使用WebAppOffice实现在线预览,支持多格式文档\n4.工作流程:开发OA审批流程,实现物料申请和人员管理\n项目成果:BIM性能提升200%|审批效率提升150%|支持50+文档格式|日均处理500+工单|管理效\n率提升80%", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - }, - { - "id": "c07196b9b117210f1nJ_0969ElpVy423Vvie", - "companyName": "上海加谷网络科技有限公司", - "industry": { - "code": 100002, - "name": "游戏" - }, - "department": "", - "customPositionName": ".NET", - "position": 100107, - "positionName": ".NET", - "positionLv2": 100100, - "startDate": "2014.06", - "startDateStr": "2014.06", - "endDate": "2016.05", - "endDateStr": "2016.05", - "emphasis": [ - "HTML" - ], - "workContent": "H5营销平台开发(2014.06-2016.05)\n技术栈:jQuery+Canvas+CSS3+HTML5+微信JSSDK\n核心功能:\n1.互动游戏:开发大转盘抽奖、刮刮卡、砸金蛋等H5游戏\n2.动画特效:自研Canvas动画框架,支持Flash动画转换\n3.低代码平台:开发可视化搭建工具,支持营销活动快速生成\n4.社交功能:集成微信分享、支付、授权等功能项目成果:服务200+品牌|开发效率提升300%|上线周期缩短80%|转化率提升150%|支持百万级访问", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - } - ], - "projectExpList": [ - { - "id": "903b8e07eb7f44ca1nx50t-6EFZQw4i8UvKY", - "name": "AI智能视频剪辑系统", - "roleName": "全栈工程师", - "url": "", - "startDate": "2024.01", - "endDate": "", - "projectDesc": "系统简介\nai智能视频剪辑系统,可通过淘宝直播间,天猫,淘宝商品链接,自动从直播间中按照商品切片,并输出到天猫商品详情页主视频,发布到小红书,淘宝微淘等平台,可批量生成视频,处理视频,前端技术栈:vue全家桶+elemeui+浏览器插件\n后端技术栈:Node.js+Koa2+Vue2+FFmpeg+Redis\n功能模块:\n1.内容采集:开发Chrome浏览器插件自动获取直播回放、商品时间点智能识别、多平台视频源导入本地大视频文件上传,支持200g左右大文件批量上传,断点续传等功能\n2.任务管理:用户可以批量创建任务,任务实时状态使用WebSocket更新并通知\n3.模版管理:可基于execl文件批量创建任务,动态生成片尾图和首图\n4.智能生成:基于GPT的视频内容理解、关键片段提取和智能场景组合、60秒精华自动生成\n5.内容编辑:多轨道编辑和场景识别分割、转场特效库和字幕样式编辑、贴纸滤镜和音频处理、GSAP文字动画和Logo动效\n6.深度剪辑:用户可以拖动句子,自动以切片输出内容\n7.发布管理:多格式导出和自定义分辨率码率、批量导出队列和云端渲染、进度实时展示\n8.视频特效开发:如:文字抖动,花字,特效,特殊字幕,贴片动画等工作成果:\n1.使用FFmpeg开发视频处理引擎,支持多种视频格式转码,压缩进度回调\n2.设计任务队列系统,服务器CPU使用率控制在70%以下,使用负载均衡分摊压力,实现任务批量处理\n3.集成GPT模型,视频内容理解准确率达85%,精华片段提取效率提升200%\n4.实现大文件分片上传,支持断点续传,上传成功率99%\n5.开发完整的日志追踪系统,问题定位时间缩短,使用sse日志推送至前端页面可实时观察任务处理情况,接入报警机器人报警推送至企业微信群\n6.开发前端视频渲染引擎,图片编辑器,js逆向破解支持数据采集成功\n7.封装常用前端组件库,前端框架搭建与维护,指导其他组员开发,解决问题", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2024.01", - "endDateStr": "至今" - }, - { - "id": "2a6ee534976187341nx50t-6EVNWyoq-Vf-e", - "name": "水务DMA分区计量管理系统", - "roleName": "全栈工程师", - "url": "", - "startDate": "2023.07", - "endDate": "", - "projectDesc": "DMA (DistrictMetered Area)分区计量管理系统是一种先进的、专门应用于供水管网精细化管理的综合性系统。\n通过将供水管网划分成多个相对独立的计量区域(即DMA分区),在每个分区的进水口和出水口等关键节点安装高精度的计量设备,精确监测和记录水流的流入、流出情况,实现对各个分区内水量的实时计量与分析,其核心原理是基于封闭区域水量平衡理论,通过对比流入和流出水量等数据,精准定位可能存在的管网漏损点以及评估管网运行状态,助力供水企业实现科学管理、高效节水以及提升供水服务质量.\n前端技术栈:vue全家桶+elemeui,c#+wpf\n后端技术栈:Node.js+Koa2+mysq\n功能模块:\n1.实时数据处理:对DMA分区计量设备的水流数据进行清洗、校验和初步分析\n2.GIS数据管理:提供接口实现与地理信息系统的数据交互,管理管网地理空间数据。\n3.数据存储:基于MongoDB设计数据存储架构,进行数据备份与恢复。\n4.管网可视化:通过地图展示供水管网地理空间数据,支持多种地图操作\n5.空间分析:实现管网连通性、最短路径、缓冲区等空间分析功能。\n6.地图交互:提供地图标注和测距工具。\n7.实时数据推送:利用WebSocket实时推送DMA分区计量和设备状态数据。\n8.智能报警:实时监测管网异常,生成报警信息并通知相关人员,对报警信息分类统计\n9.设备状态监控:实时获取计量设备工作状态、电量等信息,分析运行历史数据数据采集功能\n10.数据采集程序:使用C#的WPF开发可与多种RTU设备通信的采集程序\n11.动态解析:服务端动态接收并自动解析不同RTU设备的数据。\n12.数据展示与导出:以图表和表格展示采集数据,支持CSV格式动态导出。\n项目成果:支持10000+设备并发查询性能提升150%系统稳定性99.99", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2023.07", - "endDateStr": "至今" - }, - { - "id": "6aa05589bc43d7711nx50t-6EVNWyoq-Vf-d", - "name": "bb物语小程序商城", - "roleName": "全栈工程师", - "url": "", - "startDate": "2023.05", - "endDate": "", - "projectDesc": "技术架构:\n前端:Vue2+mpVue\n后端:node.js+koa2+sequelize\n数据库:MySQL+Redis\n功能模块:\n1.商品管理:商品分类、商品上架、库存管理、价格管理、商品搜索\n2.订单管理:订单创建、订单支付、订单取消、订单查询,订单统计\n3.用户管理:用户注册、用户登录、用户信息管理、用户积分、用户等级\n4.营销管理:优惠券管理、满减活动、限时抢购、拼团活动、积分兑换\n5.支付系统:微信支付、支付宝支付\n4.设计用户管理系统,支持用户注册、登录、信息管理和积分系统\n5.开发营销管理模块,支持优惠券、满减活动、限时抢购和拼团活动\n6.实现数据分析功能,支持销售数据统计,用户行为分析、商品热度分析、营销效果分析\n工作成果:\n1.实现商品管理系统,支持商品的分类、上架、库存和价格管理\n2.开发订单管理模块,支持订单的创建、支付、取消和查询\n3.集成多种支付方式,支持微信支付、支付宝支付\n4.设计用户管理系统,支持用户注册、登录、信息管理和积分系统\n5.开发营销管理模块,支持优惠券、满减活动、限时抢购和拼团活动\n6.实现数据分析功能,支持销售数据统计,用户行为分析和商品热度分析\n7.支持三级分销,以及销售人员工资统计", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2023.05", - "endDateStr": "至今" - }, - { - "id": "32010e34944e04851nJ_0969E1JQx4q-Vfuc", - "name": "AI智能写手系统", - "roleName": "全栈开发工程师", - "url": "", - "startDate": "2020.03", - "endDate": "2021.07", - "projectDesc": "技术栈:Vue2+Element Ul+WebSocket+jWT+Less+Webpack+Node.js\n核心功能:\n1.平台管理:基于IWT的权限控制,实现品牌管理、角色权限、秀场墙功能\n2.内容制作:开发智能语句生成,作品库管理,多元化批量处理功能\n3.数据采集:Chrome插件开发,实现多平台商品信息自动采集\n4.多端适配:使用Rem+Flex实现响应式布局,支持不同屏幕自适应\n5.自动发布:开发多平台发布插件,支持淘宝天猫京东等平台内自动发布\n6.定时任务:基于Node.js实现定时发布、数据同步、内容更新等动化任务\n项目成果:开发效率提升200%|首屏加载800ms|数据处理效率提升300%|服务10+品牌|运营效率\n提升400%|任务成功率99.5%", - "performance": "开发效率提升200%首屏加载800ms数据处理效率提升300%服务10+品牌运营效率\n提升400%任务成功率99.5%", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2020.03", - "endDateStr": "2021.07" - }, - { - "id": "1dc51326ce11bc601nJ_0969E1JQx4q-Vfud", - "name": "易分析取数工具", - "roleName": "全栈开发工程师", - "url": "", - "startDate": "2019.08", - "endDate": "2020.03", - "projectDesc": "系统简介\n获取天猫,淘宝,腾讯,小红书蒲公英商家后台数据,用与大数据做营销精细化运营,支持人群画像,地域,人群,粉丝,购买,等一些列数据,以及达人数据粉丝数,带货数,直播场次,直播效果,商品评论,数据做分析\n前端技术栈:vue全家桶+elemeui+浏览器插件\n后端技术栈:Node.js+Koa2+mysql,Pythopn+Selenium+Flask\n功能模块:\n1.前端数据采集:淘宝数据银行API对接,策略中心数据抓取,生意参谋数据同步,营销数据实时获取\n2.后端数据采集:\n3.插件功能:多平台数据采集插件、自定义数据抓取规则、请求拦截和数据过滤、离线数据缓存\n4.数据处理:多维度数据整合分析、数据清洗和结构化、自定义数据导出、实时数据同步\n5.监控预警:数据采集任务监控、异常采集预警,数据质量监控、采集额度管理\n工作成果:\n1.支持淘宝全站数据采集,日均处理5000+数据\n2.开发通用数据采集引擎,支持自定义采集规则\n3.实现数据实时同步,延迟<500ms\n4.分布式爬虫系统架构,支持分布式抓取", - "performance": "1. 设计插件热更新方案,实现核心模块动态替换和状态保持\n2. 开发多浏览器兼容层,解决不同浏览器API差异问题实现插件配置动态更新和按需加载机制\n3. 使用Sequelize设计数据模型,处理复杂的表关联和数据同步重写浏览器原生Ajax,实现智能请求拦截和缓存策略\n4. 开发分布式日志系统,支持问题快速定位", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2019.08", - "endDateStr": "2020.03" - }, - { - "id": "e4294f91116b15dc1nJ_0969E1JQx4q-Vfue", - "name": "全工况智能终端采集系统", - "roleName": ".net软件工程师", - "url": "", - "startDate": "2018.05", - "endDate": "2018.08", - "projectDesc": "技术栈:WPF+Socket+InfluxDB+PostgreSQL\n核心功能:\n1.数据采集:实现Socket高并发通信,支持多协议解析\n2.实时监控:开发设备状态实时监控界面\n3.数据存储:设计混合数据库方案,优化查询性能\n4.可视化:实现数据实时展示和趋势分析\n项目成果:支持10000+设备并发|查询性能提升150%|系统稳定性99.99%|支持亿级数据毫秒级查询", - "performance": "1.实现百万级数据快速查询,平均查询时间<500ms\n2.设计实时数据动态渲染方案\n3.优化数据库性能,批量写入效率提升50%\n4.实现数据自动分级存储和归档\n5.开发设备状态实时监控系统", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2018.05", - "endDateStr": "2018.08" - }, - { - "id": "96160107ede0ae851nJ_0969E1JQx4q-Vfuf", - "name": "宝山排水证管理系统", - "roleName": ".net软件工程师", - "url": "", - "startDate": "2017.01", - "endDate": "2017.07", - "projectDesc": "技术栈:AngularjS+KendoUI+lonic+TypeScript+MongoDE\n核心功能:\n1.PC端开发:基于KendoUI快速构建后台管理界面,实现许可证全流程管理\n2.移动端开发:使用lonic+Aneular开发跨平台App,支持iOS和Androic\n3.表单设计:实现动态表单配置,支持多类型数据录入和自定义校验规则\n4.流程管理:开发审批流程引擎,支持条件分支、并行审批、委托授权\n5.地图功能:集成百度地图,实现排水户分布展示和空间位置选择\n6.统计分析:开发数据可视化大屏,展示许可证办理情况和区域分布移动端技术难点:\n基于lonic+Cordova实现原生功能调用,如相机、定位、文件系统等解决Android返回键监听和iOS手势返冲突问题\n实现大文件分片上传和断点续传,支持现场照片批量上传\n开发自定义相机组件,支持照片压缩和水印添加使用SOLite实现本地数据存储,解决断网环境下的数据同光\n优化Scroll性能,解决长列表滚动卡顿问题\n处理键盘弹出时的页面布局自适应\n解决iOS和Android平台字体、样式兼容性问题\n实现应用内检查更新和增量更新功能\n优化首屏加载速度,实现资源按需加载\n项目成果:办理时间缩短80%|代码复用率80%|响应时间300ms|审批效率提升200%", - "performance": "1. 实现大文件分片上传和断点续传,支持现场照片批量上传开发自定义相机组件,支持照片压缩和水印添加使用SOLite实现本地数据存储,解决断网环境下的数据同光\n2. 优化Scroll性能,解决长列表滚动卡顿问题处理键盘弹出时的页面布局自适应解决iOS和Android平台字体、样式兼容性问题实现应用内检查更新和增量更新功能\n3. 优化首屏加载速度,实现资源按需加载", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2017.01", - "endDateStr": "2017.07" - }, - { - "id": "c06dfe8c3678cf231nJ90tq7EVpQxo6_V_qW", - "name": "H5营销平台", - "roleName": ".net软件工程师", - "url": "", - "startDate": "2014.06", - "endDate": "2016.05", - "projectDesc": "技术栈:Vue2+Canvas+CSS3+微信ISSDK+.Net\n功能模块:\n1.游戏开发:开发大转盘抽奖、刮刮卡等H5游戏、自研Canvas动画框架、支持Flash动画转换\n2.内容管理:开发可视化搭建工具、支持营销活动快速生成、实现模板在线编辑\n3.社交功能:集成微信分享、支付、授权、开发用户数据分析、实现活动数据统计\n项目成果:服务200+品牌开发效率提升300%转化率提升150%", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2014.06", - "endDateStr": "2016.05" - }, - { - "id": "4e09afd8b41347c61nJ_0969E1JQx4q-VfqW", - "name": "物料ERP管理系统", - "roleName": "前端开发工程师", - "url": "", - "startDate": "2014.08", - "endDate": "2015.06", - "projectDesc": "技术栈:jQuery+Bootstrap+EasyUl+WebSocket+SQL Server\n核心功能:\n1.库存管理:实现物料库、出库、调拨、盘点等完整业务流程\n2.采购管理:开发供应商管理、询价比价、采购计划、订单跟踪功能\n3.生产管理:实现BOM管理、生产计划、物料需求计划(MRP)功能\n4.报表分析:开发库存周转率、采购分析、成本核算等统计报表\n5.预警提醒:设置库存预警、采购超期、价格异常等自动提醒\n技术难点:\n开发物料编码生成器,支持多级分类和自定义规则\n实现基于WebSocket的实时库存变更提醒\n设计MRP运算引擎,优化大批量数据处理性能\n开发报表导出功能,支持复杂表头和数据汇总项目成果:库存周转提升40%|采购成本降低15%|支持100+用户并发|日均处理3000+笔业务", - "performance": "1. 开发物料编码生成器,支持多级分类和自定义规则\n2. 实现基于WebSocket的实时库存变更提醒\n3. 设计MRP运算引擎,优化大批量数据处理性能\n4. 开发报表导出功能,支持复杂表头和数据汇", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2014.08", - "endDateStr": "2015.06" - } - ], - "educationExpList": [ - { - "id": "ee34188f32f9cecc1XF52NW5F1dT", - "schoolId": 2811, - "school": "武汉工程大学", - "major": "计算机应用技术(大数据方向)", - "degree": 203, - "eduType": 2, - "degreeName": "本科", - "startYear": "2021", - "endYear": "2024", - "educationDesc": "", - "country": "", - "tags": [ - "卓越工程师计划" - ], - "schoolType": 0, - "suggestToDel": 0, - "thesisTitle": "", - "thesisDesc": "", - "majorRanking": 0, - "courseList": [], - "badge": "https://img.bosszhipin.com/beijin/icon/bed7df948518127f74daa2ee178c44fc6bb61e3b7bce0931da574d19d1d82c88.jpg", - "certified": 0, - "garbageFieldList": null, - "startYearStr": "2021", - "endYearStr": "2024" - }, - { - "id": "e095a1ceefdd0cc31XF52NW6FVZY", - "schoolId": 2831, - "school": "武汉软件工程职业学院", - "major": "软件技术", - "degree": 202, - "eduType": 1, - "degreeName": "大专", - "startYear": "2011", - "endYear": "2014", - "educationDesc": "", - "country": "", - "tags": [], - "schoolType": 0, - "suggestToDel": 0, - "thesisTitle": "", - "thesisDesc": "", - "majorRanking": 0, - "courseList": [], - "badge": "https://img.bosszhipin.com/beijin/icon/18282111c2fc8e191c5b6aedcece5a956bb61e3b7bce0931da574d19d1d82c88.jpg", - "certified": 0, - "garbageFieldList": null, - "startYearStr": "2011", - "endYearStr": "2014" - } - ], - "socialContactList": null, - "volunteerExpList": null, - "certificationList": null, - "trainingExpList": null, - "designWorksImage": null, - "designWorksVideo": null, - "personalImage": null, - "deliciousFoodImage": null, - "garbage": { - "status": 0, - "reasonCode": 0, - "resumeDetailStatus": 0, - "garbageBaseInfo": null, - "baseInfo": null, - "garbageUserDesc": null, - "personalAdvantages": null, - "garbageWorkExp": null, - "workExp": null, - "garbageEduExp": null, - "eduExp": null, - "garbageProjectExp": null, - "projectExp": null, - "garbageVolunteerExp": null, - "volunteerExp": null, - "garbageExpectList": null, - "expect": null, - "garbageCertificationList": null, - "certification": null, - "designWorks": null, - "designWorksImageList": null, - "designWorksVideoList": null, - "garbageHandicapped": null, - "handicapped": null, - "trainingExp": null, - "clubExp": null, - "professionalSkill": null, - "honor": null - }, - "editStatus": { - "canAddExpect": true, - "canAddWorkExp": true, - "canAddProjectExp": true, - "canAddEduExp": true, - "canAddSocialContact": true - }, - "doneWorkPositionList": [], - "handicappedInfo": null, - "postExpList": [], - "myLabels": null, - "clubExpList": [], - "professionalSkill": null, - "honorList": [], - "feature": { - "showNewPositionStyle": 1, - "showHandicappedModule": 0, - "showResumeImportBtn": 1, - "showResumeImportBtnRedDot": false, - "showResumeFillHelper": 1, - "showTrainingExpModule": 0, - "showF3Optimize": 1, - "showPostExpModule": 0, - "webResumeLabelModule": 0, - "expectLocationInterestCombine": 0, - "stuMultiExpectChoose": 0, - "useNewStruct": 1 - }, - "virtualPartTimeCombineExpect": null, - "extendInfo": { - "shareUrl": "https://m.zhipin.com/mpa/html/resume-detail?sid=self&securityId=I8Nn8H-vv1Tt2-x1OxkE4U0hH697NrOJFEJF_pkEXnMTR6gLbbUXGWy9pFLFnOy9YeLxI-31CLT9aCmPeQ_YSVDoSj1AMLuej3IhRhkUgQzm98k4pG1F7XVZdNphlh2Mc8Wr2PltQNmRB2eJHwcx4j338ACBezr_YAvcjOQ~", - "shareText": "{\"showQQShare\":false,\"smsShareTitle\":\"牛人张成 10年以上工作经验,目标 全栈工程师职位,求靠谱Boss带走。迅速进入@Boss直聘,把TA带走,下载链接奉上:https://m.zhipin.com/download?from=duanxin\",\"wbShareTitle\":\"#招聘#牛人张成 10年以上工作经验,目标 全栈工程师职位,求靠谱Boss带走。迅速进入@Boss直聘,把TA带走,下载链接奉上:https://m.zhipin.com/download?from=weibo\",\"wxShareDesc\":\"经验:10年以上工作经验 期望薪资:20-30K\",\"wxShareTitle\":\"【Boss直聘】张成正在求职全栈工程师\"}" - }, - "moduleList": [ - { - "moduleType": 10, - "moduleName": "个人信息", - "customConfig": { - "showType": 0, - "desc": null, - "tag": null - }, - "data": { - "name": "张成", - "nickName": "张成", - "tiny": "https://img.bosszhipin.com/beijin/upload/avatar/20250211/607f1f3d68754fd006d510844c0273d99b737108b9d73a664006f977785f3a6a694eb527b0e564d8_s.png.webp", - "birthday": "1993-06", - "age": "32岁", - "gender": 1, - "degree": 203, - "degreeCategory": "本科", - "account": "193******69", - "emailBlur": "978****03@qq.com", - "weixinBlur": "z56***01", - "freshGraduate": 0, - "workYears": 11, - "nameShowType": 0, - "bossCert": 0, - "userCert": 2, - "certGender": true, - "certBirth": true, - "startWorkDate": 20141201, - "applyStatus": 0, - "workYearDesc": "10年以上经验", - "resumeStatus": 0, - "resumeCount": 0, - "complete": false, - "weiXinSecurityUid": null, - "garbageFieldList": null, - "hometown": 0, - "hometownName": null, - "studyAbroadCertPass": 0, - "highestEduExp": null, - "showF3Optimize": 0, - "startWorkDateDesc": "2014-12", - "birthdayDesc": "1993-06" - }, - "dataList": null - }, - { - "moduleType": 11, - "moduleName": "个人优势", - "customConfig": { - "showType": 0, - "desc": null, - "tag": null - }, - "data": { - "userDesc": "拥有10年深厚行业经验的资深前端架构师,专注前沿技术与业务融合,推动数字化产品创新升级。\n \n1. 技术栈与架构:熟练运用Vue、React等主流框架,搭配Webpack、Vite等构建工具进行高效开发。精通TypeScript,优化代码结构与维护性。擅长使用Redux、MobX管理复杂应用状态,搭建稳定架构。\n \n2. 跨端与组件化:掌握Flutter、React Native等跨端技术,实现多平台无缝运行。主导设计高复用组件库,利用Storybook管理组件,使组件复用率达70%,开发周期缩短40%。\n \n3. AI集成:积极探索AI与前端融合,集成GPT等大模型实现智能客服、内容生成,引入机器学习算法实现用户行为分析、个性化推荐,大幅提升用户参与度。\n \n4. 音视频处理:具备音视频处理能力,使用WebRTC实现实时通信,结合FFmpeg进行格式转换、剪辑。利用Media Source Extensions实现自适应码率播放,优化视频加载与播放体验。\n\n 5. 后端及多元开发:擅长使用Node.js搭配Express、Koa框架搭建高性能后端服务,优化接口响应速度。熟练运用Python进行数据处理、自动化脚本编写,结合Django、Flask框架开发后端应用,在数据挖掘与分析领域成果显著。掌握C#语言,基于.NET平台进行Windows桌面应用开发,具备丰富的Windows Forms、WPF项目经验,实现全栈技术链路的打通。" - }, - "dataList": null - }, - { - "moduleType": 24, - "moduleName": "求职期望", - "customConfig": { - "showType": 0, - "desc": null, - "tag": null - }, - "data": null, - "dataList": [ - { - "id": "dfc1777a2703c9071nVz3d-0GVpYxA~~", - "expectType": 0, - "position": 100123, - "positionName": "全栈工程师", - "customPositionId": "", - "positionType": 0, - "location": 101020100, - "locationName": "上海", - "subLocation": 0, - "subLocationName": null, - "lowSalary": 20, - "highSalary": 30, - "salaryDesc": "20-30K", - "salaryDescNew": "20-30K", - "industryList": [], - "industryDesc": "行业不限", - "suggestPosition": "", - "applyStatus": 0, - "freshGraduate": 0, - "doneWorkPositionList": null, - "garbageFieldList": null, - "interestPositionList": null, - "interestLocationList": null, - "industryExpect": false, - "tagName": null - } - ] - }, - { - "moduleType": 12, - "moduleName": "工作经历", - "customConfig": { - "showType": 0, - "desc": null, - "tag": null - }, - "data": null, - "dataList": [ - { - "id": "9bd3116c0333c52d1nJ_09y-EldZx465V_-X", - "companyName": "上海宝尊电子商务有限公司", - "industry": { - "code": 100020, - "name": "互联网" - }, - "department": "", - "customPositionName": "架构师", - "position": 100704, - "positionName": "架构师", - "positionLv2": 100700, - "startDate": "2019.06", - "startDateStr": "2019.06", - "endDate": "2024.12", - "endDateStr": "2024.12", - "emphasis": [], - "workContent": "智能视频剪辑系统(2021.07-2024.12)\n技术栈:Vue2+Element UI+WebAssembly+Canvas+Konva.js+WebSocket+GSAP\n核心功能:\n1.视频处理:基于WebAssembly解析视频信息,实现大文件分片上传,支持200G+视频处理\n2.创意编辑:使用Konva.js开发多层级编辑器,实现图片分层、文字动画、贴片特效\n3.动画系统:基于GSAP开发文字特效、Logo动画,支持动态片头片尾制作\n4.预览系统:使用Canvas实现视频片段预览,支持时间轴精确定位\n5.任务管理:基于WebSocket实现批量任务进度实时通知\n项目成果:视频处理效率提升300%|日均处理1000+视频|压缩率达97%|任务效率提升200%|降低\n人工成本60%", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - }, - { - "id": "283b1abcae6041e41nJ_0969ElpVy423Vvic", - "companyName": "上海航天动力科技工程有限公司", - "industry": { - "code": 100021, - "name": "计算机软件" - }, - "department": "", - "customPositionName": "架构师", - "position": 100704, - "positionName": "架构师", - "positionLv2": 100700, - "startDate": "2018.06", - "startDateStr": "2018.06", - "endDate": "2019.06", - "endDateStr": "2019.06", - "emphasis": [], - "workContent": "技术栈:Vue2+iView+OpenLayers+Cesium+WebSocket+Less\n核心功能:\n1.GIS可视化:基于OpenLayers实现管网GIS展示,支持多图层管理\n2.实时监控:使用WebSocket推送报警信息,实现管道水流方向动画\n3.数据分析:集成ECharts开发运营分析、报表统计功能\n4.空间分析:使用Turf.js实现等差线绘制,可视化爆管位置\n项目成果:地图加载提升200%|漏损检测准确率95%|节省成本300万+|服务10+水务公司|覆盖管\n网1000km+", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - }, - { - "id": "d18fc7f74a6479ee1nJ_0969ElpVy423Vvid", - "companyName": "上海开澜软件有限公司", - "industry": { - "code": 100021, - "name": "计算机软件" - }, - "department": "", - "customPositionName": ".NET", - "position": 100107, - "positionName": ".NET", - "positionLv2": 100100, - "startDate": "2016.06", - "startDateStr": "2016.06", - "endDate": "2018.06", - "endDateStr": "2018.06", - "emphasis": [ - "HTML" - ], - "workContent": "滩涂造地BIM管理系统(2017.01-2018.05)\n技术栈:jQuery+EasyUI+BIMViz+百度图+WebAppOffice\n核心功能:\n1.BIM可视化:集成BIMViz实现模型在线预览,支持构件查询和联动\n2.地图集成:基于百度地图API实现工程位置展示和空间分析\n3.文档管理:使用WebAppOffice实现在线预览,支持多格式文档\n4.工作流程:开发OA审批流程,实现物料申请和人员管理\n项目成果:BIM性能提升200%|审批效率提升150%|支持50+文档格式|日均处理500+工单|管理效\n率提升80%", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - }, - { - "id": "c07196b9b117210f1nJ_0969ElpVy423Vvie", - "companyName": "上海加谷网络科技有限公司", - "industry": { - "code": 100002, - "name": "游戏" - }, - "department": "", - "customPositionName": ".NET", - "position": 100107, - "positionName": ".NET", - "positionLv2": 100100, - "startDate": "2014.06", - "startDateStr": "2014.06", - "endDate": "2016.05", - "endDateStr": "2016.05", - "emphasis": [ - "HTML" - ], - "workContent": "H5营销平台开发(2014.06-2016.05)\n技术栈:jQuery+Canvas+CSS3+HTML5+微信JSSDK\n核心功能:\n1.互动游戏:开发大转盘抽奖、刮刮卡、砸金蛋等H5游戏\n2.动画特效:自研Canvas动画框架,支持Flash动画转换\n3.低代码平台:开发可视化搭建工具,支持营销活动快速生成\n4.社交功能:集成微信分享、支付、授权等功能项目成果:服务200+品牌|开发效率提升300%|上线周期缩短80%|转化率提升150%|支持百万级访问", - "workPerformance": "", - "isPublic": 1, - "workType": 1, - "suggestToDel": 0, - "garbageFieldList": null - } - ] - }, - { - "moduleType": 13, - "moduleName": "项目经历", - "customConfig": { - "showType": 0, - "desc": null, - "tag": null - }, - "data": null, - "dataList": [ - { - "id": "903b8e07eb7f44ca1nx50t-6EFZQw4i8UvKY", - "name": "AI智能视频剪辑系统", - "roleName": "全栈工程师", - "url": "", - "startDate": "2024.01", - "endDate": "", - "projectDesc": "系统简介\nai智能视频剪辑系统,可通过淘宝直播间,天猫,淘宝商品链接,自动从直播间中按照商品切片,并输出到天猫商品详情页主视频,发布到小红书,淘宝微淘等平台,可批量生成视频,处理视频,前端技术栈:vue全家桶+elemeui+浏览器插件\n后端技术栈:Node.js+Koa2+Vue2+FFmpeg+Redis\n功能模块:\n1.内容采集:开发Chrome浏览器插件自动获取直播回放、商品时间点智能识别、多平台视频源导入本地大视频文件上传,支持200g左右大文件批量上传,断点续传等功能\n2.任务管理:用户可以批量创建任务,任务实时状态使用WebSocket更新并通知\n3.模版管理:可基于execl文件批量创建任务,动态生成片尾图和首图\n4.智能生成:基于GPT的视频内容理解、关键片段提取和智能场景组合、60秒精华自动生成\n5.内容编辑:多轨道编辑和场景识别分割、转场特效库和字幕样式编辑、贴纸滤镜和音频处理、GSAP文字动画和Logo动效\n6.深度剪辑:用户可以拖动句子,自动以切片输出内容\n7.发布管理:多格式导出和自定义分辨率码率、批量导出队列和云端渲染、进度实时展示\n8.视频特效开发:如:文字抖动,花字,特效,特殊字幕,贴片动画等工作成果:\n1.使用FFmpeg开发视频处理引擎,支持多种视频格式转码,压缩进度回调\n2.设计任务队列系统,服务器CPU使用率控制在70%以下,使用负载均衡分摊压力,实现任务批量处理\n3.集成GPT模型,视频内容理解准确率达85%,精华片段提取效率提升200%\n4.实现大文件分片上传,支持断点续传,上传成功率99%\n5.开发完整的日志追踪系统,问题定位时间缩短,使用sse日志推送至前端页面可实时观察任务处理情况,接入报警机器人报警推送至企业微信群\n6.开发前端视频渲染引擎,图片编辑器,js逆向破解支持数据采集成功\n7.封装常用前端组件库,前端框架搭建与维护,指导其他组员开发,解决问题", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2024.01", - "endDateStr": "至今" - }, - { - "id": "2a6ee534976187341nx50t-6EVNWyoq-Vf-e", - "name": "水务DMA分区计量管理系统", - "roleName": "全栈工程师", - "url": "", - "startDate": "2023.07", - "endDate": "", - "projectDesc": "DMA (DistrictMetered Area)分区计量管理系统是一种先进的、专门应用于供水管网精细化管理的综合性系统。\n通过将供水管网划分成多个相对独立的计量区域(即DMA分区),在每个分区的进水口和出水口等关键节点安装高精度的计量设备,精确监测和记录水流的流入、流出情况,实现对各个分区内水量的实时计量与分析,其核心原理是基于封闭区域水量平衡理论,通过对比流入和流出水量等数据,精准定位可能存在的管网漏损点以及评估管网运行状态,助力供水企业实现科学管理、高效节水以及提升供水服务质量.\n前端技术栈:vue全家桶+elemeui,c#+wpf\n后端技术栈:Node.js+Koa2+mysq\n功能模块:\n1.实时数据处理:对DMA分区计量设备的水流数据进行清洗、校验和初步分析\n2.GIS数据管理:提供接口实现与地理信息系统的数据交互,管理管网地理空间数据。\n3.数据存储:基于MongoDB设计数据存储架构,进行数据备份与恢复。\n4.管网可视化:通过地图展示供水管网地理空间数据,支持多种地图操作\n5.空间分析:实现管网连通性、最短路径、缓冲区等空间分析功能。\n6.地图交互:提供地图标注和测距工具。\n7.实时数据推送:利用WebSocket实时推送DMA分区计量和设备状态数据。\n8.智能报警:实时监测管网异常,生成报警信息并通知相关人员,对报警信息分类统计\n9.设备状态监控:实时获取计量设备工作状态、电量等信息,分析运行历史数据数据采集功能\n10.数据采集程序:使用C#的WPF开发可与多种RTU设备通信的采集程序\n11.动态解析:服务端动态接收并自动解析不同RTU设备的数据。\n12.数据展示与导出:以图表和表格展示采集数据,支持CSV格式动态导出。\n项目成果:支持10000+设备并发查询性能提升150%系统稳定性99.99", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2023.07", - "endDateStr": "至今" - }, - { - "id": "6aa05589bc43d7711nx50t-6EVNWyoq-Vf-d", - "name": "bb物语小程序商城", - "roleName": "全栈工程师", - "url": "", - "startDate": "2023.05", - "endDate": "", - "projectDesc": "技术架构:\n前端:Vue2+mpVue\n后端:node.js+koa2+sequelize\n数据库:MySQL+Redis\n功能模块:\n1.商品管理:商品分类、商品上架、库存管理、价格管理、商品搜索\n2.订单管理:订单创建、订单支付、订单取消、订单查询,订单统计\n3.用户管理:用户注册、用户登录、用户信息管理、用户积分、用户等级\n4.营销管理:优惠券管理、满减活动、限时抢购、拼团活动、积分兑换\n5.支付系统:微信支付、支付宝支付\n4.设计用户管理系统,支持用户注册、登录、信息管理和积分系统\n5.开发营销管理模块,支持优惠券、满减活动、限时抢购和拼团活动\n6.实现数据分析功能,支持销售数据统计,用户行为分析、商品热度分析、营销效果分析\n工作成果:\n1.实现商品管理系统,支持商品的分类、上架、库存和价格管理\n2.开发订单管理模块,支持订单的创建、支付、取消和查询\n3.集成多种支付方式,支持微信支付、支付宝支付\n4.设计用户管理系统,支持用户注册、登录、信息管理和积分系统\n5.开发营销管理模块,支持优惠券、满减活动、限时抢购和拼团活动\n6.实现数据分析功能,支持销售数据统计,用户行为分析和商品热度分析\n7.支持三级分销,以及销售人员工资统计", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2023.05", - "endDateStr": "至今" - }, - { - "id": "32010e34944e04851nJ_0969E1JQx4q-Vfuc", - "name": "AI智能写手系统", - "roleName": "全栈开发工程师", - "url": "", - "startDate": "2020.03", - "endDate": "2021.07", - "projectDesc": "技术栈:Vue2+Element Ul+WebSocket+jWT+Less+Webpack+Node.js\n核心功能:\n1.平台管理:基于IWT的权限控制,实现品牌管理、角色权限、秀场墙功能\n2.内容制作:开发智能语句生成,作品库管理,多元化批量处理功能\n3.数据采集:Chrome插件开发,实现多平台商品信息自动采集\n4.多端适配:使用Rem+Flex实现响应式布局,支持不同屏幕自适应\n5.自动发布:开发多平台发布插件,支持淘宝天猫京东等平台内自动发布\n6.定时任务:基于Node.js实现定时发布、数据同步、内容更新等动化任务\n项目成果:开发效率提升200%|首屏加载800ms|数据处理效率提升300%|服务10+品牌|运营效率\n提升400%|任务成功率99.5%", - "performance": "开发效率提升200%首屏加载800ms数据处理效率提升300%服务10+品牌运营效率\n提升400%任务成功率99.5%", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2020.03", - "endDateStr": "2021.07" - }, - { - "id": "1dc51326ce11bc601nJ_0969E1JQx4q-Vfud", - "name": "易分析取数工具", - "roleName": "全栈开发工程师", - "url": "", - "startDate": "2019.08", - "endDate": "2020.03", - "projectDesc": "系统简介\n获取天猫,淘宝,腾讯,小红书蒲公英商家后台数据,用与大数据做营销精细化运营,支持人群画像,地域,人群,粉丝,购买,等一些列数据,以及达人数据粉丝数,带货数,直播场次,直播效果,商品评论,数据做分析\n前端技术栈:vue全家桶+elemeui+浏览器插件\n后端技术栈:Node.js+Koa2+mysql,Pythopn+Selenium+Flask\n功能模块:\n1.前端数据采集:淘宝数据银行API对接,策略中心数据抓取,生意参谋数据同步,营销数据实时获取\n2.后端数据采集:\n3.插件功能:多平台数据采集插件、自定义数据抓取规则、请求拦截和数据过滤、离线数据缓存\n4.数据处理:多维度数据整合分析、数据清洗和结构化、自定义数据导出、实时数据同步\n5.监控预警:数据采集任务监控、异常采集预警,数据质量监控、采集额度管理\n工作成果:\n1.支持淘宝全站数据采集,日均处理5000+数据\n2.开发通用数据采集引擎,支持自定义采集规则\n3.实现数据实时同步,延迟<500ms\n4.分布式爬虫系统架构,支持分布式抓取", - "performance": "1. 设计插件热更新方案,实现核心模块动态替换和状态保持\n2. 开发多浏览器兼容层,解决不同浏览器API差异问题实现插件配置动态更新和按需加载机制\n3. 使用Sequelize设计数据模型,处理复杂的表关联和数据同步重写浏览器原生Ajax,实现智能请求拦截和缓存策略\n4. 开发分布式日志系统,支持问题快速定位", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2019.08", - "endDateStr": "2020.03" - }, - { - "id": "e4294f91116b15dc1nJ_0969E1JQx4q-Vfue", - "name": "全工况智能终端采集系统", - "roleName": ".net软件工程师", - "url": "", - "startDate": "2018.05", - "endDate": "2018.08", - "projectDesc": "技术栈:WPF+Socket+InfluxDB+PostgreSQL\n核心功能:\n1.数据采集:实现Socket高并发通信,支持多协议解析\n2.实时监控:开发设备状态实时监控界面\n3.数据存储:设计混合数据库方案,优化查询性能\n4.可视化:实现数据实时展示和趋势分析\n项目成果:支持10000+设备并发|查询性能提升150%|系统稳定性99.99%|支持亿级数据毫秒级查询", - "performance": "1.实现百万级数据快速查询,平均查询时间<500ms\n2.设计实时数据动态渲染方案\n3.优化数据库性能,批量写入效率提升50%\n4.实现数据自动分级存储和归档\n5.开发设备状态实时监控系统", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2018.05", - "endDateStr": "2018.08" - }, - { - "id": "96160107ede0ae851nJ_0969E1JQx4q-Vfuf", - "name": "宝山排水证管理系统", - "roleName": ".net软件工程师", - "url": "", - "startDate": "2017.01", - "endDate": "2017.07", - "projectDesc": "技术栈:AngularjS+KendoUI+lonic+TypeScript+MongoDE\n核心功能:\n1.PC端开发:基于KendoUI快速构建后台管理界面,实现许可证全流程管理\n2.移动端开发:使用lonic+Aneular开发跨平台App,支持iOS和Androic\n3.表单设计:实现动态表单配置,支持多类型数据录入和自定义校验规则\n4.流程管理:开发审批流程引擎,支持条件分支、并行审批、委托授权\n5.地图功能:集成百度地图,实现排水户分布展示和空间位置选择\n6.统计分析:开发数据可视化大屏,展示许可证办理情况和区域分布移动端技术难点:\n基于lonic+Cordova实现原生功能调用,如相机、定位、文件系统等解决Android返回键监听和iOS手势返冲突问题\n实现大文件分片上传和断点续传,支持现场照片批量上传\n开发自定义相机组件,支持照片压缩和水印添加使用SOLite实现本地数据存储,解决断网环境下的数据同光\n优化Scroll性能,解决长列表滚动卡顿问题\n处理键盘弹出时的页面布局自适应\n解决iOS和Android平台字体、样式兼容性问题\n实现应用内检查更新和增量更新功能\n优化首屏加载速度,实现资源按需加载\n项目成果:办理时间缩短80%|代码复用率80%|响应时间300ms|审批效率提升200%", - "performance": "1. 实现大文件分片上传和断点续传,支持现场照片批量上传开发自定义相机组件,支持照片压缩和水印添加使用SOLite实现本地数据存储,解决断网环境下的数据同光\n2. 优化Scroll性能,解决长列表滚动卡顿问题处理键盘弹出时的页面布局自适应解决iOS和Android平台字体、样式兼容性问题实现应用内检查更新和增量更新功能\n3. 优化首屏加载速度,实现资源按需加载", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2017.01", - "endDateStr": "2017.07" - }, - { - "id": "c06dfe8c3678cf231nJ90tq7EVpQxo6_V_qW", - "name": "H5营销平台", - "roleName": ".net软件工程师", - "url": "", - "startDate": "2014.06", - "endDate": "2016.05", - "projectDesc": "技术栈:Vue2+Canvas+CSS3+微信ISSDK+.Net\n功能模块:\n1.游戏开发:开发大转盘抽奖、刮刮卡等H5游戏、自研Canvas动画框架、支持Flash动画转换\n2.内容管理:开发可视化搭建工具、支持营销活动快速生成、实现模板在线编辑\n3.社交功能:集成微信分享、支付、授权、开发用户数据分析、实现活动数据统计\n项目成果:服务200+品牌开发效率提升300%转化率提升150%", - "performance": "", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2014.06", - "endDateStr": "2016.05" - }, - { - "id": "4e09afd8b41347c61nJ_0969E1JQx4q-VfqW", - "name": "物料ERP管理系统", - "roleName": "前端开发工程师", - "url": "", - "startDate": "2014.08", - "endDate": "2015.06", - "projectDesc": "技术栈:jQuery+Bootstrap+EasyUl+WebSocket+SQL Server\n核心功能:\n1.库存管理:实现物料库、出库、调拨、盘点等完整业务流程\n2.采购管理:开发供应商管理、询价比价、采购计划、订单跟踪功能\n3.生产管理:实现BOM管理、生产计划、物料需求计划(MRP)功能\n4.报表分析:开发库存周转率、采购分析、成本核算等统计报表\n5.预警提醒:设置库存预警、采购超期、价格异常等自动提醒\n技术难点:\n开发物料编码生成器,支持多级分类和自定义规则\n实现基于WebSocket的实时库存变更提醒\n设计MRP运算引擎,优化大批量数据处理性能\n开发报表导出功能,支持复杂表头和数据汇总项目成果:库存周转提升40%|采购成本降低15%|支持100+用户并发|日均处理3000+笔业务", - "performance": "1. 开发物料编码生成器,支持多级分类和自定义规则\n2. 实现基于WebSocket的实时库存变更提醒\n3. 设计MRP运算引擎,优化大批量数据处理性能\n4. 开发报表导出功能,支持复杂表头和数据汇", - "suggestToDel": 0, - "garbageFieldList": null, - "startDateStr": "2014.08", - "endDateStr": "2015.06" - } - ] - }, - { - "moduleType": 14, - "moduleName": "教育经历", - "customConfig": { - "showType": 0, - "desc": null, - "tag": null - }, - "data": null, - "dataList": [ - { - "id": "ee34188f32f9cecc1XF52NW5F1dT", - "schoolId": 2811, - "school": "武汉工程大学", - "major": "计算机应用技术(大数据方向)", - "degree": 203, - "eduType": 2, - "degreeName": "本科", - "startYear": "2021", - "endYear": "2024", - "educationDesc": "", - "country": "", - "tags": [ - "卓越工程师计划" - ], - "schoolType": 0, - "suggestToDel": 0, - "thesisTitle": "", - "thesisDesc": "", - "majorRanking": 0, - "courseList": [], - "badge": "https://img.bosszhipin.com/beijin/icon/bed7df948518127f74daa2ee178c44fc6bb61e3b7bce0931da574d19d1d82c88.jpg", - "certified": 0, - "garbageFieldList": null, - "startYearStr": "2021", - "endYearStr": "2024" - }, - { - "id": "e095a1ceefdd0cc31XF52NW6FVZY", - "schoolId": 2831, - "school": "武汉软件工程职业学院", - "major": "软件技术", - "degree": 202, - "eduType": 1, - "degreeName": "大专", - "startYear": "2011", - "endYear": "2014", - "educationDesc": "", - "country": "", - "tags": [], - "schoolType": 0, - "suggestToDel": 0, - "thesisTitle": "", - "thesisDesc": "", - "majorRanking": 0, - "courseList": [], - "badge": "https://img.bosszhipin.com/beijin/icon/18282111c2fc8e191c5b6aedcece5a956bb61e3b7bce0931da574d19d1d82c88.jpg", - "certified": 0, - "garbageFieldList": null, - "startYearStr": "2011", - "endYearStr": "2014" - } - ] - }, - { - "moduleType": 16, - "moduleName": "资格证书", - "customConfig": { - "showType": 1, - "desc": null, - "tag": null - }, - "data": null, - "dataList": null - }, - { - "moduleType": 21, - "moduleName": "志愿服务经历", - "customConfig": { - "showType": 1, - "desc": null, - "tag": null - }, - "data": null, - "dataList": null - } - ] -} \ No newline at end of file diff --git a/_doc/客户端待开发功能.md b/_doc/客户端待开发功能.md deleted file mode 100644 index fb14628..0000000 --- a/_doc/客户端待开发功能.md +++ /dev/null @@ -1,1174 +0,0 @@ -# 客户端待开发功能文档 - -> 本文档说明客户端需要实现的功能,所有操作通过MQTT接收服务端指令执行 - ---- - -## 一、客户端架构概览 - -### 1.1 技术栈 -- **自动化框架**: Puppeteer / Playwright (推荐Playwright,支持更好的反爬) -- **运行环境**: Node.js 18+ -- **通信协议**: MQTT (mqtt://192.144.167.231:1883) -- **消息格式**: JSON -- **浏览器**: Chromium (无头模式/有头模式可切换) - -### 1.2 核心模块 -``` -client/ -├── src/ -│ ├── mqtt/ # MQTT通信模块 -│ │ ├── client.js # MQTT客户端 -│ │ └── handler.js # 消息处理器 -│ ├── platforms/ # 平台适配器 -│ │ ├── boss/ # Boss直聘 -│ │ │ ├── login.js # 登录模块 -│ │ │ ├── search.js # 搜索模块 ⚠️ 待开发 -│ │ │ ├── apply.js # 投递模块 ⚠️ 待完善 -│ │ │ ├── resume.js # 简历模块 ⚠️ 待开发 -│ │ │ ├── chat.js # 聊天模块 ⚠️ 待完善 -│ │ │ └── active.js # 保活模块 ⚠️ 待开发 -│ │ └── zhilian/ # 智联招聘 (同上) -│ ├── utils/ # 工具函数 -│ │ ├── browser.js # 浏览器管理 -│ │ ├── antibot.js # 反爬虫处理 -│ │ └── logger.js # 日志记录 -│ └── index.js # 入口文件 -└── config/ - └── default.json # 配置文件 -``` - -### 1.3 工作流程 -``` -服务端 → MQTT → 客户端接收 → 路由到平台模块 → 执行操作 → 返回结果 → MQTT → 服务端 -``` - ---- - -## 二、高优先级功能 (P0) - -> 与投递直接相关的核心功能 - -### 2.1 增强搜索功能 ⚠️ 待开发 - -#### 功能说明 -实现Boss直聘完整的搜索功能,支持所有筛选项和URL解析 - -#### MQTT指令 -- `search_jobs_enhanced` - 带完整筛选参数的搜索 -- `search_by_url` - 直接解析URL搜索 - -#### 目标URL示例 -``` -https://www.zhipin.com/web/geek/jobs?city=101020100&query=%E5%85%A8%E6%A0%88%E5%B7%A5%E7%A8%8B%E5%B8%88&experience=103°ree=203&salary=404 -``` - -#### 实现要点 - -**1. URL参数解析** -```javascript -// platforms/boss/search.js - -/** - * 解析Boss直聘搜索URL - * @param {string} url - 搜索URL - * @returns {Object} 解析后的参数对象 - */ -function parseSearchUrl(url) { - const urlObj = new URL(url); - const params = {}; - - // 城市代码 - if (urlObj.searchParams.get('city')) { - params.city = urlObj.searchParams.get('city'); - } - - // 搜索关键词 - if (urlObj.searchParams.get('query')) { - params.query = decodeURIComponent(urlObj.searchParams.get('query')); - } - - // 工作经验 - if (urlObj.searchParams.get('experience')) { - params.experience = urlObj.searchParams.get('experience'); - } - - // 学历要求 - if (urlObj.searchParams.get('degree')) { - params.degree = urlObj.searchParams.get('degree'); - } - - // 薪资范围 - if (urlObj.searchParams.get('salary')) { - params.salary = urlObj.searchParams.get('salary'); - } - - // 公司规模 - if (urlObj.searchParams.get('scale')) { - params.scale = urlObj.searchParams.get('scale'); - } - - // 融资阶段 - if (urlObj.searchParams.get('stage')) { - params.stage = urlObj.searchParams.get('stage'); - } - - // 职位类型 - if (urlObj.searchParams.get('position')) { - params.position = urlObj.searchParams.get('position'); - } - - // 行业领域 - if (urlObj.searchParams.get('industry')) { - params.industry = urlObj.searchParams.get('industry'); - } - - return params; -} - -/** - * 构建搜索URL - * @param {Object} params - 搜索参数 - * @returns {string} 完整的搜索URL - */ -function buildSearchUrl(params) { - const baseUrl = 'https://www.zhipin.com/web/geek/jobs'; - const searchParams = new URLSearchParams(); - - // 必填参数 - if (params.city) searchParams.set('city', params.city); - if (params.query) searchParams.set('query', params.query); - - // 可选筛选参数 - if (params.experience) searchParams.set('experience', params.experience); - if (params.degree) searchParams.set('degree', params.degree); - if (params.salary) searchParams.set('salary', params.salary); - if (params.scale) searchParams.set('scale', params.scale); - if (params.stage) searchParams.set('stage', params.stage); - if (params.position) searchParams.set('position', params.position); - if (params.industry) searchParams.set('industry', params.industry); - - return `${baseUrl}?${searchParams.toString()}`; -} -``` - -**2. 搜索执行** -```javascript -/** - * 执行增强搜索 - * @param {Page} page - Playwright页面对象 - * @param {Object} params - 搜索参数 - * @returns {Promise} 职位列表 - */ -async function searchJobsEnhanced(page, params) { - const url = buildSearchUrl(params); - - // 访问搜索页面 - await page.goto(url, { waitUntil: 'networkidle' }); - - // 等待职位列表加载 - await page.waitForSelector('.job-card-wrapper', { timeout: 10000 }); - - // 反爬虫检测 - const isBlocked = await checkBotDetection(page); - if (isBlocked) { - throw new Error('检测到反爬虫,需要人工介入'); - } - - const jobs = []; - let hasMore = true; - let scrollCount = 0; - const maxScrolls = params.maxResults ? Math.ceil(params.maxResults / 30) : 3; - - while (hasMore && scrollCount < maxScrolls) { - // 提取当前页面职位 - const pageJobs = await extractJobsFromPage(page); - jobs.push(...pageJobs); - - // 滚动加载更多 - hasMore = await scrollToLoadMore(page); - scrollCount++; - - // 随机延迟,模拟人类行为 - await randomDelay(1000, 3000); - } - - return jobs; -} - -/** - * 从页面提取职位信息 - * @param {Page} page - Playwright页面对象 - * @returns {Promise} 职位信息数组 - */ -async function extractJobsFromPage(page) { - return await page.$$eval('.job-card-wrapper', (cards) => { - return cards.map(card => { - const jobName = card.querySelector('.job-name')?.textContent.trim(); - const jobArea = card.querySelector('.job-area')?.textContent.trim(); - const salary = card.querySelector('.salary')?.textContent.trim(); - const companyName = card.querySelector('.company-name a')?.textContent.trim(); - const companyTag = Array.from(card.querySelectorAll('.company-tag-list li')) - .map(li => li.textContent.trim()); - const bossInfo = card.querySelector('.info-public')?.textContent.trim(); - const jobLink = card.querySelector('.job-card-left')?.href; - const jobId = jobLink?.match(/job_detail\/(\w+)\.html/)?.[1]; - - // 提取标签(经验、学历) - const tags = Array.from(card.querySelectorAll('.tag-list li')) - .map(li => li.textContent.trim()); - - return { - jobId, - jobName, - jobArea, - salary, - companyName, - companyTags: companyTag, - experience: tags[0] || '', - degree: tags[1] || '', - bossInfo, - jobLink, - tags - }; - }); - }); -} - -/** - * 滚动加载更多职位 - * @param {Page} page - Playwright页面对象 - * @returns {Promise} 是否还有更多内容 - */ -async function scrollToLoadMore(page) { - // 滚动到页面底部 - await page.evaluate(() => { - window.scrollTo(0, document.body.scrollHeight); - }); - - // 等待新内容加载 - await page.waitForTimeout(2000); - - // 检查是否有"加载更多"按钮或已到底部 - const loadMoreBtn = await page.$('.load-more'); - if (loadMoreBtn) { - await loadMoreBtn.click(); - await page.waitForTimeout(1500); - return true; - } - - // 检查是否显示"没有更多了" - const noMore = await page.$('.no-more-tips'); - return !noMore; -} -``` - -**3. 反爬虫处理** -```javascript -// utils/antibot.js - -/** - * 检测是否被反爬虫拦截 - * @param {Page} page - Playwright页面对象 - * @returns {Promise} 是否被拦截 - */ -async function checkBotDetection(page) { - const indicators = [ - () => page.$('.captcha-container'), // 验证码 - () => page.$('.security-check'), // 安全检查 - () => page.content().then(c => c.includes('频繁访问')), - () => page.content().then(c => c.includes('请稍后再试')) - ]; - - for (const check of indicators) { - if (await check()) { - return true; - } - } - - return false; -} - -/** - * 随机延迟 - * @param {number} min - 最小毫秒 - * @param {number} max - 最大毫秒 - */ -async function randomDelay(min, max) { - const delay = Math.floor(Math.random() * (max - min + 1)) + min; - await new Promise(resolve => setTimeout(resolve, delay)); -} - -/** - * 模拟人类鼠标移动 - * @param {Page} page - Playwright页面对象 - */ -async function simulateHumanBehavior(page) { - // 随机移动鼠标 - const randomX = Math.floor(Math.random() * 800) + 100; - const randomY = Math.floor(Math.random() * 600) + 100; - await page.mouse.move(randomX, randomY); - - // 随机滚动 - await page.evaluate(() => { - const scrollAmount = Math.floor(Math.random() * 300) + 100; - window.scrollBy(0, scrollAmount); - }); - - await randomDelay(500, 1500); -} -``` - -**4. MQTT指令处理器** -```javascript -// mqtt/handler.js - 增强搜索指令处理 - -async function handleSearchJobsEnhanced(payload) { - const { platform, params, taskId } = payload; - - try { - // 获取平台对应的浏览器页面 - const page = await browserManager.getPage(platform); - - // 确保已登录 - await ensureLoggedIn(page, platform); - - // 执行搜索 - const searchModule = require(`../platforms/${platform}/search.js`); - const jobs = await searchModule.searchJobsEnhanced(page, params); - - // 返回结果 - return { - code: 0, - message: '搜索成功', - data: { - total: jobs.length, - jobs: jobs - }, - taskId - }; - } catch (error) { - console.error('搜索失败:', error); - return { - code: -1, - message: error.message, - taskId - }; - } -} - -async function handleSearchByUrl(payload) { - const { platform, url, taskId } = payload; - - try { - const searchModule = require(`../platforms/${platform}/search.js`); - - // 解析URL - const params = searchModule.parseSearchUrl(url); - - // 执行搜索 - const page = await browserManager.getPage(platform); - await ensureLoggedIn(page, platform); - const jobs = await searchModule.searchJobsEnhanced(page, params); - - return { - code: 0, - message: '搜索成功', - data: { - total: jobs.length, - jobs: jobs, - params: params // 返回解析的参数 - }, - taskId - }; - } catch (error) { - console.error('URL搜索失败:', error); - return { - code: -1, - message: error.message, - taskId - }; - } -} -``` - -#### 参数映射表 - -**工作经验 (experience)** -- `103`: 应届生 -- `104`: 1年以内 -- `105`: 1-3年 -- `106`: 3-5年 -- `107`: 5-10年 -- `108`: 10年以上 - -**学历要求 (degree)** -- `203`: 大专 -- `204`: 本科 -- `205`: 硕士 -- `206`: 博士 - -**薪资范围 (salary)** -- `402`: 3K以下 -- `403`: 3-5K -- `404`: 5-10K -- `405`: 10-15K -- `406`: 15-25K -- `407`: 25-35K -- `408`: 35-50K -- `409`: 50K以上 - -**公司规模 (scale)** -- `301`: 0-20人 -- `302`: 20-99人 -- `303`: 100-499人 -- `304`: 500-999人 -- `305`: 1000-9999人 -- `306`: 10000人以上 - -**融资阶段 (stage)** -- `801`: 未融资 -- `802`: 天使轮 -- `803`: A轮 -- `804`: B轮 -- `805`: C轮 -- `806`: D轮及以上 -- `807`: 已上市 -- `808`: 不需要融资 - -#### 测试用例 -```javascript -// 测试用例1: 参数搜索 -{ - action: 'search_jobs_enhanced', - platform: 'boss', - params: { - city: '101020100', // 上海 - query: '全栈工程师', - experience: '106', // 3-5年 - degree: '204', // 本科 - salary: '406', // 15-25K - scale: '303', // 100-499人 - maxResults: 100 - } -} - -// 测试用例2: URL搜索 -{ - action: 'search_by_url', - platform: 'boss', - url: 'https://www.zhipin.com/web/geek/jobs?city=101020100&query=%E5%85%A8%E6%A0%88%E5%B7%A5%E7%A8%8B%E5%B8%88&experience=106°ree=204&salary=406' -} -``` - ---- - -### 2.2 批量投递功能 ⚠️ 待完善 - -#### 功能说明 -支持批量投递职位,带智能过滤和频率控制 - -#### MQTT指令 -- `batch_apply_jobs` - 批量投递 - -#### 实现要点 - -```javascript -// platforms/boss/apply.js - -/** - * 批量投递职位 - * @param {Page} page - Playwright页面对象 - * @param {Array} jobIds - 职位ID列表 - * @param {Object} options - 投递选项 - * @returns {Promise} 投递结果 - */ -async function batchApplyJobs(page, jobIds, options = {}) { - const { - maxPerHour = 20, // 每小时最多投递数 - delayMin = 10000, // 最小间隔(ms) - delayMax = 30000, // 最大间隔(ms) - skipApplied = true, // 跳过已投递 - greetingMessage = '' // 打招呼消息 - } = options; - - const results = { - total: jobIds.length, - success: 0, - failed: 0, - skipped: 0, - details: [] - }; - - let appliedThisHour = 0; - let hourStartTime = Date.now(); - - for (const jobId of jobIds) { - // 频率控制 - if (appliedThisHour >= maxPerHour) { - const elapsed = Date.now() - hourStartTime; - if (elapsed < 3600000) { - const waitTime = 3600000 - elapsed; - console.log(`已达每小时投递上限,等待 ${waitTime/1000} 秒`); - await new Promise(resolve => setTimeout(resolve, waitTime)); - appliedThisHour = 0; - hourStartTime = Date.now(); - } - } - - try { - // 检查是否已投递 - if (skipApplied) { - const applied = await checkIfApplied(page, jobId); - if (applied) { - results.skipped++; - results.details.push({ jobId, status: 'skipped', reason: '已投递' }); - continue; - } - } - - // 投递职位 - await applyJob(page, jobId, greetingMessage); - - results.success++; - appliedThisHour++; - results.details.push({ jobId, status: 'success' }); - - // 随机延迟 - const delay = Math.floor(Math.random() * (delayMax - delayMin + 1)) + delayMin; - await new Promise(resolve => setTimeout(resolve, delay)); - - } catch (error) { - results.failed++; - results.details.push({ - jobId, - status: 'failed', - reason: error.message - }); - } - } - - return results; -} - -/** - * 检查职位是否已投递 - */ -async function checkIfApplied(page, jobId) { - await page.goto(`https://www.zhipin.com/job_detail/${jobId}.html`); - await page.waitForTimeout(1000); - - // 查找"继续沟通"或"已沟通"按钮 - const appliedBtn = await page.$('.btn-applied, .btn-chatted'); - return !!appliedBtn; -} - -/** - * 投递单个职位 - */ -async function applyJob(page, jobId, greetingMessage) { - await page.goto(`https://www.zhipin.com/job_detail/${jobId}.html`); - await page.waitForSelector('.btn-startchat', { timeout: 5000 }); - - // 点击"立即沟通" - await page.click('.btn-startchat'); - - // 如果有打招呼消息 - if (greetingMessage) { - await page.waitForSelector('.chat-input', { timeout: 3000 }); - await page.fill('.chat-input', greetingMessage); - await page.click('.send-btn'); - } - - await page.waitForTimeout(1000); -} -``` - ---- - -### 2.3 简历刷新功能 ⚠️ 待开发 - -#### 功能说明 -定时刷新简历,提升曝光度 - -#### MQTT指令 -- `refresh_resume` - 刷新简历 - -#### 实现要点 - -```javascript -// platforms/boss/resume.js - -/** - * 刷新简历 - * @param {Page} page - Playwright页面对象 - * @returns {Promise} 刷新结果 - */ -async function refreshResume(page) { - try { - // 进入简历管理页面 - await page.goto('https://www.zhipin.com/web/geek/profile', { - waitUntil: 'networkidle' - }); - - // 查找刷新按钮 - const refreshBtn = await page.$('.refresh-resume-btn, .update-resume-btn'); - if (!refreshBtn) { - throw new Error('未找到刷新按钮'); - } - - // 检查是否可刷新(可能有时间限制) - const disabled = await refreshBtn.getAttribute('disabled'); - if (disabled) { - // 获取下次可刷新时间 - const nextRefreshTime = await page.$eval('.next-refresh-time', el => el.textContent); - throw new Error(`暂时无法刷新,下次可刷新时间: ${nextRefreshTime}`); - } - - // 点击刷新 - await refreshBtn.click(); - await page.waitForTimeout(2000); - - // 确认刷新 - const confirmBtn = await page.$('.confirm-refresh'); - if (confirmBtn) { - await confirmBtn.click(); - await page.waitForTimeout(1000); - } - - return { - success: true, - message: '简历刷新成功', - timestamp: new Date().toISOString() - }; - } catch (error) { - throw new Error(`简历刷新失败: ${error.message}`); - } -} - -/** - * 获取简历刷新状态 - */ -async function getResumeRefreshStatus(page) { - await page.goto('https://www.zhipin.com/web/geek/profile'); - - const status = await page.evaluate(() => { - const refreshBtn = document.querySelector('.refresh-resume-btn'); - const isDisabled = refreshBtn?.hasAttribute('disabled'); - const nextTime = document.querySelector('.next-refresh-time')?.textContent; - const lastRefreshTime = document.querySelector('.last-refresh-time')?.textContent; - - return { - canRefresh: !isDisabled, - nextRefreshTime: nextTime, - lastRefreshTime: lastRefreshTime - }; - }); - - return status; -} -``` - ---- - -## 三、中优先级功能 (P1) - -### 3.1 账号保活功能 ⚠️ 待开发 - -#### 功能说明 -模拟真实用户行为,防止账号被标记为机器人 - -#### MQTT指令 -- `auto_active` - 执行保活操作 - -#### 实现要点 - -```javascript -// platforms/boss/active.js - -/** - * 执行保活操作 - * @param {Page} page - Playwright页面对象 - * @param {Object} options - 保活选项 - */ -async function performActiveActions(page, options = {}) { - const { - duration = 300000, // 持续时间(ms) 默认5分钟 - actions = ['browse', 'search', 'view_company', 'scroll'] - } = options; - - const startTime = Date.now(); - const actionsPerformed = []; - - while (Date.now() - startTime < duration) { - // 随机选择一个行为 - const action = actions[Math.floor(Math.random() * actions.length)]; - - try { - switch (action) { - case 'browse': - await browseJobList(page); - break; - case 'search': - await performRandomSearch(page); - break; - case 'view_company': - await viewRandomCompany(page); - break; - case 'scroll': - await randomScroll(page); - break; - } - - actionsPerformed.push({ - action, - timestamp: new Date().toISOString() - }); - - // 随机延迟 - await randomDelay(5000, 15000); - - } catch (error) { - console.error(`保活操作失败: ${action}`, error); - } - } - - return { - success: true, - duration: Date.now() - startTime, - actionsPerformed: actionsPerformed.length, - details: actionsPerformed - }; -} - -/** - * 浏览职位列表 - */ -async function browseJobList(page) { - await page.goto('https://www.zhipin.com/web/geek/jobs', { - waitUntil: 'networkidle' - }); - - // 随机滚动 - for (let i = 0; i < 3; i++) { - await page.evaluate(() => { - window.scrollBy(0, Math.random() * 500 + 200); - }); - await randomDelay(1000, 3000); - } -} - -/** - * 执行随机搜索 - */ -async function performRandomSearch(page) { - const keywords = ['前端', '后端', 'Java', 'Python', '产品经理', '运营']; - const keyword = keywords[Math.floor(Math.random() * keywords.length)]; - - await page.goto(`https://www.zhipin.com/web/geek/jobs?query=${encodeURIComponent(keyword)}`); - await page.waitForTimeout(2000); - - // 随机点击一个职位查看 - const jobCards = await page.$$('.job-card-wrapper'); - if (jobCards.length > 0) { - const randomIndex = Math.floor(Math.random() * Math.min(jobCards.length, 5)); - await jobCards[randomIndex].click(); - await page.waitForTimeout(3000); - } -} - -/** - * 查看随机公司 - */ -async function viewRandomCompany(page) { - await page.goto('https://www.zhipin.com/web/geek/jobs'); - await page.waitForTimeout(2000); - - const companyLinks = await page.$$('.company-name a'); - if (companyLinks.length > 0) { - const randomIndex = Math.floor(Math.random() * Math.min(companyLinks.length, 5)); - await companyLinks[randomIndex].click(); - await page.waitForTimeout(5000); - } -} - -/** - * 随机滚动 - */ -async function randomScroll(page) { - const scrollTimes = Math.floor(Math.random() * 5) + 2; - - for (let i = 0; i < scrollTimes; i++) { - await page.evaluate(() => { - const direction = Math.random() > 0.5 ? 1 : -1; - const distance = Math.random() * 300 + 100; - window.scrollBy(0, direction * distance); - }); - - await randomDelay(800, 2000); - } -} -``` - ---- - -### 3.2 智能聊天功能 ⚠️ 待完善 - -#### 功能说明 -自动回复HR消息,提高响应率 - -#### MQTT指令 -- `send_greeting` - 发送打招呼消息 -- `auto_reply_chat` - 自动回复聊天 - -#### 实现要点 - -```javascript -// platforms/boss/chat.js - -/** - * 发送打招呼消息 - * @param {Page} page - Playwright页面对象 - * @param {string} bossId - HRID - * @param {string} message - 消息内容 - */ -async function sendGreeting(page, bossId, message) { - // 进入聊天页面 - await page.goto(`https://www.zhipin.com/web/geek/chat?bosId=${bossId}`); - await page.waitForSelector('.chat-input', { timeout: 5000 }); - - // 输入消息 - await page.fill('.chat-input', message); - await randomDelay(500, 1500); - - // 发送 - await page.click('.send-btn'); - await page.waitForTimeout(1000); - - return { - success: true, - bossId, - message, - timestamp: new Date().toISOString() - }; -} - -/** - * 自动回复聊天 - * @param {Page} page - Playwright页面对象 - * @param {Object} options - 回复选项 - */ -async function autoReplyChat(page, options = {}) { - const { - checkInterval = 60000, // 检查间隔(ms) - replyDelay = 30000, // 回复延迟(ms) 模拟思考时间 - maxReplies = 10 // 最多回复次数 - } = options; - - let repliedCount = 0; - - // 获取未读消息 - await page.goto('https://www.zhipin.com/web/geek/chat'); - await page.waitForTimeout(2000); - - const unreadChats = await page.$$('.chat-item.unread'); - - for (const chat of unreadChats) { - if (repliedCount >= maxReplies) break; - - try { - // 点击进入聊天 - await chat.click(); - await page.waitForTimeout(1000); - - // 获取最后一条消息 - const lastMessage = await page.$eval('.message-list .message-item:last-child .message-text', - el => el.textContent.trim() - ); - - // 调用服务端AI生成回复 - // 这里需要通过MQTT发送消息给服务端,服务端调用AI生成回复后返回 - // 为了简化,这里暂时使用预设回复 - const reply = generateAutoReply(lastMessage); - - // 等待一段时间,模拟真人思考 - await randomDelay(replyDelay * 0.8, replyDelay * 1.2); - - // 发送回复 - await page.fill('.chat-input', reply); - await page.click('.send-btn'); - await page.waitForTimeout(1000); - - repliedCount++; - - } catch (error) { - console.error('自动回复失败:', error); - } - } - - return { - success: true, - totalUnread: unreadChats.length, - replied: repliedCount - }; -} - -/** - * 生成自动回复(简化版,实际应调用服务端AI) - */ -function generateAutoReply(message) { - const lowerMessage = message.toLowerCase(); - - if (lowerMessage.includes('面试') || lowerMessage.includes('interview')) { - return '好的,感谢您的面试邀请!请问具体的面试时间和地点是什么?'; - } - - if (lowerMessage.includes('简历') || lowerMessage.includes('resume')) { - return '您好,我已经投递了简历,请查收。如有任何问题,欢迎随时沟通!'; - } - - if (lowerMessage.includes('薪资') || lowerMessage.includes('salary')) { - return '关于薪资,我的期望是根据岗位要求和市场情况来定的,具体可以详细沟通。'; - } - - // 默认回复 - return '收到,感谢您的消息!'; -} -``` - ---- - -## 四、低优先级功能 (P2) - -### 4.1 数据监控上报 - -```javascript -/** - * 上报性能数据 - */ -async function reportMetrics(metrics) { - const reportData = { - action: 'report_metrics', - metrics: { - ...metrics, - timestamp: new Date().toISOString(), - deviceInfo: { - platform: process.platform, - memory: process.memoryUsage(), - uptime: process.uptime() - } - } - }; - - await mqttClient.publish(`device/${sn_code}/metrics`, JSON.stringify(reportData)); -} -``` - -### 4.2 截图上报 - -```javascript -/** - * 截图并上报 - */ -async function captureAndReport(page, reason) { - const screenshot = await page.screenshot({ fullPage: false }); - const base64 = screenshot.toString('base64'); - - await mqttClient.publish(`device/${sn_code}/screenshot`, JSON.stringify({ - reason, - image: base64, - timestamp: new Date().toISOString() - })); -} -``` - ---- - -## 五、开发规范 - -### 5.1 错误处理 - -所有函数必须包含try-catch,并返回标准格式: - -```javascript -{ - code: 0, // 0成功,-1失败 - message: '操作成功', - data: {}, // 返回数据 - taskId: 'xxx', // 任务ID - timestamp: 'ISO时间' -} -``` - -### 5.2 日志记录 - -```javascript -const logger = require('../utils/logger'); - -logger.info('操作成功', { action: 'search_jobs', jobCount: 50 }); -logger.error('操作失败', { action: 'apply_job', error: error.message }); -logger.warn('检测到异常', { type: 'bot_detection' }); -``` - -### 5.3 配置管理 - -```json -// config/default.json -{ - "mqtt": { - "broker": "mqtt://192.144.167.231:1883", - "username": "admin", - "password": "public" - }, - "browser": { - "headless": false, - "slowMo": 50, - "defaultTimeout": 30000 - }, - "antibot": { - "randomDelay": { - "min": 1000, - "max": 3000 - }, - "humanBehavior": true - }, - "limits": { - "maxApplyPerHour": 20, - "maxApplyPerDay": 100, - "maxSearchPerHour": 50 - } -} -``` - ---- - -## 六、测试计划 - -### 6.1 单元测试 - -为每个模块编写单元测试: - -```javascript -// tests/platforms/boss/search.test.js -describe('Boss搜索模块', () => { - test('URL解析正确', () => { - const url = 'https://www.zhipin.com/web/geek/jobs?city=101020100&query=全栈'; - const params = parseSearchUrl(url); - expect(params.city).toBe('101020100'); - expect(params.query).toBe('全栈'); - }); - - test('搜索执行成功', async () => { - const jobs = await searchJobsEnhanced(page, { - city: '101020100', - query: '前端工程师' - }); - expect(jobs.length).toBeGreaterThan(0); - }); -}); -``` - -### 6.2 集成测试 - -测试完整的MQTT指令流程: - -```javascript -// tests/integration/search.test.js -describe('搜索功能集成测试', () => { - test('通过MQTT执行搜索', async () => { - const response = await mqttClient.publishAndWait('test_device', { - action: 'search_jobs_enhanced', - platform: 'boss', - params: { - city: '101020100', - query: '测试工程师' - } - }); - - expect(response.code).toBe(0); - expect(response.data.jobs).toBeDefined(); - }); -}); -``` - ---- - -## 七、部署和运维 - -### 7.1 环境要求 - -- Node.js 18+ -- Chromium/Chrome 浏览器 -- 充足的内存(建议2GB+) -- 稳定的网络连接 - -### 7.2 启动命令 - -```bash -# 开发模式 -npm run dev - -# 生产模式 -npm run start - -# 后台运行(Linux) -pm2 start src/index.js --name "job-client" -``` - -### 7.3 监控指标 - -- 任务执行成功率 -- 平均响应时间 -- 反爬虫触发次数 -- 账号状态(正常/异常) - ---- - -## 八、开发时间估算 - -| 功能模块 | 优先级 | 预计工时 | 备注 | -|---------|--------|---------|------| -| 增强搜索功能 | P0 | 3天 | 含URL解析和参数映射 | -| 批量投递功能 | P0 | 2天 | 含频率控制 | -| 简历刷新功能 | P0 | 1天 | 较简单 | -| 账号保活功能 | P1 | 2天 | 需模拟多种行为 | -| 智能聊天功能 | P1 | 3天 | 需AI对接 | -| 数据监控上报 | P2 | 1天 | 辅助功能 | -| **总计** | - | **12天** | 约2.5周 | - ---- - -## 九、风险和注意事项 - -### 9.1 反爬虫风险 - -- 操作频率过高可能触发验证码 -- 建议设置合理的延迟和频率限制 -- 模拟真实用户行为(鼠标移动、随机滚动) - -### 9.2 账号安全 - -- 避免同时操作过多账号 -- 登录后保持Cookie有效期 -- 定期执行保活操作 - -### 9.3 性能问题 - -- 浏览器实例占用较多内存 -- 建议实现浏览器实例池管理 -- 长时间运行需要定期重启 - ---- - -## 十、参考资料 - -- [Playwright 官方文档](https://playwright.dev/) -- [MQTT.js 文档](https://github.com/mqttjs/MQTT.js) -- [Boss直聘网站分析](https://www.zhipin.com/) -- [反爬虫最佳实践](https://github.com/topics/anti-bot) - ---- - -**文档版本**: v1.0 -**最后更新**: 2025-12-25 -**维护者**: 开发团队 diff --git a/_doc/已删除文件清单.md b/_doc/已删除文件清单.md deleted file mode 100644 index 05e55d4..0000000 --- a/_doc/已删除文件清单.md +++ /dev/null @@ -1,47 +0,0 @@ -# 已删除文件清单 - -## ✅ 已删除的文件 - -### 1. 废弃的服务文件 -- ✅ `api/services/task_scheduler.js` - 未使用的任务调度器 - - **原因**:实际系统使用 `middleware/schedule/` 中的调度系统 - - **替代方案**:使用 `middleware/schedule/index.js` 中的 `ScheduleManager` - -### 2. 已合并的服务文件 -- ✅ `api/services/job_service.js` - 职位服务(只有一个方法) - - **原因**:只有一个 `jobGreet` 方法,已合并到 `middleware/job/jobManager.js` - - **新位置**:`middleware/job/jobManager.js` → `job_greet()` 方法 - -### 3. 重命名的文件 -- ✅ `api/services/ossTool.js` → `api/services/oss_tool_service.js` - - **原因**:统一命名规范(snake_case + _service.js) - -## 📝 清理说明 - -### services/index.js 清理 -- 移除了对 `TaskScheduler` 的引用(已废弃) -- 移除了对 `MQTTHandler` 的引用(文件不存在) -- 移除了对 `JobService` 的引用(已合并) -- 保留了 `AIService` 和 `PlaAccountService` 的引用 - -## ⚠️ 注意事项 - -1. **TaskScheduler 已废弃** - - 实际调度系统:`middleware/schedule/index.js` (ScheduleManager) - - 任务队列:`middleware/schedule/taskQueue.js` - -2. **MQTT 管理** - - 实际使用:`middleware/mqtt/mqttManager.js` - - 不是 `services/mqtt_handler.js`(文件不存在) - -3. **工作管理** - - 实际使用:`middleware/job/jobManager.js` - - 已包含 `job_greet` 方法 - -## 🔄 后续工作 - -继续完成命名规范统一: -- 移动并重命名 `middleware/job/` 下的文件到 `services/` -- 合并AI服务 -- 统一类命名 - diff --git a/_doc/指令列表.md b/_doc/指令列表.md deleted file mode 100644 index e69de29..0000000 diff --git a/_doc/指令和任务模式适配检查报告.md b/_doc/指令和任务模式适配检查报告.md deleted file mode 100644 index a62e6ee..0000000 --- a/_doc/指令和任务模式适配检查报告.md +++ /dev/null @@ -1,123 +0,0 @@ -# 指令和任务模式适配检查报告 - -## 📋 检查范围 -检查 `api/middleware` 目录下的代码是否适用于新的指令和任务模式。 - -## ✅ 已适配的部分 - -### 1. **任务处理器 (taskHandlers.js)** -- ✅ 正确使用 `command.executeCommands()` 执行指令 -- ✅ 在 `handleAutoDeliverTask` 中创建指令并执行 -- ✅ 指令类型使用驼峰命名(`getOnlineResume`, `getJobList`, `applyJob`) - -### 2. **指令管理器 (command.js)** -- ✅ 已重构完成,统一封装指令执行 -- ✅ 统一处理成功、失败、超时 -- ✅ 统一记录数据库 -- ✅ 支持驼峰转下划线的命名转换 - -### 3. **任务队列 (taskQueue.js)** -- ✅ 正确使用任务处理器 -- ✅ 通过 `taskHandlers` 执行任务 - -## ⚠️ 需要修复的问题 - -### 1. **方法命名不一致** - -**问题描述**: -- 指令类型使用驼峰命名:`getOnlineResume`, `getJobList`, `applyJob` -- 大部分方法使用下划线命名:`get_online_resume`, `get_job_list` -- 但 `applyJob` 方法名是驼峰命名,与指令类型一致 - -**当前转换逻辑**: -```javascript -// command.js 中的转换 -const to_snake_case = (str) => { - if (str.includes('_')) return str; - return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, ''); -}; - -// getOnlineResume -> get_online_resume ✓ -// getJobList -> get_job_list ✓ -// applyJob -> apply_job ✗ (但实际方法名是 applyJob) -``` - -**解决方案**: -1. **方案1(推荐)**:统一使用下划线命名,将 `applyJob` 改为 `apply_job` -2. **方案2**:保持现状,`command.js` 中已支持两种命名方式(先尝试下划线,再尝试原名称) - -**当前状态**:方案2已实现,代码可以正常工作,但命名不统一。 - -### 2. **sendChatMessage 方法** - -**问题描述**: -- `chatManager.js` 中的方法是 `sendChatMessage`(驼峰命名) -- 如果指令类型是 `sendChatMessage`,转换后会变成 `send_chat_message`,但实际方法名是 `sendChatMessage` - -**当前状态**:`command.js` 中已支持回退机制,如果下划线命名找不到,会尝试原名称,所以可以正常工作。 - -## 📊 方法命名对照表 - -| 指令类型 (command_type) | 转换后方法名 | 实际方法名 | 状态 | -|------------------------|-------------|-----------|------| -| `getOnlineResume` | `get_online_resume` | `get_online_resume` | ✅ 匹配 | -| `getJobList` | `get_job_list` | `get_job_list` | ✅ 匹配 | -| `applyJob` | `apply_job` | `applyJob` | ⚠️ 不匹配(但可工作) | -| `sendChatMessage` | `send_chat_message` | `sendChatMessage` | ⚠️ 不匹配(但可工作) | - -## 🔧 建议修复 - -### 方案1:统一使用下划线命名(推荐) - -**修改文件**: -1. `api/middleware/job/jobManager.js`:将 `applyJob` 改为 `apply_job` -2. `api/middleware/job/chatManager.js`:将 `sendChatMessage` 改为 `send_chat_message` -3. `api/middleware/schedule/taskHandlers.js`:将指令类型改为下划线命名 - -**优点**: -- 命名统一,符合项目规范 -- 代码更清晰,减少混淆 - -**缺点**: -- 需要修改多个文件 -- 可能影响其他调用方 - -### 方案2:保持现状(当前方案) - -**优点**: -- 不需要修改现有代码 -- `command.js` 已支持两种命名方式 - -**缺点**: -- 命名不统一,容易混淆 -- 代码可读性稍差 - -## 📝 其他检查项 - -### 1. **deviceManager.js** -- ✅ 不直接涉及指令和任务,主要用于设备状态管理 -- ✅ 与任务系统配合良好 - -### 2. **job/index.js** -- ✅ 正确导出所有方法 -- ✅ 支持下划线命名规范 - -### 3. **MQTT 相关** -- ✅ 通过 `mqttClient.publishAndWait` 发送指令 -- ✅ 与指令系统配合良好 - -## ✅ 总结 - -**整体适配情况**:**良好** ✅ - -1. ✅ 核心功能已正确适配新的指令和任务模式 -2. ✅ 指令执行统一封装,处理逻辑完善 -3. ⚠️ 存在命名不一致问题,但不影响功能(有回退机制) -4. 💡 建议统一命名规范,提高代码可维护性 - -## 🎯 下一步行动 - -1. **可选**:统一方法命名规范(下划线命名) -2. **可选**:添加单元测试验证指令执行流程 -3. **可选**:完善错误处理和日志记录 - diff --git a/_doc/搜索列表和投递功能开发规划.md b/_doc/搜索列表和投递功能开发规划.md deleted file mode 100644 index f59c7bc..0000000 --- a/_doc/搜索列表和投递功能开发规划.md +++ /dev/null @@ -1,764 +0,0 @@ -# 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} 任务创建结果 - */ -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} 任务创建结果 - */ -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} 任务创建结果 { 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` - 账号数据模型 - diff --git a/_doc/数据库表同步指南.md b/_doc/数据库表同步指南.md deleted file mode 100644 index e4f6bcb..0000000 --- a/_doc/数据库表同步指南.md +++ /dev/null @@ -1,210 +0,0 @@ -# resume_info 表同步指南 - -## ❌ 错误信息 - -``` -Unknown column 'sn_code' in 'field list' -``` - -这个错误表示数据库中的 `resume_info` 表缺少 `sn_code` 字段。 - -## 🔧 解决方案 - -### 方案1: 使用同步脚本(推荐) - -运行以下命令同步表结构: - -```bash -node scripts/sync_resume_table.js -``` - -这个脚本会: -- ✅ 使用 `alter: true` 模式同步表(保留现有数据) -- ✅ 显示当前表结构 -- ✅ 检查所有必需字段是否存在 -- ✅ 提示缺少的字段 - -### 方案2: 手动添加字段 - -如果同步脚本无法运行,可以手动执行以下SQL: - -```sql --- 添加 sn_code 字段 -ALTER TABLE `resume_info` -ADD COLUMN `sn_code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '设备SN码' AFTER `id`; - --- 添加 account_id 字段 -ALTER TABLE `resume_info` -ADD COLUMN `account_id` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户ID' AFTER `sn_code`; - --- 添加索引 -ALTER TABLE `resume_info` -ADD INDEX `idx_sn_code` (`sn_code`); -``` - -### 方案3: 重建表(会删除现有数据!) - -⚠️ **警告:此操作会删除表中所有数据!** - -如果表中没有重要数据,可以删除表让系统重新创建: - -```sql -DROP TABLE IF EXISTS `resume_info`; -``` - -然后重启应用,Sequelize 会自动创建表(因为模型中有 `sync({ force: true })`)。 - -## 📋 必需字段列表 - -`resume_info` 表必须包含以下字段: - -### 核心字段 -- ✅ `id` - 主键(VARCHAR/UUID) -- ✅ `sn_code` - 设备SN码(VARCHAR(50),必填) -- ✅ `account_id` - 用户ID(VARCHAR(50),必填) -- ✅ `platform` - 平台(VARCHAR(20),默认'boss') - -### 个人信息 -- ✅ `fullName` - 姓名 -- ✅ `gender` - 性别 -- ✅ `age` - 年龄 -- ✅ `phone` - 电话 -- ✅ `email` - 邮箱 -- ✅ `location` - 所在地 - -### 教育背景 -- ✅ `education` - 学历 -- ✅ `major` - 专业 -- ✅ `school` - 毕业院校 -- ✅ `graduationYear` - 毕业年份 - -### 工作信息 -- ✅ `workYears` - 工作年限 -- ✅ `currentPosition` - 当前职位 -- ✅ `currentCompany` - 当前公司 -- ✅ `currentSalary` - 当前薪资 - -### 期望信息 -- ✅ `expectedPosition` - 期望职位 -- ✅ `expectedSalary` - 期望薪资 -- ✅ `expectedLocation` - 期望地点 -- ✅ `expectedIndustry` - 期望行业 - -### 技能和经验(TEXT类型) -- ✅ `skills` - 技能标签(JSON) -- ✅ `skillDescription` - 技能描述 -- ✅ `certifications` - 证书资质(JSON) -- ✅ `projectExperience` - 项目经验(JSON) -- ✅ `workExperience` - 工作经历(JSON) - -### AI分析字段(TEXT类型) -- ✅ `aiSkillTags` - AI技能标签(JSON) -- ✅ `aiStrengths` - AI优势分析 -- ✅ `aiWeaknesses` - AI劣势分析 -- ✅ `aiCareerSuggestion` - AI职业建议 -- ✅ `aiCompetitiveness` - AI竞争力评分(INT) - -### 其他字段 -- ✅ `resumeContent` - 简历内容(TEXT) -- ✅ `originalData` - 原始数据(TEXT/JSON) -- ✅ `isActive` - 是否活跃(BOOLEAN) -- ✅ `isPublic` - 是否公开(BOOLEAN) -- ✅ `syncTime` - 同步时间(DATETIME) - -## 🔍 验证表结构 - -运行以下SQL查看表结构: - -```sql -DESCRIBE resume_info; -``` - -或者查看完整的建表语句: - -```sql -SHOW CREATE TABLE resume_info; -``` - -## 📝 完整建表SQL(参考) - -```sql -CREATE TABLE `resume_info` ( - `id` varchar(255) NOT NULL, - `sn_code` varchar(50) NOT NULL DEFAULT '' COMMENT '设备SN码', - `account_id` varchar(50) NOT NULL DEFAULT '' COMMENT '用户ID', - `platform` varchar(20) NOT NULL DEFAULT 'boss' COMMENT '平台', - `fullName` varchar(50) DEFAULT '' COMMENT '姓名', - `gender` varchar(10) DEFAULT '' COMMENT '性别', - `age` int(11) DEFAULT 0 COMMENT '年龄', - `phone` varchar(20) DEFAULT '' COMMENT '电话', - `email` varchar(100) DEFAULT '' COMMENT '邮箱', - `location` varchar(100) DEFAULT '' COMMENT '所在地', - `education` varchar(50) DEFAULT '' COMMENT '学历', - `major` varchar(100) DEFAULT '' COMMENT '专业', - `school` varchar(200) DEFAULT '' COMMENT '毕业院校', - `graduationYear` int(11) DEFAULT 0 COMMENT '毕业年份', - `workYears` varchar(50) DEFAULT '' COMMENT '工作年限', - `currentPosition` varchar(100) DEFAULT '' COMMENT '当前职位', - `currentCompany` varchar(200) DEFAULT '' COMMENT '当前公司', - `currentSalary` varchar(50) DEFAULT '' COMMENT '当前薪资', - `expectedPosition` varchar(100) DEFAULT '' COMMENT '期望职位', - `expectedSalary` varchar(50) DEFAULT '' COMMENT '期望薪资', - `expectedLocation` varchar(100) DEFAULT '' COMMENT '期望地点', - `expectedIndustry` varchar(100) DEFAULT '' COMMENT '期望行业', - `skills` text COMMENT '技能标签(JSON)', - `skillDescription` text COMMENT '技能描述', - `certifications` text COMMENT '证书资质(JSON)', - `projectExperience` text COMMENT '项目经验(JSON)', - `workExperience` text COMMENT '工作经历(JSON)', - `aiSkillTags` text COMMENT 'AI技能标签(JSON)', - `aiStrengths` text COMMENT 'AI优势分析', - `aiWeaknesses` text COMMENT 'AI劣势分析', - `aiCareerSuggestion` text COMMENT 'AI职业建议', - `aiCompetitiveness` int(11) DEFAULT 0 COMMENT 'AI竞争力评分', - `resumeContent` text COMMENT '简历内容', - `originalData` text COMMENT '原始数据(JSON)', - `isActive` tinyint(1) DEFAULT 1 COMMENT '是否活跃', - `isPublic` tinyint(1) DEFAULT 1 COMMENT '是否公开', - `syncTime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '同步时间', - PRIMARY KEY (`id`), - KEY `idx_sn_code` (`sn_code`), - KEY `idx_platform` (`platform`), - KEY `idx_isActive` (`isActive`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='简历信息表'; -``` - -## ✅ 验证修复 - -修复后,运行以下代码验证: - -```javascript -const db = require('./api/middleware/dbProxy'); -const resume_info = db.getModel('resume_info'); - -// 测试创建记录 -const testResume = await resume_info.create({ - id: 'test-uuid-123', - sn_code: 'TEST001', - account_id: 'user123', - platform: 'boss', - fullName: '测试用户', - isActive: true -}); - -console.log('✅ 创建成功:', testResume.id); -``` - -## 🚀 下一步 - -表结构同步完成后,就可以正常使用简历存储功能了: - -```javascript -const jobManager = require('./api/middleware/job/jobManager'); - -const resumeData = await jobManager.get_online_resume( - 'GHJU', - mqttClient, - { platform: 'boss' } -); -``` - diff --git a/_doc/文件清理总结.md b/_doc/文件清理总结.md deleted file mode 100644 index d10490c..0000000 --- a/_doc/文件清理总结.md +++ /dev/null @@ -1,57 +0,0 @@ -# 文件清理总结 - -## ✅ 已删除的文件 - -### 1. 废弃的服务文件 -- ✅ `api/services/task_scheduler.js` - - **删除原因**:未使用,实际系统使用 `middleware/schedule/` 中的调度系统 - - **替代方案**:使用 `middleware/schedule/index.js` 中的 `ScheduleManager` - -### 2. 已合并的服务文件 -- ✅ `api/services/job_service.js` - - **删除原因**:只有一个方法,已合并到 `middleware/job/jobManager.js` - - **新位置**:`middleware/job/jobManager.js` → `job_greet()` 方法 - -### 3. 重命名的文件 -- ✅ `api/services/ossTool.js` → `api/services/oss_tool_service.js` - - **原因**:统一命名规范 - -## 🔧 已清理的引用 - -### services/index.js -- ✅ 移除了对 `TaskScheduler` 的引用(已删除) -- ✅ 移除了对 `MQTTHandler` 的引用(文件不存在) -- ✅ 移除了对 `JobService` 的引用(已合并) -- ✅ 移除了相关的初始化代码和监听器设置 -- ✅ 保留了 `AIService` 和 `PlaAccountService` 的引用 - -## 📋 当前 services/ 目录结构 - -``` -api/services/ -├── index.js # 服务管理器(已清理) -├── ai_service.js # AI服务 -├── pla_account_service.js # 账号服务 -└── oss_tool_service.js # OSS服务(已重命名) -``` - -## ⚠️ 注意事项 - -1. **调度系统** - - 实际使用:`middleware/schedule/index.js` (ScheduleManager) - - 不要使用:`services/task_scheduler.js`(已删除) - -2. **MQTT管理** - - 实际使用:`middleware/mqtt/mqttManager.js` - - 不要使用:`services/mqtt_handler.js`(文件不存在) - -3. **工作管理** - - 实际使用:`middleware/job/jobManager.js` - - 包含 `job_greet` 方法(原 `job_service.js` 的方法) - -## 🎯 清理效果 - -- **减少文件数量**:删除了2个不需要的文件 -- **代码更清晰**:移除了无效引用 -- **结构更合理**:services 目录只保留实际使用的服务 - diff --git a/_doc/服务合并完成说明.md b/_doc/服务合并完成说明.md deleted file mode 100644 index e8a41a7..0000000 --- a/_doc/服务合并完成说明.md +++ /dev/null @@ -1,54 +0,0 @@ -# 服务合并完成说明 - -## ✅ 已完成 - -### 1. job_service.js 合并 -- ✅ 将 `job_service.js` 的 `jobGreet` 方法合并到 `jobManager.js` -- ✅ 方法重命名为 `job_greet`(统一使用下划线命名) -- ✅ 更新了 `api/controller_admin/job_postings.js` 中的引用 -- ✅ 更新了 `api/services/index.js`,移除了 `JobService` 的引用 -- ✅ 删除了 `job_service.js` 文件 - -### 2. 方法改进 -- ✅ `job_greet` 方法支持可选的 `mqttClient` 参数 -- ✅ 修复了 `getResumeAnalysis` 方法的 `mqttClient` 参数问题 - -## 📝 变更详情 - -### 方法位置变更 -- **原位置**:`api/services/job_service.js` → `JobService.jobGreet()` -- **新位置**:`api/middleware/job/jobManager.js` → `JobManager.job_greet()` - -### 方法签名变更 -```javascript -// 旧方法 -async jobGreet(params) { - // ... -} - -// 新方法 -async job_greet(params) { - const { sn_code, encryptJobId, securityId, brandName, platform = 'boss', mqttClient } = params; - // 支持可选的 mqttClient 参数 - // ... -} -``` - -### 引用更新 -- `api/controller_admin/job_postings.js` - - `jobService.jobGreet()` → `jobManager.job_greet()` - -## 🎯 优势 - -1. **代码更集中**:所有工作管理相关的方法都在 `jobManager.js` 中 -2. **减少文件数量**:删除了只有一个方法的服务文件 -3. **命名统一**:使用下划线命名 `job_greet`,与其他方法一致 -4. **更好的复用性**:支持可选的 `mqttClient` 参数 - -## 📋 后续工作 - -继续完成命名规范统一: -- 移动并重命名 `middleware/job/` 下的文件到 `services/` -- 合并AI服务 -- 统一类命名 - diff --git a/_doc/服务端升级功能逻辑说明.md b/_doc/服务端升级功能逻辑说明.md deleted file mode 100644 index fe1e4fc..0000000 --- a/_doc/服务端升级功能逻辑说明.md +++ /dev/null @@ -1,320 +0,0 @@ -# 服务端升级功能逻辑说明 - -## 概述 - -本文档说明服务端需要实现的升级功能逻辑,配合客户端的自动升级功能。 - -## API 接口要求 - -### GET /version/check - -**功能**:检查是否有新版本可用 - -**请求参数**(Query 参数): -- `current_version`: 当前版本号(x.y.z 格式,如 "1.0.0") -- `platform`: 平台类型(如 "win32", "darwin", "linux") -- `arch`: 架构类型(如 "x64", "ia32", "arm64") -- `sn_code`: 设备序列号(可选,用于权限控制) - -**响应格式**: -```json -{ - "code": 0, - "message": "success", - "data": { - "version": "1.1.0", - "download_url": "http://work.light120.com/downloads/app-1.1.0.exe", - "release_notes": "修复了一些bug,新增了xxx功能", - "force_update": false, - "file_size": 52428800, - "file_hash": "abc123def456..." - } -} -``` - -**字段说明**: -- `version`: 最新版本号(x.y.z 格式) -- `download_url`: 更新包下载地址(完整的 HTTP/HTTPS URL) -- `release_notes`: 更新日志(可选,字符串) -- `force_update`: 是否强制更新(可选,布尔值,默认 false) -- `file_size`: 文件大小(字节,可选) -- `file_hash`: 文件 SHA256 哈希值(可选,用于校验文件完整性) - -**业务逻辑**: - -1. **版本比较**: - - 从数据库查询最新版本信息(根据 platform 和 arch) - - 比较请求中的 `current_version` 与数据库中的最新版本 - - 如果最新版本 > 当前版本,返回更新信息 - - 如果版本相同或更旧,返回 `code: 0, data: null` 或提示"已是最新版本" - -2. **版本号格式**: - - 格式:x.y.z(如 1.0.0, 1.1.0, 2.0.0) - - 比较规则:主版本号 > 次版本号 > 修订号 - - 示例:1.1.0 > 1.0.0, 2.0.0 > 1.9.9 - -3. **平台和架构过滤**: - - 只返回匹配 platform 和 arch 的版本信息 - - 如果某个平台没有新版本,返回空结果 - -4. **序列号验证**(可选): - - 可以根据 sn_code 验证设备权限 - - 如果启用权限控制,未授权的设备返回错误 - -5. **错误处理**: - - 参数缺失:返回 `code: 400, message: "参数错误"` - - 服务器错误:返回 `code: 500, message: "服务器错误"` - - 无新版本:返回 `code: 0, data: null` 或 `has_update: false` - -## 数据库设计建议 - -### 版本信息表(version_info) - -| 字段名 | 类型 | 说明 | 约束 | -|--------|------|------|------| -| id | INT/BIGINT | 主键 | PRIMARY KEY, AUTO_INCREMENT | -| version | VARCHAR(20) | 版本号(x.y.z 格式) | NOT NULL, UNIQUE | -| platform | VARCHAR(20) | 平台类型(win32/darwin/linux) | NOT NULL | -| arch | VARCHAR(20) | 架构类型(x64/ia32/arm64) | NOT NULL | -| download_url | VARCHAR(500) | 下载地址 | NOT NULL | -| file_path | VARCHAR(500) | 服务器文件路径 | NOT NULL | -| file_size | BIGINT | 文件大小(字节) | DEFAULT 0 | -| file_hash | VARCHAR(64) | SHA256 哈希值 | | -| release_notes | TEXT | 更新日志 | | -| force_update | TINYINT(1) | 是否强制更新 | DEFAULT 0 | -| status | TINYINT(1) | 状态(1:启用 0:禁用) | DEFAULT 1 | -| create_time | DATETIME | 创建时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP | -| last_modify_time | DATETIME | 最后修改时间 | NOT NULL, DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | - -**索引建议**: -- PRIMARY KEY (id) -- UNIQUE KEY (version, platform, arch) -- INDEX (platform, arch, status) - -### 版本发布历史表(version_history)(可选) - -用于记录版本发布历史,便于管理: - -| 字段名 | 类型 | 说明 | -|--------|------|------| -| id | INT/BIGINT | 主键 | -| version_id | INT | 关联 version_info.id | -| release_type | VARCHAR(20) | 发布类型(stable/beta/alpha) | -| create_time | DATETIME | 发布时间 | -| last_modify_time | DATETIME | 最后修改时间 | - -## 业务逻辑流程 - -### 1. 版本检查流程 - -``` -客户端请求 - ↓ -接收参数(current_version, platform, arch, sn_code) - ↓ -验证参数有效性 - ↓ -查询数据库最新版本(按 platform + arch + status=1) - ↓ -版本号比较 - ↓ -有更新? - ├─ 是 → 构建返回数据(包含文件信息) - └─ 否 → 返回空结果或提示"已是最新版本" - ↓ -返回响应 -``` - -### 2. 版本管理流程 - -**新增版本**: -1. 上传安装包文件到服务器指定目录 -2. 计算文件 SHA256 哈希值 -3. 获取文件大小 -4. 插入数据库记录(status=1 表示启用) - -**禁用版本**: -1. 更新 status=0(不删除记录,保留历史) - -**删除版本**: -1. 删除数据库记录 -2. 删除服务器上的文件 - -### 3. 文件存储建议 - -**目录结构**: -``` -/uploads/ - └── versions/ - ├── win32/ - │ ├── x64/ - │ │ ├── app-1.0.0.exe - │ │ └── app-1.1.0.exe - │ └── ia32/ - └── darwin/ - └── x64/ - └── app-1.1.0.dmg -``` - -**文件命名规则**: -- 格式:`app-{version}.{ext}` -- 示例:`app-1.1.0.exe`, `app-1.1.0.dmg` - -**下载 URL 生成**: -- 基础 URL:`http://work.light120.com/downloads/` -- 完整 URL:`http://work.light120.com/downloads/app-1.1.0.exe` - -## 关键逻辑说明 - -### 1. 版本号比较逻辑 - -**字符串比较规则**: -- 将版本号按 "." 分割成数组:["1", "1", "0"] -- 逐位比较数字大小 -- 主版本号优先级最高,依次递减 - -**示例**: -```javascript -// 伪代码 -compareVersion("1.1.0", "1.0.0") → true // 1.1.0 > 1.0.0 -compareVersion("2.0.0", "1.9.9") → true // 2.0.0 > 1.9.9 -compareVersion("1.0.0", "1.0.0") → false // 相等 -``` - -### 2. 文件哈希计算 - -**计算方法**: -- 使用 SHA256 算法 -- 读取文件内容,计算哈希值 -- 返回小写的十六进制字符串 - -**用途**: -- 客户端下载后校验文件完整性 -- 防止文件被篡改 -- 确保文件下载完整 - -### 3. 强制更新逻辑 - -**force_update 字段**: -- `true`: 强制更新,客户端必须更新才能使用 -- `false`: 可选更新,客户端可以选择稍后更新 - -**业务场景**: -- 安全漏洞修复 → 强制更新 -- 重大功能更新 → 强制更新 -- 小版本更新 → 可选更新 - -### 4. 平台和架构支持 - -**支持列表**: -- Windows: `win32` + `x64` / `ia32` -- macOS: `darwin` + `x64` / `arm64` -- Linux: `linux` + `x64` / `arm64` - -**查询逻辑**: -- 必须同时匹配 platform 和 arch -- 如果某个组合没有版本,返回空结果 - -## 安全考虑 - -### 1. 文件下载安全 - -- **HTTPS 下载**:优先使用 HTTPS 协议 -- **文件校验**:提供 SHA256 哈希值供客户端校验 -- **文件大小验证**:返回文件大小,客户端可以验证下载完整性 - -### 2. 权限控制 - -- **序列号验证**:可以根据 sn_code 控制哪些设备可以更新 -- **版本状态**:使用 status 字段控制版本是否可用 -- **IP 限制**:可以限制下载 IP 范围(可选) - -### 3. 防止恶意更新 - -- **文件类型验证**:只允许上传 .exe、.dmg、.AppImage 等安装包 -- **文件大小限制**:设置最大文件大小限制 -- **版本号验证**:验证版本号格式是否正确 - -## 返回状态码说明 - -| code | 说明 | 处理方式 | -|------|------|----------| -| 0 | 成功 | 检查 data 是否为空判断是否有更新 | -| 400 | 参数错误 | 客户端提示参数错误 | -| 401 | 未授权 | 客户端提示未授权 | -| 404 | 未找到版本 | 客户端提示版本不存在 | -| 500 | 服务器错误 | 客户端提示服务器错误,稍后重试 | - -## 示例场景 - -### 场景1:有新版本 - -**请求**: -``` -GET /version/check?current_version=1.0.0&platform=win32&arch=x64&sn_code=GHJU -``` - -**响应**: -```json -{ - "code": 0, - "message": "success", - "data": { - "version": "1.1.0", - "download_url": "http://work.light120.com/downloads/app-1.1.0.exe", - "release_notes": "1. 修复了登录问题\n2. 新增自动升级功能", - "force_update": false, - "file_size": 52428800, - "file_hash": "a1b2c3d4e5f6..." - } -} -``` - -### 场景2:已是最新版本 - -**请求**: -``` -GET /version/check?current_version=1.1.0&platform=win32&arch=x64&sn_code=GHJU -``` - -**响应**: -```json -{ - "code": 0, - "message": "已是最新版本", - "data": null -} -``` - -### 场景3:参数错误 - -**请求**: -``` -GET /version/check?current_version=1.0.0 -``` - -**响应**: -```json -{ - "code": 400, - "message": "缺少必要参数:platform, arch", - "data": null -} -``` - -## 注意事项 - -1. **日期字段命名**:统一使用 `create_time` 和 `last_modify_time` -2. **版本号格式**:严格按照 x.y.z 格式,便于版本比较 -3. **文件存储**:建议使用 CDN 或静态文件服务器,提高下载速度 -4. **日志记录**:记录版本检查请求,便于统计和分析 -5. **缓存策略**:可以考虑缓存最新版本信息,减少数据库查询 -6. **灰度发布**:可以通过 sn_code 控制部分设备先更新(可选) - -## 实现优先级 - -1. **基础功能**:版本检查、版本比较、返回下载信息 -2. **文件管理**:文件上传、文件存储、哈希计算 -3. **安全功能**:文件校验、权限控制 -4. **管理功能**:版本管理后台、历史记录 - diff --git a/_doc/目录整理执行计划.md b/_doc/目录整理执行计划.md deleted file mode 100644 index 4ed64fd..0000000 --- a/_doc/目录整理执行计划.md +++ /dev/null @@ -1,26 +0,0 @@ -# 目录整理执行计划 - -## 📋 整理步骤 - -### 第一步:合并AI服务 -- 将 `middleware/job/aiService.js` 的功能合并到 `services/ai_service.js` -- 保留更完整的功能(middleware/job/aiService.js 功能更全) -- 删除 `middleware/job/aiService.js` - -### 第二步:移动业务服务 -- `middleware/job/jobManager.js` → `services/job_manager_service.js` -- `middleware/job/chatManager.js` → `services/chat_manager_service.js` -- `middleware/job/resumeManager.js` → `services/resume_manager_service.js` - -### 第三步:更新引用 -- 更新 `command.js` 中的引用 -- 更新所有其他文件中的引用 - -### 第四步:处理废弃文件 -- `services/task_scheduler.js` 标记为废弃(添加注释说明) - -## ⚠️ 注意事项 - -- 更新所有 require 路径 -- 测试确保功能正常 - diff --git a/_doc/目录结构整理方案.md b/_doc/目录结构整理方案.md deleted file mode 100644 index 54fa35f..0000000 --- a/_doc/目录结构整理方案.md +++ /dev/null @@ -1,60 +0,0 @@ -# 目录结构整理方案 - -## 📋 职责划分 - -### services/ - 业务服务层 -**职责**:对外提供业务逻辑服务,处理业务相关的操作 -- 职位服务(job_service.js) -- 账号服务(pla_account_service.js) -- AI服务(ai_service.js) -- OSS服务(ossTool.js) -- 工作管理服务(jobManager.js) -- 聊天管理服务(chatManager.js) -- 简历管理服务(resumeManager.js) - -### middleware/ - 中间件层 -**职责**:系统级功能,基础设施服务 -- 调度系统(schedule/) -- MQTT通信(mqtt/) -- 数据库代理(dbProxy.js) -- 日志代理(logProxy.js) - -## 🔄 需要移动的文件 - -### 1. 从 middleware/job/ 移到 services/ -- `jobManager.js` → `services/job_manager_service.js` -- `chatManager.js` → `services/chat_manager_service.js` -- `resumeManager.js` → `services/resume_manager_service.js` - -### 2. 合并重复的AI服务 -- `middleware/job/aiService.js` 和 `services/ai_service.js` 合并 -- 保留 `services/ai_service.js`,删除 `middleware/job/aiService.js` - -### 3. 处理未使用的文件 -- `services/task_scheduler.js` - 标记为废弃或删除(实际未使用) - -## 📁 整理后的目录结构 - -``` -api/ -├── services/ # 业务服务层 -│ ├── index.js # 服务管理器 -│ ├── ai_service.js # AI服务(合并后) -│ ├── job_service.js # 职位服务 -│ ├── pla_account_service.js # 账号服务 -│ ├── ossTool.js # OSS服务 -│ ├── job_manager_service.js # 工作管理服务(从middleware/job/移入) -│ ├── chat_manager_service.js # 聊天管理服务(从middleware/job/移入) -│ └── resume_manager_service.js # 简历管理服务(从middleware/job/移入) -│ -└── middleware/ # 中间件层 - ├── schedule/ # 调度系统 - │ ├── index.js - │ ├── taskQueue.js - │ ├── command.js - │ └── ... - ├── mqtt/ # MQTT通信 - ├── dbProxy.js # 数据库代理 - └── logProxy.js # 日志代理 -``` - diff --git a/_doc/简历功能使用前置条件.md b/_doc/简历功能使用前置条件.md deleted file mode 100644 index 13b216b..0000000 --- a/_doc/简历功能使用前置条件.md +++ /dev/null @@ -1,239 +0,0 @@ -# 简历存储功能 - 前置条件和使用说明 - -## ⚠️ 重要前置条件 - -在使用简历存储功能之前,必须确保以下条件已满足: - -### 1. 数据库表已创建 - -#### ✅ `pla_account` 表(平台账户表) - -此表存储设备与平台账户的绑定关系,**必须先有记录**才能存储简历。 - -**表结构**: -```sql -CREATE TABLE `pla_account` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID', - `name` varchar(50) NOT NULL DEFAULT '' COMMENT '账户名', - `sn_code` varchar(50) NOT NULL DEFAULT '' COMMENT '设备SN码', - `platform_type` varchar(50) NOT NULL DEFAULT '' COMMENT '平台类型(boss/liepin)', - `login_name` varchar(50) NOT NULL DEFAULT '' COMMENT '登录名', - `pwd` varchar(50) NOT NULL DEFAULT '' COMMENT '密码', - `keyword` varchar(50) NOT NULL DEFAULT '' COMMENT '关键词', - `search_url` varchar(50) NOT NULL DEFAULT '' COMMENT '搜索页网址', - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -``` - -**示例数据**: -```sql -INSERT INTO `pla_account` (`name`, `sn_code`, `platform_type`, `login_name`, `pwd`) -VALUES ('张三的Boss账号', 'GHJU', 'boss', '13800138000', 'password123'); -``` - -#### ✅ `resume_info` 表(简历信息表) - -此表存储简历详细信息,会自动创建(通过 Sequelize sync)。 - -**关键字段**: -- `id` - 简历UUID(主键) -- `sn_code` - 设备SN码(关联设备) -- `account_id` - 账户ID(**关联 pla_account.id**) -- `platform` - 平台类型(boss/liepin) - -### 2. 数据关联关系 - -``` -┌─────────────────┐ ┌──────────────────┐ -│ pla_account │ │ resume_info │ -├─────────────────┤ ├──────────────────┤ -│ id (自增) │◄────────│ account_id │ -│ sn_code │ │ sn_code │ -│ platform_type │ │ platform │ -│ login_name │ │ fullName │ -│ pwd │ │ ... │ -└─────────────────┘ └──────────────────┘ -``` - -**查询逻辑**: -1. 通过 `sn_code` + `platform` 查询 `pla_account` 表 -2. 获取 `pla_account.id` 作为 `account_id` -3. 将 `account_id` 存入 `resume_info` 表 - -### 3. 环境配置 - -#### 数据库连接 -确保数据库连接配置正确(`config/config.js`) - -#### AI服务配置(可选) -如需AI分析功能,需配置 DeepSeek API: - -```env -DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxx -DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions -DEEPSEEK_MODEL=deepseek-chat -``` - -## 🚀 使用流程 - -### 步骤1: 创建平台账户记录 - -在调用简历存储功能之前,必须先在 `pla_account` 表中创建账户记录: - -```javascript -const db = require('./api/middleware/dbProxy'); -const pla_account = db.getModel('pla_account'); - -// 创建账户记录 -await pla_account.create({ - name: '张三的Boss账号', - sn_code: 'GHJU', - platform_type: 'boss', - login_name: '13800138000', - pwd: 'password123', - keyword: '前端工程师', - search_url: 'https://www.zhipin.com/web/geek/job' -}); -``` - -### 步骤2: 同步数据库表结构 - -运行同步脚本确保表结构正确: - -```bash -node scripts/sync_resume_table.js -``` - -### 步骤3: 调用简历存储功能 - -```javascript -const jobManager = require('./api/middleware/job/jobManager'); - -// 获取在线简历(自动存储) -const resumeData = await jobManager.get_online_resume( - 'GHJU', // 设备SN码(必须在 pla_account 中存在) - mqttClient, // MQTT客户端 - { platform: 'boss' } // 平台类型(必须与 pla_account.platform_type 匹配) -); -``` - -## ❌ 常见错误 - -### 错误1: "未找到设备 GHJU 在平台 boss 的账户信息" - -**原因**: `pla_account` 表中没有对应的记录 - -**解决方案**: -```javascript -// 检查是否存在账户记录 -const account = await pla_account.findOne({ - where: { sn_code: 'GHJU', platform_type: 'boss' } -}); - -if (!account) { - // 创建账户记录 - await pla_account.create({ - name: '账户名称', - sn_code: 'GHJU', - platform_type: 'boss', - login_name: '登录名', - pwd: '密码' - }); -} -``` - -### 错误2: "Unknown column 'sn_code' in 'field list'" - -**原因**: 数据库表结构未同步 - -**解决方案**: -```bash -# 运行同步脚本 -node scripts/sync_resume_table.js - -# 或手动执行SQL -ALTER TABLE `resume_info` -ADD COLUMN `sn_code` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '设备SN码', -ADD COLUMN `account_id` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户ID'; -``` - -### 错误3: "account_id 不能为空" - -**原因**: `pla_account` 查询失败或返回 null - -**解决方案**: -1. 确认 `sn_code` 和 `platform_type` 匹配 -2. 检查 `pla_account` 表中是否有对应记录 -3. 确认 `platform` 参数正确('boss' 不是 'Boss') - -## ✅ 验证清单 - -使用简历存储功能前,请确认: - -- [ ] `pla_account` 表已创建 -- [ ] `pla_account` 表中有对应设备的记录 -- [ ] `sn_code` 和 `platform_type` 匹配 -- [ ] `resume_info` 表已创建 -- [ ] `resume_info` 表包含 `sn_code` 和 `account_id` 字段 -- [ ] 数据库连接正常 -- [ ] MQTT 客户端可用 -- [ ] (可选)DeepSeek API 配置正确 - -## 📝 完整示例 - -```javascript -const db = require('./api/middleware/dbProxy'); -const jobManager = require('./api/middleware/job/jobManager'); - -async function setupAndGetResume() { - const pla_account = db.getModel('pla_account'); - - // 1. 检查或创建账户记录 - let account = await pla_account.findOne({ - where: { sn_code: 'GHJU', platform_type: 'boss' } - }); - - if (!account) { - console.log('创建账户记录...'); - account = await pla_account.create({ - name: '测试账号', - sn_code: 'GHJU', - platform_type: 'boss', - login_name: '13800138000', - pwd: 'password123' - }); - console.log('账户创建成功,ID:', account.id); - } else { - console.log('账户已存在,ID:', account.id); - } - - // 2. 获取简历(自动存储) - console.log('获取在线简历...'); - const resumeData = await jobManager.get_online_resume( - 'GHJU', - mqttClient, - { platform: 'boss' } - ); - - console.log('简历获取成功!'); - console.log('姓名:', resumeData.baseInfo?.name); - - // 3. 验证存储结果 - const resume_info = db.getModel('resume_info'); - const savedResume = await resume_info.findOne({ - where: { sn_code: 'GHJU', platform: 'boss', isActive: true } - }); - - console.log('简历已保存,ID:', savedResume.id); - console.log('关联账户ID:', savedResume.account_id); - console.log('竞争力评分:', savedResume.aiCompetitiveness); -} -``` - -## 🔗 相关文档 - -- 详细功能说明: `_doc/简历存储和分析功能说明.md` -- 数据库同步指南: `_doc/数据库表同步指南.md` -- 快速参考: `_doc/简历功能快速参考.md` -- 示例代码: `examples/resume_storage_example.js` - diff --git a/_doc/简历功能实现总结.md b/_doc/简历功能实现总结.md deleted file mode 100644 index a1dfa70..0000000 --- a/_doc/简历功能实现总结.md +++ /dev/null @@ -1,238 +0,0 @@ -# 简历存储和AI分析功能实现总结 - -## ✅ 已完成的工作 - -### 1. 核心功能实现 - -#### 📝 文件修改 -**文件**: `api/middleware/job/jobManager.js` - -**新增依赖**: -```javascript -const db = require('../dbProxy'); -const { v4: uuidv4 } = require('uuid'); -``` - -**新增/修改的方法**: - -1. **`get_online_resume(sn_code, mqttClient, params)`** ✅ - - 从MQTT获取在线简历数据 - - 自动调用存储方法保存到数据库 - - 支持平台参数配置(默认boss) - - 容错处理:存储失败不影响数据返回 - -2. **`saveResumeToDatabase(sn_code, platform, resumeData)`** ✅ 新增 - - 解析Boss直聘响应数据 - - 映射到resume_info模型字段 - - 自动提取技能标签 - - 处理项目经验和工作经历(JSON格式) - - 支持创建/更新简历(去重机制) - - 自动触发AI分析 - -3. **`extractSkillsFromDesc(description)`** ✅ 新增 - - 从简历描述中自动提取技能标签 - - 支持40+常见技术栈识别 - - 自动去重 - -4. **`analyzeResumeWithAI(resumeId, resumeInfo)`** ✅ 新增 - - 调用AI服务分析简历 - - 生成专业的分析提示词 - - 解析AI返回结果 - - 更新AI分析字段到数据库 - - 失败时使用默认分析 - -5. **`parseAIAnalysis(aiResponse, resumeInfo)`** ✅ 新增 - - 智能解析AI返回的JSON或文本格式 - - 支持中英文字段识别 - - 正则表达式提取关键信息 - - 容错处理 - -6. **`getDefaultAnalysis(resumeInfo)`** ✅ 新增 - - 基于规则的默认分析算法 - - 工作年限评分 - - 技能数量评分 - - 学历评分 - - 综合竞争力计算(0-100分) - -### 2. 数据映射实现 - -#### Boss直聘 → resume_info 字段映射 - -| 数据类型 | 映射字段数 | 状态 | -|---------|-----------|------| -| 基本信息 | 6个字段 | ✅ | -| 教育背景 | 4个字段 | ✅ | -| 工作经验 | 4个字段 | ✅ | -| 期望信息 | 4个字段 | ✅ | -| 技能专长 | 3个字段 | ✅ | -| 项目经验 | JSON数组 | ✅ | -| 工作经历 | JSON数组 | ✅ | -| AI分析 | 5个字段 | ✅ | -| 原始数据 | 完整JSON | ✅ | - -**总计**: 30+ 字段完整映射 - -### 3. AI分析功能 - -#### 分析维度 -- ✅ 技能标签提取(5-10个) -- ✅ 优势分析(100字以内) -- ✅ 劣势分析(100字以内) -- ✅ 职业建议(150字以内) -- ✅ 竞争力评分(0-100分) - -#### 评分算法 -``` -基础分: 50分 -+ 工作年限: 10年以上(+20) | 5-10年(+15) | 3-5年(+10) -+ 技能数量: 10个以上(+15) | 5-10个(+10) -+ 学历: 硕士(+10) | 本科(+5) -= 最终竞争力评分 (0-100) -``` - -### 4. 文档和示例 - -#### 📚 创建的文档 -1. **`_doc/简历存储和分析功能说明.md`** ✅ - - 功能概述 - - 数据映射表 - - 使用示例 - - 注意事项 - -2. **`_doc/简历功能实现总结.md`** ✅ - - 实现总结 - - 技术细节 - - 测试指南 - -#### 💻 创建的示例代码 -**`examples/resume_storage_example.js`** ✅ -- 示例1: 获取在线简历并自动存储 -- 示例2: 查询已存储的简历 -- 示例3: 查看简历的项目经验 -- 示例4: 统计简历数据 - -## 🎯 功能特性 - -### 核心特性 -- ✅ **自动存储**: 获取简历后自动保存到数据库 -- ✅ **智能去重**: 同设备同平台只保留一份活跃简历 -- ✅ **AI分析**: 自动调用AI服务进行简历分析 -- ✅ **容错处理**: 存储或分析失败不影响主流程 -- ✅ **完整数据**: 保留原始JSON数据便于追溯 -- ✅ **技能提取**: 自动识别40+常见技术栈 - -### 技术亮点 -- 🔹 使用UUID作为简历唯一标识 -- 🔹 JSON格式存储复杂数据(项目、工作经历) -- 🔹 智能解析AI返回的多种格式 -- 🔹 基于规则的默认分析作为降级方案 -- 🔹 完善的日志输出便于调试 - -## 📊 数据流程图 - -``` -┌─────────────┐ -│ MQTT请求 │ -│ get_online_ │ -│ resume │ -└──────┬──────┘ - │ - ▼ -┌─────────────┐ -│ 获取简历数据 │ -│ (Boss直聘) │ -└──────┬──────┘ - │ - ▼ -┌─────────────┐ -│ 解析数据 │ -│ 字段映射 │ -└──────┬──────┘ - │ - ▼ -┌─────────────┐ -│ 保存到数据库 │ -│ resume_info │ -└──────┬──────┘ - │ - ▼ -┌─────────────┐ -│ AI分析简历 │ -│ (DeepSeek) │ -└──────┬──────┘ - │ - ▼ -┌─────────────┐ -│ 更新AI字段 │ -│ 完成存储 │ -└─────────────┘ -``` - -## 🧪 测试建议 - -### 单元测试 -```bash -# 运行示例代码 -node examples/resume_storage_example.js -``` - -### 集成测试 -1. 确保数据库连接正常 -2. 确保MQTT服务可用 -3. 确保DeepSeek API配置正确 -4. 调用 `get_online_resume` 方法 -5. 检查数据库中的记录 -6. 验证AI分析字段 - -### 测试用例 -- ✅ 新简历创建 -- ✅ 已有简历更新 -- ✅ 技能标签提取 -- ✅ AI分析成功 -- ✅ AI分析失败降级 -- ✅ 数据库存储失败容错 - -## 🔧 配置要求 - -### 环境变量 -```env -# DeepSeek AI配置(用于简历分析) -DEEPSEEK_API_KEY=your_api_key_here -DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions -DEEPSEEK_MODEL=deepseek-chat -``` - -### 数据库 -- 表: `resume_info` -- 引擎: MySQL/MariaDB -- 字符集: UTF8MB4 - -## 📈 性能指标 - -- **数据获取**: ~2-5秒(取决于MQTT响应) -- **数据存储**: ~100-300ms -- **AI分析**: ~3-10秒(取决于API响应) -- **总耗时**: ~5-15秒 - -## 🚀 后续优化方向 - -1. **性能优化** - - 异步AI分析(不阻塞主流程) - - 批量处理多份简历 - - 缓存AI分析结果 - -2. **功能增强** - - 支持更多招聘平台 - - 简历版本管理 - - 简历对比功能 - - 导出PDF/Word - -3. **AI优化** - - 优化提示词模板 - - 增加更多分析维度 - - 训练专用模型 - -## ✨ 总结 - -本次实现完成了从在线简历获取、数据存储到AI智能分析的完整闭环,为自动化求职系统提供了坚实的数据基础。所有核心功能已实现并经过测试,可以投入使用。 - diff --git a/_doc/简历功能快速参考.md b/_doc/简历功能快速参考.md deleted file mode 100644 index 08e78ab..0000000 --- a/_doc/简历功能快速参考.md +++ /dev/null @@ -1,251 +0,0 @@ -# 简历存储和分析功能 - 快速参考 - -## 🚀 快速开始 - -### 1. 基本使用 - -```javascript -const jobManager = require('./api/middleware/job/jobManager'); - -// 获取在线简历(自动存储和分析) -const resumeData = await jobManager.get_online_resume( - 'GHJU', // 设备SN码 - mqttClient, // MQTT客户端 - { platform: 'boss' } // 平台(可选,默认boss) -); -``` - -### 2. 查询已存储的简历 - -```javascript -const db = require('./api/middleware/dbProxy'); -const resume_info = db.getModel('resume_info'); - -// 查询指定设备的简历 -const resume = await resume_info.findOne({ - where: { - sn_code: 'GHJU', - platform: 'boss', - isActive: true - } -}); - -console.log('姓名:', resume.fullName); -console.log('竞争力评分:', resume.aiCompetitiveness); -``` - -## 📋 主要字段说明 - -### 基本信息 -- `fullName` - 姓名 -- `gender` - 性别 -- `age` - 年龄 -- `phone` - 电话 -- `email` - 邮箱 - -### 工作信息 -- `workYears` - 工作年限 -- `currentPosition` - 当前职位 -- `currentCompany` - 当前公司 -- `expectedPosition` - 期望职位 -- `expectedSalary` - 期望薪资 - -### AI分析字段 -- `aiSkillTags` - AI提取的技能标签(JSON数组) -- `aiStrengths` - 优势分析 -- `aiWeaknesses` - 劣势分析 -- `aiCareerSuggestion` - 职业建议 -- `aiCompetitiveness` - 竞争力评分(0-100) - -### 复杂数据(JSON格式) -- `skills` - 技能标签数组 -- `projectExperience` - 项目经验数组 -- `workExperience` - 工作经历数组 -- `originalData` - 完整原始数据 - -## 🔍 常用查询示例 - -### 查询高竞争力简历 -```javascript -const highScoreResumes = await resume_info.findAll({ - where: { - aiCompetitiveness: { [db.models.op.gte]: 80 } - }, - order: [['aiCompetitiveness', 'DESC']] -}); -``` - -### 按技能搜索 -```javascript -const vueResumes = await resume_info.findAll({ - where: { - skills: { [db.models.op.like]: '%Vue%' } - } -}); -``` - -### 统计数据 -```javascript -// 总数 -const total = await resume_info.count(); - -// 按平台统计 -const bossCount = await resume_info.count({ - where: { platform: 'boss' } -}); - -// 平均竞争力 -const avgScore = await resume_info.findAll({ - attributes: [ - [db.models.sequelize.fn('AVG', - db.models.sequelize.col('aiCompetitiveness')), - 'avgScore'] - ] -}); -``` - -## 🎯 数据处理技巧 - -### 解析JSON字段 -```javascript -// 解析技能标签 -const skills = JSON.parse(resume.skills || '[]'); -console.log('技能:', skills.join(', ')); - -// 解析项目经验 -const projects = JSON.parse(resume.projectExperience || '[]'); -projects.forEach(p => { - console.log(`项目: ${p.name} - ${p.role}`); -}); - -// 解析工作经历 -const workExp = JSON.parse(resume.workExperience || '[]'); -workExp.forEach(w => { - console.log(`${w.company} - ${w.position}`); -}); -``` - -### 获取原始数据 -```javascript -const originalData = JSON.parse(resume.originalData); -console.log('完整Boss直聘数据:', originalData); -``` - -## ⚙️ 配置说明 - -### 环境变量(.env) -```env -# DeepSeek AI配置 -DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxx -DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions -DEEPSEEK_MODEL=deepseek-chat -``` - -### 数据库配置 -确保 `resume_info` 表已创建,字段定义参考: -`api/model/resume_info.js` - -## 🐛 常见问题 - -### Q1: 简历保存失败怎么办? -A: 系统有容错机制,保存失败不会影响数据返回。检查日志: -``` -[工作管理] 保存简历数据失败: [错误信息] -``` - -### Q2: AI分析失败怎么办? -A: 系统会自动使用基于规则的默认分析。检查: -- DeepSeek API配置是否正确 -- API密钥是否有效 -- 网络连接是否正常 - -### Q3: 如何更新已有简历? -A: 再次调用 `get_online_resume`,系统会自动检测并更新: -```javascript -// 同一设备同一平台会自动更新 -await jobManager.get_online_resume('GHJU', mqttClient); -``` - -### Q4: 如何查看详细日志? -A: 查看控制台输出: -``` -[工作管理] 开始获取设备 GHJU 的在线简历 -[工作管理] 成功获取简历数据 -[工作管理] 简历已创建/更新 - ID: xxx -[工作管理] AI分析完成 - 竞争力评分: 85 -``` - -## 📊 性能优化建议 - -### 1. 批量查询 -```javascript -// 使用 findAll 而不是多次 findOne -const resumes = await resume_info.findAll({ - where: { sn_code: { [db.models.op.in]: ['GHJU', 'ABCD'] } } -}); -``` - -### 2. 选择性字段 -```javascript -// 只查询需要的字段 -const resumes = await resume_info.findAll({ - attributes: ['id', 'fullName', 'aiCompetitiveness'], - where: { isActive: true } -}); -``` - -### 3. 分页查询 -```javascript -const resumes = await resume_info.findAndCountAll({ - limit: 20, - offset: 0, - order: [['aiCompetitiveness', 'DESC']] -}); -``` - -## 🔗 相关文档 - -- 详细说明: `_doc/简历存储和分析功能说明.md` -- 实现总结: `_doc/简历功能实现总结.md` -- 示例代码: `examples/resume_storage_example.js` -- 模型定义: `api/model/resume_info.js` -- 响应示例: `_doc/在线简历响应文本.json` - -## 💡 最佳实践 - -1. **总是检查返回值** -```javascript -const resume = await resume_info.findOne({...}); -if (resume) { - // 处理简历数据 -} -``` - -2. **安全解析JSON** -```javascript -try { - const skills = JSON.parse(resume.skills || '[]'); -} catch (e) { - console.error('解析失败:', e); -} -``` - -3. **使用事务处理批量操作** -```javascript -const t = await db.models.sequelize.transaction(); -try { - // 批量操作 - await t.commit(); -} catch (error) { - await t.rollback(); -} -``` - -4. **定期清理旧数据** -```javascript -// 删除非活跃简历 -await resume_info.destroy({ - where: { isActive: false } -}); -``` - diff --git a/_doc/简历存储和分析功能说明.md b/_doc/简历存储和分析功能说明.md deleted file mode 100644 index 4415915..0000000 --- a/_doc/简历存储和分析功能说明.md +++ /dev/null @@ -1,169 +0,0 @@ -# 简历存储和分析功能说明 - -## 📋 功能概述 - -本功能实现了从在线平台(Boss直聘)获取用户简历数据,并自动存储到数据库,同时使用AI进行智能分析的完整流程。 - -## 🔗 数据关联 - -- **`pla_account`** 表:存储平台账户信息(设备与平台的绑定关系) -- **`resume_info`** 表:存储简历详细信息 -- **关联关系**:`resume_info.account_id` = `pla_account.id`(自增ID) -- **查询逻辑**:通过 `sn_code` + `platform` 查询 `pla_account` 获取 `account_id` - -## 🔧 核心功能 - -### 1. 简历数据获取与存储 - -**位置**: `api/middleware/job/jobManager.js` - -**主要方法**: -- `get_online_resume(sn_code, mqttClient, params)` - 获取在线简历 -- `saveResumeToDatabase(sn_code, platform, resumeData)` - 保存简历到数据库 - -**数据流程**: -``` -MQTT请求 → 获取简历数据 → 解析数据 → 存储到resume_info表 → AI分析 → 更新AI分析字段 -``` - -### 2. 数据映射关系 - -#### 从Boss直聘响应到数据库字段的映射 - -| Boss直聘字段 | 数据库字段 | 说明 | -|-------------|-----------|------| -| `baseInfo.name` | `fullName` | 姓名 | -| `baseInfo.gender` | `gender` | 性别(1=男,0=女) | -| `baseInfo.age` | `age` | 年龄 | -| `baseInfo.account` | `phone` | 电话 | -| `baseInfo.emailBlur` | `email` | 邮箱 | -| `expectList[0].locationName` | `location` | 所在地 | -| `educationExpList[0].degreeName` | `education` | 学历 | -| `educationExpList[0].major` | `major` | 专业 | -| `educationExpList[0].school` | `school` | 毕业院校 | -| `educationExpList[0].endYear` | `graduationYear` | 毕业年份 | -| `baseInfo.workYearDesc` | `workYears` | 工作年限 | -| `workExpList[0].positionName` | `currentPosition` | 当前职位 | -| `workExpList[0].companyName` | `currentCompany` | 当前公司 | -| `expectList[0].positionName` | `expectedPosition` | 期望职位 | -| `expectList[0].salaryDesc` | `expectedSalary` | 期望薪资 | -| `expectList[0].locationName` | `expectedLocation` | 期望地点 | -| `expectList[0].industryDesc` | `expectedIndustry` | 期望行业 | -| `userDesc` | `skillDescription` | 技能描述 | -| `projectExpList` | `projectExperience` | 项目经验(JSON) | -| `workExpList` | `workExperience` | 工作经历(JSON) | - -### 3. AI智能分析 - -**分析维度**: -1. **技能标签提取** - 从简历描述中自动提取技术栈 -2. **优势分析** - 分析候选人的核心优势 -3. **劣势分析** - 指出需要改进的方面 -4. **职业建议** - 提供职业发展建议 -5. **竞争力评分** - 0-100分的综合评分 - -**评分规则**(默认分析): -- 基础分:50分 -- 工作年限:10年以上+20分,5-10年+15分,3-5年+10分 -- 技能数量:10个以上+15分,5-10个+10分 -- 学历:硕士+10分,本科+5分 - -### 4. 技能标签自动提取 - -系统会自动从简历描述中提取以下技能标签: - -**前端技术**: -- Vue, React, Angular, JavaScript, TypeScript -- Webpack, Vite, Redux, MobX -- jQuery, Bootstrap, Element UI, Ant Design - -**后端技术**: -- Node.js, Python, Java, C#, .NET -- Express, Koa, Django, Flask - -**数据库**: -- MySQL, MongoDB, Redis - -**其他技术**: -- WebRTC, FFmpeg, Canvas, WebSocket -- Git, Docker, Kubernetes, AWS, Azure -- Selenium, Jest, Mocha, Cypress - -## 📊 数据库表结构 - -**表名**: `resume_info` - -**主要字段**: -```sql -- id: 简历ID(UUID) -- sn_code: 设备SN码 -- platform: 平台(boss/liepin) -- fullName: 姓名 -- gender: 性别 -- age: 年龄 -- phone: 电话 -- email: 邮箱 -- education: 学历 -- workYears: 工作年限 -- expectedPosition: 期望职位 -- expectedSalary: 期望薪资 -- skills: 技能标签(JSON) -- projectExperience: 项目经验(JSON) -- workExperience: 工作经历(JSON) -- aiSkillTags: AI提取的技能标签(JSON) -- aiStrengths: AI分析的优势 -- aiWeaknesses: AI分析的劣势 -- aiCareerSuggestion: AI职业建议 -- aiCompetitiveness: AI竞争力评分 -- originalData: 原始数据(JSON) -- isActive: 是否活跃 -- syncTime: 同步时间 -``` - -## 🚀 使用示例 - -### 调用方式 - -```javascript -const jobManager = require('./api/middleware/job/jobManager'); - -// 获取在线简历(自动存储和分析) -const resumeData = await jobManager.get_online_resume( - 'GHJU', // 设备SN码 - mqttClient, // MQTT客户端实例 - { platform: 'boss' } // 参数(可选) -); -``` - -### 响应数据示例 - -参考文件: `_doc/在线简历响应文本.json` - -## 🔍 日志输出 - -系统会输出以下日志信息: - -``` -[工作管理] 开始获取设备 GHJU 的在线简历 -[工作管理] 成功获取简历数据: {...} -[工作管理] 简历已创建 - ID: xxx-xxx-xxx -[工作管理] 开始AI分析简历 - ID: xxx-xxx-xxx -[工作管理] AI分析完成 - 竞争力评分: 85 -[工作管理] 简历数据已保存到数据库 -``` - -## ⚠️ 注意事项 - -1. **数据安全**: 原始简历数据会完整保存在 `originalData` 字段中 -2. **去重机制**: 同一设备同一平台只保留一份活跃简历 -3. **容错处理**: 如果AI分析失败,会使用基于规则的默认分析 -4. **异步处理**: 简历保存失败不会影响数据返回 - -## 📝 后续优化建议 - -1. 增加更多平台支持(猎聘、拉勾等) -2. 优化AI提示词,提高分析准确度 -3. 添加简历版本管理功能 -4. 实现简历对比功能 -5. 增加简历导出功能(PDF、Word等) - diff --git a/_doc/聊天列表功能说明.md b/_doc/聊天列表功能说明.md deleted file mode 100644 index 9767055..0000000 --- a/_doc/聊天列表功能说明.md +++ /dev/null @@ -1,281 +0,0 @@ -# 聊天列表功能说明 - -## 功能概述 - -聊天列表模块实现了管理后台的实时聊天功能,包括: -- 会话列表展示 -- 实时消息收发 -- 消息历史记录 -- 轮询机制接收新消息 - -## 功能特性 - -### 1. 会话列表 -- **按会话分组**: 自动按照 `conversationId` 或 `jobId + sn_code` 组合进行分组 -- **最新消息展示**: 显示每个会话的最新一条消息 -- **未读消息标记**: 显示未读消息数量(开发中) -- **平台过滤**: 支持按 Boss直聘/猎聘 平台筛选 -- **搜索功能**: 支持按公司名称/职位名称搜索 - -### 2. 聊天窗口 -- **消息列表**: 按时间顺序展示所有聊天消息 -- **消息方向**: 区分发送和接收的消息,不同样式展示 -- **AI标记**: 显示AI生成的消息标记 -- **面试邀约**: 特殊样式展示面试邀约消息 -- **实时刷新**: 自动轮询获取新消息(默认5秒) - -### 3. 消息发送 -- **快速回复**: 输入框支持快速发送消息 -- **Enter发送**: 支持回车键发送消息 -- **发送状态**: 显示消息发送中的加载状态 -- **AI生成**: 预留AI消息生成功能接口(开发中) - -### 4. 定时刷新机制 -- **自动刷新**: 使用 setInterval 定时刷新消息 -- **可配置间隔**: 默认10秒,可自定义刷新间隔 -- **资源释放**: 页面销毁时自动清除定时器 -- **简单高效**: 使用Ajax轮询,无需WebSocket - -## 文件结构 - -``` -admin/src/ -├── views/chat/ -│ ├── chat_list.vue # 聊天列表页面(新增) -│ └── chat_records.vue # 聊天记录管理页面(原有) -├── api/operation/ -│ └── chat_records_server.js # 聊天API服务 -└── router/ - └── component-map.js # 路由组件映射 - -api/ -├── controller_admin/ -│ └── chat_records.js # 聊天记录后端控制器(已扩展) -└── model/ - └── chat_records.js # 聊天记录数据模型 -``` - -## API 接口 - -### 前端API服务 (chat_records_server.js) - -| 方法 | 说明 | 参数 | -|------|------|------| -| `page(param)` | 分页查询聊天记录 | seachOption, pageOption | -| `getByJobId(params)` | 获取指定职位的聊天记录 | jobId, sn_code | -| `sendMessage(data)` | 发送聊天消息 | sn_code, jobId, content, chatType, platform | -| `getUnreadCount(params)` | 获取未读消息数量 | sn_code | -| `markAsRead(data)` | 标记消息为已读 | chatId | -| `getStatistics()` | 获取聊天统计数据 | - | - -### 后端API接口 - -| 接口 | 方法 | 说明 | -|------|------|------| -| `/admin_api/chat/list` | POST | 获取聊天记录列表 | -| `/admin_api/chat/by-job` | GET | 获取指定职位的聊天记录 | -| `/admin_api/chat/send` | POST | 发送聊天消息 | -| `/admin_api/chat/unread-count` | GET | 获取未读消息数量 | -| `/admin_api/chat/mark-read` | POST | 标记消息为已读 | -| `/admin_api/chat/statistics` | GET | 获取聊天统计数据 | -| `/admin_api/chat/detail` | GET | 获取聊天记录详情 | -| `/admin_api/chat/delete` | POST | 删除聊天记录 | - -## 使用说明 - -### 1. 访问聊天列表页面 - -在后台菜单中添加聊天列表页面的路由配置: - -```javascript -{ - name: '聊天列表', - path: '/chat/chat_list', - component: 'chat/chat_list' -} -``` - -### 2. 查看会话列表 - -- 左侧显示所有会话列表 -- 每个会话显示公司名称、职位名称、最新消息和时间 -- 点击会话可在右侧查看完整的聊天记录 - -### 3. 发送消息 - -1. 在左侧选择一个会话 -2. 在右侧聊天窗口底部的输入框中输入消息 -3. 点击"发送"按钮或按回车键发送 -4. 消息发送成功后会自动刷新聊天记录 - -### 4. 筛选和搜索 - -- **平台筛选**: 在顶部选择 Boss直聘 或 猎聘 进行筛选 -- **关键词搜索**: 在搜索框输入公司名称或职位名称进行搜索 -- 筛选和搜索会实时更新会话列表 - -## 数据模型 - -### 聊天记录模型 (chat_records) - -主要字段: - -| 字段 | 类型 | 说明 | -|------|------|------| -| id | INTEGER | 主键ID | -| sn_code | STRING | 设备SN码 | -| platform | STRING | 平台(boss/liepin) | -| jobId | STRING | 职位ID | -| companyName | STRING | 公司名称 | -| jobTitle | STRING | 职位名称 | -| hrName | STRING | HR姓名 | -| content | TEXT | 消息内容 | -| direction | STRING | 消息方向(sent/received) | -| chatType | STRING | 聊天类型(greeting/reply/interview) | -| sendStatus | STRING | 发送状态(pending/sent/failed) | -| sendTime | DATE | 发送时间 | -| receiveTime | DATE | 接收时间 | -| hasReply | BOOLEAN | 是否有回复 | -| conversationId | STRING | 会话ID | -| isAiGenerated | BOOLEAN | 是否AI生成 | -| isInterviewInvitation | BOOLEAN | 是否面试邀约 | - -## 技术实现 - -### 1. 会话分组逻辑 - -```javascript -// 按 conversationId 或 jobId+sn_code 分组 -const convId = record.conversationId || `${record.jobId}_${record.sn_code}` -``` - -### 2. 定时刷新机制 - -```javascript -// 启动定时刷新 -startAutoRefresh() { - this.refreshTimer = setInterval(() => { - // 如果有选中的会话,刷新消息 - if (this.activeConversation) { - this.loadChatMessages() - } - // 刷新会话列表 - this.loadConversations() - }, this.refreshInterval) // 默认10秒 -} - -// 停止定时刷新 -stopAutoRefresh() { - if (this.refreshTimer) { - clearInterval(this.refreshTimer) - this.refreshTimer = null - } -} -``` - -### 3. 消息发送流程 - -1. 前端调用 `chatRecordsServer.sendMessage()` -2. 后端创建聊天记录,状态为 `pending` -3. 后端通过MQTT发送消息到设备(待实现) -4. 更新聊天记录状态为 `sent` -5. 前端刷新消息列表 - -## 待开发功能 - -### 1. 优化刷新机制(可选) -当前使用简单的定时刷新,如果需要更高的实时性,可以考虑: -- WebSocket实时推送(需要服务端支持) -- 长轮询(Long Polling) -- Server-Sent Events (SSE) -- 智能刷新间隔(根据活跃度动态调整) - -### 2. AI消息生成 -集成AI服务生成智能回复: -- 根据聊天上下文生成合适的回复 -- 支持不同的回复风格 -- 提高回复效率 - -### 3. 富文本消息 -支持更丰富的消息类型: -- 图片消息 -- 文件消息 -- 表情包 -- Markdown格式 - -### 4. 消息状态管理 -完善消息状态: -- 已读/未读状态 -- 消息撤回 -- 消息编辑 -- 消息引用回复 - -### 5. 会话管理 -增强会话管理功能: -- 会话置顶 -- 会话静音 -- 会话归档 -- 会话标签 - -## 注意事项 - -### 1. MQTT集成 -当前消息发送功能需要集成MQTT客户端才能真正发送到设备。在 `chat_records.js` 控制器中有TODO标记: - -```javascript -// TODO: 这里需要通过MQTT发送消息到设备 -// 目前先简单返回成功,实际需要集成MQTT客户端 -``` - -### 2. 数据同步 -- 刷新间隔不宜过短,避免服务器压力(建议10秒以上) -- 可根据实际需求调整刷新间隔 -- 考虑添加手动刷新按钮,让用户主动刷新 - -### 3. 性能优化 -- 会话列表分页加载 -- 消息列表虚拟滚动 -- 图片懒加载 -- 消息缓存机制 - -### 4. 安全性 -- 消息内容过滤和验证 -- 防止XSS攻击 -- 消息发送频率限制 -- 敏感信息加密 - -## 测试建议 - -### 1. 功能测试 -- 测试会话列表加载 -- 测试消息发送和接收 -- 测试筛选和搜索功能 -- 测试定时刷新机制 - -### 2. 边界测试 -- 测试空会话列表 -- 测试空消息列表 -- 测试网络异常情况 -- 测试大量消息加载 - -### 3. 性能测试 -- 测试大量会话的加载速度 -- 测试长时间运行的内存占用 -- 测试频繁切换会话的响应速度 - -## 更新日志 - -### v1.0.0 (2025-01-XX) -- ✅ 创建聊天列表页面 -- ✅ 实现会话分组和展示 -- ✅ 实现消息发送功能 -- ✅ 实现定时刷新接收新消息(Ajax轮询) -- ✅ 添加后端API接口 -- ✅ 支持平台筛选和搜索 - -### 计划中 -- ⏳ AI消息生成 -- ⏳ 富文本消息支持 -- ⏳ 完善消息状态管理 -- ⏳ 增强会话管理功能 -- ⏳ 优化刷新机制(WebSocket/长轮询等) diff --git a/_doc/聊天功能快速开始.md b/_doc/聊天功能快速开始.md deleted file mode 100644 index 099c49e..0000000 --- a/_doc/聊天功能快速开始.md +++ /dev/null @@ -1,151 +0,0 @@ -# 聊天功能快速开始 - -## 快速配置 - -### 1. 添加菜单路由 - -在后台管理系统的菜单配置中添加以下菜单项: - -```json -{ - "name": "聊天列表", - "path": "/chat/chat_list", - "component": "chat/chat_list", - "icon": "md-chatbubbles" -} -``` - -### 2. 启动项目 - -```bash -# 启动后端API服务 -cd api -npm install -npm start - -# 启动前端管理后台 -cd admin -npm install -npm run dev -``` - -### 3. 访问聊天列表 - -在浏览器中访问: `http://localhost:8080/#/chat/chat_list` - -## 功能演示 - -### 查看会话列表 -1. 左侧显示所有聊天会话 -2. 每个会话显示: - - 公司名称 - - 职位名称 - - 最新消息内容 - - 消息时间 - - 平台标签(Boss/猎聘) - -### 查看聊天记录 -1. 点击左侧的任意会话 -2. 右侧显示完整的聊天历史记录 -3. 消息按时间顺序排列 -4. 区分发送和接收的消息 - -### 发送消息 -1. 选择一个会话 -2. 在底部输入框输入消息 -3. 点击"发送"按钮或按回车键 -4. 消息发送成功后会自动刷新 - -### 筛选和搜索 -- **平台筛选**: 选择Boss直聘或猎聘 -- **关键词搜索**: 输入公司名称或职位名称 - -## API测试 - -### 测试获取聊天列表 - -```bash -curl -X POST http://localhost:3000/admin_api/chat/list \ - -H "Content-Type: application/json" \ - -d '{ - "page": 1, - "pageSize": 20 - }' -``` - -### 测试发送消息 - -```bash -curl -X POST http://localhost:3000/admin_api/chat/send \ - -H "Content-Type: application/json" \ - -d '{ - "sn_code": "GHJU", - "jobId": "12345", - "content": "您好,我对这个职位很感兴趣", - "platform": "boss", - "chatType": "reply" - }' -``` - -### 测试获取指定职位的聊天记录 - -```bash -curl -X GET "http://localhost:3000/admin_api/chat/by-job?jobId=12345&sn_code=GHJU" -``` - -## 常见问题 - -### 1. 页面显示空白? -- 检查API服务是否正常运行 -- 检查浏览器控制台是否有错误 -- 确认数据库中是否有聊天记录数据 - -### 2. 消息发送失败? -- 检查设备SN码是否正确 -- 检查职位ID是否存在 -- 查看后端日志确认错误原因 -- 注意: 当前MQTT集成待完成,消息会保存但不会真正发送到设备 - -### 3. 轮询不工作? -- 检查浏览器控制台是否有网络错误 -- 确认轮询定时器是否正常启动 -- 可以调整轮询间隔 (默认5秒) - -### 4. 会话列表为空? -- 检查筛选条件是否过于严格 -- 尝试清空搜索关键词 -- 确认数据库中有聊天记录 - -## 下一步 - -### 功能扩展 -- 集成MQTT实现真实消息发送 -- 添加WebSocket实现实时推送 -- 集成AI生成智能回复 -- 支持富文本和文件消息 - -### 性能优化 -- 实现消息虚拟滚动 -- 添加消息缓存机制 -- 优化大量会话的加载性能 - -### 用户体验 -- 添加消息已读状态 -- 支持消息撤回 -- 添加消息搜索功能 -- 支持会话置顶和归档 - -## 技术支持 - -如有问题,请查看: -- [聊天列表功能说明.md](./聊天列表功能说明.md) - 完整的功能文档 -- 项目代码中的注释 -- 后端API的Swagger文档 - -## 更新记录 - -- **2025-01-XX**: 初始版本发布 - - 实现基础聊天列表功能 - - 支持消息发送和接收 - - 添加轮询机制 - - 支持平台筛选和搜索 diff --git a/_doc/职位列表.json b/_doc/职位列表.json deleted file mode 100644 index a2b7170..0000000 --- a/_doc/职位列表.json +++ /dev/null @@ -1,4020 +0,0 @@ -[ - { - "url": "https://www.zhipin.com/wapi/zpgeek/pc/recommend/job/list.json?page=1&pageSize=15&city=101020100&encryptExpectId=&mixExpectType=&expectInfo=&jobType=&salary=&experience=°ree=&industry=&scale=&_=1763023191101", - "method": "GET", - "status": 200, - "data": { - "code": 0, - "message": "Success", - "zpData": { - "hasMore": true, - "jobList": [ - { - "securityId": "DMbfpwkFuyWJM-X1jRqsDTQIQFHssAfqW-Ygb5H9M1R5L2qz7ztIcinG7ZhjAF-CFftnrrnHBv8oCtYgH-YcZNvvccSRT1mhNGMe-6kDTrBMnDAULGu0glvhI83Gvje_z4pcywR8wXE9p0Lu5oNq-D-Qjh4c", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250113/607f1f3d68754fd0a0df0f2d30bbb5552b65cbf4c3df23d141ce3a8e2f80bf17206080dcc0a056de_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "437245c32896129f1XR-2ty9Elc~", - "bossName": "王先生", - "bossTitle": "HRD", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "05a5d92ae93bcbe103B839W0E1dQ", - "expectId": 1196299886, - "jobName": "全栈工程师", - "lid": "1hfcKRGLEBx.search.1", - "salaryDesc": "25-35K·13薪", - "jobLabels": [ - "10年以上", - "本科", - "全栈无侧重", - "JavaScript", - "HTML" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "全栈无侧重", - "JavaScript", - "HTML", - "Vue", - "React", - "计算机相关专业", - "全栈项目经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "徐汇区", - "businessDistrict": "漕河泾", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 1, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.400992, - "latitude": 31.170706 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "df2ff527436fe3381HB-3dW7E1Y~", - "brandName": "本原智数", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/workfeel/20240508/7bf6f160950405e90e22440f08f5454aa4e8f2f9a602bf48a721dd6624dee98ec17edcc98b7b36f9.png.webp", - "brandStageName": "不需要融资", - "brandIndustry": "人工智能", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100028, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "5uj026Ev_FG1V-C1qfj_hgaPWbdf6659V1QHMQ8rn9NEDqbF5OR5QG4pTpKTt1sJWhEdlBJei-8JXdpVG3C0jCAYIYclnCgvnlJKzvzRpkGZcrbwSvCOvnhw676La3wTFdqQnBHo8TTKapdggASd_Cp7aKXv", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20220720/607f1f3d68754fd092bf39bd396efe16aa3f2b014c1d1b8085b43ec85fd3532b58ba045faff365ef_s.png", - "bossCert": 3, - "encryptBossId": "dc5fa4cef624078803N42Ni7F1M~", - "bossName": "杨女士", - "bossTitle": "HR", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "377e1b725235f88703152Nm9EFFZ", - "expectId": 1196299886, - "jobName": "Java Full Stack-英语流利-上海浦东", - "lid": "1hfcKRGLEBx.search.2", - "salaryDesc": "18-28K", - "jobLabels": [ - "10年以上", - "大专", - "JavaScript", - "TypeScript", - "React" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "JavaScript", - "TypeScript", - "React", - "Java", - "英语流利" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "大专", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "陆家嘴", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 2, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.500461, - "latitude": 31.233978 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "2fc82baee8dcd8361XZ-29u_GFE~", - "brandName": "思堤克斯", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/workfeel/20220905/7bf6f160950405e9a932e6d4b283b6a4283135b28bd288c485b43ec85fd3532b58ba045faff365ef.jpg", - "brandStageName": "不需要融资", - "brandIndustry": "计算机软件", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100021, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "SuAd_RvKENaoO-F1pFupLOk9qCLT9VmncO8w-o4Qfm7LVPM0yi-BXSQMaSugRoU0og1aLkvDltjBy-M0uSs5xXXngBSF48X_KBILF2R9kKZPZ-HocjNgo80n", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20251009/607f1f3d68754fd067f3a20a30608d88bb870ea400f29d4b5a651d9d34a79d7cffbcb4a6bc36c002_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "a382dcfe4ef810140HZ92N61EFVR", - "bossName": "杨女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "76de02256a328d0303x93dW-GFFS", - "expectId": 1196299886, - "jobName": "[英文口语]首席/资深全栈开发", - "lid": "1hfcKRGLEBx.search.3", - "salaryDesc": "30-55K·15薪", - "jobLabels": [ - "10年以上", - "本科", - "Java", - "全栈侧重后端", - "全栈" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "Java", - "全栈侧重后端", - "全栈", - "英语读写能力良好", - "全栈项目经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 3, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.482326, - "latitude": 31.157313 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型生物/制药公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "不需要融资", - "brandIndustry": "生物/制药", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100401, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "-22fMwM3Pk9XA-L1sApf1o4Nzj3wIWNvMhe5LWljlqRUFmzjASYOH5MpIIviYuKjgr5VD1GcX_Y1D6zHMU4B1Xqo3z5pDbk_FQoiqnSHymWcaKAlUd66j4t_", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250812/607f1f3d68754fd069f1d56a0ba94de09237fc91ddabc869a3492ccd0138d8027ef1afdf02ef2ebd_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "55a3cb8842c7c5861XJ53d-5FFs~", - "bossName": "易女士", - "bossTitle": "经理", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "910d5309e3e37b4703J909u9FlVY", - "expectId": 1196299886, - "jobName": "全栈工程师(PHP)", - "lid": "1hfcKRGLEBx.search.4", - "salaryDesc": "15-21K", - "jobLabels": [ - "10年以上", - "本科", - "后端开发经验", - "Vue", - "PHP" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "后端开发经验", - "Vue", - "PHP", - "全栈侧重前端", - "计算机相关专业", - "前端开发经验", - "英语读写能力良好", - "全栈项目经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "普陀区", - "businessDistrict": "曹杨", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 4, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.420618, - "latitude": 31.241656 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "7ec68e6f58d02ce803d409-0EVE~", - "brandName": "上海聚亿宝网络技术", - "brandLogo": "https://img.bosszhipin.com/beijin/icon/894ce6fa7e58d64d57e7f22d2f3a9d18afa7fcceaa24b8ea28f56f1bb14732c0.png", - "brandStageName": "", - "brandIndustry": "计算机服务", - "brandScaleName": "0-20人", - "welfareList": [], - "industry": 100023, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "pbaV5sQ2KF7Gb-L1nFRbNKLoa8fGs9F-mEj_HU1LLoDNMNJg_V4JnS6riUTKdE3ORboP7wO-wGixKu1J_hfI7kn6WYLBoNYcDsO3Sm1y52C_kKfPHOkjD3TtRWfk9B-YzkXnLvEx-MgXtNVjgo4GWr8inFWx", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20211103/607f1f3d68754fd075797a9b701b17a8eb6435390eddefc5af74c09b8413a6ec2cd7a645cc382c5a_s.jpg", - "bossCert": 3, - "encryptBossId": "aa19849a95f4479803R73ty1FVQ~", - "bossName": "牛影", - "bossTitle": "招聘专家", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "20cd12f77ae92bb5031609-6ElBT", - "expectId": 1196299886, - "jobName": "AI芯片软件测试架构师", - "lid": "1hfcKRGLEBx.search.5", - "salaryDesc": "30-60K·16薪", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "张江", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 5, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.628425536085, - "latitude": 31.2090782008146 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "171fce07e7fa16fb1XVz2Ny5F1Q~", - "brandName": "亿铸智能", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/logo/20250715/7b5b554d84f9729c392e1471ba605452fffada42bb1b9c566bb61e3b7bce0931da574d19d1d82c88.jpg.webp", - "brandStageName": "天使轮", - "brandIndustry": "半导体/芯片", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 101405, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "X8oNXPzk2dLKr-R1Ko9veecPR99w4-SZVxfF4iRnpYHjMQcBS7EncQHcqVaQ2VMYI-vbjV_RI8Pk1vfOJy2nXvSQPuuyDXt2KHWAA7kWA61tqnkf7Li8JYzK", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20191013/b00a719f76d05a48bbe2a01648a231c9b251a55acefccada76cd6ae4787533c1_s.jpg", - "bossCert": 3, - "encryptBossId": "8376d253bdd816460Hx50926GFc~", - "bossName": "柴女士", - "bossTitle": "HR", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "7efec04c06c574be03N429i0FlpY", - "expectId": 1196299886, - "jobName": "医学经理", - "lid": "1hfcKRGLEBx.search.6", - "salaryDesc": "20-40K", - "jobLabels": [ - "10年以上", - "本科", - "抗肿瘤药物", - "KOL维护", - "医药相关专业" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "抗肿瘤药物", - "KOL维护", - "医药相关专业", - "临床工作经验", - "临床医学专业" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "普陀区", - "businessDistrict": "桃浦", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 6, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.334968, - "latitude": 31.288098 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "067b7fe4cb63124c1XJ_2t27GFQ~", - "brandName": "益世康宁", - "brandLogo": "https://img.bosszhipin.com/beijin/icon/894ce6fa7e58d64d57e7f22d2f3a9d18afa7fcceaa24b8ea28f56f1bb14732c0.png", - "brandStageName": "不需要融资", - "brandIndustry": "生物/制药", - "brandScaleName": "20-99人", - "welfareList": [], - "industry": 100401, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "4zDY9pcmBBaO9-q1PiIubHbmd4ots69SaKNpfSJVdOjB6YRd_cUCvQOUThDg9nZO8XtZKp9oHehDLdkvntbSvXx_wIrn4YNRusNMBJQrdPtKwv2ciBLa1c3A", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20211118/607f1f3d68754fd0527e48962f19998ade7de15f9f3141d9a7731af3c3194594b02b65e19093c32e_s.png", - "bossCert": 3, - "encryptBossId": "88241b9525387e901XN639m6FVs~", - "bossName": "杨贺强", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "b28267dc4230edad03x-2tm8GVVY", - "expectId": 1196299886, - "jobName": "子公司委派财务总监", - "lid": "1hfcKRGLEBx.search.7", - "salaryDesc": "30-50K·14薪", - "jobLabels": [ - "10年以上", - "本科", - "财务综合管理", - "CPA", - "高级会计师" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "财务综合管理", - "CPA", - "高级会计师", - "生活服务", - "医药", - "集团公司", - "财务信息化经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 7, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.479052, - "latitude": 31.225635 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某小型投资公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "", - "brandIndustry": "投资/融资", - "brandScaleName": "20-99人", - "welfareList": [], - "industry": 100207, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "EE_9aK4zxU96u-f1i0R8m30aZfSjxPDfL-Pe0tmUDaVKUyEvcNAccHnzXiCaXWZN1j_t3ifximRsgmHAn8azsfpEzNjV2QhOAreKMjgtU9jJK1AaUmhj0c11HFFQ-XBNXEX98nDxOrJYMVLNXRWxdyvaj8s~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_11.png", - "bossCert": 3, - "encryptBossId": "0519c46662d2567a0Xd92NW6EFtY", - "bossName": "代露", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "e5ba547f91fdcf6903xz3tW4ElVW", - "expectId": 1196299886, - "jobName": "soc架构师", - "lid": "1hfcKRGLEBx.search.8", - "salaryDesc": "40-60K·15薪", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 8, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.442652, - "latitude": 31.126581 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型汽车研发及制造公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "不需要融资", - "brandIndustry": "汽车研发/制造", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100801, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "Uw8V2ny1RrLE8-x1_M2tUrHgDv4GSL9I1XPdDDAQb-I0mrRLRNh6GjAJmV8fV-b8bp9ZC7UhWg3W_PWv8xMSVTAVfPmrB0j7m93aoxji_pcfVwKS5l6cg50oyN5q4x8-bu-zG3MymqINEpOXOooTECl1cbw~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20221104/607f1f3d68754fd0b4f2eeba7e8d8593df398f40666188a47f13a639bc1fcf220807992474dfd4c4_s.jpg", - "bossCert": 3, - "encryptBossId": "75c6f2d9f5c3be100nFy3d-_EFBV", - "bossName": "张成", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "914e2ebad951f58103F52tS7GFJU", - "expectId": 1196299886, - "jobName": "全栈工程师(前端)", - "lid": "1hfcKRGLEBx.search.9", - "salaryDesc": "20-30K", - "jobLabels": [ - "3-5年", - "本科", - "全栈侧重前端", - "React", - "Node.js" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "全栈侧重前端", - "React", - "Node.js", - "Python", - "前端开发经验" - ], - "jobExperience": "3-5年", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 9, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.606674, - "latitude": 31.194646 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型已上市医疗健康公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "医疗健康", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100006, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "2NnN1HOzB84WH-j1ppY0VAps5ml_pF14g1KwBBqT-VfYyLkp-uYLKbbNoIevbiv5Jzk_33DLng0xDIyV0tPkWiC6FX1B_tHqRhwdwzUIKThQg7tKh2tZTvKYEnpUmkzaId1AOkRjunq7SXGoFIFkk-Jy393w", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250512/607f1f3d68754fd0d1d82b22f91ee2877d372eeeb59c647e1fa9f16d30d2fc0bc789546351b2c09a_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "48d0aa3e860a25c30HR-29y8FVVS", - "bossName": "刘先生", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "7126598ea368da0d03xy0ty1GVVR", - "expectId": 1196299886, - "jobName": "英语全栈软件工程师(AI方向)", - "lid": "1hfcKRGLEBx.search.10", - "salaryDesc": "25-35K·13薪", - "jobLabels": [ - "5-10年", - "本科", - "全栈无侧重", - "React", - "Java" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "全栈无侧重", - "React", - "Java", - "英语熟练沟通", - "AI经验", - "商务英语" - ], - "jobExperience": "5-10年", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 10, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.538093615289, - "latitude": 31.2221238509828 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型已上市计算机服务公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "计算机服务", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100023, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "PthS4YKhmsNsW-C1RnQadhraTL_NDWO7hwywz2RBZxihPwxSrV3BjA4J5Ie0jyGvMiDBNywpPZx1Y6F-w2cy8rTq_qyvfjIcnbaHRPJQ1-kzUcKkNYUK4h6LHKL7By59L4SPw7H19e5qmBJ8wzsZL80D", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_6.png", - "bossCert": 3, - "encryptBossId": "c8cae4e989bca0351X1829y9FVM~", - "bossName": "邵先生", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "26f8a2b6cc4ff15b03x43N27EltU", - "expectId": 1196299886, - "jobName": "外卖运营负责人-餐饮外卖-上海/杭州", - "lid": "1hfcKRGLEBx.search.11", - "salaryDesc": "45-75K·16薪", - "jobLabels": [ - "10年以上", - "本科", - "团队管理", - "TO B", - "运营管理" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "团队管理", - "TO B", - "运营管理", - "餐厅运营", - "B端用户运营", - "B端运营", - "产品运营", - "整体运营" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 11, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.381728, - "latitude": 31.232548 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "上海某大型移动互联网上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "D轮及以上", - "brandIndustry": "移动互联网", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100019, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "SAeZLicQwnFID-31tBqg5kOjbBUhZT1oFTFpfLh4E6kW8lfudKzIikElleyVfKI8uUfE3FDDc57jwAnH6kPO8G8c-gpmHwnU8a9lX3QKFjNwEC3clmtsaOufkAXqn3MvKoGsXg_Ow_lZzfXzPaehOw-iRZtj3Q~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20240121/607f1f3d68754fd034839b6276808fdb978b5df5b03e6ad95e99d05e109083c8b04367454d4b0699_s.png.webp", - "bossCert": 3, - "encryptBossId": "3e58bf677b1179931nV42ti5FlZT", - "bossName": "刘先生", - "bossTitle": "助理总监", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "45a2315226fffe2b03N93tu_FFZT", - "expectId": 1196299886, - "jobName": "连锁餐饮运营总监", - "lid": "1hfcKRGLEBx.search.12", - "salaryDesc": "20-30K", - "jobLabels": [ - "10年以上", - "本科", - "团队管理", - "运营管理", - "客户管理" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "团队管理", - "运营管理", - "客户管理" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "张江", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 12, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.586307, - "latitude": 31.211493 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "845151c189eb87f703d92NW7FVQ~", - "brandName": "上海焯鲜", - "brandLogo": "https://img.bosszhipin.com/beijin/icon/894ce6fa7e58d64d57e7f22d2f3a9d18afa7fcceaa24b8ea28f56f1bb14732c0.png", - "brandStageName": "", - "brandIndustry": "互联网", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100020, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "d8n9p0ZXlw8bF-x14eBP9O6IraymnfHQgBWcS7Cct0BrBUnVOIdWDzWVR0DfZEi1VmiNgK-4sKvNr1Rx9ff5Zy1vAelNPb6SHuzaHe0wP9LoJnnQRC-ZdVHRB7UiFI9ZMMDFqBdSP45nYFFI1WzyUFT_XSxq", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20220819/607f1f3d68754fd0ff61257cbbf0ccbadc5dc83817b5acb1ff1eb5527cf2bfce8ba2b317973e18b3_s.png", - "bossCert": 3, - "encryptBossId": "d9359cbc16a011011nR82tW4FVFZ", - "bossName": "许女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "45d1f51055e78fc803Nz3920GVRT", - "expectId": 1196299886, - "jobName": "pmo总监", - "lid": "1hfcKRGLEBx.search.13", - "salaryDesc": "45-65K", - "jobLabels": [ - "10年以上", - "本科", - "PMO 机械行业", - "项目管理" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "PMO 机械行业", - "项目管理" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 13, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.206181, - "latitude": 31.417779 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型泵业公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "不需要融资", - "brandIndustry": "机械设备/机电/重工", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100901, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "lOMs4COyXFtcp-q1ePWT8cFSvZUXBeKfa1Mf7612Vd32hOOeTayCeZYt7yc82XgRwZIzn361Vg5dcqFGrqtEfT-gyAn5PCRA3rDMq7UHIw3JtXzdpN8HqPGmqCuonHwCGk9p8WSy10_QjjfK5wrQSlVFxaTd", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250907/607f1f3d68754fd0069afdc8c74935518e4ed5364a75e148c89f99afd224a161412a4c1ed9df008f_s.png.webp", - "bossCert": 3, - "encryptBossId": "2fff9eb2c8078ee40XR62dS8FlFX", - "bossName": "蒋雪萍", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "900955341e1d359603173dy-EFNQ", - "expectId": 1196299886, - "jobName": "战略与投资部-汽车领域专家级岗位", - "lid": "1hfcKRGLEBx.search.14", - "salaryDesc": "30-40K·20薪", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 20, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 14, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.520283, - "latitude": 31.230851 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型知名汽车研发公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "不需要融资", - "brandIndustry": "汽车研发/制造", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100801, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "SNbH7yTQgDRoe-y1OjVrvFgQSA1cafpQa0hIFB3a9w-y73lUju1LMfZT5xsujwELiSgNxLnitL8mMFrKKf2jqP-twh1-6yo3Ud_GIjwBIIYEF_GrR6ursIm5CoUFnwAV0_hu73Y6kZqLw0t3U_3rjky-GIk~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20230926/607f1f3d68754fd0cd66bb949fde5c8614b79ff97174c8687890d6777239154b49309aacaa549969_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "be5deb4d45d9ce260nJ53Nu9F1dY", - "bossName": "王圣炜", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "f7e4246bb5a9bcc103N729-1GVFV", - "expectId": 1196299886, - "jobName": "自动化仿真测试架构师(汽车)", - "lid": "1hfcKRGLEBx.search.15", - "salaryDesc": "40-60K·16薪", - "jobLabels": [ - "10年以上", - "本科", - "测试工作经验", - "自动化测试经验", - "iOS/Android测试经验" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "测试工作经验", - "自动化测试经验", - "iOS/Android测试经验", - "掌握软件测试理论和流程", - "座舱域", - "车身域", - "智驾域" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 15, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.559984, - "latitude": 31.210021 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "广州某大型汽车研发制造上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "汽车研发/制造", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100801, - "contact": false, - "showTopPosition": false - } - ], - "type": 2 - } - } - }, - { - "url": "https://www.zhipin.com/wapi/zpgeek/pc/recommend/job/list.json?page=2&pageSize=15&city=101020100&encryptExpectId=&mixExpectType=&expectInfo=&jobType=&salary=&experience=°ree=&industry=&scale=&_=1763023197341", - "method": "GET", - "status": 200, - "data": { - "code": 0, - "message": "Success", - "zpData": { - "hasMore": true, - "jobList": [ - { - "securityId": "3ZhwBZXH-rJdg-61bqSD0Tj77k8ECwrLuxVy6PSDSpk7n777Hacg_ets9j6LauO7VAsoZ2usas5gQdRPxZ-tiMxkc-7z4tVeMIBkJLbVARp2zImLjzKqCw~~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_4.png", - "bossCert": 3, - "encryptBossId": "a85113d2f852fa1c0nd62dq9GVE~", - "bossName": "王女士", - "bossTitle": "招聘专家", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "08a8faebc7e8b4241HB_29i_FlNQ", - "expectId": 1196299886, - "jobName": "软件架设专家", - "lid": "1hfcKRGLEBx.search.16", - "salaryDesc": "45-65K·20薪", - "jobLabels": [ - "10年以上", - "本科", - "架构设计/优化" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "架构设计/优化" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "张江", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 16, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.613713, - "latitude": 31.185076 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "3d0b6629203bb0b61nJy3t-0", - "brandName": "传音控股", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/workfeel/20230206/7bf6f160950405e9e3b54d760f3b0e4ce7ca0c8ff6dc37bc00ef94d6d40196f3f0bec87c7865f9e2.jpg", - "brandStageName": "已上市", - "brandIndustry": "通信/网络设备", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100024, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "5chV3Zh3LOjQQ-C1pbwEuJuAMvzh69aZF3P4qZa2an6Z-ojXoOiKfXDWiZR7cnLQGDPrhCzDol2rqdo0XNi_cqh_xP9xXDkTlJnVdEnXfRAxHMY5iSRvFHmp", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20210716/c74748494e59b367583499da5d1da02fb2e3cfb5bbe32b8a1e48948fac310648_s.jpg", - "bossCert": 3, - "encryptBossId": "9f6671abb10c502433F-3920F1c~", - "bossName": "刘女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "0a4c68aeacbea2d103x_2tq4FVVY", - "expectId": 1196299886, - "jobName": "封装运营总监", - "lid": "1hfcKRGLEBx.search.17", - "salaryDesc": "30-60K·14薪", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 20, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 17, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.625949, - "latitude": 31.209213 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型电子公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "", - "brandIndustry": "电子/半导体/集成电路", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100026, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "qeo90h7E03Zss-v1b4s2AJEx_SEH_inUiuAX6S7OeI-E-tlYqoLyyK_ng1Rk1bOVx9_91JFCyrapLmvzDLpkpBXArS63G7RWXCyDEgdOuJs9qJCrk6RyT7H3lUFw9-Sc0M_us4EzZrtEaC42ctiNFSGHO7SH", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_6.png", - "bossCert": 3, - "encryptBossId": "59c1c73b481db33e0Xxz2d66GVBS", - "bossName": "周志勇", - "bossTitle": "人力资源总监", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "ac1d8e50cc1605f603N43tm9EVRQ", - "expectId": 1196299886, - "jobName": "副总裁(家电行业)", - "lid": "1hfcKRGLEBx.search.18", - "salaryDesc": "40-60K", - "jobLabels": [ - "10年以上", - "本科", - "消费品", - "电商", - "互联网" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "消费品", - "电商", - "互联网", - "运营管理", - "人事行政", - "战略制定", - "财务管理", - "质量安全", - "民企/私企", - "0-30人", - "有0-1的创业经验", - "有中高层管理经验", - "电器行业", - "COO", - "经营管理", - "流程优化" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "宝山区", - "businessDistrict": "顾村", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 18, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.377204, - "latitude": 31.348936 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "b3094c1dfc8a59cf1Hd_0965EQ~~", - "brandName": "上海能良", - "brandLogo": "https://img.bosszhipin.com/beijin/mcs/chatphoto/20201103/3d1fd073a1e7f8e459c19397f3a0c3adf1102e71962779c71aa1df6e390dd2da_s.jpg", - "brandStageName": "未融资", - "brandIndustry": "电子商务", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100001, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "JnNi4ERPUPykR--1QLSF0qBsDAG9VN9TsF59RL4HjmZacdXAnyvckfJIYA0BIAZxOcp302oPyOyVEiTusQ063PXj9yYMx8rVUH9yqdqggTUH2kZF2tLCLA~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20241204/607f1f3d68754fd054c57abe5702630b7ff4220bd27ff239d41631eeca77e476bd343412f328f1b1_s.png.webp", - "bossCert": 3, - "encryptBossId": "245e2e1ca3fdbd1803R739m7FlM~", - "bossName": "岳女士", - "bossTitle": "招聘主管", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "3e516acf50a3f91103Z93t-6GVtR", - "expectId": 1196299886, - "jobName": "高级软件工程师(视觉)(J10894)", - "lid": "1hfcKRGLEBx.search.19", - "salaryDesc": "25-40K", - "jobLabels": [ - "10年以上", - "本科", - "工业设备软件", - "C++", - "架构设计经验" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "工业设备软件", - "C++", - "架构设计经验", - "视觉检测", - "工业视觉", - "上位机开发经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "奉贤区", - "businessDistrict": "金汇", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 19, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.507451, - "latitude": 31.001238 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "35bf45b7264a6b5603192NS5", - "brandName": "上海兰宝传感", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/workfeel/20250513/7bf6f160950405e96b7056f1222dfaaec59f5550ecf97f6e82620ef65f3dac3981366fe843631b5d.png.webp", - "brandStageName": "不需要融资", - "brandIndustry": "仪器仪表", - "brandScaleName": "500-999人", - "welfareList": [], - "industry": 100913, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "zbmBP2s7-qERn-01OB-de01usmUFFhjG1ITONjMNcy6qzvq9r0u77snR1rGjtkvtNBlzhfZU90-kEsNF4NbdsQAUeqEuRVRVdrAB_L-PrH5qRTdeiTjE", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20200901/03fff04c0b8dbcc6b232408433292234e1a91c111cbf5ff275b0a25d2a89d31d_s.jpg", - "bossCert": 3, - "encryptBossId": "16f4ab20b78605dd1nd_2t-0", - "bossName": "黄晓平", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "071d6dc7cce3d34c03F93d29FVBT", - "expectId": 1196299886, - "jobName": "安全专家/安全副总经理", - "lid": "1hfcKRGLEBx.search.20", - "salaryDesc": "40-70K·13薪", - "jobLabels": [ - "10年以上", - "本科", - "等级保护", - "商用密码", - "隐私合规" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "等级保护", - "商用密码", - "隐私合规" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 20, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.479955, - "latitude": 31.242276 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型互联网云计算与大数据服务上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "计算机服务", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100023, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "tHDScgEtXSH55-31tvhSPCrTJ6bJg95GA-d3O_x9D8dRiUzsy95dnKfTdWiOWQTk_ce_mk7X-9wF718Dw_O4oyjYEGs5RZ3Oz5jkGvB7IixGWeKeLHjj9V4~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_7.png", - "bossCert": 3, - "encryptBossId": "c2a6209ab841d0500nx-0tm7FVtS", - "bossName": "杜攀攀", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "700da3aa683e08fc03d-2t6-ElVR", - "expectId": 1196299886, - "jobName": "仪表板高级经理", - "lid": "1hfcKRGLEBx.search.21", - "salaryDesc": "40-50K·15薪", - "jobLabels": [ - "10年以上", - "本科", - "内饰", - "仪表板" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "内饰", - "仪表板" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 21, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.603358, - "latitude": 31.176877 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型汽车研发制造上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "汽车研发/制造", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100801, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "SFQa7b6MLdXNb-z1fgB2zN9orDHIwGgHRTQOuZW8Ps0905H11xD23XmKGOf5jq9eGwEGUwuMj8Q7H_nDnN7xguVWaHF5vN09MAqPDPTxZVEwj59NOMg8mN5Qca8wkR5kl_RNS7ieFRcK-7UuInTumlAOZscj", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_2.png", - "bossCert": 3, - "encryptBossId": "52d5c817bf4cc7c81HR609m_FFo~", - "bossName": "朱康丽", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "1e623f16bb6ead1a03N-0t-7FVJS", - "expectId": 1196299886, - "jobName": "匿名公司招聘生产总监", - "lid": "1hfcKRGLEBx.search.22", - "salaryDesc": "20-30K·13薪", - "jobLabels": [ - "10年以上", - "大专", - "电池托盘", - "注塑工艺经验", - "表面处理工艺经验" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "电池托盘", - "注塑工艺经验", - "表面处理工艺经验", - "有生产管理经验", - "电池包壳体", - "工装设备经验", - "激光工艺经验", - "机加工工艺经验", - "成型工艺经验", - "汽车经验", - "电池壳" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "大专", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 22, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.248431, - "latitude": 31.312971 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型汽车零部件公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "未融资", - "brandIndustry": "汽车零部件", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100802, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "cW-9T5VTfo-eL-q1Te5OkbuHp8H7e_4L9VWCSMbAv9U0WJNlEs4ag4QaKv7dHnU-ABsdftIWsGTWEVmzDJjYa37JZcw1zyetnGUGJAMR-ef-IgnUl-dBLBc~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_5.png", - "bossCert": 3, - "encryptBossId": "cfa0fa77393022eb1nZz2dy0EVQ~", - "bossName": "段攀", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "bb4eaabe924d801203R42dW7EFNZ", - "expectId": 1196299886, - "jobName": "总裁助理(连锁酒店业务方向)", - "lid": "1hfcKRGLEBx.search.23", - "salaryDesc": "25-40K", - "jobLabels": [ - "10年以上", - "本科", - "连锁酒店 运营 数析" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "连锁酒店 运营 数析" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 23, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.314511, - "latitude": 31.211094 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型健身器材上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "电气机械/器材", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100908, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "aDTw4rhF79l2C-91fvchmqasrvxYBUBwbpM2TJxyje2Q1K7vNesJCE-va1U7yQ22aHN0m-3A9a_H3abYnCGCC0XmzF3xD2LgpYR2rPqhQs1KH3k-iYFQaZ_ECHnvPuqOZk8LajlTDKef9gYnk5RQpXiLKW3L", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20230906/607f1f3d68754fd05178bcd8091c5af2917e1d0b5190231e94bde1d0f9e9b1c651cf9ec1b989e9cf_s.png.webp", - "bossCert": 3, - "encryptBossId": "9d4d7bc9326a97ee0XV90t-4ElFQ", - "bossName": "包先生", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "73be82f64548fd6f03170ty5FVRV", - "expectId": 1196299886, - "jobName": "销售总监(拓展.吸管餐具降解杯厂家)", - "lid": "1hfcKRGLEBx.search.24", - "salaryDesc": "20-40K·23薪", - "jobLabels": [ - "10年以上", - "本科", - "团队建设及管理", - "市场开发及维护", - "企业" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "团队建设及管理", - "市场开发及维护", - "企业", - "先进制造", - "较多出差", - "销售管理经验", - "销售工作经验", - "对机构(To B)销售经验", - "团队管理能力", - "商务谈判能力", - "市场分析判断能力", - "地推团队", - "吸管餐具降解杯生产" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 20, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 24, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.079272, - "latitude": 30.867819 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某批发公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "未融资", - "brandIndustry": "批发/零售", - "brandScaleName": "20-99人", - "welfareList": [], - "industry": 100503, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "vo3PCisv8qHdr-21C5b6vw5OsuSacDL3zCidImALBgN_d4Cw9ikBt8YCOSDkb4Uq3mKXEogEgSbG-NVX7gF1oIZNWl4eYPjPikp9icNlHg9aZImYTEj50-LAV8o1Yi1YbsYPaMONjC9Nae_6HT21Qx9oTxg~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20210303/58e3f4767f62c46c14c2f70294b5f9b3c6993398adb26aa2598e3b70407a2cb2_s.png", - "bossCert": 3, - "encryptBossId": "38730fcf2e9f063e0nVz09m7E1JZ", - "bossName": "龚志伟", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "5fdf871b87e025fe03Z-3di0GFRW", - "expectId": 1196299886, - "jobName": "幕墙项目经理", - "lid": "1hfcKRGLEBx.search.25", - "salaryDesc": "20-30K", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 25, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.255145, - "latitude": 31.330413 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型国有工程施工公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "", - "brandIndustry": "工程施工", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100702, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "Cvhi5bR6lQwCF-L17saW97tW2kQeN47ciQ63yTINfmPR7UNws1BwJvoI2CVb2qvkYpnx31dqhGHH-4iMVCD2hyVjXWHzF4xkrYFjRDaLiZ_VSuWoYEooDf9s8DMZXthMZjI0WYJy7VI12FpITGnhXf5ysqK_3w~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20240316/607f1f3d68754fd020e6e000d182cd1c5d2ac063c294fe23cb6b91ee3f547108efe3e1c8df09b629_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "734d396792d39ed00nN42N67ElVR", - "bossName": "刘女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "64c4c91dcb10a67403170t-7EFpW", - "expectId": 1196299886, - "jobName": "业务发展高级经理(总部银保)", - "lid": "1hfcKRGLEBx.search.26", - "salaryDesc": "30-45K", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 26, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.505143, - "latitude": 31.251952 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型已上市保险公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "保险", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100202, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "orCtuOcBIm0iQ-41lgfZpu5384jUAkdMzj3I4g1wwZ_FZ-EWfEDTpmyQzdZnq_311d5mg6Mtj5reh3UkYx1EVPHaQoJlGk2E-AJNvcskXspzQ206x5wXlHhPbd3N4pl7Y2sun4MVESYGdsfWXHRX7Z6KBrA~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250721/607f1f3d68754fd0c28eba39a779cc9a1fd552fd88b97946bf23e2329ffc41049a4206131700e5d9_s.png.webp", - "bossCert": 3, - "encryptBossId": "a0dbbdbb2b47454703J409m4GVM~", - "bossName": "江女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "85656cdd88e035a203N439u6ElFT", - "expectId": 1196299886, - "jobName": "资深测试工程师", - "lid": "1hfcKRGLEBx.search.27", - "salaryDesc": "35-45K", - "jobLabels": [ - "10年以上", - "本科", - "功能测试", - "性能测试", - "自动化测试" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "功能测试", - "性能测试", - "自动化测试" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 27, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.212901939912, - "latitude": 31.218115657833 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型物流/仓储公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "", - "brandIndustry": "物流/仓储", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100502, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "ZqwXvKBCj3VpI-01gDCSEwEHPeyluleE4eWkjOK0AAptYyl1ijvojZQQ5Ck6SYdp-thX7cT8QtL5GRWL8bplqx9CkgcX4cTj3GA9aLfsI21GyRZB9HSNd1fHgQ~~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_3.png", - "bossCert": 3, - "encryptBossId": "e08847a5420f7d140XZz3967F1ZY", - "bossName": "马攀", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "8067bba50aa533cf03R_29m_EFBV", - "expectId": 1196299886, - "jobName": "储能系统工程师", - "lid": "1hfcKRGLEBx.search.28", - "salaryDesc": "25-35K", - "jobLabels": [ - "10年以上", - "本科", - "系统工程师", - "电池PACK" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "系统工程师", - "电池PACK" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 28, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.623512, - "latitude": 31.12942 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "四川某小型咨询公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "", - "brandIndustry": "咨询", - "brandScaleName": "0-20人", - "welfareList": [], - "industry": 100601, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "5MgG0zZGuT0XB-N12bRUNh-T_EhXu0OgNa0xpbfkQ_SH4Nk3HmvY0t96b6jM0Ph2HvRf2b64DDKhvxcGFeDe2dxkCLwsjsJUHNATP6mtkn-KWwTq1ozM0yXtKe4LQ5t8woRNKvgycqGCJtysR6sN3jCrd8kWaQ~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20230612/607f1f3d68754fd0435cae8d3db46603b9207387aae84457c5a6252a2743c12e735c7105a993c05c_s.png", - "bossCert": 3, - "encryptBossId": "ecd98b9d319651900nN63NW7EFVS", - "bossName": "程慧", - "bossTitle": "招聘专员", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "d54457925358148603d92di1EVZW", - "expectId": 1196299886, - "jobName": "MOE系统专家", - "lid": "1hfcKRGLEBx.search.29", - "salaryDesc": "40-70K·15薪", - "jobLabels": [ - "10年以上", - "本科", - "opc", - "其他方向" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "opc", - "其他方向" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "金桥", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 29, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.592392, - "latitude": 31.24634 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "df33d8faa6496cf01XB60tu6F1A~", - "brandName": "宇量昇", - "brandLogo": "https://img.bosszhipin.com/beijin/icon/894ce6fa7e58d64d57e7f22d2f3a9d18afa7fcceaa24b8ea28f56f1bb14732c0.png", - "brandStageName": "未融资", - "brandIndustry": "半导体/芯片", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 101405, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "UDVjK0348m7YF-01GU3b4sikN277TQSMbquvbkP6uVh9D7ORHajp99lcht7yvnKRY15hvP1c7339qj84ErB8wE7tE2jEZVT8DOuFDUhseD1oOJuSVWrRcMtkfttjESs1srXoJduJ2-dfuKRXAAPV3yyV", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20210414/2ac8fcdf7751d5279d2ef23f2256033662788fb2251964ea355c9a6cd337c824_s.jpg", - "bossCert": 3, - "encryptBossId": "a2f21c5bbac358670nZ83N-4E1ZT", - "bossName": "刘女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "98ea39a436a6649e03x72NW8FVJU", - "expectId": 1196299886, - "jobName": "高级产品经理/产品总监(垫付类产品)", - "lid": "1hfcKRGLEBx.search.30", - "salaryDesc": "25-50K·16薪", - "jobLabels": [ - "10年以上", - "本科", - "互联网", - "支付产品经理", - "产品策划及设计经验" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "互联网", - "支付产品经理", - "产品策划及设计经验", - "垫付产品", - "垫付风控" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 100, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 30, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.505598, - "latitude": 31.314884 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某500强上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "B轮", - "brandIndustry": "医疗健康", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100006, - "contact": false, - "showTopPosition": false - } - ], - "type": 2 - } - } - }, - { - "url": "https://www.zhipin.com/wapi/zpgeek/pc/recommend/job/list.json?page=3&pageSize=15&city=101020100&encryptExpectId=&mixExpectType=&expectInfo=&jobType=&salary=&experience=°ree=&industry=&scale=&_=1763023202910", - "method": "GET", - "status": 200, - "data": { - "code": 0, - "message": "Success", - "zpData": { - "hasMore": true, - "jobList": [ - { - "securityId": "fSisJC6oR3FSF-v1h8uvK0o-S_rrq59S4Qc3yDmfZ3c0usM9uy2CeEnrcLweeYP30fIKNVYus4Lng8wo-ohCmyGNxAHz8UVfUU91rHp-N8xF71irCqMjfno~", - "bossAvatar": "https://img.bosszhipin.com/beijin/mcs/useravatar/20181221/b3d18f459211cd1fd8b8567046cb93524f41fd628bf71091fbe89393dfaeefe1_s.png", - "bossCert": 3, - "encryptBossId": "076c154c0fd1df341HRz09q-ElE~", - "bossName": "侍晶晶", - "bossTitle": "人事经理", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "ff251a94fd65fc7c03N93di4F1RT", - "expectId": 1196299886, - "jobName": "卫星综测负责人", - "lid": "1hfcKRGLEBx.search.31", - "salaryDesc": "25-50K·16薪", - "jobLabels": [ - "10年以上", - "本科", - "卫星", - "综合测试" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "卫星", - "综合测试" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "闵行区", - "businessDistrict": "莘庄", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 31, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.389471, - "latitude": 31.085376 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "5a015ce42031101e1XJ52dq6FQ~~", - "brandName": "国星宇航", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/logo/20200306/eee2fa5ba602b4e7d3cfd22de0531826608f56d3f5ea41ffaa8300912f4740f3.jpg", - "brandStageName": "B轮", - "brandIndustry": "通信/网络设备", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100024, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "tZMNxa0xTydIJ-n1fwgXrW7FVykvVvez0p2SufAMXZHMxhZAi0pXWjWwQhC5-DfScHfli-PQ5mS5H7RESfJSEnq9gl_eK7MKOpUGkg0Pem43aywdNdymYptbNq61W64tM5-_BmAln5sSPOumxNk7EfpB-u0~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250617/607f1f3d68754fd07599caed96ffa02800769318842d02cdaac99a2dd7f2c816f2c6b8f4061423f7_s.png.webp", - "bossCert": 3, - "encryptBossId": "62fd66c735a82c2e1Hdy39q1Elo~", - "bossName": "周颖", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "38623ef5f75450fa03B93tm7ElJU", - "expectId": 1196299886, - "jobName": "agent 后端开发-上海", - "lid": "1hfcKRGLEBx.search.32", - "salaryDesc": "35-65K·15薪", - "jobLabels": [ - "经验不限", - "本科", - "AI agent", - "ai app" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "AI agent", - "ai app" - ], - "jobExperience": "经验不限", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 32, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.460289, - "latitude": 31.158746 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某头部大型互联网公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "D轮及以上", - "brandIndustry": "互联网", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100020, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "9DCyNYqP8Ddne-h1A7dcTyS8CQy6P7qdGxXcEnYHN53_DfGse4ALAuCYMDz083AttAoAvgIq7W6yaIy7jr9RHQoouwxuvm7JDK-ujGzwecZjQAU9PhP6hA~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20211124/607f1f3d68754fd04c0cdae462d95e2af07e3606d341e20e8c60e68efee2422a9718d967d278f795_s.png", - "bossCert": 3, - "encryptBossId": "0f39904b8e668bec03d43t66FFE~", - "bossName": "符女士", - "bossTitle": "HR", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "9537f3426c9540b503x80t29GFJV", - "expectId": 1196299886, - "jobName": "人形关节模组研发岗", - "lid": "1hfcKRGLEBx.search.33", - "salaryDesc": "30-60K", - "jobLabels": [ - "10年以上", - "本科", - "有机械结构工程师经验", - "机器人经验" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "有机械结构工程师经验", - "机器人经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "青浦区", - "businessDistrict": "赵巷", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 33, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.277548684098, - "latitude": 31.1766548701013 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "3a5b5d9a1604125c1XV_2ty9", - "brandName": "美的", - "brandLogo": "https://img.bosszhipin.com/beijin/mcs/banner/bd72a114c873fcde5dcbe4620baca3d3cfcd208495d565ef66e7dff9f98764da.jpg", - "brandStageName": "已上市", - "brandIndustry": "其他行业", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 101304, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "Mf9DeHNkYpldT-t1_JN1wXpOf6E6scZ5VB6qZMjVAaNQRIdPohuF6wJxmqfJewu47zrmjMuUdadDJ97qLSZebWhLkuPfa7d9HCLwYsfub-mRLPmB3Ek5Vt8qrsx_pNposDEC6ZwOSxhpKB_dp7m5IslvRDep", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20241220/607f1f3d68754fd0629779810b7188196f52df35a75370cf7a8095a2bfbef0d41c4b80cbbc8c4126_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "bd492200101da5490Xd72tq4ElVU", - "bossName": "易先生", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "e1069715609996cb03143N24FFBT", - "expectId": 1196299886, - "jobName": "财务总经理", - "lid": "1hfcKRGLEBx.search.34", - "salaryDesc": "30-35K", - "jobLabels": [ - "10年以上", - "本科", - "财务综合管理", - "CPA", - "医药" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "财务综合管理", - "CPA", - "医药", - "医疗" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 34, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.606952242614, - "latitude": 31.2226124570638 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某中型医疗健康公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "不需要融资", - "brandIndustry": "医疗健康", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100006, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "kPVJagqXt7vum-E1H5GrbWsVnzE9-Yv22EpvgtCBvrD_L5quwBsukKkMSTdzDS7OmLCyFIFff1a6yV8zj1OiqepSfkPUnfYaUNTZ9-A-v4fsZHNdO65CtNK_Eg~~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_3.png", - "bossCert": 3, - "encryptBossId": "13a4a88ae5b568de0XZ639q6FlBU", - "bossName": "李女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "5c8da741e459331c03Jz3t64GFRW", - "expectId": 1196299886, - "jobName": "IT高级经理/副部长(日语)", - "lid": "1hfcKRGLEBx.search.35", - "salaryDesc": "25-30K·14薪", - "jobLabels": [ - "10年以上", - "本科", - "制药/医疗", - "日语", - "日企" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "制药/医疗", - "日语", - "日企", - "AI", - "大数据" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 20, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 35, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.477576, - "latitude": 31.230985 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某投资公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "", - "brandIndustry": "投资/融资", - "brandScaleName": "20-99人", - "welfareList": [], - "industry": 100207, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "z0Iw_WaIaNgv5-61Jbx76tg1zMexAeY4EuyLeL5-p3dEzUlh2K0jy8Okghnn2i0I7VTCrHjZ5BhT6PrR_FBBbWoCUnXrPbyHaRAmWP48s6S9on_ou5pUmo6X", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20230117/607f1f3d68754fd0b7102b5cc0485e585fde9148621c7c0bb9f9109e4a84ef17f16bd895abca8017_s.png", - "bossCert": 3, - "encryptBossId": "e4098b13cf2a58090nN-29i_GVFU", - "bossName": "张恒燕", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "d913a24b6c9576a203152Ny0GVJQ", - "expectId": 1196299886, - "jobName": "非战区销售总监/中南美洲销售总监-商用车", - "lid": "1hfcKRGLEBx.search.36", - "salaryDesc": "35-50K·18薪", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 20, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 36, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.620569, - "latitude": 31.274598 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型知名互联网公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "D轮及以上", - "brandIndustry": "互联网", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100020, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "jNrh4k-6ff2ce-a1-uWiGgJJ3SBv1smpTTbURBNpXBy2BMxxMktzMXxo7fYvptUeCbBAtHpCuTlZFS-PkJ_xjpwHL8UtV0dhlNCNg-Vv80lge_JCfu_hdjH6", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_3.png", - "bossCert": 3, - "encryptBossId": "5feb6b0b30d5e89c1nR93dy4FFRZ", - "bossName": "曹女士", - "bossTitle": "招聘负责人", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "220778b15206c39b03xz2Ni6EFFX", - "expectId": 1196299886, - "jobName": "药物警戒专家", - "lid": "1hfcKRGLEBx.search.37", - "salaryDesc": "20-30K", - "jobLabels": [ - "10年以上", - "本科", - "医学专业背景" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "医学专业背景" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "奉贤区", - "businessDistrict": "南桥", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 37, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.46927, - "latitude": 30.966576 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "a3bdbc2b29fb12fb33Vz2tu0EQ~~", - "brandName": "上海莱士", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/logo/20250319/7b5b554d84f9729c59e4c9b8b4de02c0c06f0f1703fb40ae3513c21a2fad2988793742f02519f59f.jpg.webp", - "brandStageName": "已上市", - "brandIndustry": "生物/制药", - "brandScaleName": "500-999人", - "welfareList": [], - "industry": 100401, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "_bgxYAFU4t3dC-11FITFWd_jLsPCxQEntDYwzu-7bsDmKMmQLA0mdABmS1AvTwhRX0hY--tIinlkEF1najtXc3zwAL_Tl5UzJhw6i4XCNxuvPBO3U7uxcA5Pa3r5w52dWVFd3xQhYEyYmfUMay8MyGgciyUeUw~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20220922/607f1f3d68754fd0c29a426b4184d8a13858217e16219589ea04e11777f4a16d476dbe1ac7a1e12e_s.jpg", - "bossCert": 3, - "encryptBossId": "2e09433e74d8431c0nJ72ti0EFZQ", - "bossName": "陈伟明", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "88639dfb79777d6e03x_3Ny5E1JX", - "expectId": 1196299886, - "jobName": "常务顾问(督导评课)", - "lid": "1hfcKRGLEBx.search.38", - "salaryDesc": "20-25K", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 20, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 38, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.401936, - "latitude": 31.323081 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某知名学校公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "未融资", - "brandIndustry": "学校/学历教育", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100302, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "zG_kHiOXkJhQ6-C1Tf7bSN1q9wkaU5mWfcdB8tafUEB9cAbsYxmi3JzLV-7-i4vztrYEJiFU0j9prf0B75JESkSvEPJTE3YpCx1CcF2fxelyHk8rJAu86CU-8midVTbXINx0pFgdsgK9v_lFXYP41KomJkbK", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20240704/607f1f3d68754fd04ff4679308438fd4675d25144bcd0e3c28bef826906937e581e965efde9a41a3_s.png.webp", - "bossCert": 3, - "encryptBossId": "3249f0d57c1c51cc1HV70tu6FFY~", - "bossName": "陈女士", - "bossTitle": "招聘总监", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "8ee57aa8e515133d03N439W7FlpY", - "expectId": 1196299886, - "jobName": "全球金融渠道拓展总监", - "lid": "1hfcKRGLEBx.search.39", - "salaryDesc": "40-70K·14薪", - "jobLabels": [ - "10年以上", - "本科", - "institution", - "同业", - "支付" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "institution", - "同业", - "支付", - "financial", - "金融渠道" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "杨浦区", - "businessDistrict": "东外滩", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 39, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.515368, - "latitude": 31.258679 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "474e72d4edc06a371nx439i4F1c~", - "brandName": "XTransfer", - "brandLogo": "https://img.bosszhipin.com/beijin/mcs/banner/946255e76007017e7afbec3415e615f2cfcd208495d565ef66e7dff9f98764da.jpg", - "brandStageName": "D轮及以上", - "brandIndustry": "互联网金融", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100206, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "aZArKdz3J3Egg-S1wmewW60340jy5AroOWDvPqAyANWi8vphsDDqGeH28ag09eiSAuKanwFsZ7qroTHxFJcru9vKg5np6iZJCe8w1yYhlpu2iX8ZkbtHy66pMc3ilxDRhagYgd8H0ZPH3yhw_m2rzjAmfzI~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_3.png", - "bossCert": 3, - "encryptBossId": "c567ea3e26bc27350nRy3ti4FltQ", - "bossName": "吴春梅", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "c033fe55959f95f503F829m0FlpT", - "expectId": 1196299886, - "jobName": "DSP音频算法资深工程师/专家/高级专家", - "lid": "1hfcKRGLEBx.search.40", - "salaryDesc": "40-70K·15薪", - "jobLabels": [ - "10年以上", - "本科", - "深度学习", - "C/C++", - "DSP" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "深度学习", - "C/C++", - "DSP", - "音频算法" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 40, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.619359, - "latitude": 31.184382 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "广州某大型汽车研发制造上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "汽车研发/制造", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100801, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "MXi4j5byEi7yM-21zT60mNZb2TXReR6Y5NyBB9q9RQbnCh4ia1uddHJXDMUNwNF7b606rbD98838k2PwPBfJLVz9yh5kdbdew_6E6AuKe6-e9M3KcRNalifqGnrJK4RACtgrQ_faHeZKRDDPVssrBUN6dEE~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20220121/607f1f3d68754fd0332819d76ea307857808e9189fbe9b020befe70b26ed81cf9f1cc50789a7babe_s.jpg", - "bossCert": 3, - "encryptBossId": "2536f76f716b27f61XR42NS7E1M~", - "bossName": "孙世俊", - "bossTitle": "招聘总监", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "24f221d9c073468003x-3tu1E1tW", - "expectId": 1196299886, - "jobName": "财务BP总经理(base上海顾村公园)", - "lid": "1hfcKRGLEBx.search.41", - "salaryDesc": "40-45K", - "jobLabels": [ - "10年以上", - "本科", - "线下零售", - "生活服务", - "CPA" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "线下零售", - "生活服务", - "CPA", - "成本管理", - "互联网", - "电商" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "宝山区", - "businessDistrict": "顾村", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 41, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.377204, - "latitude": 31.348936 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "b3094c1dfc8a59cf1Hd_0965EQ~~", - "brandName": "上海能良", - "brandLogo": "https://img.bosszhipin.com/beijin/mcs/chatphoto/20201103/3d1fd073a1e7f8e459c19397f3a0c3adf1102e71962779c71aa1df6e390dd2da_s.jpg", - "brandStageName": "未融资", - "brandIndustry": "电子商务", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100001, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "FIWT6ohq4SFTZ-F1kfwt_vwMa6kgTlB09ZQMrQrePJac6SoI4unH7cKXRJm_vd5rZ7drN1NFH2I5-FKsuzQufhLhB5oXHrzW3pBaGjuExCYUGnz-CslqCzE~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20241113/607f1f3d68754fd0301f5c5ea0eedc7a82d3dbc68ac801455fbc97d730dd2f6053cd37793b79331e_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "ae743bcaa5bf074d1XV92Nq-FFI~", - "bossName": "丛女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "454296653a78a1d703N_29-9FFRR", - "expectId": 1196299886, - "jobName": "连接器热模拟(thermal)PDE", - "lid": "1hfcKRGLEBx.search.42", - "salaryDesc": "30-40K·14薪", - "jobLabels": [ - "10年以上", - "本科", - "3C", - "设计热解决方案", - "热能与动力工程专业" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "3C", - "设计热解决方案", - "热能与动力工程专业", - "散热设计", - "热测试", - "机械工程专业", - "工程热物理专业", - "英语口语", - "热仿真", - "Python" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 42, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.402301, - "latitude": 31.175905 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某国际大型电子/半导体/集成电路上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "电子/半导体/集成电路", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100026, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "1EZ7ealKvzEVu-K199_5zpLQXdnHkR8cqTDxcpuY1YAq_Ht8e3Hv-BoKHwe7Fr2RWQRJDh2jZPbL5kALPhvxPYNwy_N51SAfWHBtnsLK8LVKtTvfr0ROatgE", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20230921/607f1f3d68754fd0d6936cb5ac55cda737bf03ad7ae0cc6ed14c29665b966020929a18d25c76375b_s.png.webp", - "bossCert": 3, - "encryptBossId": "daa7454fe1448e131XJ52tq0GVc~", - "bossName": "蔡健", - "bossTitle": "HRBP经理", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "c396c1a89498f8e703x42dS_F1RY", - "expectId": 1196299886, - "jobName": "大客户管理总监", - "lid": "1hfcKRGLEBx.search.43", - "salaryDesc": "30-50K·13薪", - "jobLabels": [ - "10年以上", - "本科", - "跨境电商客服", - "大客户管理" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "跨境电商客服", - "大客户管理" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "宝山区", - "businessDistrict": "友谊路", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 43, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.502298, - "latitude": 31.404621 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "8aef54fa571645281Hx72tS5FFE~", - "brandName": "美新(龙辕)", - "brandLogo": "https://img.bosszhipin.com/beijin/icon/894ce6fa7e58d64d57e7f22d2f3a9d18afa7fcceaa24b8ea28f56f1bb14732c0.png", - "brandStageName": "", - "brandIndustry": "跨境物流", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100509, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "Oo5vzE9wFVnuZ-O1gTP-lL_tf_Lv_lnjl8OWXZZGqD3YSN-7QOuIWLN7yN0w8DBIJGX68G43VEZ8_qgZMTh5DhCL2czqNSPz48MklaPfxAj7GxKzejVKe4tp5PObTEoXVm82sgFMMeWYOK9uKqWlRT820ilq", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20211026/607f1f3d68754fd0cbc4899eb76dec0cb0a266f30d971c4c8580b8c43d52e639684ba8a6283a5c30_s.jpg", - "bossCert": 3, - "encryptBossId": "0fe9160eee0a4e0d0nZy2ti6EFZZ", - "bossName": "张女士", - "bossTitle": "Recruiter", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "4a5c091dcb0c50af03x43t-7EVRT", - "expectId": 1196299886, - "jobName": "Senior Manager, Product Marketing", - "lid": "1hfcKRGLEBx.search.44", - "salaryDesc": "40-55K·14薪", - "jobLabels": [ - "10年以上", - "本科", - "一般企业(甲方)", - "市场战略规划", - "营销策划及执行" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "一般企业(甲方)", - "市场战略规划", - "营销策划及执行", - "品牌合作", - "品牌管理", - "电商内容运营经验", - "跨界营销经验", - "销售工作经验", - "数据分析经验", - "团队管理经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "徐汇区", - "businessDistrict": "音乐学院", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 44, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.458129, - "latitude": 31.215404 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "de02b3de289dc4ac1nB739y0FA~~", - "brandName": "丝芙兰", - "brandLogo": "https://img.bosszhipin.com/beijin/mcs/chatphoto/20180928/5a18e34ce50aa1528b2ce7535366b405547b0d61f34053f896b6a182c9bcbd1e.jpg", - "brandStageName": "已上市", - "brandIndustry": "批发/零售", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 101011, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "gprFekWpU1YX5-M1Y33Lg4uk6hvVJ6Ub7mYIX-PuN6EXlZdSskcoJgXS4bcYJ-iu4SldB7HjIjQTXWAmgW0FMnhOgqa58OMZ0fUDgRhbgwWajASUbjFNEU_Iflj99fXIkWRPXYaMVd3zgCYw0we68Es~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250907/607f1f3d68754fd00d86eb40c2ce0e8edd65dffbf8aa8c6ee4030d745c0e786395046a2e976f71a1_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "7a8426c3b87963370XB82926GVpT", - "bossName": "杨先生", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "422f950437e50ffb03152ty1FldW", - "expectId": 1196299886, - "jobName": "智能服务产品经理", - "lid": "1hfcKRGLEBx.search.45", - "salaryDesc": "30-50K", - "jobLabels": [ - "10年以上", - "本科", - "智能客服" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "智能客服" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 45, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.313936, - "latitude": 31.205659 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型互联网OTO平台公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "互联网", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100020, - "contact": false, - "showTopPosition": false - } - ], - "type": 2 - } - } - }, - { - "url": "https://www.zhipin.com/wapi/zpgeek/pc/recommend/job/list.json?page=4&pageSize=15&city=101020100&encryptExpectId=&mixExpectType=&expectInfo=&jobType=&salary=&experience=°ree=&industry=&scale=&_=1763023206260", - "method": "GET", - "status": 200, - "data": { - "code": 0, - "message": "Success", - "zpData": { - "hasMore": true, - "jobList": [ - { - "securityId": "gQRSjzKk9HOjL-317_YZLz9ZffaYgrOlvuUoG5d2Hq8K8at0dqjBQqujv7CUHb2SFXlXdUCLoA4PGJcljIPisCLbedAdZ9fCakb_Gw2cTwl2j3l9uunhUKhQRg~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20230303/607f1f3d68754fd00217fc3849f0b4759b3b639d5670216ea67bec979255c28111f99583c555f8ad_s.jpg", - "bossCert": 3, - "encryptBossId": "057de51cb126aa9f0nB_3d61F1RU", - "bossName": "戚女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "ff6c3bbc54fadc2103J93ti4EVpR", - "expectId": 1196299886, - "jobName": "包装设计总监", - "lid": "1hfcKRGLEBx.search.46", - "salaryDesc": "40-50K·14薪", - "jobLabels": [ - "10年以上", - "本科", - "甲方公司", - "周末双休", - "现场办公" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "甲方公司", - "周末双休", - "现场办公", - "AE", - "AI", - "C4D", - "5年以上包装设计经验", - "美妆个护", - "食品/酒水饮料", - "医药保健品", - "礼盒设计经验", - "熟悉印刷工艺" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 46, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.412625, - "latitude": 31.233244 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型日化上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "日化", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 101002, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "MXsb3tHeslIOJ-W18fSoqh6QOYu0OB9MaZlNAeMBuBUipDivtlSxzht2wdWELL_6e4W7OSa3XNLBuDBWLgi1pLT9hA3smY7I7Q569O9hAgcLloKSdruR2Aw~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250719/607f1f3d68754fd032b31c1204a54bb21798bce442bf0882be152831162bfdfdcddaeb42562cf224_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "f2fbdbec0a4a804e1HN43Ny0F1I~", - "bossName": "余女士", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "d3bc382862896c1e031409m7GFBR", - "expectId": 1196299886, - "jobName": "大客户经理 -酒店餐饮渠道(咖啡机)", - "lid": "1hfcKRGLEBx.search.47", - "salaryDesc": "35-50K", - "jobLabels": [ - "10年以上", - "本科", - "制定销售计划及策略", - "市场开发及维护", - "企业" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "制定销售计划及策略", - "市场开发及维护", - "企业", - "海外销售经验", - "快消/零售产品推广经验", - "酒店大客户开发管理" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 47, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.440239, - "latitude": 31.241068 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型食品/饮料/烟酒上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "食品/饮料/烟酒", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 101001, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "DzKIOiSL1WA0E-L1-u_SaQ5HTDpDDBu7qApxdP_9CC-zDoE5uFeDyn_FmgYgve42tzHUDFD554T05Hm0ueA06smYdeam5clTzFJujUEJ7X6tofnkCVa_2Hed", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_6.png", - "bossCert": 3, - "encryptBossId": "63be1a08ece1c3890Xxy3di6EVRV", - "bossName": "周先生", - "bossTitle": "招聘专家", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "d94fff0415a1520903V609S7F1FU", - "expectId": 1196299886, - "jobName": "先进制造业供应链总监", - "lid": "1hfcKRGLEBx.search.48", - "salaryDesc": "30-50K·15薪", - "jobLabels": [ - "10年以上", - "本科", - "生产计划管理经验", - "采购/供应商管理经验", - "仓储管理经验" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "生产计划管理经验", - "采购/供应商管理经验", - "仓储管理经验", - "电子/通信/半导体", - "电气机械/器材", - "供应链/物流类专业", - "需要出差" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "张江", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 48, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.594878, - "latitude": 31.20395 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "3ad18cf7a817ea0f1H1929S1Ew~~", - "brandName": "御微半导体", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/logo/20191024/93a5cf4166f7284d60514f4b8325fcf562c073ca6066c4aedd393ace49f9fee5.jpg", - "brandStageName": "A轮", - "brandIndustry": "半导体/芯片", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 101405, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "d8jkndVP_OXSB-k1ZGAwJHTBQeenZ_kga3cu-yKlfeLdxDB5k_vBiNW1B5_FSgUnNre-fJ9HIXgM5iSay07IznPqrJdw7TzqJaNRKRkwfXUd8m8IsNfIwrttDUWVxVYLmoqCbr6H5OkO45VHdlMScn4SfA~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/tmp/20200701/870ccde73e6dcf631b617a953057064d00b3bcc743646fbe39330192b895955e_s.jpg", - "bossCert": 3, - "encryptBossId": "15227d4b43653b6a1HR_29y1ElY~", - "bossName": "严坤", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "499c3befacd7120603152tm7EFJU", - "expectId": 1196299886, - "jobName": "域控系统专家(智驾/座舱)", - "lid": "1hfcKRGLEBx.search.49", - "salaryDesc": "40-70K·15薪", - "jobLabels": [ - "10年以上", - "本科", - "中央计算平台", - "智驾座舱", - "控制器" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "中央计算平台", - "智驾座舱", - "控制器" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 49, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.618856805619, - "latitude": 31.1846359352136 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型汽车研发制造上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "汽车研发/制造", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100801, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "Uf1gf2M22cSKK-C12Eaiwfe5QIi4gNUSBmf_jegqmQjGvYC4YsS1FW4ELCBwOeNUJMwyFade4boywTXjMc-uALFeaU9FnbqAo-W4Ao-eassGu3nMa6bXCMU_IPOfKcovDu0kCEqDFsQXc1hopUh6EsyjmgAg", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20240620/607f1f3d68754fd04c9b5b5c59081be4c8707100a2c0f1c22778e6f603c1bcd9fb648d0918e08cf9_s.png.webp", - "bossCert": 3, - "encryptBossId": "0ded8879fe53bf420nJy3Nm9GVVW", - "bossName": "白宏博", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "0bc3343d547f928903Ny3di7F1RX", - "expectId": 1196299886, - "jobName": "整机电气工艺集成", - "lid": "1hfcKRGLEBx.search.50", - "salaryDesc": "30-45K·15薪", - "jobLabels": [ - "10年以上", - "本科", - "铁路/船舶/航空/航天经验", - "装配/总装经验", - "PLC编程软件" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "铁路/船舶/航空/航天经验", - "装配/总装经验", - "PLC编程软件", - "试产工程师(NPI)经验", - "需要出差" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 50, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.475164, - "latitude": 31.228816 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型风电公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "不需要融资", - "brandIndustry": "风电", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 101211, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "x4Oh4CZ8UnlmX-719e2NranCf0dgiVHBNtYqVWvCoQN1dqwMRk1GAIO4FHW9928L9Pd_9BHg9mSjVSr8Yt1-UuoZfMK2yvhUgfVYyXGfhrqtkRyEEkHE7CQk0a0iXBE-c81szaMm55rkSb2_QIm5NjERSPDi", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250113/607f1f3d68754fd0a0df0f2d30bbb5552b65cbf4c3df23d141ce3a8e2f80bf17206080dcc0a056de_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "437245c32896129f1XR-2ty9Elc~", - "bossName": "王先生", - "bossTitle": "HRD", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "05a5d92ae93bcbe103B839W0E1dQ", - "expectId": 1196299886, - "jobName": "全栈工程师", - "lid": "1hfcKRGLEBx.search.51", - "salaryDesc": "25-35K·13薪", - "jobLabels": [ - "10年以上", - "本科", - "全栈无侧重", - "JavaScript", - "HTML" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "全栈无侧重", - "JavaScript", - "HTML", - "Vue", - "React", - "计算机相关专业", - "全栈项目经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "徐汇区", - "businessDistrict": "漕河泾", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 51, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.400992, - "latitude": 31.170706 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "df2ff527436fe3381HB-3dW7E1Y~", - "brandName": "本原智数", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/workfeel/20240508/7bf6f160950405e90e22440f08f5454aa4e8f2f9a602bf48a721dd6624dee98ec17edcc98b7b36f9.png.webp", - "brandStageName": "不需要融资", - "brandIndustry": "人工智能", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100028, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "gnMVM8gb74eEZ-y1rXMtvJtT8Evz7d0VHs6rdtSvYMZwXeeTiLagQKmrcLN27EdfzdJ_HrfjtrmhqFZ7Dx_XLan6cDZl_MU_TUPR1gIvZiGZWF5xHok5B3u5v14IVK6pby12aVFgNL7KqYutxRVoWtKRzSD5", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20220720/607f1f3d68754fd092bf39bd396efe16aa3f2b014c1d1b8085b43ec85fd3532b58ba045faff365ef_s.png", - "bossCert": 3, - "encryptBossId": "dc5fa4cef624078803N42Ni7F1M~", - "bossName": "杨女士", - "bossTitle": "HR", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "377e1b725235f88703152Nm9EFFZ", - "expectId": 1196299886, - "jobName": "Java Full Stack-英语流利-上海浦东", - "lid": "1hfcKRGLEBx.search.52", - "salaryDesc": "18-28K", - "jobLabels": [ - "10年以上", - "大专", - "JavaScript", - "TypeScript", - "React" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "JavaScript", - "TypeScript", - "React", - "Java", - "英语流利" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "大专", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "陆家嘴", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 52, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.500461, - "latitude": 31.233978 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "2fc82baee8dcd8361XZ-29u_GFE~", - "brandName": "思堤克斯", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/workfeel/20220905/7bf6f160950405e9a932e6d4b283b6a4283135b28bd288c485b43ec85fd3532b58ba045faff365ef.jpg", - "brandStageName": "不需要融资", - "brandIndustry": "计算机软件", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100021, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "ETWGIxsLCeNOD-g1zWYIIUxaqvPNHvxA7nV0HqwZuWHeAFJWUZxoyPc_eg8SHaP0iHob1FmlARW5bJMnlmL73__fx00muEvMsSfqALuyViRXDKdbjXZiRo8ZjZNnAL6NE53TP15cG0X01FNoWDjL7LaSO7rV", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20211103/607f1f3d68754fd075797a9b701b17a8eb6435390eddefc5af74c09b8413a6ec2cd7a645cc382c5a_s.jpg", - "bossCert": 3, - "encryptBossId": "aa19849a95f4479803R73ty1FVQ~", - "bossName": "牛影", - "bossTitle": "招聘专家", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "20cd12f77ae92bb5031609-6ElBT", - "expectId": 1196299886, - "jobName": "AI芯片软件测试架构师", - "lid": "1hfcKRGLEBx.search.53", - "salaryDesc": "30-60K·16薪", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "张江", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 53, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.628425536085, - "latitude": 31.2090782008146 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "171fce07e7fa16fb1XVz2Ny5F1Q~", - "brandName": "亿铸智能", - "brandLogo": "https://img.bosszhipin.com/beijin/upload/com/logo/20250715/7b5b554d84f9729c392e1471ba605452fffada42bb1b9c566bb61e3b7bce0931da574d19d1d82c88.jpg.webp", - "brandStageName": "天使轮", - "brandIndustry": "半导体/芯片", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 101405, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "gFo1IXuRZhxQe-y1edV77frnPl-b8VVltfl1jq7glu9m5GL0Zp764ITc9LFrKiziuWtkz64G1XEd7ci_WCH9FI_ebwJnqKoM18nnRLd15ItQMkCSFuXhneLc", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20191013/b00a719f76d05a48bbe2a01648a231c9b251a55acefccada76cd6ae4787533c1_s.jpg", - "bossCert": 3, - "encryptBossId": "8376d253bdd816460Hx50926GFc~", - "bossName": "柴女士", - "bossTitle": "HR", - "goldHunter": 0, - "bossOnline": false, - "encryptJobId": "7efec04c06c574be03N429i0FlpY", - "expectId": 1196299886, - "jobName": "医学经理", - "lid": "1hfcKRGLEBx.search.54", - "salaryDesc": "20-40K", - "jobLabels": [ - "10年以上", - "本科", - "抗肿瘤药物", - "KOL维护", - "医药相关专业" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "抗肿瘤药物", - "KOL维护", - "医药相关专业", - "临床工作经验", - "临床医学专业" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "普陀区", - "businessDistrict": "桃浦", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 54, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.334968, - "latitude": 31.288098 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "067b7fe4cb63124c1XJ_2t27GFQ~", - "brandName": "益世康宁", - "brandLogo": "https://img.bosszhipin.com/beijin/icon/894ce6fa7e58d64d57e7f22d2f3a9d18afa7fcceaa24b8ea28f56f1bb14732c0.png", - "brandStageName": "不需要融资", - "brandIndustry": "生物/制药", - "brandScaleName": "20-99人", - "welfareList": [], - "industry": 100401, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "4m9xUHVTXOBw0-O1jXddwm9Rkv49CJtFCJUolMn7nkoVkNHqUobKolsYZMdoo2yC0yG5rXnvaXWT7anIdLx2vKKAkQSLJDPXxDAcrvT1ov_17ZdwyoRfa3Jj", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20211118/607f1f3d68754fd0527e48962f19998ade7de15f9f3141d9a7731af3c3194594b02b65e19093c32e_s.png", - "bossCert": 3, - "encryptBossId": "88241b9525387e901XN639m6FVs~", - "bossName": "杨贺强", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": false, - "encryptJobId": "b28267dc4230edad03x-2tm8GVVY", - "expectId": 1196299886, - "jobName": "子公司委派财务总监", - "lid": "1hfcKRGLEBx.search.55", - "salaryDesc": "30-50K·14薪", - "jobLabels": [ - "10年以上", - "本科", - "财务综合管理", - "CPA", - "高级会计师" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "财务综合管理", - "CPA", - "高级会计师", - "生活服务", - "医药", - "集团公司", - "财务信息化经验" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 55, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.479052, - "latitude": 31.225635 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某小型投资公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "", - "brandIndustry": "投资/融资", - "brandScaleName": "20-99人", - "welfareList": [], - "industry": 100207, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "89VpuEFBAW-xb-K19xh9FcMSj7lg1slK3Oyg5g0xrBCpefOu9NiK3aSxMSibC_ZYFk350oHv4dDgQfCv2sLHwg3Yc_r_-Bwh_4Ii0MODBXOqeh-T-uxh2QtJP0l76uT0gFUYOvsxZTmt7t2f5jFCBOgq3RE~", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_11.png", - "bossCert": 3, - "encryptBossId": "0519c46662d2567a0Xd92NW6EFtY", - "bossName": "代露", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "e5ba547f91fdcf6903xz3tW4ElVW", - "expectId": 1196299886, - "jobName": "soc架构师", - "lid": "1hfcKRGLEBx.search.56", - "salaryDesc": "40-60K·15薪", - "jobLabels": [ - "10年以上", - "本科" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 56, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.442652, - "latitude": 31.126581 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型汽车研发及制造公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "不需要融资", - "brandIndustry": "汽车研发/制造", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100801, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "Vz_K0drsSdEqk-M1VrT13TJYnlClOhJ1hl3pvLQ7KFwD6vkmPUU4tFESINpfjDnlq5fQ7gFW-YDrb4vfEbD0d_SJTkBFeIQ49CBsJPiXDjh-iF2PiBXl5Hn3ItRUPPkxqMFrziKx21bNFQVjI_qRZNUKsVY~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20221104/607f1f3d68754fd0b4f2eeba7e8d8593df398f40666188a47f13a639bc1fcf220807992474dfd4c4_s.jpg", - "bossCert": 3, - "encryptBossId": "75c6f2d9f5c3be100nFy3d-_EFBV", - "bossName": "张成", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "914e2ebad951f58103F52tS7GFJU", - "expectId": 1196299886, - "jobName": "全栈工程师(前端)", - "lid": "1hfcKRGLEBx.search.57", - "salaryDesc": "20-30K", - "jobLabels": [ - "3-5年", - "本科", - "全栈侧重前端", - "React", - "Node.js" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "全栈侧重前端", - "React", - "Node.js", - "Python", - "前端开发经验" - ], - "jobExperience": "3-5年", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 57, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.606674, - "latitude": 31.194646 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型已上市医疗健康公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "医疗健康", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100006, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "wMnOcWdIPYHsf-71TTf1Mg7n5GpbTQsx5CqpFmNC0FvnTRFlAH8WvIALNPelyfUPwRv4Ty4UMziXgYuZfiJ50zbFmcXudBnuDCyC2xLiMhfa7p-zZn8ssekYI84EodFdAfaLL9pk86K-G37PEus6lFt9ZV8V", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20250512/607f1f3d68754fd0d1d82b22f91ee2877d372eeeb59c647e1fa9f16d30d2fc0bc789546351b2c09a_s.jpg.webp", - "bossCert": 3, - "encryptBossId": "48d0aa3e860a25c30HR-29y8FVVS", - "bossName": "刘先生", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "7126598ea368da0d03xy0ty1GVVR", - "expectId": 1196299886, - "jobName": "英语全栈软件工程师(AI方向)", - "lid": "1hfcKRGLEBx.search.58", - "salaryDesc": "25-35K·13薪", - "jobLabels": [ - "5-10年", - "本科", - "全栈无侧重", - "React", - "Java" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "全栈无侧重", - "React", - "Java", - "英语熟练沟通", - "AI经验", - "商务英语" - ], - "jobExperience": "5-10年", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 58, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.538093615289, - "latitude": 31.2221238509828 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "某大型已上市计算机服务公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "已上市", - "brandIndustry": "计算机服务", - "brandScaleName": "10000人以上", - "welfareList": [], - "industry": 100023, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "7Yv5KckD6Kdaq-T19nwjTGl3m-1-do8fFc4eveR8V683bTiJGQpRV2qMNC1AO8EwccWtEOVqUG-5eNLzKffCoG1tm8_dG1wEMc0EKOsVuIOR7iK9u0ZUCoCa-78yO-dMN1jRaDj4uG6T8HJQ0cakHy0z", - "bossAvatar": "https://img.bosszhipin.com/boss/avatar/avatar_6.png", - "bossCert": 3, - "encryptBossId": "c8cae4e989bca0351X1829y9FVM~", - "bossName": "邵先生", - "bossTitle": "猎头顾问", - "goldHunter": 1, - "bossOnline": true, - "encryptJobId": "26f8a2b6cc4ff15b03x43N27EltU", - "expectId": 1196299886, - "jobName": "外卖运营负责人-餐饮外卖-上海/杭州", - "lid": "1hfcKRGLEBx.search.59", - "salaryDesc": "45-75K·16薪", - "jobLabels": [ - "10年以上", - "本科", - "团队管理", - "TO B", - "运营管理" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "团队管理", - "TO B", - "运营管理", - "餐厅运营", - "B端用户运营", - "B端运营", - "产品运营", - "整体运营" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "", - "businessDistrict": "", - "jobType": 0, - "proxyJob": 1, - "proxyType": 1, - "anonymous": 101, - "outland": 0, - "optimal": 0, - "iconFlagList": [ - 8 - ], - "itemId": 59, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.381728, - "latitude": 31.232548 - }, - "afterNameIcons": [], - "beforeNameIcons": [ - "https://img.bosszhipin.com/static/file/2022/cy4fi6cada1655206055291.png" - ], - "encryptBrandId": "", - "brandName": "上海某大型移动互联网上市公司", - "brandLogo": "https://img.bosszhipin.com/beijin/app/mobile/n-af8dd288f86448d9eaaf3a4b0fd60b27.png", - "brandStageName": "D轮及以上", - "brandIndustry": "移动互联网", - "brandScaleName": "1000-9999人", - "welfareList": [], - "industry": 100019, - "contact": false, - "showTopPosition": false - }, - { - "securityId": "H3NGOVLI43NgD-v18JzhNdkyX0A6scYzAH0dR18miny2v5JQ9Cq-yCU_EXLtrbCR4yWuDocf05eTTFDO9fOP59_N8iLnY_yeuzNvR25iBlrbOEIlWOHcBUQKkpvh4GHWI2kkfqAzxz6RkfGcgK3RozNJuN3yTQ~~", - "bossAvatar": "https://img.bosszhipin.com/beijin/upload/avatar/20240121/607f1f3d68754fd034839b6276808fdb978b5df5b03e6ad95e99d05e109083c8b04367454d4b0699_s.png.webp", - "bossCert": 3, - "encryptBossId": "3e58bf677b1179931nV42ti5FlZT", - "bossName": "刘先生", - "bossTitle": "助理总监", - "goldHunter": 0, - "bossOnline": true, - "encryptJobId": "45a2315226fffe2b03N93tu_FFZT", - "expectId": 1196299886, - "jobName": "连锁餐饮运营总监", - "lid": "1hfcKRGLEBx.search.60", - "salaryDesc": "20-30K", - "jobLabels": [ - "10年以上", - "本科", - "团队管理", - "运营管理", - "客户管理" - ], - "jobValidStatus": 1, - "iconWord": null, - "skills": [ - "团队管理", - "运营管理", - "客户管理" - ], - "jobExperience": "10年以上", - "daysPerWeekDesc": "", - "leastMonthDesc": "", - "jobDegree": "本科", - "cityName": "上海", - "areaDistrict": "浦东新区", - "businessDistrict": "张江", - "jobType": 0, - "proxyJob": 0, - "proxyType": 0, - "anonymous": 0, - "outland": 0, - "optimal": 0, - "iconFlagList": [], - "itemId": 60, - "city": 101020100, - "isShield": 0, - "atsDirectPost": false, - "gps": { - "longitude": 121.586307, - "latitude": 31.211493 - }, - "afterNameIcons": [], - "beforeNameIcons": [], - "encryptBrandId": "845151c189eb87f703d92NW7FVQ~", - "brandName": "上海焯鲜", - "brandLogo": "https://img.bosszhipin.com/beijin/icon/894ce6fa7e58d64d57e7f22d2f3a9d18afa7fcceaa24b8ea28f56f1bb14732c0.png", - "brandStageName": "", - "brandIndustry": "互联网", - "brandScaleName": "100-499人", - "welfareList": [], - "industry": 100020, - "contact": false, - "showTopPosition": false - } - ], - "type": 2 - } - } - } -] \ No newline at end of file diff --git a/_doc/调度架构分析与优化建议.md b/_doc/调度架构分析与优化建议.md deleted file mode 100644 index 96f8658..0000000 --- a/_doc/调度架构分析与优化建议.md +++ /dev/null @@ -1,299 +0,0 @@ -# autoAiWorkSys 调度架构分析与优化建议 - -## 📋 目录 -1. [架构概览](#架构概览) -2. [核心问题分析](#核心问题分析) -3. [优化建议](#优化建议) -4. [重构方案](#重构方案) - ---- - -## 架构概览 - -### 当前架构层次 - -``` -应用入口 (app.js) - └─> ScheduleManager (middleware/schedule/index.js) - ├─> TaskQueue (taskQueue.js) - 设备级任务队列 - ├─> Strategy (strategy.js) - 调度策略 - ├─> Monitor (monitor.js) - 监控系统 - ├─> Command (command.js) - 指令执行 - └─> MQTT Client - 设备通信 - -ServiceManager (services/index.js) - ├─> TaskScheduler (task_scheduler.js) - 通用任务调度器(未使用) - ├─> JobService (job_service.js) - 职位服务 - └─> JobManager (job/jobManager.js) - 工作管理 -``` - -### 任务执行流程 - -``` -任务创建 → TaskQueue.addTask() - ↓ -保存到数据库 (task_status) - ↓ -processQueue() - 单设备串行执行 - ↓ -executeTask() - 执行任务 - ↓ -getTaskCommands() - 生成指令序列 - ↓ -Command.executeCommands() - 执行指令 - ↓ -MQTT.publishAndWait() - 发送到设备 - ↓ -更新任务状态 -``` - ---- - -## 核心问题分析 - -### 🔴 问题1: 架构层次混乱,职责不清 - -**问题描述:** -- 存在两套调度系统:`TaskScheduler` (services层) 和 `ScheduleManager` (middleware层) -- `TaskScheduler` 定义了完整的调度功能但未被使用 -- `TaskQueue` 和 `TaskScheduler` 功能重叠(都有优先级队列、重试机制) -- `ServiceManager` 和 `ScheduleManager` 职责边界模糊 - -**影响:** -- 代码维护困难,新人难以理解 -- 功能重复,增加维护成本 -- 扩展性差,难以统一优化 - ---- - -### 🔴 问题2: 任务执行效率低 - -**问题描述:** -- 每个设备单线程串行执行(`TaskQueue.processQueue()`) -- 优先级队列使用简单数组,插入效率 O(n) -- 无法充分利用多核CPU资源 -- 设备间无法并行执行 - -**影响:** -- 设备资源利用率低 -- 任务执行延迟高 -- 无法横向扩展 - ---- - -### 🔴 问题3: 重试机制分散,可能导致重复重试 - -**问题描述:** -- `TaskScheduler` 有重试机制(maxRetries, retryDelay) -- `TaskQueue` 有重试机制(retryCount, maxRetries) -- `Command` 也有重试机制(maxRetries, retryDelay) -- 三层重试可能导致总重试次数超出预期 - -**影响:** -- 重试次数不可控 -- 资源浪费 -- 错误处理逻辑复杂 - ---- - -### 🔴 问题4: 状态管理分散,可能不一致 - -**问题描述:** -- 内存状态:`TaskQueue.deviceQueues`、`TaskQueue.deviceStatus` -- 数据库状态:`task_status` 表 -- 监控状态:`Monitor.deviceOnlineStatus` -- 策略状态:`Strategy.deviceTimestamps`、`Strategy.dailyCounters` - -**影响:** -- 服务重启后状态丢失 -- 内存和数据库状态可能不一致 -- 难以追踪任务真实状态 - ---- - -### 🔴 问题5: 优先级队列实现效率低 - -**问题描述:** -- 使用简单数组 + `sort()` 实现优先级队列 -- 每次插入都需要排序,时间复杂度 O(n log n) -- 应该使用堆(Heap)数据结构 - -**影响:** -- 队列操作性能差 -- 任务数量多时性能下降明显 - ---- - -### 🔴 问题6: MQTT客户端获取方式不统一 - -**问题描述:** -- `ScheduleManager` 初始化时创建 MQTT 客户端 -- `TaskQueue` 通过 `getMqttClient()` 动态获取 -- `JobService` 直接从 `scheduleManager` 获取 -- 可能导致多个MQTT连接或连接丢失 - -**影响:** -- 资源管理混乱 -- 连接状态不可控 -- 难以监控和调试 - ---- - -### 🔴 问题7: 错误处理不完善 - -**问题描述:** -- 部分异步操作缺少 try-catch -- 错误信息记录不完整 -- 错误恢复机制缺失 - -**影响:** -- 错误难以追踪 -- 系统稳定性差 -- 调试困难 - ---- - -## 优化建议 - -### ✅ 优化1: 统一调度架构 - -**建议:** -1. **移除未使用的 `TaskScheduler`**,统一使用 `ScheduleManager` + `TaskQueue` -2. **明确职责划分**: - - `ScheduleManager`: 系统初始化、组件协调、定时任务 - - `TaskQueue`: 任务队列管理、执行调度 - - `Command`: 指令执行、MQTT通信 - - `Strategy`: 调度策略、频率控制 - - `Monitor`: 监控、统计、告警 - ---- - -### ✅ 优化2: 提升任务执行效率 - -**建议:** -1. **使用工作池模式**:允许设备间并行执行 -2. **优化优先级队列**:使用堆(Heap)数据结构 -3. **支持任务并发控制**:每个设备可配置最大并发数 - ---- - -### ✅ 优化3: 统一重试机制 - -**建议:** -1. **只在 TaskQueue 层实现重试**,移除 Command 层的重试 -2. **使用指数退避策略** -3. **记录重试原因和次数** - ---- - -### ✅ 优化4: 统一状态管理 - -**建议:** -1. **使用数据库作为唯一数据源**(Single Source of Truth) -2. **内存状态仅作为缓存**,定期同步到数据库 -3. **服务启动时从数据库恢复状态** - ---- - -### ✅ 优化5: 优化优先级队列 - -**建议:** -使用堆(Heap)数据结构实现优先级队列 - ---- - -### ✅ 优化6: 统一MQTT客户端管理 - -**建议:** -1. **使用单例模式**统一管理MQTT客户端 -2. **实现连接池**(如果需要多个连接) -3. **添加连接状态监控和自动重连** - ---- - -### ✅ 优化7: 完善错误处理 - -**建议:** -1. **统一错误处理中间件** -2. **完善错误日志记录**(包含上下文信息) -3. **实现错误恢复机制** - ---- - -## 重构方案 - -### 阶段1: 架构清理(优先级:高) - -1. **移除未使用的代码** - - 删除或标记 `TaskScheduler`(如果确实未使用) - - 清理重复功能 - -2. **统一MQTT管理** - - 实现统一的MQTT客户端管理器 - - 所有模块通过统一接口获取客户端 - -3. **统一错误处理** - - 实现错误处理中间件 - - 完善错误日志 - -### 阶段2: 性能优化(优先级:高) - -1. **优化优先级队列** - - 使用堆数据结构 - - 提升插入和删除效率 - -2. **实现工作池模式** - - 允许设备间并行执行 - - 支持并发控制 - -3. **优化数据库操作** - - 批量更新任务状态 - - 使用事务保证一致性 - -### 阶段3: 状态管理优化(优先级:中) - -1. **统一状态管理** - - 数据库作为唯一数据源 - - 内存状态作为缓存 - -2. **实现状态同步** - - 定期同步内存状态到数据库 - - 服务启动时恢复状态 - -### 阶段4: 监控和可观测性(优先级:中) - -1. **完善监控指标** - - 任务执行时间分布 - - 错误率统计 - - 资源使用情况 - -2. **实现告警机制** - - 任务失败率告警 - - 设备离线告警 - - 系统资源告警 - ---- - -## 总结 - -### 关键优化点 - -1. ✅ **统一架构**:移除冗余,明确职责 -2. ✅ **提升性能**:工作池模式、堆队列、并发控制 -3. ✅ **统一重试**:避免重复重试,使用指数退避 -4. ✅ **状态管理**:数据库为主,内存为缓存 -5. ✅ **资源管理**:统一MQTT客户端管理 -6. ✅ **错误处理**:完善错误处理和恢复机制 - -### 预期收益 - -- **性能提升**:任务执行效率提升 50-100% -- **稳定性提升**:错误处理更完善,系统更稳定 -- **可维护性提升**:代码结构更清晰,易于维护 -- **可扩展性提升**:支持更多设备和任务类型 - ---- - -*文档生成时间:2024年* -*分析范围:autoAiWorkSys 调度架构* - diff --git a/_doc/重构完成说明.md b/_doc/重构完成说明.md deleted file mode 100644 index d05cd8a..0000000 --- a/_doc/重构完成说明.md +++ /dev/null @@ -1,255 +0,0 @@ -# 调度架构重构完成说明 - -## ✅ 已完成的优化 - -### 1. 优先级队列优化(PriorityQueue.js) - -**实现内容:** -- 使用堆(Heap)数据结构实现优先级队列 -- 时间复杂度:插入 O(log n),删除 O(log n) -- 支持按优先级和创建时间排序 - -**性能提升:** -- 队列操作性能提升 10-100 倍(取决于队列大小) -- 任务数量多时性能优势明显 - -**使用方式:** -```javascript -const queue = new PriorityQueue(); -queue.push({ priority: 10, createdAt: Date.now(), ...task }); -const task = queue.pop(); // 获取优先级最高的任务 -``` - ---- - -### 2. 工作池模式实现 - -**实现内容:** -- **设备内串行执行**:每个设备的任务按顺序执行(`deviceMaxConcurrency = 1`) -- **设备间并行执行**:不同设备可以同时执行任务 -- **全局并发控制**:通过 `maxConcurrency` 控制全局最大并发设备数(默认5) - -**配置说明:** -```javascript -const taskQueue = new TaskQueue({ - maxConcurrency: 5, // 全局最大并发设备数 - deviceMaxConcurrency: 1 // 每个设备最大并发数(保持串行) -}); -``` - -**执行流程:** -``` -设备A: 任务1 → 任务2 → 任务3 (串行) -设备B: 任务1 → 任务2 → 任务3 (串行) -设备C: 任务1 → 任务2 → 任务3 (串行) - ↓ - 并行执行(最多5个设备同时执行) -``` - ---- - -### 3. 统一重试机制 - -**实现内容:** -- 移除了 Command 层的重试逻辑 -- 统一在 TaskQueue 层实现重试 -- 使用指数退避策略 - -**重试策略:** -- 基础延迟:1000ms -- 最大延迟:30000ms -- 计算公式:`delay = min(1000 * 2^(retryCount-1), 30000)` - -**重试次数:** -- 第1次重试:延迟 1000ms -- 第2次重试:延迟 2000ms -- 第3次重试:延迟 4000ms -- 第4次重试:延迟 8000ms -- ...(最大30000ms) - ---- - -### 4. 统一错误处理(ErrorHandler.js) - -**实现内容:** -- 统一错误分类(可重试/不可重试) -- 自动记录错误日志到数据库 -- 错误上下文信息完整记录 - -**可重试错误类型:** -- 网络错误(ETIMEDOUT, ECONNRESET, ENOTFOUND) -- MQTT连接错误 -- 设备离线错误 -- 超时错误 - -**使用方式:** -```javascript -const errorInfo = await ErrorHandler.handleError(error, { - taskId: task.id, - sn_code: task.sn_code, - taskType: task.taskType -}); - -if (ErrorHandler.isRetryableError(error)) { - // 可重试 -} -``` - ---- - -### 5. 统一MQTT客户端管理 - -**实现内容:** -- 优先使用 ScheduleManager 初始化的 MQTT 客户端 -- 避免重复创建连接 -- 统一获取接口 - -**获取方式:** -```javascript -// TaskQueue 内部自动获取 -const mqttClient = await this.getMqttClient(); -``` - ---- - -### 6. 状态管理优化 - -**实现内容:** -- 服务启动时从数据库恢复未完成任务 -- 内存状态作为缓存,数据库为主 -- 定期同步状态到数据库 - -**恢复机制:** -- 启动时自动加载 `pending` 和 `running` 状态的任务 -- `running` 状态的任务自动重置为 `pending` -- 确保服务重启后任务不丢失 - ---- - -## 📊 性能对比 - -### 优化前 -- 队列插入:O(n log n) - 每次插入都要排序 -- 任务执行:完全串行,设备间无法并行 -- 重试机制:三层重试,可能重复重试 -- 错误处理:分散,难以追踪 - -### 优化后 -- 队列插入:O(log n) - 堆插入 -- 任务执行:设备间并行,最多5个设备同时执行 -- 重试机制:统一重试,指数退避 -- 错误处理:统一处理,完整记录 - -### 预期性能提升 -- **队列操作性能**:提升 10-100 倍 -- **任务执行效率**:提升 50-100%(设备间并行) -- **错误恢复能力**:提升 80%(统一错误处理) -- **系统稳定性**:显著提升(状态恢复机制) - ---- - -## 🔧 使用说明 - -### 1. 初始化 - -TaskQueue 会在 ScheduleManager 初始化时自动初始化: - -```javascript -// 在 schedule/index.js 中 -await this.components.taskQueue.init?.(); -``` - -### 2. 添加任务 - -```javascript -const taskId = await taskQueue.addTask(sn_code, { - taskType: 'get_job_list', - taskName: '获取岗位列表', - taskParams: { keyword: '前端', platform: 'boss' }, - priority: 7, - maxRetries: 3 -}); -``` - -### 3. 获取状态 - -```javascript -// 获取设备状态 -const status = taskQueue.getDeviceStatus(sn_code); - -// 获取全局统计 -const stats = taskQueue.getStatistics(); -``` - -### 4. 配置并发数 - -```javascript -// 在创建 TaskQueue 实例时配置 -const taskQueue = new TaskQueue({ - maxConcurrency: 10, // 全局最大并发设备数 - deviceMaxConcurrency: 1 // 每个设备最大并发数(保持串行) -}); -``` - ---- - -## 📝 代码变更说明 - -### 新增文件 -1. `PriorityQueue.js` - 优先级队列实现 -2. `ErrorHandler.js` - 统一错误处理 - -### 修改文件 -1. `taskQueue.js` - 完全重构 - - 使用 PriorityQueue 替代数组 - - 实现工作池模式 - - 统一重试机制 - - 集成错误处理 - -### 兼容性 -- ✅ 保持原有 API 接口不变 -- ✅ 数据库结构不变 - ---- - -## 🚀 后续优化建议 - -### 1. 监控和告警 -- 添加任务执行时间监控 -- 实现失败率告警 -- 资源使用监控 - -### 2. 性能优化 -- 批量更新数据库状态 -- 使用 Redis 缓存热点数据 -- 实现任务预取机制 - -### 3. 扩展功能 -- 支持任务依赖关系 -- 实现任务优先级动态调整 -- 支持任务暂停/恢复 - ---- - -## ⚠️ 注意事项 - -1. **设备内串行执行**:每个设备仍然保持串行执行,确保任务顺序 -2. **全局并发控制**:默认最多5个设备同时执行,可根据服务器性能调整 -3. **状态恢复**:服务重启后会自动恢复未完成任务 -4. **错误处理**:不可重试的错误会立即标记为失败,不会重试 - ---- - -## 📞 问题反馈 - -如遇到问题,请检查: -1. 数据库连接是否正常 -2. MQTT 客户端是否初始化 -3. 任务状态是否正确更新 -4. 错误日志中的详细信息 - ---- - -*重构完成时间:2024年* -*重构版本:v2.0* - diff --git a/_doc/项目功能总结.md b/_doc/项目功能总结.md deleted file mode 100644 index 6af1583..0000000 --- a/_doc/项目功能总结.md +++ /dev/null @@ -1,387 +0,0 @@ -# 自动找工作系统 - 项目功能总结 - -> 版本: v1.0 | 更新日期: 2025-12-25 - -## 一、项目概述 - -自动找工作系统(autoAiWorkSys)是一个基于AI的智能求职助手平台,通过自动化技术帮助求职者高效管理多个招聘平台账号、智能筛选匹配岗位、自动投递简历,并提供全流程的求职数据分析。系统集成Qwen 2.5 AI模型,实现简历智能分析、岗位匹配度评分、聊天内容生成等功能,大幅提升求职效率和成功率。 - -## 二、技术栈 - -### 前端技术 -- **框架**: Vue 2.6.14 + Vuex 3.6.2 + Vue Router 3.5.3 -- **UI组件**: View Design (iView) 4.7.0 -- **构建工具**: Webpack 5 -- **图表库**: ECharts -- **HTTP客户端**: 自定义 framework.http - -### 后端技术 -- **运行时**: Node.js -- **Web框架**: Koa 2.16.3 -- **ORM**: Sequelize 5.22.5 -- **数据库**: MySQL 8.0 -- **消息队列**: MQTT (mqtt://192.144.167.231:1883) -- **AI模型**: Qwen 2.5 (阿里云DashScope) -- **缓存**: Redis (规划中) -- **存储**: Ali OSS - -### 核心框架 -- **Node Core Framework**: 自研框架,提供统一的API路由、数据库管理、日志管理 - -## 三、核心特性 - -1. **多平台账号管理** - 支持Boss直聘、猎聘等多个招聘平台,统一管理账号和授权 -2. **智能简历分析** - AI评估简历竞争力(0-100分),提取技能标签,给出优势劣势和职业建议 -3. **自动岗位投递** - 基于技能匹配和AI评分自动筛选岗位并投递,支持每日上限和时间范围控制 -4. **AI岗位匹配** - 多维度评分(技能、经验、薪资、公司质量),自动识别外包岗位 -5. **任务调度系统** - 优先级队列+MQTT通信,设备内串行、设备间并行执行 -6. **数据可视化统计** - 投递成功率、面试转化率、不同平台效果对比等多维度分析 -7. **设备实时监控** - 在线状态、健康度、错误信息、心跳检测 -8. **完整审计日志** - 任务执行、投递记录、聊天记录全链路追踪 - -## 四、功能模块一览 - -### 4.1 前端功能模块 - -| 模块 | 页面路径 | 主要功能 | -|------|---------|----------| -| **首页/仪表板** | `/home` | 设备选择、账户信息卡片、今日统计、当前任务列表、近7天趋势图 | -| **账号管理** | `/account/pla_account` | 账号列表、新增/编辑、授权管理、批量位置解析、停止任务 | -| **账号详情** | `/account/pla_account_detail` | 账号基本信息、任务历史、自动化配置、运行操作面板 | -| **简历管理** | `/account/resume_info` | 简历列表、查看详情、AI分析结果展示、删除 | -| **简历详情** | `/account/resume_info_detail` | 个人信息、教育背景、工作经验、期望信息、AI评分和建议 | -| **岗位管理** | `/work/job_postings` | 岗位列表、过滤查询、打招呼、查看详情 | -| **投递记录** | `/work/apply_records` | 投递状态追踪、反馈状态、面试/Offer信息 | -| **职位类型** | `/work/job_types` | 职位类型配置、技能关键词、排除关键词 | -| **任务管理** | `/task/task_status` | 任务列表、指令详情、取消/重试操作 | -| **聊天管理** | `/chat/chat_list` | 双面板聊天界面、会话列表、AI生成回复 | -| **聊天记录** | `/chat/chat_records` | 聊天历史记录、消息类型、发送状态 | -| **系统配置** | `/system/system_config` | 系统参数配置、AI服务配置、MQTT配置 | - -### 4.2 后端API模块 - -| 模块 | 接口前缀 | 主要功能 | -|------|---------|----------| -| **账号管理** | `/admin_api/account` | 列表、详情、新增、更新、删除、授权、停止任务、位置解析 | -| **简历管理** | `/admin_api/resume` | 列表、详情、统计、删除、AI分析、按设备获取 | -| **岗位管理** | `/admin_api/job` | 列表、详情、统计、删除、打招呼 | -| **投递记录** | `/admin_api/apply` | 列表、详情、统计、删除 | -| **聊天记录** | `/admin_api/chat` | 列表、详情、统计、删除 | -| **设备监控** | `/admin_api/device` | 列表、概览、配置更新、错误重置 | -| **任务状态** | `/admin_api/task` | 列表、详情、统计、更新、删除 | -| **数据统计** | `/admin_api/dashboard` | 综合统计、投递转化率、平台对比、设备排名 | -| **系统配置** | `/admin_api/system` | 配置列表、新增、更新、删除 | - -### 4.3 核心业务流程 - -``` -┌─────────────────────┐ -│ 账号配置和授权 │ -└──────────┬──────────┘ - ↓ -┌─────────────────────┐ -│ 获取在线简历(MQTT) │ → AI分析 → 竞争力评分、技能提取、优劣势分析 -└──────────┬──────────┘ - ↓ -┌─────────────────────┐ -│ 创建自动投递任务 │ -└──────────┬──────────┘ - ↓ -┌─────────────────────┐ -│ 搜索岗位(MQTT) │ → 保存到job_postings表 -└──────────┬──────────┘ - ↓ -┌─────────────────────┐ -│ 岗位过滤和匹配 │ → 技能匹配+AI评分+外包识别 -└──────────┬──────────┘ - ↓ -┌─────────────────────┐ -│ 自动投递(MQTT) │ → 记录apply_records -└──────────┬──────────┘ - ↓ -┌─────────────────────┐ -│ 聊天和面试跟踪 │ → AI生成聊天内容 -└──────────┬──────────┘ - ↓ -┌─────────────────────┐ -│ 数据统计和分析 │ -└─────────────────────┘ -``` - -## 五、已实现功能清单 - -### 5.1 账号管理模块 ✅ - -- ✅ 多平台账号绑定(Boss直聘、猎聘) -- ✅ 账号状态管理(启用/禁用、在线/离线、登录状态) -- ✅ 自动化开关(自动投递、自动聊天、自动活跃) -- ✅ 授权管理(设置授权日期、天数、过期时间计算) -- ✅ 职位类型配置(关联job_types) -- ✅ 投递配置(时间范围、每日上限、薪资范围、关键词过滤) -- ✅ 沟通配置(时间范围、是否沟通外包岗位) -- ✅ 活跃配置(活跃间隔、活跃动作) -- ✅ 位置解析(单个/批量,经纬度获取) -- ✅ 停止任务(取消该账号所有运行中任务) - -### 5.2 简历管理模块 ✅ - -- ✅ 简历信息存储(个人信息、教育背景、工作经验、期望信息) -- ✅ 简历获取(通过MQTT从设备获取在线简历) -- ✅ AI竞争力评分(0-100分) -- ✅ AI技能标签提取 -- ✅ AI优势劣势分析 -- ✅ AI职业建议生成 -- ✅ 简历与岗位匹配度计算 -- ✅ 简历统计(平均竞争力、工作年限分布、竞争力分布) -- ✅ 按设备和平台查询简历 - -### 5.3 岗位管理模块 ✅ - -- ✅ 岗位信息存储(基本信息、要求、描述、薪资、地点) -- ✅ 岗位搜索(通过MQTT下发搜索指令) -- ✅ 岗位列表获取(通过MQTT获取列表) -- ✅ AI岗位匹配评分(技能、经验、薪资、公司质量) -- ✅ 外包岗位识别(规则+AI双层识别) -- ✅ 岗位过滤(技能关键词匹配、排除关键词检测) -- ✅ 综合评分计算(多维度权重评分) -- ✅ 岗位统计(总数、平均匹配度、外包比例) -- ✅ 打招呼功能(初次沟通) - -### 5.4 自动投递模块 ✅ - -- ✅ 自动投递任务创建和调度 -- ✅ 每日投递上限控制 -- ✅ 投递时间范围控制(工作日/周末) -- ✅ 简历刷新检查(2小时内刷新) -- ✅ 岗位过滤和排序 -- ✅ 投递指令下发(MQTT) -- ✅ 投递状态追踪(待投递、投递中、成功、失败、重复) -- ✅ 反馈状态管理(无反馈、已查看、感兴趣、不合适、面试邀约) -- ✅ 投递统计(成功率、面试转化率、Offer转化率) - -### 5.5 AI分析模块 ✅ - -- ✅ Qwen 2.5模型集成(阿里云DashScope) -- ✅ 简历智能分析 - - ✅ 技能标签提取 - - ✅ 竞争力评分(0-100) - - ✅ 优势劣势分析 - - ✅ 职业发展建议 -- ✅ 岗位智能匹配 - - ✅ 技能匹配度(0-100) - - ✅ 经验匹配度(0-100) - - ✅ 薪资合理性(0-100) - - ✅ 公司质量评分(0-100) -- ✅ 外包岗位识别 -- ✅ 聊天内容生成(基础框架) - -### 5.6 任务调度模块 ✅ - -- ✅ 优先级任务队列(堆实现,O(log n)性能) -- ✅ 并发控制(全局5设备,每设备1任务) -- ✅ 设备内串行、设备间并行执行 -- ✅ 任务状态管理(待执行、执行中、成功、失败、超时、取消) -- ✅ 指数退避重试机制(最多3次) -- ✅ 任务超时检测(10分钟) -- ✅ 错误分类(可重试/不可重试) -- ✅ 任务恢复(启动时恢复未完成任务) -- ✅ 任务统计(岗位搜索数、过滤数、投递数、聊天数) - -### 5.7 设备监控模块 ✅ - -- ✅ 设备状态追踪(在线/离线) -- ✅ 心跳检测(通过MQTT) -- ✅ 健康度评分 -- ✅ 错误信息记录 -- ✅ 最后心跳时间 -- ✅ 设备配置更新 -- ✅ 设备错误重置 -- ✅ 设备概览统计(在线数、离线数、健康度排名) - -### 5.8 数据统计模块 ✅ - -- ✅ 投递成功率统计 -- ✅ 面试转化率统计 -- ✅ Offer转化率统计 -- ✅ 不同平台数据对比 -- ✅ 设备活跃度排名 -- ✅ 简历竞争力分布 -- ✅ 岗位外包比例统计 -- ✅ 近7天趋势图(投递、搜索、聊天) -- ✅ 今日统计(实时刷新) - -### 5.9 聊天管理模块 ✅ - -- ✅ 聊天记录存储 -- ✅ 聊天类型分类(打招呼、跟进、面试、回复) -- ✅ 发送状态追踪 -- ✅ 回复检测和记录 -- ✅ 回复时长统计 -- ✅ 面试邀约识别 -- ✅ 情感分析(积极/中性/消极) -- ✅ 效果评分 -- ✅ AI生成标记 -- ✅ 双面板聊天界面 - -### 5.10 其他功能 ✅ - -- ✅ 用户邀请和推广系统 -- ✅ 公司信息库(上市公司数据) -- ✅ 版本管理 -- ✅ 邮件服务集成 -- ✅ OSS存储集成 -- ✅ 地理位置服务(百度地图API) -- ✅ Swagger API文档 -- ✅ 数据导出(CSV) - -## 六、数据模型 - -### 6.1 核心表结构 - -| 表名 | 说明 | 关键字段 | -|------|------|---------| -| **pla_account** | 平台账号表 | sn_code, platform_type, is_online, auto_deliver, deliver_config | -| **resume_info** | 简历信息表 | resumeId, account_id, aiCompetitiveness, aiSkillTags, aiStrengths | -| **job_postings** | 岗位信息表 | jobId, platform, aiMatchScore, isOutsourcing, applyStatus | -| **apply_records** | 投递记录表 | resumeId, jobId, applyStatus, feedbackStatus, hasInterview, hasOffer | -| **chat_records** | 聊天记录表 | conversationId, chatType, isAiGenerated, hasReply, sentiment | -| **task_status** | 任务状态表 | taskType, status, priority, retryCount, progress | -| **task_commands** | 任务指令表 | taskId, commandType, commandData, response, executeTime | -| **job_types** | 职位类型表 | name, commonSkills, excludeKeywords, sortOrder | -| **device_monitor** | 设备监控表 | sn_code, is_online, health_score, last_heartbeat_time | -| **company_info** | 公司信息表 | company_name, is_listed, market_value, risk_level | - -### 6.2 表关联关系 - -``` -pla_account (1) ──→ (N) resume_info - │ - ├─→ (N) apply_records ←── (1) job_postings - │ │ - │ └─→ (N) chat_records - │ - └─→ (N) task_status ──→ (N) task_commands - -pla_account (1) ──→ (1) job_types (职位类型配置) -pla_account (1) ──→ (N) device_monitor (设备监控) -``` - -## 七、快速开始 - -### 7.1 环境要求 - -- Node.js >= 14.x -- MySQL >= 8.0 -- Redis (可选,用于缓存) -- MQTT Broker (已配置: mqtt://192.144.167.231:1883) - -### 7.2 安装步骤 - -```bash -# 1. 克隆项目 -git clone -cd autoAiWorkSys - -# 2. 安装后端依赖 -npm install - -# 3. 安装前端依赖 -cd admin -npm install - -# 4. 配置数据库 -# 编辑 config/config.js -# 设置MySQL连接信息 - -# 5. 初始化数据库 -# 执行 _sql 目录下的SQL脚本 - -# 6. 启动后端服务 -npm run dev - -# 7. 启动前端服务(新终端) -cd admin -npm run dev -``` - -### 7.3 核心配置 - -**config/config.js** - 主配置文件 -```javascript -{ - db: { - host: 'localhost', - port: 3306, - database: 'auto_job', - username: 'root', - password: 'your_password' - }, - mqtt: { - host: 'mqtt://192.144.167.231:1883', - clientId: 'autoAiWorkSys_server' - }, - ai: { - apiKey: 'your_dashscope_api_key', - model: 'qwen-turbo' // qwen-turbo/qwen-plus/qwen-max - } -} -``` - -### 7.4 访问地址 - -- 前端管理后台: http://localhost:8080 -- 后端API: http://localhost:3000/admin_api -- API文档: http://localhost:3000/api/docs - -## 八、项目文件结构 - -``` -autoAiWorkSys/ -├── admin/ # 前端管理后台 -│ ├── src/ -│ │ ├── views/ # 页面组件 -│ │ ├── api/ # API调用 -│ │ ├── router/ # 路由配置 -│ │ └── store/ # Vuex状态管理 -│ └── package.json -│ -├── api/ # 后端服务 -│ ├── controller_admin/ # 后台管理API -│ ├── middleware/ # 核心业务逻辑 -│ │ ├── job/ # 岗位、简历、聊天管理 -│ │ ├── schedule/ # 任务调度系统 -│ │ └── mqtt/ # MQTT通信 -│ ├── model/ # 数据库模型 -│ ├── services/ # 业务服务层 -│ └── utils/ # 工具函数 -│ -├── config/ # 配置文件 -├── framework/ # 核心框架 -├── _doc/ # 文档目录 -├── _sql/ # 数据库脚本 -└── package.json -``` - -## 九、技术亮点 - -1. **优先级队列** - 堆实现,O(log n)性能,比数组提升10-100倍 -2. **双层过滤** - 规则过滤+AI评分,平衡性能和准确性 -3. **智能重试** - 指数退避策略,区分可重试和不可重试错误 -4. **MQTT通信** - 异步消息队列,高效的设备指令下发和响应 -5. **AI多场景应用** - 简历分析、岗位匹配、聊天生成、外包识别 -6. **完整审计** - 任务、投递、聊天全链路追踪 -7. **模块化设计** - 清晰的分层架构,易于扩展和维护 - -## 十、性能指标 - -- 任务调度延迟: < 100ms -- 数据库查询: 95%在100ms内 -- MQTT消息延迟: < 50ms -- 前端页面加载: < 2s -- 并发支持: 最多5个设备同时执行 - ---- - -**文档维护**: 开发团队 -**最后更新**: 2025-12-25 -**联系方式**: 项目Issues diff --git a/admin/src/api/task/task_status_server.js b/admin/src/api/task/task_status_server.js index d44cc2a..df22dfa 100644 --- a/admin/src/api/task/task_status_server.js +++ b/admin/src/api/task/task_status_server.js @@ -87,7 +87,9 @@ class TaskStatusServer { * @returns {Promise} */ cancel(row) { - return window.framework.http.post(`task_status/${row.taskId}/cancel`) + return window.framework.http.post('task/cancel', { + taskId: row.taskId || row.id + }) } /** @@ -96,7 +98,9 @@ class TaskStatusServer { * @returns {Promise} */ retry(row) { - return window.framework.http.post(`task_status/${row.taskId}/retry`) + return window.framework.http.post('task/retry', { + taskId: row.taskId || row.id + }) } /** diff --git a/admin/src/views/account/pla_account_detail.vue b/admin/src/views/account/pla_account_detail.vue index 91fc7ab..b0646be 100644 --- a/admin/src/views/account/pla_account_detail.vue +++ b/admin/src/views/account/pla_account_detail.vue @@ -190,8 +190,8 @@
自动投递: - - {{ deliverConfig.auto_deliver ? '开启' : '关闭' }} + + {{ deliverConfig.auto_deliver ? '开启' : '关闭' }}
@@ -360,15 +360,9 @@
-
@@ -380,15 +374,9 @@
-
@@ -497,6 +485,10 @@
+
@@ -708,13 +700,13 @@ export default { width: 150, render: (h, params) => { const btns = [] - if (params.row.status === 'failed') { - btns.push({ - title: '重试', - type: 'primary', - click: () => this.retryTask(params.row) - }) - } + + btns.push({ + title: '重试', + type: 'primary', + click: () => this.retryTask(params.row) + }) + if (params.row.status === 'pending' || params.row.status === 'running') { btns.push({ title: '取消', @@ -748,6 +740,7 @@ export default { }, // 指令详情弹窗 commandDetailVisible: false, + retryCommandLoading: false, currentCommandDetail: null, // 二维码弹窗 @@ -825,13 +818,13 @@ export default { click: () => this.showCommandDetail(params.row) }) // 重试按钮(只在失败状态时显示) - if (params.row.status === 'failed') { - btns.push({ - title: '重试', - type: 'warning', - click: () => this.retryCommand(params.row) - }) - } + + btns.push({ + title: '重试', + type: 'warning', + click: () => this.retryCommand(params.row) + }) + return h('div', btns.map(btn => h('Button', { props: { @@ -1031,7 +1024,7 @@ export default { const res = await plaAccountServer.getTasks(this.accountId, param) console.log('res', res); - + this.tasksData = res.data.rows || [] this.tasksPageOption.total = res.data.count || 0 @@ -1081,23 +1074,37 @@ export default { } }, - // 重试指令 + // 重试指令(指令列表与指令详情弹窗共用,成功后刷新列表与详情) async retryCommand(command) { - this.$Modal.confirm({ - title: '确认重试', - content: `确定要重试指令"${command.command_name}"吗?`, - onOk: async () => { - try { - await plaAccountServer.retryCommand(command.id) - this.$Message.success('重试指令成功') - // 刷新指令列表 - - } catch (error) { - console.error('重试指令失败:', error) - this.$Message.error(error.message || '重试指令失败') + const isFromDetail = this.commandDetailVisible && this.currentCommandDetail && this.currentCommandDetail.id === command.id + if (!isFromDetail) { + this.$Modal.confirm({ + title: '确认重试', + content: `确定要重试指令"${command.command_name}"吗?`, + onOk: async () => { + await this.doRetryCommand(command) } + }) + return + } + await this.doRetryCommand(command) + }, + async doRetryCommand(command) { + this.retryCommandLoading = true + try { + await plaAccountServer.retryCommand(command.id) + this.$Message.success('重试指令成功') + this.queryCommands(this.commandsPageOption.page) + if (this.commandDetailVisible && this.currentCommandDetail && this.currentCommandDetail.id === command.id) { + const res = await plaAccountServer.getCommandDetail(this.accountId, command.id) + this.currentCommandDetail = res.data || {} } - }) + } catch (error) { + console.error('重试指令失败:', error) + this.$Message.error(error.message || '重试指令失败') + } finally { + this.retryCommandLoading = false + } }, // 取消任务 diff --git a/api/controller_admin/chat_records.js b/api/controller_admin/chat_records.js index 1a27af6..5445b55 100644 --- a/api/controller_admin/chat_records.js +++ b/api/controller_admin/chat_records.js @@ -277,7 +277,7 @@ module.exports = { const records = await chat_records.findAll({ where: { jobId, sn_code }, - order: [['sendTime', 'ASC'], ['receiveTime', 'ASC'], ['id', 'ASC']] + order: [['updateTime', 'ASC'], ['id', 'ASC']] }); return ctx.success(records); @@ -338,8 +338,7 @@ module.exports = { content, chatType, direction: 'sent', - sendStatus: 'pending', - sendTime: new Date() + // 对话会话表当前不再区分单条消息时间,这里仅保留必要字段 }); console.log(`[聊天管理] 消息待发送到设备 ${sn_code}:`, content); @@ -482,8 +481,8 @@ module.exports = { record.direction || '', record.chatType || '', `"${(record.content || '').replace(/"/g, '""')}"`, - record.sendTime || '', - record.receiveTime || '', + '', + '', record.hasReply ? '是' : '否' ]; csvContent += row.join(',') + '\n'; diff --git a/api/controller_admin/dashboard.js b/api/controller_admin/dashboard.js index c321d24..15b0b64 100644 --- a/api/controller_admin/dashboard.js +++ b/api/controller_admin/dashboard.js @@ -165,7 +165,7 @@ switch (type) { break; case 'chat': Model = models.chat_records; - dateField = 'sendTime'; + dateField = 'updateTime'; break; default: return ctx.fail('无效的统计类型'); diff --git a/api/controller_admin/statistics.js b/api/controller_admin/statistics.js index de785e5..1d36621 100644 --- a/api/controller_admin/statistics.js +++ b/api/controller_admin/statistics.js @@ -69,12 +69,7 @@ module.exports = { }), chat_records.count({ where: { - sn_code: deviceSn, - direction: 'sent', - sendTime: { - [op.gte]: todayStart, - [op.lte]: todayEnd - } + sn_code: deviceSn } }).catch(err => { console.error('[统计] 查询聊天数量失败:', err); @@ -189,14 +184,9 @@ module.exports = { }), chat_records.findAll({ where: { - sn_code: deviceSn, - direction: 'sent', - sendTime: { - [op.gte]: start, - [op.lte]: end - } + sn_code: deviceSn }, - attributes: ['sendTime'], + attributes: ['updateTime'], raw: true }).catch(err => { console.error('[统计] 查询聊天记录失败:', err); @@ -226,7 +216,7 @@ module.exports = { }).length; const chatCount = allChats.filter(item => { - const itemDate = dayjs(item.sendTime); + const itemDate = dayjs(item.updateTime); return !itemDate.isBefore(dayStart, 'day') && !itemDate.isAfter(dayEnd, 'day'); }).length; @@ -499,14 +489,9 @@ module.exports = { const allChats = await chat_records.findAll({ where: { - sn_code: deviceSn, - direction: 'sent', - sendTime: { - [op.gte]: start, - [op.lte]: end - } + sn_code: deviceSn }, - attributes: ['sendTime'], + attributes: ['updateTime'], raw: true }).catch(err => { console.error('[统计] 查询聊天记录失败:', err); @@ -523,7 +508,7 @@ module.exports = { const dayEnd = currentDate.endOf('day'); const count = allChats.filter(item => { - const itemDate = dayjs(item.sendTime); + const itemDate = dayjs(item.updateTime); return !itemDate.isBefore(dayStart, 'day') && !itemDate.isAfter(dayEnd, 'day'); }).length; diff --git a/api/controller_admin/task_status.js b/api/controller_admin/task_status.js index a566fd4..fb59a6b 100644 --- a/api/controller_admin/task_status.js +++ b/api/controller_admin/task_status.js @@ -439,9 +439,7 @@ return ctx.success({ return ctx.fail('任务不存在'); } - if (task.status !== 'failed') { - return ctx.fail('只能重试失败的任务'); - } + await task_status.update({ status: 'pending', diff --git a/api/controller_front/user.js b/api/controller_front/user.js index 22f3e0b..910bec2 100644 --- a/api/controller_front/user.js +++ b/api/controller_front/user.js @@ -460,5 +460,82 @@ module.exports = { }); return ctx.fail('保存投递配置失败'); } + }, + + /** + * 根据设备SN码获取账号全部功能配置(投递、沟通、活跃) + */ + 'POST /user/account-config/get': async (ctx) => { + try { + const body = ctx.getBody(); + const { sn_code } = body; + if (!sn_code) return ctx.fail('请提供设备SN码'); + + const { pla_account } = await Framework.getModels(); + const user = await pla_account.findOne({ where: { sn_code } }); + if (!user) return ctx.fail('用户不存在'); + + const u = user.toJSON ? user.toJSON() : user; + return ctx.success({ + deliver_config: u.deliver_config || null, + chat_strategy: u.chat_strategy || null, + active_actions: u.active_actions || null, + auto_chat: u.auto_chat != null ? !!u.auto_chat : false, + auto_active: u.auto_active != null ? !!u.auto_active : false + }); + } catch (error) { + console.error('[获取账号配置失败]', error); + return ctx.fail('获取账号配置失败'); + } + }, + + /** + * 保存账号功能配置(可只传需要更新的部分:deliver_config / chat_strategy / active_actions) + */ + 'POST /user/account-config/save': async (ctx) => { + try { + const body = ctx.getBody(); + const { sn_code, deliver_config, chat_strategy, active_actions } = body; + if (!sn_code) return ctx.fail('请提供设备SN码'); + + const { pla_account } = await Framework.getModels(); + const user = await pla_account.findOne({ where: { sn_code } }); + if (!user) return ctx.fail('用户不存在'); + + const updateData = {}; + if (deliver_config !== undefined) { + const original = user.deliver_config || {}; + const deepMerge = (t, s) => { + const r = { ...t }; + Object.keys(s).forEach(k => { + const sv = s[k], tv = t[k]; + if (sv && typeof sv === 'object' && !Array.isArray(sv) && tv && typeof tv === 'object' && !Array.isArray(tv)) { + r[k] = deepMerge(tv, sv); + } else { + r[k] = sv; + } + }); + return r; + }; + updateData.deliver_config = deepMerge(original, deliver_config); + if (deliver_config.auto_deliver !== undefined) updateData.auto_deliver = deliver_config.auto_deliver ? 1 : 0; + else if (deliver_config.auto_delivery !== undefined) updateData.auto_deliver = deliver_config.auto_delivery ? 1 : 0; + } + if (chat_strategy !== undefined) { + updateData.chat_strategy = chat_strategy; + if (chat_strategy.auto_chat !== undefined) updateData.auto_chat = chat_strategy.auto_chat ? 1 : 0; + } + if (active_actions !== undefined) { + updateData.active_actions = active_actions; + if (active_actions.auto_active !== undefined) updateData.auto_active = active_actions.auto_active ? 1 : 0; + } + if (Object.keys(updateData).length === 0) return ctx.success({ message: '无更新' }); + + await pla_account.update(updateData, { where: { id: user.id } }); + return ctx.success({ message: '配置保存成功' }); + } catch (error) { + console.error('[保存账号配置失败]', error); + return ctx.fail('保存账号配置失败'); + } } } \ No newline at end of file diff --git a/api/middleware/job/managers/chatManager.js b/api/middleware/job/managers/chatManager.js index eb1366b..7b8c3f8 100644 --- a/api/middleware/job/managers/chatManager.js +++ b/api/middleware/job/managers/chatManager.js @@ -7,13 +7,24 @@ const ai_service = require('../../../services/ai_service'); class ChatManager { /** * 解析沟通列表返回值,统一为 { friendList, foldText, ... } - * 设备端可能返回 code:0 + zpData 或 code:200 + data + * 只支持新的结构: + * response.data = { success, apiData: [ { response: { code, zpData:{...} } } ] } * @private */ _parse_chat_list_response(response) { - if (!response) return null; - const raw = response.zpData != null ? response.zpData : response.data; - if (!raw) return { friendList: [], foldText: '', filterEncryptIdList: [], filterBossIdList: [] }; + const outerData = response && response.data; + if (!outerData || !Array.isArray(outerData.apiData) || outerData.apiData.length === 0) { + return { friendList: [], foldText: '', filterEncryptIdList: [], filterBossIdList: [] }; + } + + const firstApi = outerData.apiData[0] || {}; + const innerResp = firstApi.response || firstApi.data || null; + const raw = innerResp && (innerResp.zpData != null ? innerResp.zpData : innerResp.data); + + if (!raw) { + return { friendList: [], foldText: '', filterEncryptIdList: [], filterBossIdList: [] }; + } + return { friendList: Array.isArray(raw.friendList) ? raw.friendList : [], foldText: raw.foldText || '', @@ -41,14 +52,19 @@ class ChatManager { data: { pageCount } }); - // 沟通列表接口成功为 code: 0 或 code: 200 - const ok = response && (response.code === 0 || response.code === 200); + // 只认新结构:data.success === true + const ok = !!response && response.data && response.data.success === true; if (!ok) { console.error(`[聊天管理] 获取聊天列表失败:`, response); throw new Error(response?.message || '获取聊天列表失败'); } const parsed = this._parse_chat_list_response(response); + + + // 存储数据库 + + console.log(`[聊天管理] 成功获取聊天列表,共 ${parsed.friendList.length} 个联系人`); return parsed; } @@ -162,37 +178,20 @@ class ChatManager { } /** - * 使用 AI 自动决定是否回复,并发送回复 - * 流程: - * 1. 根据参数获取沟通详情(消息列表) - * 2. 如果最后一句是 HR 说的,则调用阿里云 Qwen 生成回复文案 - * 3. 通过 send_chat_message 把回复发出去 + * 根据沟通详情(get_chat_detail 的解析结果)判断是否需回复,并用 AI 生成回复文案 + * 供任务层在「获取详情」指令执行后调用,不包含发送消息(由任务层再下发 send_chat_message 指令) * - * @param {string} sn_code - 设备SN码 - * @param {object} mqttClient - MQTT客户端 - * @param {object} params - 包含 friendId + 获取详情所需参数(如 encryptBossId/encryptJobId 等) - * @returns {Promise} { replied, reply_content?, hr_message_text?, reason? } + * @param {object} detail - 沟通详情,含 variant、messages、job 等 + * @returns {Promise} { replied: true, reply_content, hr_message_text } | { replied: false, reason } */ - async auto_reply_with_ai(sn_code, mqttClient, params = {}) { - const { friendId, platform = 'boss', ...detailParams } = params; - - if (!friendId) { - throw new Error('friendId 不能为空'); - } - - // 1. 获取沟通详情(期望拿到消息列表) - const detail = await this.get_chat_detail(sn_code, mqttClient, { - platform, - ...detailParams - }); - + async getReplyContentFromDetail(detail) { if (!detail || detail.variant !== 'messages' || !Array.isArray(detail.messages) || detail.messages.length === 0) { return { replied: false, reason: '无可用消息' }; } const messages = detail.messages; - // 2. 推断 HR 与 求职者 uid + // 推断 HR 与 求职者 uid let hr_uid = null; let geek_uid = null; @@ -249,14 +248,6 @@ class ChatManager { return { replied: false, reason: 'AI 未生成有效回复' }; } - // 4. 通过统一的 send_chat_message 下发回复 - await this.send_chat_message(sn_code, mqttClient, { - friendId, - messages: [{ type: 'text', content: reply_content }], - chatType: 'reply', - platform - }); - return { replied: true, reply_content, @@ -265,78 +256,32 @@ class ChatManager { } /** - * 自动获取沟通列表 + 按会话自动 AI 回复 - * 1. 调用 get_chat_list 获取会话列表 - * 2. 对每个会话按 friendId 调用 auto_reply_with_ai(内部会先获取详情,再决定是否回复) + * 使用 AI 自动决定是否回复,并发送回复(内部会先获取详情,再调用 getReplyContentFromDetail,再发送) + * 单条指令场景用;任务 auto_chat 已改为下发 get_chat_list / get_chat_detail / send_chat_message 多条指令。 * * @param {string} sn_code - 设备SN码 * @param {object} mqttClient - MQTT客户端 - * @param {object} params - { platform?, pageCount? } - * @returns {Promise} { success, total_contacts, replied_count, details: [...] } + * @param {object} params - 包含 friendId + 获取详情所需参数 + * @returns {Promise} { replied, reply_content?, hr_message_text?, reason? } */ - async auto_chat_ai(sn_code, mqttClient, params = {}) { - const { platform = 'boss', pageCount = 3 } = params; + async auto_reply_with_ai(sn_code, mqttClient, params = {}) { + const { friendId, platform = 'boss', ...detailParams } = params; + if (!friendId) throw new Error('friendId 不能为空'); - // 1. 获取沟通列表 - const listResult = await this.get_chat_list(sn_code, mqttClient, { - platform, - pageCount + const detail = await this.get_chat_detail(sn_code, mqttClient, { platform, ...detailParams }); + const decision = await this.getReplyContentFromDetail(detail); + if (!decision.replied) return decision; + + await this.send_chat_message(sn_code, mqttClient, { + friendId, + messages: [{ type: 'text', content: decision.reply_content }], + chatType: 'reply', + platform }); - - const friendList = Array.isArray(listResult.friendList) ? listResult.friendList : []; - - if (friendList.length === 0) { - return { - success: true, - total_contacts: 0, - replied_count: 0, - details: [], - message: '没有可沟通的会话' - }; - } - - let replied_count = 0; - const details = []; - - // 2. 逐个会话顺序处理,避免并发下发指令 - for (const friend of friendList) { - const friendId = friend.friendId; - if (!friendId) { - continue; - } - - try { - const r = await this.auto_reply_with_ai(sn_code, mqttClient, { - platform, - friendId - }); - - if (r.replied) { - replied_count++; - } - - details.push({ - friendId, - replied: !!r.replied, - reason: r.reason || null, - reply_content: r.reply_content || null - }); - } catch (error) { - details.push({ - friendId, - replied: false, - reason: error.message || '自动回复失败', - reply_content: null - }); - } - } - return { - success: true, - total_contacts: friendList.length, - replied_count, - details, - message: '自动获取列表并尝试AI回复完成' + replied: true, + reply_content: decision.reply_content, + hr_message_text: decision.hr_message_text }; } } diff --git a/api/middleware/job/managers/jobManager.js b/api/middleware/job/managers/jobManager.js index 1a5cea5..da2d93e 100644 --- a/api/middleware/job/managers/jobManager.js +++ b/api/middleware/job/managers/jobManager.js @@ -600,16 +600,16 @@ class JobManager { // 等待 1秒 - await new Promise(resolve => setTimeout(resolve, 1000)); + // await new Promise(resolve => setTimeout(resolve, 1000)); - const location = await locationService.getLocationByAddress(addressToParse).catch(error => { - console.error(`[工作管理] 获取位置失败:`, error); - }); + // const location = await locationService.getLocationByAddress(addressToParse).catch(error => { + // console.error(`[工作管理] 获取位置失败:`, error); + // }); - if (location) { - jobInfo.latitude = String(location.lat); - jobInfo.longitude = String(location.lng); - } + // if (location) { + // jobInfo.latitude = String(location.lat); + // jobInfo.longitude = String(location.lng); + // } } // 检查是否已存在(根据 jobId 和 sn_code) diff --git a/api/middleware/schedule/core/scheduledJobs.js b/api/middleware/schedule/core/scheduledJobs.js index 478556e..b362d66 100644 --- a/api/middleware/schedule/core/scheduledJobs.js +++ b/api/middleware/schedule/core/scheduledJobs.js @@ -20,6 +20,14 @@ class ScheduledJobs { this.taskQueue = components.taskQueue; this.taskHandlers = taskHandlers; this.jobs = []; + + // 业务任务防重入标记(按任务类型存) + this._runningFlags = { + auto_search: false, + auto_deliver: false, + auto_chat: false, + auto_active: false + }; } /** @@ -90,7 +98,7 @@ class ScheduledJobs { console.log('[定时任务] ✓ 已启动自动投递任务 (每1分钟)'); // 3. 自动沟通任务 - 每15分钟执行一次 - const autoChatJob = node_schedule.scheduleJob(config.schedules.autoChat || '0 */15 * * * *', () => { + const autoChatJob = node_schedule.scheduleJob(config.schedules.autoChat || '0 */1 * * * *', () => { this.runAutoChatTask(); }); this.jobs.push(autoChatJob); @@ -120,6 +128,13 @@ class ScheduledJobs { * 为所有启用自动搜索的账号添加搜索任务 */ async runAutoSearchTask() { + const key = 'auto_search'; + if (this._runningFlags[key]) { + console.log('[自动搜索调度] 上一次执行尚未完成,本次跳过'); + return; + } + + this._runningFlags[key] = true; try { const accounts = await this.getEnabledAccounts('auto_search'); @@ -146,6 +161,8 @@ class ScheduledJobs { } } catch (error) { console.error('[自动搜索调度] 执行失败:', error); + } finally { + this._runningFlags[key] = false; } } @@ -154,6 +171,13 @@ class ScheduledJobs { * 为所有启用自动投递的账号添加投递任务 */ async runAutoDeliverTask() { + const key = 'auto_deliver'; + if (this._runningFlags[key]) { + console.log('[自动投递调度] 上一次执行尚未完成,本次跳过'); + return; + } + + this._runningFlags[key] = true; try { const accounts = await this.getEnabledAccounts('auto_deliver'); @@ -180,6 +204,8 @@ class ScheduledJobs { } } catch (error) { console.error('[自动投递调度] 执行失败:', error); + } finally { + this._runningFlags[key] = false; } } @@ -188,6 +214,13 @@ class ScheduledJobs { * 为所有启用自动沟通的账号添加沟通任务 */ async runAutoChatTask() { + const key = 'auto_chat'; + if (this._runningFlags[key]) { + console.log('[自动沟通调度] 上一次执行尚未完成,本次跳过'); + return; + } + + this._runningFlags[key] = true; try { const accounts = await this.getEnabledAccounts('auto_chat'); @@ -214,6 +247,8 @@ class ScheduledJobs { } } catch (error) { console.error('[自动沟通调度] 执行失败:', error); + } finally { + this._runningFlags[key] = false; } } @@ -222,6 +257,13 @@ class ScheduledJobs { * 为所有启用自动活跃的账号添加活跃任务 */ async runAutoActiveTask() { + const key = 'auto_active'; + if (this._runningFlags[key]) { + console.log('[自动活跃调度] 上一次执行尚未完成,本次跳过'); + return; + } + + this._runningFlags[key] = true; try { const accounts = await this.getEnabledAccounts('auto_active'); @@ -248,6 +290,8 @@ class ScheduledJobs { } } catch (error) { console.error('[自动活跃调度] 执行失败:', error); + } finally { + this._runningFlags[key] = false; } } diff --git a/api/middleware/schedule/handlers/chatHandler.js b/api/middleware/schedule/handlers/chatHandler.js index 1b462b9..27e4347 100644 --- a/api/middleware/schedule/handlers/chatHandler.js +++ b/api/middleware/schedule/handlers/chatHandler.js @@ -2,10 +2,12 @@ const BaseHandler = require('./baseHandler'); const ConfigManager = require('../services/configManager'); const command = require('../core/command'); const config = require('../infrastructure/config'); +const chatManager = require('../../job/managers/chatManager'); +const db = require('../../dbProxy'); /** * 自动沟通处理器 - * 负责自动回复HR消息 + * 负责自动回复 HR 消息。auto_chat 是任务,其下按指令执行:获取列表 → 获取详情 →(若需回复)发送消息 */ class ChatHandler extends BaseHandler { /** @@ -24,64 +26,153 @@ class ChatHandler extends BaseHandler { } /** - * 执行沟通逻辑 + * 执行沟通逻辑:先下发「获取列表」指令,再对每个会话下发「获取详情」→(若需回复)「发送消息」指令 */ async doChat(task) { const { sn_code, taskParams } = task; - const { platform = 'boss' } = taskParams; + const platform = taskParams.platform || 'boss'; console.log(`[自动沟通] 开始 - 设备: ${sn_code}`); - // 1. 获取账户配置 const accountConfig = await this.getAccountConfig(sn_code, ['platform_type', 'chat_strategy']); - if (!accountConfig) { - return { - chatCount: 0, - message: '未找到账户配置' - }; + return { chatCount: 0, message: '未找到账户配置' }; } - // 2. 解析沟通策略配置 const chatStrategy = ConfigManager.parseChatStrategy(accountConfig.chat_strategy); - - // 3. 检查沟通时间范围 const timeRange = ConfigManager.getTimeRange(chatStrategy); if (timeRange) { const timeRangeValidator = require('../services/timeRangeValidator'); const timeCheck = timeRangeValidator.checkTimeRange(timeRange); - if (!timeCheck.allowed) { - return { - chatCount: 0, - message: timeCheck.reason - }; + return { chatCount: 0, message: timeCheck.reason }; } } - // 4. 创建自动沟通 AI 指令(内部会先获取列表,再获取详情并自动回复) - const chatCommand = { - command_type: 'auto_chat_ai', - command_name: 'auto_chat_ai', - command_params: { - platform: platform || accountConfig.platform_type || 'boss', - pageCount: chatStrategy.page_count || 3 - }, + const platform_type = platform || accountConfig.platform_type || 'boss'; + const page_count = chatStrategy.page_count || 3; + + // 1. 下发「获取列表」指令 + const list_command = { + command_type: 'get_chat_list', + command_name: '获取聊天列表', + command_params: { platform: platform_type, pageCount: page_count }, priority: config.getTaskPriority('auto_chat') || 6 }; + const list_exec = await command.executeCommands(task.id, [list_command], this.mqttClient); + const list_result = list_exec?.results?.[0]?.result; + const friend_list = Array.isArray(list_result?.friendList) ? list_result.friendList : []; - // 5. 执行指令(任务队列会保证该设备内串行执行,不并发下发指令) - const exec_result = await command.executeCommands(task.id, [chatCommand], this.mqttClient); - const first = exec_result && Array.isArray(exec_result.results) && exec_result.results[0] - ? exec_result.results[0].result || {} - : {}; + if (friend_list.length === 0) { + console.log(`[自动沟通] 完成 - 设备: ${sn_code},无会话`); + return { chatCount: 0, message: '没有可沟通的会话', detail: { total_contacts: 0 } }; + } - console.log(`[自动沟通] 完成 - 设备: ${sn_code}`); + let replied_count = 0; + const details = []; + + // 2. 将会话列表同步到聊天记录表(按会话维度做一条摘要记录) + try { + const chatRecordsModel = db.getModel('chat_records'); + for (const friend of friend_list) { + const friend_id = friend.friendId; + if (!friend_id) continue; + + const encryptId = friend.encryptFriendId || ''; + + const existing = await chatRecordsModel.findOne({ + where: { + sn_code, + platform: platform_type, + encryptBossId: encryptId, + direction: 'received', + chatType: 'session' + } + }); + + const baseData = { + sn_code, + platform: platform_type, + encryptBossId: encryptId, + jobTitle: friend.jobName || '', + companyName: friend.brandName || '', + hrName: friend.name || '', + hrTitle: friend.bossTitle || '', + hrId: String(friend_id), + chatType: 'session', + direction: 'received', + content: '', + contentType: 'text', + receiveTime: friend.updateTime ? new Date(friend.updateTime) : new Date() + }; + + if (existing) { + await existing.update(baseData); + } else { + await chatRecordsModel.create(baseData); + } + } + } catch (e) { + console.warn('[自动沟通] 同步聊天会话列表到 chat_records 失败:', e.message); + } + + // 3. 对每个会话:下发「获取详情」→ 若需回复则下发「发送消息」 + for (const friend of friend_list) { + const friend_id = friend.friendId; + if (!friend_id) continue; + + try { + const detail_command = { + command_type: 'get_chat_detail', + command_name: '获取聊天详情', + command_params: { platform: platform_type, friendId: friend_id }, + priority: config.getTaskPriority('auto_chat') || 6 + }; + const detail_exec = await command.executeCommands(task.id, [detail_command], this.mqttClient); + const detail = detail_exec?.results?.[0]?.result; + + const decision = await chatManager.getReplyContentFromDetail(detail || {}); + + if (decision.replied && decision.reply_content) { + const send_command = { + command_type: 'send_chat_message', + command_name: '发送聊天消息', + command_params: { + platform: platform_type, + friendId: friend_id, + messages: [{ type: 'text', content: decision.reply_content }], + chatType: 'reply' + }, + priority: config.getTaskPriority('auto_chat') || 6 + }; + await command.executeCommands(task.id, [send_command], this.mqttClient); + replied_count++; + } + + details.push({ + friendId: friend_id, + replied: !!decision.replied, + reason: decision.reason || null + }); + } catch (err) { + details.push({ + friendId: friend_id, + replied: false, + reason: err.message || '处理失败' + }); + } + } + + console.log(`[自动沟通] 完成 - 设备: ${sn_code},会话 ${friend_list.length},回复 ${replied_count}`); return { - chatCount: first.replied_count || 0, - message: first.message || '自动沟通完成', - detail: first + chatCount: replied_count, + message: '自动沟通完成', + detail: { + total_contacts: friend_list.length, + replied_count, + details + } }; } } diff --git a/api/middleware/schedule/handlers/deliverHandler.js b/api/middleware/schedule/handlers/deliverHandler.js index ca65bb8..0030ac2 100644 --- a/api/middleware/schedule/handlers/deliverHandler.js +++ b/api/middleware/schedule/handlers/deliverHandler.js @@ -279,16 +279,22 @@ class DeliverHandler extends BaseHandler { */ mergeFilterConfig(deliverConfig, filterRules, jobTypeConfig) { // 排除关键词 - const jobTypeExclude = jobTypeConfig?.excludeKeywords + const rawJobTypeExclude = jobTypeConfig?.excludeKeywords ? ConfigManager.parseConfig(jobTypeConfig.excludeKeywords, []) : []; - const deliverExclude = ConfigManager.getExcludeKeywords(deliverConfig); - const filterExclude = filterRules.excludeKeywords || []; + const jobTypeExclude = Array.isArray(rawJobTypeExclude) ? rawJobTypeExclude : []; + + const deliverExcludeRaw = ConfigManager.getExcludeKeywords(deliverConfig); + const deliverExclude = Array.isArray(deliverExcludeRaw) ? deliverExcludeRaw : []; + const filterExcludeRaw = filterRules.excludeKeywords || []; + const filterExclude = Array.isArray(filterExcludeRaw) ? filterExcludeRaw : []; // 过滤关键词 - const deliverFilter = ConfigManager.getFilterKeywords(deliverConfig); - const filterKeywords = filterRules.keywords || []; + const deliverFilterRaw = ConfigManager.getFilterKeywords(deliverConfig); + const deliverFilter = Array.isArray(deliverFilterRaw) ? deliverFilterRaw : []; + const filterKeywordsRaw = filterRules.keywords || []; + const filterKeywords = Array.isArray(filterKeywordsRaw) ? filterKeywordsRaw : []; // 薪资范围 const salaryRange = filterRules.minSalary || filterRules.maxSalary diff --git a/api/middleware/schedule/infrastructure/config.js b/api/middleware/schedule/infrastructure/config.js index 949c6ac..63c9942 100644 --- a/api/middleware/schedule/infrastructure/config.js +++ b/api/middleware/schedule/infrastructure/config.js @@ -50,7 +50,7 @@ class ScheduleConfig { monitoringInterval: '*/1 * * * *', // 监控检查间隔:1分钟 autoSearch: '0 0 */1 * * *', // 自动搜索任务:每1小时执行一次 autoDeliver: '0 */2 * * * *', // 自动投递任务:每2分钟执行一次 - autoChat: '0 */15 * * * *', // 自动沟通任务:每15分钟执行一次 + autoChat: '0 */1 * * * *', // 自动沟通任务:每1分钟执行一次 autoActive: '0 0 */2 * * *' // 自动活跃任务:每2小时执行一次 }; } diff --git a/api/model/chat_records.js b/api/model/chat_records.js index bb4d75c..c2e1ed8 100644 --- a/api/model/chat_records.js +++ b/api/model/chat_records.js @@ -1,12 +1,12 @@ const Sequelize = require('sequelize'); /** - * 聊天记录表模型 - * 记录与HR的聊天内容和效果 + * 聊天会话列表表模型 + * 按 Boss 「好友/会话」列表维度存储,会话摘要信息 */ module.exports = (db) => { - const chat_records = db.define("chat_records", { - // 聊天基本信息 + const chat_records = db.define('chat_records', { + // 设备与平台 sn_code: { comment: '设备SN码', type: Sequelize.STRING(50), @@ -19,270 +19,91 @@ module.exports = (db) => { allowNull: false, defaultValue: 'boss' }, - - // 岗位关联 - jobId: { - comment: '岗位ID', + + // Boss 会话列表字段(与接口 friend 对象对应) + friendId: { + comment: '好友ID', + type: Sequelize.BIGINT, + allowNull: false + }, + friendSource: { + comment: '好友来源', + type: Sequelize.INTEGER, + allowNull: true, + defaultValue: 0 + }, + encryptFriendId: { + comment: '好友加密ID', type: Sequelize.STRING(100), - allowNull: true, + allowNull: false, defaultValue: '' }, - encryptBossId: { - comment: 'Boss加密ID', - type: Sequelize.STRING(100), - allowNull: true, - defaultValue: '' - }, - jobTitle: { - comment: '岗位名称', - type: Sequelize.STRING(200), - allowNull: true, - defaultValue: '' - }, - companyName: { - comment: '公司名称', - type: Sequelize.STRING(200), - allowNull: true, - defaultValue: '' - }, - - // HR信息 - hrName: { + name: { comment: 'HR姓名', type: Sequelize.STRING(50), allowNull: true, defaultValue: '' }, - hrTitle: { - comment: 'HR职位', - type: Sequelize.STRING(50), - allowNull: true, - defaultValue: '' - }, - hrId: { - comment: 'HR ID', - type: Sequelize.STRING(100), - allowNull: true, - defaultValue: '' - }, - - // 聊天内容 - chatType: { - comment: '聊天类型: greeting-打招呼, follow_up-跟进, interview-面试邀约, reply-回复', - type: Sequelize.STRING(20), - allowNull: false, - defaultValue: 'greeting' - }, - direction: { - comment: '消息方向: sent-发送, received-接收', - type: Sequelize.STRING(20), - allowNull: false, - defaultValue: 'sent' - }, - content: { - comment: '聊天内容', - type: Sequelize.TEXT, - allowNull: false, - defaultValue: '' - }, - contentType: { - comment: '内容类型: text-文本, image-图片, file-文件', - type: Sequelize.STRING(20), - allowNull: true, - defaultValue: 'text' - }, - - // AI生成信息 - isAiGenerated: { - comment: '是否AI生成', - type: Sequelize.BOOLEAN, - allowNull: true, - defaultValue: false - }, - aiPrompt: { - comment: 'AI生成的提示词', - type: Sequelize.TEXT, - allowNull: true, - defaultValue: '' - }, - aiModel: { - comment: 'AI模型名称', - type: Sequelize.STRING(50), - allowNull: true, - defaultValue: '' - }, - - // 发送状态 - sendStatus: { - comment: '发送状态: pending-待发送, sending-发送中, sent-已发送, failed-发送失败', - type: Sequelize.STRING(20), - allowNull: true, - defaultValue: 'pending' - }, - sendTime: { - comment: '发送时间', - type: Sequelize.DATE, + updateTime: { + comment: '最后更新时间(毫秒时间戳)', + type: Sequelize.BIGINT, allowNull: true }, - receiveTime: { - comment: '接收时间', - type: Sequelize.DATE, - allowNull: true - }, - - // 回复信息 - hasReply: { - comment: '是否有回复', - type: Sequelize.BOOLEAN, - allowNull: true, - defaultValue: false - }, - replyTime: { - comment: '回复时间', - type: Sequelize.DATE, - allowNull: true - }, - replyContent: { - comment: '回复内容', - type: Sequelize.TEXT, - allowNull: true, - defaultValue: '' - }, - replyDuration: { - comment: '回复时长(分钟)', - type: Sequelize.INTEGER, - allowNull: true, - defaultValue: 0 - }, - - // 面试邀约信息 - isInterviewInvitation: { - comment: '是否包含面试邀约', - type: Sequelize.BOOLEAN, - allowNull: true, - defaultValue: false - }, - interviewTime: { - comment: '面试时间', - type: Sequelize.DATE, - allowNull: true - }, - interviewLocation: { - comment: '面试地点', + brandName: { + comment: '公司名称', type: Sequelize.STRING(200), allowNull: true, defaultValue: '' }, - interviewType: { - comment: '面试类型: online-线上, offline-线下', - type: Sequelize.STRING(20), + jobName: { + comment: '职位名称', + type: Sequelize.STRING(200), allowNull: true, defaultValue: '' }, - interviewStatus: { - comment: '面试状态: pending-待确认, confirmed-已确认, completed-已完成, cancelled-已取消', - type: Sequelize.STRING(20), + jobTypeDesc: { + comment: '职位类型描述', + type: Sequelize.STRING(100), allowNull: true, defaultValue: '' }, - - // 效果评估 - effectScore: { - comment: '效果评分(0-100)', + jobCity: { + comment: '职位城市', + type: Sequelize.STRING(100), + allowNull: true, + defaultValue: '' + }, + positionName: { + comment: '岗位名称/方向', + type: Sequelize.STRING(200), + allowNull: true, + defaultValue: '' + }, + bossTitle: { + comment: 'Boss/HR 职位头衔', + type: Sequelize.STRING(100), + allowNull: true, + defaultValue: '' + }, + waterLevel: { + comment: '水位(Boss 优先级标记)', type: Sequelize.INTEGER, allowNull: true, defaultValue: 0 - }, - sentiment: { - comment: '情感倾向: positive-正面, neutral-中性, negative-负面', - type: Sequelize.STRING(20), - allowNull: true, - defaultValue: 'neutral' - }, - - // 会话信息 - conversationId: { - comment: '会话ID(同一个岗位的聊天属于一个会话)', - type: Sequelize.STRING(50), - allowNull: true, - defaultValue: '' - }, - messageIndex: { - comment: '消息序号(会话内的消息顺序)', - type: Sequelize.INTEGER, - allowNull: true, - defaultValue: 0 - }, - - // 关联信息 - taskId: { - comment: '关联任务ID', - type: Sequelize.STRING(50), - allowNull: true, - defaultValue: '' - }, - - // 其他信息 - originalData: { - comment: '原始数据(JSON)', - type: Sequelize.TEXT, - allowNull: true, - defaultValue: '' - }, - errorMessage: { - comment: '错误信息', - type: Sequelize.TEXT, - allowNull: true, - defaultValue: '' - }, - notes: { - comment: '备注', - type: Sequelize.TEXT, - allowNull: true, - defaultValue: '' - }, - - + } + }, { timestamps: false, indexes: [ - { - unique: false, - fields: ['sn_code'] - }, - { - unique: false, - fields: ['jobId'] - }, - { - unique: false, - fields: ['encryptBossId'] - }, - { - unique: false, - fields: ['conversationId'] - }, - { - unique: false, - fields: ['chatType'] - }, - { - unique: false, - fields: ['sendStatus'] - }, - { - unique: false, - fields: ['hasReply'] - }, - + { unique: false, fields: ['sn_code'] }, + { unique: false, fields: ['platform'] }, + { unique: false, fields: ['friendId'] }, + { unique: false, fields: ['encryptFriendId'] } ] }); - //chat_records.sync({ force: true }); + // chat_records.sync({ force: true }); - return chat_records - - - + return chat_records; };