2026-07-10 16:44:49 +08:00
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
|
import { onMounted, onUnmounted } from 'vue'
|
|
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
|
import AppSidebar from '@/components/AppSidebar.vue'
|
|
|
|
|
|
import AppHeader from '@/components/AppHeader.vue'
|
|
|
|
|
|
import { useSystemStore } from '@/stores/system'
|
|
|
|
|
|
import { useModelsStore } from '@/stores/models'
|
|
|
|
|
|
|
|
|
|
|
|
const systemStore = useSystemStore()
|
|
|
|
|
|
const modelsStore = useModelsStore()
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
// 启动顶部栏系统监控轮询
|
|
|
|
|
|
systemStore.start()
|
|
|
|
|
|
// 预加载模型列表缓存(列表页渲染模型名用)
|
|
|
|
|
|
modelsStore.load()
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
|
|
|
systemStore.stop()
|
|
|
|
|
|
})
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="main-layout">
|
|
|
|
|
|
<AppSidebar />
|
|
|
|
|
|
<div class="layout-main">
|
|
|
|
|
|
<AppHeader />
|
|
|
|
|
|
<main class="layout-content">
|
|
|
|
|
|
<div
|
|
|
|
|
|
class="page-canvas"
|
|
|
|
|
|
:class="{ 'is-self-surface': route.meta.pageSurface === 'self' }"
|
|
|
|
|
|
>
|
|
|
|
|
|
<router-view v-slot="{ Component }">
|
|
|
|
|
|
<component :is="Component" />
|
|
|
|
|
|
</router-view>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</main>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.main-layout {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.layout-main {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.layout-content {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
padding: 8px 8px 16px;
|
|
|
|
|
|
background-color: var(--app-shell-bg);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
|
|
|
|
|
|
&:has(.data-table-page),
|
|
|
|
|
|
&:has(.eval-page),
|
|
|
|
|
|
&:has(.manage-card-container) {
|
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&:has(.create-wizard-layout) {
|
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
.page-canvas {
|
|
|
|
|
|
flex: 1 1 auto;
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-07-11 14:49:37 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (min-width: 1181px) {
|
|
|
|
|
|
.layout-content:has(.dashboard-view) {
|
2026-07-14 16:10:59 +08:00
|
|
|
|
overflow-y: auto;
|
2026-07-11 14:49:37 +08:00
|
|
|
|
|
|
|
|
|
|
.page-canvas {
|
2026-07-14 16:10:59 +08:00
|
|
|
|
flex: 1 0 auto;
|
2026-07-11 14:49:37 +08:00
|
|
|
|
min-height: 0;
|
|
|
|
|
|
padding: 16px;
|
2026-07-14 16:10:59 +08:00
|
|
|
|
overflow: visible;
|
2026-07-11 14:49:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-07-10 16:44:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.page-canvas {
|
|
|
|
|
|
flex: 1 0 auto;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
padding: 24px;
|
|
|
|
|
|
border-radius: 16px;
|
|
|
|
|
|
background-color: var(--app-page-bg);
|
|
|
|
|
|
box-shadow: var(--card-shadow);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.page-canvas.is-self-surface {
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
|
box-shadow: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.page-canvas:has(.has-fixed-footer) {
|
|
|
|
|
|
margin-bottom: 56px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 路由直接输出 PageCard,或显式声明根卡片宿主时,复用外层白色画布 */
|
|
|
|
|
|
.page-canvas:not(.is-self-surface) > :deep(.page-card),
|
|
|
|
|
|
.page-canvas:not(.is-self-surface) > :deep(.page-card-host > .page-card) {
|
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
|
background-color: transparent;
|
|
|
|
|
|
border-radius: 0 !important;
|
|
|
|
|
|
box-shadow: none !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|