diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/AdminController.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/AdminController.java index 0c7248cdf..2d0340d42 100644 --- a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/AdminController.java +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/AdminController.java @@ -1,22 +1,72 @@ package cn.iocoder.mall.admin.application.controller; import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.admin.api.ResourceService; +import cn.iocoder.mall.admin.api.bo.ResourceBO; +import cn.iocoder.mall.admin.api.constant.ResourceConstants; +import cn.iocoder.mall.admin.application.convert.ResourceConvert; +import cn.iocoder.mall.admin.application.vo.AdminMenuTreeNodeVO; import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder; import cn.iocoder.mall.admin.application.convert.AdminConvert; import cn.iocoder.mall.admin.application.vo.AdminInfoVO; +import com.alibaba.dubbo.config.annotation.Reference; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.*; +import java.util.stream.Collectors; + @RestController @RequestMapping("admin/admin") @Api("管理员模块") public class AdminController { + @Reference(validation = "true") + private ResourceService resourceService; + @GetMapping("/info") public CommonResult info() { return CommonResult.success(AdminConvert.INSTANCE.convert(AdminSecurityContextHolder.getContext())); } + // =========== 当前管理员相关的资源 API =========== + + @SuppressWarnings("Duplicates") + @GetMapping("/menu_resource_tree") + @ApiOperation(value = "获得当前登陆的管理员拥有的菜单权限", notes = "以树结构返回") + public CommonResult> menuResourceTree() { + List resources = resourceService.getResourcesByTypeAndRoleIds(ResourceConstants.TYPE_MENU, AdminSecurityContextHolder.getContext().getRoleIds()); + // 创建 AdminMenuTreeNodeVO Map + Map treeNodeMap = resources.stream().collect(Collectors.toMap(ResourceBO::getId, ResourceConvert.INSTANCE::convert)); + // 处理父子关系 + treeNodeMap.values().stream() + .filter(node -> !node.getPid().equals(ResourceConstants.PID_ROOT)) + .forEach((childNode) -> { + // 获得父节点 + AdminMenuTreeNodeVO parentNode = treeNodeMap.get(childNode.getPid()); + if (parentNode.getChildren() == null) { // 初始化 children 数组 + parentNode.setChildren(new ArrayList<>()); + } + // 将自己添加到父节点中 + parentNode.getChildren().add(childNode); + }); + // 获得到所有的根节点 + List rootNodes = treeNodeMap.values().stream() + .filter(node -> node.getPid().equals(ResourceConstants.PID_ROOT)) + .sorted(Comparator.comparing(AdminMenuTreeNodeVO::getSort)) + .collect(Collectors.toList()); + return CommonResult.success(rootNodes); + } + + @GetMapping("/url_resource_list") + @ApiOperation(value = "获得当前登陆的管理员拥有的 URL 权限列表") +// @ApiModelProperty(value = "data", example = "['/admin/role/add', '/admin/role/update']") 没效果 + public CommonResult> urlResourceList() { + List resources = resourceService.getResourcesByTypeAndRoleIds(ResourceConstants.TYPE_URL, AdminSecurityContextHolder.getContext().getRoleIds()); + return CommonResult.success(resources.stream().map(ResourceBO::getHandler).collect(Collectors.toSet())); + } + } \ No newline at end of file diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/ResourceController.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/ResourceController.java index 109934095..68f2c1485 100644 --- a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/ResourceController.java +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/ResourceController.java @@ -7,7 +7,6 @@ import cn.iocoder.mall.admin.api.constant.ResourceConstants; import cn.iocoder.mall.admin.api.dto.ResourceAddDTO; import cn.iocoder.mall.admin.api.dto.ResourceUpdateDTO; import cn.iocoder.mall.admin.application.convert.ResourceConvert; -import cn.iocoder.mall.admin.application.vo.AdminMenuTreeNodeVO; import cn.iocoder.mall.admin.application.vo.ResourceTreeNodeVO; import cn.iocoder.mall.admin.application.vo.ResourceVO; import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder; @@ -18,7 +17,10 @@ import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @RestController @@ -29,43 +31,6 @@ public class ResourceController { @Reference(validation = "true") private ResourceService resourceService; - // =========== 当前管理员相关的资源 API =========== - - @SuppressWarnings("Duplicates") - @GetMapping("/admin_menu_tree") - @ApiOperation(value = "获得当前登陆的管理员拥有的菜单权限", notes = "以树结构返回") - public CommonResult> adminMenuTree() { - List resources = resourceService.getResourcesByTypeAndRoleIds(ResourceConstants.TYPE_MENU, AdminSecurityContextHolder.getContext().getRoleIds()); - // 创建 AdminMenuTreeNodeVO Map - Map treeNodeMap = resources.stream().collect(Collectors.toMap(ResourceBO::getId, ResourceConvert.INSTANCE::convert)); - // 处理父子关系 - treeNodeMap.values().stream() - .filter(node -> !node.getPid().equals(ResourceConstants.PID_ROOT)) - .forEach((childNode) -> { - // 获得父节点 - AdminMenuTreeNodeVO parentNode = treeNodeMap.get(childNode.getPid()); - if (parentNode.getChildren() == null) { // 初始化 children 数组 - parentNode.setChildren(new ArrayList<>()); - } - // 将自己添加到父节点中 - parentNode.getChildren().add(childNode); - }); - // 获得到所有的根节点 - List rootNodes = treeNodeMap.values().stream() - .filter(node -> node.getPid().equals(ResourceConstants.PID_ROOT)) - .sorted(Comparator.comparing(AdminMenuTreeNodeVO::getSort)) - .collect(Collectors.toList()); - return CommonResult.success(rootNodes); - } - - @GetMapping("/admin_url_list") - @ApiOperation(value = "获得当前登陆的管理员拥有的 URL 权限列表") -// @ApiModelProperty(value = "data", example = "['/admin/role/add', '/admin/role/update']") 没效果 - public CommonResult> adminUrlList() { - List resources = resourceService.getResourcesByTypeAndRoleIds(ResourceConstants.TYPE_URL, AdminSecurityContextHolder.getContext().getRoleIds()); - return CommonResult.success(resources.stream().map(ResourceBO::getHandler).collect(Collectors.toSet())); - } - // =========== 资源管理 API =========== @SuppressWarnings("Duplicates") diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/RoleController.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/RoleController.java new file mode 100644 index 000000000..d2faa0c9b --- /dev/null +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/RoleController.java @@ -0,0 +1,116 @@ +package cn.iocoder.mall.admin.application.controller; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.admin.api.ResourceService; +import cn.iocoder.mall.admin.api.RoleService; +import cn.iocoder.mall.admin.api.bo.ResourceBO; +import cn.iocoder.mall.admin.api.bo.RolePageBO; +import cn.iocoder.mall.admin.api.constant.ResourceConstants; +import cn.iocoder.mall.admin.api.dto.RoleAddDTO; +import cn.iocoder.mall.admin.api.dto.RolePageDTO; +import cn.iocoder.mall.admin.api.dto.RoleUpdateDTO; +import cn.iocoder.mall.admin.application.convert.ResourceConvert; +import cn.iocoder.mall.admin.application.convert.RoleConvert; +import cn.iocoder.mall.admin.application.vo.RolePageVO; +import cn.iocoder.mall.admin.application.vo.RoleResourceTreeNodeVO; +import cn.iocoder.mall.admin.application.vo.RoleVO; +import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder; +import com.alibaba.dubbo.config.annotation.Reference; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import java.util.*; +import java.util.stream.Collectors; + +@RestController +@RequestMapping("admin/role") +public class RoleController { + + @Reference(validation = "true") + private RoleService roleService; + @Reference(validation = "true") + private ResourceService resourceService; + + @GetMapping("/page") + @ApiOperation(value = "角色分页") + public CommonResult page(@RequestParam(value = "name", required = false) String name, + @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { + CommonResult result = roleService.getRolePage(new RolePageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize)); + return RoleConvert.INSTANCE.convert2(result); + } + + @PostMapping("/add") + @ApiOperation(value = "创建角色") + @ApiImplicitParams({ + @ApiImplicitParam(name = "name", value = "角色", required = true, example = "系统管理员"), + }) + public CommonResult add(@RequestParam("name") String name) { + RoleAddDTO roleAddDTO = new RoleAddDTO().setName(name); + return RoleConvert.INSTANCE.convert(roleService.addRole(AdminSecurityContextHolder.getContext().getAdminId(), roleAddDTO)); + } + + @PostMapping("/update") + @ApiOperation(value = "更新角色") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1"), + @ApiImplicitParam(name = "name", value = "角色名", required = true, example = "系统管理员"), + }) + public CommonResult update(@RequestParam("id") Integer id, + @RequestParam("name") String name) { + RoleUpdateDTO roleUpdateDTO = new RoleUpdateDTO().setId(id).setName(name); + return roleService.updateRole(AdminSecurityContextHolder.getContext().getAdminId(), roleUpdateDTO); + } + + @PostMapping("/delete") + @ApiOperation(value = "删除角色") + @ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1") + public CommonResult delete(@RequestParam("id") Integer id) { + return roleService.deleteRole(AdminSecurityContextHolder.getContext().getAdminId(), id); + } + + @SuppressWarnings("Duplicates") + @GetMapping("/resource_tree") + @ApiOperation(value = "获得角色拥有的菜单权限", notes = "以树结构返回") + @ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1") + public CommonResult> resourceTree(@RequestParam("id") Integer id) { + // 芋艿:此处,严格来说可以在校验下角色是否存在。不过呢,校验了也没啥意义,因为一般不存在这个情况,且不会有业务上的影响。并且,反倒多了一次 rpc 调用。 + Set roleIds = new HashSet<>(); + roleIds.add(id); + List resources = resourceService.getResourcesByTypeAndRoleIds(null, roleIds); + // 创建 AdminMenuTreeNodeVO Map + Map treeNodeMap = resources.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 rootNodes = treeNodeMap.values().stream() + .filter(node -> node.getPid().equals(ResourceConstants.PID_ROOT)) + .sorted(Comparator.comparing(RoleResourceTreeNodeVO::getSort)) + .collect(Collectors.toList()); + return CommonResult.success(rootNodes); + } + + @PostMapping("/assign_resource") + @ApiOperation(value = "分配角色资源") + @ApiImplicitParams({ + @ApiImplicitParam(name = "id", value = "角色编号", required = true, example = "1"), + @ApiImplicitParam(name = "resourceIds", value = "资源数组", required = true, example = "1,2,3"), + }) + public CommonResult assignResource(@RequestParam("id") Integer id, + @RequestParam(value = "resourceIds", required = false) Set resourceIds) { + return roleService.assignResource(AdminSecurityContextHolder.getContext().getAdminId(), id, resourceIds); + } + +} \ No newline at end of file diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/convert/ResourceConvert.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/convert/ResourceConvert.java index 777e5b27a..a3fda7381 100644 --- a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/convert/ResourceConvert.java +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/convert/ResourceConvert.java @@ -5,6 +5,7 @@ import cn.iocoder.mall.admin.api.bo.ResourceBO; import cn.iocoder.mall.admin.application.vo.AdminMenuTreeNodeVO; import cn.iocoder.mall.admin.application.vo.ResourceTreeNodeVO; import cn.iocoder.mall.admin.application.vo.ResourceVO; +import cn.iocoder.mall.admin.application.vo.RoleResourceTreeNodeVO; import org.mapstruct.Mapper; import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; @@ -20,6 +21,9 @@ public interface ResourceConvert { @Mappings({}) ResourceTreeNodeVO convert2(ResourceBO resourceBO); + @Mappings({}) + RoleResourceTreeNodeVO convert4(ResourceBO resourceBO); + @Mappings({}) ResourceVO convert3(ResourceBO resourceBO); diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/convert/RoleConvert.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/convert/RoleConvert.java new file mode 100644 index 000000000..61d0ee351 --- /dev/null +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/convert/RoleConvert.java @@ -0,0 +1,26 @@ +package cn.iocoder.mall.admin.application.convert; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.admin.api.bo.RoleBO; +import cn.iocoder.mall.admin.api.bo.RolePageBO; +import cn.iocoder.mall.admin.application.vo.RolePageVO; +import cn.iocoder.mall.admin.application.vo.RoleVO; +import org.mapstruct.Mapper; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface RoleConvert { + + RoleConvert INSTANCE = Mappers.getMapper(RoleConvert.class); + + @Mappings({}) + RoleVO convert(RoleBO roleBO); + + @Mappings({}) + CommonResult convert(CommonResult resourceBO); + + @Mappings({}) + CommonResult convert2(CommonResult resourceBO); + +} \ No newline at end of file diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RolePageVO.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RolePageVO.java new file mode 100644 index 000000000..12946c504 --- /dev/null +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RolePageVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.mall.admin.application.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel("角色分页 VO") +public class RolePageVO { + + @ApiModelProperty(value = "角色数组") + private List roles; + @ApiModelProperty(value = "角色总数") + private Integer count; + + public List getRoles() { + return roles; + } + + public RolePageVO setRoles(List roles) { + this.roles = roles; + return this; + } + + public Integer getCount() { + return count; + } + + public RolePageVO setCount(Integer count) { + this.count = count; + return this; + } + +} \ No newline at end of file diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RoleResourceTreeNodeVO.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RoleResourceTreeNodeVO.java new file mode 100644 index 000000000..1f5d321f2 --- /dev/null +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RoleResourceTreeNodeVO.java @@ -0,0 +1,80 @@ +package cn.iocoder.mall.admin.application.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.List; + +@ApiModel("角色拥有的资源 VO") +public class RoleResourceTreeNodeVO { + + @ApiModelProperty(value = "菜单编号", required = true, example = "1") + private Integer id; +// @ApiModelProperty(value = "菜单名", required = true, example = "商品管理") +// private String name; + @ApiModelProperty(value = "菜单操作", required = true, example = "/order/list") + private String handler; + @ApiModelProperty(value = "父菜单编号", required = true, example = "1", notes = "如果无父菜单,则值为 0") + private Integer pid; + @ApiModelProperty(value = "排序", required = true, example = "1") + private Integer sort; + @ApiModelProperty(value = "菜单展示名", required = true, example = "商品管理") + private String displayName; + @ApiModelProperty(value = "子节点数组") + private List children; + + public Integer getId() { + return id; + } + + public RoleResourceTreeNodeVO setId(Integer id) { + this.id = id; + return this; + } + + public String getHandler() { + return handler; + } + + public RoleResourceTreeNodeVO setHandler(String handler) { + this.handler = handler; + return this; + } + + public Integer getPid() { + return pid; + } + + public RoleResourceTreeNodeVO setPid(Integer pid) { + this.pid = pid; + return this; + } + + public Integer getSort() { + return sort; + } + + public RoleResourceTreeNodeVO setSort(Integer sort) { + this.sort = sort; + return this; + } + + public String getDisplayName() { + return displayName; + } + + public RoleResourceTreeNodeVO setDisplayName(String displayName) { + this.displayName = displayName; + return this; + } + + public List getChildren() { + return children; + } + + public RoleResourceTreeNodeVO setChildren(List children) { + this.children = children; + return this; + } + +} \ No newline at end of file diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RoleVO.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RoleVO.java new file mode 100644 index 000000000..8d3251146 --- /dev/null +++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/vo/RoleVO.java @@ -0,0 +1,45 @@ +package cn.iocoder.mall.admin.application.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import java.util.Date; + +@ApiModel("角色 VO") +public class RoleVO { + + @ApiModelProperty(value = "角色编号", required = true, example = "1") + private Integer id; + @ApiModelProperty(value = "角色名字", required = true, example = "系统管理员") + private String name; + @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式") + private Date createTime; + + public Integer getId() { + return id; + } + + public RoleVO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public RoleVO setName(String name) { + this.name = name; + return this; + } + + public Date getCreateTime() { + return createTime; + } + + public RoleVO setCreateTime(Date createTime) { + this.createTime = createTime; + return this; + } + +} \ No newline at end of file diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/ResourceService.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/ResourceService.java index fa0f87812..7edacb804 100644 --- a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/ResourceService.java +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/ResourceService.java @@ -14,11 +14,11 @@ public interface ResourceService { /** * 查询指定类型 + 指定角色的资源列表 * - * @param type 指定类型。 + * @param type 指定类型。可以为空,此时不作为过滤条件 * @param roleIds 指定角色的数组。 * @return 资源列表 */ - List getResourcesByTypeAndRoleIds(Integer type, Set roleIds); + List getResourcesByTypeAndRoleIds(@Nullable Integer type, Set roleIds); /** * 查询指定类型的资源列表 diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/RoleService.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/RoleService.java index b19deee5d..ee5c64a12 100644 --- a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/RoleService.java +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/RoleService.java @@ -1,4 +1,24 @@ package cn.iocoder.mall.admin.api; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.admin.api.bo.RoleBO; +import cn.iocoder.mall.admin.api.bo.RolePageBO; +import cn.iocoder.mall.admin.api.dto.RoleAddDTO; +import cn.iocoder.mall.admin.api.dto.RolePageDTO; +import cn.iocoder.mall.admin.api.dto.RoleUpdateDTO; + +import java.util.Set; + public interface RoleService { -} + + CommonResult getRolePage(RolePageDTO rolePageDTO); + + CommonResult addRole(Integer adminId, RoleAddDTO roleAddDTO); + + CommonResult updateRole(Integer adminId, RoleUpdateDTO roleUpdateDTO); + + CommonResult deleteRole(Integer adminId, Integer roleId); + + CommonResult assignResource(Integer adminId, Integer roleId, Set resourceIds); + +} \ No newline at end of file diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/RoleBO.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/RoleBO.java new file mode 100644 index 000000000..c8458034e --- /dev/null +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/RoleBO.java @@ -0,0 +1,50 @@ +package cn.iocoder.mall.admin.api.bo; + +import java.util.Date; + +/** + * 角色 BO + */ +public class RoleBO { + + /** + * 角色编号 + */ + private Integer id; + /** + * 角色名字 + */ + private String name; + /** + * 添加时间 + */ + private Date createTime; + + public Integer getId() { + return id; + } + + public RoleBO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public RoleBO setName(String name) { + this.name = name; + return this; + } + + public Date getCreateTime() { + return createTime; + } + + public RoleBO setCreateTime(Date createTime) { + this.createTime = createTime; + return this; + } + +} \ No newline at end of file diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/RolePageBO.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/RolePageBO.java new file mode 100644 index 000000000..ce92e8eed --- /dev/null +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/RolePageBO.java @@ -0,0 +1,34 @@ +package cn.iocoder.mall.admin.api.bo; + +import java.util.List; + +public class RolePageBO { + + /** + * 角色数组 + */ + private List roles; + /** + * 总量 + */ + private Integer count; + + public List getRoles() { + return roles; + } + + public RolePageBO setRoles(List roles) { + this.roles = roles; + return this; + } + + public Integer getCount() { + return count; + } + + public RolePageBO setCount(Integer count) { + this.count = count; + return this; + } + +} \ No newline at end of file diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/AdminErrorCodeEnum.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/AdminErrorCodeEnum.java index 1be91e3ca..42f90d10a 100644 --- a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/AdminErrorCodeEnum.java +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/AdminErrorCodeEnum.java @@ -31,6 +31,10 @@ public enum AdminErrorCodeEnum { RESOURCE_PARENT_ERROR(1002003002, "不能设置自己为父资源"), RESOURCE_NOT_EXISTS(1002003003, "资源不存在"), RESOURCE_EXISTS_CHILDREN(1002003004, "存在子资源,无法删除"), + + // ========== 角色模块 1002004000 ========== + ROLE_NOT_EXISTS(1002004000, "角色不存在"), + ROLE_ASSIGN_RESOURCE_NOT_EXISTS(1002004001, "分配角色资源时,有资源不存在"), ; private final int code; diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RoleAddDTO.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RoleAddDTO.java new file mode 100644 index 000000000..f7ea73b0f --- /dev/null +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RoleAddDTO.java @@ -0,0 +1,25 @@ +package cn.iocoder.mall.admin.api.dto; + +import javax.validation.constraints.NotEmpty; + +/** + * 角色添加 DTO + */ +public class RoleAddDTO { + + /** + * 角色名字(标识) + */ + @NotEmpty(message = "角色名字不能为空") + private String name; + + public String getName() { + return name; + } + + public RoleAddDTO setName(String name) { + this.name = name; + return this; + } + +} \ No newline at end of file diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RolePageDTO.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RolePageDTO.java new file mode 100644 index 000000000..7b1fbd743 --- /dev/null +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RolePageDTO.java @@ -0,0 +1,35 @@ +package cn.iocoder.mall.admin.api.dto; + +public class RolePageDTO { + + private Integer pageNo; + private Integer pageSize; + private String name; + + public Integer getPageNo() { + return pageNo; + } + + public RolePageDTO setPageNo(Integer pageNo) { + this.pageNo = pageNo; + return this; + } + + public Integer getPageSize() { + return pageSize; + } + + public RolePageDTO setPageSize(Integer pageSize) { + this.pageSize = pageSize; + return this; + } + + public String getName() { + return name; + } + + public RolePageDTO setName(String name) { + this.name = name; + return this; + } +} diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RoleUpdateDTO.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RoleUpdateDTO.java new file mode 100644 index 000000000..e69dc295e --- /dev/null +++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/RoleUpdateDTO.java @@ -0,0 +1,40 @@ +package cn.iocoder.mall.admin.api.dto; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 角色添加 DTO + */ +public class RoleUpdateDTO { + + /** + * 角色编号 + */ + @NotNull(message = "角色编号不能为空") + private Integer id; + /** + * 角色名字(标识) + */ + @NotEmpty(message = "角色名字不能为空") + private String name; + + public Integer getId() { + return id; + } + + public RoleUpdateDTO setId(Integer id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public RoleUpdateDTO setName(String name) { + this.name = name; + return this; + } + +} \ No newline at end of file diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/RoleConvert.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/RoleConvert.java new file mode 100644 index 000000000..73ad2c417 --- /dev/null +++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/RoleConvert.java @@ -0,0 +1,30 @@ +package cn.iocoder.mall.admin.convert; + +import cn.iocoder.mall.admin.api.bo.RoleBO; +import cn.iocoder.mall.admin.api.dto.RoleAddDTO; +import cn.iocoder.mall.admin.api.dto.RoleUpdateDTO; +import cn.iocoder.mall.admin.dataobject.RoleDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +@Mapper +public interface RoleConvert { + + RoleConvert INSTANCE = Mappers.getMapper(RoleConvert.class); + + @Mappings({}) + RoleDO convert(RoleAddDTO roleAddDTO); + + @Mappings({}) + RoleDO convert(RoleUpdateDTO roleUpdateDTO); + + @Mappings({}) + RoleBO convert(RoleDO roleDO); + + @Mappings({}) + List convert(List roleDOs); + +} \ No newline at end of file diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java index 2201bc43c..9f4efdd3c 100644 --- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java +++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java @@ -22,6 +22,8 @@ public interface ResourceMapper { ResourceDO selectById(@Param("id") Integer id); + List selectListByIds(@Param("ids") Set ids); + void insert(ResourceDO resource); int update(ResourceDO resource); diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleMapper.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleMapper.java new file mode 100644 index 000000000..7b628bd48 --- /dev/null +++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleMapper.java @@ -0,0 +1,24 @@ +package cn.iocoder.mall.admin.dao; + +import cn.iocoder.mall.admin.dataobject.RoleDO; +import org.apache.ibatis.annotations.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface RoleMapper { + + void insert(RoleDO roleDO); + + int update(RoleDO roleDO); + + RoleDO selectById(@Param("id") Integer id); + + List selectListByNameLike(@Param("name") String name, + @Param("offset") Integer offset, + @Param("limit") Integer limit); + + Integer selectCountByNameLike(@Param("name") String name); + +} \ No newline at end of file diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleResourceMapper.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleResourceMapper.java index 7bcc9555b..05023dbb5 100644 --- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleResourceMapper.java +++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/RoleResourceMapper.java @@ -9,6 +9,8 @@ import java.util.List; @Repository public interface RoleResourceMapper { + int insertList(@Param("roleResources") List resourceDOs); + List selectByResourceHandler(@Param("resourceHandler") String resourceHandler); List selectByResourceId(@Param("resourceId") Integer resourceId); diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleDO.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleDO.java index fdc9ffc26..b124e2c83 100644 --- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleDO.java +++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/RoleDO.java @@ -1,20 +1,11 @@ package cn.iocoder.mall.admin.dataobject; -import java.util.Date; +import cn.iocoder.common.framework.dataobject.BaseDO; /** * 角色实体 */ -public class RoleDO { - - /** - * 账号状态 - 开启 - */ - public static final Integer STATUS_ENABLE = 1; - /** - * 账号状态 - 禁用 - */ - public static final Integer STATUS_DISABLE = 2; +public class RoleDO extends BaseDO { /** * 角色编号 @@ -24,14 +15,6 @@ public class RoleDO { * 角色名 */ private String name; - /** - * 创建时间 - */ - private Date createTime; - /** - * 状态 - */ - private Integer status; public Integer getId() { return id; @@ -51,22 +34,4 @@ public class RoleDO { return this; } - public Date getCreateTime() { - return createTime; - } - - public RoleDO setCreateTime(Date createTime) { - this.createTime = createTime; - return this; - } - - public Integer getStatus() { - return status; - } - - public RoleDO setStatus(Integer status) { - this.status = status; - return this; - } - } diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/ResourceServiceImpl.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/ResourceServiceImpl.java index af2209db9..10bbe2887 100644 --- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/ResourceServiceImpl.java +++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/ResourceServiceImpl.java @@ -31,7 +31,6 @@ public class ResourceServiceImpl implements ResourceService { @Autowired private RoleResourceMapper roleResourceMapper; - public ResourceDO getResourceByTypeAndHandler(Integer type, String handler) { return resourceMapper.selectByTypeAndHandler(type, handler); } @@ -136,6 +135,13 @@ public class ResourceServiceImpl implements ResourceService { return CommonResult.success(true); } + public List getResources(Set resourceIds) { + if (resourceIds == null || resourceIds.isEmpty()) { + return Collections.emptyList(); + } + return resourceMapper.selectListByIds(resourceIds); + } + private boolean isValidResourceType(Integer type) { return ResourceConstants.TYPE_MENU.equals(type) || ResourceConstants.TYPE_URL.equals(type); diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/RoleServiceImpl.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/RoleServiceImpl.java index 78f59bdb2..8ffc40e00 100644 --- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/RoleServiceImpl.java +++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/RoleServiceImpl.java @@ -1,12 +1,28 @@ package cn.iocoder.mall.admin.service; +import cn.iocoder.common.framework.dataobject.BaseDO; +import cn.iocoder.common.framework.util.ServiceExceptionUtil; +import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.mall.admin.api.RoleService; +import cn.iocoder.mall.admin.api.bo.RoleBO; +import cn.iocoder.mall.admin.api.bo.RolePageBO; +import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum; +import cn.iocoder.mall.admin.api.dto.RoleAddDTO; +import cn.iocoder.mall.admin.api.dto.RolePageDTO; +import cn.iocoder.mall.admin.api.dto.RoleUpdateDTO; +import cn.iocoder.mall.admin.convert.RoleConvert; +import cn.iocoder.mall.admin.dao.RoleMapper; import cn.iocoder.mall.admin.dao.RoleResourceMapper; +import cn.iocoder.mall.admin.dataobject.ResourceDO; +import cn.iocoder.mall.admin.dataobject.RoleDO; import cn.iocoder.mall.admin.dataobject.RoleResourceDO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Date; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; @Service @com.alibaba.dubbo.config.annotation.Service @@ -14,6 +30,11 @@ public class RoleServiceImpl implements RoleService { @Autowired private RoleResourceMapper roleResourceMapper; + @Autowired + private RoleMapper roleMapper; + + @Autowired + private ResourceServiceImpl resourceService; public List getRoleByResourceHandler(String resourceHandler) { return roleResourceMapper.selectByResourceHandler(resourceHandler); @@ -23,4 +44,86 @@ public class RoleServiceImpl implements RoleService { return roleResourceMapper.selectByResourceId(resourceId); } + @Override + public CommonResult getRolePage(RolePageDTO rolePageDTO) { + RolePageBO rolePage = new RolePageBO(); + // 查询分页数据 + int offset = rolePageDTO.getPageNo() * rolePageDTO.getPageSize(); + rolePage.setRoles(RoleConvert.INSTANCE.convert(roleMapper.selectListByNameLike(rolePageDTO.getName(), + offset, rolePageDTO.getPageSize()))); + // 查询分页总数 + rolePage.setCount(roleMapper.selectCountByNameLike(rolePageDTO.getName())); + return CommonResult.success(rolePage); + } + + @Override + public CommonResult addRole(Integer adminId, RoleAddDTO roleAddDTO) { + // TODO 芋艿,角色名是否要唯一呢?貌似一般系统都是允许的。 + // 保存到数据库 + RoleDO role = RoleConvert.INSTANCE.convert(roleAddDTO); + role.setCreateTime(new Date()).setDeleted(BaseDO.DELETED_NO); + roleMapper.insert(role); + // TODO 插入操作日志 + // 返回成功 + return CommonResult.success(RoleConvert.INSTANCE.convert(role)); + } + + @Override + public CommonResult updateRole(Integer adminId, RoleUpdateDTO roleUpdateDTO) { + // TODO 芋艿,角色名是否要唯一呢?貌似一般系统都是允许的。 + // 校验角色是否存在 + if (roleMapper.selectById(roleUpdateDTO.getId()) == null) { + return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode()); + } + // 更新到数据库 + RoleDO roleDO = RoleConvert.INSTANCE.convert(roleUpdateDTO); + roleMapper.update(roleDO); + // TODO 插入操作日志 + // 返回成功 + return CommonResult.success(true); + } + + @Override + public CommonResult deleteRole(Integer adminId, Integer roleId) { + // 校验角色是否存在 + if (roleMapper.selectById(roleId) == null) { + return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode()); + } + // 更新到数据库,标记删除 + RoleDO roleDO = new RoleDO().setId(roleId); + roleDO.setDeleted(RoleDO.DELETED_YES); + roleMapper.update(roleDO); + // TODO 插入操作日志 + // 返回成功 + return CommonResult.success(true); + } + + @Override + public CommonResult assignResource(Integer adminId, Integer roleId, Set resourceIds) { + // 校验角色是否存在 + if (roleMapper.selectById(roleId) == null) { + return ServiceExceptionUtil.error(AdminErrorCodeEnum.RESOURCE_NOT_EXISTS.getCode()); + } + // 校验是否有不存在的资源 + List resources = resourceService.getResources(resourceIds); + if (resources.size() != resourceIds.size()) { + return ServiceExceptionUtil.error(AdminErrorCodeEnum.ROLE_ASSIGN_RESOURCE_NOT_EXISTS.getCode()); + } + // TODO 芋艿,这里先简单实现。即方式是,删除老的分配的资源关系,然后添加新的分配的资源关系 + // 标记角色原资源关系都为删除 + roleResourceMapper.updateToDeletedByRoleId(roleId); + // 创建 RoleResourceDO 数组,并插入到数据库 + if (!resourceIds.isEmpty()) { + List roleResources = resourceIds.stream().map(resourceId -> { + RoleResourceDO roleResource = new RoleResourceDO().setRoleId(roleId).setResourceId(resourceId); + roleResource.setCreateTime(new Date()).setDeleted(BaseDO.DELETED_NO); + return roleResource; + }).collect(Collectors.toList()); + roleResourceMapper.insertList(roleResources); + } + // TODO 插入操作日志 + // 返回成功 + return CommonResult.success(true); + } + } \ No newline at end of file diff --git a/admin/admin-service-impl/src/main/resources/mapper/ResourceMapper.xml b/admin/admin-service-impl/src/main/resources/mapper/ResourceMapper.xml index 04ccd24e9..727d63791 100644 --- a/admin/admin-service-impl/src/main/resources/mapper/ResourceMapper.xml +++ b/admin/admin-service-impl/src/main/resources/mapper/ResourceMapper.xml @@ -42,12 +42,14 @@ r.id, r.name, r.type, r.sort, r.display_name, r.create_time, r.pid, r.handler FROM resource r, role_resource rr - WHERE r.type = #{type} - AND deleted = 0 + WHERE r.deleted = 0 + + AND r.type = #{type} + AND rr.role_id IN - - #{roleId} - + + #{roleId} + AND r.id = rr.resource_id @@ -68,6 +70,17 @@ AND deleted = 0 + + + SELECT + id, name, create_time + FROM role + WHERE id = #{id} + AND deleted = 0 + + + + + + + \ No newline at end of file diff --git a/admin/admin-service-impl/src/main/resources/mapper/RoleResourceMapper.xml b/admin/admin-service-impl/src/main/resources/mapper/RoleResourceMapper.xml index 9ce9772b9..467b64ee9 100644 --- a/admin/admin-service-impl/src/main/resources/mapper/RoleResourceMapper.xml +++ b/admin/admin-service-impl/src/main/resources/mapper/RoleResourceMapper.xml @@ -41,4 +41,13 @@ AND deleted = 0 + + INSERT INTO role_resource ( + resource_id, role_id, create_time, deleted + ) VALUES + + (#{roleResource.resourceId}, #{roleResource.roleId}, #{roleResource.createTime}, #{roleResource.deleted}) + + + \ No newline at end of file