You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
499 lines
17 KiB
499 lines
17 KiB
<template>
|
|
<div class="app-container">
|
|
<div class="filter-container">
|
|
<sticky style="margin-bottom: 10px;">
|
|
<div class="sub-navbar">
|
|
<el-button type="primary" icon="el-icon-edit" @click="showCreate">
|
|
添加
|
|
</el-button>
|
|
</div>
|
|
</sticky>
|
|
<el-form size="mini">
|
|
<el-form-item>
|
|
<el-input v-model="listQuery.title" placeholder="请输入要查询的菜单名称" clearable style="width: 230px" @keyup.enter.native="handleFilter" />
|
|
<el-button type="primary" icon="el-icon-search" @click="handleFilter">
|
|
查询
|
|
</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</div>
|
|
<el-table
|
|
ref="list"
|
|
:data="list"
|
|
border
|
|
fit
|
|
size="mini"
|
|
highlight-current-row
|
|
row-key="id"
|
|
:default-sort="{prop: 'sort'}"
|
|
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
|
@row-click="onRowClick"
|
|
@selection-change="handleSelectionChange"
|
|
>
|
|
<el-table-column label="菜单名称" prop="title" />
|
|
<el-table-column align="center" label="菜单代码" prop="name" width="100px" />
|
|
<el-table-column align="center" prop="icon" label="图标" width="100px">
|
|
<template slot-scope="scope">
|
|
<svg-icon v-if="scope.row.icon" :icon-class="scope.row.icon" />
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column align="center" prop="menu" label="权限标识" width="100px" />
|
|
<el-table-column align="center" prop="path" label="路由地址" />
|
|
<el-table-column align="center" prop="sort" label="排序" width="80px" />
|
|
<el-table-column align="center" prop="component" label="组件路径" />
|
|
<el-table-column align="center" prop="cache" label="缓存" width="80px">
|
|
<template slot-scope="scope">
|
|
<span v-if="scope.row.cache">是</span>
|
|
<span v-else>否</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column align="center" prop="hidden" label="可见" width="80px">
|
|
<template slot-scope="scope">
|
|
<span v-if="scope.row.hidden">否</span>
|
|
<span v-else>是</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column align="center" prop="iframe" label="外链" width="80px">
|
|
<template slot-scope="scope">
|
|
<span v-if="scope.row.iframe">是</span>
|
|
<span v-else>否</span>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column align="center" prop="createTime" label="创建日期" width="160px" />
|
|
<el-table-column align="center" label="操作" width="180" fixed="right">
|
|
<template slot-scope="scope">
|
|
<el-button type="primary" icon="el-icon-edit" size="mini" title="编辑" @click="showUpdate(scope.row)" />
|
|
<el-popover
|
|
:ref="scope.row.id"
|
|
placement="top"
|
|
width="200"
|
|
>
|
|
<p>确定删除吗,如果存在下级节点则一并删除,此操作不能撤销!</p>
|
|
<div style="text-align: right; margin: 0">
|
|
<el-button type="text" size="mini" @click="$refs[scope.row.id].doClose()">
|
|
取消
|
|
</el-button>
|
|
<el-button type="primary" size="mini" @click="deletePermission(scope.row.id)">
|
|
确定
|
|
</el-button>
|
|
</div>
|
|
<el-button slot="reference" size="mini" type="danger" icon="el-icon-delete" />
|
|
</el-popover>
|
|
<el-button type="primary" size="mini" title="复制" @click="copyMenu(scope.$index, scope.row)">
|
|
<svg-icon icon-class="clipboard" />
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
|
<el-form
|
|
ref="tempPermission"
|
|
:model="tempPermission"
|
|
:rules="rules"
|
|
class="small-space"
|
|
label-width="100px"
|
|
style="margin-left:50px;height: 450px;"
|
|
size="mini"
|
|
>
|
|
<el-row :gutter="10">
|
|
<el-col :span="11">
|
|
<el-form-item label="菜单标题" prop="title">
|
|
<el-input v-model="tempPermission.title" placeholder="填写菜单标题" :min="0" :max="100" type="text" />
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="11">
|
|
<el-form-item label="菜单代码" prop="name">
|
|
<el-input v-model="tempPermission.name" placeholder="如base、BaseList" :min="0" :max="100" type="text" />
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="10">
|
|
<el-col :span="11">
|
|
<el-form-item label="菜单图标" prop="icon">
|
|
<el-popover
|
|
placement="bottom-start"
|
|
width="450"
|
|
trigger="click"
|
|
@show="$refs['iconSelect'].reset()"
|
|
>
|
|
<IconSelect ref="iconSelect" @selected="selected" />
|
|
<el-input slot="reference" v-model="icon" placeholder="点击选择图标" readonly>
|
|
<svg-icon v-if="icon" :icon-class="icon" class="el-input__icon" style="height: 32px;width: 16px;" />
|
|
<i v-else slot="prefix" class="el-icon-search el-input__icon" />
|
|
</el-input>
|
|
</el-popover>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="11">
|
|
<el-form-item label="权限标识" prop="menu">
|
|
<el-input v-model="tempPermission.menu" placeholder="如base" :min="0" :max="50" type="text" />
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="10">
|
|
<el-col :span="11">
|
|
<el-form-item label="路由地址" prop="path">
|
|
<el-input v-model="tempPermission.path" placeholder="如base、base-list" :min="0" :max="200" type="text" />
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="11">
|
|
<el-form-item label="菜单排序" prop="sort">
|
|
<el-input-number v-model.number="tempPermission.sort" placeholder="菜单序号" :min="0" :max="999" />
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="10">
|
|
<el-col :span="11">
|
|
<el-form-item label="组件路径" prop="component">
|
|
<el-input v-model="tempPermission.component" placeholder="如Layout" :min="0" :max="50" type="text" />
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="11">
|
|
<el-form-item label="上级类目" prop="pid">
|
|
<el-cascader
|
|
v-model="pid"
|
|
:options="menus"
|
|
:props="{ value: 'id', label: 'title', checkStrictly: true }"
|
|
clearable
|
|
placeholder="选择上级类目"
|
|
size="mini"
|
|
style="width: 100%;"
|
|
/>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="10">
|
|
<el-col :span="11">
|
|
<el-form-item label="菜单缓存" prop="cache">
|
|
<el-radio-group v-model="tempPermission.cache">
|
|
<el-radio-button label="true">
|
|
是
|
|
</el-radio-button>
|
|
<el-radio-button label="false">
|
|
否
|
|
</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-col>
|
|
<el-col :span="11">
|
|
<el-form-item label="外链菜单" prop="iframe">
|
|
<el-radio-group v-model="tempPermission.iframe">
|
|
<el-radio-button label="true">
|
|
是
|
|
</el-radio-button>
|
|
<el-radio-button label="false">
|
|
否
|
|
</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row :gutter="10">
|
|
<el-col :span="11">
|
|
<el-form-item label="菜单可见" prop="hidden">
|
|
<el-radio-group v-model="tempPermission.hidden">
|
|
<el-radio-button label="false">
|
|
是
|
|
</el-radio-button>
|
|
<el-radio-button label="true">
|
|
否
|
|
</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-row>
|
|
<el-form-item label="所含资源" prop="useless">
|
|
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
|
|
全选
|
|
</el-checkbox>
|
|
<!-- <span style="margin-left: 20px;color: red;">列表选项默认必选!</span>-->
|
|
<el-checkbox-group v-model="checkedPermissions" @change="handleCheckedCitiesChange">
|
|
<el-checkbox v-for="permission in permissionTypeList" :key="permission.code" :label="permission.code">
|
|
{{ permission.name }}
|
|
</el-checkbox>
|
|
</el-checkbox-group>
|
|
</el-form-item>
|
|
</el-form>
|
|
<div slot="footer" class="dialog-footer">
|
|
<el-button size="mini" @click="dialogFormVisible = false">
|
|
取 消
|
|
</el-button>
|
|
<el-button v-if="dialogStatus==='create'" size="mini" type="success" @click="createPermission">
|
|
创 建
|
|
</el-button>
|
|
<el-button v-else size="mini" type="primary" @click="updatePermission">
|
|
修 改
|
|
</el-button>
|
|
</div>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Sticky from '@/components/Sticky'
|
|
import IconSelect from '@/components/IconSelect'
|
|
export default {
|
|
name: 'PermissionList',
|
|
components: { Sticky, IconSelect },
|
|
data() {
|
|
return {
|
|
list: [], // 表格的数据
|
|
menus: [], // 上级菜单列表
|
|
pid: [],
|
|
listQuery: {},
|
|
textMap: {
|
|
update: '编辑菜单',
|
|
create: '新建菜单'
|
|
},
|
|
tempPermission: {},
|
|
dialogStatus: 'create',
|
|
dialogFormVisible: false,
|
|
icon: '',
|
|
rules: {
|
|
name: [
|
|
{ required: true, message: '请填写菜单代码', trigger: 'blur' }
|
|
],
|
|
title: [
|
|
{ required: true, message: '请填写菜单名称', trigger: 'blur' }
|
|
],
|
|
path: [
|
|
{ required: true, message: '请填写路由地址', trigger: 'blur' }
|
|
],
|
|
// menu: [
|
|
// { required: true, message: '请填写权限标识', trigger: 'change' }
|
|
// ],
|
|
component: [
|
|
{ required: true, message: '请填写组件路径', trigger: 'blur' }
|
|
]
|
|
},
|
|
permissionTypeList: [],
|
|
multipleSelection: [],
|
|
checkAll: false,
|
|
checkAllPermission: [],
|
|
checkedPermissions: [],
|
|
isIndeterminate: false
|
|
}
|
|
},
|
|
created() {
|
|
this.getList()
|
|
this.getPermissionTypeList()
|
|
},
|
|
methods: {
|
|
handleCheckAllChange(val) {
|
|
if (val) {
|
|
this.permissionTypeList.forEach(ad => {
|
|
this.checkedPermissions.push(ad.code)
|
|
})
|
|
} else {
|
|
this.checkedPermissions = []
|
|
}
|
|
this.isIndeterminate = false
|
|
},
|
|
handleCheckedCitiesChange(value) {
|
|
const checkedCount = value.length
|
|
this.checkAll = checkedCount === this.permissionTypeList.length
|
|
this.isIndeterminate = checkedCount > 0 && checkedCount < this.permissionTypeList.length
|
|
},
|
|
getList() {
|
|
// 查询列表
|
|
this.api({
|
|
url: '/permission/list',
|
|
method: 'get',
|
|
params: this.listQuery
|
|
}).then(data => {
|
|
this.list = data
|
|
// 获取菜单类目
|
|
if (!this.listQuery.title) {
|
|
this.menus = []
|
|
const menu = { id: 0, title: '顶级类目', children: [] }
|
|
menu.children = data
|
|
this.menus.push(menu)
|
|
}
|
|
})
|
|
},
|
|
getPermissionTypeList: function() {
|
|
this.api({
|
|
url: '/dicData/getDicDataByTypeCode',
|
|
method: 'get',
|
|
params: {
|
|
typeCode: 'PERMISSION_TYPE',
|
|
parentId: null
|
|
}
|
|
}).then(data => {
|
|
if (data != null) {
|
|
this.permissionTypeList = data.filter(a => a.code !== 'list')
|
|
}
|
|
})
|
|
},
|
|
handleFilter() {
|
|
// 查询事件
|
|
this.getList()
|
|
},
|
|
onRowClick(row) {
|
|
this.$refs.list.toggleRowSelection(row)
|
|
},
|
|
handleSelectionChange: function(val) {
|
|
this.multipleSelection = val
|
|
},
|
|
selected(name) {
|
|
this.icon = name
|
|
},
|
|
showCreate() {
|
|
this.api({
|
|
url: '/permission/getPermissionMaxSort',
|
|
method: 'get'
|
|
}).then(data => {
|
|
this.tempPermission = {
|
|
sort: data + 1,
|
|
iframe: false,
|
|
cache: true,
|
|
hidden: false
|
|
}
|
|
})
|
|
this.pid = []
|
|
this.checkedPermissions = []
|
|
this.isIndeterminate = false
|
|
this.checkAll = false
|
|
this.icon = ''
|
|
this.dialogStatus = 'create'
|
|
this.showTempPermissionForm(true)
|
|
},
|
|
copyMenu($index, row) {
|
|
const data = row.pid ? this.list.filter(tempRow => tempRow.id === row.pid)[0].children.filter(tempRow => tempRow.id === row.id)[0] : this.list[$index]
|
|
this.loadFromData(data)
|
|
this.dialogStatus = 'create'
|
|
this.showTempPermissionForm(false)
|
|
},
|
|
showUpdate(data) {
|
|
this.loadFromData(data)
|
|
this.dialogStatus = 'update'
|
|
this.showTempPermissionForm(false)
|
|
},
|
|
loadFromData(data) {
|
|
this.$set(this, 'tempPermission', data)
|
|
this.icon = this.tempPermission.icon
|
|
this.pid = this.getPermissionPid(this.menus, this.tempPermission.id)
|
|
this.pid.splice(this.pid.length - 1, 1)
|
|
this.checkedPermissions = []
|
|
this.getPermissionTypesById(this.tempPermission.id)
|
|
},
|
|
showTempPermissionForm(bol) {
|
|
this.dialogFormVisible = true
|
|
if (bol) {
|
|
this.$nextTick(() => {
|
|
this.$refs.tempPermission.resetFields()
|
|
})
|
|
}
|
|
},
|
|
getPermissionPid(data, pid) {
|
|
const temp = []
|
|
// eslint-disable-next-line no-unused-vars
|
|
const forFn = function(arr, pid) {
|
|
for (let i = 0; i < arr.length; i++) {
|
|
const item = arr[i]
|
|
if (item.id === pid) {
|
|
temp.push(item.id)
|
|
if (item.id !== 0) {
|
|
forFn(data, item.pid)
|
|
}
|
|
} else {
|
|
if (item.children) {
|
|
forFn(item.children, pid)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
forFn(data, pid)
|
|
return temp.reverse()
|
|
},
|
|
createPermission() {
|
|
this.$refs['tempPermission'].validate((valid) => {
|
|
if (valid) {
|
|
const pid = this.iconUpdate()
|
|
if (pid) {
|
|
this.api({
|
|
url: '/permission',
|
|
method: 'post',
|
|
data: this.tempPermission
|
|
}).then(() => {
|
|
this.$message.success('添加成功。')
|
|
this.getList()
|
|
this.dialogFormVisible = false
|
|
})
|
|
}
|
|
} else {
|
|
return false
|
|
}
|
|
})
|
|
},
|
|
updatePermission() {
|
|
this.$refs['tempPermission'].validate((valid) => {
|
|
if (valid) {
|
|
const pid = this.iconUpdate()
|
|
if (pid) {
|
|
this.api({
|
|
url: '/permission',
|
|
method: 'put',
|
|
data: this.tempPermission
|
|
}).then(() => {
|
|
this.$message.success('更新成功。')
|
|
this.getList()
|
|
this.dialogFormVisible = false
|
|
})
|
|
}
|
|
} else {
|
|
return false
|
|
}
|
|
})
|
|
},
|
|
iconUpdate() {
|
|
this.tempPermission.pid = this.pid[this.pid.length - 1]
|
|
if (this.tempPermission.pid == null) {
|
|
this.$message.error('请选择上级目录!')
|
|
return false
|
|
}
|
|
this.tempPermission.icon = this.icon
|
|
if (this.checkedPermissions.indexOf('list') < 0) {
|
|
this.checkedPermissions.push('list')
|
|
}
|
|
this.tempPermission.permissionTypes = this.checkedPermissions
|
|
return true
|
|
},
|
|
deletePermission(id) {
|
|
this.$confirm('删除此资源会影响到角色的权限,确定要删除吗?', '提示', {
|
|
confirmButtonText: '确定',
|
|
showCancelButton: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
this.api({
|
|
url: '/permission',
|
|
method: 'delete',
|
|
params: {
|
|
id: id
|
|
}
|
|
}).then(() => {
|
|
this.$message.success('删除成功。')
|
|
this.getList()
|
|
})
|
|
})
|
|
},
|
|
getPermissionTypesById(id) {
|
|
this.api({
|
|
url: '/permission/getPermissionTypesById',
|
|
method: 'get',
|
|
params: {
|
|
permissionId: id
|
|
}
|
|
}).then(data => {
|
|
if (data !== null && data.length > 0) {
|
|
data.filter(d => d.permissionType !== 'list').forEach(d => {
|
|
this.checkedPermissions.push(d.permissionType)
|
|
})
|
|
this.checkAll = this.checkedPermissions.length === this.permissionTypeList.length
|
|
this.isIndeterminate = this.checkedPermissions.length > 0 && this.checkedPermissions.length < this.permissionTypeList.length
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|