diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeCvInfo.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeCvInfo.java index 88e8717..b3a0f35 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeCvInfo.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/HotakeCvInfo.java @@ -59,6 +59,9 @@ public class HotakeCvInfo extends BaseEntity @ApiModelProperty("简历评分以及说明") private String cvScore; + @ApiModelProperty("简历内容MD5 Hash") + private String cvMd5; + @ApiModelProperty("简历详细信息-固定模版") private HotakeCvInfoDto cvInfoDto; diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcEducationDto.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcEducationDto.java index cf010eb..da91ad8 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcEducationDto.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcEducationDto.java @@ -20,8 +20,11 @@ public class VcEducationDto { @ApiModelProperty("学校名") private String institution; - @ApiModelProperty("时间") - private String date; + @ApiModelProperty("开始时间") + private String durationStart; + + @ApiModelProperty("结束时间") + private String durationEnd; @ApiModelProperty("证书附件") private VcCertificateDto certificate; diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcExperienceDto.java b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcExperienceDto.java index 8ca9e2c..c1b84d7 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcExperienceDto.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/domain/dto/VcDto/VcExperienceDto.java @@ -25,8 +25,11 @@ public class VcExperienceDto { @ApiModelProperty("地点") private String location; - @ApiModelProperty("时间") - private String duration; + @ApiModelProperty("开始时间") + private String durationStart; + + @ApiModelProperty("结束时间") + private String durationEnd; @ApiModelProperty("描述集合") private List description; diff --git a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeCvInfoServiceImpl.java b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeCvInfoServiceImpl.java index f1a3e49..9c0d3ce 100644 --- a/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeCvInfoServiceImpl.java +++ b/vetti-hotakes/src/main/java/com/vetti/hotake/service/impl/HotakeCvInfoServiceImpl.java @@ -3,6 +3,7 @@ package com.vetti.hotake.service.impl; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.digest.MD5; import cn.hutool.json.JSONUtil; import com.vetti.common.ai.gpt.ChatGPTClient; import com.vetti.common.core.service.BaseServiceImpl; @@ -246,6 +247,12 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC .object(cvInfo.getCvUrl()) .build()); String contents = FileContentUtil.readFileContent(inputStream, cvInfo.getCvFileSuffix()); + //验证文件内容是否改变,如果未改变不进行模型解析直接返回原有结果 + String md5Hash = MD5.create().digestHex16(contents); + if(StrUtil.isNotEmpty(md5Hash) && md5Hash.equals(cvInfo.getCvMd5())){ + //直接返回简历结果 + return cvInfo; + } //生成简历模版数据信息 HotakeCvInfoDto cvInfoDto = handleAnalysisCvInfo(contents); cvInfo.setCvInfoDto(cvInfoDto); @@ -278,7 +285,7 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC List> list = new LinkedList(); Map entity = new HashMap<>(); entity.put("role","user"); - entity.put("content","从下面提供的文本中提取所有能识别到的简历信息,只提取原文中存在的内容,不要补充、不推测、不总结。需要提取的字段包括:name(姓名)、phone(电话号码)、email(电子邮件地址)、position(岗位)、location(地点)、links(所有链接地址)、currentWork(当前工作公司)、about(关于我/自我介绍)、skills_tools(关键资格(许可证、注册/会员资格、认证))、languages(语言能力)、experience(工作经历(除了title、company、location、duration,其他的都放到description里面,并且description里面要根据换行符分成不同的content))、education(教育经历)。请将提取结果以结构化 JSON 格式返回,格式如下:{ \\\"name\\\": \\\"\\\", \\\"phone\\\": \\\"\\\", \\\"email\\\": \\\"\\\", \\\"links\\\": [{\\\"content\\\":\\\"\\\"}], \\\"about\\\": \\\"\\\", \\\"skillsTools\\\": [{\\\"content\\\":\\\"\\\"}], \\\"languages\\\": [{\\\"content\\\":\\\"\\\"}], \\\"experience\\\": [{\\\"title\\\": \\\"\\\", \\\"company\\\": \\\"\\\",\\\"location\\\": \\\"\\\",\\\"duration\\\": \\\"\\\",\\\"description\\\": [{\\\"content\\\":\\\"\\\"}]}], \\\"education\\\": [{\\\"degree\\\": \\\"\\\",\\\"institution\\\": \\\"\\\",\\\"date\\\": \\\"\\\"}] }。字段不存在则返回 null 或空数组。只返回标准可解析的 JSON结构 ,不要多余的```json等信息,不要解释说明,不要改写内容。以下为待处理文本:"+contents); + entity.put("content","从下面提供的文本中提取所有能识别到的简历信息,只提取原文中存在的内容,不要补充、不推测、不总结。需要提取的字段包括:name(姓名)、phone(电话号码)、email(电子邮件地址)、position(岗位)、location(地点)、links(所有链接地址)、currentWork(当前工作公司)、about(关于我/自我介绍)、skills_tools(关键资格(许可证、注册/会员资格、认证))、languages(语言能力)、experience(工作经历,除了title、company、location、durationStart、durationEnd,其他的都放到description里面,并且description里面要根据换行符分成不同的content),日期要拆分成开始时间(durationStart)和结束时间(durationEnd))、education(教育经历,日期要拆分成开始时间(durationStart)和结束时间(durationEnd))。请将提取结果以结构化 JSON 格式返回,格式如下:{ \\\"name\\\": \\\"\\\", \\\"phone\\\": \\\"\\\", \\\"email\\\": \\\"\\\", \\\"links\\\": [{\\\"content\\\":\\\"\\\"}], \\\"about\\\": \\\"\\\", \\\"skillsTools\\\": [{\\\"content\\\":\\\"\\\"}], \\\"languages\\\": [{\\\"content\\\":\\\"\\\"}], \\\"experience\\\": [{\\\"title\\\": \\\"\\\", \\\"company\\\": \\\"\\\",\\\"location\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\",\\\"description\\\": [{\\\"content\\\":\\\"\\\"}]}], \\\"education\\\": [{\\\"degree\\\": \\\"\\\",\\\"institution\\\": \\\"\\\",\\\"durationStart\\\": \\\"\\\",\\\"durationEnd\\\": \\\"\\\"}] }。字段不存在则返回 null 或空数组。只返回标准可解析的 JSON结构 ,不要多余的```json等信息,不要解释说明,不要改写内容。以下为待处理文本:"+contents); //根据AI做 list.add(entity); String resultCv = chatGPTClient.handleAiChat(JSONUtil.toJsonStr(list), "JX"); @@ -341,8 +348,11 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC if(StrUtil.isEmpty(experienceDto.getLocation())){ experienceDto.setLocation("-"); } - if(StrUtil.isEmpty(experienceDto.getDuration())){ - experienceDto.setDuration("-"); + if(StrUtil.isEmpty(experienceDto.getDurationStart())){ + experienceDto.setDurationStart("-"); + } + if(StrUtil.isEmpty(experienceDto.getDurationEnd())){ + experienceDto.setDurationEnd("-"); } if (CollectionUtil.isNotEmpty(experienceDto.getDescription())){ for(VcExperienceDescriptionDto descriptionDto :experienceDto.getDescription()){ @@ -363,8 +373,11 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC if(StrUtil.isEmpty(educationDto.getInstitution())){ educationDto.setInstitution("-"); } - if(StrUtil.isEmpty(educationDto.getDate())){ - educationDto.setDate("-"); + if(StrUtil.isEmpty(educationDto.getDurationStart())){ + educationDto.setDurationStart("-"); + } + if(StrUtil.isEmpty(educationDto.getDurationEnd())){ + educationDto.setDurationEnd("-"); } if(educationDto.getCertificate() != null){ if(StrUtil.isEmpty(educationDto.getCertificate().getFileName())){ @@ -426,4 +439,11 @@ public class HotakeCvInfoServiceImpl extends BaseServiceImpl implements IHotakeC return resultMsg; } + public static void main(String[] args){ + String md5s = MD5.create().digestHex16("You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format."); + System.out.println(md5s); + String md5s1 = MD5.create().digestHex16("You 1are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format.You are a construction industry interview expert. Evaluate candidate responses and provide scores (1-5) and follow-up questions when needed. Always respond in JSON format."); + System.out.println(md5s1); + } + } diff --git a/vetti-hotakes/src/main/resources/mapper/hotake/HotakeCvInfoMapper.xml b/vetti-hotakes/src/main/resources/mapper/hotake/HotakeCvInfoMapper.xml index 34bdaa2..78ed392 100644 --- a/vetti-hotakes/src/main/resources/mapper/hotake/HotakeCvInfoMapper.xml +++ b/vetti-hotakes/src/main/resources/mapper/hotake/HotakeCvInfoMapper.xml @@ -15,6 +15,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -24,7 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, user_id, cv_name, cv_file_type, cv_url,file_size_show,cv_file_suffix, status,cv_template_json,cv_score, + select id, user_id, cv_name, cv_file_type, cv_url,file_size_show,cv_file_suffix, status,cv_template_json,cv_score,cv_md5, del_flag, create_by, create_time, update_by, update_time, remark from hotake_cv_info @@ -58,6 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" status, cv_template_json, cv_score, + cv_md5, del_flag, create_by, create_time, @@ -75,6 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{status}, #{cvTemplateJson}, #{cvScore}, + #{cvMd5}, #{delFlag}, #{createBy}, #{createTime}, @@ -96,6 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" status = #{status}, cv_template_json = #{cvTemplateJson}, cv_score = #{cvScore}, + cv_md5 = #{cvMd5}, del_flag = #{delFlag}, create_by = #{createBy}, create_time = #{createTime}, diff --git a/vetti-system/src/main/java/com/vetti/system/service/impl/SysUserServiceImpl.java b/vetti-system/src/main/java/com/vetti/system/service/impl/SysUserServiceImpl.java index 9cf04d2..16fad64 100644 --- a/vetti-system/src/main/java/com/vetti/system/service/impl/SysUserServiceImpl.java +++ b/vetti-system/src/main/java/com/vetti/system/service/impl/SysUserServiceImpl.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.stream.Collectors; import javax.validation.Validator; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.vetti.common.core.domain.dto.UserBestSideDto; @@ -349,6 +350,8 @@ public class SysUserServiceImpl implements ISysUserService @Override public int updateUserProfile(SysUser user) { + //更新用户的链接地址 + user.setBestSideJson(JSONUtil.toJsonStr(user.getBestSideDtoList())); return userMapper.updateUser(user); }