admin/src/views/system/menu/index.vue

221 lines
5.4 KiB
Vue

<template>
<el-container>
<el-aside width="300px" v-loading="menuloading">
<el-container>
<el-header>
<el-input placeholder="输入关键字进行过滤" v-model="menuFilterText" clearable></el-input>
</el-header>
<el-main class="nopadding">
<el-tree ref="menuRef" class="menu" node-key="menu_id" :data="menuList" :props="menuProps"
highlight-current :expand-on-click-node="false" check-strictly show-checkbox
:filter-node-method="menuFilterNode" @node-click="menuClick" :check-on-click-leaf="false">
<template #default="{node, data}">
<span class="custom-tree-node el-tree-node__label">
<span class="label">
{{ node.label }}
<el-button v-if="data.type == 0" link size="small" type="warning"
style="margin-left: 5px;">菜单</el-button>
<el-button v-if="data.type == 1" link size="small" type="primary"
style="margin-left: 5px;">按钮</el-button>
<el-button v-if="data.type == 2" link size="small" type="success"
style="margin-left: 5px;">接口</el-button>
<el-button v-if="data.type == 3" link size="small" type="danger"
style="margin-left: 5px;">外链</el-button>
</span>
<span class="do">
<el-icon @click.stop="add(node, data)"><el-icon-plus/></el-icon>
<el-icon @click.stop="quick(node, data)"><pi-icon-quick/></el-icon>
</span>
</span>
</template>
</el-tree>
</el-main>
<el-footer style="height:51px;">
<el-button type="primary" size="small" icon="el-icon-plus" @click="add"></el-button>
<el-button type="danger" size="small" plain icon="el-icon-delete" @click="delMenu"></el-button>
</el-footer>
</el-container>
</el-aside>
<el-container>
<el-main class="nopadding" style="padding:20px;" ref="mainRef">
<save ref="saveRef" :menu="menuList"></save>
</el-main>
</el-container>
<quick-dialog v-if="quickShow" ref="quickRef" @success="success" @closed="quickShow = false"></quick-dialog>
</el-container>
</template>
<script setup>
import quickDialog from "./quick"
import {ref, watch, getCurrentInstance, nextTick} from "vue";
import save from './save'
import api from "@/api/index";
defineOptions({
name: "systemMenu"
})
const menuRef = ref(null)
const saveRef = ref(null)
const mainRef = ref(null)
const quickRef = ref(null)
const {proxy} = getCurrentInstance()
let menuloading = ref(false)
let menuList = ref([])
let menuProps = ref({
label: (data) => {
return data.title
}
})
let menuFilterText = ref("")
let newMenuIndex = ref(1);
let quickShow = ref(false)
watch(menuFilterText, (val) => {
menuRef.value.filter(val);
})
getMenu()
async function getMenu() {
menuloading.value = true
var res = await api.system.menu.list();
menuloading.value = false
menuList.value = treeData(res.data, 0);
}
function treeData(menus, menu_id) {
if (menus == undefined || menus.length <= 0) return [];
const arr = [];
for (let item of menus) {
// 数据格式处理
const tmp = item;
if (item.parent_id == menu_id) {
var children = treeData(menus, item.menu_id);
if (children.length > 0) {
tmp['children'] = children
}
arr.push(tmp)
}
}
return arr
}
function menuClick(data) {
saveRef.value.setData(data)
mainRef.value.$el.scrollTop = 0
}
function menuFilterNode(value, data) {
if (!value) return true;
var targetText = data.title;
return targetText.indexOf(value) !== -1;
}
async function add(node, data) {
var newMenuName = "未命名" + newMenuIndex.value++;
var newMenuData = {
menu_id: "",
parent_id: data ? data.menu_id : 0,
name: newMenuName,
path: "",
title: newMenuName,
type: 0,
rank: 1
}
menuloading.value = false
menuRef.value.append(newMenuData, node)
menuRef.value.setCurrentKey(newMenuData.menu_id)
saveRef.value.setData(newMenuData)
}
function quick(node, data) {
quickShow.value = true
nextTick(() => {
quickRef.value.open(data.menu_id)
})
}
function success() {
quickShow.value = false
reload()
}
async function delMenu() {
var CheckedNodes = menuRef.value.getCheckedNodes()
if (CheckedNodes.length == 0) {
proxy.$message.warning("请选择需要删除的项")
return false;
}
var confirm = await proxy.$confirm('确认删除已选择的菜单吗?', '提示', {
type: 'warning',
confirmButtonText: '删除',
cancelButtonText: '取消',
confirmButtonClass: 'el-button--danger'
}).catch(() => {
})
if (confirm != 'confirm') {
return false
}
menuloading.value = true
var res = await api.system.menu.del({ids: CheckedNodes.map(item => item.menu_id)})
menuloading.value = false
proxy.$message.success(res.msg)
CheckedNodes.forEach(item => {
var node = menuRef.value.getNode(item)
if (node == null) {
reload()
} else if (node.isCurrent) {
saveRef.value.setData({})
}
menuRef.value.remove(item)
})
}
function reload() {
getMenu()
saveRef.value.setData(menuList.value[0])
mainRef.value.$el.scrollTop = 0
}
</script>
<style scoped>
.custom-tree-node {
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 24px;
height: 100%;
}
.custom-tree-node .label {
display: flex;
align-items: center;;
height: 100%;
}
.custom-tree-node .label .el-tag {
margin-left: 5px;
}
.custom-tree-node .do {
display: none;
}
.custom-tree-node .do i {
margin-left: 5px;
color: #999;
}
.custom-tree-node .do i:hover {
color: #333;
}
.custom-tree-node:hover .do {
display: inline-block;
}
</style>