申请岗位列表信息查询以及简历解析评分计算和工作年限添加

This commit is contained in:
2025-12-18 00:06:18 +08:00
parent 2b61159038
commit efc6c6e5a9
11 changed files with 339 additions and 14 deletions

View File

@@ -1,6 +1,8 @@
package com.vetti.hotake.domain;
import java.math.BigDecimal;
import com.vetti.hotake.domain.dto.HotakeCvInfoDto;
import lombok.Data;
import lombok.experimental.Accessors;
import io.swagger.annotations.ApiModelProperty;
@@ -28,6 +30,11 @@ public class HotakeRolesApplyInfo extends BaseEntity
@Excel(name = "候选人ID")
private Long candidateId;
/** 招聘人ID */
@ApiModelProperty("招聘人ID")
@Excel(name = "招聘人ID")
private Long recruiterId;
/** 岗位ID */
@ApiModelProperty("岗位ID")
@Excel(name = "岗位ID")
@@ -109,4 +116,10 @@ public class HotakeRolesApplyInfo extends BaseEntity
@Excel(name = "AI评分百分比")
private BigDecimal aiMatchScorePercentage;
@ApiModelProperty("岗位信息")
private HotakeRolesInfo rolesInfo;
@ApiModelProperty("解析的简历数据信息")
private HotakeCvInfoDto cvInfoDto;
}

View File

@@ -29,6 +29,8 @@ public class HotakeCvInfoDto {
private String location;
@ApiModelProperty("当前工作公司")
private String currentWork;
@ApiModelProperty("工作年限")
private String experienceYear;
@ApiModelProperty("链接对象集合")
private List<VcLinksDto> links;
@ApiModelProperty("自我介绍")

View File

@@ -1,5 +1,6 @@
package com.vetti.hotake.domain.dto;
import com.vetti.common.core.domain.entity.SysUser;
import com.vetti.hotake.domain.HotakeAiInterviewQuestionsInfo;
import com.vetti.hotake.domain.HotakeInitialScreeningQuestionsInfo;
import com.vetti.hotake.domain.HotakeRolesInfo;
@@ -44,4 +45,7 @@ public class HotakeRolesInfoDto extends HotakeRolesInfo {
@ApiModelProperty("AI面试问题数据集合")
private List<HotakeAiInterviewQuestionsInfo> aiInterviewQuestionsInfoList;
@ApiModelProperty("招聘人详细信息")
private SysUser recruiterUser;
}

View File

@@ -26,6 +26,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -265,7 +266,23 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC
cvInfo.setProblemBaseInfo(problemBaseInfo);
//生成对应的简历评分
String resultMsg = handleHotakeCvInfoScore(cvInfoDto);
cvInfo.setScore(resultMsg);
cvInfo.setCvScore(resultMsg);
cvInfo.setExperience(cvInfoDto.getExperienceYear());
//分数解析
String[] strs = resultMsg.split("\n");
if(strs != null && strs.length > 0){
String score = strs[0].replaceAll("Score:","").trim();
String[] scores = score.split("/");
if(scores != null && scores.length > 0){
cvInfo.setAiMatchScore(scores[0]);
try{
cvInfo.setAiMatchScorePercentage(String.valueOf(new BigDecimal(scores[0]).
divide(new BigDecimal(5)).setScale(2,4)));
}catch (Exception e){e.printStackTrace();}
}
}
cvInfo.setCvTemplateJson(JSONUtil.toJsonStr(cvInfoDto));
fill(FillTypeEnum.UPDATE.getCode(), cvInfo);
hotakeCvInfoMapper.updateHotakeCvInfo(cvInfo);
@@ -289,7 +306,7 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC
List<Map<String,String>> list = new LinkedList();
Map<String,String> entity = new HashMap<>();
entity.put("role","user");
entity.put("content","从下面提供的文本中提取所有能识别到的简历信息只提取原文中存在的内容不要补充、不推测、不总结。需要提取的字段包括name姓名或人名、phone电话号码、email电子邮件地址、position岗位或者简历中自己期望的职位等、location地点或者地址、家庭住址、links所有链接地址、currentWork(当前工作公司)、about关于我/自我介绍、skills_tools关键资格许可证、注册/会员资格、认证、languages语言能力,主要就是Languages下面的语言、experience工作经历,除了title、company、location、durationStart、durationEnd,其他的都放到description里面,并且description里面要根据换行符分成不同的content),日期要拆分成开始时间(durationStart)和结束时间(durationEnd)、education教育经历,日期要拆分成开始时间(durationStart)和结束时间(durationEnd))。请将提取结果以结构化 JSON 格式返回,格式如下:{ \\\"name\\\": \\\"\\\", \\\"phone\\\": \\\"\\\", \\\"currentWork\\\": \\\"\\\", \\\"position\\\": \\\"\\\", \\\"location\\\": \\\"\\\", \\\"email\\\": \\\"\\\", \\\"links\\\": [{\\\"content\\\":\\\"\\\"}], \\\"about\\\": \\\"\\\", \\\"skillsTools\\\": [{\\\"content\\\":\\\"\\\"}], \\\"languages\\\": [{\\\"content\\\":\\\"\\\"}], \\\"experience\\\": [{\\\"title\\\": \\\"\\\", \\\"company\\\": \\\"\\\",\\\"location\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\",\\\"description\\\": [{\\\"content\\\":\\\"\\\"}]}], \\\"education\\\": [{\\\"degree\\\": \\\"\\\",\\\"institution\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\"}] }。字段不存在则返回 null 或空数组。只返回标准可解析的 JSON结构 ,不要多余的```json等信息不要解释说明不要改写内容。以下为待处理文本"+contents);
entity.put("content","从下面提供的文本中提取所有能识别到的简历信息只提取原文中存在的内容不要补充、不推测、不总结。需要提取的字段包括name姓名或人名、phone电话号码、email电子邮件地址experienceYear根据工作经验计算出来的工作年限position岗位或者简历中自己期望的职位等、location地点或者地址、家庭住址、links所有链接地址、currentWork(当前工作公司)、about关于我/自我介绍、skills_tools关键资格许可证、注册/会员资格、认证、languages语言能力,主要就是Languages下面的语言、experience工作经历,除了title、company、location、durationStart、durationEnd,其他的都放到description里面,并且description里面要根据换行符分成不同的content),日期要拆分成开始时间(durationStart)和结束时间(durationEnd)、education教育经历,日期要拆分成开始时间(durationStart)和结束时间(durationEnd))。请将提取结果以结构化 JSON 格式返回,格式如下:{ \\\"name\\\": \\\"\\\", \\\"phone\\\": \\\"\\\", \\\"currentWork\\\": \\\"\\\", \\\"position\\\": \\\"\\\", \\\"location\\\": \\\"\\\", \\\"email\\\": \\\"\\\", \\\"experienceYear\\\": \\\"\\\", \\\"links\\\": [{\\\"content\\\":\\\"\\\"}], \\\"about\\\": \\\"\\\", \\\"skillsTools\\\": [{\\\"content\\\":\\\"\\\"}], \\\"languages\\\": [{\\\"content\\\":\\\"\\\"}], \\\"experience\\\": [{\\\"title\\\": \\\"\\\", \\\"company\\\": \\\"\\\",\\\"location\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\",\\\"description\\\": [{\\\"content\\\":\\\"\\\"}]}], \\\"education\\\": [{\\\"degree\\\": \\\"\\\",\\\"institution\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\"}] }。字段不存在则返回 null 或空数组。只返回标准可解析的 JSON结构 ,不要多余的```json等信息不要解释说明不要改写内容。以下为待处理文本"+contents);
//根据AI做
list.add(entity);
String resultCv = chatGPTClient.handleAiChat(JSONUtil.toJsonStr(list), "JX");
@@ -444,5 +461,16 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC
}
public static void main(String[] args){
String str = "Score: 4.8/5\n" +
"Recommendation: Highly recommended candidate - strong match for the role\n" +
"Strengths: Extensive relevant experience, Professional certifications, Strong skill set alignment\n" +
"Concerns: -";
String[] strs = str.split("\n");
System.out.println(strs[0].replaceAll("Score:","").trim().split("/")[0]);
}
}

View File

@@ -1,6 +1,7 @@
package com.vetti.hotake.service.impl;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -12,19 +13,20 @@ import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONUtil;
import com.vetti.common.ai.gpt.ChatGPTClient;
import com.vetti.common.core.service.BaseServiceImpl;
import com.vetti.common.enums.CandidateStatusEnum;
import com.vetti.common.enums.FillTypeEnum;
import com.vetti.common.enums.MinioBucketNameEnum;
import com.vetti.common.enums.StageEnum;
import com.vetti.common.utils.DateUtils;
import com.vetti.common.utils.SecurityUtils;
import com.vetti.common.utils.readFile.FileContentUtil;
import com.vetti.hotake.domain.HotakeCvInfo;
import com.vetti.hotake.domain.HotakeProblemBaseInfo;
import com.vetti.hotake.domain.HotakeRolesApplyInfo;
import com.vetti.hotake.domain.*;
import com.vetti.hotake.domain.dto.HotakeCvInfoDto;
import com.vetti.hotake.domain.dto.VcDto.*;
import com.vetti.hotake.domain.vo.HotakeInitScreQuestionsReplyRecordInfoVo;
import com.vetti.hotake.mapper.HotakeCvInfoMapper;
import com.vetti.hotake.mapper.HotakeRolesApplyInfoMapper;
import com.vetti.hotake.mapper.HotakeRolesInfoMapper;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
@@ -33,7 +35,6 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.vetti.hotake.mapper.HotakeInitScreQuestionsReplyRecordInfoMapper;
import com.vetti.hotake.domain.HotakeInitScreQuestionsReplyRecordInfo;
import com.vetti.hotake.service.IHotakeInitScreQuestionsReplyRecordInfoService;
/**
@@ -53,6 +54,9 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
@Autowired
private HotakeRolesApplyInfoMapper hotakeRolesApplyInfoMapper;
@Autowired
private HotakeRolesInfoMapper hotakeRolesInfoMapper;
@Autowired
private HotakeCvInfoMapper hotakeCvInfoMapper;
@@ -175,6 +179,7 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
//获取申请的简历数据
HotakeRolesApplyInfo applyInfo = hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoById(initScreQuestionsReplyRecordInfoVo.getRoleApplyId());
if (applyInfo != null) {
HotakeRolesInfo rolesInf = hotakeRolesInfoMapper.selectHotakeRolesInfoById(initScreQuestionsReplyRecordInfoVo.getRoleId());
//查询候选人的当前最新简历信息
HotakeCvInfo queryCv = new HotakeCvInfo();
queryCv.setUserId(SecurityUtils.getUserId());
@@ -196,12 +201,15 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
log.info("简历信息:{}", contents);
//验证文件内容是否改变,如果未改变不进行模型解析直接返回原有结果
String md5Hash = MD5.create().digestHex16(contents);
String scoreStr = "";
if (StrUtil.isNotEmpty(md5Hash) && cvInfo != null && md5Hash.equals(cvInfo.getCvMd5())) {
//直接获取简历表中的简历解析的详细数据
applyInfo.setCvScore(cvInfo.getCvScore());
applyInfo.setCvTemplateJson(cvInfo.getCvTemplateJson());
fill(FillTypeEnum.UPDATE.getCode(), applyInfo);
applyInfo.setCvMd5(md5Hash);
applyInfo.setExperience(cvInfo.getExperience());
scoreStr = cvInfo.getCvScore();
}else{
//生成简历模版数据信息
HotakeCvInfoDto cvInfoDto = handleAnalysisCvInfo(contents);
@@ -211,10 +219,38 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
applyInfo.setCvTemplateJson(JSONUtil.toJsonStr(cvInfoDto));
fill(FillTypeEnum.UPDATE.getCode(), cvInfo);
applyInfo.setCvMd5(md5Hash);
applyInfo.setExperience(cvInfoDto.getExperienceYear());
scoreStr = resultMsg;
}
//更新岗位申请数据记录
applyInfo.setCandidateStatus("Pending");
applyInfo.setStage("");
//更新岗位申请数据记录--根据评分进行计算
//分数解析
String[] strs = scoreStr.split("\n");
if(strs != null && strs.length > 0){
String score = strs[0].replaceAll("Score:","").trim();
String[] scores = score.split("/");
if(scores != null && scores.length > 0){
applyInfo.setAiMatchScore(scores[0]);
try{
applyInfo.setAiMatchScorePercentage(new BigDecimal(scores[0]).
divide(new BigDecimal(5)).setScale(2,4));
}catch (Exception e){e.printStackTrace();}
}
}
if(applyInfo.getAiMatchScorePercentage() != null){
if(applyInfo.getAiMatchScorePercentage().compareTo(new BigDecimal(0.85)) >= 0){
applyInfo.setCandidateStatus(CandidateStatusEnum.HOT.getCode());
}else if(applyInfo.getAiMatchScorePercentage().compareTo(new BigDecimal(0.85)) < 0
&& applyInfo.getAiMatchScorePercentage().compareTo(new BigDecimal(0.6)) >= 0){
applyInfo.setCandidateStatus(CandidateStatusEnum.WARM.getCode());
}else if(applyInfo.getAiMatchScorePercentage().compareTo(new BigDecimal(0.6)) < 0
&& applyInfo.getAiMatchScorePercentage().compareTo(new BigDecimal(0.3)) >= 0){
applyInfo.setCandidateStatus(CandidateStatusEnum.COLD.getCode());
}else {
applyInfo.setCandidateStatus(CandidateStatusEnum.PENDING.getCode());
}
}
applyInfo.setRecruiterId(rolesInf.getRecruiterId());
applyInfo.setStage(StageEnum.APPLIED.getCode());
hotakeRolesApplyInfoMapper.updateHotakeRolesApplyInfo(applyInfo);
} catch (Exception e) {
e.printStackTrace();
@@ -238,7 +274,7 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
List<Map<String,String>> list = new LinkedList();
Map<String,String> entity = new HashMap<>();
entity.put("role","user");
entity.put("content","从下面提供的文本中提取所有能识别到的简历信息只提取原文中存在的内容不要补充、不推测、不总结。需要提取的字段包括name姓名或人名、phone电话号码、email电子邮件地址、position岗位或者简历中自己期望的职位等、location地点或者地址、家庭住址、links所有链接地址、currentWork(当前工作公司)、about关于我/自我介绍、skills_tools关键资格许可证、注册/会员资格、认证、languages语言能力,主要就是Languages下面的语言、experience工作经历,除了title、company、location、durationStart、durationEnd,其他的都放到description里面,并且description里面要根据换行符分成不同的content),日期要拆分成开始时间(durationStart)和结束时间(durationEnd)、education教育经历,日期要拆分成开始时间(durationStart)和结束时间(durationEnd))。请将提取结果以结构化 JSON 格式返回,格式如下:{ \\\"name\\\": \\\"\\\", \\\"phone\\\": \\\"\\\", \\\"currentWork\\\": \\\"\\\", \\\"position\\\": \\\"\\\", \\\"location\\\": \\\"\\\", \\\"email\\\": \\\"\\\", \\\"links\\\": [{\\\"content\\\":\\\"\\\"}], \\\"about\\\": \\\"\\\", \\\"skillsTools\\\": [{\\\"content\\\":\\\"\\\"}], \\\"languages\\\": [{\\\"content\\\":\\\"\\\"}], \\\"experience\\\": [{\\\"title\\\": \\\"\\\", \\\"company\\\": \\\"\\\",\\\"location\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\",\\\"description\\\": [{\\\"content\\\":\\\"\\\"}]}], \\\"education\\\": [{\\\"degree\\\": \\\"\\\",\\\"institution\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\"}] }。字段不存在则返回 null 或空数组。只返回标准可解析的 JSON结构 ,不要多余的```json等信息不要解释说明不要改写内容。以下为待处理文本"+contents);
entity.put("content","从下面提供的文本中提取所有能识别到的简历信息只提取原文中存在的内容不要补充、不推测、不总结。需要提取的字段包括name姓名或人名、phone电话号码、email电子邮件地址experienceYear根据工作经验计算出来的工作年限position岗位或者简历中自己期望的职位等、location地点或者地址、家庭住址、links所有链接地址、currentWork(当前工作公司)、about关于我/自我介绍、skills_tools关键资格许可证、注册/会员资格、认证、languages语言能力,主要就是Languages下面的语言、experience工作经历,除了title、company、location、durationStart、durationEnd,其他的都放到description里面,并且description里面要根据换行符分成不同的content),日期要拆分成开始时间(durationStart)和结束时间(durationEnd)、education教育经历,日期要拆分成开始时间(durationStart)和结束时间(durationEnd))。请将提取结果以结构化 JSON 格式返回,格式如下:{ \\\"name\\\": \\\"\\\", \\\"phone\\\": \\\"\\\", \\\"currentWork\\\": \\\"\\\", \\\"position\\\": \\\"\\\", \\\"location\\\": \\\"\\\", \\\"email\\\": \\\"\\\", \\\"experienceYear\\\": \\\"\\\", \\\"links\\\": [{\\\"content\\\":\\\"\\\"}], \\\"about\\\": \\\"\\\", \\\"skillsTools\\\": [{\\\"content\\\":\\\"\\\"}], \\\"languages\\\": [{\\\"content\\\":\\\"\\\"}], \\\"experience\\\": [{\\\"title\\\": \\\"\\\", \\\"company\\\": \\\"\\\",\\\"location\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\",\\\"description\\\": [{\\\"content\\\":\\\"\\\"}]}], \\\"education\\\": [{\\\"degree\\\": \\\"\\\",\\\"institution\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\"}] }。字段不存在则返回 null 或空数组。只返回标准可解析的 JSON结构 ,不要多余的```json等信息不要解释说明不要改写内容。以下为待处理文本"+contents);
//根据AI做
list.add(entity);
String resultCv = chatGPTClient.handleAiChat(JSONUtil.toJsonStr(list), "JX");
@@ -261,6 +297,9 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
if(StrUtil.isEmpty(cvInfoDto.getLocation())){
cvInfoDto.setLocation("-");
}
if (StrUtil.isEmpty(cvInfoDto.getExperienceYear())){
cvInfoDto.setExperienceYear("-");
}
if(StrUtil.isEmpty(cvInfoDto.getAbout())){
cvInfoDto.setAbout("-");
}

View File

@@ -1,13 +1,22 @@
package com.vetti.hotake.service.impl;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.vetti.common.core.service.BaseServiceImpl;
import com.vetti.common.enums.FillTypeEnum;
import com.vetti.common.utils.DateUtils;
import com.vetti.common.utils.SecurityUtils;
import com.vetti.hotake.domain.HotakeRolesInfo;
import com.vetti.hotake.domain.dto.HotakeCvInfoDto;
import com.vetti.hotake.domain.dto.VcDto.*;
import com.vetti.hotake.mapper.HotakeRolesInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -29,6 +38,9 @@ public class HotakeRolesApplyInfoServiceImpl extends BaseServiceImpl implements
@Autowired
private HotakeRolesApplyInfoMapper hotakeRolesApplyInfoMapper;
@Autowired
private HotakeRolesInfoMapper hotakeRolesInfoMapper;
/**
* 查询候选人岗位申请信息
*
@@ -52,7 +64,22 @@ public class HotakeRolesApplyInfoServiceImpl extends BaseServiceImpl implements
@Override
public List<HotakeRolesApplyInfo> selectHotakeRolesApplyInfoList(HotakeRolesApplyInfo hotakeRolesApplyInfo)
{
return hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoList(hotakeRolesApplyInfo);
List<HotakeRolesApplyInfo> applyInfoList = hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoList(hotakeRolesApplyInfo);
if(CollectionUtil.isEmpty(applyInfoList)) {
//查询岗位数据集合
HotakeRolesInfo query = new HotakeRolesInfo();
query.setRecruiterId(SecurityUtils.getUserId());
List<HotakeRolesInfo> rolesInfoList = hotakeRolesInfoMapper.selectHotakeRolesInfoList(query);
for(HotakeRolesApplyInfo applyInfo : applyInfoList) {
for(HotakeRolesInfo rolesInfo : rolesInfoList) {
if(rolesInfo.getId().longValue() == applyInfo.getRoleId().longValue()) {
applyInfo.setRolesInfo(rolesInfo);
}
}
}
}
return applyInfoList;
}
/**
@@ -133,4 +160,131 @@ public class HotakeRolesApplyInfoServiceImpl extends BaseServiceImpl implements
public int batchInsertHotakeRolesApplyInfo(List<HotakeRolesApplyInfo> hotakeRolesApplyInfoList){
return hotakeRolesApplyInfoMapper.batchInsertHotakeRolesApplyInfo(hotakeRolesApplyInfoList);
}
/**
* 简历解析数据
*
* @param contents
* @return
*/
private HotakeCvInfoDto handleAnalysisCvInfo(String contents) {
try {
HotakeCvInfoDto cvInfoDto = JSONUtil.toBean(contents, HotakeCvInfoDto.class);
//数据添加默认值
if(cvInfoDto != null){
if(StrUtil.isEmpty(cvInfoDto.getName())){
cvInfoDto.setName("-");
}
if(StrUtil.isEmpty(cvInfoDto.getPhone())){
cvInfoDto.setPhone("-");
}
if(StrUtil.isEmpty(cvInfoDto.getEmail())){
cvInfoDto.setEmail("-");
}
if(StrUtil.isEmpty(cvInfoDto.getPosition())){
cvInfoDto.setPosition("-");
}
if(StrUtil.isEmpty(cvInfoDto.getLocation())){
cvInfoDto.setLocation("-");
}
if (StrUtil.isEmpty(cvInfoDto.getExperienceYear())){
cvInfoDto.setExperienceYear("-");
}
if(StrUtil.isEmpty(cvInfoDto.getAbout())){
cvInfoDto.setAbout("-");
}
if (StrUtil.isEmpty(cvInfoDto.getCurrentWork())){
cvInfoDto.setCurrentWork("-");
}
if(CollectionUtil.isNotEmpty(cvInfoDto.getSkillsTools())){
for (VcSkillsToolsDto toolsDto :cvInfoDto.getSkillsTools()) {
if(StrUtil.isEmpty(toolsDto.getContent())){
toolsDto.setContent("-");
}
}
}
if(CollectionUtil.isNotEmpty(cvInfoDto.getLinks())){
for (VcLinksDto linksDto :cvInfoDto.getLinks()) {
if(StrUtil.isEmpty(linksDto.getContent())){
linksDto.setContent("-");
}
}
}
if(CollectionUtil.isNotEmpty(cvInfoDto.getLanguages())){
for (VcLanguagesDto languagesDto :cvInfoDto.getLanguages()) {
if(StrUtil.isEmpty(languagesDto.getContent())){
languagesDto.setContent("-");
}
}
}
if(CollectionUtil.isNotEmpty(cvInfoDto.getExperience())){
for (VcExperienceDto experienceDto :cvInfoDto.getExperience()) {
if (StrUtil.isEmpty(experienceDto.getTitle())){
experienceDto.setTitle("-");
}
if(StrUtil.isEmpty(experienceDto.getCompany())){
experienceDto.setCompany("-");
}
if(StrUtil.isEmpty(experienceDto.getLocation())){
experienceDto.setLocation("-");
}
if(StrUtil.isEmpty(experienceDto.getDurationStart())){
experienceDto.setDurationStart("-");
}
if(StrUtil.isEmpty(experienceDto.getDurationEnd())){
experienceDto.setDurationEnd("-");
}
if (CollectionUtil.isNotEmpty(experienceDto.getDescription())){
for(VcExperienceDescriptionDto descriptionDto :experienceDto.getDescription()){
if(StrUtil.isEmpty(descriptionDto.getContent())){
descriptionDto.setContent("-");
}
}
}
}
}
if(CollectionUtil.isNotEmpty(cvInfoDto.getEducation())){
for (VcEducationDto educationDto :cvInfoDto.getEducation()) {
if (StrUtil.isEmpty(educationDto.getDegree())){
educationDto.setDegree("-");
}
if(StrUtil.isEmpty(educationDto.getInstitution())){
educationDto.setInstitution("-");
}
if(StrUtil.isEmpty(educationDto.getDurationStart())){
educationDto.setDurationStart("-");
}
if(StrUtil.isEmpty(educationDto.getDurationEnd())){
educationDto.setDurationEnd("-");
}
if(educationDto.getCertificate() != null){
if(StrUtil.isEmpty(educationDto.getCertificate().getFileName())){
educationDto.getCertificate().setFileName("-");
}
if (StrUtil.isEmpty(educationDto.getCertificate().getFileSuffix())){
educationDto.getCertificate().setFileSuffix("-");
}
if (StrUtil.isEmpty(educationDto.getCertificate().getFileUrl())){
educationDto.getCertificate().setFileUrl("-");
}
if (StrUtil.isEmpty(educationDto.getCertificate().getFileSizeShow())){
educationDto.getCertificate().setFileSizeShow("-");
}
}
}
}
}
return cvInfoDto;
} catch (Exception e) {
e.printStackTrace();
}
return new HotakeCvInfoDto();
}
}

View File

@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.vetti.common.core.domain.entity.SysUser;
import com.vetti.common.core.service.BaseServiceImpl;
import com.vetti.common.enums.FillTypeEnum;
import com.vetti.common.enums.RoleOperStepsEnum;
@@ -23,6 +24,7 @@ import com.vetti.hotake.mapper.HotakeRolesInfoMapper;
import com.vetti.hotake.service.IHotakeAiInterviewQuestionsInfoService;
import com.vetti.hotake.service.IHotakeInitialScreeningQuestionsInfoService;
import com.vetti.hotake.service.IHotakeRolesInfoService;
import com.vetti.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -43,6 +45,9 @@ public class HotakeRolesInfoServiceImpl extends BaseServiceImpl implements IHota
@Autowired
private HotakeRolesInfoMapper hotakeRolesInfoMapper;
@Autowired
private SysUserMapper sysUserMapper;
@Autowired
private IHotakeInitialScreeningQuestionsInfoService hotakeInitialScreeningQuestionsInfoService;
@@ -121,6 +126,9 @@ public class HotakeRolesInfoServiceImpl extends BaseServiceImpl implements IHota
queryAiQuestion.setRoleId(id);
List<HotakeAiInterviewQuestionsInfo> aiInterviewQuestionsInfoList = hotakeAiInterviewQuestionsInfoService.selectHotakeAiInterviewQuestionsInfoList(queryAiQuestion);
dto.setAiInterviewQuestionsInfoList(aiInterviewQuestionsInfoList);
SysUser user = sysUserMapper.selectUserById(hotakeRolesInfo.getRecruiterId());
dto.setRecruiterUser(user);
}
return dto;

View File

@@ -7,6 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="HotakeRolesApplyInfo" id="HotakeRolesApplyInfoResult">
<result property="id" column="id" />
<result property="candidateId" column="candidate_id" />
<result property="recruiterId" column="recruiter_id" />
<result property="roleId" column="role_id" />
<result property="fullName" column="full_name" />
<result property="email" column="email" />
@@ -33,13 +34,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectHotakeRolesApplyInfoVo">
select id, candidate_id, role_id, full_name, email, phone_number, cv_file, cv_file_suffix,file_size_show,cover_letter, candidate_status, stage, last_contact, cv_template_json, cv_score, cv_md5, experience, ai_match_score, ai_match_score_percentage, del_flag, create_by, create_time, update_by, update_time, remark from hotake_roles_apply_info
select id, candidate_id,recruiter_id, role_id, full_name, email, phone_number, cv_file, cv_file_suffix,file_size_show,cover_letter, candidate_status, stage, last_contact, cv_template_json, cv_score, cv_md5, experience, ai_match_score, ai_match_score_percentage, del_flag, create_by, create_time, update_by, update_time, remark from hotake_roles_apply_info
</sql>
<select id="selectHotakeRolesApplyInfoList" parameterType="HotakeRolesApplyInfo" resultMap="HotakeRolesApplyInfoResult">
<include refid="selectHotakeRolesApplyInfoVo"/>
<where>
<if test="candidateId != null "> and candidate_id = #{candidateId}</if>
<if test="recruiterId != null "> and recruiter_id = #{recruiterId}</if>
<if test="roleId != null "> and role_id = #{roleId}</if>
<if test="fullName != null and fullName != ''"> and full_name like concat('%', #{fullName}, '%')</if>
<if test="email != null and email != ''"> and email = #{email}</if>
@@ -69,6 +71,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
insert into hotake_roles_apply_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="candidateId != null">candidate_id,</if>
<if test="recruiterId != null">recruiter_id,</if>
<if test="roleId != null">role_id,</if>
<if test="fullName != null">full_name,</if>
<if test="email != null">email,</if>
@@ -95,6 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="candidateId != null">#{candidateId},</if>
<if test="recruiterId != null">#{recruiterId},</if>
<if test="roleId != null">#{roleId},</if>
<if test="fullName != null">#{fullName},</if>
<if test="email != null">#{email},</if>
@@ -125,6 +129,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update hotake_roles_apply_info
<trim prefix="SET" suffixOverrides=",">
<if test="candidateId != null">candidate_id = #{candidateId},</if>
<if test="recruiterId != null">recruiter_id = #{recruiterId},</if>
<if test="roleId != null">role_id = #{roleId},</if>
<if test="fullName != null">full_name = #{fullName},</if>
<if test="email != null">email = #{email},</if>
@@ -164,9 +169,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete>
<insert id="batchInsertHotakeRolesApplyInfo">
insert into hotake_roles_apply_info( id, candidate_id, role_id, full_name, email, phone_number, cv_file, cover_letter, candidate_status, stage, last_contact, cv_template_json, cv_score, cv_md5, experience, ai_match_score, ai_match_score_percentage, del_flag, create_by, create_time, update_by, update_time, remark) values
insert into hotake_roles_apply_info( id, candidate_id,recruiter_id, role_id, full_name, email, phone_number, cv_file, cover_letter, candidate_status, stage, last_contact, cv_template_json, cv_score, cv_md5, experience, ai_match_score, ai_match_score_percentage, del_flag, create_by, create_time, update_by, update_time, remark) values
<foreach item="item" index="index" collection="list" separator=",">
( #{item.id}, #{item.candidateId}, #{item.roleId}, #{item.fullName}, #{item.email}, #{item.phoneNumber}, #{item.cvFile}, #{item.coverLetter}, #{item.candidateStatus}, #{item.stage}, #{item.lastContact}, #{item.cvTemplateJson}, #{item.cvScore}, #{item.cvMd5}, #{item.experience}, #{item.aiMatchScore}, #{item.aiMatchScorePercentage}, #{item.delFlag}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.remark})
( #{item.id}, #{item.candidateId},#{item.recruiterId}, #{item.roleId}, #{item.fullName}, #{item.email}, #{item.phoneNumber}, #{item.cvFile}, #{item.coverLetter}, #{item.candidateStatus}, #{item.stage}, #{item.lastContact}, #{item.cvTemplateJson}, #{item.cvScore}, #{item.cvMd5}, #{item.experience}, #{item.aiMatchScore}, #{item.aiMatchScorePercentage}, #{item.delFlag}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime}, #{item.remark})
</foreach>
</insert>
</mapper>