增加权限管理
This commit is contained in:
parent
51145413ca
commit
3f1b287057
@ -1,5 +1,29 @@
|
||||
import request from '@/utils/request'
|
||||
export interface IAdmin {
|
||||
id: string
|
||||
username: string
|
||||
showname: string
|
||||
comment: string
|
||||
locked: boolean
|
||||
roles: string[]
|
||||
sex: string
|
||||
avatar: string
|
||||
password: string
|
||||
department: string
|
||||
}
|
||||
|
||||
export const defaultAdmin: IAdmin = {
|
||||
id: '',
|
||||
username: '',
|
||||
showname: '',
|
||||
comment: '',
|
||||
locked: false,
|
||||
roles: [],
|
||||
sex: '0',
|
||||
password: '',
|
||||
avatar: '',
|
||||
department: ''
|
||||
}
|
||||
export const getAdminInfo = (data: any) =>
|
||||
request({
|
||||
url: '/admin/info',
|
||||
|
22
src/api/permissions.ts
Normal file
22
src/api/permissions.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export const getPermissions = (params: any) =>
|
||||
request({
|
||||
url: '/permissions',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
|
||||
export const savePermission = (data: any) =>
|
||||
request({
|
||||
url: '/permission',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
|
||||
export const deletePermission = (id: number) =>
|
||||
request({
|
||||
url: `/permission/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
|
@ -38,6 +38,7 @@ import './password'
|
||||
import './pdf'
|
||||
import './people'
|
||||
import './peoples'
|
||||
import './permission'
|
||||
import './points'
|
||||
import './promo'
|
||||
import './qq'
|
||||
|
12
src/icons/components/permission.ts
Normal file
12
src/icons/components/permission.ts
Normal file
@ -0,0 +1,12 @@
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
// @ts-ignore
|
||||
import icon from 'vue-svgicon'
|
||||
icon.register({
|
||||
'permission': {
|
||||
width: 64,
|
||||
height: 64,
|
||||
viewBox: '0 0 1024 1024',
|
||||
data: '<defs/><path pid="0" d="M679.413 45.034c-156.304 0-283.008 126.702-283.008 283.008 0 17.717 1.641 35.036 4.754 51.847L56.796 724.253V894.06c0 31.273 25.329 56.602 56.602 56.602H170v-56.603h113.203V780.855h113.203V667.652h84.146c27.923-117.059 133.172-204.086 258.79-204.086 57.558 0 110.839 18.273 154.37 49.33 42.814-49.59 68.71-114.196 68.71-184.855 0-156.306-126.702-283.007-283.009-283.007zm84.79 283.12c-46.895 0-84.902-38.008-84.902-84.903 0-46.894 38.007-84.903 84.903-84.903 46.894 0 84.902 38.01 84.902 84.903 0 46.896-38.008 84.903-84.902 84.903z"/><path pid="1" d="M952.278 684.148h-42.187c-3.974-8.568-9.615-26.392-16.83-39.094l29.796-28.954c9.409-9.408 9.417-24.208.018-33.598l-34.01-33.805c-9.392-9.394-24.62-9.292-34.028.111l-28.133 29.836c-12.682-7.205-30.505-12.802-39.074-16.777v-42.18c0-13.299-14.088-24.06-27.362-24.06H712.37c-13.282 0-27.37 10.761-27.37 24.06v42.188c-8.569 3.975-26.382 9.615-39.081 16.822l-28.965-29.796c-9.407-9.409-24.216-9.409-33.6-.018l-33.805 34.02c-9.384 9.383-9.297 24.61.112 34.029l29.846 28.13c-7.216 12.7-12.803 30.516-16.78 39.086H520.55c-13.308 0-24.07 14.087-24.07 27.359v48.097c0 13.276 10.763 27.372 24.07 27.372h42.186c3.977 8.57 9.624 26.384 16.821 39.083l-29.793 28.973c-9.41 9.407-9.41 24.197-.018 33.589l34.01 33.815c9.381 9.38 24.618 9.285 34.029-.122l28.13-29.846c12.7 7.21 30.513 12.804 39.083 16.778v42.186c0 13.3 14.087 24.064 27.36 24.064h48.1c13.272 0 27.37-10.765 27.37-24.07v-42.187c8.569-3.977 26.381-9.62 39.09-16.828l28.966 29.794c9.407 9.409 24.198 9.409 33.59.016l33.814-34.009c9.383-9.392 9.286-24.621-.121-34.027l-29.847-28.132c7.207-12.702 12.804-30.506 16.778-39.076h42.19c13.297 0 24.061-14.09 24.061-27.361v-48.1c0-13.282-10.762-27.368-24.07-27.368zM736.415 843.763c-59.77 0-108.221-48.45-108.221-108.21 0-59.772 48.451-108.22 108.22-108.22 59.78 0 108.22 48.448 108.22 108.22 0 59.76-48.44 108.21-108.22 108.21z"/>'
|
||||
}
|
||||
})
|
1
src/icons/svg/permission.svg
Normal file
1
src/icons/svg/permission.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1619341321242" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6926" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M679.413 45.034c-156.304 0-283.008 126.702-283.008 283.008 0 17.717 1.641 35.036 4.754 51.847L56.796 724.253V894.06c0 31.273 25.329 56.602 56.602 56.602H170v-56.603h113.203V780.855h113.203V667.652h84.146c27.923-117.059 133.172-204.086 258.79-204.086 57.558 0 110.839 18.273 154.37 49.33 42.814-49.59 68.71-114.196 68.71-184.855 0-156.306-126.702-283.007-283.009-283.007z m84.79 283.12c-46.895 0-84.902-38.008-84.902-84.903 0-46.894 38.007-84.903 84.903-84.903 46.894 0 84.902 38.01 84.902 84.903 0 46.896-38.008 84.903-84.902 84.903z" p-id="6927"></path><path d="M952.278 684.148h-42.187c-3.974-8.568-9.615-26.392-16.83-39.094l29.796-28.954c9.409-9.408 9.417-24.208 0.018-33.598l-34.01-33.805c-9.392-9.394-24.62-9.292-34.028 0.111l-28.133 29.836c-12.682-7.205-30.505-12.802-39.074-16.777v-42.18c0-13.299-14.088-24.06-27.362-24.06H712.37c-13.282 0-27.37 10.761-27.37 24.06v42.188c-8.569 3.975-26.382 9.615-39.081 16.822l-28.965-29.796c-9.407-9.409-24.216-9.409-33.6-0.018l-33.805 34.02c-9.384 9.383-9.297 24.61 0.112 34.029l29.846 28.13c-7.216 12.7-12.803 30.516-16.78 39.086H520.55c-13.308 0-24.07 14.087-24.07 27.359v48.097c0 13.276 10.763 27.372 24.07 27.372h42.186c3.977 8.57 9.624 26.384 16.821 39.083l-29.793 28.973c-9.41 9.407-9.41 24.197-0.018 33.589l34.01 33.815c9.381 9.38 24.618 9.285 34.029-0.122l28.13-29.846c12.7 7.21 30.513 12.804 39.083 16.778v42.186c0 13.3 14.087 24.064 27.36 24.064h48.1c13.272 0 27.37-10.765 27.37-24.07v-42.187c8.569-3.977 26.381-9.62 39.09-16.828l28.966 29.794c9.407 9.409 24.198 9.409 33.59 0.016l33.814-34.009c9.383-9.392 9.286-24.621-0.121-34.027l-29.847-28.132c7.207-12.702 12.804-30.506 16.778-39.076h42.19c13.297 0 24.061-14.09 24.061-27.361v-48.1c0-13.282-10.762-27.368-24.07-27.368zM736.415 843.763c-59.77 0-108.221-48.45-108.221-108.21 0-59.772 48.451-108.22 108.22-108.22 59.78 0 108.22 48.448 108.22 108.22 0 59.76-48.44 108.21-108.22 108.21z" p-id="6928"></path></svg>
|
After Width: | Height: | Size: 2.2 KiB |
@ -78,6 +78,7 @@ export default {
|
||||
createQuestion: 'Create Question',
|
||||
shop: 'Shop Setting',
|
||||
shop_list: 'Shop List',
|
||||
shop_admin: 'Shop Admins',
|
||||
create_shop: 'Create Shop',
|
||||
shop_edit: 'Shop Editor',
|
||||
game_setting: 'Game Setting',
|
||||
|
@ -5,7 +5,7 @@ export default {
|
||||
system: '系统',
|
||||
adminuser: '管理员',
|
||||
guide: '引导页',
|
||||
permission: '权限测试页',
|
||||
permission: '权限管理',
|
||||
rolePermission: '角色权限',
|
||||
pagePermission: '页面权限',
|
||||
directivePermission: '指令权限',
|
||||
@ -78,6 +78,7 @@ export default {
|
||||
createQuestion: '创建题目',
|
||||
shop: '店铺设置',
|
||||
shop_list: '店铺列表',
|
||||
shop_admin: '店铺管理员',
|
||||
create_shop: '创建店铺',
|
||||
shop_edit: '编辑店铺',
|
||||
game_setting: '游戏设置',
|
||||
|
@ -10,6 +10,16 @@ const shopRoutes: RouteConfig = {
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'shopadmin',
|
||||
component: () => import('@/views/shop/shop_admin.vue'),
|
||||
name: 'ShopAdmin',
|
||||
meta: {
|
||||
title: 'shop_admin',
|
||||
permissions: ['adminuser:read'],
|
||||
icon: 'admin'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'setting',
|
||||
component: () => import('@/views/game/game_setting.vue'),
|
||||
|
@ -11,6 +11,16 @@ const systemRoutes: RouteConfig = {
|
||||
alwaysShow: true
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'permission',
|
||||
component: () => import('@/views/system/permission.vue'),
|
||||
name: 'Permission',
|
||||
meta: {
|
||||
title: 'permission',
|
||||
permissions: ['role:read'],
|
||||
icon: 'permission'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'role',
|
||||
component: () => import('@/views/system/role.vue'),
|
||||
|
524
src/views/shop/shop_admin.vue
Normal file
524
src/views/shop/shop_admin.vue
Normal file
@ -0,0 +1,524 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- filter -->
|
||||
<el-form ref="filterForm" :inline="true" :model="filterForm" class="filter">
|
||||
<el-form-item label="关键字" prop="key">
|
||||
<el-input v-model="filterForm.key" placeholder="关键字"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色">
|
||||
<el-select
|
||||
v-model="filterForm.role"
|
||||
placeholder="所有"
|
||||
class="w100"
|
||||
>
|
||||
<el-option value="">所有</el-option>
|
||||
<el-option
|
||||
v-for="item in roleList"
|
||||
:key="item.key"
|
||||
:label="item.name"
|
||||
:value="item.key"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="店铺">
|
||||
<el-select
|
||||
v-model="filterForm.department"
|
||||
placeholder="所有"
|
||||
class="w100"
|
||||
>
|
||||
<el-option value="">所有</el-option>
|
||||
<el-option value="未指定">未指定</el-option>
|
||||
<el-option
|
||||
v-for="item in allDepts"
|
||||
:key="item._id"
|
||||
:label="item.name"
|
||||
:value="item._id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="search">查询</el-button>
|
||||
<el-button @click="resetFilterForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleCreateAdmin"
|
||||
>
|
||||
{{$t('admin.addAdmin')}}
|
||||
</el-button>
|
||||
|
||||
<el-table
|
||||
v-loading="isLoad"
|
||||
:data="tableData"
|
||||
style="width: 100%;margin-top:30px;"
|
||||
border
|
||||
>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="帐号名"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
{{row.username}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="显示名"
|
||||
>
|
||||
<template slot-scope="{row}">
|
||||
{{row.showname}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="sex"
|
||||
align="center"
|
||||
label="性别"
|
||||
:formatter="formSex"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="角色"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-tag
|
||||
v-for="(item, index) in scope.row.roles"
|
||||
:key="index"
|
||||
size="small"
|
||||
style="margin-right: 10px;"
|
||||
>{{ formatRole(item) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="department"
|
||||
align="center"
|
||||
label="店铺"
|
||||
:formatter = "formatDept"
|
||||
>
|
||||
|
||||
</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="操作"
|
||||
fixed="right"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="handleEdit(scope)"
|
||||
>
|
||||
{{$t('admin.editAdmin')}}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
@click="handleDelete(scope)"
|
||||
>
|
||||
{{$t('permission.delete')}}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- pagination -->
|
||||
<el-pagination
|
||||
:hide-on-single-page="false"
|
||||
:current-page="currentPage"
|
||||
:page-sizes="[5, 10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="dataCount"
|
||||
class="al-r"
|
||||
@size-change="sizeChange"
|
||||
@current-change="pageChange"
|
||||
/>
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
:title="dialogType==='edit'?'Edit Admin':'New Admin'"
|
||||
>
|
||||
<el-form
|
||||
:model="record"
|
||||
ref="modalForm"
|
||||
:rules="modalRules"
|
||||
label-width="80px"
|
||||
label-position="left"
|
||||
>
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input
|
||||
v-model="record.username"
|
||||
placeholder="用户名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" v-if="dialogType==='edit'">
|
||||
<el-input
|
||||
type="password"
|
||||
v-model="record.password"
|
||||
placeholder="不修改就留空"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" v-if="dialogType!=='edit'">
|
||||
<el-input
|
||||
type="password"
|
||||
v-model="record.password"
|
||||
placeholder="密码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示名" prop="showname">
|
||||
<el-input
|
||||
v-model="record.showname"
|
||||
placeholder="显示名"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别">
|
||||
<el-radio-group v-model="record.sex">
|
||||
<el-radio label="0">未指定</el-radio>
|
||||
<el-radio label="1">男</el-radio>
|
||||
<el-radio label="2">女</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色">
|
||||
<el-checkbox-group v-model="record.roles">
|
||||
<el-checkbox v-for="role in roleList"
|
||||
:key="role.key"
|
||||
:label="role.key"
|
||||
name="type"
|
||||
>{{role.name}}
|
||||
</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="店铺"
|
||||
class="postInfo-container-item"
|
||||
>
|
||||
<el-select
|
||||
v-model="record.department"
|
||||
:remote-method="getRemoteDeptList"
|
||||
filterable
|
||||
default-first-option
|
||||
remote
|
||||
placeholder=""
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in deptListOptions"
|
||||
:key="item._id"
|
||||
:label="item.name"
|
||||
:value="item._id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="锁定">
|
||||
<el-switch v-model="record.locked"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input
|
||||
v-model="record.comment"
|
||||
:autosize="{minRows: 2, maxRows: 4}"
|
||||
type="textarea"
|
||||
placeholder="备注"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="text-align:right;">
|
||||
<el-button
|
||||
type="danger"
|
||||
@click="closeModal"
|
||||
>
|
||||
{{$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 { getRoles } from '@/api/roles'
|
||||
import {
|
||||
defaultAdmin,
|
||||
deleteAdmin,
|
||||
getUsers,
|
||||
IAdmin,
|
||||
saveAdmin
|
||||
} from '@/api/admins'
|
||||
import { IRole } from '@/views/system/role.vue'
|
||||
import { getShops } from '@/api/shop'
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
name: 'ShopAdmin',
|
||||
components: {
|
||||
}
|
||||
})
|
||||
export default class extends Vue {
|
||||
private record = Object.assign({}, defaultAdmin)
|
||||
private adminList: IAdmin[] = []
|
||||
private tableData: IAdmin[] = []
|
||||
private roleList: IRole[] = []
|
||||
private dialogVisible = false
|
||||
private dialogType = 'new'
|
||||
private checkStrictly = false
|
||||
private isLoad = false
|
||||
// pagination
|
||||
private currentPage = 1
|
||||
private pageSize = 5
|
||||
private dataCount = 0
|
||||
private deptListOptions = []
|
||||
private allDepts = []
|
||||
private defaultProps = {
|
||||
children: 'children',
|
||||
label: 'title'
|
||||
}
|
||||
|
||||
private filterForm = {
|
||||
key: '',
|
||||
role: '',
|
||||
department: ''
|
||||
}
|
||||
|
||||
$refs!: {
|
||||
modalForm: HTMLFormElement
|
||||
filterForm: HTMLFormElement
|
||||
}
|
||||
|
||||
private modalRules = {
|
||||
username: [{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
{ min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9.·-]+$/,
|
||||
message: '用户名不支持特殊字符',
|
||||
trigger: 'blur'
|
||||
}],
|
||||
showname: [{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||
{ min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9.·-]+$/,
|
||||
message: '显示名不支持特殊字符',
|
||||
trigger: 'blur'
|
||||
}]
|
||||
}
|
||||
|
||||
async created() {
|
||||
this.allDepts = await this.getRemoteDeptList('')
|
||||
this.getRecords()
|
||||
this.getAllRole()
|
||||
}
|
||||
|
||||
private search() {
|
||||
this.tableData = this.filterData()
|
||||
this.currentPage = 1
|
||||
}
|
||||
|
||||
private filterData() {
|
||||
let result = [...this.adminList]
|
||||
if (this.filterForm.key) {
|
||||
result = result.filter(user => {
|
||||
const reg = new RegExp(this.filterForm.key)
|
||||
return (reg.test(user.showname)) || (reg.test(user.username))
|
||||
})
|
||||
}
|
||||
if (this.filterForm.role) {
|
||||
result = result.filter(user => {
|
||||
return user.roles.indexOf(this.filterForm.role) >= 0
|
||||
})
|
||||
}
|
||||
if (this.filterForm.department) {
|
||||
if (this.filterForm.department == '未指定') {
|
||||
result = result.filter(user => {
|
||||
return !user.department
|
||||
})
|
||||
} else {
|
||||
result = result.filter(user => {
|
||||
return user.department == this.filterForm.department
|
||||
})
|
||||
}
|
||||
}
|
||||
this.dataCount = result.length
|
||||
return result
|
||||
}
|
||||
|
||||
private resetFilterForm() {
|
||||
this.$refs.filterForm.resetFields()
|
||||
}
|
||||
|
||||
// pagination
|
||||
private sizeChange(val: number) {
|
||||
this.pageSize = val
|
||||
this.sliceData()
|
||||
}
|
||||
|
||||
private pageChange(val: number) {
|
||||
this.currentPage = val
|
||||
this.sliceData()
|
||||
}
|
||||
|
||||
private sliceData() {
|
||||
// 满足过滤条件 -> 分页
|
||||
const data = this.filterData()
|
||||
this.tableData = data.slice(
|
||||
(this.currentPage - 1) * this.pageSize,
|
||||
this.currentPage * this.pageSize
|
||||
)
|
||||
}
|
||||
|
||||
private async getRecords() {
|
||||
this.isLoad = true
|
||||
const { data } = await getUsers({ /* Your params here */ })
|
||||
this.adminList = data
|
||||
this.dataCount = data.length
|
||||
this.sliceData()
|
||||
this.isLoad = false
|
||||
}
|
||||
|
||||
private async getAllRole() {
|
||||
const { data } = await getRoles({ /* Your params here */ })
|
||||
this.roleList = data
|
||||
}
|
||||
|
||||
private formSex(row: number, column: number, cellValue: string) {
|
||||
switch (cellValue) {
|
||||
case '0':
|
||||
return '未指定'
|
||||
case '1':
|
||||
return '男'
|
||||
case '2':
|
||||
return '女'
|
||||
default:
|
||||
return '未指定'
|
||||
}
|
||||
}
|
||||
|
||||
private formatRole(val: string) {
|
||||
const data = this.roleList.find(o => {
|
||||
return o.key === val
|
||||
})
|
||||
return data?.name || ''
|
||||
}
|
||||
|
||||
private handleCreateAdmin() {
|
||||
this.record = Object.assign({}, defaultAdmin)
|
||||
|
||||
this.dialogType = 'new'
|
||||
this.dialogVisible = true
|
||||
}
|
||||
|
||||
private handleEdit(scope: any) {
|
||||
this.dialogType = 'edit'
|
||||
this.dialogVisible = true
|
||||
this.checkStrictly = true
|
||||
this.record = cloneDeep(scope.row)
|
||||
}
|
||||
|
||||
private handleDelete(scope: any) {
|
||||
const { $index, row } = scope
|
||||
this.$confirm('Confirm to remove the record?', 'Warning', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(async() => {
|
||||
await deleteAdmin(row.id)
|
||||
this.adminList.splice($index, 1)
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: 'Deleted!'
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
|
||||
private closeModal() {
|
||||
this.dialogVisible = false
|
||||
this.$refs.modalForm.clearValidate()
|
||||
}
|
||||
|
||||
private async confirmRole() {
|
||||
const isEdit = this.dialogType === 'edit'
|
||||
this.$refs.modalForm.validate(async(valid: boolean) => {
|
||||
if (!valid) {
|
||||
this.$message.error('请按要求填写表单')
|
||||
return false
|
||||
}
|
||||
const { data } = await saveAdmin(this.record)
|
||||
console.log(data)
|
||||
if (isEdit) {
|
||||
for (let index = 0; index < this.adminList.length; index++) {
|
||||
if (this.adminList[index].id === this.record.id) {
|
||||
this.adminList.splice(index, 1, Object.assign({}, this.record))
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.adminList.push(data)
|
||||
}
|
||||
this.sliceData()
|
||||
const { username, showname } = this.record
|
||||
this.dialogVisible = false
|
||||
this.$notify({
|
||||
title: 'Success',
|
||||
dangerouslyUseHTMLString: true,
|
||||
message: `
|
||||
<div>Admin Username: ${username}</div>
|
||||
<div>Admin Showname: ${showname}</div>
|
||||
`,
|
||||
type: 'success'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private async getRemoteDeptList(name: string) {
|
||||
const { data } = await getShops({ key: name })
|
||||
if (!data.records) return
|
||||
this.deptListOptions = data.records
|
||||
return data.records
|
||||
}
|
||||
|
||||
private formatDept(row: number, column: number, cellValue: string, index: number) {
|
||||
let result = '未指定'
|
||||
for (const dep of this.allDepts) {
|
||||
if (dep._id == cellValue) {
|
||||
result = dep.name
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
.roles-table {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.permission-tree {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
read-only {
|
||||
color: #a09d9d;
|
||||
}
|
||||
</style>
|
@ -250,35 +250,17 @@
|
||||
import { cloneDeep } from 'lodash'
|
||||
import { Component, Vue } from 'vue-property-decorator'
|
||||
import { getRoles } from '@/api/roles'
|
||||
import { deleteAdmin, getUsers, saveAdmin } from '@/api/admins'
|
||||
import {
|
||||
defaultAdmin,
|
||||
deleteAdmin,
|
||||
getUsers,
|
||||
IAdmin,
|
||||
saveAdmin
|
||||
} from '@/api/admins'
|
||||
import { IRole } from '@/views/system/role.vue'
|
||||
import { getShops } from '@/api/shop'
|
||||
|
||||
interface IAdmin {
|
||||
id: string
|
||||
username: string
|
||||
showname: string
|
||||
comment: string
|
||||
locked: boolean
|
||||
roles: string[]
|
||||
sex: string
|
||||
avatar: string
|
||||
password: string
|
||||
department: string
|
||||
}
|
||||
|
||||
const defaultAdmin: IAdmin = {
|
||||
id: '',
|
||||
username: '',
|
||||
showname: '',
|
||||
comment: '',
|
||||
locked: false,
|
||||
roles: [],
|
||||
sex: '0',
|
||||
password: '',
|
||||
avatar: '',
|
||||
department: ''
|
||||
}
|
||||
|
||||
@Component({
|
||||
name: 'AdminSystem',
|
||||
|
345
src/views/system/permission.vue
Normal file
345
src/views/system/permission.vue
Normal file
@ -0,0 +1,345 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row style="margin-bottom: 24px;">
|
||||
<el-col :span="12" :offset="2">
|
||||
<el-button
|
||||
type="primary"
|
||||
v-loading="loading"
|
||||
@click="saveVal"
|
||||
>
|
||||
保存
|
||||
</el-button>
|
||||
<el-button @click="onCancel">
|
||||
取消
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12" :offset="2">
|
||||
<el-tree
|
||||
:data="typeOptions"
|
||||
accordion
|
||||
node-key="id"
|
||||
ref="tree"
|
||||
highlight-current
|
||||
default-expand-all
|
||||
:expand-on-click-node="false"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<span>{{ node.label }}</span>
|
||||
<span class="action">
|
||||
<a v-if="node.level === 1"
|
||||
@click="append(data)">
|
||||
增加
|
||||
</a>
|
||||
<a v-if="node.level !== 1 && node.level !== 3"
|
||||
@click="edit(node, data)">
|
||||
修改
|
||||
</a>
|
||||
<a v-if="node.level !== 1"
|
||||
@click="remove(node, data)">
|
||||
删除
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
:title="dialogType==='edit'?'编辑权限':'添加权限'"
|
||||
>
|
||||
<el-form
|
||||
:model="record"
|
||||
ref="modalForm"
|
||||
:rules="modalRules"
|
||||
label-width="80px"
|
||||
label-position="left"
|
||||
>
|
||||
<el-form-item label="权限id" prop="id">
|
||||
<el-input
|
||||
v-model="record.id"
|
||||
placeholder="权限id"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="权限名" prop="label">
|
||||
<el-input
|
||||
v-model="record.label"
|
||||
placeholder="权限名"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作名" prop="actions">
|
||||
<el-select
|
||||
v-model="record.actions"
|
||||
multiple
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
style="width: 100%"
|
||||
placeholder="请选择或输入操作">
|
||||
<el-option
|
||||
v-for="item in actions"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="danger"
|
||||
@click="closeModal"
|
||||
>
|
||||
取消
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="savePermission"
|
||||
>
|
||||
确定
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Watch } from 'vue-property-decorator'
|
||||
import { getGames, IGameData } from '@/api/game'
|
||||
import Sticky from '@/components/Sticky/index.vue'
|
||||
import {
|
||||
getShopGameInfo,
|
||||
getShops,
|
||||
saveShopGameInfo,
|
||||
updateShopQtypes
|
||||
} from '@/api/shop'
|
||||
import { getAllCategory } from '@/api/question'
|
||||
import { getPermissions, savePermission } from '@/api/permissions'
|
||||
import { Form } from 'element-ui'
|
||||
|
||||
@Component({
|
||||
name: 'PermissionSetting',
|
||||
components: {
|
||||
Sticky
|
||||
},
|
||||
filters: {
|
||||
parseGameType: (type: number) => {
|
||||
return type === 0 ? '微信小游戏' : '网页版'
|
||||
}
|
||||
}
|
||||
})
|
||||
export default class extends Vue {
|
||||
private loading = true
|
||||
private shop = ''
|
||||
private dialogType = 'new'
|
||||
private dialogVisible = false
|
||||
private record = {actions: []}
|
||||
private actions = [
|
||||
'read', 'edit', 'delete'
|
||||
]
|
||||
|
||||
|
||||
private typeSelected = []
|
||||
private typeOptions: {id: string, label: string, children?: any[]}[] = []
|
||||
private initAdmin() {
|
||||
return {
|
||||
id: '',
|
||||
label: '',
|
||||
actions: []
|
||||
}
|
||||
}
|
||||
private modalRules = {
|
||||
id: [{ required: true, message: '请输入权限id', trigger: 'blur' },
|
||||
{ min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[a-zA-Z]+$/,
|
||||
message: '权限只支持英文字母',
|
||||
trigger: 'blur'
|
||||
}],
|
||||
|
||||
label: [{ required: true, message: '请输入权限名', trigger: 'blur' },
|
||||
{ min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
pattern: /^[\u4e00-\u9fa5_a-zA-Z0-9.·-]+$/,
|
||||
message: '权限名不支持特殊字符',
|
||||
trigger: 'blur'
|
||||
}],
|
||||
|
||||
}
|
||||
async created() {
|
||||
await this.getRemoteCategory()
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
|
||||
private async onCancel() {
|
||||
try {
|
||||
await this.$confirm('确认不保存当前信息?', 'Warning', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
this.$store.dispatch('delView', this.$route)
|
||||
this.$router.go(-1)
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private append(data) {
|
||||
this.record = this.initAdmin()
|
||||
this.dialogType = 'new'
|
||||
this.dialogVisible = true
|
||||
this.record.actions = this.actions
|
||||
this.record.parent = data
|
||||
}
|
||||
private edit(node, data) {
|
||||
console.log(data)
|
||||
this.record = this.initAdmin()
|
||||
this.record.idx = node.parent.data.children.indexOf(data)
|
||||
this.record.actions = data.children.map(o=>o.label)
|
||||
this.record.parent = node.parent.data
|
||||
this.dialogType = 'edit'
|
||||
this.dialogVisible = true
|
||||
this.record.id = data.id
|
||||
this.record.label = data.label
|
||||
}
|
||||
private async remove(node, data) {
|
||||
const parent = node.parent.data;
|
||||
const children = parent.children || parent.data;
|
||||
const index = children.findIndex(d => d.id === data.id);
|
||||
console.log(node, data)
|
||||
try {
|
||||
await this.$confirm('确认删除此权限?', 'Warning', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
})
|
||||
children.splice(index, 1);
|
||||
} catch(err) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
private async saveVal() {
|
||||
try {
|
||||
let records = []
|
||||
for (let data of this.typeOptions[0].children) {
|
||||
records.push({
|
||||
_id: data.id,
|
||||
name: data.label,
|
||||
actions: data.children.map(o => o.label)
|
||||
})
|
||||
}
|
||||
await savePermission({datas: records})
|
||||
console.log(records)
|
||||
this.$notify({
|
||||
title: 'Success',
|
||||
message: '更新权限列表成功',
|
||||
type: 'success',
|
||||
duration: 2000
|
||||
})
|
||||
} catch (err) {
|
||||
console.log('save permission error', err)
|
||||
}
|
||||
}
|
||||
|
||||
private async getRemoteCategory() {
|
||||
const { data } = await getPermissions()
|
||||
|
||||
this.typeOptions.push({
|
||||
id: 'root',
|
||||
label: 'Root',
|
||||
children: data
|
||||
})
|
||||
}
|
||||
private closeModal() {
|
||||
this.dialogVisible = false
|
||||
this.$refs.modalForm.clearValidate()
|
||||
}
|
||||
private async savePermission() {
|
||||
const form = <Form>this.$refs.modalForm
|
||||
try {
|
||||
await form.validate()
|
||||
const subArr = []
|
||||
for (const s of this.record.actions) {
|
||||
subArr.push({
|
||||
id: `${this.record.id}:${s}`,
|
||||
label: s
|
||||
})
|
||||
}
|
||||
let data = {
|
||||
id: this.record.id,
|
||||
label: this.record.label,
|
||||
children: subArr
|
||||
}
|
||||
if (this.dialogType == 'new') {
|
||||
this.record.parent.children.push(data)
|
||||
} else {
|
||||
this.record.parent.children.splice(this.record.idx, 1, data)
|
||||
}
|
||||
|
||||
this.dialogVisible = false
|
||||
this.$refs.modalForm.clearValidate()
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.bottom {
|
||||
margin-top: 13px;
|
||||
line-height: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.bottom span{
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.button {
|
||||
padding: 0;
|
||||
min-height: auto;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.one-block{
|
||||
border: 1px solid #ebebeb;
|
||||
border-radius: 3px;
|
||||
transition: .2s;
|
||||
padding: 24px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
|
||||
}
|
||||
.custom-tree-node .action{
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user