| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <template>
- <el-config-provider :locale="zhCn">
- <!-- 登录/注册页面不显示布局 -->
- <template v-if="hideLayout">
- <router-view />
- </template>
-
- <!-- 正常布局 -->
- <div v-else class="app-container">
- <!-- 顶部导航 -->
- <header class="app-header">
- <div class="header-left">
- <div class="logo" @click="router.push('/')">
- <div class="logo-icon">📊</div>
- <span>灵越智报</span>
- </div>
- <el-input
- v-model="searchKeyword"
- placeholder="搜索报告、模板..."
- prefix-icon="Search"
- class="search-input"
- clearable
- />
- </div>
- <div class="header-right">
- <el-badge :value="3" class="notification-badge">
- <el-button :icon="Bell" circle />
- </el-badge>
- <el-dropdown trigger="click" @command="handleUserCommand">
- <div class="user-menu">
- <el-avatar :size="32" class="user-avatar">{{ userInitial }}</el-avatar>
- <span class="user-name">{{ username }}</span>
- </div>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item command="profile">个人中心</el-dropdown-item>
- <el-dropdown-item command="settings">系统设置</el-dropdown-item>
- <el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- </div>
- </header>
- <!-- 主体区域 -->
- <div class="app-body">
- <!-- 侧边栏 -->
- <aside class="app-sidebar" v-if="!isEditorPage">
- <el-menu
- :default-active="currentRoute"
- router
- class="sidebar-menu"
- >
- <el-menu-item index="/">
- <el-icon><HomeFilled /></el-icon>
- <span>首页</span>
- </el-menu-item>
- <el-menu-item index="/templates">
- <el-icon><Files /></el-icon>
- <span>模板管理</span>
- </el-menu-item>
- <el-menu-item index="/generations">
- <el-icon><Document /></el-icon>
- <span>生成记录</span>
- </el-menu-item>
- <el-divider />
- <el-menu-item index="/help">
- <el-icon><QuestionFilled /></el-icon>
- <span>帮助中心</span>
- </el-menu-item>
- </el-menu>
- </aside>
- <!-- 内容区 -->
- <main class="app-main" :class="{ 'full-width': isEditorPage }">
- <router-view />
- </main>
- </div>
- <!-- 任务中心悬浮按钮和面板 -->
- <TaskCenterFab />
- <TaskCenterPanel />
- </div>
- </el-config-provider>
- </template>
- <script setup>
- import { ref, computed } from 'vue'
- import { useRouter, useRoute } from 'vue-router'
- import { Bell, HomeFilled, Files, Document, QuestionFilled } from '@element-plus/icons-vue'
- import { ElMessage, ElMessageBox } from 'element-plus'
- import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
- import TaskCenterFab from '@/components/TaskCenter/TaskCenterFab.vue'
- import TaskCenterPanel from '@/components/TaskCenter/TaskCenterPanel.vue'
- const router = useRouter()
- const route = useRoute()
- const searchKeyword = ref('')
- const currentRoute = computed(() => route.path)
- const isEditorPage = computed(() => route.path.startsWith('/editor'))
- const hideLayout = computed(() => route.meta.hideLayout === true)
- // 用户信息
- const username = computed(() => localStorage.getItem('username') || '用户')
- const userInitial = computed(() => username.value.charAt(0))
- // 用户菜单操作
- function handleUserCommand(command) {
- switch (command) {
- case 'profile':
- ElMessage.info('个人中心开发中...')
- break
- case 'settings':
- ElMessage.info('系统设置开发中...')
- break
- case 'logout':
- ElMessageBox.confirm('确定要退出登录吗?', '退出确认', {
- confirmButtonText: '退出',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- // 清除登录信息
- localStorage.removeItem('accessToken')
- localStorage.removeItem('refreshToken')
- localStorage.removeItem('userId')
- localStorage.removeItem('username')
- ElMessage.success('已退出登录')
- router.push('/login')
- }).catch(() => {})
- break
- }
- }
- </script>
- <style lang="scss">
- .app-container {
- height: 100vh;
- display: flex;
- flex-direction: column;
- }
- .app-header {
- height: 56px;
- background: #fff;
- border-bottom: 1px solid #e8e8e8;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 20px;
- flex-shrink: 0;
- }
- .header-left {
- display: flex;
- align-items: center;
- gap: 20px;
- }
- .logo {
- display: flex;
- align-items: center;
- gap: 8px;
- font-size: 17px;
- font-weight: 600;
- color: #1890ff;
- cursor: pointer;
- .logo-icon {
- width: 32px;
- height: 32px;
- background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
- border-radius: 8px;
- display: flex;
- align-items: center;
- justify-content: center;
- color: white;
- font-size: 18px;
- }
- }
- .search-input {
- width: 320px;
- }
- .header-right {
- display: flex;
- align-items: center;
- gap: 16px;
- }
- .notification-badge {
- .el-button {
- font-size: 18px;
- }
- }
- .user-menu {
- display: flex;
- align-items: center;
- gap: 8px;
- cursor: pointer;
- padding: 4px 8px;
- border-radius: 20px;
-
- &:hover {
- background: #f5f7fa;
- }
- }
- .user-avatar {
- background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
- }
- .user-name {
- font-size: 14px;
- font-weight: 500;
- }
- .app-body {
- flex: 1;
- display: flex;
- overflow: hidden;
- }
- .app-sidebar {
- width: 200px;
- background: #fff;
- border-right: 1px solid #e8e8e8;
- flex-shrink: 0;
- .sidebar-menu {
- border-right: none;
- height: 100%;
- }
- }
- .app-main {
- flex: 1;
- overflow-y: auto;
- background: #f5f7fa;
- padding: 20px;
- &.full-width {
- padding: 0;
- }
- }
- </style>
|