优化若干功能
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
<template>
|
||||
<div class="home-container">
|
||||
<div class="home-container" :class="{ dark: isDark }">
|
||||
<div class="home-top">
|
||||
<div class="toolbar">
|
||||
<div class="toolbar-left">
|
||||
<span class="system-name">云泽管理平台</span>
|
||||
<template v-if="tenantName">
|
||||
<span class="tenant-divider"></span>
|
||||
<span class="tenant-name" :title="tenantName">
|
||||
<el-icon class="tenant-icon"><OfficeBuilding /></el-icon>
|
||||
{{ tenantName }}
|
||||
@@ -41,7 +39,10 @@
|
||||
<el-avatar :size="32" :src="userAvatar">
|
||||
{{ userName?.charAt(0)?.toUpperCase() }}
|
||||
</el-avatar>
|
||||
<span class="user-name">{{ userName }}</span>
|
||||
<span class="user-meta">
|
||||
<span class="user-name">{{ userName }}</span>
|
||||
<span v-if="userSubtitle" class="user-subtitle">{{ userSubtitle }}</span>
|
||||
</span>
|
||||
<el-icon><ArrowDown /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
@@ -135,11 +136,15 @@
|
||||
<p class="empty-tip">请联系管理员配置系统菜单</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="home-footer">
|
||||
<span class="copyright">云泽管理平台</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from "vue";
|
||||
import { ref, reactive, computed, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
@@ -155,6 +160,7 @@ import {
|
||||
} from "@element-plus/icons-vue";
|
||||
|
||||
import { getTenantList } from "@/api/modules";
|
||||
import { getCurrentUserProfile, logout } from "@/api/login";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { useMenuStore } from "@/stores/menu";
|
||||
|
||||
@@ -229,6 +235,33 @@ const userName = computed(
|
||||
);
|
||||
const userAvatar = computed(() => authStore.user?.avatar || "");
|
||||
|
||||
// 当前登录用户的角色 / 部门 / 职位(来自后端 /backend/getCurrentUserProfile)
|
||||
const userProfile = reactive({ department: "", position: "", role_name: "" });
|
||||
|
||||
// 优先展示「部门 · 职位」,二者皆无时回退到角色名
|
||||
const userSubtitle = computed(() => {
|
||||
const dept = (userProfile.department || "").trim();
|
||||
const pos = (userProfile.position || "").trim();
|
||||
if (dept || pos) {
|
||||
return [dept, pos].filter(Boolean).join(" · ");
|
||||
}
|
||||
return (userProfile.role_name || "").trim();
|
||||
});
|
||||
|
||||
const fetchUserProfile = async () => {
|
||||
if (!authStore.token) return;
|
||||
try {
|
||||
const res = await getCurrentUserProfile();
|
||||
if (res && res.code === 200 && res.data) {
|
||||
userProfile.department = res.data.department || "";
|
||||
userProfile.position = res.data.position || "";
|
||||
userProfile.role_name = res.data.role_name || "";
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch current user profile:", e);
|
||||
}
|
||||
};
|
||||
|
||||
// 当前租户(企业)名称,来自后端 /backend/getCurrentUser 或登录接口返回的 tenant_name
|
||||
const tenantName = computed(() => authStore.user?.tenant_name || "");
|
||||
|
||||
@@ -271,7 +304,7 @@ async function handleCommand(command: string) {
|
||||
async function handleLogout() {
|
||||
try {
|
||||
const user = authStore.user;
|
||||
if (user?.id) await authStore.logout(user.id);
|
||||
if (user?.id) await logout(user);
|
||||
} catch (error) {
|
||||
console.error("退出登录接口调用失败:", error);
|
||||
}
|
||||
@@ -312,6 +345,10 @@ async function loadModules() {
|
||||
onMounted(() => {
|
||||
loadModules();
|
||||
initTheme();
|
||||
// 拉取当前登录用户的角色 / 部门 / 职位,用于右上角展示
|
||||
if (authStore.token) {
|
||||
fetchUserProfile();
|
||||
}
|
||||
// 兜底:若登录时未带租户名称(老会话/缓存),主动拉取一次以显示企业名称
|
||||
if (!tenantName.value) {
|
||||
authStore.fetchCurrentUser();
|
||||
@@ -349,20 +386,6 @@ onMounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.system-name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: @text-main;
|
||||
}
|
||||
|
||||
.tenant-divider {
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
background: @text-regular;
|
||||
opacity: 0.25;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.tenant-name {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -418,10 +441,27 @@ onMounted(() => {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.user-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
line-height: 1.2;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 14px;
|
||||
color: @text-regular;
|
||||
max-width: 80px;
|
||||
max-width: 120px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.user-subtitle {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
max-width: 160px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -631,6 +671,18 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.home-footer {
|
||||
border-top: 1px solid #ebeef5;
|
||||
padding: 18px 24px 28px;
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
|
||||
.copyright {
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.modules-section {
|
||||
.module-grid {
|
||||
@@ -676,13 +728,6 @@ onMounted(() => {
|
||||
.toolbar-left {
|
||||
min-width: 0;
|
||||
flex-shrink: 1;
|
||||
|
||||
.system-name {
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar-right {
|
||||
@@ -774,7 +819,7 @@ onMounted(() => {
|
||||
.user-dropdown-link {
|
||||
padding: 6px 4px;
|
||||
|
||||
.user-name {
|
||||
.user-meta {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -834,12 +879,8 @@ onMounted(() => {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||
|
||||
.toolbar {
|
||||
.toolbar-left .system-name {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.toolbar-left .tenant-name {
|
||||
color: #b0b0b0;
|
||||
color: #cfd3dc;
|
||||
|
||||
.tenant-icon {
|
||||
color: #5a8dff;
|
||||
@@ -865,7 +906,11 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.user-name {
|
||||
color: #b0b0b0;
|
||||
color: #cfd3dc;
|
||||
}
|
||||
|
||||
.user-subtitle {
|
||||
color: #8c8c8c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -873,12 +918,18 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.modules-section {
|
||||
.category-title {
|
||||
color: #f5f7fa;
|
||||
border-left-color: #667eea;
|
||||
}
|
||||
|
||||
.module-card {
|
||||
background: #1a1a1a;
|
||||
border-color: #3d3d3d;
|
||||
|
||||
.card-title {
|
||||
color: #e0e0e0 !important;
|
||||
color: #ffffff !important;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.card-desc {
|
||||
@@ -890,6 +941,29 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.home-footer {
|
||||
border-top-color: #2d2d2d;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
}
|
||||
|
||||
// 在容器自身挂上 .dark 时同样应用暗色样式,避免仅靠 <html class="dark"> 时未命中
|
||||
&.dark {
|
||||
.modules-section .category-title {
|
||||
color: #ffffff !important;
|
||||
border-left-color: #667eea;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.modules-section .module-card .card-title {
|
||||
color: #ffffff !important;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.modules-section .module-card .card-desc {
|
||||
color: #8c8c8c !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user