dev-tmp1
luotaiqian 2026-08-11 14:06:50 +08:00
parent 88172e0868
commit 1e48fb8cf3
2 changed files with 63 additions and 119 deletions

View File

@ -3,10 +3,8 @@ package org.qinan.safetyeval.app.support;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.validation.ValidationUtil;
import com.alibaba.excel.EasyExcel;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.jjb.saas.framework.core.utils.ValidatorUtils;
import com.jjb.saas.system.client.user.request.RoleDeptAddCmd;
import com.jjb.saas.system.client.user.request.UserAddCmd;
import com.zcloud.gbscommon.utils.MD5;
@ -34,10 +32,10 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
@ -61,12 +59,12 @@ public class OrgPersonnelExcelImporter {
private static final DateTimeFormatter SLASH_DATE_FORMATTER =
new DateTimeFormatterBuilder().appendPattern("yyyy/M/d").toFormatter();
/** 手机号格式11位纯数字、1开头 */
private static final String MOBILE_PHONE_REGEX = "^1\\d{10}$";
@Resource
private OrgDepartmentGateway orgDepartmentGateway;
@Resource
private javax.validation.Validator validator;
@Resource
private OrgPositionGateway orgPositionGateway;
@ -227,12 +225,12 @@ public class OrgPersonnelExcelImporter {
}
row.setRowIndex(i + 2);
// 账号(手机号)校验:必填、格式、文件内去重
if (!validateAccount(row, seenAccounts, errors)) {
// 字段校验JSR-303 注解(必填、长度、手机号格式)+ 身份证号 + 日期格式
if (!validateRowFields(row, errors)) {
continue;
}
// 字段级校验:必填、长度、格式
if (!validateRowFields(row, errors)) {
// 账号文件内去重
if (!checkAccountDuplicate(row, seenAccounts, errors)) {
continue;
}
rows.add(row);
@ -241,48 +239,13 @@ public class OrgPersonnelExcelImporter {
}
/**
*
*
* @param row
* @param seenAccounts
* @param errors
* @return true false
*/
private boolean validateAccount(OrgPersonnelImportRow row, Set<String> seenAccounts,
List<OrgPersonnelImportErrorCO> errors) {
Integer rowIndex = row.getRowIndex();
String account = trim(row.getAccount());
String userName = trim(row.getUserName());
// 账号必填DB: account NOT NULL
if (!StringUtils.hasText(account)) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "账号不能为空"));
return false;
}
// 手机号格式校验11位纯数字、1开头
if (!account.matches(MOBILE_PHONE_REGEX)) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
"手机号格式不正确应为11位数字且以1开头"));
return false;
}
// 文件内去重
if (!seenAccounts.add(account)) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
"账号在文件内重复,已剔除该行"));
return false;
}
return true;
}
/**
* /
* <p>
* {@code org_personnel}
* <ul>
* <li>NOT NULL user_nameaccount</li>
* <li>varchar </li>
* <li>/</li>
* </ul>
*
* <ol>
* <li>JSR-303 {@link OrgPersonnelImportRow} @NotBlank/@Size/@Pattern
* </li>
* <li>使 {@link IdcardUtil} </li>
* <li> yyyy-MM-dd / yyyy/M/d </li>
* </ol>
*
* @param row
* @param errors
@ -293,17 +256,21 @@ public class OrgPersonnelExcelImporter {
String account = trim(row.getAccount());
String userName = trim(row.getUserName());
// 姓名必填DB: user_name varchar(50) NOT NULL
if (!StringUtils.hasText(userName)) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "姓名不能为空"));
return false;
}
if (userName.length() > 50) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "姓名长度不能超过50个字符"));
// 1. JSR-303 注解校验:每字段仅取第一条违规,避免 @NotBlank+@Pattern 重复报错
Set<ConstraintViolation<OrgPersonnelImportRow>> violations = validator.validate(row);
if (!violations.isEmpty()) {
violations.stream()
.collect(Collectors.toMap(
v -> v.getPropertyPath().toString(),
v -> v,
(a, b) -> a))
.values()
.forEach(v -> errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
v.getMessage())));
return false;
}
// 身份证号可选格式校验DB: id_card_no varchar(18)
// 2. 身份证号格式校验DB: id_card_no varchar(18)
String idCardNo = trim(row.getIdCardNo());
if (StringUtils.hasText(idCardNo) && !IdcardUtil.isValidCard(idCardNo)) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
@ -311,22 +278,13 @@ public class OrgPersonnelExcelImporter {
return false;
}
// 性别名称最大10DB: gender_name varchar(10)
String gender = trim(row.getGender());
if (StringUtils.hasText(gender) && gender.length() > 10) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "性别长度不能超过10个字符"));
return false;
}
// 出生日期日期格式校验DB: birth_date date
// 3. 日期格式校验DB: birth_date / join_work_date date
String birthDate = trim(row.getBirthDate());
if (StringUtils.hasText(birthDate) && parseDate(birthDate) == null) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
"出生日期格式不正确应为yyyy-MM-dd或yyyy/M/d"));
return false;
}
// 参加工作时间日期格式校验DB: join_work_date date
String joinWorkDate = trim(row.getJoinWorkDate());
if (StringUtils.hasText(joinWorkDate) && parseDate(joinWorkDate) == null) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
@ -334,57 +292,25 @@ public class OrgPersonnelExcelImporter {
return false;
}
// 学历名称最大50DB: education_name varchar(50)
String education = trim(row.getEducation());
if (StringUtils.hasText(education) && education.length() > 50) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "学历长度不能超过50个字符"));
return true;
}
/**
*
*
* @param row
* @param seenAccounts
* @param errors
* @return true false
*/
private boolean checkAccountDuplicate(OrgPersonnelImportRow row, Set<String> seenAccounts,
List<OrgPersonnelImportErrorCO> errors) {
String account = trim(row.getAccount());
if (StringUtils.hasText(account) && !seenAccounts.add(account)) {
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), account, trim(row.getUserName()),
"账号在文件内重复,已剔除该行"));
return false;
}
// 毕业院校最大200DB: graduate_school varchar(200)
String graduateSchool = trim(row.getGraduateSchool());
if (StringUtils.hasText(graduateSchool) && graduateSchool.length() > 200) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "毕业院校长度不能超过200个字符"));
return false;
}
// 所学专业最大100DB: major varchar(100)
String major = trim(row.getMajor());
if (StringUtils.hasText(major) && major.length() > 100) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "所学专业长度不能超过100个字符"));
return false;
}
// 现住地址最大500DB: current_address varchar(500)
String currentAddress = trim(row.getCurrentAddress());
if (StringUtils.hasText(currentAddress) && currentAddress.length() > 500) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "现住地址长度不能超过500个字符"));
return false;
}
// 办公地址最大500DB: office_address varchar(500)
String officeAddress = trim(row.getOfficeAddress());
if (StringUtils.hasText(officeAddress) && officeAddress.length() > 500) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, "办公地址长度不能超过500个字符"));
return false;
}
// 出版学术专著等最大1000DB: publications varchar(1000)
String publications = trim(row.getPublications());
if (StringUtils.hasText(publications) && publications.length() > 1000) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
"出版学术专著等信息长度不能超过1000个字符"));
return false;
}
// 自我申报专业能力最大1000DB: ability_declaration varchar(1000)
String abilityDeclaration = trim(row.getAbilityDeclaration());
if (StringUtils.hasText(abilityDeclaration) && abilityDeclaration.length() > 1000) {
errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName,
"自我申报的专业能力信息长度不能超过1000个字符"));
return false;
}
return true;
}

View File

@ -5,6 +5,10 @@ import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import org.springframework.util.StringUtils;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
/**
* Excel
* <p>
@ -36,27 +40,37 @@ public class OrgPersonnelImportRow {
private String positionName;
@ExcelProperty(value = "账号", index = 4)
@NotBlank(message = "账号不能为空")
@Pattern(regexp = "^1\\d{10}$", message = "手机号格式不正确应为11位数字且以1开头")
@Size(max = 50, message = "账号长度不能超过50个字符")
private String account;
@ExcelProperty(value = "姓名", index = 5)
@NotBlank(message = "姓名不能为空")
@Size(max = 50, message = "姓名长度不能超过50个字符")
private String userName;
@ExcelProperty(value = "性别", index = 6)
@Size(max = 10, message = "性别长度不能超过10个字符")
private String gender;
@ExcelProperty(value = "出生日期", index = 7)
private String birthDate;
@ExcelProperty(value = "身份证号", index = 8)
@Size(max = 18, message = "身份证号长度不能超过18个字符")
private String idCardNo;
@ExcelProperty(value = "学历", index = 9)
@Size(max = 50, message = "学历长度不能超过50个字符")
private String education;
@ExcelProperty(value = "毕业院校", index = 10)
@Size(max = 200, message = "毕业院校长度不能超过200个字符")
private String graduateSchool;
@ExcelProperty(value = "所学专业", index = 11)
@Size(max = 100, message = "所学专业长度不能超过100个字符")
private String major;
@ExcelProperty(value = "职称", index = 12)
@ -69,18 +83,22 @@ public class OrgPersonnelImportRow {
private String registerEngineer;
@ExcelProperty(value = "现住地址", index = 15)
@Size(max = 500, message = "现住地址长度不能超过500个字符")
private String currentAddress;
@ExcelProperty(value = "办公地址", index = 16)
@Size(max = 500, message = "办公地址长度不能超过500个字符")
private String officeAddress;
@ExcelProperty(value = "主要学习工作经历", index = 17)
private String workExperience;
@ExcelProperty(value = "出版学术专著、专利、获奖、发表学术论文等", index = 18)
@Size(max = 1000, message = "出版学术专著等信息长度不能超过1000个字符")
private String publications;
@ExcelProperty(value = "自我申报的专业能力及认定方式", index = 19)
@Size(max = 1000, message = "自我申报的专业能力信息长度不能超过1000个字符")
private String abilityDeclaration;
/**