Jelajahi Sumber

:tada: 增加接口权限业务模块

smallchill 6 tahun lalu
induk
melakukan
840b619aaa
23 mengubah file dengan 625 tambahan dan 57 penghapusan
  1. 5 0
      pom.xml
  2. 122 0
      src/main/java/org/springblade/modules/system/controller/ApiScopeController.java
  3. 0 1
      src/main/java/org/springblade/modules/system/controller/DataScopeController.java
  4. 22 5
      src/main/java/org/springblade/modules/system/controller/MenuController.java
  5. 3 2
      src/main/java/org/springblade/modules/system/controller/RoleController.java
  6. 72 0
      src/main/java/org/springblade/modules/system/entity/ApiScope.java
  7. 1 1
      src/main/java/org/springblade/modules/system/entity/DataScope.java
  8. 8 2
      src/main/java/org/springblade/modules/system/entity/RoleScope.java
  9. 30 0
      src/main/java/org/springblade/modules/system/mapper/ApiScopeMapper.java
  10. 5 0
      src/main/java/org/springblade/modules/system/mapper/ApiScopeMapper.xml
  11. 17 2
      src/main/java/org/springblade/modules/system/mapper/MenuMapper.java
  12. 122 28
      src/main/java/org/springblade/modules/system/mapper/MenuMapper.xml
  13. 30 0
      src/main/java/org/springblade/modules/system/service/IApiScopeService.java
  14. 18 2
      src/main/java/org/springblade/modules/system/service/IMenuService.java
  15. 5 4
      src/main/java/org/springblade/modules/system/service/IRoleService.java
  16. 34 0
      src/main/java/org/springblade/modules/system/service/impl/ApiScopeServiceImpl.java
  17. 14 3
      src/main/java/org/springblade/modules/system/service/impl/MenuServiceImpl.java
  18. 25 4
      src/main/java/org/springblade/modules/system/service/impl/RoleServiceImpl.java
  19. 39 0
      src/main/java/org/springblade/modules/system/vo/ApiScopeVO.java
  20. 3 1
      src/main/java/org/springblade/modules/system/vo/CheckedTreeVO.java
  21. 3 1
      src/main/java/org/springblade/modules/system/vo/GrantTreeVO.java
  22. 46 0
      src/main/java/org/springblade/modules/system/wrapper/ApiScopeWrapper.java
  23. 1 1
      src/main/java/org/springblade/modules/system/wrapper/DataScopeWrapper.java

+ 5 - 0
pom.xml

@@ -65,6 +65,11 @@
                 </exclusion>
             </exclusions>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-starter-datascope</artifactId>
+            <version>${bladex.tool.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.springblade</groupId>
             <artifactId>blade-starter-swagger</artifactId>

+ 122 - 0
src/main/java/org/springblade/modules/system/controller/ApiScopeController.java

@@ -0,0 +1,122 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiOperationSupport;
+import io.swagger.annotations.ApiParam;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.launch.constant.AppConstant;
+import org.springblade.core.mp.support.Condition;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.modules.system.entity.ApiScope;
+import org.springblade.modules.system.service.IApiScopeService;
+import org.springblade.modules.system.vo.ApiScopeVO;
+import org.springblade.modules.system.wrapper.ApiScopeWrapper;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
+
+/**
+ * 接口权限控制器
+ *
+ * @author BladeX
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping(AppConstant.APPLICATION_SYSTEM_NAME + "/api-scope")
+@Api(value = "接口权限", tags = "接口权限")
+public class ApiScopeController extends BladeController {
+
+	private IApiScopeService apiScopeService;
+
+	/**
+	 * 详情
+	 */
+	@GetMapping("/detail")
+	@ApiOperationSupport(order = 1)
+	@ApiOperation(value = "详情", notes = "传入dataScope")
+	public R<ApiScope> detail(ApiScope dataScope) {
+		ApiScope detail = apiScopeService.getOne(Condition.getQueryWrapper(dataScope));
+		return R.data(detail);
+	}
+
+	/**
+	 * 分页
+	 */
+	@GetMapping("/list")
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "分页", notes = "传入dataScope")
+	public R<IPage<ApiScopeVO>> list(ApiScope dataScope, Query query) {
+		IPage<ApiScope> pages = apiScopeService.page(Condition.getPage(query), Condition.getQueryWrapper(dataScope));
+		return R.data(ApiScopeWrapper.build().pageVO(pages));
+	}
+
+	/**
+	 * 新增
+	 */
+	@PostMapping("/save")
+	@ApiOperationSupport(order = 3)
+	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
+	@ApiOperation(value = "新增", notes = "传入dataScope")
+	public R save(@Valid @RequestBody ApiScope dataScope) {
+		return R.status(apiScopeService.save(dataScope));
+	}
+
+	/**
+	 * 修改
+	 */
+	@PostMapping("/update")
+	@ApiOperationSupport(order = 4)
+	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
+	@ApiOperation(value = "修改", notes = "传入dataScope")
+	public R update(@Valid @RequestBody ApiScope dataScope) {
+		return R.status(apiScopeService.updateById(dataScope));
+	}
+
+	/**
+	 * 新增或修改
+	 */
+	@PostMapping("/submit")
+	@ApiOperationSupport(order = 5)
+	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
+	@ApiOperation(value = "新增或修改", notes = "传入dataScope")
+	public R submit(@Valid @RequestBody ApiScope dataScope) {
+		return R.status(apiScopeService.saveOrUpdate(dataScope));
+	}
+
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 6)
+	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+		return R.status(apiScopeService.deleteLogic(Func.toLongList(ids)));
+	}
+
+}

+ 0 - 1
src/main/java/org/springblade/modules/system/controller/DataScopeController.java

@@ -43,7 +43,6 @@ import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
  * 数据权限控制器
  *
  * @author BladeX
- * @since 2019-06-23
  */
 @RestController
 @AllArgsConstructor

+ 22 - 5
src/main/java/org/springblade/modules/system/controller/MenuController.java

@@ -80,11 +80,26 @@ public class MenuController extends BladeController {
 	@ApiOperationSupport(order = 2)
 	@ApiOperation(value = "列表", notes = "传入menu")
 	public R<List<MenuVO>> list(@ApiIgnore @RequestParam Map<String, Object> menu) {
-		@SuppressWarnings("unchecked")
 		List<Menu> list = menuService.list(Condition.getQueryWrapper(menu, Menu.class).lambda().orderByAsc(Menu::getSort));
 		return R.data(MenuWrapper.build().listNodeVO(list));
 	}
 
+	/**
+	 * 列表
+	 */
+	@GetMapping("/menu-list")
+	@ApiImplicitParams({
+		@ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"),
+		@ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string")
+	})
+	@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
+	@ApiOperationSupport(order = 2)
+	@ApiOperation(value = "列表", notes = "传入menu")
+	public R<List<MenuVO>> menuList(@ApiIgnore @RequestParam Map<String, Object> menu) {
+		List<Menu> list = menuService.list(Condition.getQueryWrapper(menu, Menu.class).lambda().eq(Menu::getAlias, "menu").orderByAsc(Menu::getSort));
+		return R.data(MenuWrapper.build().listNodeVO(list));
+	}
+
 	/**
 	 * 新增或修改
 	 */
@@ -158,12 +173,13 @@ public class MenuController extends BladeController {
 	 * 获取权限分配树形结构
 	 */
 	@GetMapping("/grant-tree")
-	@ApiOperationSupport(order = 9)
+	@ApiOperationSupport(order = 8)
 	@ApiOperation(value = "权限分配树形结构", notes = "权限分配树形结构")
 	public R<GrantTreeVO> grantTree(BladeUser user) {
 		GrantTreeVO vo = new GrantTreeVO();
 		vo.setMenu(menuService.grantTree(user));
-		vo.setScope(menuService.grantScopeTree(user));
+		vo.setDataScope(menuService.grantDataScopeTree(user));
+		vo.setApiScope(menuService.grantApiScopeTree(user));
 		return R.data(vo);
 	}
 
@@ -171,12 +187,13 @@ public class MenuController extends BladeController {
 	 * 获取权限分配树形结构
 	 */
 	@GetMapping("/role-tree-keys")
-	@ApiOperationSupport(order = 10)
+	@ApiOperationSupport(order = 9)
 	@ApiOperation(value = "角色所分配的树", notes = "角色所分配的树")
 	public R<CheckedTreeVO> roleTreeKeys(String roleIds) {
 		CheckedTreeVO vo = new CheckedTreeVO();
 		vo.setMenu(menuService.roleTreeKeys(roleIds));
-		vo.setScope(menuService.scopeTreeKeys(roleIds));
+		vo.setDataScope(menuService.dataScopeTreeKeys(roleIds));
+		vo.setApiScope(menuService.apiScopeTreeKeys(roleIds));
 		return R.data(vo);
 	}
 

+ 3 - 2
src/main/java/org/springblade/modules/system/controller/RoleController.java

@@ -129,8 +129,9 @@ public class RoleController extends BladeController {
 	@CacheEvict(cacheNames = {SYS_CACHE}, allEntries = true)
 	public R grant(@ApiParam(value = "roleId集合", required = true) @RequestParam String roleIds,
 				   @ApiParam(value = "menuId集合", required = true) @RequestParam String menuIds,
-				   @ApiParam(value = "scopeId集合") String scopeIds) {
-		boolean temp = roleService.grant(Func.toLongList(roleIds), Func.toLongList(menuIds), Func.toLongList(scopeIds));
+				   @ApiParam(value = "dataScopeId集合") String dataScopeIds,
+				   @ApiParam(value = "apiScopeId集合") String apiScopeIds) {
+		boolean temp = roleService.grant(Func.toLongList(roleIds), Func.toLongList(menuIds), Func.toLongList(dataScopeIds), Func.toLongList(apiScopeIds));
 		return R.status(temp);
 	}
 

+ 72 - 0
src/main/java/org/springblade/modules/system/entity/ApiScope.java

@@ -0,0 +1,72 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * 实体类
+ *
+ * @author BladeX
+ * @since 2019-06-23
+ */
+@Data
+@TableName("blade_scope_api")
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "ApiScope对象", description = "ApiScope对象")
+public class ApiScope extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 菜单主键
+	 */
+	@ApiModelProperty(value = "菜单主键")
+	private Long menuId;
+	/**
+	 * 资源编号
+	 */
+	@ApiModelProperty(value = "资源编号")
+	private String resourceCode;
+	/**
+	 * 接口权限名称
+	 */
+	@ApiModelProperty(value = "接口权限名称")
+	private String scopeName;
+	/**
+	 * 接口权限字段
+	 */
+	@ApiModelProperty(value = "接口权限字段")
+	private String scopePath;
+	/**
+	 * 接口权限类型
+	 */
+	@ApiModelProperty(value = "接口权限类型")
+	private Integer scopeType;
+	/**
+	 * 接口权限备注
+	 */
+	@ApiModelProperty(value = "接口权限备注")
+	private String remark;
+
+
+}

+ 1 - 1
src/main/java/org/springblade/modules/system/entity/DataScope.java

@@ -30,7 +30,7 @@ import io.swagger.annotations.ApiModelProperty;
  * @since 2019-06-23
  */
 @Data
-@TableName("blade_data_scope")
+@TableName("blade_scope_data")
 @EqualsAndHashCode(callSuper = true)
 @ApiModel(value = "DataScope对象", description = "DataScope对象")
 public class DataScope extends BaseEntity {

+ 8 - 2
src/main/java/org/springblade/modules/system/entity/RoleScope.java

@@ -48,10 +48,16 @@ public class RoleScope implements Serializable {
 	private Long id;
 
 	/**
-	 * 数据权限id
+	 * 权限类型
+	 */
+	@ApiModelProperty(value = "权限类型")
+	private Integer scopeCategory;
+
+	/**
+	 * 权限id
 	 */
 	@JsonSerialize(using = ToStringSerializer.class)
-	@ApiModelProperty(value = "数据权限id")
+	@ApiModelProperty(value = "权限id")
 	private Long scopeId;
 
 	/**

+ 30 - 0
src/main/java/org/springblade/modules/system/mapper/ApiScopeMapper.java

@@ -0,0 +1,30 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.modules.system.entity.ApiScope;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2019-06-23
+ */
+public interface ApiScopeMapper extends BaseMapper<ApiScope> {
+
+}

+ 5 - 0
src/main/java/org/springblade/modules/system/mapper/ApiScopeMapper.xml

@@ -0,0 +1,5 @@
+<?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="org.springblade.modules.system.mapper.ApiScopeMapper">
+
+</mapper>

+ 17 - 2
src/main/java/org/springblade/modules/system/mapper/MenuMapper.java

@@ -67,7 +67,14 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 *
 	 * @return
 	 */
-	List<MenuVO> grantScopeTree();
+	List<MenuVO> grantDataScopeTree();
+
+	/**
+	 * 接口权限授权树形结构
+	 *
+	 * @return
+	 */
+	List<MenuVO> grantApiScopeTree();
 
 	/**
 	 * 数据权限授权树形结构
@@ -75,7 +82,15 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<MenuVO> grantScopeTreeByRole(List<Long> roleId);
+	List<MenuVO> grantDataScopeTreeByRole(List<Long> roleId);
+
+	/**
+	 * 接口权限授权树形结构
+	 *
+	 * @param roleId
+	 * @return
+	 */
+	List<MenuVO> grantApiScopeTreeByRole(List<Long> roleId);
 
 	/**
 	 * 所有菜单

+ 122 - 28
src/main/java/org/springblade/modules/system/mapper/MenuMapper.xml

@@ -139,7 +139,7 @@
         order by sort
     </select>
 
-    <select id="grantScopeTree" resultMap="treeNodeResultMap">
+    <select id="grantDataScopeTree" resultMap="treeNodeResultMap">
         SELECT
             *
         FROM
@@ -155,7 +155,7 @@
                 WHERE
                     category = 1
                   AND is_deleted = 0
-                  AND id IN ( SELECT menu_id FROM blade_data_scope WHERE is_deleted = 0 AND menu_id IS NOT NULL )
+                  AND id IN ( SELECT menu_id FROM blade_scope_data WHERE is_deleted = 0 AND menu_id IS NOT NULL )
                 ORDER BY
                     sort
             ) menu
@@ -169,13 +169,13 @@
             id AS 'value',
             id AS 'key'
         FROM
-            blade_data_scope
+            blade_scope_data
         WHERE
             is_deleted = 0
           AND menu_id IS NOT NULL
     </select>
 
-    <select id="grantScopeTreeByRole" resultMap="treeNodeResultMap">
+    <select id="grantApiScopeTree" resultMap="treeNodeResultMap">
         SELECT
             *
         FROM
@@ -191,18 +191,7 @@
                 WHERE
                     category = 1
                   AND is_deleted = 0
-                  AND id IN ( SELECT menu_id FROM blade_data_scope WHERE is_deleted = 0 AND menu_id IS NOT NULL )
-                  AND id IN ( select menu_id from blade_role_menu where role_id in
-                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
-                        #{item}
-                    </foreach> )
-                    OR id IN (
-                    select parent_id from blade_menu where is_deleted = 0
-                    and id in ( select menu_id from blade_role_menu where role_id in
-                    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
-                        #{item}
-                    </foreach> )
-                  )
+                  AND id IN ( SELECT menu_id FROM blade_scope_api WHERE is_deleted = 0 AND menu_id IS NOT NULL )
                 ORDER BY
                     sort
             ) menu
@@ -216,23 +205,128 @@
             id AS 'value',
             id AS 'key'
         FROM
-            blade_data_scope
+            blade_scope_api
         WHERE
             is_deleted = 0
-            AND menu_id IN ( select menu_id from blade_role_menu where role_id in
-            <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
-                #{item}
-            </foreach> )
-            OR menu_id IN (
-            select parent_id from blade_menu where is_deleted = 0
-            and id in ( select menu_id from blade_role_menu where role_id in
-            <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
-                #{item}
-            </foreach> )
-            )
           AND menu_id IS NOT NULL
     </select>
 
+    <select id="grantDataScopeTreeByRole" resultMap="treeNodeResultMap">
+        SELECT
+        *
+        FROM
+        (
+        SELECT
+        id,
+        parent_id,
+        NAME AS title,
+        id AS 'value',
+        id AS 'key'
+        FROM
+        blade_menu
+        WHERE
+        category = 1
+        AND is_deleted = 0
+        AND id IN ( SELECT menu_id FROM blade_scope_data WHERE is_deleted = 0 AND menu_id IS NOT NULL )
+        AND id IN ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        OR id IN (
+        select parent_id from blade_menu where is_deleted = 0
+        and id in ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        )
+        ORDER BY
+        sort
+        ) menu
+
+        UNION ALL
+
+        SELECT
+        id,
+        menu_id AS parent_id,
+        scope_name AS title,
+        id AS 'value',
+        id AS 'key'
+        FROM
+        blade_scope_data
+        WHERE
+        is_deleted = 0
+        AND menu_id IN ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        OR menu_id IN (
+        select parent_id from blade_menu where is_deleted = 0
+        and id in ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        )
+        AND menu_id IS NOT NULL
+    </select>
+
+    <select id="grantApiScopeTreeByRole" resultMap="treeNodeResultMap">
+        SELECT
+        *
+        FROM
+        (
+        SELECT
+        id,
+        parent_id,
+        NAME AS title,
+        id AS 'value',
+        id AS 'key'
+        FROM
+        blade_menu
+        WHERE
+        category = 1
+        AND is_deleted = 0
+        AND id IN ( SELECT menu_id FROM blade_scope_api WHERE is_deleted = 0 AND menu_id IS NOT NULL )
+        AND id IN ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        OR id IN (
+        select parent_id from blade_menu where is_deleted = 0
+        and id in ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        )
+        ORDER BY
+        sort
+        ) menu
+
+        UNION ALL
+
+        SELECT
+        id,
+        menu_id AS parent_id,
+        scope_name AS title,
+        id AS 'value',
+        id AS 'key'
+        FROM
+        blade_scope_api
+        WHERE
+        is_deleted = 0
+        AND menu_id IN ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        OR menu_id IN (
+        select parent_id from blade_menu where is_deleted = 0
+        and id in ( select menu_id from blade_role_menu where role_id in
+        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach> )
+        )
+        AND menu_id IS NOT NULL
+    </select>
+
     <select id="authRoutes" resultType="org.springblade.modules.system.dto.MenuDTO">
         SELECT
             GROUP_CONCAT(r.role_alias) as alias,

+ 30 - 0
src/main/java/org/springblade/modules/system/service/IApiScopeService.java

@@ -0,0 +1,30 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.service;
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.modules.system.entity.ApiScope;
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2019-06-23
+ */
+public interface IApiScopeService extends BaseService<ApiScope> {
+
+}

+ 18 - 2
src/main/java/org/springblade/modules/system/service/IMenuService.java

@@ -86,7 +86,15 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<MenuVO> grantScopeTree(BladeUser user);
+	List<MenuVO> grantDataScopeTree(BladeUser user);
+
+	/**
+	 * 接口权限授权树形结构
+	 *
+	 * @param user
+	 * @return
+	 */
+	List<MenuVO> grantApiScopeTree(BladeUser user);
 
 	/**
 	 * 默认选中节点
@@ -102,7 +110,15 @@ public interface IMenuService extends IService<Menu> {
 	 * @param roleIds
 	 * @return
 	 */
-	List<String> scopeTreeKeys(String roleIds);
+	List<String> dataScopeTreeKeys(String roleIds);
+
+	/**
+	 * 默认选中节点
+	 *
+	 * @param roleIds
+	 * @return
+	 */
+	List<String> apiScopeTreeKeys(String roleIds);
 
 	/**
 	 * 获取配置的角色权限

+ 5 - 4
src/main/java/org/springblade/modules/system/service/IRoleService.java

@@ -51,12 +51,13 @@ public interface IRoleService extends IService<Role> {
 	/**
 	 * 权限配置
 	 *
-	 * @param roleIds  角色id集合
-	 * @param menuIds  菜单id集合
-	 * @param scopeIds 数据权限id集合
+	 * @param roleIds 角色id集合
+	 * @param menuIds 菜单id集合
+	 * @param dataScopeIds 数据权限id集合
+	 * @param apiScopeIds 接口权限id集合
 	 * @return 是否成功
 	 */
-	boolean grant(@NotEmpty List<Long> roleIds, @NotEmpty List<Long> menuIds, List<Long> scopeIds);
+	boolean grant(@NotEmpty List<Long> roleIds, @NotEmpty List<Long> menuIds, List<Long> dataScopeIds, List<Long> apiScopeIds);
 
 	/**
 	 * 获取角色名

+ 34 - 0
src/main/java/org/springblade/modules/system/service/impl/ApiScopeServiceImpl.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.service.impl;
+
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.modules.system.entity.ApiScope;
+import org.springblade.modules.system.mapper.ApiScopeMapper;
+import org.springblade.modules.system.service.IApiScopeService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 服务实现类
+ *
+ * @author BladeX
+ * @since 2019-06-23
+ */
+@Service
+public class ApiScopeServiceImpl extends BaseServiceImpl<ApiScopeMapper, ApiScope> implements IApiScopeService {
+
+}

+ 14 - 3
src/main/java/org/springblade/modules/system/service/impl/MenuServiceImpl.java

@@ -117,8 +117,13 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM
 	}
 
 	@Override
-	public List<MenuVO> grantScopeTree(BladeUser user) {
-		return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantScopeTree() : baseMapper.grantScopeTreeByRole(Func.toLongList(user.getRoleId())));
+	public List<MenuVO> grantDataScopeTree(BladeUser user) {
+		return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantDataScopeTree() : baseMapper.grantDataScopeTreeByRole(Func.toLongList(user.getRoleId())));
+	}
+
+	@Override
+	public List<MenuVO> grantApiScopeTree(BladeUser user) {
+		return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantApiScopeTree() : baseMapper.grantApiScopeTreeByRole(Func.toLongList(user.getRoleId())));
 	}
 
 	@Override
@@ -128,7 +133,13 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IM
 	}
 
 	@Override
-	public List<String> scopeTreeKeys(String roleIds) {
+	public List<String> dataScopeTreeKeys(String roleIds) {
+		List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().in(RoleScope::getRoleId, Func.toLongList(roleIds)));
+		return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
+	}
+
+	@Override
+	public List<String> apiScopeTreeKeys(String roleIds) {
 		List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().in(RoleScope::getRoleId, Func.toLongList(roleIds)));
 		return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
 	}

+ 25 - 4
src/main/java/org/springblade/modules/system/service/impl/RoleServiceImpl.java

@@ -54,6 +54,9 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
 	private IRoleMenuService roleMenuService;
 	private IRoleScopeService roleScopeService;
 
+	private static Integer DATA_SCOPE_CATEGORY = 1;
+	private static Integer API_SCOPE_CATEGORY = 2;
+
 	@Override
 	public IPage<RoleVO> selectRolePage(IPage<RoleVO> page, RoleVO role) {
 		return page.setRecords(baseMapper.selectRolePage(page, role));
@@ -71,7 +74,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
 
 	@Override
 	@Transactional(rollbackFor = Exception.class)
-	public boolean grant(@NotEmpty List<Long> roleIds, @NotEmpty List<Long> menuIds, List<Long> scopeIds) {
+	public boolean grant(@NotEmpty List<Long> roleIds, @NotEmpty List<Long> menuIds, List<Long> dataScopeIds, List<Long> apiScopeIds) {
 		// 菜单权限模块
 		// 删除角色配置的菜单集合
 		roleMenuService.remove(Wrappers.<RoleMenu>update().lambda().in(RoleMenu::getRoleId, roleIds));
@@ -87,13 +90,14 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
 		roleMenuService.saveBatch(roleMenus);
 
 		// 数据权限模块
-		if (CollectionUtil.isNotEmpty(scopeIds)) {
+		if (CollectionUtil.isNotEmpty(dataScopeIds)) {
 			// 删除角色配置的数据权限集合
-			roleScopeService.remove(Wrappers.<RoleScope>update().lambda().in(RoleScope::getRoleId, roleIds));
+			roleScopeService.remove(Wrappers.<RoleScope>update().lambda().eq(RoleScope::getScopeCategory, DATA_SCOPE_CATEGORY).in(RoleScope::getRoleId, roleIds));
 			// 组装配置
 			List<RoleScope> roleScopes = new ArrayList<>();
-			roleIds.forEach(roleId -> scopeIds.forEach(scopeId -> {
+			roleIds.forEach(roleId -> dataScopeIds.forEach(scopeId -> {
 				RoleScope roleScope = new RoleScope();
+				roleScope.setScopeCategory(DATA_SCOPE_CATEGORY);
 				roleScope.setRoleId(roleId);
 				roleScope.setScopeId(scopeId);
 				roleScopes.add(roleScope);
@@ -102,6 +106,23 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IR
 			roleScopeService.saveBatch(roleScopes);
 		}
 
+		// 接口权限模块
+		if (CollectionUtil.isNotEmpty(apiScopeIds)) {
+			// 删除角色配置的数据权限集合
+			roleScopeService.remove(Wrappers.<RoleScope>update().lambda().eq(RoleScope::getScopeCategory, API_SCOPE_CATEGORY).in(RoleScope::getRoleId, roleIds));
+			// 组装配置
+			List<RoleScope> roleScopes = new ArrayList<>();
+			roleIds.forEach(roleId -> apiScopeIds.forEach(scopeId -> {
+				RoleScope roleScope = new RoleScope();
+				roleScope.setScopeCategory(API_SCOPE_CATEGORY);
+				roleScope.setScopeId(scopeId);
+				roleScope.setRoleId(roleId);
+				roleScopes.add(roleScope);
+			}));
+			// 新增配置
+			roleScopeService.saveBatch(roleScopes);
+		}
+
 		return true;
 	}
 

+ 39 - 0
src/main/java/org/springblade/modules/system/vo/ApiScopeVO.java

@@ -0,0 +1,39 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.modules.system.entity.ApiScope;
+
+/**
+ * 视图实体类
+ *
+ * @author Chill
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "ApiScopeVO对象", description = "ApiScopeVO对象")
+public class ApiScopeVO extends ApiScope {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 规则类型名
+	 */
+	private String scopeTypeName;
+}

+ 3 - 1
src/main/java/org/springblade/modules/system/vo/CheckedTreeVO.java

@@ -30,6 +30,8 @@ public class CheckedTreeVO {
 
 	private List<String> menu;
 
-	private List<String> scope;
+	private List<String> dataScope;
+
+	private List<String> apiScope;
 
 }

+ 3 - 1
src/main/java/org/springblade/modules/system/vo/GrantTreeVO.java

@@ -30,6 +30,8 @@ public class GrantTreeVO {
 
 	private List<MenuVO> menu;
 
-	private List<MenuVO> scope;
+	private List<MenuVO> dataScope;
+
+	private List<MenuVO> apiScope;
 
 }

+ 46 - 0
src/main/java/org/springblade/modules/system/wrapper/ApiScopeWrapper.java

@@ -0,0 +1,46 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.modules.system.wrapper;
+
+import org.springblade.common.cache.DictCache;
+import org.springblade.core.mp.support.BaseEntityWrapper;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.modules.system.entity.ApiScope;
+import org.springblade.modules.system.vo.ApiScopeVO;
+
+
+/**
+ * 包装类,返回视图层所需的字段
+ *
+ * @author Chill
+ */
+public class ApiScopeWrapper extends BaseEntityWrapper<ApiScope, ApiScopeVO> {
+
+	public static ApiScopeWrapper build() {
+		return new ApiScopeWrapper();
+	}
+
+	@Override
+	public ApiScopeVO entityVO(ApiScope dataScope) {
+		ApiScopeVO apiScopeVO = BeanUtil.copy(dataScope, ApiScopeVO.class);
+		assert apiScopeVO != null;
+		String scopeTypeName = DictCache.getValue("api_scope_type", dataScope.getScopeType());
+		apiScopeVO.setScopeTypeName(scopeTypeName);
+		return apiScopeVO;
+	}
+
+}

+ 1 - 1
src/main/java/org/springblade/modules/system/wrapper/DataScopeWrapper.java

@@ -38,7 +38,7 @@ public class DataScopeWrapper extends BaseEntityWrapper<DataScope, DataScopeVO>
 	public DataScopeVO entityVO(DataScope dataScope) {
 		DataScopeVO dataScopeVO = BeanUtil.copy(dataScope, DataScopeVO.class);
 		assert dataScopeVO != null;
-		String scopeTypeName = DictCache.getValue("scope_type", dataScope.getScopeType());
+		String scopeTypeName = DictCache.getValue("data_scope_type", dataScope.getScopeType());
 		dataScopeVO.setScopeTypeName(scopeTypeName);
 		return dataScopeVO;
 	}