组织同步逻辑修改
This commit is contained in:
+7
@@ -199,4 +199,11 @@ public interface IDeptService extends IService<Dept> {
|
||||
*/
|
||||
void rebuildOaHierarchy();
|
||||
|
||||
/**
|
||||
* 删除 OA 同步后无法挂到上级的组织(上级 OA 主键在本地不存在),并级联删除其子级
|
||||
*
|
||||
* @return 删除数量
|
||||
*/
|
||||
int removeOaOrphansWithoutParent();
|
||||
|
||||
}
|
||||
|
||||
+73
@@ -632,6 +632,79 @@ public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements ID
|
||||
this.refreshAncestors(true, null);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public int removeOaOrphansWithoutParent() {
|
||||
List<Dept> oaDeptList = this.list(Wrappers.<Dept>lambdaQuery()
|
||||
.isNotNull(Dept::getOaId)
|
||||
.ne(Dept::getOaId, ""));
|
||||
if (CollectionUtil.isEmpty(oaDeptList)) {
|
||||
return 0;
|
||||
}
|
||||
Map<String, Dept> companyByOaId = this.indexByOaId(oaDeptList, DeptCategory.COMPANY.getCode());
|
||||
Map<String, Dept> departmentByOaId = this.indexByOaId(oaDeptList, DeptCategory.DEPT.getCode());
|
||||
Set<Long> deleteIds = new HashSet<>();
|
||||
for (Dept dept : oaDeptList) {
|
||||
String parentOaId = dept.getOaSupSubComId();
|
||||
// 上级为空或为 0:视为本地锚点/根级,不作为孤儿删除
|
||||
if (StringUtil.isBlank(parentOaId) || OAConstant.ROOT_COMPANY_ID.equals(parentOaId)) {
|
||||
continue;
|
||||
}
|
||||
boolean parentExists;
|
||||
if (DeptCategory.COMPANY.getCode().equals(dept.getDeptCategory())) {
|
||||
parentExists = companyByOaId.containsKey(parentOaId);
|
||||
} else {
|
||||
parentExists = departmentByOaId.containsKey(parentOaId) || companyByOaId.containsKey(parentOaId);
|
||||
}
|
||||
if (!parentExists) {
|
||||
deleteIds.add(dept.getId());
|
||||
}
|
||||
}
|
||||
if (CollectionUtil.isEmpty(deleteIds)) {
|
||||
log.info("没有需要清理的OA孤儿组织");
|
||||
return 0;
|
||||
}
|
||||
// 按 OA 上级关系级联:上级被删则子级一并删除
|
||||
boolean oaCascadeChanged = true;
|
||||
while (oaCascadeChanged) {
|
||||
oaCascadeChanged = false;
|
||||
for (Dept dept : oaDeptList) {
|
||||
if (deleteIds.contains(dept.getId())) {
|
||||
continue;
|
||||
}
|
||||
String parentOaId = dept.getOaSupSubComId();
|
||||
if (StringUtil.isBlank(parentOaId) || OAConstant.ROOT_COMPANY_ID.equals(parentOaId)) {
|
||||
continue;
|
||||
}
|
||||
Dept parent = DeptCategory.COMPANY.getCode().equals(dept.getDeptCategory())
|
||||
? companyByOaId.get(parentOaId)
|
||||
: Optional.ofNullable(departmentByOaId.get(parentOaId)).orElse(companyByOaId.get(parentOaId));
|
||||
if (parent != null && deleteIds.contains(parent.getId())) {
|
||||
deleteIds.add(dept.getId());
|
||||
oaCascadeChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 按本地 parent_id 再级联一轮,清掉挂在已删节点下的子树
|
||||
List<Dept> allDeptList = this.list();
|
||||
boolean parentIdCascadeChanged = true;
|
||||
while (parentIdCascadeChanged) {
|
||||
parentIdCascadeChanged = false;
|
||||
for (Dept dept : allDeptList) {
|
||||
if (deleteIds.contains(dept.getId())) {
|
||||
continue;
|
||||
}
|
||||
if (dept.getParentId() != null && deleteIds.contains(dept.getParentId())) {
|
||||
deleteIds.add(dept.getId());
|
||||
parentIdCascadeChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.removeByIds(deleteIds);
|
||||
log.info("删除OA层级无法挂载的组织{}条", deleteIds.size());
|
||||
return deleteIds.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按机构类型建立 OA 主键索引
|
||||
*/
|
||||
|
||||
+10
-3
@@ -74,10 +74,14 @@ public class OASyncServiceImpl implements IOASyncService {
|
||||
Date startTime = this.syncAndRecord(DataSyncRecordUtils::createOAOrgFetch, queryStartTime -> {
|
||||
// 1. 同步公司
|
||||
this.syncCompany(queryStartTime);
|
||||
// 公司分批入库后,重建层级并清理无法挂载的公司
|
||||
deptService.rebuildOaHierarchy();
|
||||
deptService.removeOaOrphansWithoutParent();
|
||||
// 2. 同步部门
|
||||
this.syncDept(queryStartTime);
|
||||
// 3. 分批写入完成后,按 OA 主键重建组织、部门层级
|
||||
deptService.rebuildOaHierarchy();
|
||||
deptService.removeOaOrphansWithoutParent();
|
||||
// 4. 更新部门祖级列表
|
||||
deptService.updateAncestors(queryStartTime);
|
||||
CacheUtil.clear(SYS_CACHE);
|
||||
@@ -344,7 +348,9 @@ public class OASyncServiceImpl implements IOASyncService {
|
||||
}
|
||||
OaOrgSyncPageVO pageVO = buildOrgSyncPageVO("company", pageNo, pageSize, totalSize, oaCompanies.size(), syncCount);
|
||||
if (Boolean.TRUE.equals(pageVO.getFinished())) {
|
||||
// 公司全部分批入库后:重建层级,并删除上级不存在的数据
|
||||
deptService.rebuildOaHierarchy();
|
||||
deptService.removeOaOrphansWithoutParent();
|
||||
}
|
||||
CacheUtil.clear(SYS_CACHE);
|
||||
CacheUtil.clear(SYS_CACHE, Boolean.FALSE);
|
||||
@@ -388,8 +394,9 @@ public class OASyncServiceImpl implements IOASyncService {
|
||||
}
|
||||
OaOrgSyncPageVO pageVO = buildOrgSyncPageVO("department", pageNo, pageSize, totalSize, oaDepartments.size(), syncCount);
|
||||
if (Boolean.TRUE.equals(pageVO.getFinished())) {
|
||||
// 部门分批同步完成后,按 OA 主键重建层级并刷新祖级列表
|
||||
// 部门分批同步完成后,重建层级、清理无法挂载数据并刷新祖级列表
|
||||
deptService.rebuildOaHierarchy();
|
||||
deptService.removeOaOrphansWithoutParent();
|
||||
deptService.updateAncestors(null);
|
||||
}
|
||||
CacheUtil.clear(SYS_CACHE);
|
||||
@@ -587,7 +594,7 @@ public class OASyncServiceImpl implements IOASyncService {
|
||||
}
|
||||
});
|
||||
|
||||
// 重新把没有父id的数据设置一下父id;上级尚未入库时,新增记录先挂到根节点,分批结束后再重建
|
||||
// 重新把没有父id的数据设置一下父id;上级尚未入库时,新增记录先挂到根节点,全部分批完成后重建层级并清理无法挂载的数据
|
||||
int unresolvedParentCount = 0;
|
||||
for (Dept dept : allParam) {
|
||||
if (dept.getParentId() != null) {
|
||||
@@ -604,7 +611,7 @@ public class OASyncServiceImpl implements IOASyncService {
|
||||
}
|
||||
}
|
||||
if (unresolvedParentCount > 0) {
|
||||
ComposeLogUtil.getLastLog().warn("同步{}时有{}条上级尚未入库,已先保存,分批结束后按OA主键重建层级",
|
||||
ComposeLogUtil.getLastLog().warn("同步{}时有{}条上级尚未入库,已先保存,分批结束后重建层级并清理无法挂载数据",
|
||||
deptCategory.getName(), unresolvedParentCount);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user