feat(login): 添加租户名称获取功能并优化前端布局

- 在登录控制器中注入租户服务并获取租户名称信息
- 添加租户名称到登录响应结果中
- 更新样式变量定义侧边栏宽度和Logo高度
- 重构公告面板组件统一公告通知显示逻辑
- 简化公告类型图标和样式映射关系
- 更新侧边栏为垂直菜单布局并添加折叠功能
- 优化Logo组件显示租户名称和系统标题
- 调整导航栏布局结构和响应式样式
- 重构主应用容器样式和标签页显示逻辑
This commit is contained in:
2025-12-31 10:28:52 +08:00
parent 10e738edd9
commit 4d4828ea71
54 changed files with 3510 additions and 754 deletions

View File

@@ -1,17 +1,29 @@
<template>
<div class="navbar">
<div class="right-menu">
<template v-if="appStore.device !== 'mobile'">
<header-search id="header-search" class="right-menu-item" />
</template>
<!-- 公告和通知按钮 -->
<el-tooltip content="公告/通知" placement="bottom">
<div class="right-menu-item notice-btn" @click="openNoticePanel">
<el-badge :value="unreadCount" :hidden="unreadCount === 0" class="notice-badge">
<el-icon><Bell /></el-icon>
</el-badge>
<div class="left-menu">
<div class="hamburger-container">
<div class="hamburger" @click="toggleSideBar">
<el-icon :size="20">
<component :is="sidebar.opened ? 'Fold' : 'Expand'" />
</el-icon>
</div>
</el-tooltip>
</div>
<!-- 搜索和公告通知 -->
<div class="left-actions">
<template v-if="appStore.device !== 'mobile'">
<header-search id="header-search" class="left-action-item" />
</template>
<!-- 公告和通知按钮 -->
<el-tooltip content="公告/通知" placement="bottom">
<div class="left-action-item notice-btn" @click="openNoticePanel">
<el-badge :value="unreadCount" :hidden="unreadCount === 0" class="notice-badge">
<el-icon><Bell /></el-icon>
</el-badge>
</div>
</el-tooltip>
</div>
</div>
<div class="right-menu">
<div class="avatar-container">
<div class="avatar-wrapper">
<el-dropdown
@@ -40,9 +52,6 @@
<router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
<!-- <el-dropdown-item command="setLayout" v-if="settingsStore.showSettings">
<span>布局设置</span>
</el-dropdown-item> -->
<el-dropdown-item divided command="logout">
<span>退出登录</span>
</el-dropdown-item>
@@ -86,8 +95,8 @@
</el-select>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submit"> </el-button>
<el-button @click="showDialog = false"> </el-button>
<el-button type="primary" @click="submit">确定</el-button>
<el-button @click="showDialog = false">取消</el-button>
</div>
</template>
</el-dialog>
@@ -98,9 +107,9 @@
</template>
<script setup>
import {onMounted, ref} from 'vue';
import {onMounted, ref, computed} from 'vue';
import {ElMessageBox} from 'element-plus';
import {Bell} from '@element-plus/icons-vue';
import {Fold, Expand, Bell} from '@element-plus/icons-vue';
import HeaderSearch from '@/components/HeaderSearch';
import NoticePanel from '@/components/NoticePanel';
import useAppStore from '@/store/modules/app';
@@ -108,16 +117,19 @@ import useUserStore from '@/store/modules/user';
import useSettingsStore from '@/store/modules/settings';
import {getOrg, switchOrg} from '@/api/login';
import {getUnreadCount} from '@/api/system/notice';
import {useRouter} from 'vue-router';
const appStore = useAppStore();
const userStore = useUserStore();
const settingsStore = useSettingsStore();
const router = useRouter();
const orgOptions = ref([]);
const showDialog = ref(false);
const orgId = ref('');
const noticePanelRef = ref(null);
const unreadCount = ref(0);
const sidebar = computed(() => appStore.sidebar);
// 加载未读数量
function loadUnreadCount() {
getUnreadCount().then(res => {
@@ -132,6 +144,11 @@ function updateUnreadCount() {
loadUnreadCount();
}
// 切换侧边栏
function toggleSideBar() {
appStore.toggleSideBar();
}
function loadOrgList() {
getOrg().then((res) => {
orgOptions.value = res.data;
@@ -220,16 +237,78 @@ function openNoticePanel() {
<style lang='scss' scoped>
.navbar {
height: 50px;
overflow: visible;
width: 100%;
overflow: hidden;
position: relative;
background-color: transparent;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 10px;
flex-shrink: 0;
min-width: 200px;
z-index: 1002;
justify-content: space-between;
padding: 0 15px;
.left-menu {
display: flex;
align-items: center;
flex-shrink: 0;
gap: 8px;
.hamburger-container {
display: flex;
align-items: center;
.hamburger {
cursor: pointer;
padding: 0 12px;
height: 50px;
display: flex;
align-items: center;
transition: background 0.3s;
color: #5a5e66;
&:hover {
background-color: #f6f6f6;
color: var(--el-color-primary);
}
}
}
.left-actions {
display: flex;
align-items: center;
gap: 4px;
.left-action-item {
display: flex;
align-items: center;
padding: 0 10px;
height: 50px;
font-size: 16px;
color: #606266;
cursor: pointer;
transition: background 0.3s;
&:hover {
background-color: #f6f6f6;
}
.notice-badge {
:deep(.el-badge__content) {
top: -5px;
right: -5px;
}
}
.el-icon {
font-size: 20px;
&:hover {
color: #409eff;
}
}
}
}
}
.right-menu {
display: flex;
@@ -241,49 +320,6 @@ function openNoticePanel() {
outline: none;
}
.right-menu-item {
display: flex;
align-items: center;
padding: 0 6px;
height: 100%;
font-size: 16px;
color: #606266;
flex-shrink: 0;
&.hover-effect {
cursor: pointer;
transition: background 0.3s;
&:hover {
background: rgba(255,255,255,0.1);
}
}
}
.notice-btn {
cursor: pointer;
padding: 0 10px;
height: 100%;
display: flex;
align-items: center;
.notice-badge {
:deep(.el-badge__content) {
top: -5px;
right: -5px;
}
}
.el-icon {
font-size: 20px;
color: #606266;
&:hover {
color: #409eff;
}
}
}
.avatar-container {
margin-right: 0;
margin-left: 5px;
@@ -313,8 +349,8 @@ function openNoticePanel() {
.user-avatar {
cursor: pointer;
width: 30px;
height: 30px;
width: 32px;
height: 32px;
border-radius: 6px;
flex-shrink: 0;
}
@@ -364,8 +400,21 @@ function openNoticePanel() {
}
@media (max-width: 768px) {
min-width: 150px;
padding-right: 5px;
padding: 0 10px;
.left-menu {
.hamburger-container {
.hamburger {
padding: 0 8px;
}
}
.left-actions {
.left-action-item {
padding: 0 6px;
}
}
}
.right-menu {
.avatar-container {
@@ -388,8 +437,8 @@ function openNoticePanel() {
}
.user-avatar {
width: 24px;
height: 24px;
width: 28px;
height: 28px;
}
}
}
@@ -397,8 +446,21 @@ function openNoticePanel() {
}
@media (max-width: 480px) {
min-width: 120px;
padding-right: 5px;
padding: 0 8px;
.left-menu {
.hamburger-container {
.hamburger {
padding: 0 6px;
}
}
.left-actions {
.left-action-item {
padding: 0 4px;
}
}
}
.right-menu {
.avatar-container {
@@ -415,6 +477,11 @@ function openNoticePanel() {
max-width: 80px;
font-size: 11px;
}
.user-avatar {
width: 24px;
height: 24px;
}
}
}
}