diff --git a/Touchkebao/src/pages/pc/ckbox/components/NavCommon/api.ts b/Touchkebao/src/pages/pc/ckbox/components/NavCommon/api.ts new file mode 100644 index 00000000..f814b6b9 --- /dev/null +++ b/Touchkebao/src/pages/pc/ckbox/components/NavCommon/api.ts @@ -0,0 +1,16 @@ +import request from "@/api/request"; + +// 消息列表 +export const noticeList = (params: { page: number; limit: number }) => { + return request(`/v1/kefu/notice/list`, params, "GET"); +}; + +// 消息列表 +export const readMessage = (params: { id: number }) => { + return request(`/v1/kefu/notice/readMessage`, params, "PUT"); +}; + +// 消息列表 +export const readAll = () => { + return request(`/v1/kefu/notice/readAll`, undefined, "PUT"); +}; diff --git a/Touchkebao/src/pages/pc/ckbox/components/NavCommon/index.tsx b/Touchkebao/src/pages/pc/ckbox/components/NavCommon/index.tsx index 431f9702..c4701072 100644 --- a/Touchkebao/src/pages/pc/ckbox/components/NavCommon/index.tsx +++ b/Touchkebao/src/pages/pc/ckbox/components/NavCommon/index.tsx @@ -1,16 +1,24 @@ -import React, { useState } from "react"; -import { Layout, Drawer, Avatar, Space, Button, Badge, Dropdown } from "antd"; +import React, { useState, useEffect } from "react"; +import { + Layout, + Drawer, + Avatar, + Space, + Button, + Badge, + Dropdown, + Empty, +} from "antd"; import { BarChartOutlined, UserOutlined, BellOutlined, LogoutOutlined, - UserSwitchOutlined, ThunderboltOutlined, SettingOutlined, WechatOutlined, } from "@ant-design/icons"; - +import { noticeList, readMessage, readAll } from "./api"; import { useUserStore } from "@/store/module/user"; import { useNavigate, useLocation } from "react-router-dom"; import styles from "./index.module.scss"; @@ -22,13 +30,39 @@ interface NavCommonProps { onMenuClick?: () => void; } +// 消息数据类型 +interface MessageItem { + id: number; + type: number; + companyId: number; + userId: number; + bindId: number; + title: string; + message: string; + isRead: number; + createTime: string; + readTime: string; + friendData: { + nickname: string; + avatar: string; + }; +} + const NavCommon: React.FC = ({ title = "触客宝" }) => { const [messageDrawerVisible, setMessageDrawerVisible] = useState(false); - const [messageCount] = useState(3); // 模拟消息数量 + const [messageList, setMessageList] = useState([]); + const [messageCount, setMessageCount] = useState(0); + const [loading, setLoading] = useState(false); const navigate = useNavigate(); const location = useLocation(); const { user, logout } = useUserStore(); + // 初始化时获取消息列表 + useEffect(() => { + fetchMessageList(); + setInterval(IntervalMessageCount, 30 * 1000); + }, []); + // 处理菜单图标点击:在两个路由之间切换 const handleMenuClick = () => { const current = location.pathname; @@ -43,9 +77,41 @@ const NavCommon: React.FC = ({ title = "触客宝" }) => { return location.pathname.startsWith("/pc/weChat"); }; + // 定时器获取消息条数 + const IntervalMessageCount = async () => { + try { + const response = await noticeList({ page: 1, limit: 20 }); + if (response && response.noRead) { + setMessageCount(response.noRead); + } + } catch (error) { + console.error("获取消息列表失败:", error); + } + }; + // 获取消息列表 + const fetchMessageList = async () => { + try { + setLoading(true); + const response = await noticeList({ page: 1, limit: 20 }); + if (response && response.list) { + setMessageList(response.list); + // 计算未读消息数量 + const unreadCount = response.list.filter( + (item: MessageItem) => item.isRead === 0, + ).length; + setMessageCount(unreadCount); + } + } catch (error) { + console.error("获取消息列表失败:", error); + } finally { + setLoading(false); + } + }; + // 处理消息中心点击 const handleMessageClick = () => { setMessageDrawerVisible(true); + fetchMessageList(); }; // 处理消息抽屉关闭 @@ -59,6 +125,61 @@ const NavCommon: React.FC = ({ title = "触客宝" }) => { navigate("/login"); // 跳转到登录页面 }; + // 处理消息已读 + const handleReadMessage = async (messageId: number) => { + try { + await readMessage({ id: messageId }); // 这里需要根据实际API调整参数 + // 更新本地状态 + setMessageList(prev => + prev.map(item => + item.id === messageId ? { ...item, isRead: 1 } : item, + ), + ); + // 重新计算未读数量 + const unreadCount = + messageList.filter(item => item.isRead === 0).length - 1; + setMessageCount(Math.max(0, unreadCount)); + } catch (error) { + console.error("标记消息已读失败:", error); + } + }; + + // 处理全部已读 + const handleReadAll = async () => { + try { + await readAll(); // 这里需要根据实际API调整参数 + // 更新本地状态 + setMessageList(prev => prev.map(item => ({ ...item, isRead: 1 }))); + setMessageCount(0); + } catch (error) { + console.error("全部已读失败:", error); + } + }; + + // 格式化时间 + const formatTime = (timeStr: string) => { + const date = new Date(timeStr); + const now = new Date(); + const diff = now.getTime() - date.getTime(); + const days = Math.floor(diff / (1000 * 60 * 60 * 24)); + + if (days === 0) { + return date.toLocaleTimeString("zh-CN", { + hour: "2-digit", + minute: "2-digit", + }); + } else if (days === 1) { + return "昨天"; + } else if (days < 7) { + return `${days}天前`; + } else { + return date.toLocaleDateString("zh-CN", { + month: "2-digit", + day: "2-digit", + }); + } + }; + // 用户菜单项 const userMenuItems = [ { @@ -120,14 +241,7 @@ const NavCommon: React.FC = ({ title = "触客宝" }) => { - {/* */} + = ({ title = "触客宝" }) => { className={styles.messageDrawer} extra={ - } >
-
-
- - 林 - + {loading ? ( +
+ 加载中...
-
-
- 新消息 -
+ ) : messageList.length === 0 ? ( + + ) : ( + messageList.map(item => ( +
handleReadMessage(item.id)} + > +
+ + {item.friendData?.nickname?.charAt(0) || "U"} + +
+
+
+ {item.title} + {item.isRead === 0 && ( +
+ )} +
+
{item.message}
+ {item.isRead === 0 && ( +
+ {formatTime(item.createTime)} + +
+ )} +
-
- 林秀杰:关于自由主时间特惠,原价1999元,现在只需1699元 -
-
- 03-05 - -
-
-
- -
-
- - E - -
-
-
- 群提醒 -
-
-
- Eric在「云归营私域银行项目群」中@了您 -
-
03-05
-
-
- -
-
- - 李 - -
-
-
- 好友申请 -
-
李翔想请求添加您为好友
-
03-04
-
- - -
-
-
+ )) + )}