调整主菜单, 增加角色编辑功能

This commit is contained in:
zhl 2021-01-20 23:12:53 +08:00
parent ff0f2b0cfa
commit 5cd7fb81b9
7 changed files with 322 additions and 47 deletions

View File

@ -15,6 +15,7 @@
"clipboard": "^2.0.6",
"element-ui": "^2.14.0",
"file-saver": "^2.0.5",
"fuse.js": "^6.4.3",
"js-cookie": "^2.2.1",
"jszip": "^3.5.0",
"lodash": "^4.17.20",
@ -22,6 +23,7 @@
"nprogress": "^0.2.0",
"path-to-regexp": "^6.2.0",
"register-service-worker": "^1.7.1",
"screenfull": "^5.0.2",
"tinymce": "^5.5.1",
"vue": "^2.6.12",
"vue-class-component": "^7.2.6",
@ -30,8 +32,6 @@
"vue-router": "^3.4.8",
"vue-svgicon": "^3.2.9",
"vuex": "^3.5.1",
"screenfull": "^5.0.2",
"fuse.js": "^6.4.3",
"vuex-module-decorators": "^1.0.1",
"xlsx": "^0.16.8"
},
@ -43,6 +43,7 @@
"@types/lodash": "^4.14.168",
"@types/node": "^14.14.6",
"@types/nprogress": "^0.2.0",
"@types/tinymce": "^4.6.0",
"@types/webpack-env": "^1.15.3",
"@typescript-eslint/eslint-plugin": "^4.6.0",
"@typescript-eslint/parser": "^4.6.0",
@ -71,7 +72,6 @@
"sass": "^1.28.0",
"sass-loader": "^10.0.4",
"style-resources-loader": "^1.3.3",
"@types/tinymce": "^4.6.0",
"ts-jest": "^26.4.3",
"typescript": "^4.0.5",
"vue-cli-plugin-element": "^1.0.1",

View File

@ -1,6 +1,7 @@
export default {
route: {
dashboard: 'Dashboard',
system: 'System',
documentation: 'Documentation',
guide: 'Guide',
permission: 'Permission',

View File

@ -2,6 +2,7 @@ export default {
route: {
dashboard: '首页',
documentation: '文档',
system: '系统',
guide: '引导页',
permission: '权限测试页',
rolePermission: '角色权限',

View File

@ -16,6 +16,9 @@
v-if="theOnlyOneChild.meta.icon"
:name="theOnlyOneChild.meta.icon"
/>
<i
v-if="item.meta && item.meta.elicon"
:class="item.meta.elicon" />
<span
v-if="theOnlyOneChild.meta.title"
slot="title"
@ -33,6 +36,9 @@
v-if="item.meta && item.meta.icon"
:name="item.meta.icon"
/>
<i
v-if="item.meta && item.meta.elicon"
:class="item.meta.elicon" />
<span
v-if="item.meta && item.meta.title"
slot="title"

View File

@ -6,6 +6,7 @@ import Layout from '@/layout/index.vue'
/* Router modules */
import tableRouter from './modules/table'
import systemRoutes from '@/router/modules/system'
Vue.use(VueRouter)
@ -112,16 +113,7 @@ export const constantRoutes: RouteConfig[] = [
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes: RouteConfig[] = [
{
path: '/system',
component: Layout,
redirect: '/system/list',
meta: {
title: '',
icon: 'lock',
alwaysShow: true
}
},
systemRoutes,
{
path: '/permission',
component: Layout,
@ -162,7 +154,6 @@ export const asyncRoutes: RouteConfig[] = [
]
},
/** when your routing map is too long, you can split it into small modules **/
tableRouter,
{
path: '/example',
@ -191,7 +182,7 @@ export const asyncRoutes: RouteConfig[] = [
noCache: true,
activeMenu: '/example/list',
hidden: true
}
},
},
{
path: 'list',
@ -201,6 +192,15 @@ export const asyncRoutes: RouteConfig[] = [
title: 'articleList',
icon: 'list'
}
},
{
path: 'form',
component: () => import(/* webpackChunkName: "permission-role" */ '@/views/form/index.vue'),
name: 'Form',
meta: {
title: 'form',
roles: ['admin']
}
}
]
},
@ -264,38 +264,6 @@ export const asyncRoutes: RouteConfig[] = [
}
]
},
{
path: '/theme',
component: Layout,
redirect: 'noredirect',
children: [
{
path: 'index',
component: () => import(/* webpackChunkName: "theme" */ '@/views/theme/index.vue'),
name: 'Theme',
meta: {
title: 'theme',
icon: 'theme'
}
}
]
},
{
path: '/i18n',
component: Layout,
children: [
{
path: 'index',
component: () => import(/* webpackChunkName: "i18n-demo" */ '@/views/i18n-demo/index.vue'),
name: 'I18n',
meta: {
title: 'i18n',
icon: 'international'
}
}
]
},
{
path: '*',
redirect: '/404',

View File

@ -0,0 +1,45 @@
import { RouteConfig } from 'vue-router'
import Layout from '@/layout/index.vue'
const systemRoutes: RouteConfig = {
path: '/system',
component: Layout,
redirect: '/system/list',
meta: {
title: 'system',
icon: 'component',
alwaysShow: true
},
children: [
{
path: 'role',
component: () => import('@/views/system/role.vue'),
name: 'RolePermission',
meta: {
title: 'rolePermission',
permissions: ['role:read'],
elicon: 'el-icon-arrow-right'
}
},
{
path: 'i18n',
component: () => import(/* webpackChunkName: "i18n-demo" */ '@/views/i18n-demo/index.vue'),
name: 'I18n',
meta: {
title: 'i18n',
elicon: 'el-icon-arrow-right'
}
},
{
path: 'theme',
component: () => import(/* webpackChunkName: "theme" */ '@/views/theme/index.vue'),
name: 'Theme',
meta: {
title: 'theme',
elicon: 'el-icon-arrow-right'
}
}
]
}
export default systemRoutes

254
src/views/system/role.vue Normal file
View File

@ -0,0 +1,254 @@
<template>
<div class="app-container">
<el-button
type="primary"
@click="handleCreateRole"
>
{{ $t('permission.createRole') }}
</el-button>
<el-table
:data="rolesList"
style="width: 100%;margin-top:30px;"
border
>
<el-table-column
align="center"
label="角色key"
>
<template slot-scope="{row}">
{{ row.key }}
</template>
</el-table-column>
<el-table-column
align="center"
label="角色名"
>
<template slot-scope="{row}">
{{ row.name }}
</template>
</el-table-column>
<el-table-column
align="center"
label="权限"
>
<template slot-scope="{row}">
{{ row.permissions.join(',') }}
</template>
</el-table-column>
<el-table-column
align="header-center"
label="备注"
>
<template slot-scope="{row}">
{{ row.comment }}
</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
>
<template slot-scope="scope">
<el-button
type="primary"
size="small"
@click="handleEdit(scope)"
>
{{ $t('permission.editPermission') }}
</el-button>
<el-button
type="danger"
size="small"
@click="handleDelete(scope)"
>
{{ $t('permission.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog
:visible.sync="dialogVisible"
:title="dialogType==='edit'?'Edit Role':'New Role'"
>
<el-form
:model="role"
label-width="80px"
label-position="left"
>
<el-form-item label="角色key1">
<el-input
:readonly="dialogType==='edit'"
v-model="role.key"
placeholder="角色key"
/>
</el-form-item>
<el-form-item label="角色名">
<el-input
v-model="role.name"
placeholder="角色名"
/>
</el-form-item>
<el-form-item label="权限">
<el-input
v-model="role.pstr"
placeholder="权限"
/>
</el-form-item>
<el-form-item label="备注">
<el-input
v-model="role.comment"
:autosize="{minRows: 2, maxRows: 4}"
type="textarea"
placeholder="备注"
/>
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button
type="danger"
@click="dialogVisible=false"
>
{{ $t('permission.cancel') }}
</el-button>
<el-button
type="primary"
@click="confirmRole"
>
{{ $t('permission.confirm') }}
</el-button>
</div>
</el-dialog>
</div>
</template>
<script lang="ts">
import path from 'path'
import { cloneDeep } from 'lodash'
import { Component, Vue } from 'vue-property-decorator'
import { RouteConfig } from 'vue-router'
import { getRoles, saveRole, deleteRole } from '@/api/roles'
interface IRole {
key: string
name: string
comment: string
permissions: string[],
pstr: string
}
const defaultRole: IRole = {
key: '',
name: '',
comment: '',
permissions: [],
pstr: ''
}
@Component({
name: 'RoleSystem',
})
export default class extends Vue {
private role = Object.assign({}, defaultRole)
private rolesList: IRole[] = []
private dialogVisible = false
private dialogType = 'new'
private checkStrictly = false
private defaultProps = {
children: 'children',
label: 'title'
}
created() {
this.getRoles()
}
private async getRoles() {
const { data } = await getRoles({ /* Your params here */ })
this.rolesList = data
}
private handleCreateRole() {
this.role = Object.assign({}, defaultRole)
this.dialogType = 'new'
this.dialogVisible = true
}
private handleEdit(scope: any) {
this.dialogType = 'edit'
this.dialogVisible = true
this.checkStrictly = true
this.role = cloneDeep(scope.row)
this.role.pstr = this.role.permissions.join(',')
}
private handleDelete(scope: any) {
const { $index, row } = scope
this.$confirm('Confirm to remove the role?', 'Warning', {
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
type: 'warning'
})
.then(async() => {
await deleteRole(row.key)
this.rolesList.splice($index, 1)
this.$message({
type: 'success',
message: 'Deleted!'
})
})
.catch(err => { console.error(err) })
}
private async confirmRole() {
const isEdit = this.dialogType === 'edit'
this.role.permissions = this.role.pstr.split(',')
const { data } = await saveRole(this.role)
if (isEdit) {
for (let index = 0; index < this.rolesList.length; index++) {
if (this.rolesList[index].key === this.role.key) {
this.rolesList.splice(index, 1, Object.assign({}, this.role))
break
}
}
} else {
this.rolesList.push(this.role)
}
const { permissions, key, name } = this.role
this.dialogVisible = false
this.$notify({
title: 'Success',
dangerouslyUseHTMLString: true,
message: `
<div>Role Key: ${key}</div>
<div>Role Name: ${name}</div>
<div>Description: ${permissions}</div>
`,
type: 'success'
})
}
}
</script>
<style lang="scss" scoped>
.app-container {
.roles-table {
margin-top: 30px;
}
.permission-tree {
margin-bottom: 30px;
}
}
</style>