112 lines
3.0 KiB
Vue
112 lines
3.0 KiB
Vue
<template>
|
|
<div class="flex h-screen bg-gray-100">
|
|
<!-- 移动端遮罩层 -->
|
|
<div
|
|
v-if="sidebarOpen"
|
|
class="fixed inset-0 z-40 bg-gray-600 bg-opacity-75 lg:hidden"
|
|
@click="sidebarOpen = false"
|
|
></div>
|
|
|
|
<!-- 固定侧边栏 -->
|
|
<div
|
|
class="fixed inset-y-0 left-0 z-50 transform transition-transform duration-300 ease-in-out lg:translate-x-0"
|
|
:class="sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'"
|
|
>
|
|
<Sidebar />
|
|
</div>
|
|
|
|
<!-- 主内容区域 -->
|
|
<div class="flex-1 flex flex-col lg:ml-64">
|
|
<!-- 头部 -->
|
|
<header class="bg-white shadow-sm border-b border-gray-200 px-4 py-4 lg:px-6">
|
|
<div class="flex items-center justify-between">
|
|
<!-- 移动端菜单按钮 -->
|
|
<button
|
|
@click="sidebarOpen = !sidebarOpen"
|
|
class="lg:hidden p-2 rounded-md text-gray-600 hover:text-gray-900 hover:bg-gray-100"
|
|
>
|
|
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
|
</svg>
|
|
</button>
|
|
|
|
<h1 class="text-xl font-semibold text-gray-900 ml-2 lg:ml-0">{{ getCurrentPageTitle() }}</h1>
|
|
<div class="text-sm text-gray-500">
|
|
{{ getCurrentTime() }}
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- 主内容 - 可滚动 -->
|
|
<main class="flex-1 overflow-y-auto bg-gray-50 p-4 lg:p-6">
|
|
<slot />
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { BellIcon } from '@heroicons/vue/24/outline'
|
|
|
|
const route = useRoute()
|
|
|
|
// 响应式侧边栏状态
|
|
const sidebarOpen = ref(false)
|
|
|
|
// 获取当前页面标题
|
|
const getCurrentPageTitle = () => {
|
|
const titleMap = {
|
|
'/dashboard': '仪表板',
|
|
'/users': '用户管理',
|
|
'/orders': '订单管理',
|
|
'/finance': '财务管理',
|
|
'/reports': '数据报表',
|
|
'/settings': '系统设置',
|
|
'/diagnostic': '系统诊断'
|
|
}
|
|
return titleMap[route.path] || '翻译管理系统'
|
|
}
|
|
|
|
// 获取当前时间
|
|
const getCurrentTime = () => {
|
|
const now = new Date()
|
|
return now.toLocaleString('zh-CN', {
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
day: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
})
|
|
}
|
|
|
|
// 当前时间响应式变量
|
|
const currentTime = ref(getCurrentTime())
|
|
|
|
// 每分钟更新时间
|
|
onMounted(() => {
|
|
const timer = setInterval(() => {
|
|
currentTime.value = getCurrentTime()
|
|
}, 60000)
|
|
|
|
onUnmounted(() => {
|
|
clearInterval(timer)
|
|
})
|
|
})
|
|
|
|
// 监听路由变化,关闭移动端侧边栏
|
|
watch(() => useRoute().path, () => {
|
|
sidebarOpen.value = false
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.nav-item {
|
|
@apply flex items-center space-x-3 px-3 py-2 rounded-lg text-sm font-medium text-gray-600 hover:bg-gray-100 hover:text-gray-900 transition-colors duration-200;
|
|
}
|
|
|
|
.nav-item-active {
|
|
@apply bg-blue-100 text-blue-700;
|
|
}
|
|
</style>
|
|
|