FanHong преди 1 седмица
родител
ревизия
d5ec07e160
променени са 1 файла, в които са добавени 27 реда и са изтрити 14 реда
  1. 27 14
      shudao-vue-frontend/src/views/Chat.vue

+ 27 - 14
shudao-vue-frontend/src/views/Chat.vue

@@ -6,7 +6,7 @@
     <!-- 中间历史记录区域 -->
     <div class="history-sidebar">
       <div class="new-chat-container">
-        <button class="new-chat-btn-full" @click="createNewChat" :disabled="isSending">
+        <button class="new-chat-btn-full" @click="createNewChat" :disabled="isSending || hasTypingMessage">
           <span class="plus-icon">+</span>
           新建任务
         </button>
@@ -29,9 +29,9 @@
           v-for="(item, index) in historyData" 
           :key="index"
           :class="['history-item', { active: item.isActive }]"
-          @click="item.isActive ? null : (isSending ? null : handleHistoryItem(item))"
+          @click="item.isActive ? null : ((isSending || hasTypingMessage) ? null : handleHistoryItem(item))"
           :style="{ 
-            cursor: item.isActive ? 'default' : (isSending ? 'not-allowed' : 'pointer')
+            cursor: item.isActive ? 'default' : ((isSending || hasTypingMessage) ? 'not-allowed' : 'pointer')
           }"
         >
           <div class="history-content">
@@ -327,7 +327,7 @@
                         <img :src="copyIcon" alt="复制" class="action-icon">
                         复制
                       </button>
-                      <button class="action-btn regenerate-btn" @click="regenerateResponse(index)" :disabled="hasTypingMessage">
+                      <button class="action-btn regenerate-btn" @click="regenerateResponse(index)" :disabled="isSending || hasTypingMessage">
                         <img :src="regenerateIcon" alt="重新生成" class="action-icon">
                         重新生成
                       </button>
@@ -488,7 +488,7 @@
               v-model="messageText"
               @keyup.enter.exact="handleSendMessage"
               @input="handleInput"
-              :disabled="hasTypingMessage"
+              :disabled="isSending || hasTypingMessage"
               maxlength="2000"
               rows="3"
             ></textarea>
@@ -497,7 +497,7 @@
             <div class="input-toolbar">
               <div class="toolbar-left">
                 <!-- 语音输入 -->
-                <button class="voice-btn" @click="handleVoiceClick" :disabled="hasTypingMessage" :class="{ 'recording': isListening }">
+                <button class="voice-btn" @click="handleVoiceClick" :disabled="isSending || hasTypingMessage" :class="{ 'recording': isListening }">
                   <div class="icon-container">
                     <img :src="voiceInputIcon" alt="语音" class="action-icon">
                     <div v-if="isListening" class="recording-indicator"></div>
@@ -544,7 +544,7 @@
                   class="model-link-btn" 
                   :class="{ 'active': isOnlineModel }"
                   @click="toggleModelType" 
-                  :disabled="hasTypingMessage" 
+                  :disabled="isSending || hasTypingMessage" 
                   :title="isOnlineModel ? '当前:在线大模型 (glm-4-plus)' : '当前:本地模型'"
                 >
                   <div class="icon-container">
@@ -553,7 +553,7 @@
                 </button>
 
                 <!-- 附件图标 (右侧) -->
-                <button class="attach-btn" @click="triggerFileUpload" :disabled="hasTypingMessage">
+                <button class="attach-btn" @click="triggerFileUpload" :disabled="isSending || hasTypingMessage">
                   <div class="icon-container">
                     <img :src="attachmentIcon" alt="附件" class="action-icon">
                   </div>
@@ -561,11 +561,11 @@
 
                 <button 
                   class="send-btn" 
-                  @click="isSending ? handleStopGeneration() : handleSendMessage()" 
-                  :disabled="!isSending && (hasTypingMessage || !messageText.trim())"
+                  @click="(isSending || hasTypingMessage) ? handleStopGeneration() : handleSendMessage()" 
+                  :disabled="!(isSending || hasTypingMessage) && !messageText.trim()"
                 >
-                  <span v-if="isSending" class="stop-text">停止</span>
-                  <div v-else class="send-icon-circle" :class="{ 'active': messageText.trim() && !hasTypingMessage }">
+                  <span v-if="isSending || hasTypingMessage" class="stop-text">停止</span>
+                  <div v-else class="send-icon-circle" :class="{ 'active': messageText.trim() }">
                     <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                       <path d="M12 19V5M12 5L5 12M12 5L19 12" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                     </svg>
@@ -1716,6 +1716,12 @@ const handleNonStreamingSubmit = async (data) => {
 
     if (response.statusCode === 200) {
       const aiMessage = chatMessages.value[aiMessageIndex]
+      
+      // 如果用户已经点击了停止,则不再继续输出
+      if (aiMessage._stopped) {
+        return
+      }
+      
       aiMessage.isTyping = false
       aiMessage.content = response.data
       
@@ -1752,6 +1758,11 @@ const handleNonStreamingSubmit = async (data) => {
   } catch (error) {
     console.error('发送请求失败:', error)
     const aiMessage = chatMessages.value[aiMessageIndex]
+    
+    if (aiMessage._stopped) {
+      return
+    }
+    
     aiMessage.isTyping = false
     aiMessage.displayContent = '抱歉,生成内容时发生错误,请重试。'
     ElMessage.error(`请求失败: ${error.message}`)
@@ -2608,7 +2619,7 @@ const handleCancel = () => {
 
 // 停止报告生成
 const handleStopGeneration = async () => {
-  if (!sseConnection || ai_conversation_id.value === undefined || ai_conversation_id.value === null) {
+  if (ai_conversation_id.value === undefined || ai_conversation_id.value === null) {
     return
   }
   
@@ -2619,10 +2630,12 @@ const handleStopGeneration = async () => {
   
   isSending.value = false
   streamingReports.value.clear()
+  clearAllTypeIntervals()
   
   chatMessages.value.forEach(message => {
     if (message.type === 'ai' && message.isTyping) {
       message.isTyping = false
+      message._stopped = true
       
       // 停止时设置为完成状态
       updateMessageStatus(message, 'completed')
@@ -2715,7 +2728,7 @@ const handleReportGeneratorSubmit = async (data) => {
   })
   
   try {
-    const apiPrefix = getApiPrefix()
+    const apiPrefix = getReportApiPrefix() // 改为使用 getReportApiPrefix
     const url = `${apiPrefix}/report/complete-flow`
 
     // 构建 POST 请求体