Просмотр исходного кода

:tada: 增加接口权限、拆分数据权限

smallchill 6 лет назад
Родитель
Сommit
6795f50094

+ 10 - 45
src/api/system/menu.js

@@ -11,45 +11,10 @@ export const getList = (current, size, params) => {
     }
   })
 }
-export const remove = (ids) => {
-  return request({
-    url: '/api/blade-system/menu/remove',
-    method: 'post',
-    params: {
-      ids,
-    }
-  })
-}
-
-export const add = (row) => {
-  return request({
-    url: '/api/blade-system/menu/submit',
-    method: 'post',
-    data: row
-  })
-}
 
-export const update = (row) => {
+export const getMenuList = (current, size, params) => {
   return request({
-    url: '/api/blade-system/menu/submit',
-    method: 'post',
-    data: row
-  })
-}
-
-export const getMenu = (id) => {
-  return request({
-    url: '/api/blade-system/menu/detail',
-    method: 'get',
-    params: {
-      id,
-    }
-  })
-}
-
-export const getListScope = (current, size, params) => {
-  return request({
-    url: '/api/blade-system/data-scope/list',
+    url: '/api/blade-system/menu/menu-list',
     method: 'get',
     params: {
       ...params,
@@ -59,9 +24,9 @@ export const getListScope = (current, size, params) => {
   })
 }
 
-export const removeScope = (ids) => {
+export const remove = (ids) => {
   return request({
-    url: '/api/blade-system/data-scope/remove',
+    url: '/api/blade-system/menu/remove',
     method: 'post',
     params: {
       ids,
@@ -69,25 +34,25 @@ export const removeScope = (ids) => {
   })
 }
 
-export const addScope = (row) => {
+export const add = (row) => {
   return request({
-    url: '/api/blade-system/data-scope/submit',
+    url: '/api/blade-system/menu/submit',
     method: 'post',
     data: row
   })
 }
 
-export const updateScope = (row) => {
+export const update = (row) => {
   return request({
-    url: '/api/blade-system/data-scope/submit',
+    url: '/api/blade-system/menu/submit',
     method: 'post',
     data: row
   })
 }
 
-export const getMenuScope = (id) => {
+export const getMenu = (id) => {
   return request({
-    url: '/api/blade-system/data-scope/detail',
+    url: '/api/blade-system/menu/detail',
     method: 'get',
     params: {
       id,

+ 3 - 2
src/api/system/role.js

@@ -18,14 +18,15 @@ export const grantTree = () => {
   })
 }
 
-export const grant = (roleIds, menuIds, scopeIds) => {
+export const grant = (roleIds, menuIds, dataScopeIds, apiScopeIds) => {
   return request({
     url: '/api/blade-system/role/grant',
     method: 'post',
     params: {
       roleIds,
       menuIds,
-      scopeIds
+      dataScopeIds,
+      apiScopeIds
     }
   })
 }

+ 97 - 0
src/api/system/scope.js

@@ -0,0 +1,97 @@
+import request from '@/router/axios';
+
+export const getListDataScope = (current, size, params) => {
+  return request({
+    url: '/api/blade-system/data-scope/list',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const removeDataScope = (ids) => {
+  return request({
+    url: '/api/blade-system/data-scope/remove',
+    method: 'post',
+    params: {
+      ids,
+    }
+  })
+}
+
+export const addDataScope = (row) => {
+  return request({
+    url: '/api/blade-system/data-scope/submit',
+    method: 'post',
+    data: row
+  })
+}
+
+export const updateDataScope = (row) => {
+  return request({
+    url: '/api/blade-system/data-scope/submit',
+    method: 'post',
+    data: row
+  })
+}
+
+export const getMenuDataScope = (id) => {
+  return request({
+    url: '/api/blade-system/data-scope/detail',
+    method: 'get',
+    params: {
+      id,
+    }
+  })
+}
+
+export const getListApiScope = (current, size, params) => {
+  return request({
+    url: '/api/blade-system/api-scope/list',
+    method: 'get',
+    params: {
+      ...params,
+      current,
+      size,
+    }
+  })
+}
+
+export const removeApiScope = (ids) => {
+  return request({
+    url: '/api/blade-system/api-scope/remove',
+    method: 'post',
+    params: {
+      ids,
+    }
+  })
+}
+
+export const addApiScope = (row) => {
+  return request({
+    url: '/api/blade-system/api-scope/submit',
+    method: 'post',
+    data: row
+  })
+}
+
+export const updateApiScope = (row) => {
+  return request({
+    url: '/api/blade-system/api-scope/submit',
+    method: 'post',
+    data: row
+  })
+}
+
+export const getMenuApiScope = (id) => {
+  return request({
+    url: '/api/blade-system/api-scope/detail',
+    method: 'get',
+    params: {
+      id,
+    }
+  })
+}

+ 606 - 0
src/views/system/apiscope.vue

@@ -0,0 +1,606 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option"
+               :data="data"
+               ref="crud"
+               v-model="form"
+               :permission="permissionList"
+               :before-open="beforeOpen"
+               @row-del="rowDel"
+               @row-update="rowUpdate"
+               @row-save="rowSave"
+               @search-change="searchChange"
+               @search-reset="searchReset"
+               @selection-change="selectionChange"
+               @current-change="currentChange"
+               @size-change="sizeChange"
+               @on-load="onLoad">
+      <template slot-scope="{row}" slot="menu">
+        <el-button type="text"
+                   icon="el-icon-setting"
+                   size="small"
+                   v-if="permission.api_scope_setting"
+                   plain
+                   class="none-border"
+                   @click.stop="handleDataScope(row)">权限配置
+        </el-button>
+      </template>
+      <template slot-scope="{row}" slot="source">
+        <div style="text-align:center">
+          <i :class="row.source"></i>
+        </div>
+      </template>
+    </avue-crud>
+    <avue-drawer :title="`[${scopeMenuName}] 接口权限配置`" show-close :width="1000" v-model="drawerVisible"
+                 :before-close="handleDrawerClose">
+      <avue-crud :option="optionScope"
+                 :data="dataScope"
+                 :page="pageScope"
+                 v-model="formScope"
+                 ref="crudScope"
+                 @row-del="rowDelScope"
+                 @row-update="rowUpdateScope"
+                 @row-save="rowSaveScope"
+                 :before-open="beforeOpenScope"
+                 @search-change="searchChangeScope"
+                 @search-reset="searchResetScope"
+                 @selection-change="selectionChangeScope"
+                 @current-change="currentChangeScope"
+                 @size-change="sizeChangeScope"
+                 @on-load="onLoadScope">
+        <template slot="menuLeft">
+          <el-button type="danger"
+                     size="small"
+                     icon="el-icon-delete"
+                     plain
+                     @click="handleDeleteScope">删 除
+          </el-button>
+        </template>
+        <template slot-scope="{row}"
+                  slot="scopeType">
+          <el-tag>{{row.scopeTypeName}}</el-tag>
+        </template>
+      </avue-crud>
+    </avue-drawer>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    add,
+    remove,
+    update,
+    getMenuList,
+    getMenu
+  } from "@/api/system/menu";
+  import {
+    addApiScope,
+    removeApiScope,
+    updateApiScope,
+    getListApiScope,
+    getMenuApiScope
+  } from "@/api/system/scope";
+  import {mapGetters} from "vuex";
+  import iconList from "@/config/iconList";
+
+  export default {
+    data() {
+      return {
+        form: {},
+        selectionList: [],
+        query: {},
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        drawerVisible: false,
+        scopeMenuId: 0,
+        scopeMenuName: "菜单",
+        menu: true,
+        option: {
+          tip: false,
+          dialogWidth: "60%",
+          tree: true,
+          border: true,
+          index: true,
+          selection: true,
+          viewBtn: false,
+          editBtn: false,
+          addBtn: false,
+          delBtn: false,
+          menuWidth: 250,
+          column: [
+            {
+              label: "菜单名称",
+              prop: "name",
+              search: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单名称",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "路由地址",
+              prop: "path",
+              rules: [
+                {
+                  required: true,
+                  message: "请输入路由地址",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "上级菜单",
+              prop: "parentId",
+              type: "tree",
+              dicUrl: "/api/blade-system/menu/tree",
+              hide: true,
+              props: {
+                label: "title"
+              },
+              rules: [
+                {
+                  required: false,
+                  message: "请选择上级菜单",
+                  trigger: "click"
+                }
+              ]
+            },
+            {
+              label: "菜单图标",
+              prop: "source",
+              type: "icon-select",
+              slot: true,
+              width: 80,
+              iconList: iconList,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单图标",
+                  trigger: "click"
+                }
+              ]
+            },
+            {
+              label: "菜单编号",
+              prop: "code",
+              search: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单编号",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "菜单类型",
+              prop: "category",
+              type: "radio",
+              dicData: [
+                {
+                  label: "菜单",
+                  value: 1
+                },
+                {
+                  label: "按钮",
+                  value: 2
+                }
+              ],
+              hide: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请选择菜单类型",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "菜单别名",
+              prop: "alias",
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单别名",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "按钮功能",
+              prop: "action",
+              type: "radio",
+              dicData: [
+                {
+                  label: "工具栏",
+                  value: 0
+                },
+                {
+                  label: "操作栏",
+                  value: 1
+                },
+                {
+                  label: "工具操作栏",
+                  value: 2
+                }
+              ],
+              hide: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请选择按钮功能",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "菜单排序",
+              prop: "sort",
+              type: "number",
+              width: 80,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单排序",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "新窗口",
+              prop: "isOpen",
+              type: "radio",
+              dicData: [
+                {
+                  label: "否",
+                  value: 0
+                },
+                {
+                  label: "是",
+                  value: 1
+                },
+              ],
+              hide: true
+            },
+            {
+              label: "菜单备注",
+              prop: "remark",
+              type: "textarea",
+              span: 24,
+              minRows: 6,
+              hide: true
+            }
+          ]
+        },
+        data: [],
+        formScope: {},
+        selectionListScope: [],
+        pageScope: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        optionScope: {
+          tip: false,
+          border: true,
+          index: true,
+          viewBtn: true,
+          selection: true,
+          menuWidth: 175,
+          dialogWidth: 450,
+          dialogHeight: 230,
+          column: [
+            {
+              label: "权限名称",
+              prop: "scopeName",
+              search: true,
+              rules: [{
+                required: true,
+                message: "请输入数据权限名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "权限编号",
+              prop: "resourceCode",
+              search: true,
+              width: 100,
+              rules: [{
+                required: true,
+                message: "请输入数据权限编号",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "权限路径",
+              prop: "scopePath",
+              width: 130,
+              rules: [{
+                required: true,
+                message: "请输入数据权限编号",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "接口类型",
+              type: "select",
+              dicUrl: "/api/blade-system/dict/dictionary?code=api_scope_type",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              slot: true,
+              width: 140,
+              prop: "scopeType",
+              rules: [{
+                required: true,
+                message: "请输入通知类型",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "备注",
+              prop: "remark",
+              span: 24,
+              hide: true,
+            },
+          ]
+        },
+        dataScope: []
+      };
+    },
+
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.menu_add, false),
+          viewBtn: this.vaildData(this.permission.menu_view, false),
+          delBtn: this.vaildData(this.permission.menu_delete, false),
+          editBtn: this.vaildData(this.permission.menu_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
+      scopeIds() {
+        let ids = [];
+        this.selectionListScope.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    methods: {
+      // 菜单管理模块
+      rowSave(row, loading, done) {
+        add(row).then(() => {
+          loading();
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowUpdate(row, index, loading, done) {
+        update(row).then(() => {
+          loading();
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowDel(row) {
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params) {
+        this.query = params;
+        this.onLoad(this.page, params);
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getMenu(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      currentChange(currentPage) {
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        this.page.pageSize = pageSize;
+      },
+      onLoad(page, params = {}) {
+        getMenuList(page.currentPage, page.pageSize, params).then(res => {
+          this.data = res.data.data;
+        });
+      },
+      // 数据权限模块
+      handleDataScope(row) {
+        this.drawerVisible = true;
+        this.scopeMenuId = row.id;
+        this.scopeMenuName = row.name;
+      },
+      handleDrawerClose(hide) {
+        hide();
+      },
+      rowSaveScope(row, loading, done) {
+        row = {
+          ...row,
+          menuId: this.scopeMenuId,
+        }
+        addApiScope(row).then(() => {
+          loading();
+          this.onLoadScope(this.pageScope);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowUpdateScope(row, index, loading, done) {
+        row = {
+          ...row,
+          menuId: this.scopeMenuId,
+        }
+        updateApiScope(row).then(() => {
+          loading();
+          this.onLoadScope(this.pageScope);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowDelScope(row) {
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return removeApiScope(row.id);
+          })
+          .then(() => {
+            this.onLoadScope(this.pageScope);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDeleteScope() {
+        if (this.selectionListScope.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return removeApiScope(this.scopeIds);
+          })
+          .then(() => {
+            this.onLoadScope(this.pageScope);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crudScope.toggleSelection();
+          });
+      },
+      beforeOpenScope(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getMenuApiScope(this.formScope.id).then(res => {
+            this.formScope = res.data.data;
+          });
+        }
+        done();
+      },
+      searchResetScope() {
+        this.onLoadScope(this.pageScope);
+      },
+      searchChangeScope(params) {
+        this.onLoadScope(this.pageScope, params);
+      },
+      selectionChangeScope(list) {
+        this.selectionListScope = list;
+      },
+      currentChangeScope(currentPage) {
+        this.pageScope.currentPage = currentPage;
+      },
+      sizeChangeScope(pageSize) {
+        this.pageScope.pageSize = pageSize;
+      },
+      onLoadScope(page, params = {}) {
+        const values = {
+          ...params,
+          menuId: this.scopeMenuId,
+        }
+        getListApiScope(page.currentPage, page.pageSize, Object.assign(values, this.query)).then(res => {
+          const data = res.data.data;
+          this.pageScope.total = data.total;
+          this.dataScope = data.records;
+        });
+      },
+    }
+  };
+</script>
+
+<style>
+  .none-border {
+    border: 0;
+    background-color: transparent !important;
+  }
+</style>

+ 636 - 0
src/views/system/datascope.vue

@@ -0,0 +1,636 @@
+<template>
+  <basic-container>
+    <avue-crud :option="option"
+               :data="data"
+               ref="crud"
+               v-model="form"
+               :permission="permissionList"
+               :before-open="beforeOpen"
+               @row-del="rowDel"
+               @row-update="rowUpdate"
+               @row-save="rowSave"
+               @search-change="searchChange"
+               @search-reset="searchReset"
+               @selection-change="selectionChange"
+               @current-change="currentChange"
+               @size-change="sizeChange"
+               @on-load="onLoad">
+      <template slot-scope="{row}" slot="menu">
+        <el-button type="text"
+                   icon="el-icon-setting"
+                   size="small"
+                   v-if="permission.data_scope_setting"
+                   plain
+                   class="none-border"
+                   @click.stop="handleDataScope(row)">权限配置
+        </el-button>
+      </template>
+      <template slot-scope="{row}" slot="source">
+        <div style="text-align:center">
+          <i :class="row.source"></i>
+        </div>
+      </template>
+    </avue-crud>
+    <avue-drawer :title="`[${scopeMenuName}] 数据权限配置`" show-close :width="1000" v-model="drawerVisible"
+                 :before-close="handleDrawerClose">
+      <avue-crud :option="optionScope"
+                 :data="dataScope"
+                 :page="pageScope"
+                 v-model="formScope"
+                 ref="crudScope"
+                 @row-del="rowDelScope"
+                 @row-update="rowUpdateScope"
+                 @row-save="rowSaveScope"
+                 :before-open="beforeOpenScope"
+                 @search-change="searchChangeScope"
+                 @search-reset="searchResetScope"
+                 @selection-change="selectionChangeScope"
+                 @current-change="currentChangeScope"
+                 @size-change="sizeChangeScope"
+                 @on-load="onLoadScope">
+        <template slot="menuLeft">
+          <el-button type="danger"
+                     size="small"
+                     icon="el-icon-delete"
+                     plain
+                     @click="handleDeleteScope">删 除
+          </el-button>
+        </template>
+        <template slot-scope="{row}"
+                  slot="scopeType">
+          <el-tag>{{row.scopeTypeName}}</el-tag>
+        </template>
+      </avue-crud>
+    </avue-drawer>
+  </basic-container>
+</template>
+
+<script>
+  import {
+    add,
+    remove,
+    update,
+    getMenuList,
+    getMenu
+  } from "@/api/system/menu";
+  import {
+    addDataScope,
+    removeDataScope,
+    updateDataScope,
+    getListDataScope,
+    getMenuDataScope
+  } from "@/api/system/scope";
+  import {mapGetters} from "vuex";
+  import iconList from "@/config/iconList";
+
+  export default {
+    data() {
+      return {
+        form: {},
+        selectionList: [],
+        query: {},
+        page: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        drawerVisible: false,
+        scopeMenuId: 0,
+        scopeMenuName: "菜单",
+        menu: true,
+        option: {
+          tip: false,
+          dialogWidth: "60%",
+          tree: true,
+          border: true,
+          index: true,
+          selection: true,
+          viewBtn: false,
+          editBtn: false,
+          addBtn: false,
+          delBtn: false,
+          menuWidth: 250,
+          column: [
+            {
+              label: "菜单名称",
+              prop: "name",
+              search: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单名称",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "路由地址",
+              prop: "path",
+              rules: [
+                {
+                  required: true,
+                  message: "请输入路由地址",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "上级菜单",
+              prop: "parentId",
+              type: "tree",
+              dicUrl: "/api/blade-system/menu/tree",
+              hide: true,
+              props: {
+                label: "title"
+              },
+              rules: [
+                {
+                  required: false,
+                  message: "请选择上级菜单",
+                  trigger: "click"
+                }
+              ]
+            },
+            {
+              label: "菜单图标",
+              prop: "source",
+              type: "icon-select",
+              slot: true,
+              width: 80,
+              iconList: iconList,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单图标",
+                  trigger: "click"
+                }
+              ]
+            },
+            {
+              label: "菜单编号",
+              prop: "code",
+              search: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单编号",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "菜单类型",
+              prop: "category",
+              type: "radio",
+              dicData: [
+                {
+                  label: "菜单",
+                  value: 1
+                },
+                {
+                  label: "按钮",
+                  value: 2
+                }
+              ],
+              hide: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请选择菜单类型",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "菜单别名",
+              prop: "alias",
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单别名",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "按钮功能",
+              prop: "action",
+              type: "radio",
+              dicData: [
+                {
+                  label: "工具栏",
+                  value: 0
+                },
+                {
+                  label: "操作栏",
+                  value: 1
+                },
+                {
+                  label: "工具操作栏",
+                  value: 2
+                }
+              ],
+              hide: true,
+              rules: [
+                {
+                  required: true,
+                  message: "请选择按钮功能",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "菜单排序",
+              prop: "sort",
+              type: "number",
+              width: 80,
+              rules: [
+                {
+                  required: true,
+                  message: "请输入菜单排序",
+                  trigger: "blur"
+                }
+              ]
+            },
+            {
+              label: "新窗口",
+              prop: "isOpen",
+              type: "radio",
+              dicData: [
+                {
+                  label: "否",
+                  value: 0
+                },
+                {
+                  label: "是",
+                  value: 1
+                },
+              ],
+              hide: true
+            },
+            {
+              label: "菜单备注",
+              prop: "remark",
+              type: "textarea",
+              span: 24,
+              minRows: 6,
+              hide: true
+            }
+          ]
+        },
+        data: [],
+        formScope: {},
+        selectionListScope: [],
+        pageScope: {
+          pageSize: 10,
+          currentPage: 1,
+          total: 0
+        },
+        optionScope: {
+          tip: false,
+          border: true,
+          index: true,
+          viewBtn: true,
+          selection: true,
+          menuWidth: 175,
+          dialogWidth: 450,
+          dialogHeight: 510,
+          column: [
+            {
+              label: "权限名称",
+              prop: "scopeName",
+              search: true,
+              rules: [{
+                required: true,
+                message: "请输入数据权限名称",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "权限编号",
+              prop: "resourceCode",
+              search: true,
+              width: 100,
+              rules: [{
+                required: true,
+                message: "请输入数据权限编号",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "权限字段",
+              prop: "scopeColumn",
+              width: 130,
+              rules: [{
+                required: true,
+                message: "请输入数据权限编号",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "规则类型",
+              type: "select",
+              dicUrl: "/api/blade-system/dict/dictionary?code=data_scope_type",
+              props: {
+                label: "dictValue",
+                value: "dictKey"
+              },
+              slot: true,
+              width: 140,
+              prop: "scopeType",
+              rules: [{
+                required: true,
+                message: "请输入通知类型",
+                trigger: "blur"
+              }]
+            },
+            {
+              label: "可见字段",
+              prop: "scopeField",
+              span: 24,
+              hide: true,
+              rules: [{
+                required: true,
+                message: "请输入数据权限可见的字段",
+                trigger: "blur"
+              }],
+            },
+            {
+              label: "权限类名",
+              prop: "scopeClass",
+              span: 24,
+              hide: true,
+              rules: [{
+                required: true,
+                message: "请输入MybatisMapper对应方法的完整类名路径",
+                trigger: "blur"
+              }],
+            },
+            {
+              label: "规则值",
+              prop: "scopeValue",
+              span: 24,
+              minRows: 5,
+              type: "textarea",
+              hide: true,
+            },
+            {
+              label: "备注",
+              prop: "remark",
+              span: 24,
+              hide: true,
+            },
+          ]
+        },
+        dataScope: []
+      };
+    },
+
+    computed: {
+      ...mapGetters(["permission"]),
+      permissionList() {
+        return {
+          addBtn: this.vaildData(this.permission.menu_add, false),
+          viewBtn: this.vaildData(this.permission.menu_view, false),
+          delBtn: this.vaildData(this.permission.menu_delete, false),
+          editBtn: this.vaildData(this.permission.menu_edit, false)
+        };
+      },
+      ids() {
+        let ids = [];
+        this.selectionList.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      },
+      scopeIds() {
+        let ids = [];
+        this.selectionListScope.forEach(ele => {
+          ids.push(ele.id);
+        });
+        return ids.join(",");
+      }
+    },
+    methods: {
+      // 菜单管理模块
+      rowSave(row, loading, done) {
+        add(row).then(() => {
+          loading();
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowUpdate(row, index, loading, done) {
+        update(row).then(() => {
+          loading();
+          this.onLoad(this.page);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowDel(row) {
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return remove(row.id);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      searchReset() {
+        this.query = {};
+        this.onLoad(this.page);
+      },
+      searchChange(params) {
+        this.query = params;
+        this.onLoad(this.page, params);
+      },
+      selectionChange(list) {
+        this.selectionList = list;
+      },
+      handleDelete() {
+        if (this.selectionList.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return remove(this.ids);
+          })
+          .then(() => {
+            this.onLoad(this.page);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crud.toggleSelection();
+          });
+      },
+      beforeOpen(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getMenu(this.form.id).then(res => {
+            this.form = res.data.data;
+          });
+        }
+        done();
+      },
+      currentChange(currentPage) {
+        this.page.currentPage = currentPage;
+      },
+      sizeChange(pageSize) {
+        this.page.pageSize = pageSize;
+      },
+      onLoad(page, params = {}) {
+        getMenuList(page.currentPage, page.pageSize, params).then(res => {
+          this.data = res.data.data;
+        });
+      },
+      // 数据权限模块
+      handleDataScope(row) {
+        this.drawerVisible = true;
+        this.scopeMenuId = row.id;
+        this.scopeMenuName = row.name;
+      },
+      handleDrawerClose(hide) {
+        hide();
+      },
+      rowSaveScope(row, loading, done) {
+        row = {
+          ...row,
+          menuId: this.scopeMenuId,
+        }
+        addDataScope(row).then(() => {
+          loading();
+          this.onLoadScope(this.pageScope);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowUpdateScope(row, index, loading, done) {
+        row = {
+          ...row,
+          menuId: this.scopeMenuId,
+        }
+        updateDataScope(row).then(() => {
+          loading();
+          this.onLoadScope(this.pageScope);
+          this.$message({
+            type: "success",
+            message: "操作成功!"
+          });
+        }, error => {
+          done();
+          console.log(error);
+        });
+      },
+      rowDelScope(row) {
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return removeDataScope(row.id);
+          })
+          .then(() => {
+            this.onLoadScope(this.pageScope);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+          });
+      },
+      handleDeleteScope() {
+        if (this.selectionListScope.length === 0) {
+          this.$message.warning("请选择至少一条数据");
+          return;
+        }
+        this.$confirm("确定将选择数据删除?", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        })
+          .then(() => {
+            return removeDataScope(this.scopeIds);
+          })
+          .then(() => {
+            this.onLoadScope(this.pageScope);
+            this.$message({
+              type: "success",
+              message: "操作成功!"
+            });
+            this.$refs.crudScope.toggleSelection();
+          });
+      },
+      beforeOpenScope(done, type) {
+        if (["edit", "view"].includes(type)) {
+          getMenuDataScope(this.formScope.id).then(res => {
+            this.formScope = res.data.data;
+          });
+        }
+        done();
+      },
+      searchResetScope() {
+        this.onLoadScope(this.pageScope);
+      },
+      searchChangeScope(params) {
+        this.onLoadScope(this.pageScope, params);
+      },
+      selectionChangeScope(list) {
+        this.selectionListScope = list;
+      },
+      currentChangeScope(currentPage) {
+        this.pageScope.currentPage = currentPage;
+      },
+      sizeChangeScope(pageSize) {
+        this.pageScope.pageSize = pageSize;
+      },
+      onLoadScope(page, params = {}) {
+        const values = {
+          ...params,
+          menuId: this.scopeMenuId,
+        }
+        getListDataScope(page.currentPage, page.pageSize, Object.assign(values, this.query)).then(res => {
+          const data = res.data.data;
+          this.pageScope.total = data.total;
+          this.dataScope = data.records;
+        });
+      },
+    }
+  };
+</script>
+
+<style>
+  .none-border {
+    border: 0;
+    background-color: transparent !important;
+  }
+</style>

+ 9 - 298
src/views/system/menu.vue

@@ -24,69 +24,18 @@
                    @click="handleDelete">删 除
         </el-button>
       </template>
-      <template slot-scope="{row}" slot="menu">
-        <el-button type="text"
-                   icon="el-icon-setting"
-                   size="small"
-                   v-if="permission.menu_data_scope"
-                   plain
-                   class="none-border"
-                   @click.stop="handleDataScope(row)">数据权限
-        </el-button>
-      </template>
-      <template slot-scope="{row}" slot="source">
+      <template slot-scope="{row}"
+                slot="source">
         <div style="text-align:center">
           <i :class="row.source"></i>
         </div>
       </template>
     </avue-crud>
-    <avue-drawer :title="`[${scopeMenuName}] 数据权限配置`" show-close :width="1000" v-model="drawerVisible"
-                 :before-close="handleDrawerClose">
-      <avue-crud :option="optionScope"
-                 :data="dataScope"
-                 :page="pageScope"
-                 v-model="formScope"
-                 ref="crudScope"
-                 @row-del="rowDelScope"
-                 @row-update="rowUpdateScope"
-                 @row-save="rowSaveScope"
-                 :before-open="beforeOpenScope"
-                 @search-change="searchChangeScope"
-                 @search-reset="searchResetScope"
-                 @selection-change="selectionChangeScope"
-                 @current-change="currentChangeScope"
-                 @size-change="sizeChangeScope"
-                 @on-load="onLoadScope">
-        <template slot="menuLeft">
-          <el-button type="danger"
-                     size="small"
-                     icon="el-icon-delete"
-                     plain
-                     @click="handleDeleteScope">删 除
-          </el-button>
-        </template>
-        <template slot-scope="{row}"
-                  slot="scopeType">
-          <el-tag>{{row.scopeTypeName}}</el-tag>
-        </template>
-      </avue-crud>
-    </avue-drawer>
   </basic-container>
 </template>
 
 <script>
-  import {
-    add,
-    remove,
-    update,
-    getList,
-    getMenu,
-    addScope,
-    removeScope,
-    updateScope,
-    getListScope,
-    getMenuScope
-  } from "@/api/system/menu";
+  import {getList, remove, update, add, getMenu} from "@/api/system/menu";
   import {mapGetters} from "vuex";
   import iconList from "@/config/iconList";
 
@@ -94,17 +43,13 @@
     data() {
       return {
         form: {},
-        selectionList: [],
         query: {},
+        selectionList: [],
         page: {
           pageSize: 10,
           currentPage: 1,
           total: 0
         },
-        drawerVisible: false,
-        scopeMenuId: 0,
-        scopeMenuName: "菜单",
-        menu: true,
         option: {
           tip: false,
           dialogWidth: "60%",
@@ -113,7 +58,6 @@
           index: true,
           selection: true,
           viewBtn: true,
-          menuWidth: 250,
           column: [
             {
               label: "菜单名称",
@@ -160,7 +104,6 @@
               prop: "source",
               type: "icon-select",
               slot: true,
-              width: 80,
               iconList: iconList,
               rules: [
                 {
@@ -247,7 +190,6 @@
               label: "菜单排序",
               prop: "sort",
               type: "number",
-              width: 80,
               rules: [
                 {
                   required: true,
@@ -282,110 +224,7 @@
             }
           ]
         },
-        data: [],
-        formScope: {},
-        selectionListScope: [],
-        pageScope: {
-          pageSize: 10,
-          currentPage: 1,
-          total: 0
-        },
-        optionScope: {
-          tip: false,
-          border: true,
-          index: true,
-          viewBtn: true,
-          selection: true,
-          menuWidth: 175,
-          dialogHeight: 510,
-          column: [
-            {
-              label: "权限名称",
-              prop: "scopeName",
-              search: true,
-              rules: [{
-                required: true,
-                message: "请输入数据权限名称",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "权限编号",
-              prop: "resourceCode",
-              search: true,
-              width: 100,
-              rules: [{
-                required: true,
-                message: "请输入数据权限编号",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "权限字段",
-              prop: "scopeColumn",
-              width: 130,
-              rules: [{
-                required: true,
-                message: "请输入数据权限编号",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "规则类型",
-              type: "select",
-              dicUrl: "/api/blade-system/dict/dictionary?code=scope_type",
-              props: {
-                label: "dictValue",
-                value: "dictKey"
-              },
-              slot: true,
-              width: 140,
-              prop: "scopeType",
-              rules: [{
-                required: true,
-                message: "请输入通知类型",
-                trigger: "blur"
-              }]
-            },
-            {
-              label: "可见字段",
-              prop: "scopeField",
-              span: 24,
-              hide: true,
-              rules: [{
-                required: true,
-                message: "请输入数据权限可见的字段",
-                trigger: "blur"
-              }],
-            },
-            {
-              label: "权限类名",
-              prop: "scopeClass",
-              span: 24,
-              hide: true,
-              rules: [{
-                required: true,
-                message: "请输入MybatisMapper对应方法的完整类名路径",
-                trigger: "blur"
-              }],
-            },
-            {
-              label: "规则值",
-              prop: "scopeValue",
-              span: 24,
-              minRows: 5,
-              type: "textarea",
-              hide: true,
-            },
-            {
-              label: "备注",
-              prop: "remark",
-              span: 24,
-              hide: true,
-            },
-          ]
-        },
-        dataScope: []
+        data: []
       };
     },
 
@@ -405,17 +244,9 @@
           ids.push(ele.id);
         });
         return ids.join(",");
-      },
-      scopeIds() {
-        let ids = [];
-        this.selectionListScope.forEach(ele => {
-          ids.push(ele.id);
-        });
-        return ids.join(",");
       }
     },
     methods: {
-      // 菜单管理模块
       rowSave(row, loading, done) {
         add(row).then(() => {
           loading();
@@ -500,140 +331,20 @@
         }
         done();
       },
-      currentChange(currentPage) {
+      currentChange(currentPage){
         this.page.currentPage = currentPage;
       },
-      sizeChange(pageSize) {
+      sizeChange(pageSize){
         this.page.pageSize = pageSize;
       },
       onLoad(page, params = {}) {
-        getList(page.currentPage, page.pageSize, params).then(res => {
+        getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
           this.data = res.data.data;
         });
-      },
-      // 数据权限模块
-      handleDataScope(row) {
-        this.drawerVisible = true;
-        this.scopeMenuId = row.id;
-        this.scopeMenuName = row.name;
-      },
-      handleDrawerClose(hide) {
-        hide();
-      },
-      rowSaveScope(row, loading, done) {
-        row = {
-          ...row,
-          menuId: this.scopeMenuId,
-        }
-        addScope(row).then(() => {
-          loading();
-          this.onLoadScope(this.pageScope);
-          this.$message({
-            type: "success",
-            message: "操作成功!"
-          });
-        }, error => {
-          done();
-          console.log(error);
-        });
-      },
-      rowUpdateScope(row, index, loading, done) {
-        row = {
-          ...row,
-          menuId: this.scopeMenuId,
-        }
-        updateScope(row).then(() => {
-          loading();
-          this.onLoadScope(this.pageScope);
-          this.$message({
-            type: "success",
-            message: "操作成功!"
-          });
-        }, error => {
-          done();
-          console.log(error);
-        });
-      },
-      rowDelScope(row) {
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return removeScope(row.id);
-          })
-          .then(() => {
-            this.onLoadScope(this.pageScope);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-          });
-      },
-      handleDeleteScope() {
-        if (this.selectionListScope.length === 0) {
-          this.$message.warning("请选择至少一条数据");
-          return;
-        }
-        this.$confirm("确定将选择数据删除?", {
-          confirmButtonText: "确定",
-          cancelButtonText: "取消",
-          type: "warning"
-        })
-          .then(() => {
-            return removeScope(this.scopeIds);
-          })
-          .then(() => {
-            this.onLoadScope(this.pageScope);
-            this.$message({
-              type: "success",
-              message: "操作成功!"
-            });
-            this.$refs.crudScope.toggleSelection();
-          });
-      },
-      beforeOpenScope(done, type) {
-        if (["edit", "view"].includes(type)) {
-          getMenuScope(this.formScope.id).then(res => {
-            this.formScope = res.data.data;
-          });
-        }
-        done();
-      },
-      searchResetScope() {
-        this.onLoadScope(this.pageScope);
-      },
-      searchChangeScope(params) {
-        this.onLoadScope(this.pageScope, params);
-      },
-      selectionChangeScope(list) {
-        this.selectionListScope = list;
-      },
-      currentChangeScope(currentPage) {
-        this.pageScope.currentPage = currentPage;
-      },
-      sizeChangeScope(pageSize) {
-        this.pageScope.pageSize = pageSize;
-      },
-      onLoadScope(page, params = {}) {
-        const values = {
-          ...params,
-          menuId: this.scopeMenuId,
-        }
-        getListScope(page.currentPage, page.pageSize, Object.assign(values, this.query)).then(res => {
-          const data = res.data.data;
-          this.pageScope.total = data.total;
-          this.dataScope = data.records;
-        });
-      },
+      }
     }
   };
 </script>
 
 <style>
-  .none-border {
-    border: 0;
-    background-color: transparent !important;
-  }
 </style>

+ 24 - 11
src/views/system/role.vue

@@ -43,15 +43,23 @@
           </el-tree>
         </el-tab-pane>
         <el-tab-pane label="数据权限">
-          <el-tree :data="scopeGrantList"
+          <el-tree :data="dataScopeGrantList"
                    show-checkbox
                    node-key="id"
-                   ref="treeScope"
-                   :default-checked-keys="scopeTreeObj"
+                   ref="treeDataScope"
+                   :default-checked-keys="dataScopeTreeObj"
+                   :props="props">
+          </el-tree>
+        </el-tab-pane>
+        <el-tab-pane label="接口权限">
+          <el-tree :data="apiScopeGrantList"
+                   show-checkbox
+                   node-key="id"
+                   ref="treeApiScope"
+                   :default-checked-keys="apiScopeTreeObj"
                    :props="props">
           </el-tree>
         </el-tab-pane>
-        <el-tab-pane label="接口权限">敬请期待</el-tab-pane>
       </el-tabs>
 
       <span slot="footer"
@@ -79,10 +87,12 @@
           value: "key"
         },
         menuGrantList: [],
-        scopeGrantList: [],
+        dataScopeGrantList: [],
+        apiScopeGrantList: [],
         apiGrantList: [],
         menuTreeObj: [],
-        scopeTreeObj: [],
+        dataScopeTreeObj: [],
+        apiScopeTreeObj: [],
         selectionList: [],
         query: {},
         page: {
@@ -204,8 +214,9 @@
     methods: {
       submit() {
         const menuList = this.$refs.treeMenu.getCheckedKeys().join(",");
-        const scopeList = this.$refs.treeScope.getCheckedKeys().join(",");
-        grant(this.ids, menuList, scopeList).then(() => {
+        const dataScopeList = this.$refs.treeDataScope.getCheckedKeys().join(",");
+        const apiScopeList = this.$refs.treeApiScope.getCheckedKeys().join(",");
+        grant(this.ids, menuList, dataScopeList, apiScopeList).then(() => {
           this.box = false;
           this.$message({
             type: "success",
@@ -275,14 +286,16 @@
           return;
         }
         this.menuTreeObj = [];
-        this.scopeTreeObj = [];
+        this.dataScopeTreeObj = [];
         grantTree()
           .then(res => {
             this.menuGrantList = res.data.data.menu;
-            this.scopeGrantList = res.data.data.scope;
+            this.dataScopeGrantList = res.data.data.dataScope;
+            this.apiScopeGrantList = res.data.data.apiScope;
             getRole(this.ids).then(res => {
               this.menuTreeObj = res.data.data.menu;
-              this.scopeTreeObj = res.data.data.scope;
+              this.dataScopeTreeObj = res.data.data.dataScope;
+              this.apiScopeTreeObj = res.data.data.apiScope;
               this.box = true;
             });
           });