|
|
@ -309,6 +309,44 @@ const getPathByQueryId = (queryId) => { |
|
|
return matchedRoutes[0]?.path || null |
|
|
return matchedRoutes[0]?.path || null |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ------------------ 侧边栏拖拽调整宽度 ------------------ |
|
|
|
|
|
const sidebarWidth = ref(230) // 默认宽度 |
|
|
|
|
|
const isResizing = ref(false) |
|
|
|
|
|
|
|
|
|
|
|
const startResize = (e) => { |
|
|
|
|
|
// 阻止浏览器默认行为(如文本选择),解决"拖动前几像素无反应"的延迟问题 |
|
|
|
|
|
e.preventDefault() |
|
|
|
|
|
|
|
|
|
|
|
isResizing.value = true |
|
|
|
|
|
// 记录初始X坐标 |
|
|
|
|
|
const startX = e.clientX |
|
|
|
|
|
const startWidth = sidebarWidth.value |
|
|
|
|
|
|
|
|
|
|
|
// 动态添加全局事件监听,确保拖拽流畅 |
|
|
|
|
|
const doDrag = (e) => { |
|
|
|
|
|
if (!isResizing.value) return |
|
|
|
|
|
// 计算新宽度 = 初始宽度 + (当前鼠标X - 初始鼠标X) |
|
|
|
|
|
const newWidth = startWidth + (e.clientX - startX) |
|
|
|
|
|
// 限制最小最大宽度 |
|
|
|
|
|
if (newWidth >= 200 && newWidth <= 350) { |
|
|
|
|
|
sidebarWidth.value = newWidth |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const stopDrag = () => { |
|
|
|
|
|
isResizing.value = false |
|
|
|
|
|
document.removeEventListener('mousemove', doDrag) |
|
|
|
|
|
document.removeEventListener('mouseup', stopDrag) |
|
|
|
|
|
document.body.style.cursor = '' // 恢复鼠标样式 |
|
|
|
|
|
document.body.style.userSelect = '' // 恢复文字选择 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
document.addEventListener('mousemove', doDrag) |
|
|
|
|
|
document.addEventListener('mouseup', stopDrag) |
|
|
|
|
|
document.body.style.cursor = 'col-resize' // 强制鼠标样式 |
|
|
|
|
|
document.body.style.userSelect = 'none' // 禁止文字选中 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 点击消息 → 已读 + 跳转 |
|
|
// 点击消息 → 已读 + 跳转 |
|
|
const handleMessageClick = async (item) => { |
|
|
const handleMessageClick = async (item) => { |
|
|
const res = await API({ |
|
|
const res = await API({ |
|
|
@ -350,7 +388,10 @@ onMounted(() => getMessage()) |
|
|
<div class="background-glass"> |
|
|
<div class="background-glass"> |
|
|
<!-- 侧边栏 --> |
|
|
<!-- 侧边栏 --> |
|
|
<div class="sidebar-container"> |
|
|
<div class="sidebar-container"> |
|
|
<el-aside class="sidebar-layout"> |
|
|
|
|
|
|
|
|
<el-aside class="sidebar-layout" :class="{ 'no-transition': isResizing }" :style="{ width: sidebarWidth + 'px' }"> |
|
|
|
|
|
<!-- 拖拽手柄 --> |
|
|
|
|
|
<div class="resize-handle" @mousedown="startResize"></div> |
|
|
|
|
|
|
|
|
<div class="logo"> |
|
|
<div class="logo"> |
|
|
<img src="../assets/logo.png" alt="logo" style="width: 9vh; height: 9vh"/> |
|
|
<img src="../assets/logo.png" alt="logo" style="width: 9vh; height: 9vh"/> |
|
|
</div> |
|
|
</div> |
|
|
@ -368,7 +409,7 @@ onMounted(() => getMessage()) |
|
|
style="width: 4vh; height: 4vh; margin-right: 4px;" |
|
|
style="width: 4vh; height: 4vh; margin-right: 4px;" |
|
|
> |
|
|
> |
|
|
|
|
|
|
|
|
<span class="menu-item-text">{{ menu.menuName }}</span> |
|
|
|
|
|
|
|
|
<span class="menu-item-text" :title="menu.menuName">{{ menu.menuName }}</span> |
|
|
</template> |
|
|
</template> |
|
|
<!-- 子菜单 --> |
|
|
<!-- 子菜单 --> |
|
|
<template v-for="child in menu.children" :key="child.id"> |
|
|
<template v-for="child in menu.children" :key="child.id"> |
|
|
@ -377,7 +418,7 @@ onMounted(() => getMessage()) |
|
|
<el-icon style="margin-right: 4px;"> |
|
|
<el-icon style="margin-right: 4px;"> |
|
|
<Folder/> |
|
|
<Folder/> |
|
|
</el-icon> |
|
|
</el-icon> |
|
|
<span class="menu-item-text">{{ child.menuName }}</span> |
|
|
|
|
|
|
|
|
<span class="menu-item-text" :title="child.menuName">{{ child.menuName }}</span> |
|
|
</el-menu-item> |
|
|
</el-menu-item> |
|
|
|
|
|
|
|
|
<!-- 子菜单有下级 --> |
|
|
<!-- 子菜单有下级 --> |
|
|
@ -386,7 +427,7 @@ onMounted(() => getMessage()) |
|
|
<el-icon style="margin-right: 4px;"> |
|
|
<el-icon style="margin-right: 4px;"> |
|
|
<Folder/> |
|
|
<Folder/> |
|
|
</el-icon> |
|
|
</el-icon> |
|
|
<span class="menu-item-text">{{ child.menuName }}</span> |
|
|
|
|
|
|
|
|
<span class="menu-item-text" :title="child.menuName">{{ child.menuName }}</span> |
|
|
</template> |
|
|
</template> |
|
|
<!-- 递归 下一级--> |
|
|
<!-- 递归 下一级--> |
|
|
<template v-for="grandChild in child.children" :key="grandChild.id"> |
|
|
<template v-for="grandChild in child.children" :key="grandChild.id"> |
|
|
@ -394,7 +435,7 @@ onMounted(() => getMessage()) |
|
|
<el-icon style="margin-right: 4px;"> |
|
|
<el-icon style="margin-right: 4px;"> |
|
|
<Folder/> |
|
|
<Folder/> |
|
|
</el-icon> |
|
|
</el-icon> |
|
|
<span class="menu-item-text">{{ grandChild.menuName }}</span> |
|
|
|
|
|
|
|
|
<span class="menu-item-text" :title="grandChild.menuName">{{ grandChild.menuName }}</span> |
|
|
</el-menu-item> |
|
|
</el-menu-item> |
|
|
</template> |
|
|
</template> |
|
|
</el-sub-menu> |
|
|
</el-sub-menu> |
|
|
@ -408,7 +449,7 @@ onMounted(() => getMessage()) |
|
|
:alt="`${menu.menuName}图标`" |
|
|
:alt="`${menu.menuName}图标`" |
|
|
style="width: 4vh; height: 4vh; margin-right: 4px;" |
|
|
style="width: 4vh; height: 4vh; margin-right: 4px;" |
|
|
> |
|
|
> |
|
|
<span class="menu-item-text">{{ menu.menuName }}</span> |
|
|
|
|
|
|
|
|
<span class="menu-item-text" :title="menu.menuName">{{ menu.menuName }}</span> |
|
|
</el-menu-item> |
|
|
</el-menu-item> |
|
|
</template> |
|
|
</template> |
|
|
</el-menu> |
|
|
</el-menu> |
|
|
@ -639,19 +680,21 @@ onMounted(() => getMessage()) |
|
|
/* 菜单项文字样式 */ |
|
|
/* 菜单项文字样式 */ |
|
|
.menu-item-text { |
|
|
.menu-item-text { |
|
|
display: inline-block; |
|
|
display: inline-block; |
|
|
max-width: 120px; /* 设置最大宽度 */ |
|
|
|
|
|
min-width: 80px; /* 设置最小宽度 */ |
|
|
|
|
|
/* overflow: hidden; */ |
|
|
|
|
|
/* text-overflow: ellipsis; */ |
|
|
|
|
|
|
|
|
/* max-width: 120px; 移除固定最大宽度,使其随容器自适应 */ |
|
|
|
|
|
/* min-width: 80px; */ |
|
|
|
|
|
overflow: hidden; |
|
|
|
|
|
text-overflow: ellipsis; |
|
|
white-space: nowrap; /* 不换行 */ |
|
|
white-space: nowrap; /* 不换行 */ |
|
|
flex: 1; /* 自动填充剩余空间 */ |
|
|
flex: 1; /* 自动填充剩余空间 */ |
|
|
text-align: left; /* 文字左对齐 */ |
|
|
text-align: left; /* 文字左对齐 */ |
|
|
|
|
|
margin-right: 10px; /* 增加右侧间距,防止紧贴箭头 */ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 中间可滚动菜单容器 */ |
|
|
/* 中间可滚动菜单容器 */ |
|
|
.menu-scroll-container { |
|
|
.menu-scroll-container { |
|
|
flex: 1; |
|
|
flex: 1; |
|
|
overflow-y: auto; |
|
|
overflow-y: auto; |
|
|
|
|
|
overflow-x: hidden; |
|
|
padding: 10px 0; |
|
|
padding: 10px 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -679,6 +722,7 @@ onMounted(() => getMessage()) |
|
|
|
|
|
|
|
|
.sidebar-layout { |
|
|
.sidebar-layout { |
|
|
width: 16vw; |
|
|
width: 16vw; |
|
|
|
|
|
min-width: 230px; /* 设置最小宽度,防止内容被压缩 */ |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
background: #E7F4FD; /* 浅蓝色背景 */ |
|
|
background: #E7F4FD; /* 浅蓝色背景 */ |
|
|
/* backdrop-filter: blur(5px); 毛玻璃效果 --消耗性能 */ |
|
|
/* backdrop-filter: blur(5px); 毛玻璃效果 --消耗性能 */ |
|
|
@ -687,7 +731,30 @@ onMounted(() => getMessage()) |
|
|
display: flex; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
flex-direction: column; |
|
|
position: relative; |
|
|
position: relative; |
|
|
transition: all 0.3s ease; |
|
|
|
|
|
|
|
|
transition: width 0.3s ease; /* 恢复原本的平滑过渡,仅在非拖拽时生效 */ |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 拖拽时禁用过渡动画,解决卡顿 */ |
|
|
|
|
|
.sidebar-layout.no-transition { |
|
|
|
|
|
transition: none !important; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 拖拽手柄样式 */ |
|
|
|
|
|
.resize-handle { |
|
|
|
|
|
position: absolute; |
|
|
|
|
|
top: 0; |
|
|
|
|
|
right: 0; |
|
|
|
|
|
width: 5px; |
|
|
|
|
|
height: 100%; |
|
|
|
|
|
cursor: col-resize; |
|
|
|
|
|
z-index: 10; |
|
|
|
|
|
background: transparent; |
|
|
|
|
|
transition: background 0.2s; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.resize-handle:hover, |
|
|
|
|
|
.resize-handle:active { |
|
|
|
|
|
background: rgba(64, 158, 255, 0.5); /* 悬停或拖拽时显示蓝色 */ |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 内容区域容器 */ |
|
|
/* 内容区域容器 */ |
|
|
@ -789,7 +856,7 @@ onMounted(() => getMessage()) |
|
|
|
|
|
|
|
|
/* 消息中心整体容器 */ |
|
|
/* 消息中心整体容器 */ |
|
|
.message-container { |
|
|
.message-container { |
|
|
padding: 10px 50px 10px 50px; /* 上,右, 下,左 */ |
|
|
|
|
|
|
|
|
padding: 10px 20px 10px 10px; /* 上,右, 下,左 - 减小内边距 */ |
|
|
display: flex; |
|
|
display: flex; |
|
|
align-items: center; /* 垂直居中 */ |
|
|
align-items: center; /* 垂直居中 */ |
|
|
} |
|
|
} |
|
|
@ -897,4 +964,18 @@ display: flex; |
|
|
padding: 8px; |
|
|
padding: 8px; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* 滚动条美化 */ |
|
|
|
|
|
::-webkit-scrollbar { |
|
|
|
|
|
width: 6px; |
|
|
|
|
|
height: 6px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
::-webkit-scrollbar-thumb { |
|
|
|
|
|
background: rgba(0, 0, 0, 0.2); |
|
|
|
|
|
border-radius: 3px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
::-webkit-scrollbar-track { |
|
|
|
|
|
background: transparent; |
|
|
|
|
|
} |
|
|
</style> |
|
|
</style> |