fix: 日历页显示页签+页签样式优化+iframe自适应+骨架屏

- useProjects: 访问 hidden 模块(/cqy)时仍显示其页签并高亮,
  让用户知道当前位置;主页仍隐藏日历页签
- TabNav: 非激活页签加圆角背景与 hover 背景反馈,激活页签
  下边线贯通整宽,更像页签
- Calendar: iframe 去除固定 800x600,改 width/height:100% +
  aspect-ratio 自适应(宽屏16:10,窄屏4:3,min-height 400px)
- Calendar: 加载骨架屏覆盖层(iframe @load 后淡出),
  iframe 始终在 DOM 中确保 load 事件触发
- i18n: 日历页签文案改「cqy课程表」/「CQY Timetable」
headless 验证:/cqy 显示页签且激活、hover 有背景反馈、
iframe 自适应宽窄屏、骨架屏加载后淡出
This commit is contained in:
Zikai
2026-07-13 14:13:23 +00:00
parent 49900d2363
commit 337d516c08
5 changed files with 73 additions and 20 deletions

View File

@@ -1,26 +1,38 @@
<script setup>
// 日历页 -- 隐藏页,仅可通过手动访问 /cqy 进入,不在导航中显示
const calendarSrc =
import { ref, computed } from 'vue'
import { useLocale } from '../../composables/useLocale.js'
const { t } = useLocale()
// 谷歌日历 embed URL周视图
const calendarSrc = computed(() =>
'https://calendar.google.com/calendar/embed?height=600&wkst=2&ctz=Australia%2FMelbourne&showPrint=0&mode=WEEK' +
'&src=Y2E0YTE5ZWYwNDM3OTYyYzY5YjEyYzYxYWVmOGVlZjY3MGU5ZDdmYjRlNzJlOTFjNDJjMzllM2Q2NGU5ZTAzNkBncm91cC5jYWxlbmRhci5nb29nbGUuY29t' +
'&src=emguYXVzdHJhbGlhbiNob2xpZGF5QGdyb3VwLnYuY2FsZW5kYXIuZ29vZ2xlLmNvbQ' +
'&color=%237986cb&color=%230b8043'
)
const loaded = ref(false)
</script>
<template>
<div class="calendar-page">
<div class="container">
<h1 class="calendar-page__title">Calendar</h1>
<h1 class="calendar-page__title">{{ t('tabs.calendar') }}</h1>
<div class="calendar-page__frame">
<!-- 加载占位骨架覆盖层iframe 加载完成后淡出 -->
<Transition name="fade">
<div v-if="!loaded" class="calendar-page__skeleton">
<div class="calendar-page__skeleton-text">{{ t('common.loading') }}</div>
</div>
</Transition>
<iframe
:src="calendarSrc"
style="border: solid 1px #777"
width="800"
height="600"
class="calendar-page__iframe"
frameborder="0"
scrolling="no"
loading="lazy"
title="Google Calendar"
:title="t('tabs.calendar')"
@load="loaded = true"
/>
</div>
</div>
@@ -36,13 +48,47 @@ const calendarSrc =
margin-bottom: var(--space-lg);
}
.calendar-page__frame {
position: relative;
border-radius: var(--radius);
overflow: hidden;
box-shadow: var(--shadow);
}
.calendar-page__frame iframe {
border: 1px solid var(--border);
/* 自适应宽高:宽屏 16:9窄屏更高 */
width: 100%;
max-width: 800px;
aspect-ratio: 4 / 3;
min-height: 400px;
}
.calendar-page__iframe {
width: 100%;
height: 100%;
display: block;
border: 0;
}
.calendar-page__skeleton {
position: absolute;
inset: 0;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
background: var(--surface);
}
.calendar-page__skeleton-text {
color: var(--text-tertiary);
font-size: 0.95rem;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.4s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
@media (min-width: 769px) {
.calendar-page__frame {
aspect-ratio: 16 / 10;
}
}
</style>