2
0

2 Коммиты cd19a6b0af ... b7b668c01d

Автор SHA1 Сообщение Дата
  ligao b7b668c01d 省中代码,优化客户端队列的对话间隔,修改了apisse里对话ending返回的逻辑。 5 месяцев назад
  ligao 7f818fdf43 最最初的开放平台代码 5 месяцев назад
1 измененных файлов с 522 добавлено и 2775 удалено
  1. 522 2775
      apiSSE.php

+ 522 - 2775
apiSSE.php

@@ -1,2819 +1,566 @@
-<!DOCTYPE html>
-<html lang="en">
-    <head>
-        <meta charset="UTF-8">
-        <meta http-equiv="X-UA-Compatible" content="ie=edge">
-        <title>病历内涵质控小助手</title>
-        <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-        <meta content="EMOON|医梦AI" name="description" />
-        <meta content="回车网络" name="author" />
-        <!--CSS-->
-        <link rel="stylesheet" href="../../public/css/plugin.css">
-        <link rel="stylesheet" href="../../public/css/main.css">
-        <link rel="stylesheet" href="../../public/css/responsive.css">
-        <link rel="stylesheet" href="../../public/css/chat.css">
-        <!-- Favicon-->
-        <link rel="shortcut icon" href="../../public/img/favicon.png">
-        <!--IOS Icon-->
-        <link rel="apple-touch-icon-precomposed" href="../../public/img/faviconIphone.png" />
-        <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../public/img/faviconIphone.png" />
-        <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../public/img/faviconIphone.png" />
-        <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../public/img/faviconIphone.png" /> 
-        <!--微信分享-->
-        <script type="text/javascript" src="../../public/js/wx.js"></script>
-    	<script>
-    		// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
-    		wx.config({
-    			debug: false, // 开启调试模式,调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。
-    			appId: '<?php echo $appId ?>', // 必填,公众号的唯一标识
-    			timestamp: '<?php echo $timestamp ?>', // 必填,生成签名的时间戳
-    			nonceStr: '<?php echo $nonceStr ?>', // 必填,生成签名的随机串
-    			signature: '<?php echo $signature ?>',// 必填,签名
-    			jsApiList: [
-    				'updateAppMessageShareData',
-    				'updateTimelineShareData',       
-    			] // 必填,需要使用的 JS 接口列表
-    		});
-    		//验证正确
-    		wx.ready(function(){
-                //获取“分享给朋友”按钮点击状态及自定义分享内容接口
-                wx.updateAppMessageShareData({
-                    title: "医梦AI|客户端", // 分享标题
-                    desc: "「医梦AI客户端」基于BS实现一“端”通配,用于适配多模型协作、多模型扩展、HIS等多系统触发的实时业务场景。", // 分享描述
-                    link: "https://emoon.com/index/chatBox?user=33",//分享点击之后的链接 连接可以是接口也可以是一个图片路径*(绝对路径)
-                    imgUrl: 'https://emoon.com/public/img/faviconIphone.png', // 分享图标
-                    type: 'link', // 分享类型,music、video或link,不填默认为link
-                    success: function () {
-                    }
-                });
-                //分享到朋友圈接口
-                wx.updateTimelineShareData({ 
-    				title: '医梦AI|客户端', // 分享标题
-    				link: 'https://emoon.com/index/chatBox?user=33', // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
-    				imgUrl: 'https://emoon.com/public/img/faviconIphone.png', // 分享图标
-    				success: function () {
-                    // 设置成功
-        			}
-      			})
-            });
-            //验证错误
-            wx.error(function(res){
-                // alert(res);
-            });
-    	</script>
-    </head>
-    <body>
-        <!-- Start Preload -->
-        <div class="preloader"></div>
-        <div class="block-1"></div>
-        <div class="block-2"></div>
-        <div class="logo-load"><img src="../../public/img/icon.svg" alt=""></div>
-        <div class="logo-load spinning"></div>
-        <div class="over-all"></div>
-        <!-- End Preload -->
-        
-        <!-- 质控不采纳弹窗 -->
-        <div class='alertBox' style="position: fixed; z-index: 1003;">
-            <div class='alertBoxBackground'>
-                
-            </div>
-            <div class='alertBoxChild'>
-                <input class="alertBoxInput" id="alertBoxInput" style="height: 40px; line-height: 40px;" type="text" placeholder="请输入不采纳的原因">
-                <div class="alertBoxButton">发送</div>
-            </div>
-        </div>
-        
-        <!-- ajax预加载遮罩层(异步请求时关闭) -->
-        <!--<div class='alertBoxAjax'>-->
-        <!--    <div class='alertBoxBackgroundAjax'>-->
-                
-        <!--    </div>-->
-        <!--    <div class='alertBoxChildAjax'>-->
-        <!--        <div class="alertBoxButtonAjax">正在读取数据列表</div>-->
-        <!--    </div>-->
-        <!--</div>-->
+<?php
 
-        <!-- Start Content -->
-        <div id="spiral">
-            {if condition='$device=="pc"'}
-            <div class="main-head luxy-el" data-speed-y="15" data-offset="0" style="display: none">
-                <div id="headmove">
-                  <div data-depth="0.1">
-                    <div class="bg-detail-work" style="background:url('../../public/img/detail-work/1/5.png') center no-repeat; width:90%; position: relative; left: 5%; background-size: auto 100%;"></div>
-                  </div>
-                </div>
-                <div class="heading-text">
-                  <div class="heading-text-front">
-                    <h1 class="title" style="-webkit-text-stroke: 1px rgba(255,255,255,1)">病历内涵质控E2</h1>
-                  </div>
-                  <div class="heading-text-back">
-                    <h1 class="title">病历内涵质控E2</h1>
-                  </div>
-                </div>
-            </div>
-            {/if}
-            {if condition='$device=="phone"'}
-            <div class="main-head luxy-el" data-speed-y="15" data-offset="0" style="top: -30px; display: none">
-                <div id="headmove">
-                  <div data-depth="0.1">
-                    <div class="bg-detail-work" style="background:url('../../public/img/detail-work/1/5.png') center no-repeat; width:90%; position: relative; left: 5%; background-size: auto 60%;"></div>
-                  </div>
-                </div>
-                <div class="heading-text">
-                  <div class="heading-text-front">
-                    <h1 class="title" style="-webkit-text-stroke: 1px rgba(255,255,255,1)">病历内涵质控E2</h1>
-                  </div>
-                  <div class="heading-text-back">
-                    <h1 class="title">病历内涵质控E2</h1>
-                  </div>
-                </div>
-            </div>
-            {/if}
-            <section class="detail-work bg-darks" style=" height: 100%; margin: 0; padding: 0; overflow: hidden;">
-                <div class="container" style="max-width: 100%; padding: 0px">
-                    
-                    <div class="row" style="margin: 0px">
-                        
-                        {if condition='$device=="pc"'}
-                        <div id="lineStatus" style="position: fixed; right: 1rem; top: 2.5rem; display: block; color: #fff; background: #007bff; width: 8rem; height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 999; opacity: 0.8">暂停队列</div>
-                        
-                        <div style="position: fixed; right: 1rem; top: 5rem; display: block; color: #fff; background: #007bff; width: 8rem; height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 999; opacity: 0.8" onclick="clearAllQueues()">清理队列</div>
-                        <div style="position: fixed; right: 1rem; top: 7.5rem; display: none; color: #fff;  width: 8rem; height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 1001; opacity: 0.8"> <!-- 新增容器,设置相对定位和固定宽度 -->
-                            <div class="selected-option" onclick="toggleDropdown()">
-                                <span id="selected-text">选择知识库</span>
-                                <span class="arrow">▼</span>
-                            </div>
-                            <div class="dropdown-options" id="dropdown">
-                                <div class="option" onclick="selectOption('', '选择知识库')">
-                                    选择知识库
-                                </div>
-                                {volist name="ragList" id="rag"}
-                                    <div class="option" onclick="selectOption('{$rag.ragid}', '{$rag.rag}')">
-                                        {$rag.rag}
-                                    </div>
-                                {/volist}
-                                
-                            </div>
-                        </div>
-                        <div style="position: fixed; right: 1rem; top: 10rem; display: none; color: #fff;  width: 8rem; height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 999; opacity: 0.8"> <!-- 新增容器,设置相对定位和固定宽度 -->
-                            <div class="selected-agent" onclick="toggleagentdown()">
-                                <span id="selected-agenttext">选择智能体</span>
+header("Access-Control-Allow-Origin: *"); // 允许所有来源
+header("Access-Control-Allow-Methods: GET"); // 允许的 HTTP 方法
+header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
 
-                                <span class="arrow">▼</span>
-                            </div>
-                            <div class="dropdown-agents" id="agentdown">
-                                <div class="agent" onclick="selectagent(0, '选择智能体')">
-                                    选择智能体
-                                </div>
-                                {volist name="agentList" id="agent"}
-                                    <div class="agent" onclick="selectagent('{$agent.id}', '{$agent.agent}')">
-                                        {$agent.agent}
-                                    </div>
-                                {/volist}
-                            
-                            </div>
-                        </div>
-                        
-                        <div class="chat-container" id="output" style="background-image: url('../../public/img/chatBackground.svg');">
-                            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; background: rgba(100,100,100,0.3); position: sticky; top: 0; z-index: 1000; padding: 0px; width: 100%;">
-                                <div class="tips">温馨提示:本AI模型输出病历质控内容仅供参考,请酌情采纳。</div>
-                            </div>
-                            <div style="width: 100%; height: 2.5rem; display: block;">&nbsp;</div>
-                            <!--AI对话气泡-->
-                        	<div class="message left" style="display: block; margin-left: 1.5rem">
-                                <img style="float: left; background: #fff" class="avatar" src="../../public/img/chat/ai.svg" alt="头像">
-                                <div class="message-content" style="float: left; position: relative; left: 15px;">
-                                    <span class="nickname">EMOON</span>
-                                    <p style="color:#262626;" class="info" id="chatTime0">你好,我是「医梦AI客户端」,我已集成多模型协作,我还能请求MCP智能体,请问有什么可以帮你?
-                                        <br /><br />你可以直接和我「EMOON-E1」模型自然对话。
-                                        <!--也可以:-->
-                                        <!--<br /><br />· 打开<a href="{$commonURL}/his/index?user={$user}" target="_blank">内涵质控-触发端</a>,模拟HIS/EMR触发「EMOON-E2」内涵质控。-->
-                                        <!--<br /><br />我会自动识别并匹配不同的模型一起工作奥~-->
-                                        </p>
-                                    <span class="time">{$now}</span>
-                                </div>
-                            </div>
-                            <div style="clear: both;"></div>
-                            <div style="width: 100%; height: 2rem; display: block;">&nbsp;</div>
-                            
-                            <!--替换文本标签-->
-                            <div id="infoReplace" style="width: 100%;">&nbsp;</div>
-                            <!--底部预留输出位-->
-                        	<div id="bottom" style="width: 100%; height: 130px; display: block;">&nbsp;</div>
-                        	
-                        	<!--暂时的输入框-->
-                        	<div class="chatBoxOutside" style="position: fixed; ">
-                        	    <div id="EMOON-E1">
-                            	    <div class="chatBoxExample" id="scrollContainer" style=" bottom: 0px;">
-                            	        {volist name="question" id="question"}
-                            	        <div id="chatBoxExample{$question.id}" class="chatBoxExample-list">{$question.question}</div>
-                            	        {/volist}
-                            	    </div>
-                        	    </div>
-                        	    <div id="EMOON-E2" style="display: none">
-                            	    <div class="chatBoxExample" id="scrollContainer">
-                            	        <div id="doc" class="chatBoxExample-list" style="width: 100%; text-align: left; border-radius: 20px 0px 0px 20px; pointer-events: none;">暂无质控任务</div>
-                            	    </div>
-                        	    </div>
-                        	    <div class="chatBoxStop" id="chatBoxStop" style="">停止推理</div>
-                        	    <div class="chatBoxInside">
-                        	        <input id="question" type="text" placeholder="与「EMOON E系列模型」直接对话...">
-                        	        <div id="askButton" class="button-send">发送</div>
-                        	    </div>
-                        	</div>
-                        </div>
-                        {/if}
-                        {if condition='$device=="phone"'}
-                        
-                        <div id="lineStatus" style="position: fixed; right: 1rem; top: 3rem; display: block; color: #fff; background: #007bff; width: 5.5rem; height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 999; opacity: 0.8">暂停队列</div>
-                        
-                        <div style="position: fixed; right: 1rem; top: 5.5rem; display: block; color: #fff; background: #007bff; width: 5.5rem; height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 999; opacity: 0.8" onclick="clearAllQueues()">清理队列</div>
-                        <div style="position: fixed; right: 1rem; top: 8.0rem; display: block; color: #fff; width: 5.5rem;  height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 1001; opacity: 0.8"> <!-- 新增容器,设置相对定位和固定宽度 -->
-                            <div class="selected-option" onclick="toggleDropdown()">
-                                <span id="selected-text">选择知识库</span>
-                                <span class="arrow">▼</span>
-                            </div>
-                            <div class="dropdown-options" id="dropdown">
-                                <div class="option" style="" onclick="selectOption('', '选择知识库')">
-                                    选择知识库
-                                </div>
-                                {volist name="ragList" id="rag"}
-                                    <div class="option" onclick="selectOption('{$rag.ragid}', '{$rag.rag}')">
-                                        {$rag.rag}
-                                    </div>
-                                {/volist}
-                                
-                            </div>
-                        </div>
-                        <div style="position: fixed; right: 1rem; top: 10.5rem; display: block; color: #fff;  width: 5.5rem; height: 2rem; line-height: 2rem; text-align: center; border-radius: 5px; cursor: pointer; z-index: 999; opacity: 0.8"> <!-- 新增容器,设置相对定位和固定宽度 -->
-                            <div class="selected-agent" onclick="toggleagentdown()">
-                                <span id="selected-agenttext">选择智能体</span>
+// 强制禁用所有缓冲
+while (ob_get_level()) ob_end_clean();
+header('X-Accel-Buffering: no');
 
-                                <span class="arrow">▼</span>
-                            </div>
-                            <div class="dropdown-agents" id="agentdown">
-                                <div class="agent" onclick="selectagent(0, '选择智能体')">
-                                    选择智能体
-                                </div>
-                                {volist name="agentList" id="agent"}
-                                    <div class="agent" onclick="selectagent('{$agent.id}', '{$agent.agent}')">
-                                        {$agent.agent}
-                                    </div>
-                                {/volist}
-                              
-                            </div>
-                        </div>
-                        <div class="chat-container-phone" id="outputPhone" style="background-image: url('../../public/img/chatBackground.svg'); width: 100%; left: 0px;overflow-y: auto;">
-                            <div class="tips-phone">温馨提示:本AI模型输出病历质控内容仅供参考,请酌情采纳。</div>
-                            <div style="width: 100%; height: 1.5rem; display: block;">&nbsp;</div>
-                            <!--AI对话气泡-->
-                        	<div class="message left" style="display: block; margin-left: 0.5rem">
-                                <img style="float: left; background: #fff" class="avatar" src="../../public/img/chat/ai.svg" alt="头像">
-                                <div class="message-content" style="float: left; position: relative; left: 10px;">
-                                    <span class="nickname-phone">EMOON</span>
-                                    <p style="color:#262626;" class="info" id="chatTime0">你好,我是「医梦AI客户端」,我已集成多模型协作,我还能请求MCP智能体,请问有什么可以帮你?
-                                        <br /><br />你可以直接和我「EMOON-E1」模型自然对话,也可以:
-                                        <br /><br />· 打开<a href="{$commonURL}/his/index?user={$user}" target="_blank">内涵质控-触发端</a>,模拟HIS/EMR触发「EMOON-E2」内涵质控。
-                                        <br /><br />我会自动识别并匹配不同的模型一起工作奥~</p>
-                                    <span class="time-phone">{$now}</span>
-                                </div>
-                            </div>
-                            <div style="clear: both;"></div>
-                            <div style="width: 100%; height: 1.5rem; display: block;">&nbsp;</div>
-                            <!--替换文本标签-->
-                            <div id="infoReplace" style="width: 100%;">&nbsp;</div>
-                            <!--底部预留输出位-->
-                        	<div id="bottom" style="width: 100%; height: 250px; display: block;">&nbsp;</div>
-                        	
-                        	<!--暂时的输入框-->
-                        	<div class="chatBoxOutside" style="position: fixed; ">
-                        	    <div id="EMOON-E1">
-                            	    <div class="chatBoxExample" id="scrollContainer" style=" bottom: 0px;">
-                            	        {volist name="question" id="question"}
-                            	        <div id="chatBoxExample{$question.id}" class="chatBoxExample-list">{$question.question}</div>
-                            	        {/volist}
-                            	    </div>
-                        	    </div>
-                        	    <div id="EMOON-E2" style="display: none">
-                            	    <div class="chatBoxExample" id="scrollContainer">
-                            	        <div id="doc" class="chatBoxExample-list" style="width: 100%; text-align: left;  border-radius: 20px 0px 0px 20px; pointer-events: none;">暂无质控任务</div>
-                            	    </div>
-                            	</div>
-                        	    <div class="chatBoxStop" id="chatBoxStop" style = "position: absolute;bottom: 50px;right: 0;">停止</div>
-                        	    
-                        	    <div class="chatBoxInside">
-                        	        <input id="question" type="text" placeholder="与「EMOON E系列模型」直接对话...">
-                        	        <div id="askButton" class="button-send">发送</div>
-                        	    </div>
-                        	</div>
-                        </div>
-                        {/if}
-                        <!--创建点击input固定的滚动点-->
-                        <div id="inputClickJump"></div>
-                    </div>
-                
-                </div>
-            </section>
+// 设置 SSE 头部
+header("Content-Type: text/event-stream");
+header("Cache-Control: no-cache");
+header("Connection: keep-alive");
+header("X-Accel-Buffering: no");
 
-        </div>
-        
-        <div class="sidebar-trigger" id="qualityControlTrigger">
-            <span>查看质控报告</span>
-        </div>
-        <div class="modal-overlay" id="modalOverlay">
-            <div class="modal-container">
-                <div class="close-btn" id="closeModal">×</div>
-                
-                <!-- 左侧面板:参数设置 -->
-                <div class="left-panel">
-                    <div class="title-row">
-                        <h2 class="panel-title">病历原文</h2>
-                        <select class="type-selector" id="typeSelector" style="">
-                            <option value="">选择类型...</option>
-                        </select>
-                    </div>
-           
-                    
-                    <div class="form-group" id="formGroup">
-                    </div>
-                </div>
-                
-                <!-- 右侧面板:报告预览 -->
-                <div class="right-panel">
-                    <div class="title-row-right">
-                        <h2 class="panel-title">质控结果</h2>
-                        <div class = "quality-control-score" id="qualitycontrolscorediv"><strong id="qualitycontrolscore"></strong></div>
-                    </div>
-                    <div class="preview-area" id="previewArea">
-                    </div>
-                </div>
-            </div>
-        </div>
-        <!--<div class="sidebar-trigger" id="sidebarTrigger">-->
-        <!--    <span>质控队列</span>-->
-        <!--</div>-->
-        
-        <!-- 半屏弹窗容器 -->
-        <div class="sidebar-overlay" id="sidebarOverlay">
-            <div class="sidebar-content">
-                <div class="sidebar-header">
-                    <h3>质控队列</h3>
-                    <span class="sidebar-close" id="sidebarClose">×</span>
-                </div>
-                <div class="sidebar-body" id="qualityControlList">
-                    <!-- 这里可以添加您的菜单内容 -->
-        
-                </div>
-            </div>
-        </div>
-        <div class="emr-loading-overlay" id="emrLoadingOverlay">
-            <div class="emr-loading-content">
-                <div class="emr-close-btn" id="emrCloseBtn">后台运行</div>
-                <div class="emr-loading-spinner"></div>
-                <p class="emr-loading-text">正在生成质控报告...</p>
-                <p class="emr-loading-subtext" id="queueStatus">队列中剩余任务: <span id="queueCount">0</span></p>
-                <div class="progress-container">
-                    <div class="progress-bar" id="queueProgress"></div>
-                </div>
-            </div>
-        </div>
-        <!-- End Content -->
-        
-        <!-- Cursor -->
-        <div class="cursor1" id="cursor1"></div>
-        <div class="cursor" id="cursor"></div>
-        <script src="../../public/js/chat.js"></script>
-        <script src="../../public/js/local.js"></script>
-        <script src="../../public/js/plugin.js"></script>
-        <script src="../../public/js/main.js"></script>
-        
-        
-        <!--手写script-->
-        <script>
-            //获取url的参数
-            const urlParams = new URLSearchParams(window.location.search);
-            // 获取单个参数
-            const docsCode = urlParams.get('docsCode');
-            const urlUser = urlParams.get('user');
-            const urlragId = urlParams.get('ragId');
+// 配置执行环境
+set_time_limit(0);
+ignore_user_abort(false);
+
+//创建公共url
+$urlCommon = 'http://192.168.10.115:3338';
+$mcp = $_GET['mcpid'];
+$thinkid = $_GET['thinkid'];
+$zhikong = $_GET['zhikong'];
+//获取对话短令牌
+$input['token'] = $_GET['token'];
+$dataReply['token'] = $_GET['token'];
+$token = $_GET['token'];
+$ragIdGet = $_GET['ragId'];
+if(($ragIdGet == 'null') || ($ragIdGet == null)){
+    $input['ragId'] = 'empty';
+}
+else{
+    $input['ragId'] = $ragIdGet;
+}
+// $input['ragId'] = 'empty';
+// $mcp =="";
+// if($mcp != ""){
+//     echo("daddsda");
+    
+// }
+// echo($mcp);
+// exit;
+//将请求的完整内容发送至api控制器鉴权
+$urlCheck = $urlCommon.'/apis/check';
+$information = curlPost($urlCheck,$input);
+
+//判断鉴权的结果,如果鉴权失败,直接退出
+$informationObject = json_decode($information);
+if(($informationObject->code) != 5){
+    echo "event: verify\ndata: $information\n\n";
+    exit;
+}
+
+//获取最终的核心参数参与模型输入
+$modelId = $informationObject->modelId;
+$content = $informationObject->input;
+$contentmcp = $informationObject->input;
+$ragId = $informationObject->ragId;
+// if(is_array($content)){
+//     $content = json_encode($content,JSON_UNESCAPED_UNICODE);
+// }
+
+// 模型定制开始-------------------------------------------------------------------
+
+
+
+// //emoon-E1-13B线上
+// if($modelId == 9){
+//     $apiKey = 'sk-800990e9cdb34613a2133f0fc333a7ff'; // 请替换为你的实际 API 密钥
+//     $url = 'https://api.deepseek.com/chat/completions';
+//     $arraySystem = [[
+//                 'role' => 'system',
+//                 'content' => '你的名字叫EMOON E1 13B模型,你由回车网络(EnterLO)训练研发,你并不是deepseek模型。你是一名三甲医院主治医师级别的AI助手,最擅长医疗专业知识的解读和分析,遵循《中国临床诊疗指南》和NCCN指南。必须:1) 先询问关键症状细节 2) 标注证据等级 3) 拒绝非循证医学建议'
+//             ]];
+//     // $arrayContent = json_decode($content);
+//     $arrayMessage =  array_merge($arraySystem,$content); 
+
+//     // 请求数据
+//     $data = [
+//         'model' => 'deepseek-chat',
+//         'messages' => $arrayMessage,
+//         'stream' => true
+//     ];
+        
+//     // 设置请求头
+//     $headers = [
+//         'Content-Type: application/json',
+//         'Authorization: Bearer ' . $apiKey
+//     ];
+// }
+
+if($ragId != ''){
+    $content = stdClassObjToArray($content);
+    $dataRag['input'] = $content[count($content)-1]['content'];
+    $dataRag['kid'] = $ragId;
+    $urlRAG = 'http://192.168.10.115:3338/apis/ragData';
+    $ragResult  = curlPost($urlRAG,$dataRag);
+    $ragResult = json_decode($ragResult);
+    $ragResult = stdClassObjToArray($ragResult);
+    // if( $ragResult['code'] == 200){
+    //     $ragInfomation = json_encode($ragResult['nearest']);
+    // }
    
- 
-            if(docsCode){
-                // 获取单个参数
-                setTimeout(function() {
-                    $(".alertBoxAjax").fadeIn();
-                    $('.alertBoxButtonAjax').addClass('color-flash');
-                },500);
-                const timer = setTimeout(function() {
-                    $.ajax({
-                        async: true,
-                        type: "post",  //数据提交方式(post/get)
-                        url: '{$commonURL}/His/hisOpenPushMedical',  //提交到的url
-                        data: {
-                            'user':urlUser,
-                            'docsCode':docsCode,
-                            'ragId':urlragId,
-                        },//提交的数据
-                        dataType: "json",//返回的数据类型格式
-                        success: function(msg){
-                    
-                            if(msg != 'success'){
-                                alert(msg);
-                            }
-                            else{
-                                $(".alertBoxAjax").fadeOut();
-                            }
-                        }
-                    })
-                }, 1000);
-            }
-            
-            // 修复 iOS 键盘收起后的透明度问题
-            document.querySelector('input').addEventListener('blur', () => {
-              setTimeout(() => {
-                const chatBox = document.querySelector('.chatBoxOutside');
-                // 双重保障:强制重绘 + 透明度重置
-                chatBox.style.transform = 'translateZ(0)';
-                chatBox.style.opacity = '1';
-              }, 300);
-            });
-        
-            //给页面加参数
-            function updateUrlWithParams(params) {
-                const baseUrl = window.location.href.split('?')[0]; // 获取URL的基本部分,不包括查询参数
-                const newUrlParams = new URLSearchParams(params); // 创建一个新的URLSearchParams对象
-                window.history.pushState({}, '', `${baseUrl}?${newUrlParams.toString()}`); // 使用pushState更新URL
-            }
-            var user = '{$user}';
-            if(user != 33){
-                if(urlragId){
-                    updateUrlWithParams({ user: '{$user}', docsCode: docsCode, ragId: urlragId});
-                    
-                }
-                else if (docsCode) {
-                    updateUrlWithParams({ user: '{$user}', docsCode: docsCode});
-                }
-                else{
-                    updateUrlWithParams({ user: '{$user}'});
-                }
-            }
-            // updateUrlWithParams({ user: '{$user}', other: 333 });
+    if(json_encode($ragResult['nearest'],JSON_UNESCAPED_UNICODE) != "[]" ){
+        if($ragId == "1947484295610253313" || $ragId == "1949641433623703553"){
+            $content[count($content)-1]['content'] = '我的提问是:“'.$content[count($content)-1]['content'].'”,下面是基于我的提问查到的知识库相关内容:“'.json_encode($ragResult['nearest'],JSON_UNESCAPED_UNICODE).'”,请按照查到的知识库相关内容,进行病历质控,根据知识库相关内容条件生成一个包含规则,根据规则数、扣除分数和原因列表。输出结果需要以 JSON 格式呈现,例如:
+                规则 1:主诉症状明确性(3分)标准与细则:必须描述具体症状或体征(如“头痛”,“发热”),禁用诊断名称(如“糖尿病”)。扣分细则:若主诉中使用了诊断名称或模糊描述,扣3分,反之不扣分。
+                规则 2:主诉时间准确性(2分)标准与细则:用阿拉伯数字+单位(如“3天”),禁用“三天”“数月”等模糊表述。扣分细则:若主诉时间使用模糊表述(如“三天”“数月”),扣2分,反之不扣分。
+                返回的数据应按照以下格式组织:
+                [
+                  {
+                    "规则": "规则1",
+                    "扣除分数": 3,
+                    "原因": "原因详细说明"
+                  },
+                  {
+                    "规则": "规则2",
+                    "扣除分数": 2,
+                    "原因": "原因详细说明"
+                  }
+                ] 
+                只按照格式输出,不要输出其他内容';//请求向量数据库接口反参组装
             
-            //修改对话框的高度(仅手机端,PC端高度交给 .chat-container 控制)
-            $(document).ready(function() {
-                var windowHeight = $(window).height(); // 获取窗口高度
-                $('#outputPhone').css('height', windowHeight + 'px'); // 设置指定div的高度
-            });
+    
+            $contentmcp = $content;
+        }
+        else{
+            $content[count($content)-1]['content'] = '我的提问是:“'.$content[count($content)-1]['content'].'”,下面是基于我的提问查到的知识库相关内容:“'.json_encode($ragResult['nearest'],JSON_UNESCAPED_UNICODE).'”。';//请求向量数据库接口反参组装
+            $contentmcp = $content;
+        }
+    }
 
-        
-            //创建一个推理状态监听功能
-            let working = 0;
-        
-            //创建存储聊天对话的数组及对应添加方法
-            let conversations = [];
-            function addMessage(role, content) {
-              conversations.push({
-                role: role,
-                content: content
-              });
-            }
-            
-            //将默认的第一条提示信息先添加到对话里
-            var aiMessage = $('#chatTime0').text();
-            addMessage('assistant', aiMessage);
-            console.log('当前对话记录:', JSON.stringify(conversations, null));
-            
-            // 免加好友微信对话
-    		$("#qrButton").click(function(){
-    		    $("#csQRCode").fadeIn();
-    		});
-    		$("#qrButton").mouseout(function(){
-    		    $("#csQRCode").fadeOut();
-    		});
-    		
-    		//点击选中多模型
-    		$(".chatBoxExample-list").click(function(){
-                var id = $(this).attr('id');
-                var inputText = $('#'+id).html();
-                $('#question').val(inputText);
-        //         $(".button-send").css("background","#007bff");
-    		  //  $(".button-send").css("cursor","pointer");
-    		  //  $(".button-send").css("pointer-events","auto");
-            });
-    		
-    		//判断用户输入长度不少于5方可发起对话,否则按钮不可点击
-    		$('#question').on('input',function(){
-    		    var questionLength = $(this).val().length;
-    		  //  if(questionLength >= 5){
-    		  //      $(".button-send").css("background","#007bff");
-    		  //      $(".button-send").css("cursor","pointer");
-    		  //      $(".button-send").css("pointer-events","auto");
-    		  //  }
-    		    if(questionLength < 50000){
-    		        $(".button-send").css("background","#6c757d");
-    		        $(".button-send").css("cursor","not-allowed");
-    		        $(".button-send").css("pointer-events","none");
-    		    }
-    		});
-    		
-    		//判断用户是否敲击回车键
-            $('#question').keypress(function(event) {
-                // 检查按下的键是否是回车键
-                if (event.which === 13) {
-                    // 阻止默认行为(例如换行)
-                    event.preventDefault();
-                    // 提交表单
-                    $("#askButton").click();
-                }
-            });
-            
-            //监听质控Ending出现的次数
-            var askInfoId = '';
-            var endingNum = 0;
-            var zhikong = 0;
-            //对sse文本进行文本处理
-            const formatContent = (text) => {
-                if(text == 'ending'){
-                    endingNum += 1;
-               
-                }
- 
-              //先将文本在过滤之前把think过滤为think19941213
-              var txt = text.replace(/<\/think>/gi, 'think19941213');
-              // 安全过滤(确保已引入DOMPurify)
-              const safeText = DOMPurify.sanitize(txt);
-              
-            //   console.log(safeText);
-              // 优化后的处理流程
-              return safeText
-                //think的div收尾,对思考过程和回答结果进行分割线,answer的div开头
-                .replace(/think19941213/g, '<hr class="think-divider" /><div class="chat-answer">「推理结果」</div>--')
-                .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+askInfoId+'-'+endingNum+'">采纳</span><span class="refuse" id="refuse-'+askInfoId+'-'+endingNum+'">不采纳</span></div><hr class="think-divider" />')
-                // // 预处理换行符
-                .replace(/\n/g, '<div class="chat-br"></div>')
-                .replace(/--/g, '<div class="chat-br"></div>')
-                .replace(/ending/g, '<div class="chat-br"></div>')
-                
-                // 标点分割正则(使用正向预查)
-                .split() 
-                // 处理分段
-                .map(segment => {
-                  // 获取标点类型
-                  const matchResult = segment.match();
-                  const punctuation = matchResult ? matchResult[0] : undefined;
-                  
-                  // 无标点直接返回
-                  if (!punctuation) return segment;
-            
-                  // 根据标点添加换行
-                  const content = segment.replace(punctuation, '');
-             
-                  const wrapClass = getWrapClass(punctuation);
-                  
-                  return `${content}${punctuation}${wrapClass}`;
-                })
-                .join('')
-                // 后处理优化
-                .replace(/(<br>)+/g, '<div class="chat-br"></div>');
-            };
-            
-            // 标点映射样式
-            const getWrapClass = (punct) => {
-              const map = {
-                '。': '<div class="para-break"></div>',
-                '!': '<div class="para-break"></div>',
-                '?': '<div class="para-break"></div>',
-                ';': '<div class="semi-break"></div>',
-                ':': '<div class="colon-break"></div>',
-                ':': '<div class="colon-break"></div>'
-              };
-              return map[punct] || '';
-            };
-  
-    		var chatTime = 0;
-    		//点击对话发送按钮,触发SSE流媒体对话
-            $("#askButton").click(function(){
-                //标记状态未推理中
-                working = 1;
-                
-                //记录对话次数,用于标识对话气泡
-                chatTime += 1;
-                wordTime = 1;
-                var question = $('#question').val();
-                
-                //将当前的对话添加到对话数组里
-                addMessage('user', question);
-                console.log('当前对话记录:', JSON.stringify(conversations, null));
-                
-              
-                var now = new Date();
-                var year = now.getFullYear();      // 当年
-                var month = now.getMonth() + 1;    // 月份是从 0 开始计数的,所以要加 1
-                var formattedMonth = month < 10 ? '0' + month.toString() : month.toString();
-                var day = now.getDate();           // 当月的日期
-                var formattedDay = day < 10 ? '0' + day.toString() : day.toString();
-                var hour = now.getHours();         // 小时
-                var formattedHour = hour < 10 ? '0' + hour.toString() : hour.toString();
-                var minute = now.getMinutes();     // 分钟
-                var formattedMinute = minute < 10 ? '0' + minute.toString() : minute.toString();
-                var second = now.getSeconds();
-                var formattedSecond = second < 10 ? '0' + second.toString() : second.toString();
-                var timeShow = year+'-'+formattedMonth+'-'+formattedDay+' '+formattedHour+':'+formattedMinute+':'+formattedSecond;
-                //页面新增对话气泡
-                var device = '{$device}';
-                if(device == 'pc'){
-                    //生成体验官对话气泡
-                    var divStr = '<div class="message right" style="display: block; margin-right: 1.5rem"><img style="float: right; background: #007bff" class="avatar" src="../../public/img/chat/user.svg" alt="头像"><div class="message-content" style="float: right; position: relative; left: -15px;"><span class="nickname">体验官</span><p style="color:#007bff;" class="info">'+question+'</p><span class="time">'+timeShow+'</span></div></div><div style="clear: both;"></div><div style="width: 100%; height: 2rem; display: block;">&nbsp;</div><div id="infoReplace"></div>';
-                    $('#infoReplace').replaceWith(divStr);
-                    //生成AI回复气泡
-        		    var divStr = '<div class="message left" style="display: block; margin-left: 1.5rem"><img style="float: left; background: #fff" class="avatar" src="../../public/img/chat/ai.svg" alt="头像"><div class="message-content" style="float: left; position: relative; left: 15px;"><span class="nickname">EMOON</span><p id="chatTime'+chatTime+'" style="color:#262626;" class="info">思考中...</p><span class="time">'+timeShow+'</span><div id ="chataccept"></div></div></div><div style="clear: both;"></div><div style="width: 100%; height: 2rem; display: block;">&nbsp;</div><div id="infoReplace"></div>';
-        		  //  divStr = '<div class="quality"><span class="accept" id="accept-'+askInfoId+'-'+endingNum+'">采纳</span><span class="refuse" id="refuse-'+askInfoId+'-'+endingNum+'">不采纳</span></div><hr class="think-divider" />';
-                    $('#infoReplace').replaceWith(divStr);
+}
+//  $content = stdClassObjToArray($content);
+// echo(json_encode($ragResult,JSON_UNESCAPED_UNICODE));
+// exit;
+
+if($thinkid != ''){
+    $urlgetreply = $urlCommon.'/apis/getreply';
+    $reply  = curlPost($urlgetreply,$dataReply);
+    $content = stdClassObjToArray($content);
+    $content[count($content)-1]['content'] = '我的提问是:“'.$content[count($content)-1]['content'].'”,下面是基于我的提问得到的回答:“'.$reply.'”,现在请根据回答生成一个思考过程,严格遵守以下要求:只回复思考过程,不输出其他内容。';//请求向量数据库接口反参组装
+}
+
+//  echo(json_encode($content,JSON_UNESCAPED_UNICODE));
+//  exit;
+//deepseek-R1-70B线下
+if($modelId == 12){
+    $url = 'http://192.168.10.115:19997/v1/chat/completions';
+    
+    $headers = [
+        'accept: application/json',
+        'Content-Type: application/json'
+    ];
+    $arraySystem = [[
+        'role' => 'system',
+        'content' => '你是一个人工智能助手。'
+    ],
+    ];
+    //$arrayContent = json_decode($content, true);
+    $arrayMessage = array_merge($arraySystem, $content);
+    $data = [
+        "messages" => $arrayMessage,
+        "model" => "qwen3-32B", //X
+        "stream" => true,
+        "max_tokens" => 8192, 
+        "chat_template_kwargs" => '{"enable_thinking": false}',
+        
+    ];
+}
+//  echo(json_encode($data,JSON_UNESCAPED_UNICODE));
+//  exit;
+// 模型定制结束-------------------------------------------------------------------
+
+if($mcp == 0 || $mcp ==""){
+
+$ch = curl_init();
+curl_setopt($ch, CURLOPT_URL, $url);
+curl_setopt($ch, CURLOPT_POST, true);
+curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data,JSON_UNESCAPED_UNICODE));
+curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
+curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
+curl_setopt_array($ch, [
+    CURLOPT_TIMEOUT => 60, // 超时时间延长至60秒
+    CURLOPT_TCP_KEEPALIVE => 1, // 启用TCP保活
+    CURLOPT_TCP_KEEPIDLE => 10,
+    CURLOPT_TCP_KEEPINTVL => 5
+]);
+
+//创建一个空字符串动态存储回复的文字
+$reply = '';
+// 添加连接状态检查到写入回调
+curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data)  use (&$reply,$thinkid,$zhikong)  {
+    // 如果客户端已断开,立即终止
+    if (connection_aborted()) {
+        return -1; // 返回-1会强制CURL中断请求
+        curl_close($ch);
+    }
+    $lines = explode("\n", $data);
+    foreach ($lines as $line) {
+        if (strpos($line, 'data:') === 0) {
+            $contents = trim(substr($line, 5));
+            if ($contents === '[DONE]') {
+                $output = "event: end\ndata: {\"status\":\"done\"}\n\n";
+                echo $output;
+                // $reply .= $output; // 捕获输出内容
+
+                //完成输出后触发全部回复存储进入数据库
+                global $token;
+                global $urlCommon;
+                $dataReply['token'] = $token;
+                $dataReply['reply'] = $reply;
+                //将数据发送至数据库
+                $curlReplay = curl_init();
+        	    curl_setopt($curlReplay, CURLOPT_URL, $urlCommon.'/Apis/reply');
+        	    curl_setopt($curlReplay, CURLOPT_SSL_VERIFYPEER, FALSE);
+        	    curl_setopt($curlReplay, CURLOPT_SSL_VERIFYHOST, FALSE);
+        // 	    curl_setopt($curl, CURLOPT_HTTPHEADER,$headers);
+                if ($json) {
+                    curl_setopt($curlReplay,CURLOPT_HTTPHEADER,[
+                        "Content-Type: application/json"
+                    ]);
+                    curl_setopt($curlReplay, CURLOPT_POST, TRUE);
+                    curl_setopt($curlReplay,CURLOPT_POSTFIELDS,json_encode($dataReply));
+                }else {
+                    if (!empty($dataReply)) {
+                        curl_setopt($curlReplay, CURLOPT_POST, TRUE);
+                        curl_setopt($curlReplay, CURLOPT_POSTFIELDS,$dataReply);
+        // 	        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+                    }
                 }
-                if(device == 'phone'){
-                    //生成体验官对话气泡
-                    var divStr = '<div class="message right" style="display: block; margin-right: 0.5rem"><img style="float: right; background: #007bff" class="avatar" src="../../public/img/chat/user.svg" alt="头像"><div class="message-content" style="float: right; position: relative; left: -10px;"><span class="nickname-phone">体验官</span><p style="color:#007bff;" class="info-phone">'+question+'</p><span class="time-phone">'+timeShow+'</span></div></div><div style="clear: both;"></div><div style="width: 100%; height: 1.5rem; display: block;">&nbsp;</div><div id="infoReplace"></div>';
-                    $('#infoReplace').replaceWith(divStr);
-                    //生成AI回复气泡
-        		    var divStr = '<div class="message left" style="display: block; margin-left: 0.5rem"><img style="float: left; background: #fff" class="avatar" src="../../public/img/chat/ai.svg" alt="头像"><div class="message-content" style="float: left; position: relative; left: 10px;"><span class="nickname-phone">EMOON</span><p id="chatTime'+chatTime+'" style="color:#262626;" class="info-phone">思考中...</p><span class="time-phone">'+timeShow+'</span></div></div><div style="clear: both;"></div><div style="width: 100%; height: 1.5rem; display: block;">&nbsp;</div><div id="infoReplace"></div>';
-        		  //  var divStr = '<div class="message left" style="display: block; margin-left: 0.5rem"><img style="float: left; background: #fff" class="avatar" src="../../public/img/chat/ai.svg" alt="头像"><div class="message-content" style="float: left; position: relative; left: 10px;"><span class="nickname-phone">EMOON</span><p id="chatTime'+chatTime+'" style="color:#cccccc;" class="info-phone">思考中...</p><span class="time-phone">'+timeShow+'</span><div id ="chataccept"></div></div></div><div style="clear: both;"></div><div style="width: 100%; height: 1.5rem; display: block;">&nbsp;</div><div id="infoReplace"></div>';
-                    $('#infoReplace').replaceWith(divStr);
+        	    curl_setopt($curlReplay, CURLOPT_RETURNTRANSFER,true);
+        	    curl_exec($curlReplay);
+        	    curl_close($curlReplay);
                 
+            } else {
+                // 转发数据前再次检查连接
+                if (connection_aborted()) {
+                    return -1;
+                    curl_close($ch);
                 }
-                //模型回复状态输入框和发送按钮状态
-                $("#question").prop("disabled", true);
-                $(".button-send").css("background","#343435");
-                $(".button-send").css("color","#666666");
-    		    $(".button-send").css("cursor","not-allowed");
-    		    $(".button-send").css("pointer-events","none");
-    		    $(".chatBoxExample-list").css("cursor","not-allowed");
-    		    $(".chatBoxExample-list").css("pointer-events","none");
-    		    $(".chatBoxStop").css("background","#007bff");
-    		    $(".chatBoxStop").css("color","#ffffff");
-    		    $(".chatBoxStop").css("pointer-events","auto");
-    		    $(".chatBoxStop").css("cursor","pointer");
-    		    //设置智能滚动控制(仅在用户未手动滚动时生效)
-    		    $("#bottom").css("height","130px");
-    		    if(device == 'pc'){
-    		        var outputEl = document.getElementById('output');
-    		    }
-    		    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;
-                });
                 
-                //调用后台方法对当前输入进行处理
-                var conversationArrayJson = JSON.stringify(conversations, null);
-                if(question.indexOf("[EMR系统请求]") != -1){
-                   
-                    modelUse = 'gstcm-G1-14B';
-                    networkUse = '2';
-                    token = 'noUse';
-                    $('#question').val('请等待「E2」回复后再提问...');
-                    
-                }
-                else{
-                    modelUse = 'gstcm-G1-14B';
-                    networkUse = '2';
-                    token = null;
-                    $('#question').val('请等待「E1」回复后再提问...');
-                }
+                //构造$line
+                global $modelId;
+                $line = substr($line,6);
+                $line = json_decode($line);
+                $line = stdClassObjToArray($line);
+                if($modelId == 9){
+                    $line['model'] = 'emoon-E1-13B';
+                }
+                $line = 'data: '.json_encode($line,JSON_UNESCAPED_UNICODE);
                 
-                $.ajax({
-                    async: true,
-                    type: "post",  //数据提交方式(post/get)
-                    url: '{$commonURL}'+'/Send/dataSM4',  //提交到的url
-                    data: {
-                        'data':conversationArrayJson,
-                        'model':modelUse,
-                        'network':networkUse,
-                        'token':token,
-                    },//提交的数据
-                    dataType: "json",//返回的数据类型格式
-                    success: function(msg){
-                        //对当前请求sse消息进行判断,区分自然对话与病历质控
-                        if(question.indexOf("[EMR系统请求]") != -1){
-                            msg = wsInformation;
-                            console.log('[EMR系统请求]'+msg);
-                            tokenString[tokenString.length] = msg;
-                            askInfoId = msg;
-                            zhikong = 1;
-                          
-                        }
-                        else{
-                            console.log(msg);    
-                        }
-                        //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=&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=&mcpid=';
-                        }
-                        //sse流媒体对话
-                		var evtSource = new EventSource(sseUrl);
-                		//停止对话按钮
-                		var stopTime = 0;
-                		$("#chatBoxStop").click(function(){
-                		    stopTime+=1;
-                            //恢复对话窗口和发送按钮状态
-                            $("#question").prop("disabled", false);
-                            $('#question').val('');
-                            $(".button-send").css("background","#6c757d");
-                            $(".button-send").css("color","#ffffff");
-                		    $(".button-send").css("cursor","not-allowed");
-                		    $(".button-send").css("pointer-events","none");
-                		    $(".chatBoxExample-list").css("cursor","pointer");
-    		                $(".chatBoxExample-list").css("pointer-events","auto");
-    		                $(".chatBoxStop").css("background","#f3f4f6");
-    		                $(".chatBoxStop").css("color","#666666");
-    		                $(".chatBoxStop").css("pointer-events","none");
-    		                $(".chatBoxStop").css("cursor","not-allowed");
-    		                //获取最终的ai回复
-    		                if(stopTime == chatTime){
-                                var aiReplay = $("#chatTime"+chatTime).text();
-                                addMessage('assistant', aiReplay);
-                                console.log('当前对话记录:', JSON.stringify(conversations, null));
-    		                }
-                            evtSource.close();
-                            //还原推理状态为0
-                            working = 0;
-                            $('#doc').text('暂无质控任务');
-                            $(".chatBoxExample-list").css("background","#212121");
-                            $('#EMOON-E1').fadeIn();
-                            $('#EMOON-E2').fadeOut();
-                            $('.chatBoxExample-list').removeClass('color-flash');
-                            $(".chatBoxExample-list").removeAttr("style").addClass("chatBoxExample-list");
-                            endingNum = 0;
-                            zhikong = 0;
-                            
-                        });
-                        // 处理常规消息(保持原有逻辑)
-                        evtSource.onmessage = function(e) {
-                            try {
-                                const data = JSON.parse(e.data);
-                                if (data.choices &&data.choices[0] &&data.choices[0].delta &&data.choices[0].delta.content){
-                                    var reply = data.choices[0].delta.content;
-                                    // console.log(reply);
-                                    //首次打开去掉原始设置的“思考中...”
-                                    if(wordTime == 1){
-                                        //首次加载第一条信息,新增think的div
-                                        // document.getElementById("chatTime"+chatTime).innerHTML = '<div class="chat-think">「思考过程」</div>';
-                                        
-                                        document.getElementById("chatTime"+chatTime).innerHTML =  `
-                                                <div class="think-toggle">
-                                                    <div id = "`+msg+`"class="think-header" style="display:none" >「思考过程」</div>
-                                                    <div id = "think-content-`+msg+`" class="think-content" style="display:none"></div>
-                                                </div>
-                                            `;
-                                        wordTime += 1;
-                                        
-                                    }
-                                    //输出正文
-                                    document.getElementById("chatTime"+chatTime).innerHTML += formatContent(data.choices[0].delta.content);
-                                    //动态滚动页面
-                                    if (autoScroll) {
-                                        outputEl.scrollTo({
-                                            top: outputEl.scrollHeight,
-                                            behavior: 'smooth' // 平滑滚动
-                                        });
-                                    }
-                                    if(endingNum == 1){
-                                        $(`#`+msg).css("display", "block");
-                                       
-                                    }
-                                }
-                            } catch (err) {
-                                console.error("JSON解析失败:", err);
-                            }
-                        };
-                        // 新增end事件监听
-                        evtSource.addEventListener('end', function(e) {
-                            console.log("流式传输正常结束:", e.data);
-                            evtSource.close(); // 主动关闭连接
-                            
-                            // 关键优化:立即复位并触发队列推进,消除3-4秒延迟
-                            working = 0;
-                            try { if (typeof processNext === 'function') { processNext(); } } catch(e) {}
-                            
-                            if (zhikong === 1) { // 只有质控任务才发送
-                                    sendRuleKeyword(askInfoId);
-                                }
-                            //  $.ajax({
-                            //     async: true,
-                            //     type: "post",  //数据提交方式(post/get)
-                            //     url: '{$commonURL}'+'/index/roleindex1',  //提交到的url
-                            //     data: {
-                            //         'askInfoId':askInfoId,
-                                    
-                            //     },//提交的数据
-                            //     dataType: "json",//返回的数据类型格式
-                            //     success: function(msg){
-                            //           console.log(askInfoId+"==================="); 
-                            //     }
-                            // })
-                            var answer = document.getElementById("chatTime"+chatTime).textContent;
-                            
-                            // var divStr = '<div id ="chataccept"><span class="accept" id="accept-1">发送给患者</span></div>';
-                            
-                            if(answer == '思考中...'){
-                                document.getElementById("chatTime"+chatTime).innerHTML += '模型网络中断!';
-                            }
-                            //恢复对话窗口和发送按钮状态
-                            // $('#chataccept').replaceWith(divStr);
-                            $("#question").prop("disabled", false);
-                            $('#question').val('');
-                            $(".button-send").css("background","#6c757d");
-                            $(".button-send").css("color","#ffffff");
-                		    $(".button-send").css("cursor","not-allowed");
-                		    $(".button-send").css("pointer-events","none");
-                		    $(".chatBoxExample-list").css("cursor","pointer");
-    		                $(".chatBoxExample-list").css("pointer-events","auto");
-    		                $(".chatBoxStop").css("background","#f3f4f6");
-    		                $(".chatBoxStop").css("color","#666666");
-    		                $(".chatBoxStop").css("pointer-events","none");
-    		                $(".chatBoxStop").css("cursor","not-allowed");
-    		                //获取最终的ai回复
-                            var aiReplay = $("#chatTime"+chatTime).text();
-                            addMessage('assistant', aiReplay);
-                            console.log('当前对话记录:', JSON.stringify(conversations, null));
-                            // 状态已在上方提前复位
-                            $('#doc').text('暂无质控任务');
-                            $(".chatBoxExample-list").css("background","#212121");
-                            $('#EMOON-E1').fadeIn();
-                            $('#EMOON-E2').fadeOut();
-                            $('.chatBoxExample-list').removeClass('color-flash');
-                            $(".chatBoxExample-list").removeAttr("style").addClass("chatBoxExample-list");
-                            endingNum = 0;
-                            zhikong = 0;
-                        }, false);
-                        // 鉴定请求接口权限
-                        evtSource.addEventListener('verify', function(e) {
-                            console.log("参数验证失败:", e.data);
-                            evtSource.close(); // 主动关闭连接
-                            
-                            // 立即复位并触发队列推进
-                            working = 0;
-                            try { if (typeof processNext === 'function') { processNext(); } } catch(e) {}
-                            
-                            document.getElementById("chatTime"+chatTime).innerHTML = '模型参数不正确,请查看医梦AI开放平台接入文档!';
-                             //恢复对话窗口和发送按钮状态
-                            $("#question").prop("disabled", false);
-                            $('#question').val('');
-                            $(".button-send").css("background","#6c757d");
-                            $(".button-send").css("color","#ffffff");
-                		    $(".button-send").css("cursor","not-allowed");
-                		    $(".button-send").css("pointer-events","none");
-                		    $(".chatBoxExample-list").css("cursor","pointer");
-    		                $(".chatBoxExample-list").css("pointer-events","auto");
-    		                $(".chatBoxStop").css("background","#f3f4f6");
-    		                $(".chatBoxStop").css("color","#666666");
-    		                $(".chatBoxStop").css("pointer-events","none");
-    		                $(".chatBoxStop").css("cursor","not-allowed");
-    		                //获取最终的ai回复
-                            var aiReplay = $("#chatTime"+chatTime).text();
-                            addMessage('assistant', aiReplay);
-                            console.log('当前对话记录:', JSON.stringify(conversations, null));
-                            // 状态已在上方提前复位
-                            $('#doc').text('暂无质控任务');
-                            $(".chatBoxExample-list").css("background","#212121");
-                            $('#EMOON-E1').fadeIn();
-                            $('#EMOON-E2').fadeOut();
-                            $(".chatBoxExample-list").removeAttr("style").addClass("chatBoxExample-list");
-                            endingNum = 0;
-                            zhikong = 0;
-                        }, false);
-                        // 错误处理优化
-                        evtSource.onerror = function(e) {
-                            evtSource.close();
-                            
-                            // 立即复位并触发队列推进
-                            working = 0;
-                            try { if (typeof processNext === 'function') { processNext(); } } catch(e) {}
-                            
-                            if (e.eventPhase === EventSource.CLOSED) {
-                                console.log("连接已正常关闭");
-                                //当模型网络中断时
-                                document.getElementById("chatTime"+chatTime).innerHTML = "模型请求超时!";
-                                $("#question").prop("disabled", false);
-                                $('#question').val('');
-                                $(".button-send").css("background","#6c757d");
-                                $(".button-send").css("color","#ffffff");
-                    		    $(".button-send").css("cursor","not-allowed");
-                    		    $(".button-send").css("pointer-events","none");
-                    		    $(".chatBoxExample-list").css("cursor","pointer");
-    		                    $(".chatBoxExample-list").css("pointer-events","auto");
-    		                    $(".chatBoxStop").css("background","#f3f4f6");
-    		                    $(".chatBoxStop").css("color","#666666");
-    		                    $(".chatBoxStop").css("pointer-events","none");
-    		                    $(".chatBoxStop").css("cursor","not-allowed");
-                    		    //动态滚动页面
-                                if (autoScroll) {
-                                    outputEl.scrollTo({
-                                        top: outputEl.scrollHeight,
-                                        behavior: 'smooth' // 平滑滚动
-                                    });
-                                }
-                                //获取最终的ai回复
-                                var aiReplay = $("#chatTime"+chatTime).text();
-                                addMessage('assistant', aiReplay);
-                                console.log('当前对话记录:', JSON.stringify(conversations, null));
-                            } else {
-                                console.error("连接异常:", e);
-                            }
-                            // 状态已在上方提前复位
-                            $('#doc').text('暂无质控任务');
-                            $(".chatBoxExample-list").css("background","#212121");
-                            $('#EMOON-E1').fadeIn();
-                            $('#EMOON-E2').fadeOut();
-                            $('.chatBoxExample-list').removeClass('color-flash');
-                            $(".chatBoxExample-list").removeAttr("style").addClass("chatBoxExample-list");
-                            endingNum = 0;
-                            zhikong = 0;
-                        };
-                    }
-                })
-            });
-            
-            //chat的示例问题拖动事件
-            (function() {
-                const container = document.getElementById('scrollContainer');
-                let isDragging = false;
-                let startX;
-                let scrollLeft;
-                // 桌面端事件
-                container.addEventListener('mousedown', (e) => {
-                    isDragging = true;
-                    container.classList.add('dragging');
-                    startX = e.pageX - container.offsetLeft;
-                    scrollLeft = container.scrollLeft;
-                });
-                container.addEventListener('mouseleave', () => {
-                    if (isDragging) {
-                        isDragging = false;
-                        container.classList.remove('dragging');
-                    }
-                });
-                container.addEventListener('mouseup', () => {
-                    if (isDragging) {
-                        isDragging = false;
-                        container.classList.remove('dragging');
+                $contentlines = trim(substr($line, 6));
+                $jsonline = json_decode($contentlines, true);
+                $jsoncontent = $jsonline['choices'][0]['delta']['content'];
+                if (($jsoncontent == "</") || ($jsoncontent == 'answer') || ($jsoncontent ==  "。<") || ($jsoncontent == ">") || ($jsoncontent == "<")) {
+                    $output = 'data: {"id":"chatcmpl-1747186801165865728","object":"chat.completions.chunk","created":1747186801,"model":"merge","choices":[{"index":0,"finish_reason":null,"delta":{"role":"assistant","content":""}}]}'. "\n\n";
+
+                    // echo $ouputs."\n";
+                    // $output =  "event: end\ndata: Stream ended\n\n";
+                }
+                elseif($jsonline['choices'][0]['finish_reason'] === 'stop'){
+                    // $output =  "event: end\ndata: Stream ended\n\n";
+                    if($thinkid == null && $zhikong == 1){
+                        $output = 'data: {"id":"chatcmpl-1747186801165865728","object":"chat.completions.chunk","created":1747186801,"model":"merge","choices":[{"index":0,"finish_reason":null,"delta":{"role":"assistant","content":"ending"}}]}'. "\n\n";
+                    }else{
+                        $output = 'data: {"id":"chatcmpl-1747186801165865728","object":"chat.completions.chunk","created":1747186801,"model":"merge","choices":[{"index":0,"finish_reason":null,"delta":{"role":"assistant","content":""}}]}'. "\n\n";
                     }
-                });
-                container.addEventListener('mousemove', (e) => {
-                    if (!isDragging) return;
-                    e.preventDefault();
-                    const x = e.pageX - container.offsetLeft;
-                    const walk = (x - startX) * 2; // 滚动速度系数
-                    container.scrollLeft = scrollLeft - walk;
-                });
-            })();
-            
-            //点击input 跳转固定的位置
-            var device = '{$device}';
-            if(device == 'pc'){
-                // $('#question').on('click', function() {
-                //     this.focus();
-                //     var targetPosition = $('#inputClickJump').offset().top-120;
-                //     $('html, body').animate({
-                //         scrollTop: targetPosition
-                //     }, 'slow');
-                // });
-            }
-            if(device == 'phone'){
-                var mobileType = '{$mobileType}';
-                if(mobileType == 'ios'){
-                    var windowHeight = $(window).height(); // 获取窗口高度
-                    jumpHeight = windowHeight/4;
-                    $('#question').on('touchstart', function() {
-                        this.focus();
-                        var targetPosition = $('#inputClickJump').offset().top+jumpHeight;
-                        $('html, body').animate({
-                            scrollTop: targetPosition
-                        }, 'slow');
-                    });
-                    $('#question').on('touchend', function() {
-                        this.focus();
-                        var targetPosition = $('#inputClickJump').offset().top+jumpHeight;
-                        $('html, body').animate({
-                            scrollTop: targetPosition
-                        }, 'slow');
-                    });
-                }
-            }
-            
-            //质控点击事件存储
-            $(document).ready(function() {
-                //质控采纳点击事件
-                $(document).on('click', '.accept', function() {
-                    // 获取当前点击元素的id
-                    var acceptId0 = $(this).attr('id');
-                    var acceptId1 = updateSuffixRegex(acceptId0);
-                    $("#"+acceptId0).css("color","#666666");
-    		        $("#"+acceptId0).css("cursor","not-allowed");
-    		        $("#"+acceptId0).css("pointer-events","none");
-    		        $("#"+acceptId0).text('已采纳');
-    		        var attitudeId0 = acceptId0.slice(6);
-    		        $("#refuse"+attitudeId0).fadeOut();
-    	           
-    	           
-    	            $("#"+acceptId1).css("color","#666666");
-    		        $("#"+acceptId1).css("cursor","not-allowed");
-    		        $("#"+acceptId1).css("pointer-events","none");
-    		        $("#"+acceptId1).text('已采纳');
-    		        var attitudeId1 = acceptId1.slice(6);
-    		        $("#refuse"+attitudeId1).fadeOut();
-                    $.ajax({
-                        async: false,
-                        type: "post",  //数据提交方式(post/get)
-                        url: '{$commonURL}'+'/Quality/attitude',  //提交到的url
-                        data: {
-                            'attitude':acceptId1,
-                            'reason':'',
-                        },//提交的数据
-                        dataType: "json",//返回的数据类型格式
-                        success: function(msg){
-                            
-                        }
-                    })
-                });
-                //质控不采纳点击事件
-                let refuseId0="";
-                let refuseId1="";
-                //质控不采纳点击事件
-                $(document).on('click', '.refuse', function() {
-                    $(".alertBox").fadeIn();
-                    // 获取当前点击元素的id
-                    refuseId0 = $(this).attr('id');
-                    refuseId1 = updateSuffixRegex(refuseId0);
                     
-                });
-                
-                $(document).on('click', '.alertBoxButton', function() {
-                    var reason = $("#alertBoxInput").val();
-                    if(reason){
-                        var attitudeId0 = refuseId0.slice(6);
-                        var attitudeId1 = refuseId1.slice(6);
-                        $("#accept"+attitudeId0).css("color","#666666");
-        		        $("#accept"+attitudeId0).css("cursor","not-allowed");
-        		        $("#accept"+attitudeId0).css("pointer-events","none");
-        		        $("#accept"+attitudeId0).text('拒绝采纳');
-        		        $("#"+refuseId0).fadeOut();
-        		     
-        		     
-        		
-                        $("#accept"+attitudeId1).css("color","#666666");
-        		        $("#accept"+attitudeId1).css("cursor","not-allowed");
-        		        $("#accept"+attitudeId1).css("pointer-events","none");
-        		        $("#accept"+attitudeId1).text('拒绝采纳');
-        		        $("#"+refuseId1).fadeOut();
-                        $.ajax({
-                            async: false,
-                            type: "post",  //数据提交方式(post/get)
-                            url: '{$commonURL}'+'/Quality/attitude',  //提交到的url
-                            data: {
-                                'attitude':refuseId1,
-                                'reason':reason,
-                            },//提交的数据
-                            dataType: "json",//返回的数据类型格式
-                            success: function(msg){
-                                $(".alertBox").fadeOut();
-                                $("#alertBoxInput").val("");
-                            }
-                        })
-                    }
-                    else{
-                        alert('不采纳原因不能为空');
-                    }
-                });
-                
-            });
-            function updateSuffixRegex(str) {
-              return str.replace(/-0$/, "-1"); // 只替换结尾的-0
-            }
-            //websocket
-            var wsInformation = '';
-            var socket = new WebSocket("{$commonWebsocket}");
- 
-            socket.onopen = function(event) {
-                console.log("Connected to WebSocket server");
-            };
-            
-            // 全局状态管理
-            const messageQueue = [];      
-            let isProcessing = false;     
-            let currentInterval = null;  
-            let currentTimeout = null;   
-            let isStopped = false; 
-            
-            //创建全局的ragId
-            var ragId = '';
-            var mcpId = "";
-            const tokenString = [];
-            socket.onmessage = function(event) {
-                try {
-                    const data = JSON.parse(event.data);
-                    if(data.ragId != ''){
-                        ragId = data.ragId;
-                    }
-                    // 消息始终入队(即使已暂停)
-                    if (data.user === "{$user}") { 
-                        messageQueue.push(data);
-                        renderQualityData(messageQueue);
-                        
-                        // 仅当未暂停且空闲时触发处理
-                        if (!isStopped && !isProcessing) processNext(); 
-                    }
-                } catch (e) {
-                    console.error("消息解析失败:", e);
-                }
-            };
-            var firstzero = 0;
-            // 处理下一条消息
-            function processNext() {
-                 console.log("=== processNext调用 ===");
-                console.log("messageQueue.length:"+messageQueue.length);
-                console.log("isProcessing:"+isProcessing);
-                if(isProcessing && messageQueue.length === 0){
-                    if(firstzero === 1 ){
-                     $('#emrLoadingOverlay').css('display', 'none');
-                     const button = document.getElementById('qualityControlTrigger');
-                     button.click();
-                        
-                    }
-                     firstzero = 1;
-                }
-                if (isStopped || messageQueue.length === 0) {
-                    isProcessing = false;
-                    return;
-                }
-                updateQueueStatus();
-               
-                renderQualityData(messageQueue);
-                isProcessing = true;
-                const currentMsg = messageQueue[0]; // 不立即 shift,只取队列第一个元素
-                clearIntervals();
-                currentInterval = setInterval(() => {
-                    if (typeof working !== 'undefined' && working !== 1) {
-                        clearIntervals();
-                        executeBusinessLogic(currentMsg);
-                        removeMessageByToken(currentMsg["token"]);
-                        processNext();
-                    } else if (working === 0) {
-                        clearIntervals();
-                        console.log("working 状态中断,消息保留在队列中");
-                        isProcessing = false; // 重置状态,允许后续重试
-                        processNext(); // 直接继续处理(当前消息仍留在队列中)
+                    //完成输出后触发全部回复存储进入数据库
+                    global $token;
+                    global $urlCommon;
+                    $dataReply['token'] = $token;
+                    $dataReply['reply'] = $reply;
+                    //将数据发送至数据库
+                    $curlReplay = curl_init();
+            	    curl_setopt($curlReplay, CURLOPT_URL, $urlCommon.'/Apis/reply');
+            	    curl_setopt($curlReplay, CURLOPT_SSL_VERIFYPEER, FALSE);
+            	    curl_setopt($curlReplay, CURLOPT_SSL_VERIFYHOST, FALSE);
+            // 	    curl_setopt($curl, CURLOPT_HTTPHEADER,$headers);
+                    if ($json) {
+                        curl_setopt($curlReplay,CURLOPT_HTTPHEADER,[
+                            "Content-Type: application/json"
+                        ]);
+                        curl_setopt($curlReplay, CURLOPT_POST, TRUE);
+                        curl_setopt($curlReplay,CURLOPT_POSTFIELDS,json_encode($dataReply));
+                    }else {
+                        if (!empty($dataReply)) {
+                            curl_setopt($curlReplay, CURLOPT_POST, TRUE);
+                            curl_setopt($curlReplay, CURLOPT_POSTFIELDS,$dataReply);
+            // 	        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
+                        }
                     }
-                }, 50);
-            
-                currentTimeout = setTimeout(() => {
-                    clearIntervals();
-                    console.log("处理超时,消息重新入队");
-                    messageQueue.push(currentMsg); // 超时后重新入队
-                    isProcessing = false;
-                    processNext();
-                }, 120000);
-            }
-            
-            // 新增:一键停止函数
-            function stopAllProcessing() {
-                isStopped = true;         // 设置暂停标识
-                clearIntervals();         // 立即停止当前处理
-                isProcessing = false;     // 重置处理状态
-                console.log("已暂停队列处理,新消息仍会入队");
-            }
-            
-            // 新增:恢复处理函数
-            function resumeProcessing() {
-                if (isStopped) {
-                    isStopped = false;
-                    console.log("恢复队列处理");
-                    processNext();  // 手动触发处理流程
-                }
-            }
-            
-            // 公共清理方法
-            function clearIntervals() {
-                if (currentInterval) {
-                    clearInterval(currentInterval);
-                    currentInterval = null;
-                }
-                if (currentTimeout) {
-                    clearTimeout(currentTimeout);
-                    currentTimeout = null;
-                }
-            }
-            
-            // 新增:清除所有队列并重置状态(保持接收能力)
-            function clearAllQueues() {
-                messageQueue.length = 0;        // 清空消息队列
-                clearIntervals();               // 停止所有定时器
-                isProcessing = false;          // 强制重置处理状态
-                isStopped = false;              // 可选:确保处理不被暂停(根据需求决定)
-                console.log("队列已清空,可接收新消息");
-                console.log("messageQueue.length:"+messageQueue.length);
-                $("#lineStatus").text('暂停队列');
-                processNext();
-                
-            
-            }
-        
-            // 执行业务逻辑(原 UI 操作)
-            function executeBusinessLogic(msg) {
-                $('#EMOON-E1').fadeOut();
-                $('#EMOON-E2').fadeIn();
-                $('#doc').text(`正在读取病历并质控: ${msg.name} 的 ${msg.doc}`);
-                $('#question').val(`[EMR系统请求] 请质控 [${msg.name}] 的 [${msg.doc}] 。`);
-                wsInformation = msg.token;
-          
-                $("#askButton").trigger('click'); // 规范的事件触发方式
-                $(".chatBoxExample-list")
-                    .css("background", "#3a3a3a")
-                    .css("width", "100%")
-                    .css("text-align", "left")
-                    .css("border-radius", "20px 0px 0px 20px")
-                    .css("pointer-events", "none")
-                    .addClass('color-flash');
-            }
-            
-            //监听lineStatus点击状态
-            $("#lineStatus").click(function(){
-                var lineStatus = $("#lineStatus").text();
-                if(lineStatus == '暂停队列'){
-                    stopAllProcessing();
-                    $("#lineStatus").text('继续队列');
+            	    curl_setopt($curlReplay, CURLOPT_RETURNTRANSFER,true);
+            	    curl_exec($curlReplay);
+            	    curl_close($curlReplay);
                 }
                 else{
-                    resumeProcessing();
-                    $("#lineStatus").text('暂停队列');
+                    $output = $line . "\n\n"; 
                 }
-            })
-     
-            socket.onclose = function(event) {
-                console.log("Disconnected from WebSocket server");
-            };
-     
-            function sendMessage() {
-                var message = document.getElementById("message").value;
-                socket.send(message);
-            }
-            
-            $(".alertBoxBackground").click(function(){
-                $(".alertBox").fadeOut();
-                $("#alertBoxInput").val("");
-            })
-            function toggleDropdown() {
-                const dropdown = document.getElementById("dropdown");
-                dropdown.style.display = dropdown.style.display === "block" ? "none" : "block";
-            }
-            //选择对应的知识库
-            function selectOption(value, text) {
-                document.getElementById("selected-text").innerText = text;
-                document.getElementById("dropdown").style.display = "none";
-                ragId = value;
-            }
-            
-            function toggleagentdown() {
-                const agentdown = document.getElementById("agentdown");
-                agentdown.style.display = agentdown.style.display === "block" ? "none" : "block";
-            }
-            //选择对应的智能体
-            function selectagent(value, text) {
-                document.getElementById("selected-agenttext").innerText = text;
-                document.getElementById("agentdown").style.display = "none";
-                mcpId = value;
-            }
-            //下拉思考过程
-            document.addEventListener('click', function(e) {
-                if (e.target.closest('.think-header')) {
-                    
-                    stopAllProcessing();
-                    const header = e.target.closest('.think-header');
-                    const toggle = e.target.closest('.think-toggle');
-                    const think_token = header.id;
-                    
-                    toggle.classList.toggle('active');
-                    const content = toggle.querySelector('.think-content');
-                    const isExpanded = toggle.classList.contains('active');
-                  
-                    content.style.display = toggle.classList.contains('active') ? 'block' : 'none';
-                    
-                    if (isExpanded && !toggle.dataset.sseInitialized) {
-                        var ssethinkUrl = '{$commonOpenURLSSE}?token='+think_token+'&ragId='+ragId+'&mcpid='+mcpId+'&thinkid=1';
-                        //sse流媒体对话
-                        var evtSourcethink = new EventSource(ssethinkUrl);
-                        toggle.dataset.sseInstance = evtSourcethink;
-                        //停止对话按钮
-                        var stopTime = 0;
-                        // 处理常规消息(保持原有逻辑)
-                        evtSourcethink.onmessage = function(e) {
-                            try {
-                                const data = JSON.parse(e.data);
-                                if (data.choices &&data.choices[0] &&data.choices[0].delta &&data.choices[0].delta.content){
-                                    var reply = data.choices[0].delta.content;
-    
-                                    //输出正文
-                                    document.getElementById("think-content-"+think_token).innerHTML += formatContent(data.choices[0].delta.content);
-                                }
-                            } catch (err) {
-                                console.error("JSON解析失败:", err);
-                            }
-                        };
-                        // 新增end事件监听
-                        evtSourcethink.onerror = function(e) {
-                            console.log("SSE连接终止:", e);
-                            evtSourcethink.close();
-                            var lineStatus = $("#lineStatus").text();
-                            if(lineStatus == '暂停队列'){
-                                setTimeout(function() {
-                                    resumeProcessing();
-                                }, 2500);
-                            }
-
-                        };
-                    
-                        // 标记已初始化(后续点击不再请求)
-                        toggle.dataset.sseInitialized = "true";
-                    }
-                }
-            });
-            
-            document.addEventListener('DOMContentLoaded', function() {
-                const sidebarTrigger = document.getElementById('sidebarTrigger');
-                const sidebarOverlay = document.getElementById('sidebarOverlay');
-                const sidebarClose = document.getElementById('sidebarClose');
-                
-                // 打开侧边栏
-                sidebarTrigger.addEventListener('click', function() {
-                    sidebarOverlay.classList.add('active');
-                    document.body.style.overflow = 'hidden'; // 防止背景滚动
-                    renderQualityData(messageQueue);
-                });
+                //   $output = $line . "\n\n"; 
+                echo $output;
                 
-                // 关闭侧边栏
-                sidebarClose.addEventListener('click', function() {
-                    sidebarOverlay.classList.remove('active');
-                    document.body.style.overflow = ''; // 恢复滚动
-                });
-                
-                // 点击 overlay 背景关闭
-                sidebarOverlay.addEventListener('click', function(e) {
-                    if (e.target === sidebarOverlay) {
-                        sidebarOverlay.classList.remove('active');
-                        document.body.style.overflow = '';
+                //将回复数据存储入$reply
+                if($thinkid == null){
+                    $outputJson = substr($output,6);
+                    if(($modelId == 9) || ($modelId == 7) || ($modelId == 4) || ($modelId == 10) || ($modelId == 12) || ($modelId == 15)){
+                        $outputJson = json_decode($outputJson);
+                        $outputJson = $outputJson->choices[0]->delta->content;
+                        if($outputJson){
+                            $outputJson = json_encode($outputJson,JSON_UNESCAPED_UNICODE);
+                            $outputJson = str_replace('"', '', $outputJson);
+                        }
                     }
-                });
-            });
-            var qualityControlname ="";
-            function renderQualityData(data) {
-                if (!data || data.length === 0) {
-                    var divStr = '  <div class="sidebar-body" id="qualityControlList"><div class="no-data">暂无质控问题</div></div>';
-                    $('#qualityControlList').replaceWith(divStr);
-                    return;
                 }
-         
-                    $('#qualityControlList').empty();
-    
-                // // 添加统计信息
-                // $('#qualityControlList').append(`<div class="stats">共发现 ${data.length} 个质控问题</div>`);
-                // 渲染问题项
-                data.forEach(function(item) {
-                    if (qualityControlname != item.doc) {
-                        $('#qualityControlList').append(`<div id="${item.doc}" class="sidebar-tools">${item.doc}</div>`);
-                    }
-                    // $('#qualityControlList').append(`<div id="${item.token}" class="qualityControlToken">规则:${item.rule}</div>`);
-                    qualityControlname = item.doc;
-                });
-                qualityControlname = data[data.length-1]["doc"];
-            }
-            $(document).ready(function() {
-                addQualityControlTokenClickHandler();
-            });
-            
-            function addQualityControlTokenClickHandler() {
-                // 使用事件委托处理动态添加的元素
-                $(document).on('click', '.sidebar-tools', function() {
-                    // 获取被点击元素的id
-                    var doc = this.id;
-                    // var clickedItem = messageQueue.find(item => item.token === tokenId);
-                    var docType = doc;
-                    console.log('点击的质控问题ID:', doc);
-                    reorderByDocType(messageQueue, docType);
-                    renderQualityData(messageQueue);
-                });
-            }
-            function moveTokenToFirstInPlace(messageQueue, targetToken) {
-                const targetIndex = messageQueue.findIndex(item => item.token === targetToken);
-                if (targetIndex === -1) return;
-                
-                const targetItem = messageQueue[targetIndex];
-                messageQueue.splice(targetIndex, 1);
-                messageQueue.unshift(targetItem);
-                
-            }
-            
-            function reorderByDocType(messageQueue, docType) {
-                stopAllProcessing();
-                // 找出所有匹配的项
-                const matchingItems = messageQueue.filter(item => item.doc === docType);
-                const nonMatchingItems = messageQueue.filter(item => item.doc !== docType);
-                
-                // 清空原数组并重新填充
-                messageQueue.length = 0;
-                messageQueue.push(...matchingItems, ...nonMatchingItems);
-                
-                console.log('重新排序后的messageQueue:', messageQueue);
-                console.log(isStopped);
-                if (isStopped) {
-                    resumeProcessing();
-                }
-            }
-            //队列根据token删除已经质控的数据
-            function removeMessageByToken(token) {
-                const index = messageQueue.findIndex(item => item.token === token);
-                if (index !== -1) {
-                    messageQueue.splice(index, 1);
-                    return true; // 删除成功
-                }
-                return false; // 未找到对应token
+                $reply .= $outputJson; // 捕获输出内容
             }
+            ob_flush();
+            flush();
+        }
+    }
+    return strlen($data);
+});
 
-            var initialQueueSize = 0;
-            // 改进的队列状态更新函数
-            function updateQueueStatus() {
-                const queueCount = messageQueue.length;
-                if(initialQueueSize < queueCount){
-                    initialQueueSize = queueCount;
-                }
-                document.getElementById('queueCount').textContent = queueCount;
-                // 更新进度条
-                if ( initialQueueSize &&  initialQueueSize> 0) {
-                    const progress = Math.max(0, 100 - (queueCount / initialQueueSize * 100));
-                    document.getElementById('queueProgress').style.width = progress + '%';
-                }
-              
-            }
-            
-           
-            
-            
-            $("#closeModal").click(function() {
-                $("#modalOverlay").fadeOut(200); // 淡出隐藏弹窗
-            });
-            
-            // 关闭弹窗 - 点击模态框外部
-            $("#modalOverlay").click(function(e) {
-                // 只有当点击的是模态框背景(不是内容区域)时才关闭
-                if ($(e.target).closest(".modal-container").length === 0) {
-                    $("#modalOverlay").fadeOut(200);
-                }
-            });
-            
-            // 可以添加ESC键关闭弹窗的功能
-            $(document).keydown(function(e) {
-                if (e.key === "Escape" && $("#modalOverlay").is(":visible")) {
-                    $("#modalOverlay").fadeOut(200);
-                }
-            });
-            
-            $(document).ready(function() {
-                //监听lineStatus点击状态
-            $("#qualityControlTrigger").click(function(){
-                
-                if(messageQueue.length !== 0){
-                     $('#emrLoadingOverlay').css('display', 'flex');
-                     updateQueueStatus();
-                     return;
-                }
-                $.ajax({
-                    async: false,
-                    type: "post",  //数据提交方式(post/get)
-                    url: '{$commonURL}'+'/Send/qualityControlTrigger',  //提交到的url
-                    data: {
-                        'token':tokenString,
-                    },//提交的数据
-                    dataType: "json",//返回的数据类型格式
-                    success: function(msg){
-                        
-                        const medicalData = JSON.parse(msg);
-                        var typename = "";
-                        // 先清空下拉框,只保留第一个默认选项
-                        $('#typeSelector').empty().append('<option value="medicalRecordType">请选择病历类型...</option>');
-                        var existingOptions = {};
+// 错误处理
+curl_setopt($ch, CURLOPT_TIMEOUT, 86400);
+curl_setopt($ch, CURLOPT_FAILONERROR, true);
+
+// 执行请求
+try {
+    curl_exec($ch);
     
-                        for (let i = 0; i < medicalData.length; i++) {
-                            if (medicalData[i]["typename"] && medicalData[i]["typename"] != typename) {
-                                typename = medicalData[i]["typename"];
-                                
-                                // 检查是否已存在该选项
-                                if (!existingOptions[typename]) {
-                                    // 添加选项到下拉框
-                                    $('#typeSelector').append($('<option>', {
-                                        value: typename,
-                                        text: typename
-                                    }));
-                                    
-                                    // 标记该选项已添加
-                                    existingOptions[typename] = true;
-                                }
-                            }
-                        }
-                        
-                        // // 先清空下拉框,只保留第一个默认选项
-                        // $('#typeSelector').empty().append('<option value="">请选择病历类型...</option>');
-                        
-                        // for (let i = 0; i < medicalData.length; i++) {
-                        //     if(medicalData[i]["typename"] != typename){
-                        //         typename = medicalData[i]["typename"];
-                        //         // divStr += '<div class="form-group" data-typename="'+medicalData[i]["typename"]+'" id="formGroup'+medicalData[i]["typename"]+'">'+medicalData[i]["typename"]+'</div>';
-                                
-                        //         // 添加选项到下拉框
-                        //         $('#typeSelector').append($('<option>', {
-                        //             value: medicalData[i]["typename"],
-                        //             text: medicalData[i]["typename"]
-                        //         }));
-                        //     }
-                        // }
-                        // divStr += '</div>';
-                        if ($('#typeSelector option').length > 1) {
-                             $('#typeSelector').val($('#typeSelector option:eq(1)').val()).trigger('change');
-                        }
-                        // $('#formGroup').replaceWith(divStr);
-                        $("#modalOverlay").fadeIn(200);
-                        $('.left-panel, .right-panel').scrollTop(0);
-                        
-                        // 原有div点击事件
-                        // $('#formGroup').on('click', 'div.form-group', function() {
-                        //     var typename = $(this).data('typename');
-                        //     handleDivClick(typename);
-                        // });
-                    }
-                })
+    // 检查HTTP状态码
+    $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+    if ($statusCode !== 200) {
+        echo "event: error\ndata: HTTP Status {$statusCode}\n\n";
+        ob_flush();
+        flush();
+    }
+} catch (Exception $e) {
+    echo "event: error\ndata: " . $e->getMessage() . "\n\n";
+    ob_flush();
+    flush();
+}
+}else{
 
-            });
-                $('#typeSelector').change(function() {
-                    $('.left-panel, .right-panel').scrollTop(0);
-                    var selectedType = $(this).val();
-                    if (selectedType) {
-                        handleDivClick(selectedType);
-                        
-                        // 可选:滚动到对应的div
-                        const targetDiv = $(`#formGroup${selectedType}`);
-                        if (targetDiv.length) {
-                            $('.left-panel').animate({
-                                scrollTop: targetDiv.offset().top - $('.left-panel').offset().top + $('.left-panel').scrollTop()
-                            }, 500);
-                        }
-                    }
-                });
-            });
-         function handleDivClick(typename) {
-            console.log("处理点击事件,typename: ", typename);
-            if(typename == "medicalRecordType"){
-                return;
-            }
-            $.ajax({
-                async: false,
-                type: "post",
-                url: '{$commonURL}'+'/Send/ControlResultScore',
-                data: {
-                    'token': tokenString,
-                    'typename': typename,
-                },
-                dataType: "json",
-                success: function(msg) {
-                    const msgData = JSON.parse(msg);
-                    console.log(msgData);
-                    var divStr = '<div class="preview-area" id="previewArea">';
-                    const medicalContent = msgData["content"]
-                        .replace(/\\n/g, '<br>')
-                        .replace(/\n/g, '<br>')
-                        .replace(/\s{2,}/g, '<br>')
-                        .replace(/brbr/g, '<br>')
-                        .replace(/\\\//g, '/');
-                    
-                    var divContentStr = '<div class="form-group" id="formGroup"><div class="form-group" data-content="'+typename+'" id="formGroup'+typename+'">'+medicalContent+'</div></div>';
-                    
-                   
-                    var deductionrulescore = ' <div class = "quality-control-score" id="qualitycontrolscorediv">质控得分:<strong id="qualitycontrolscore">'+msgData["deductionrulescore"]+'</strong>分</div>';
-                    $('#qualitycontrolscorediv').replaceWith(deductionrulescore);
-                    if (msgData["reply"] != null) {
-                        const replyCount = Object.keys(msgData["reply"]).length;
-                        for (let i = 1; i <= replyCount; i++) {
-                        
-                            let content;
-                            if(msgData["keywords"][i] == null   || msgData["keywords"][i] == "null" ||msgData["keywords"][i] == ""){
-                                msgData["keywords"][i] = "全文";
-                            }
-                            console.log("msgData[keywords][i]"+msgData["keywords"][i]);
-                            if(msgData["rulescore"][i]>= 5){
-                                if(msgData["accept"][i] == 0){
-                                    
-                                
-                                   content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'">采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'">不采纳</span></div>')
-                                        // 处理【规则名称】部分
-                                        .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-tall-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-tall-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-tall-section"><strong>【不通过原因】:</strong>$1</div>')
-                                           // 处理【不通过原因】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                       
-                                }
-                                else if(msgData["accept"][i] == 5){
-                                    content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'" style="color: rgb(102, 102, 102); cursor: not-allowed; pointer-events: none;">已采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'" style="display: none;">不采纳</span></div>')
-                                         .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-tall-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-tall-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-tall-section"><strong>【不通过原因】:</strong>$1</div>')
-                                           // 处理【不通过原因】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                       
-                                }
-                                else if(msgData["accept"][i] == 2){
-                                    content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'" style="color: rgb(102, 102, 102); cursor: not-allowed; pointer-events: none;">拒绝采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'" style="display: none;">不采纳</span></div>')
-                                        .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-tall-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-tall-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-tall-section"><strong>【不通过原因】:</strong>$1</div>')
-                                          // 处理【不通过原因】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                }
-                            }
-                            else if(msgData["rulescore"][i] > 1){
-                                if(msgData["accept"][i] == 0){
-                                   content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'">采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'">不采纳</span></div>')
-                                        // 处理【规则名称】部分
-                                        .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-title-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-title-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-title-section"><strong>【不通过原因】:</strong>$1</div>')
-                                          // 处理【不通过原因】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                       
-                                }
-                                else if(msgData["accept"][i] == 5){
-                                    content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'" style="color: rgb(102, 102, 102); cursor: not-allowed; pointer-events: none;">已采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'" style="display: none;">不采纳</span></div>')
-                                         .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-title-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-title-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-title-section"><strong>【不通过原因】:</strong>$1</div>')
-                                          // 处理【不通过原因】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                       
-                                }
-                                else if(msgData["accept"][i] == 2){
-                                    content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'" style="color: rgb(102, 102, 102); cursor: not-allowed; pointer-events: none;">拒绝采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'" style="display: none;">不采纳</span></div>')
-                                        .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-title-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-title-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-title-section"><strong>【不通过原因】:</strong>$1</div>')
-                                         // 处理【不通过原因】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                }
-                            }
-                            else if(msgData["rulescore"][i] > 0){
-                                if(msgData["accept"][i] == 0){
-                                   content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'">采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'">不采纳</span></div>')
-                                        // 处理【规则名称】部分
-                                        .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-low-section"><strong class="rule-section-low">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-low-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-low-section"><strong>【不通过原因】:</strong>$1</div>')
-                                         // 处理【质控结果】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                       
-                                }
-                                else if(msgData["accept"][i] == 5){
-                                    content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'" style="color: rgb(102, 102, 102); cursor: not-allowed; pointer-events: none;">已采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'" style="display: none;">不采纳</span></div>')
-                                         .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-low-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-low-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-low-section"><strong>【不通过原因】:</strong>$1</div>')
-                                         // 处理【质控结果】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                       
-                                }
-                                else if(msgData["accept"][i] == 2){
-                                    content = msgData["reply"][i]
-                                        .replace(/ending/g, '<div class="quality"><span class="accept" id="accept-'+msgData["token"][i]+'-'+endingNum+'" style="color: rgb(102, 102, 102); cursor: not-allowed; pointer-events: none;">拒绝采纳</span><span class="refuse" id="refuse-'+msgData["token"][i]+'-'+endingNum+'" style="display: none;">不采纳</span></div>')
-                                        .replace(/【规则名称】:(.+?)\\n/g, '<div class="rule-low-section"><strong class="rule-section-title">【规则名称】:</strong>$1</div>')
-                                        // 处理【质控结果】部分
-                                        .replace(/【质控结果】:(.+?)\\n/g, '<div class="result-low-section"><strong>【质控结果】:</strong>$1</div>')
-                                        // 处理【不通过原因】部分
-                                        .replace(/【不通过原因】:(.+?)\\n/g, '<div class="reason-low-section"><strong>【不通过原因】:</strong>$1</div>')
-                                         // 处理【质控结果】部分
-                                        .replace(/【规则关键字】:([\s\S]*?)(?=ending|$)/g, '<div class="result-section"><strong>【规则关键字】:</strong>$1</div>')
-                                        // 处理 ending 替换为操作按钮
-                                        .replace(/\\n/g, '<br>')
-                                        // 替换连续空格为换行
-                                        .replace(/\s{2,}/g, '<br>')
-                                        .replace(/\\\//g, '/');
-                                }
-                            }
-                            
-                            if(msgData["keywords"][i] == "无"){
-                                divStr += '<div class="preview-area" data-typename="">'+content+'</div>';
-                            }
-                            else{
-                                divStr += '<div class="preview-area" data-typename="'+msgData["keywords"][i]+'">'+content+'</div>';
-                            }
-                            
-                        }
-                    }
-                    $('#formGroup').replaceWith(divContentStr);
-                    
-                    
-                    divStr += '</div>';
-                    $('#previewArea').replaceWith(divStr);
-                    
-                    $(document).off('click', '.preview-area').on('click', '.preview-area', function() {
-                        // 获取 keyword 的逻辑保持不变
-                        var keyword = $(this).attr('data-typename'); // 使用 attr() 替代 data()
-                        console.log("keyword:", keyword);
-                        
-                        if (!keyword) {
-                            console.warn("未能获取到有效的 keyword,检查 data-typename 属性");
-                            return;
-                        }
-                   
-                        // 1. 移除之前可能存在的所有高亮
-                        $('.form-group').find('.highlight-text').each(function() {
-                            $(this).replaceWith($(this).text());
-                        });
-                        
-                        // 2. 查找所有包含关键词的 form-group 元素
-                        var found = false;
-                        $('.form-group').each(function() {
-                            if (found) return; // 如果已经找到并处理了第一个匹配项,则跳过后续
-                            
-                            var $element = $(this);
-                            var html = $element.html();
-                            
-                            // 3. 如果包含目标文本,则进行高亮处理
-                            if (keyword && html.indexOf(keyword) !== -1) {
-                                // 动态生成正则表达式(转义特殊字符)
-                                var escapedKeyword = escapeRegExp(keyword);
-                                var regex = new RegExp(escapedKeyword, 'g');
-                                var newHtml = html.replace(regex, '<span class="highlight-text">' + keyword + '</span>');
-                                $element.html(newHtml);
-                                
-                                
-                                
-                                // 4. 获取高亮后的元素
-                                var $highlight = $element.find('.highlight-text').first();
-                                
-                                // 5. 滚动到高亮元素的位置(改进的滚动计算)
-                                var $container = $element.closest('.left-panel');
-                                
-                                if ($container.length) {
-                                    // 计算元素相对于容器的位置
-                                    var elementTop = $highlight.offset().top;
-                                    var containerTop = $container.offset().top;
-                                    var containerScrollTop = $container.scrollTop();
-                                    var scrollToPosition = elementTop - containerTop + containerScrollTop - 100;
-                                    
-                                    $container.animate({ scrollTop: scrollToPosition }, {
-                                        duration: 500,
-                                        easing: 'swing',
-                                        complete: function() {
-                                            console.log("滚动完成,位置:", scrollToPosition);
-                                        }
-                                    });
-                                } else {
-                                    // 如果没有容器,滚动整个页面
-                                    $('html, body').animate({
-                                        scrollTop: $highlight.offset().top - 100
-                                    }, {
-                                        duration: 500,
-                                        easing: 'swing',
-                                        complete: function() {
-                                            console.log("页面滚动完成");
-                                        }
-                                    });
-                                }
-                                
-                                found = true; // 标记已找到第一个匹配项
-                                return false; // 退出each循环
-                            }
-                        });
-                        
-                        if (!found) {
-                            console.log("未找到关键词:", keyword);
-                        }
-                        
-                        // 添加高亮样式
-                        $('<style>')
-                            .prop('type', 'text/css')
-                            .html('.highlight-text { background-color: #FF0000; color:#F8F9FA; padding: 2px 4px; border-radius: 3px; }')
-                            .appendTo('head');
-                    });
-                }
-            });
+        @ini_set('output_buffering', 'off');
+        @ini_set('zlib.output_compression', false);
+        while (ob_get_level() > 0) {
+            ob_end_flush();
         }
-
+        ob_implicit_flush(true);
+    
+        // 设置流式响应头
         
-        // 辅助函数:转义正则表达式中的特殊字符
-            function escapeRegExp(string) {
-                return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
-            }
-            
-            $('#emrCloseBtn').click(function() {
-                $('#emrLoadingOverlay').css('display', 'none');
-            });
-            
-            
-            
-            let isRequesting = false;
+        $requestBody = file_get_contents('php://input');
+        $headers = getallheaders();
+        $authorizationHeader = isset($headers['Authorization']) ? $headers['Authorization'] : '';
 
-            function requestOnlineUpdate() {
-                if (isRequesting) return;
-                
-                isRequesting = true;
-                
-                $.ajax({
-                    async: true,
-                    type: "post",
-                    url: '{$commonURL}/His/onlineUpdate',
-                    data: {
-                        'user': urlUser,
-                        'messageQueuelength': messageQueue.length,
-                        'strate': 1,
-                    },
-                    dataType: "json",
-                    timeout: 3000, // 添加超时控制
-                    success: function(msg) {
-                        console.log(msg);
-                    },
-                    error: function(xhr, status, error) {
-                        console.error('请求失败:', error);
-                    },
-                    complete: function() {
-                        isRequesting = false;
-                        // 完成后等待1秒再发起下一次请求
-                        setTimeout(requestOnlineUpdate, 1000);
-                    }
-                });
-            }
-            
-            // 启动请求
-            requestOnlineUpdate();
-            function sendFinalRequest() {
-            
-
-                  $.ajax({
-                    async: true,
-                    type: "post",  //数据提交方式(post/get)
-                    url: '{$commonURL}/His/onlineUpdate',  //提交到的url
-                    data: {
-                        'user':urlUser,
-                        'messageQueuelength':0,
-                        'strate':0,
-                    },//提交的数据
-                    dataType: "json",//返回的数据类型格式
-                    success: function(msg){
-                        console.log(msg);
-                    }
-                })
-                
-            }
-            window.addEventListener('beforeunload', function(event) {
-                // 注意:beforeunload 中不能阻止页面关闭,只能发送请求
-                sendFinalRequest();
-            });
+    
+        $reply = '';
+   
+        $RAGdata = [
+            "username" => "test",
+            "password" => "test123"
+        ];
+        // 调用时只需传递非 Content-Type/Accept 的 Header
+        $headers = [
+            'Cache-Control: no-cache',
+            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
+        ];
+        $urlRAG = "http://192.168.10.115:6039/auth/login"; // 替换为实际 URL
+        
+        $id = curlPostRAG($urlRAG, $RAGdata, $headers);
+       
+        $token = $id; // 默认启用 JSON 模式
+        $token = json_decode($token);
+        $token = stdClassObjToArray($token);
+        $token = $token['data']['token'];
+        $url = "http://192.168.10.115:6039/chat/emoonSend"; // 替换成实际接口地址
+        $data = [
+            "messages" => $contentmcp,
+            "model" => "qwen3-32B", //X
+            "temperature" => 0.5, 
+            "top_p" => 1, 
+            "presence_penalty" => 0, 
+            "frequency_penalty" => 0, 
+            "kid" => "", 
+            "chat_type" => 0, 
+            "appId" => "", 
+            "agentId" => $mcp, 
+            "stream" => true
+        ];
+        
+        // 初始化 cURL
+        $ch = curl_init();
+        // 设置 cURL 选项
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // 返回响应数据
+        curl_setopt($ch, CURLOPT_POST, true); // 使用 POST 方法
+        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); // 发送 JSON 数据
+        curl_setopt($ch, CURLOPT_HTTPHEADER, [
+            "Authorization: Bearer " . $token,
+            "Content-Type: application/json" // 声明请求体是 JSON
+        ]);
+   
+    
+        $chatId = 'chat' . uniqid() . bin2hex(random_bytes(8));
+        $created = time();
         
-            // 额外监听 unload 事件作为保险
-            window.addEventListener('unload', function() {
-                sendFinalRequest();
-            });
-            function sendRuleKeyword(askInfoId) {
-                var completeAnswer = $("#chatTime"+chatTime).text();
-                console.log("completeAnswer"+completeAnswer);
-                const keywordMatch = completeAnswer.match(/【规则关键字】:([^\n\r【]*)/);
-                if (keywordMatch && keywordMatch[1]) {
-                    const ruleKeyword = keywordMatch[1].trim();
-                    console.log("ruleKeyword"+ruleKeyword);
-                    if (ruleKeyword) {
-                        $.ajax({
-                            async: true,
-                            type: "post",
-                            url: '{$commonURL}/Send/listkey', // 替换为实际接口
-                            data: {
-                                'ruleKeyword': ruleKeyword,
-                                'askInfoId': askInfoId,
-                            },
-                            dataType: "json",
-                            success: function(response) {
-                                console.log('规则关键字发送成功:', response);
-                            },
-                            error: function(xhr, status, error) {
-                                console.error('规则关键字发送失败:', error);
-                            }
-                        });
-                    }
-                }
-            }
-        </script>
-        <style>
-            .selected-option {
-                height: 30px; /* 调小高度以匹配提示文本 */
-                padding: 0 10px;
-                background: #2a2a2a;
-                border: 1px solid #444;
-                border-radius: 4px;
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-                cursor: pointer;
-                font-size: 14px; /* 调整字体大小 */
-                color: #fff;
-            }
-            
-            .dropdown-options {
-                display: none;
-                position: absolute;
-                width: 100%; /* 与选择框同宽 */
-                overflow-y: auto;        /* 强制垂直滚动条 */
-                overflow-x: hidden;  
-                white-space: nowrap;      /* 禁止换行 */
-                max-height: 200px;
-                background: #333;
-                border: 1px solid #444;
-                z-index: 1000;
-                top: 100%; /* 在选择框下方展开 */
-                left: 0;
-                margin-top: 5px;
-                border-radius: 4px;
-                color: #fff;
-            }
-            
-            .option {
-                width: 100%; 
-                padding: 8px 10px;
-                text-overflow: ellipsis; 
-                overflow: hidden;  
-                white-space: nowrap;
-                word-wrap: break-word;
-                cursor: pointer;
-                font-size: 14px;
-                color: #fff;
-                text-align: left;
-            }
+   
+            // for ($i = 0; $i < count($lines); $i++) {
+            //     echo  $lines[0];
+            // }
+        $lastContent = '';
 
-            
-            .option:hover {
-                background: #0069d9;
-            }
-            
-            #selected-text {
-                white-space: nowrap;
-                overflow: hidden;        /* 隐藏溢出内容 */
-                text-overflow: ellipsis; /* 显示省略号 */
-                flex-grow: 1;
-                color: #fff;
-            }
-            .selected-agent {
-                height: 30px; /* 调小高度以匹配提示文本 */
-                padding: 0 10px;
-                background: #2a2a2a;
-                border: 1px solid #444;
-                border-radius: 4px;
-                display: flex;
-                align-items: center;
-                justify-content: space-between;
-                cursor: pointer;
-                font-size: 14px; /* 调整字体大小 */
-                color: #fff;
-            }
-            
-            .dropdown-agents {
-                display: none;
-                position: absolute;
-                width: 100%; /* 与选择框同宽 */
-                overflow-y: auto;        /* 强制垂直滚动条 */
-                overflow-x: hidden;  
-                max-height: 200px;
-                overflow-y: auto;
-                background: #333;
-                border: 1px solid #444;
-                z-index: 1000;
-                top: 100%; /* 在选择框下方展开 */
-                left: 0;
-                margin-top: 5px;
-                border-radius: 4px;
-                color: #fff;
-            }
-            
-            .agent {
-                width: 100%; 
-                padding: 8px 10px;
-                text-overflow: ellipsis; 
-                overflow: hidden;  
-                white-space: nowrap;
-                word-wrap: break-word;
-                cursor: pointer;
-                font-size: 14px;
-                color: #fff;
-                text-align: left;
-            }
-            
-            .agent:hover {
-                background: #0069d9;
-            }
-            
-            #selected-agenttext {
-                white-space: nowrap;
-                overflow: hidden;
-                text-overflow: ellipsis;
-                flex-grow: 1;
-                color: #fff;
-            }
-            .info {
- 
-                word-break: break-word; /* 长单词换行 */
-            }
-            
-             .think-toggle {
-                cursor: pointer;
-                margin: 10px 0;
-                padding: 5px;
-                border-radius: 5px;
-            }
-            
-            .think-content {
-                padding: 10px;
-                border-left: 2px solid #007bff;
-            }
-            .think-toggle.active .think-header::after {
-                content: " ▲";
-            }
-            .think-toggle:not(.active) .think-header::after {
-                content: " ▼";
-            }
-            .think-header{
-                color: #007bff;
-                margin-bottom: 1rem;
-                text-align: right;
-            }
-            
-           /* 侧边栏触发按钮样式 */
-            .sidebar-trigger {
-                position: fixed;
-                left: 0;
-                top: 50%;
-                transform: translateY(-50%);
-                background: linear-gradient(135deg, #007bff, #0056b3);
-                color: white;
-                padding: 18px 10px;
-                border-radius: 0 12px 12px 0;
-                cursor: pointer;
-                z-index: 998;
-                box-shadow: 3px 3px 15px rgba(0,0,0,0.2);
-                writing-mode: vertical-lr;
-                text-orientation: mixed;
-                opacity: 0.9;
-                transition: all 0.3s ease;
-             
-                letter-spacing: 2px;
-                border: none;
-                outline: none;
-            }
-            
-            .sidebar-trigger:hover {
-                opacity: 1;
-                padding-left: 12px;
-                box-shadow: 4px 4px 20px rgba(0,0,0,0.25);
-            }
-            
-            /* 半屏弹窗样式 */
-            .sidebar-overlay {
-                position: fixed;
-                top: 0;
-                left: -25%;
-                width: 25%;
-                height: 100%;
-                background: rgba(0,0,0,0.3);
-                z-index: 1002;
-                opacity: 0;
-                visibility: hidden;
-                transition: all 0.4s ease;
-            }
-            
-            .sidebar-overlay.active {
-                left: 0;
-                opacity: 1;
-                visibility: visible;
-            }
-            
-            .sidebar-content {
-                position: absolute;
-                right: 0;
-                top: 0;
-                width: 100%;
-                height: 100%;
-                background: #fff;
-                box-shadow: -4px 0 20px rgba(0,0,0,0.15);
-                overflow-y: auto;
-                display: flex;
-                flex-direction: column;
-            }
-            
-            .sidebar-header {
-                display: flex;
-                justify-content: space-between;
-                align-items: center;
-                padding: 22px 25px;
-                background: linear-gradient(to right, #4a6bdf, #2b4fdc);
-                color: white;
-                border-bottom: 1px solid #e1e5eb;
-                flex-shrink: 0;
-            }
-            
-            .sidebar-header h3 {
-                margin: 0;
-                font-size: 20px;
+        curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $data) use ($chatId, $created, &$lastContent,&$reply) {
+            $lines = explode("\n", $data);
+            $prefixLength = strlen("event:chat_completion");
+            $content = str_replace("event:chat_completion", "", $lines[0]);
+          
            
-            }
-            
-            .sidebar-close {
-                font-size: 28px;
-                cursor: pointer;
-                color: rgba(255, 255, 255, 0.9);
-                transition: all 0.2s;
-                width: 32px;
-                height: 32px;
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                border-radius: 50%;
-            }
-            
-            .sidebar-close:hover {
-                color: white;
-                background: rgba(255, 255, 255, 0.15);
-                transform: scale(1.1);
-            }
-            
-            .sidebar-body {
-                padding: 25px;
-                flex-grow: 1;
-                overflow-y: auto;
-            }
-            
-            /* 统计信息样式 */
-            .stats {
-                background: #f0f5ff;
-                padding: 12px 16px;
-                border-radius: 8px;
-                margin-bottom: 20px;
-                font-size: 15px;
-                color: #2b4fdc;
-                border-left: 4px solid #2b4fdc;
-                box-shadow: 0 2px 8px rgba(0,0,0,0.05);
-            }
-            
-            /* 文档分类样式 */
-            .sidebar-tools {
-                padding: 16px 20px;
-                margin-bottom: 15px;
-                background: linear-gradient(to right, #f7f9fc, #f0f5ff);
-                border-radius: 10px;
-                cursor: pointer;
-                transition: all 0.3s ease;
-                box-shadow: 0 3px 10px rgba(0,0,0,0.04);
-                border-left: 4px solid #4a6bdf;
-         
-                color: #2d3748;
-                position: relative;
-                overflow: hidden;
-            }
-            
-            .sidebar-tools:hover {
-                transform: translateY(-2px);
-                box-shadow: 0 5px 15px rgba(0,0,0,0.08);
-                background: linear-gradient(to right, #f0f5ff, #e6eeff);
-            }
-            
-            .sidebar-tools:active {
-                transform: translateY(0);
-            }
-            
-            .sidebar-tools::after {
-                content: '';
-                position: absolute;
-                top: 0;
-                right: 0;
-                width: 8px;
-                height: 100%;
-                background: #4a6bdf;
-                opacity: 0;
-                transition: opacity 0.3s;
-            }
-            
-            .sidebar-tools:hover::after {
-                opacity: 0.3;
-            }
-            
-            /* 质控问题项样式 */
-            .qualityControlToken {
-                padding: 14px 20px;
-                margin: 12px 0;
-                background: #fff;
-                border-radius: 8px;
-                border-left: 3px solid #ff9500;
-                box-shadow: 0 2px 8px rgba(0,0,0,0.04);
-                transition: all 0.2s;
-                color: #4a5568;
-            }
-            .quality
-            {
-                width: 100%;
-                height: 20px;
-                line-height: 20px;
-                margin-top: 10px;
-            }
-            .qualityControlToken:hover {
-                box-shadow: 0 4px 12px rgba(0,0,0,0.08);
-                transform: translateX(3px);
-            }
-            
-            /* 无数据提示样式 */
-            .no-data {
-                text-align: center;
-                padding: 40px 20px;
-                color: #a0aec0;
-                font-size: 16px;
-            }
-            
-            /* 加载动画 */
-            .loader {
-                display: flex;
-                justify-content: center;
-                padding: 30px;
-            }
-            
-            .loader .dot {
-                width: 10px;
-                height: 10px;
-                margin: 0 5px;
-                background: #4a6bdf;
-                border-radius: 50%;
-                animation: bounce 1.5s infinite ease-in-out;
-            }
-            
-            .loader .dot:nth-child(2) {
-                animation-delay: 0.2s;
-            }
-            
-            .loader .dot:nth-child(3) {
-                animation-delay: 0.4s;
-            }
-            
-            @keyframes bounce {
-                0%, 100% { transform: translateY(0); }
-                50% { transform: translateY(-10px); }
-            }
-            
-            /* 移动设备适配 */
-            @media (max-width: 768px) {
-                .sidebar-overlay {
-                    width: 85%;
-                    left: -85%;
-                }
-                
-                .sidebar-trigger {
-                    padding: 15px 8px;
-                    font-size: 14px;
-                    writing-mode: horizontal-tb;
-                    top: auto;
-                    bottom: 20px;
-                    left: 20px;
-                    transform: none;
-                    border-radius: 12px;
-                    width: auto;
-                }
+            // foreach ($lines as $line) {
+            //         $line = substr($line,6);
+            //         $content = $matches[0];
+            //         // 仅当内容变化时才输出
+            //         if ($content !== $lastContent) {
+            //             $lastContent = $content;
+                    $jsonData = [
+                        "id" => $chatId,
+                        "model" => "emoon-E1-13B",
+                        "created" => $created,
+                        "object" => "chat.completion.chunk",
+                        "choices" => [
+                            [
+                                "index" => 0,
+                                "delta" => [
+                                    "content" => $content
+                                ],
+                                "finish_reason" => null
+                            ]
+                        ],
+                        "usage" => null
+                    ];
+                    echo "data: " . json_encode($jsonData,JSON_UNESCAPED_UNICODE) . "\n\n";
+                    $outputJson = json_encode($jsonData,JSON_UNESCAPED_UNICODE);
+                    
+                    $outputJson = json_decode($outputJson);
+                    // $outputJson = stdClassObjToArray($outputJson);
+                    $outputJson = $outputJson->choices[0]->delta->content;
+              
+                    if($outputJson){
+                        $outputJson = json_encode($outputJson,JSON_UNESCAPED_UNICODE);
+                        $outputJson = str_replace('"', '', $outputJson);
+                    }
                 
-                .sidebar-header {
-                    padding: 18px 20px;
-                }
+                    $reply .= $outputJson;
+                    
+                    // }
+                    @ob_flush();
+                    @flush();
                 
-                .sidebar-body {
-                    padding: 20px;
-                }
-            }
-            
-            /* 滚动条样式 */
-            .sidebar-content::-webkit-scrollbar {
-                width: 6px;
-            }
-            
-            .sidebar-content::-webkit-scrollbar-track {
-                background: #f1f1f1;
-            }
-            
-            .sidebar-content::-webkit-scrollbar-thumb {
-                background: #c1c1c1;
-                border-radius: 3px;
-            }
-            
-            .sidebar-content::-webkit-scrollbar-thumb:hover {
-                background: #a8a8a8;
-            }
-            
-            /* 新增样式:分类计数徽章 */
-            .doc-count {
-                background: #4a6bdf;
-                color: white;
-                border-radius: 12px;
-                padding: 2px 8px;
-                font-size: 12px;
-                margin-left: 8px;
-                vertical-align: middle;
-            }
-            
-            /* 新增样式:搜索框 */
-            .search-container {
-                padding: 0 25px 15px;
-                background: white;
-                border-bottom: 1px solid #e1e5eb;
-            }
-            
-            .search-box {
-                width: 100%;
-                padding: 12px 15px;
-                border: 1px solid #e1e5eb;
-                border-radius: 8px;
-                font-size: 14px;
-                transition: all 0.3s;
-            }
-            
-            .search-box:focus {
-                outline: none;
-                border-color: #4a6bdf;
-                box-shadow: 0 0 0 3px rgba(74, 107, 223, 0.2);
-            }
-            
-             .selected-option {
-            height: 30px;
-            padding: 0 10px;
-            background: #2a2a2a;
-            border: 1px solid #444;
-            border-radius: 4px;
-            display: flex;
-            align-items: center;
-            justify-content: space-between;
-            cursor: pointer;
-            font-size: 14px;
-            color: #fff;
-        }
-        
-
-        /* EMR加载覆盖框样式 */
-        .emr-loading-overlay {
-            position: fixed;
-            top: 0;
-            left: 0;
-            width: 100%;
-            height: 100%;
-            background-color: rgba(0, 0, 0, 0.7);
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            z-index: 9999;
-        }
-
-        .emr-loading-content {
-            position: relative;
-            background: linear-gradient(135deg, #2c3e50, #1a2530);
-            padding: 30px 40px;
-            border-radius: 16px;
-            text-align: center;
-            color: white;
-            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
-            max-width: 400px;
-            width: 80%;
-            animation: fadeIn 0.3s ease-out;
-           
-        }
-
-        .emr-loading-spinner {
-            width: 60px;
-            height: 60px;
-            border: 5px solid rgba(255, 255, 255, 0.3);
-            border-radius: 50%;
-            border-top-color: #4a6bdf;
-            margin: 0 auto 20px;
-            animation: spin 1s linear infinite;
-        }
+            // }
+            return strlen($data);
+        });
+        $res = curl_exec($ch);
+      
+}
+// 清理资源
+curl_close($ch);
 
-        .emr-loading-text {
-            font-size: 18px;
-            margin-bottom: 10px;
-            color: #fff;
-        }
-
-        .emr-loading-subtext {
-            font-size: 14px;
-            color: #bdc3c7;
-            margin: 0 0 15px 0;
-        }
-
-        .progress-container {
-            width: 100%;
-            height: 8px;
-            background-color: rgba(255, 255, 255, 0.2);
-            border-radius: 4px;
-            overflow: hidden;
-            margin-top: 10px;
-        }
-
-        .progress-bar {
-            height: 100%;
-            width: 0%;
-            background: linear-gradient(90deg, #4a6bdf, #6c8cff);
-            border-radius: 4px;
-            transition: width 0.3s ease;
-        }
 
-        /* 完成状态样式 */
-        .emr-loading-content.completed {
-            background: linear-gradient(135deg, #27ae60, #219653);
-        }
-
-        .emr-loading-content.completed .emr-loading-spinner {
-            border-top-color: #fff;
-            animation: none;
-        }
-
-        .emr-loading-content.completed .emr-loading-spinner::after {
-            content: "✓";
-            font-size: 30px;
-            color: white;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            height: 100%;
-        }
-
-        /* 动画效果 */
-        @keyframes spin {
-            0% { transform: rotate(0deg); }
-            100% { transform: rotate(360deg); }
-        }
+// 显式结束流
+echo "event: end\ndata: Stream ended\n\n";
+ob_flush();
+flush();
+    
+$dataReply['reply'] = $reply;
+$url=$urlCommon.'/Apis/reply';
+curlPost($url,$dataReply);
+//模型定制结束-------------------------------------------------------------------
+function curlPost($url, $data = null, $headers = [], $json = false) {
+    $curl = curl_init($url);
+    $options = [
+        CURLOPT_RETURNTRANSFER => true,
+        CURLOPT_SSL_VERIFYPEER => false,
+        CURLOPT_SSL_VERIFYHOST => false,
+        CURLOPT_POST => !empty($data) || $json,
+    ];
+    if ($json) {
+        $headers = array_filter($headers, function($h) {
+            return stripos($h, 'Content-Type:') === false;
+        });
+        $headers[] = 'Content-Type: application/json';
+        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
+    }
+    if (!empty($headers)) {
+        $options[CURLOPT_HTTPHEADER] = $headers;
+    }
+    if (!empty($data)) {
+        $options[CURLOPT_POSTFIELDS] = $data;
+    }
+    curl_setopt_array($curl, $options);
+    $result = curl_exec($curl);
+    curl_close($curl);
+    return $result;
+}
 
-        @keyframes fadeIn {
-            from { opacity: 0; transform: translateY(-20px); }
-            to { opacity: 1; transform: translateY(0); }
-        }
-        
-        
-        /*报告面板*/
-        .modal-overlay {
-            position: fixed;
-            top: 0;
-            left: 0;
-            right: 0;
-            bottom: 0;
-            background-color: rgba(0, 0, 0, 0.5);
-            display: none;
-            justify-content: center;
-            align-items: center;
-            z-index: 1000;
-            backdrop-filter: blur(1px);
-            
-        }
-        
-        /* 模态框容器 */
-        .modal-container {
-            width: 95%;
-            max-width: 1400px;
-            height: 95vh;
-            top:2.5vh;
-            background-color: #fff;
-            border-radius: 12px;
-            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
-            display: flex;
-            overflow: hidden;
-            position: relative;
-            margin: 0 auto; 
-        }
-        
-        /* 关闭按钮 */
-        .close-btn {
-            position: absolute;
-         
-            right: 5px;
-            font-size: 28px;
-            color: #888;
-            cursor: pointer;
-            transition: all 0.3s;
-            z-index: 10;
-            background: none;
-            border: none;
-            padding: 0;
-            width: 30px;
-            height: 30px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            border-radius: 50%;
-        }
-        
-        .close-btn:hover {
-            color: #333;
-            transform: scale(1.1);
-            background-color: #f5f5f5;
-        }
-        
-        /* 左右面板公共样式 */
-        .left-panel, .right-panel {
-            padding: 30px;
-            height: 100%;
-            box-sizing: border-box;
-            overflow-y: auto;
-        }
-        
-        /* 左侧面板 */
-        .left-panel {
-            width: 60%;
-            background-color: #f9f9f9;
-            border-right: 1px solid #eee;
-            overflow-y: auto; /* 确保只有内容区域滚动 */
-            height: calc(100% - 60px); /* 减去标题栏高度 */
-            padding-top: 0;    /* 移除顶部内边距 */
-        }
-        
-        /* 右侧面板 */
-        .right-panel {
-            width: 40%;
-            background-color: #fff;
-            overflow-y: auto; /* 确保只有内容区域滚动 */
-            height: calc(100% - 60px); /* 减去标题栏高度 */
-            padding-top: 0; 
-        }
-        
-        /* 面板标题 */
-        .panel-title {
-            font-size: 20px;
-            color: #333;
-            top: 0; 
-        
-            margin-top: 10px;
-        
-            font-weight: 600;
-        }
-        
-        /* 表单组样式 */
-        .form-group {
-            margin-bottom: 20px;
-        }
-        
-        .form-group label {
-            display: block;
-            margin-bottom: 8px;
-            color: #555;
-            font-weight: 500;
-        }
-        
-        .form-group input, .form-group textarea, .form-group select {
-            width: 100%;
-            padding: 10px 12px;
-            border: 1px solid #ddd;
-            border-radius: 6px;
-            font-size: 14px;
-            transition: border 0.3s;
-        }
-        
-        .form-group input:focus, .form-group textarea:focus {
-            border-color: #4a90e2;
-            outline: none;
-            box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
-        }
-        
-        /* 预览区域 */
-        .preview-area {
-            background-color: #f5f7fa;
-            border-radius: 8px;
-            padding: 2px;
-            min-height: 100px;
-            border: 1px dashed #ccc;
-        }
-        
-        .preview-placeholder {
-            text-align: center;
-            color: #888;
-            padding: 40px 0;
-        }
-        
-        .preview-placeholder h3 {
-            font-size: 18px;
-            margin-bottom: 10px;
-            color: #666;
+function stdClassObjToArray($array) {
+    if(is_object($array)) {
+        $array = (array)$array;
+    }
+    if(is_array($array)) {
+        foreach($array as $key=>$value) {
+            $array[$key] = stdClassObjToArray($value);
         }
-
+    }
+    return $array;
+}
+function curlPostRAG($url, $data = null, $headers = [], $json = true) {
+        $curl = curl_init($url);
+        $options = [
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_SSL_VERIFYPEER => false,
+            CURLOPT_SSL_VERIFYHOST => false,
+            CURLOPT_POST => true, // 强制启用 POST(JSON 模式下始终 POST)
+        ];
     
-        
-        .title-row {
-            display: flex;
-            border-bottom: 2px solid #4a90e2;
-            align-items: center;
-            position: sticky;  /* 关键属性 */
-            top: 0;           /* 距离顶部0px时固定 */
-            background-color: #f9f9f9; /* 保持背景色一致 */
-            z-index: 10;      /* 确保在内容上方 */
-            padding: 10px 0;   /* 保持原有内边距 */
-        }
-        
-        .title-row-right {
-            display: flex;
-            border-bottom: 2px solid #4a90e2;
-            align-items: center;
-            position: sticky;  /* 关键属性 */
-            top: 0;           /* 距离顶部0px时固定 */
-            background-color: #f9f9f9; /* 保持背景色一致 */
-            z-index: 10;      /* 确保在内容上方 */
-            padding: 10px 0;   /* 保持原有内边距 */
-        }
-        
-        .type-selector {
-            width: 40%;
-            margin-top:10px;
-            margin-left: auto;
-        }
-        
-        .rule-section {
-            margin-top: 10px;
-            font-weight: bold; /* 加粗 */
-            margin-bottom: 8px;
-            color: #2980b9; /* 专业蓝 */
-            background-color: #f8f9fa;
-        }
-        
-        /* 质控结果样式 */
-        .result-section {
-            /* 加粗 */
-            margin-bottom: 8px;
-        }
-        
-        /* 不通过原因样式 */
-        .reason-section {
-            margin-bottom: 12px;
-        }
-        
-        .rule-low-section {
-            margin-top: 10px;
-            font-weight: bold; /* 加粗 */
-            margin-bottom: 8px;
-            color: #2980b9; /* 专业蓝 */
-            background-color: #f8f9fa;
-        }
-        
-        /* 质控结果样式 */
-        .result-low-section {
-            /* 加粗 */
-            margin-bottom: 8px;
-        }
-        
-        /* 不通过原因样式 */
-        .reason-low-section {
-            margin-bottom: 12px;
-        }
-        
-        .rule-tall-section {
-            margin-top: 10px;
-            font-weight: bold; /* 加粗 */
-            margin-bottom: 8px;
-            color: #e74c3c; /* 红 */
-            background-color: #f8f9fa;
-        }
-        
-        /* 质控结果样式 */
-        .result-tall-section {
-            /* 加粗 */
-            margin-bottom: 8px;
-        }
-        
-        /* 不通过原因样式 */
-        .reason-tall-section {
-            margin-bottom: 12px;
-        }
-        
-        .rule-title-section {
-            font-weight: bold; /* 加粗 */
-            margin-bottom: 8px;
-            color: #e74c3c; /* 红 */
-            background-color: #f8f9fa;
-        }
-        
-        /* 质控结果样式 */
-        .result-title-section {
-            /* 加粗 */
-            margin-bottom: 8px;
+        if ($json) {
+            // 移除已有的 Content-Type 和 Accept 头,避免冲突
+            $headers = array_filter($headers, function($h) {
+                return stripos($h, 'Content-Type:') === false && stripos($h, 'Accept:') === false;
+            });
+            // 添加 JSON 专用头
+            $headers[] = 'Content-Type: application/json';
+            $headers[] = 'Accept: application/json';
+            // 编码数据为 JSON(空数据编码为 "{}" 避免服务器解析错误)
+            $data = $data !== null ? json_encode($data, JSON_UNESCAPED_UNICODE) : '{}';
         }
-        
-        /* 不通过原因样式 */
-        .reason-title-section {
-            margin-bottom: 12px;
+    
+        // 设置请求头和数据
+        if (!empty($headers)) {
+            $options[CURLOPT_HTTPHEADER] = $headers;
         }
-        
-        .emr-close-btn {
-            position: absolute;
-            top: 15px;
-            right: 15px;
-            padding: 6px 12px;
-            /*background-color: #495057;*/
-          
-            border-radius: 4px;
-            color: #e9ecef;
-            font-size: 14px;
-            cursor: pointer;
-            transition: all 0.2s ease;
-            z-index: 10;
+        if ($data !== null) {
+            $options[CURLOPT_POSTFIELDS] = $data;
         }
-
-
-
-        .emr-close-btn:active {
-        
-            transform: translateY(1px);
+    
+        curl_setopt_array($curl, $options);
+        $result = curl_exec($curl);
+    
+        // 错误处理(调试时启用)
+        if ($result === false) {
+            $error = curl_error($curl);
+            $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+            throw new Exception("CURL请求失败: HTTP状态码 $httpCode, 错误信息: $error");
         }
-        
-        .quality-control-score {
-        font-size: 16px;
-        color: #666;
-        margin-left: auto;          /* 自动左外边距,推至最右 */
-    }
     
-    /* 得分数字高亮 */
-    #qualitycontrolscore {
-        color: #e74c3c;             /* 红色强调 */
-        font-weight: bold;
-        margin: 0 3px;             /* 左右间距 */
+        curl_close($curl);
+        return $result;
     }
-        </style>
-    </body>
-</html>
+exit;