2021-05-08 11:40:49 +08:00

296 lines
7.3 KiB
Vue

<template>
<div class="app-container">
<el-button
type="primary"
@click="handleCreateRole"
>
{{ $t('permission.createRole') }}
</el-button>
<el-table
:data="rolesList"
stripe
style="width: 100%;margin-top:30px;"
border
>
<el-table-column
align="center"
label="角色key"
prop="key"
>
</el-table-column>
<el-table-column
align="center"
label="角色名"
prop="name"
>
</el-table-column>
<el-table-column
align="center"
label="权限"
prop="permissions"
:formatter="formatPermissionCol"
>
</el-table-column>
<el-table-column
align="header-center"
label="备注"
prop="comment"
>
</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="角色key">
<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="操作" prop="permissions">
<el-select
v-model="role.permissions"
multiple
filterable
:filter-method = "filterPermission"
allow-create
default-first-option
style="width: 60%"
@change="permissionChange"
placeholder="请选择权限">
<el-option
v-for="item in filterPermissions"
:key="item.id"
:label="item.label"
:value="item.id">
<span style="float: left">{{ item.label }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.id }}</span>
</el-option>
</el-select>
</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 { cloneDeep } from 'lodash'
import { Component, Vue } from 'vue-property-decorator'
import { deleteRole, getRoles, saveRole } from '@/api/roles'
import TagInput from '@/components/TagInput/index.vue'
import { getPermissions } from '@/api/permissions'
export interface IRole {
key: string
name: string
comment: string
permissions: string[]
}
export interface IPermission {
id: string
label: string
}
const defaultRole: IRole = {
key: '',
name: '',
comment: '',
permissions: []
}
@Component({
name: 'RoleSystem',
components: {
TagInput
}
})
export default class extends Vue {
private role = Object.assign({}, defaultRole)
private rolesList: IRole[] = []
private dialogVisible = false
private dialogType = 'new'
private checkStrictly = false
private permissions: IPermission[] = []
private filterPermissions: IPermission[] = []
async created() {
await this.getRoles()
await this.getRemotePermissions()
}
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)
}
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'
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'
})
}
private async getRemotePermissions() {
const { data } = await getPermissions()
for (const sub of data) {
for (const c of sub.children) {
this.permissions.push({
id: c.id,
label: `${sub.label}:${c.label}`
})
}
}
this.filterPermission()
}
private filterPermission(val?: string) {
if (val) {
this.filterPermissions = this.permissions.filter(data => {
return data.id.indexOf(val) >= 0 || data.label.indexOf(val) >= 0
})
} else {
this.filterPermissions = [...this.permissions]
}
}
private formatPermissionCol(row: number, column: number, cellValue: string[]) {
const results: string[] = []
for (const p of cellValue) {
const data: IPermission | undefined = this.permissions.find(o => o.id === p)
if (data) {
results.push(data.label)
} else {
results.push(p)
}
}
return results.join(',')
}
private permissionChange(vals: string[]) {
if (vals.length > 0) {
const lastVal = this.role.permissions[this.role.permissions.length - 1]
if (!/^([a-zA-Z0-9*]:[a-zA-Z0-9*]|\*)$/.test(lastVal)) {
this.role.permissions.pop()
this.$message({
type: 'error',
message: '权限的格式错误, 比如 app:read, app:*'
})
}
}
}
}
</script>