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.

213 lines
5.8 KiB

7 months ago
<template>
<div class="menu-manage-content">
<a-page-header class="ns-page-header" title="栏目管理">
<template #extra>
<!-- todo 隐藏取消-->
<a-button type="primary" @click="submit">提交</a-button>
<a-button style="margin-left: 10px" @click="navigateBack">取消</a-button>
</template>
</a-page-header>
<ns-tree
v-model:expandedKeys="expandedKeys"
:tree-data="treeData"
:fieldNames="fieldNames"
:autoExpandParent="true"
:draggable="true"
@drop="drop">
<template #title="{ code: treeKey, label }">
<a-dropdown :trigger="['contextmenu']">
<span>{{ label }}</span>
<template #overlay>
<a-menu @click="({ key: menuKey }) => onContextMenuClick(treeKey, menuKey, label)">
<a-menu-item key="edit">编辑</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
</ns-tree>
</div>
<a-drawer
title="栏目编辑"
:width="500"
:visible="visible"
:body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }"
@close="onClose">
<ns-form :schemas="formSchema" :model="formData" />
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
<a-button type="primary" @click="onEdit">提交</a-button>
</a-drawer>
</template>
<script lang="ts">
import { computed, defineComponent, reactive, ref, watch } from 'vue';
import { cloneDeep } from 'lodash-es';
import { dropMenu, RouteMenu, editMenuLabel } from '/nerv-base/router/helper/menu-helper';
import { message } from 'ant-design-vue';
import { useRouteStore } from '/nerv-base/store/modules/route';
import { storeToRefs } from 'pinia';
import { useNavigate } from '/nerv-lib/use/use-navigate';
import { useTags } from '/nerv-base/store/modules/tags';
export default defineComponent({
name: 'NsViewMenuManage',
components: {},
setup() {
const { routeModule } = storeToRefs(useRouteStore());
const routeStore = useRouteStore();
const visible = ref(false);
const onClose = () => {
visible.value = false;
};
const { navigateBack } = useNavigate();
const formData = reactive({
key: '',
className: '',
});
const formSchema = reactive([
{
field: 'className',
label: '栏目名称',
component: 'NsInput',
componentProps: {
placeholder: '请输入栏目名称',
rules: [
{
required: true,
message: '请输入栏目名称',
trigger: 'blur',
},
],
},
},
]);
/**
* 去除菜单里的最终子节点
* @param data
*/
function getTreeData(data: RouteMenu[]) {
const list = cloneDeep(data);
const _list: any = [];
list.forEach((module) => {
module.menus && (module.menus = checkMenu(module.menus));
if (module.code !== 'root') _list.push(module);
});
return _list;
}
function checkMenu(menus) {
menus.forEach((children) => {
// if (children.type === 'noChildrenMenu') {
// children.menus = [];
// } else {
// if (children.menus) children.menus = checkMenu(children.menus);
// }
if (children.route?.meta?.hideChildren) {
children.menus = [];
} else {
if (children.menus) children.menus = checkMenu(children.menus);
}
});
return menus;
}
const treeData = computed(() => {
return getTreeData(routeModule.value);
});
const expandedKeys = ref<string[]>([]);
const fieldNames = { children: 'menus', title: 'label', key: 'code' };
function drop(info) {
console.log('event', info);
const data = dropMenu(routeModule.value, info);
if (data.success === false) {
message.error(data.msg);
}
if (data.success === true) {
// 移动成功
}
}
const onContextMenuClick = (treeKey: string, menuKey: string | number, label: string) => {
switch (menuKey) {
case 'edit':
visible.value = true;
formData.key = treeKey;
formData.className = label;
break;
default:
message.error('无此操作');
}
console.log(`treeKey: ${treeKey}, menuKey: ${menuKey}`, label);
};
const onEdit = () => {
visible.value = false;
editMenuLabel(routeModule.value, formData.key, formData.className);
// console.log('formData.className', formData.key, formData.className);
};
//保存
function submit() {
//todo 提交给后端 routeModule.value 成功后同步菜单
// testTags.testEdit(2);
routeStore.syncRoute();
}
return {
navigateBack,
expandedKeys,
fieldNames,
treeData,
drop,
onContextMenuClick,
visible,
onClose,
onEdit,
formSchema,
formData,
submit,
};
},
});
</script>
<style lang="less" scoped>
.menu-manage-content {
// padding: 0 16px 16px 16px;
min-height: 100%;
height: 100%;
background: #e5ebf0;
}
:deep(.ant-tree .ant-tree-treenode) {
padding: 2px 0 4px 0;
}
.ns-page-header {
margin-bottom: 0 !important;
padding-top: 7px !important;
padding-bottom: 7px !important;
width: calc(100% + 32px);
margin-left: -16px;
background: #fff;
font-size: 18px;
.title {
cursor: pointer;
font-size: 18px !important;
}
}
:deep(.ant-tree) {
border-top: 16px solid #e5ebf0;
padding: 16px 21px;
background: #fff;
height: calc(100% - 47px) !important;
}
</style>