diff --git a/src/pages/ai/index.tsx b/src/pages/ai/index.tsx index c6383d6..5cdf2fb 100644 --- a/src/pages/ai/index.tsx +++ b/src/pages/ai/index.tsx @@ -11,6 +11,7 @@ import MarkdownRenderer from '@/components/MarkdownRenderer'; import {View, RichText} from '@tarojs/components' import './index.scss'; import {WSS_API_URL} from "@/utils/server"; +import {Image} from '@nutui/nutui-react-taro'; // 消息类型 interface Message { @@ -33,6 +34,7 @@ const AiChat = () => { const [currentTaskId, setCurrentTaskId] = useState(''); const [wsConnected, setWsConnected] = useState(false); const [isInitialized, setIsInitialized] = useState(false); + const [isStopped, setIsStopped] = useState(false); const messagesEndRef = useRef(null); const wsRef = useRef(null); @@ -78,8 +80,15 @@ const AiChat = () => { wsRef.current = createWebSocket(WSS_API_URL + "/chat/" + userToken); wsRef.current.onMessage((data: any) => { - console.log('收到WebSocket消息:', data.taskId); - setCurrentTaskId(data.taskId) + console.log('收到WebSocket消息:', data.taskId, '停止状态:', isStopped); + + // 如果已经停止,忽略所有消息 + if (isStopped) { + console.log('已停止,忽略WebSocket消息'); + return; + } + + setCurrentTaskId(data.taskId); if (data.answer) { if (data.answer === '__END__') { // 消息结束,移除typing状态 @@ -198,6 +207,9 @@ const AiChat = () => { const handleSendMessage = async (content: string) => { if (!content.trim() || isLoading) return; + // 重置停止状态,允许接收新的WebSocket消息 + setIsStopped(false); + // 检查并确保AI Token存在 const aiToken = checkAiToken(); if (!aiToken) { @@ -274,22 +286,70 @@ const AiChat = () => { }; // 停止AI回复 + // @ts-ignore const handleStop = async () => { - if (currentTaskId) { - try { - await stopAiMessage({ - taskId: currentTaskId, - authCode: '1fbfa21a-a3df-445e-9ca5-2c1a9eead7f4', - user: `${Taro.getStorageSync('AI_TOKEN') || 'anonymous'}` - }); - setIsLoading(false); - setCurrentTaskId(''); - setMessages(prev => prev.map(msg => - msg.isTyping ? {...msg, isTyping: false} : msg - )); - } catch (error) { - console.error('停止消息失败:', error); - } + console.log('点击停止按钮,当前taskId:', currentTaskId); + + // 立即设置停止状态,阻止后续WebSocket消息 + setIsStopped(true); + + if (!currentTaskId) { + console.log('没有正在进行的任务,直接停止加载状态'); + setIsLoading(false); + setMessages(prev => prev.map(msg => + msg.isTyping ? {...msg, isTyping: false} : msg + )); + return; + } + + try { + console.log('发送停止请求...'); + await stopAiMessage({ + taskId: currentTaskId, + authCode: '1fbfa21a-a3df-445e-9ca5-2c1a9eead7f4', + user: `${Taro.getStorageSync('AI_TOKEN') || 'anonymous'}` + }); + + console.log('停止请求成功'); + + // 立即停止加载状态 + setIsLoading(false); + setCurrentTaskId(''); + + // 停止所有正在输入的消息 + setMessages(prev => prev.map(msg => { + if (msg.isTyping && msg.type === 'ai') { + return { + ...msg, + isTyping: false, + query: (msg.query || '') + '\n\n[已停止回复]' + }; + } + return msg; + })); + + // 显示停止成功提示 + Taro.showToast({ + title: '已停止回复', + icon: 'success', + duration: 1500 + }); + + } catch (error) { + console.error('停止消息失败:', error); + + // 即使API调用失败,也要停止本地状态 + setIsLoading(false); + setCurrentTaskId(''); + setMessages(prev => prev.map(msg => + msg.isTyping ? {...msg, isTyping: false} : msg + )); + + Taro.showToast({ + title: '停止失败,但已终止本地回复', + icon: 'none', + duration: 2000 + }); } }; @@ -409,11 +469,32 @@ const AiChat = () => { className={'flex justify-center items-center pr-1'} onClick={() => handleSendMessage(inputValue)} > - {'发送'} + + {/*{isLoading ? (*/} + {/* */} + {/* 停止*/} + {/* */} + {/*) : (*/} + {/* */} + {/*)}*/} -