2025-03-12 18:41:20 +08:00
|
|
|
|
<template>
|
2025-03-14 20:03:14 +08:00
|
|
|
|
<d-layout class="d-layout h-full" :class="{ 'home-background': isHome }">
|
2025-03-12 18:41:20 +08:00
|
|
|
|
<d-header class="d-header">
|
|
|
|
|
|
<!-- header -->
|
|
|
|
|
|
<Header @clickMenu="handleClickMenu" :asideSetShow="asideSetShow" ref="refHeader">
|
|
|
|
|
|
<!-- 二级导航左侧内容 -->
|
|
|
|
|
|
<template v-if="$slots.headerLeft && !route?.meta?.hideNav" #info>
|
|
|
|
|
|
<slot name="headerLeft"></slot>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 二级导航右侧内容 -->
|
|
|
|
|
|
<template v-if="$slots.headerRight && !route?.meta?.hideNav" #menu>
|
|
|
|
|
|
<slot name="headerRight"></slot>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<template v-if="$slots.bodyHeader && !route?.meta?.hideNav" #bodyHeader>
|
|
|
|
|
|
<slot name="bodyHeader"></slot>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-if="$slots.headerBottom && !route?.meta?.hideNav" #headerBottom>
|
|
|
|
|
|
<slot name="headerBottom"></slot>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</Header>
|
|
|
|
|
|
</d-header>
|
|
|
|
|
|
<!-- 顶栏信息 -->
|
|
|
|
|
|
<div v-if="$slots.contentBanner">
|
|
|
|
|
|
<slot name="contentBanner"></slot>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 主体 -->
|
|
|
|
|
|
<d-layout class="flex-col">
|
|
|
|
|
|
<d-aside class="left-side-bar" v-if="asideSetShow" :style="{ width: mainMarginLeftWidth + 'px' }">
|
|
|
|
|
|
<Aside :asideDefaultWidth="mainMarginLeftWidth"></Aside>
|
|
|
|
|
|
</d-aside>
|
|
|
|
|
|
<d-drawer v-model="asideVisible" position="left" lock-scroll style="max-height: 100%; top: 0;"
|
|
|
|
|
|
:style="{ width: '240px', overflowY: 'hidden' }">
|
|
|
|
|
|
<div class="p-[16px] flex justify-between items-center h-[60px]">
|
|
|
|
|
|
<GLink class="g-toolbar-left-logo" href="/" />
|
|
|
|
|
|
<d-icon class="cursor-pointer" name="close" @click="asideVisible = false"></d-icon>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Aside :asideDefaultWidth="240" @on-select="handleClickMenu" style="height: calc(100% - 60px);padding-top: 0px;"></Aside>
|
|
|
|
|
|
</d-drawer>
|
|
|
|
|
|
<d-layout :style="{ marginLeft: mainMarginLeftWidth + 'px', transition: 'margin-left ease 0.1s' }">
|
|
|
|
|
|
<d-layout :class="responsiveClass" :style="{ minHeight: `calc(100% - ${footerSize?.height.value || 0}px)` }">
|
|
|
|
|
|
<!-- sidebar -->
|
|
|
|
|
|
<d-aside class="d-aside mr-[32px] pt-24" v-if="route?.meta?.sidebarType">
|
|
|
|
|
|
<slot name="sidebar"></slot>
|
|
|
|
|
|
</d-aside>
|
|
|
|
|
|
<!-- 内容 -->
|
|
|
|
|
|
<d-content>
|
|
|
|
|
|
<slot name="content">
|
|
|
|
|
|
<RouterView />
|
|
|
|
|
|
</slot>
|
|
|
|
|
|
</d-content>
|
|
|
|
|
|
</d-layout>
|
|
|
|
|
|
<!-- footer -->
|
|
|
|
|
|
<!-- <d-footer v-if="!route?.meta?.hiddenFooter" ref="refFooter">
|
|
|
|
|
|
<slot name="footer">
|
|
|
|
|
|
<Footer />
|
|
|
|
|
|
</slot>
|
|
|
|
|
|
</d-footer> -->
|
|
|
|
|
|
</d-layout>
|
|
|
|
|
|
</d-layout>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 浮动工具栏(移动端不显示) -->
|
|
|
|
|
|
<!-- <ToolsFloat v-if="showToolsFloat" />-->
|
|
|
|
|
|
|
|
|
|
|
|
</d-layout>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
defineOptions({ name: 'DefaultLayout' });
|
|
|
|
|
|
import { RouterView, useRoute, useRouter } from 'vue-router';
|
|
|
|
|
|
import { computed, ref, watch, watchEffect, onMounted, onUnmounted } from 'vue';
|
|
|
|
|
|
import Header from '@/components/Header/index.vue';
|
|
|
|
|
|
import Footer from '@/components/Footer/index.vue';
|
|
|
|
|
|
import Aside from './aside.vue';
|
|
|
|
|
|
import { useGlobalInfoStore } from '@/stores/Global';
|
|
|
|
|
|
|
|
|
|
|
|
import ToolsFloat from '@/components/ToolsFloat/index.vue';
|
|
|
|
|
|
import { useStorage, useElementSize } from '@vueuse/core';
|
|
|
|
|
|
import { usePageResize } from '@/utils/hooks/usePageResize';
|
|
|
|
|
|
import microApp from '@micro-zoe/micro-app';
|
|
|
|
|
|
defineProps<{ customAside?: boolean; }>();
|
|
|
|
|
|
const router = useRouter();
|
|
|
|
|
|
const solt = defineSlots();
|
|
|
|
|
|
const sizeStore = usePageResize();
|
|
|
|
|
|
const globalStore = useGlobalInfoStore();
|
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
|
const asideVisible = ref(false);
|
|
|
|
|
|
const refFooter = ref(null);
|
|
|
|
|
|
const refHeader: any = ref(null);
|
|
|
|
|
|
const footerSize = useElementSize(refFooter);
|
2025-03-14 20:03:14 +08:00
|
|
|
|
const isHome = computed(() => route.name === 'home');
|
2025-03-12 18:41:20 +08:00
|
|
|
|
|
|
|
|
|
|
// aside 设置可见性 header有两层,有顶栏信息,两层sidebar 都不可见
|
|
|
|
|
|
const asideSetShow = computed(() => {
|
|
|
|
|
|
if (route.meta.asideMenu === 'drawer') return false;
|
|
|
|
|
|
return refHeader.value?.height <= 56 && !solt.contentBanner && !route.meta.sidebarType;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
|
|
clickMenu: [];
|
|
|
|
|
|
}>();
|
|
|
|
|
|
watch(route, () => {
|
|
|
|
|
|
globalStore.setIsNotFound(false); // 切换路由默认不显示404,防止一直显示404
|
|
|
|
|
|
}, { deep: true });
|
|
|
|
|
|
|
|
|
|
|
|
const asideDefaultWidth = useStorage('asideDefaultWidth', sizeStore.isMobile.value ? 0 : 240);
|
|
|
|
|
|
const mainMarginLeftWidth = computed(() => {
|
|
|
|
|
|
if (!asideSetShow.value || sizeStore.isMobile.value) {
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return asideDefaultWidth.value;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 是否展示浮动工具栏(非移动端 || 未设置隐藏)
|
|
|
|
|
|
const showToolsFloat = computed(() => {
|
|
|
|
|
|
return sizeStore.widthType.value !== 'sm' && !route.meta.hiddenToolsFloat;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const responsiveClass = computed(() => { // 控制移动和pc布局
|
|
|
|
|
|
let className = 'm-auto max-w-normal px-normal w-full';
|
|
|
|
|
|
let viewportContent = 'width=device-width,initial-scale=0,user-scalable=yes,maximum-scale=1.0';
|
|
|
|
|
|
|
|
|
|
|
|
if (sizeStore.isMobile.value) { // 设备是否为手机
|
|
|
|
|
|
if (route?.meta?.hasMobile) { // 是否有手机端页面
|
|
|
|
|
|
className = 'w-full';
|
|
|
|
|
|
viewportContent = 'width=device-width, initial-scale=1.0';
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (route?.meta?.className) {
|
|
|
|
|
|
className = `${route?.meta?.className as string}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (route.name === 'homepage' && globalStore.namespaceType === 1) { // 组织主页样式特殊处理
|
|
|
|
|
|
className = 'm-auto min-w-sm px-normal max-w-[1280px] w-full pt-[12px]';
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
document?.querySelector("meta[name='viewport']")?.setAttribute('content', viewportContent);
|
|
|
|
|
|
return className;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const handleClickMenu = () => {
|
|
|
|
|
|
if (sizeStore.isMobile.value || !asideSetShow.value) { // 不可见时弹框
|
|
|
|
|
|
asideVisible.value = !asideVisible.value;
|
|
|
|
|
|
} else { // 可见时收起
|
|
|
|
|
|
asideDefaultWidth.value = asideDefaultWidth.value >= 240 ? 0 : 240;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const outOfSearch = ref(true); // 在search页面隐藏footer
|
|
|
|
|
|
router.afterEach((to, form) => {
|
|
|
|
|
|
outOfSearch.value = to.name !== 'search';
|
|
|
|
|
|
});
|
|
|
|
|
|
microApp.router.afterEach({
|
|
|
|
|
|
'micoro-app-homeweb-app': (to, from) => {
|
|
|
|
|
|
outOfSearch.value = to.pathname !== '/search';
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
const checkPage = (data: any) => {
|
|
|
|
|
|
if (data.type === 'checkPage') {
|
|
|
|
|
|
return 'ready';
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
microApp.addDataListener('micoro-app-homeweb-app', checkPage, false);
|
|
|
|
|
|
});
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
microApp.removeDataListener('micoro-app-homeweb-app', checkPage);
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.left-side-bar {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
top: 56px;
|
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
|
z-index: 10;
|
|
|
|
|
|
border-right: 1px solid #F1F1F8;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
overflow-x: hidden;
|
|
|
|
|
|
transition: width ease 0.1s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.g-toolbar-left-logo {
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
width: 102px;
|
|
|
|
|
|
height: 28px;
|
|
|
|
|
|
background: url(../../assets/imgs/logo/logo.png) no-repeat;
|
|
|
|
|
|
background-size: contain;
|
|
|
|
|
|
vertical-align: middle;
|
|
|
|
|
|
background-position: 0 center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-14 20:03:14 +08:00
|
|
|
|
.home-background {
|
|
|
|
|
|
&::before {
|
|
|
|
|
|
content: '';
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
2025-03-21 11:00:56 +08:00
|
|
|
|
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 1)),url('@/assets/imgs/home/bg.png');
|
2025-03-14 20:03:14 +08:00
|
|
|
|
background-size: cover;
|
|
|
|
|
|
background-position: center;
|
|
|
|
|
|
z-index: -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-03-12 18:41:20 +08:00
|
|
|
|
</style>
|