Bladeren bron

刷新按钮逻辑解决

zhaohan 2 weken geleden
bovenliggende
commit
79dc9e488c

File diff suppressed because it is too large
+ 0 - 0
RobotSample-main/app/src/main/assets/medical_triage/css/app.0fa1d7f9.css


+ 1 - 1
RobotSample-main/app/src/main/assets/medical_triage/index.html

@@ -22,4 +22,4 @@
         min-height: 100vh;
         min-height: 100dvh;
         min-height: -webkit-fill-available;
-      }</style><script defer="defer" src="js/chunk-vendors.ea83c1f4.js"></script><script defer="defer" src="js/app.330852b0.js"></script><link href="css/app.f36a6820.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but 甘肃省中医院 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
+      }</style><script defer="defer" src="js/chunk-vendors.ea83c1f4.js"></script><script defer="defer" src="js/app.1052ef3d.js"></script><link href="css/app.0fa1d7f9.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but 甘肃省中医院 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because it is too large
+ 0 - 0
RobotSample-main/app/src/main/assets/medical_triage/js/app.1052ef3d.js


File diff suppressed because it is too large
+ 0 - 0
RobotSample-main/app/src/main/assets/medical_triage/js/app.1052ef3d.js.map


+ 79 - 8
medical-card-demo/frontend/src/components/ChatInterface.vue

@@ -247,6 +247,9 @@ export default {
 
     const isInDepartmentFollowup = ref(false)
 
+    /** 软刷新时自增,用于忽略刷新前未结束的 SSE/异步回调,避免旧数据写回已清空的对话 */
+    const chatResetEpoch = ref(0)
+
     /** 机器人追问病情/症状时出现的关键词,用于标记「科室推荐后的追问阶段」 */
     const FOLLOWUP_HINT_REGEX = /(症状|主诉|不适|多久|多长时间|部位|程度|具体|哪些|诱因|加重|减轻|伴随|发作|持续|反复|既往|过敏|用药|体温|疼痛|请补充|请描述|详细说说|还有其他|进一步|请问)/
 
@@ -376,6 +379,7 @@ export default {
     const sendMessage = async () => {
       const query = inputMessage.value.trim()
       if (!query || isLoading.value) return
+      const opEpoch = chatResetEpoch.value
 
       disableWelcomePlaybackForSession()
       stopAllTtsPlayback()
@@ -414,6 +418,9 @@ export default {
       let timedOut = false
       const timeoutMs = 30000
       const timeoutId = setTimeout(() => {
+        if (opEpoch !== chatResetEpoch.value) {
+          return
+        }
         timedOut = true
         // 超时后停止界面 loading,且忽略后续 SSE 推送
         if (isLoading.value) isLoading.value = false
@@ -422,6 +429,9 @@ export default {
 
       try {
         await chatApi.sendMessage(query, conversationId.value, (data) => {
+          if (opEpoch !== chatResetEpoch.value) {
+            return
+          }
           if (timedOut) return
           console.log('收到SSE消息:', data)
           if (data.type === 'text') {
@@ -444,6 +454,9 @@ export default {
           }
         })
       } catch (error) {
+        if (opEpoch !== chatResetEpoch.value) {
+          return
+        }
         if (timedOut) return
         console.error('发送消息失败:', error)
         addMessage('ai', '抱歉,服务暂时不可用,请稍后重试。')
@@ -467,6 +480,7 @@ export default {
       }
       
       if (action.type === 'select-department') {
+        const opEpoch = chatResetEpoch.value
         stopAllTtsPlayback()
         isLoading.value = true
         try {
@@ -474,6 +488,9 @@ export default {
             conversationId.value, 
             action.departmentId,
             (data) => {
+              if (opEpoch !== chatResetEpoch.value) {
+                return
+              }
               if (data.type === 'text') {
                 addMessage('ai', data.content)
               } else if (data.type === 'card') {
@@ -490,6 +507,7 @@ export default {
       }
       
       if (action.type === 'select-doctor') {
+        const opEpoch = chatResetEpoch.value
         stopAllTtsPlayback()
         isLoading.value = true
         try {
@@ -498,6 +516,9 @@ export default {
             action.doctorId,
             action.date,
             (data) => {
+              if (opEpoch !== chatResetEpoch.value) {
+                return
+              }
               if (data.type === 'card_update') {
                 // 更新医生卡片数据
                 const lastCardMessage = messages.value
@@ -522,6 +543,7 @@ export default {
       }
       
       if (action.type === 'create-appointment') {
+        const opEpoch = chatResetEpoch.value
         stopAllTtsPlayback()
         isLoading.value = true
         try {
@@ -535,6 +557,9 @@ export default {
               conversationId: conversationId.value
             },
             (data) => {
+              if (opEpoch !== chatResetEpoch.value) {
+                return
+              }
               if (data.type === 'text') {
                 addMessage('ai', data.content)
               } else if (data.type === 'card') {
@@ -552,6 +577,7 @@ export default {
       
       // 处理身份证拍摄
       if (action.type === 'idcard-capture') {
+        const opEpoch = chatResetEpoch.value
         const instanceId = message?.card?.instanceId
         processingIdCardInstanceId.value = instanceId
         stopAllTtsPlayback()
@@ -561,6 +587,9 @@ export default {
             conversationId.value,
             action.image,
             (data) => {
+              if (opEpoch !== chatResetEpoch.value) {
+                return
+              }
               if (data.type === 'text') {
                 addMessage('ai', data.content)
               } else if (data.type === 'card') {
@@ -588,10 +617,14 @@ export default {
         }
         isLoading.value = true
         try {
+          const opEpoch = chatResetEpoch.value
           await chatApi.submitRecord(
             conversationId.value,
             action.patient,
             (data) => {
+              if (opEpoch !== chatResetEpoch.value) {
+                return
+              }
               if (data.type === 'text') {
                 const t = String(data.content || '').trim()
                 if (t) addMessage('ai', data.content)
@@ -619,6 +652,7 @@ export default {
       
       // 处理报告拍摄
       if (action.type === 'report-capture') {
+        const opEpoch = chatResetEpoch.value
         const instanceId = message?.card?.instanceId
         processingReportInstanceId.value = instanceId
         stopAllTtsPlayback()
@@ -629,6 +663,9 @@ export default {
             action.reportType,
             action.image,
             (data) => {
+              if (opEpoch !== chatResetEpoch.value) {
+                return
+              }
               if (data.type === 'text') {
                 addMessage('ai', data.content)
               } else if (data.type === 'card') {
@@ -642,9 +679,12 @@ export default {
         } catch (error) {
           console.error('报告解读失败:', error)
         } finally {
-          // SSE 被网关/服务端提前断开时可能收不到 message_end,避免界面永久卡在「解读中」
-          processingReportInstanceId.value = null
-          isLoading.value = false
+          // 软刷新后忽略旧请求的收尾,避免把新对话的 loading 清掉
+          if (opEpoch === chatResetEpoch.value) {
+            // SSE 被网关/服务端提前断开时可能收不到 message_end,避免界面永久卡在「解读中」
+            processingReportInstanceId.value = null
+            isLoading.value = false
+          }
         }
       }
       
@@ -672,6 +712,7 @@ export default {
         stopAllTtsPlayback()
         isLoading.value = true
         try {
+          const opEpoch = chatResetEpoch.value
           const tongueCaptureData = message?.card?.data || {}
           const result = await chatApi.analyzeTongueDiagnosis({
             imageBase64: action.image,
@@ -682,6 +723,9 @@ export default {
             patientAge: tongueCaptureData.patientAge || 0,
             patientGender: tongueCaptureData.patientGender || 0
           })
+          if (opEpoch !== chatResetEpoch.value) {
+            return
+          }
           const isRediagnosis = !!action.isRediagnosis
 
           if (isRediagnosis) {
@@ -889,8 +933,12 @@ export default {
     }
 
     const uploadVoiceAudio = async (audioBlob, fileName) => {
+      const uEpoch = chatResetEpoch.value
       try {
         const text = await chatApi.uploadVoiceAudio(audioBlob, fileName)
+        if (uEpoch !== chatResetEpoch.value) {
+          return
+        }
         const cleaned = (text || '').trim()
         const ignoreText = '请不吝点赞 订阅 转发 打赏支持明镜与点点栏目'
         const shouldIgnore = !cleaned || cleaned === ignoreText
@@ -975,11 +1023,6 @@ export default {
       }
     }
 
-    // 顶部按钮:重新加载整个页面(重新打开当前路由)
-    const refreshPage = () => {
-      window.location.reload()
-    }
-
     const disableWelcomePlaybackForSession = () => {
       stopAllTtsPlayback()
       resetSequentialTts()
@@ -991,6 +1034,34 @@ export default {
       sequentialEnqueueText(welcomeText.value)
     }
 
+    // 顶部「刷新」:仅重置导诊对话与相关状态,不重载整页(避免 triageOpen 丢失回到假桌面)
+    const refreshPage = async () => {
+      chatResetEpoch.value++
+      stopAllTtsPlayback()
+      resetSequentialTts()
+      clearWelcomeTtsPlaybackFlag()
+      if (isVoiceRecording.value) {
+        stopVoiceRecording()
+      }
+      isVoiceUploading.value = false
+      androidFileRecorderActive = false
+      if (voiceRecordTimeout) {
+        clearTimeout(voiceRecordTimeout)
+        voiceRecordTimeout = null
+      }
+      messages.value = []
+      inputMessage.value = ''
+      isLoading.value = false
+      conversationId.value = ''
+      processingReportInstanceId.value = null
+      processingIdCardInstanceId.value = null
+      isInDepartmentFollowup.value = false
+      await applyBranding()
+      addMessage('ai', welcomeText.value, null, true)
+      playWelcomeTtsOnOpen()
+      scrollToBottom()
+    }
+
     // 初始化欢迎消息、语音支持检测
     onMounted(async () => {
       clearWelcomeTtsPlaybackFlag()

Some files were not shown because too many files changed in this diff