Bladeren bron

改回请求反向代理,而不是直接调用接口,根据用户是否手动操作滚动条来开启和关闭自动滚动。

ligao 5 maanden geleden
bovenliggende
commit
4da8f2be50
1 gewijzigde bestanden met toevoegingen van 82 en 21 verwijderingen
  1. 82 21
      application/index/view/index/chatBox.html

+ 82 - 21
application/index/view/index/chatBox.html

@@ -396,6 +396,10 @@
             const docsCode = urlParams.get('docsCode');
             const urlUser = urlParams.get('user');
             const urlragId = urlParams.get('ragId');
+            	    // 滚动控制变量:1表示在底部(允许自动滚动),0表示不在底部(禁止自动滚动)
+    		    let shouldAutoScroll = 1;
+    		    // 标记是否是程序在滚动(用于区分用户手动滚动和程序自动滚动)
+    		    let isProgrammaticScroll = false;
    
  
             if(docsCode){
@@ -660,12 +664,57 @@
     		    if(device == 'phone'){
     		        var outputEl = document.getElementById('outputPhone');
     		    }
-    		    let autoScroll = true;
-                // 监听用户滚动行为
-                outputEl.addEventListener('scroll', () => {
-                  const threshold = 150; // 容错像素
-                  autoScroll = (outputEl.scrollTop + outputEl.clientHeight + threshold) >= outputEl.scrollHeight;
-                });
+    		    
+    		    // 判断是否在底部
+    		    function checkIsAtBottom(element) {
+    		        if (!element) return false;
+    		        const threshold = 10;
+    		        return (element.scrollTop + element.clientHeight + threshold) >= element.scrollHeight;
+    		    }
+    		    
+    		    // 监听用户滚动行为:更新shouldAutoScroll变量(只响应用户手动滚动)
+    		    // 确保只添加一次监听器,避免重复添加
+    		    if (!outputEl.hasAttribute('data-scroll-listener-added')) {
+    		        outputEl.setAttribute('data-scroll-listener-added', 'true');
+    		        outputEl.addEventListener('scroll', () => {
+    		            // 如果是程序自动滚动,忽略此事件
+    		            if (isProgrammaticScroll) {
+    		                return;
+    		            }
+    		            // 只有用户手动滚动时才更新shouldAutoScroll
+    		            if (checkIsAtBottom(outputEl)) {
+    		                // 用户手动滚动到底部,设置为1
+    		                shouldAutoScroll = 1;
+    		                console.log(shouldAutoScroll+"==用户手动滚动到底部")
+    		            } else {
+    		                // 用户手动滚动到其他位置(不在底部),设置为0
+    		                shouldAutoScroll = 0;
+    		                console.log(shouldAutoScroll+"==用户手动滚动离开底部")
+    		            }
+    		        });
+    		    }
+    		    
+    		    // 程序滚动到底部的函数
+    		    function scrollToBottom() {
+    		        if (!outputEl) return;
+    		        // 确保标志已设置(防止在scrollToBottom被单独调用时标志未设置)
+    		        if (!isProgrammaticScroll) {
+    		            isProgrammaticScroll = true;
+    		        }
+    		        outputEl.scrollTop = outputEl.scrollHeight;
+    		        // 滚动完成后,重置标志(增加延迟时间,确保所有滚动事件都已处理完成)
+    		        setTimeout(() => {
+    		            isProgrammaticScroll = false;
+    		        }, 100);
+    		    }
+    		    
+    		    // 新消息气泡创建后,根据shouldAutoScroll变量决定是否滚动
+    		     console.log(shouldAutoScroll+"==s新消息气泡创建houldAutoScrollshouldAutoScroll")
+    		    setTimeout(() => {
+    		        if (outputEl && shouldAutoScroll === 1) {
+    		            scrollToBottom();
+    		        }
+    		    }, 50);
                 
                 //调用后台方法对当前输入进行处理
                 var conversationArrayJson = JSON.stringify(conversations, null);
@@ -710,11 +759,11 @@
                         }
                         //msg就是需要传递的参数,组装请求的完整地址
                         if(networkUse == '1'){
-                            var sseUrl = 'http://192.168.10.115:3338/apiSS1E.php?token='+msg+'&ragId='+ragId+'&mcpid='+mcpId+'&zhikong='+zhikong;
+                            var sseUrl = '{$commonOpenURLSSE}?token='+msg+'&ragId='+ragId+'&mcpid='+mcpId+'&zhikong='+zhikong;
                             // var sseUrl = '{$commonOpenURLSSE}?token='+msg+'&ragId=&mcpid=';
                         }
                         else{
-                            var sseUrl = 'http://192.168.10.115:3338/apiSS1E.php?token='+msg+'&ragId='+ragId+'&mcpid='+mcpId+'&zhikong='+zhikong;
+                            var sseUrl = '{$commonOpenURLLocalSSE}?token='+msg+'&ragId='+ragId+'&mcpid='+mcpId+'&zhikong='+zhikong;
                             //  var sseUrl = '{$commonOpenURLLocalSSE}?token='+msg+'&ragId=&mcpid=';
                         }
                         //sse流媒体对话
@@ -777,14 +826,22 @@
                                         
                                     }
                                     //输出正文
+                                    // 在更新内容前设置标志,防止内容高度变化触发滚动事件
+                                    isProgrammaticScroll = true;
                                     document.getElementById("chatTime"+chatTime).innerHTML += formatContent(data.choices[0].delta.content);
-                                    //动态滚动页面
-                                    if (autoScroll) {
-                                        outputEl.scrollTo({
-                                            top: outputEl.scrollHeight,
-                                            behavior: 'smooth' // 平滑滚动
-                                        });
-                                    }
+                                    //动态滚动页面:根据shouldAutoScroll变量决定是否滚动
+                                    // 使用requestAnimationFrame确保DOM更新完成后再滚动
+                                    requestAnimationFrame(() => {
+                                        console.log(shouldAutoScroll+"==s输出正文建houldAutoScrollshouldAutoScroll")
+                                        if (shouldAutoScroll === 1) {
+                                            scrollToBottom();
+                                        } else {
+                                            // 如果不滚动,也要重置标志
+                                            setTimeout(() => {
+                                                isProgrammaticScroll = false;
+                                            }, 100);
+                                        }
+                                    });
                                     if(endingNum == 1){
                                         $(`#`+msg).css("display", "block");
                                        
@@ -825,6 +882,8 @@
                             
                             if(answer == '思考中...'){
                                 document.getElementById("chatTime"+chatTime).innerHTML += '模型网络中断!';
+                          
+                          
                             }
                             //恢复对话窗口和发送按钮状态
                             // $('#chataccept').replaceWith(divStr);
@@ -864,6 +923,11 @@
                             try { if (typeof processNext === 'function') { processNext(); } } catch(e) {}
                             
                             document.getElementById("chatTime"+chatTime).innerHTML = '模型参数不正确,请查看医梦AI开放平台接入文档!';
+                            // 根据shouldAutoScroll变量决定是否滚动
+                             console.log(shouldAutoScroll+"==s模型参数不正确houldAutoScrollshouldAutoScroll")
+                            if (shouldAutoScroll === 1) {
+                                scrollToBottom();
+                            }
                              //恢复对话窗口和发送按钮状态
                             $("#question").prop("disabled", false);
                             $('#question').val('');
@@ -914,12 +978,9 @@
     		                    $(".chatBoxStop").css("color","#666666");
     		                    $(".chatBoxStop").css("pointer-events","none");
     		                    $(".chatBoxStop").css("cursor","not-allowed");
-                    		    //动态滚动页面
-                                if (autoScroll) {
-                                    outputEl.scrollTo({
-                                        top: outputEl.scrollHeight,
-                                        behavior: 'smooth' // 平滑滚动
-                                    });
+                    		    //动态滚动页面:根据shouldAutoScroll变量决定是否滚动
+                                if (shouldAutoScroll === 1) {
+                                    scrollToBottom();
                                 }
                                 //获取最终的ai回复
                                 var aiReplay = $("#chatTime"+chatTime).text();