Browse Source

Merge branch 'feature/权限管理' into develop

ZZH-wl 3 years ago
parent
commit
79902962fc
35 changed files with 1634 additions and 460 deletions
  1. 0 0
      src/api/system/dept.js
  2. 7 0
      src/api/system/dict.js
  3. 18 0
      src/api/system/group.js
  4. 0 0
      src/api/system/menu.js
  5. 18 0
      src/api/system/post.js
  6. 19 0
      src/api/system/role.js
  7. 0 0
      src/api/system/router.js
  8. 0 0
      src/api/system/systemLog.js
  9. 1 1
      src/api/system/user.js
  10. 0 9
      src/api/test.js
  11. 154 0
      src/components/table/TableTool.vue
  12. 2 0
      src/main.js
  13. 1 1
      src/store/modules/routes.js
  14. 1 1
      src/store/modules/user.js
  15. 1 1
      src/vab/components/VabQueryForm/index.vue
  16. 1 1
      src/views/system/dept/components/DeptEdit.vue
  17. 98 28
      src/views/system/dept/index.vue
  18. 1 1
      src/views/system/dict/components/DataEdit.vue
  19. 1 1
      src/views/system/dict/components/TypeEdit.vue
  20. 2 2
      src/views/system/dict/dataList.vue
  21. 2 2
      src/views/system/dict/index.vue
  22. 94 0
      src/views/system/group/components/GroupEdit.vue
  23. 202 0
      src/views/system/group/index.vue
  24. 1 1
      src/views/system/menu/components/MenuEdit.vue
  25. 1 1
      src/views/system/menu/index.vue
  26. 94 0
      src/views/system/post/components/PostEdit.vue
  27. 202 0
      src/views/system/post/index.vue
  28. 223 0
      src/views/system/role/components/RoleDataScopeEdit.vue
  29. 86 34
      src/views/system/role/components/RoleEdit.vue
  30. 12 9
      src/views/system/role/index.vue
  31. 1 1
      src/views/system/systemLog/index.vue
  32. 223 29
      src/views/system/user/components/UserEdit.vue
  33. 168 109
      src/views/system/user/index.vue
  34. 0 82
      src/views/test/components/Edit.vue
  35. 0 146
      src/views/test/index.vue

+ 0 - 0
src/api/dept.js → src/api/system/dept.js


+ 7 - 0
src/api/dict.js → src/api/system/dict.js

@@ -2,6 +2,13 @@ import micro_request from '@/utils/micro_request'
 
 const basePath = process.env.VUE_APP_AdminPath
 export default {
+  // 获取字典信息
+  getDictDataByType(dictType) {
+    return micro_request.postRequest(basePath, 'Dict', 'GetDictDataByType', {
+      dictType: dictType,
+    })
+  },
+
   // 字典类型
   getDictTypeList(query) {
     return micro_request.postRequest(basePath, 'Dict', 'GetDictTypeList', query)

+ 18 - 0
src/api/system/group.js

@@ -0,0 +1,18 @@
+import micro_request from '@/utils/micro_request'
+
+const basePath = process.env.VUE_APP_AdminPath
+export default {
+  // 获取列表
+  getList(query) {
+    return micro_request.postRequest(basePath, 'Group', 'GetList', query)
+  },
+  doAdd(query) {
+    return micro_request.postRequest(basePath, 'Group', 'Create', query)
+  },
+  doEdit(query) {
+    return micro_request.postRequest(basePath, 'Group', 'UpdateById', query)
+  },
+  doDelete(query) {
+    return micro_request.postRequest(basePath, 'Group', 'DeleteByIds', query)
+  },
+}

+ 0 - 0
src/api/menu.js → src/api/system/menu.js


+ 18 - 0
src/api/system/post.js

@@ -0,0 +1,18 @@
+import micro_request from '@/utils/micro_request'
+
+const basePath = process.env.VUE_APP_AdminPath
+export default {
+  // 获取列表
+  getList(query) {
+    return micro_request.postRequest(basePath, 'Post', 'GetList', query)
+  },
+  doAdd(query) {
+    return micro_request.postRequest(basePath, 'Post', 'Create', query)
+  },
+  doEdit(query) {
+    return micro_request.postRequest(basePath, 'Post', 'UpdateById', query)
+  },
+  doDelete(query) {
+    return micro_request.postRequest(basePath, 'Post', 'DeleteByIds', query)
+  },
+}

+ 19 - 0
src/api/role.js → src/api/system/role.js

@@ -6,12 +6,31 @@ export default {
   getList(query) {
     return micro_request.postRequest(basePath, 'Role', 'GetList', query)
   },
+  getEntityById(query) {
+    return micro_request.postRequest(basePath, 'Role', 'GetEntityById', query)
+  },
+  getRoleDeptTreeselect(query) {
+    return micro_request.postRequest(
+      basePath,
+      'Role',
+      'GetRoleDeptTreeselect',
+      query
+    )
+  },
   doAdd(query) {
     return micro_request.postRequest(basePath, 'Role', 'Create', query)
   },
   doEdit(query) {
     return micro_request.postRequest(basePath, 'Role', 'UpdateById', query)
   },
+  updateRoleDataScope(query) {
+    return micro_request.postRequest(
+      basePath,
+      'Role',
+      'UpdateRoleDataScope',
+      query
+    )
+  },
   doDelete(query) {
     return micro_request.postRequest(basePath, 'Role', 'DeleteByIds', query)
   },

+ 0 - 0
src/api/router.js → src/api/system/router.js


+ 0 - 0
src/api/systemLog.js → src/api/system/systemLog.js


+ 1 - 1
src/api/user.js → src/api/system/user.js

@@ -16,7 +16,7 @@ export default {
     return micro_request.postRequest(basePath, 'User', 'GetList', query)
   },
   doAdd(query) {
-    return micro_request.postRequest(basePath, 'User', 'Add', query)
+    return micro_request.postRequest(basePath, 'User', 'Create', query)
   },
   doEdit(query) {
     return micro_request.postRequest(basePath, 'User', 'UpdateById', query)

+ 0 - 9
src/api/test.js

@@ -1,9 +0,0 @@
-import request from '@/utils/request'
-
-export async function getList(data) {
-  return request({
-    url: '/test/getList',
-    method: 'get',
-    data,
-  })
-}

+ 154 - 0
src/components/table/TableTool.vue

@@ -0,0 +1,154 @@
+<template>
+  <div>
+    <!--    <div v-show="stripe" class="stripe-panel">-->
+    <!--      <el-checkbox v-model="stripe">斑马纹</el-checkbox>-->
+    <!--    </div>-->
+    <!--    <div class="border-panel">-->
+    <!--      <el-checkbox v-model="border">边框(可拉伸列)</el-checkbox>-->
+    <!--    </div>-->
+    <!--    <el-button-->
+    <!--      style="margin: 0 10px 10px 0 !important"-->
+    <!--      type="primary"-->
+    <!--      @click="clickFullScreen">-->
+    <!--      <vab-icon-->
+    <!--        :icon="isFullscreen ? 'fullscreen-exit-fill' : 'fullscreen-fill'" />-->
+    <!--      表格全屏-->
+    <!--    </el-button>-->
+    <!--    <el-popover-->
+    <!--      ref="popover"-->
+    <!--      popper-class="custom-table-checkbox"-->
+    <!--      trigger="hover">-->
+    <!--      <el-radio-group v-model="lineHeight">-->
+    <!--        <el-radio label="medium">大</el-radio>-->
+    <!--        <el-radio label="small">中</el-radio>-->
+    <!--        <el-radio label="mini">小</el-radio>-->
+    <!--      </el-radio-group>-->
+    <!--      <template #reference>-->
+    <!--        <el-button style="margin: 0 10px 10px 0 !important" type="primary">-->
+    <!--          <vab-icon icon="line-height" />-->
+    <!--          表格尺寸-->
+    <!--        </el-button>-->
+    <!--      </template>-->
+    <!--    </el-popover>-->
+    <el-popover popper-class="custom-table-checkbox" trigger="hover">
+      <el-checkbox-group v-model="checkColumns">
+        <vab-draggable v-bind="dragOptions" :list="columns">
+          <div v-for="(item, index) in columns" :key="item + index">
+            <vab-icon icon="drag-drop-line" />
+            <el-checkbox
+              :disabled="item.disableCheck === true"
+              :label="item.label">
+              {{ item.label }}
+            </el-checkbox>
+          </div>
+        </vab-draggable>
+      </el-checkbox-group>
+      <template #reference>
+        <el-button
+          icon="el-icon-setting"
+          style="
+            margin: 0 10px 10px 0 !important;
+            font-size: 18px;
+            color: black;
+          "
+          type="text" />
+      </template>
+    </el-popover>
+  </div>
+</template>
+
+<script>
+  import VabDraggable from 'vuedraggable'
+
+  export default {
+    name: 'TableTool',
+    components: {
+      VabDraggable,
+    },
+    props: {
+      columns: {
+        type: Array,
+        default() {
+          return []
+        },
+      },
+      checkList: {
+        type: Array,
+        default() {
+          return []
+        },
+      },
+    },
+    data() {
+      return {
+        isFullscreen: false,
+        border: true,
+        height: this.$baseTableHeight(1),
+        stripe: false,
+        lineHeight: 'medium',
+        // checkList: ['标题', '作者', '评级', '点击量', '时间'],
+        // columns: [
+        //   {
+        //     label: '标题',
+        //     width: 'auto',
+        //     prop: 'title',
+        //     sortable: true,
+        //     disableCheck: true,
+        //   },
+        // ],
+        flag: true,
+      }
+    },
+    computed: {
+      dragOptions() {
+        return {
+          animation: 600,
+          group: 'description',
+        }
+      },
+      checkColumns: {
+        get() {
+          return this.checkList
+        },
+        set(val) {
+          this.$emit('update:checkList', val)
+        },
+      },
+    },
+    created() {
+      let list = []
+      for (let item of this.columns) {
+        list.push(item['label'])
+      }
+      this.$emit('update:checkList', list)
+    },
+    methods: {},
+  }
+</script>
+
+<style lang="scss" scoped>
+  .custom-table-container {
+    :deep() {
+      i {
+        cursor: pointer;
+      }
+    }
+
+    .stripe-panel,
+    .border-panel {
+      margin: 0 10px #{$base-margin/2} 10px !important;
+    }
+  }
+</style>
+<style lang="scss">
+  .custom-table-checkbox {
+    [class*='ri'] {
+      vertical-align: -2.5px;
+      cursor: pointer;
+    }
+
+    .el-checkbox {
+      margin: 5px 0 5px 8px;
+    }
+  }
+</style>

+ 2 - 0
src/main.js

@@ -6,9 +6,11 @@ import router from './router'
 import '@/vab'
 
 import { parseTime, translateDataToTree } from '@/utils'
+import dictApi from '@/api/system/dict'
 
 Vue.prototype.parseTime = parseTime
 Vue.prototype.translateDataToTree = translateDataToTree
+Vue.prototype.getDicts = dictApi.getDictDataByType
 
 Vue.config.productionTip = false
 new Vue({

+ 1 - 1
src/store/modules/routes.js

@@ -3,7 +3,7 @@
  */
 import Vue from 'vue'
 import { asyncRoutes, constantRoutes, resetRouter } from '@/router'
-import menuApi from '@/api/menu'
+import menuApi from '@/api/system/menu'
 import { convertRouter, filterRoutes } from '@/utils/routes'
 import { authentication, rolesControl } from '@/config'
 import { isArray } from '@/utils/validate'

+ 1 - 1
src/store/modules/user.js

@@ -2,7 +2,7 @@
  * @description 登录、获取用户信息、退出登录、清除token逻辑,不建议修改
  */
 import Vue from 'vue'
-import userApi from '@/api/user'
+import userApi from '@/api/system/user'
 import { getToken, removeToken, setToken } from '@/utils/token'
 import { resetRouter } from '@/router'
 import { isArray, isString } from '@/utils/validate'

+ 1 - 1
src/vab/components/VabQueryForm/index.vue

@@ -18,7 +18,7 @@
     align-items: center;
     justify-content: flex-start;
     min-height: $base-input-height;
-    margin: 0 0 $base-margin/2 0;
+    margin: 0 0 0 0;
     > .el-button {
       margin: 0 10px $base-margin/2 0 !important;
     }

+ 1 - 1
src/views/system/dept/components/DeptEdit.vue

@@ -72,7 +72,7 @@
 </template>
 
 <script>
-  import deptApi from '@/api/dept'
+  import deptApi from '@/api/system/dept'
   import Treeselect from '@riophae/vue-treeselect'
   import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 

+ 98 - 28
src/views/system/dept/index.vue

@@ -1,6 +1,29 @@
 <template>
   <div class="department-management-container">
     <vab-query-form>
+      <vab-query-form-top-panel>
+        <el-form :inline="true" :model="queryForm" @submit.native.prevent>
+          <el-form-item>
+            <el-input
+              v-model.trim="queryForm.deptName"
+              clearable
+              placeholder="请输入名称" />
+          </el-form-item>
+          <el-form-item>
+            <el-button icon="el-icon-search" type="primary" @click="queryData">
+              查询
+            </el-button>
+            <el-button type="text" @click="handleFold">
+              <span v-if="fold">展开</span>
+              <span v-else>合并</span>
+              <vab-icon
+                class="vab-dropdown"
+                :class="{ 'vab-dropdown-active': fold }"
+                icon="arrow-up-s-line" />
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </vab-query-form-top-panel>
       <vab-query-form-left-panel :span="12">
         <el-button
           icon="el-icon-plus"
@@ -12,29 +35,16 @@
           icon="el-icon-delete"
           type="danger"
           @click="handleDelete($event)">
-          批量删除
+          删除
         </el-button>
       </vab-query-form-left-panel>
       <vab-query-form-right-panel :span="12">
-        <el-form :inline="true" :model="queryForm" @submit.native.prevent>
-          <el-form-item>
-            <el-input
-              v-model.trim="queryForm.deptName"
-              clearable
-              placeholder="请输入名称" />
-          </el-form-item>
-          <el-form-item>
-            <el-button icon="el-icon-search" type="primary" @click="queryData">
-              查询
-            </el-button>
-          </el-form-item>
-        </el-form>
+        <table-tool :check-list.sync="checkList" :columns="columns" />
       </vab-query-form-right-panel>
     </vab-query-form>
 
     <el-table
       v-loading="listLoading"
-      border
       :data="list"
       default-expand-all
       :height="$baseTableHeight(1)"
@@ -42,20 +52,23 @@
       :tree-props="{ children: 'children' }"
       @selection-change="setSelectRows">
       <el-table-column show-overflow-tooltip type="selection" />
-      <el-table-column label="部门名称" prop="deptName" show-overflow-tooltip />
       <el-table-column
+        v-for="(item, index) in finallyColumns"
+        :key="index"
         align="center"
-        label="显示排序"
-        prop="sort"
-        show-overflow-tooltip />
-      <el-table-column align="center" label="状态" prop="status">
+        :label="item.label"
+        :prop="item.prop"
+        show-overflow-tooltip
+        :sortable="item.sortable"
+        :width="item.width">
         <template #default="{ row }">
-          {{ row.status === '10' ? '正常' : '停用' }}
-        </template>
-      </el-table-column>
-      <el-table-column align="center" label="创建时间" prop="createdTime">
-        <template #default="scope">
-          <span>{{ parseTime(scope.row.createdTime) }}</span>
+          <span v-if="item.label === '状态'">
+            {{ row.status === '10' ? '正常' : '停用' }}
+          </span>
+          <span v-else-if="item.label === '创建时间'">
+            {{ parseTime(row[item.prop]) }}
+          </span>
+          <span v-else>{{ row[item.prop] }}</span>
         </template>
       </el-table-column>
       <el-table-column label="操作" width="85">
@@ -75,17 +88,27 @@
           :src="require('@/assets/empty_images/data_empty.png')" />
       </template>
     </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNo"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
     <edit ref="edit" @fetch-data="fetchData" />
   </div>
 </template>
 
 <script>
-  import deptApi from '@/api/dept'
+  import deptApi from '@/api/system/dept'
   import Edit from './components/DeptEdit'
+  import VabQueryFormTopPanel from '@/vab/components/VabQueryForm/components/VabQueryFormTopPanel'
+  import TableTool from '@/components/table/TableTool'
 
   export default {
     name: 'Dept',
-    components: { Edit },
+    components: { VabQueryFormTopPanel, Edit, TableTool },
     data() {
       return {
         list: [],
@@ -93,17 +116,64 @@
         layout: 'total, sizes, prev, pager, next, jumper',
         total: 0,
         selectRows: '',
+        fold: false,
+        height: this.$baseTableHeight(3) - 30,
         queryForm: {
           pageNum: 1,
           pageSize: 10,
           title: '',
         },
+        checkList: [],
+        columns: [
+          {
+            label: '部门名称',
+            width: 'auto',
+            prop: 'deptName',
+            sortable: true,
+            disableCheck: true,
+          },
+          {
+            label: '显示排序',
+            width: 'auto',
+            prop: 'sort',
+            sortable: true,
+          },
+          {
+            label: '状态',
+            width: 'auto',
+            prop: 'status',
+            sortable: true,
+          },
+          {
+            label: '创建时间',
+            width: 'auto',
+            prop: 'createdTime',
+            sortable: true,
+          },
+        ],
       }
     },
+    computed: {
+      finallyColumns() {
+        return this.columns.filter((item) =>
+          this.checkList.includes(item.label)
+        )
+      },
+    },
     created() {
       this.fetchData()
     },
     methods: {
+      handleFold() {
+        this.fold = !this.fold
+        this.handleHeight()
+      },
+      handleHeight() {
+        if (this.fold) this.height = this.$baseTableHeight(2) - 47
+        else this.height = this.$baseTableHeight(3) - 30
+
+        console.log(this.height)
+      },
       setSelectRows(val) {
         this.selectRows = val
       },

+ 1 - 1
src/views/system/dict/components/DataEdit.vue

@@ -60,7 +60,7 @@
 </template>
 
 <script>
-  import dictApi from '@/api/dict'
+  import dictApi from '@/api/system/dict'
 
   export default {
     name: 'DataEdit',

+ 1 - 1
src/views/system/dict/components/TypeEdit.vue

@@ -39,7 +39,7 @@
 </template>
 
 <script>
-  import dictApi from '@/api/dict'
+  import dictApi from '@/api/system/dict'
 
   export default {
     name: 'TypeEdit',

+ 2 - 2
src/views/system/dict/dataList.vue

@@ -12,7 +12,7 @@
           icon="el-icon-delete"
           type="danger"
           @click="handleDelete($event)">
-          批量删除
+          删除
         </el-button>
       </vab-query-form-left-panel>
       <vab-query-form-right-panel :span="19">
@@ -116,7 +116,7 @@
 </template>
 
 <script>
-  import dictApi from '@/api/dict'
+  import dictApi from '@/api/system/dict'
   import Edit from './components/DataEdit'
 
   export default {

+ 2 - 2
src/views/system/dict/index.vue

@@ -12,7 +12,7 @@
           icon="el-icon-delete"
           type="danger"
           @click="handleDelete($event)">
-          批量删除
+          删除
         </el-button>
       </vab-query-form-left-panel>
       <vab-query-form-right-panel :span="19">
@@ -120,7 +120,7 @@
 </template>
 
 <script>
-  import dictApi from '@/api/dict'
+  import dictApi from '@/api/system/dict'
   import Edit from './components/TypeEdit'
 
   export default {

+ 94 - 0
src/views/system/group/components/GroupEdit.vue

@@ -0,0 +1,94 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="dialogFormVisible"
+    width="500px"
+    @close="close">
+    <el-form ref="form" label-width="100px" :model="form" :rules="rules">
+      <el-form-item label="用户组名称" prop="groupName">
+        <el-input v-model="form.groupName" placeholder="请输入用户组名称" />
+      </el-form-item>
+      <el-form-item label="用户组编号" prop="groupCode">
+        <el-input v-model="form.groupCode" placeholder="请输入用户组编号" />
+      </el-form-item>
+      <el-form-item label="用户组顺序" prop="sort">
+        <el-input-number
+          v-model="form.sort"
+          controls-position="right"
+          :min="0" />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-radio-group v-model="form.status">
+          <el-radio-group v-model="form.status">
+            <el-radio label="10">正常</el-radio>
+            <el-radio label="20">停用</el-radio>
+          </el-radio-group>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input
+          v-model="form.remark"
+          placeholder="请输入内容"
+          type="textarea" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="close">取 消</el-button>
+      <el-button type="primary" @click="save">确 定</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script>
+  import groupApi from '@/api/system/group'
+
+  export default {
+    name: 'GroupEdit',
+    data() {
+      return {
+        form: { status: '10' },
+        rules: {
+          groupName: [
+            { required: true, message: '用户组名称不能为空', trigger: 'blur' },
+          ],
+          groupCode: [
+            { required: true, message: '用户组编码不能为空', trigger: 'blur' },
+          ],
+        },
+        title: '',
+        dialogFormVisible: false,
+      }
+    },
+    methods: {
+      showEdit(row) {
+        if (!row) {
+          this.title = '添加'
+        } else {
+          this.title = '编辑'
+          this.form = Object.assign({}, row)
+        }
+        this.dialogFormVisible = true
+      },
+      close() {
+        this.$refs['form'].resetFields()
+        this.form = this.$options.data().form
+        this.dialogFormVisible = false
+      },
+      save() {
+        this.$refs['form'].validate(async (valid) => {
+          if (valid) {
+            if (this.form.id) {
+              const { msg } = await groupApi.doEdit(this.form)
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            } else {
+              const { msg } = await groupApi.doAdd(this.form)
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            }
+            this.$emit('fetch-data')
+            this.close()
+          }
+        })
+      },
+    },
+  }
+</script>

+ 202 - 0
src/views/system/group/index.vue

@@ -0,0 +1,202 @@
+<template>
+  <div class="user-management-container">
+    <vab-query-form>
+      <vab-query-form-left-panel :span="5">
+        <el-button
+          icon="el-icon-plus"
+          type="primary"
+          @click="handleEdit($event)">
+          添加
+        </el-button>
+        <el-button
+          icon="el-icon-delete"
+          type="danger"
+          @click="handleDelete($event)">
+          删除
+        </el-button>
+      </vab-query-form-left-panel>
+      <vab-query-form-right-panel :span="19">
+        <el-form :inline="true" :model="queryForm" @submit.native.prevent>
+          <el-form-item label="用户组名称" prop="dictName">
+            <el-input
+              v-model.trim="queryForm.groupName"
+              clearable
+              placeholder="请输入用户组名称" />
+          </el-form-item>
+          <el-form-item label="用户组编码" prop="dictType">
+            <el-input
+              v-model.trim="queryForm.groupCode"
+              clearable
+              placeholder="请输入用户组编码" />
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-select v-model="queryForm.status" clearable placeholder="状态">
+              <el-option label="正常" value="10" />
+              <el-option label="停用" value="20" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button icon="el-icon-search" type="primary" @click="queryData">
+              查询
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </vab-query-form-right-panel>
+    </vab-query-form>
+
+    <el-table
+      v-loading="listLoading"
+      border
+      :data="list"
+      :height="height"
+      @selection-change="setSelectRows">
+      <el-table-column align="center" show-overflow-tooltip type="selection" />
+      <el-table-column
+        align="center"
+        label="用户组编号"
+        prop="id"
+        show-overflow-tooltip />
+      <el-table-column
+        align="center"
+        label="用户组名称"
+        prop="groupName"
+        show-overflow-tooltip />
+      <el-table-column
+        align="center"
+        label="用户组编码"
+        prop="groupCode"
+        show-overflow-tooltip />
+      <el-table-column align="center" label="状态" prop="status">
+        <template #default="{ row }">
+          {{ row.status === '10' ? '正常' : '停用' }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="用户组排序"
+        prop="sort"
+        show-overflow-tooltip />
+      <el-table-column
+        align="center"
+        label="备注"
+        prop="remark"
+        show-overflow-tooltip />
+      <el-table-column align="center" label="创建时间" prop="createdTime">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createdTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="操作"
+        show-overflow-tooltip
+        width="85">
+        <template #default="{ row }">
+          <el-button type="text" @click="handleEdit(row)">编辑</el-button>
+          <el-button type="text" @click="handleDelete(row)">删除</el-button>
+        </template>
+      </el-table-column>
+      <template #empty>
+        <el-image
+          class="vab-data-empty"
+          :src="require('@/assets/empty_images/data_empty.png')" />
+      </template>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNum"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <edit ref="edit" @fetch-data="fetchData" />
+  </div>
+</template>
+
+<script>
+  import groupApi from '@/api/system/group'
+  import Edit from './components/GroupEdit'
+
+  export default {
+    name: 'Group',
+    components: { Edit },
+    data() {
+      return {
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: '',
+        queryForm: {
+          pageNum: 1,
+          pageSize: 10,
+          groupName: undefined,
+          groupCode: undefined,
+          status: undefined,
+        },
+      }
+    },
+    computed: {
+      height() {
+        return this.$baseTableHeight(1)
+      },
+    },
+    created() {
+      this.fetchData()
+    },
+    methods: {
+      setSelectRows(val) {
+        this.selectRows = val
+      },
+      handleEdit(row) {
+        if (row.id) {
+          this.$refs['edit'].showEdit(row)
+        } else {
+          this.$refs['edit'].showEdit()
+        }
+      },
+      handleDelete(row) {
+        if (row.id) {
+          this.$baseConfirm('你确定要删除当前项吗', null, async () => {
+            const { msg } = await groupApi.doDelete({ ids: [row.id] })
+            this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            await this.fetchData()
+          })
+        } else {
+          if (this.selectRows.length > 0) {
+            const ids = this.selectRows.map((item) => item.id).join()
+            this.$baseConfirm('你确定要删除选中项吗', null, async () => {
+              const { msg } = await groupApi.doDelete({ ids })
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+              await this.fetchData()
+            })
+          } else {
+            this.$baseMessage('未选中任何行', 'error', 'vab-hey-message-error')
+          }
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNum = val
+        this.fetchData()
+      },
+      queryData() {
+        this.queryForm.pageNum = 1
+        this.fetchData()
+      },
+      async fetchData() {
+        this.listLoading = true
+        const {
+          data: { list, total },
+        } = await groupApi.getList(this.queryForm)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+    },
+  }
+</script>

+ 1 - 1
src/views/system/menu/components/MenuEdit.vue

@@ -270,7 +270,7 @@
 </template>
 
 <script>
-  import menuApi from '@/api/menu'
+  import menuApi from '@/api/system/menu'
   import VabIconSelector from '@/extra/VabIconSelector'
   import Treeselect from '@riophae/vue-treeselect'
   import '@riophae/vue-treeselect/dist/vue-treeselect.css'

+ 1 - 1
src/views/system/menu/index.vue

@@ -139,7 +139,7 @@
 </template>
 
 <script>
-  import menuApi from '@/api/menu'
+  import menuApi from '@/api/system/menu'
   import Edit from './components/MenuEdit'
 
   export default {

+ 94 - 0
src/views/system/post/components/PostEdit.vue

@@ -0,0 +1,94 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="dialogFormVisible"
+    width="500px"
+    @close="close">
+    <el-form ref="form" label-width="80px" :model="form" :rules="rules">
+      <el-form-item label="岗位名称" prop="postName">
+        <el-input v-model="form.postName" placeholder="请输入岗位名称" />
+      </el-form-item>
+      <el-form-item label="岗位编号" prop="postCode">
+        <el-input v-model="form.postCode" placeholder="请输入岗位编号" />
+      </el-form-item>
+      <el-form-item label="岗位顺序" prop="sort">
+        <el-input-number
+          v-model="form.sort"
+          controls-position="right"
+          :min="0" />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-radio-group v-model="form.status">
+          <el-radio-group v-model="form.status">
+            <el-radio label="10">正常</el-radio>
+            <el-radio label="20">停用</el-radio>
+          </el-radio-group>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input
+          v-model="form.remark"
+          placeholder="请输入内容"
+          type="textarea" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="close">取 消</el-button>
+      <el-button type="primary" @click="save">确 定</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script>
+  import postApi from '@/api/system/post'
+
+  export default {
+    name: 'PostEdit',
+    data() {
+      return {
+        form: { status: '10' },
+        rules: {
+          postName: [
+            { required: true, message: '岗位名称不能为空', trigger: 'blur' },
+          ],
+          postCode: [
+            { required: true, message: '岗位编码不能为空', trigger: 'blur' },
+          ],
+        },
+        title: '',
+        dialogFormVisible: false,
+      }
+    },
+    methods: {
+      showEdit(row) {
+        if (!row) {
+          this.title = '添加'
+        } else {
+          this.title = '编辑'
+          this.form = Object.assign({}, row)
+        }
+        this.dialogFormVisible = true
+      },
+      close() {
+        this.$refs['form'].resetFields()
+        this.form = this.$options.data().form
+        this.dialogFormVisible = false
+      },
+      save() {
+        this.$refs['form'].validate(async (valid) => {
+          if (valid) {
+            if (this.form.id) {
+              const { msg } = await postApi.doEdit(this.form)
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            } else {
+              const { msg } = await postApi.doAdd(this.form)
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            }
+            this.$emit('fetch-data')
+            this.close()
+          }
+        })
+      },
+    },
+  }
+</script>

+ 202 - 0
src/views/system/post/index.vue

@@ -0,0 +1,202 @@
+<template>
+  <div class="user-management-container">
+    <vab-query-form>
+      <vab-query-form-left-panel :span="5">
+        <el-button
+          icon="el-icon-plus"
+          type="primary"
+          @click="handleEdit($event)">
+          添加
+        </el-button>
+        <el-button
+          icon="el-icon-delete"
+          type="danger"
+          @click="handleDelete($event)">
+          删除
+        </el-button>
+      </vab-query-form-left-panel>
+      <vab-query-form-right-panel :span="19">
+        <el-form :inline="true" :model="queryForm" @submit.native.prevent>
+          <el-form-item label="岗位名称" prop="dictName">
+            <el-input
+              v-model.trim="queryForm.postName"
+              clearable
+              placeholder="请输入岗位名称" />
+          </el-form-item>
+          <el-form-item label="岗位编码" prop="dictType">
+            <el-input
+              v-model.trim="queryForm.postCode"
+              clearable
+              placeholder="请输入岗位编码" />
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-select v-model="queryForm.status" clearable placeholder="状态">
+              <el-option label="正常" value="10" />
+              <el-option label="停用" value="20" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button icon="el-icon-search" type="primary" @click="queryData">
+              查询
+            </el-button>
+          </el-form-item>
+        </el-form>
+      </vab-query-form-right-panel>
+    </vab-query-form>
+
+    <el-table
+      v-loading="listLoading"
+      border
+      :data="list"
+      :height="height"
+      @selection-change="setSelectRows">
+      <el-table-column align="center" show-overflow-tooltip type="selection" />
+      <el-table-column
+        align="center"
+        label="岗位编号"
+        prop="id"
+        show-overflow-tooltip />
+      <el-table-column
+        align="center"
+        label="岗位名称"
+        prop="postName"
+        show-overflow-tooltip />
+      <el-table-column
+        align="center"
+        label="岗位编码"
+        prop="postCode"
+        show-overflow-tooltip />
+      <el-table-column align="center" label="状态" prop="status">
+        <template #default="{ row }">
+          {{ row.status === '10' ? '正常' : '停用' }}
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="岗位排序"
+        prop="sort"
+        show-overflow-tooltip />
+      <el-table-column
+        align="center"
+        label="备注"
+        prop="remark"
+        show-overflow-tooltip />
+      <el-table-column align="center" label="创建时间" prop="createdTime">
+        <template #default="scope">
+          <span>{{ parseTime(scope.row.createdTime) }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column
+        align="center"
+        label="操作"
+        show-overflow-tooltip
+        width="85">
+        <template #default="{ row }">
+          <el-button type="text" @click="handleEdit(row)">编辑</el-button>
+          <el-button type="text" @click="handleDelete(row)">删除</el-button>
+        </template>
+      </el-table-column>
+      <template #empty>
+        <el-image
+          class="vab-data-empty"
+          :src="require('@/assets/empty_images/data_empty.png')" />
+      </template>
+    </el-table>
+    <el-pagination
+      background
+      :current-page="queryForm.pageNum"
+      :layout="layout"
+      :page-size="queryForm.pageSize"
+      :total="total"
+      @current-change="handleCurrentChange"
+      @size-change="handleSizeChange" />
+    <edit ref="edit" @fetch-data="fetchData" />
+  </div>
+</template>
+
+<script>
+  import postApi from '@/api/system/post'
+  import Edit from './components/PostEdit'
+
+  export default {
+    name: 'Post',
+    components: { Edit },
+    data() {
+      return {
+        list: [],
+        listLoading: true,
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        selectRows: '',
+        queryForm: {
+          pageNum: 1,
+          pageSize: 10,
+          postName: undefined,
+          postCode: undefined,
+          status: undefined,
+        },
+      }
+    },
+    computed: {
+      height() {
+        return this.$baseTableHeight(1)
+      },
+    },
+    created() {
+      this.fetchData()
+    },
+    methods: {
+      setSelectRows(val) {
+        this.selectRows = val
+      },
+      handleEdit(row) {
+        if (row.id) {
+          this.$refs['edit'].showEdit(row)
+        } else {
+          this.$refs['edit'].showEdit()
+        }
+      },
+      handleDelete(row) {
+        if (row.id) {
+          this.$baseConfirm('你确定要删除当前项吗', null, async () => {
+            const { msg } = await postApi.doDelete({ ids: [row.id] })
+            this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+            await this.fetchData()
+          })
+        } else {
+          if (this.selectRows.length > 0) {
+            const ids = this.selectRows.map((item) => item.id).join()
+            this.$baseConfirm('你确定要删除选中项吗', null, async () => {
+              const { msg } = await postApi.doDelete({ ids })
+              this.$baseMessage(msg, 'success', 'vab-hey-message-success')
+              await this.fetchData()
+            })
+          } else {
+            this.$baseMessage('未选中任何行', 'error', 'vab-hey-message-error')
+          }
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        this.fetchData()
+      },
+      handleCurrentChange(val) {
+        this.queryForm.pageNum = val
+        this.fetchData()
+      },
+      queryData() {
+        this.queryForm.pageNum = 1
+        this.fetchData()
+      },
+      async fetchData() {
+        this.listLoading = true
+        const {
+          data: { list, total },
+        } = await postApi.getList(this.queryForm)
+        this.list = list
+        this.total = total
+        this.listLoading = false
+      },
+    },
+  }
+</script>

+ 223 - 0
src/views/system/role/components/RoleDataScopeEdit.vue

@@ -0,0 +1,223 @@
+<template>
+  <!-- 分配角色数据权限对话框 -->
+  <el-dialog
+    append-to-body
+    :close-on-click-modal="false"
+    :title="title"
+    :visible.sync="openDataScope"
+    width="500px">
+    <el-form ref="form" label-width="80px" :model="form" :rules="rules">
+      <el-form-item label="角色名称">
+        <el-input v-model="form.roleName" :disabled="true" />
+      </el-form-item>
+      <el-form-item label="权限字符">
+        <el-input v-model="form.roleKey" :disabled="true" />
+      </el-form-item>
+
+      <el-form-item label="权限范围">
+        <el-select v-model="form.dataScope">
+          <el-option
+            v-for="item in dataScopeOptions"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value" />
+        </el-select>
+      </el-form-item>
+      <el-form-item v-show="form.dataScope == 2" label="数据权限">
+        <el-checkbox
+          v-model="deptExpand"
+          @change="handleCheckedTreeExpand($event, 'dept')">
+          展开/折叠
+        </el-checkbox>
+        <el-checkbox
+          v-model="deptNodeAll"
+          @change="handleCheckedTreeNodeAll($event, 'dept')">
+          全选/全不选
+        </el-checkbox>
+        <el-checkbox
+          v-model="form.deptCheckStrictly"
+          @change="handleCheckedTreeConnect($event, 'dept')">
+          父子联动
+        </el-checkbox>
+        <el-tree
+          ref="dept"
+          :check-strictly="!form.deptCheckStrictly"
+          class="tree-border"
+          :data="treeList"
+          default-expand-all
+          empty-text="加载中,请稍后"
+          node-key="id"
+          :props="deptProps"
+          show-checkbox />
+      </el-form-item>
+    </el-form>
+    <div slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="submitDataScope">确 定</el-button>
+      <el-button @click="close">取 消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+  import roleApi from '@/api/system/role'
+  import deptApi from '@/api/system/dept'
+
+  export default {
+    name: 'RoleEdit',
+    data() {
+      return {
+        form: {},
+        rules: {},
+        title: '',
+        dialogFormVisible: false,
+        treeList: [],
+        // 是否显示弹出层(数据权限)
+        openDataScope: false,
+        deptExpand: true,
+        deptNodeAll: false,
+        deptProps: {
+          children: 'children',
+          label: 'deptName',
+        },
+        // 数据范围选项
+        dataScopeOptions: [
+          {
+            value: '1',
+            label: '全部数据权限',
+          },
+          {
+            value: '2',
+            label: '自定数据权限',
+          },
+          {
+            value: '3',
+            label: '本部门数据权限',
+          },
+          {
+            value: '4',
+            label: '本部门及以下数据权限',
+          },
+          {
+            value: '5',
+            label: '仅本人数据权限',
+          },
+        ],
+      }
+    },
+    created() {
+      this.getDeptTreeselect()
+    },
+    methods: {
+      close() {
+        this.$refs['form'].resetFields()
+        this.form = this.$options.data().form
+        this.openDataScope = false
+      },
+      /** 获取详情 */
+      async getEntityById(id) {
+        const { data: data } = await roleApi.getEntityById({ id: id })
+        this.form = data
+        this.form.menuCheckStrictly = this.form.menuCheckStrictly === '10'
+        this.form.deptCheckStrictly = this.form.deptCheckStrictly === '10'
+      },
+      /** 查询部门树结构 */
+      getDeptTreeselect() {
+        deptApi.getTree().then((response) => {
+          this.treeList = response.data
+        })
+      },
+      /** 查询角色部门树结构 */
+      getRoleDeptTreeselect(id) {
+        roleApi.getRoleDeptTreeselect({ id: id }).then((response) => {
+          if (this.$refs.dept) {
+            this.$refs.dept.setCheckedKeys(response.data, true)
+          }
+        })
+      },
+      /** 分配数据权限操作 */
+      handleDataScope(row) {
+        const _this = this
+        _this.title = '分配数据权限'
+        _this.getEntityById(row.id)
+        _this.$nextTick(() => {
+          _this.getRoleDeptTreeselect(row.id)
+        })
+        _this.openDataScope = true
+      },
+      /** 提交按钮(数据权限) */
+      submitDataScope: function () {
+        if (this.form.id != undefined) {
+          this.form.deptIds = this.getDeptAllCheckedKeys()
+          let data = {
+            roleId: this.form.id,
+            dataScope: Number(this.form.dataScope),
+            deptIds: this.form.deptIds,
+          }
+          roleApi.updateRoleDataScope(data).then((response) => {
+            if (response.code === 200) {
+              this.$baseMessage(
+                response.msg,
+                'success',
+                'vab-hey-message-success'
+              )
+              this.openDataScope = false
+              this.getList()
+            } else {
+              this.$baseMessage(
+                response.msg,
+                'error',
+                'vab-hey-message-success'
+              )
+            }
+          })
+        }
+      },
+      // 所有部门节点数据
+      getDeptAllCheckedKeys() {
+        // 目前被选中的部门节点
+        let checkedKeys = this.$refs.dept.getCheckedKeys()
+        return checkedKeys
+      },
+      // 树权限(展开/折叠)
+      handleCheckedTreeExpand(value, type) {
+        if (type == 'menu') {
+          let treeList = this.treeList
+          for (let i = 0; i < treeList.length; i++) {
+            this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value
+          }
+        } else if (type == 'dept') {
+          let treeList = this.treeList
+          for (let i = 0; i < treeList.length; i++) {
+            this.$refs.dept.store.nodesMap[treeList[i].deptId].expanded = value
+          }
+        }
+      },
+      // 树权限(全选/全不选)
+      handleCheckedTreeNodeAll(value, type) {
+        if (type == 'menu') {
+          this.$refs.menu.setCheckedNodes(value ? this.treeList : [])
+        } else if (type == 'dept') {
+          this.$refs.dept.setCheckedNodes(value ? this.treeList : [])
+        }
+      },
+      // 树权限(父子联动)
+      handleCheckedTreeConnect(value, type) {
+        if (type == 'menu') {
+          this.form.menuCheckStrictly = value ? true : false
+        } else if (type == 'dept') {
+          this.form.deptCheckStrictly = value ? true : false
+        }
+      },
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  .vab-tree-border {
+    height: 200px;
+    padding: $base-padding;
+    overflow-y: auto;
+    border: 1px solid #dcdfe6;
+    border-radius: $base-border-radius;
+  }
+</style>

+ 86 - 34
src/views/system/role/components/RoleEdit.vue

@@ -29,12 +29,26 @@
         </el-radio-group>
       </el-form-item>
       <el-form-item label="菜单权限">
+        <el-checkbox
+          v-model="menuExpand"
+          @change="handleCheckedTreeExpand($event, 'menu')">
+          展开/折叠
+        </el-checkbox>
+        <el-checkbox
+          v-model="menuNodeAll"
+          @change="handleCheckedTreeNodeAll($event, 'menu')">
+          全选/全不选
+        </el-checkbox>
+        <el-checkbox
+          v-model="form.menuCheckStrictly"
+          @change="handleCheckedTreeConnect($event, 'menu')">
+          父子联动
+        </el-checkbox>
         <div class="vab-tree-border">
           <el-tree
-            ref="tree"
-            :data="list"
-            :default-checked-keys="[]"
-            :default-expanded-keys="[]"
+            ref="menu"
+            :check-strictly="!form.menuCheckStrictly"
+            :data="treeList"
             node-key="id"
             show-checkbox>
             <template #default="{ data }">
@@ -59,8 +73,8 @@
 </template>
 
 <script>
-  import roleApi from '@/api/role'
-  import menuApi from '@/api/menu'
+  import roleApi from '@/api/system/role'
+  import menuApi from '@/api/system/menu'
 
   export default {
     name: 'RoleEdit',
@@ -81,22 +95,9 @@
         },
         title: '',
         dialogFormVisible: false,
-        list: [],
-        /* btnRoles demo */
-        btnRoles: [
-          {
-            lable: '读',
-            value: 'read:system',
-          },
-          {
-            lable: '写',
-            value: 'write:system',
-          },
-          {
-            lable: '删',
-            value: 'delete:system',
-          },
-        ],
+        treeList: [],
+        menuExpand: false,
+        menuNodeAll: false,
       }
     },
     created() {
@@ -108,7 +109,7 @@
           this.title = '添加'
         } else {
           this.title = '编辑'
-          this.form = Object.assign({}, row)
+          this.getEntityById(row.id)
         }
         this.dialogFormVisible = true
       },
@@ -119,25 +120,37 @@
       },
       async fetchData() {
         const { data: data } = await menuApi.getTree({ isAll: 'all' })
-        this.list = data
+        this.treeList = data
+      },
+      async getEntityById(id) {
+        const { data: data } = await roleApi.getEntityById({ id: id })
+        this.form = data
+        this.form.menuCheckStrictly = this.form.menuCheckStrictly === '10'
+        this.form.deptCheckStrictly = this.form.deptCheckStrictly === '10'
+        this.$nextTick(() => {
+          this.$refs.menu.setCheckedKeys(this.form.menuIds)
+        })
       },
       save() {
         // 具体业务请自行调整
         this.$refs['form'].validate(async (valid) => {
           if (valid) {
-            const tree = this.$refs.tree.getCheckedKeys()
-            const treeObject = { 'treeArray:': tree }
+            if (this.form.menuCheckStrictly) {
+              this.form.menuCheckStrictly = '10'
+            } else {
+              this.form.menuCheckStrictly = '20'
+            }
+            if (this.form.deptCheckStrictly) {
+              this.form.deptCheckStrictly = '10'
+            } else {
+              this.form.deptCheckStrictly = '20'
+            }
+            this.form.menuIds = this.getMenuAllCheckedKeys()
             if (this.form.id) {
-              const { msg } = await roleApi.doEdit({
-                ...this.form,
-                ...treeObject,
-              })
+              const { msg } = await roleApi.doEdit(this.form)
               this.$baseMessage(msg, 'success', 'vab-hey-message-success')
             } else {
-              const { msg } = await roleApi.doAdd({
-                ...this.form,
-                ...treeObject,
-              })
+              const { msg } = await roleApi.doAdd(this.form)
               this.$baseMessage(msg, 'success', 'vab-hey-message-success')
             }
 
@@ -146,6 +159,45 @@
           }
         })
       },
+      // 所有菜单节点数据
+      getMenuAllCheckedKeys() {
+        // 目前被选中的菜单节点
+        let checkedKeys = this.$refs.menu.getHalfCheckedKeys()
+        // 半选中的菜单节点
+        let halfCheckedKeys = this.$refs.menu.getCheckedKeys()
+        checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
+        return checkedKeys
+      },
+      // 树权限(展开/折叠)
+      handleCheckedTreeExpand(value, type) {
+        if (type == 'menu') {
+          let treeList = this.treeList
+          for (let i = 0; i < treeList.length; i++) {
+            this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value
+          }
+        } else if (type == 'dept') {
+          let treeList = this.treeList
+          for (let i = 0; i < treeList.length; i++) {
+            this.$refs.dept.store.nodesMap[treeList[i].deptId].expanded = value
+          }
+        }
+      },
+      // 树权限(全选/全不选)
+      handleCheckedTreeNodeAll(value, type) {
+        if (type == 'menu') {
+          this.$refs.menu.setCheckedNodes(value ? this.treeList : [])
+        } else if (type == 'dept') {
+          this.$refs.dept.setCheckedNodes(value ? this.treeList : [])
+        }
+      },
+      // 树权限(父子联动)
+      handleCheckedTreeConnect(value, type) {
+        if (type == 'menu') {
+          this.form.menuCheckStrictly = value ? true : false
+        } else if (type == 'dept') {
+          this.form.deptCheckStrictly = value ? true : false
+        }
+      },
     },
   }
 </script>

+ 12 - 9
src/views/system/role/index.vue

@@ -12,7 +12,7 @@
           icon="el-icon-delete"
           type="danger"
           @click="handleDelete($event)">
-          批量删除
+          删除
         </el-button>
       </vab-query-form-left-panel>
       <vab-query-form-right-panel :span="12">
@@ -44,11 +44,6 @@
           {{ $index + 1 }}
         </template>
       </el-table-column>
-      <el-table-column
-        align="center"
-        label="id"
-        prop="id"
-        show-overflow-tooltip />
       <el-table-column
         align="center"
         label="角色名称"
@@ -83,9 +78,12 @@
         align="center"
         label="操作"
         show-overflow-tooltip
-        width="85">
+        width="150">
         <template #default="{ row }">
           <el-button type="text" @click="handleEdit(row)">编辑</el-button>
+          <el-button type="text" @click="handleDataScope(row)">
+            数据权限
+          </el-button>
           <el-button type="text" @click="handleDelete(row)">删除</el-button>
         </template>
       </el-table-column>
@@ -104,16 +102,18 @@
       @current-change="handleCurrentChange"
       @size-change="handleSizeChange" />
     <edit ref="edit" @fetch-data="fetchData" />
+    <role-data-scope-edit ref="role-data-scope-edit" @fetch-data="fetchData" />
   </div>
 </template>
 
 <script>
-  import roleApi from '@/api/role'
+  import roleApi from '@/api/system/role'
   import Edit from './components/RoleEdit'
+  import RoleDataScopeEdit from './components/RoleDataScopeEdit'
 
   export default {
     name: 'Role',
-    components: { Edit },
+    components: { Edit, RoleDataScopeEdit },
     data() {
       return {
         list: [],
@@ -142,6 +142,9 @@
           this.$refs['edit'].showEdit()
         }
       },
+      handleDataScope(row) {
+        this.$refs['role-data-scope-edit'].handleDataScope(row)
+      },
       handleDelete(row) {
         if (row.id) {
           this.$baseConfirm('你确定要删除当前项吗', null, async () => {

+ 1 - 1
src/views/system/systemLog/index.vue

@@ -83,7 +83,7 @@
 </template>
 
 <script>
-  import { getList } from '@/api/systemLog'
+  import { getList } from '@/api/system/systemLog'
 
   export default {
     name: 'SystemLog',

+ 223 - 29
src/views/system/user/components/UserEdit.vue

@@ -1,44 +1,146 @@
 <template>
+  <!-- 添加或修改参数配置对话框 -->
   <el-dialog
     :title="title"
     :visible.sync="dialogFormVisible"
-    width="500px"
+    width="600px"
     @close="close">
     <el-form ref="form" label-width="80px" :model="form" :rules="rules">
-      <el-form-item label="用户名" prop="userName">
-        <el-input v-model.trim="form.userName" />
-      </el-form-item>
-      <el-form-item label="密码" prop="password">
-        <el-input v-model.trim="form.password" type="password" />
-      </el-form-item>
-      <el-form-item label="用户昵称" prop="nickName">
-        <el-input v-model.trim="form.nickName" />
-      </el-form-item>
-      <el-form-item label="手机号" prop="phone">
-        <el-input v-model.trim="form.phone" />
-      </el-form-item>
-      <el-form-item label="邮箱" prop="email">
-        <el-input v-model.trim="form.email" />
-      </el-form-item>
-      <!--      <el-form-item label="角色" prop="roles">-->
-      <!--        <el-checkbox-group v-model="form.roles">-->
-      <!--          <el-checkbox label="admin" />-->
-      <!--          <el-checkbox label="editor" />-->
-      <!--        </el-checkbox-group>-->
-      <!--      </el-form-item>-->
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="用户昵称" prop="nickName">
+            <el-input v-model="form.nickName" placeholder="请输入用户昵称" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="归属部门" prop="deptId">
+            <treeselect
+              v-model="form.deptId"
+              :normalizer="normalizer"
+              :options="deptOptions"
+              placeholder="请选择归属部门" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="手机号码" prop="phone">
+            <el-input
+              v-model="form.phone"
+              maxlength="11"
+              placeholder="请输入手机号码" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="邮箱" prop="email">
+            <el-input
+              v-model="form.email"
+              maxlength="50"
+              placeholder="请输入邮箱" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item
+            v-if="form.id == undefined"
+            label="用户账号"
+            prop="userName">
+            <el-input v-model="form.userName" placeholder="请输入用户账号" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item
+            v-if="form.id == undefined"
+            label="用户密码"
+            prop="password">
+            <el-input
+              v-model="form.password"
+              placeholder="请输入用户密码"
+              type="password" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="用户性别">
+            <el-select v-model="form.sex" placeholder="请选择">
+              <el-option
+                v-for="dict in sexOptions"
+                :key="dict.key"
+                :label="dict.value"
+                :value="dict.key" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="状态">
+            <el-radio-group v-model="form.status">
+              <el-radio
+                v-for="dict in statusOptions"
+                :key="dict.key"
+                :label="dict.key">
+                {{ dict.value }}
+              </el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="岗位">
+            <el-select v-model="form.postIds" multiple placeholder="请选择">
+              <el-option
+                v-for="item in postOptions"
+                :key="item.id"
+                :label="item.postName"
+                :value="item.id" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="角色">
+            <el-select v-model="form.roleIds" multiple placeholder="请选择">
+              <el-option
+                v-for="item in roleOptions"
+                :key="item.id"
+                :label="item.roleName"
+                :value="item.id" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="用户组">
+            <el-select v-model="form.groupIds" multiple placeholder="请选择">
+              <el-option
+                v-for="item in groupOptions"
+                :key="item.id"
+                :label="item.groupName"
+                :value="item.id" />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="备注">
+            <el-input
+              v-model="form.remark"
+              placeholder="请输入内容"
+              type="textarea" />
+          </el-form-item>
+        </el-col>
+      </el-row>
     </el-form>
     <template #footer>
-      <el-button @click="close">取 消</el-button>
       <el-button type="primary" @click="save">确 定</el-button>
+      <el-button @click="close">取 消</el-button>
     </template>
   </el-dialog>
 </template>
 
 <script>
-  import userApi from '@/api/user'
+  import deptApi from '@/api/system/dept'
+  import roleApi from '@/api/system/role'
+  import postApi from '@/api/system/post'
+  import groupApi from '@/api/system/group'
+  import userApi from '@/api/system/user'
+  import Treeselect from '@riophae/vue-treeselect'
+  import '@riophae/vue-treeselect/dist/vue-treeselect.css'
 
   export default {
     name: 'UserEdit',
+    components: { Treeselect },
     data() {
       return {
         form: {
@@ -46,25 +148,117 @@
         },
         rules: {
           userName: [
-            { required: true, trigger: 'blur', message: '请输入用户名' },
+            { required: true, message: '用户名称不能为空', trigger: 'blur' },
+          ],
+          nickName: [
+            { required: true, message: '用户昵称不能为空', trigger: 'blur' },
+          ],
+          deptId: [
+            { required: true, message: '归属部门不能为空', trigger: 'blur' },
           ],
           password: [
-            { required: true, trigger: 'blur', message: '请输入密码' },
+            { required: true, message: '用户密码不能为空', trigger: 'blur' },
+          ],
+          email: [
+            { required: true, message: '邮箱地址不能为空', trigger: 'blur' },
+            {
+              type: 'email',
+              message: "'请输入正确的邮箱地址",
+              trigger: ['blur', 'change'],
+            },
+          ],
+          phone: [
+            { required: true, message: '手机号码不能为空', trigger: 'blur' },
+            {
+              pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
+              message: '请输入正确的手机号码',
+              trigger: 'blur',
+            },
           ],
-          email: [{ required: true, trigger: 'blur', message: '请输入邮箱' }],
-          roles: [{ required: true, trigger: 'blur', message: '请选择角色' }],
         },
         title: '',
         dialogFormVisible: false,
+
+        // 部门树选项
+        deptOptions: undefined,
+        // 部门名称
+        deptName: undefined,
+        // 默认密码
+        initPassword: undefined,
+        // 日期范围
+        dateRange: [],
+        // 状态数据字典
+        statusOptions: [],
+        // 性别状态字典
+        sexOptions: [],
+        // 岗位选项
+        postOptions: [],
+        // 角色选项
+        roleOptions: [],
+        // 用户组
+        groupOptions: [],
+        defaultProps: {
+          id: 'id',
+          children: 'children',
+          label: 'deptName',
+        },
+        normalizer(node) {
+          return {
+            id: node.id,
+            label: node.deptName,
+            children: node.children,
+          }
+        },
       }
     },
+    watch: {
+      // 根据名称筛选部门树
+      deptName(val) {
+        this.$refs.tree.filter(val)
+      },
+    },
+    created() {
+      this.getDicts('sys_normal_disable').then((response) => {
+        this.statusOptions = response.data.values || []
+      })
+      this.getDicts('sys_user_sex').then((response) => {
+        this.sexOptions = response.data.values || []
+      })
+      this.getTreeselect()
+      this.getRoleAndPost()
+    },
     methods: {
+      // 获取角色和岗位
+      getRoleAndPost() {
+        roleApi.getList({ status: '10' }).then((response) => {
+          this.roleOptions = response.data.list
+        })
+        postApi.getList({ status: '10' }).then((response) => {
+          this.postOptions = response.data.list
+        })
+        groupApi.getList({ status: '10' }).then((response) => {
+          this.groupOptions = response.data.list
+        })
+      },
+      /** 查询部门下拉树结构 */
+      getTreeselect() {
+        deptApi.getTree().then((response) => {
+          this.deptOptions = response.data
+        })
+      },
+      async getUserInfo(id) {
+        const { data: data } = await userApi.getUserInfo({ id: id })
+        this.form = data.entity
+        this.$set(this.form, 'roleIds', data.roleIds)
+        this.$set(this.form, 'postIds', data.postIds)
+        this.$set(this.form, 'groupIds', data.groupIds)
+      },
       showEdit(row) {
         if (!row) {
           this.title = '添加'
         } else {
           this.title = '编辑'
-          this.form = Object.assign({}, row)
+          this.getUserInfo(row.id)
         }
         this.dialogFormVisible = true
       },

+ 168 - 109
src/views/system/user/index.vue

@@ -1,122 +1,155 @@
 <template>
   <div class="user-management-container">
-    <vab-query-form>
-      <vab-query-form-left-panel :span="12">
-        <el-button
-          icon="el-icon-plus"
-          type="primary"
-          @click="handleEdit($event)">
-          添加
-        </el-button>
-        <el-button
-          icon="el-icon-delete"
-          type="danger"
-          @click="handleDelete($event)">
-          批量删除
-        </el-button>
-      </vab-query-form-left-panel>
-      <vab-query-form-right-panel :span="12">
-        <el-form :inline="true" :model="queryForm" @submit.native.prevent>
-          <el-form-item>
-            <el-input
-              v-model.trim="queryForm.userName"
-              clearable
-              placeholder="请输入用户名" />
-          </el-form-item>
-          <el-form-item>
-            <el-button icon="el-icon-search" type="primary" @click="queryData">
-              查询
+    <el-row :gutter="20">
+      <!--部门数据-->
+      <el-col :span="4" :xs="24">
+        <div class="head-container">
+          <el-input
+            v-model="deptName"
+            clearable
+            placeholder="请输入部门名称"
+            prefix-icon="el-icon-search"
+            size="small"
+            style="margin-bottom: 20px" />
+        </div>
+        <div class="head-container">
+          <el-tree
+            ref="tree"
+            :data="deptOptions"
+            default-expand-all
+            :expand-on-click-node="false"
+            :filter-node-method="filterNode"
+            :props="defaultProps"
+            @node-click="handleNodeClick" />
+        </div>
+      </el-col>
+      <!--用户数据-->
+      <el-col :span="20" :xs="24">
+        <vab-query-form>
+          <vab-query-form-left-panel :span="12">
+            <el-button
+              icon="el-icon-plus"
+              type="primary"
+              @click="handleEdit($event)">
+              添加
             </el-button>
-          </el-form-item>
-        </el-form>
-      </vab-query-form-right-panel>
-    </vab-query-form>
+            <el-button
+              icon="el-icon-delete"
+              type="danger"
+              @click="handleDelete($event)">
+              删除
+            </el-button>
+          </vab-query-form-left-panel>
+          <vab-query-form-right-panel :span="12">
+            <el-form :inline="true" :model="queryForm" @submit.native.prevent>
+              <el-form-item>
+                <el-input
+                  v-model.trim="queryForm.userName"
+                  clearable
+                  placeholder="请输入用户名" />
+              </el-form-item>
+              <el-form-item>
+                <el-button
+                  icon="el-icon-search"
+                  type="primary"
+                  @click="queryData">
+                  查询
+                </el-button>
+              </el-form-item>
+            </el-form>
+          </vab-query-form-right-panel>
+        </vab-query-form>
 
-    <el-table
-      v-loading="listLoading"
-      border
-      :data="list"
-      :height="height"
-      @selection-change="setSelectRows">
-      <el-table-column align="center" show-overflow-tooltip type="selection" />
-      <!--      <el-table-column align="center" label="序号" width="55">
-        <template #default="{ $index }">
-          {{ $index + 1 }}
-        </template>
-      </el-table-column>-->
-      <el-table-column
-        align="center"
-        label="id"
-        prop="id"
-        show-overflow-tooltip />
-      <el-table-column
-        align="center"
-        label="用户名"
-        prop="userName"
-        show-overflow-tooltip />
-      <el-table-column
-        align="center"
-        label="昵称"
-        prop="nickName"
-        show-overflow-tooltip />
-      <el-table-column
-        align="center"
-        label="手机号"
-        prop="phone"
-        show-overflow-tooltip />
-      <el-table-column
-        align="center"
-        label="邮箱"
-        prop="email"
-        show-overflow-tooltip />
-      <el-table-column
-        align="center"
-        label="部门"
-        prop="email"
-        show-overflow-tooltip />
-      <el-table-column align="center" label="角色" show-overflow-tooltip>
-        <template #default="{ row }">
-          <el-tag v-for="(item, index) in row.roles" :key="index">
-            {{ item }}
-          </el-tag>
-        </template>
-      </el-table-column>
+        <el-table
+          v-loading="listLoading"
+          :data="list"
+          :height="height"
+          @selection-change="setSelectRows">
+          <el-table-column
+            align="center"
+            show-overflow-tooltip
+            type="selection" />
+          <!--      <el-table-column align="center" label="序号" width="55">
+            <template #default="{ $index }">
+              {{ $index + 1 }}
+            </template>
+          </el-table-column>-->
+          <el-table-column
+            align="center"
+            label="id"
+            prop="id"
+            show-overflow-tooltip />
+          <el-table-column
+            align="center"
+            label="用户名"
+            prop="userName"
+            show-overflow-tooltip />
+          <el-table-column
+            align="center"
+            label="昵称"
+            prop="nickName"
+            show-overflow-tooltip />
+          <el-table-column
+            align="center"
+            label="手机号"
+            prop="phone"
+            show-overflow-tooltip />
+          <el-table-column
+            align="center"
+            label="邮箱"
+            prop="email"
+            show-overflow-tooltip />
+          <el-table-column
+            align="center"
+            label="部门"
+            prop="email"
+            show-overflow-tooltip />
+          <el-table-column align="center" label="角色" show-overflow-tooltip>
+            <template #default="{ row }">
+              <el-tag v-for="(item, index) in row.roles" :key="index">
+                {{ item }}
+              </el-tag>
+            </template>
+          </el-table-column>
 
-      <el-table-column align="center" label="创建时间" prop="createdTime">
-        <template #default="scope">
-          <span>{{ parseTime(scope.row.createdTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column
-        align="center"
-        label="操作"
-        show-overflow-tooltip
-        width="85">
-        <template #default="{ row }">
-          <el-button type="text" @click="handleEdit(row)">编辑</el-button>
-          <el-button type="text" @click="handleDelete(row)">删除</el-button>
-        </template>
-      </el-table-column>
-      <template #empty>
-        <el-image
-          class="vab-data-empty"
-          :src="require('@/assets/empty_images/data_empty.png')" />
-      </template>
-    </el-table>
-    <el-pagination
-      background
-      :current-page="queryForm.pageNum"
-      :layout="layout"
-      :page-size="queryForm.pageSize"
-      :total="total"
-      @current-change="handleCurrentChange"
-      @size-change="handleSizeChange" />
+          <el-table-column align="center" label="创建时间" prop="createdTime">
+            <template #default="scope">
+              <span>{{ parseTime(scope.row.createdTime) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            label="操作"
+            show-overflow-tooltip
+            width="85">
+            <template #default="{ row }">
+              <el-button type="text" @click="handleEdit(row)">编辑</el-button>
+              <el-button type="text" @click="handleDelete(row)">删除</el-button>
+            </template>
+          </el-table-column>
+          <template #empty>
+            <el-image
+              class="vab-data-empty"
+              :src="require('@/assets/empty_images/data_empty.png')" />
+          </template>
+        </el-table>
+        <el-pagination
+          background
+          :current-page="queryForm.pageNum"
+          :layout="layout"
+          :page-size="queryForm.pageSize"
+          :total="total"
+          @current-change="handleCurrentChange"
+          @size-change="handleSizeChange" />
+      </el-col>
+    </el-row>
     <edit ref="edit" @fetch-data="fetchData" />
   </div>
 </template>
 
 <script>
-  import userApi from '@/api/user'
+  import deptApi from '@/api/system/dept'
+  import userApi from '@/api/system/user'
   import Edit from './components/UserEdit'
 
   export default {
@@ -134,6 +167,14 @@
           pageSize: 10,
           userName: '',
         },
+        deptName: '',
+        // 部门树选项
+        deptOptions: undefined,
+        defaultProps: {
+          id: 'id',
+          children: 'children',
+          label: 'deptName',
+        },
       }
     },
     computed: {
@@ -143,8 +184,26 @@
     },
     created() {
       this.fetchData()
+      this.getTreeselect()
     },
     methods: {
+      /** 查询部门下拉树结构 */
+      async getTreeselect() {
+        const { data: data } = await deptApi.getTree({
+          deptName: this.deptName,
+        })
+        this.deptOptions = data
+      },
+      // 筛选节点
+      filterNode(value, data) {
+        if (!value) return true
+        return data[this.defaultProps.label].indexOf(value) !== -1
+      },
+      // 节点单击事件
+      handleNodeClick(data) {
+        this.queryForm.deptId = data.id
+        this.fetchData()
+      },
       setSelectRows(val) {
         this.selectRows = val
       },

+ 0 - 82
src/views/test/components/Edit.vue

@@ -1,82 +0,0 @@
-<template>
-  <el-dialog
-    :title="title"
-    :visible.sync="dialogFormVisible"
-    width="500px"
-    @close="close">
-    <el-form ref="form" label-width="80px" :model="form" :rules="rules">
-      <el-form-item label="用户名" prop="username">
-        <el-input v-model.trim="form.username" />
-      </el-form-item>
-      <el-form-item label="密码" prop="password">
-        <el-input v-model.trim="form.password" type="password" />
-      </el-form-item>
-      <el-form-item label="邮箱" prop="email">
-        <el-input v-model.trim="form.email" />
-      </el-form-item>
-      <el-form-item label="角色" prop="roles">
-        <el-checkbox-group v-model="form.roles">
-          <el-checkbox label="admin" />
-          <el-checkbox label="editor" />
-        </el-checkbox-group>
-      </el-form-item>
-    </el-form>
-    <template #footer>
-      <el-button @click="close">取 消</el-button>
-      <el-button type="primary" @click="save">确 定</el-button>
-    </template>
-  </el-dialog>
-</template>
-
-<script>
-  import userApi from '@/api/user'
-
-  export default {
-    name: 'UserEdit',
-    data() {
-      return {
-        form: {
-          roles: [],
-        },
-        rules: {
-          username: [
-            { required: true, trigger: 'blur', message: '请输入用户名' },
-          ],
-          password: [
-            { required: true, trigger: 'blur', message: '请输入密码' },
-          ],
-          email: [{ required: true, trigger: 'blur', message: '请输入邮箱' }],
-          roles: [{ required: true, trigger: 'blur', message: '请选择角色' }],
-        },
-        title: '',
-        dialogFormVisible: false,
-      }
-    },
-    methods: {
-      showEdit(row) {
-        if (!row) {
-          this.title = '添加'
-        } else {
-          this.title = '编辑'
-          this.form = Object.assign({}, row)
-        }
-        this.dialogFormVisible = true
-      },
-      close() {
-        this.$refs['form'].resetFields()
-        this.form = this.$options.data().form
-        this.dialogFormVisible = false
-      },
-      save() {
-        this.$refs['form'].validate(async (valid) => {
-          if (valid) {
-            const { msg } = await userApi.doEdit(this.form)
-            this.$baseMessage(msg, 'success', 'vab-hey-message-success')
-            this.$emit('fetch-data')
-            this.close()
-          }
-        })
-      },
-    },
-  }
-</script>

+ 0 - 146
src/views/test/index.vue

@@ -1,146 +0,0 @@
-<template>
-  <div class="text-container">
-    <vab-query-form>
-      <vab-query-form-left-panel :span="12">
-        <el-button
-          icon="el-icon-plus"
-          type="primary"
-          @click="handleEdit($event)">
-          添加
-        </el-button>
-        <el-button
-          icon="el-icon-delete"
-          type="danger"
-          @click="handleDelete($event)">
-          批量删除
-        </el-button>
-      </vab-query-form-left-panel>
-      <vab-query-form-right-panel :span="12">
-        <el-form :inline="true" :model="queryForm" @submit.native.prevent>
-          <el-form-item>
-            <el-input
-              v-model.trim="queryForm.name"
-              clearable
-              placeholder="请输入名称" />
-          </el-form-item>
-          <el-form-item>
-            <el-button icon="el-icon-search" type="primary" @click="queryData">
-              查询
-            </el-button>
-          </el-form-item>
-        </el-form>
-      </vab-query-form-right-panel>
-    </vab-query-form>
-
-    <el-table
-      v-loading="listLoading"
-      border
-      :data="list"
-      default-expand-all
-      :height="height"
-      row-key="id"
-      :tree-props="{ children: 'children' }"
-      @selection-change="setSelectRows">
-      <el-table-column show-overflow-tooltip type="selection" />
-      <el-table-column label="名称" prop="name" show-overflow-tooltip />
-      <el-table-column label="父节点Id" prop="parentId" show-overflow-tooltip />
-      <el-table-column label="排序" prop="order" show-overflow-tooltip />
-      <el-table-column
-        label="创建时间"
-        prop="createTime"
-        show-overflow-tooltip />
-      <el-table-column label="操作" width="85">
-        <template #default="{ row }">
-          <el-button type="text" @click="handleEdit(row)">编辑</el-button>
-          <el-button
-            :disabled="!row.parentId"
-            type="text"
-            @click="handleDelete({ row })">
-            删除
-          </el-button>
-        </template>
-      </el-table-column>
-      <template #empty>
-        <el-image
-          class="vab-data-empty"
-          :src="require('@/assets/empty_images/data_empty.png')" />
-      </template>
-    </el-table>
-    <el-pagination
-      background
-      :current-page="queryForm.pageNum"
-      :layout="layout"
-      :page-size="queryForm.pageSize"
-      :total="total"
-      @current-change="handleCurrentChange"
-      @size-change="handleSizeChange" />
-    <edit ref="edit" @fetch-data="fetchData" />
-  </div>
-</template>
-
-<script>
-  import { getList } from '@/api/test'
-  import Edit from './components/Edit'
-  export default {
-    components: {
-      Edit,
-    },
-    data() {
-      return {
-        list: [],
-        listLoading: true,
-        layout: 'total, sizes, prev, pager, next, jumper',
-        total: 0,
-        selectRows: '',
-        queryForm: {
-          pageNum: 1,
-          pageSize: 10,
-          title: '',
-        },
-      }
-    },
-    computed: {
-      height() {
-        return this.$baseTableHeight(1)
-      },
-    },
-    mounted() {
-      this.fetchData()
-    },
-    methods: {
-      setSelectRows(val) {
-        this.selectRows = val
-      },
-      handleEdit(row) {
-        if (row.id) {
-          this.$refs['edit'].showEdit(row)
-        } else {
-          this.$refs['edit'].showEdit()
-        }
-      },
-      handleSizeChange(val) {
-        this.queryForm.pageSize = val
-        this.fetchData()
-      },
-      handleCurrentChange(val) {
-        this.queryForm.pageNum = val
-        this.fetchData()
-      },
-      queryData() {
-        this.queryForm.pageNum = 1
-        this.fetchData()
-      },
-      async fetchData() {
-        this.listLoading = true
-        const {
-          data: { list, total },
-        } = await getList(this.queryForm)
-        this.list = list
-        this.total = total
-        this.listLoading = false
-      },
-    },
-  }
-</script>
-
-<style></style>