From 85149e5af00d21a12b72fe28f87ed65c17aefcee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Mon, 29 Sep 2025 17:12:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AF=BC=E8=88=AA=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=EF=BC=9A=E6=96=B0=E5=A2=9E=E6=B6=88=E6=81=AF=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=AE=9A=E6=97=B6=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=9C=AA=E8=AF=BB=E6=B6=88=E6=81=AF=E6=95=B0=E9=87=8F?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E6=A0=87=E8=AE=B0=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E4=B8=BA=E5=B7=B2=E8=AF=BB=E5=92=8C=E5=85=A8=E9=83=A8=E5=B7=B2?= =?UTF-8?q?=E8=AF=BB=EF=BC=8C=E6=8F=90=E5=8D=87=E7=94=A8=E6=88=B7=E4=BD=93?= =?UTF-8?q?=E9=AA=8C=E5=92=8C=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pc/ckbox/components/NavCommon/api.ts | 16 ++ .../pc/ckbox/components/NavCommon/index.tsx | 243 ++++++++++++------ 2 files changed, 186 insertions(+), 73 deletions(-) create mode 100644 Touchkebao/src/pages/pc/ckbox/components/NavCommon/api.ts 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
-
- - -
-
-
+ )) + )}