优化钉钉部门同步:修复parent_id更新逻辑,确保父子关系正确处理(支持多级关系)

This commit is contained in:
Your Name 2026-01-02 13:58:17 +08:00
parent 9ad09332cb
commit 7e72c665ee

View File

@ -538,13 +538,15 @@ public class DingTalkService {
log.info("从钉钉获取到 {} 个部门", allDepartments.size());
// 同步每个部门到数据库
// 按照层级排序:父部门在前,子部门在后
// 通过多次遍历确保父部门先创建
Map<String, Long> dingDeptIdToSysIdMap = new HashMap<>(); // 缓存ding_dept_id到系统ID的映射
// 第一遍:创建所有部门(如果不存在),并设置ding_dept_id和parent_id为0
for (Map<String, Object> dingDept : allDepartments) {
Object deptIdObj = dingDept.get("dept_id");
String dingDeptId = deptIdObj != null ? deptIdObj.toString() : null;
String deptName = (String) dingDept.get("name");
Object parentIdObj = dingDept.get("parent_id");
String parentDingDeptId = parentIdObj != null ? parentIdObj.toString() : null;
if (dingDeptId == null || deptName == null) {
log.warn("跳过无效的部门信息: {}", dingDept);
@ -569,29 +571,10 @@ public class DingTalkService {
);
}
if (sysDept != null) {
// 更新现有部门:设置ding_dept_id
sysDept.setDingDeptId(dingDeptId);
departmentMapper.updateById(sysDept);
log.info("更新部门: id={}, name={}, ding_dept_id={}", sysDept.getId(), deptName, dingDeptId);
} else {
// 部门不存在,自动创建
if (sysDept == null) {
// 部门不存在,自动创建(先不设置parent_id,等第二遍再设置)
try {
Long parentId = 0L;
if (parentDingDeptId != null && !parentDingDeptId.equals("1")) {
// 查找父部门的系统ID
com.designhub.entity.Department parentDept = departmentMapper.selectOne(
new LambdaQueryWrapper<com.designhub.entity.Department>()
.eq(com.designhub.entity.Department::getDingDeptId, parentDingDeptId)
.eq(com.designhub.entity.Department::getDeleted, 0)
.last("LIMIT 1")
);
if (parentDept != null) {
parentId = parentDept.getId();
}
}
// 根据部门名称智能判断部门类型(可根据实际业务规则调整)
// 根据部门名称智能判断部门类型
String deptType = inferDeptType(deptName);
// 创建新部门
@ -599,24 +582,75 @@ public class DingTalkService {
newDept.setDeptName(deptName);
newDept.setDingDeptId(dingDeptId);
newDept.setDeptType(deptType);
newDept.setParentId(parentId);
newDept.setParentId(0L); // 先设置为0,第二遍再更新
newDept.setStatus(1); // 启用
newDept.setSortOrder(0);
departmentMapper.insert(newDept);
sysDept = newDept;
// 初始化积分池会在DepartmentService.createDepartment中处理
// 这里直接调用createDepartment会触发积分池初始化
// 但为了避免循环依赖,我们直接使用mapper插入,积分池可以稍后初始化
// 如果需要积分池,可以在后台手动初始化,或者用户首次使用时会自动创建
log.info("自动创建部门: id={}, name={}, ding_dept_id={}, type={}, parentId={}",
newDept.getId(), deptName, dingDeptId, deptType, parentId);
log.info("自动创建部门(第一遍): id={}, name={}, ding_dept_id={}, type={}",
newDept.getId(), deptName, dingDeptId, deptType);
} catch (Exception e) {
log.error("自动创建部门失败: name={}, ding_dept_id={}", deptName, dingDeptId, e);
// 创建失败不影响其他部门的同步,继续处理下一个
continue; // 跳过失败的部门
}
} else {
// 更新ding_dept_id(如果还没有)
if (!dingDeptId.equals(sysDept.getDingDeptId())) {
sysDept.setDingDeptId(dingDeptId);
departmentMapper.updateById(sysDept);
log.info("更新部门ding_dept_id: id={}, name={}, ding_dept_id={}",
sysDept.getId(), deptName, dingDeptId);
}
}
// 缓存映射关系
dingDeptIdToSysIdMap.put(dingDeptId, sysDept.getId());
}
// 第二遍:更新所有部门的parent_id
for (Map<String, Object> dingDept : allDepartments) {
Object deptIdObj = dingDept.get("dept_id");
String dingDeptId = deptIdObj != null ? deptIdObj.toString() : null;
String deptName = (String) dingDept.get("name");
Object parentIdObj = dingDept.get("parent_id");
String parentDingDeptId = parentIdObj != null ? parentIdObj.toString() : null;
if (dingDeptId == null || deptName == null) {
continue;
}
Long sysDeptId = dingDeptIdToSysIdMap.get(dingDeptId);
if (sysDeptId == null) {
continue; // 第一遍创建失败的部门跳过
}
// 获取系统部门
com.designhub.entity.Department sysDept = departmentMapper.selectById(sysDeptId);
if (sysDept == null) {
continue;
}
// 确定parent_id
Long parentId = 0L;
if (parentDingDeptId != null && !parentDingDeptId.equals("1")) {
// 从缓存中获取父部门的系统ID
Long parentSysId = dingDeptIdToSysIdMap.get(parentDingDeptId);
if (parentSysId != null) {
parentId = parentSysId;
}
}
// 更新parent_id(如果不同)
Long currentParentId = sysDept.getParentId() != null ? sysDept.getParentId() : 0L;
if (!parentId.equals(currentParentId)) {
sysDept.setParentId(parentId);
departmentMapper.updateById(sysDept);
log.info("更新部门父子关系: id={}, name={}, parentId: {} -> {}",
sysDept.getId(), deptName, currentParentId, parentId);
}
syncCount++;
}