lixing 4 vuotta sitten
vanhempi
commit
122613a2bc

+ 21 - 9
fm-person/src/main/java/com/persagy/fm/department/jms/handler/GroupMsgHandler.java

@@ -109,19 +109,31 @@ public class GroupMsgHandler{
     }
 
     /**
-     * 创建集团
+     * 创建集团(包含幂等性处理)
      * @param groupCreateMsg 集团创建消息
      */
     private void createGroup(GroupCreateMsg groupCreateMsg) {
-        // 给appContext赋值
-        AppContext.getContext().setAccountId(groupCreateMsg.getUpdateUser());
+        /* 先查询后创建, 通过加锁的方式避免并行导致的重复创建 */
+        synchronized (groupCreateMsg.getGroupCode().intern()) {
+            // 给appContext赋值
+            AppContext.getContext().setAccountId(groupCreateMsg.getUpdateUser());
 
-        Department department = new Department();
-        departmentService.setDefaultValue(department);
-        department.setType(DepTypeEnum.GROUP.getType());
-        department.setName(groupCreateMsg.getGroupName());
-        department.setFullPath(groupCreateMsg.getGroupName());
+            // 判断集团下是否已经有类型为集团的部门
+            QueryDepartmentDTO queryDepartmentDTO = new QueryDepartmentDTO();
+            queryDepartmentDTO.setType(DepTypeEnum.GROUP.getType());
+            List<Department> departments = departmentService.queryDepartmentList(queryDepartmentDTO);
 
-        departmentService.createDepartment(department);
+            if (CollectionUtils.isEmpty(departments)) {
+                Department department = new Department();
+                departmentService.setDefaultValue(department);
+                department.setType(DepTypeEnum.GROUP.getType());
+                department.setName(groupCreateMsg.getGroupName());
+                department.setFullPath(groupCreateMsg.getGroupName());
+
+                departmentService.createDepartment(department);
+            } else {
+                log.error("集团下已包含类型为集团的部门,拒绝重复创建");
+            }
+        }
     }
 }

+ 102 - 27
fm-person/src/main/java/com/persagy/fm/department/service/impl/DepartmentServiceImpl.java

@@ -13,7 +13,6 @@ import com.persagy.fm.common.constant.enums.BoolEnum;
 import com.persagy.fm.common.constant.enums.ValidEnum;
 import com.persagy.fm.common.context.DefaultAppContext;
 import com.persagy.fm.common.model.dto.Sort;
-import com.persagy.fm.common.model.vo.SimpleObjVO;
 import com.persagy.fm.department.constant.enums.DepTypeEnum;
 import com.persagy.fm.department.constant.enums.ResourceFromEnum;
 import com.persagy.fm.department.dao.DepartmentMapper;
@@ -39,7 +38,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
-import java.util.Collection;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -102,7 +100,7 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
      */
     private Department saveDepartment(AddDepartmentDTO addDepartmentDTO) {
         // 校验部门名称重复
-        checkDuplicateDeptName(addDepartmentDTO);
+        checkDuplicateDeptName(addDepartmentDTO.getName(), addDepartmentDTO.getParentId());
         // 同一集团下只能有一个类型为集团的部门
         checkDuplicateGroup(addDepartmentDTO);
 
@@ -163,11 +161,11 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
      * @author lixing
      * @version V1.0 2021/3/12 10:49 上午
      */
-    private void checkDuplicateDeptName(AddDepartmentDTO addDepartmentDTO) {
+    private void checkDuplicateDeptName(String depName, String parentId) {
         // 拼装查询参数
         QueryDepartmentDTO queryDepartmentDTO = new QueryDepartmentDTO();
-        queryDepartmentDTO.setName(addDepartmentDTO.getName());
-        queryDepartmentDTO.setParentId(addDepartmentDTO.getParentId());
+        queryDepartmentDTO.setName(depName);
+        queryDepartmentDTO.setParentId(parentId);
 
         // 查询
         List<Department> departments = queryDepartmentList(queryDepartmentDTO);
@@ -194,17 +192,22 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
         if (department == null) {
             throw new IllegalArgumentException("无法找到要更新的部门, id:" + updateDepartmentDTO.getId());
         }
-        String nameBeforeChange = department.getName();
+
+        // 部门名称或者父部门id发生变化,需要更新子部门的全路径
+        String fullPathAfterChange = getFullPathAfterChange(updateDepartmentDTO, department);
+        updateSonDepsFullPath(department.getFullPath(), fullPathAfterChange);
+
+        // 更新部门
         department = ConvertDepartmentTool.INSTANCE.convertUpdateDto2Entity(department, updateDepartmentDTO);
-        // 如果部门名称发生变化,级联更新自己和子部门的全路径
-        if (!nameBeforeChange.equals(updateDepartmentDTO.getName())) {
-            cascadeUpdateFullPathWhenNameChange(department, nameBeforeChange);
-        }
+        department.setFullPath(fullPathAfterChange);
         department.setModifier(DefaultAppContext.getContext().getAccountId());
         updateById(department);
+
+        // 更新部门关联的项目
         String depId = department.getId();
         List<String> projectIds = updateDepartmentDTO.getProjectIds();
         updateDepProject(projectIds, depId);
+
         // 将负责人的工作信息标记为主管
         List<String> managers = updateDepartmentDTO.getManagers();
         if (!CollectionUtils.isEmpty(managers)) {
@@ -217,6 +220,67 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
         }
     }
 
+    /**
+     * 获取更新后的部门全路径
+     *
+     * @param updateDepartmentDTO 更新人员入参
+     * @param department 更新前的部门对象
+     * @return 更新后的部门全路径
+     * @author lixing
+     * @version V1.0 2021/4/11 8:35 下午
+     */
+    private String getFullPathAfterChange(UpdateDepartmentDTO updateDepartmentDTO, Department department) {
+        String nameBeforeChange = department.getName();
+        String fullPathBeforeChange = department.getFullPath();
+        String parentIdBeforeChange = department.getParentId();
+        String nameAfterChange = nameBeforeChange;
+        String fullPathAfterChange = fullPathBeforeChange;
+        // 如果部门名称发生变化
+        if (StringUtils.isNotBlank(updateDepartmentDTO.getName()) &&
+                !nameBeforeChange.equals(updateDepartmentDTO.getName())) {
+            nameAfterChange = updateDepartmentDTO.getName();
+            checkDuplicateDeptName(updateDepartmentDTO.getName(), department.getParentId());
+            fullPathAfterChange = getDepFullPathWhenNameChange(
+                    nameBeforeChange, fullPathBeforeChange, nameAfterChange);
+        }
+
+        // 如果上级部门发生了变化,级联更新自己和子部门的全路径
+        if (StringUtils.isNotBlank(updateDepartmentDTO.getParentId())) {
+            if (updateDepartmentDTO.getParentId().equals(department.getId())) {
+                throw new IllegalArgumentException("父部门不能选择自己");
+            }
+
+            if (!updateDepartmentDTO.getParentId().equals(parentIdBeforeChange)) {
+                fullPathAfterChange = getDepFullPathWhenParentIdChange(
+                        nameAfterChange, updateDepartmentDTO.getParentId());
+            }
+        }
+
+        return fullPathAfterChange;
+    }
+
+    /**
+     * 当部门父部门发生变化时获取更新后的部门的全路径
+     *
+     * @param depName             更新后的部门名称
+     * @param parentIdAfterChange 更新后的父部门id
+     * @return 更新后的部门全路径
+     * @author lixing
+     * @version V1.0 2021/4/11 7:30 下午
+     */
+    private String getDepFullPathWhenParentIdChange(String depName, String parentIdAfterChange) {
+        String separator = "-";
+        // 获取更新后的父部门的全路径
+        Department parentDep = queryDepartmentDetail(parentIdAfterChange);
+        String parentFullPath = parentDep.getFullPath();
+
+        if (StringUtils.isBlank(parentFullPath)) {
+            return depName;
+        } else {
+            return parentFullPath + separator + depName;
+        }
+    }
+
     @Override
     public void updateDepartment(Department department) {
         updateById(department);
@@ -239,33 +303,44 @@ public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Departm
     }
 
     /**
-     * 部门名称发生变化,级联更新自己和子部门的全路径
+     * 当部门名称发生变化时获取更新后的部门全路径
      *
-     * @param department       名称发生变更的部门
-     * @param nameBeforeChange 修改之前的部门名称
+     * @param nameBeforeChange     更新前的部门名称
+     * @param fullPathBeforeChange 更新前的部门全路径
+     * @param nameAfterChange      更新后的部门名称
+     * @return 更新后的部门全路径
      * @author lixing
-     * @version V1.0 2021/3/19 10:53 上午
+     * @version V1.0 2021/4/11 7:30 下
      */
-    private void cascadeUpdateFullPathWhenNameChange(Department department, String nameBeforeChange) {
-        String fullPathBeforeChange = department.getFullPath();
-
-        // 根据部门全路径查询子部门
-        QueryDepartmentDTO queryDepartmentDTO = new QueryDepartmentDTO();
-        queryDepartmentDTO.setFullPath(fullPathBeforeChange + "-");
-        List<Department> sonDeps = queryDepartmentList(queryDepartmentDTO);
-
-
+    private String getDepFullPathWhenNameChange(
+            String nameBeforeChange, String fullPathBeforeChange, String nameAfterChange) {
         String fullPathAfterChange = fullPathBeforeChange;
         int i = fullPathBeforeChange.lastIndexOf(nameBeforeChange);
         if (i != -1) {
-            fullPathAfterChange = fullPathBeforeChange.substring(0, i) + department.getName();
-            department.setFullPath(fullPathAfterChange);
+            fullPathAfterChange = fullPathBeforeChange.substring(0, i) + nameAfterChange;
         }
+        return fullPathAfterChange;
+    }
 
+    /**
+     * 更新子部门全路径
+     *
+     * @param fullPathBeforeChange 更新前部门的全路径
+     * @param fullPathAfterChange  更新后部门的全路径
+     * @author lixing
+     * @version V1.0 2021/4/11 7:27 下午
+     */
+    private void updateSonDepsFullPath(String fullPathBeforeChange, String fullPathAfterChange) {
+        String separator = "-";
+        // 根据部门全路径查询子部门
+        QueryDepartmentDTO queryDepartmentDTO = new QueryDepartmentDTO();
+        queryDepartmentDTO.setFullPath(fullPathBeforeChange + separator);
+        List<Department> sonDeps = queryDepartmentList(queryDepartmentDTO);
         // 修改子部门全路径
         for (Department sonDep : sonDeps) {
             String tmpFullPath = sonDep.getFullPath();
-            tmpFullPath = tmpFullPath.replaceFirst(fullPathBeforeChange + "-", fullPathAfterChange + "-");
+            tmpFullPath = tmpFullPath.replaceFirst(fullPathBeforeChange + separator,
+                    fullPathAfterChange + separator);
             sonDep.setFullPath(tmpFullPath);
         }
 

+ 31 - 17
fm-person/src/main/java/com/persagy/fm/person/jms/handler/AccountMsgHandler.java

@@ -11,6 +11,7 @@ import com.persagy.fm.person.jms.model.AccountCreateMsg;
 import com.persagy.fm.person.jms.model.AccountUpdateMsg;
 import com.persagy.fm.person.model.ConvertPersonTool;
 import com.persagy.fm.person.model.Person;
+import com.persagy.fm.person.model.dto.QueryPersonDTO;
 import com.persagy.fm.person.service.IPersonService;
 import com.persagy.fm.workresume.model.dto.AddWorkResumeDTO;
 import com.persagy.fm.workresume.service.IWorkResumeService;
@@ -44,31 +45,44 @@ public class AccountMsgHandler {
     MsgBaseHandler msgBaseHandler;
 
     /**
-     * 处理账号创建消息
+     * 处理账号创建消息(包含幂等性处理)
      *
      * @param accountCreateMsg 账号创建消息
      * @author lixing
      * @version V1.0 2021/3/18 11:40 上午
      */
     public void createAccount(AccountCreateMsg accountCreateMsg) {
-        // 找到集团下类型为集团的部门
-        QueryDepartmentDTO queryDepartmentDTO = new QueryDepartmentDTO();
-        queryDepartmentDTO.setType(DepTypeEnum.GROUP.getType());
-        List<Department> departments = departmentService.queryDepartmentList(queryDepartmentDTO);
-        if (CollectionUtils.isEmpty(departments)) {
-            log.error("创建集团管理员发生异常,尚未创建集团");
-        }
-        Department group = departments.get(0);
+        String accountId = accountCreateMsg.getId();
+        /* 先查询后创建, 通过加锁的方式避免并行导致的重复创建 */
+        synchronized (accountId.intern()) {
+            // 查询集团下有没有使用消息中的账号id的用户
+            QueryPersonDTO queryPersonDTO = new QueryPersonDTO();
+            Person tmpPerson = personService.queryByAccountId(accountId);
+
+            if (tmpPerson != null) {
+                log.error("已有人员使用该账号,拒绝创建人员");
+                return;
+            }
 
-        Person person = ConvertPersonTool.INSTANCE.convert2Entity(accountCreateMsg);
-        personService.createPerson(person);
+            // 找到集团下类型为集团的部门
+            QueryDepartmentDTO queryDepartmentDTO = new QueryDepartmentDTO();
+            queryDepartmentDTO.setType(DepTypeEnum.GROUP.getType());
+            List<Department> departments = departmentService.queryDepartmentList(queryDepartmentDTO);
+            if (CollectionUtils.isEmpty(departments)) {
+                log.error("创建集团管理员发生异常,尚未创建集团");
+            }
+            Department group = departments.get(0);
+
+            Person person = ConvertPersonTool.INSTANCE.convert2Entity(accountCreateMsg);
+            personService.createPerson(person);
 
-        // 创建人员的工作信息
-        AddWorkResumeDTO addWorkResumeDTO = new AddWorkResumeDTO();
-        addWorkResumeDTO.setHiredDate(new Date());
-        addWorkResumeDTO.setDepId(group.getId());
-        addWorkResumeDTO.setPersonId(person.getId());
-        workResumeService.createWorkResume(addWorkResumeDTO);
+            // 创建人员的工作信息
+            AddWorkResumeDTO addWorkResumeDTO = new AddWorkResumeDTO();
+            addWorkResumeDTO.setHiredDate(new Date());
+            addWorkResumeDTO.setDepId(group.getId());
+            addWorkResumeDTO.setPersonId(person.getId());
+            workResumeService.createWorkResume(addWorkResumeDTO);
+        }
     }