import { useState, useEffect } from 'react' import { Input, Spin, message } from 'antd' import { SearchOutlined, UserOutlined, StarFilled } from '@ant-design/icons' import { useAuth } from '@/stores/auth' import { getSessions, getSession, type Session as SessionType } from '@/services/api' interface SessionDetail { id: number customerName: string phone: string email: string source: string tags: string[] status: string conversationCount: number satisfaction: number note: string messages: { sender: string; content: string; time: string }[] } const priorityColors: Record = { urgent: '#dc2626', normal: '#d97706', waiting: '#d97706' } const priorityLabels: Record = { urgent: '紧急', waiting: '等待中', active: '进行中', normal: '进行中' } const Dashboard = () => { const { user } = useAuth() const [sessions, setSessions] = useState([]) const [loading, setLoading] = useState(true) const [selectedId, setSelectedId] = useState(null) const [detail, setDetail] = useState(null) const [detailLoading, setDetailLoading] = useState(false) const [messageInput, setMessageInput] = useState('') useEffect(() => { loadSessions() }, []) const loadSessions = async () => { try { setLoading(true) const res = await getSessions() setSessions(res.list) if (res.list.length > 0 && !selectedId) { setSelectedId(res.list[0].id) } } catch { // fallback to empty } finally { setLoading(false) } } useEffect(() => { if (selectedId) { loadDetail(selectedId) } }, [selectedId]) const loadDetail = async (id: number) => { setDetailLoading(true) try { const res = await getSession(id) const { session } = res.data setDetail({ id: session.id, customerName: `客户${session.customer_id}`, phone: '获取中...', email: '', source: '网页', tags: session.priority === 'urgent' ? ['VIP'] : [], status: session.status, conversationCount: 0, satisfaction: session.satisfaction_score || 0, note: '', messages: (res.data as any).messages?.map((m: any) => ({ sender: m.sender_type === 'agent' ? `客服(${m.sender_id})` : '客户', content: m.content, time: new Date(m.sent_at).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }), })) || [], }) } catch { message.error('加载会话详情失败') } finally { setDetailLoading(false) } } const handleSend = () => { if (!messageInput.trim()) return setMessageInput('') message.info('WebSocket 消息发送(待连接)') } if (loading) { return
} return (
{/* 左侧:会话列表 */}
{user?.nickname || '客服'}
在线
} placeholder="搜索会话..." variant="borderless" size="small" />
{sessions.length === 0 ? (
暂无会话
) : ( sessions.map(s => (
setSelectedId(s.id)} >
客户{s.customer_id}
{new Date(s.created_at).toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })}

)) )}
{/* 中间:聊天区 */}
{detail ? ( <>
{detail.customerName}
转接 结束
{detailLoading ? (
) : detail.messages.length === 0 ? (
暂无消息
) : ( detail.messages.map((msg, i) => (
{msg.content}
{msg.time}
)) )}
setMessageInput(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') handleSend() }} /> 😊
) : (
选择一个会话
)}
{/* 右侧:客户信息面板 */}
{detail ? (
{detail.customerName}
ID: {detail.id}
标签
{detail.tags.map(t => {t})}
统计数据
{detail.conversationCount}
对话次数
{detail.satisfaction > 0 ? detail.satisfaction : '-'} {detail.satisfaction > 0 && }
满意度
) : null}
) } function TagBadge({ status, priority }: { status: string; priority: string }) { const color = status === 'ended' ? '#16a34a' : priorityColors[priority] || '#2563eb' const text = status === 'ended' ? '已结束' : status === 'waiting' ? '等待中' : priorityLabels[priority] || status return {text} } export default Dashboard