修改layouts插件

This commit is contained in:
yuyan02 2025-02-14 20:12:39 +08:00
parent 7ef85d5361
commit fd3668c7bf
7 changed files with 1170 additions and 0 deletions

View File

@ -0,0 +1,49 @@
<!--
* @MoudelName: 模块名称
* @Company: 湖南xx科技有限公司
* @Author: LJ
* @Date: 2024-06-26 16:33:03
-->
<!-- 模块 -->
<template>
<div class="layout-content" :class="tabHeight ? 'tabHeight' : ''">
<RouterView v-slot="{ Component, route }">
<Transition name="fade" mode="out-in">
<keep-alive :exclude="['addressListHome', 'CviIndex', 'Zbzxzbtj','Qxzxjsgl','Qxzxyyjsgl']">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</Transition>
</RouterView>
</div>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
tabHeight: {
type: Boolean,
default: false,
},
})
</script>
<style lang="scss" scoped>
.layout-content {
width: 100%;
height: 100%;
}
.tabHeight {
height: calc(100% - 40px);
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>

View File

@ -0,0 +1,31 @@
<!-- 模块 -->
<template>
<div class="content-container">
<RouterView v-slot="{ Component, route }">
<transition appear :name="route.meta.transition">
<!-- 这里暂时调整为所有页面都缓存 -->
<keep-alive>
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</transition>
</RouterView>
</div>
</template>
<script setup></script>
<style lang="scss" scoped>
.content-container {
width: 100%;
height: 100%;
margin: 0 !important;
padding: 0 !important;
background: transparent;
border-radius: 8px;
overflow: hidden;
.cvi-tabs + & {
--cvi-tabs-height: 40px;
}
}
</style>

View File

@ -0,0 +1,156 @@
<template>
<div class="notification-bell">
<el-badge :value="unreadCount" :max="99" :hidden="unreadCount === 0" class="item" @click="handleClick">
<i class="iconfont icon-yjpt_lxyj" title="消息通知" style="color: #ADD8E6; font-size: 20px;"></i>
</el-badge>
<!-- 消息下拉面板 -->
<el-popover v-model:visible="popoverVisible" placement="bottom-end" :width="250" trigger="click">
<template #reference>
<div style="display: inline-block"></div>
</template>
<div class="notification-panel">
<el-scrollbar max-height="300px">
<div v-for="(msg, index) in messages" :key="index" class="message-item" :class="{ 'unread': !msg.read }"
@click="readMessage(msg)">
<div class="message-content">
<div class="message-title">{{ msg.content }}</div>
<div class="message-time">{{ msg.createTime }}</div>
</div>
</div>
<el-empty v-if="messages.length === 0" description="暂无消息"/>
</el-scrollbar>
<!-- <div class="panel-footer">-->
<!-- <el-button :disabled="unreadCount === 0" type="text" @click="viewAll">查看全部</el-button>-->
<!-- </div>-->
</div>
</el-popover>
</div>
</template>
<script setup>
import {onMounted, onUnmounted, reactive, toRefs} from 'vue'
import notifications from "@/api/lawenforcement/Notification.js"
import messagesApi from "@/api/lawenforcement/Message.js"
import { useRouter } from 'vue-router'
const route = useRouter()
const state = reactive({
apiConfig: {
api: notifications
},
unreadCount: 0,
messages: [],
popoverVisible: false
})
const {unreadCount, messages, popoverVisible} = toRefs(state)
//
const handleClick = () => {
popoverVisible.value = !popoverVisible.value
}
//
const viewAll = () => {
popoverVisible.value = false
}
let timer = null
const getMsg = () => {
messagesApi.getUserMessages({status: 'UNREAD', page: 0, size: 100}).then(rs => {
messages.value = rs.data
unreadCount.value = rs.data.length
})
}
function readMessage(msg) {
messagesApi.updateMessageStatus(msg.id, {status: 'READ'}).then(rs => {
if (rs.success) {
getMsg()
}
})
route.push(msg.routeUrl)
}
//
onMounted(() => {
getMsg()
timer = setInterval(getMsg, 60 * 1000)
})
onUnmounted(() => {
clearInterval(timer)
})
</script>
<style scoped>
.notification-bell {
display: flex;
align-items: center;
margin-right: 20px;
cursor: pointer;
}
.notification-bell .el-icon {
color: #606266;
transition: color 0.3s;
}
.notification-bell .el-icon:hover {
color: var(--el-color-primary);
}
.notification-panel {
padding: 0;
}
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
border-bottom: 1px solid var(--el-border-color-light);
}
.message-item {
padding: 12px 15px;
border-bottom: 1px solid var(--el-border-color-lighter);
transition: background-color 0.3s;
color: #373E52;
}
.message-item.unread {
background-color: #f6faff;
}
.message-item:hover {
cursor: pointer;
background-color: #3C86FF;
color: white;
border-radius: 8px;
}
.message-content {
display: flex;
flex-direction: column;
}
.message-title {
font-size: 14px;
margin-bottom: 4px;
}
.message-time {
font-size: 12px;
}
.panel-footer {
padding: 10px;
text-align: center;
border-top: 1px solid var(--el-border-color-light);
}
</style>

View File

@ -0,0 +1,10 @@
<template>
<div>表头</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
onMounted(() => { })
</script>
<style lang='scss' scoped></style>

View File

@ -0,0 +1,415 @@
<template>
<div class="header-container">
<div class="header-left" :class="{'header-height': projectName != 'gzt'}">
<img class="logo" :src="logo" alt=""/>
<div class="header-title">
<div class="main-title">{{ titleMain || '西安智慧应急' }}</div>
<template v-if="subTitle">
<div class="subtitle">{{ subTitle }}</div>
</template>
</div>
</div>
<div class="menu-conten" v-if="projectName == 'gzt'">
<el-dropdown v-for="(item, index) in MyApplocation" :key="index" size="large">
<span class="el-dropdown-link">
<span class="profile-name fs-base">{{ item.name }}</span>
</span>
<template #dropdown>
<el-dropdown-menu :class="`menuTop-list${index} menuTop-public`">
<template v-for="(childItem, childIndex) in item.list">
<div :class="`menuTop-list${index}-item menuTop-public-item`" @click="handleGO(childItem)">
<img :src="childItem.avatar" alt=""/>
<div class="menuTop-item-text ccw fs-base" :title="childItem.name">{{ childItem.name }}</div>
</div>
</template>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<div class="menu-conten" v-if="topMenuList[projectName].length">
<div class="menu-conten-item" v-for="(item, index) in topMenuList[projectName]" :key="index" :title="item.name"
@click="handleTo(item)" :class="{ isActive: item.path == topActive }">
<span>
{{ item.name }}
</span>
</div>
</div>
<div class="right-profile">
<span class="zyt" @click="skipPage"><i>综合执法一张图</i></span>
<span class="el-dropdown-link">
<el-avatar :src="userAvatar" class="profile-avatar">
{{ username.slice(0, 1) }}
</el-avatar>
<span class="profile-name fs-base">{{ username }}</span>
</span>
<i class="iconfont icon-zngzt_zfdc" v-if="projectName == 'gzt'" title="编辑桌面"></i>
<i class="iconfont icon-zngzt_syfw" v-if="projectName != 'gzt'" @click="handleTo({ path: 'gzt' })" title="首页"></i>
<NotificationBell/>
<public-full-screen></public-full-screen>
<i class="iconfont icon-zngzt_tcdl" @click="handleLogout" title="退出"></i>
</div>
</div>
</template>
<script setup>
import {onMounted, reactive, toRefs, watch} from 'vue'
import {useRouter} from 'vue-router'
import {useUserStore} from '@/stores/modules/user'
import {ElLoading, ElMessage} from 'element-plus'
import PublicFullScreen from '@/components/PublicFullScreen/index.vue'
import NotificationBell from './NotificationBell.vue'
import logo from '@/assets/image/logo.png'
import {useRouteStore} from '@/stores/modules/router'
const router = useRouter()
const userStore = useUserStore()
const routerStore = useRouteStore()
const currentPageURL = window.location.href
const urlParts = currentPageURL.split('/')
const projectName = urlParts[3]
const baseURL = import.meta.env.VITE_BASE_URL
const state = reactive({
topActive: '',
topMenuList: userStore.topMenu,
titleMain: import.meta.env.VITE_APP_TITLE,
subTitle: import.meta.env.VITE_APP_SUB_TITLE,
version: import.meta.env.VITE_APP_VERSION,
MyApplocation: userStore.myAppLocations,
username: userStore.username,
userAvatar: userStore.userAvatar
})
const {topActive, topMenuList, titleMain, subTitle, version, MyApplocation, username, userAvatar} = toRefs(state)
const handleGO = (data) => {
console.log(data)
if (data.isTrue) {
window.open(data.url)
} else if (data.isImg) {
userStore.imageIndex = data.url
window.open(data.url)
} else if (data.router) {
router.push({
path: data.url,
})
} else {
ElMessage.error('对不起,您没有该应用权限。')
}
}
const handleTo = (data) => {
topActive.value = data.path
if (data.router) {
router.push({
path: data.path,
})
} else {
window.open(`${baseURL}/${data.path}/index.html#/`)
}
}
const handleEdit = () => {
userStore.isDraggable = true
}
const handleLogout = async () => {
await userStore.logout()
}
const skipPage = () => {
router.push('/big-screen')
}
watch(
() => router.currentRoute.value.path,
(val) => {
if (val) {
topActive.value = router.currentRoute.value.path
}
},
{immediate: true}
)
onMounted(() => {
window.document.documentElement.setAttribute('data-theme', 'whiteblueTheme')
})
</script>
<style lang="scss">
.menuTop-public {
display: flex;
flex-wrap: wrap;
width: 896px;
padding: 15px !important;
.menuTop-public-item {
display: flex;
align-items: center;
width: calc(25% - 56px) !important;
height: 45px;
padding: 16px;
margin: 12px;
border-radius: 8px;
cursor: pointer;
img {
width: 40px;
height: 40px;
margin-right: 16px;
}
.MyApplocation-item-text {
margin-left: 16px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
/* .menuTop-list0 {
width: 896px;
.menuTop-list0-item {
width: calc(25% - 56px) !important;
}
}
.menuTop-list4 {
width: 1120px;
flex-wrap: nowrap;
.menuTop-list4-item {
width: calc(20% - 56px) !important;
}
} */
</style>
<style lang="scss" scoped>
.header-container {
position: relative;
display: flex;
height: 100%;
.header-left {
position: relative;
display: flex;
align-items: center;
padding-left: 20px;
padding-right: 20px;
height: 100%;
.logo {
height: 30px;
margin-right: 10px;
}
.header-title {
height: 60px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
align-content: center;
font-size: 24px;
background-clip: text;
-webkit-text-fill-color: transparent;
font-family: 'AlimamaShuHeiTi-Bold';
}
.version {
margin-left: 8px;
font-weight: 500;
}
.subtitle {
font-size: 14px;
margin-top: 0px; /* 减小与主标题的间距 */
text-align: center;
line-height: 1; /* 减小行高 */
}
.main-title {
text-align: center;
line-height: 1.2; /* 减小行高 */
margin-bottom: 0; /* 移除底部边距 */
padding-bottom: 0; /* 移除底部内边距 */
}
.logo-right {
position: absolute;
right: -15px;
bottom: 6px;
width: 58px;
height: 10px;
background-image: url('@/assets/image/logobg.png');
background-size: 100% 100%;
background-repeat: no-repeat;
}
}
.menu-conten {
width: calc(85% - 460px);
display: flex;
margin-left: 50px;
color: #fff;
.el-dropdown {
align-items: center;
padding: 0 30px;
.el-dropdown-link {
padding: 8px 12px;
border-radius: 4px;
cursor: pointer;
}
}
.menu-conten-item {
// min-width: 80px;
min-width: auto;
padding: 0 18px;
line-height: 56px;
text-align: center;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
display: flex;
justify-content: center;
align-items: center;
border-radius: 2px;
span {
/* 使用flex布局确保文本居中 */
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
width: 100%;
height: 100%;
}
/* 为悬浮和选中状态准备的样式 */
transition: all 0.3s ease;
&:hover {
background: linear-gradient(to top, rgba(255, 255, 255, 0.4), transparent) !important;
color: #fff !important;
span {
font-weight: 700;
font-family: 'OPlusSans3-Bold';
}
/* 悬浮时显示底部装饰线 */
&::after {
content: '';
position: absolute;
bottom: 0;
left: 15%;
width: 70%;
height: 4px;
background-color: #fff;
border-radius: 2px 2px 0 0;
}
}
}
.menu-conten-item.isActive {
background: linear-gradient(to top, rgba(255, 255, 255, 0.4), transparent) !important;
color: #fff !important;
span {
font-weight: 700;
font-family: 'OPlusSans3-Bold';
}
/* 选中状态显示底部装饰线 */
&::after {
content: '';
position: absolute;
bottom: 0;
left: 15%;
width: 70%;
height: 4px;
background-color: #fff;
border-radius: 2px 2px 0 0;
}
}
}
.right-profile {
position: absolute;
right: 0;
display: flex;
justify-content: flex-end;
align-items: center;
width: 26%;
height: 100%;
.profile-name {
display: inline-block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: auto;
margin-top: 3px;
}
.system {
margin-right: 18px;
cursor: pointer;
}
.profile-avatar {
width: 34px;
height: 34px;
margin-right: 10px;
border-radius: 50%;
}
> .iconfont {
margin-right: 14px;
height: 32px;
line-height: 32px;
font-size: 22px;
color: #ADD8E6; //
cursor: pointer;
}
}
.right-profile .zyt {
display: flex;
margin: 6px 64px 0px 0px;
width: 207px;
height: 43px;
background-image: url('@/assets/image/yztan.png');
background-size: 100% 100%;
background-repeat: no-repeat;
cursor: pointer;
position: relative;
}
.right-profile .zyt i {
display: flex;
width: 100%;
font-size: 14px;
font-style: normal;
transform: none;
justify-content: center;
line-height: 40px;
position: absolute;
left: 6.5%;
}
.right-profile .el-dropdown-link {
display: flex;
justify-content: center;
align-items: center;
height: 30px;
margin-right: 16px;
}
}
</style>

View File

@ -0,0 +1,209 @@
<!--
* @MoudelName: 基本视图
* @Company: 湖南xx科技有限公司
* @Author: LJ
* @Date: 2024-04-08 17:27:06
-->
<template>
<div class="cvi-layout-container">
<el-header>
<Header />
</el-header>
<el-main
v-if="
projectName == 'tyrz' ||
projectName == 'zbzx' ||
projectName == 'rwzx' ||
projectName == 'jqzx' ||
projectName == 'zhgl' ||
projectName == 'zdry' ||
projectName == 'jcjcgk' ||
projectName == 'zygl'
"
>
<el-menu
:default-active="activeMenu"
background-color="#545c64"
text-color="#ffffff"
active-text-color="#ffffff"
:unique-opened="true"
:default-openeds="defaultOpends"
>
<template v-for="item in allMenuData[projectName]">
<MenuItem v-if="!item.hidden" @select="handleSelect" :key="item.gncdbh" :item="item" />
</template>
</el-menu>
<div class="cvi-left">
<ElTabs :tabsdata="tabsData" @selected-data="handleTabClick" @tab-remove="removeTab"></ElTabs>
<Content :tabHeight="true" />
</div>
</el-main>
<el-main v-else>
<Content />
</el-main>
</div>
</template>
<script setup>
import { ref, watch, onMounted, defineEmits, defineComponent } from 'vue'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/modules/user'
import { useRouteStore } from '@/stores/modules/router'
import MenuItem from '@/components/ElMenu/index.vue'
import ElTabs from '@/components/ElTabs/index.vue'
import Header from './header/index-cvi.vue'
import Content from './content/index-cvi.vue'
const router = useRouter()
const userStore = useUserStore()
const routerStore = useRouteStore()
const allMenuData = routerStore.allMenuData
const currentPageURL = window.location.href
const urlParts = currentPageURL.split('/')
const projectName = urlParts[3]
const activeMenu = ref('')
const tabsData = ref([])
const defaultOpends = ref([])
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)
addTab(selectedItem)
}
const findItemByRoute = (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
routerStore.setCurrentRoute(router.currentRoute.value.path)
}
onMounted(async () => {
initTags()
const projectNameArr = ['tyrz', 'rwzx', 'jqzx', 'zhgl', 'zdry', 'zygl']
if (projectNameArr.indexOf(projectName) != -1) {
activeMenu.value = routerStore.currentRoute
tabsData.value = routerStore.visitedRoutes
}
if (projectName == 'zbzx') {
initNoClosableTabs(allMenuData[projectName])
activeMenu.value = allMenuData[projectName][0].children[1].path
activeMenu.value = routerStore.currentRoute
tabsData.value = routerStore.visitedRoutes
}
})
</script>
<style lang="scss" scoped>
.cvi-layout-container {
width: 100%;
height: 100%;
background-size: 100% 100%;
transition: all 0.4s;
.el-header {
width: 100%;
height: 56px;
}
.el-main {
display: flex;
overflow: hidden;
width: 100%;
height: calc(100% - 56px);
padding: 0;
.cvi-left {
width: 100%;
}
.cvi-left::-webkit-scrollbar {
width: 0;
}
}
.newHeight {
height: 100%;
}
}
</style>

View File

@ -0,0 +1,300 @@
<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>