sign
parent
61b0c76aa2
commit
daab31b998
|
|
@ -1,5 +1,7 @@
|
||||||
package org.qinan.safetyeval.app.support;
|
package org.qinan.safetyeval.app.support;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Pair;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.EasyExcel;
|
||||||
import com.jjb.saas.framework.auth.utils.AuthContext;
|
import com.jjb.saas.framework.auth.utils.AuthContext;
|
||||||
import com.jjb.saas.system.client.user.request.RoleDeptAddCmd;
|
import com.jjb.saas.system.client.user.request.RoleDeptAddCmd;
|
||||||
|
|
@ -27,6 +29,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
|
@ -83,6 +86,9 @@ public class OrgPersonnelExcelImporter {
|
||||||
private String orgRoleCode;
|
private String orgRoleCode;
|
||||||
|
|
||||||
public OrgPersonnelImportResultCO importPersonnel(MultipartFile file) {
|
public OrgPersonnelImportResultCO importPersonnel(MultipartFile file) {
|
||||||
|
OrgPersonnelImportResultCO result = new OrgPersonnelImportResultCO();
|
||||||
|
result.setSuccessCount(0);
|
||||||
|
|
||||||
if (file == null || file.isEmpty()) {
|
if (file == null || file.isEmpty()) {
|
||||||
throw new BizException(ErrorCode.FILE_UPLOAD_EMPTY);
|
throw new BizException(ErrorCode.FILE_UPLOAD_EMPTY);
|
||||||
}
|
}
|
||||||
|
|
@ -90,23 +96,35 @@ public class OrgPersonnelExcelImporter {
|
||||||
List<OrgPersonnelImportErrorCO> errors = new ArrayList<>();
|
List<OrgPersonnelImportErrorCO> errors = new ArrayList<>();
|
||||||
List<OrgPersonnelImportRow> rows = parseRows(file, errors);
|
List<OrgPersonnelImportRow> rows = parseRows(file, errors);
|
||||||
if (rows.isEmpty()) {
|
if (rows.isEmpty()) {
|
||||||
throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_EMPTY);
|
result.setErrors(errors);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Long orgId = ThreadLocalUserInfoAdapter.getOrgId();
|
Long orgId = ThreadLocalUserInfoAdapter.getOrgId();
|
||||||
|
|
||||||
OrgPersonnelImportResultCO result = new OrgPersonnelImportResultCO();
|
|
||||||
result.setSuccessCount(0);
|
|
||||||
result.setFailCount(0);
|
|
||||||
|
|
||||||
// 1. 批量校验并回填部门ID
|
// 1. 批量校验并回填部门ID
|
||||||
validateAndFillDept(rows, orgId);
|
validateAndFillDept(rows, orgId, errors);
|
||||||
|
rows = rows.stream().filter(it -> !it.isValidateFail()).collect(Collectors.toList());
|
||||||
|
if (rows.isEmpty()) {
|
||||||
|
result.setErrors(errors);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// 2. 批量校验并回填岗位ID
|
// 2. 批量校验并回填岗位ID
|
||||||
validateAndFillPosition(rows, orgId);
|
validateAndFillPosition(rows, orgId, errors);
|
||||||
|
rows = rows.stream().filter(it -> !it.isValidateFail()).collect(Collectors.toList());
|
||||||
|
if (rows.isEmpty()) {
|
||||||
|
result.setErrors(errors);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 批量校验并回填所学专业ID
|
// 3. 批量校验并回填所学专业ID
|
||||||
validateAndFillMajor(rows);
|
validateAndFillMajor(rows, errors);
|
||||||
|
rows = rows.stream().filter(it -> !it.isValidateFail()).collect(Collectors.toList());
|
||||||
|
if (rows.isEmpty()) {
|
||||||
|
result.setErrors(errors);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// 4. 批量查询库中已存在的账号(未删除)
|
// 4. 批量查询库中已存在的账号(未删除)
|
||||||
Set<String> existingAccounts = batchQueryExistingAccounts(rows, orgId);
|
Set<String> existingAccounts = batchQueryExistingAccounts(rows, orgId);
|
||||||
|
|
@ -142,7 +160,6 @@ public class OrgPersonnelExcelImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
result.setSuccessCount(successCount);
|
result.setSuccessCount(successCount);
|
||||||
result.setFailCount(errors.size());
|
|
||||||
result.setErrors(errors);
|
result.setErrors(errors);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -217,53 +234,175 @@ public class OrgPersonnelExcelImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量校验部门名称是否在当前机构下存在,校验通过的同时回填 deptId;不存在则抛出异常。
|
* 批量校验部门层级是否在当前机构下存在且层级关系正确。
|
||||||
|
* <p>
|
||||||
|
* 三级部门 -> 二级部门 -> 一级部门 逐级校验 parentId:
|
||||||
|
* <ul>
|
||||||
|
* <li>名称在机构下不存在的部门视为异常;</li>
|
||||||
|
* <li>任一相邻层级的 parentId 关系不匹配视为异常;</li>
|
||||||
|
* <li>全部校验通过后,取最底层(最深一级)不为空的部门 ID 作为 deptId 回填。</li>
|
||||||
|
* </ul>
|
||||||
*/
|
*/
|
||||||
private void validateAndFillDept(List<OrgPersonnelImportRow> rows, Long orgId) {
|
private void validateAndFillDept(List<OrgPersonnelImportRow> rows, Long orgId, List<OrgPersonnelImportErrorCO> errors) {
|
||||||
Set<String> deptNames = rows.stream()
|
// 收集所有层级中不为空的部门名称
|
||||||
.map(r -> trim(r.getDeptName()))
|
Set<String> deptNames = new LinkedHashSet<>();
|
||||||
.filter(StringUtils::hasText)
|
|
||||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
|
||||||
|
|
||||||
Map<String, OrgDepartmentEntity> deptMap = new HashMap<>();
|
|
||||||
if (!deptNames.isEmpty()) {
|
|
||||||
for (OrgDepartmentEntity dept : orgDepartmentGateway.listByOrgIdAndNames(orgId, deptNames)) {
|
|
||||||
if (dept.getDeptName() != null) {
|
|
||||||
deptMap.putIfAbsent(dept.getDeptName().trim(), dept);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 收集所有缺失部门(保留出现顺序,附带首个出现行号)
|
|
||||||
Map<String, Integer> missingDeptRows = new LinkedHashMap<>();
|
|
||||||
for (OrgPersonnelImportRow row : rows) {
|
for (OrgPersonnelImportRow row : rows) {
|
||||||
String name = trim(row.getDeptName());
|
row.setDeptNameLevel3(StrUtil.trim(row.getDeptNameLevel3()));
|
||||||
if (!StringUtils.hasText(name)) {
|
row.setDeptNameLevel2(StrUtil.trim(row.getDeptNameLevel2()));
|
||||||
missingDeptRows.putIfAbsent("(空)", row.getRowIndex());
|
row.setDeptNameLevel1(StrUtil.trim(row.getDeptNameLevel1()));
|
||||||
|
|
||||||
|
collectDeptName(deptNames, row.getDeptNameLevel1());
|
||||||
|
collectDeptName(deptNames, row.getDeptNameLevel2());
|
||||||
|
collectDeptName(deptNames, row.getDeptNameLevel3());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<OrgDepartmentEntity> orgDepartmentList = orgDepartmentGateway.listByOrgIdAndNames(orgId, deptNames);
|
||||||
|
Map<String, List<OrgDepartmentEntity>> nameMapList =
|
||||||
|
orgDepartmentList.stream().collect(Collectors.groupingBy(OrgDepartmentEntity::getDeptName));
|
||||||
|
for (OrgPersonnelImportRow row : rows) {
|
||||||
|
Pair<Boolean, OrgDepartmentEntity> l1 = getL1(errors, row, nameMapList);
|
||||||
|
if (!l1.getKey()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!deptMap.containsKey(name)) {
|
OrgDepartmentEntity l1Dept = l1.getValue();
|
||||||
missingDeptRows.putIfAbsent(name, row.getRowIndex());
|
Pair<Boolean, OrgDepartmentEntity> l2 = getL2(errors, row, nameMapList, l1Dept);
|
||||||
}
|
if (!l2.getKey() || l2.getValue() == null) {
|
||||||
}
|
continue;
|
||||||
if (!missingDeptRows.isEmpty()) {
|
|
||||||
String detail = missingDeptRows.entrySet().stream()
|
|
||||||
.map(e -> e.getKey() + "(第" + e.getValue() + "行)")
|
|
||||||
.collect(Collectors.joining("; "));
|
|
||||||
throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_NOT_FOUND,
|
|
||||||
ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_NOT_FOUND.getMessage() + ":" + detail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 校验通过,回填部门ID
|
getL3(errors, row, nameMapList, l2.getValue());
|
||||||
for (OrgPersonnelImportRow row : rows) {
|
|
||||||
row.setDeptId(deptMap.get(trim(row.getDeptName())).getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量校验岗位名称在所属部门下是否存在(dept_id + org_id),校验通过的同时回填 postId;不存在则抛出异常。
|
*
|
||||||
|
* @param errors errors
|
||||||
|
* @param row row
|
||||||
|
* @param nameMapList nameMapList
|
||||||
|
* @param l2Dept l2Dept
|
||||||
|
* @return Pair<Boolean, OrgDepartmentEntity> key 是否通过 true 通过 false 不通
|
||||||
|
* ;value (key =true ,value=null 说明没有二级部门)
|
||||||
*/
|
*/
|
||||||
private void validateAndFillPosition(List<OrgPersonnelImportRow> rows, Long orgId) {
|
private Pair<Boolean, OrgDepartmentEntity> getL3(List<OrgPersonnelImportErrorCO> errors, OrgPersonnelImportRow row
|
||||||
|
, Map<String, List<OrgDepartmentEntity>> nameMapList, OrgDepartmentEntity l2Dept) {
|
||||||
|
String l3 = row.getDeptNameLevel3();
|
||||||
|
if (StrUtil.isBlank(l3)) {
|
||||||
|
return Pair.of(true, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// l3 部门查询
|
||||||
|
List<OrgDepartmentEntity> departmentEntities = nameMapList.get(l3);
|
||||||
|
if (CollectionUtils.isEmpty(departmentEntities)) {
|
||||||
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L3_NOT_EXIST.getMessage()));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 三级部门
|
||||||
|
for (OrgDepartmentEntity departmentEntity : departmentEntities) {
|
||||||
|
if (departmentEntity.getDeptName().equals(l3)
|
||||||
|
&& departmentEntity.getParentId().compareTo(l2Dept.getId()) == 0) {
|
||||||
|
row.setDeptId(departmentEntity.getId());
|
||||||
|
return Pair.of(true, departmentEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
l2Dept.getDeptName() + "下"
|
||||||
|
+ ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L3_NOT_EXIST.getMessage()));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param errors errors
|
||||||
|
* @param row row
|
||||||
|
* @param nameMapList nameMapList
|
||||||
|
* @param l1Dept l1Dept
|
||||||
|
* @return Pair<Boolean, OrgDepartmentEntity> key 是否通过 true 通过 false 不通
|
||||||
|
* ;value (key =true ,value=null 说明没有二级部门)
|
||||||
|
*/
|
||||||
|
private Pair<Boolean, OrgDepartmentEntity> getL2(List<OrgPersonnelImportErrorCO> errors
|
||||||
|
, OrgPersonnelImportRow row, Map<String, List<OrgDepartmentEntity>> nameMapList, OrgDepartmentEntity l1Dept) {
|
||||||
|
String l2 = row.getDeptNameLevel2();
|
||||||
|
if (StrUtil.isBlank(l2)) {
|
||||||
|
return Pair.of(true, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// l2 部门查询
|
||||||
|
List<OrgDepartmentEntity> departmentEntities = nameMapList.get(l2);
|
||||||
|
if (CollectionUtils.isEmpty(departmentEntities)) {
|
||||||
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L2_NOT_EXIST.getMessage()));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 二级部门
|
||||||
|
for (OrgDepartmentEntity departmentEntity : departmentEntities) {
|
||||||
|
if (departmentEntity.getDeptName().equals(l2)
|
||||||
|
&& departmentEntity.getParentId().compareTo(l1Dept.getId()) == 0) {
|
||||||
|
row.setDeptId(departmentEntity.getId());
|
||||||
|
return Pair.of(true, departmentEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
l1Dept.getDeptName() + "下" + ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L2_NOT_EXIST.getMessage()));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param errors errors
|
||||||
|
* @param row row
|
||||||
|
* @param nameMapList nameMapList
|
||||||
|
* @return Pair<Boolean, String> key 是否通过 true 通过 false 不通
|
||||||
|
*/
|
||||||
|
private static Pair<Boolean, OrgDepartmentEntity> getL1(List<OrgPersonnelImportErrorCO> errors, OrgPersonnelImportRow row
|
||||||
|
, Map<String, List<OrgDepartmentEntity>> nameMapList) {
|
||||||
|
String l1 = row.getDeptNameLevel1();
|
||||||
|
if (StrUtil.isBlank(l1)) {
|
||||||
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L1_NOT_EXIST.getMessage()));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// l1 部门查询
|
||||||
|
List<OrgDepartmentEntity> departmentEntities = nameMapList.get(l1);
|
||||||
|
if (CollectionUtils.isEmpty(departmentEntities)) {
|
||||||
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L1_NOT_EXIST.getMessage()));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 一级部门重复
|
||||||
|
if (departmentEntities.size() > 1) {
|
||||||
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L1_REPEAT.getMessage()));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
return Pair.of(false, null);
|
||||||
|
}
|
||||||
|
row.setDeptId(departmentEntities.get(0).getId());
|
||||||
|
return Pair.of(false, departmentEntities.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectDeptName(Set<String> deptNames, String name) {
|
||||||
|
if (StringUtils.hasText(name)) {
|
||||||
|
deptNames.add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量校验岗位名称在所属部门下是否存在(dept_id + org_id),校验通过的同时回填 postId;
|
||||||
|
* 岗位名称为空或部门下岗位不存在的行,记录异常并标记 validateFail。
|
||||||
|
*/
|
||||||
|
private void validateAndFillPosition(List<OrgPersonnelImportRow> rows, Long orgId, List<OrgPersonnelImportErrorCO> errors) {
|
||||||
Set<Long> deptIds = new HashSet<>();
|
Set<Long> deptIds = new HashSet<>();
|
||||||
Set<String> positionNames = new HashSet<>();
|
Set<String> positionNames = new HashSet<>();
|
||||||
for (OrgPersonnelImportRow row : rows) {
|
for (OrgPersonnelImportRow row : rows) {
|
||||||
|
|
@ -285,43 +424,35 @@ public class OrgPersonnelExcelImporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收集缺失岗位
|
// 逐行校验:岗位名称为空或部门下岗位不存在 -> 记录异常并标记;校验通过则回填岗位ID
|
||||||
Map<String, Integer> missingPositionRows = new LinkedHashMap<>();
|
|
||||||
Map<String, String> missingDeptName = new LinkedHashMap<>();
|
|
||||||
for (OrgPersonnelImportRow row : rows) {
|
for (OrgPersonnelImportRow row : rows) {
|
||||||
String posName = trim(row.getPositionName());
|
String posName = trim(row.getPositionName());
|
||||||
if (!StringUtils.hasText(posName)) {
|
if (!StringUtils.hasText(posName)) {
|
||||||
missingPositionRows.putIfAbsent("(空)", row.getRowIndex());
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
missingDeptName.putIfAbsent("(空)", trim(row.getDeptName()));
|
ErrorCode.ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND.getMessage()
|
||||||
|
+ "(部门:" + row.getDeptDisplayName() + ")"));
|
||||||
|
row.setValidateFail(true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String key = row.getDeptId() + "|" + posName;
|
String key = row.getDeptId() + "|" + posName;
|
||||||
if (!positionMap.containsKey(key)) {
|
OrgPositionEntity pos = positionMap.get(key);
|
||||||
missingPositionRows.putIfAbsent(posName, row.getRowIndex());
|
if (pos == null) {
|
||||||
missingDeptName.putIfAbsent(posName, trim(row.getDeptName()));
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
|
ErrorCode.ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND.getMessage()
|
||||||
|
+ ":" + posName + "(部门:" + row.getDeptDisplayName() + ")"));
|
||||||
|
row.setValidateFail(true);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
row.setPostId(pos.getId());
|
||||||
if (!missingPositionRows.isEmpty()) {
|
|
||||||
String detail = missingPositionRows.entrySet().stream()
|
|
||||||
.map(e -> e.getKey() + "(部门:" + missingDeptName.get(e.getKey()) + ",第" + e.getValue() + "行)")
|
|
||||||
.collect(Collectors.joining("; "));
|
|
||||||
throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND,
|
|
||||||
ErrorCode.ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND.getMessage() + ":" + detail);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验通过,回填岗位ID
|
|
||||||
for (OrgPersonnelImportRow row : rows) {
|
|
||||||
String key = row.getDeptId() + "|" + trim(row.getPositionName());
|
|
||||||
row.setPostId(positionMap.get(key).getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量校验所学专业名称在基础学科专业对照表中是否存在(basic_discipline_major.professional_name),
|
* 批量校验所学专业名称在基础学科专业对照表中是否存在(basic_discipline_major.professional_name),
|
||||||
* 校验通过的同时回填 basicDisciplineMajorId;不存在则抛出异常。
|
* 校验通过的同时回填 basicDisciplineMajorId;不存在的行记录异常并标记 validateFail。
|
||||||
* <p>专业名称为空的行不参与校验(该字段可空)。</p>
|
* <p>专业名称为空的行不参与校验(该字段可空)。</p>
|
||||||
*/
|
*/
|
||||||
private void validateAndFillMajor(List<OrgPersonnelImportRow> rows) {
|
private void validateAndFillMajor(List<OrgPersonnelImportRow> rows, List<OrgPersonnelImportErrorCO> errors) {
|
||||||
Set<String> majorNames = rows.stream()
|
Set<String> majorNames = rows.stream()
|
||||||
.map(r -> trim(r.getMajor()))
|
.map(r -> trim(r.getMajor()))
|
||||||
.filter(StringUtils::hasText)
|
.filter(StringUtils::hasText)
|
||||||
|
|
@ -336,31 +467,20 @@ public class OrgPersonnelExcelImporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收集所有缺失专业(保留出现顺序,附带首个出现行号)
|
// 逐行校验:专业名称为空的行跳过;对照表中不存在的行记录异常并标记;校验通过则回填专业ID
|
||||||
Map<String, Integer> missingMajorRows = new LinkedHashMap<>();
|
|
||||||
for (OrgPersonnelImportRow row : rows) {
|
for (OrgPersonnelImportRow row : rows) {
|
||||||
String name = trim(row.getMajor());
|
String name = trim(row.getMajor());
|
||||||
if (!StringUtils.hasText(name)) {
|
if (!StringUtils.hasText(name)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!majorMap.containsKey(name)) {
|
BasicDisciplineMajorE major = majorMap.get(name);
|
||||||
missingMajorRows.putIfAbsent(name, row.getRowIndex());
|
if (major == null) {
|
||||||
}
|
errors.add(new OrgPersonnelImportErrorCO(row.getRowIndex(), row.getAccount(), row.getUserName(),
|
||||||
}
|
ErrorCode.ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND.getMessage() + ":" + name));
|
||||||
if (!missingMajorRows.isEmpty()) {
|
row.setValidateFail(true);
|
||||||
String detail = missingMajorRows.entrySet().stream()
|
continue;
|
||||||
.map(e -> e.getKey() + "(第" + e.getValue() + "行)")
|
|
||||||
.collect(Collectors.joining("; "));
|
|
||||||
throw new BizException(ErrorCode.ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND,
|
|
||||||
ErrorCode.ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND.getMessage() + ":" + detail);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 校验通过,回填专业ID
|
|
||||||
for (OrgPersonnelImportRow row : rows) {
|
|
||||||
String name = trim(row.getMajor());
|
|
||||||
if (StringUtils.hasText(name)) {
|
|
||||||
row.setBasicDisciplineMajorId(majorMap.get(name).getId());
|
|
||||||
}
|
}
|
||||||
|
row.setBasicDisciplineMajorId(major.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,19 @@ package org.qinan.safetyeval.app.support;
|
||||||
import com.alibaba.excel.annotation.ExcelIgnore;
|
import com.alibaba.excel.annotation.ExcelIgnore;
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 人员导入 Excel 行模型(按列下标映射,避免表头存在重名列)。
|
* 人员导入 Excel 行模型(按列下标映射,避免表头存在重名列)。
|
||||||
* <p>
|
* <p>
|
||||||
* 列顺序:部门 / 岗位 / 账号(手机号) / 姓名 / 性别 / 出生日期 / 身份证号 /
|
* 列顺序:一级部门 / 二级部门 / 三级部门 / 岗位 / 账号(手机号) / 姓名 / 性别 /
|
||||||
* 学历 / 毕业院校 / 所学专业 / 职称 / 参加工作时间 / 是否注册安全工程师 /
|
* 出生日期 / 身份证号 / 学历 / 毕业院校 / 所学专业 / 职称 / 参加工作时间 /
|
||||||
* 现住地址 / 办公地址 / 主要学习工作经历 / 出版学术专著、专利、获奖、发表学术论文等 /
|
* 是否注册安全工程师 / 现住地址 / 办公地址 / 主要学习工作经历 /
|
||||||
* 自我申报的专业能力及认定方式。
|
* 出版学术专著、专利、获奖、发表学术论文等 / 自我申报的专业能力及认定方式。
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* 部门按三级层级填写:一级部门为根,二级部门 parentId 指向一级部门,
|
||||||
|
* 三级部门 parentId 指向二级部门;导入时校验层级关系,取最底层不为空的一级作为 deptId。
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author safety-eval
|
* @author safety-eval
|
||||||
|
|
@ -18,73 +23,109 @@ import lombok.Data;
|
||||||
@Data
|
@Data
|
||||||
public class OrgPersonnelImportRow {
|
public class OrgPersonnelImportRow {
|
||||||
|
|
||||||
@ExcelProperty(value = "部门", index = 0)
|
@ExcelProperty(value = "一级部门", index = 0)
|
||||||
private String deptName;
|
private String deptNameLevel1;
|
||||||
|
|
||||||
@ExcelProperty(value = "岗位", index = 1)
|
@ExcelProperty(value = "二级部门", index = 1)
|
||||||
|
private String deptNameLevel2;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "三级部门", index = 2)
|
||||||
|
private String deptNameLevel3;
|
||||||
|
|
||||||
|
@ExcelProperty(value = "岗位", index = 3)
|
||||||
private String positionName;
|
private String positionName;
|
||||||
|
|
||||||
@ExcelProperty(value = "账号", index = 2)
|
@ExcelProperty(value = "账号", index = 4)
|
||||||
private String account;
|
private String account;
|
||||||
|
|
||||||
@ExcelProperty(value = "姓名", index = 3)
|
@ExcelProperty(value = "姓名", index = 5)
|
||||||
private String userName;
|
private String userName;
|
||||||
|
|
||||||
@ExcelProperty(value = "性别", index = 4)
|
@ExcelProperty(value = "性别", index = 6)
|
||||||
private String gender;
|
private String gender;
|
||||||
|
|
||||||
@ExcelProperty(value = "出生日期", index = 5)
|
@ExcelProperty(value = "出生日期", index = 7)
|
||||||
private String birthDate;
|
private String birthDate;
|
||||||
|
|
||||||
@ExcelProperty(value = "身份证号", index = 6)
|
@ExcelProperty(value = "身份证号", index = 8)
|
||||||
private String idCardNo;
|
private String idCardNo;
|
||||||
|
|
||||||
@ExcelProperty(value = "学历", index = 7)
|
@ExcelProperty(value = "学历", index = 9)
|
||||||
private String education;
|
private String education;
|
||||||
|
|
||||||
@ExcelProperty(value = "毕业院校", index = 8)
|
@ExcelProperty(value = "毕业院校", index = 10)
|
||||||
private String graduateSchool;
|
private String graduateSchool;
|
||||||
|
|
||||||
@ExcelProperty(value = "所学专业", index = 9)
|
@ExcelProperty(value = "所学专业", index = 11)
|
||||||
private String major;
|
private String major;
|
||||||
|
|
||||||
@ExcelProperty(value = "职称", index = 10)
|
@ExcelProperty(value = "职称", index = 12)
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
@ExcelProperty(value = "参加工作时间", index = 11)
|
@ExcelProperty(value = "参加工作时间", index = 13)
|
||||||
private String joinWorkDate;
|
private String joinWorkDate;
|
||||||
|
|
||||||
@ExcelProperty(value = "是否注册安全工程师", index = 12)
|
@ExcelProperty(value = "是否注册安全工程师", index = 14)
|
||||||
private String registerEngineer;
|
private String registerEngineer;
|
||||||
|
|
||||||
@ExcelProperty(value = "现住地址", index = 13)
|
@ExcelProperty(value = "现住地址", index = 15)
|
||||||
private String currentAddress;
|
private String currentAddress;
|
||||||
|
|
||||||
@ExcelProperty(value = "办公地址", index = 14)
|
@ExcelProperty(value = "办公地址", index = 16)
|
||||||
private String officeAddress;
|
private String officeAddress;
|
||||||
|
|
||||||
@ExcelProperty(value = "主要学习工作经历", index = 15)
|
@ExcelProperty(value = "主要学习工作经历", index = 17)
|
||||||
private String workExperience;
|
private String workExperience;
|
||||||
|
|
||||||
@ExcelProperty(value = "出版学术专著、专利、获奖、发表学术论文等", index = 16)
|
@ExcelProperty(value = "出版学术专著、专利、获奖、发表学术论文等", index = 18)
|
||||||
private String publications;
|
private String publications;
|
||||||
|
|
||||||
@ExcelProperty(value = "自我申报的专业能力及认定方式", index = 17)
|
@ExcelProperty(value = "自我申报的专业能力及认定方式", index = 19)
|
||||||
private String abilityDeclaration;
|
private String abilityDeclaration;
|
||||||
|
|
||||||
/** EasyExcel 解析时记录的物理行号(从1开始,含表头),由导入器填充。 */
|
/**
|
||||||
|
* EasyExcel 解析时记录的物理行号(从1开始,含表头),由导入器填充。
|
||||||
|
*/
|
||||||
@ExcelIgnore
|
@ExcelIgnore
|
||||||
private Integer rowIndex;
|
private Integer rowIndex;
|
||||||
|
|
||||||
/** 校验通过后回填的部门ID(非Excel列)。 */
|
/**
|
||||||
|
* 校验通过后回填的部门ID(非Excel列)。
|
||||||
|
*/
|
||||||
@ExcelIgnore
|
@ExcelIgnore
|
||||||
private Long deptId;
|
private Long deptId;
|
||||||
|
|
||||||
/** 校验通过后回填的岗位ID(非Excel列)。 */
|
/**
|
||||||
|
* 校验通过后回填的岗位ID(非Excel列)。
|
||||||
|
*/
|
||||||
@ExcelIgnore
|
@ExcelIgnore
|
||||||
private Long postId;
|
private Long postId;
|
||||||
|
|
||||||
/** 校验通过后回填的学科基础专业对照表ID(非Excel列)。 */
|
/**
|
||||||
|
* 校验通过后回填的学科基础专业对照表ID(非Excel列)。
|
||||||
|
*/
|
||||||
@ExcelIgnore
|
@ExcelIgnore
|
||||||
private Long basicDisciplineMajorId;
|
private Long basicDisciplineMajorId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验失败 true 失败 ,false 未失败
|
||||||
|
*/
|
||||||
|
@ExcelIgnore
|
||||||
|
private boolean validateFail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回最底层(最深一级)不为空的部门名称,用于错误提示。
|
||||||
|
*/
|
||||||
|
public String getDeptDisplayName() {
|
||||||
|
if (StringUtils.hasText(deptNameLevel3)) {
|
||||||
|
return deptNameLevel3.trim();
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(deptNameLevel2)) {
|
||||||
|
return deptNameLevel2.trim();
|
||||||
|
}
|
||||||
|
if (StringUtils.hasText(deptNameLevel1)) {
|
||||||
|
return deptNameLevel1.trim();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package org.qinan.safetyeval.client.co;
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -12,14 +13,18 @@ import java.util.List;
|
||||||
* @author safety-eval
|
* @author safety-eval
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
public class OrgPersonnelImportResultCO {
|
public class OrgPersonnelImportResultCO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "成功导入条数")
|
@ApiModelProperty(value = "成功导入条数")
|
||||||
private Integer successCount;
|
private Integer successCount;
|
||||||
|
|
||||||
@ApiModelProperty(value = "失败/跳过条数")
|
|
||||||
private Integer failCount;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "异常明细")
|
@ApiModelProperty(value = "异常明细")
|
||||||
private List<OrgPersonnelImportErrorCO> errors = new ArrayList<>();
|
private List<OrgPersonnelImportErrorCO> errors = new ArrayList<>();
|
||||||
|
|
||||||
|
public OrgPersonnelImportResultCO(Integer successCount, List<OrgPersonnelImportErrorCO> errors) {
|
||||||
|
this.successCount = successCount;
|
||||||
|
this.errors = errors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,14 @@ public enum ErrorCode {
|
||||||
ORG_PERSONNEL_IMPORT_EMPTY("01-05-007", "导入文件没有有效数据"),
|
ORG_PERSONNEL_IMPORT_EMPTY("01-05-007", "导入文件没有有效数据"),
|
||||||
ORG_PERSONNEL_IMPORT_PARSE_ERROR("01-05-008", "导入文件解析失败"),
|
ORG_PERSONNEL_IMPORT_PARSE_ERROR("01-05-008", "导入文件解析失败"),
|
||||||
ORG_PERSONNEL_IMPORT_DEPT_NOT_FOUND("01-05-009", "导入文件中存在不存在的部门"),
|
ORG_PERSONNEL_IMPORT_DEPT_NOT_FOUND("01-05-009", "导入文件中存在不存在的部门"),
|
||||||
|
ORG_PERSONNEL_IMPORT_DEPT_HIERARCHY_INVALID("01-05-012", "导入文件中部门层级关系不匹配"),
|
||||||
ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND("01-05-010", "导入文件中存在不存在的岗位"),
|
ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND("01-05-010", "导入文件中存在不存在的岗位"),
|
||||||
ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND("01-05-011", "导入文件中存在不存在的所学专业"),
|
ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND("01-05-011", "导入文件中存在不存在的所学专业"),
|
||||||
|
ORG_PERSONNEL_IMPORT_DEPT_NOT_EXIST("01-05-013", "请填写部门名称"),
|
||||||
|
ORG_PERSONNEL_IMPORT_DEPT_L1_NOT_EXIST("01-05-014", "一级部门名称不存在"),
|
||||||
|
ORG_PERSONNEL_IMPORT_DEPT_L1_REPEAT("01-05-015", "一级部门名称查询到多个,请在部门目录去核验"),
|
||||||
|
ORG_PERSONNEL_IMPORT_DEPT_L2_NOT_EXIST("01-05-016", "二级部门名称不存在"),
|
||||||
|
ORG_PERSONNEL_IMPORT_DEPT_L3_NOT_EXIST("01-05-017", "三级部门名称不存在"),
|
||||||
|
|
||||||
// ---- 人员证书 ----
|
// ---- 人员证书 ----
|
||||||
ORG_PERSONNEL_CERT_NOT_FOUND("01-06-001", "人员证书不存在"),
|
ORG_PERSONNEL_CERT_NOT_FOUND("01-06-001", "人员证书不存在"),
|
||||||
|
|
|
||||||
|
|
@ -217,9 +217,9 @@ public class QualFilingChangeGatewayImpl implements QualFilingChangeGateway {
|
||||||
}
|
}
|
||||||
//备案人员证书
|
//备案人员证书
|
||||||
if (CollectionUtils.isEmpty(personnelCertEntities)) {
|
if (CollectionUtils.isEmpty(personnelCertEntities)) {
|
||||||
|
if (!CollectionUtils.isEmpty(personnelEntities)) {
|
||||||
List<Long> sourcePersonnelIds = personnelEntities
|
List<Long> sourcePersonnelIds = personnelEntities
|
||||||
.stream().map(QualFilingPersonnelChangeE::getSourcePersonnelId).collect(Collectors.toList());
|
.stream().map(QualFilingPersonnelChangeE::getSourcePersonnelId).collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(sourcePersonnelIds)) {
|
|
||||||
List<OrgPersonnelCertDO> orgPersonnelCertDOS = orgPersonnelCertMapper.selectList(new LambdaQueryWrapper<OrgPersonnelCertDO>()
|
List<OrgPersonnelCertDO> orgPersonnelCertDOS = orgPersonnelCertMapper.selectList(new LambdaQueryWrapper<OrgPersonnelCertDO>()
|
||||||
.in(OrgPersonnelCertDO::getPersonnelId, sourcePersonnelIds));
|
.in(OrgPersonnelCertDO::getPersonnelId, sourcePersonnelIds));
|
||||||
if (!CollectionUtils.isEmpty(orgPersonnelCertDOS)) {
|
if (!CollectionUtils.isEmpty(orgPersonnelCertDOS)) {
|
||||||
|
|
|
||||||
|
|
@ -240,8 +240,8 @@ public class QualFilingGatewayImpl implements QualFilingGateway {
|
||||||
}
|
}
|
||||||
//备案人员证书
|
//备案人员证书
|
||||||
if (CollectionUtils.isEmpty(personnelCertEntities)) {
|
if (CollectionUtils.isEmpty(personnelCertEntities)) {
|
||||||
|
if (!CollectionUtils.isEmpty(personnelEntities)) {
|
||||||
List<Long> sourcePersonnelIds = personnelEntities.stream().map(QualFilingPersonnelEntity::getSourcePersonnelId).collect(Collectors.toList());
|
List<Long> sourcePersonnelIds = personnelEntities.stream().map(QualFilingPersonnelEntity::getSourcePersonnelId).collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(sourcePersonnelIds)) {
|
|
||||||
List<OrgPersonnelCertDO> orgPersonnelCertDOS = orgPersonnelCertMapper.selectList(new LambdaQueryWrapper<OrgPersonnelCertDO>()
|
List<OrgPersonnelCertDO> orgPersonnelCertDOS = orgPersonnelCertMapper.selectList(new LambdaQueryWrapper<OrgPersonnelCertDO>()
|
||||||
.in(OrgPersonnelCertDO::getPersonnelId, sourcePersonnelIds));
|
.in(OrgPersonnelCertDO::getPersonnelId, sourcePersonnelIds));
|
||||||
if (!CollectionUtils.isEmpty(orgPersonnelCertDOS)) {
|
if (!CollectionUtils.isEmpty(orgPersonnelCertDOS)) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue