1. system 提供新的 Resource 相关接口

2. admin-web 接入新的 Resource 相关接口
This commit is contained in:
YunaiV
2020-04-27 19:48:58 +08:00
parent caf605063c
commit f7157d283c
34 changed files with 684 additions and 368 deletions

View File

@@ -4,8 +4,8 @@ import cn.iocoder.common.framework.constant.MallConstants;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceTreeNodeBO;
import cn.iocoder.mall.system.biz.dto.authorization.AuthorizationGetResourcesByAccountIdDTO;
import cn.iocoder.mall.system.biz.enums.authorization.ResourceIdEnum;
import cn.iocoder.mall.system.biz.enums.authorization.ResourceTypeEnum;
import cn.iocoder.mall.system.biz.service.authorization.AuthorizationService;
import cn.iocoder.mall.system.rest.convert.authorization.AdminsAuthorizationConvert;
@@ -18,7 +18,8 @@ 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.List;
import java.util.Set;
import java.util.stream.Collectors;
@RestController
@@ -33,34 +34,9 @@ public class AdminsAuthorizationController {
@GetMapping("/menu-resource-tree")
@ApiOperation(value = "获得当前账号的菜单资源树", notes = "以树结构返回")
public CommonResult<List<AdminsAuthorizationMenuTreeResponse>> menuResourceTree() {
List<ResourceBO> resources = authorizationService.getResourcesByAccountId(new AuthorizationGetResourcesByAccountIdDTO()
.setAccountId(AdminSecurityContextHolder.getAccountId()).setType(ResourceTypeEnum.MENU.getValue()));
// 创建 AdminMenuTreeNodeVO Map
// 使用 LinkedHashMap 的原因,是为了排序 。实际也可以用 Stream API ,就是太丑了。
Map<Integer, AdminsAuthorizationMenuTreeResponse> treeNodeMap = new LinkedHashMap<>();
resources.stream().sorted(Comparator.comparing(ResourceBO::getSort))
.forEach(resourceBO -> treeNodeMap.put(resourceBO.getId(), AdminsAuthorizationConvert.INSTANCE.convert(resourceBO)));
// 处理父子关系
treeNodeMap.values().stream()
.filter(node -> !node.getPid().equals(ResourceIdEnum.ROOT.getId()))
.forEach((childNode) -> {
// 获得父节点
AdminsAuthorizationMenuTreeResponse parentNode = treeNodeMap.get(childNode.getPid());
if (parentNode == null) {
log.error("[menuResourceTree][resource({}) 找不到父资源({})]", childNode.getId(), childNode.getPid());
return;
}
if (parentNode.getChildren() == null) { // 初始化 children 数组
parentNode.setChildren(new ArrayList<>());
}
// 将自己添加到父节点中
parentNode.getChildren().add(childNode);
});
// 获得到所有的根节点
List<AdminsAuthorizationMenuTreeResponse> rootNodes = treeNodeMap.values().stream()
.filter(node -> node.getPid().equals(ResourceIdEnum.ROOT.getId()))
.collect(Collectors.toList());
return CommonResult.success(rootNodes);
List<ResourceTreeNodeBO> resourceTreeNodeBOs = authorizationService.getResourceTreeByAccountId(new AuthorizationGetResourcesByAccountIdDTO()
.setAccountId(AdminSecurityContextHolder.getAccountId()).setType(ResourceTypeEnum.MENU.getType()));
return CommonResult.success(AdminsAuthorizationConvert.INSTANCE.convertList(resourceTreeNodeBOs));
}
@GetMapping("/resource-permissions")

View File

@@ -0,0 +1,71 @@
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.mall.security.core.annotation.RequiresPermissions;
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceTreeNodeBO;
import cn.iocoder.mall.system.biz.dto.authorization.ResourceAddDTO;
import cn.iocoder.mall.system.biz.dto.authorization.ResourceDeleteDTO;
import cn.iocoder.mall.system.biz.dto.authorization.ResourceGetTreeDTO;
import cn.iocoder.mall.system.biz.dto.authorization.ResourceUpdateDTO;
import cn.iocoder.mall.system.biz.service.authorization.ResourceService;
import cn.iocoder.mall.system.rest.convert.authorization.AdminsResourceConvert;
import cn.iocoder.mall.system.rest.request.authorization.AdminsResourceAddRequest;
import cn.iocoder.mall.system.rest.request.authorization.AdminsResourceUpdateRequest;
import cn.iocoder.mall.system.rest.response.authorization.AdminsResourceTreeResponse;
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.*;
import java.util.List;
@RestController
@RequestMapping(MallConstants.ROOT_PATH_ADMIN + "/resource")
@Api(tags = "管理员 - 资源 API")
public class AdminsResourceController {
@Autowired
private ResourceService resourceService;
@GetMapping("/tree")
@ApiOperation(value = "获得所有资源,按照树形结构返回")
@RequiresPermissions("system:resource:tree")
public CommonResult<List<AdminsResourceTreeResponse>> tree() {
List<ResourceTreeNodeBO> resourceTreeNodeBOs = resourceService.getResourceTree(new ResourceGetTreeDTO());
return CommonResult.success(AdminsResourceConvert.INSTANCE.convertList(resourceTreeNodeBOs));
}
@PostMapping("/add")
@ApiOperation(value = "创建资源", notes = "例如说,菜单资源,按钮资源")
@RequiresPermissions("system:resource:add")
public CommonResult<Integer> add(AdminsResourceAddRequest request) {
ResourceAddDTO addDTO = AdminsResourceConvert.INSTANCE.convert(request)
.setAdminId(AdminSecurityContextHolder.getAdminId());
return CommonResult.success(resourceService.addResource(addDTO));
}
@PostMapping("/update")
@ApiOperation(value = "更新资源")
@RequiresPermissions("system:resource:update")
public CommonResult<Boolean> update(AdminsResourceUpdateRequest request) {
ResourceUpdateDTO updateDTO = AdminsResourceConvert.INSTANCE.convert(request)
.setAdminId(AdminSecurityContextHolder.getAdminId());
resourceService.updateResource(updateDTO);
return CommonResult.success(true);
}
@PostMapping("/delete")
@ApiOperation(value = "删除资源")
@ApiImplicitParam(name = "id", value = "资源编号", required = true, example = "1")
@RequiresPermissions("system:resource:delete")
public CommonResult<Boolean> delete(@RequestParam("id") Integer id) {
ResourceDeleteDTO deleteDTO = new ResourceDeleteDTO().setId(id)
.setAdminId(AdminSecurityContextHolder.getAdminId());
resourceService.deleteResource(deleteDTO);
return CommonResult.success(true);
}
}

View File

@@ -1,11 +1,7 @@
package cn.iocoder.mall.system.rest.controller.datadict;
import cn.iocoder.common.framework.constant.MallConstants;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.security.core.annotation.RequiresPermissions;
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;
@@ -17,13 +13,6 @@ public class AdminsDataDictController {
// @Reference(validation = "true", version = "${dubbo.provider.DataDictService.version}")
// private DataDictService dataDictService;
@GetMapping("/demo")
@ApiOperation(value = "数据字典全列表")
@RequiresPermissions("system.dataDict.list")
public CommonResult<Boolean> list() {
return CommonResult.success(true);
}
// @GetMapping("/list")
// @ApiOperation(value = "数据字典全列表")
// @RequiresPermissions("system.dataDict.list")

View File

@@ -1,10 +1,14 @@
package cn.iocoder.mall.system.rest.convert.authorization;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceBO;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceTreeNodeBO;
import cn.iocoder.mall.system.rest.response.authorization.AdminsAuthorizationMenuTreeResponse;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface AdminsAuthorizationConvert {
@@ -12,4 +16,12 @@ public interface AdminsAuthorizationConvert {
AdminsAuthorizationMenuTreeResponse convert(ResourceBO bean);
@Mapping(source = "node.id", target = "id")
@Mapping(source = "node.name", target = "name")
@Mapping(source = "node.route", target = "route")
@Mapping(source = "node.icon", target = "icon")
AdminsAuthorizationMenuTreeResponse convert(ResourceTreeNodeBO bean);
List<AdminsAuthorizationMenuTreeResponse> convertList(List<ResourceTreeNodeBO> beans);
}

View File

@@ -0,0 +1,36 @@
package cn.iocoder.mall.system.rest.convert.authorization;
import cn.iocoder.mall.system.biz.bo.authorization.ResourceTreeNodeBO;
import cn.iocoder.mall.system.biz.dto.authorization.ResourceAddDTO;
import cn.iocoder.mall.system.biz.dto.authorization.ResourceUpdateDTO;
import cn.iocoder.mall.system.rest.request.authorization.AdminsResourceAddRequest;
import cn.iocoder.mall.system.rest.request.authorization.AdminsResourceUpdateRequest;
import cn.iocoder.mall.system.rest.response.authorization.AdminsResourceTreeResponse;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface AdminsResourceConvert {
AdminsResourceConvert INSTANCE = Mappers.getMapper(AdminsResourceConvert.class);
@Mapping(source = "node.id", target = "id")
@Mapping(source = "node.name", target = "name")
@Mapping(source = "node.permission", target = "permission")
@Mapping(source = "node.type", target = "type")
@Mapping(source = "node.sort", target = "sort")
@Mapping(source = "node.pid", target = "pid")
@Mapping(source = "node.route", target = "route")
@Mapping(source = "node.icon", target = "icon")
AdminsResourceTreeResponse convert(ResourceTreeNodeBO bean);
List<AdminsResourceTreeResponse> convertList(List<ResourceTreeNodeBO> beans);
ResourceAddDTO convert(AdminsResourceAddRequest bean);
ResourceUpdateDTO convert(AdminsResourceUpdateRequest bean);
}

View File

@@ -0,0 +1,44 @@
package cn.iocoder.mall.system.rest.request.authorization;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.mall.system.biz.enums.authorization.ResourceTypeEnum;
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 AdminsResourceAddRequest {
@ApiModelProperty(value = "资源类型。1 代表【菜单】2 代表【按钮】", required = true, example = "1")
@NotNull(message = "类型不能为空")
@InEnum(value = ResourceTypeEnum.class, message = "资源类型必须是 {value}")
private Integer type;
@ApiModelProperty(value = "排序", required = true, example = "1")
@NotNull(message = "类型不能为空")
private Integer sort;
@ApiModelProperty(value = "菜单名", required = true, example = "商品管理")
@NotEmpty(message = "菜单名不能为空")
private String name;
@ApiModelProperty(value = "父级资源编号", required = true, example = "1")
@NotNull(message = "父级资源编号不能为空")
private Integer pid;
@ApiModelProperty(value = "前端路由", example = "/order/list")
private String route;
@ApiModelProperty(value = "图标", example = "add")
private String icon;
@ApiModelProperty(value = "权限标识", example = "permission")
private String permission;
}

View File

@@ -0,0 +1,48 @@
package cn.iocoder.mall.system.rest.request.authorization;
import cn.iocoder.common.framework.validator.InEnum;
import cn.iocoder.mall.system.biz.enums.authorization.ResourceTypeEnum;
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 AdminsResourceUpdateRequest {
@ApiModelProperty(value = "资源编号", required = true, example = "1")
@NotNull(message = "资源编号不能为空")
private Integer id;
@ApiModelProperty(value = "资源类型。1 代表【菜单】2 代表【按钮】", required = true, example = "1")
@NotNull(message = "类型不能为空")
@InEnum(value = ResourceTypeEnum.class, message = "资源类型必须是 {value}")
private Integer type;
@ApiModelProperty(value = "排序", required = true, example = "1")
@NotNull(message = "类型不能为空")
private Integer sort;
@ApiModelProperty(value = "菜单名", required = true, example = "商品管理")
@NotEmpty(message = "菜单名不能为空")
private String name;
@ApiModelProperty(value = "父级资源编号", required = true, example = "1")
@NotNull(message = "父级资源编号不能为空")
private Integer pid;
@ApiModelProperty(value = "前端路由", example = "/order/list")
private String route;
@ApiModelProperty(value = "图标", example = "add")
private String icon;
@ApiModelProperty(value = "权限标识", example = "permission")
private String permission;
}

View File

@@ -16,13 +16,10 @@ public class AdminsAuthorizationMenuTreeResponse {
private Integer id;
@ApiModelProperty(value = "菜单名", required = true, example = "商品管理")
private String name;
@ApiModelProperty(value = "排序", required = true, example = "1")
private Integer sort;
@ApiModelProperty(value = "父菜单编号", required = true, example = "1", notes = "如果无父菜单,则值为 0")
private Integer pid;
@ApiModelProperty(value = "route", required = true, example = "/order/list")
@ApiModelProperty(value = "前端路由", required = true, example = "/order/list")
private String route;
@ApiModelProperty(value = "菜单图标", required = true, example = "user")
private String icon;
@ApiModelProperty(value = "子节点数组")
private List<AdminsAuthorizationMenuTreeResponse> children;

View File

@@ -0,0 +1,36 @@
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.List;
@ApiModel("管理员 - 授权模块 - 菜单资源树")
@Data
@Accessors(chain = true)
public class AdminsResourceTreeResponse {
@ApiModelProperty(value = "菜单编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "菜单名", required = true, example = "商品管理")
private String name;
@ApiModelProperty(value = "权限标识", example = "/order/list")
private String permission;
@ApiModelProperty(value = "资源类型", required = true, example = "1-菜单2-按钮")
private Integer type;
@ApiModelProperty(value = "排序", required = true, example = "1")
private Integer sort;
@ApiModelProperty(value = "父菜单编号", required = true, example = "1", notes = "如果无父菜单,则值为 0")
private Integer pid;
@ApiModelProperty(value = "前端路由", example = "/order/list")
private String route;
@ApiModelProperty(value = "菜单图标", example = "user")
private String icon;
/**
* 子节点数组
*/
private List<AdminsResourceTreeResponse> children;
}