300 lines
8.9 KiB
Vue
300 lines
8.9 KiB
Vue
<template>
|
|
<div class="layout-container">
|
|
<el-header>
|
|
<Header />
|
|
</el-header>
|
|
<el-main v-if="menuList.length">
|
|
<el-menu
|
|
:default-active="activeMenu"
|
|
|
|
|
|
:unique-opened="true"
|
|
:default-openeds="defaultOpends"
|
|
>
|
|
<el-scrollbar class="menu-scrollbar" height="calc(100% - 80px)" :min-size="0.2">
|
|
<template v-for="item in menuList">
|
|
<MenuItem v-if="!item.hidden" @select="handleSelect" :key="item.gncdbh" :item="item" />
|
|
</template>
|
|
</el-scrollbar>
|
|
</el-menu>
|
|
<div class="cvi-left svi-new-card-public">
|
|
<!-- <ElTabs :tabsdata="tabsData" @selected-data="handleTabClick" @tab-remove="removeTab"></ElTabs> -->
|
|
<Content :tabHeight="true" />
|
|
</div>
|
|
</el-main>
|
|
<el-main v-else>
|
|
<Content class="svi"/>
|
|
</el-main>
|
|
</div>
|
|
</template>
|
|
<script setup>
|
|
import { onMounted, ref, watch, reactive, toRefs } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useUserStore } from '@/stores/modules/user'
|
|
import { useRouteStore } from '@/stores/modules/router'
|
|
|
|
import Header from './header/index-svi.vue'
|
|
import Content from './content/index-svi.vue'
|
|
import MenuItem from '@/components/ElMenu/index.vue'
|
|
import ElTabs from '@/components/ElTabs/index.vue'
|
|
|
|
const router = useRouter()
|
|
const userStore = useUserStore()
|
|
const routerStore = useRouteStore()
|
|
|
|
const allMenuData = userStore.allMenus
|
|
console.log(allMenuData, 'allMenuData')
|
|
const currentPageURL = window.location.href
|
|
const urlParts = currentPageURL.split('/')
|
|
let projectName = urlParts[3]
|
|
const state = reactive({
|
|
activeMenu: '',
|
|
routerName: '',
|
|
currentProjectName: '',
|
|
tabsData: [],
|
|
menuList: [],
|
|
defaultOpends: [],
|
|
})
|
|
|
|
const { activeMenu, routerName, currentProjectName, menuList, tabsData, defaultOpends } = toRefs(state)
|
|
|
|
const handleSelect = (item) => {
|
|
activeMenu.value = item.path
|
|
userStore.frameUrl = item.frameUrl
|
|
router.push({ path: item.path, query: { frameUrl: item.frameUrl, label: item.label } })
|
|
// const selectedItem = findItemByRoute(allMenuData[projectName], item.path)
|
|
// 临时处理显示出完整效果,修复标签栏显示。 todo 等后续对接实际用户登录信息生成具体的数据时在做调整。
|
|
const items = Object.values(allMenuData[projectName]).reduce((acc, value) => {
|
|
return acc.concat(Array.isArray(value) ? value : [value])
|
|
}, [])
|
|
const selectedItem = findItemByRoute(items, item.path)
|
|
addTab(selectedItem)
|
|
}
|
|
const findItemByRoute = (items, path) => {
|
|
console.log(items, path)
|
|
|
|
for (const item of items) {
|
|
if (item.path === path) {
|
|
return item
|
|
}
|
|
if (item.children) {
|
|
const found = findItemByRoute(item.children, path)
|
|
if (found) {
|
|
return found
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
const addTab = (item, isActive) => {
|
|
const existingTab = tabsData.value.find((tab) => tab.path === item.path)
|
|
if (!existingTab) {
|
|
if (tabsData.value.length >= 10) {
|
|
tabsData.value.splice(0, 1)
|
|
}
|
|
tabsData.value.push({
|
|
path: item.path,
|
|
label: item.label,
|
|
name: item.name,
|
|
icon: item.icon,
|
|
noClosable: item.noClosable,
|
|
frameUrl: item.frameUrl,
|
|
query: item.query,
|
|
})
|
|
routerStore.setVisitedRoutes(tabsData.value)
|
|
if (isActive) return
|
|
activeMenu.value = item.path
|
|
routerStore.setCurrentRoute(activeMenu.value)
|
|
} else {
|
|
activeMenu.value = item.path
|
|
routerStore.setCurrentRoute(item.path)
|
|
}
|
|
}
|
|
const handleTabClick = (data) => {
|
|
const currentRoute = tabsData.value.find((item) => item.path == data.props.name)
|
|
activeMenu.value = data.props.name
|
|
routerStore.setCurrentRoute(activeMenu.value)
|
|
router.push({ path: data.props.name, query: currentRoute.query })
|
|
}
|
|
|
|
const removeTab = (name, type) => {
|
|
const index = tabsData.value.findIndex((item) => item.path === name)
|
|
if (index !== -1) {
|
|
if (type == 'current') {
|
|
if (tabsData.value.length > 1) {
|
|
tabsData.value.splice(index, 1)
|
|
if (activeMenu.value === name) {
|
|
activeMenu.value = tabsData.value.length > 0 ? tabsData.value[tabsData.value.length - 1].path : ''
|
|
const currentRoute = tabsData.value.find((item) => item.path == activeMenu.value)
|
|
routerStore.setCurrentRoute(activeMenu.value)
|
|
routerStore.setVisitedRoutes(tabsData.value)
|
|
router.push({
|
|
path: activeMenu.value,
|
|
query: { frameUrl: currentRoute.frameUrl, label: currentRoute.label },
|
|
})
|
|
}
|
|
}
|
|
} else {
|
|
for (let i = tabsData.value.length - 1; i >= 0; i--) {
|
|
if (tabsData.value[i].path !== name && !tabsData.value[i].noClosable) {
|
|
tabsData.value.splice(i, 1)
|
|
routerStore.setVisitedRoutes(tabsData.value)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const initNoClosableTabs = (routes) => {
|
|
routes.forEach((route) => {
|
|
if (route.noClosable) addTab(route, true)
|
|
if (route.children) initNoClosableTabs(route.children)
|
|
})
|
|
}
|
|
|
|
const initTags = () => {
|
|
activeMenu.value = router.currentRoute.value.path
|
|
tabsData.value = routerStore.visitedRoutes
|
|
routerStore.setCurrentRoute(router.currentRoute.value.path)
|
|
}
|
|
|
|
watch(
|
|
() => router.currentRoute.value.path,
|
|
(val) => {
|
|
if (val) {
|
|
const projectNameArr = ['kfpt', 'yjzy', 'gmzx', 'zhzf']
|
|
let currentPath = router.currentRoute.value.path
|
|
const routeArr = currentPath.split('/')
|
|
if (projectNameArr.indexOf(projectName) != -1 && currentProjectName.value != routeArr[1]) {
|
|
initTags()
|
|
tabsData.value = []
|
|
initNoClosableTabs(allMenuData[projectName][routeArr[1]])
|
|
activeMenu.value = router.currentRoute.value.path
|
|
menuList.value = allMenuData[projectName][routeArr[1]]
|
|
routerName.value = routeArr[1]
|
|
currentProjectName.value = routeArr[1]
|
|
}
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
onMounted(async () => {
|
|
initTags()
|
|
const projectNameArr = ['kfpt', 'yjzy', 'gmzx', 'zhzf']
|
|
if (projectNameArr.indexOf(projectName) != -1) {
|
|
let currentPath = router.currentRoute.value.path
|
|
console.log(currentPath)
|
|
const routeArr = currentPath.split('/')
|
|
console.log(routeArr)
|
|
initNoClosableTabs(allMenuData[projectName][routeArr[1]])
|
|
activeMenu.value = router.currentRoute.value.path
|
|
menuList.value = allMenuData[projectName][routeArr[1]]
|
|
routerName.value = routeArr[1]
|
|
currentProjectName.value = routeArr[1]
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style>
|
|
.el-dropdown {
|
|
color: #fff !important;
|
|
|
|
.iconfont {
|
|
color: #fff !important;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<style lang="scss" scoped>
|
|
.layout-container {
|
|
--el-menu-width: 256px;
|
|
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
.el-header {
|
|
height: 64px;
|
|
padding: 0 0 0 0;
|
|
}
|
|
|
|
.el-main {
|
|
width: 100%;
|
|
height: calc(100%);
|
|
padding: 0;
|
|
display: flex;
|
|
overflow: hidden;
|
|
margin-right: 0;
|
|
|
|
.svi-new-card-public {
|
|
margin: 40px 20px 40px 20px;
|
|
padding: 10px 15px 10px 15px;
|
|
height: calc(100%);
|
|
box-sizing: border-box;
|
|
border-radius: 0.25rem;
|
|
border-radius: 1.125rem;
|
|
border: 0.0625rem solid #a9c7da;
|
|
background: #ffffff38;
|
|
backdrop-filter: blur(1rem);
|
|
}
|
|
|
|
.el-menu {
|
|
width: var(--el-menu-width);
|
|
flex: 0 0 var(--el-menu-width);
|
|
height: calc(100%);
|
|
padding: 40px 8px 40px 0;
|
|
margin-right: 0;
|
|
margin-left: 0;
|
|
border-left: 0;
|
|
// border-radius: 0 1.125rem 1.125rem 0;
|
|
overflow: hidden;
|
|
|
|
}
|
|
|
|
:deep .el-menu {
|
|
width: var(--el-menu-width);
|
|
--el-menu-text-color: #fff !important;
|
|
--el-menu-hover-text-color: #fff !important;
|
|
--el-menu-bg-color: transparent !important;
|
|
}
|
|
|
|
/* 确保子菜单和父菜单宽度一致 */
|
|
:deep(.el-sub-menu) {
|
|
width: calc(var(--el-menu-width) - 8px - var(--el-border-width)) !important;
|
|
|
|
.el-sub-menu__icon-arrow {
|
|
width: 14px !important;
|
|
height: 14px;
|
|
}
|
|
|
|
.el-menu.el-menu--inline {
|
|
--el-menu-text-color: rgba(255, 255, 255, 0.6) !important;
|
|
--el-menu-hover-text-color: rgba(255, 255, 255, 0.6) !important;
|
|
|
|
width: calc(var(--el-menu-width) - 8px - var(--el-border-width));
|
|
border: none !important;
|
|
}
|
|
}
|
|
|
|
.cvi-left {
|
|
flex: 1;
|
|
height: calc(100% - 130px);
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden; /* 防止内容溢出 */
|
|
}
|
|
|
|
.cvi-left::-webkit-scrollbar {
|
|
width: 0;
|
|
}
|
|
|
|
.svi {
|
|
flex: 1;
|
|
margin: 40px 20px 40px 20px;
|
|
padding: 10px 15px 10px 15px;
|
|
height: 100%;
|
|
}
|
|
}
|
|
}
|
|
</style>
|