根据简历ID同步更新个人资料
This commit is contained in:
@@ -53,6 +53,14 @@ public class UserProfileController {
|
||||
userProfileService.saveProfile(po);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据简历ID同步更新个人资料(主表+5子表全量覆盖,触发一次异步AI分析)
|
||||
*/
|
||||
@PostMapping("/syncFromResume")
|
||||
public void syncFromResume(@RequestParam Long resumeId) {
|
||||
userProfileService.syncProfileFromResume(resumeId);
|
||||
}
|
||||
|
||||
// ==================== 教育经历 ====================
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,8 @@ package org.jiayunet.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jiayunet.exception.BusinessException;
|
||||
import org.jiayunet.exception.BusinessExpCodeEnum;
|
||||
import org.jiayunet.mapper.*;
|
||||
import org.jiayunet.pojo.po.*;
|
||||
import org.jiayunet.tool.UserSecurityTool;
|
||||
@@ -11,6 +13,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
@@ -47,6 +51,34 @@ public class UserProfileService {
|
||||
@Autowired
|
||||
private org.jiayunet.service.UserProfileAnalyzeService userProfileAnalyzeService;
|
||||
|
||||
@Autowired
|
||||
private UserResumeMapper userResumeMapper;
|
||||
|
||||
@Autowired
|
||||
private UserResumeEducationMapper resumeEducationMapper;
|
||||
|
||||
@Autowired
|
||||
private UserResumeWorkMapper resumeWorkMapper;
|
||||
|
||||
@Autowired
|
||||
private UserResumeInternshipMapper resumeInternshipMapper;
|
||||
|
||||
@Autowired
|
||||
private UserResumeProjectMapper resumeProjectMapper;
|
||||
|
||||
@Autowired
|
||||
private UserResumeCompetitionMapper resumeCompetitionMapper;
|
||||
|
||||
/** 学历文本→枚举映射 */
|
||||
private static final Map<String, Integer> DEGREE_MAP = Map.of(
|
||||
"大专", 1, "本科", 2, "硕士", 3, "博士", 4
|
||||
);
|
||||
|
||||
/** 学习形式文本→枚举映射 */
|
||||
private static final Map<String, Integer> STUDY_TYPE_MAP = Map.of(
|
||||
"全日制", 0, "非全日制", 1
|
||||
);
|
||||
|
||||
// ==================== 主表 ====================
|
||||
|
||||
/** 查询当前用户个人资料 */
|
||||
@@ -265,6 +297,178 @@ public class UserProfileService {
|
||||
userProfileAnalyzeService.analyzeUserProfile(userId);
|
||||
}
|
||||
|
||||
// ==================== 从简历同步到个人资料 ====================
|
||||
|
||||
/**
|
||||
* 根据简历ID同步更新个人资料
|
||||
* <p>1. 校验简历归属 2. 读取简历主表+5子表 3. 事务内覆盖写入Profile主表+5子表 4. 触发一次异步AI分析</p>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void syncProfileFromResume(Long resumeId) {
|
||||
Long userId = UserSecurityTool.getUserId();
|
||||
|
||||
// 1. 校验简历归属当前用户
|
||||
UserResume resume = userResumeMapper.selectById(resumeId);
|
||||
if (resume == null || !resume.getUserId().equals(userId)) {
|
||||
throw new BusinessException(BusinessExpCodeEnum.PERMISSION_DENIED, "简历不存在或无权操作");
|
||||
}
|
||||
|
||||
// 2. 读取简历5张子表
|
||||
List<UserResumeEducation> resumeEducationList = resumeEducationMapper.selectList(
|
||||
new LambdaQueryWrapper<UserResumeEducation>().eq(UserResumeEducation::getResumeId, resumeId).orderByAsc(UserResumeEducation::getSortOrder));
|
||||
List<UserResumeWork> resumeWorkList = resumeWorkMapper.selectList(
|
||||
new LambdaQueryWrapper<UserResumeWork>().eq(UserResumeWork::getResumeId, resumeId).orderByAsc(UserResumeWork::getSortOrder));
|
||||
List<UserResumeInternship> resumeInternshipList = resumeInternshipMapper.selectList(
|
||||
new LambdaQueryWrapper<UserResumeInternship>().eq(UserResumeInternship::getResumeId, resumeId).orderByAsc(UserResumeInternship::getSortOrder));
|
||||
List<UserResumeProject> resumeProjectList = resumeProjectMapper.selectList(
|
||||
new LambdaQueryWrapper<UserResumeProject>().eq(UserResumeProject::getResumeId, resumeId).orderByAsc(UserResumeProject::getSortOrder));
|
||||
List<UserResumeCompetition> resumeCompetitionList = resumeCompetitionMapper.selectList(
|
||||
new LambdaQueryWrapper<UserResumeCompetition>().eq(UserResumeCompetition::getResumeId, resumeId).orderByAsc(UserResumeCompetition::getSortOrder));
|
||||
|
||||
Instant now = Instant.now();
|
||||
|
||||
// 3. 同步主表(upsert,只更新共有字段,保留Profile独有字段原值)
|
||||
UserProfile existing = userProfileMapper.selectOne(
|
||||
new LambdaQueryWrapper<UserProfile>().eq(UserProfile::getUserId, userId));
|
||||
Long profileId;
|
||||
if (existing != null) {
|
||||
profileId = existing.getId();
|
||||
existing.setName(resume.getName());
|
||||
existing.setEmail(resume.getEmail());
|
||||
existing.setMobileNumber(resume.getMobileNumber());
|
||||
existing.setWechatNumber(resume.getWechatNumber());
|
||||
existing.setPortfolioUrl(resume.getPortfolioUrl());
|
||||
existing.setSkills(resume.getSkills());
|
||||
existing.setCertificates(resume.getCertificates());
|
||||
existing.setUpdateTime(now);
|
||||
userProfileMapper.updateById(existing);
|
||||
} else {
|
||||
UserProfile profile = new UserProfile();
|
||||
profile.setUserId(userId);
|
||||
profile.setName(resume.getName());
|
||||
profile.setEmail(resume.getEmail());
|
||||
profile.setMobileNumber(resume.getMobileNumber());
|
||||
profile.setWechatNumber(resume.getWechatNumber());
|
||||
profile.setPortfolioUrl(resume.getPortfolioUrl());
|
||||
profile.setSkills(resume.getSkills());
|
||||
profile.setCertificates(resume.getCertificates());
|
||||
profile.setCreateTime(now);
|
||||
profile.setUpdateTime(now);
|
||||
userProfileMapper.insert(profile);
|
||||
profileId = profile.getId();
|
||||
}
|
||||
|
||||
// 4. 同步教育经历(先删后插,含degree/studyType映射)
|
||||
educationMapper.delete(new LambdaQueryWrapper<UserProfileEducation>().eq(UserProfileEducation::getUserId, userId));
|
||||
if (!resumeEducationList.isEmpty()) {
|
||||
List<UserProfileEducation> profileEducationList = IntStream.range(0, resumeEducationList.size()).mapToObj(i -> {
|
||||
UserResumeEducation src = resumeEducationList.get(i);
|
||||
UserProfileEducation dest = new UserProfileEducation();
|
||||
dest.setProfileId(profileId);
|
||||
dest.setUserId(userId);
|
||||
dest.setSchool(src.getSchool());
|
||||
dest.setMajor(src.getMajor());
|
||||
dest.setDegree(DEGREE_MAP.get(src.getDegree()));
|
||||
dest.setStudyType(STUDY_TYPE_MAP.get(src.getStudyType()));
|
||||
dest.setStartDate(src.getStartDate());
|
||||
dest.setEndDate(src.getEndDate());
|
||||
dest.setDescription(src.getDescription());
|
||||
dest.setSortOrder(i);
|
||||
dest.setCreateTime(now);
|
||||
dest.setUpdateTime(now);
|
||||
return dest;
|
||||
}).collect(Collectors.toList());
|
||||
educationMapper.batchInsert(profileEducationList);
|
||||
}
|
||||
|
||||
// 5. 同步工作经历
|
||||
workMapper.delete(new LambdaQueryWrapper<UserProfileWork>().eq(UserProfileWork::getUserId, userId));
|
||||
if (!resumeWorkList.isEmpty()) {
|
||||
List<UserProfileWork> profileWorkList = IntStream.range(0, resumeWorkList.size()).mapToObj(i -> {
|
||||
UserResumeWork src = resumeWorkList.get(i);
|
||||
UserProfileWork dest = new UserProfileWork();
|
||||
dest.setProfileId(profileId);
|
||||
dest.setUserId(userId);
|
||||
dest.setCompanyName(src.getCompanyName());
|
||||
dest.setPosition(src.getPosition());
|
||||
dest.setStartDate(src.getStartDate());
|
||||
dest.setEndDate(src.getEndDate());
|
||||
dest.setDescription(src.getDescription());
|
||||
dest.setSortOrder(i);
|
||||
dest.setCreateTime(now);
|
||||
dest.setUpdateTime(now);
|
||||
return dest;
|
||||
}).collect(Collectors.toList());
|
||||
workMapper.batchInsert(profileWorkList);
|
||||
}
|
||||
|
||||
// 6. 同步实习经历
|
||||
internshipMapper.delete(new LambdaQueryWrapper<UserProfileInternship>().eq(UserProfileInternship::getUserId, userId));
|
||||
if (!resumeInternshipList.isEmpty()) {
|
||||
List<UserProfileInternship> profileInternshipList = IntStream.range(0, resumeInternshipList.size()).mapToObj(i -> {
|
||||
UserResumeInternship src = resumeInternshipList.get(i);
|
||||
UserProfileInternship dest = new UserProfileInternship();
|
||||
dest.setProfileId(profileId);
|
||||
dest.setUserId(userId);
|
||||
dest.setCompanyName(src.getCompanyName());
|
||||
dest.setPosition(src.getPosition());
|
||||
dest.setStartDate(src.getStartDate());
|
||||
dest.setEndDate(src.getEndDate());
|
||||
dest.setDescription(src.getDescription());
|
||||
dest.setSortOrder(i);
|
||||
dest.setCreateTime(now);
|
||||
dest.setUpdateTime(now);
|
||||
return dest;
|
||||
}).collect(Collectors.toList());
|
||||
internshipMapper.batchInsert(profileInternshipList);
|
||||
}
|
||||
|
||||
// 7. 同步项目经历
|
||||
projectMapper.delete(new LambdaQueryWrapper<UserProfileProject>().eq(UserProfileProject::getUserId, userId));
|
||||
if (!resumeProjectList.isEmpty()) {
|
||||
List<UserProfileProject> profileProjectList = IntStream.range(0, resumeProjectList.size()).mapToObj(i -> {
|
||||
UserResumeProject src = resumeProjectList.get(i);
|
||||
UserProfileProject dest = new UserProfileProject();
|
||||
dest.setProfileId(profileId);
|
||||
dest.setUserId(userId);
|
||||
dest.setCompanyName(src.getCompanyName());
|
||||
dest.setProjectName(src.getProjectName());
|
||||
dest.setRole(src.getRole());
|
||||
dest.setStartDate(src.getStartDate());
|
||||
dest.setEndDate(src.getEndDate());
|
||||
dest.setDescription(src.getDescription());
|
||||
dest.setSortOrder(i);
|
||||
dest.setCreateTime(now);
|
||||
dest.setUpdateTime(now);
|
||||
return dest;
|
||||
}).collect(Collectors.toList());
|
||||
projectMapper.batchInsert(profileProjectList);
|
||||
}
|
||||
|
||||
// 8. 同步竞赛经历
|
||||
competitionMapper.delete(new LambdaQueryWrapper<UserProfileCompetition>().eq(UserProfileCompetition::getUserId, userId));
|
||||
if (!resumeCompetitionList.isEmpty()) {
|
||||
List<UserProfileCompetition> profileCompetitionList = IntStream.range(0, resumeCompetitionList.size()).mapToObj(i -> {
|
||||
UserResumeCompetition src = resumeCompetitionList.get(i);
|
||||
UserProfileCompetition dest = new UserProfileCompetition();
|
||||
dest.setProfileId(profileId);
|
||||
dest.setUserId(userId);
|
||||
dest.setCompetitionName(src.getCompetitionName());
|
||||
dest.setAward(src.getAward());
|
||||
dest.setAwardDate(src.getAwardDate());
|
||||
dest.setDescription(src.getDescription());
|
||||
dest.setSortOrder(i);
|
||||
dest.setCreateTime(now);
|
||||
dest.setUpdateTime(now);
|
||||
return dest;
|
||||
}).collect(Collectors.toList());
|
||||
competitionMapper.batchInsert(profileCompetitionList);
|
||||
}
|
||||
|
||||
// 9. 事务内所有数据写入完成,触发一次异步AI分析
|
||||
userProfileAnalyzeService.analyzeUserProfile(userId);
|
||||
}
|
||||
|
||||
// ==================== 内部方法 ====================
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user