iwork 人员组织同步相关

This commit is contained in:
chenbowen
2025-11-25 20:31:56 +08:00
parent 6c8c479984
commit dc1db47d07

View File

@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.zt.plat.framework.common.enums.CommonStatusEnum;
import com.zt.plat.framework.tenant.core.context.TenantContextHolder;
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.DeptExternalCodeSaveReqVO;
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
import com.zt.plat.module.system.controller.admin.dept.vo.post.PostSaveReqVO;
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkHrDepartmentPageRespVO;
@@ -13,7 +12,6 @@ import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkHrSu
import com.zt.plat.module.system.controller.admin.integration.iwork.vo.IWorkHrUserPageRespVO;
import com.zt.plat.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
import com.zt.plat.module.system.dal.dataobject.dept.DeptExternalCodeDO;
import com.zt.plat.module.system.dal.dataobject.dept.PostDO;
import com.zt.plat.module.system.dal.dataobject.user.AdminUserDO;
import com.zt.plat.module.system.dal.mysql.dept.PostMapper;
@@ -21,7 +19,6 @@ import com.zt.plat.module.system.dal.mysql.user.AdminUserMapper;
import com.zt.plat.module.system.enums.common.SexEnum;
import com.zt.plat.module.system.enums.dept.DeptSourceEnum;
import com.zt.plat.module.system.enums.user.UserSourceEnum;
import com.zt.plat.module.system.service.dept.DeptExternalCodeService;
import com.zt.plat.module.system.service.dept.DeptService;
import com.zt.plat.module.system.service.dept.PostService;
import com.zt.plat.module.system.service.integration.iwork.IWorkSyncProcessor;
@@ -46,20 +43,17 @@ import java.util.concurrent.ConcurrentHashMap;
@RequiredArgsConstructor
public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
private static final String SYSTEM_CODE_SUBCOMPANY = "IWORK_SUBCOMPANY";
private static final String SYSTEM_CODE_DEPARTMENT = "IWORK_DEPARTMENT";
private static final String JOB_CODE_PREFIX = "IWORK_JOB_";
private static final String DEFAULT_USER_PASSWORD = "Zgty@9527";
private static final int DEFAULT_SORT = 999;
private final DeptService deptService;
private final DeptExternalCodeService deptExternalCodeService;
private final PostService postService;
private final PostMapper postMapper;
private final AdminUserService adminUserService;
private final AdminUserMapper adminUserMapper;
private final Map<String, DeptExternalCodeDO> deptExternalCache = new ConcurrentHashMap<>();
private final Map<Long, Boolean> deptPresenceCache = new ConcurrentHashMap<>();
private final Map<String, PostDO> postCache = new ConcurrentHashMap<>();
@Override
@@ -83,23 +77,23 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
iterator.remove();
continue;
}
if (sub.getSubcompanyid1() == null) {
Integer externalId = sub.getSubcompanyid1();
if (externalId == null) {
log.warn("[iWork] 分部缺少标识,跳过:{}", sub.getSubcompanyname());
result.increaseFailed();
iterator.remove();
continue;
}
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, parentHolder.parentId(), canceled);
DeptSaveReqVO saveReq = buildSubcompanySaveReq(sub, deptId, parentHolder.parentId(), canceled);
try {
DeptSyncOutcome outcome = upsertDept(saveReq,
SYSTEM_CODE_SUBCOMPANY,
sub.getSubcompanyid1().toString(),
sub.getSubcompanyname(),
DeptSyncOutcome outcome = upsertDept(deptId,
saveReq,
canceled,
options);
applyDeptOutcome(result, outcome, "分部", sub.getSubcompanyname());
@@ -145,23 +139,23 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
iterator.remove();
continue;
}
if (dept.getDepartmentid() == null) {
Integer externalId = dept.getDepartmentid();
if (externalId == null) {
log.warn("[iWork] 部门缺少标识,跳过:{}", dept.getDepartmentname());
result.increaseFailed();
iterator.remove();
continue;
}
Long deptId = externalId.longValue();
ParentHolder parentHolder = resolveDepartmentParent(dept);
if (parentHolder.required() && parentHolder.parentId() == null) {
continue;
}
boolean canceled = isCanceledFlag(dept.getCanceled());
DeptSaveReqVO saveReq = buildDepartmentSaveReq(dept, parentHolder.parentId(), canceled);
DeptSaveReqVO saveReq = buildDepartmentSaveReq(dept, deptId, parentHolder.parentId(), canceled);
try {
DeptSyncOutcome outcome = upsertDept(saveReq,
SYSTEM_CODE_DEPARTMENT,
dept.getDepartmentid().toString(),
dept.getDepartmentname(),
DeptSyncOutcome outcome = upsertDept(deptId,
saveReq,
canceled,
options);
applyDeptOutcome(result, outcome, "部门", dept.getDepartmentname());
@@ -285,31 +279,22 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
return result;
}
private DeptSyncOutcome upsertDept(DeptSaveReqVO desired,
String systemCode,
String externalCode,
String externalName,
private DeptSyncOutcome upsertDept(Long deptId,
DeptSaveReqVO desired,
boolean disabled,
SyncOptions options) {
DeptExternalCodeDO mapping = getDeptMapping(systemCode, externalCode);
if (mapping == null) {
if (!options.isCreateIfMissing()) {
return new DeptSyncOutcome(SyncAction.SKIPPED, false, null);
}
Long deptId = deptService.createDept(desired);
persistDeptExternalCode(null, deptId, systemCode, externalCode, externalName, desired.getStatus());
return new DeptSyncOutcome(SyncAction.CREATED, CommonStatusEnum.isDisable(desired.getStatus()), deptId);
if (deptId == null) {
return new DeptSyncOutcome(SyncAction.SKIPPED, false, null);
}
Long deptId = mapping.getDeptId();
DeptDO existing = deptService.getDept(deptId);
if (existing == null) {
deptExternalCache.remove(buildDeptCacheKey(systemCode, externalCode));
if (!options.isCreateIfMissing()) {
return new DeptSyncOutcome(SyncAction.SKIPPED, false, null);
}
Long recreatedId = deptService.createDept(desired);
persistDeptExternalCode(mapping.getId(), recreatedId, systemCode, externalCode, externalName, desired.getStatus());
return new DeptSyncOutcome(SyncAction.CREATED, CommonStatusEnum.isDisable(desired.getStatus()), recreatedId);
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())) {
return new DeptSyncOutcome(SyncAction.SKIPPED, false, existing.getId());
@@ -319,9 +304,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
desired.setId(existing.getId());
mergeDeptDefaults(desired, existing);
boolean disabledChanged = CommonStatusEnum.isDisable(desired.getStatus()) && CommonStatusEnum.isEnable(existing.getStatus());
boolean disabledChanged = disabled && CommonStatusEnum.isEnable(existing.getStatus());
deptService.updateDept(desired);
persistDeptExternalCode(mapping.getId(), existing.getId(), systemCode, externalCode, externalName, desired.getStatus());
markDeptExists(existing.getId());
return new DeptSyncOutcome(SyncAction.UPDATED, disabledChanged, existing.getId());
}
@@ -399,9 +384,11 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
private DeptSaveReqVO buildSubcompanySaveReq(IWorkHrSubcompanyPageRespVO.Subcompany data,
Long deptId,
Long parentId,
boolean canceled) {
DeptSaveReqVO req = new DeptSaveReqVO();
req.setId(deptId);
req.setName(limitLength(StrUtil.blankToDefault(data.getSubcompanyname(), "未命名分部"), 30));
req.setShortName(limitLength(data.getSubcompanyname(), 20));
req.setCode(trimToNull(data.getSubcompanycode()));
@@ -415,9 +402,11 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
private DeptSaveReqVO buildDepartmentSaveReq(IWorkHrDepartmentPageRespVO.Department data,
Long deptId,
Long parentId,
boolean canceled) {
DeptSaveReqVO req = new DeptSaveReqVO();
req.setId(deptId);
req.setName(limitLength(StrUtil.blankToDefault(data.getDepartmentname(), "未命名部门"), 30));
req.setShortName(limitLength(StrUtil.blankToDefault(data.getDepartmentmark(), data.getDepartmentname()), 20));
req.setCode(trimToNull(data.getDepartmentcode()));
@@ -469,80 +458,50 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
if (parentExternalId == null || parentExternalId <= 0) {
return new ParentHolder(DeptDO.PARENT_ID_ROOT, false);
}
Long parentId = resolveDeptId(SYSTEM_CODE_SUBCOMPANY, parentExternalId.toString());
return new ParentHolder(parentId, true);
Long parentId = parentExternalId.longValue();
if (hasDept(parentId)) {
return new ParentHolder(parentId, true);
}
return new ParentHolder(null, true);
}
private ParentHolder resolveDepartmentParent(IWorkHrDepartmentPageRespVO.Department dept) {
Integer parentDeptId = dept.getParentdeptid();
if (parentDeptId != null && parentDeptId > 0) {
Long parentId = resolveDeptId(SYSTEM_CODE_DEPARTMENT, parentDeptId.toString());
return new ParentHolder(parentId, true);
Long parentId = parentDeptId.longValue();
if (hasDept(parentId)) {
return new ParentHolder(parentId, true);
}
return new ParentHolder(null, true);
}
Integer subcompanyId = dept.getSubcompanyid1();
if (subcompanyId != null && subcompanyId > 0) {
Long parentId = resolveDeptId(SYSTEM_CODE_SUBCOMPANY, subcompanyId.toString());
return new ParentHolder(parentId, true);
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 DeptExternalCodeDO getDeptMapping(String systemCode, String externalCode) {
if (StrUtil.isBlank(externalCode)) {
return null;
private boolean hasDept(Long deptId) {
if (deptId == null) {
return false;
}
String key = buildDeptCacheKey(systemCode, externalCode);
DeptExternalCodeDO cached = deptExternalCache.get(key);
Boolean cached = deptPresenceCache.get(deptId);
if (cached != null) {
return cached;
}
DeptExternalCodeDO mapping = deptExternalCodeService.getBySystemCodeAndExternalCode(systemCode, externalCode);
if (mapping != null) {
deptExternalCache.put(key, mapping);
boolean exists = deptService.getDept(deptId) != null;
deptPresenceCache.put(deptId, exists);
return exists;
}
private void markDeptExists(Long deptId) {
if (deptId != null) {
deptPresenceCache.put(deptId, true);
}
return mapping;
}
private void persistDeptExternalCode(Long mappingId,
Long deptId,
String systemCode,
String externalCode,
String externalName,
Integer status) {
DeptExternalCodeSaveReqVO req = new DeptExternalCodeSaveReqVO();
req.setDeptId(deptId);
req.setSystemCode(systemCode);
req.setExternalDeptCode(externalCode);
req.setExternalDeptName(StrUtil.blankToDefault(externalName, externalCode));
req.setStatus(status);
req.setRemark("iWork 同步");
DeptExternalCodeDO mapping;
if (mappingId == null) {
Long id = deptExternalCodeService.createDeptExternalCode(req);
mapping = buildMapping(id, deptId, req);
} else {
req.setId(mappingId);
deptExternalCodeService.updateDeptExternalCode(req);
mapping = buildMapping(mappingId, deptId, req);
}
deptExternalCache.put(buildDeptCacheKey(systemCode, externalCode), mapping);
}
private DeptExternalCodeDO buildMapping(Long id, Long deptId, DeptExternalCodeSaveReqVO req) {
DeptExternalCodeDO mapping = new DeptExternalCodeDO();
mapping.setId(id);
mapping.setDeptId(deptId);
mapping.setSystemCode(req.getSystemCode());
mapping.setExternalDeptCode(req.getExternalDeptCode());
mapping.setExternalDeptName(req.getExternalDeptName());
mapping.setStatus(req.getStatus());
mapping.setRemark(req.getRemark());
return mapping;
}
private Long resolveDeptId(String systemCode, String externalCode) {
DeptExternalCodeDO mapping = getDeptMapping(systemCode, externalCode);
return mapping == null ? null : mapping.getDeptId();
}
private PostDO resolvePostByCode(String code) {
@@ -559,17 +518,13 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
private Long resolveUserDeptId(IWorkHrUserPageRespVO.User user) {
if (user.getDepartmentid() != null) {
Long deptId = resolveDeptId(SYSTEM_CODE_DEPARTMENT, user.getDepartmentid().toString());
if (deptId != null) {
return deptId;
}
Long deptId = toLong(user.getDepartmentid());
if (deptId != null && hasDept(deptId)) {
return deptId;
}
if (user.getSubcompanyid1() != null) {
Long deptId = resolveDeptId(SYSTEM_CODE_SUBCOMPANY, user.getSubcompanyid1().toString());
if (deptId != null) {
return deptId;
}
Long subcompanyId = toLong(user.getSubcompanyid1());
if (subcompanyId != null && hasDept(subcompanyId)) {
return subcompanyId;
}
return null;
}
@@ -670,6 +625,10 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
}
}
private Long toLong(Integer value) {
return value == null ? null : value.longValue();
}
private String resolveUsername(IWorkHrUserPageRespVO.User user) {
String candidate = sanitizeUsername(user.getLoginid());
if (candidate == null) {
@@ -737,11 +696,6 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
return JOB_CODE_PREFIX + jobTitleId;
}
private String buildDeptCacheKey(String systemCode, String externalCode) {
Long tenantId = TenantContextHolder.getTenantId();
return (tenantId == null ? "_" : tenantId.toString()) + "::" + systemCode + "::" + externalCode;
}
private String buildPostCacheKey(String code) {
Long tenantId = TenantContextHolder.getTenantId();
return (tenantId == null ? "_" : tenantId.toString()) + "::POST::" + code;