heart_cabin_bg/src/pages/index/menu/index.vue
2023-08-23 16:06:42 +08:00

271 lines
6.8 KiB
Vue

<template>
<!-- 面包屑 -->
<el-breadcrumb>
<el-breadcrumb-item>系统管理</el-breadcrumb-item>
<el-breadcrumb-item to="/system/menu">菜单管理</el-breadcrumb-item>
</el-breadcrumb>
<el-row :gutter="20">
<el-col :span="12">
<template v-if="checkData.length">
<el-button type="danger" @click="handleCheckDeleteClick">
批量删除
</el-button>
</template>
<el-input v-model="filterText" placeholder="搜索菜单" />
<el-tree
ref="treeRef"
:filter-node-method="filterNode"
:data="treeData"
show-checkbox
draggable
default-expand-all
:highlight-current="true"
:expand-on-click-node="false"
node-key="id"
@node-drop="handleDrop"
@check="handleCheck"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<span>{{ node.label }}</span>
<span>
<a @click="handleTreeClick('create', data)"> 添加 </a>
<a v-if="data.id != 0" @click="handleTreeClick('edit', data)">
编辑
</a>
</span>
</span>
</template>
</el-tree>
</el-col>
<el-col :span="12">
<div v-if="model.menu_guid">
<el-form ref="formRef" :model="model" :rules="rules">
<el-form-item label="名称" prop="menu_name">
<el-input v-model="model.menu_name" type="text"></el-input>
</el-form-item>
<el-form-item label="路由" prop="menu_url">
<el-input v-model="model.menu_url" type="text"></el-input>
</el-form-item>
<el-form-item label="排序" prop="menu_order">
<el-input v-model="model.menu_order" type="number"></el-input>
</el-form-item>
<el-form-item label="展示" prop="menu_show">
<el-switch
v-model="model.menu_show"
active-text="展示"
inactive-text="隐藏"
/>
</el-form-item>
<el-form-item label="状态" prop="menu_status">
<el-switch
v-model="model.menu_status"
active-text="启用"
inactive-text="停用"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSaveClick">
保存
</el-button>
<el-button
v-if="model.menu_guid && model.menu_guid != 'create'"
type="danger"
@click="handleDeleteClick"
>
删除
</el-button>
</el-form-item>
</el-form>
</div>
<div v-else>
<el-empty description="请选择菜单" />
</div>
</el-col>
</el-row>
</template>
<script setup>
import { ref, reactive, watch } from 'vue';
import { getMenuTree, addMenu, updateMenu, deleteMenu } from '~/service/menu';
const formRef = ref();
const treeRef = ref();
const filterText = ref('');
const treeData = ref([]);
const checkData = ref([]);
const model = reactive({
menu_guid: '',
menu_parent_guid: '',
menu_name: '',
menu_status: true,
menu_show: true,
menu_url: '',
menu_index: 0,
menu_order: 0
});
const rules = {
menu_name: [
{
required: true,
message: '请输入菜单名称'
}
],
menu_url: [
{
required: true,
message: '请输入菜单url'
}
],
menu_order: [
{
required: true,
message: '请输入菜单排序'
}
]
};
const loadTree = async () => {
const { code, data } = await getMenuTree();
if (code == 0) {
treeData.value = data;
}
};
loadTree();
watch(filterText, v => {
treeRef.value.filter(v);
});
// 搜索树组件
const filterNode = (value, data) => {
if (!value) return true;
return data.label.indexOf(value) !== -1;
};
// 拖拽排序
const handleDrop = async (current, to, action) => {
const currentData = current.data;
const toData = to.data;
console.log({
current: currentData,
to: toData,
action
});
const data = {
menu_guid: current.data.id,
menu_parent_guid: '',
menu_index: '',
menu_order: ''
};
switch (action) {
case 'before':
data.menu_parent_guid = toData.parent_id;
data.menu_index = toData.index;
data.menu_order = toData.order + 1;
break;
case 'after':
data.menu_parent_guid = toData.parent_id;
data.menu_index = toData.index;
data.menu_order = toData.order - 1;
break;
case 'inner':
data.menu_parent_guid = toData.id;
data.menu_index = toData.index + 1;
data.menu_order = 0;
break;
}
const { code } = await updateMenu(data);
if (code == 0) {
loadTree();
}
};
// 选中菜单
const handleCheck = (_, { checkedKeys }) => {
checkData.value = checkedKeys;
};
// 表单提交
const handleSaveClick = async () => {
try {
await formRef.value.validate();
const data = {
...model,
menu_status: model.menu_status ? 1 : 2,
menu_show: model.menu_show ? 1 : 2
};
if (model.menu_guid === 'create') {
const { code } = await addMenu(data);
if (code == 0) {
loadTree();
}
model.menu_guid = '';
} else {
const { code } = await updateMenu(data);
if (code == 0) {
loadTree();
}
}
} catch (error) {}
};
// 批量删除
const handleCheckDeleteClick = () => {
ElMessageBox.alert('您确定要删除该菜单吗?', '删除菜单', {
confirmButtonText: '确定'
}).then(async () => {
const isSuccess = await deleteMenu({
menu_guid: checkData.value.join()
});
if (isSuccess) {
loadTree();
checkData.value = [];
}
});
};
// 删除菜单
const handleDeleteClick = () => {
ElMessageBox.alert('您确定要删除该菜单吗?', '删除菜单', {
confirmButtonText: '确定'
}).then(async () => {
const isSuccess = await deleteMenu(model);
if (isSuccess) {
loadTree();
model.menu_guid = '';
}
});
};
const handleTreeClick = (type, data) => {
switch (type) {
case 'create':
model.menu_guid = 'create';
model.menu_parent_guid = data.id;
model.menu_index = data.index + 1;
model.menu_name = '';
model.menu_url = '';
model.menu_order = 0;
model.menu_status = true;
model.menu_show = true;
break;
case 'edit':
model.menu_guid = data.id;
model.menu_parent_guid = data.parent_id;
model.menu_index = data.index;
model.menu_name = data.label;
model.menu_order = data.order;
model.menu_url = data.url;
model.menu_status = data.status == 1;
model.menu_show = data.show == 1;
break;
}
};
</script>
<style scoped>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>