diff --git a/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java b/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java index 359a8d0..b3b456c 100644 --- a/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java +++ b/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeAiCommonToolsController.java @@ -197,7 +197,7 @@ public class HotakeAiCommonToolsController extends BaseController { */ @ApiOperation("招聘者 AI简历评分和排名系统") @PostMapping(value = "/aiCvScoringRanking") - public R aiCvScoringRanking(@RequestBody HotakeAiCvScoringRankingRoleApplyVo roleApplyVo) + public R aiCvScoringRanking(@RequestBody HotakeAiCvScoringRankingRoleApplyVo roleApplyVo) { return R.ok(hotakeAiCommonToolsService.handleAiCvScoringRanking(roleApplyVo)); } @@ -207,7 +207,7 @@ public class HotakeAiCommonToolsController extends BaseController { */ @ApiOperation("招聘者查看候选人匹配度") @PostMapping(value = "/candidateCompatibility") - public R candidateCompatibility(@RequestBody HotakeCandidateCompatibilityVo compatibilityVo) + public R candidateCompatibility(@RequestBody HotakeCandidateCompatibilityVo compatibilityVo) { return R.ok(hotakeAiCommonToolsService.handleCandidateCompatibility(compatibilityVo)); } diff --git a/vetti-admin/src/main/java/com/vetti/web/controller/hotake/HotakeRolesApplyInfoController.java b/vetti-admin/src/main/java/com/vetti/web/controller/hotake/HotakeRolesApplyInfoController.java index 09ac240..5eeb38f 100644 --- a/vetti-admin/src/main/java/com/vetti/web/controller/hotake/HotakeRolesApplyInfoController.java +++ b/vetti-admin/src/main/java/com/vetti/web/controller/hotake/HotakeRolesApplyInfoController.java @@ -110,5 +110,25 @@ public class HotakeRolesApplyInfoController extends BaseController return R.ok(); } + /** + * AI简历评分和排名系统 + */ + @ApiOperation("AI简历评分和排名系统") + @GetMapping("/aiCvScoringRankingList") + public R> getAiCvScoringRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo) + { + List list = hotakeRolesApplyInfoService.handleAiCvScoringRankingList(hotakeRolesApplyInfo); + return R.ok(list,""); + } + /** + * 招聘者查看候选人匹配度 + */ + @ApiOperation("招聘者查看候选人匹配度") + @GetMapping("/candidateCompatibilityInfo") + public R getCandidateCompatibilityInfo(HotakeRolesApplyInfo hotakeRolesApplyInfo) + { + HotakeRolesApplyInfo info = hotakeRolesApplyInfoService.handleCandidateCompatibilityInfo(hotakeRolesApplyInfo); + return R.ok(info,""); + } } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeRolesApplyInfo.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeRolesApplyInfo.java index 5990bc2..d5b3679 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeRolesApplyInfo.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeRolesApplyInfo.java @@ -3,6 +3,9 @@ package com.vetti.hotake.domain; import java.math.BigDecimal; 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 lombok.Data; import lombok.experimental.Accessors; @@ -121,6 +124,18 @@ public class HotakeRolesApplyInfo extends BaseEntity @ApiModelProperty("申请状态(pending:进行中,complete:已完成,canceled:取消)") private String status; + @ApiModelProperty("AI简历评分和排名JSON") + private String aiCvScoringRankingJson; + + @ApiModelProperty("AI简历评分和排名最终得分") + private BigDecimal aiCvScore; + + @ApiModelProperty("候选人匹配度JSON") + private String candidateCompatibilityJson; + + @ApiModelProperty("候选人匹配度最终得分") + private BigDecimal candidateCompatibilityScore; + @ApiModelProperty("岗位信息") private HotakeRolesInfo rolesInfo; @@ -130,6 +145,15 @@ public class HotakeRolesApplyInfo extends BaseEntity @ApiModelProperty("岗位申请操作记录数据集合") private List applyOperRecords; + @ApiModelProperty("候选人用户信息") + private SysUser candidateUSer; + + @ApiModelProperty("AI简历评分和排名数据对象") + private HotakeAiCvScoringRankingDto rankingDto; + + @ApiModelProperty("招聘者查看候选人匹配度数据对象") + private HotakeCandidateCompatibilityDto compatibilityDto; + @ApiModelProperty("岗位申请ID数据集合") private List applyRoleIdList; diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeAiCvScoringRankingDto.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeAiCvScoringRankingDto.java new file mode 100644 index 0000000..f535f3f --- /dev/null +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeAiCvScoringRankingDto.java @@ -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 strengths; + + @ApiModelProperty("不足点列表 ") + private List weaknesses; + + @ApiModelProperty("推荐等级 ") + private String recommendation; + + @ApiModelProperty("推荐理由 ") + private String reason; + + @ApiModelProperty("总体评分") + private BigDecimal overallScore; + +} diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeCandidateCompatibilityDto.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeCandidateCompatibilityDto.java new file mode 100644 index 0000000..06354dd --- /dev/null +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/HotakeCandidateCompatibilityDto.java @@ -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 keyStrengths; + + @ApiModelProperty("关键差异评分(越高差异越小) ") + private BigDecimal differencesScore; + + @ApiModelProperty("关键差异列表 ") + private List keyDifferences; + + @ApiModelProperty("文化契合评分 ") + private BigDecimal culturalScore; + + @ApiModelProperty("文化契合详情 ") + private List culturalFitDetails; + + @ApiModelProperty("总体评分") + private BigDecimal overallScore; + +} diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingRoleApplyVo.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingRoleApplyVo.java index f255b39..b7b6091 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingRoleApplyVo.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingRoleApplyVo.java @@ -1,11 +1,10 @@ package com.vetti.hotake.domain.vo; +import com.vetti.hotake.domain.HotakeRolesApplyInfo; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; -import java.util.List; - /** * 招聘者AI简历评分和排名系统-岗位申请 请求对象 * @@ -16,6 +15,10 @@ import java.util.List; @Accessors(chain = true) public class HotakeAiCvScoringRankingRoleApplyVo { - @ApiModelProperty("岗位申请ID集合") - private List roleApplyIds; + @ApiModelProperty("岗位申请信息") + private HotakeRolesApplyInfo applyInfo; + + /** 简历模版Json */ + @ApiModelProperty("简历模版Json") + private String cvTemplateJson; } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingVo.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingVo.java index 26a46eb..7681550 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingVo.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/vo/HotakeAiCvScoringRankingVo.java @@ -35,7 +35,7 @@ public class HotakeAiCvScoringRankingVo { private String educationRequired; @ApiModelProperty("候选人信息") - private List candidates; + private HotakeCandidateVcInfoVo candidates; } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/mapper/HotakeRolesApplyInfoMapper.java b/vetti-hotakes/src/main/java/com/vetti/hotake/mapper/HotakeRolesApplyInfoMapper.java index 201ea79..1047b91 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/mapper/HotakeRolesApplyInfoMapper.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/mapper/HotakeRolesApplyInfoMapper.java @@ -27,6 +27,22 @@ public interface HotakeRolesApplyInfoMapper */ public List selectHotakeRolesApplyInfoList(HotakeRolesApplyInfo hotakeRolesApplyInfo); + /** + * 查询候选人岗位申请信息列表 + * + * @param hotakeRolesApplyInfo 候选人岗位申请信息 + * @return 候选人岗位申请信息集合 + */ + public List selectHotakeRolesApplyInfoRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo); + + /** + * 查询候选人岗位申请信息列表 + * + * @param hotakeRolesApplyInfo 候选人岗位申请信息 + * @return 候选人岗位申请信息集合 + */ + public List selectHotakeRolesApplyInfoCompatibilityScoreList(HotakeRolesApplyInfo hotakeRolesApplyInfo); + /** * 新增候选人岗位申请信息 * diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java index e1c0769..f04b659 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeAiCommonToolsService.java @@ -141,7 +141,7 @@ public interface IHotakeAiCommonToolsService { * @param roleApplyVo 岗位申请数据对象 * @return */ - public String handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo); + public HotakeAiCvScoringRankingDto handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo); /** @@ -149,6 +149,6 @@ public interface IHotakeAiCommonToolsService { * @param compatibilityVo 招聘者查看候选人匹配度 输入信息 * @return */ - public String handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo); + public HotakeCandidateCompatibilityDto handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo); } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeRolesApplyInfoService.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeRolesApplyInfoService.java index 820d5af..3998ad7 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeRolesApplyInfoService.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/IHotakeRolesApplyInfoService.java @@ -76,5 +76,20 @@ public interface IHotakeRolesApplyInfoService */ public int updateBatchEditStage(List stageVoList); + /** + * AI简历评分和排名系统 + * + * @param hotakeRolesApplyInfo 候选人岗位申请信息 + * @return 候选人岗位申请信息集合 + */ + public List handleAiCvScoringRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo); + + /** + * 招聘者查看候选人匹配度 + * + * @param hotakeRolesApplyInfo 候选人岗位申请信息 + * @return 候选人岗位申请信息集合 + */ + public HotakeRolesApplyInfo handleCandidateCompatibilityInfo(HotakeRolesApplyInfo hotakeRolesApplyInfo); } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java index 3edc123..8f2cf0d 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeAiCommonToolsServiceImpl.java @@ -44,8 +44,7 @@ import java.util.stream.Collectors; @Slf4j @SuppressWarnings("all") @Service -public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements IHotakeAiCommonToolsService -{ +public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements IHotakeAiCommonToolsService { @Autowired private HotakeRolesInfoMapper hotakeRolesInfoMapper; @@ -65,8 +64,9 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 职位描述生成器 - * @param roleId 岗位ID - * @param industry Industry sector 行业领域 + * + * @param roleId 岗位ID + * @param industry Industry sector 行业领域 * @param coreRequirements Key skills or experience requirements 关键技能或经验要求 * @return */ @@ -75,29 +75,29 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I HotakeJobDescriptionGeneratorDto generatorDto = new HotakeJobDescriptionGeneratorDto(); //根据岗位ID查询岗位基本信息 HotakeRolesInfo rolesInfo = hotakeRolesInfoMapper.selectHotakeRolesInfoById(roleId); - String prompt = AiCommonPromptConstants.initializationJobDescriptionPrompt(rolesInfo.getRoleName(),rolesInfo.getRoleType(), + String prompt = AiCommonPromptConstants.initializationJobDescriptionPrompt(rolesInfo.getRoleName(), rolesInfo.getRoleType(), rolesInfo.getRequiredSkillsJson()); List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"JD"); - log.info("返回职位描述:{}",resultStr); + String resultStr = chatGPTClient.handleAiChat(promptJson, "JD"); + log.info("返回职位描述:{}", resultStr); //开始解析职位描述详细信息,主要生成的数据为第二步中的必备技能和优先加分技能,第三步中的关于岗位和职责 - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); - Map dataMap = JSONUtil.toBean(resultJson,Map.class); + Map dataMap = JSONUtil.toBean(resultJson, Map.class); Map aboutRoleMap = (Map) dataMap.get("job_description"); String aboutRole = aboutRoleMap.get("overview").toString(); generatorDto.setAboutRole(aboutRole); - List keyResponsibilitiesList = (List)dataMap.get("key_responsibilities"); + List keyResponsibilitiesList = (List) dataMap.get("key_responsibilities"); List responsibilitiesList = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(keyResponsibilitiesList)){ - for(Map map : keyResponsibilitiesList){ + if (CollectionUtil.isNotEmpty(keyResponsibilitiesList)) { + for (Map map : keyResponsibilitiesList) { ResponsibilitiesDto responsibilitiesDto = new ResponsibilitiesDto(); responsibilitiesDto.setResponsibilities(map.get("responsibility").toString()); responsibilitiesList.add(responsibilitiesDto); @@ -108,10 +108,10 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I Map requirementsMap = (Map) dataMap.get("requirements"); - List essentialList = (List)requirementsMap.get("essential"); + List essentialList = (List) requirementsMap.get("essential"); List skillsDtoList = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(essentialList)){ - for(Map map : essentialList){ + if (CollectionUtil.isNotEmpty(essentialList)) { + for (Map map : essentialList) { RequiredSkillsDto skillsDto = new RequiredSkillsDto(); skillsDto.setKeyValue(map.get("requirement").toString()); skillsDtoList.add(skillsDto); @@ -120,10 +120,10 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I generatorDto.setSkillsDtoList(skillsDtoList); - List preferredList = (List)requirementsMap.get("preferred"); + List preferredList = (List) requirementsMap.get("preferred"); List haveSkillsDtoList = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(preferredList)){ - for(Map map : preferredList){ + if (CollectionUtil.isNotEmpty(preferredList)) { + for (Map map : preferredList) { NiceToHaveSkillsDto haveSkillsDto = new NiceToHaveSkillsDto(); haveSkillsDto.setKeyValue(map.get("requirement").toString()); haveSkillsDtoList.add(haveSkillsDto); @@ -136,6 +136,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 初筛问题生成 + * * @return */ @Override @@ -143,37 +144,37 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List questionsInfoList = new ArrayList<>(); //根据岗位ID查询岗位基本信息 HotakeRolesInfo rolesInfo = hotakeRolesInfoMapper.selectHotakeRolesInfoById(questionsVo.getRoleId()); - String prompt = AiCommonPromptConstants.initializationInitialScreeningQuestionsPrompt(rolesInfo.getRoleName(),rolesInfo.getAboutRole(), + String prompt = AiCommonPromptConstants.initializationInitialScreeningQuestionsPrompt(rolesInfo.getRoleName(), rolesInfo.getAboutRole(), rolesInfo.getResponsibilities()); List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"ISQ"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("初筛问题生成:{}",resultStr); + String resultStr = chatGPTClient.handleAiChat(promptJson, "ISQ"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("初筛问题生成:{}", resultStr); //筛选问题结构化处理-进行初始化问题解析处理 - Map dataMap = JSONUtil.toBean(resultJson,Map.class); + Map dataMap = JSONUtil.toBean(resultJson, Map.class); - List questionsList = (List)dataMap.get("questions"); - if(CollectionUtil.isNotEmpty(questionsList)){ - for(Map map : questionsList){ + List questionsList = (List) dataMap.get("questions"); + if (CollectionUtil.isNotEmpty(questionsList)) { + for (Map map : questionsList) { HotakeInitialScreeningQuestionsInfo questionsInfo = new HotakeInitialScreeningQuestionsInfo(); questionsInfo.setQuestionType(map.get("type").toString()); questionsInfo.setQuestionTitle(map.get("question").toString()); questionsInfo.setRequiredField("0"); - List optionsList = (List)map.get("options"); - List answerOptionsList = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(optionsList)){ - for(String option : optionsList){ + List optionsList = (List) map.get("options"); + List answerOptionsList = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(optionsList)) { + for (String option : optionsList) { AnswerOptionsDto answerOptionsDto = new AnswerOptionsDto(); answerOptionsDto.setAnswers(option); answerOptionsList.add(answerOptionsDto); } } - if(CollectionUtil.isNotEmpty(answerOptionsList)){ + if (CollectionUtil.isNotEmpty(answerOptionsList)) { questionsInfo.setAnswerOptions(JSONUtil.toJsonStr(answerOptionsList)); questionsInfo.setAnswerOptionsList(answerOptionsList); } @@ -185,30 +186,32 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 简历岗位匹配度评分 + * * @return */ @Override public String getResumeJobMatchingScore(HotakeResumeJobMatchingScoreVo scoreVo) { //查询岗位信息 - String prompt = AiCommonPromptConstants.initializationResumeJobMatchingScorePrompt(scoreVo.getJobTitle(),scoreVo.getJobDescription(), - scoreVo.getKeyResponsibilities(),scoreVo.getJobRequirements(),scoreVo.getPersonalInformation(), - scoreVo.getWorkHistory(),scoreVo.getProjectExperience(),scoreVo.getSkillsList(), - scoreVo.getEducationalBackground(),scoreVo.getOtherRelevantInformation()); + String prompt = AiCommonPromptConstants.initializationResumeJobMatchingScorePrompt(scoreVo.getJobTitle(), scoreVo.getJobDescription(), + scoreVo.getKeyResponsibilities(), scoreVo.getJobRequirements(), scoreVo.getPersonalInformation(), + scoreVo.getWorkHistory(), scoreVo.getProjectExperience(), scoreVo.getSkillsList(), + scoreVo.getEducationalBackground(), scoreVo.getOtherRelevantInformation()); List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"ROLECV"); - log.info("简历岗位匹配度评分:{}",resultStr); + String resultStr = chatGPTClient.handleAiChat(promptJson, "ROLECV"); + log.info("简历岗位匹配度评分:{}", resultStr); return ""; } /** * 简历分析优化器 + * * @param cvConnect 简历内容 * @return */ @@ -219,40 +222,40 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content","请分析以下简历并提供优化建议:\\n\\n"+cvConnect); + mapUserEntity.put("content", "请分析以下简历并提供优化建议:\\n\\n" + cvConnect); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"CVJX"); - log.info("简历分析优化器:{}",resultStr); + String resultStr = chatGPTClient.handleAiChat(promptJson, "CVJX"); + log.info("简历分析优化器:{}", resultStr); HotakeCvOptimizeDto cvOptimizeDto = new HotakeCvOptimizeDto(); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("初筛问题生成:{}",resultStr); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("初筛问题生成:{}", resultStr); //筛选问题结构化处理-进行初始化问题解析处理 - Map dataMap = JSONUtil.toBean(resultJson,Map.class); - if(dataMap != null){ + Map dataMap = JSONUtil.toBean(resultJson, Map.class); + if (dataMap != null) { //分析总结 CvAnalysisSummaryDto analysisSummary = new CvAnalysisSummaryDto(); - Map analysisSummaryMap = (Map)dataMap.get("analysis_summary"); + Map analysisSummaryMap = (Map) dataMap.get("analysis_summary"); analysisSummary.setOverallScore(analysisSummaryMap.get("overall_score").toString()); - List mainStrengthsList = (List)analysisSummaryMap.get("main_strengths"); + List mainStrengthsList = (List) analysisSummaryMap.get("main_strengths"); analysisSummary.setMainStrengths(mainStrengthsList); - List criticalIssuesList = (List)analysisSummaryMap.get("critical_issues"); + List criticalIssuesList = (List) analysisSummaryMap.get("critical_issues"); analysisSummary.setCriticalIssues(criticalIssuesList); analysisSummary.setImprovementPotential(analysisSummaryMap.get("improvement_potential").toString()); cvOptimizeDto.setAnalysisSummary(analysisSummary); //文本修正(文字、语法等错误) CvTextCorrectionsDto textCorrections = new CvTextCorrectionsDto(); - Map textCorrectionsMap = (Map)dataMap.get("text_corrections"); + Map textCorrectionsMap = (Map) dataMap.get("text_corrections"); List spellingErrors = new ArrayList<>(); - List spellingErrorsMapList = (List)textCorrectionsMap.get("spelling_errors"); - if(CollectionUtil.isNotEmpty(spellingErrorsMapList)){ - for(Map map : spellingErrorsMapList){ + List spellingErrorsMapList = (List) textCorrectionsMap.get("spelling_errors"); + if (CollectionUtil.isNotEmpty(spellingErrorsMapList)) { + for (Map map : spellingErrorsMapList) { CvSpellingErrorsDto spellingErrorsDto = new CvSpellingErrorsDto(); spellingErrorsDto.setOriginal(map.get("original").toString()); spellingErrorsDto.setCorrected(map.get("corrected").toString()); @@ -263,9 +266,9 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I } List grammarErrors = new ArrayList<>(); - List grammarErrorsMapList = (List)textCorrectionsMap.get("grammar_errors"); - if(CollectionUtil.isNotEmpty(grammarErrorsMapList)){ - for(Map map : grammarErrorsMapList){ + List grammarErrorsMapList = (List) textCorrectionsMap.get("grammar_errors"); + if (CollectionUtil.isNotEmpty(grammarErrorsMapList)) { + for (Map map : grammarErrorsMapList) { CvGrammarErrorsDto grammarErrorsDto = new CvGrammarErrorsDto(); grammarErrorsDto.setOriginal(map.get("original").toString()); grammarErrorsDto.setCorrected(map.get("corrected").toString()); @@ -277,13 +280,13 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I } List formattingIssues = new ArrayList<>(); - List formattingIssuesMapList = (List)textCorrectionsMap.get("formatting_issues"); - if(CollectionUtil.isNotEmpty(formattingIssuesMapList)){ - for(Map map : formattingIssuesMapList){ + List formattingIssuesMapList = (List) textCorrectionsMap.get("formatting_issues"); + if (CollectionUtil.isNotEmpty(formattingIssuesMapList)) { + for (Map map : formattingIssuesMapList) { CvFormattingIssuesDto formattingIssuesDto = new CvFormattingIssuesDto(); formattingIssuesDto.setIssue(map.get("issue").toString()); formattingIssuesDto.setSuggestion(map.get("suggestion").toString()); - List locationList = (List)textCorrectionsMap.get("locations"); + List locationList = (List) textCorrectionsMap.get("locations"); formattingIssuesDto.setLocations(locationList); formattingIssues.add(formattingIssuesDto); } @@ -293,12 +296,12 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I //逻辑修正 CvLogicCorrectionsDto logicCorrections = new CvLogicCorrectionsDto(); - Map logicCorrectionsMap = (Map)dataMap.get("logic_corrections"); + Map logicCorrectionsMap = (Map) dataMap.get("logic_corrections"); List timelineConflicts = new ArrayList<>(); - List timelineConflictsMapList = (List)textCorrectionsMap.get("timeline_conflicts"); - if(CollectionUtil.isNotEmpty(timelineConflictsMapList)){ - for(Map map : timelineConflictsMapList){ + List timelineConflictsMapList = (List) textCorrectionsMap.get("timeline_conflicts"); + if (CollectionUtil.isNotEmpty(timelineConflictsMapList)) { + for (Map map : timelineConflictsMapList) { CvTimelineConflictsDto timelineConflictsDto = new CvTimelineConflictsDto(); timelineConflictsDto.setConflict(map.get("conflict").toString()); timelineConflictsDto.setDetails(map.get("details").toString()); @@ -309,9 +312,9 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I } List careerProgressionDtos = new ArrayList<>(); - List careerProgressionDtosMapList = (List)textCorrectionsMap.get("career_progression"); - if(CollectionUtil.isNotEmpty(careerProgressionDtosMapList)){ - for(Map map : careerProgressionDtosMapList){ + List careerProgressionDtosMapList = (List) textCorrectionsMap.get("career_progression"); + if (CollectionUtil.isNotEmpty(careerProgressionDtosMapList)) { + for (Map map : careerProgressionDtosMapList) { CvCareerProgressionDto careerProgressionDto = new CvCareerProgressionDto(); careerProgressionDto.setIssue(map.get("issue").toString()); careerProgressionDto.setDetails(map.get("details").toString()); @@ -322,9 +325,9 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I } List skillExperienceMismatchDtos = new ArrayList<>(); - List skillExperienceMismatchDtosMapList = (List)textCorrectionsMap.get("formatting_issues"); - if(CollectionUtil.isNotEmpty(skillExperienceMismatchDtosMapList)){ - for(Map map : skillExperienceMismatchDtosMapList){ + List skillExperienceMismatchDtosMapList = (List) textCorrectionsMap.get("formatting_issues"); + if (CollectionUtil.isNotEmpty(skillExperienceMismatchDtosMapList)) { + for (Map map : skillExperienceMismatchDtosMapList) { CvSkillExperienceMismatchDto skillExperienceMismatchDto = new CvSkillExperienceMismatchDto(); skillExperienceMismatchDto.setIssue(map.get("issue").toString()); skillExperienceMismatchDto.setSuggestion(map.get("suggestion").toString()); @@ -337,28 +340,28 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I //优化建议 CvOptimizationSuggestionsDto optimizationSuggestions = new CvOptimizationSuggestionsDto(); - Map optimizationSuggestionsMap = (Map)dataMap.get("optimization_suggestions"); + Map optimizationSuggestionsMap = (Map) dataMap.get("optimization_suggestions"); CvPersonalSummaryDto personalSummary = new CvPersonalSummaryDto(); - Map personalSummaryMap = (Map)optimizationSuggestionsMap.get("personal_summary"); - if(personalSummaryMap != null){ - List currentIssues = (List)personalSummaryMap.get("current_issues"); + Map personalSummaryMap = (Map) optimizationSuggestionsMap.get("personal_summary"); + if (personalSummaryMap != null) { + List currentIssues = (List) personalSummaryMap.get("current_issues"); personalSummary.setCurrentIssues(currentIssues); personalSummary.setOptimizedVersion(personalSummaryMap.get("optimized_version").toString()); - List keyImprovements = (List)personalSummaryMap.get("key_improvements"); + List keyImprovements = (List) personalSummaryMap.get("key_improvements"); personalSummary.setKeyImprovements(keyImprovements); } optimizationSuggestions.setPersonalSummary(personalSummary); List workExperienceDtoList = new ArrayList<>(); - List workExperienceMapList = (List)optimizationSuggestionsMap.get("work_experience"); - if(CollectionUtil.isNotEmpty(workExperienceMapList)){ - for(Map map : workExperienceMapList){ + List workExperienceMapList = (List) optimizationSuggestionsMap.get("work_experience"); + if (CollectionUtil.isNotEmpty(workExperienceMapList)) { + for (Map map : workExperienceMapList) { CvWorkExperienceDto workExperienceDto = new CvWorkExperienceDto(); workExperienceDto.setPosition(map.get("position").toString()); workExperienceDto.setOptimizedDescription(map.get("optimized_description").toString()); workExperienceDto.setCurrentDescription(map.get("current_description").toString()); - List improvements = (List)personalSummaryMap.get("improvements"); + List improvements = (List) personalSummaryMap.get("improvements"); workExperienceDto.setImprovements(improvements); workExperienceDtoList.add(workExperienceDto); } @@ -367,18 +370,18 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I CvSkillsSectionDto skillsSection = new CvSkillsSectionDto(); - Map skillsSectionMap = (Map)optimizationSuggestionsMap.get("skills_section"); - if(skillsSectionMap != null){ - List currentIssues = (List)skillsSectionMap.get("current_issues"); + Map skillsSectionMap = (Map) optimizationSuggestionsMap.get("skills_section"); + if (skillsSectionMap != null) { + List currentIssues = (List) skillsSectionMap.get("current_issues"); skillsSection.setCurrentIssues(currentIssues); CvSuggestedStructureDto suggestedStructureDto = new CvSuggestedStructureDto(); - Map suggestedStructureDtoMap = (Map)skillsSectionMap.get("suggested_structure"); - List coreSkills = (List)suggestedStructureDtoMap.get("core_skills"); + Map suggestedStructureDtoMap = (Map) skillsSectionMap.get("suggested_structure"); + List coreSkills = (List) suggestedStructureDtoMap.get("core_skills"); suggestedStructureDto.setCoreSkills(coreSkills); - List technicalSkills = (List)suggestedStructureDtoMap.get("technical_skills"); + List technicalSkills = (List) suggestedStructureDtoMap.get("technical_skills"); suggestedStructureDto.setTechnicalSkills(technicalSkills); - List certifications = (List)suggestedStructureDtoMap.get("certifications"); + List certifications = (List) suggestedStructureDtoMap.get("certifications"); suggestedStructureDto.setCertifications(certifications); skillsSection.setSuggestedStructureDto(suggestedStructureDto); } @@ -386,15 +389,15 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I CvKeywordOptimizationDto keywordOptimization = new CvKeywordOptimizationDto(); - Map keywordOptimizationMap = (Map)optimizationSuggestionsMap.get("keyword_optimization"); - if(keywordOptimizationMap != null){ - List atsKeywords = (List)keywordOptimizationMap.get("ats_keywords"); + Map keywordOptimizationMap = (Map) optimizationSuggestionsMap.get("keyword_optimization"); + if (keywordOptimizationMap != null) { + List atsKeywords = (List) keywordOptimizationMap.get("ats_keywords"); keywordOptimization.setAtsKeywords(atsKeywords); - List missingKeywords = (List)keywordOptimizationMap.get("missing_keywords"); + List missingKeywords = (List) keywordOptimizationMap.get("missing_keywords"); keywordOptimization.setMissingKeywords(missingKeywords); - List industryTerms = (List)keywordOptimizationMap.get("industry_terms"); + List industryTerms = (List) keywordOptimizationMap.get("industry_terms"); keywordOptimization.setIndustryTerms(industryTerms); } optimizationSuggestions.setKeywordOptimization(keywordOptimization); @@ -403,23 +406,23 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I //行动计划 CvActionPlanDto actionPlan = new CvActionPlanDto(); - Map actionPlanMap = (Map)dataMap.get("action_plan"); - if(actionPlanMap != null){ - List immediateFixes = (List)actionPlanMap.get("immediate_fixes"); + Map actionPlanMap = (Map) dataMap.get("action_plan"); + if (actionPlanMap != null) { + List immediateFixes = (List) actionPlanMap.get("immediate_fixes"); actionPlan.setImmediateFixes(immediateFixes); - List contentImprovements = (List)actionPlanMap.get("content_improvements"); + List contentImprovements = (List) actionPlanMap.get("content_improvements"); actionPlan.setContentImprovements(contentImprovements); - List strategicEnhancements = (List)actionPlanMap.get("strategic_enhancements"); + List strategicEnhancements = (List) actionPlanMap.get("strategic_enhancements"); actionPlan.setStrategicEnhancements(strategicEnhancements); } cvOptimizeDto.setActionPlan(actionPlan); //预期改进效果 CvEstimatedImprovementDto estimatedImprovement = new CvEstimatedImprovementDto(); - Map estimatedImprovementMap = (Map)dataMap.get("estimated_improvement"); - if(estimatedImprovementMap != null){ + Map estimatedImprovementMap = (Map) dataMap.get("estimated_improvement"); + if (estimatedImprovementMap != null) { estimatedImprovement.setCurrentAtsScore(estimatedImprovementMap.get("current_ats_score").toString()); estimatedImprovement.setInterviewProbability(estimatedImprovementMap.get("interview_probability").toString()); estimatedImprovement.setPotentialAtsScore(estimatedImprovementMap.get("potential_ats_score").toString()); @@ -433,6 +436,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 初步筛选问题淘汰评分 + * * @param cvConnect * @return */ @@ -449,36 +453,37 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); - if(CollectionUtil.isNotEmpty(screeningQuestionsInfoList)){ - for(HotakeInitialScreeningQuestionsInfo questionsInfo : screeningQuestionsInfoList){ + if (CollectionUtil.isNotEmpty(screeningQuestionsInfoList)) { + for (HotakeInitialScreeningQuestionsInfo questionsInfo : screeningQuestionsInfoList) { //根据问题获取答案数据 String answer = ""; - if(CollectionUtil.isNotEmpty(questionEliminationScoreVo.getInitScreQuestionsReplyRecordInfoList())){ + if (CollectionUtil.isNotEmpty(questionEliminationScoreVo.getInitScreQuestionsReplyRecordInfoList())) { List initScreQuestionsReplyRecordInfoList = questionEliminationScoreVo. - getInitScreQuestionsReplyRecordInfoList().stream().filter(e->e.getQuestionId().longValue() == questionsInfo.getId().longValue()).toList(); - if(CollectionUtil.isNotEmpty(initScreQuestionsReplyRecordInfoList)){ + getInitScreQuestionsReplyRecordInfoList().stream().filter(e -> e.getQuestionId().longValue() == questionsInfo.getId().longValue()).toList(); + if (CollectionUtil.isNotEmpty(initScreQuestionsReplyRecordInfoList)) { answer = initScreQuestionsReplyRecordInfoList.get(0).getAnswerConnect(); } } Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content", "question:"+questionsInfo.getQuestionTitle()+",answer:"+answer); + mapUserEntity.put("content", "question:" + questionsInfo.getQuestionTitle() + ",answer:" + answer); list.add(mapUserEntity); } } String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"CBQPF"); - log.info("初步筛选问题评分数据:{}",resultStr); + String resultStr = chatGPTClient.handleAiChat(promptJson, "CBQPF"); + log.info("初步筛选问题评分数据:{}", resultStr); //初步筛选问题评分数据 - dto = JSONUtil.toBean(resultStr,HotakeInitialQuestionEliminationScoreDto.class); + dto = JSONUtil.toBean(resultStr, HotakeInitialQuestionEliminationScoreDto.class); return dto; } /** * 处理分析附件结果 + * * @param connect * @return */ @@ -489,46 +494,48 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content",connect); + mapUserEntity.put("content", connect); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"AAFX"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); + String resultStr = chatGPTClient.handleAiChat(promptJson, "AAFX"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); return resultJson; } /** * 处理附件分析结果合并信息 - * @param basicInformation 基础信息 + * + * @param basicInformation 基础信息 * @param attachmentContent 所有附件信息 * @return */ @Override public String handleAttachmentResultMerging(String basicInformation, String attachmentContent) { //处理提示词数据 - String prompt = AiCommonPromptConstants.initializationAttachmentResultMergingPrompt(basicInformation,attachmentContent); + String prompt = AiCommonPromptConstants.initializationAttachmentResultMergingPrompt(basicInformation, attachmentContent); List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content","基本信息:"+basicInformation+"\\n分析结果:"+attachmentContent); + mapUserEntity.put("content", "基本信息:" + basicInformation + "\\n分析结果:" + attachmentContent); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"AAHB"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("处理附件分析结果合并信息:{}",resultJson); + String resultStr = chatGPTClient.handleAiChat(promptJson, "AAHB"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("处理附件分析结果合并信息:{}", resultJson); return resultJson; } /** * 生成最终的Markdown格式简历 + * * @param markdown * @return */ @@ -538,22 +545,23 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content",markdown); + mapUserEntity.put("content", markdown); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"MARKDOWN"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("处理附件分析结果合并信息:{}",resultJson); + String resultStr = chatGPTClient.handleAiChat(promptJson, "MARKDOWN"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("处理附件分析结果合并信息:{}", resultJson); return resultJson; } /** * 网站内容抓取 + * * @param webUrl 网站链接地址 * @return */ @@ -573,6 +581,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 网站AI信息提取(使用提示词) + * * @param webInfoExtractVo 网站提取对象 * @return */ @@ -584,28 +593,28 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I String prompt = AiCommonPromptConstants.initializationWebInfoExtractPrompt(); String userPrompt = "Please analyze the following company website:\n" + "\n" + - "URL: "+webInfoExtractVo.getWebUrl()+"\n" + + "URL: " + webInfoExtractVo.getWebUrl() + "\n" + "\n" + "Content:\n" + webContent; List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content",userPrompt); + mapUserEntity.put("content", userPrompt); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"WEBAITQ"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("网站AI信息提取:{}",resultJson); + String resultStr = chatGPTClient.handleAiChat(promptJson, "WEBAITQ"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("网站AI信息提取:{}", resultJson); //直接更新个人信息中的企业名和地址 - Map dataMap = JSONUtil.toBean(resultJson,Map.class); - Map companyOverviewMap = (Map)dataMap.get("company_overview"); + Map dataMap = JSONUtil.toBean(resultJson, Map.class); + Map companyOverviewMap = (Map) dataMap.get("company_overview"); String companyName = companyOverviewMap.get("company_name").toString(); - Map contactInfoMap = (Map)companyOverviewMap.get("contact_info"); + Map contactInfoMap = (Map) companyOverviewMap.get("contact_info"); String location = contactInfoMap.get("address").toString(); SysUser user = userMapper.selectUserById(SecurityUtils.getUserId()); @@ -618,6 +627,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 网站信息增强处理 + * * @param webUlr * @param webContent 网站内容 * @return @@ -628,23 +638,24 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content","You are a professional HR consultant...\n" + + mapEntity.put("content", "You are a professional HR consultant...\n" + "Please enhance and structure the company information..."); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content","Please enhance the following company information:\n" +webContent); + mapUserEntity.put("content", "Please enhance the following company information:\n" + webContent); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"WEBAITQ"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("网站信息增强处理:{}",resultJson); + String resultStr = chatGPTClient.handleAiChat(promptJson, "WEBAITQ"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("网站信息增强处理:{}", resultJson); return resultJson; } /** * 个人简介生成器 + * * @param personalProfileGeneratorVo 个人信息 * @return */ @@ -654,46 +665,47 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I String linedIn = ""; String website = ""; - if(CollectionUtil.isNotEmpty(personalProfileGeneratorVo.getLinks())){ - List linedInList = personalProfileGeneratorVo.getLinks().stream().filter(e->"LinkedIn".equals(e.getDataType())).toList(); - if(CollectionUtil.isNotEmpty(linedInList)){ + if (CollectionUtil.isNotEmpty(personalProfileGeneratorVo.getLinks())) { + List linedInList = personalProfileGeneratorVo.getLinks().stream().filter(e -> "LinkedIn".equals(e.getDataType())).toList(); + if (CollectionUtil.isNotEmpty(linedInList)) { linedIn = linedInList.get(0).getContent(); } - List websiteList = personalProfileGeneratorVo.getLinks().stream().filter(e->"Website".equals(e.getDataType())).toList(); + List websiteList = personalProfileGeneratorVo.getLinks().stream().filter(e -> "Website".equals(e.getDataType())).toList(); - if(CollectionUtil.isNotEmpty(websiteList)){ + if (CollectionUtil.isNotEmpty(websiteList)) { website = websiteList.get(0).getContent(); } } - String candidateText = " Full Name: "+personalProfileGeneratorVo.getName()+" Birthday: "+personalProfileGeneratorVo.getBirthday()+" Job Position: "+personalProfileGeneratorVo.getPosition() - +"Location: "+personalProfileGeneratorVo.getLocation()+" Email: "+personalProfileGeneratorVo.getEmail()+" Phone Number: "+personalProfileGeneratorVo.getPhone() - +"LinkedIn: "+linedIn+" Website: "+website; + String candidateText = " Full Name: " + personalProfileGeneratorVo.getName() + " Birthday: " + personalProfileGeneratorVo.getBirthday() + " Job Position: " + personalProfileGeneratorVo.getPosition() + + "Location: " + personalProfileGeneratorVo.getLocation() + " Email: " + personalProfileGeneratorVo.getEmail() + " Phone Number: " + personalProfileGeneratorVo.getPhone() + + "LinkedIn: " + linedIn + " Website: " + website; - String userPrompt = "Please generate a professional personal summary based on the following candidate information:\\n\\n"+candidateText; + String userPrompt = "Please generate a professional personal summary based on the following candidate information:\\n\\n" + candidateText; List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content",userPrompt); + mapUserEntity.put("content", userPrompt); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"PPG"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("个人简介生成器:{}",resultJson); + String resultStr = chatGPTClient.handleAiChat(promptJson, "PPG"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("个人简介生成器:{}", resultJson); - Map dataMap = JSONUtil.toBean(resultJson,Map.class); + Map dataMap = JSONUtil.toBean(resultJson, Map.class); HotakePersonalProfileGeneratorDto generatorDto = new HotakePersonalProfileGeneratorDto(); - Map personalSummaryMap = (Map)dataMap.get("personal_summary"); + Map personalSummaryMap = (Map) dataMap.get("personal_summary"); generatorDto.setAbout(personalSummaryMap.get("generated_text").toString()); return generatorDto; } /** * 工作经验生成器 + * * @param workExperienceGeneratorVo 工作信息 * @return */ @@ -701,37 +713,37 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I public HotakeWorkExperienceGeneratorDto getWorkExperienceGenerator(HotakeWorkExperienceGeneratorVo workExperienceGeneratorVo) { String prompt = AiCommonPromptConstants.initializationWorkExperienceGeneratorPrompt(); - String candidateText = " Job Title: "+workExperienceGeneratorVo.getTitle()+" Company Name: "+workExperienceGeneratorVo.getCompany()+" Work Period: "+workExperienceGeneratorVo.getDurationStart()+"-"+workExperienceGeneratorVo.getDurationEnd() - +"Additional Info: "; + String candidateText = " Job Title: " + workExperienceGeneratorVo.getTitle() + " Company Name: " + workExperienceGeneratorVo.getCompany() + " Work Period: " + workExperienceGeneratorVo.getDurationStart() + "-" + workExperienceGeneratorVo.getDurationEnd() + + "Additional Info: "; - String userPrompt = "Please generate a professional work experience description based on the following information:\\n\\n"+candidateText; + String userPrompt = "Please generate a professional work experience description based on the following information:\\n\\n" + candidateText; List> list = new LinkedList(); Map mapEntity = new HashMap<>(); mapEntity.put("role", "system"); - mapEntity.put("content",prompt); + mapEntity.put("content", prompt); list.add(mapEntity); Map mapUserEntity = new HashMap<>(); mapUserEntity.put("role", "user"); - mapUserEntity.put("content",userPrompt); + mapUserEntity.put("content", userPrompt); list.add(mapUserEntity); String promptJson = JSONUtil.toJsonStr(list); - String resultStr = chatGPTClient.handleAiChat(promptJson,"PPG"); - String resultJson = resultStr.replaceAll("```json","").replaceAll("```",""); - log.info("工作经验生成器:{}",resultJson); + String resultStr = chatGPTClient.handleAiChat(promptJson, "PPG"); + String resultJson = resultStr.replaceAll("```json", "").replaceAll("```", ""); + log.info("工作经验生成器:{}", resultJson); - Map dataMap = JSONUtil.toBean(resultJson,Map.class); + Map dataMap = JSONUtil.toBean(resultJson, Map.class); HotakeWorkExperienceGeneratorDto generatorDto = new HotakeWorkExperienceGeneratorDto(); List description = new ArrayList<>(); - Map workExperienceMap = (Map)dataMap.get("work_experience"); + Map workExperienceMap = (Map) dataMap.get("work_experience"); VcExperienceDescriptionDto descriptionDto = new VcExperienceDescriptionDto(); descriptionDto.setContent(workExperienceMap.get("position_summary").toString()); description.add(descriptionDto); - List keyResponsibilitiesList = (List)workExperienceMap.get("key_responsibilities"); - if(CollectionUtil.isNotEmpty(keyResponsibilitiesList)){ - for (String Str : keyResponsibilitiesList){ + List keyResponsibilitiesList = (List) workExperienceMap.get("key_responsibilities"); + if (CollectionUtil.isNotEmpty(keyResponsibilitiesList)) { + for (String Str : keyResponsibilitiesList) { VcExperienceDescriptionDto descriptionDto1 = new VcExperienceDescriptionDto(); descriptionDto1.setContent(Str); description.add(descriptionDto1); @@ -743,6 +755,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 招聘链接信息分析补全 + * * @param roleLinkAnalysisVo 岗位链接对象 * @return */ @@ -769,26 +782,26 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I // String promptJson = JSONUtil.toJsonStr(list); // String resultStr = chatGPTClient.handleAiChat(promptJson,"RLINKAL"); String resultJson = "{\"jobTitle\":\"Senior Software Engineer\",\"companyName\":\"Tech Innovation Corp\",\"jobType\":null}"; - log.info("招聘链接信息提取:{}",resultJson); + log.info("招聘链接信息提取:{}", resultJson); //处理岗位信息补充 - String userPrompt_1 = "Please generate complete API-formatted data based on the extracted job information below:\\n\\n" +resultJson; + String userPrompt_1 = "Please generate complete API-formatted data based on the extracted job information below:\\n\\n" + resultJson; List> listOne = new LinkedList(); Map mapEntityOne = new HashMap<>(); mapEntityOne.put("role", "system"); - mapEntityOne.put("content",prompt); + mapEntityOne.put("content", prompt); listOne.add(mapEntityOne); Map mapUserEntityOne = new HashMap<>(); mapUserEntityOne.put("role", "user"); - mapUserEntityOne.put("content",userPrompt_1); + mapUserEntityOne.put("content", userPrompt_1); listOne.add(mapUserEntityOne); String promptJsonOne = JSONUtil.toJsonStr(listOne); - String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne,"RLINKAL"); - String resultJsonOne = resultStrOne.replaceAll("```json","").replaceAll("```",""); - log.info("招聘链接信息补全:{}",resultJsonOne); + String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "RLINKAL"); + String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); + log.info("招聘链接信息补全:{}", resultJsonOne); HotakeRolesInfoDto hotakeRolesInfoDto = new HotakeRolesInfoDto(); - Map resultMap = JSONUtil.toBean(resultJsonOne,Map.class); + Map resultMap = JSONUtil.toBean(resultJsonOne, Map.class); - Map dataMap = (Map)resultMap.get("data"); + Map dataMap = (Map) resultMap.get("data"); hotakeRolesInfoDto.setRoleName(dataMap.get("jobTitle").toString()); hotakeRolesInfoDto.setCompanyName(dataMap.get("companyName").toString()); @@ -804,25 +817,25 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I hotakeRolesInfoDto.setResponsibilities(dataMap.get("responsibilities").toString()); //岗位所需技能信息 - List requiredSkillsList = (List)dataMap.get("requiredSkillsList"); + List requiredSkillsList = (List) dataMap.get("requiredSkillsList"); hotakeRolesInfoDto.setRequiredSkillsList(requiredSkillsList); hotakeRolesInfoDto.setRequiredSkillsJson(JSONUtil.toJsonStr(requiredSkillsList)); - List niceToHaveSkillsList = (List)dataMap.get("niceToHaveSkillsList"); + List niceToHaveSkillsList = (List) dataMap.get("niceToHaveSkillsList"); hotakeRolesInfoDto.setNiceToHaveSkillsList(niceToHaveSkillsList); hotakeRolesInfoDto.setNiceToHaveSkillsJson(JSONUtil.toJsonStr(niceToHaveSkillsList)); - List roleBenefitsMapList = (List)dataMap.get("roleBenefitsList"); + List roleBenefitsMapList = (List) dataMap.get("roleBenefitsList"); List roleBenefitsList = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(roleBenefitsMapList)){ - for(Map dto : roleBenefitsMapList){ + if (CollectionUtil.isNotEmpty(roleBenefitsMapList)) { + for (Map dto : roleBenefitsMapList) { //福利转换 RoleBenefitsDto dto1 = new RoleBenefitsDto(); - if(ObjectUtil.isNotEmpty(dto.get("keyValue"))){ + if (ObjectUtil.isNotEmpty(dto.get("keyValue"))) { RoleBenefitsEnum benefitsEnum = RoleBenefitsEnum.getByCode(dto.get("keyValue").toString()); - if(benefitsEnum != null){ + if (benefitsEnum != null) { dto1.setKeyValue(benefitsEnum.getCode()); roleBenefitsList.add(dto1); } @@ -833,28 +846,28 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I hotakeRolesInfoDto.setRoleBenefitsJson(JSONUtil.toJsonStr(roleBenefitsList)); - Map educationRequirementsMap = (Map)dataMap.get("educationRequirements"); + Map educationRequirementsMap = (Map) dataMap.get("educationRequirements"); EducationRequirementsDto educationRequirements = new EducationRequirementsDto(); educationRequirements.setAcademicMajor(educationRequirementsMap.get("academicMajor").toString()); educationRequirements.setDegree(educationRequirementsMap.get("degree").toString()); hotakeRolesInfoDto.setEducationRequirements(educationRequirements); hotakeRolesInfoDto.setEducationRequirementsJson(JSONUtil.toJsonStr(educationRequirements)); - List certificationsLicensesList = (List)dataMap.get("certificationsLicensesList"); + List certificationsLicensesList = (List) dataMap.get("certificationsLicensesList"); hotakeRolesInfoDto.setCertificationsLicensesList(certificationsLicensesList); hotakeRolesInfoDto.setCertificationsLicensesJson(JSONUtil.toJsonStr(certificationsLicensesList)); - fill(FillTypeEnum.INSERT.getCode(),hotakeRolesInfoDto); + fill(FillTypeEnum.INSERT.getCode(), hotakeRolesInfoDto); hotakeRolesInfoMapper.insertHotakeRolesInfo(hotakeRolesInfoDto); return hotakeRolesInfoDto; } - /** * 招聘链接信息分析补全 + * * @param roleLinkAnalysisVo 岗位链接对象 * @return */ @@ -864,36 +877,36 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I String prompt = AiCommonPromptConstants.initializationRoleLinkAnalysisPrompt(); String resultJson = "{\n" + - " \"jobTitle\": "+rolesInfoDto.getRoleName()+",\n" + - " \"companyName\": "+rolesInfoDto.getCompanyName()+",\n" + - " \"location\": "+rolesInfoDto.getLocations()+",\n" + - " \"salaryRange\": "+rolesInfoDto.getSalaryStart()+"-"+rolesInfoDto.getSalaryEnd()+",\n" + - " \"jobType\": "+rolesInfoDto.getJobType()+",\n" + - " \"experience\": "+rolesInfoDto.getJobExperience()+",\n" + - " \"education\": "+JSONUtil.toJsonStr(rolesInfoDto.getEducationRequirements())+",\n" + - " \"skills\": "+JSONUtil.toJsonStr(rolesInfoDto.getRequiredSkillsList())+",\n" + - " \"description\": "+rolesInfoDto.getAboutRole()+"\n" + + " \"jobTitle\": " + rolesInfoDto.getRoleName() + ",\n" + + " \"companyName\": " + rolesInfoDto.getCompanyName() + ",\n" + + " \"location\": " + rolesInfoDto.getLocations() + ",\n" + + " \"salaryRange\": " + rolesInfoDto.getSalaryStart() + "-" + rolesInfoDto.getSalaryEnd() + ",\n" + + " \"jobType\": " + rolesInfoDto.getJobType() + ",\n" + + " \"experience\": " + rolesInfoDto.getJobExperience() + ",\n" + + " \"education\": " + JSONUtil.toJsonStr(rolesInfoDto.getEducationRequirements()) + ",\n" + + " \"skills\": " + JSONUtil.toJsonStr(rolesInfoDto.getRequiredSkillsList()) + ",\n" + + " \"description\": " + rolesInfoDto.getAboutRole() + "\n" + "}"; - log.info("招聘链接信息提取:{}",resultJson); + log.info("招聘链接信息提取:{}", resultJson); //处理岗位信息补充 - String userPrompt_1 = "Please generate complete API-formatted data based on the extracted job information below:\\n\\n" +resultJson; + String userPrompt_1 = "Please generate complete API-formatted data based on the extracted job information below:\\n\\n" + resultJson; List> listOne = new LinkedList(); Map mapEntityOne = new HashMap<>(); mapEntityOne.put("role", "system"); - mapEntityOne.put("content",prompt); + mapEntityOne.put("content", prompt); listOne.add(mapEntityOne); Map mapUserEntityOne = new HashMap<>(); mapUserEntityOne.put("role", "user"); - mapUserEntityOne.put("content",userPrompt_1); + mapUserEntityOne.put("content", userPrompt_1); listOne.add(mapUserEntityOne); String promptJsonOne = JSONUtil.toJsonStr(listOne); - String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne,"RLINKAL"); - String resultJsonOne = resultStrOne.replaceAll("```json","").replaceAll("```",""); - log.info("招聘信息补全:{}",resultJsonOne); + String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "RLINKAL"); + String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); + log.info("招聘信息补全:{}", resultJsonOne); HotakeRolesInfoDto hotakeRolesInfoDto = new HotakeRolesInfoDto(); - Map resultMap = JSONUtil.toBean(resultJsonOne,Map.class); + Map resultMap = JSONUtil.toBean(resultJsonOne, Map.class); - Map dataMap = (Map)resultMap.get("data"); + Map dataMap = (Map) resultMap.get("data"); hotakeRolesInfoDto.setRoleName(dataMap.get("jobTitle").toString()); hotakeRolesInfoDto.setCompanyName(dataMap.get("companyName").toString()); @@ -909,25 +922,25 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I hotakeRolesInfoDto.setResponsibilities(dataMap.get("responsibilities").toString()); //岗位所需技能信息 - List requiredSkillsList = (List)dataMap.get("requiredSkillsList"); + List requiredSkillsList = (List) dataMap.get("requiredSkillsList"); hotakeRolesInfoDto.setRequiredSkillsList(requiredSkillsList); hotakeRolesInfoDto.setRequiredSkillsJson(JSONUtil.toJsonStr(requiredSkillsList)); - List niceToHaveSkillsList = (List)dataMap.get("niceToHaveSkillsList"); + List niceToHaveSkillsList = (List) dataMap.get("niceToHaveSkillsList"); hotakeRolesInfoDto.setNiceToHaveSkillsList(niceToHaveSkillsList); hotakeRolesInfoDto.setNiceToHaveSkillsJson(JSONUtil.toJsonStr(niceToHaveSkillsList)); - List roleBenefitsMapList = (List)dataMap.get("roleBenefitsList"); + List roleBenefitsMapList = (List) dataMap.get("roleBenefitsList"); List roleBenefitsList = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(roleBenefitsMapList)){ - for(Map dto : roleBenefitsMapList){ + if (CollectionUtil.isNotEmpty(roleBenefitsMapList)) { + for (Map dto : roleBenefitsMapList) { //福利转换 RoleBenefitsDto dto1 = new RoleBenefitsDto(); - if(ObjectUtil.isNotEmpty(dto.get("keyValue"))){ + if (ObjectUtil.isNotEmpty(dto.get("keyValue"))) { RoleBenefitsEnum benefitsEnum = RoleBenefitsEnum.getByCode(dto.get("keyValue").toString()); - if(benefitsEnum != null){ + if (benefitsEnum != null) { dto1.setKeyValue(benefitsEnum.getCode()); roleBenefitsList.add(dto1); } @@ -937,14 +950,14 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I hotakeRolesInfoDto.setRoleBenefitsList(roleBenefitsList); hotakeRolesInfoDto.setRoleBenefitsJson(JSONUtil.toJsonStr(roleBenefitsList)); - Map educationRequirementsMap = (Map)dataMap.get("educationRequirements"); + Map educationRequirementsMap = (Map) dataMap.get("educationRequirements"); EducationRequirementsDto educationRequirements = new EducationRequirementsDto(); educationRequirements.setAcademicMajor(educationRequirementsMap.get("academicMajor").toString()); educationRequirements.setDegree(educationRequirementsMap.get("degree").toString()); hotakeRolesInfoDto.setEducationRequirements(educationRequirements); hotakeRolesInfoDto.setEducationRequirementsJson(JSONUtil.toJsonStr(educationRequirements)); - List certificationsLicensesList = (List)dataMap.get("certificationsLicensesList"); + List certificationsLicensesList = (List) dataMap.get("certificationsLicensesList"); hotakeRolesInfoDto.setCertificationsLicensesList(certificationsLicensesList); hotakeRolesInfoDto.setCertificationsLicensesJson(JSONUtil.toJsonStr(certificationsLicensesList)); @@ -955,6 +968,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * AI面试问题生成 + * * @param rolesInfo 岗位信息 * @return */ @@ -966,34 +980,35 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I String userPrompt_1 = "Please generate AI interview questions based on the following job description:\n" + "\n" + "**Job Information**:\n" + - "Job Title:【"+rolesInfo.getRoleName()+"】\n" + - "Technical Requirements:【"+rolesInfo.getRequiredSkillsJson()+"-"+rolesInfo.getNiceToHaveSkillsJson()+"】\n" + - "Experience Requirements:【"+rolesInfo.getJobExperience()+"】\n" + + "Job Title:【" + rolesInfo.getRoleName() + "】\n" + + "Technical Requirements:【" + rolesInfo.getRequiredSkillsJson() + "-" + rolesInfo.getNiceToHaveSkillsJson() + "】\n" + + "Experience Requirements:【" + rolesInfo.getJobExperience() + "】\n" + "Interview Duration:【】\n" + "Company Culture:【】\n" + - "Special Requirements:【"+rolesInfo.getAboutRole()+"】\n" + + "Special Requirements:【" + rolesInfo.getAboutRole() + "】\n" + "`;"; - log.info("AI面试问题生成:{}",userPrompt_1); + log.info("AI面试问题生成:{}", userPrompt_1); //处理岗位信息补充 List> listOne = new LinkedList(); Map mapEntityOne = new HashMap<>(); mapEntityOne.put("role", "system"); - mapEntityOne.put("content",prompt); + mapEntityOne.put("content", prompt); listOne.add(mapEntityOne); Map mapUserEntityOne = new HashMap<>(); mapUserEntityOne.put("role", "user"); - mapUserEntityOne.put("content",userPrompt_1); + mapUserEntityOne.put("content", userPrompt_1); listOne.add(mapUserEntityOne); String promptJsonOne = JSONUtil.toJsonStr(listOne); - String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne,"RLINKAL"); - String resultJsonOne = resultStrOne.replaceAll("```json","").replaceAll("```",""); - log.info("AI面试问题生成结果:{}",resultJsonOne); + String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "RLINKAL"); + String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); + log.info("AI面试问题生成结果:{}", resultJsonOne); return resultJsonOne; } /** * 候选人AI面试分析 + * * @param rolesInfo 候选人AI面试分析信息 * @return */ @@ -1002,74 +1017,74 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I HotakeCandidateAiInterviewAnalysisDto analysisDto = new HotakeCandidateAiInterviewAnalysisDto(); String prompt = AiCommonPromptConstants.initializationCandidateAiInterviewAnalysisPrompt(); String qa = ""; - if(CollectionUtil.isNotEmpty(analysisVo.getAiInterviewQuestionRecordVoList())){ - for(HotakeAiInterviewQuestionRecordVo recordVo : analysisVo.getAiInterviewQuestionRecordVoList()){ - if("assistant".equals(recordVo.getUserType())){ - qa = qa + "Question:"+recordVo.getContentText(); + if (CollectionUtil.isNotEmpty(analysisVo.getAiInterviewQuestionRecordVoList())) { + for (HotakeAiInterviewQuestionRecordVo recordVo : analysisVo.getAiInterviewQuestionRecordVoList()) { + if ("assistant".equals(recordVo.getUserType())) { + qa = qa + "Question:" + recordVo.getContentText(); } - if("user".equals(recordVo.getUserType())){ - qa = qa + "Answer:"+recordVo.getContentText(); + if ("user".equals(recordVo.getUserType())) { + qa = qa + "Answer:" + recordVo.getContentText(); } } } String userPrompt_1 = "Please conduct an interview analysis based on the questions answered by the following candidates:\n" + "\n" + "**Job Information**:\n" + - "Position:【"+analysisVo.getPosition()+"】\n" + - "Question And Answer:【"+qa+"】\n"+ - "Please return the analysis results in the required JSON format."; + "Position:【" + analysisVo.getPosition() + "】\n" + + "Question And Answer:【" + qa + "】\n" + + "Please return the analysis results in the required JSON format."; - log.info("AI面试问题生成:{}",userPrompt_1); + log.info("AI面试问题生成:{}", userPrompt_1); //处理岗位信息补充 List> listOne = new LinkedList(); Map mapEntityOne = new HashMap<>(); mapEntityOne.put("role", "system"); - mapEntityOne.put("content",prompt); + mapEntityOne.put("content", prompt); listOne.add(mapEntityOne); Map mapUserEntityOne = new HashMap<>(); mapUserEntityOne.put("role", "user"); - mapUserEntityOne.put("content",userPrompt_1); + mapUserEntityOne.put("content", userPrompt_1); listOne.add(mapUserEntityOne); String promptJsonOne = JSONUtil.toJsonStr(listOne); - String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne,"AIINTPF"); - String resultJsonOne = resultStrOne.replaceAll("```json","").replaceAll("```",""); - log.info("候选人AI面试分析结果:{}",resultJsonOne); - if(StrUtil.isNotEmpty(resultJsonOne)){ + String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "AIINTPF"); + String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); + log.info("候选人AI面试分析结果:{}", resultJsonOne); + if (StrUtil.isNotEmpty(resultJsonOne)) { try { - Map dataMap = JSONUtil.toBean(resultJsonOne,Map.class); - Map scoresMap = (Map)dataMap.get("scores"); + Map dataMap = JSONUtil.toBean(resultJsonOne, Map.class); + Map scoresMap = (Map) dataMap.get("scores"); analysisDto.setTechnical(new BigDecimal(scoresMap.get("technical").toString())); analysisDto.setCommunication(new BigDecimal(scoresMap.get("communication").toString())); analysisDto.setCultural(new BigDecimal(scoresMap.get("cultural").toString())); - Map analysisMap = (Map)dataMap.get("analysis"); - Map technicalMap = (Map)analysisMap.get("technical"); + Map analysisMap = (Map) dataMap.get("analysis"); + Map technicalMap = (Map) analysisMap.get("technical"); HotakeCandidateAiInterviewAnalysisAnalysisDto technicalDto = new HotakeCandidateAiInterviewAnalysisAnalysisDto(); - List improvements = (List)technicalMap.get("improvements"); - List strengths = (List)technicalMap.get("strengths"); + List improvements = (List) technicalMap.get("improvements"); + List strengths = (List) technicalMap.get("strengths"); technicalDto.setImprovements(improvements); technicalDto.setStrengths(strengths); analysisDto.setTechnicalDto(technicalDto); - Map communicationMap = (Map)analysisMap.get("communication"); + Map communicationMap = (Map) analysisMap.get("communication"); HotakeCandidateAiInterviewAnalysisAnalysisDto communicationDto = new HotakeCandidateAiInterviewAnalysisAnalysisDto(); - List improvements1 = (List)communicationMap.get("improvements"); - List strengths1 = (List)communicationMap.get("strengths"); + List improvements1 = (List) communicationMap.get("improvements"); + List strengths1 = (List) communicationMap.get("strengths"); communicationDto.setImprovements(improvements1); communicationDto.setStrengths(strengths1); analysisDto.setCommunicationDto(communicationDto); - Map culturalMap = (Map)analysisMap.get("cultural"); + Map culturalMap = (Map) analysisMap.get("cultural"); HotakeCandidateAiInterviewAnalysisAnalysisDto culturalDto = new HotakeCandidateAiInterviewAnalysisAnalysisDto(); - List improvements2 = (List)culturalMap.get("improvements"); - List strengths2 = (List)culturalMap.get("strengths"); + List improvements2 = (List) culturalMap.get("improvements"); + List strengths2 = (List) culturalMap.get("strengths"); culturalDto.setImprovements(improvements2); culturalDto.setStrengths(strengths2); analysisDto.setCulturalDto(culturalDto); List notesDtoList = new ArrayList<>(); - List notesMapList = (List)dataMap.get("notes"); - if(CollectionUtil.isNotEmpty(notesMapList)){ - for(Map noteMap : notesMapList){ + List notesMapList = (List) dataMap.get("notes"); + if (CollectionUtil.isNotEmpty(notesMapList)) { + for (Map noteMap : notesMapList) { HotakeCandidateAiInterviewAnalysisNotesDto analysisNotesDto = new HotakeCandidateAiInterviewAnalysisNotesDto(); analysisNotesDto.setType(noteMap.get("type").toString()); analysisNotesDto.setContent(noteMap.get("content").toString()); @@ -1078,7 +1093,7 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I } analysisDto.setNotesDtoList(notesDtoList); - }catch (Exception e){ + } catch (Exception e) { throw new ServiceException("No rating"); } } @@ -1089,41 +1104,29 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I /** * 招聘者AI简历评分和排名系统 + * * @param scoringRankingVo 招聘者AI简历评分和排名系统输入信息 * @return */ @Override - public String handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo) { - if(CollectionUtil.isEmpty(roleApplyVo.getRoleApplyIds()) || roleApplyVo.getRoleApplyIds().size() < 2){ - throw new ServiceException("Please select at least two pieces of data"); - } - //根据岗位申请Id查询岗位申请数据信息列表 - HotakeRolesApplyInfo queryApplyInfo = new HotakeRolesApplyInfo(); - queryApplyInfo.setApplyRoleIdList(roleApplyVo.getRoleApplyIds()); - List applyInfoList = hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoList(queryApplyInfo); - - List roleIds = applyInfoList.stream().map(HotakeRolesApplyInfo::getRoleId).collect(Collectors.toList());; - Set 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)); + public HotakeAiCvScoringRankingDto handleAiCvScoringRanking(HotakeAiCvScoringRankingRoleApplyVo roleApplyVo) { + HotakeAiCvScoringRankingDto dto = new HotakeAiCvScoringRankingDto(); + HotakeRolesInfo rolesInfo = hotakeRolesInfoMapper.selectHotakeRolesInfoById(roleApplyVo.getApplyInfo().getRoleId()); HotakeAiCvScoringRankingVo scoringRankingVo = new HotakeAiCvScoringRankingVo(); scoringRankingVo.setTitle(rolesInfo.getRoleName()); scoringRankingVo.setDescription(rolesInfo.getAboutRole()); - List requiredSkillsList = JSONUtil.toList(rolesInfo.getRequiredSkillsJson(),RequiredSkillsDto.class); + List requiredSkillsList = JSONUtil.toList(rolesInfo.getRequiredSkillsJson(), RequiredSkillsDto.class); List requiredSkills = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(requiredSkillsList)){ + if (CollectionUtil.isNotEmpty(requiredSkillsList)) { for (RequiredSkillsDto requiredSkillsDto : requiredSkillsList) { requiredSkills.add(requiredSkillsDto.getKeyValue()); } } - List niceToHaveSkillsList = JSONUtil.toList(rolesInfo.getNiceToHaveSkillsJson(),NiceToHaveSkillsDto.class); + List niceToHaveSkillsList = JSONUtil.toList(rolesInfo.getNiceToHaveSkillsJson(), NiceToHaveSkillsDto.class); List niceToHaveSkills = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(niceToHaveSkillsList)){ + if (CollectionUtil.isNotEmpty(niceToHaveSkillsList)) { for (NiceToHaveSkillsDto haveSkillsDto : niceToHaveSkillsList) { niceToHaveSkills.add(haveSkillsDto.getKeyValue()); } @@ -1131,30 +1134,27 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I scoringRankingVo.setRequiredSkills(requiredSkills); scoringRankingVo.setNiceToHaveSkills(niceToHaveSkills); scoringRankingVo.setExperienceRequired(rolesInfo.getJobExperience()); - EducationRequirementsDto educationRequirements = JSONUtil.toBean(rolesInfo.getEducationRequirementsJson(),EducationRequirementsDto.class); - scoringRankingVo.setEducationRequired(educationRequirements.getDegree()+","+educationRequirements.getAcademicMajor()); + EducationRequirementsDto educationRequirements = JSONUtil.toBean(rolesInfo.getEducationRequirementsJson(), EducationRequirementsDto.class); + scoringRankingVo.setEducationRequired(educationRequirements.getDegree() + "," + educationRequirements.getAcademicMajor()); - List candidates = new ArrayList<>(); - for(HotakeRolesApplyInfo applyInfo : applyInfoList){ - HotakeCvInfoDto cvInfoDto = JSONUtil.toBean(applyInfo.getCvTemplateJson(), HotakeCvInfoDto.class); - HotakeCandidateVcInfoVo infoVo = new HotakeCandidateVcInfoVo(); + HotakeCvInfoDto cvInfoDto = JSONUtil.toBean(roleApplyVo.getCvTemplateJson(), HotakeCvInfoDto.class); + HotakeCandidateVcInfoVo infoVo = new HotakeCandidateVcInfoVo(); - infoVo.setName(cvInfoDto.getName()); - infoVo.setCurrentPosition(cvInfoDto.getPosition()); - infoVo.setWorkExperience(JSONUtil.toJsonStr(cvInfoDto.getExperience())); - infoVo.setEducation(JSONUtil.toJsonStr(cvInfoDto.getEducation())); + infoVo.setName(cvInfoDto.getName()); + infoVo.setCurrentPosition(cvInfoDto.getPosition()); + infoVo.setWorkExperience(JSONUtil.toJsonStr(cvInfoDto.getExperience())); + infoVo.setEducation(JSONUtil.toJsonStr(cvInfoDto.getEducation())); - List skills = new ArrayList<>(); - if(CollectionUtil.isNotEmpty(cvInfoDto.getSkillsTools())){ - for (VcSkillsToolsDto skillsToolsDto : cvInfoDto.getSkillsTools()) { - skills.add(skillsToolsDto.getContent()); - } + List skills = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(cvInfoDto.getSkillsTools())) { + for (VcSkillsToolsDto skillsToolsDto : cvInfoDto.getSkillsTools()) { + skills.add(skillsToolsDto.getContent()); } - infoVo.setSkills(skills); - infoVo.setSummary(cvInfoDto.getAbout()); - candidates.add(infoVo); } - scoringRankingVo.setCandidates(candidates); + infoVo.setSkills(skills); + infoVo.setSummary(cvInfoDto.getAbout()); + + scoringRankingVo.setCandidates(infoVo); String prompt = AiCommonPromptConstants.initializationAiCvScoringRankingPrompt(); String userPrompt_1 = JSONUtil.toJsonStr(scoringRankingVo); @@ -1162,39 +1162,85 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List> listOne = new LinkedList(); Map mapEntityOne = new HashMap<>(); mapEntityOne.put("role", "system"); - mapEntityOne.put("content",prompt); + mapEntityOne.put("content", prompt); listOne.add(mapEntityOne); Map mapUserEntityOne = new HashMap<>(); mapUserEntityOne.put("role", "user"); - mapUserEntityOne.put("content",userPrompt_1); + mapUserEntityOne.put("content", userPrompt_1); listOne.add(mapUserEntityOne); String promptJsonOne = JSONUtil.toJsonStr(listOne); - String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne,"AICVSR"); - String resultJsonOne = resultStrOne.replaceAll("```json","").replaceAll("```",""); - log.info("招聘者AI简历评分和排名系统结果:{}",resultJsonOne); + String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "AICVSR"); + String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); + 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 strengths = (List)dataMap.get("strengths"); + dto.setStrengths(strengths); + List weaknesses = (List)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 招聘者查看候选人匹配度 输入信息 * @return */ @Override - public String handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo) { + public HotakeCandidateCompatibilityDto handleCandidateCompatibility(HotakeCandidateCompatibilityVo compatibilityVo) { + HotakeCandidateCompatibilityDto dto = new HotakeCandidateCompatibilityDto(); String prompt = AiCommonPromptConstants.initializationCandidateCompatibilityPrompt(); String userPrompt_1 = "Please analyze the matching details of the following candidates:\n" + "\n" + - "【Position】: "+compatibilityVo.getPosition()+"\n" + - "【Candidate】: "+compatibilityVo.getCandidate()+"\n" + - "【Current position】: "+compatibilityVo.getCurrentPosition()+"\n" + - "【Work Experience】: "+compatibilityVo.getWorkExperience()+"\n" + - "【Skill】: "+JSONUtil.toJsonStr(compatibilityVo.getSkills())+"\n" + - "【Overall Rating】: "+compatibilityVo.getOverallRating()+"\n" + + "【Position】: " + compatibilityVo.getPosition() + "\n" + + "【Candidate】: " + compatibilityVo.getCandidate() + "\n" + + "【Current position】: " + compatibilityVo.getCurrentPosition() + "\n" + + "【Work Experience】: " + compatibilityVo.getWorkExperience() + "\n" + + "【Skill】: " + JSONUtil.toJsonStr(compatibilityVo.getSkills()) + "\n" + + "【Overall Rating】: " + compatibilityVo.getOverallRating() + "\n" + "\n" + "Please return a detailed analysis in JSON format。"; @@ -1202,17 +1248,46 @@ public class HotakeAiCommonToolsServiceImpl extends BaseServiceImpl implements I List> listOne = new LinkedList(); Map mapEntityOne = new HashMap<>(); mapEntityOne.put("role", "system"); - mapEntityOne.put("content",prompt); + mapEntityOne.put("content", prompt); listOne.add(mapEntityOne); Map mapUserEntityOne = new HashMap<>(); mapUserEntityOne.put("role", "user"); - mapUserEntityOne.put("content",userPrompt_1); + mapUserEntityOne.put("content", userPrompt_1); listOne.add(mapUserEntityOne); String promptJsonOne = JSONUtil.toJsonStr(listOne); - String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne,"AICAC"); - String resultJsonOne = resultStrOne.replaceAll("```json","").replaceAll("```",""); - log.info("招聘者查看候选人匹配度结果:{}",resultJsonOne); + String resultStrOne = chatGPTClient.handleAiChat(promptJsonOne, "AICAC"); + String resultJsonOne = resultStrOne.replaceAll("```json", "").replaceAll("```", ""); + 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 strengths = (List)dataMap.get("key_strengths"); + dto.setKeyStrengths(strengths); + + List differences = (List)dataMap.get("key_differences"); + dto.setKeyDifferences(differences); + + List fitDetails = (List)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; } } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeInitScreQuestionsReplyRecordInfoServiceImpl.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeInitScreQuestionsReplyRecordInfoServiceImpl.java index 71ef352..b8bfbc9 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeInitScreQuestionsReplyRecordInfoServiceImpl.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeInitScreQuestionsReplyRecordInfoServiceImpl.java @@ -2,10 +2,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; -import java.util.Map; +import java.util.*; import cn.hutool.core.collection.CollectionUtil; 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.readFile.FileContentUtil; 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.HotakeInitialQuestionEliminationScoreDto; 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.HotakeInitialQuestionEliminationScoreVo; import com.vetti.hotake.mapper.HotakeCvInfoMapper; @@ -192,65 +193,13 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi eliminationScoreVo.setInitScreQuestionsReplyRecordInfoList(initScreQuestionsReplyRecordInfoVo.getInitScreQuestionsReplyRecordInfoList()); HotakeInitialQuestionEliminationScoreDto eliminationScoreDto = aiCommonToolsService.getInitialQuestionEliminationScore(eliminationScoreVo); - - //查询候选人的当前最新简历信息 -// HotakeCvInfo queryCv = new HotakeCvInfo(); -// queryCv.setUserId(SecurityUtils.getUserId()); -// queryCv.setCvFileType("cv"); -// List 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 { applyInfo.setAiMatchScorePercentage(new BigDecimal(eliminationScoreDto.getScore()). divide(new BigDecimal(100)).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()); @@ -264,6 +213,73 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi applyInfo.setCandidateStatus(CandidateStatusEnum.PENDING.getCode()); } } + //解析简历数据 + //查询候选人的当前最新简历信息 + HotakeCvInfo queryCv = new HotakeCvInfo(); + queryCv.setUserId(SecurityUtils.getUserId()); + queryCv.setCvFileType("cv"); + List 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 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.setStage(StageEnum.APPLIED.getCode()); hotakeRolesApplyInfoMapper.updateHotakeRolesApplyInfo(applyInfo); @@ -274,11 +290,6 @@ public class HotakeInitScreQuestionsReplyRecordInfoServiceImpl extends BaseServi hotakeRolesApplyOperRecord.setRoleApplyId(applyInfo.getId()); hotakeRolesApplyOperRecord.setRoleId(rolesInf.getId()); rolesApplyOperRecordService.insertHotakeRolesApplyOperRecord(hotakeRolesApplyOperRecord); - -// } catch (Exception e) { -// e.printStackTrace(); -// } - return 0; } return 0; } diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeRolesApplyInfoServiceImpl.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeRolesApplyInfoServiceImpl.java index fbd0ce8..2c6683a 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeRolesApplyInfoServiceImpl.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeRolesApplyInfoServiceImpl.java @@ -4,13 +4,17 @@ 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.domain.entity.SysUser; import com.vetti.common.core.service.BaseServiceImpl; import com.vetti.common.enums.FillTypeEnum; import com.vetti.common.enums.StageEnum; +import com.vetti.common.exception.ServiceException; import com.vetti.common.utils.SecurityUtils; import com.vetti.hotake.domain.HotakeRolesApplyInfo; import com.vetti.hotake.domain.HotakeRolesApplyOperRecord; 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.VcDto.*; 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.service.IHotakeRolesApplyInfoService; import com.vetti.hotake.service.IHotakeRolesApplyOperRecordService; +import com.vetti.system.service.ISysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -43,6 +48,9 @@ public class HotakeRolesApplyInfoServiceImpl extends BaseServiceImpl implements @Autowired private IHotakeRolesApplyOperRecordService rolesApplyOperRecordService; + @Autowired + private ISysUserService userService; + /** * 查询候选人岗位申请信息 * @@ -371,4 +379,77 @@ public class HotakeRolesApplyInfoServiceImpl extends BaseServiceImpl implements return resultNum; } + /** + * AI简历评分和排名系统 + * @param hotakeRolesApplyInfo 候选人岗位申请信息 + * @return + */ + @Override + public List handleAiCvScoringRankingList(HotakeRolesApplyInfo hotakeRolesApplyInfo) { + if(CollectionUtil.isEmpty(hotakeRolesApplyInfo.getApplyRoleIdList())){ + throw new ServiceException("Please select at least one piece of business data"); + } + List applyInfoList = hotakeRolesApplyInfoMapper.selectHotakeRolesApplyInfoRankingList(hotakeRolesApplyInfo); + if(CollectionUtil.isNotEmpty(applyInfoList)) { + //查询岗位数据集合 + HotakeRolesInfo query = new HotakeRolesInfo(); + List rolesInfoList = hotakeRolesInfoMapper.selectHotakeRolesInfoList(query); + + List sysUserList = userService.selectUserList(new SysUser()); + + for(HotakeRolesApplyInfo applyInfo : applyInfoList) { + if(applyInfo.getRoleId() != null){ + List 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 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 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(); + } + } diff --git a/vetti-hotakes/src/main/resources/mapper/hotake/HotakeRolesApplyInfoMapper.xml b/vetti-hotakes/src/main/resources/mapper/hotake/HotakeRolesApplyInfoMapper.xml index 0a5cccd..ed73873 100644 --- a/vetti-hotakes/src/main/resources/mapper/hotake/HotakeRolesApplyInfoMapper.xml +++ b/vetti-hotakes/src/main/resources/mapper/hotake/HotakeRolesApplyInfoMapper.xml @@ -26,6 +26,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + + + @@ -37,7 +44,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 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,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 + + + +