From f53d924e1e0e15062f7f1d8e3cd9872675d92911 Mon Sep 17 00:00:00 2001
From: YunaiV <>
Date: Wed, 27 Feb 2019 23:56:05 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AE=A1=E7=90=86=E5=91=98?=
 =?UTF-8?q?=E8=8E=B7=E5=BE=97=E8=8F=9C=E5=8D=95=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../admin/controller/AdminController.java     |   7 +-
 .../admin/controller/ResourceController.java  |  61 ++++++++++
 .../mall/admin/convert/AdminConvert.java      |  17 +++
 .../mall/admin/convert/ResourceConvert.java   |  17 +++
 .../cn/iocoder/mall/admin/vo/AdminInfoVO.java |  34 ++++++
 .../mall/admin/vo/AdminMenuTreeNodeVO.java    |  72 +++++++++++
 .../mall/admin/api/ResourceService.java       |  12 ++
 .../iocoder/mall/admin/api/bo/ResourceBO.java | 115 ++++++++++++++++++
 .../mall/admin/api/constant/ResourceType.java |  17 +++
 admin/admin-service-impl/pom.xml              |   6 +
 .../mall/admin/convert/ResourceConvert.java   |  22 ++++
 .../mall/admin/dao/ResourceMapper.java        |  19 +++
 .../mall/admin/dao/RoleResourceMapper.java    |   2 +
 .../mall/admin/dataobject/ResourceDO.java     |  10 +-
 .../mall/admin/service/AdminServiceImpl.java  |   2 +-
 .../mall/admin/service/OAuth2ServiceImpl.java |  23 ++--
 .../admin/service/ResourceServiceImpl.java    |  34 ++++++
 .../mall/admin/service/RoleServiceImpl.java   |   4 +
 .../main/resources/mapper/ResourceMapper.xml  |  37 ++++++
 .../resources/mapper/RoleResourceMapper.xml   |   7 ++
 common/common-framework/pom.xml               |   5 +
 .../common/framework/dataobject/BaseDO.java   |  47 +++++++
 22 files changed, 556 insertions(+), 14 deletions(-)
 create mode 100644 admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/ResourceController.java
 create mode 100644 admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/AdminConvert.java
 create mode 100644 admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java
 create mode 100644 admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminInfoVO.java
 create mode 100644 admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminMenuTreeNodeVO.java
 create mode 100644 admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/ResourceService.java
 create mode 100644 admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/ResourceBO.java
 create mode 100644 admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/ResourceType.java
 create mode 100644 admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java
 create mode 100644 admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java
 create mode 100644 admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/ResourceServiceImpl.java
 create mode 100644 admin/admin-service-impl/src/main/resources/mapper/ResourceMapper.xml
 create mode 100644 common/common-framework/src/main/java/cn/iocoder/common/framework/dataobject/BaseDO.java

diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/AdminController.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/AdminController.java
index 4e08f3f7..56a32126 100644
--- a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/AdminController.java
+++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/AdminController.java
@@ -1,6 +1,9 @@
 package cn.iocoder.mall.admin.controller;
 
 import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
+import cn.iocoder.mall.admin.convert.AdminConvert;
+import cn.iocoder.mall.admin.vo.AdminInfoVO;
 import io.swagger.annotations.Api;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -12,8 +15,8 @@ import org.springframework.web.bind.annotation.RestController;
 public class AdminController {
 
     @GetMapping("/info")
-    public CommonResult<Void> info() {
-        return null;
+    public CommonResult<AdminInfoVO> info() {
+        return CommonResult.success(AdminConvert.INSTANCE.convert(AdminSecurityContextHolder.getContext()));
     }
 
 }
\ No newline at end of file
diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/ResourceController.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/ResourceController.java
new file mode 100644
index 00000000..216e6c05
--- /dev/null
+++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/controller/ResourceController.java
@@ -0,0 +1,61 @@
+package cn.iocoder.mall.admin.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.ResourceType;
+import cn.iocoder.mall.admin.convert.ResourceConvert;
+import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
+import cn.iocoder.mall.admin.vo.AdminMenuTreeNodeVO;
+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.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("admin/resource")
+@Api("资源模块")
+public class ResourceController {
+
+    @Reference
+    private ResourceService resourceService;
+
+    @GetMapping("/admin_menu_tree")
+    @ApiOperation(value = "获得管理员拥有的菜单权限", notes = "以树结构返回")
+    public CommonResult<List<AdminMenuTreeNodeVO>> adminMenuTree() {
+        List<ResourceBO> resources = resourceService.getResourceByTypeAndRoleIds(ResourceType.MENU, AdminSecurityContextHolder.getContext().getRoleIds());
+        // 创建 AdminMenuTreeNodeVO Map
+        Map<Integer, AdminMenuTreeNodeVO> treeNodeMap = resources.stream().collect(Collectors.toMap(ResourceBO::getId, ResourceConvert.INSTANCE::convert));
+        // 处理父子关系
+        treeNodeMap.values().stream().filter(node -> {
+            return node.getPid() != 0; // TODO magic number
+        }).forEach((childNode) -> {
+            // 获得父节点
+            AdminMenuTreeNodeVO parentNode = treeNodeMap.get(childNode.getPid());
+            if (parentNode.getChildren() == null) { // 初始化 children 数组
+                parentNode.setChildren(new ArrayList<>());
+            }
+            // 将自己添加到父节点中
+            parentNode.getChildren().add(childNode);
+        });
+        // 获得到所有的根节点
+        List<AdminMenuTreeNodeVO> rootNodes = treeNodeMap.values().stream().filter(node -> {
+            return node.getPid() == 0; // TODO magic number
+        }).collect(Collectors.toList());
+        return CommonResult.success(rootNodes);
+    }
+
+    @GetMapping("/admin_url_list")
+    @ApiOperation(value = "获得管理员拥有的 URL 权限列表")
+    public CommonResult adminUrlList() {
+        return null;
+    }
+
+}
\ No newline at end of file
diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/AdminConvert.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/AdminConvert.java
new file mode 100644
index 00000000..e18fc9e7
--- /dev/null
+++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/AdminConvert.java
@@ -0,0 +1,17 @@
+package cn.iocoder.mall.admin.convert;
+
+import cn.iocoder.mall.admin.sdk.context.AdminSecurityContext;
+import cn.iocoder.mall.admin.vo.AdminInfoVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface AdminConvert {
+
+    AdminConvert INSTANCE = Mappers.getMapper(AdminConvert.class);
+
+    @Mappings({})
+    AdminInfoVO convert(AdminSecurityContext adminSecurityContext);
+
+}
\ No newline at end of file
diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java
new file mode 100644
index 00000000..c0a9cd34
--- /dev/null
+++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java
@@ -0,0 +1,17 @@
+package cn.iocoder.mall.admin.convert;
+
+import cn.iocoder.mall.admin.api.bo.ResourceBO;
+import cn.iocoder.mall.admin.vo.AdminMenuTreeNodeVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface ResourceConvert {
+
+    ResourceConvert INSTANCE = Mappers.getMapper(ResourceConvert.class);
+
+    @Mappings({})
+    AdminMenuTreeNodeVO convert(ResourceBO resourceBO);
+
+}
diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminInfoVO.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminInfoVO.java
new file mode 100644
index 00000000..b0e609e5
--- /dev/null
+++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminInfoVO.java
@@ -0,0 +1,34 @@
+package cn.iocoder.mall.admin.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Set;
+
+@ApiModel("管理员信息 VO")
+public class AdminInfoVO {
+
+    @ApiModelProperty(value = "管理员比那好", required = true, example = "1")
+    private Integer adminId;
+    @ApiModelProperty(value = "角色编号的数组", required = true, example = "[1, 2]")
+    private Set<Integer> roleIds;
+
+    public Integer getAdminId() {
+        return adminId;
+    }
+
+    public AdminInfoVO setAdminId(Integer adminId) {
+        this.adminId = adminId;
+        return this;
+    }
+
+    public Set<Integer> getRoleIds() {
+        return roleIds;
+    }
+
+    public AdminInfoVO setRoleIds(Set<Integer> roleIds) {
+        this.roleIds = roleIds;
+        return this;
+    }
+
+}
\ No newline at end of file
diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminMenuTreeNodeVO.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminMenuTreeNodeVO.java
new file mode 100644
index 00000000..1e9d8b88
--- /dev/null
+++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/vo/AdminMenuTreeNodeVO.java
@@ -0,0 +1,72 @@
+package cn.iocoder.mall.admin.vo;
+
+import java.util.List;
+
+public class AdminMenuTreeNodeVO {
+
+    /**
+     * 菜单编号
+     */
+    private Integer id;
+    /**
+     * 彩蛋名
+     */
+    private String name;
+    /**
+     * 操作
+     */
+    private String handler;
+    /**
+     * 父菜单编号
+     */
+    private Integer pid;
+    /**
+     * 子节点数组
+     */
+    private List<AdminMenuTreeNodeVO> children;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public AdminMenuTreeNodeVO setId(Integer id) {
+        this.id = id;
+        return this;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public AdminMenuTreeNodeVO setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    public String getHandler() {
+        return handler;
+    }
+
+    public AdminMenuTreeNodeVO setHandler(String handler) {
+        this.handler = handler;
+        return this;
+    }
+
+    public List<AdminMenuTreeNodeVO> getChildren() {
+        return children;
+    }
+
+    public AdminMenuTreeNodeVO setChildren(List<AdminMenuTreeNodeVO> children) {
+        this.children = children;
+        return this;
+    }
+
+    public Integer getPid() {
+        return pid;
+    }
+
+    public AdminMenuTreeNodeVO setPid(Integer pid) {
+        this.pid = pid;
+        return this;
+    }
+}
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
new file mode 100644
index 00000000..4baeaa91
--- /dev/null
+++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/ResourceService.java
@@ -0,0 +1,12 @@
+package cn.iocoder.mall.admin.api;
+
+import cn.iocoder.mall.admin.api.bo.ResourceBO;
+
+import java.util.List;
+import java.util.Set;
+
+public interface ResourceService {
+
+    List<ResourceBO> getResourceByTypeAndRoleIds(Integer type, Set<Integer> roleIds);
+
+}
\ No newline at end of file
diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/ResourceBO.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/ResourceBO.java
new file mode 100644
index 00000000..ca6d79bc
--- /dev/null
+++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/ResourceBO.java
@@ -0,0 +1,115 @@
+package cn.iocoder.mall.admin.api.bo;
+
+import java.util.Date;
+
+/**
+ * 资源 BO
+ */
+public class ResourceBO {
+
+    /**
+     * 资源编号
+     */
+    private Integer id;
+    /**
+     * 资源名字(标识)
+     */
+    private String name;
+    /**
+     * 资源类型
+     */
+    private Integer type;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 展示名
+     */
+    private String displayName;
+    /**
+     * 添加时间
+     */
+    private Date createTime;
+    /**
+     * 父级资源编号
+     */
+    private Integer pid;
+    /**
+     * 操作
+     */
+    private String handler;
+
+    public Integer getId() {
+        return id;
+    }
+
+    public ResourceBO setId(Integer id) {
+        this.id = id;
+        return this;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public ResourceBO setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public ResourceBO setType(Integer type) {
+        this.type = type;
+        return this;
+    }
+
+    public Integer getSort() {
+        return sort;
+    }
+
+    public ResourceBO setSort(Integer sort) {
+        this.sort = sort;
+        return this;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public ResourceBO setDisplayName(String displayName) {
+        this.displayName = displayName;
+        return this;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public ResourceBO setCreateTime(Date createTime) {
+        this.createTime = createTime;
+        return this;
+    }
+
+    public Integer getPid() {
+        return pid;
+    }
+
+    public ResourceBO setPid(Integer pid) {
+        this.pid = pid;
+        return this;
+    }
+
+    public String getHandler() {
+        return handler;
+    }
+
+    public ResourceBO setHandler(String handler) {
+        this.handler = handler;
+        return this;
+    }
+
+}
\ No newline at end of file
diff --git a/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/ResourceType.java b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/ResourceType.java
new file mode 100644
index 00000000..1b87eca0
--- /dev/null
+++ b/admin/admin-service-api/src/main/java/cn/iocoder/mall/admin/api/constant/ResourceType.java
@@ -0,0 +1,17 @@
+package cn.iocoder.mall.admin.api.constant;
+
+/**
+ * 资源类型
+ */
+public interface ResourceType {
+
+    /**
+     * 彩蛋
+     */
+    Integer MENU = 1;
+    /**
+     * URL
+     */
+    Integer URL = 2;
+
+}
\ No newline at end of file
diff --git a/admin/admin-service-impl/pom.xml b/admin/admin-service-impl/pom.xml
index 578ae076..f8c28884 100644
--- a/admin/admin-service-impl/pom.xml
+++ b/admin/admin-service-impl/pom.xml
@@ -49,6 +49,12 @@
             <version>${org.mapstruct.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>27.0.1-jre</version>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java
new file mode 100644
index 00000000..093ddf9a
--- /dev/null
+++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/convert/ResourceConvert.java
@@ -0,0 +1,22 @@
+package cn.iocoder.mall.admin.convert;
+
+import cn.iocoder.mall.admin.api.bo.ResourceBO;
+import cn.iocoder.mall.admin.dataobject.ResourceDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface ResourceConvert {
+
+    ResourceConvert INSTANCE = Mappers.getMapper(ResourceConvert.class);
+
+    @Mappings({})
+    ResourceBO convert(ResourceDO resourceDO);
+
+    @Mappings({})
+    List<ResourceBO> convert(List<ResourceDO> resourceDOs);
+
+}
\ 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
new file mode 100644
index 00000000..7b68eed4
--- /dev/null
+++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dao/ResourceMapper.java
@@ -0,0 +1,19 @@
+package cn.iocoder.mall.admin.dao;
+
+import cn.iocoder.mall.admin.dataobject.ResourceDO;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Set;
+
+@Repository
+public interface ResourceMapper {
+
+    ResourceDO selectByTypeAndHandler(@Param("type") Integer type,
+                                      @Param("handler") String handler);
+
+    List<ResourceDO> selectListByTypeAndRoleIds(@Param("type") Integer type,
+                                                @Param("roleIds") Set<Integer> roleIds);
+
+}
\ 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 92f882c0..25daf33c 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
@@ -11,4 +11,6 @@ public interface RoleResourceMapper {
 
     List<RoleResourceDO> selectByResourceHandler(@Param("resourceHandler") String resourceHandler);
 
+    List<RoleResourceDO> selectRoleByResourceId(@Param("resourceId") Integer resourceId);
+
 }
\ No newline at end of file
diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ResourceDO.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ResourceDO.java
index b8b27826..79c887ad 100644
--- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ResourceDO.java
+++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/ResourceDO.java
@@ -1,21 +1,25 @@
 package cn.iocoder.mall.admin.dataobject;
 
+import cn.iocoder.common.framework.dataobject.BaseDO;
+
 import java.util.Date;
 
 /**
  * 资源实体
  */
-public class ResourceDO {
+public class ResourceDO extends BaseDO {
 
     /**
      * 资源类型 - 菜单
      */
+    @Deprecated
     public static final Integer TYPE_MENU = 1;
     /**
      * 资源类型 - 操作
      *
      * 例如,按钮。
      */
+    @Deprecated
     public static final Integer TYPE_OPERATION = 2;
 
     /**
@@ -23,7 +27,7 @@ public class ResourceDO {
      */
     private Integer id;
     /**
-     * 资源名字
+     * 资源名字(标识)
      */
     private String name;
     /**
@@ -50,7 +54,7 @@ public class ResourceDO {
      * 操作
      *
      * 当资源类型为【菜单】时,handler 配置为界面 URL ,或者前端组件名
-     * 当资源类型为【操作】时,handler 配置为后端 URL 。举个例子,如果有一个「创建管理员」的表单,那么前端界面上的按钮可以根据这个 url 判断是否展示,后端接收到该 url 的请求时会判断是否有权限。
+     * 当资源类型为【URL】时,handler 配置为后端 URL 。举个例子,如果有一个「创建管理员」的表单,那么前端界面上的按钮可以根据这个 url 判断是否展示,后端接收到该 url 的请求时会判断是否有权限。
      */
     private String handler;
 
diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java
index 64033c46..16a5594f 100644
--- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java
+++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/AdminServiceImpl.java
@@ -4,9 +4,9 @@ import cn.iocoder.common.framework.util.ServiceExceptionUtil;
 import cn.iocoder.common.framework.vo.CommonResult;
 import cn.iocoder.mall.admin.api.AdminService;
 import cn.iocoder.mall.admin.api.constant.AdminErrorCodeEnum;
+import cn.iocoder.mall.admin.dataobject.AdminDO;
 import cn.iocoder.mall.admin.dao.AdminMapper;
 import cn.iocoder.mall.admin.dao.AdminRoleMapper;
-import cn.iocoder.mall.admin.dataobject.AdminDO;
 import cn.iocoder.mall.admin.dataobject.AdminRoleDO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
diff --git a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/OAuth2ServiceImpl.java b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/OAuth2ServiceImpl.java
index 27734f4f..e827e2a4 100644
--- a/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/OAuth2ServiceImpl.java
+++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/OAuth2ServiceImpl.java
@@ -14,7 +14,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
 
 @Service
 @com.alibaba.dubbo.config.annotation.Service
@@ -39,6 +42,8 @@ public class OAuth2ServiceImpl implements OAuth2Service {
     private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
     @Autowired
     private RoleServiceImpl roleService;
+    @Autowired
+    private ResourceServiceImpl resourceService;
 
     @Override
     public CommonResult<OAuth2AccessTokenBO> getAccessToken(String username, String password) {
@@ -76,15 +81,17 @@ public class OAuth2ServiceImpl implements OAuth2Service {
 
     @Override
     public CommonResult<Boolean> checkPermission(Integer adminId, Set<Integer> roleIds, String url) {
-        // 避免传入的是空集合
-        if (roleIds == null) {
-            roleIds = Collections.emptySet();
-        }
-        // 校验权限
-        List<RoleResourceDO> roleResourceDOs = roleService.getRoleByResourceHandler(url);
-        if (roleResourceDOs.isEmpty()) { // 任何角色,都可以访问。TODO 后面调整下,如果未配置的资源,直接不校验权限
+        // 如果未配置该资源,说明无需权限控制。
+        ResourceDO resource = resourceService.getResourceByTypeAndHandler(ResourceDO.TYPE_OPERATION, url);
+        if (resource == null) {
             return CommonResult.success(true);
         }
+        // 资源存在,结果无角色,说明没有权限。
+        if (roleIds == null || roleIds.isEmpty()) {
+            return ServiceExceptionUtil.error(AdminErrorCodeEnum.OAUTH_INVALID_PERMISSION.getCode());
+        }
+        // 校验是否有资源对应的角色,即 RBAC 。
+        List<RoleResourceDO> roleResourceDOs = roleService.getRoleByResourceId(resource.getId());
         for (RoleResourceDO roleResourceDO : roleResourceDOs) {
             if (roleIds.contains(roleResourceDO.getRoleId())) {
                 return CommonResult.success(true);
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
new file mode 100644
index 00000000..7f796065
--- /dev/null
+++ b/admin/admin-service-impl/src/main/java/cn/iocoder/mall/admin/service/ResourceServiceImpl.java
@@ -0,0 +1,34 @@
+package cn.iocoder.mall.admin.service;
+
+import cn.iocoder.mall.admin.api.ResourceService;
+import cn.iocoder.mall.admin.api.bo.ResourceBO;
+import cn.iocoder.mall.admin.convert.ResourceConvert;
+import cn.iocoder.mall.admin.dao.ResourceMapper;
+import cn.iocoder.mall.admin.dataobject.ResourceDO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+@Service
+@com.alibaba.dubbo.config.annotation.Service
+public class ResourceServiceImpl implements ResourceService {
+
+    @Autowired
+    private ResourceMapper resourceMapper;
+
+    public ResourceDO getResourceByTypeAndHandler(Integer type, String handler) {
+        return resourceMapper.selectByTypeAndHandler(type, handler);
+    }
+
+    @Override
+    public List<ResourceBO> getResourceByTypeAndRoleIds(Integer type, Set<Integer> roleIds) {
+        if (roleIds == null || roleIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return ResourceConvert.INSTANCE.convert(resourceMapper.selectListByTypeAndRoleIds(type, roleIds));
+    }
+
+}
\ No newline at end of file
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 22aace4d..70c2313a 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
@@ -19,4 +19,8 @@ public class RoleServiceImpl implements RoleService {
         return roleResourceMapper.selectByResourceHandler(resourceHandler);
     }
 
+    public List<RoleResourceDO> getRoleByResourceId(Integer resourceId) {
+        return roleResourceMapper.selectRoleByResourceId(resourceId);
+    }
+
 }
\ 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
new file mode 100644
index 00000000..eeb7caea
--- /dev/null
+++ b/admin/admin-service-impl/src/main/resources/mapper/ResourceMapper.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.mall.admin.dao.ResourceMapper">
+
+    <!--<insert id="insert" parameterType="UserDO" useGeneratedKeys="true" keyProperty="id">-->
+    <!--INSERT INTO users (-->
+    <!--id, mobile, create_time-->
+    <!--) VALUES (-->
+    <!--#{id}, #{mobile}, #{createTime}-->
+    <!--)-->
+    <!--</insert>-->
+
+    <select id="selectByTypeAndHandler" resultType="ResourceDO">
+      SELECT
+        id, name, type, sort, display_name,
+        create_time, pid, handler
+      FROM resource
+      WHERE type = #{type}
+      AND handler = #{handler}
+      AND deleted = 0
+    </select>
+
+    <select id="selectListByTypeAndRoleIds" resultType="ResourceDO">
+      SELECT
+        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
+      AND rr.role_id IN
+        <foreach item="roleId" collection="roleIds" separator="," open="(" close=")" index="">
+         #{roleId}
+        </foreach>
+      AND r.id = rr.resource_id
+    </select>
+
+</mapper>
\ 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 b351fccf..7cebdd0f 100644
--- a/admin/admin-service-impl/src/main/resources/mapper/RoleResourceMapper.xml
+++ b/admin/admin-service-impl/src/main/resources/mapper/RoleResourceMapper.xml
@@ -18,4 +18,11 @@
       AND r.id = rr.resource_id
     </select>
 
+    <select id="selectRoleByResourceId" parameterType="Integer" resultType="RoleResourceDO">
+      SELECT
+        id, role_id, resource_id
+      FROM role_resource
+      WHERE resource_id = #{resourceId}
+    </select>
+
 </mapper>
\ No newline at end of file
diff --git a/common/common-framework/pom.xml b/common/common-framework/pom.xml
index 2a6830d6..8ffb4f05 100644
--- a/common/common-framework/pom.xml
+++ b/common/common-framework/pom.xml
@@ -44,6 +44,11 @@
             <artifactId>jackson-annotations</artifactId>
             <version>2.9.7</version>
         </dependency>
+        <!--<dependency>-->
+            <!--<groupId>com.baomidou</groupId>-->
+            <!--<artifactId>mybatis-plus-support</artifactId>-->
+            <!--<version>2.3</version>-->
+        <!--</dependency>-->
 
     </dependencies>
 
diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/dataobject/BaseDO.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/dataobject/BaseDO.java
new file mode 100644
index 00000000..51e3ee09
--- /dev/null
+++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/dataobject/BaseDO.java
@@ -0,0 +1,47 @@
+package cn.iocoder.common.framework.dataobject;
+
+import java.util.Date;
+
+/**
+ * 基础实体对象
+ */
+public class BaseDO {
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+    /**
+     * 最后更新时间
+     */
+    private Date updateTime;
+    private Boolean deleted;
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public BaseDO setCreateTime(Date createTime) {
+        this.createTime = createTime;
+        return this;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public BaseDO setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+        return this;
+    }
+
+    public Boolean getDeleted() {
+        return deleted;
+    }
+
+    public BaseDO setDeleted(Boolean deleted) {
+        this.deleted = deleted;
+        return this;
+    }
+
+}
\ No newline at end of file
-- 
2.17.1