1. 迁移角色相关逻辑
This commit is contained in:
parent
4e38bf75ca
commit
4e5b6ff2cf
@ -24,6 +24,8 @@
|
|||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
<knife4j.version>2.0.2</knife4j.version>
|
<knife4j.version>2.0.2</knife4j.version>
|
||||||
<!-- DB 相关 -->
|
<!-- DB 相关 -->
|
||||||
|
<mysql-connector-java.version>5.1.46</mysql-connector-java.version>
|
||||||
|
<druid.version>1.1.16</druid.version>
|
||||||
<mybatis-spring-boot-starter.version>2.0.0</mybatis-spring-boot-starter.version>
|
<mybatis-spring-boot-starter.version>2.0.0</mybatis-spring-boot-starter.version>
|
||||||
<mybatis.version>3.5.1</mybatis.version>
|
<mybatis.version>3.5.1</mybatis.version>
|
||||||
<mybatis-plus.version>3.1.1</mybatis-plus.version>
|
<mybatis-plus.version>3.1.1</mybatis-plus.version>
|
||||||
@ -65,6 +67,18 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- DB 相关 -->
|
<!-- DB 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>${mysql-connector-java.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
<version>${druid.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mybatis</groupId>
|
<groupId>org.mybatis</groupId>
|
||||||
<artifactId>mybatis</artifactId>
|
<artifactId>mybatis</artifactId>
|
||||||
|
13
pom.xml
13
pom.xml
@ -33,8 +33,7 @@
|
|||||||
<spring-boot-admin-starter-client.version>2.2.2</spring-boot-admin-starter-client.version>
|
<spring-boot-admin-starter-client.version>2.2.2</spring-boot-admin-starter-client.version>
|
||||||
<!-- <com.alibab.dubbo.version>2.6.5</com.alibab.dubbo.version>-->
|
<!-- <com.alibab.dubbo.version>2.6.5</com.alibab.dubbo.version>-->
|
||||||
<dubbo.version>2.7.4.1</dubbo.version>
|
<dubbo.version>2.7.4.1</dubbo.version>
|
||||||
<mysql-connector-java.version>5.1.46</mysql-connector-java.version>
|
|
||||||
<druid.version>1.1.16</druid.version>
|
|
||||||
<!-- <dubbo-spring-boot-starter.version>0.2.1.RELEASE</dubbo-spring-boot-starter.version>-->
|
<!-- <dubbo-spring-boot-starter.version>0.2.1.RELEASE</dubbo-spring-boot-starter.version>-->
|
||||||
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
|
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
|
||||||
<curator.version>2.13.0</curator.version>
|
<curator.version>2.13.0</curator.version>
|
||||||
@ -119,17 +118,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- DB 相关 -->
|
<!-- DB 相关 -->
|
||||||
<dependency>
|
|
||||||
<groupId>mysql</groupId>
|
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
|
||||||
<version>${mysql-connector-java.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba</groupId>
|
|
||||||
<artifactId>druid-spring-boot-starter</artifactId>
|
|
||||||
<version>${druid.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Job 相关 -->
|
<!-- Job 相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -49,7 +49,9 @@ public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
|
|||||||
RESOURCE_PARENT_NOT_MENU(1002003005, "父资源的类型必须是菜单"),
|
RESOURCE_PARENT_NOT_MENU(1002003005, "父资源的类型必须是菜单"),
|
||||||
|
|
||||||
// ========== 角色模块 1002004000 ==========
|
// ========== 角色模块 1002004000 ==========
|
||||||
// ROLE_NOT_EXISTS(1002004000, "角色不存在"),
|
ROLE_NOT_EXISTS(1002004000, "角色不存在"),
|
||||||
|
ROLE_NAME_DUPLICATE(1002004001, "已经存在名为【{}}】的角色"),
|
||||||
|
ROLE_CODE_DUPLICATE(1002004002, "已经存在编码为【{}}】的角色"),
|
||||||
// ROLE_ASSIGN_RESOURCE_NOT_EXISTS(1002004001, "分配角色资源时,有资源不存在"),
|
// ROLE_ASSIGN_RESOURCE_NOT_EXISTS(1002004001, "分配角色资源时,有资源不存在"),
|
||||||
|
|
||||||
// ========== 数据字典模块 1002005000 ==========
|
// ========== 数据字典模块 1002005000 ==========
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
package cn.iocoder.mall.system.biz.convert.authorization;
|
package cn.iocoder.mall.system.biz.convert.authorization;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.PageResult;
|
||||||
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
||||||
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
|
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleAddDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleUpdateDTO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -16,4 +21,11 @@ public interface RoleConvert {
|
|||||||
|
|
||||||
List<RoleBO> convertList(List<RoleDO> beans);
|
List<RoleBO> convertList(List<RoleDO> beans);
|
||||||
|
|
||||||
|
@Mapping(source = "records", target = "list")
|
||||||
|
PageResult<RoleBO> convertPage(IPage<RoleDO> page);
|
||||||
|
|
||||||
|
RoleDO convert(RoleAddDTO bean);
|
||||||
|
|
||||||
|
RoleDO convert(RoleUpdateDTO bean);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,11 @@ public interface ResourceMapper extends BaseMapper<ResourceDO> {
|
|||||||
return selectOne(new QueryWrapper<ResourceDO>().eq("permission", permission));
|
return selectOne(new QueryWrapper<ResourceDO>().eq("permission", permission));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default ResourceDO selectByPidAndName(Integer pid, String name) {
|
||||||
|
return selectOne(new QueryWrapperX<ResourceDO>().eqIfPresent("pid", pid)
|
||||||
|
.eqIfPresent("name", name));
|
||||||
|
}
|
||||||
|
|
||||||
default List<ResourceDO> selectListByPermissions(Collection<String> permissions) {
|
default List<ResourceDO> selectListByPermissions(Collection<String> permissions) {
|
||||||
return selectList(new QueryWrapper<ResourceDO>().in("permission", permissions));
|
return selectList(new QueryWrapper<ResourceDO>().in("permission", permissions));
|
||||||
}
|
}
|
||||||
|
@ -23,4 +23,12 @@ public interface RoleMapper extends BaseMapper<RoleDO> {
|
|||||||
new QueryWrapperX<RoleDO>().likeIfPresent("name", rolePageDTO.getName()));
|
new QueryWrapperX<RoleDO>().likeIfPresent("name", rolePageDTO.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default RoleDO selectByName(String name) {
|
||||||
|
return selectOne(new QueryWrapperX<RoleDO>().eqIfPresent("name", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
default RoleDO selectByCode(String code) {
|
||||||
|
return selectOne(new QueryWrapperX<RoleDO>().eqIfPresent("code", code));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,11 @@ package cn.iocoder.mall.system.biz.dto.authorization;
|
|||||||
|
|
||||||
import cn.iocoder.common.framework.validator.InEnum;
|
import cn.iocoder.common.framework.validator.InEnum;
|
||||||
import cn.iocoder.mall.system.biz.enums.authorization.ResourceTypeEnum;
|
import cn.iocoder.mall.system.biz.enums.authorization.ResourceTypeEnum;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 资源模块 - 更新资源 DTO
|
* 资源模块 - 更新资源 DTO
|
||||||
@ -20,34 +18,33 @@ public class ResourceUpdateDTO {
|
|||||||
@NotNull(message = "管理员编号不能为空")
|
@NotNull(message = "管理员编号不能为空")
|
||||||
private Integer adminId;
|
private Integer adminId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "资源编号", required = true, example = "1")
|
|
||||||
@NotNull(message = "资源编号不能为空")
|
@NotNull(message = "资源编号不能为空")
|
||||||
private Integer id;
|
private Integer id;
|
||||||
|
|
||||||
@ApiModelProperty(value = "资源类型。1 代表【菜单】;2 代表【按钮】", required = true, example = "1")
|
|
||||||
@NotNull(message = "类型不能为空")
|
@NotNull(message = "类型不能为空")
|
||||||
@InEnum(value = ResourceTypeEnum.class, message = "资源类型必须是 {value}")
|
@InEnum(value = ResourceTypeEnum.class, message = "资源类型必须是 {value}")
|
||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
@ApiModelProperty(value = "排序", required = true, example = "1")
|
|
||||||
@NotNull(message = "类型不能为空")
|
@NotNull(message = "类型不能为空")
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
@ApiModelProperty(value = "菜单展示名", required = true, example = "商品管理")
|
|
||||||
@NotEmpty(message = "资源名字不能为空")
|
@NotEmpty(message = "资源名字不能为空")
|
||||||
private String displayName;
|
private String name;
|
||||||
|
|
||||||
@ApiModelProperty(value = "父级资源编号", required = true, example = "1")
|
|
||||||
@NotNull(message = "父级资源编号不能为空")
|
@NotNull(message = "父级资源编号不能为空")
|
||||||
private Integer pid;
|
private Integer pid;
|
||||||
|
|
||||||
@ApiModelProperty(value = "操作", example = "/order/list")
|
/**
|
||||||
private String handler;
|
* 前端路由
|
||||||
|
*/
|
||||||
@ApiModelProperty(value = "图标", example = "add")
|
private String route;
|
||||||
|
/**
|
||||||
|
* 图标
|
||||||
|
*/
|
||||||
private String icon;
|
private String icon;
|
||||||
|
/**
|
||||||
@ApiModelProperty(value = "权限标识数组", example = "system.order.add,system.order.update")
|
* 权限标识
|
||||||
private List<String> permissions;
|
*/
|
||||||
|
private String permission;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.iocoder.mall.system.biz.dto.authorization;
|
package cn.iocoder.mall.system.biz.dto.authorization;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.vo.PageParam;
|
import cn.iocoder.common.framework.vo.PageParam;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@ -14,7 +13,9 @@ import lombok.experimental.Accessors;
|
|||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public class RolePageDTO extends PageParam {
|
public class RolePageDTO extends PageParam {
|
||||||
|
|
||||||
@ApiModelProperty( value = "角色名,模糊匹配", example = "系统管理员")
|
/**
|
||||||
|
* 角色名,模糊匹配
|
||||||
|
*/
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package cn.iocoder.mall.system.biz.event.authorization;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link RoleDO} 删除事件
|
||||||
|
*/
|
||||||
|
public class RoleDeleteEvent extends ApplicationEvent {
|
||||||
|
/**
|
||||||
|
* 角色编号
|
||||||
|
*/
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
public RoleDeleteEvent(Object source) {
|
||||||
|
super(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoleDeleteEvent(Object source, Integer id) {
|
||||||
|
super(source);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -124,4 +124,12 @@ public class AuthorizationServiceImpl implements AuthorizationService {
|
|||||||
roleResourceMapper.deleteByResourceId(event.getId());
|
roleResourceMapper.deleteByResourceId(event.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventListener
|
||||||
|
public void handleRoleDeleteEvent(ResourceDeleteEvent event) {
|
||||||
|
// 标记删除 RoleResource
|
||||||
|
roleResourceMapper.deleteByRoleId(event.getId());
|
||||||
|
// 标记删除 AdminRole
|
||||||
|
accountRoleMapper.deleteByRoleId(event.getId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationEventPublisher;
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -77,6 +78,8 @@ public class ResourceServiceImpl implements ResourceService {
|
|||||||
public Integer addResource(ResourceAddDTO addDTO) {
|
public Integer addResource(ResourceAddDTO addDTO) {
|
||||||
// 校验父资源存在
|
// 校验父资源存在
|
||||||
checkParentResource(addDTO.getPid(), null);
|
checkParentResource(addDTO.getPid(), null);
|
||||||
|
// 校验资源(自己)
|
||||||
|
checkResource(addDTO.getPid(), addDTO.getName(), null);
|
||||||
// 存储到数据库
|
// 存储到数据库
|
||||||
ResourceDO resource = ResourceConvert.INSTANCE.convert(addDTO);
|
ResourceDO resource = ResourceConvert.INSTANCE.convert(addDTO);
|
||||||
initResourceProperty(resource);
|
initResourceProperty(resource);
|
||||||
@ -92,10 +95,12 @@ public class ResourceServiceImpl implements ResourceService {
|
|||||||
public void updateResource(ResourceUpdateDTO updateDTO) {
|
public void updateResource(ResourceUpdateDTO updateDTO) {
|
||||||
// 校验更新的资源是否存在
|
// 校验更新的资源是否存在
|
||||||
if (resourceMapper.selectById(updateDTO.getId()) == null) {
|
if (resourceMapper.selectById(updateDTO.getId()) == null) {
|
||||||
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
// 校验父资源存在
|
// 校验父资源存在
|
||||||
checkParentResource(updateDTO.getPid(), updateDTO.getId());
|
checkParentResource(updateDTO.getPid(), updateDTO.getId());
|
||||||
|
// 校验资源(自己)
|
||||||
|
checkResource(updateDTO.getPid(), updateDTO.getName(), updateDTO.getId());
|
||||||
// 更新到数据库
|
// 更新到数据库
|
||||||
ResourceDO resource = ResourceConvert.INSTANCE.convert(updateDTO);
|
ResourceDO resource = ResourceConvert.INSTANCE.convert(updateDTO);
|
||||||
initResourceProperty(resource);
|
initResourceProperty(resource);
|
||||||
@ -104,24 +109,29 @@ public class ResourceServiceImpl implements ResourceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional
|
||||||
public void deleteResource(ResourceDeleteDTO deleteDTO) {
|
public void deleteResource(ResourceDeleteDTO deleteDTO) {
|
||||||
// 校验更新的资源是否存在
|
// 校验更新的资源是否存在
|
||||||
if (resourceMapper.selectById(deleteDTO.getId()) == null) {
|
if (resourceMapper.selectById(deleteDTO.getId()) == null) {
|
||||||
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
// 校验是否还有子资源
|
// 校验是否还有子资源
|
||||||
if (resourceMapper.selectCountByPid(deleteDTO.getId()) > 0) {
|
if (resourceMapper.selectCountByPid(deleteDTO.getId()) > 0) {
|
||||||
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_EXISTS_CHILDREN.getCode());
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_EXISTS_CHILDREN);
|
||||||
}
|
}
|
||||||
// 更新到数据库
|
// 更新到数据库
|
||||||
resourceMapper.deleteById(deleteDTO.getId());
|
resourceMapper.deleteById(deleteDTO.getId());
|
||||||
// 删除资源关联表
|
// 发布资源删除事件,方便清理关联表
|
||||||
eventPublisher.publishEvent(new ResourceDeleteEvent(this, deleteDTO.getId()));
|
eventPublisher.publishEvent(new ResourceDeleteEvent(this, deleteDTO.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验父资源是否合法
|
* 校验父资源是否合法
|
||||||
*
|
*
|
||||||
|
* 1. 不能舌质红自己为父资源
|
||||||
|
* 2. 父资源不存在
|
||||||
|
* 3. 父资源必须是 {@link ResourceTypeEnum#MENU} 菜单类型
|
||||||
|
*
|
||||||
* @param pid 父资源编号
|
* @param pid 父资源编号
|
||||||
* @param childId 当前资源编号
|
* @param childId 当前资源编号
|
||||||
*/
|
*/
|
||||||
@ -130,14 +140,37 @@ public class ResourceServiceImpl implements ResourceService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pid.equals(childId)) { // 不能设置自己为父资源
|
if (pid.equals(childId)) { // 不能设置自己为父资源
|
||||||
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_PARENT_ERROR.getCode());
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_PARENT_ERROR);
|
||||||
}
|
}
|
||||||
ResourceDO resource = resourceMapper.selectById(pid);
|
ResourceDO resource = resourceMapper.selectById(pid);
|
||||||
if (resource == null) { // 父资源不存在
|
if (resource == null) { // 父资源不存在
|
||||||
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_PARENT_NOT_EXISTS.getCode());
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_PARENT_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
if (!ResourceTypeEnum.MENU.getType().equals(resource.getType())) { // 父资源必须是菜单类型
|
if (!ResourceTypeEnum.MENU.getType().equals(resource.getType())) { // 父资源必须是菜单类型
|
||||||
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_PARENT_NOT_MENU.getCode());
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_PARENT_NOT_MENU);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验资源是否合法
|
||||||
|
*
|
||||||
|
* 1. 校验相同父资源编号下,是否存在相同的资源名
|
||||||
|
*
|
||||||
|
* @param name 资源名字
|
||||||
|
* @param pid 父资源编号
|
||||||
|
* @param id 资源编号
|
||||||
|
*/
|
||||||
|
private void checkResource(Integer pid, String name, Integer id) {
|
||||||
|
ResourceDO resource = resourceMapper.selectByPidAndName(pid, name);
|
||||||
|
if (resource == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 如果 id 为空,说明不用比较是否为相同 id 的资源
|
||||||
|
if (id == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_NAME_DUPLICATE);
|
||||||
|
}
|
||||||
|
if (!resource.getId().equals(id)) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.RESOURCE_NAME_DUPLICATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,10 +182,6 @@ public class ResourceServiceImpl implements ResourceService {
|
|||||||
* @param resource 资源
|
* @param resource 资源
|
||||||
*/
|
*/
|
||||||
private void initResourceProperty(ResourceDO resource) {
|
private void initResourceProperty(ResourceDO resource) {
|
||||||
// 初始化根节点的情况
|
|
||||||
if (resource.getPid() == null) {
|
|
||||||
resource.setPid(ResourceIdEnum.ROOT.getId());
|
|
||||||
}
|
|
||||||
// 初始化资源为按钮类型时,无需 route 和 icon 属性
|
// 初始化资源为按钮类型时,无需 route 和 icon 属性
|
||||||
if (ResourceTypeEnum.BUTTON.getType().equals(resource.getType())) {
|
if (ResourceTypeEnum.BUTTON.getType().equals(resource.getType())) {
|
||||||
resource.setRoute(null);
|
resource.setRoute(null);
|
||||||
|
@ -1,14 +1,24 @@
|
|||||||
package cn.iocoder.mall.system.biz.service.authorization;
|
package cn.iocoder.mall.system.biz.service.authorization;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.PageResult;
|
||||||
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleAddDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleDeleteDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleUpdateDTO;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 角色模块 - Service 接口
|
||||||
|
*/
|
||||||
public interface RoleService {
|
public interface RoleService {
|
||||||
|
|
||||||
List<RoleBO> getRoleList(Collection<Integer> ids);
|
List<RoleBO> getRoleList(Collection<Integer> ids);
|
||||||
|
|
||||||
|
PageResult<RoleBO> getRolePage(RolePageDTO pageDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断指定角色是否包含超级管理员角色
|
* 判断指定角色是否包含超级管理员角色
|
||||||
*
|
*
|
||||||
@ -17,4 +27,10 @@ public interface RoleService {
|
|||||||
*/
|
*/
|
||||||
boolean hasSuperAdmin(Collection<Integer> ids);
|
boolean hasSuperAdmin(Collection<Integer> ids);
|
||||||
|
|
||||||
|
Integer addRole(RoleAddDTO roleAddDTO);
|
||||||
|
|
||||||
|
void updateRole(RoleUpdateDTO roleUpdateDTO);
|
||||||
|
|
||||||
|
void deleteRole(RoleDeleteDTO roleDeleteDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,36 @@
|
|||||||
package cn.iocoder.mall.system.biz.service.authorization;
|
package cn.iocoder.mall.system.biz.service.authorization;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||||
|
import cn.iocoder.common.framework.util.StringUtil;
|
||||||
|
import cn.iocoder.common.framework.vo.PageResult;
|
||||||
|
import cn.iocoder.mall.mybatis.enums.DeletedStatusEnum;
|
||||||
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
||||||
import cn.iocoder.mall.system.biz.convert.authorization.RoleConvert;
|
import cn.iocoder.mall.system.biz.convert.authorization.RoleConvert;
|
||||||
import cn.iocoder.mall.system.biz.dao.authorization.RoleMapper;
|
import cn.iocoder.mall.system.biz.dao.authorization.RoleMapper;
|
||||||
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
|
import cn.iocoder.mall.system.biz.dataobject.authorization.RoleDO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleAddDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleDeleteDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleUpdateDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.enums.SystemErrorCodeEnum;
|
||||||
import cn.iocoder.mall.system.biz.enums.authorization.RoleCodeEnum;
|
import cn.iocoder.mall.system.biz.enums.authorization.RoleCodeEnum;
|
||||||
|
import cn.iocoder.mall.system.biz.event.authorization.ResourceDeleteEvent;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class RoleServiceImpl implements RoleService {
|
public class RoleServiceImpl implements RoleService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoleMapper roleMapper;
|
private RoleMapper roleMapper;
|
||||||
|
|
||||||
@ -23,6 +40,12 @@ public class RoleServiceImpl implements RoleService {
|
|||||||
return RoleConvert.INSTANCE.convertList(roleDOs);
|
return RoleConvert.INSTANCE.convertList(roleDOs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<RoleBO> getRolePage(RolePageDTO pageDTO) {
|
||||||
|
IPage<RoleDO> pageResult = roleMapper.selectPage(pageDTO);
|
||||||
|
return RoleConvert.INSTANCE.convertPage(pageResult);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSuperAdmin(Collection<Integer> ids) {
|
public boolean hasSuperAdmin(Collection<Integer> ids) {
|
||||||
List<RoleDO> roleDOs = roleMapper.selectBatchIds(ids);
|
List<RoleDO> roleDOs = roleMapper.selectBatchIds(ids);
|
||||||
@ -34,4 +57,84 @@ public class RoleServiceImpl implements RoleService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer addRole(RoleAddDTO roleAddDTO) {
|
||||||
|
// 校验角色
|
||||||
|
checkRole(roleAddDTO.getName(), roleAddDTO.getCode(), null);
|
||||||
|
// 保存到数据库
|
||||||
|
RoleDO role = RoleConvert.INSTANCE.convert(roleAddDTO);
|
||||||
|
role.setCreateTime(new Date());
|
||||||
|
role.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||||
|
roleMapper.insert(role);
|
||||||
|
// TODO 插入操作日志
|
||||||
|
// 返回成功
|
||||||
|
return role.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateRole(RoleUpdateDTO roleUpdateDTO) {
|
||||||
|
// 校验角色是否存在
|
||||||
|
if (roleMapper.selectById(roleUpdateDTO.getId()) == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
// 校验角色
|
||||||
|
checkRole(roleUpdateDTO.getName(), roleUpdateDTO.getCode(), roleUpdateDTO.getId());
|
||||||
|
// 更新到数据库
|
||||||
|
RoleDO roleDO = RoleConvert.INSTANCE.convert(roleUpdateDTO);
|
||||||
|
roleMapper.updateById(roleDO);
|
||||||
|
// TODO 插入操作日志
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void deleteRole(RoleDeleteDTO roleDeleteDTO) {
|
||||||
|
// 校验角色是否存在
|
||||||
|
if (roleMapper.selectById(roleDeleteDTO.getId()) == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
// 更新到数据库,标记删除
|
||||||
|
roleMapper.deleteById(roleDeleteDTO.getId());
|
||||||
|
// TODO 插入操作日志
|
||||||
|
// 发布角色删除事件,方便清理关联表
|
||||||
|
eventPublisher.publishEvent(new ResourceDeleteEvent(this, roleDeleteDTO.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验角色是否合法
|
||||||
|
*
|
||||||
|
* 1. 是否存在相同名字的角色
|
||||||
|
* 2. 是否存在相同编码的角色
|
||||||
|
*
|
||||||
|
* @param name 角色名字
|
||||||
|
* @param code 角色额编码
|
||||||
|
* @param id 角色编号
|
||||||
|
*/
|
||||||
|
private void checkRole(String name, String code, Integer id) {
|
||||||
|
// 1. 是否存在相同名字的角色
|
||||||
|
RoleDO role = roleMapper.selectByName(name);
|
||||||
|
if (role != null) {
|
||||||
|
// 如果 id 为空,说明不用比较是否为相同 id 的资源
|
||||||
|
if (id == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NAME_DUPLICATE, name);
|
||||||
|
}
|
||||||
|
if (!role.getId().equals(id)) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_NAME_DUPLICATE, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2. 是否存在相同编码的角色
|
||||||
|
if (!StringUtil.hasText(code)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
role = roleMapper.selectByCode(code);
|
||||||
|
if (role != null) {
|
||||||
|
// 如果 id 为空,说明不用比较是否为相同 id 的资源
|
||||||
|
if (id == null) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_CODE_DUPLICATE, name);
|
||||||
|
}
|
||||||
|
if (!role.getId().equals(id)) {
|
||||||
|
throw ServiceExceptionUtil.exception(SystemErrorCodeEnum.ROLE_CODE_DUPLICATE, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
package cn.iocoder.mall.system.rest.controller.authorization;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.constant.MallConstants;
|
||||||
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.common.framework.vo.PageResult;
|
||||||
|
import cn.iocoder.mall.security.core.annotation.RequiresPermissions;
|
||||||
|
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
|
||||||
|
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleAddDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleDeleteDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleUpdateDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.service.authorization.RoleService;
|
||||||
|
import cn.iocoder.mall.system.rest.convert.authorization.AdminsRoleConvert;
|
||||||
|
import cn.iocoder.mall.system.rest.request.authorization.AdminsRoleAddRequest;
|
||||||
|
import cn.iocoder.mall.system.rest.request.authorization.AdminsRolePageRequest;
|
||||||
|
import cn.iocoder.mall.system.rest.request.authorization.AdminsRoleUpdateRequest;
|
||||||
|
import cn.iocoder.mall.system.rest.response.authorization.AdminsRolePageResponse;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiImplicitParam;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "/role")
|
||||||
|
@Api(tags = "管理员 - 角色 API")
|
||||||
|
public class AdminsRoleController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RoleService roleService;
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@ApiOperation(value = "角色分页")
|
||||||
|
@RequiresPermissions("system:role:page")
|
||||||
|
public CommonResult<PageResult<AdminsRolePageResponse>> page(AdminsRolePageRequest request) {
|
||||||
|
RolePageDTO pageDTO = AdminsRoleConvert.INSTANCE.convert(request);
|
||||||
|
PageResult<RoleBO> pageResult = roleService.getRolePage(pageDTO);
|
||||||
|
return CommonResult.success(AdminsRoleConvert.INSTANCE.convertPage(pageResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/add")
|
||||||
|
@ApiOperation(value = "创建角色")
|
||||||
|
@RequiresPermissions("system:role:add")
|
||||||
|
public CommonResult<Integer> add(AdminsRoleAddRequest request) {
|
||||||
|
RoleAddDTO addDTO = AdminsRoleConvert.INSTANCE.convert(request)
|
||||||
|
.setAdminId(AdminSecurityContextHolder.getAdminId());
|
||||||
|
return CommonResult.success(roleService.addRole(addDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/update")
|
||||||
|
@ApiOperation(value = "更新角色")
|
||||||
|
@RequiresPermissions("system:role:update")
|
||||||
|
public CommonResult<Boolean> update(AdminsRoleUpdateRequest request) {
|
||||||
|
RoleUpdateDTO updateDTO = AdminsRoleConvert.INSTANCE.convert(request)
|
||||||
|
.setAdminId(AdminSecurityContextHolder.getAdminId());
|
||||||
|
roleService.updateRole(updateDTO);
|
||||||
|
return CommonResult.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete")
|
||||||
|
@ApiOperation(value = "删除角色")
|
||||||
|
@RequiresPermissions("system:role:delete")
|
||||||
|
@ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1")
|
||||||
|
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
|
||||||
|
RoleDeleteDTO deleteDTO = new RoleDeleteDTO().setId(id)
|
||||||
|
.setAdminId(AdminSecurityContextHolder.getAdminId());
|
||||||
|
roleService.deleteRole(deleteDTO);
|
||||||
|
return CommonResult.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @GetMapping("/role_tree")
|
||||||
|
// @ApiOperation(value = "获得角色拥有的菜单权限", notes = "以树结构返回")
|
||||||
|
// @ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1")
|
||||||
|
// public CommonResult<List<RoleRoleTreeNodeVO>> roleTree(@RequestParam("id") Integer id) {
|
||||||
|
// // 芋艿:此处,严格来说可以在校验下角色是否存在。不过呢,校验了也没啥意义,因为一般不存在这个情况,且不会有业务上的影响。并且,反倒多了一次 rpc 调用。
|
||||||
|
// // 第一步,获得角色拥有的资源数组
|
||||||
|
// Set<Integer> roleRoles = roleService.getRolesByTypeAndRoleIds(null, CollectionUtil.asSet(id))
|
||||||
|
// .stream().map(RoleBO::getId).collect(Collectors.toSet());
|
||||||
|
// // 第二步,获得资源树
|
||||||
|
// List<RoleBO> allRoles = roleService.getRolesByType(null);
|
||||||
|
// // 创建 AdminMenuTreeNodeVO Map
|
||||||
|
// Map<Integer, RoleRoleTreeNodeVO> treeNodeMap = allRoles.stream().collect(Collectors.toMap(RoleBO::getId, RoleConvert.INSTANCE::convert4));
|
||||||
|
// // 处理父子关系
|
||||||
|
// treeNodeMap.values().stream()
|
||||||
|
// .filter(node -> !node.getPid().equals(RoleConstants.PID_ROOT))
|
||||||
|
// .forEach((childNode) -> {
|
||||||
|
// // 获得父节点
|
||||||
|
// RoleRoleTreeNodeVO parentNode = treeNodeMap.get(childNode.getPid());
|
||||||
|
// if (parentNode.getChildren() == null) { // 初始化 children 数组
|
||||||
|
// parentNode.setChildren(new ArrayList<>());
|
||||||
|
// }
|
||||||
|
// // 将自己添加到父节点中
|
||||||
|
// parentNode.getChildren().add(childNode);
|
||||||
|
// });
|
||||||
|
// // 获得到所有的根节点
|
||||||
|
// List<RoleRoleTreeNodeVO> rootNodes = treeNodeMap.values().stream()
|
||||||
|
// .filter(node -> node.getPid().equals(RoleConstants.PID_ROOT))
|
||||||
|
// .sorted(Comparator.comparing(RoleRoleTreeNodeVO::getSort))
|
||||||
|
// .collect(Collectors.toList());
|
||||||
|
// // 第三步,设置角色是否有该角色
|
||||||
|
// treeNodeMap.values().forEach(nodeVO -> nodeVO.setAssigned(roleRoles.contains(nodeVO.getId())));
|
||||||
|
// // 返回结果
|
||||||
|
// return success(rootNodes);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @PostMapping("/assign_role")
|
||||||
|
// @ApiOperation(value = "分配角色资源")
|
||||||
|
// public CommonResult<Boolean> assignRole(RoleAssignRoleDTO roleAssignRoleDTO) {
|
||||||
|
// return success(roleService.assignRoleRole(AdminSecurityContextHolder.getContext().getAdminId(), roleAssignRoleDTO));
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package cn.iocoder.mall.system.rest.convert.authorization;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.PageResult;
|
||||||
|
import cn.iocoder.mall.system.biz.bo.authorization.RoleBO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleAddDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RolePageDTO;
|
||||||
|
import cn.iocoder.mall.system.biz.dto.authorization.RoleUpdateDTO;
|
||||||
|
import cn.iocoder.mall.system.rest.request.authorization.AdminsRoleAddRequest;
|
||||||
|
import cn.iocoder.mall.system.rest.request.authorization.AdminsRolePageRequest;
|
||||||
|
import cn.iocoder.mall.system.rest.request.authorization.AdminsRoleUpdateRequest;
|
||||||
|
import cn.iocoder.mall.system.rest.response.authorization.AdminsRolePageResponse;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface AdminsRoleConvert {
|
||||||
|
|
||||||
|
AdminsRoleConvert INSTANCE = Mappers.getMapper(AdminsRoleConvert.class);
|
||||||
|
|
||||||
|
RoleAddDTO convert(AdminsRoleAddRequest bean);
|
||||||
|
|
||||||
|
RoleUpdateDTO convert(AdminsRoleUpdateRequest bean);
|
||||||
|
|
||||||
|
RolePageDTO convert(AdminsRolePageRequest bean);
|
||||||
|
|
||||||
|
PageResult<AdminsRolePageResponse> convertPage(PageResult<RoleBO> bean);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package cn.iocoder.mall.system.rest.request.authorization;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.PageParam;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
@ApiModel("管理员 - 角色模块 - 分页列表 Request")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AdminsRolePageRequest extends PageParam {
|
||||||
|
|
||||||
|
@ApiModelProperty( value = "角色名,模糊匹配", example = "系统管理员")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.mall.system.rest.request.authorization;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@ApiModel("管理员 - 角色模块 - 修改角色 Request")
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AdminsRoleUpdateRequest {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "角色编号", required = true, example = "1")
|
||||||
|
@NotNull(message = "角色编号不能为空")
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "角色名字", required = true, example = "系统管理员")
|
||||||
|
@NotEmpty(message = "角色名字不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "角色编码", example = "SUPER_ADMIN")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package cn.iocoder.mall.system.rest.response.authorization;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ApiModel("管理员 - 角色模块 - 分页列表 Response")
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class AdminsRolePageResponse {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "角色编号", required = true, example = "1")
|
||||||
|
private Integer id;
|
||||||
|
@ApiModelProperty(value = "角色名字", required = true, example = "管理员")
|
||||||
|
private String name;
|
||||||
|
@ApiModelProperty(value = "角色编码", example = "SUPER_ADMIN")
|
||||||
|
private String code;
|
||||||
|
@ApiModelProperty(value = "创建时间", required = true)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
}
|
@ -19,12 +19,6 @@ public interface RoleService {
|
|||||||
*/
|
*/
|
||||||
List<RoleBO> getRoleList();
|
List<RoleBO> getRoleList();
|
||||||
|
|
||||||
RoleBO addRole(Integer adminId, RoleAddDTO roleAddDTO);
|
|
||||||
|
|
||||||
Boolean updateRole(Integer adminId, RoleUpdateDTO roleUpdateDTO);
|
|
||||||
|
|
||||||
Boolean deleteRole(Integer adminId, Integer roleId);
|
|
||||||
|
|
||||||
Boolean assignRoleResource(Integer adminId, RoleAssignResourceDTO roleAssignResourceDTO);
|
Boolean assignRoleResource(Integer adminId, RoleAssignResourceDTO roleAssignResourceDTO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,7 @@ public class RoleServiceImpl implements RoleService {
|
|||||||
private RoleResourceMapper roleResourceMapper;
|
private RoleResourceMapper roleResourceMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private AdminRoleMapper adminRoleMapper;
|
private AdminRoleMapper adminRoleMapper;
|
||||||
@Autowired
|
|
||||||
private RoleMapper roleMapper;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ResourceServiceImpl resourceService;
|
private ResourceServiceImpl resourceService;
|
||||||
@ -36,70 +35,6 @@ public class RoleServiceImpl implements RoleService {
|
|||||||
return roleResourceMapper.selectListByResourceId(resourceId);
|
return roleResourceMapper.selectListByResourceId(resourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<RoleBO> getRolePage(RolePageDTO rolePageDTO) {
|
|
||||||
IPage<RoleDO> page = roleMapper.selectPage(rolePageDTO);
|
|
||||||
return RoleConvert.INSTANCE.convert(page);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<RoleBO> getRoleList() {
|
|
||||||
List<RoleDO> roleList = roleMapper.selectList();
|
|
||||||
return RoleConvert.INSTANCE.convert(roleList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<RoleBO> getRoleList(Collection<Integer> ids) {
|
|
||||||
List<RoleDO> roles = roleMapper.selectBatchIds(ids);
|
|
||||||
return RoleConvert.INSTANCE.convert(roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public RoleBO addRole(Integer adminId, RoleAddDTO roleAddDTO) {
|
|
||||||
// TODO 芋艿,角色名是否要唯一呢?貌似一般系统都是允许的。
|
|
||||||
// 保存到数据库
|
|
||||||
RoleDO role = RoleConvert.INSTANCE.convert(roleAddDTO);
|
|
||||||
role.setCreateTime(new Date());
|
|
||||||
role.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
|
||||||
roleMapper.insert(role);
|
|
||||||
// TODO 插入操作日志
|
|
||||||
// 返回成功
|
|
||||||
return RoleConvert.INSTANCE.convert(role);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean updateRole(Integer adminId, RoleUpdateDTO roleUpdateDTO) {
|
|
||||||
// TODO 芋艿,角色名是否要唯一呢?貌似一般系统都是允许的。
|
|
||||||
// 校验角色是否存在
|
|
||||||
if (roleMapper.selectById(roleUpdateDTO.getId()) == null) {
|
|
||||||
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
|
||||||
}
|
|
||||||
// 更新到数据库
|
|
||||||
RoleDO roleDO = RoleConvert.INSTANCE.convert(roleUpdateDTO);
|
|
||||||
roleMapper.updateById(roleDO);
|
|
||||||
// TODO 插入操作日志
|
|
||||||
// 返回成功
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional
|
|
||||||
public Boolean deleteRole(Integer adminId, Integer roleId) {
|
|
||||||
// 校验角色是否存在
|
|
||||||
if (roleMapper.selectById(roleId) == null) {
|
|
||||||
throw ServiceExceptionUtil.exception(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode());
|
|
||||||
}
|
|
||||||
// 更新到数据库,标记删除
|
|
||||||
roleMapper.deleteById(roleId);
|
|
||||||
// 标记删除 RoleResource
|
|
||||||
roleResourceMapper.deleteByRoleId(roleId);
|
|
||||||
// 标记删除 AdminRole
|
|
||||||
adminRoleMapper.deleteByRoleId(roleId);
|
|
||||||
// TODO 插入操作日志
|
|
||||||
// 返回成功
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public Boolean assignRoleResource(Integer adminId, RoleAssignResourceDTO roleAssignResourceDTO) {
|
public Boolean assignRoleResource(Integer adminId, RoleAssignResourceDTO roleAssignResourceDTO) {
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
package cn.iocoder.mall.system.application.controller.admins;
|
|
||||||
|
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
|
||||||
import cn.iocoder.mall.system.api.ResourceService;
|
|
||||||
import cn.iocoder.mall.system.api.bo.resource.ResourceBO;
|
|
||||||
import cn.iocoder.mall.system.api.constant.ResourceConstants;
|
|
||||||
import cn.iocoder.mall.system.api.dto.resource.ResourceAddDTO;
|
|
||||||
import cn.iocoder.mall.system.api.dto.resource.ResourceUpdateDTO;
|
|
||||||
import cn.iocoder.mall.system.application.convert.ResourceConvert;
|
|
||||||
import cn.iocoder.mall.system.application.vo.resource.ResourceTreeNodeVO;
|
|
||||||
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.apache.dubbo.config.annotation.Reference;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("admins/resource")
|
|
||||||
@Api("资源模块")
|
|
||||||
public class ResourceController {
|
|
||||||
|
|
||||||
@Reference(validation = "true", version = "${dubbo.provider.ResourceService.version}")
|
|
||||||
private ResourceService resourceService;
|
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
|
||||||
@GetMapping("/tree")
|
|
||||||
@ApiOperation(value = "获得所有资源,按照树形结构返回")
|
|
||||||
public CommonResult<List<ResourceTreeNodeVO>> tree() {
|
|
||||||
List<ResourceBO> resources = resourceService.getResourcesByType(null);
|
|
||||||
// 创建 AdminMenuTreeNodeVO Map
|
|
||||||
Map<Integer, ResourceTreeNodeVO> treeNodeMap = resources.stream().collect(Collectors.toMap(ResourceBO::getId, ResourceConvert.INSTANCE::convert2));
|
|
||||||
// 处理父子关系
|
|
||||||
treeNodeMap.values().stream()
|
|
||||||
.filter(node -> !node.getPid().equals(ResourceConstants.PID_ROOT))
|
|
||||||
.forEach((childNode) -> {
|
|
||||||
// 获得父节点
|
|
||||||
ResourceTreeNodeVO parentNode = treeNodeMap.get(childNode.getPid());
|
|
||||||
if (parentNode.getChildren() == null) { // 初始化 children 数组
|
|
||||||
parentNode.setChildren(new ArrayList<>());
|
|
||||||
}
|
|
||||||
// 将自己添加到父节点中
|
|
||||||
parentNode.getChildren().add(childNode);
|
|
||||||
});
|
|
||||||
// 获得到所有的根节点
|
|
||||||
List<ResourceTreeNodeVO> rootNodes = treeNodeMap.values().stream()
|
|
||||||
.filter(node -> node.getPid().equals(ResourceConstants.PID_ROOT))
|
|
||||||
.sorted(Comparator.comparing(ResourceTreeNodeVO::getSort))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
return success(rootNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/add")
|
|
||||||
@ApiOperation(value = "创建资源", notes = "例如说,菜单资源,Url 资源")
|
|
||||||
public CommonResult<ResourceBO> add(ResourceAddDTO resourceAddDTO) {
|
|
||||||
return success(resourceService.addResource(AdminSecurityContextHolder.getContext().getAdminId(), resourceAddDTO));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/update")
|
|
||||||
@ApiOperation(value = "更新资源")
|
|
||||||
public CommonResult<Boolean> update(ResourceUpdateDTO resourceUpdateDTO) {
|
|
||||||
return success(resourceService.updateResource(AdminSecurityContextHolder.getContext().getAdminId(), resourceUpdateDTO));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/delete")
|
|
||||||
@ApiOperation(value = "删除资源")
|
|
||||||
@ApiImplicitParam(name = "id", value = "资源编号", required = true, example = "1")
|
|
||||||
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
|
|
||||||
return success(resourceService.deleteResource(AdminSecurityContextHolder.getContext().getAdminId(), id));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,107 +0,0 @@
|
|||||||
package cn.iocoder.mall.system.application.controller.admins;
|
|
||||||
|
|
||||||
import cn.iocoder.common.framework.util.CollectionUtil;
|
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
|
||||||
import cn.iocoder.common.framework.vo.PageResult;
|
|
||||||
import cn.iocoder.mall.system.api.ResourceService;
|
|
||||||
import cn.iocoder.mall.system.api.RoleService;
|
|
||||||
import cn.iocoder.mall.system.api.bo.resource.ResourceBO;
|
|
||||||
import cn.iocoder.mall.system.api.bo.role.RoleBO;
|
|
||||||
import cn.iocoder.mall.system.api.constant.ResourceConstants;
|
|
||||||
import cn.iocoder.mall.system.api.dto.role.RoleAddDTO;
|
|
||||||
import cn.iocoder.mall.system.api.dto.role.RoleAssignResourceDTO;
|
|
||||||
import cn.iocoder.mall.system.api.dto.role.RolePageDTO;
|
|
||||||
import cn.iocoder.mall.system.api.dto.role.RoleUpdateDTO;
|
|
||||||
import cn.iocoder.mall.system.application.convert.ResourceConvert;
|
|
||||||
import cn.iocoder.mall.system.application.vo.role.RoleResourceTreeNodeVO;
|
|
||||||
import cn.iocoder.mall.system.sdk.context.AdminSecurityContextHolder;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiImplicitParam;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.apache.dubbo.config.annotation.Reference;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("admins/role")
|
|
||||||
@Api("角色模块")
|
|
||||||
public class RoleController {
|
|
||||||
|
|
||||||
@Reference(validation = "true", version = "${dubbo.provider.RoleService.version}")
|
|
||||||
private RoleService roleService;
|
|
||||||
|
|
||||||
@Reference(validation = "true", version = "${dubbo.provider.ResourceService.version}")
|
|
||||||
private ResourceService resourceService;
|
|
||||||
|
|
||||||
@GetMapping("/page")
|
|
||||||
@ApiOperation(value = "角色分页")
|
|
||||||
public CommonResult<PageResult<RoleBO>> page(RolePageDTO rolePageDTO) {
|
|
||||||
return success(roleService.getRolePage(rolePageDTO));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/add")
|
|
||||||
@ApiOperation(value = "创建角色")
|
|
||||||
public CommonResult<RoleBO> add(RoleAddDTO roleAddDTO) {
|
|
||||||
return success(roleService.addRole(AdminSecurityContextHolder.getContext().getAdminId(), roleAddDTO));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/update")
|
|
||||||
@ApiOperation(value = "更新角色")
|
|
||||||
public CommonResult<Boolean> update(RoleUpdateDTO roleUpdateDTO) {
|
|
||||||
return success(roleService.updateRole(AdminSecurityContextHolder.getContext().getAdminId(), roleUpdateDTO));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/delete")
|
|
||||||
@ApiOperation(value = "删除角色")
|
|
||||||
@ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1")
|
|
||||||
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
|
|
||||||
return success(roleService.deleteRole(AdminSecurityContextHolder.getContext().getAdminId(), id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
|
||||||
@GetMapping("/resource_tree")
|
|
||||||
@ApiOperation(value = "获得角色拥有的菜单权限", notes = "以树结构返回")
|
|
||||||
@ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1")
|
|
||||||
public CommonResult<List<RoleResourceTreeNodeVO>> resourceTree(@RequestParam("id") Integer id) {
|
|
||||||
// 芋艿:此处,严格来说可以在校验下角色是否存在。不过呢,校验了也没啥意义,因为一般不存在这个情况,且不会有业务上的影响。并且,反倒多了一次 rpc 调用。
|
|
||||||
// 第一步,获得角色拥有的资源数组
|
|
||||||
Set<Integer> roleResources = resourceService.getResourcesByTypeAndRoleIds(null, CollectionUtil.asSet(id))
|
|
||||||
.stream().map(ResourceBO::getId).collect(Collectors.toSet());
|
|
||||||
// 第二步,获得资源树
|
|
||||||
List<ResourceBO> allResources = resourceService.getResourcesByType(null);
|
|
||||||
// 创建 AdminMenuTreeNodeVO Map
|
|
||||||
Map<Integer, RoleResourceTreeNodeVO> treeNodeMap = allResources.stream().collect(Collectors.toMap(ResourceBO::getId, ResourceConvert.INSTANCE::convert4));
|
|
||||||
// 处理父子关系
|
|
||||||
treeNodeMap.values().stream()
|
|
||||||
.filter(node -> !node.getPid().equals(ResourceConstants.PID_ROOT))
|
|
||||||
.forEach((childNode) -> {
|
|
||||||
// 获得父节点
|
|
||||||
RoleResourceTreeNodeVO parentNode = treeNodeMap.get(childNode.getPid());
|
|
||||||
if (parentNode.getChildren() == null) { // 初始化 children 数组
|
|
||||||
parentNode.setChildren(new ArrayList<>());
|
|
||||||
}
|
|
||||||
// 将自己添加到父节点中
|
|
||||||
parentNode.getChildren().add(childNode);
|
|
||||||
});
|
|
||||||
// 获得到所有的根节点
|
|
||||||
List<RoleResourceTreeNodeVO> rootNodes = treeNodeMap.values().stream()
|
|
||||||
.filter(node -> node.getPid().equals(ResourceConstants.PID_ROOT))
|
|
||||||
.sorted(Comparator.comparing(RoleResourceTreeNodeVO::getSort))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
// 第三步,设置角色是否有该角色
|
|
||||||
treeNodeMap.values().forEach(nodeVO -> nodeVO.setAssigned(roleResources.contains(nodeVO.getId())));
|
|
||||||
// 返回结果
|
|
||||||
return success(rootNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/assign_resource")
|
|
||||||
@ApiOperation(value = "分配角色资源")
|
|
||||||
public CommonResult<Boolean> assignResource(RoleAssignResourceDTO roleAssignResourceDTO) {
|
|
||||||
return success(roleService.assignRoleResource(AdminSecurityContextHolder.getContext().getAdminId(), roleAssignResourceDTO));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user