From 2b57bdc0c889976d2e4ffc8f26f62f6be134e40d Mon Sep 17 00:00:00 2001 From: yml2213 Date: Mon, 31 Aug 2026 14:15:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=A2=E6=9C=8D=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=A3=B0=E9=9F=B3=E4=B8=8E=E6=B5=8F=E8=A7=88=E5=99=A8?= =?UTF-8?q?=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/layout/AgentLayout.tsx | 13 +- web/src/components/layout/AgentSidebar.tsx | 62 +++++- web/src/pages/agent/Dashboard.tsx | 15 +- web/src/pages/agent/Settings.tsx | 2 +- web/src/stores/notifications.tsx | 231 +++++++++++++++++++++ 5 files changed, 312 insertions(+), 11 deletions(-) create mode 100644 web/src/stores/notifications.tsx diff --git a/web/src/components/layout/AgentLayout.tsx b/web/src/components/layout/AgentLayout.tsx index 1e5cc8c..983cee5 100644 --- a/web/src/components/layout/AgentLayout.tsx +++ b/web/src/components/layout/AgentLayout.tsx @@ -1,14 +1,17 @@ import { Outlet } from 'react-router-dom' import AgentSidebar from './AgentSidebar' +import { AgentNotificationProvider } from '@/stores/notifications' const AgentLayout = () => { return ( -
- -
- + +
+ +
+ +
-
+ ) } diff --git a/web/src/components/layout/AgentSidebar.tsx b/web/src/components/layout/AgentSidebar.tsx index 7ba1fb6..65ada8e 100644 --- a/web/src/components/layout/AgentSidebar.tsx +++ b/web/src/components/layout/AgentSidebar.tsx @@ -3,10 +3,11 @@ import { useLocation, useNavigate } from 'react-router-dom' import { AppstoreOutlined, MessageOutlined, HistoryOutlined, TeamOutlined, FileTextOutlined, BarChartOutlined, SettingOutlined, LogoutOutlined, - ThunderboltOutlined, DownOutlined, StopOutlined, SafetyOutlined, + ThunderboltOutlined, DownOutlined, StopOutlined, SafetyOutlined, BellOutlined, BellFilled, } from '@ant-design/icons' -import { Dropdown, message as antMsg } from 'antd' +import { Button, Dropdown, message as antMsg, Popover, Switch } from 'antd' import { useAuth } from '@/stores/auth' +import { useAgentNotifications } from '@/stores/notifications' import type { AgentPresence } from '@/services/api' const menuItems = [ @@ -36,7 +37,15 @@ const AgentSidebar = () => { const location = useLocation() const navigate = useNavigate() const { user, permissions, logout, setPresence } = useAuth() - const [switching, setSwitching] = useState(false) + const { + soundEnabled, + desktopEnabled, + permission, + setSoundEnabled, + setDesktopEnabled, + requestDesktopPermission, + } = useAgentNotifications() + const [switching, setSwitching] = useState(false) const visibleMenuItems = menuItems.filter(item => item.permissions.some(code => permissions.has(code))) @@ -62,7 +71,41 @@ const AgentSidebar = () => { } const initial = (user?.nickname || '客').slice(0, 1) - const current = presenceMeta(user?.status || 'online') + const current = presenceMeta(user?.status || 'online') + + const notificationContent = ( +
+
+
+
声音提醒
+
收到访客消息时播放提示音
+
+ +
+
+
+
浏览器通知
+
+ {permission === 'denied' ? '已被浏览器禁止' : permission === 'unsupported' ? '当前浏览器不支持' : '在后台弹出新消息'} +
+
+ { + if (enabled) void requestDesktopPermission() + else setDesktopEnabled(false) + }} + /> +
+ {permission === 'default' && ( + + )} +
+ ) return (
在线客服 + + +