AI 业务逻辑完善

This commit is contained in:
2026-01-21 13:42:38 +08:00
parent 474a71c4db
commit fb05cadd0f
14 changed files with 824 additions and 389 deletions

View File

@@ -197,7 +197,7 @@ public class HotakeAiCommonToolsController extends BaseController {
*/ */
@ApiOperation("招聘者 AI简历评分和排名系统") @ApiOperation("招聘者 AI简历评分和排名系统")
@PostMapping(value = "/aiCvScoringRanking") @PostMapping(value = "/aiCvScoringRanking")
public R<?> aiCvScoringRanking(@RequestBody HotakeAiCvScoringRankingRoleApplyVo roleApplyVo) public R<HotakeAiCvScoringRankingDto> aiCvScoringRanking(@RequestBody HotakeAiCvScoringRankingRoleApplyVo roleApplyVo)
{ {
return R.ok(hotakeAiCommonToolsService.handleAiCvScoringRanking(roleApplyVo)); return R.ok(hotakeAiCommonToolsService.handleAiCvScoringRanking(roleApplyVo));
} }
@@ -207,7 +207,7 @@ public class HotakeAiCommonToolsController extends BaseController {
*/ */
@ApiOperation("招聘者查看候选人匹配度") @ApiOperation("招聘者查看候选人匹配度")
@PostMapping(value = "/candidateCompatibility") @PostMapping(value = "/candidateCompatibility")
public R<?> candidateCompatibility(@RequestBody HotakeCandidateCompatibilityVo compatibilityVo) public R<HotakeCandidateCompatibilityDto> candidateCompatibility(@RequestBody HotakeCandidateCompatibilityVo compatibilityVo)
{ {
return R.ok(hotakeAiCommonToolsService.handleCandidateCompatibility(compatibilityVo)); return R.ok(hotakeAiCommonToolsService.handleCandidateCompatibility(compatibilityVo));
} }

View File

@@ -110,5 +110,25 @@ public class HotakeRolesApplyInfoController extends BaseController
return R.ok(); return R.ok();
} }
/**
* AI简历评分和排名系统
*/
@ApiOperation("AI简历评分和排名系统")
@GetMapping("/aiCvScoringRankingList")
public R<List<HotakeRolesApplyInfo>> getAiCvScoringRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo)
{
List<HotakeRolesApplyInfo> list = hotakeRolesApplyInfoService.handleAiCvScoringRankingList(hotakeRolesApplyInfo);
return R.ok(list,"");
}
/**
* 招聘者查看候选人匹配度
*/
@ApiOperation("招聘者查看候选人匹配度")
@GetMapping("/candidateCompatibilityInfo")
public R<HotakeRolesApplyInfo> getCandidateCompatibilityInfo(HotakeRolesApplyInfo hotakeRolesApplyInfo)
{
HotakeRolesApplyInfo info = hotakeRolesApplyInfoService.handleCandidateCompatibilityInfo(hotakeRolesApplyInfo);
return R.ok(info,"");
}
} }

View File

@@ -3,6 +3,9 @@ package com.vetti.hotake.domain;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.List; import java.util.List;
import com.vetti.common.core.domain.entity.SysUser;
import com.vetti.hotake.domain.dto.HotakeAiCvScoringRankingDto;
import com.vetti.hotake.domain.dto.HotakeCandidateCompatibilityDto;
import com.vetti.hotake.domain.dto.HotakeCvInfoDto; import com.vetti.hotake.domain.dto.HotakeCvInfoDto;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@@ -121,6 +124,18 @@ public class HotakeRolesApplyInfo extends BaseEntity
@ApiModelProperty("申请状态pending:进行中complete已完成canceled取消") @ApiModelProperty("申请状态pending:进行中complete已完成canceled取消")
private String status; private String status;
@ApiModelProperty("AI简历评分和排名JSON")
private String aiCvScoringRankingJson;
@ApiModelProperty("AI简历评分和排名最终得分")
private BigDecimal aiCvScore;
@ApiModelProperty("候选人匹配度JSON")
private String candidateCompatibilityJson;
@ApiModelProperty("候选人匹配度最终得分")
private BigDecimal candidateCompatibilityScore;
@ApiModelProperty("岗位信息") @ApiModelProperty("岗位信息")
private HotakeRolesInfo rolesInfo; private HotakeRolesInfo rolesInfo;
@@ -130,6 +145,15 @@ public class HotakeRolesApplyInfo extends BaseEntity
@ApiModelProperty("岗位申请操作记录数据集合") @ApiModelProperty("岗位申请操作记录数据集合")
private List<HotakeRolesApplyOperRecord> applyOperRecords; private List<HotakeRolesApplyOperRecord> applyOperRecords;
@ApiModelProperty("候选人用户信息")
private SysUser candidateUSer;
@ApiModelProperty("AI简历评分和排名数据对象")
private HotakeAiCvScoringRankingDto rankingDto;
@ApiModelProperty("招聘者查看候选人匹配度数据对象")
private HotakeCandidateCompatibilityDto compatibilityDto;
@ApiModelProperty("岗位申请ID数据集合") @ApiModelProperty("岗位申请ID数据集合")
private List<Long> applyRoleIdList; private List<Long> applyRoleIdList;

View File

@@ -0,0 +1,51 @@
package com.vetti.hotake.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* 招聘者AI简历评分和排名系统 返回对象
*
* @author ID
* @date 2025-09-06
*/
@Data
@Accessors(chain = true)
public class HotakeAiCvScoringRankingDto {
@ApiModelProperty("技能匹配评分 ")
private BigDecimal skills;
@ApiModelProperty("经验匹配评分 ")
private BigDecimal experience;
@ApiModelProperty("教育背景评分 ")
private BigDecimal education;
@ApiModelProperty("文化契合评分 ")
private BigDecimal cultural;
@ApiModelProperty("发展潜力评分 ")
private BigDecimal potential;
@ApiModelProperty("优势点列表 ")
private List<String> strengths;
@ApiModelProperty("不足点列表 ")
private List<String> weaknesses;
@ApiModelProperty("推荐等级 ")
private String recommendation;
@ApiModelProperty("推荐理由 ")
private String reason;
@ApiModelProperty("总体评分")
private BigDecimal overallScore;
}

View File

@@ -0,0 +1,41 @@
package com.vetti.hotake.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* 招聘者查看候选人匹配度 返回对象
*
* @author ID
* @date 2025-09-06
*/
@Data
@Accessors(chain = true)
public class HotakeCandidateCompatibilityDto {
@ApiModelProperty("核心优势评分 ")
private BigDecimal strengthsScore;
@ApiModelProperty("核心优势列表 ")
private List<String> keyStrengths;
@ApiModelProperty("关键差异评分(越高差异越小) ")
private BigDecimal differencesScore;
@ApiModelProperty("关键差异列表 ")
private List<String> keyDifferences;
@ApiModelProperty("文化契合评分 ")
private BigDecimal culturalScore;
@ApiModelProperty("文化契合详情 ")
private List<String> culturalFitDetails;
@ApiModelProperty("总体评分")
private BigDecimal overallScore;
}

View File

@@ -1,11 +1,10 @@
package com.vetti.hotake.domain.vo; package com.vetti.hotake.domain.vo;
import com.vetti.hotake.domain.HotakeRolesApplyInfo;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.List;
/** /**
* 招聘者AI简历评分和排名系统-岗位申请 请求对象 * 招聘者AI简历评分和排名系统-岗位申请 请求对象
* *
@@ -16,6 +15,10 @@ import java.util.List;
@Accessors(chain = true) @Accessors(chain = true)
public class HotakeAiCvScoringRankingRoleApplyVo { public class HotakeAiCvScoringRankingRoleApplyVo {
@ApiModelProperty("岗位申请ID集合") @ApiModelProperty("岗位申请信息")
private List<Long> roleApplyIds; private HotakeRolesApplyInfo applyInfo;
/** 简历模版Json */
@ApiModelProperty("简历模版Json")
private String cvTemplateJson;
} }

View File

@@ -35,7 +35,7 @@ public class HotakeAiCvScoringRankingVo {
private String educationRequired; private String educationRequired;
@ApiModelProperty("候选人信息") @ApiModelProperty("候选人信息")
private List<HotakeCandidateVcInfoVo> candidates; private HotakeCandidateVcInfoVo candidates;
} }

View File

@@ -27,6 +27,22 @@ public interface HotakeRolesApplyInfoMapper
*/ */
public List<HotakeRolesApplyInfo> selectHotakeRolesApplyInfoList(HotakeRolesApplyInfo hotakeRolesApplyInfo); public List<HotakeRolesApplyInfo> selectHotakeRolesApplyInfoList(HotakeRolesApplyInfo hotakeRolesApplyInfo);
/**
* 查询候选人岗位申请信息列表
*
* @param hotakeRolesApplyInfo 候选人岗位申请信息
* @return 候选人岗位申请信息集合
*/
public List<HotakeRolesApplyInfo> selectHotakeRolesApplyInfoRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo);
/**
* 查询候选人岗位申请信息列表
*
* @param hotakeRolesApplyInfo 候选人岗位申请信息
* @return 候选人岗位申请信息集合
*/
public List<HotakeRolesApplyInfo> selectHotakeRolesApplyInfoCompatibilityScoreList(HotakeRolesApplyInfo hotakeRolesApplyInfo);
/** /**
* 新增候选人岗位申请信息 * 新增候选人岗位申请信息
* *

View File

@@ -141,7 +141,7 @@ public interface IHotakeAiCommonToolsService {
* @param roleApplyVo 岗位申请数据对象 * @param roleApplyVo 岗位申请数据对象
* @return * @return
*/ */
public String handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo); public HotakeAiCvScoringRankingDto handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo);
/** /**
@@ -149,6 +149,6 @@ public interface IHotakeAiCommonToolsService {
* @param compatibilityVo 招聘者查看候选人匹配度 输入信息 * @param compatibilityVo 招聘者查看候选人匹配度 输入信息
* @return * @return
*/ */
public String handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo); public HotakeCandidateCompatibilityDto handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo);
} }

View File

@@ -76,5 +76,20 @@ public interface IHotakeRolesApplyInfoService
*/ */
public int updateBatchEditStage(List<HotakeRolesApplyStageVo> stageVoList); public int updateBatchEditStage(List<HotakeRolesApplyStageVo> stageVoList);
/**
* AI简历评分和排名系统
*
* @param hotakeRolesApplyInfo 候选人岗位申请信息
* @return 候选人岗位申请信息集合
*/
public List<HotakeRolesApplyInfo> handleAiCvScoringRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo);
/**
* 招聘者查看候选人匹配度
*
* @param hotakeRolesApplyInfo 候选人岗位申请信息
* @return 候选人岗位申请信息集合
*/
public HotakeRolesApplyInfo handleCandidateCompatibilityInfo(HotakeRolesApplyInfo hotakeRolesApplyInfo);
} }

View File

@@ -44,8 +44,7 @@ import java.util.stream.Collectors;
@Slf4j @Slf4j
@SuppressWarnings("all") @SuppressWarnings("all")
@Service @Service
public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements IHotakeAiCommonToolsService public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements IHotakeAiCommonToolsService {
{
@Autowired @Autowired
private HotakeRolesInfoMapper hotakeRolesInfoMapper; private HotakeRolesInfoMapper hotakeRolesInfoMapper;
@@ -65,6 +64,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 职位描述生成器 * 职位描述生成器
*
* @param roleId 岗位ID * @param roleId 岗位ID
* @param industry Industry sector 行业领域 * @param industry Industry sector 行业领域
* @param coreRequirements Key skills or experience requirements 关键技能或经验要求 * @param coreRequirements Key skills or experience requirements 关键技能或经验要求
@@ -136,6 +136,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 初筛问题生成 * 初筛问题生成
*
* @return * @return
*/ */
@Override @Override
@@ -185,6 +186,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 简历岗位匹配度评分 * 简历岗位匹配度评分
*
* @return * @return
*/ */
@Override @Override
@@ -209,6 +211,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 简历分析优化器 * 简历分析优化器
*
* @param cvConnect 简历内容 * @param cvConnect 简历内容
* @return * @return
*/ */
@@ -433,6 +436,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 初步筛选问题淘汰评分 * 初步筛选问题淘汰评分
*
* @param cvConnect * @param cvConnect
* @return * @return
*/ */
@@ -479,6 +483,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 处理分析附件结果 * 处理分析附件结果
*
* @param connect * @param connect
* @return * @return
*/ */
@@ -503,6 +508,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 处理附件分析结果合并信息 * 处理附件分析结果合并信息
*
* @param basicInformation 基础信息 * @param basicInformation 基础信息
* @param attachmentContent 所有附件信息 * @param attachmentContent 所有附件信息
* @return * @return
@@ -529,6 +535,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 生成最终的Markdown格式简历 * 生成最终的Markdown格式简历
*
* @param markdown * @param markdown
* @return * @return
*/ */
@@ -554,6 +561,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 网站内容抓取 * 网站内容抓取
*
* @param webUrl 网站链接地址 * @param webUrl 网站链接地址
* @return * @return
*/ */
@@ -573,6 +581,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 网站AI信息提取使用提示词 * 网站AI信息提取使用提示词
*
* @param webInfoExtractVo 网站提取对象 * @param webInfoExtractVo 网站提取对象
* @return * @return
*/ */
@@ -618,6 +627,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 网站信息增强处理 * 网站信息增强处理
*
* @param webUlr * @param webUlr
* @param webContent 网站内容 * @param webContent 网站内容
* @return * @return
@@ -645,6 +655,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 个人简介生成器 * 个人简介生成器
*
* @param personalProfileGeneratorVo 个人信息 * @param personalProfileGeneratorVo 个人信息
* @return * @return
*/ */
@@ -694,6 +705,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 工作经验生成器 * 工作经验生成器
*
* @param workExperienceGeneratorVo 工作信息 * @param workExperienceGeneratorVo 工作信息
* @return * @return
*/ */
@@ -743,6 +755,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 招聘链接信息分析补全 * 招聘链接信息分析补全
*
* @param roleLinkAnalysisVo 岗位链接对象 * @param roleLinkAnalysisVo 岗位链接对象
* @return * @return
*/ */
@@ -852,9 +865,9 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
} }
/** /**
* 招聘链接信息分析补全 * 招聘链接信息分析补全
*
* @param roleLinkAnalysisVo 岗位链接对象 * @param roleLinkAnalysisVo 岗位链接对象
* @return * @return
*/ */
@@ -955,6 +968,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* AI面试问题生成 * AI面试问题生成
*
* @param rolesInfo 岗位信息 * @param rolesInfo 岗位信息
* @return * @return
*/ */
@@ -994,6 +1008,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 候选人AI面试分析 * 候选人AI面试分析
*
* @param rolesInfo 候选人AI面试分析信息 * @param rolesInfo 候选人AI面试分析信息
* @return * @return
*/ */
@@ -1089,26 +1104,14 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
/** /**
* 招聘者AI简历评分和排名系统 * 招聘者AI简历评分和排名系统
*
* @param scoringRankingVo 招聘者AI简历评分和排名系统输入信息 * @param scoringRankingVo 招聘者AI简历评分和排名系统输入信息
* @return * @return
*/ */
@Override @Override
public String handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo) { public HotakeAiCvScoringRankingDto handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo) {
if(CollectionUtil.isEmpty(roleApplyVo.getRoleApplyIds()) || roleApplyVo.getRoleApplyIds().size() < 2){ HotakeAiCvScoringRankingDto dto = new HotakeAiCvScoringRankingDto();
throw new ServiceException("Please select at least two pieces of data"); HotakeRolesInfo rolesInfo = hotakeRolesInfoMapper.selectHotakeRolesInfoById(roleApplyVo.getApplyInfo().getRoleId());
}
//根据岗位申请Id查询岗位申请数据信息列表
HotakeRolesApplyInfo queryApplyInfo = new HotakeRolesApplyInfo();
queryApplyInfo.setApplyRoleIdList(roleApplyVo.getRoleApplyIds());
List<HotakeRolesApplyInfo> applyInfoList = hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoList(queryApplyInfo);
List<Long> roleIds = applyInfoList.stream().map(HotakeRolesApplyInfo::getRoleId).collect(Collectors.toList());;
Set<Long> setDatas = new HashSet<>();
setDatas.addAll(roleIds);
if(setDatas.size() > 1){
throw new ServiceException("Only data from the same position can be selected");
}
HotakeRolesInfo rolesInfo = hotakeRolesInfoMapper.selectHotakeRolesInfoById(roleIds.get(0));
HotakeAiCvScoringRankingVo scoringRankingVo = new HotakeAiCvScoringRankingVo(); HotakeAiCvScoringRankingVo scoringRankingVo = new HotakeAiCvScoringRankingVo();
scoringRankingVo.setTitle(rolesInfo.getRoleName()); scoringRankingVo.setTitle(rolesInfo.getRoleName());
@@ -1134,9 +1137,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
EducationRequirementsDto educationRequirements = JSONUtil.toBean(rolesInfo.getEducationRequirementsJson(), EducationRequirementsDto.class); EducationRequirementsDto educationRequirements = JSONUtil.toBean(rolesInfo.getEducationRequirementsJson(), EducationRequirementsDto.class);
scoringRankingVo.setEducationRequired(educationRequirements.getDegree() + "," + educationRequirements.getAcademicMajor()); scoringRankingVo.setEducationRequired(educationRequirements.getDegree() + "," + educationRequirements.getAcademicMajor());
List<HotakeCandidateVcInfoVo> candidates = new ArrayList<>(); HotakeCvInfoDto cvInfoDto = JSONUtil.toBean(roleApplyVo.getCvTemplateJson(), HotakeCvInfoDto.class);
for(HotakeRolesApplyInfo applyInfo : applyInfoList){
HotakeCvInfoDto cvInfoDto = JSONUtil.toBean(applyInfo.getCvTemplateJson(), HotakeCvInfoDto.class);
HotakeCandidateVcInfoVo infoVo = new HotakeCandidateVcInfoVo(); HotakeCandidateVcInfoVo infoVo = new HotakeCandidateVcInfoVo();
infoVo.setName(cvInfoDto.getName()); infoVo.setName(cvInfoDto.getName());
@@ -1152,9 +1153,8 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
} }
infoVo.setSkills(skills); infoVo.setSkills(skills);
infoVo.setSummary(cvInfoDto.getAbout()); infoVo.setSummary(cvInfoDto.getAbout());
candidates.add(infoVo);
} scoringRankingVo.setCandidates(infoVo);
scoringRankingVo.setCandidates(candidates);
String prompt = AiCommonPromptConstants.initializationAiCvScoringRankingPrompt(); String prompt = AiCommonPromptConstants.initializationAiCvScoringRankingPrompt();
String userPrompt_1 = JSONUtil.toJsonStr(scoringRankingVo); String userPrompt_1 = JSONUtil.toJsonStr(scoringRankingVo);
@@ -1172,19 +1172,65 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "AICVSR"); String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "AICVSR");
String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", "");
log.info("招聘者AI简历评分和排名系统结果:{}", resultJsonOne); log.info("招聘者AI简历评分和排名系统结果:{}", resultJsonOne);
try {
Map dataMap = JSONUtil.toBean(resultJsonOne, Map.class);
Map scoresMap = (Map) dataMap.get("scores");
if(ObjectUtil.isNotEmpty(scoresMap.get("skills"))){
dto.setSkills(new BigDecimal(scoresMap.get("skills").toString()));
}else{
dto.setSkills(BigDecimal.ZERO);
}
if(ObjectUtil.isNotEmpty(scoresMap.get("experience"))){
dto.setExperience(new BigDecimal(scoresMap.get("experience").toString()));
}else{
dto.setExperience(BigDecimal.ZERO);
}
if(ObjectUtil.isNotEmpty(scoresMap.get("education"))){
dto.setEducation(new BigDecimal(scoresMap.get("education").toString()));
}else{
dto.setEducation(BigDecimal.ZERO);
}
if(ObjectUtil.isNotEmpty(scoresMap.get("cultural"))){
dto.setCultural(new BigDecimal(scoresMap.get("cultural").toString()));
}else{
dto.setCultural(BigDecimal.ZERO);
}
if(ObjectUtil.isNotEmpty(scoresMap.get("potential"))){
dto.setPotential(new BigDecimal(scoresMap.get("potential").toString()));
}else{
dto.setPotential(BigDecimal.ZERO);
}
List<String> strengths = (List<String>)dataMap.get("strengths");
dto.setStrengths(strengths);
List<String> weaknesses = (List<String>)dataMap.get("weaknesses");
dto.setWeaknesses(weaknesses);
return resultJsonOne; dto.setReason(dataMap.get("reason").toString());
dto.setRecommendation(dataMap.get("recommendation").toString());
//计算总体评分 (70×0.3 + 75×0.25 + 80×0.15 + 85×0.15 + 88×0.15)
BigDecimal overallScore = dto.getSkills().multiply(new BigDecimal(0.3)).
add(dto.getExperience().multiply(new BigDecimal(0.25)).add(dto.getEducation().multiply(new BigDecimal(0.15))).
add(dto.getCultural().multiply(new BigDecimal(0.15)).add(dto.getPotential().multiply(new BigDecimal(0.15)))));
dto.setOverallScore(overallScore);
}catch (Exception e) {
e.printStackTrace();
}
return dto;
} }
/** /**
* 招聘者查看候选人匹配度 * 招聘者查看候选人匹配度
*
* @param compatibilityVo 招聘者查看候选人匹配度 输入信息 * @param compatibilityVo 招聘者查看候选人匹配度 输入信息
* @return * @return
*/ */
@Override @Override
public String handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo) { public HotakeCandidateCompatibilityDto handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo) {
HotakeCandidateCompatibilityDto dto = new HotakeCandidateCompatibilityDto();
String prompt = AiCommonPromptConstants.initializationCandidateCompatibilityPrompt(); String prompt = AiCommonPromptConstants.initializationCandidateCompatibilityPrompt();
String userPrompt_1 = "Please analyze the matching details of the following candidates\n" + String userPrompt_1 = "Please analyze the matching details of the following candidates\n" +
@@ -1212,7 +1258,36 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I
String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "AICAC"); String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "AICAC");
String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", "");
log.info("招聘者查看候选人匹配度结果:{}", resultJsonOne); log.info("招聘者查看候选人匹配度结果:{}", resultJsonOne);
Map dataMap = JSONUtil.toBean(resultJsonOne, Map.class);
if(ObjectUtil.isNotEmpty(dataMap.get("strengths_score"))){
dto.setStrengthsScore(new BigDecimal(dataMap.get("strengths_score").toString()));
}else{
dto.setStrengthsScore(BigDecimal.ZERO);
}
if(ObjectUtil.isNotEmpty(dataMap.get("differences_score"))){
dto.setDifferencesScore(new BigDecimal(dataMap.get("differences_score").toString()));
}else{
dto.setDifferencesScore(BigDecimal.ZERO);
}
if(ObjectUtil.isNotEmpty(dataMap.get("cultural_score"))){
dto.setCulturalScore(new BigDecimal(dataMap.get("cultural_score").toString()));
}else{
dto.setCulturalScore(BigDecimal.ZERO);
}
return resultJsonOne; List<String> strengths = (List<String>)dataMap.get("key_strengths");
dto.setKeyStrengths(strengths);
List<String> differences = (List<String>)dataMap.get("key_differences");
dto.setKeyDifferences(differences);
List<String> fitDetails = (List<String>)dataMap.get("cultural_fit_details");
dto.setCulturalFitDetails(fitDetails);
BigDecimal overallScore = dto.getStrengthsScore().multiply(new BigDecimal(0.4)).
add(dto.getDifferencesScore().multiply(new BigDecimal(0.3)).add(dto.getCulturalScore().multiply(new BigDecimal(0.3))));
dto.setOverallScore(overallScore);
return dto;
} }
} }

View File

@@ -2,10 +2,7 @@ package com.vetti.hotake.service.impl;
import java.io.InputStream; import java.io.InputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashMap; import java.util.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
@@ -21,9 +18,13 @@ import com.vetti.common.utils.DateUtils;
import com.vetti.common.utils.SecurityUtils; import com.vetti.common.utils.SecurityUtils;
import com.vetti.common.utils.readFile.FileContentUtil; import com.vetti.common.utils.readFile.FileContentUtil;
import com.vetti.hotake.domain.*; import com.vetti.hotake.domain.*;
import com.vetti.hotake.domain.dto.HotakeAiCvScoringRankingDto;
import com.vetti.hotake.domain.dto.HotakeCandidateCompatibilityDto;
import com.vetti.hotake.domain.dto.HotakeCvInfoDto; import com.vetti.hotake.domain.dto.HotakeCvInfoDto;
import com.vetti.hotake.domain.dto.HotakeInitialQuestionEliminationScoreDto; import com.vetti.hotake.domain.dto.HotakeInitialQuestionEliminationScoreDto;
import com.vetti.hotake.domain.dto.VcDto.*; import com.vetti.hotake.domain.dto.VcDto.*;
import com.vetti.hotake.domain.vo.HotakeAiCvScoringRankingRoleApplyVo;
import com.vetti.hotake.domain.vo.HotakeCandidateCompatibilityVo;
import com.vetti.hotake.domain.vo.HotakeInitScreQuestionsReplyRecordInfoVo; import com.vetti.hotake.domain.vo.HotakeInitScreQuestionsReplyRecordInfoVo;
import com.vetti.hotake.domain.vo.HotakeInitialQuestionEliminationScoreVo; import com.vetti.hotake.domain.vo.HotakeInitialQuestionEliminationScoreVo;
import com.vetti.hotake.mapper.HotakeCvInfoMapper; import com.vetti.hotake.mapper.HotakeCvInfoMapper;
@@ -192,65 +193,13 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
eliminationScoreVo.setInitScreQuestionsReplyRecordInfoList(initScreQuestionsReplyRecordInfoVo.getInitScreQuestionsReplyRecordInfoList()); eliminationScoreVo.setInitScreQuestionsReplyRecordInfoList(initScreQuestionsReplyRecordInfoVo.getInitScreQuestionsReplyRecordInfoList());
HotakeInitialQuestionEliminationScoreDto eliminationScoreDto = aiCommonToolsService.getInitialQuestionEliminationScore(eliminationScoreVo); HotakeInitialQuestionEliminationScoreDto eliminationScoreDto = aiCommonToolsService.getInitialQuestionEliminationScore(eliminationScoreVo);
//查询候选人的当前最新简历信息
// HotakeCvInfo queryCv = new HotakeCvInfo();
// queryCv.setUserId(SecurityUtils.getUserId());
// queryCv.setCvFileType("cv");
// List<HotakeCvInfo> cvInfos = hotakeCvInfoMapper.selectHotakeCvInfoList(queryCv);
// HotakeCvInfo cvInfo = null;
// if(CollectionUtil.isNotEmpty(cvInfos)) {
// cvInfo = cvInfos.get(0);
// }
// //解析简历内容以及获取简历对应的评分数据
// log.info("开始处理简历");
// try {
// InputStream inputStream = minioClient.getObject(
// GetObjectArgs.builder()
// .bucket(MinioBucketNameEnum.CV.getCode())
// .object(applyInfo.getCvFile())
// .build());
// String contents = FileContentUtil.readFileContent(inputStream, applyInfo.getCvFileSuffix());
// 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);
// //生成对应的简历评分
// String resultMsg = handleHotakeCvInfoScore(cvInfoDto);
// applyInfo.setCvScore(resultMsg);
// applyInfo.setCvTemplateJson(JSONUtil.toJsonStr(cvInfoDto));
// fill(FillTypeEnum.UPDATE.getCode(), cvInfo);
// applyInfo.setCvMd5(md5Hash);
// applyInfo.setExperience(cvInfoDto.getExperienceYear());
// scoreStr = resultMsg;
// }
//更新岗位申请数据记录--根据评分进行计算
//分数解析
// 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 { try {
applyInfo.setAiMatchScorePercentage(new BigDecimal(eliminationScoreDto.getScore()). applyInfo.setAiMatchScorePercentage(new BigDecimal(eliminationScoreDto.getScore()).
divide(new BigDecimal(100)).setScale(2, 4)); divide(new BigDecimal(100)).setScale(2, 4));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
// }
// }
if (applyInfo.getAiMatchScorePercentage() != null) { if (applyInfo.getAiMatchScorePercentage() != null) {
if (applyInfo.getAiMatchScorePercentage().compareTo(new BigDecimal(0.85)) >= 0) { if (applyInfo.getAiMatchScorePercentage().compareTo(new BigDecimal(0.85)) >= 0) {
applyInfo.setCandidateStatus(CandidateStatusEnum.HOT.getCode()); applyInfo.setCandidateStatus(CandidateStatusEnum.HOT.getCode());
@@ -264,6 +213,73 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
applyInfo.setCandidateStatus(CandidateStatusEnum.PENDING.getCode()); applyInfo.setCandidateStatus(CandidateStatusEnum.PENDING.getCode());
} }
} }
//解析简历数据
//查询候选人的当前最新简历信息
HotakeCvInfo queryCv = new HotakeCvInfo();
queryCv.setUserId(SecurityUtils.getUserId());
queryCv.setCvFileType("cv");
List<HotakeCvInfo> cvInfos = hotakeCvInfoMapper.selectHotakeCvInfoList(queryCv);
HotakeCvInfo cvInfo = null;
if(CollectionUtil.isNotEmpty(cvInfos)) {
cvInfo = cvInfos.get(0);
}
//解析简历内容以及获取简历对应的评分数据
log.info("开始处理简历");
try {
InputStream inputStream = minioClient.getObject(
GetObjectArgs.builder()
.bucket(MinioBucketNameEnum.CV.getCode())
.object(applyInfo.getCvFile())
.build());
String contents = FileContentUtil.readFileContent(inputStream, applyInfo.getCvFileSuffix());
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());
applyInfo.setCvMd5(md5Hash);
applyInfo.setExperience(cvInfo.getExperience());
} else {
//生成简历模版数据信息
HotakeCvInfoDto cvInfoDto = handleAnalysisCvInfo(contents);
//生成对应的简历评分
applyInfo.setCvTemplateJson(JSONUtil.toJsonStr(cvInfoDto));
applyInfo.setCvMd5(md5Hash);
applyInfo.setExperience(cvInfoDto.getExperienceYear());
}
}catch (Exception e) {
e.printStackTrace();
}
//AI简历评分和排名系统-直接传到简历系统中
HotakeAiCvScoringRankingRoleApplyVo roleApplyVo = new HotakeAiCvScoringRankingRoleApplyVo();
roleApplyVo.setApplyInfo(applyInfo);
roleApplyVo.setCvTemplateJson(applyInfo.getCvTemplateJson());
HotakeAiCvScoringRankingDto scoringRankingDto = aiCommonToolsService.handleAiCvScoringRanking(roleApplyVo);
applyInfo.setAiCvScoringRankingJson(JSONUtil.toJsonStr(scoringRankingDto));
applyInfo.setAiCvScore(scoringRankingDto.getOverallScore());
//招聘者查看候选人匹配度
HotakeCandidateCompatibilityVo compatibilityVo = new HotakeCandidateCompatibilityVo();
compatibilityVo.setPosition(rolesInf.getRoleName());
HotakeCvInfoDto cvInfoDto = JSONUtil.toBean(applyInfo.getCvTemplateJson(), HotakeCvInfoDto.class);
compatibilityVo.setCurrentPosition(cvInfoDto.getPosition());
compatibilityVo.setOverallRating(scoringRankingDto.getOverallScore().toString());
compatibilityVo.setWorkExperience(cvInfoDto.getExperienceYear());
List<String> skills = new ArrayList<>();
if(CollectionUtil.isNotEmpty(cvInfoDto.getSkillsTools())){
for (VcSkillsToolsDto toolsDto : cvInfoDto.getSkillsTools()){
skills.add(toolsDto.getContent());
}
}
compatibilityVo.setSkills(skills);
HotakeCandidateCompatibilityDto compatibilityDto = aiCommonToolsService.handleCandidateCompatibility(compatibilityVo);
applyInfo.setCandidateCompatibilityJson(JSONUtil.toJsonStr(compatibilityDto));
applyInfo.setCandidateCompatibilityScore(compatibilityDto.getOverallScore());
applyInfo.setRecruiterId(rolesInf.getRecruiterId()); applyInfo.setRecruiterId(rolesInf.getRecruiterId());
applyInfo.setStage(StageEnum.APPLIED.getCode()); applyInfo.setStage(StageEnum.APPLIED.getCode());
hotakeRolesApplyInfoMapper.updateHotakeRolesApplyInfo(applyInfo); hotakeRolesApplyInfoMapper.updateHotakeRolesApplyInfo(applyInfo);
@@ -274,11 +290,6 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi
hotakeRolesApplyOperRecord.setRoleApplyId(applyInfo.getId()); hotakeRolesApplyOperRecord.setRoleApplyId(applyInfo.getId());
hotakeRolesApplyOperRecord.setRoleId(rolesInf.getId()); hotakeRolesApplyOperRecord.setRoleId(rolesInf.getId());
rolesApplyOperRecordService.insertHotakeRolesApplyOperRecord(hotakeRolesApplyOperRecord); rolesApplyOperRecordService.insertHotakeRolesApplyOperRecord(hotakeRolesApplyOperRecord);
// } catch (Exception e) {
// e.printStackTrace();
// }
return 0;
} }
return 0; return 0;
} }

View File

@@ -4,13 +4,17 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.vetti.common.core.domain.entity.SysUser;
import com.vetti.common.core.service.BaseServiceImpl; import com.vetti.common.core.service.BaseServiceImpl;
import com.vetti.common.enums.FillTypeEnum; import com.vetti.common.enums.FillTypeEnum;
import com.vetti.common.enums.StageEnum; import com.vetti.common.enums.StageEnum;
import com.vetti.common.exception.ServiceException;
import com.vetti.common.utils.SecurityUtils; import com.vetti.common.utils.SecurityUtils;
import com.vetti.hotake.domain.HotakeRolesApplyInfo; import com.vetti.hotake.domain.HotakeRolesApplyInfo;
import com.vetti.hotake.domain.HotakeRolesApplyOperRecord; import com.vetti.hotake.domain.HotakeRolesApplyOperRecord;
import com.vetti.hotake.domain.HotakeRolesInfo; import com.vetti.hotake.domain.HotakeRolesInfo;
import com.vetti.hotake.domain.dto.HotakeAiCvScoringRankingDto;
import com.vetti.hotake.domain.dto.HotakeCandidateCompatibilityDto;
import com.vetti.hotake.domain.dto.HotakeCvInfoDto; import com.vetti.hotake.domain.dto.HotakeCvInfoDto;
import com.vetti.hotake.domain.dto.VcDto.*; import com.vetti.hotake.domain.dto.VcDto.*;
import com.vetti.hotake.domain.vo.HotakeRolesApplyStageVo; import com.vetti.hotake.domain.vo.HotakeRolesApplyStageVo;
@@ -18,6 +22,7 @@ import com.vetti.hotake.mapper.HotakeRolesApplyInfoMapper;
import com.vetti.hotake.mapper.HotakeRolesInfoMapper; import com.vetti.hotake.mapper.HotakeRolesInfoMapper;
import com.vetti.hotake.service.IHotakeRolesApplyInfoService; import com.vetti.hotake.service.IHotakeRolesApplyInfoService;
import com.vetti.hotake.service.IHotakeRolesApplyOperRecordService; import com.vetti.hotake.service.IHotakeRolesApplyOperRecordService;
import com.vetti.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -43,6 +48,9 @@ public class HotakeRolesApplyInfoServiceImpl extends BaseServiceImpl implements
@Autowired @Autowired
private IHotakeRolesApplyOperRecordService rolesApplyOperRecordService; private IHotakeRolesApplyOperRecordService rolesApplyOperRecordService;
@Autowired
private ISysUserService userService;
/** /**
* 查询候选人岗位申请信息 * 查询候选人岗位申请信息
* *
@@ -371,4 +379,77 @@ public class HotakeRolesApplyInfoServiceImpl extends BaseServiceImpl implements
return resultNum; return resultNum;
} }
/**
* AI简历评分和排名系统
* @param hotakeRolesApplyInfo 候选人岗位申请信息
* @return
*/
@Override
public List<HotakeRolesApplyInfo> handleAiCvScoringRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo) {
if(CollectionUtil.isEmpty(hotakeRolesApplyInfo.getApplyRoleIdList())){
throw new ServiceException("Please select at least one piece of business data");
}
List<HotakeRolesApplyInfo> applyInfoList = hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoRankingList(hotakeRolesApplyInfo);
if(CollectionUtil.isNotEmpty(applyInfoList)) {
//查询岗位数据集合
HotakeRolesInfo query = new HotakeRolesInfo();
List<HotakeRolesInfo> rolesInfoList = hotakeRolesInfoMapper.selectHotakeRolesInfoList(query);
List<SysUser> sysUserList = userService.selectUserList(new SysUser());
for(HotakeRolesApplyInfo applyInfo : applyInfoList) {
if(applyInfo.getRoleId() != null){
List<HotakeRolesInfo> rolesInfos = rolesInfoList.stream().filter(e->e.getId().longValue() == applyInfo.getRoleId().longValue()).toList();
if(CollectionUtil.isNotEmpty(rolesInfos)) {
applyInfo.setRolesInfo(rolesInfos.get(0));
}
}
if(StrUtil.isNotEmpty(applyInfo.getCvTemplateJson())){
HotakeCvInfoDto cvInfoDto = handleAnalysisCvInfo(applyInfo.getCvTemplateJson());
applyInfo.setCvInfoDto(cvInfoDto);
}
if(applyInfo.getCandidateId() != null){
List<SysUser> userList = sysUserList.stream().filter(e->e.getUserId().longValue() == applyInfo.getCandidateId().longValue()).toList();
if(CollectionUtil.isNotEmpty(userList)) {
applyInfo.setCandidateUSer(userList.get(0));
}
}
if(StrUtil.isNotEmpty(applyInfo.getAiCvScoringRankingJson())){
HotakeAiCvScoringRankingDto rankingDto = JSONUtil.toBean(applyInfo.getAiCvScoringRankingJson(), HotakeAiCvScoringRankingDto.class);
applyInfo.setRankingDto(rankingDto);
}
}
}
return applyInfoList;
}
/**
* 招聘者查看候选人匹配度
* @param hotakeRolesApplyInfo 候选人岗位申请信息
* @return
*/
@Override
public HotakeRolesApplyInfo handleCandidateCompatibilityInfo(HotakeRolesApplyInfo hotakeRolesApplyInfo) {
if(CollectionUtil.isEmpty(hotakeRolesApplyInfo.getApplyRoleIdList())){
throw new ServiceException("Please select at least one piece of business data");
}
List<HotakeRolesApplyInfo> applyInfoList = hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoCompatibilityScoreList(hotakeRolesApplyInfo);
if(CollectionUtil.isNotEmpty(applyInfoList)) {
HotakeRolesApplyInfo applyInfo = applyInfoList.get(0);
HotakeRolesInfo rolesInfo = hotakeRolesInfoMapper.selectHotakeRolesInfoById(applyInfo.getRoleId());
applyInfo.setRolesInfo(rolesInfo);
SysUser user = userService.selectUserById(applyInfo.getCandidateId());
applyInfo.setCandidateUSer(user);
if(StrUtil.isNotEmpty(applyInfo.getCandidateCompatibilityJson())){
HotakeCandidateCompatibilityDto compatibilityDto = JSONUtil.toBean(applyInfo.getCandidateCompatibilityJson(), HotakeCandidateCompatibilityDto.class);
applyInfo.setCompatibilityDto(compatibilityDto);
}
return applyInfo;
}
return new HotakeRolesApplyInfo();
}
} }

View File

@@ -26,6 +26,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="aiMatchScore" column="ai_match_score" /> <result property="aiMatchScore" column="ai_match_score" />
<result property="aiMatchScorePercentage" column="ai_match_score_percentage" /> <result property="aiMatchScorePercentage" column="ai_match_score_percentage" />
<result property="status" column="status" /> <result property="status" column="status" />
<result property="aiCvScoringRankingJson" column="ai_cv_scoring_ranking_json" />
<result property="aiCvScore" column="ai_cv_score" />
<result property="candidateCompatibilityJson" column="candidate_compatibility_json" />
<result property="candidateCompatibilityScore" column="candidate_compatibility_score" />
<result property="delFlag" column="del_flag" /> <result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
@@ -37,7 +44,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<sql id="selectHotakeRolesApplyInfoVo"> <sql id="selectHotakeRolesApplyInfoVo">
select id, candidate_id,recruiter_id, role_id, full_name, email, phone_number, cv_file, cv_file_suffix,file_size_show, 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, cover_letter, candidate_status, stage, last_contact, cv_template_json, cv_score, cv_md5, experience, ai_match_score,
ai_match_score_percentage,status, del_flag, create_by, create_time, update_by, update_time, remark from hotake_roles_apply_info ai_match_score_percentage,status, ai_cv_scoring_ranking_json,ai_cv_score,candidate_compatibility_json,candidate_compatibility_score,
del_flag, create_by, create_time, update_by, update_time, remark from hotake_roles_apply_info
</sql> </sql>
<select id="selectHotakeRolesApplyInfoList" parameterType="HotakeRolesApplyInfo" resultMap="HotakeRolesApplyInfoResult"> <select id="selectHotakeRolesApplyInfoList" parameterType="HotakeRolesApplyInfo" resultMap="HotakeRolesApplyInfoResult">
@@ -66,6 +74,76 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</where> </where>
</select> </select>
<select id="selectHotakeRolesApplyInfoRankingList" 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>
<if test="phoneNumber != null and phoneNumber != ''"> and phone_number = #{phoneNumber}</if>
<if test="cvFile != null and cvFile != ''"> and cv_file = #{cvFile}</if>
<if test="cvFileSuffix != null and cvFileSuffix != ''"> and cv_file_suffix = #{cvFileSuffix}</if>
<if test="coverLetter != null and coverLetter != ''"> and cover_letter = #{coverLetter}</if>
<if test="candidateStatus != null and candidateStatus != ''"> and candidate_status = #{candidateStatus}</if>
<if test="stage != null and stage != ''"> and stage = #{stage}</if>
<if test="lastContact != null and lastContact != ''"> and last_contact = #{lastContact}</if>
<if test="cvTemplateJson != null and cvTemplateJson != ''"> and cv_template_json = #{cvTemplateJson}</if>
<if test="cvScore != null and cvScore != ''"> and cv_score = #{cvScore}</if>
<if test="cvMd5 != null and cvMd5 != ''"> and cv_md5 = #{cvMd5}</if>
<if test="experience != null and experience != ''"> and experience = #{experience}</if>
<if test="aiMatchScore != null and aiMatchScore != ''"> and ai_match_score = #{aiMatchScore}</if>
<if test="aiMatchScorePercentage != null "> and ai_match_score_percentage = #{aiMatchScorePercentage}</if>
<if test="status != null "> and status = #{status}</if>
<if test="applyRoleIdList != null ">
and id in
<foreach item="applyRoleId" collection="applyRoleIdList" open="(" separator="," close=")">
#{applyRoleId}
</foreach>
</if>
</where>
order by ai_cv_score DESC
</select>
<select id="selectHotakeRolesApplyInfoCompatibilityScoreList" 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>
<if test="phoneNumber != null and phoneNumber != ''"> and phone_number = #{phoneNumber}</if>
<if test="cvFile != null and cvFile != ''"> and cv_file = #{cvFile}</if>
<if test="cvFileSuffix != null and cvFileSuffix != ''"> and cv_file_suffix = #{cvFileSuffix}</if>
<if test="coverLetter != null and coverLetter != ''"> and cover_letter = #{coverLetter}</if>
<if test="candidateStatus != null and candidateStatus != ''"> and candidate_status = #{candidateStatus}</if>
<if test="stage != null and stage != ''"> and stage = #{stage}</if>
<if test="lastContact != null and lastContact != ''"> and last_contact = #{lastContact}</if>
<if test="cvTemplateJson != null and cvTemplateJson != ''"> and cv_template_json = #{cvTemplateJson}</if>
<if test="cvScore != null and cvScore != ''"> and cv_score = #{cvScore}</if>
<if test="cvMd5 != null and cvMd5 != ''"> and cv_md5 = #{cvMd5}</if>
<if test="experience != null and experience != ''"> and experience = #{experience}</if>
<if test="aiMatchScore != null and aiMatchScore != ''"> and ai_match_score = #{aiMatchScore}</if>
<if test="aiMatchScorePercentage != null "> and ai_match_score_percentage = #{aiMatchScorePercentage}</if>
<if test="status != null "> and status = #{status}</if>
<if test="applyRoleIdList != null ">
and id in
<foreach item="applyRoleId" collection="applyRoleIdList" open="(" separator="," close=")">
#{applyRoleId}
</foreach>
</if>
</where>
order by candidate_compatibility_score DESC
</select>
<select id="selectHotakeRolesApplyInfoById" parameterType="Long" resultMap="HotakeRolesApplyInfoResult"> <select id="selectHotakeRolesApplyInfoById" parameterType="Long" resultMap="HotakeRolesApplyInfoResult">
<include refid="selectHotakeRolesApplyInfoVo"/> <include refid="selectHotakeRolesApplyInfoVo"/>
where id = #{id} where id = #{id}
@@ -94,6 +172,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="aiMatchScore != null">ai_match_score,</if> <if test="aiMatchScore != null">ai_match_score,</if>
<if test="aiMatchScorePercentage != null">ai_match_score_percentage,</if> <if test="aiMatchScorePercentage != null">ai_match_score_percentage,</if>
<if test="status != null">status,</if> <if test="status != null">status,</if>
<if test="aiCvScoringRankingJson != null">ai_cv_scoring_ranking_json,</if>
<if test="aiCvScore != null">ai_cv_score,</if>
<if test="candidateCompatibilityJson != null">candidate_compatibility_json,</if>
<if test="candidateCompatibilityScore != null">candidate_compatibility_score,</if>
<if test="delFlag != null">del_flag,</if> <if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</if> <if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if> <if test="createTime != null">create_time,</if>
@@ -122,6 +206,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="aiMatchScore != null">#{aiMatchScore},</if> <if test="aiMatchScore != null">#{aiMatchScore},</if>
<if test="aiMatchScorePercentage != null">#{aiMatchScorePercentage},</if> <if test="aiMatchScorePercentage != null">#{aiMatchScorePercentage},</if>
<if test="status != null">#{status},</if> <if test="status != null">#{status},</if>
<if test="aiCvScoringRankingJson != null">#{aiCvScoringRankingJson},</if>
<if test="aiCvScore != null">#{aiCvScore},</if>
<if test="candidateCompatibilityJson != null">#{candidateCompatibilityJson},</if>
<if test="candidateCompatibilityScore != null">#{candidateCompatibilityScore},</if>
<if test="delFlag != null">#{delFlag},</if> <if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</if> <if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if> <if test="createTime != null">#{createTime},</if>
@@ -154,6 +244,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="aiMatchScore != null">ai_match_score = #{aiMatchScore},</if> <if test="aiMatchScore != null">ai_match_score = #{aiMatchScore},</if>
<if test="aiMatchScorePercentage != null">ai_match_score_percentage = #{aiMatchScorePercentage},</if> <if test="aiMatchScorePercentage != null">ai_match_score_percentage = #{aiMatchScorePercentage},</if>
<if test="status != null">status = #{status},</if> <if test="status != null">status = #{status},</if>
<if test="aiCvScoringRankingJson != null">ai_cv_scoring_ranking_json = #{aiCvScoringRankingJson},</if>
<if test="aiCvScore != null">ai_cv_score = #{aiCvScore},</if>
<if test="candidateCompatibilityJson != null">candidate_compatibility_json = #{candidateCompatibilityJson},</if>
<if test="candidateCompatibilityScore != null">candidate_compatibility_score = #{candidateCompatibilityScore},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if> <if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createBy != null">create_by = #{createBy},</if> <if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if> <if test="createTime != null">create_time = #{createTime},</if>
@@ -176,7 +272,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete> </delete>
<insert id="batchInsertHotakeRolesApplyInfo"> <insert id="batchInsertHotakeRolesApplyInfo">
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 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=","> <foreach item="item" index="index" collection="list" separator=",">
( #{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}) ( #{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> </foreach>