Compare commits
3 Commits
d67a1de321
...
af585ecb17
Author | SHA1 | Date | |
---|---|---|---|
af585ecb17 | |||
a16c5a44f3 | |||
76b448b203 |
@ -23,6 +23,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode MENU_NOT_EXISTS = new ErrorCode(1_002_001_003, "菜单不存在");
|
||||
ErrorCode MENU_EXISTS_CHILDREN = new ErrorCode(1_002_001_004, "存在子菜单,无法删除");
|
||||
ErrorCode MENU_PARENT_NOT_DIR_OR_MENU = new ErrorCode(1_002_001_005, "父菜单的类型必须是目录或者菜单");
|
||||
ErrorCode MENU_APP_NOT_EXISTS = new ErrorCode(1_002_001_006, "APP菜单权限不存在");
|
||||
|
||||
// ========== 角色模块 1-002-002-000 ==========
|
||||
ErrorCode ROLE_NOT_EXISTS = new ErrorCode(1_002_002_000, "角色不存在");
|
||||
|
@ -0,0 +1,85 @@
|
||||
package com.inspur.module.system.controller.admin.permission;
|
||||
|
||||
import com.inspur.framework.common.enums.CommonStatusEnum;
|
||||
import com.inspur.framework.common.pojo.CommonResult;
|
||||
import com.inspur.framework.common.util.object.BeanUtils;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.APPMenuSimpleRespVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppPageReqVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppRespVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppSaveReqVO;
|
||||
import com.inspur.module.system.dal.dataobject.menuapp.MenuAppDO;
|
||||
import com.inspur.module.system.service.permission.MenuAppService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.inspur.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - 菜单权限")
|
||||
@RestController
|
||||
@RequestMapping("/system/menu-app")
|
||||
@Validated
|
||||
public class MenuAppController {
|
||||
|
||||
@Resource
|
||||
private MenuAppService menuAppService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建APP菜单权限")
|
||||
public CommonResult<Long> createMenuApp(@Valid @RequestBody MenuAppSaveReqVO createReqVO) {
|
||||
Long menuId = menuAppService.createMenuApp(createReqVO);
|
||||
return success(menuId);
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新APP菜单权限")
|
||||
public CommonResult<Boolean> updateMenuApp(@Valid @RequestBody MenuAppSaveReqVO updateReqVO) {
|
||||
menuAppService.updateMenuApp(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除APP菜单权限")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
public CommonResult<Boolean> deleteMenuApp(@RequestParam("id") Long id) {
|
||||
menuAppService.deleteMenuApp(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得APP菜单权限分页")
|
||||
public CommonResult<List<MenuAppRespVO>> getMenuAppPage(@Valid MenuAppPageReqVO pageReqVO) {
|
||||
List<MenuAppDO> list = menuAppService.getMenuAppPage(pageReqVO);
|
||||
list.sort(Comparator.comparing(MenuAppDO::getSort));
|
||||
return success(BeanUtils.toBean(list, MenuAppRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping({"/list-all-simple", "simple-list"})
|
||||
@Operation(summary = "获取菜单精简信息列表", description = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" +
|
||||
"在多租户的场景下,会只返回租户所在套餐有的菜单")
|
||||
public CommonResult<List<APPMenuSimpleRespVO>> getSimpleMenuList() {
|
||||
MenuAppPageReqVO reqVO = new MenuAppPageReqVO();
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
List<MenuAppDO> list = menuAppService.getMenuListByTenant(reqVO);
|
||||
list = menuAppService.filterDisableMenus(list);
|
||||
list.sort(Comparator.comparing(MenuAppDO::getSort));
|
||||
|
||||
return success(BeanUtils.toBean(list, APPMenuSimpleRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得APP菜单权限")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
public CommonResult<MenuAppRespVO> getMenuApp(@RequestParam("id") Long id) {
|
||||
MenuAppDO menuApp = menuAppService.getMenuApp(id);
|
||||
return success(BeanUtils.toBean(menuApp, MenuAppRespVO.class));
|
||||
}
|
||||
|
||||
}
|
@ -70,10 +70,12 @@ public class MenuController {
|
||||
@Operation(summary = "获取菜单精简信息列表", description = "只包含被开启的菜单,用于【角色分配菜单】功能的选项。" +
|
||||
"在多租户的场景下,会只返回租户所在套餐有的菜单")
|
||||
public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() {
|
||||
List<MenuDO> list = menuService.getMenuListByTenant(
|
||||
new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
MenuListReqVO reqVO = new MenuListReqVO();
|
||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
List<MenuDO> list = menuService.getMenuListByTenant(reqVO);
|
||||
list = menuService.filterDisableMenus(list);
|
||||
list.sort(Comparator.comparing(MenuDO::getSort));
|
||||
|
||||
return success(BeanUtils.toBean(list, MenuSimpleRespVO.class));
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,14 @@ public class PermissionController {
|
||||
return success(permissionService.getRoleMenuListByRoleId(roleId));
|
||||
}
|
||||
|
||||
@Operation(summary = "获得角色拥有的APP菜单编号")
|
||||
@Parameter(name = "roleId", description = "角色编号", required = true)
|
||||
@GetMapping("/list-role-APPmenus")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-appmenu')")
|
||||
public CommonResult<Set<Long>> getRoleAPPMenuList(Long roleId) {
|
||||
return success(permissionService.getRoleAPPMenuListByRoleId(roleId));
|
||||
}
|
||||
|
||||
@PostMapping("/assign-role-menu")
|
||||
@Operation(summary = "赋予角色菜单")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-menu')")
|
||||
@ -55,6 +63,17 @@ public class PermissionController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/assign-role-appmenu")
|
||||
@Operation(summary = "赋予角色APP菜单")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-appmenu')")
|
||||
public CommonResult<Boolean> assignRoleAPPMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) {
|
||||
// 开启多租户的情况下,需要过滤掉未开通的菜单
|
||||
tenantService.handleTenantAPPMenu(menuIds -> reqVO.getMenuIds().removeIf(menuId -> !CollUtil.contains(menuIds, menuId)));
|
||||
// 执行菜单的分配
|
||||
permissionService.assignRoleAPPMenu(reqVO.getRoleId(), reqVO.getMenuIds());
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@PostMapping("/assign-role-data-scope")
|
||||
@Operation(summary = "赋予角色数据权限")
|
||||
@PreAuthorize("@ss.hasPermission('system:permission:assign-role-data-scope')")
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.inspur.module.system.controller.admin.permission.vo.appmenu;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Schema(description = "管理后台 - 菜单精简信息 Response VO")
|
||||
@Data
|
||||
public class APPMenuSimpleRespVO {
|
||||
|
||||
@Schema(description = "菜单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "父菜单 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "类型,参见 MenuTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer type;
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.inspur.module.system.controller.admin.permission.vo.appmenu;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - APP菜单列表 Request VO")
|
||||
@Data
|
||||
public class MenuAppListReqVO {
|
||||
@Schema(description = "APP菜单名称,模糊匹配", example = "芋道")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")
|
||||
private Integer status;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.inspur.module.system.controller.admin.permission.vo.appmenu;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import com.inspur.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static com.inspur.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - 菜单权限分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class MenuAppPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "菜单名称", example = "芋艿")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "权限标识")
|
||||
private String permission;
|
||||
|
||||
@Schema(description = "菜单类型", example = "1")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "显示顺序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "父菜单ID", example = "6433")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "路由地址")
|
||||
private String path;
|
||||
|
||||
@Schema(description = "菜单图标")
|
||||
private String icon;
|
||||
|
||||
@Schema(description = "组件路径")
|
||||
private String component;
|
||||
|
||||
@Schema(description = "组件名", example = "芋艿")
|
||||
private String componentName;
|
||||
|
||||
@Schema(description = "菜单状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否可见")
|
||||
private Boolean visible;
|
||||
|
||||
@Schema(description = "是否缓存")
|
||||
private Boolean keepAlive;
|
||||
|
||||
@Schema(description = "是否总是显示")
|
||||
private Boolean alwaysShow;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.inspur.module.system.controller.admin.permission.vo.appmenu;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import com.alibaba.excel.annotation.*;
|
||||
|
||||
@Schema(description = "管理后台 - 菜单权限 Response VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class MenuAppRespVO {
|
||||
|
||||
@Schema(description = "菜单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "22580")
|
||||
@ExcelProperty("菜单ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
|
||||
@ExcelProperty("菜单名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "权限标识", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("权限标识")
|
||||
private String permission;
|
||||
|
||||
@Schema(description = "菜单类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("菜单类型")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("显示顺序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "父菜单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6433")
|
||||
@ExcelProperty("父菜单ID")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "路由地址")
|
||||
@ExcelProperty("路由地址")
|
||||
private String path;
|
||||
|
||||
@Schema(description = "菜单图标")
|
||||
@ExcelProperty("菜单图标")
|
||||
private String icon;
|
||||
|
||||
@Schema(description = "组件路径")
|
||||
@ExcelProperty("组件路径")
|
||||
private String component;
|
||||
|
||||
@Schema(description = "组件名", example = "芋艿")
|
||||
@ExcelProperty("组件名")
|
||||
private String componentName;
|
||||
|
||||
@Schema(description = "菜单状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("菜单状态")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否可见", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("是否可见")
|
||||
private Boolean visible;
|
||||
|
||||
@Schema(description = "是否缓存", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("是否缓存")
|
||||
private Boolean keepAlive;
|
||||
|
||||
@Schema(description = "是否总是显示", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("是否总是显示")
|
||||
private Boolean alwaysShow;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.inspur.module.system.controller.admin.permission.vo.appmenu;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
|
||||
@Schema(description = "管理后台 - 菜单权限新增/修改 Request VO")
|
||||
@Data
|
||||
public class MenuAppSaveReqVO {
|
||||
@Schema(description = "菜单编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "菜单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
|
||||
@NotBlank(message = "菜单名称不能为空")
|
||||
@Size(max = 50, message = "菜单名称长度不能超过50个字符")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "权限标识,仅菜单类型为按钮时,才需要传递", example = "sys:menu:add")
|
||||
@Size(max = 100)
|
||||
private String permission;
|
||||
|
||||
@Schema(description = "类型,参见 MenuTypeEnum 枚举类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "菜单类型不能为空")
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "显示顺序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "显示顺序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "父菜单 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
@NotNull(message = "父菜单 ID 不能为空")
|
||||
private Long parentId;
|
||||
|
||||
@Schema(description = "路由地址,仅菜单类型为菜单或者目录时,才需要传", example = "post")
|
||||
@Size(max = 200, message = "路由地址不能超过200个字符")
|
||||
private String path;
|
||||
|
||||
@Schema(description = "菜单图标,仅菜单类型为菜单或者目录时,才需要传", example = "/menu/list")
|
||||
private String icon;
|
||||
|
||||
@Schema(description = "组件路径,仅菜单类型为菜单时,才需要传", example = "system/post/index")
|
||||
@Size(max = 200, message = "组件路径不能超过255个字符")
|
||||
private String component;
|
||||
|
||||
@Schema(description = "组件名", example = "SystemUser")
|
||||
private String componentName;
|
||||
|
||||
@Schema(description = "状态,见 CommonStatusEnum 枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否可见", example = "false")
|
||||
private Boolean visible;
|
||||
|
||||
@Schema(description = "是否缓存", example = "false")
|
||||
private Boolean keepAlive;
|
||||
|
||||
@Schema(description = "是否总是显示", example = "false")
|
||||
private Boolean alwaysShow;
|
||||
}
|
@ -25,6 +25,9 @@ public class TenantPackageRespVO {
|
||||
@Schema(description = "关联的菜单编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Set<Long> menuIds;
|
||||
|
||||
@Schema(description = "关联的APP菜单编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Set<Long> appMenuIds;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
|
@ -32,4 +32,8 @@ public class TenantPackageSaveReqVO {
|
||||
@NotNull(message = "关联的菜单编号不能为空")
|
||||
private Set<Long> menuIds;
|
||||
|
||||
@Schema(description = "关联的菜单编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "关联的菜单编号不能为空")
|
||||
private Set<Long> appMenuIds;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
package com.inspur.module.system.dal.dataobject.menuapp;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalDateTime;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.inspur.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
/**
|
||||
* 菜单权限 DO
|
||||
*
|
||||
* @author 管理员
|
||||
*/
|
||||
@TableName("system_menu_app")
|
||||
@KeySequence("system_menu_app_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MenuAppDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 权限标识
|
||||
*/
|
||||
private String permission;
|
||||
/**
|
||||
* 菜单类型
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 父菜单ID
|
||||
*/
|
||||
private Long parentId;
|
||||
/**
|
||||
* 路由地址
|
||||
*/
|
||||
private String path;
|
||||
/**
|
||||
* 菜单图标
|
||||
*/
|
||||
private String icon;
|
||||
/**
|
||||
* 组件路径
|
||||
*/
|
||||
private String component;
|
||||
/**
|
||||
* 组件名
|
||||
*/
|
||||
private String componentName;
|
||||
/**
|
||||
* 菜单状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 是否可见
|
||||
*/
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 是否缓存
|
||||
*/
|
||||
private Boolean keepAlive;
|
||||
/**
|
||||
* 是否总是显示
|
||||
*/
|
||||
private Boolean alwaysShow;
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.inspur.module.system.dal.dataobject.permission;
|
||||
|
||||
import com.inspur.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 角色和菜单关联
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@TableName("system_role_menu_app")
|
||||
@KeySequence("system_role_menu_app_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RoleMenuAppDO extends TenantBaseDO {
|
||||
|
||||
/**
|
||||
* 自增主键
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
private Long menuId;
|
||||
|
||||
}
|
@ -49,4 +49,10 @@ public class TenantPackageDO extends BaseDO {
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Set<Long> menuIds;
|
||||
|
||||
/**
|
||||
* 关联的菜单编号
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private Set<Long> appMenuIds;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package com.inspur.module.system.dal.mysql.permission;
|
||||
|
||||
import com.inspur.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.inspur.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppPageReqVO;
|
||||
import com.inspur.module.system.dal.dataobject.menuapp.MenuAppDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* APP菜单权限 Mapper
|
||||
*
|
||||
* @author 管理员
|
||||
*/
|
||||
@Mapper
|
||||
public interface MenuAppMapper extends BaseMapperX<MenuAppDO> {
|
||||
|
||||
default MenuAppDO selectByParentIdAndName(Long parentId, String name) {
|
||||
return selectOne(MenuAppDO::getParentId, parentId, MenuAppDO::getName, name);
|
||||
}
|
||||
|
||||
default Long selectCountByParentId(Long parentId) {
|
||||
return selectCount(MenuAppDO::getParentId, parentId);
|
||||
}
|
||||
|
||||
default List<MenuAppDO> selectPage(MenuAppPageReqVO reqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<MenuAppDO>()
|
||||
.likeIfPresent(MenuAppDO::getName, reqVO.getName())
|
||||
.eqIfPresent(MenuAppDO::getStatus, reqVO.getStatus()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.inspur.module.system.dal.mysql.permission;
|
||||
|
||||
import com.inspur.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.inspur.module.system.dal.dataobject.permission.RoleMenuAppDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface RoleMenuAppMapper extends BaseMapperX<RoleMenuAppDO> {
|
||||
|
||||
default List<RoleMenuAppDO> selectListByRoleId(Long roleId) {
|
||||
return selectList(RoleMenuAppDO::getRoleId, roleId);
|
||||
}
|
||||
|
||||
default List<RoleMenuAppDO> selectListByRoleId(Collection<Long> roleIds) {
|
||||
return selectList(RoleMenuAppDO::getRoleId, roleIds);
|
||||
}
|
||||
|
||||
default List<RoleMenuAppDO> selectListByMenuId(Long menuId) {
|
||||
return selectList(RoleMenuAppDO::getMenuId, menuId);
|
||||
}
|
||||
|
||||
default void deleteListByRoleIdAndMenuIds(Long roleId, Collection<Long> menuIds) {
|
||||
delete(new LambdaQueryWrapper<RoleMenuAppDO>()
|
||||
.eq(RoleMenuAppDO::getRoleId, roleId)
|
||||
.in(RoleMenuAppDO::getMenuId, menuIds));
|
||||
}
|
||||
|
||||
default void deleteListByMenuId(Long menuId) {
|
||||
delete(new LambdaQueryWrapper<RoleMenuAppDO>().eq(RoleMenuAppDO::getMenuId, menuId));
|
||||
}
|
||||
|
||||
default void deleteListByRoleId(Long roleId) {
|
||||
delete(new LambdaQueryWrapper<RoleMenuAppDO>().eq(RoleMenuAppDO::getRoleId, roleId));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.inspur.module.system.service.permission;
|
||||
|
||||
import com.inspur.framework.common.pojo.PageResult;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppListReqVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppPageReqVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppSaveReqVO;
|
||||
import com.inspur.module.system.dal.dataobject.menuapp.MenuAppDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单权限 Service 接口
|
||||
*
|
||||
* @author 管理员
|
||||
*/
|
||||
public interface MenuAppService {
|
||||
|
||||
/**
|
||||
* 创建菜单权限
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createMenuApp(@Valid MenuAppSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新菜单权限
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateMenuApp(@Valid MenuAppSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除菜单权限
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteMenuApp(Long id);
|
||||
|
||||
/**
|
||||
* 获得菜单权限
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 菜单权限
|
||||
*/
|
||||
MenuAppDO getMenuApp(Long id);
|
||||
|
||||
/**
|
||||
* 获得菜单权限分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 菜单权限分页
|
||||
*/
|
||||
List<MenuAppDO> getMenuAppPage(MenuAppPageReqVO pageReqVO);
|
||||
|
||||
List<MenuAppDO> getMenuListByTenant(MenuAppPageReqVO reqVO);
|
||||
|
||||
List<MenuAppDO> filterDisableMenus(List<MenuAppDO> list);
|
||||
|
||||
public List<MenuAppDO> getMenuList(MenuAppPageReqVO reqVO);
|
||||
|
||||
public List<MenuAppDO> getAPPMenuList();
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
package com.inspur.module.system.service.permission;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.inspur.framework.common.enums.CommonStatusEnum;
|
||||
import com.inspur.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import com.inspur.framework.common.pojo.PageResult;
|
||||
import com.inspur.framework.common.util.object.BeanUtils;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppListReqVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppPageReqVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.appmenu.MenuAppSaveReqVO;
|
||||
import com.inspur.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
||||
import com.inspur.module.system.dal.dataobject.menuapp.MenuAppDO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.inspur.module.system.dal.mysql.permission.MenuAppMapper;
|
||||
import com.inspur.module.system.enums.ErrorCodeConstants;
|
||||
import com.inspur.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.inspur.module.system.service.tenant.TenantService;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.inspur.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.inspur.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static com.inspur.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
|
||||
import static com.inspur.module.system.enums.ErrorCodeConstants.MENU_APP_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 菜单权限 Service 实现类
|
||||
*
|
||||
* @author 管理员
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class MenuAppServiceImpl implements MenuAppService {
|
||||
|
||||
@Resource
|
||||
private MenuAppMapper menuAppMapper;
|
||||
@Resource
|
||||
private PermissionService permissionService;
|
||||
@Resource
|
||||
@Lazy // 延迟,避免循环依赖报错
|
||||
private TenantService tenantService;
|
||||
|
||||
@Override
|
||||
public Long createMenuApp(MenuAppSaveReqVO createReqVO) {
|
||||
|
||||
// 校验父菜单存在
|
||||
validateParentMenu(createReqVO.getParentId(), null);
|
||||
// 校验菜单(自己)
|
||||
validateMenu(createReqVO.getParentId(), createReqVO.getName(), null);
|
||||
|
||||
// 插入
|
||||
MenuAppDO menuApp = BeanUtils.toBean(createReqVO, MenuAppDO.class);
|
||||
menuAppMapper.insert(menuApp);
|
||||
// 返回
|
||||
return menuApp.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMenuApp(MenuAppSaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateMenuAppExists(updateReqVO.getId());
|
||||
// 校验父菜单存在
|
||||
validateParentMenu(updateReqVO.getParentId(), updateReqVO.getId());
|
||||
// 校验菜单(自己)
|
||||
validateMenu(updateReqVO.getParentId(), updateReqVO.getName(), updateReqVO.getId());
|
||||
// 更新
|
||||
MenuAppDO updateObj = BeanUtils.toBean(updateReqVO, MenuAppDO.class);
|
||||
menuAppMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteMenuApp(Long id) {
|
||||
// 校验存在
|
||||
validateMenuAppExists(id);
|
||||
// 校验是否还有子菜单
|
||||
if (menuAppMapper.selectCountByParentId(id) > 0) {
|
||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.MENU_EXISTS_CHILDREN);
|
||||
}
|
||||
// 删除
|
||||
menuAppMapper.deleteById(id);
|
||||
// 删除授予给角色的权限
|
||||
//TODO permissionService.processMenuDeleted(id);
|
||||
permissionService.processMenuDeleted(id);
|
||||
}
|
||||
|
||||
private void validateMenuAppExists(Long id) {
|
||||
if (menuAppMapper.selectById(id) == null) {
|
||||
throw exception(MENU_APP_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuAppDO getMenuApp(Long id) {
|
||||
return menuAppMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuAppDO> getMenuAppPage(MenuAppPageReqVO pageReqVO) {
|
||||
return menuAppMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuAppDO> getMenuListByTenant(MenuAppPageReqVO reqVO) {
|
||||
// 查询所有菜单,并过滤掉关闭的节点
|
||||
List<MenuAppDO> menus = getMenuList(reqVO);
|
||||
// 开启多租户的情况下,需要过滤掉未开通的菜单
|
||||
tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
|
||||
return menus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuAppDO> filterDisableMenus(List<MenuAppDO> menuList) {
|
||||
if (CollUtil.isEmpty(menuList)){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Long, MenuAppDO> menuMap = convertMap(menuList, MenuAppDO::getId);
|
||||
|
||||
// 遍历 menu 菜单,查找不是禁用的菜单,添加到 enabledMenus 结果
|
||||
List<MenuAppDO> enabledMenus = new ArrayList<>();
|
||||
Set<Long> disabledMenuCache = new HashSet<>(); // 存下递归搜索过被禁用的菜单,防止重复的搜索
|
||||
for (MenuAppDO menu : menuList) {
|
||||
if (isMenuDisabled(menu, menuMap, disabledMenuCache)) {
|
||||
continue;
|
||||
}
|
||||
enabledMenus.add(menu);
|
||||
}
|
||||
return enabledMenus;
|
||||
}
|
||||
|
||||
private boolean isMenuDisabled(MenuAppDO node, Map<Long, MenuAppDO> menuMap, Set<Long> disabledMenuCache) {
|
||||
// 如果已经判定是禁用的节点,直接结束
|
||||
if (disabledMenuCache.contains(node.getId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 1. 遍历到 parentId 为根节点,则无需判断
|
||||
Long parentId = node.getParentId();
|
||||
if (ObjUtil.equal(parentId, ID_ROOT)) {
|
||||
if (CommonStatusEnum.isDisable(node.getStatus())) {
|
||||
disabledMenuCache.add(node.getId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 继续遍历 parent 节点
|
||||
MenuAppDO parent = menuMap.get(parentId);
|
||||
if (parent == null || isMenuDisabled(parent, menuMap, disabledMenuCache)) {
|
||||
disabledMenuCache.add(node.getId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuAppDO> getMenuList(MenuAppPageReqVO reqVO) {
|
||||
return menuAppMapper.selectPage(reqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuAppDO> getAPPMenuList() {
|
||||
return menuAppMapper.selectList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验父菜单是否合法
|
||||
* <p>
|
||||
* 1. 不能设置自己为父菜单
|
||||
* 2. 父菜单不存在
|
||||
* 3. 父菜单必须是 {@link MenuTypeEnum#MENU} 菜单类型
|
||||
*
|
||||
* @param parentId 父菜单编号
|
||||
* @param childId 当前菜单编号
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void validateParentMenu(Long parentId, Long childId) {
|
||||
if (parentId == null || ID_ROOT.equals(parentId)) {
|
||||
return;
|
||||
}
|
||||
// 不能设置自己为父菜单
|
||||
if (parentId.equals(childId)) {
|
||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.MENU_PARENT_ERROR);
|
||||
}
|
||||
MenuAppDO menu = menuAppMapper.selectById(parentId);
|
||||
// 父菜单不存在
|
||||
if (menu == null) {
|
||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.MENU_PARENT_NOT_EXISTS);
|
||||
}
|
||||
// 父菜单必须是目录或者菜单类型
|
||||
if (!MenuTypeEnum.DIR.getType().equals(menu.getType())
|
||||
&& !MenuTypeEnum.MENU.getType().equals(menu.getType())) {
|
||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.MENU_PARENT_NOT_DIR_OR_MENU);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验菜单是否合法
|
||||
* <p>
|
||||
* 1. 校验相同父菜单编号下,是否存在相同的菜单名
|
||||
*
|
||||
* @param name 菜单名字
|
||||
* @param parentId 父菜单编号
|
||||
* @param id 菜单编号
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void validateMenu(Long parentId, String name, Long id) {
|
||||
MenuAppDO menu = menuAppMapper.selectByParentIdAndName(parentId, name);
|
||||
if (menu == null) {
|
||||
return;
|
||||
}
|
||||
// 如果 id 为空,说明不用比较是否为相同 id 的菜单
|
||||
if (id == null) {
|
||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.MENU_NAME_DUPLICATE);
|
||||
}
|
||||
if (!menu.getId().equals(id)) {
|
||||
throw ServiceExceptionUtil.exception(ErrorCodeConstants.MENU_NAME_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -42,6 +42,15 @@ public interface PermissionService {
|
||||
* @param menuIds 菜单编号集合
|
||||
*/
|
||||
void assignRoleMenu(Long roleId, Set<Long> menuIds);
|
||||
// ========== 角色-菜单的相关方法 ==========
|
||||
|
||||
/**
|
||||
* 设置角色菜单
|
||||
*
|
||||
* @param roleId 角色编号
|
||||
* @param menuIds 菜单编号集合
|
||||
*/
|
||||
void assignRoleAPPMenu(Long roleId, Set<Long> menuIds);
|
||||
|
||||
/**
|
||||
* 处理角色删除时,删除关联授权数据
|
||||
@ -57,6 +66,13 @@ public interface PermissionService {
|
||||
*/
|
||||
void processMenuDeleted(Long menuId);
|
||||
|
||||
/**
|
||||
* 处理菜单删除时,删除关联授权数据
|
||||
*
|
||||
* @param menuId 菜单编号
|
||||
*/
|
||||
void processAPPMenuDeleted(Long menuId);
|
||||
|
||||
/**
|
||||
* 获得角色拥有的菜单编号集合
|
||||
*
|
||||
@ -66,7 +82,15 @@ public interface PermissionService {
|
||||
default Set<Long> getRoleMenuListByRoleId(Long roleId) {
|
||||
return getRoleMenuListByRoleId(singleton(roleId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得角色拥有的APP菜单编号集合
|
||||
*
|
||||
* @param roleId 角色编号
|
||||
* @return APP菜单编号集合
|
||||
*/
|
||||
default Set<Long> getRoleAPPMenuListByRoleId(Long roleId){
|
||||
return getRoleAPPMenuListByRoleId(singleton(roleId));
|
||||
};
|
||||
/**
|
||||
* 获得角色们拥有的菜单编号集合
|
||||
*
|
||||
@ -75,6 +99,14 @@ public interface PermissionService {
|
||||
*/
|
||||
Set<Long> getRoleMenuListByRoleId(Collection<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 获得角色们拥有的APP菜单编号集合
|
||||
*
|
||||
* @param roleIds 角色编号数组
|
||||
* @return APP菜单编号集合
|
||||
*/
|
||||
Set<Long> getRoleAPPMenuListByRoleId(Collection<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 获得拥有指定菜单的角色编号数组,从缓存中获取
|
||||
*
|
||||
@ -143,4 +175,5 @@ public interface PermissionService {
|
||||
*/
|
||||
DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
|
||||
|
||||
|
||||
}
|
||||
|
@ -8,10 +8,9 @@ import com.inspur.framework.common.enums.CommonStatusEnum;
|
||||
import com.inspur.framework.common.util.collection.CollectionUtils;
|
||||
import com.inspur.framework.datapermission.core.annotation.DataPermission;
|
||||
import com.inspur.module.system.api.permission.dto.DeptDataPermissionRespDTO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.RoleDO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.RoleMenuDO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.UserRoleDO;
|
||||
import com.inspur.module.system.dal.dataobject.menuapp.MenuAppDO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.*;
|
||||
import com.inspur.module.system.dal.mysql.permission.RoleMenuAppMapper;
|
||||
import com.inspur.module.system.dal.mysql.permission.RoleMenuMapper;
|
||||
import com.inspur.module.system.dal.mysql.permission.UserRoleMapper;
|
||||
import com.inspur.module.system.dal.redis.RedisKeyConstants;
|
||||
@ -48,6 +47,8 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
@Resource
|
||||
private RoleMenuMapper roleMenuMapper;
|
||||
@Resource
|
||||
private RoleMenuAppMapper roleMenuAppMapper;
|
||||
@Resource
|
||||
private UserRoleMapper userRoleMapper;
|
||||
|
||||
@Resource
|
||||
@ -55,6 +56,8 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
@Resource
|
||||
private MenuService menuService;
|
||||
@Resource
|
||||
private MenuAppService menuAppService;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
@ -155,6 +158,36 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 角色-菜单的相关方法 ==========
|
||||
|
||||
@Override
|
||||
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
|
||||
@CacheEvict(value = RedisKeyConstants.MENU_ROLE_ID_LIST,
|
||||
allEntries = true) // allEntries 清空所有缓存,主要一次更新涉及到的 menuIds 较多,反倒批量会更快
|
||||
public void assignRoleAPPMenu(Long roleId, Set<Long> appmenuIds) {
|
||||
// 获得角色拥有菜单编号
|
||||
Set<Long> dbAPPMenuIds = convertSet(roleMenuAppMapper.selectListByRoleId(roleId), RoleMenuAppDO::getMenuId);
|
||||
// 计算新增和删除的菜单编号
|
||||
Set<Long> appmenuIdList = CollUtil.emptyIfNull(appmenuIds);
|
||||
|
||||
Collection<Long> createMenuIds = CollUtil.subtract(appmenuIdList, dbAPPMenuIds);
|
||||
|
||||
Collection<Long> deleteMenuIds = CollUtil.subtract(dbAPPMenuIds, appmenuIdList);
|
||||
|
||||
// 执行新增和删除。对于已经授权的菜单,不用做任何处理
|
||||
if (CollUtil.isNotEmpty(createMenuIds)) {
|
||||
roleMenuAppMapper.insertBatch(CollectionUtils.convertList(createMenuIds, menuId -> {
|
||||
RoleMenuAppDO entity = new RoleMenuAppDO();
|
||||
entity.setRoleId(roleId);
|
||||
entity.setMenuId(menuId);
|
||||
return entity;
|
||||
}));
|
||||
}
|
||||
if (CollUtil.isNotEmpty(deleteMenuIds)) {
|
||||
roleMenuAppMapper.deleteListByRoleIdAndMenuIds(roleId, deleteMenuIds);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Caching(evict = {
|
||||
@ -176,6 +209,12 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
roleMenuMapper.deleteListByMenuId(menuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = RedisKeyConstants.MENU_ROLE_ID_LIST, key = "#menuId")
|
||||
public void processAPPMenuDeleted(Long menuId) {
|
||||
roleMenuAppMapper.deleteListByMenuId(menuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getRoleMenuListByRoleId(Collection<Long> roleIds) {
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
@ -190,6 +229,21 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
return convertSet(roleMenuMapper.selectListByRoleId(roleIds), RoleMenuDO::getMenuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> getRoleAPPMenuListByRoleId(Collection<Long> roleIds) {
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
// 如果是管理员的情况下,获取全部菜单编号
|
||||
if (roleService.hasAnySuperAdmin(roleIds)) {
|
||||
return convertSet(menuAppService.getAPPMenuList(), MenuAppDO::getId);
|
||||
}
|
||||
// 如果是非管理员的情况下,获得拥有的菜单编号
|
||||
return convertSet(roleMenuAppMapper.selectListByRoleId(roleIds), RoleMenuAppDO::getMenuId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@Cacheable(value = RedisKeyConstants.MENU_ROLE_ID_LIST, key = "#menuId")
|
||||
public Set<Long> getMenuRoleIdListByMenuIdFromCache(Long menuId) {
|
||||
|
@ -113,6 +113,14 @@ public interface TenantService {
|
||||
*/
|
||||
void handleTenantMenu(TenantMenuHandler handler);
|
||||
|
||||
/**
|
||||
* 进行租户的APP菜单处理逻辑
|
||||
* 其中,租户编号从 {@link TenantContextHolder} 上下文中获取
|
||||
*
|
||||
* @param handler 处理器
|
||||
*/
|
||||
void handleTenantAPPMenu(TenantMenuHandler handler);
|
||||
|
||||
/**
|
||||
* 获得所有租户
|
||||
*
|
||||
|
@ -17,6 +17,7 @@ import com.inspur.module.system.controller.admin.permission.vo.role.RoleSaveReqV
|
||||
import com.inspur.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
|
||||
import com.inspur.module.system.controller.admin.tenant.vo.tenant.TenantSaveReqVO;
|
||||
import com.inspur.module.system.convert.tenant.TenantConvert;
|
||||
import com.inspur.module.system.dal.dataobject.menuapp.MenuAppDO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.inspur.module.system.dal.dataobject.permission.RoleDO;
|
||||
import com.inspur.module.system.dal.dataobject.tenant.TenantDO;
|
||||
@ -24,6 +25,7 @@ import com.inspur.module.system.dal.dataobject.tenant.TenantPackageDO;
|
||||
import com.inspur.module.system.dal.mysql.tenant.TenantMapper;
|
||||
import com.inspur.module.system.enums.permission.RoleCodeEnum;
|
||||
import com.inspur.module.system.enums.permission.RoleTypeEnum;
|
||||
import com.inspur.module.system.service.permission.MenuAppService;
|
||||
import com.inspur.module.system.service.permission.MenuService;
|
||||
import com.inspur.module.system.service.permission.PermissionService;
|
||||
import com.inspur.module.system.service.permission.RoleService;
|
||||
@ -73,6 +75,8 @@ public class TenantServiceImpl implements TenantService {
|
||||
@Resource
|
||||
private MenuService menuService;
|
||||
@Resource
|
||||
private MenuAppService menuAppService;
|
||||
@Resource
|
||||
private PermissionService permissionService;
|
||||
|
||||
@Override
|
||||
@ -135,8 +139,10 @@ public class TenantServiceImpl implements TenantService {
|
||||
private Long createRole(TenantPackageDO tenantPackage) {
|
||||
// 创建角色
|
||||
RoleSaveReqVO reqVO = new RoleSaveReqVO();
|
||||
reqVO.setName(RoleCodeEnum.TENANT_ADMIN.getName()).setCode(RoleCodeEnum.TENANT_ADMIN.getCode())
|
||||
.setSort(0).setRemark("系统自动生成");
|
||||
reqVO.setName(RoleCodeEnum.TENANT_ADMIN.getName());
|
||||
reqVO.setCode(RoleCodeEnum.TENANT_ADMIN.getCode());
|
||||
reqVO.setSort(0);
|
||||
reqVO.setRemark("系统自动生成");
|
||||
Long roleId = roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
|
||||
// 分配权限
|
||||
permissionService.assignRoleMenu(roleId, tenantPackage.getMenuIds());
|
||||
@ -300,6 +306,24 @@ public class TenantServiceImpl implements TenantService {
|
||||
handler.handle(menuIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTenantAPPMenu(TenantMenuHandler handler) {
|
||||
// 如果禁用,则不执行逻辑
|
||||
if (isTenantDisable()) {
|
||||
return;
|
||||
}
|
||||
// 获得租户,然后获得菜单
|
||||
TenantDO tenant = getTenant(TenantContextHolder.getRequiredTenantId());
|
||||
Set<Long> menuIds;
|
||||
if (isSystemTenant(tenant)) { // 系统租户,菜单是全量的
|
||||
menuIds = CollectionUtils.convertSet(menuAppService.getAPPMenuList(), MenuAppDO::getId);
|
||||
} else {
|
||||
menuIds = tenantPackageService.getTenantPackage(tenant.getPackageId()).getAppMenuIds();
|
||||
}
|
||||
// 执行处理器
|
||||
handler.handle(menuIds);
|
||||
}
|
||||
|
||||
private static boolean isSystemTenant(TenantDO tenant) {
|
||||
return Objects.equals(tenant.getPackageId(), TenantDO.PACKAGE_ID_SYSTEM);
|
||||
}
|
||||
|
@ -252,6 +252,7 @@ imt:
|
||||
- system_dict_type
|
||||
- system_error_code
|
||||
- system_menu
|
||||
- system_menu_app
|
||||
- system_sms_channel
|
||||
- system_sms_template
|
||||
- system_sms_log
|
||||
|
0
imt-ui/src/api/system/appMenu.js
Normal file
0
imt-ui/src/api/system/appMenu.js
Normal file
0
imt-ui/src/views/system/appMenu/index.vue
Normal file
0
imt-ui/src/views/system/appMenu/index.vue
Normal file
@ -71,6 +71,12 @@
|
||||
<el-tree class="tree-border" :data="menuOptions" show-checkbox ref="menu" node-key="id"
|
||||
:check-strictly="menuCheckStrictly" empty-text="加载中,请稍后" :props="defaultProps"></el-tree>
|
||||
</el-form-item>
|
||||
<el-form-item label="APP菜单权限">
|
||||
<el-checkbox v-model="APPmenuExpand" @change="handleCheckedAPPTreeExpand($event)">展开/折叠</el-checkbox>
|
||||
<el-checkbox v-model="APPmenuNodeAll" @change="handleCheckedAPPTreeNodeAll($event)">全选/全不选</el-checkbox>
|
||||
<el-tree class="tree-border" :data="APPmenuOptions" show-checkbox ref="APPmenu" node-key="id"
|
||||
:check-strictly="APPmenuCheckStrictly" empty-text="加载中,请稍后" :props="APPdefaultProps"></el-tree>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
|
||||
@ -93,6 +99,7 @@
|
||||
import { createTenantPackage, updateTenantPackage, deleteTenantPackage, getTenantPackage, getTenantPackagePage} from "@/api/system/tenantPackage";
|
||||
import {CommonStatusEnum} from "@/utils/constants";
|
||||
import {listSimpleMenus} from "@/api/system/menu";
|
||||
import {listSimpleAPPMenus} from "@/api/system/appMenu";
|
||||
|
||||
export default {
|
||||
name: "SystemTenantPackage",
|
||||
@ -124,13 +131,21 @@ export default {
|
||||
// 表单参数
|
||||
form: {},
|
||||
menuExpand: false,
|
||||
APPmenuExpand: false,
|
||||
menuNodeAll: false,
|
||||
APPmenuNodeAll: false,
|
||||
menuCheckStrictly: true,
|
||||
APPmenuCheckStrictly: true,
|
||||
defaultProps: {
|
||||
label: "name",
|
||||
children: "children"
|
||||
},
|
||||
APPdefaultProps: {
|
||||
label: "name",
|
||||
children: "children"
|
||||
},
|
||||
menuOptions: [], // 菜单列表
|
||||
APPmenuOptions: [], // 菜单列表
|
||||
// 表单校验
|
||||
rules: {
|
||||
name: [{ required: true, message: "套餐名不能为空", trigger: "blur" }],
|
||||
@ -165,9 +180,15 @@ export default {
|
||||
if (this.$refs.menu !== undefined) {
|
||||
this.$refs.menu.setCheckedKeys([]);
|
||||
}
|
||||
if (this.$refs.APPmenu !== undefined) {
|
||||
this.$refs.APPmenu.setCheckedKeys([]);
|
||||
}
|
||||
this.menuExpand = false;
|
||||
this.APPmenuExpand = false;
|
||||
this.menuNodeAll = false;
|
||||
this.APPmenuNodeAll = false;
|
||||
this.menuCheckStrictly = true;
|
||||
this.APPmenuCheckStrictly = true;
|
||||
// 表单重置
|
||||
this.form = {
|
||||
id: undefined,
|
||||
@ -175,6 +196,7 @@ export default {
|
||||
status: CommonStatusEnum.ENABLE,
|
||||
remark: undefined,
|
||||
menuIds: undefined,
|
||||
appMenuIds: undefined,
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
@ -196,6 +218,7 @@ export default {
|
||||
this.title = "添加租户套餐";
|
||||
// 设置为非严格,继续使用半选中
|
||||
this.menuCheckStrictly = false;
|
||||
this.APPmenuCheckStrictly = false;
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
@ -209,10 +232,13 @@ export default {
|
||||
// 设置菜单项
|
||||
// 设置为严格,避免设置父节点自动选中子节点,解决半选中问题
|
||||
this.menuCheckStrictly = true
|
||||
this.APPmenuCheckStrictly = true
|
||||
// 设置选中
|
||||
this.$refs.menu.setCheckedKeys(response.data.menuIds);
|
||||
this.$refs.APPmenu.setCheckedKeys(response.data.appMenuIds);
|
||||
// 设置为非严格,继续使用半选中
|
||||
this.menuCheckStrictly = false
|
||||
this.APPmenuCheckStrictly = false
|
||||
});
|
||||
},
|
||||
/** 获得菜单 */
|
||||
@ -223,6 +249,12 @@ export default {
|
||||
// 只需要配置
|
||||
this.menuOptions.push(...this.handleTree(response.data, "id"));
|
||||
});
|
||||
listSimpleAPPMenus().then(response => {
|
||||
// 处理 APPmenuOptions 参数
|
||||
this.APPmenuOptions = [];
|
||||
// 只需要配置
|
||||
this.APPmenuOptions.push(...this.handleTree(response.data, "id"));
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
@ -234,7 +266,8 @@ export default {
|
||||
if (this.form.id != null) {
|
||||
updateTenantPackage({
|
||||
...this.form,
|
||||
menuIds: [...this.$refs.menu.getCheckedKeys(), ...this.$refs.menu.getHalfCheckedKeys()]
|
||||
menuIds: [...this.$refs.menu.getCheckedKeys(), ...this.$refs.menu.getHalfCheckedKeys()],
|
||||
appMenuIds: [...this.$refs.APPmenu.getCheckedKeys(), ...this.$refs.APPmenu.getHalfCheckedKeys()]
|
||||
}).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.open = false;
|
||||
@ -245,7 +278,8 @@ export default {
|
||||
// 添加的提交
|
||||
createTenantPackage({
|
||||
...this.form,
|
||||
menuIds: [...this.$refs.menu.getCheckedKeys(), ...this.$refs.menu.getHalfCheckedKeys()]
|
||||
menuIds: [...this.$refs.menu.getCheckedKeys(), ...this.$refs.menu.getHalfCheckedKeys()],
|
||||
appMenuIds: [...this.$refs.APPmenu.getCheckedKeys(), ...this.$refs.APPmenu.getHalfCheckedKeys()]
|
||||
}).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
@ -274,6 +308,17 @@ export default {
|
||||
handleCheckedTreeNodeAll(value) {
|
||||
this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
|
||||
},
|
||||
// 树权限(展开/折叠)
|
||||
handleCheckedAPPTreeExpand(value, type) {
|
||||
let treeList = this.APPmenuOptions;
|
||||
for (let i = 0; i < treeList.length; i++) {
|
||||
this.$refs.APPmenu.store.nodesMap[treeList[i].id].expanded = value;
|
||||
}
|
||||
},
|
||||
// 树权限(全选/全不选)
|
||||
handleCheckedAPPTreeNodeAll(value) {
|
||||
this.$refs.APPmenu.setCheckedNodes(value ? this.APPmenuOptions: []);
|
||||
},
|
||||
// 树权限(父子联动)
|
||||
handleCheckedTreeConnect(value) {
|
||||
this.form.menuCheckStrictly = value;
|
||||
|
Loading…
Reference in New Issue
Block a user