252 lines
5.6 KiB
Markdown
252 lines
5.6 KiB
Markdown
# 简历存储和分析功能 - 快速参考
|
||
|
||
## 🚀 快速开始
|
||
|
||
### 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 }
|
||
});
|
||
```
|
||
|