longz
2026-06-29 9d4cbff7464ebfd7803c2ce53ded49d0f73fe011
backend/src/main/java/com/sinata/appointment/service/DeptManageApplicationService.java
@@ -2,6 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sinata.appointment.constants.BizErrorCode;
import com.sinata.appointment.constants.MiniUserType;
import com.sinata.appointment.dto.DeptCreateRequest;
import com.sinata.appointment.dto.DeptTreeNodeVo;
import com.sinata.appointment.dto.DeptUpdateRequest;
@@ -86,6 +87,7 @@
        d.setDeptName(trimName(req.getDeptName()));
        d.setStatus(normalizeStatus(req.getStatus()));
        d.setSortOrder(0);
        applyDeptLeaders(d, req.getLeaderIds());
        sysDeptMapper.insert(d);
        SysDept fresh = sysDeptMapper.selectById(d.getId());
        if (fresh == null || !StringUtils.hasText(fresh.getUuid())) {
@@ -102,6 +104,7 @@
        SysDept d = loadActiveWithUuid(id, req.getUuid());
        d.setDeptName(trimName(req.getDeptName()));
        d.setStatus(normalizeStatus(req.getStatus()));
        applyDeptLeaders(d, req.getLeaderIds());
        Long oldParent = d.getParentId() == null ? 0L : d.getParentId();
        if (oldParent == 0L) {
@@ -183,6 +186,47 @@
            cur = p;
        }
        return false;
    }
    private void applyDeptLeaders(SysDept dept, List<Long> leaderIds) {
        List<Long> normalized = normalizeLeaderIds(leaderIds);
        validateLeaders(normalized);
        dept.setLeaderIds(joinIds(normalized));
    }
    private List<Long> normalizeLeaderIds(List<Long> leaderIds) {
        List<Long> raw = leaderIds == null ? new ArrayList<>() : new ArrayList<>(leaderIds);
        List<Long> out = new ArrayList<>();
        Set<Long> seen = new HashSet<>();
        for (Long id : raw) {
            if (id == null || id <= 0 || !seen.add(id)) {
                continue;
            }
            out.add(id);
        }
        return out;
    }
    private void validateLeaders(List<Long> leaderIds) {
        if (leaderIds == null || leaderIds.isEmpty()) {
            return;
        }
        List<MpUser> users =
                mpUserMapper.selectList(
                        new LambdaQueryWrapper<MpUser>()
                                .eq(MpUser::getDelFlag, 0)
                                .eq(MpUser::getStatus, 1)
                                .eq(MpUser::getUserType, MiniUserType.EMPLOYEE)
                                .in(MpUser::getId, leaderIds));
        Set<Long> validIds = new HashSet<>();
        for (MpUser user : users) {
            validIds.add(user.getId());
        }
        for (Long id : leaderIds) {
            if (!validIds.contains(id)) {
                throw new BizException(BizErrorCode.RESOURCE_VERIFY_FAILED, "部门负责人不存在或已禁用: " + id);
            }
        }
    }
    private int subtreeHeight(long id, Map<Long, List<SysDept>> byParent) {
@@ -284,9 +328,67 @@
        v.setDeptName(d.getDeptName());
        v.setSortOrder(d.getSortOrder());
        v.setStatus(d.getStatus() == null ? 1 : d.getStatus());
        List<Long> leaderIds = parseLeaderIds(d);
        v.setLeaderIds(leaderIds);
        v.setLeaderNames(resolveLeaderNames(leaderIds));
        return v;
    }
    private List<Long> parseLeaderIds(SysDept dept) {
        return parseIds(dept.getLeaderIds());
    }
    private List<Long> parseIds(String raw) {
        if (!StringUtils.hasText(raw)) {
            return List.of();
        }
        List<Long> ids = new ArrayList<>();
        Set<Long> seen = new HashSet<>();
        for (String part : raw.split(",")) {
            if (!StringUtils.hasText(part)) {
                continue;
            }
            try {
                Long id = Long.parseLong(part.trim());
                if (id > 0 && seen.add(id)) {
                    ids.add(id);
                }
            } catch (NumberFormatException ignored) {
            }
        }
        return ids;
    }
    private String joinIds(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return null;
        }
        return ids.stream().map(String::valueOf).collect(java.util.stream.Collectors.joining(","));
    }
    private String resolveLeaderNames(List<Long> leaderIds) {
        if (leaderIds == null || leaderIds.isEmpty()) {
            return null;
        }
        List<MpUser> users =
                mpUserMapper.selectList(
                        new LambdaQueryWrapper<MpUser>()
                                .eq(MpUser::getDelFlag, 0)
                                .in(MpUser::getId, leaderIds));
        Map<Long, String> names = new HashMap<>();
        for (MpUser user : users) {
            names.put(user.getId(), user.getNickName());
        }
        List<String> ordered = new ArrayList<>();
        for (Long id : leaderIds) {
            String name = names.get(id);
            if (StringUtils.hasText(name)) {
                ordered.add(name.trim());
            }
        }
        return ordered.isEmpty() ? null : String.join("、", ordered);
    }
    private SysDept loadActive(long id) {
        SysDept d = sysDeptMapper.selectById(id);
        if (d == null || d.getDelFlag() != null && d.getDelFlag() == 1) {