完成客服工作台闭环

This commit is contained in:
yml2213
2026-07-15 10:49:52 +08:00
parent 8cff2a5824
commit 1d31c9eba3
12 changed files with 727 additions and 235 deletions
+10
View File
@@ -28,9 +28,11 @@ const VisitorChat = ({ defaultOpen = false }: { defaultOpen?: boolean }) => {
const [showRating, setShowRating] = useState(false)
const [rated, setRated] = useState(false)
const [sessionEnded, setSessionEnded] = useState(false)
const [agentTyping, setAgentTyping] = useState(false)
const [ratingText, setRatingText] = useState('')
const pollRef = useRef<number | null>(null)
const initRef = useRef(false)
const typingTimerRef = useRef<number | null>(null)
const loadMessages = useCallback(async (sid?: number, token?: string) => {
const s = sid || sessionId
@@ -101,6 +103,12 @@ const VisitorChat = ({ defaultOpen = false }: { defaultOpen?: boolean }) => {
socket.onmessage = (event) => {
try {
const payload = JSON.parse(event.data)
if (payload.session_id === sessionId && payload.type === 'typing') {
setAgentTyping(true)
if (typingTimerRef.current) clearTimeout(typingTimerRef.current)
typingTimerRef.current = window.setTimeout(() => setAgentTyping(false), 1800)
return
}
if (payload.session_id === sessionId && (payload.type === 'message' || payload.type === 'session_updated')) {
if (payload.type === 'session_updated' && payload.data?.status === 'ended') {
setSessionEnded(true)
@@ -114,6 +122,7 @@ const VisitorChat = ({ defaultOpen = false }: { defaultOpen?: boolean }) => {
}
return () => {
socket.close()
if (typingTimerRef.current) clearTimeout(typingTimerRef.current)
}
}, [sessionId, visitorToken, open, loadMessages])
@@ -200,6 +209,7 @@ const VisitorChat = ({ defaultOpen = false }: { defaultOpen?: boolean }) => {
<div className="text-sm"></div>
</div>
)}
{agentTyping && <div className="text-xs text-neutral-400"></div>}
{messages.map(msg => (
<div key={msg.id} className={`flex ${msg.sender === 'visitor' ? 'justify-end' : 'justify-start'}`}>
<div className={`max-w-[75%] rounded-lg px-3 py-2 text-sm ${msg.sender === 'visitor' ? 'bg-blue-500 text-white' : 'bg-white text-neutral-700 border border-neutral-200'}`}>