style(sidebar, appMain): 优化侧边栏折叠样式和加载动画

1. 修复折叠侧边栏分组标题图标被隐藏的问题
2. 替换实训任务加载动画为更美观的圆点弹跳效果
3. 更新加载文案和加载面板样式
4. 调整keep-alive缓存最大数量为30
fix/exam-question-access-material-excel-delete-draft
qinzhenpen 3 weeks ago
parent b1470e0069
commit 1804e3fa58

@ -1151,6 +1151,17 @@
} }
.student-menu-icon { margin-right: 0; } .student-menu-icon { margin-right: 0; }
/* 恢复折叠模式下 sub-menu title 里的 icon 尺寸 ——
Element Plus 默认把 .hideSidebar 里 sub-menu title 的 <i> 也压成 0 宽高,
但分组标题在折叠轨道模式下仍需显示图标 */
.el-menu--collapse .el-sub-menu > .el-sub-menu__title > i.student-menu-icon {
width: var(--el-menu-icon-width, 24px) !important;
height: var(--el-menu-icon-width, 24px) !important;
overflow: visible !important;
visibility: visible !important;
display: inline-flex !important;
}
} }
} }

@ -10,17 +10,18 @@
<section :class="mainClass"> <section :class="mainClass">
<div v-if="isDemo" class="student-demo-banner">演示模式:{{ demoClassName }}<button @click="exitDemo">退出演示</button></div> <div v-if="isDemo" class="student-demo-banner">演示模式:{{ demoClassName }}<button @click="exitDemo">退出演示</button></div>
<router-view v-slot="{ Component, route }"> <router-view v-slot="{ Component, route }">
<keep-alive :include="tagsViewStore.cachedViews"> <keep-alive :max="30">
<component v-if="!route.meta.link" v-show="!studentTaskLoading" :is="Component" :key="route.path" /> <component v-if="!route.meta.link" v-show="!studentTaskLoading" :is="Component" :key="route.path" />
</keep-alive> </keep-alive>
</router-view> </router-view>
<div v-if="studentTaskLoading" class="student-task-loading" role="status" aria-live="polite"> <div v-if="studentTaskLoading" class="student-task-loading" role="status" aria-live="polite">
<div class="student-task-loading__panel"> <div class="student-task-loading__panel">
<span class="student-task-loading__label">正在加载当前实训配置</span> <div class="student-task-loading__spinner">
<span class="student-task-loading__line student-task-loading__line--title"></span> <span class="dot dot--1"></span>
<span class="student-task-loading__line"></span> <span class="dot dot--2"></span>
<span class="student-task-loading__line"></span> <span class="dot dot--3"></span>
<span class="student-task-loading__line student-task-loading__line--short"></span> </div>
<span class="student-task-loading__label">AI 正在思考</span>
</div> </div>
</div> </div>
<iframe-toggle /> <iframe-toggle />
@ -72,10 +73,10 @@ watch(currentStudentTaskKey, (taskKey) => {
onMounted(() => window.addEventListener("student-task-config-loading", handleStudentTaskConfigLoading)); onMounted(() => window.addEventListener("student-task-config-loading", handleStudentTaskConfigLoading));
onBeforeUnmount(() => window.removeEventListener("student-task-config-loading", handleStudentTaskConfigLoading)); onBeforeUnmount(() => window.removeEventListener("student-task-config-loading", handleStudentTaskConfigLoading));
const module = ["市场需求挖掘", "产品规划", "产品投放测试", "供应渠道管理", "产品评估与考核"]; const module = ["市场需求挖掘", "产品规划", "产品投放测试", "供应渠道管理", "产品评估与考核"];
// 全局监听路由进入和离开
// onBeforeRouteUpdate 处理同组件内 query/params 变化的场景
onBeforeRouteUpdate((to, from) => { onBeforeRouteUpdate((to, from) => {
tagsViewStore.addVisitedView(to); tagsViewStore.addVisitedView(to);
tagsViewStore.addCachedView(to);
}); });
function findParentByTitle(routes, targetTitle) { function findParentByTitle(routes, targetTitle) {
for (const route of routes) { for (const route of routes) {
@ -192,7 +193,7 @@ router.beforeEach((to, from, next) => {
background-size: 100% 100%; background-size: 100% 100%;
} }
.student-demo-banner{position:sticky;top:0;z-index:30;display:flex;justify-content:space-between;padding:8px 18px;color:#fff;background:#b45309}.student-demo-banner button{border:0;border-radius:4px;padding:3px 10px;cursor:pointer} .student-demo-banner{position:sticky;top:0;z-index:30;display:flex;justify-content:space-between;padding:8px 18px;color:#fff;background:#b45309}.student-demo-banner button{border:0;border-radius:4px;padding:3px 10px;cursor:pointer}
.student-task-loading{position:fixed;inset:50px 0 0;z-index:90;display:grid;place-items:start center;padding-top:96px;background:linear-gradient(135deg,rgba(2,15,26,.985),rgba(4,31,47,.985));}.student-task-loading__panel{display:grid;gap:18px;width:min(820px,calc(100vw - 72px));padding:32px;border:1px solid rgba(66,201,250,.34);border-radius:18px;background:rgba(4,27,42,.8);box-shadow:0 22px 52px rgba(0,0,0,.32)}.student-task-loading__label{color:#bdefff;font-weight:700;letter-spacing:.04em}.student-task-loading__line{display:block;height:18px;border-radius:99px;background:linear-gradient(90deg,rgba(26,107,143,.32),rgba(88,208,255,.58),rgba(26,107,143,.32));background-size:200% 100%;animation:student-task-loading-shimmer 1.2s linear infinite}.student-task-loading__line--title{width:42%;height:30px}.student-task-loading__line--short{width:68%}@keyframes student-task-loading-shimmer{to{background-position:-200% 0}} .student-task-loading{position:fixed;inset:50px 0 0;z-index:90;display:grid;place-items:center;background:rgba(255,255,255,.72);backdrop-filter:blur(6px);animation:student-task-fade-in .2s ease-out}.student-task-loading__panel{display:flex;flex-direction:column;align-items:center;gap:18px;padding:28px 40px;border-radius:16px;background:#ffffff;border:1px solid #e5e7eb;box-shadow:0 8px 32px rgba(31,41,55,.12)}.student-task-loading__spinner{display:flex;align-items:center;gap:8px}.student-task-loading__spinner .dot{width:10px;height:10px;border-radius:50%;background:linear-gradient(135deg,#38bdf8,#0ea5e9);animation:student-task-dot-bounce 1.2s ease-in-out infinite}.student-task-loading__spinner .dot--2{animation-delay:.2s}.student-task-loading__spinner .dot--3{animation-delay:.4s}.student-task-loading__label{color:#1f2937;font-weight:600;font-size:14px;letter-spacing:.02em}@keyframes student-task-dot-bounce{0%,80%,100%{transform:scale(.7);opacity:.55}40%{transform:scale(1);opacity:1}}@keyframes student-task-fade-in{from{opacity:0}to{opacity:1}}
.app-main2 { .app-main2 {
min-height: calc(100vh - 50px); min-height: calc(100vh - 50px);
width: 100%; width: 100%;

Loading…
Cancel
Save