From b483cbc26db3322a112b2e9184aba577aec67abb Mon Sep 17 00:00:00 2001 From: yml2213 Date: Sun, 19 Jul 2026 23:52:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E5=8F=B0=E5=8F=B3=E4=BE=A7?= =?UTF-8?q?=E6=A0=8F=E7=B2=BE=E7=AE=80=E5=AE=A2=E6=88=B7=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=B9=B6=E5=86=85=E5=B5=8C=E5=BF=AB=E6=8D=B7=E5=9B=9E=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 去掉访问来源区块以缩短信息区;保留浏览轨迹、历史会话与内部备注,下方增加团队/个人快捷回复列表。 --- web/src/pages/agent/Dashboard.tsx | 372 +++++++++++++++--------------- 1 file changed, 180 insertions(+), 192 deletions(-) diff --git a/web/src/pages/agent/Dashboard.tsx b/web/src/pages/agent/Dashboard.tsx index 130a034..6168ed5 100644 --- a/web/src/pages/agent/Dashboard.tsx +++ b/web/src/pages/agent/Dashboard.tsx @@ -193,24 +193,6 @@ function channelLabel(source?: string) { return source.length > 6 ? '网页' : source } -/** 从 UA 摘要设备信息,与后端 summarizeUserAgent 逻辑对齐 */ -function summarizeDevice(ua?: string) { - if (!ua) return '' - let browser = '浏览器' - let osName = '未知系统' - if (ua.includes('Edg/')) browser = 'Edge' - else if (ua.includes('Chrome/') && !ua.includes('Edg/')) browser = 'Chrome' - else if (ua.includes('Firefox/')) browser = 'Firefox' - else if (ua.includes('Safari/') && !ua.includes('Chrome/')) browser = 'Safari' - else if (ua.includes('MicroMessenger')) browser = '微信' - if (ua.includes('Windows')) osName = 'Windows' - else if (ua.includes('Mac OS X') || ua.includes('Macintosh')) osName = 'macOS' - else if (ua.includes('Android')) osName = 'Android' - else if (ua.includes('iPhone') || ua.includes('iPad')) osName = 'iOS' - else if (ua.includes('Linux')) osName = 'Linux' - return `${browser} / ${osName}` -} - interface SessionDetail { messages: Message[] events: SessionEvent[] @@ -236,7 +218,6 @@ function shortPagePath(url?: string): string { if (!url) return '—' try { const u = new URL(url) - // 必须带 hash:demo-shop 等 SPA 靠 #/cart 区分页面 const path = u.pathname + (u.search || '') + (u.hash || '') return path.length > 56 ? `${path.slice(0, 54)}…` : path || '/' } catch { @@ -274,6 +255,11 @@ const Dashboard = () => { const [quickKeyword, setQuickKeyword] = useState('') const [quickList, setQuickList] = useState([]) const [quickLoading, setQuickLoading] = useState(false) + /** 右侧栏快捷回复:团队 / 个人 */ + const [sidebarQuickScope, setSidebarQuickScope] = useState<'team' | 'personal'>('team') + const [sidebarQuickKeyword, setSidebarQuickKeyword] = useState('') + const [sidebarQuickList, setSidebarQuickList] = useState([]) + const [sidebarQuickLoading, setSidebarQuickLoading] = useState(false) /** 输入框快捷回复建议:slash=/ 输入码;keyword=正文关键字 */ const [suggestOpen, setSuggestOpen] = useState(false) const [suggestMode, setSuggestMode] = useState<'slash' | 'keyword'>('slash') @@ -723,6 +709,28 @@ const Dashboard = () => { }).catch(() => setQuickList([])).finally(() => setQuickLoading(false)) }, [quickOpen, quickKeyword]) + // 右侧栏快捷回复列表(始终可用) + useEffect(() => { + let cancelled = false + setSidebarQuickLoading(true) + getQuickReplies({ + scope: sidebarQuickScope, + // 团队仅展示已发布;个人展示自己的全部可用 + status: sidebarQuickScope === 'team' ? 'published' : undefined, + q: sidebarQuickKeyword.trim() || undefined, + page: 1, + pageSize: 50, + }).then(response => { + if (cancelled) return + setSidebarQuickList(Array.isArray(response.list) ? response.list : []) + }).catch(() => { + if (!cancelled) setSidebarQuickList([]) + }).finally(() => { + if (!cancelled) setSidebarQuickLoading(false) + }) + return () => { cancelled = true } + }, [sidebarQuickScope, sidebarQuickKeyword]) + const closeSuggest = useCallback(() => { setSuggestOpen(false) setSuggestItems([]) @@ -873,7 +881,6 @@ const Dashboard = () => { setCustomerHistory([]) return } - // 从已加载会话中筛出该客户的历史(含已结束) getSessions({ page: 1, pageSize: 50 }).then(res => { const list = Array.isArray(res.list) ? res.list : [] setCustomerHistory( @@ -1745,20 +1752,21 @@ const Dashboard = () => { )} - {/* 右侧客户信息 320px */} -