菜单优化
This commit is contained in:
248
core/apps/AppMenuManager/AppMenuManager.vue
Normal file
248
core/apps/AppMenuManager/AppMenuManager.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<section class="AppMenuManager">
|
||||
<ai-list>
|
||||
<ai-title slot="title" title="菜单配置" isShowBottomBorder/>
|
||||
<template #content>
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
<el-button type="primary" icon="el-icon-circle-plus" @click="addRootMenu">添加一级目录</el-button>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-button icon="iconfont iconResetting" @click="getData">刷新</el-button>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<el-row type="flex" class="headerRow">
|
||||
<div class="menuName" v-text="`菜单名称`"/>
|
||||
<el-row type="flex" align="middle" class="info">
|
||||
<div class="style" v-text="`图标`"/>
|
||||
<div class="type" v-text="`菜单类型`"/>
|
||||
<div class="component" v-text="`应用模块`"/>
|
||||
<div class="status" v-text="`是否显示`"/>
|
||||
<div class="showIndex" v-text="`排序`"/>
|
||||
</el-row>
|
||||
<div class="operation" v-text="`操作`"/>
|
||||
</el-row>
|
||||
<el-scrollbar>
|
||||
<el-tree ref="MenuTree" :data="treeData" :props="{children:'subSet'}" highlight-current node-key="id">
|
||||
<el-row type="flex" align="middle" slot-scope="{node,data}" class="menuItem">
|
||||
<div class="menuName" v-text="data.name"/>
|
||||
<el-row type="flex" align="middle" class="info">
|
||||
<div class="style" :class="data.style"/>
|
||||
<div class="type" v-text="dict.getLabel('menuType',data.type)"/>
|
||||
<div class="component" v-text="data.component"/>
|
||||
<div class="status" v-text="dict.getLabel('yesOrNo',data.status)"/>
|
||||
<div class="showIndex" v-text="data.showIndex"/>
|
||||
</el-row>
|
||||
<el-row type="flex" align="middle" class="operation">
|
||||
<div v-if="node.isLeaf" class="opBtn del" v-text="`删除`" @click="handleDelete(data)"/>
|
||||
<div v-if="data.type==0" class="opBtn" v-text="`添加下级`" @click="addMenu(data)"/>
|
||||
<div class="opBtn" v-text="`编辑`" @click="handleEdit(data)"/>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</el-tree>
|
||||
</el-scrollbar>
|
||||
</template>
|
||||
</ai-list>
|
||||
<ai-dialog :visible.sync="dialog" title="菜单设置" width="500px" @onConfirm="handleSubmit"
|
||||
@closed="form={},selected={}">
|
||||
<el-form ref="MenuForm" :model="form" size="small" label-width="100px" :rules="rules">
|
||||
<el-form-item label="菜单名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入" clearable/>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单类型" prop="type">
|
||||
<ai-select v-model="form.type" clearable :selectList="dict.getDict('menuType')"/>
|
||||
</el-form-item>
|
||||
<template v-if="form.type==0">
|
||||
<el-form-item label="菜单图标" prop="style">
|
||||
<el-input v-model="form.style" placeholder="请输入" clearable/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="form.type==1">
|
||||
<el-form-item label="菜单应用" prop="component">
|
||||
<el-input v-model="form.component" placeholder="请输入" clearable/>
|
||||
</el-form-item>
|
||||
<el-form-item label="路径(path)" prop="path">
|
||||
<el-input v-model="form.path" placeholder="请输入" clearable/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-if="form.type==1">
|
||||
<el-form-item label="权限码" prop="permission">
|
||||
<el-input v-model="form.permission" placeholder="请输入" clearable/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<el-form-item label="显示菜单" prop="status">
|
||||
<ai-select v-model="form.status" clearable :selectList="dict.getDict('yesOrNo')"/>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.type<2" label="排序" prop="showIndex">
|
||||
<el-input v-model="form.showIndex" placeholder="请输入" clearable/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "AppMenuManager",
|
||||
label: "菜单管理",
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: {default: () => ({})}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
treeData: [],
|
||||
dialog: false,
|
||||
form: {},
|
||||
selected: {},
|
||||
rules: {
|
||||
name: [{required: true, message: "请输入 菜单名称"}],
|
||||
type: [{required: true, message: "请选择 菜单类型"}],
|
||||
status: [{required: true, message: "请选择 显示菜单"}],
|
||||
showIndex: [{required: true, message: "请输入 排序"}],
|
||||
permission: [{required: true, message: "请输入 权限码"}],
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getData() {
|
||||
this.instance.post("/admin/menu/menuTree").then(res => {
|
||||
if (res?.data) {
|
||||
this.treeData = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.MenuForm.validate(v => {
|
||||
if (v) {
|
||||
this.instance.post("/admin/menu/addOrUpdate", this.form).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$message.success("提交成功!")
|
||||
if (!this.form.id) {
|
||||
this.getData()
|
||||
} else this.$refs.MenuTree.append(this.form, this.selected)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleDelete(data) {
|
||||
let {id} = data
|
||||
this.$confirm("是否要删除该菜单").then(() => {
|
||||
this.instance.post("/admin/menu/delete", null, {
|
||||
params: {id}
|
||||
}).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$message.success("删除成功!")
|
||||
this.$refs.MenuTree.remove(data)
|
||||
}
|
||||
})
|
||||
}).catch(() => 0)
|
||||
},
|
||||
addRootMenu(row) {
|
||||
this.dialog = true
|
||||
this.selected = row
|
||||
},
|
||||
addMenu(row) {
|
||||
this.dialog = true
|
||||
this.form = {parentId: row.id}
|
||||
this.selected = row
|
||||
},
|
||||
handleEdit(row) {
|
||||
this.dialog = true
|
||||
this.form = JSON.parse(JSON.stringify(row))
|
||||
this.selected = row
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getData()
|
||||
this.dict.load("yesOrNo", "menuType")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AppMenuManager {
|
||||
height: 100%;
|
||||
|
||||
::v-deep .ai-list__content--right-wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-tree {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 14px;
|
||||
|
||||
.menuItem {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.el-tree-node__content {
|
||||
border-bottom: 1px solid #d0d4dc;
|
||||
}
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
|
||||
.el-scrollbar__wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.headerRow {
|
||||
background: #f3f4f5;
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
align-items: center;
|
||||
height: 40px;
|
||||
|
||||
.menuName {
|
||||
padding-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
gap: 16px;
|
||||
text-align: center;
|
||||
|
||||
.showIndex, .status, .type, .style {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.component {
|
||||
width: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.operation {
|
||||
width: 200px;
|
||||
flex-shrink: 0;
|
||||
justify-content: flex-end;
|
||||
text-align: center;
|
||||
|
||||
.opBtn {
|
||||
cursor: pointer;
|
||||
width: 60px;
|
||||
|
||||
font-size: 14px;
|
||||
color: #26f;
|
||||
|
||||
&.del {
|
||||
color: #f46;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menuName {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user