暂存
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div class="h-full">
|
||||
<div
|
||||
v-if="mode === 'head'"
|
||||
class="bg-white h-[calc(100%-4px)] text-slate-700 dark:text-slate-300 mx-2 dark:bg-slate-900 flex items-center w-[calc(100vw-600px)] overflow-auto"
|
||||
class="gva-tech-aside-head h-[calc(100%-4px)] mx-2 flex items-center w-[calc(100vw-600px)] overflow-auto"
|
||||
>
|
||||
<el-menu
|
||||
:default-active="routerStore.topActive"
|
||||
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="mode === 'normal'"
|
||||
class="relative h-full bg-white text-slate-700 dark:text-slate-300 dark:bg-slate-900 border-r shadow dark:shadow-gray-700"
|
||||
class="gva-tech-aside relative h-full border-r"
|
||||
:class="isCollapse ? '' : ' px-2'"
|
||||
:style="{
|
||||
width: layoutSideWidth + 'px'
|
||||
@@ -48,7 +48,7 @@
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
<div
|
||||
class="absolute bottom-8 right-2 w-8 h-8 bg-gray-50 dark:bg-slate-800 flex items-center justify-center rounded cursor-pointer"
|
||||
class="gva-tech-collapse-btn absolute bottom-8 right-2 w-8 h-8 flex items-center justify-center rounded cursor-pointer"
|
||||
:class="isCollapse ? 'right-0 left-0 mx-auto' : 'right-2'"
|
||||
@click="toggleCollapse"
|
||||
>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="bg-white h-[calc(100%-4px)] text-slate-700 dark:text-slate-300 mx-2 dark:bg-slate-900 flex items-center w-[calc(100vw-600px)] overflow-auto"
|
||||
class="gva-tech-aside-head h-[calc(100%-4px)] mx-2 flex items-center w-[calc(100vw-600px)] overflow-auto"
|
||||
ref="menuContainer"
|
||||
>
|
||||
<el-menu
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="relative h-full bg-white text-slate-700 dark:text-slate-300 dark:bg-slate-900 border-r shadow dark:shadow-gray-700"
|
||||
class="gva-tech-aside relative h-full border-r"
|
||||
:class="isCollapse ? '' : ' px-2'"
|
||||
:style="{
|
||||
width: layoutSideWidth + 'px'
|
||||
@@ -25,7 +25,7 @@
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
<div
|
||||
class="absolute bottom-8 right-2 w-8 h-8 bg-gray-50 dark:bg-slate-800 flex items-center justify-center rounded cursor-pointer"
|
||||
class="gva-tech-collapse-btn absolute bottom-8 right-2 w-8 h-8 flex items-center justify-center rounded cursor-pointer"
|
||||
:class="isCollapse ? 'right-0 left-0 mx-auto' : 'right-2'"
|
||||
@click="toggleCollapse"
|
||||
>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="flex h-full">
|
||||
<!-- 一级菜单常驻侧边栏 -->
|
||||
<div
|
||||
class="relative !h-full bg-white text-slate-700 dark:text-slate-300 dark:bg-slate-900 border-r shadow dark:shadow-gray-700"
|
||||
class="gva-tech-aside-rail relative !h-full border-r"
|
||||
:style="{
|
||||
width: config.layout_side_collapsed_width + 'px'
|
||||
}"
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
<!-- 二级菜单并列显示 -->
|
||||
<div
|
||||
class="relative h-full bg-white text-slate-700 dark:text-slate-300 dark:bg-slate-900 border-r shadow dark:shadow-gray-700 px-2"
|
||||
class="gva-tech-aside-secondary relative h-full border-r px-2"
|
||||
:style="{
|
||||
width: layoutSideWidth + 'px'
|
||||
}"
|
||||
@@ -88,7 +88,7 @@
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
<div
|
||||
class="absolute bottom-8 right-2 w-8 h-8 bg-gray-50 dark:bg-slate-800 flex items-center justify-center rounded cursor-pointer"
|
||||
class="gva-tech-collapse-btn absolute bottom-8 right-2 w-8 h-8 flex items-center justify-center rounded cursor-pointer"
|
||||
:class="isCollapse ? 'right-0 left-0 mx-auto' : 'right-2'"
|
||||
@click="toggleCollapse"
|
||||
>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex justify-between fixed top-0 left-0 right-0 z-10 h-16 bg-white text-slate-700 dark:text-slate-300 dark:bg-slate-900 shadow dark:shadow-gray-700 items-center px-2"
|
||||
class="gva-tech-header flex justify-between fixed top-0 left-0 right-0 z-10 h-16 items-center px-2"
|
||||
>
|
||||
<div class="flex items-center cursor-pointer flex-1">
|
||||
<div
|
||||
@@ -16,7 +16,7 @@
|
||||
<Logo />
|
||||
<div
|
||||
v-if="!isMobile"
|
||||
class="inline-flex font-bold text-2xl ml-2"
|
||||
class="gva-tech-brand inline-flex font-bold text-2xl ml-2"
|
||||
:class="
|
||||
(config.side_mode === 'head' ||
|
||||
config.side_mode === 'combination') &&
|
||||
@@ -55,7 +55,7 @@
|
||||
<el-dropdown>
|
||||
<div class="flex justify-center items-center h-full w-full">
|
||||
<span
|
||||
class="cursor-pointer flex justify-center items-center text-black dark:text-gray-100"
|
||||
class="cursor-pointer flex justify-center items-center text-cyan-50"
|
||||
>
|
||||
<CustomPic />
|
||||
<span v-show="!isMobile" class="w-16">{{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="bg-gray-50 text-slate-700 dark:text-slate-500 dark:bg-slate-800 w-screen h-screen">
|
||||
<div class="gva-tech-layout w-screen h-screen">
|
||||
<el-watermark
|
||||
v-if="config.show_watermark"
|
||||
:font="font"
|
||||
:font="[font]"
|
||||
:z-index="9999"
|
||||
:gap="[180, 150]"
|
||||
class="!absolute !inset-0 !pointer-events-none"
|
||||
@@ -14,18 +14,25 @@
|
||||
v-if="
|
||||
config.side_mode === 'normal' ||
|
||||
config.side_mode === 'sidebar' ||
|
||||
(device === 'mobile' && config.side_mode == 'head') ||
|
||||
(device === 'mobile' && config.side_mode == 'combination')
|
||||
(device === 'mobile' && config.side_mode === 'head') ||
|
||||
(device === 'mobile' && config.side_mode === 'combination')
|
||||
"
|
||||
/>
|
||||
<gva-aside v-if="config.side_mode === 'combination' && device !== 'mobile'" mode="normal" />
|
||||
<div class="flex-1 w-0 h-full">
|
||||
<div class="gva-tech-main flex-1 w-0 h-full">
|
||||
<gva-tabs v-if="config.showTabs" />
|
||||
<div class="overflow-auto px-2" :class="config.showTabs ? 'gva-container2' : 'gva-container pt-1'">
|
||||
<div class="gva-tech-scroll overflow-auto px-2" :class="config.showTabs ? 'gva-container2' : 'gva-container pt-1'">
|
||||
<router-view v-if="reloadFlag" v-slot="{ Component, route }">
|
||||
<div id="gva-base-load-dom" class="gva-body-h bg-gray-50 dark:bg-slate-800">
|
||||
<transition mode="out-in" :name="route.meta.transitionType || config.transition_type">
|
||||
<keep-alive :include="routerStore.keepAliveRouters">
|
||||
<div id="gva-base-load-dom" class="gva-body-h gva-tech-router-view">
|
||||
<div v-if="showPageBanner(route)" class="gva-page-banner">
|
||||
<div>
|
||||
<div class="gva-page-kicker">INDUSTRIAL CONTROL</div>
|
||||
<h1 class="gva-page-title">{{ fmtTitle(route.meta.title, route) }}</h1>
|
||||
<p class="gva-page-subtitle">智慧用电安全监控 · 实时态势感知平台</p>
|
||||
</div>
|
||||
</div>
|
||||
<transition mode="out-in" :name="route.meta['transitionType'] || config.transition_type">
|
||||
<keep-alive :include="keepAliveRouterNames">
|
||||
<component :is="Component" :key="route.fullPath" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
@@ -45,12 +52,13 @@
|
||||
import GvaTabs from './tabs/index.vue'
|
||||
import BottomInfo from '@/components/bottomInfo/bottomInfo.vue'
|
||||
import { emitter } from '@/utils/bus.js'
|
||||
import { ref, onMounted, nextTick, reactive, watchEffect } from 'vue'
|
||||
import { ref, onMounted, nextTick, computed } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { useRouterStore } from '@/pinia/modules/router'
|
||||
import { useUserStore } from '@/pinia/modules/user'
|
||||
import { useAppStore } from '@/pinia'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { fmtTitle } from '@/utils/fmtRouterTitle'
|
||||
import '@/style/transition.scss'
|
||||
const appStore = useAppStore()
|
||||
const { config, isDark, device } = storeToRefs(appStore)
|
||||
@@ -60,23 +68,20 @@
|
||||
})
|
||||
|
||||
useResponsive(true)
|
||||
const font = reactive({
|
||||
color: 'rgba(0, 0, 0, .15)'
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
font.color = isDark.value ? 'rgba(255,255,255, .15)' : 'rgba(0, 0, 0, .15)'
|
||||
})
|
||||
const font = computed(() => ({
|
||||
color: isDark.value ? 'rgba(255,255,255, .15)' : 'rgba(0, 0, 0, .15)'
|
||||
}))
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const routerStore = useRouterStore()
|
||||
const keepAliveRouterNames = computed(() => routerStore.keepAliveRouters)
|
||||
|
||||
onMounted(() => {
|
||||
// 挂载一些通用的事件
|
||||
emitter.on('reload', reload)
|
||||
if (userStore.loadingInstance) {
|
||||
userStore.loadingInstance.close()
|
||||
if (userStore['loadingInstance']) {
|
||||
userStore['loadingInstance']['close']()
|
||||
}
|
||||
nextTick(() => {
|
||||
document.getElementsByClassName(
|
||||
@@ -88,6 +93,13 @@
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
const hideBannerRouteNames = ['Login', 'Reload', 'Init']
|
||||
const showPageBanner = (currentRoute) => {
|
||||
if (!currentRoute?.meta?.title) return false
|
||||
if (hideBannerRouteNames.includes(currentRoute.name)) return false
|
||||
return !currentRoute.meta.client && !currentRoute.meta['hidePageHeader']
|
||||
}
|
||||
|
||||
const reloadFlag = ref(true)
|
||||
let reloadTimer = null
|
||||
const reload = async () => {
|
||||
@@ -95,13 +107,13 @@
|
||||
window.clearTimeout(reloadTimer)
|
||||
}
|
||||
reloadTimer = window.setTimeout(async () => {
|
||||
if (route.meta.keepAlive) {
|
||||
if (route.meta['keepAlive']) {
|
||||
reloadFlag.value = false
|
||||
await nextTick()
|
||||
reloadFlag.value = true
|
||||
} else {
|
||||
const title = route.meta.title
|
||||
router.push({ name: 'Reload', params: { title } })
|
||||
const title = route.meta['title']
|
||||
await router.push({ name: 'Reload', params: { title } })
|
||||
}
|
||||
}, 400)
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
@date: 2024/5/7
|
||||
!-->
|
||||
<template>
|
||||
<div class="gva-tabs">
|
||||
<div class="gva-tabs gva-tech-tabs">
|
||||
<el-tabs
|
||||
v-model="activeValue"
|
||||
:closable="!(historys.length === 1 && $route.name === defaultRouter)"
|
||||
type="card"
|
||||
class="bg-white text-slate-700 dark:text-slate-500 dark:bg-slate-900 pt-1"
|
||||
class="pt-1"
|
||||
@contextmenu.prevent="openContextMenu($event)"
|
||||
@tab-click="changeTab"
|
||||
@tab-remove="removeTab"
|
||||
@@ -44,16 +44,19 @@
|
||||
</el-tabs>
|
||||
|
||||
<!--自定义右键菜单html代码-->
|
||||
<ul
|
||||
v-show="contextMenuVisible"
|
||||
:style="{ left: left + 'px', top: top + 'px' }"
|
||||
class="contextmenu"
|
||||
>
|
||||
<li @click="closeAll">关闭所有</li>
|
||||
<li @click="closeLeft">关闭左侧</li>
|
||||
<li @click="closeRight">关闭右侧</li>
|
||||
<li @click="closeOther">关闭其他</li>
|
||||
</ul>
|
||||
<teleport to="body">
|
||||
<ul
|
||||
v-show="contextMenuVisible"
|
||||
:style="{ left: left + 'px', top: top + 'px' }"
|
||||
ref="contextMenuRef"
|
||||
class="contextmenu"
|
||||
>
|
||||
<li @click="closeAll">关闭所有</li>
|
||||
<li @click="closeLeft">关闭左侧</li>
|
||||
<li @click="closeRight">关闭右侧</li>
|
||||
<li @click="closeOther">关闭其他</li>
|
||||
</ul>
|
||||
</teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -83,6 +86,7 @@
|
||||
|
||||
const left = ref(0)
|
||||
const top = ref(0)
|
||||
const contextMenuRef = ref(null)
|
||||
const isCollapse = ref(false)
|
||||
const isMobile = ref(false)
|
||||
const rightActive = ref('')
|
||||
@@ -93,18 +97,25 @@
|
||||
if (historys.value.length === 1 && route.name === defaultRouter.value) {
|
||||
return false
|
||||
}
|
||||
let id = ''
|
||||
if (e.srcElement.nodeName === 'SPAN') {
|
||||
id = e.srcElement.offsetParent.id
|
||||
} else {
|
||||
id = e.srcElement.id
|
||||
}
|
||||
const tabEl = e.target?.closest?.('[id^="tab-"]')
|
||||
const id = tabEl?.id || ''
|
||||
if (id) {
|
||||
contextMenuVisible.value = true
|
||||
|
||||
left.value = e.clientX
|
||||
top.value = e.clientY + 10
|
||||
rightActive.value = id.substring(4)
|
||||
const tabRect = tabEl.getBoundingClientRect()
|
||||
left.value = tabRect.left
|
||||
top.value = tabRect.bottom + 6
|
||||
nextTick(() => {
|
||||
const menu = contextMenuRef.value
|
||||
if (!menu) return
|
||||
const { offsetWidth, offsetHeight } = menu
|
||||
const edgeSpace = 8
|
||||
const maxLeft = window.innerWidth - offsetWidth - edgeSpace
|
||||
const maxTop = window.innerHeight - offsetHeight - edgeSpace
|
||||
left.value = Math.max(edgeSpace, Math.min(left.value, maxLeft))
|
||||
top.value = Math.max(edgeSpace, Math.min(top.value, maxTop))
|
||||
})
|
||||
}
|
||||
}
|
||||
const closeAll = () => {
|
||||
@@ -379,16 +390,46 @@
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.contextmenu {
|
||||
@apply bg-white dark:bg-slate-900 w-28 m-0 py-2.5 px-0 border border-gray-200 text-sm shadow-md rounded absolute z-50 border-solid dark:border-slate-800;
|
||||
min-width: 120px;
|
||||
padding: 6px;
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
z-index: 3000;
|
||||
overflow: hidden;
|
||||
list-style: none;
|
||||
border: 1px solid rgba(0, 212, 255, 0.26);
|
||||
border-radius: 12px;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(9, 24, 48, 0.98), rgba(5, 16, 32, 0.94)),
|
||||
radial-gradient(circle at 100% 0%, rgba(0, 212, 255, 0.12), transparent 34%);
|
||||
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.42), 0 0 22px rgba(0, 212, 255, 0.16);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.contextmenu li {
|
||||
@apply text-slate-700 dark:text-slate-200 text-base list-none px-4 py-1.5 hover:bg-gray-100 dark:hover:bg-gray-600 cursor-pointer;
|
||||
min-height: 32px;
|
||||
padding: 6px 14px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: var(--tech-text-muted, #bfdbfe);
|
||||
cursor: pointer;
|
||||
border-radius: 8px;
|
||||
transition: color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
color: #67e8f9;
|
||||
background: rgba(14, 165, 233, 0.18);
|
||||
box-shadow: inset 0 0 14px rgba(0, 212, 255, 0.08);
|
||||
transform: translateX(2px);
|
||||
}
|
||||
}
|
||||
|
||||
$base-tag-item-height: 4rem;
|
||||
|
||||
.gva-tabs {
|
||||
position: relative;
|
||||
|
||||
::v-deep(.el-tabs--card > .el-tabs__header) {
|
||||
border: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user