package com.lantone.security.facade;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.lantone.security.dto.GetCreateRoleDTO;
import com.lantone.security.dto.GetDictionaryInfoByTypeDTO;
import com.lantone.security.dto.GetRoleDTO;
import com.lantone.security.dto.GetRolePageDTO;
import com.lantone.security.dto.GetUserShowTreeDTO;
import com.lantone.security.dto.SoftwareDTO;
import com.lantone.security.dto.UserMenuResourceTreeDTO;
import com.lantone.security.dto.UserRoleDTO;
import com.lantone.common.enums.StatusEnum;
import com.lantone.common.exception.Asserts;
import com.lantone.common.util.DateUtil;
import com.lantone.common.util.EntityUtil;
import com.lantone.common.util.ListUtil;
import com.lantone.common.util.StringUtil;
import com.lantone.common.util.SysUserUtils;
import com.lantone.security.vo.AddRoleSoftwareVO;
import com.lantone.security.vo.AddRoleVO;
import com.lantone.security.vo.GetRolePageVO;
import com.lantone.security.vo.UpdateRoleVO;
import com.lantone.security.entity.Hospital;
import com.lantone.security.entity.Menu;
import com.lantone.security.entity.Resource;
import com.lantone.security.entity.Role;
import com.lantone.security.entity.RoleSoftwareMenu;
import com.lantone.security.entity.RoleSoftwareResource;
import com.lantone.security.entity.SoftwareMenu;
import com.lantone.security.entity.SoftwareResource;
import com.lantone.security.entity.UserRole;
import com.lantone.security.facade.base.DictionaryInfoFacade;
import com.lantone.security.facade.base.HospitalFacade;
import com.lantone.security.facade.base.MenuFacade;
import com.lantone.security.facade.base.ResourceFacade;
import com.lantone.security.facade.base.RoleFacade;
import com.lantone.security.facade.base.RoleSoftwareMenuFacade;
import com.lantone.security.facade.base.RoleSoftwareResourceFacade;
import com.lantone.security.facade.base.SoftwareFacade;
import com.lantone.security.facade.base.SoftwareMenuFacade;
import com.lantone.security.facade.base.SoftwareResourceFacade;
import com.lantone.security.facade.base.UserFacade;
import com.lantone.security.facade.base.UserRoleFacade;
import com.lantone.security.service.impl.RoleSoftwareMenuServiceImpl;
import com.lantone.security.service.impl.RoleSoftwareResourceServiceImpl;
import com.lantone.common.enums.IsDeleteEnum;
import com.lantone.security.enums.DictionaryEnum;
import com.lantone.security.enums.RelationEnum;
import com.lantone.security.enums.ReturnTypeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @ClassName: FuncManagementFacade
 * @Description: 功能管理API
 * @Author songxl
 */
@Component
public class RoleManagementFacade {
    @Autowired
    private RoleFacade roleFacade;
    @Autowired
    private UserFacade userFacade;
    @Autowired
    private UserRoleFacade userRoleFacade;
    @Autowired
    private RoleSoftwareMenuFacade roleSoftwareMenuFacade;
    @Autowired
    private RoleSoftwareResourceFacade roleSoftwareResourceFacade;
    @Autowired
    private SoftwareFacade softwareFacade;
    @Autowired
    private HospitalFacade hospitalFacade;
    @Autowired
    private DictionaryInfoFacade dictionaryInfoFacade;
    @Autowired
    private ResourceFacade resourceFacade;
    @Autowired
    private MenuFacade menuFacade;
    @Autowired
    private SoftwareMenuFacade softwareMenuFacade;
    @Autowired
    private SoftwareResourceFacade softwareResourceFacade;
    @Autowired
    private DataAuthManagementFacade dataAuthManagementFacade;


    /**
     * @param roleId
     * @Description删除角色
     * @Return java.lang.Boolean
     */
    public Boolean deleteRole(Long roleId) {
        if (roleFacade.update(new UpdateWrapper<Role>()
                .set("is_deleted", IsDeleteEnum.Y.getKey())
                .eq("id", roleId)
                .eq("is_deleted", IsDeleteEnum.N.getKey()))) {
            if (roleSoftwareMenuFacade.update(new UpdateWrapper<RoleSoftwareMenu>()
                    .set("is_deleted", IsDeleteEnum.Y.getKey())
                    .eq("role_id", roleId)
                    .eq("is_deleted", IsDeleteEnum.N.getKey()))) {
                return roleSoftwareResourceFacade.update(new UpdateWrapper<RoleSoftwareResource>()
                        .set("is_deleted", IsDeleteEnum.Y.getKey())
                        .eq("role_id", roleId)
                        .eq("is_deleted", IsDeleteEnum.N.getKey()));
            }
        } else {
            Asserts.fail("角色删除失败");
        }
        return false;
    }


    /**
     * @param roleId
     * @Description删除角色
     * @Return java.lang.Boolean
     */
    public Boolean delete(Long roleId) {
        if (roleFacade.remove(new UpdateWrapper<Role>()
                .eq("id", roleId)
                .eq("is_deleted", IsDeleteEnum.N.getKey()))) {
            if (roleSoftwareMenuFacade.remove(new UpdateWrapper<RoleSoftwareMenu>()
                    .eq("role_id", roleId)
                    .eq("is_deleted", IsDeleteEnum.N.getKey()))) {
                return roleSoftwareResourceFacade.remove(new UpdateWrapper<RoleSoftwareResource>()
                        .eq("role_id", roleId)
                        .eq("is_deleted", IsDeleteEnum.N.getKey()));
            }
        } else {
            Asserts.fail("角色删除失败");
        }
        return false;
    }
    /**
     * @param roleId
     * @param status
     * @Description
     * @Return java.lang.Boolean
     */
    public Boolean disableRole(Long roleId, String status) {
        return roleFacade.update(new UpdateWrapper<Role>()
                .set("status", status)
                .eq("id", roleId)
                .eq("is_deleted", IsDeleteEnum.N.getKey()));
    }

    /**
     * @param addRoleVO
     * @Description添加角色
     * @Return java.lang.Boolean
     */
    public Boolean addRole(AddRoleVO addRoleVO) {
        //校验
        checkRole(null, addRoleVO.getName(), addRoleVO.getSoftwares());

        //1.角色表插入角色信息
        addRoleVO.setCreator(SysUserUtils.getCurrentPrincipleId());
        if (addRoleVO.getHospitalId() == null) {
            addRoleVO.setHospitalId(SysUserUtils.getCurrentHospitalId());
        }
        Role role = new Role();
        BeanUtils.copyProperties(addRoleVO, role);
        role.setCreator(SysUserUtils.getCurrentPrincipleId() + "");
        role.setGmtCreate(DateUtil.now());
        if (roleFacade.save(role)) {
            //2.插入角色与系统菜单的对应关系以及角色与功能权限的对应关系sys_role_software_menu,sys_role_software_resource
            return saveRoleSoftwareMenu(addRoleVO.getSoftwares(), role.getId());
        } else {
            Asserts.fail("角色插入失败");
        }
        return false;
    }

    /**
     * @param name
     * @param softwares
     * @Description角色新增修改校验
     * @Return void
     */
    private void checkRole(Long id, String name, List<AddRoleSoftwareVO> softwares) {
        List<Role> roles = roleFacade.list(new QueryWrapper<Role>()
                .eq("hospital_id", SysUserUtils.getCurrentHospitalId())
                .eq("name", name)
                .eq("is_deleted", IsDeleteEnum.N.getKey()));
        if (id == null) {
            if (roles.size() > 0) {
                Asserts.fail("该角色已存在请重新输入");
            }
        } else {
            if (ListUtil.isNotEmpty(roles)) {
                roles.stream().forEach(role -> {
                    if (!id.equals(role.getId())) {
                        Asserts.fail("该角色已存在请重新输入");
                    }
                });
            }
        }

        if (ListUtil.isNotEmpty(softwares)) {
            softwares.stream().forEach(addRoleSoftwareVO -> {
                //移除菜单中的系统信息
                addRoleSoftwareVO.getSoftwareMenuIds().remove(addRoleSoftwareVO.getId());
                //获取菜单比对插入的功能菜单都能正常使用
                List<SoftwareMenu> softwareMenus = softwareMenuFacade.list(new QueryWrapper<SoftwareMenu>()
                        .select("menu_id")
                        .eq("is_deleted", IsDeleteEnum.N.getKey())
                        .in("id", addRoleSoftwareVO.getSoftwareMenuIds()));
                if (ListUtil.isEmpty(softwareMenus)) {
                    Asserts.fail("该功能菜单不存在，刷新后重新添加~");
                }
                if (ListUtil.isNotEmpty(addRoleSoftwareVO.getSoftwareMenuIds())) {
                    if (addRoleSoftwareVO.getSoftwareMenuIds().size() != menuFacade.count(new QueryWrapper<Menu>()
                            .eq("status", StatusEnum.Enable.getKey())
                            .eq("is_deleted", IsDeleteEnum.N.getKey())
                            .in("id", softwareMenus.stream().map(SoftwareMenu::getMenuId).collect(Collectors.toList())))) {
                        Asserts.fail("该角色要绑定的功能菜单已更新请刷新重试~");
                    }
                }
                //功能权限校验
                //获取菜单比对插入的功能菜单都能正常使用
                if (ListUtil.isNotEmpty(addRoleSoftwareVO.getSoftwareResourceIds())) {
                    //去重 菜单对应的功能权限可能是一个
                    List<SoftwareResource> softwareResources = softwareResourceFacade.list(new QueryWrapper<SoftwareResource>()
                            .select("resource_id")
                            .eq("is_deleted", IsDeleteEnum.N.getKey())
                            .in("id", addRoleSoftwareVO.getSoftwareResourceIds()));
                    if (ListUtil.isEmpty(softwareResources)) {
                        Asserts.fail("该功能菜单不存在，刷新后重新添加~");
                    }
                    Set resourceSet = new HashSet(addRoleSoftwareVO.getSoftwareResourceIds());
                    if (resourceSet.size() != resourceFacade.count(new QueryWrapper<Resource>()
                            .eq("status", StatusEnum.Enable.getKey())
                            .eq("is_deleted", IsDeleteEnum.N.getKey())
                            .in("id", softwareResources.stream().map(SoftwareResource::getResourceId).collect(Collectors.toList())))) {
                        Asserts.fail("该角色要绑定的功能菜单已更新请刷新重试~");
                    }
                }
            });
        }
    }

    /**
     * @param softwares
     * @param roleId
     * @Description插入角色与系统、菜单的对应关系
     * @Return void
     */
    public Boolean saveRoleSoftwareMenu(List<AddRoleSoftwareVO> softwares, Long roleId) {
        //插入sys_role_software_menu,sys_role_software_resource
        AtomicReference<Boolean> out = new AtomicReference<>(false);
        //获取角色必备的权限添加给用户
        String hasMenuResourceStr = dictionaryInfoFacade.getDicMap(ReturnTypeEnum.INTERFACE.getKey(),
                Lists.newArrayList(DictionaryEnum.MANAGE_HIDE_MENU.getKey() + ""))
                .get(DictionaryEnum.MANAGE_HIDE_MENU.getKey() + "").get("hasMenuResource");

        softwares.stream().forEach(addRoleSoftwareVO -> {
            JSONObject hasMenuResourceJSON = null;
            if (StringUtil.isNotEmpty(hasMenuResourceStr)) {
                hasMenuResourceJSON = JSONObject.parseObject(hasMenuResourceStr);
            }
            if (ListUtil.isNotEmpty(addRoleSoftwareVO.getSoftwareMenuIds())) {
                //1.添加该角色对应的系统功能菜单关系sys_role_software_menu
                List<RoleSoftwareMenu> roleSoftwareMenus = new ArrayList<>();
                //去重
                Set<Long> softwareMenus = new HashSet(addRoleSoftwareVO.getSoftwareMenuIds());
                try {
                    if (hasMenuResourceJSON != null) {
                        softwareMenus.addAll(hasMenuResourceJSON.getJSONObject(addRoleSoftwareVO.getId() + "")
                                .getJSONArray("menu").toJavaList(Long.class));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                softwareMenus.stream().forEach(softwareMenuId -> {
                    RoleSoftwareMenu roleSoftwareMenu = new RoleSoftwareMenu();
                    roleSoftwareMenu.setRoleId(roleId);
                    roleSoftwareMenu.setSoftwareMenuId(softwareMenuId);
                    roleSoftwareMenus.add(roleSoftwareMenu);
                });
                out.set(new RoleSoftwareMenuServiceImpl().saveBatch(roleSoftwareMenus));
            }
            if (ListUtil.isNotEmpty(addRoleSoftwareVO.getSoftwareResourceIds())) {
                //2.添加该角色对应的系统功能权限关系sys_role_software_resource
                List<RoleSoftwareResource> roleSoftwareResources = new ArrayList<>();
                //资源去重
                Set<Long> softwareResourceIds = new HashSet(addRoleSoftwareVO.getSoftwareResourceIds());
                try {
                    if (hasMenuResourceJSON != null) {
                        softwareResourceIds.addAll(hasMenuResourceJSON.getJSONObject(addRoleSoftwareVO.getId() + "")
                                .getJSONArray("resource").toJavaList(Long.class));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                softwareResourceIds.stream().forEach(softwareResourceId -> {
                    RoleSoftwareResource roleSoftwareResource = new RoleSoftwareResource();
                    roleSoftwareResource.setRoleId(roleId);
                    roleSoftwareResource.setSoftwareResourceId(softwareResourceId);
                    roleSoftwareResources.add(roleSoftwareResource);
                });
                out.set(new RoleSoftwareResourceServiceImpl().saveBatch(roleSoftwareResources));
            }
        });
        return out.get();
    }

    /**
     * @param updateRoleVO
     * @Description修改角色
     * @Return java.lang.Boolean
     */
    public Boolean updateRole(UpdateRoleVO updateRoleVO) {
        //校验
        checkRole(updateRoleVO.getId(), updateRoleVO.getName(), updateRoleVO.getSoftwares());
        //1.删除原来角色系统菜单关联关系、角色系统功能权限关联关系
        if (deleteRoleSoftwareMenu(updateRoleVO.getId())) {
            //2.修改角色基本信息
            if (roleFacade.update(new UpdateWrapper<Role>()
                    .set("name", updateRoleVO.getName())
                    .set("status", updateRoleVO.getStatus())
                    .set(StringUtil.isNotEmpty(updateRoleVO.getRemark()), "remark", updateRoleVO.getRemark())
                    .set(StringUtil.isNotEmpty(updateRoleVO.getOrderNo()), "order_no", updateRoleVO.getOrderNo())
                    .eq("id", updateRoleVO.getId())
                    .eq("is_deleted", IsDeleteEnum.N.getKey()))) {

                return saveRoleSoftwareMenu(updateRoleVO.getSoftwares(), updateRoleVO.getId());
            } else {
                Asserts.fail("角色基本信息修改失败");
            }
        } else {
            Asserts.fail("原来角色与系统菜单关联关系删除失败");
        }
        return false;
    }

    /**
     * @param id
     * @Description删除原来角色系统菜单关联关系、角色系统功能权限关联关系
     * @Return boolean
     */
    private boolean deleteRoleSoftwareMenu(Long id) {
        if (roleSoftwareMenuFacade.remove(new UpdateWrapper<RoleSoftwareMenu>()
                .eq("role_id", id)
                .eq("is_deleted", IsDeleteEnum.N.getKey()))) {
            return roleSoftwareResourceFacade.remove(new UpdateWrapper<RoleSoftwareResource>()
                    .eq("role_id", id)
                    .eq("is_deleted", IsDeleteEnum.N.getKey()));
        }
        return false;
    }

    /**
     * @param getRolePageVO
     * @Description获取角色列表
     * @Return java.util.List<com.lantone.security.dto.RoleDTO>
     */
    public IPage<GetRolePageDTO> getRolePage(GetRolePageVO getRolePageVO) {
        //1.获取当前登录人id和组织id
        getRolePageVO.setCreator(SysUserUtils.getCurrentPrincipleId());
        getRolePageVO.setHospitalId(SysUserUtils.getCurrentHospitalId());
        return roleFacade.getBaseMapper().getRolePage(getRolePageVO);
    }

    /**
     * @param roleId
     * @param type   区分组织管理添加角色、普通添加角色的功能菜单不同
     * @Description通过角色id获取角色详情
     * @Return com.lantone.security.dto.GetRoleDTO
     */
    public GetRoleDTO getRoleById(Long roleId, String type) {
        GetRoleDTO getRoleDTO = new GetRoleDTO();
        //1.获取角色基本信息
        List<Role> roles = roleFacade.list(new QueryWrapper<Role>()
                .eq("id", roleId)
                .eq("is_deleted", IsDeleteEnum.N.getKey()));
        if (ListUtil.isNotEmpty(roles)) {
            BeanUtils.copyProperties(roles.get(0), getRoleDTO);
            //2.获取当前登录用户(管理员)的功能菜单树
            //获取管理员的角色列表
            List<Long> loginRoles = userRoleFacade.getBaseMapper().getUserRoles(SysUserUtils.getCurrentPrincipleId())
                    .stream().map(UserRoleDTO::getRoleId).collect(Collectors.toList());
            if (ListUtil.isNotEmpty(loginRoles)) {
                List<UserMenuResourceTreeDTO> userMenuResourceTreeDTOS = getUserMenuResourceTreeByRoles(loginRoles, roles.stream().map(Role::getId).collect(Collectors.toList()), type);
                //获取用户服务
                List<SoftwareDTO> loginSoftwares = softwareFacade.getBaseMapper().getUserSoftware(loginRoles);
                List<Long> hasSoftwareIds = softwareFacade.getBaseMapper().getUserSoftware(roles.stream().map(Role::getId).collect(Collectors.toList()))
                        .stream().map(SoftwareDTO::getId).collect(Collectors.toList());
                loginSoftwares.stream().forEach(softwareDTO -> {
                    if (hasSoftwareIds.contains(softwareDTO.getId())) {
                        softwareDTO.setRelation(RelationEnum.Y.getName());
                    } else {
                        softwareDTO.setRelation(RelationEnum.N.getName());
                    }
                });
                //添加功能树服务已关联标志
                userMenuResourceTreeDTOS.stream().forEach(userMenuResourceTreeDTO -> {
                    if (hasSoftwareIds.contains(userMenuResourceTreeDTO.getSoftwareId())) {
                        userMenuResourceTreeDTO.setRelation(RelationEnum.Y.getName());
                    } else {
                        userMenuResourceTreeDTO.setRelation(RelationEnum.N.getName());
                    }
                });
                getRoleDTO.setLoginSoftwares(loginSoftwares);
                getRoleDTO.setLoginUserMenuResourceTree(userMenuResourceTreeDTOS);
                return getRoleDTO;
            } else {
                Asserts.fail("该登录用户无角色信息");
            }

        } else {
            Asserts.fail("角色的基本信息不存在");
        }
        return null;
    }

    /**
     * 递归获取菜单结构
     *
     * @param menu    当前菜单
     * @param menuMap 菜单集
     * @return 菜单结构
     */
    public List<GetUserShowTreeDTO> getSonMenu(GetUserShowTreeDTO menu, Map<Long, List<GetUserShowTreeDTO>> menuMap) {
        List<GetUserShowTreeDTO> sonMenu = new ArrayList<>();
        List<GetUserShowTreeDTO> menuList = menuMap.get(menu.getMenuId());
        if (ListUtil.isNotEmpty(menuList)) {
            menu.setChildren(menuList);
            for (GetUserShowTreeDTO bean : menuList) {
                getSonMenu(bean, menuMap);
            }
        }
        return sonMenu;
    }

    /**
     * 递归获取菜单结构
     *
     * @param menu    当前菜单
     * @param menuMap 菜单集
     * @return 菜单结构
     */
    public List<UserMenuResourceTreeDTO> getSonMenu(UserMenuResourceTreeDTO menu, Map<Long, List<UserMenuResourceTreeDTO>> menuMap) {
        List<UserMenuResourceTreeDTO> sonMenu = new ArrayList<>();
        List<UserMenuResourceTreeDTO> menuList = menuMap.get(menu.getMenuId());
        if (ListUtil.isNotEmpty(menuList)) {
            menu.setChildren(menuList);
            for (UserMenuResourceTreeDTO bean : menuList) {
                getSonMenu(bean, menuMap);
            }
        }
        return sonMenu;
    }

    /**
     * @Description
     * @param获取用户功能菜单树
     * @Return java.util.Map<java.lang.Long, java.util.List < com.lantone.security.dto.UserMenuResourceTreeDTO>>
     */
    public List<UserMenuResourceTreeDTO> getUserMenuResourceTree(String type) {
        //1.获取当前用户的角色列表
        List<Long> roles = userRoleFacade.getBaseMapper().getUserRoles(SysUserUtils.getCurrentPrincipleId())
                .stream().map(UserRoleDTO::getRoleId).collect(Collectors.toList());
        if (ListUtil.isNotEmpty(roles)) {
            return getUserMenuResourceTreeByRoles(roles, type);
        } else {
            Asserts.fail("当前登录用户无角色信息");
        }
        return null;
    }

    /**
     * @param roles
     * @Description通过角色列表获取用户功能菜单树
     * @Return java.util.Map<java.lang.Long, java.util.List < com.lantone.security.dto.UserMenuResourceTreeDTO>>
     */
    private List<UserMenuResourceTreeDTO> getUserMenuResourceTreeByRoles(List<Long> roles, String type) {
        List hideMenus = null;
        //获取type下要隐藏的菜单
        String dictionaryInfoStr  = dictionaryInfoFacade.getDicMap(ReturnTypeEnum.INTERFACE.getKey(),
                Lists.newArrayList(DictionaryEnum.MANAGE_HIDE_MENU.getKey() + ""))
                .get(DictionaryEnum.MANAGE_HIDE_MENU.getKey() + "").get("manageHideMenu");
        if (StringUtil.isNotEmpty(dictionaryInfoStr)) {
            try {
                hideMenus = JSONObject.parseObject(dictionaryInfoStr).getJSONArray(type).toJavaList(Long.class);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        List<UserMenuResourceTreeDTO> userMenuResourceTree = roleSoftwareMenuFacade.getBaseMapper().getUserMenuResourceTree(roles, hideMenus);
        return getTree(userMenuResourceTree);
    }

    /**
     * @param loginRoles  当前登录用户的角色列表
     * @param selectRoles 要查询用户的角色列表
     * @Description通过角色列表获取用户功能菜单树
     * @Return java.util.Map<java.lang.Long, java.util.List < com.lantone.security.dto.UserMenuResourceTreeDTO>>
     */
    private List<UserMenuResourceTreeDTO> getUserMenuResourceTreeByRoles(List<Long> loginRoles, List<Long> selectRoles, String type) {
        List hideMenus = null;
        //获取type下要隐藏的菜单
        String dictionaryInfoStr  = dictionaryInfoFacade.getDicMap(ReturnTypeEnum.INTERFACE.getKey(),
                Lists.newArrayList(DictionaryEnum.MANAGE_HIDE_MENU.getKey() + ""))
                .get(DictionaryEnum.MANAGE_HIDE_MENU.getKey() + "").get("manageHideMenu");
        if (StringUtil.isNotEmpty(dictionaryInfoStr)) {
            try {
                hideMenus = JSONObject.parseObject(dictionaryInfoStr).getJSONArray(type).toJavaList(Long.class);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        List<UserMenuResourceTreeDTO> userMenuResourceTree = roleSoftwareMenuFacade.getBaseMapper().getMenuResourceRelation(loginRoles, selectRoles, hideMenus);
        return getTree(userMenuResourceTree);
    }

    private List<UserMenuResourceTreeDTO> getTree(List<UserMenuResourceTreeDTO> userMenuResourceTree) {
        List<UserMenuResourceTreeDTO> resUserMenuResourceTree = new ArrayList<>();
        //2.获取每个系统下的菜单、功能权限
        Map<Long, List<UserMenuResourceTreeDTO>> userMenuResourceMap = EntityUtil
                .makeEntityListMap(userMenuResourceTree, "softwareId");
        //3.获取每个系统下的功能菜单树
        if (!userMenuResourceMap.keySet().isEmpty()) {
            userMenuResourceMap.keySet().stream().forEach(softwareId -> {
                Map<Long, List<UserMenuResourceTreeDTO>> menuResourceMap = EntityUtil
                        .makeEntityListMap(userMenuResourceMap.get(softwareId), "parentId");
                List<UserMenuResourceTreeDTO> menuRes = menuResourceMap.get(0L);
                UserMenuResourceTreeDTO tempSoftware = new UserMenuResourceTreeDTO();
                tempSoftware.setSoftwareId(softwareId);
                for (UserMenuResourceTreeDTO bean : menuRes) {
                    tempSoftware.setSoftwareName(bean.getSoftwareName());
                    getSonMenu(bean, menuResourceMap);
                }
                tempSoftware.setChildren(menuRes);
                resUserMenuResourceTree.add(tempSoftware);
            });
        }
        return resUserMenuResourceTree;
    }

    /**
     * @param
     * @Description获取当前登录用户管理的角色列表
     * @Return java.util.List<com.lantone.security.dto.GetCreateRoleDTO>
     */
    public List<GetCreateRoleDTO> getCreateRoles(Long softwareId) {
        return roleFacade.getBaseMapper().getCreateRoles(SysUserUtils.getCurrentPrincipleId(), softwareId);
    }

    /**
     * @param
     * @Description获取当前登录用户的显示的菜单列表
     * @Return java.util.Map<java.lang.Long, java.util.List < com.lantone.security.dto.GetUserShowTreeDTO>>
     */
    public Map<String, Object> getUserShowMemuTree() {
        if (SysUserUtils.getCurrentSoftwareId() == null) {
            Asserts.fail("请求头服务id为空");
        }
        Long softwareId = SysUserUtils.getCurrentSoftwareId();
        Map<String, Object> out = new HashMap<>();
        AtomicReference<List> notShowSoftwareMenuIds = new AtomicReference<>();
        //1.1获取当前用户的角色列表
        List<Role> roles = roleFacade.list(new QueryWrapper<Role>().
                in("id", userRoleFacade.list(new QueryWrapper<UserRole>()
                        .eq("user_id", SysUserUtils.getCurrentPrincipleId())).stream().map(UserRole::getRoleId).collect(Collectors.toList())));
        //1.2判断该用户是否是管理用户
        if (ListUtil.isNotEmpty(roles.stream().filter(role -> "ManagementRole".equals(role.getRemark())).collect(Collectors.toList()))) {
            Hospital hospital = hospitalFacade.getById(SysUserUtils.getCurrentHospitalId());
            if (hospital != null) {
                //2.获取字典禁用菜单配置
                List<GetDictionaryInfoByTypeDTO> notShowMenus = dictionaryInfoFacade.getBaseMapper()
                        .getDictionaryInfoByType(DictionaryEnum.NOT_SHOW_MENU.getKey());
                notShowMenus.stream().forEach(getDictionaryInfoByTypeDTO -> {
                    if (hospital.getType().equals(getDictionaryInfoByTypeDTO.getName())) {
                        notShowSoftwareMenuIds.set(Arrays.asList(getDictionaryInfoByTypeDTO.getVal().split(",")));
                    }
                });
            }
        }
        List<GetUserShowTreeDTO> getUserShowTreeDTOS = roleSoftwareMenuFacade.getBaseMapper()
                .getUserShowMemuTree(roles.stream().map(Role::getId).collect(Collectors.toList()), notShowSoftwareMenuIds.get(), softwareId);
        //菜单转成树状结构
        if (ListUtil.isNotEmpty(getUserShowTreeDTOS)) {
            out.put("showMenuInfo", getShowTree(getUserShowTreeDTOS).get(softwareId));
        }
        return out;
    }


    private Map<Long, List<GetUserShowTreeDTO>> getShowTree(List<GetUserShowTreeDTO> userMenuResourceTree) {
        Map<Long, List<GetUserShowTreeDTO>> resUserMenuResourceTree = new HashMap<>();
        //2.获取每个系统下的菜单、功能权限
        Map<Long, List<GetUserShowTreeDTO>> userMenuResourceMap = EntityUtil
                .makeEntityListMap(userMenuResourceTree, "softwareId");
        //3.获取每个系统下的功能菜单树
        if (!userMenuResourceMap.keySet().isEmpty()) {
            userMenuResourceMap.keySet().stream().forEach(softwareId -> {
                Map<Long, List<GetUserShowTreeDTO>> menuResourceMap = EntityUtil
                        .makeEntityListMap(userMenuResourceMap.get(softwareId), "parentId");
                List<GetUserShowTreeDTO> menuRes = menuResourceMap.get(0L);
                if (ListUtil.isEmpty(menuRes)) {
                    Asserts.fail("菜单目录为空");
                }
                for (GetUserShowTreeDTO bean : menuRes) {
                    getSonMenu(bean, menuResourceMap);
                }
                resUserMenuResourceTree.put(softwareId, menuRes);
            });
        }
        return resUserMenuResourceTree;
    }
}
