From 75f043dfa6660716364e66ee0b3cf99f44255686 Mon Sep 17 00:00:00 2001 From: DYL0109 <dn18191638832@163.com> Date: 星期三, 16 四月 2025 19:20:36 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/develop1.0' into dyl_dev --- zhitan-vue/src/layout/index.vue | 300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 281 insertions(+), 19 deletions(-) diff --git a/zhitan-vue/src/layout/index.vue b/zhitan-vue/src/layout/index.vue index 444d714..90aaa04 100644 --- a/zhitan-vue/src/layout/index.vue +++ b/zhitan-vue/src/layout/index.vue @@ -1,34 +1,99 @@ <template> <div :class="classObj" class="app-wrapper" :style="{ '--current-color': theme }"> <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> - <sidebar v-if="!sidebar.hide" class="sidebar-container" /> - <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container"> - <div :class="{ 'fixed-header': fixedHeader }"> - <navbar @setLayout="setLayout" v-if="!sidebar.hide"/> - <tags-view v-if="needTagsView" v-show="!sidebar.hide"/> + <div class="navbar-container"> + <div class="navbar"> + <div class="left"> + <div class="sidebar-logo-container" :class="{ collapse: !sidebar.opened }"> + <div class="logo" v-if="systemInfo && systemInfo.leftLogo"> + <img v-if="sideTheme === 'theme-dark'" :src="systemInfo.leftLogo" class="sidebar-logo" /> + <img v-else :src="systemInfo.leftLogo" class="sidebar-logo" /> + </div> + <div class="name" v-if="sidebar.opened" :style="{ color: sideTheme === 'theme-dark' ? '#fff' : '#333' }"> + {{ title }} + </div> + </div> + <hamburger + id="hamburger-container" + :is-active="appStore.sidebar.opened" + class="hamburger-container" + @toggleClick="toggleSideBar" + /> + </div> + <top-nav /> + <div class="right"> + <!-- 鎶ヨ鍜屽ぇ妯″瀷鎸夐挳 --> + <div class="right-menu"> + <!-- 鎶ヨ鎸夐挳 --> + <div class="right-menu-item alarm-btn" @click="goToAlarm"> + <el-badge :value="alarmCount" :max="99" class="alarm-badge"> + <svg-icon icon-class="bell" class="right-menu-icon" /> + </el-badge> + <span class="right-menu-text">鎶ヨ</span> + </div> + + <!-- 澶фā鍨嬫寜閽� --> + <div class="right-menu-item ai-btn" @click="openAIModel"> + <svg-icon icon-class="ai" class="right-menu-icon" /> + <span class="right-menu-text">鏅鸿兘鍔╂墜</span> + </div> + </div> + </div> </div> - <app-main /> - <settings ref="settingRef" /> + </div> + <div class="content-container"> + <sidebar v-if="!sidebar.hide" class="sidebar-container" /> + <div :class="{ hasTagsView: needTagsView, sidebarHide: sidebar.hide }" class="main-container"> + <div :class="{ 'fixed-header': fixedHeader }"> + <tags-view v-if="needTagsView" v-show="!sidebar.hide"/> + </div> + <app-main /> + <settings ref="settingRef" /> + </div> </div> </div> </template> <script setup> +import { ref, computed, watchEffect, onMounted } from 'vue' import { useWindowSize } from '@vueuse/core' +import { useRoute, useRouter } from 'vue-router' import Sidebar from './components/Sidebar/index.vue' -import { AppMain, Navbar, Settings, TagsView } from './components' +import { AppMain, Settings, TagsView } from './components' +import TopNav from '@/components/TopNav' +import Hamburger from '@/components/Hamburger' import defaultSettings from '@/settings' +import Cookies from "js-cookie" import useAppStore from '@/store/modules/app' import useSettingsStore from '@/store/modules/settings' +const route = useRoute() +const router = useRouter() +const appStore = useAppStore() const settingsStore = useSettingsStore() const theme = computed(() => settingsStore.theme); const sideTheme = computed(() => settingsStore.sideTheme); -const sidebar = computed(() => useAppStore().sidebar); -const device = computed(() => useAppStore().device); +const sidebar = computed(() => appStore.sidebar); +const device = computed(() => appStore.device); const needTagsView = computed(() => settingsStore.tagsView); const fixedHeader = computed(() => settingsStore.fixedHeader); +const systemInfo = JSON.parse(Cookies.get("SystemInfo") || '{"systemName":"鏅烘睍鑳芥簮绠$悊绯荤粺","leftLogo":""}') +const title = systemInfo.systemName || import.meta.env.VITE_APP_TITLE + +// 鎶ヨ鏁伴噺锛屽彲浠ヤ粠鎺ュ彛鑾峰彇 +const alarmCount = ref(5) + +// 璺宠浆鍒版姤璀﹂〉闈� +function goToAlarm() { + router.push('/alarmmanage/measuremen?modelCode=BJGL') +} + +// 鎵撳紑AI澶фā鍨嬪璇濇 +function openAIModel() { + // 璺宠浆鍒版寚瀹氱殑URL + window.open('https://deepseek.tan-zhonghe.com/chat', '_blank') +} const classObj = computed(() => ({ hideSidebar: !sidebar.value.opened, @@ -38,22 +103,51 @@ })) const { width, height } = useWindowSize(); -const WIDTH = 992; // refer to Bootstrap's responsive design +const WIDTH = 992; watchEffect(() => { if (device.value === 'mobile' && sidebar.value.opened) { - useAppStore().closeSideBar({ withoutAnimation: false }) + appStore.closeSideBar({ withoutAnimation: false }) } if (width.value - 1 < WIDTH) { - useAppStore().toggleDevice('mobile') - useAppStore().closeSideBar({ withoutAnimation: true }) + appStore.toggleDevice('mobile') + appStore.closeSideBar({ withoutAnimation: true }) } else { - useAppStore().toggleDevice('desktop') + appStore.toggleDevice('desktop') + } +}) + +// 鐩戝惉璺敱鍙樺寲锛屽鐞嗛椤电殑渚ц竟鏍忔樉绀� +watchEffect(() => { + // 妫�鏌ユ槸鍚︽槸棣栭〉璺敱锛屼絾鎺掗櫎/index/index瀛愯矾鐢� + if ((route.path === '/index' || route.path === '/') && route.path !== '/index/index') { + // 棣栭〉璺敱锛岀‘淇濅晶杈规爮涓嶉殣钘忥紝浣嗙姸鎬佹槸鎶樺彔鐨� + appStore.toggleSideBarHide(false) // 鏀逛负涓嶉殣钘忎晶杈规爮 + } else if (route.meta && route.meta.showSidebar === false) { + // 濡傛灉璺敱鏄庣‘鎸囧畾闅愯棌渚ц竟鏍� + appStore.toggleSideBarHide(true) + } else { + // 鍏朵粬璺敱锛岀‘淇濅晶杈规爮鍙 + appStore.toggleSideBarHide(false) + } +}) + +// 缁勪欢鎸傝浇鏃讹紝纭繚棣栭〉渚ц竟鏍忕姸鎬佹纭� +onMounted(() => { + // 濡傛灉褰撳墠鏄椤靛瓙椤甸潰锛屽彧纭繚渚ц竟鏍忎笉琚殣钘忥紝浣嗕繚鎸佹姌鍙�/灞曞紑鐘舵�佷笉鍙� + if (route.path === '/index/index') { + // 鍙缃笉闅愯棌渚ц竟鏍忥紝浣嗕笉鏀瑰彉鍏跺睍寮�/鎶樺彔鐘舵�� + appStore.toggleSideBarHide(false) + // 涓嶅啀寮哄埗璁剧疆opened涓簍rue锛屼繚鎸佺敤鎴蜂箣鍓嶇殑璁剧疆 } }) function handleClickOutside() { - useAppStore().closeSideBar({ withoutAnimation: false }) + appStore.closeSideBar({ withoutAnimation: false }) +} + +function toggleSideBar() { + appStore.toggleSideBar() } const settingRef = ref(null); @@ -69,8 +163,11 @@ .app-wrapper { @include clearfix; position: relative; - height: 100%; - width: 100%; + height: 100vh; + width: 100vw; + display: flex; + flex-direction: column; + overflow-x: hidden; &.mobile.openSidebar { position: fixed; @@ -88,13 +185,138 @@ z-index: 999; } -.fixed-header { +.navbar-container { position: fixed; top: 0; + left: 0; + right: 0; + height: 60px; + z-index: 1000; + width: 100%; +} + +.navbar { + display: flex; + justify-content: space-between; + align-items: center; + background-color: var(--current-color); + height: 60px; + width: 100%; + padding: 0; + + .left { + display: flex; + align-items: center; + padding-left: 16px; + + .sidebar-logo-container { + display: flex; + align-items: center; + height: 60px; + padding: 0 15px; + min-width: 220px; + + .logo { + width: 40px; + height: 40px; + margin-right: 10px; + flex-shrink: 0; + + .sidebar-logo { + width: 100%; + height: 100%; + } + } + + .name { + font-family: OPPOSans, OPPOSans; + font-weight: bold; + font-size: 20px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + &.collapse { + min-width: 70px; + + .name { + display: none; + } + } + } + } + + .right { + display: flex; + align-items: center; + padding-right: 20px; + + .right-menu { + display: flex; + align-items: center; + + .right-menu-item { + display: flex; + align-items: center; + margin-left: 20px; + cursor: pointer; + color: #fff; + font-size: 14px; + transition: all 0.3s; + + &:hover { + opacity: 0.8; + } + + .right-menu-icon { + font-size: 18px; + margin-right: 5px; + } + + .right-menu-text { + margin-left: 5px; + } + } + + .alarm-badge { + :deep(.el-badge__content) { + background-color: #f56c6c; + } + } + } + } +} + +.content-container { + display: flex; + position: relative; + margin-top: 60px; + height: calc(100vh - 60px); + width: 100%; + overflow: hidden; +} + +.sidebar-container { + position: relative; + height: 100%; + z-index: 900; + flex-shrink: 0; + width: $base-sidebar-width; + +} + +.fixed-header { + position: fixed; + top: 60px; right: 0; z-index: 9; width: calc(100% - #{$base-sidebar-width}); transition: width 0.28s; + display: flex; + flex-direction: column; + box-sizing: border-box; + padding: 0; } .hideSidebar .fixed-header { @@ -108,4 +330,44 @@ .mobile .fixed-header { width: 100%; } + +.main-container { + flex: 1; + position: relative; + height: 100%; + overflow-y: auto; + overflow-x: hidden; + transition: margin-left 0.28s; + box-sizing: border-box; +} + +.hideSidebar .main-container { + margin-left: 0; +} + +.sidebarHide .main-container { + margin-left: 0; +} + +.mobile .main-container { + margin-left: 0; +} + +.hideSidebar .sidebar-container { + width: 54px; +} + +.sidebarHide .sidebar-container { + display: none; +} + +.themeDark { + .navbar { + background: #002866 !important; + } + + .sidebar-container { + background-color: #002866 !important; + } +} </style> \ No newline at end of file -- Gitblit v1.9.3