feat(NavCommon): 重构导航栏样式并添加消息中心和用户菜单功能

- 重新设计用户信息区域样式,增加间距和悬停效果
- 添加消息中心抽屉组件,包含消息列表和操作按钮
- 实现用户下拉菜单,包含个人资料和退出登录选项
- 统一PC端和移动端的导航栏样式
This commit is contained in:
超级老白兔
2025-09-12 16:19:08 +08:00
parent 1ccdfa3e12
commit d3ee0bde5a
3 changed files with 376 additions and 29 deletions

View File

@@ -43,33 +43,91 @@
.headerRight {
display: flex;
align-items: center;
gap: 16px;
}
.userInfo {
cursor: pointer;
padding: 8px 12px;
border-radius: 6px;
transition: all 0.3s;
display: flex;
align-items: center;
gap: 16px;
padding: 8px 0;
&:hover {
background-color: #f5f5f5;
}
.suanli {
font-size: 16px;
display: flex;
align-items: center;
gap: 4px;
font-size: 14px;
color: #666;
font-weight: 500;
padding: 6px 12px;
background: #f8f9fa;
border-radius: 20px;
border: 1px solid #e9ecef;
.suanliIcon {
font-size: 24px;
font-size: 16px;
color: #ffc107;
}
}
}
.avatar {
border: 2px solid #f0f0f0;
.messageButton {
display: flex;
align-items: center;
justify-content: center;
width: 44px;
height: 44px;
border-radius: 50%;
transition: all 0.3s;
border: 1px solid #e9ecef;
background: #fff;
&:hover {
background-color: #f8f9fa;
border-color: #1890ff;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15);
}
.anticon {
font-size: 18px;
color: #666;
}
}
.userSection {
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
padding: 8px 16px;
border-radius: 24px;
transition: all 0.3s;
border: 1px solid #e9ecef;
background: #fff;
&:hover {
background-color: #f8f9fa;
border-color: #1890ff;
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15);
}
}
.userNickname {
font-size: 14px;
color: #333;
font-weight: 600;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.avatar {
border: 2px solid #e9ecef;
transition: all 0.3s;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.username {

View File

@@ -43,32 +43,173 @@
.headerRight {
display: flex;
align-items: center;
gap: 16px;
padding-right: 10px;
}
.userInfo {
cursor: pointer;
padding: 8px 12px;
border-radius: 6px;
transition: all 0.3s;
display: flex;
align-items: center;
gap: 16px;
padding: 8px 0;
&:hover {
background-color: #f5f5f5;
}
.suanli {
display: flex;
align-items: center;
gap: 4px;
font-size: 16px;
color: #666;
font-weight: 500;
cursor: pointer;
.suanliIcon {
font-size: 24px;
font-size: 20px;
color: #ffc107;
}
&:hover {
color: #52c41a;
transition: all 0.3s;
}
}
}
.bell {
cursor: pointer;
background: #f5f5f5;
}
.messageButton {
display: flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 80px;
transition: all 0.3s;
border: 1px solid #e9ecef;
background: #fff;
cursor: pointer;
&:hover {
background-color: #f8f9fa;
border-color: #1890ff;
box-shadow: 0 0px 12px rgba(24, 144, 255, 0.15);
}
.anticon {
font-size: 18px;
color: #666;
}
}
.userSection {
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
padding: 8px 16px;
}
.userNickname {
font-size: 14px;
color: #333;
font-weight: 600;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.avatar {
border: 2px solid #f0f0f0;
border: 2px solid #e9ecef;
transition: all 0.3s;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
// 消息抽屉样式
.messageDrawer {
:global(.ant-drawer-header) {
border-bottom: 1px solid #f0f0f0;
}
:global(.ant-drawer-body) {
padding: 0;
}
}
.messageContent {
height: 100%;
overflow-y: auto;
}
.messageItem {
display: flex;
padding: 16px;
border-bottom: 1px solid #f5f5f5;
transition: background-color 0.2s;
&:hover {
border-color: #1890ff;
background-color: #fafafa;
}
&:last-child {
border-bottom: none;
}
}
.messageAvatar {
margin-right: 12px;
flex-shrink: 0;
}
.messageInfo {
flex: 1;
min-width: 0;
}
.messageTitle {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 8px;
}
.messageType {
font-size: 14px;
font-weight: 500;
color: #262626;
}
.messageStatus {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #1890ff;
}
.messageText {
font-size: 13px;
color: #595959;
line-height: 1.4;
margin-bottom: 8px;
word-break: break-word;
}
.messageTime {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
color: #8c8c8c;
}
.messageActions {
display: flex;
gap: 8px;
margin-top: 8px;
:global(.ant-btn) {
height: 24px;
padding: 0 8px;
font-size: 12px;
}
}

View File

@@ -1,6 +1,12 @@
import React, { useState } from "react";
import { Layout, Drawer, Avatar, Space, Button } from "antd";
import { MenuOutlined, UserOutlined } from "@ant-design/icons";
import { Layout, Drawer, Avatar, Space, Button, Badge, Dropdown } from "antd";
import {
MenuOutlined,
UserOutlined,
BellOutlined,
UserSwitchOutlined,
LogoutOutlined,
} from "@ant-design/icons";
import { useUserStore } from "@/store/module/user";
import { useCkChatStore } from "@/store/module/ckchat/ckchat";
import { useNavigate } from "react-router-dom";
@@ -19,9 +25,12 @@ const NavCommon: React.FC<NavCommonProps> = ({
onMenuClick,
}) => {
const [drawerVisible, setDrawerVisible] = useState(false);
const [messageDrawerVisible, setMessageDrawerVisible] = useState(false);
const [messageCount] = useState(3); // 模拟消息数量
const navigate = useNavigate();
const { userInfo } = useCkChatStore();
const { user } = useUserStore();
console.log(user);
// 处理菜单图标点击
const handleMenuClick = () => {
@@ -34,6 +43,49 @@ const NavCommon: React.FC<NavCommonProps> = ({
setDrawerVisible(false);
};
// 处理消息中心点击
const handleMessageClick = () => {
setMessageDrawerVisible(true);
};
// 处理消息抽屉关闭
const handleMessageDrawerClose = () => {
setMessageDrawerVisible(false);
};
// 处理退出登录
const handleLogout = () => {
console.log("退出登录");
// TODO: 实现退出登录逻辑
};
// 用户菜单项
const userMenuItems = [
{
key: "userInfo",
label: (
<div style={{ fontWeight: "bold", color: "#188eee" }}>
{user.username}{user.account}
</div>
),
},
{
key: "profile",
icon: <UserSwitchOutlined style={{ fontSize: 16 }} />,
label: "个人资料",
onClick: () => {
console.log("个人资料点击");
// TODO: 跳转到个人资料页面
},
},
{
key: "logout",
icon: <LogoutOutlined style={{ fontSize: 14 }} />,
label: "退出登录",
onClick: handleLogout,
},
];
// 默认抽屉内容
const defaultDrawerContent = (
<div className={styles.drawerContent}>
@@ -106,12 +158,28 @@ const NavCommon: React.FC<NavCommonProps> = ({
<span className={styles.suanliIcon}></span>
9307.423
</span>
<Avatar
size={40}
icon={<UserOutlined />}
src={user?.avatar}
className={styles.avatar}
/>
<Dropdown
menu={{ items: userMenuItems }}
placement="bottomRight"
trigger={["click"]}
>
<div className={styles.userSection}>
<Avatar
size={40}
icon={<UserOutlined />}
src={user?.avatar}
className={styles.avatar}
/>
</div>
</Dropdown>
<Badge count={messageCount} size="small">
<div
className={styles.messageButton}
onClick={handleMessageClick}
>
<BellOutlined style={{ fontSize: 18 }} />
</div>
</Badge>
</Space>
</div>
</Header>
@@ -126,6 +194,86 @@ const NavCommon: React.FC<NavCommonProps> = ({
>
{defaultDrawerContent}
</Drawer>
<Drawer
title="通知中心"
placement="right"
onClose={handleMessageDrawerClose}
open={messageDrawerVisible}
width={400}
className={styles.messageDrawer}
extra={
<Space>
<Button type="text" size="small">
</Button>
</Space>
}
>
<div className={styles.messageContent}>
<div className={styles.messageItem}>
<div className={styles.messageAvatar}>
<Avatar size={40} style={{ backgroundColor: "#87d068" }}>
</Avatar>
</div>
<div className={styles.messageInfo}>
<div className={styles.messageTitle}>
<span className={styles.messageType}></span>
<div className={styles.messageStatus}></div>
</div>
<div className={styles.messageText}>
19991699
</div>
<div className={styles.messageTime}>
03-05
<Button type="link" size="small">
</Button>
</div>
</div>
</div>
<div className={styles.messageItem}>
<div className={styles.messageAvatar}>
<Avatar size={40} style={{ backgroundColor: "#f56a00" }}>
E
</Avatar>
</div>
<div className={styles.messageInfo}>
<div className={styles.messageTitle}>
<span className={styles.messageType}></span>
<div className={styles.messageStatus}></div>
</div>
<div className={styles.messageText}>
Eric在@了您
</div>
<div className={styles.messageTime}>03-05</div>
</div>
</div>
<div className={styles.messageItem}>
<div className={styles.messageAvatar}>
<Avatar size={40} style={{ backgroundColor: "#1890ff" }}>
</Avatar>
</div>
<div className={styles.messageInfo}>
<div className={styles.messageTitle}>
<span className={styles.messageType}></span>
</div>
<div className={styles.messageText}></div>
<div className={styles.messageTime}>03-04</div>
<div className={styles.messageActions}>
<Button type="primary" size="small">
</Button>
<Button size="small"></Button>
</div>
</div>
</div>
</div>
</Drawer>
</>
);
};