122 lines
4.3 KiB
Vue
122 lines
4.3 KiB
Vue
<script setup lang="ts">
|
||
import { ref, reactive, computed, onMounted, watch } from "vue";
|
||
import { useRoute, useRouter } from "vue-router";
|
||
import layout from "./components/layout.vue";
|
||
import ModuleBar from "./components/ModuleBar.vue";
|
||
import HomeHero from "./components/HomeHero.vue";
|
||
import config from "@/assets/config/host.config";
|
||
import { baseApi } from "@/api/module/profession";
|
||
import { Message } from "view-ui-plus";
|
||
|
||
const route = useRoute();
|
||
const router = useRouter();
|
||
const isLogin = ref(false);
|
||
const layoutData = reactive({
|
||
baseHost: config.baseHost,
|
||
ssoHost: config.ssoHost,
|
||
schoolName: "教师专业发展",
|
||
appList: [] as any[],
|
||
userInfo: null as any,
|
||
});
|
||
|
||
async function initShell() {
|
||
try {
|
||
const user: any = await baseApi.getUserInfo().send();
|
||
const { id, name, type } = user || {};
|
||
layoutData.userInfo = { id, name: name || "", avatar: "", type };
|
||
layoutData.schoolName = user?.school?.name || "教师专业发展";
|
||
isLogin.value = true;
|
||
} catch (error: any) {
|
||
console.error("加载用户信息失败", error);
|
||
if (error?.message !== "redirect") {
|
||
Message.error("载入用户信息失败,请检查后端服务是否正常!");
|
||
}
|
||
layoutData.userInfo = { name: "", avatar: "" };
|
||
isLogin.value = true;
|
||
}
|
||
}
|
||
|
||
onMounted(initShell);
|
||
|
||
/* 方案D:hero 刊头仅出现在 发展首页 与 栏目列表·全校(与原型一致) */
|
||
const showHero = computed(
|
||
() => route.path === "/home" || (route.path === "/module/list" && !route.query.userid)
|
||
);
|
||
</script>
|
||
|
||
<template>
|
||
<layout v-if="isLogin" :layoutData="layoutData" />
|
||
<div v-if="isLogin" class="base-wrap-main alone-page">
|
||
<div class="main-wrapper">
|
||
<!-- 方案D · 蓝天校园:hero 刊头(首页/全校列表)+ 栏目条 + 页面内容;
|
||
no-hero:无刊头页由 body 顶部留白让出固定顶栏,刊头页靠 hero 负 margin 压入顶栏玻璃之下 -->
|
||
<div class="app-frame" :class="{ 'no-hero': !showHero }">
|
||
<HomeHero v-if="showHero"></HomeHero>
|
||
<ModuleBar></ModuleBar>
|
||
<div class="app-frame-body">
|
||
<router-view />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<footer class="app-footer">河南云海星通科技有限公司 版权所有 ©2024-2026 豫ICP备1234567890号</footer>
|
||
</template>
|
||
|
||
<style lang="scss">
|
||
html,
|
||
body {
|
||
margin: 0;
|
||
padding: 0;
|
||
height: 100%;
|
||
overflow: hidden;
|
||
}
|
||
#app {
|
||
height: 100%;
|
||
}
|
||
/* 方案D · 蓝天校园:居中容器(原型的 .container 已由 profession-ui.css 提供) */
|
||
.app-frame {
|
||
max-width: 1180px;
|
||
margin: 0 auto;
|
||
}
|
||
/* hero 刊头从视口顶起步:base-wrap-main 零 padding 后无需再抵消旧留白,
|
||
fixed 玻璃顶栏(z30)直接叠压刊头顶部,即原型 topbar margin-bottom:-51px 的效果 */
|
||
.app-frame .hero {
|
||
margin-top: 0;
|
||
}
|
||
.app-frame-body {
|
||
padding: 12px 0 56px;
|
||
}
|
||
/* 无刊头页(记录/成长足迹/区域等):base-wrap-main 已零 padding,固定顶栏(51px)悬在内容上方,
|
||
这里补回让位(51px 栏高 + 12px 原间隙),栏目条(module-bar)不致压入顶栏之下 */
|
||
.app-frame.no-hero {
|
||
padding-top: 63px;
|
||
}
|
||
/* 全站页脚:固定窗口底部始终可见,玻璃质感与顶栏呼应;滚动内容以上留白防遮挡 */
|
||
.app-footer {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 5;
|
||
padding: 9px 0;
|
||
text-align: center;
|
||
font-size: 12px;
|
||
color: #6b7f94;
|
||
letter-spacing: 0.5px;
|
||
background: rgb(255 255 255 / 55%);
|
||
-webkit-backdrop-filter: blur(8px);
|
||
backdrop-filter: blur(8px);
|
||
border-top: 1px solid rgb(255 255 255 / 55%);
|
||
}
|
||
/* 页面级滚动容器:定高 + 纵向滚动(body overflow hidden,滚动在 main-wrapper);
|
||
overflow-x hidden 裁掉 hero-banner 的 100vw 通栏溢出(100vw 含纵向滚动条宽度,必横向溢出);
|
||
scrollbar-gutter: stable 常驻滚动条槽位——各页面内容高度不同(发展首页 2030px / 栏目列表 1023px),
|
||
若不预留,窗口较高时列表页放得下→滚动条消失→居中容器整体横移(栏目切换整页晃动) */
|
||
.base-wrap-main .main-wrapper {
|
||
height: 100%;
|
||
overflow-y: auto;
|
||
overflow-x: hidden;
|
||
scrollbar-gutter: stable;
|
||
}
|
||
</style>
|