Files
faw-report-library-web/src/views/System/MenuManager.vue
T
2023-05-16 16:44:19 +08:00

474 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="content-height system-menu-manager">
<div class="title">
<span>菜单管理</span>
</div>
<div class="search">
<el-row>
<el-col :span="24">
<div class="operate-box">
<el-button @click="addMenu(null, 0)">新增菜单</el-button>
</div>
</el-col>
</el-row>
</div>
<div class="table">
<vxe-table :data="tableData" :empty-render="{name: 'NotData'}" align="left" border
:tree-config="{transform: true, rowField: 'id', parentField: 'parentId', expandAll: true }"
v-table-min-height="'calc(100vh - 320px + 44px + 42px)'">
<vxe-column show-overflow show-header-overflow type="seq" title="序号" width="77"></vxe-column>
<vxe-column show-overflow show-header-overflow title="名称" width="300" align="center" tree-node>
<template #default="{ row, level }">
<div class="menu-image">
<el-image v-if="level === 0 || level === 2" :src="row.iconHref"></el-image>
<span>{{row.name}}</span>
</div>
</template>
</vxe-column>
<vxe-column show-overflow show-header-overflow field="href" title="路径" align="center"></vxe-column>
<vxe-column show-overflow show-header-overflow field="sort" title="排序" width="60"
align="center"></vxe-column>
<vxe-column show-overflow show-header-overflow field="remarks" title="描述" align="center"></vxe-column>
<vxe-column show-overflow show-header-overflow title="操作" width="200" fixed="right" align="center">
<template #default="{ row, level }">
<el-button type="text" @click="addMenu(row, level)">添加子菜单</el-button>
<el-button type="text" @click="modifyRow(row, level)">编辑</el-button>
<el-button type="text" class="del-btn" @click="deleteRow(row)">删除</el-button>
</template>
</vxe-column>
</vxe-table>
</div>
<!-- 新增/编辑/查看 菜单 -->
<el-dialog :title="dialogTitle + '菜单'" :visible.sync="dialogMenu" width="750px" :close-on-click-modal="false"
:close-on-press-escape="false" modal-append-to-body append-to-body>
<div class="menu-form">
<el-form :model="form" label-width="186px" :disabled="mode === 'view'">
<el-form-item label="菜单名称:" required>
<el-input v-model="form.name" maxlength="20" placeholder="请输入菜单名称" show-word-limit></el-input>
</el-form-item>
<el-form-item label="菜单路径:">
<el-input v-model="form.href" placeholder="请输入菜单路径" show-word-limit></el-input>
<!--<el-select v-model="form.href" filterable placeholder="请选择菜单路径">-->
<!--<el-option label="-" value=""></el-option>-->
<!--<template v-for="item in pathList">-->
<!--<el-option :label="item" :value="item" :key="item"></el-option>-->
<!--</template>-->
<!--</el-select>-->
</el-form-item>
<el-form-item label="菜单图标:" class="icon-menu-item" v-if="level === 0 || level === 2">
<el-upload action="#" :http-request="(params)=>uploadFile(params)"
:show-file-list="false" :before-upload="beforeUploadFile">
<span class="icon-menu-text">
<img v-if="form.icon" :src="form.iconHref" alt="" class="icon-menu">
<i v-else class="el-icon-plus"></i>
</span>
</el-upload>
</el-form-item>
<el-form-item label="菜单排序:" required>
<el-input-number v-model="form.sort" controls-position="right" :min="1" :step="1"
step-strictly></el-input-number>
</el-form-item>
<el-form-item label="菜单描述:">
<el-input v-model="form.remarks" maxlength="500" type="textarea" placeholder="请填写"
show-word-limit></el-input>
</el-form-item>
<el-form-item label="跳转网页:" class="jumpClass">
<el-checkbox v-model="form.isUrl" true-label="1" false-label="0"></el-checkbox>
</el-form-item>
</el-form>
<div class="done">
<el-button v-if="mode !== 'view'" type="primary" @click="postOrPutSysMenu">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { fileType } from '@/utils/fileType'
export default {
name: 'MenuManager',
data () {
return {
form: {
name: '', // 名称
href: '', // 路径
icon: '', // 图标
iconHref: '', // 图标路径
sort: '', // 排序
remarks: '', // 描述
id: '',
parentId: '',
isUrl: 0
},
tableData: [],
dialogMenu: false,
mode: '',
pathList: [],
level: 0
}
},
methods: {
init () {
this.sysMenuFindAllMenus()
this.getRouterPath()
},
// 菜单
sysMenuFindAllMenus () {
this.$api.menu.sysMenuFindAllMenus().then(({ data }) => {
this.tableData = data.filter(item => item.id !== '6f6fafb4a7' && item.isButton=='0').sort((a, b) => {
return a.sort - b.sort
})
})
},
// 新增弹窗
addMenu (row, level) {
this.mode = 'add'
this.level = level + 1
this.form = {
name: '', // 名称
href: '', // 路径
icon: '', // 图标
iconHref: '', // 图标路径
sort: '', // 排序
remarks: '', // 描述
id: '',
parentId: '',
isUrl: 0
}
this.form.parentId = row ? row.id : '6f6fafb4a7'
this.dialogMenu = true
},
// 新增 修改
postOrPutSysMenu () {
if (!this.form.name) {
return this.$message.warning('请输入菜单名称')
}
if (this.level === 0 || this.level === 2) {
// if (!this.form.icon) {
// return this.$message.warning('请上传菜单图标');
// }
}
if (this.mode === 'add') {
this.$api.menu.postSysMenu(this.form).then(_ => {
this.$message.success('操作成功')
this.dialogMenu = false
this.sysMenuFindAllMenus()
})
}
if (this.mode === 'modify') {
this.$api.menu.putSysMenu(this.form).then(_ => {
this.$message.success('操作成功')
this.dialogMenu = false
this.sysMenuFindAllMenus()
})
}
},
// 图标上传
uploadFile (params) {
const fd = new FormData()
fd.append('file', params.file)
this.$api.report.reportUploadPicFile(fd).then(({ data }) => {
this.form.icon = data.key
this.form.iconHref = data.value
})
},
beforeUploadFile (file) {
const isType = (file.type === fileType.png || file.type === fileType.jpg)
const isSize = file.size / 1024 / 1024 < 2
if (!isType) {
this.$message.error('仅能上传 pngjpg 格式文件')
}
if (!isSize) {
this.$message.error('您最大可上传2M文件')
}
return isType && isSize
},
// 删除
deleteRow (row) {
this.$confirm('此操作将删除所选数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$api.menu.sysMenuDeleteId({ ids: row.id }).then(_ => {
this.$message.success('操作成功')
this.sysMenuFindAllMenus()
})
})
},
// 编辑
modifyRow (row, level) {
this.level = level
this.mode = 'modify'
this.form = JSON.parse(JSON.stringify(row))
this.dialogMenu = true
},
// 获取存在路径
getRouterPath () {
const pathList = []
const pathFun = (data, url) => {
data.forEach(item => {
if (item.children) {
pathFun(item.children, item.path)
} else {
pathList.push(`${url ? (url + '/') : ''}${item.path}`)
}
})
}
pathFun(this.$router.options.routes)
this.pathList = pathList
}
},
computed: {
dialogTitle () {
switch (this.mode) {
case 'add':
return '新增'
case 'modify':
return '编辑'
case 'view':
return '查看'
}
}
},
created () {
this.init()
}
}
</script>
<style lang="scss" scoped>
.jumpClass .el-checkbox {
line-height: 36px;
}
.system-menu-manager {
.title {
border-bottom: 1px solid #EBEEF5;
height: 42px;
line-height: 42px;
margin: 0 18px 0 22px;
span {
font-size: 16px;
font-weight: 600;
color: #262626;
}
}
.search {
.search-box-left {
padding-top: 20px;
display: flex;
justify-content: flex-start;
align-items: center;
label {
font-size: 14px;
font-weight: 400;
color: #595959;
margin-right: 5px;
padding-left: 22px;
}
.year {
::v-deep .el-input__inner {
padding: 0 15px !important;
}
}
::v-deep .el-input {
width: 167px;
margin-right: 5px;
}
@media screen and (max-width: 1366px) {
::v-deep .el-input {
width: 135px;
margin-right: 5px;
}
}
::v-deep .el-button {
float: right;
}
}
.search-box-right {
padding-top: 20px;
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: 14px;
}
.operate-box {
padding-left: 13px;
padding-bottom: 11px;
padding-top: 18px;
}
}
.table {
margin: 0 14px 0 13px;
padding-bottom: 10px;
// ::v-deep .el-icon-circle-plus,
// ::v-deep .el-icon-remove{
// font-size: 18px;
// margin-top: -4px;
// margin-left: -1.5px;
// }
.menu-image {
display: flex;
align-items: center;
justify-content: flex-start;
position: relative;
z-index: 10;
::v-deep .el-image {
width: 30px;
height: 30px;
margin: 0 5px;
.el-image__error {
font-size: 12px;
line-height: 12px;
text-align: center;
}
}
}
::v-deep .el-pagination {
margin-top: 13px;
padding-left: 20px;
padding-bottom: 10px;
}
}
}
.menu-form {
padding-top: 26px;
::v-deep .el-form {
padding-right: 79px;
.icon-menu-item .el-form-item__content > div:first-child {
display: flex !important;
}
.el-form-item {
margin-bottom: 10px;
.el-form-item__label {
height: 36px;
line-height: 36px;
font-size: 14px;
font-weight: 500;
color: #262626;
}
.el-input__inner {
min-height: 36px;
}
.el-input__inner,
.el-textarea__inner {
font-size: 14px;
font-weight: 400;
color: #434343;
}
.el-select {
width: 100%;
}
.el-date-editor {
width: 100%;
.el-input__inner {
padding-left: 15px;
}
.el-input__suffix {
font-size: 16px;
margin-top: 2px;
}
}
.icon-auth {
.el-icon-arrow-up {
margin-top: 2px;
transform: rotateZ(0) !important;
}
.el-icon-arrow-up:before {
content: '';
background: url("../../assets/imgs/icon-user.png") no-repeat center center;
display: inline-block;
width: 12px;
height: 14px;
background-size: 100% 100%;
}
}
.el-input-number {
width: 100%;
input {
text-align: left;
}
.el-input-number__decrease,
.el-input-number__increase {
height: 18px;
line-height: 18px;
font-size: 14px;
width: 30px;
}
}
.icon-menu-text {
display: flex;
width: 36px;
height: 36px;
overflow: hidden;
border: 1px dashed #8C8C8C;
align-items: center;
justify-content: center;
color: #8C8C8C;
font-size: 18px;
.icon-menu {
width: 100%;
height: 100%;
}
}
.el-button {
width: 80px;
height: 36px;
padding: 0;
text-align: center;
}
}
}
.done {
text-align: center;
padding: 40px 0;
::v-deep .el-button {
width: 80px;
height: 36px;
padding: 0;
}
}
}
</style>