Merge branch 'refs/heads/master' into test
This commit is contained in:
@@ -10,6 +10,8 @@ import org.jiayunet.tool.UserSecurityTool;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronization;
|
||||||
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -369,12 +371,41 @@ public class UserProfileService {
|
|||||||
// ==================== 从简历同步到个人资料 ====================
|
// ==================== 从简历同步到个人资料 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据简历ID同步更新个人资料
|
* 根据简历ID同步更新个人资料(AI分析同步执行,阻塞至分析完成)
|
||||||
* <p>1. 校验简历归属 2. 读取简历主表+6子表 3. 事务内覆盖写入Profile主表+6子表 4. 同步执行一次AI分析</p>
|
* <p>1. 校验简历归属 2. 读取简历主表+6子表 3. 事务内覆盖写入Profile主表+6子表 4. 同步执行一次AI分析</p>
|
||||||
|
* <p>适用于前端需要拿到分析结果的场景(如简历上传解析后立即展示)</p>
|
||||||
*/
|
*/
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void syncProfileFromResume(Long resumeId) {
|
public void syncProfileFromResume(Long resumeId) {
|
||||||
Long userId = UserSecurityTool.getUserId();
|
Long userId = UserSecurityTool.getUserId();
|
||||||
|
copyResumeToProfile(userId, resumeId);
|
||||||
|
// 事务内所有数据写入完成,同步执行AI分析并等待完成
|
||||||
|
userProfileAnalyzeService.analyzeUserProfileSync(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据简历ID同步更新个人资料(AI分析异步执行,立即返回)
|
||||||
|
* <p>1. 校验简历归属 2. 读取简历主表+6子表 3. 事务内覆盖写入Profile主表+6子表 4. 事务提交后异步触发AI分析</p>
|
||||||
|
* <p>适用于同步只是副作用、不需要等待分析结果的场景(如设置默认简历)</p>
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void syncProfileFromResumeAsync(Long resumeId) {
|
||||||
|
Long userId = UserSecurityTool.getUserId();
|
||||||
|
copyResumeToProfile(userId, resumeId);
|
||||||
|
// AI分析必须等事务提交后再触发,否则异步线程读不到本次写入的数据
|
||||||
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||||
|
@Override
|
||||||
|
public void afterCommit() {
|
||||||
|
userProfileAnalyzeService.analyzeUserProfile(userId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将简历数据覆盖写入个人资料(主表+6子表),不触发AI分析
|
||||||
|
* <p>由 syncProfileFromResume / syncProfileFromResumeAsync 复用,须在事务内调用</p>
|
||||||
|
*/
|
||||||
|
private void copyResumeToProfile(Long userId, Long resumeId) {
|
||||||
|
|
||||||
// 1. 校验简历归属当前用户
|
// 1. 校验简历归属当前用户
|
||||||
UserResume resume = userResumeMapper.selectById(resumeId);
|
UserResume resume = userResumeMapper.selectById(resumeId);
|
||||||
@@ -557,9 +588,6 @@ public class UserProfileService {
|
|||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
organizationMapper.batchInsert(profileOrganizationList);
|
organizationMapper.batchInsert(profileOrganizationList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. 事务内所有数据写入完成,同步执行AI分析并等待完成
|
|
||||||
userProfileAnalyzeService.analyzeUserProfileSync(userId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 从个人资料生成简历 ====================
|
// ==================== 从个人资料生成简历 ====================
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ public class UserResumeService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private MemberUserMapper memberUserMapper;
|
private MemberUserMapper memberUserMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserProfileService userProfileService;
|
||||||
|
|
||||||
@Value("${app.resume.max-count:5}")
|
@Value("${app.resume.max-count:5}")
|
||||||
private int maxResumeCount;
|
private int maxResumeCount;
|
||||||
|
|
||||||
@@ -142,6 +145,10 @@ public class UserResumeService {
|
|||||||
.set(UserResume::getHobbies, resume.getHobbies())
|
.set(UserResume::getHobbies, resume.getHobbies())
|
||||||
.set(UserResume::getLanguageSkills, resume.getLanguageSkills())
|
.set(UserResume::getLanguageSkills, resume.getLanguageSkills())
|
||||||
.set(UserResume::getUpdateTime, now));
|
.set(UserResume::getUpdateTime, now));
|
||||||
|
// 默认简历即用户主简历,内容变更后同步覆盖个人资料;AI提取异步执行,不阻塞本次请求
|
||||||
|
if (Integer.valueOf(1).equals(existing.getIsDefault())) {
|
||||||
|
userProfileService.syncProfileFromResumeAsync(resumeId);
|
||||||
|
}
|
||||||
return resumeId;
|
return resumeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -742,7 +749,8 @@ public class UserResumeService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置默认简历
|
* 设置默认简历
|
||||||
* <p>1. 查询用户所有简历,无简历则报错 2. 校验resumeId存在于用户简历中 3. 全部置为非默认,目标简历置为默认</p>
|
* <p>1. 查询用户所有简历,无简历则报错 2. 校验resumeId存在于用户简历中 3. 全部置为非默认,目标简历置为默认
|
||||||
|
* 4. 将该简历同步到个人资料,AI提取在事务提交后异步执行</p>
|
||||||
*/
|
*/
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void setDefaultResume(Long resumeId) {
|
public void setDefaultResume(Long resumeId) {
|
||||||
@@ -759,6 +767,8 @@ public class UserResumeService {
|
|||||||
userResumeMapper.update(null, new LambdaUpdateWrapper<UserResume>().eq(UserResume::getUserId, userId).set(UserResume::getIsDefault, 0));
|
userResumeMapper.update(null, new LambdaUpdateWrapper<UserResume>().eq(UserResume::getUserId, userId).set(UserResume::getIsDefault, 0));
|
||||||
// 目标简历置为默认
|
// 目标简历置为默认
|
||||||
userResumeMapper.update(null, new LambdaUpdateWrapper<UserResume>().eq(UserResume::getId, resumeId).set(UserResume::getIsDefault, 1));
|
userResumeMapper.update(null, new LambdaUpdateWrapper<UserResume>().eq(UserResume::getId, resumeId).set(UserResume::getIsDefault, 1));
|
||||||
|
// 默认简历即用户主简历,同步覆盖个人资料;AI提取异步执行,不阻塞本次请求
|
||||||
|
userProfileService.syncProfileFromResumeAsync(resumeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user