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

4 years ago
<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)">
<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) {
this.loadFromData(this.list[$index])
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/addPermission',
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/updatePermission',
method: 'post',
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/deletePermission',
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>