iwork 人员组织同步相关

This commit is contained in:
chenbowen
2025-11-25 23:26:26 +08:00
parent dc1db47d07
commit f754b1c694
5 changed files with 118 additions and 80 deletions

View File

@@ -5,11 +5,10 @@ import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.zt.plat.module.system.service.integration.iwork.jackson.LenientIntegerDeserializer;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import com.zt.plat.module.system.service.integration.iwork.jackson.LenientIntegerDeserializer;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
@@ -31,6 +30,72 @@ public class IWorkHrDepartmentPageRespVO {
@Schema(description = "是否成功")
private boolean success;
@Schema(description = "iWork 返回的数据体")
@JsonProperty("data")
private PageData data;
@JsonIgnore
public Integer getTotalSize() {
return data == null ? null : data.getTotalSize();
}
@JsonIgnore
public void setTotalSize(Integer totalSize) {
ensureData().setTotalSize(totalSize);
}
@JsonIgnore
public Integer getTotalPage() {
return data == null ? null : data.getTotalPage();
}
@JsonIgnore
public void setTotalPage(Integer totalPage) {
ensureData().setTotalPage(totalPage);
}
@JsonIgnore
public Integer getPageSize() {
return data == null ? null : data.getPageSize();
}
@JsonIgnore
public void setPageSize(Integer pageSize) {
ensureData().setPageSize(pageSize);
}
@JsonIgnore
public Integer getPageNumber() {
return data == null ? null : data.getPageNumber();
}
@JsonIgnore
public void setPageNumber(Integer pageNumber) {
ensureData().setPageNumber(pageNumber);
}
@JsonIgnore
public List<Department> getDataList() {
return data == null ? null : data.getDataList();
}
@JsonIgnore
public void setDataList(List<Department> dataList) {
ensureData().setDataList(dataList);
}
@JsonIgnore
private PageData ensureData() {
if (data == null) {
data = new PageData();
}
return data;
}
@Data
@Schema(description = "iWork 部门分页数据体")
public static class PageData {
@Schema(description = "总条数")
private Integer totalSize;
@@ -41,10 +106,13 @@ public class IWorkHrDepartmentPageRespVO {
private Integer pageSize;
@Schema(description = "当前页码")
@JsonProperty("page")
private Integer pageNumber;
@Schema(description = "部门数据列表")
@JsonProperty("dataList")
private List<Department> dataList;
}
@Data
@Schema(description = "部门信息")
@@ -52,8 +120,14 @@ public class IWorkHrDepartmentPageRespVO {
@Schema(description = "部门 ID")
@JsonProperty("departmentid")
@JsonDeserialize(using = LenientIntegerDeserializer.class)
private Integer departmentid;
@Schema(description = "部门 IDiWork 主键)")
@JsonProperty("id")
@JsonDeserialize(using = LenientIntegerDeserializer.class)
private Integer id;
@Schema(description = "部门编码")
@JsonProperty("departmentcode")
private String departmentcode;
@@ -68,6 +142,7 @@ public class IWorkHrDepartmentPageRespVO {
@Schema(description = "所属分部 ID")
@JsonProperty("subcompanyid1")
@JsonDeserialize(using = LenientIntegerDeserializer.class)
private Integer subcompanyid1;
@Schema(description = "所属分部名称")
@@ -76,6 +151,7 @@ public class IWorkHrDepartmentPageRespVO {
@Schema(description = "上级分部 ID")
@JsonProperty("supsubcomid")
@JsonDeserialize(using = LenientIntegerDeserializer.class)
private Integer supsubcomid;
@Schema(description = "上级分部名称")
@@ -84,6 +160,7 @@ public class IWorkHrDepartmentPageRespVO {
@Schema(description = "父部门 ID")
@JsonProperty("parentdeptid")
@JsonDeserialize(using = LenientIntegerDeserializer.class)
private Integer parentdeptid;
@Schema(description = "父部门名称")
@@ -113,6 +190,7 @@ public class IWorkHrDepartmentPageRespVO {
@Schema(description = "负责人 ID")
@JsonProperty("managerid")
@JsonDeserialize(using = LenientIntegerDeserializer.class)
private Integer managerid;
@Schema(description = "负责人名称")

View File

@@ -189,7 +189,7 @@ public class DeptServiceImpl implements DeptService {
// 2. 父部门不存在
DeptDO parentDept = deptMapper.selectById(parentId);
if (parentDept == null) {
throw exception(DEPT_PARENT_NOT_EXITS);
return;
}
// 3. 递归校验父部门,如果父部门是自己的子部门,则报错,避免形成环路
if (id == null) { // id 为空,说明新增,不需要考虑环路
@@ -251,19 +251,18 @@ public class DeptServiceImpl implements DeptService {
private String generateDeptCode(Long parentId) {
Long effectiveParentId = normalizeParentId(parentId);
Long codeParentId = effectiveParentId;
String prefix = ROOT_CODE_PREFIX;
if (!DeptDO.PARENT_ID_ROOT.equals(effectiveParentId)) {
DeptDO parentDept = deptMapper.selectById(effectiveParentId);
if (parentDept == null) {
throw exception(DEPT_PARENT_NOT_EXITS);
}
if (StrUtil.isBlank(parentDept.getCode())) {
throw exception(DEPT_PARENT_CODE_NOT_INITIALIZED);
}
if (parentDept == null || StrUtil.isBlank(parentDept.getCode())) {
codeParentId = DeptDO.PARENT_ID_ROOT;
} else {
prefix = parentDept.getCode();
}
}
int nextSequence = determineNextSequence(effectiveParentId, prefix);
int nextSequence = determineNextSequence(codeParentId, prefix);
assertSequenceRange(nextSequence);
return prefix + formatSequence(nextSequence);
}

View File

@@ -53,7 +53,6 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
private final AdminUserService adminUserService;
private final AdminUserMapper adminUserMapper;
private final Map<Long, Boolean> deptPresenceCache = new ConcurrentHashMap<>();
private final Map<String, PostDO> postCache = new ConcurrentHashMap<>();
@Override
@@ -86,9 +85,6 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
Long deptId = externalId.longValue();
ParentHolder parentHolder = resolveSubcompanyParent(sub.getSupsubcomid());
if (parentHolder.required() && parentHolder.parentId() == null) {
continue;
}
boolean canceled = isCanceledFlag(sub.getCanceled());
DeptSaveReqVO saveReq = buildSubcompanySaveReq(sub, deptId, parentHolder.parentId(), canceled);
try {
@@ -139,7 +135,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
iterator.remove();
continue;
}
Integer externalId = dept.getDepartmentid();
Integer externalId = dept.getId();
if (externalId == null) {
log.warn("[iWork] 部门缺少标识,跳过:{}", dept.getDepartmentname());
result.increaseFailed();
@@ -148,9 +144,6 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
Long deptId = externalId.longValue();
ParentHolder parentHolder = resolveDepartmentParent(dept);
if (parentHolder.required() && parentHolder.parentId() == null) {
continue;
}
boolean canceled = isCanceledFlag(dept.getCanceled());
DeptSaveReqVO saveReq = buildDepartmentSaveReq(dept, deptId, parentHolder.parentId(), canceled);
try {
@@ -160,7 +153,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
options);
applyDeptOutcome(result, outcome, "部门", dept.getDepartmentname());
} catch (Exception ex) {
log.error("[iWork] 同步部门失败: id={} name={}", dept.getDepartmentid(), dept.getDepartmentname(), ex);
log.error("[iWork] 同步部门失败: id={} name={}", dept.getId(), dept.getDepartmentname(), ex);
result.increaseFailed();
result.withMessage("同步部门失败: " + ex.getMessage());
}
@@ -173,7 +166,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
if (!queue.isEmpty()) {
for (IWorkHrDepartmentPageRespVO.Department remaining : queue) {
log.warn("[iWork] 部门因父级缺失未同步: id={} name={}", remaining.getDepartmentid(), remaining.getDepartmentname());
log.warn("[iWork] 部门因父级缺失未同步: id={} name={}", remaining.getId(), remaining.getDepartmentname());
result.increaseFailed();
}
}
@@ -293,7 +286,6 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
desired.setId(deptId);
Long createdId = deptService.createDept(desired);
markDeptExists(createdId);
return new DeptSyncOutcome(SyncAction.CREATED, CommonStatusEnum.isDisable(desired.getStatus()), createdId);
}
if (!Objects.equals(existing.getDeptSource(), DeptSourceEnum.IWORK.getSource())) {
@@ -306,7 +298,6 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
mergeDeptDefaults(desired, existing);
boolean disabledChanged = disabled && CommonStatusEnum.isEnable(existing.getStatus());
deptService.updateDept(desired);
markDeptExists(existing.getId());
return new DeptSyncOutcome(SyncAction.UPDATED, disabledChanged, existing.getId());
}
@@ -456,52 +447,21 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
private ParentHolder resolveSubcompanyParent(Integer parentExternalId) {
if (parentExternalId == null || parentExternalId <= 0) {
return new ParentHolder(DeptDO.PARENT_ID_ROOT, false);
return new ParentHolder(DeptDO.PARENT_ID_ROOT);
}
Long parentId = parentExternalId.longValue();
if (hasDept(parentId)) {
return new ParentHolder(parentId, true);
}
return new ParentHolder(null, true);
return new ParentHolder(parentExternalId.longValue());
}
private ParentHolder resolveDepartmentParent(IWorkHrDepartmentPageRespVO.Department dept) {
Integer parentDeptId = dept.getParentdeptid();
if (parentDeptId != null && parentDeptId > 0) {
Long parentId = parentDeptId.longValue();
if (hasDept(parentId)) {
return new ParentHolder(parentId, true);
Long parentDeptId = toLong(dept.getParentdeptid());
if (parentDeptId != null) {
return new ParentHolder(parentDeptId);
}
return new ParentHolder(null, true);
}
Integer subcompanyId = dept.getSubcompanyid1();
if (subcompanyId != null && subcompanyId > 0) {
Long parentId = subcompanyId.longValue();
if (hasDept(parentId)) {
return new ParentHolder(parentId, true);
}
return new ParentHolder(null, true);
}
return new ParentHolder(DeptDO.PARENT_ID_ROOT, false);
}
private boolean hasDept(Long deptId) {
if (deptId == null) {
return false;
}
Boolean cached = deptPresenceCache.get(deptId);
if (cached != null) {
return cached;
}
boolean exists = deptService.getDept(deptId) != null;
deptPresenceCache.put(deptId, exists);
return exists;
}
private void markDeptExists(Long deptId) {
if (deptId != null) {
deptPresenceCache.put(deptId, true);
Long subcompanyId = toLong(dept.getSubcompanyid1());
if (subcompanyId != null) {
return new ParentHolder(subcompanyId);
}
return new ParentHolder(DeptDO.PARENT_ID_ROOT);
}
private PostDO resolvePostByCode(String code) {
@@ -519,11 +479,11 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
private Long resolveUserDeptId(IWorkHrUserPageRespVO.User user) {
Long deptId = toLong(user.getDepartmentid());
if (deptId != null && hasDept(deptId)) {
if (deptId != null) {
return deptId;
}
Long subcompanyId = toLong(user.getSubcompanyid1());
if (subcompanyId != null && hasDept(subcompanyId)) {
if (subcompanyId != null) {
return subcompanyId;
}
return null;
@@ -709,7 +669,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
};
}
private record ParentHolder(Long parentId, boolean required) {
private record ParentHolder(Long parentId) {
}
private enum SyncAction {

View File

@@ -38,18 +38,21 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
respVO.setBatches(batchStats);
Set<IWorkSyncEntityTypeEnum> scopes = reqVO.resolveScopes();
boolean syncUsers = scopes.contains(IWorkSyncEntityTypeEnum.USER);
boolean syncDepartments = scopes.contains(IWorkSyncEntityTypeEnum.DEPARTMENT) || syncUsers;
boolean syncSubcompanies = scopes.contains(IWorkSyncEntityTypeEnum.SUBCOMPANY) || syncDepartments;
int processedPages = 0;
IWorkSyncProcessor.SyncOptions options = buildFullSyncOptions(reqVO);
if (scopes.contains(IWorkSyncEntityTypeEnum.SUBCOMPANY)) {
if (syncSubcompanies) {
processedPages += executeSubcompanyFullSync(reqVO, options, respVO.getSubcompanyStat(), batchStats);
}
if (scopes.contains(IWorkSyncEntityTypeEnum.DEPARTMENT)) {
if (syncDepartments) {
processedPages += executeDepartmentFullSync(reqVO, options, respVO.getDepartmentStat(), batchStats);
}
if (scopes.contains(IWorkSyncEntityTypeEnum.JOB_TITLE)) {
processedPages += executeJobTitleFullSync(reqVO, options, respVO.getJobTitleStat(), batchStats);
}
if (scopes.contains(IWorkSyncEntityTypeEnum.USER)) {
if (syncUsers) {
processedPages += executeUserFullSync(reqVO, options, respVO.getUserStat(), batchStats);
}
respVO.setProcessedPages(processedPages);

View File

@@ -523,8 +523,6 @@ public class AdminUserServiceImpl implements AdminUserService {
validateMobileUnique(id, mobile);
// 校验邮箱唯一
validateEmailUnique(id, email);
// 校验部门处于开启状态
deptService.validateDeptList(deptIds);
// 校验岗位处于开启状态
postService.validatePostList(postIds);
return user;