|
|
@@ -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();
|