|
|
@@ -0,0 +1,515 @@
|
|
|
+<template>
|
|
|
+ <div v-if="isShowMenu == -1" class="bottom-side" :class="{ 'bottom-size-show': isShowMenu }" @click="closeMenu">
|
|
|
+ <SiderBorderBg>
|
|
|
+ <div class="close-btn" @click.stop="closeMenu"></div>
|
|
|
+ <div class="menu-panel" @click.stop>
|
|
|
+ <!-- 关键修改1:panel-header 从flex默认的justify-content:flex-start(已满足),但内层wrapper改为inline-flex -->
|
|
|
+ <div class="panel-header">
|
|
|
+ <template v-for="(menu, index) in currentParentRoute.children" :key="index">
|
|
|
+ <div class="col-header-wrapper" v-if="!menu.hideMenu">
|
|
|
+ <div class="col-header">
|
|
|
+ <div class="col-header-inner">{{ menu.name }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="col-arrow"></div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 关键修改2:panel-body 改为inline-flex,取消flex:1均分,添加align-items:flex-start -->
|
|
|
+ <div class="panel-body">
|
|
|
+ <template v-for="(menu, index) in currentParentRoute.children" :key="index">
|
|
|
+ <div class="menu-col" v-if="!menu.hideMenu">
|
|
|
+ <div class="menu-col-bg">
|
|
|
+ <template v-for="(childMenu, childIndex) in menu.children" :key="childIndex">
|
|
|
+ <template v-if="!childMenu.hideMenu">
|
|
|
+ <div v-if="childMenu['ver'] == 1" class="menu-item" @click.stop="handleMenuClick(childMenu)">{{ childMenu.name }}</div>
|
|
|
+ <div v-else class="menu-item menu-item-disabled" @click.stop="handleMenuClick(childMenu)">{{ childMenu.name }}</div>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="panel-footer">
|
|
|
+ <div class="tab-group">
|
|
|
+ <template v-for="(programMenu, key) in menuModules" :key="key">
|
|
|
+ <div
|
|
|
+ v-if="!programMenu.title.startsWith('首页')"
|
|
|
+ class="tab-btn"
|
|
|
+ :class="{ 'tab-btn-active': currentParentRoute == programMenu }"
|
|
|
+ @click.stop="selectMenu($event, programMenu)"
|
|
|
+ >{{ programMenu.title }}</div
|
|
|
+ >
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </SiderBorderBg>
|
|
|
+ </div>
|
|
|
+ <div v-else-if="isShowMenu == 0" class="menu-show-icon">
|
|
|
+ <div class="icon" @click="openMenu"></div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts">
|
|
|
+ import { defineComponent, nextTick, onMounted, ref, unref } from 'vue';
|
|
|
+ import type { Menu } from '/@/router/types';
|
|
|
+ import { SvgIcon } from '/@/components/Icon';
|
|
|
+ import { getMenus } from '/@/router/menus';
|
|
|
+ import { useGo } from '/@/hooks/web/usePage';
|
|
|
+ import { useRouter } from 'vue-router';
|
|
|
+ import { getActions } from '/@/qiankun/state';
|
|
|
+ import { PageEnum } from '/@/enums/pageEnum';
|
|
|
+ import { useGlobSetting } from '/@/hooks/setting';
|
|
|
+ import { unmountMicroApps } from '/@/qiankun';
|
|
|
+ import { useUserStoreWithOut } from '/@/store/modules/user';
|
|
|
+ import { useAppStore } from '/@/store/modules/app';
|
|
|
+ import { router } from '/@/router';
|
|
|
+ import SiderBorderBg from '/@/components/vent/siderBorderBg.vue';
|
|
|
+
|
|
|
+ export default defineComponent({
|
|
|
+ name: 'BottomSider',
|
|
|
+ components: { SvgIcon, SiderBorderBg },
|
|
|
+ setup() {
|
|
|
+ let menuModules = ref<Menu[]>([]);
|
|
|
+ const actions = getActions();
|
|
|
+ const currentParentRoute = ref<Menu>();
|
|
|
+ const { currentRoute } = useRouter();
|
|
|
+ const route = unref(currentRoute);
|
|
|
+ const go = useGo();
|
|
|
+ const glob = useGlobSetting();
|
|
|
+ const isShowMenu = ref(route.path.startsWith('/cad-viewer') ? 1 : 0);
|
|
|
+ const userStore = useUserStoreWithOut();
|
|
|
+ const themeIcon = ref('styleTwo');
|
|
|
+
|
|
|
+ function selectMenu(e: Event, programMenu) {
|
|
|
+ e.stopPropagation();
|
|
|
+ currentParentRoute.value = programMenu;
|
|
|
+ }
|
|
|
+
|
|
|
+ async function handleMenuClick(path: Menu) {
|
|
|
+ if (path.path == currentRoute.value.fullPath) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (path.path.includes('sw/monitor-fanmain')) {
|
|
|
+ var url = window.open('_blank') as Window;
|
|
|
+ url.location = 'https://swkhmi.shendong.vip:9043/#SW_PW_NORTH';
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (path.path.includes('sw/forcFan')) {
|
|
|
+ var url = window.open('_blank') as Window;
|
|
|
+ url.location = 'https://swkhmi.shendong.vip:9043/#SW_CA';
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (path.path.includes('outlink/index')) {
|
|
|
+ var url = window.open('_blank') as Window;
|
|
|
+ url.location = path['frameSrc'];
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ go(path.path);
|
|
|
+ isShowMenu.value = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ function geHome() {
|
|
|
+ if (userStore.getUserInfo.homePath) {
|
|
|
+ go(userStore.getUserInfo.homePath);
|
|
|
+ } else if (currentRoute.value.path.startsWith('/micro-need-air')) {
|
|
|
+ window.history.pushState({}, '', glob.homePath || PageEnum.BASE_HOME);
|
|
|
+ } else {
|
|
|
+ go(glob.homePath || PageEnum.BASE_HOME);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ function closeMenu(e?: Event) {
|
|
|
+ e?.stopPropagation();
|
|
|
+ isShowMenu.value = 0;
|
|
|
+ document.removeEventListener('click', closeMenu);
|
|
|
+ }
|
|
|
+
|
|
|
+ function openMenu(e: Event) {
|
|
|
+ e.stopPropagation();
|
|
|
+ isShowMenu.value = -1;
|
|
|
+ document.addEventListener('click', closeMenu);
|
|
|
+ }
|
|
|
+
|
|
|
+ onMounted(async () => {
|
|
|
+ menuModules.value = await getMenus();
|
|
|
+ const index = menuModules.value.findIndex((menu) => menu.children && menu.children.length > 0);
|
|
|
+ currentParentRoute.value = menuModules.value[index];
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ themeIcon,
|
|
|
+ menuModules,
|
|
|
+ isShowMenu,
|
|
|
+ handleMenuClick,
|
|
|
+ openMenu,
|
|
|
+ closeMenu,
|
|
|
+ selectMenu,
|
|
|
+ go,
|
|
|
+ geHome,
|
|
|
+ currentParentRoute,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+ @panel-bg: #091624;
|
|
|
+ @panel-border: #1a7aaa;
|
|
|
+ @accent: #00c8ff;
|
|
|
+ @accent-dim: #1a8aaa;
|
|
|
+ @header-bg: linear-gradient(180deg, #1b4e7a 0%, #0d3055 100%);
|
|
|
+ @header-border: #2a7aaa;
|
|
|
+ @item-bg: #071828;
|
|
|
+ @item-border: #155a80;
|
|
|
+ @item-text: #b0dcf0;
|
|
|
+ @tab-active-bg: #00b8d9;
|
|
|
+ @tab-active-text: #001f30;
|
|
|
+ @white: #ffffff;
|
|
|
+
|
|
|
+ @keyframes menuFadeIn {
|
|
|
+ from {
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+ to {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes panelScaleIn {
|
|
|
+ from {
|
|
|
+ opacity: 0;
|
|
|
+ transform: scale(0.96);
|
|
|
+ }
|
|
|
+ to {
|
|
|
+ opacity: 1;
|
|
|
+ transform: scale(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom-side {
|
|
|
+ position: fixed;
|
|
|
+ inset: 0;
|
|
|
+ z-index: 99999;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background: rgba(0, 8, 22, 0.7);
|
|
|
+ backdrop-filter: blur(3px);
|
|
|
+ color: #fff;
|
|
|
+ animation: panelScaleIn 0.3s ease forwards;
|
|
|
+
|
|
|
+ .menu-panel {
|
|
|
+ position: relative;
|
|
|
+ width: 92vw;
|
|
|
+ max-width: 1440px;
|
|
|
+ background: @panel-bg;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ height: 70%;
|
|
|
+ max-height: 70%;
|
|
|
+ overflow: hidden;
|
|
|
+ background: url(/@/assets/images//vent/sider/border.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .side-bar {
|
|
|
+ position: absolute;
|
|
|
+ top: 12%;
|
|
|
+ bottom: 12%;
|
|
|
+ width: 3px;
|
|
|
+ background: linear-gradient(180deg, transparent, @accent 25%, @accent 75%, transparent);
|
|
|
+ z-index: 10;
|
|
|
+ box-shadow: 0 0 6px @accent;
|
|
|
+
|
|
|
+ &.side-bar-left {
|
|
|
+ left: -2px;
|
|
|
+ }
|
|
|
+ &.side-bar-right {
|
|
|
+ right: -2px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .close-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: -18px;
|
|
|
+ right: 0px;
|
|
|
+ width: 22px;
|
|
|
+ height: 22px;
|
|
|
+ cursor: pointer;
|
|
|
+ background: url(/@/assets/images//vent/sider/svg-close.svg) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .panel-header {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-start;
|
|
|
+ padding: 0 24px;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ overflow-x: auto;
|
|
|
+ overflow-y: hidden;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .col-header-wrapper {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 100px;
|
|
|
+ width: 175px;
|
|
|
+ position: relative;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .col-header {
|
|
|
+ min-width: 100px;
|
|
|
+ width: 100%;
|
|
|
+ padding: 24px 12px 12px 12px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin: 0;
|
|
|
+ .col-header-inner {
|
|
|
+ width: 100%;
|
|
|
+ max-width: 135px;
|
|
|
+ height: 60px;
|
|
|
+ background: url(/@/assets/images//vent/sider/buttonTitle.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 500;
|
|
|
+ letter-spacing: 1px;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .col-arrow {
|
|
|
+ width: 20px;
|
|
|
+ height: 12px;
|
|
|
+ position: absolute;
|
|
|
+ right: -10px;
|
|
|
+ top: 57%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ pointer-events: none;
|
|
|
+ background: url(/@/assets/images//vent/sider/svg-arrow.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+ .col-header-wrapper:last-of-type .col-arrow {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .panel-body {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: auto;
|
|
|
+ padding: 14px 24px 10px;
|
|
|
+
|
|
|
+ // &::-webkit-scrollbar {
|
|
|
+ // width: 2px;
|
|
|
+ // height: 2px;
|
|
|
+ // }
|
|
|
+ // &::-webkit-scrollbar-track {
|
|
|
+ // background: #071420;
|
|
|
+ // }
|
|
|
+ // &::-webkit-scrollbar-thumb {
|
|
|
+ // background: @accent-dim;
|
|
|
+ // border-radius: 2px;
|
|
|
+ // }
|
|
|
+
|
|
|
+ .menu-col {
|
|
|
+ width: 175px;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .menu-col-bg {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ gap: 15px;
|
|
|
+ height: 500px;
|
|
|
+ width: 80%;
|
|
|
+ max-width: 175px;
|
|
|
+ max-height: 600px;
|
|
|
+ background: url(/@/assets/images//vent/sider/menu-bg.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ padding: 10px;
|
|
|
+ overflow-y: auto;
|
|
|
+ overflow-x: hidden;
|
|
|
+
|
|
|
+ &::-webkit-scrollbar {
|
|
|
+ width: 6px !important;
|
|
|
+ border: 0;
|
|
|
+ }
|
|
|
+ // &::-webkit-scrollbar-track {
|
|
|
+ // background: #071420;
|
|
|
+ // }
|
|
|
+ &::-webkit-scrollbar-thumb {
|
|
|
+ // width: 1px !important;
|
|
|
+ background: @accent-dim;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .menu-item {
|
|
|
+ width: 100%;
|
|
|
+ max-width: 128px;
|
|
|
+ min-height: 30px;
|
|
|
+ padding: 5px 6px;
|
|
|
+ text-align: center;
|
|
|
+ background: url(/@/assets/images//vent/sider/buttonCont.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ font-size: 12px;
|
|
|
+ color: @item-text;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.18s;
|
|
|
+ line-height: 1.5;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: url(/@/assets/images//vent/sider/buttonCont-hover.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .menu-item-disabled {
|
|
|
+ opacity: 0.45;
|
|
|
+ cursor: default;
|
|
|
+ background: #111a26;
|
|
|
+ border-color: #2a3a4a;
|
|
|
+ color: #6a8a9a;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #111a26;
|
|
|
+ border-color: #2a3a4a;
|
|
|
+ color: #6a8a9a;
|
|
|
+ box-shadow: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .panel-footer {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 10px 20px 0 20px;
|
|
|
+ position: relative;
|
|
|
+ flex-shrink: 0;
|
|
|
+
|
|
|
+ .tab-group {
|
|
|
+ width: 50%;
|
|
|
+ height: 35px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 1px;
|
|
|
+ background: url(/@/assets/images/vent/sider/border-bottom.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ padding: 0 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tab-btn {
|
|
|
+ width: 120px;
|
|
|
+ height: 25px;
|
|
|
+ color: @white;
|
|
|
+ font-size: 13px;
|
|
|
+ cursor: pointer;
|
|
|
+ background: url(/@/assets/images/vent/sider/buttonBot.png) no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ white-space: nowrap;
|
|
|
+ padding: 3px 5px 0 5px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tab-btn-active {
|
|
|
+ width: 120px;
|
|
|
+ height: 35px;
|
|
|
+ background: url(/@/assets/images/vent/sider/buttonBot-active.png) no-repeat;
|
|
|
+ background-size: 105% 100%;
|
|
|
+ font-weight: 500;
|
|
|
+ margin: 0 0 4px -5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .setting-group {
|
|
|
+ position: absolute;
|
|
|
+ right: 20px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10px;
|
|
|
+ color: @accent-dim;
|
|
|
+
|
|
|
+ .icon-style {
|
|
|
+ cursor: pointer;
|
|
|
+ transition: color 0.18s;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: @accent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bottom-size-show {
|
|
|
+ animation: menuFadeIn 0.3s ease forwards;
|
|
|
+ }
|
|
|
+
|
|
|
+ .menu-show-icon {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 20px;
|
|
|
+ left: 25px;
|
|
|
+ z-index: 1000000;
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ width: 60px;
|
|
|
+ height: 60px;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &:before {
|
|
|
+ content: '';
|
|
|
+ display: block;
|
|
|
+ width: 60px;
|
|
|
+ height: 60px;
|
|
|
+ position: absolute;
|
|
|
+ background: url('/@/assets/images/vent/sider/icon-outer.png') no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-position: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:after {
|
|
|
+ content: '';
|
|
|
+ display: block;
|
|
|
+ width: 36px;
|
|
|
+ height: 35px;
|
|
|
+ position: absolute;
|
|
|
+ top: 18%;
|
|
|
+ right: 18%;
|
|
|
+ background: url('/@/assets/images/vent/sider/icon-inner.svg') no-repeat;
|
|
|
+ background-size: 100% 100%;
|
|
|
+ background-position: center;
|
|
|
+ animation-timing-function: ease-in;
|
|
|
+ animation: fadenum 8s infinite;
|
|
|
+ }
|
|
|
+
|
|
|
+ @keyframes fadenum {
|
|
|
+ 0% {
|
|
|
+ transform: rotate(0deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ 10% {
|
|
|
+ transform: rotate(360deg);
|
|
|
+ }
|
|
|
+
|
|
|
+ 100% {
|
|
|
+ transform: rotate(360deg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|