296 lines
7.3 KiB
Vue
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>
|