SystemRoleMenuServiceImpl.java 3.99 KB
package com.diligrp.rider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.diligrp.rider.common.enums.AdminRoleScopeEnum;
import com.diligrp.rider.common.enums.MenuScopeEnum;
import com.diligrp.rider.common.exception.BizException;
import com.diligrp.rider.dto.AdminRoleMenuAssignDTO;
import com.diligrp.rider.entity.SysMenu;
import com.diligrp.rider.entity.SysRole;
import com.diligrp.rider.entity.SysRoleMenu;
import com.diligrp.rider.mapper.SysRoleMapper;
import com.diligrp.rider.mapper.SysRoleMenuMapper;
import com.diligrp.rider.service.SystemRoleMenuService;
import com.diligrp.rider.vo.AdminRoleMenuTreeVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SystemRoleMenuServiceImpl implements SystemRoleMenuService {

    private final SysRoleMapper sysRoleMapper;
    private final SysRoleMenuMapper sysRoleMenuMapper;
    private final SystemMenuServiceImpl systemMenuService;

    @Override
    public List<AdminRoleMenuTreeVO> getRoleMenuTree(Long roleId) {
        SysRole role = requireRole(roleId);
        List<SysMenu> allowedMenus = filterMenusByScope(systemMenuService.listAllMenus(), role);
        List<SysRoleMenu> assigned = sysRoleMenuMapper.selectList(new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, roleId));
        Set<Long> assignedIds = assigned.stream().map(SysRoleMenu::getMenuId).collect(Collectors.toSet());
        Map<Long, Boolean> checkedMap = new LinkedHashMap<>();
        for (SysMenu menu : allowedMenus) {
            checkedMap.put(menu.getId(), assignedIds.contains(menu.getId()));
        }
        return systemMenuService.buildTree(allowedMenus, checkedMap, false);
    }

    @Override
    @Transactional
    public void assignMenus(Long roleId, AdminRoleMenuAssignDTO dto) {
        SysRole role = requireRole(roleId);
        List<SysMenu> allowedMenus = filterMenusByScope(systemMenuService.listAllMenus(), role);
        Set<Long> allowedIds = allowedMenus.stream().map(SysMenu::getId).collect(Collectors.toSet());
        List<Long> menuIds = dto.getMenuIds() == null ? List.of() : dto.getMenuIds();
        for (Long menuId : menuIds) {
            if (!allowedIds.contains(menuId)) {
                throw new BizException("存在不允许分配的菜单");
            }
        }

        sysRoleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, roleId));
        long now = System.currentTimeMillis() / 1000;
        for (Long menuId : menuIds) {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenu.setCreateTime(now);
            sysRoleMenuMapper.insert(roleMenu);
        }
    }

    private SysRole requireRole(Long roleId) {
        SysRole role = sysRoleMapper.selectById(roleId);
        if (role == null || role.getStatus() == null || role.getStatus() != 1) {
            throw new BizException("角色不存在或已禁用");
        }
        return role;
    }

    private List<SysMenu> filterMenusByScope(List<SysMenu> menus, SysRole role) {
        return menus.stream().filter(menu -> isScopeAllowed(role, menu)).collect(Collectors.toList());
    }

    private boolean isScopeAllowed(SysRole role, SysMenu menu) {
        if (MenuScopeEnum.BOTH.name().equals(menu.getMenuScope())) {
            return true;
        }
        if (AdminRoleScopeEnum.PLATFORM.name().equals(role.getRoleScope())) {
            return MenuScopeEnum.PLATFORM.name().equals(menu.getMenuScope());
        }
        if (AdminRoleScopeEnum.SUBSTATION.name().equals(role.getRoleScope())) {
            return MenuScopeEnum.SUBSTATION.name().equals(menu.getMenuScope());
        }
        return false;
    }
}