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 */} -