| | |
| | | * 过期时间 |
| | | */ |
| | | private LocalDateTime expiresTime; |
| | | /** |
| | | * 访问令牌 |
| | | */ |
| | | private String accessToken; |
| | | |
| | | // ========== 上下文 ========== |
| | | /** |
对比新文件 |
| | |
| | | package com.iailab.module.infra.controller.admin.actuator; |
| | | |
| | | import cn.hutool.core.util.NumberUtil; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.iailab.framework.common.pojo.CommonResult; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import javax.swing.filechooser.FileSystemView; |
| | | import java.io.File; |
| | | import java.lang.management.ManagementFactory; |
| | | import java.lang.management.OperatingSystemMXBean; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @Description: 硬盘内存监控等 |
| | | * @author: iailab |
| | | */ |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping("/infra/actuator") |
| | | public class ActuatorController { |
| | | |
| | | |
| | | /** |
| | | * 内存详情 |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | @GetMapping("/memory/info") |
| | | public CommonResult<?> getRedisInfo() throws Exception { |
| | | OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); |
| | | JSONObject operatingSystemJson = JSONObject.parseObject(JSONObject.toJSONString(operatingSystemMXBean)); |
| | | long totalPhysicalMemory = operatingSystemJson.getLongValue("totalPhysicalMemorySize"); |
| | | long freePhysicalMemory = operatingSystemJson.getLongValue("freePhysicalMemorySize"); |
| | | long usedPhysicalMemory = totalPhysicalMemory - freePhysicalMemory; |
| | | Runtime runtime = Runtime.getRuntime(); |
| | | Map<String,Number> result = new HashMap<>(); |
| | | result.put("memory.physical.total", totalPhysicalMemory); |
| | | result.put("memory.physical.used", freePhysicalMemory); |
| | | result.put("memory.physical.free", usedPhysicalMemory); |
| | | result.put("memory.physical.usage", NumberUtil.div(usedPhysicalMemory, totalPhysicalMemory)); |
| | | result.put("memory.runtime.total", runtime.totalMemory()); |
| | | result.put("memory.runtime.used", runtime.freeMemory()); |
| | | result.put("memory.runtime.max", runtime.totalMemory() - runtime.freeMemory()); |
| | | result.put("memory.runtime.free", runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory()); |
| | | result.put("memory.runtime.usage", NumberUtil.div(runtime.totalMemory() - runtime.freeMemory(), runtime.totalMemory())); |
| | | return CommonResult.success(result); |
| | | } |
| | | |
| | | /** |
| | | * @功能:获取磁盘信息 |
| | | * @return |
| | | */ |
| | | @GetMapping("/disk/info") |
| | | public CommonResult<List<Map<String,Object>>> queryDiskInfo(){ |
| | | CommonResult<List<Map<String,Object>>> res = new CommonResult<>(); |
| | | try { |
| | | // 当前文件系统类 |
| | | FileSystemView fsv = FileSystemView.getFileSystemView(); |
| | | // 列出所有windows 磁盘 |
| | | File[] fs = File.listRoots(); |
| | | log.info("查询磁盘信息:"+fs.length+"个"); |
| | | List<Map<String,Object>> list = new ArrayList<>(); |
| | | for (int i = 0; i < fs.length; i++) { |
| | | if(fs[i].getTotalSpace()==0) { |
| | | continue; |
| | | } |
| | | Map<String,Object> map = new HashMap(5); |
| | | map.put("name", fsv.getSystemDisplayName(fs[i])); |
| | | map.put("max", fs[i].getTotalSpace()); |
| | | map.put("rest", fs[i].getFreeSpace()); |
| | | map.put("restPPT", (fs[i].getTotalSpace()-fs[i].getFreeSpace())*100/fs[i].getTotalSpace()); |
| | | list.add(map); |
| | | log.info(map.toString()); |
| | | } |
| | | res.setData(list); |
| | | res.success("查询成功"); |
| | | } catch (Exception e) { |
| | | res.setMsg("查询失败"+e.getMessage()); |
| | | } |
| | | return res; |
| | | } |
| | | |
| | | } |
| | |
| | | @Operation(summary = "刷新访问令牌") |
| | | @Parameters({ |
| | | @Parameter(name = "refreshToken", description = "刷新令牌", required = true, example = "haha"), |
| | | @Parameter(name = "clientId", description = "客户端编号", required = true, example = "iailabyuanma") |
| | | @Parameter(name = "clientId", description = "客户端编号", required = true, example = "iailab") |
| | | }) |
| | | CommonResult<OAuth2AccessTokenRespDTO> refreshAccessToken(@RequestParam("refreshToken") String refreshToken, |
| | | @RequestParam("clientId") String clientId); |
| | |
| | | import com.iailab.module.system.controller.admin.app.vo.AppPageReqVO; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppRespVO; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppSaveReqVO; |
| | | import com.iailab.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO; |
| | | import com.iailab.module.system.dal.dataobject.app.AppDO; |
| | | import com.iailab.module.system.service.app.AppService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | |
| | | return success(BeanUtils.toBean(appDOS, AppRespVO.class)); |
| | | } |
| | | |
| | | // @GetMapping("/getAppMenu") |
| | | // @Operation(summary = "获得应用菜单列表") |
| | | // @PreAuthorize("@ss.hasPermission('system:app-menu:query')") |
| | | // @Parameter(name = "id", description = "ID", required = true, example = "1024") |
| | | // public CommonResult<List<AppRespVO>> getAppMenu(@RequestParam("id") Long id) { |
| | | // List<AppMenuRespDTO> appDOS = appService.getAppMenu(id); |
| | | // return success(BeanUtils.toBean(appDOS, AppRespVO.class)); |
| | | // } |
| | | @GetMapping("/getAppMenu") |
| | | @Operation(summary = "获得应用菜单列表") |
| | | @PreAuthorize("@ss.hasPermission('system:app-menu:query')") |
| | | @Parameter(name = "id", description = "ID", required = true, example = "1024") |
| | | public CommonResult<List<AppRespVO>> getAppMenu(@RequestParam("id") Long id) { |
| | | List<AuthPermissionInfoRespVO.MenuVO> appDOS = appService.getAppMenu(id); |
| | | return success(BeanUtils.toBean(appDOS, AppRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导出租户 Excel") |
| | |
| | | import com.iailab.framework.common.enums.CommonStatusEnum; |
| | | import com.iailab.framework.common.enums.UserTypeEnum; |
| | | import com.iailab.framework.common.pojo.CommonResult; |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.framework.security.config.SecurityProperties; |
| | | import com.iailab.framework.security.core.util.SecurityFrameworkUtils; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppMenuRespVO; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppRespVO; |
| | | import com.iailab.module.system.controller.admin.auth.vo.*; |
| | | import com.iailab.module.system.controller.admin.permission.vo.menu.MenuListReqVO; |
| | | import com.iailab.module.system.controller.admin.permission.vo.menu.MenuRespVO; |
| | | import com.iailab.module.system.convert.auth.AuthConvert; |
| | | import com.iailab.module.system.dal.dataobject.app.AppDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.MenuDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.RoleDO; |
| | | import com.iailab.module.system.dal.dataobject.user.AdminUserDO; |
| | | import com.iailab.module.system.enums.logger.LoginLogTypeEnum; |
| | | import com.iailab.module.system.enums.permission.MenuTypeEnum; |
| | | import com.iailab.module.system.service.app.AppService; |
| | | import com.iailab.module.system.service.auth.AdminAuthService; |
| | | import com.iailab.module.system.service.permission.MenuService; |
| | |
| | | import javax.annotation.security.PermitAll; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.validation.Valid; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static com.iailab.framework.common.pojo.CommonResult.success; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertSet; |
| | |
| | | return success(AuthConvert.INSTANCE.convert(user, roles, menuList)); |
| | | } |
| | | |
| | | @GetMapping("/get-app-permission-info") |
| | | @GetMapping("/get-app-permission") |
| | | @Operation(summary = "获取登录用户的app权限信息") |
| | | public CommonResult<AuthPermissionInfoRespVO> getAppPermissionInfo() { |
| | | public CommonResult<List<AppRespVO>> getAppPermission() { |
| | | List<AppRespVO> appList = new ArrayList<>(); |
| | | // 1.1 获得用户信息 |
| | | AdminUserDO user = userService.getUser(getLoginUserId()); |
| | | if (user == null) { |
| | | return success(null); |
| | | } |
| | | |
| | | // 1.2 获得角色列表 |
| | | Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId()); |
| | | if (CollUtil.isEmpty(roleIds)) { |
| | | return success(AuthConvert.INSTANCE.convert(user, Collections.emptyList(), Collections.emptyList())); |
| | | return success(appList); |
| | | } |
| | | List<RoleDO> roles = roleService.getRoleList(roleIds); |
| | | roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色 |
| | | |
| | | // 1.3 获得应用菜单列表 |
| | | MenuListReqVO reqVO = new MenuListReqVO(); |
| | | List<MenuDO> appMenuList = menuService.getAppMenuList(reqVO); |
| | | Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId)); |
| | | List<MenuDO> menuList = menuService.getMenuList(menuIds); |
| | | menuList.retainAll(appMenuList); |
| | | //只要一级菜单,一级菜单即是应用 |
| | | menuList = menuList.stream().filter(menu -> menu.getParentId() == 0l).collect(Collectors.toList()); |
| | | menuList = menuService.filterDisableMenus(menuList); |
| | | List<Long> ids = menuList.stream().map(MenuDO::getAppId).collect(Collectors.toList()); |
| | | List<AppDO> appDOS = appService.selectBatchIds(ids); |
| | | //排序 |
| | | Collections.sort(appDOS, Comparator.comparing(AppDO::getOrderNum)); |
| | | // 2. 拼接结果返回 |
| | | return success(AuthConvert.INSTANCE.convertAppMenu(user, roles, menuList)); |
| | | return success(BeanUtils.toBean(appDOS, AppRespVO.class)); |
| | | } |
| | | |
| | | @GetMapping("/get-app-menu-permission") |
| | | @Operation(summary = "获取登录用户的app权限信息") |
| | | public CommonResult<List<AuthPermissionInfoRespVO.MenuVO>> getAppMenuPermission(@RequestParam("id") Long id) { |
| | | List<AuthPermissionInfoRespVO.MenuVO> menuVOS = new ArrayList<>(); |
| | | // 1.1 获得用户信息 |
| | | AdminUserDO user = userService.getUser(getLoginUserId()); |
| | | if (user == null) { |
| | | return success(null); |
| | | } |
| | | // 1.2 获得角色列表 |
| | | Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId()); |
| | | if (CollUtil.isEmpty(roleIds)) { |
| | | return success(menuVOS); |
| | | } |
| | | List<RoleDO> roles = roleService.getRoleList(roleIds); |
| | | roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色 |
| | | |
| | | // 1.3 获得应用菜单列表 |
| | | Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId)); |
| | | List<MenuDO> menuList = menuService.getMenuList(menuIds); |
| | | menuList = menuService.filterDisableMenus(menuList); |
| | | MenuDO menuDO = menuService.getMenuByAppId(id); |
| | | List<MenuDO> children = new LinkedList<>(); |
| | | // 遍历每一层 |
| | | Collection<Long> parentIds = Collections.singleton(menuDO.getId()); |
| | | for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环 |
| | | // 查询当前层,所有的子应用菜单 |
| | | List<MenuDO> menus = menuService.selectListByParentId(parentIds); |
| | | // 1. 如果没有子菜单,则结束遍历 |
| | | if (CollUtil.isEmpty(menus)) { |
| | | break; |
| | | } |
| | | // 2. 如果有子应用菜单,继续遍历 |
| | | children.addAll(menus); |
| | | parentIds = convertSet(menus, MenuDO::getId); |
| | | } |
| | | children.retainAll(menuList); |
| | | List<MenuDO> tempChildren = new LinkedList<>(); |
| | | //为每一个二级菜单增加一个隐藏父级目录 |
| | | children.stream().forEach(menu -> { |
| | | if (menu.getType().equals(MenuTypeEnum.MENU.getType()) && menu.getParentId().equals(menuDO.getId())) { |
| | | MenuDO parentMenu = BeanUtils.toBean(menu, MenuDO.class); |
| | | parentMenu.setId(System.currentTimeMillis() + (int) (Math.random() * (99999 - 10000 + 1)) + 10000); |
| | | parentMenu.setType(MenuTypeEnum.DIR.getType()); |
| | | parentMenu.setVisible(true); |
| | | parentMenu.setAlwaysShow(false); |
| | | parentMenu.setParentId(menuDO.getId()); |
| | | menu.setParentId(parentMenu.getId()); |
| | | tempChildren.add(parentMenu); |
| | | tempChildren.add(menu); |
| | | } else { |
| | | tempChildren.add(menu); |
| | | } |
| | | }); |
| | | menuVOS = AuthConvert.INSTANCE.buildMenuTree(tempChildren, menuDO.getId(), menuDO.getPath()); |
| | | // 2. 拼接结果返回 |
| | | return success(menuVOS); |
| | | } |
| | | |
| | | // ========== 短信登录相关 ========== |
| | |
| | | import com.iailab.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAccessTokenRespVO; |
| | | import com.iailab.module.system.controller.admin.oauth2.vo.open.OAuth2OpenAuthorizeInfoRespVO; |
| | | import com.iailab.module.system.controller.admin.oauth2.vo.open.OAuth2OpenCheckTokenRespVO; |
| | | import com.iailab.module.system.controller.admin.oauth2.vo.open.OAuth2OpenLoginReqVO; |
| | | import com.iailab.module.system.convert.oauth2.OAuth2OpenConvert; |
| | | import com.iailab.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; |
| | | import com.iailab.module.system.dal.dataobject.oauth2.OAuth2ApproveDO; |
| | |
| | | @PostMapping("/token") |
| | | @PermitAll |
| | | @Operation(summary = "获得访问令牌", description = "适合 code 授权码模式,或者 implicit 简化模式;在 sso.vue 单点登录界面被【获取】调用") |
| | | @Parameters({ |
| | | @Parameter(name = "grant_type", required = true, description = "授权类型", example = "code"), |
| | | @Parameter(name = "code", description = "授权范围", example = "userinfo.read"), |
| | | @Parameter(name = "redirect_uri", description = "重定向 URI", example = "https://www.baidu.com"), |
| | | @Parameter(name = "state", description = "状态", example = "1"), |
| | | @Parameter(name = "username", example = "tudou"), |
| | | @Parameter(name = "password", example = "cai"), // 多个使用空格分隔 |
| | | @Parameter(name = "scope", example = "user_info"), |
| | | @Parameter(name = "refresh_token", example = "123424233"), |
| | | }) |
| | | public CommonResult<OAuth2OpenAccessTokenRespVO> postAccessToken(HttpServletRequest request, |
| | | @RequestBody OAuth2OpenLoginReqVO openLoginReqVO) { |
| | | String code = openLoginReqVO.getCode(); |
| | | String scope = openLoginReqVO.getScope(); |
| | | String grantType = openLoginReqVO.getGrantType(); |
| | | String redirectUri = openLoginReqVO.getRedirectUri(); |
| | | String state = openLoginReqVO.getState(); |
| | | String username = openLoginReqVO.getUsername(); |
| | | String password = openLoginReqVO.getPassword(); |
| | | String refreshToken = openLoginReqVO.getRefreshToken(); |
| | | @RequestParam("grant_type") String grantType, |
| | | @RequestParam(value = "code", required = false) String code, // 授权码模式 |
| | | @RequestParam(value = "redirect_uri", required = false) String redirectUri, // 授权码模式 |
| | | @RequestParam(value = "state", required = false) String state, // 授权码模式 |
| | | @RequestParam(value = "username", required = false) String username, // 密码模式 |
| | | @RequestParam(value = "password", required = false) String password, // 密码模式 |
| | | @RequestParam(value = "scope", required = false) String scope, // 密码模式 |
| | | @RequestParam(value = "refresh_token", required = false) String refreshToken) { // 刷新模式 |
| | | List<String> scopes = OAuth2Utils.buildScopes(scope); |
| | | // 1.1 校验授权类型 |
| | | OAuth2GrantTypeEnum grantTypeEnum = OAuth2GrantTypeEnum.getByGrantType(grantType); |
| | |
| | | @Builder |
| | | public class OAuth2OpenLoginReqVO { |
| | | |
| | | // @Schema(description = "客户端编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "tudou") |
| | | // private String clientId; |
| | | // |
| | | // @Schema(description = "客户端密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "fan") |
| | | // private String clientSecret; |
| | | |
| | | @Schema(description = "授权类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "password") |
| | | private String grantType; |
| | | |
| | |
| | | return success(true); |
| | | } |
| | | |
| | | @PostMapping("/assign-role-app-menu") |
| | | @Operation(summary = "赋予角色菜单") |
| | | @PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')") |
| | | public CommonResult<Boolean> assignRoleAppMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) { |
| | | // 执行菜单的分配 |
| | | permissionService.assignRoleAppMenu(reqVO.getRoleId(), reqVO.getMenuIds()); |
| | | return success(true); |
| | | } |
| | | // @PostMapping("/assign-role-app-menu") |
| | | // @Operation(summary = "赋予角色菜单") |
| | | // @PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')") |
| | | // public CommonResult<Boolean> assignRoleAppMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) { |
| | | // // 执行菜单的分配 |
| | | // permissionService.assignRoleAppMenu(reqVO.getRoleId(), reqVO.getMenuIds()); |
| | | // return success(true); |
| | | // } |
| | | |
| | | @PostMapping("/assign-role-data-scope") |
| | | @Operation(summary = "赋予角色数据权限") |
| | |
| | | parentNode.setChildren(new ArrayList<>()); |
| | | } |
| | | parentNode.getChildren().add(childNode); |
| | | |
| | | }); |
| | | // 获得到所有的根节点 |
| | | List<AuthPermissionInfoRespVO.MenuVO> menuVOS = filterList(treeNodeMap.values(), node -> id.equals(node.getParentId())); |
| | |
| | | package com.iailab.module.system.service.app; |
| | | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.module.system.api.app.dto.AppMenuRespDTO; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppPageReqVO; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppSaveReqVO; |
| | | import com.iailab.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO; |
| | | import com.iailab.module.system.dal.dataobject.app.AppDO; |
| | | |
| | | import java.util.List; |
| | |
| | | |
| | | AppDO getAppByTenantId(Long tenantId); |
| | | |
| | | // List<AppMenuRespDTO> getAppMenu(Long id); |
| | | List<AuthPermissionInfoRespVO.MenuVO> getAppMenu(Long id); |
| | | |
| | | List<AppDO> selectBatchIds(List<Long> ids); |
| | | |
| | | } |
| | |
| | | package com.iailab.module.system.service.app; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | |
| | | import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import com.iailab.framework.security.core.util.SecurityFrameworkUtils; |
| | | import com.iailab.framework.tenant.core.aop.TenantIgnore; |
| | | import com.iailab.module.system.api.app.dto.AppMenuRespDTO; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppPageReqVO; |
| | | import com.iailab.module.system.controller.admin.app.vo.AppSaveReqVO; |
| | | import com.iailab.module.system.controller.admin.auth.vo.AuthPermissionInfoRespVO; |
| | | import com.iailab.module.system.convert.auth.AuthConvert; |
| | | import com.iailab.module.system.dal.dataobject.app.AppDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.MenuDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.RoleDO; |
| | |
| | | import com.iailab.module.system.dal.mysql.tenant.TenantMapper; |
| | | import com.iailab.module.system.dal.mysql.tenant.TenantPackageMapper; |
| | | import com.iailab.module.system.enums.permission.MenuTypeEnum; |
| | | import com.iailab.module.system.service.permission.MenuService; |
| | | import com.iailab.module.system.service.permission.PermissionService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | |
| | | import java.util.*; |
| | | |
| | | import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static com.iailab.framework.tenant.core.context.TenantContextHolder.getTenantId; |
| | | import static com.iailab.module.system.enums.ErrorCodeConstants.MENU_EXISTS_CHILDREN; |
| | | import static com.iailab.module.system.enums.ErrorCodeConstants.MENU_NOT_EXISTS; |
| | |
| | | |
| | | @Resource |
| | | private TenantMapper tenantMapper; |
| | | |
| | | @Resource |
| | | private MenuService menuService; |
| | | |
| | | |
| | | @Override |
| | |
| | | //查询系统应用菜单 |
| | | // List<MenuDO> menuDOS = menuMapper.selectList(menuDOLambdaQueryWrapperX); |
| | | // List<AppDO> systemApps = convertMenuToApp(menuDOS); |
| | | //创建一个系统管理应用菜单 |
| | | AppDO aDo = new AppDO(); |
| | | aDo.setAppType(1); |
| | | aDo.setAppName("系统管理"); |
| | | aDo.setOrderNum(0); |
| | | List<AppDO> systemApps = new ArrayList<>(); |
| | | systemApps.add(aDo); |
| | | List<AppDO> appDOS = appMapper.selectList(); |
| | | //暂时先遍历处理应用菜单和应用类型 |
| | | appDOS.stream().forEach(appDO -> { |
| | |
| | | } |
| | | } |
| | | |
| | | // @Override |
| | | // public List<MenuRespDTO> getAppMenu(Long id) { |
| | | // |
| | | // List<MenuDO> children = new LinkedList<>(); |
| | | // // 遍历每一层 |
| | | // Collection<Long> parentIds = Collections.singleton(id); |
| | | // for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环 |
| | | // // 查询当前层,所有的子应用菜单 |
| | | // List<MenuDO> menus = menuMapper.selectListByParentId(parentIds); |
| | | // // 1. 如果没有子菜单,则结束遍历 |
| | | // if (CollUtil.isEmpty(menus)) { |
| | | // break; |
| | | // } |
| | | // // 2. 如果有子应用菜单,继续遍历 |
| | | // children.addAll(menus); |
| | | // parentIds = convertSet(menus, MenuDO::getId); |
| | | // } |
| | | // children = menuService.filterDisableMenus(children); |
| | | // return AuthConvert.INSTANCE.buildMenuTree(id, children); |
| | | // |
| | | // } |
| | | @Override |
| | | public List<AuthPermissionInfoRespVO.MenuVO> getAppMenu(Long id) { |
| | | MenuDO menuDO = menuMapper.selectById(id); |
| | | |
| | | List<MenuDO> children = new LinkedList<>(); |
| | | // 遍历每一层 |
| | | Collection<Long> parentIds = Collections.singleton(id); |
| | | for (int i = 0; i < Short.MAX_VALUE; i++) { // 使用 Short.MAX_VALUE 避免 bug 场景下,存在死循环 |
| | | // 查询当前层,所有的子应用菜单 |
| | | List<MenuDO> menus = menuMapper.selectListByParentId(parentIds); |
| | | // 1. 如果没有子菜单,则结束遍历 |
| | | if (CollUtil.isEmpty(menus)) { |
| | | break; |
| | | } |
| | | // 2. 如果有子应用菜单,继续遍历 |
| | | children.addAll(menus); |
| | | parentIds = convertSet(menus, MenuDO::getId); |
| | | } |
| | | children = menuService.filterDisableMenus(children); |
| | | return AuthConvert.INSTANCE.buildMenuTree(children, id, menuDO.getPath()); |
| | | |
| | | } |
| | | |
| | | private void dealAppMenu(Integer type, AppDO app){ |
| | | String loginUserNickname = SecurityFrameworkUtils.getLoginUserNickname(); |
| | |
| | | menuDO.setCreator(loginUserNickname); |
| | | menuDO.setCreateTime(app.getCreateTime()); |
| | | menuMapper.insert(menuDO); |
| | | //内置租户角色分配菜单 |
| | | assignRoleMenu(menuDO.getId(), app.getTenantId()); |
| | | // //内置租户角色分配菜单 |
| | | // assignRoleMenu(menuDO.getId(), app.getTenantId()); |
| | | } else if(type == 2){ |
| | | LambdaUpdateWrapper<MenuDO> updateWrapper = new LambdaUpdateWrapper<>(); |
| | | updateWrapper.eq(MenuDO::getAppId, app.getId()); |
| | |
| | | menuDO.setCreator(loginUserNickname); |
| | | menuDO.setCreateTime(app.getCreateTime()); |
| | | menuMapper.insert(menuDO); |
| | | //内置租户角色分配菜单 |
| | | assignRoleMenu(menuDO.getId(), app.getTenantId()); |
| | | // //内置租户角色分配菜单 |
| | | // assignRoleMenu(menuDO.getId(), app.getTenantId()); |
| | | } |
| | | } else if(type == 3){ |
| | | //删除租户、角色权限 |
| | |
| | | menuWrapper.eq(MenuDO::getType, MenuTypeEnum.DIR.getType()); |
| | | MenuDO menu = menuMapper.selectOne(menuWrapper); |
| | | TenantDO tenantDO = tenantMapper.selectById(app.getTenantId()); |
| | | TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId()); |
| | | Set<Long> menuIds = tenantPackageDO.getMenuIds(); |
| | | menuIds.remove(menu.getId()); |
| | | // 校验是否还有子菜单 |
| | | if (menuMapper.selectCountByParentId(menu.getId()) > 0) { |
| | | throw exception(MENU_EXISTS_CHILDREN); |
| | | if(ObjectUtils.isNotEmpty(menu) && ObjectUtils.isNotEmpty(tenantDO)) { |
| | | TenantPackageDO tenantPackageDO = tenantPackageMapper.selectById(tenantDO.getPackageId()); |
| | | Set<Long> menuIds = tenantPackageDO.getMenuIds(); |
| | | menuIds.remove(menu.getId()); |
| | | // 校验是否还有子菜单 |
| | | if (menuMapper.selectCountByParentId(menu.getId()) > 0) { |
| | | throw exception(MENU_EXISTS_CHILDREN); |
| | | } |
| | | // 校验删除的菜单是否存在 |
| | | if (menuMapper.selectById(menu.getId()) == null) { |
| | | throw exception(MENU_NOT_EXISTS); |
| | | } |
| | | // 标记删除 |
| | | menuMapper.deleteById(menu.getId()); |
| | | // 删除授予给角色的权限 |
| | | permissionService.processMenuDeleted(menu.getId()); |
| | | //删除菜单 |
| | | menuMapper.delete(menuWrapper); |
| | | } |
| | | // 校验删除的菜单是否存在 |
| | | if (menuMapper.selectById(menu.getId()) == null) { |
| | | throw exception(MENU_NOT_EXISTS); |
| | | } |
| | | // 标记删除 |
| | | menuMapper.deleteById(menu.getId()); |
| | | // 删除授予给角色的权限 |
| | | permissionService.processMenuDeleted(menu.getId()); |
| | | //删除菜单 |
| | | menuMapper.delete(menuWrapper); |
| | | } |
| | | } |
| | | |
| | |
| | | return appDOS; |
| | | } |
| | | |
| | | public List<AppDO> selectBatchIds(List<Long> ids) { |
| | | List<AppDO> appDOS = appMapper.selectBatchIds(ids); |
| | | return appDOS; |
| | | } |
| | | |
| | | } |
| | |
| | | MenuDO getMenu(Long id); |
| | | |
| | | /** |
| | | * 根据应用id获得菜单 |
| | | * |
| | | * @param id 菜单编号 |
| | | * @return 菜单 |
| | | */ |
| | | MenuDO getMenuByAppId(Long id); |
| | | |
| | | /** |
| | | * 获得菜单数组 |
| | | * |
| | | * @param ids 菜单编号数组 |
| | |
| | | */ |
| | | List<MenuDO> getMenuList(Collection<Long> ids); |
| | | |
| | | /** |
| | | * 根据父id查询菜单 |
| | | * @param ids |
| | | * @return |
| | | */ |
| | | List<MenuDO> selectListByParentId(Collection<Long> ids); |
| | | |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.google.common.annotations.VisibleForTesting; |
| | | import com.google.common.collect.Lists; |
| | | import com.iailab.framework.common.enums.CommonStatusEnum; |
| | |
| | | import com.iailab.module.system.dal.dataobject.app.AppDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.MenuDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.RoleDO; |
| | | import com.iailab.module.system.dal.dataobject.permission.RoleMenuDO; |
| | | import com.iailab.module.system.dal.dataobject.tenant.TenantDO; |
| | | import com.iailab.module.system.dal.dataobject.tenant.TenantPackageDO; |
| | | import com.iailab.module.system.dal.mysql.permission.MenuMapper; |
| | | import com.iailab.module.system.dal.mysql.permission.RoleMenuMapper; |
| | | import com.iailab.module.system.dal.redis.RedisKeyConstants; |
| | | import com.iailab.module.system.enums.permission.MenuTypeEnum; |
| | | import com.iailab.module.system.service.app.AppService; |
| | | import com.iailab.module.system.service.tenant.TenantPackageService; |
| | | import com.iailab.module.system.service.tenant.TenantService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.lang3.ObjectUtils; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.context.annotation.Lazy; |
| | |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static com.iailab.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertMap; |
| | | import static com.iailab.framework.common.pojo.CommonResult.success; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.*; |
| | | import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | import static com.iailab.framework.tenant.core.context.TenantContextHolder.getTenantId; |
| | | import static com.iailab.module.system.dal.dataobject.permission.MenuDO.ID_ROOT; |
| | | import static com.iailab.module.system.enums.ErrorCodeConstants.*; |
| | |
| | | |
| | | @Resource |
| | | private RoleService roleService; |
| | | |
| | | @Resource |
| | | private RoleMenuMapper roleMenuMapper; |
| | | |
| | | @Override |
| | | @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#createReqVO.permission", |
| | |
| | | public List<MenuDO> getAppMenuList(MenuListReqVO reqVO) { |
| | | // 获取 tenantId |
| | | Long tenantId = getTenantId(); |
| | | return menuMapper.selectAppMenuList(tenantId, reqVO); |
| | | List<MenuDO> menuDOS = menuMapper.selectAppMenuList(tenantId, reqVO); |
| | | Set<Long> menuDOIds = menuDOS.stream().map(MenuDO::getId).collect(Collectors.toSet()); |
| | | // 获得角色列表 |
| | | Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId()); |
| | | List<RoleDO> roles = roleService.getRoleList(roleIds); |
| | | roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色 |
| | | if (roles.stream().noneMatch(role -> role.getCode().equals("tenant_admin"))) { |
| | | // 获得菜单列表 |
| | | Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId)); |
| | | //取交集 |
| | | menuIds.retainAll(menuDOIds); |
| | | List<MenuDO> menuList = getMenuList(menuIds); |
| | | menuList = filterDisableMenus(menuList); |
| | | return menuList; |
| | | } |
| | | return menuDOS; |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public MenuDO getMenuByAppId(Long id) { |
| | | return menuMapper.selectOne(new LambdaQueryWrapper<MenuDO>().eq(MenuDO::getAppId, id).eq(MenuDO::getParentId, 0l)); |
| | | } |
| | | |
| | | @Override |
| | | public List<MenuDO> getMenuList(Collection<Long> ids) { |
| | | // 当 ids 为空时,返回一个空的实例对象 |
| | | if (CollUtil.isEmpty(ids)) { |
| | | return Lists.newArrayList(); |
| | | } |
| | | return menuMapper.selectBatchIds(ids); |
| | | } |
| | | |
| | | @Override |
| | | public List<MenuDO> selectListByParentId(Collection<Long> ids) { |
| | | return menuMapper.selectListByParentId(ids); |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | private void dealPermission(MenuDO menu) { |
| | | Long tenantId = menu.getTenantId(); |
| | | RoleDO role = roleService.getTenantAdminRole(tenantId); |
| | | RoleDO tenantRole = roleService.getTenantAdminRole(tenantId); |
| | | TenantDO tenant = tenantService.getTenant(tenantId); |
| | | TenantPackageDO tenantPackage = tenantPackageService.getTenantPackage(tenant.getPackageId()); |
| | | Set<Long> menuIds = tenantPackage.getMenuIds(); |
| | | menuIds.add(menu.getId()); |
| | | tenantPackage.setMenuIds(menuIds); |
| | | tenantPackageService.updateTenantPackage(BeanUtils.toBean(tenantPackage, TenantPackageSaveReqVO.class)); |
| | | permissionService.assignRoleMenu(role.getId(), menuIds); |
| | | permissionService.assignRoleMenu(tenantRole.getId(), menuIds); |
| | | // 开发者自己创建的应用菜单默认赋权给创建者所拥有的角色 |
| | | //查询当前用户所拥有的角色 |
| | | Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId()); |
| | | List<RoleDO> roles = roleService.getRoleList(roleIds); |
| | | roles.removeIf(role -> !CommonStatusEnum.ENABLE.getStatus().equals(role.getStatus())); // 移除禁用的角色 |
| | | roles.removeIf(role -> tenantRole.getId().equals(role.getId())); // 移除租户管理员角色 |
| | | if (!roles.isEmpty()) { |
| | | roles.stream().forEach(roleDO -> { |
| | | RoleMenuDO roleMenuDO = new RoleMenuDO(); |
| | | roleMenuDO.setMenuId(menu.getId()); |
| | | roleMenuDO.setRoleId(roleDO.getId()); |
| | | roleMenuDO.setTenantId(tenant.getId()); |
| | | roleMenuMapper.insert(roleMenuDO); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | * @param roleId 角色编号 |
| | | * @param menuIds 菜单编号集合 |
| | | */ |
| | | void assignRoleAppMenu(Long roleId, Set<Long> menuIds); |
| | | // void assignRoleAppMenu(Long roleId, Set<Long> menuIds); |
| | | |
| | | /** |
| | | * 处理角色删除时,删除关联授权数据 |
| | |
| | | |
| | | // ========== 角色-菜单的相关方法 ========== |
| | | |
| | | @Override |
| | | @DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换 |
| | | @CacheEvict(value = RedisKeyConstants.MENU_ROLE_ID_LIST, |
| | | allEntries = true) // allEntries 清空所有缓存,主要一次更新涉及到的 menuIds 较多,反倒批量会更快 |
| | | public void assignRoleAppMenu(Long roleId, Set<Long> menuIds) { |
| | | // 获得角色拥有应用菜单编号 |
| | | MenuListReqVO reqVO = new MenuListReqVO(); |
| | | List<MenuDO> appMenuList = menuService.getAppMenuList(reqVO); |
| | | Set<Long> appMenuIds = convertSet(appMenuList, MenuDO::getId); |
| | | Set<Long> dbMenuIds = convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId); |
| | | dbMenuIds.retainAll(appMenuIds); |
| | | // 计算新增和删除的菜单编号 |
| | | Set<Long> menuIdList = CollUtil.emptyIfNull(menuIds); |
| | | Collection<Long> createMenuIds = CollUtil.subtract(menuIdList, dbMenuIds); |
| | | Collection<Long> deleteMenuIds = CollUtil.subtract(dbMenuIds, menuIdList); |
| | | // 执行新增和删除。对于已经授权的菜单,不用做任何处理 |
| | | if (CollUtil.isNotEmpty(createMenuIds)) { |
| | | roleMenuMapper.insertBatch(CollectionUtils.convertList(createMenuIds, menuId -> { |
| | | RoleMenuDO entity = new RoleMenuDO(); |
| | | entity.setRoleId(roleId); |
| | | entity.setMenuId(menuId); |
| | | return entity; |
| | | })); |
| | | } |
| | | if (CollUtil.isNotEmpty(deleteMenuIds)) { |
| | | roleMenuMapper.deleteListByRoleIdAndMenuIds(roleId, deleteMenuIds); |
| | | } |
| | | } |
| | | // @Override |
| | | // @DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换 |
| | | // @CacheEvict(value = RedisKeyConstants.MENU_ROLE_ID_LIST, |
| | | // allEntries = true) // allEntries 清空所有缓存,主要一次更新涉及到的 menuIds 较多,反倒批量会更快 |
| | | // public void assignRoleAppMenu(Long roleId, Set<Long> menuIds) { |
| | | // // 获得角色拥有应用菜单编号 |
| | | // MenuListReqVO reqVO = new MenuListReqVO(); |
| | | // List<MenuDO> appMenuList = menuService.getAppMenuList(reqVO); |
| | | // Set<Long> appMenuIds = convertSet(appMenuList, MenuDO::getId); |
| | | // Set<Long> dbMenuIds = convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId); |
| | | // dbMenuIds.retainAll(appMenuIds); |
| | | // // 计算新增和删除的菜单编号 |
| | | // Set<Long> menuIdList = CollUtil.emptyIfNull(menuIds); |
| | | // Collection<Long> createMenuIds = CollUtil.subtract(menuIdList, dbMenuIds); |
| | | // Collection<Long> deleteMenuIds = CollUtil.subtract(dbMenuIds, menuIdList); |
| | | // // 执行新增和删除。对于已经授权的菜单,不用做任何处理 |
| | | // if (CollUtil.isNotEmpty(createMenuIds)) { |
| | | // roleMenuMapper.insertBatch(CollectionUtils.convertList(createMenuIds, menuId -> { |
| | | // RoleMenuDO entity = new RoleMenuDO(); |
| | | // entity.setRoleId(roleId); |
| | | // entity.setMenuId(menuId); |
| | | // return entity; |
| | | // })); |
| | | // } |
| | | // if (CollUtil.isNotEmpty(deleteMenuIds)) { |
| | | // roleMenuMapper.deleteListByRoleIdAndMenuIds(roleId, deleteMenuIds); |
| | | // } |
| | | // } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | if (CollUtil.isEmpty(roleIds)) { |
| | | return Collections.emptySet(); |
| | | } |
| | | // 如果是管理员的情况下,获取全部菜单编号 |
| | | if (roleService.hasAnySuperAdmin(roleIds)) { |
| | | return convertSet(menuService.getMenuList(), MenuDO::getId); |
| | | } |
| | | return convertSet(roleMenuMapper.selectListByRoleId(roleIds), RoleMenuDO::getMenuId); |
| | | } |
| | | |