feat: 全局移动端适配 AdminLayout 汉堡抽屉 + 67 页通用规则
This commit is contained in:
@@ -4,13 +4,24 @@
|
||||
v-if="!route.meta?.hideMenu"
|
||||
width="220px"
|
||||
class="aside"
|
||||
:class="{ 'aside-mobile-open': mobileAsideOpen }"
|
||||
>
|
||||
<transition name="aside-fade">
|
||||
<div v-if="mobileAsideOpen" class="aside-mask" @click="mobileAsideOpen = false"></div>
|
||||
</transition>
|
||||
<div class="aside-logo">
|
||||
<div class="logo-icon"><img src="/logo.png" alt="logo" /></div>
|
||||
<div class="logo-text">
|
||||
<div class="logo-name">合规管理系统</div>
|
||||
<div class="logo-role">{{ roleLabel }}</div>
|
||||
</div>
|
||||
<!-- 手机端关闭抽屉按钮 -->
|
||||
<button class="aside-close" type="button" aria-label="关闭菜单" @click="mobileAsideOpen = false">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="6" y1="6" x2="18" y2="18"/>
|
||||
<line x1="6" y1="18" x2="18" y2="6"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<el-menu :default-active="route.path" router class="aside-menu">
|
||||
<template v-for="m in menu" :key="m.path">
|
||||
@@ -36,6 +47,13 @@
|
||||
<el-container>
|
||||
<el-header v-if="!route.meta?.hideMenu" class="topbar" height="56px">
|
||||
<div class="topbar-left">
|
||||
<button class="hamburger" type="button" aria-label="打开菜单" @click="mobileAsideOpen = true">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="3" y1="6" x2="21" y2="6"/>
|
||||
<line x1="3" y1="12" x2="21" y2="12"/>
|
||||
<line x1="3" y1="18" x2="21" y2="18"/>
|
||||
</svg>
|
||||
</button>
|
||||
<el-icon class="topbar-back" @click="$router.back()"><ArrowLeft /></el-icon>
|
||||
<span class="page-title-inline">{{ headerTitle }}</span>
|
||||
</div>
|
||||
@@ -93,6 +111,9 @@ const router = useRouter()
|
||||
const store = useUserStore()
|
||||
const role = computed(() => route.meta?.role || store.role)
|
||||
|
||||
// 移动端侧栏抽屉状态 (汉堡按钮触发)
|
||||
const mobileAsideOpen = ref(false)
|
||||
|
||||
// 顶栏标题: 页面动态标题 (如会议 新建/修改/复制) 优先, 否则回退 route.meta.title
|
||||
const dynamicTitle = usePageTitle()
|
||||
const headerTitle = computed(() => dynamicTitle.value || route.meta?.title || '工作台')
|
||||
@@ -164,6 +185,8 @@ onMounted(() => {
|
||||
stopWatchRoute = watch(() => route.path, () => {
|
||||
loadInitialUnread()
|
||||
loadExpertAuditStatus()
|
||||
// 移动端侧栏抽屉: 路由变化自动关闭 (避免点完菜单后抽屉还遮住主内容)
|
||||
mobileAsideOpen.value = false
|
||||
})
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
@@ -404,4 +427,87 @@ const onCommand = (cmd) => { if (cmd === 'logout') logout() }
|
||||
.main { background: var(--brand-slate-50); padding: 16px 20px; min-height: calc(100vh - 56px); }
|
||||
/* 手机页面 (hideMenu): 白底 + 0 padding, 让 form 直接撑满 */
|
||||
.main-full { background: #fff; padding: 0; }
|
||||
|
||||
/* ========== 移动端适配 (≤768px) ========== */
|
||||
/* 顶栏: padding 收窄 + 简化用户区 */
|
||||
@media (max-width: 768px) {
|
||||
.admin-layout {
|
||||
flex-direction: column;
|
||||
}
|
||||
/* 侧栏: 桌面常驻, 手机转抽屉 (默认隐藏在屏幕左外) */
|
||||
.aside {
|
||||
position: fixed !important;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 240px !important;
|
||||
max-width: 80vw;
|
||||
height: 100vh;
|
||||
z-index: 2000;
|
||||
background: #fff;
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.25s ease;
|
||||
box-shadow: none;
|
||||
}
|
||||
.aside.aside-mobile-open {
|
||||
transform: translateX(0);
|
||||
box-shadow: 4px 0 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
.aside-close {
|
||||
display: inline-flex !important;
|
||||
margin-left: auto;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--el-text-color-secondary);
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.aside-close:hover { background: var(--brand-slate-100); }
|
||||
.aside-logo { padding: 16px 16px 14px !important; }
|
||||
|
||||
/* 顶栏: padding 收窄 + 隐藏门户首页 + 用户名只显示图标 */
|
||||
.topbar { padding: 0 12px !important; height: 52px !important; }
|
||||
.topbar-portal { display: none !important; } /* 顶部"门户首页"链接手机端隐藏, 改在抽屉 */
|
||||
.topbar-portal + .el-divider { display: none !important; }
|
||||
.page-title-inline { font-size: 14px !important; max-width: 50vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.user-name { padding: 0 6px !important; }
|
||||
.user-name > span:not(.caret):not(.user-icon) { display: none !important; } /* 隐藏用户名文字, 只留头像图标 */
|
||||
.user-name .user-icon { font-size: 18px !important; }
|
||||
|
||||
/* 汉堡按钮: 桌面隐藏, 手机显示 */
|
||||
.hamburger {
|
||||
display: inline-flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: var(--el-text-color-regular);
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: background 0.18s, color 0.18s;
|
||||
}
|
||||
.hamburger:hover { background: var(--brand-slate-100); color: var(--brand-primary); }
|
||||
|
||||
/* 主体: padding 收窄 */
|
||||
.main { padding: 12px !important; min-height: calc(100vh - 52px); }
|
||||
}
|
||||
|
||||
/* aside-close 桌面隐藏 */
|
||||
.aside-close { display: none; }
|
||||
.hamburger { display: none; }
|
||||
|
||||
/* 移动端侧栏抽屉打开时的蒙层 (放在 layout 顶层, 透过 admin-layout 主结构显示) */
|
||||
@media (max-width: 768px) {
|
||||
.admin-layout { position: relative; }
|
||||
.aside-mask {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1999;
|
||||
}
|
||||
}
|
||||
|
||||
.aside-fade-enter-active, .aside-fade-leave-active { transition: opacity 0.2s; }
|
||||
.aside-fade-enter-from, .aside-fade-leave-to { opacity: 0; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user