处理简历不在限制非空

This commit is contained in:
zk
2026-07-02 14:12:45 +08:00
parent 80af170d18
commit a915d709f4
8 changed files with 115 additions and 62 deletions
@@ -3,7 +3,7 @@ package org.jiayunet.pojo.param.resume;
import lombok.Data;
import org.jiayunet.pojo.vo.DescriptionParagraph;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.List;
/**
@@ -15,13 +15,15 @@ import java.util.List;
public class ResumeCompetitionParam {
/** 竞赛名称 */
@NotBlank(message = "竞赛名称不能为空")
@Size(max = 200, message = "竞赛名称长度不能超过200")
private String competitionName;
/** 获奖情况,如全国二等奖 */
@Size(max = 200, message = "获奖情况长度不能超过200")
private String award;
/** 获奖时间,格式:2023.07 */
@Size(max = 10, message = "获奖时间长度不能超过10")
private String awardDate;
/** 描述段落 */
@@ -3,7 +3,7 @@ package org.jiayunet.pojo.param.resume;
import lombok.Data;
import org.jiayunet.pojo.vo.DescriptionParagraph;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.List;
/**
@@ -15,22 +15,27 @@ import java.util.List;
public class ResumeEducationParam {
/** 学校名称 */
@NotBlank(message = "学校名称不能为空")
@Size(max = 100, message = "学校名称长度不能超过100")
private String school;
/** 专业 */
@Size(max = 100, message = "专业长度不能超过100")
private String major;
/** 学历:大专/本科/硕士/博士 */
@Size(max = 20, message = "学历长度不能超过20")
private String degree;
/** 学习形式:全日制/非全日制 */
@Size(max = 20, message = "学习形式长度不能超过20")
private String studyType;
/** 开始时间,格式:2023.09 */
@Size(max = 10, message = "开始时间长度不能超过10")
private String startDate;
/** 结束时间,格式:2024.06 */
@Size(max = 10, message = "结束时间长度不能超过10")
private String endDate;
/** 描述段落 */
@@ -3,7 +3,7 @@ package org.jiayunet.pojo.param.resume;
import lombok.Data;
import org.jiayunet.pojo.vo.DescriptionParagraph;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.List;
/**
@@ -15,18 +15,19 @@ import java.util.List;
public class ResumeInternshipParam {
/** 公司名称 */
@NotBlank(message = "公司名称不能为空")
@Size(max = 200, message = "公司名称长度不能超过200")
private String companyName;
/** 职位 */
@NotBlank(message = "职位不能为空")
@Size(max = 100, message = "职位长度不能超过100")
private String position;
/** 开始时间,格式:2023.06 */
@NotBlank(message = "开始时间不能为空")
@Size(max = 10, message = "开始时间长度不能超过10")
private String startDate;
/** 结束时间,格式:2023.09,至今则为空 */
@Size(max = 10, message = "结束时间长度不能超过10")
private String endDate;
/** 描述段落 */
@@ -2,6 +2,7 @@ package org.jiayunet.pojo.param.resume;
import lombok.Data;
import javax.validation.constraints.Size;
import java.util.List;
/**
@@ -16,30 +17,39 @@ public class ResumeParam {
private Long resumeId;
/** 简历名称 */
@Size(max = 100, message = "简历名称长度不能超过100")
private String resumeName;
/** 目标岗位 */
@Size(max = 100, message = "目标岗位长度不能超过100")
private String targetPosition;
/** 头像URL */
@Size(max = 500, message = "头像URL长度不能超过500")
private String avatarUrl;
/** 真实姓名 */
@Size(max = 50, message = "真实姓名长度不能超过50")
private String name;
/** 邮箱 */
@Size(max = 100, message = "邮箱长度不能超过100")
private String email;
/** 手机号码 */
@Size(max = 20, message = "手机号码长度不能超过20")
private String mobileNumber;
/** 所在城市 */
@Size(max = 50, message = "所在城市长度不能超过50")
private String city;
/** 微信号 */
@Size(max = 50, message = "微信号长度不能超过50")
private String wechatNumber;
/** 作品集链接 */
@Size(max = 500, message = "作品集链接长度不能超过500")
private String portfolioUrl;
/** 技能标签列表 */
@@ -3,7 +3,7 @@ package org.jiayunet.pojo.param.resume;
import lombok.Data;
import org.jiayunet.pojo.vo.DescriptionParagraph;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.List;
/**
@@ -15,20 +15,23 @@ import java.util.List;
public class ResumeProjectParam {
/** 所属公司 */
@Size(max = 200, message = "所属公司长度不能超过200")
private String companyName;
/** 项目名称 */
@NotBlank(message = "项目名称不能为空")
@Size(max = 200, message = "项目名称长度不能超过200")
private String projectName;
/** 担任角色 */
@Size(max = 100, message = "担任角色长度不能超过100")
private String role;
/** 开始时间,格式:2023.06 */
@NotBlank(message = "开始时间不能为空")
@Size(max = 10, message = "开始时间长度不能超过10")
private String startDate;
/** 结束时间,格式:2023.09,至今则为空 */
@Size(max = 10, message = "结束时间长度不能超过10")
private String endDate;
/** 描述段落 */
@@ -3,7 +3,7 @@ package org.jiayunet.pojo.param.resume;
import lombok.Data;
import org.jiayunet.pojo.vo.DescriptionParagraph;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.List;
/**
@@ -15,18 +15,19 @@ import java.util.List;
public class ResumeWorkParam {
/** 公司名称 */
@NotBlank(message = "公司名称不能为空")
@Size(max = 200, message = "公司名称长度不能超过200")
private String companyName;
/** 职位 */
@NotBlank(message = "职位不能为空")
@Size(max = 100, message = "职位长度不能超过100")
private String position;
/** 开始时间,格式:2023.06 */
@NotBlank(message = "开始时间不能为空")
@Size(max = 10, message = "开始时间长度不能超过10")
private String startDate;
/** 结束时间,格式:2023.09,至今则为空 */
@Size(max = 10, message = "结束时间长度不能超过10")
private String endDate;
/** 描述段落 */
@@ -341,15 +341,18 @@ public class UserProfileService {
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);
// A语义:严格镜像简历共有字段(含清空为null),与子表先删后插的镜像行为一致;
// idCard/regionCode及AI派生字段(schoolRank/majorIds等)为个人资料独有,不在同步范围
userProfileMapper.update(null, new com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper<UserProfile>()
.eq(UserProfile::getId, profileId)
.set(UserProfile::getName, resume.getName())
.set(UserProfile::getEmail, resume.getEmail())
.set(UserProfile::getMobileNumber, resume.getMobileNumber())
.set(UserProfile::getWechatNumber, resume.getWechatNumber())
.set(UserProfile::getPortfolioUrl, resume.getPortfolioUrl())
.set(UserProfile::getSkills, resume.getSkills(), JSON_TYPE_HANDLER)
.set(UserProfile::getCertificates, resume.getCertificates(), JSON_TYPE_HANDLER)
.set(UserProfile::getUpdateTime, now));
} else {
UserProfile profile = new UserProfile();
profile.setUserId(userId);
@@ -40,6 +40,9 @@ public class UserResumeService {
@Value("${app.resume.max-count:5}")
private int maxResumeCount;
/** JSON字段的TypeHandlerUpdateWrapper显式set时需指定,否则JSON字段不会正确序列化 */
private static final String JSON_TYPE_HANDLER = "typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler";
@Autowired
private UserResumeEducationMapper educationMapper;
@@ -115,16 +118,24 @@ public class UserResumeService {
userResumeMapper.insert(resume);
return resume.getId();
}
// 更新已有简历
// 更新已有简历(用户可编辑字段用LambdaUpdateWrapper显式set,允许清空为null,绕过全局update-strategy=not_null
UserResume existing = userResumeMapper.selectById(resumeId);
checkOwnership(existing);
resume.setId(resumeId);
resume.setUserId(userId);
resume.setCreateTime(existing.getCreateTime());
resume.setUpdateTime(now);
resume.setIsDefault(existing.getIsDefault());
resume.setSortOrder(existing.getSortOrder());
userResumeMapper.updateById(resume);
userResumeMapper.update(null, new LambdaUpdateWrapper<UserResume>()
.eq(UserResume::getId, resumeId)
.set(UserResume::getResumeName, resume.getResumeName())
.set(UserResume::getTargetPosition, resume.getTargetPosition())
.set(UserResume::getAvatarUrl, resume.getAvatarUrl())
.set(UserResume::getName, resume.getName())
.set(UserResume::getEmail, resume.getEmail())
.set(UserResume::getMobileNumber, resume.getMobileNumber())
.set(UserResume::getCity, resume.getCity())
.set(UserResume::getWechatNumber, resume.getWechatNumber())
.set(UserResume::getPortfolioUrl, resume.getPortfolioUrl())
.set(UserResume::getSkills, resume.getSkills(), JSON_TYPE_HANDLER)
.set(UserResume::getCertificates, resume.getCertificates(), JSON_TYPE_HANDLER)
.set(UserResume::getSummary, resume.getSummary())
.set(UserResume::getUpdateTime, now));
return resumeId;
}
@@ -491,12 +502,17 @@ public class UserResumeService {
UserResumeEducation existing = educationMapper.selectById(po.getId());
Assert.notNull(existing, "教育经历不存在");
checkResumeOwnership(existing.getResumeId());
po.setResumeId(existing.getResumeId());
po.setUserId(existing.getUserId());
po.setSortOrder(existing.getSortOrder());
po.setCreateTime(existing.getCreateTime());
po.setUpdateTime(Instant.now());
educationMapper.updateById(po);
// 显式set用户可编辑字段(允许清空为null);resumeId/userId/sortOrder/createTime保留原值
educationMapper.update(null, new LambdaUpdateWrapper<UserResumeEducation>()
.eq(UserResumeEducation::getId, po.getId())
.set(UserResumeEducation::getSchool, po.getSchool())
.set(UserResumeEducation::getMajor, po.getMajor())
.set(UserResumeEducation::getDegree, po.getDegree())
.set(UserResumeEducation::getStudyType, po.getStudyType())
.set(UserResumeEducation::getStartDate, po.getStartDate())
.set(UserResumeEducation::getEndDate, po.getEndDate())
.set(UserResumeEducation::getDescription, po.getDescription(), JSON_TYPE_HANDLER)
.set(UserResumeEducation::getUpdateTime, Instant.now()));
touchResumeUpdateTime(existing.getResumeId());
}
@@ -509,12 +525,15 @@ public class UserResumeService {
UserResumeWork existing = workMapper.selectById(po.getId());
Assert.notNull(existing, "工作经历不存在");
checkResumeOwnership(existing.getResumeId());
po.setResumeId(existing.getResumeId());
po.setUserId(existing.getUserId());
po.setSortOrder(existing.getSortOrder());
po.setCreateTime(existing.getCreateTime());
po.setUpdateTime(Instant.now());
workMapper.updateById(po);
// 显式set用户可编辑字段(允许清空为null);resumeId/userId/sortOrder/createTime保留原值
workMapper.update(null, new LambdaUpdateWrapper<UserResumeWork>()
.eq(UserResumeWork::getId, po.getId())
.set(UserResumeWork::getCompanyName, po.getCompanyName())
.set(UserResumeWork::getPosition, po.getPosition())
.set(UserResumeWork::getStartDate, po.getStartDate())
.set(UserResumeWork::getEndDate, po.getEndDate())
.set(UserResumeWork::getDescription, po.getDescription(), JSON_TYPE_HANDLER)
.set(UserResumeWork::getUpdateTime, Instant.now()));
touchResumeUpdateTime(existing.getResumeId());
}
@@ -527,12 +546,15 @@ public class UserResumeService {
UserResumeInternship existing = internshipMapper.selectById(po.getId());
Assert.notNull(existing, "实习经历不存在");
checkResumeOwnership(existing.getResumeId());
po.setResumeId(existing.getResumeId());
po.setUserId(existing.getUserId());
po.setSortOrder(existing.getSortOrder());
po.setCreateTime(existing.getCreateTime());
po.setUpdateTime(Instant.now());
internshipMapper.updateById(po);
// 显式set用户可编辑字段(允许清空为null);resumeId/userId/sortOrder/createTime保留原值
internshipMapper.update(null, new LambdaUpdateWrapper<UserResumeInternship>()
.eq(UserResumeInternship::getId, po.getId())
.set(UserResumeInternship::getCompanyName, po.getCompanyName())
.set(UserResumeInternship::getPosition, po.getPosition())
.set(UserResumeInternship::getStartDate, po.getStartDate())
.set(UserResumeInternship::getEndDate, po.getEndDate())
.set(UserResumeInternship::getDescription, po.getDescription(), JSON_TYPE_HANDLER)
.set(UserResumeInternship::getUpdateTime, Instant.now()));
touchResumeUpdateTime(existing.getResumeId());
}
@@ -545,12 +567,16 @@ public class UserResumeService {
UserResumeProject existing = projectMapper.selectById(po.getId());
Assert.notNull(existing, "项目经历不存在");
checkResumeOwnership(existing.getResumeId());
po.setResumeId(existing.getResumeId());
po.setUserId(existing.getUserId());
po.setSortOrder(existing.getSortOrder());
po.setCreateTime(existing.getCreateTime());
po.setUpdateTime(Instant.now());
projectMapper.updateById(po);
// 显式set用户可编辑字段(允许清空为null);resumeId/userId/sortOrder/createTime保留原值
projectMapper.update(null, new LambdaUpdateWrapper<UserResumeProject>()
.eq(UserResumeProject::getId, po.getId())
.set(UserResumeProject::getCompanyName, po.getCompanyName())
.set(UserResumeProject::getProjectName, po.getProjectName())
.set(UserResumeProject::getRole, po.getRole())
.set(UserResumeProject::getStartDate, po.getStartDate())
.set(UserResumeProject::getEndDate, po.getEndDate())
.set(UserResumeProject::getDescription, po.getDescription(), JSON_TYPE_HANDLER)
.set(UserResumeProject::getUpdateTime, Instant.now()));
touchResumeUpdateTime(existing.getResumeId());
}
@@ -563,12 +589,14 @@ public class UserResumeService {
UserResumeCompetition existing = competitionMapper.selectById(po.getId());
Assert.notNull(existing, "竞赛经历不存在");
checkResumeOwnership(existing.getResumeId());
po.setResumeId(existing.getResumeId());
po.setUserId(existing.getUserId());
po.setSortOrder(existing.getSortOrder());
po.setCreateTime(existing.getCreateTime());
po.setUpdateTime(Instant.now());
competitionMapper.updateById(po);
// 显式set用户可编辑字段(允许清空为null);resumeId/userId/sortOrder/createTime保留原值
competitionMapper.update(null, new LambdaUpdateWrapper<UserResumeCompetition>()
.eq(UserResumeCompetition::getId, po.getId())
.set(UserResumeCompetition::getCompetitionName, po.getCompetitionName())
.set(UserResumeCompetition::getAward, po.getAward())
.set(UserResumeCompetition::getAwardDate, po.getAwardDate())
.set(UserResumeCompetition::getDescription, po.getDescription(), JSON_TYPE_HANDLER)
.set(UserResumeCompetition::getUpdateTime, Instant.now()));
touchResumeUpdateTime(existing.getResumeId());
}