|  |  | @ -4,6 +4,9 @@ import { useUserInfo } from '../store/userPermissionCode' | 
			
		
	
		
			
				
					|  |  |  | import axios from 'axios' | 
			
		
	
		
			
				
					|  |  |  | import { ElMessage } from 'element-plus'; | 
			
		
	
		
			
				
					|  |  |  | import { Loading, Position } from '@element-plus/icons-vue'; // 引入图标组件 | 
			
		
	
		
			
				
					|  |  |  | import { marked } from 'marked'; // 引入marked库 | 
			
		
	
		
			
				
					|  |  |  | import katex from 'katex'; // 引入 KaTeX 库 | 
			
		
	
		
			
				
					|  |  |  | import 'katex/dist/katex.min.css'; // 引入 KaTeX 样式 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | const { getQueryVariable } = useUserInfo() | 
			
		
	
		
			
				
					|  |  |  | // 假设 getSessionId 已经正确定义 | 
			
		
	
	
		
			
				
					|  |  | @ -17,7 +20,7 @@ const fnGetToken = () => { | 
			
		
	
		
			
				
					|  |  |  | setTimeout(() => { | 
			
		
	
		
			
				
					|  |  |  |     fnGetToken() | 
			
		
	
		
			
				
					|  |  |  | }, 800) | 
			
		
	
		
			
				
					|  |  |  | const token = localStorage.getItem('localToken') | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | // 验证 token | 
			
		
	
		
			
				
					|  |  |  | const validateToken = async () => { | 
			
		
	
		
			
				
					|  |  |  |     const token = localStorage.getItem('localToken') | 
			
		
	
	
		
			
				
					|  |  | @ -34,7 +37,7 @@ const sessionId = ref(localStorage.getItem('sessionId') || {}); | 
			
		
	
		
			
				
					|  |  |  | const add = async () => { | 
			
		
	
		
			
				
					|  |  |  |     try { | 
			
		
	
		
			
				
					|  |  |  |         const result = await axios.post( | 
			
		
	
		
			
				
					|  |  |  |             "http://2zhyw2.natappfree.cc/api/v1/chats/8b37cd9cf0c811efa4210242ac120003/completions", | 
			
		
	
		
			
				
					|  |  |  |             "http://wnxvxx.natappfree.cc/api/v1/chats/8b37cd9cf0c811efa4210242ac120003/completions", | 
			
		
	
		
			
				
					|  |  |  |             {}, | 
			
		
	
		
			
				
					|  |  |  |             { | 
			
		
	
		
			
				
					|  |  |  |                 headers: { | 
			
		
	
	
		
			
				
					|  |  | @ -132,7 +135,7 @@ const sendMessage = async () => { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     try { | 
			
		
	
		
			
				
					|  |  |  |         // 调用API获取回复 | 
			
		
	
		
			
				
					|  |  |  |         const response = await fetch("http://2zhyw2.natappfree.cc/api/v1/chats/8b37cd9cf0c811efa4210242ac120003/completions", { | 
			
		
	
		
			
				
					|  |  |  |         const response = await fetch("http://wnxvxx.natappfree.cc/api/v1/chats/8b37cd9cf0c811efa4210242ac120003/completions", { | 
			
		
	
		
			
				
					|  |  |  |             method: 'POST', | 
			
		
	
		
			
				
					|  |  |  |             headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ragflow-hkNjEwYjcwZjBlMDExZWZiYjYzMDI0Mm' }, | 
			
		
	
		
			
				
					|  |  |  |             body: JSON.stringify({ question: content, stream: false, session_id: sessionId.value   }) | 
			
		
	
	
		
			
				
					|  |  | @ -142,44 +145,69 @@ const sendMessage = async () => { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         // 移除加载消息 | 
			
		
	
		
			
				
					|  |  |  |         messages.value = messages.value.filter(msg => !msg.isLoading); | 
			
		
	
		
			
				
					|  |  |  |         // 提取推理思考部分和结果部分 | 
			
		
	
		
			
				
					|  |  |  |         const regex = /<think>(.*?)<\/think>(.*)/s; | 
			
		
	
		
			
				
					|  |  |  |         const match = data.data.answer.match(regex); | 
			
		
	
		
			
				
					|  |  |  |         let thinking = ''; | 
			
		
	
		
			
				
					|  |  |  |         let result = data.data.answer; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         if (match) { | 
			
		
	
		
			
				
					|  |  |  |             thinking = match[1].trim(); | 
			
		
	
		
			
				
					|  |  |  |             result = match[2].trim(); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         // 组合推理思考内容和结果内容,并添加 HTML 标签 | 
			
		
	
		
			
				
					|  |  |  |         let combinedContent = ''; | 
			
		
	
		
			
				
					|  |  |  |         // if (thinking) { | 
			
		
	
		
			
				
					|  |  |  |         //     combinedContent += `<span class="thinking-content">推理思考:${thinking}</span><br>`; | 
			
		
	
		
			
				
					|  |  |  |         // } | 
			
		
	
		
			
				
					|  |  |  |         combinedContent += `<span class="result-content">${result}</span>`; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         // 添加初始空消息 | 
			
		
	
		
			
				
					|  |  |  |         const botMessageIndex = messages.value.length; | 
			
		
	
		
			
				
					|  |  |  |         messages.value.push({ | 
			
		
	
		
			
				
					|  |  |  |             content: '', | 
			
		
	
		
			
				
					|  |  |  |             sender: 'bot', | 
			
		
	
		
			
				
					|  |  |  |             timestamp: new Date() | 
			
		
	
		
			
				
					|  |  |  |         }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         // 使用定时器逐个字符更新消息内容 | 
			
		
	
		
			
				
					|  |  |  |         let currentIndex = 0; | 
			
		
	
		
			
				
					|  |  |  |         const intervalId = setInterval(() => { | 
			
		
	
		
			
				
					|  |  |  |             if (currentIndex < combinedContent.length) { | 
			
		
	
		
			
				
					|  |  |  |                 messages.value[botMessageIndex].content += combinedContent[currentIndex]; | 
			
		
	
		
			
				
					|  |  |  |                 scrollToBottom(); | 
			
		
	
		
			
				
					|  |  |  |                 currentIndex++; | 
			
		
	
		
			
				
					|  |  |  |             } else { | 
			
		
	
		
			
				
					|  |  |  |                 clearInterval(intervalId); | 
			
		
	
		
			
				
					|  |  |  |         // 检查 data 对象的结构,确保正确提取所需属性 | 
			
		
	
		
			
				
					|  |  |  |         if (data && data.data && typeof data.data.answer === 'string') { | 
			
		
	
		
			
				
					|  |  |  |             // 提取推理思考部分和结果部分 | 
			
		
	
		
			
				
					|  |  |  |             const regex = /<think>(.*?)<\/think>(.*)/s; | 
			
		
	
		
			
				
					|  |  |  |             const match = data.data.answer.match(regex); | 
			
		
	
		
			
				
					|  |  |  |             let thinking = ''; | 
			
		
	
		
			
				
					|  |  |  |             let result = data.data.answer; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             if (match) { | 
			
		
	
		
			
				
					|  |  |  |                 thinking = match[1].trim(); | 
			
		
	
		
			
				
					|  |  |  |                 result = match[2].trim(); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         }, 100); // 每100毫秒添加一个字符,可以根据需要调整 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             // 组合推理思考内容和结果内容,并添加 HTML 标签 | 
			
		
	
		
			
				
					|  |  |  |             let combinedContent = ''; | 
			
		
	
		
			
				
					|  |  |  |             // if (thinking) { | 
			
		
	
		
			
				
					|  |  |  |             //     combinedContent += `<span class="thinking-content">推理思考:${thinking}</span><br>`; | 
			
		
	
		
			
				
					|  |  |  |             // } | 
			
		
	
		
			
				
					|  |  |  |             combinedContent += `<span class="result-content">${result}</span>`; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             // 使用marked库将Markdown转换为HTML | 
			
		
	
		
			
				
					|  |  |  |             let markdownContent = marked(combinedContent); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             // 使用 KaTeX 渲染数学公式 | 
			
		
	
		
			
				
					|  |  |  |             const katexRegex = /\$\$(.*?)\$\$/g; | 
			
		
	
		
			
				
					|  |  |  |             markdownContent = markdownContent.replace(katexRegex, (match, formula) => { | 
			
		
	
		
			
				
					|  |  |  |                 try { | 
			
		
	
		
			
				
					|  |  |  |                     return katex.renderToString(formula, { throwOnError: false }); | 
			
		
	
		
			
				
					|  |  |  |                 } catch (error) { | 
			
		
	
		
			
				
					|  |  |  |                     console.error('KaTeX 渲染错误:', error); | 
			
		
	
		
			
				
					|  |  |  |                     return match; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             // 添加初始空消息 | 
			
		
	
		
			
				
					|  |  |  |             const botMessageIndex = messages.value.length; | 
			
		
	
		
			
				
					|  |  |  |             messages.value.push({ | 
			
		
	
		
			
				
					|  |  |  |                 content: '', | 
			
		
	
		
			
				
					|  |  |  |                 sender: 'bot', | 
			
		
	
		
			
				
					|  |  |  |                 timestamp: new Date() | 
			
		
	
		
			
				
					|  |  |  |             }); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             // 使用定时器逐个字符更新消息内容 | 
			
		
	
		
			
				
					|  |  |  |             let currentIndex = 0; | 
			
		
	
		
			
				
					|  |  |  |             const intervalId = setInterval(() => { | 
			
		
	
		
			
				
					|  |  |  |                 if (currentIndex < markdownContent.length) { | 
			
		
	
		
			
				
					|  |  |  |                     messages.value[botMessageIndex].content += markdownContent[currentIndex]; | 
			
		
	
		
			
				
					|  |  |  |                     scrollToBottom(); | 
			
		
	
		
			
				
					|  |  |  |                     currentIndex++; | 
			
		
	
		
			
				
					|  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |                     clearInterval(intervalId); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             }, 100); // 每100毫秒添加一个字符,可以根据需要调整 | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |             console.error('API 返回的数据格式不正确:', data); | 
			
		
	
		
			
				
					|  |  |  |             messages.value.push({ | 
			
		
	
		
			
				
					|  |  |  |                 content: '服务返回数据格式错误,请稍后再试', | 
			
		
	
		
			
				
					|  |  |  |                 sender: 'bot', | 
			
		
	
		
			
				
					|  |  |  |                 timestamp: new Date() | 
			
		
	
		
			
				
					|  |  |  |             }); | 
			
		
	
		
			
				
					|  |  |  |             scrollToBottom(); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } catch (error) { | 
			
		
	
		
			
				
					|  |  |  |         console.error('API请求失败:', error); | 
			
		
	
		
			
				
					|  |  |  |         // 移除加载消息 | 
			
		
	
	
		
			
				
					|  |  | @ -280,14 +308,34 @@ onMounted(async () => { | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | <style scoped> | 
			
		
	
		
			
				
					|  |  |  | table{ | 
			
		
	
		
			
				
					|  |  |  |     border-color: black | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | /* 使用更具体的选择器 */ | 
			
		
	
		
			
				
					|  |  |  | .message-bubble .message-content .thinking-content { | 
			
		
	
		
			
				
					|  |  |  |     color: #c8c4c4; | 
			
		
	
		
			
				
					|  |  |  |     font-style: italic; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | /* 新增表格样式 */ | 
			
		
	
		
			
				
					|  |  |  | .message-bubble .message-content table { | 
			
		
	
		
			
				
					|  |  |  |     border-collapse: collapse; /* 合并边框 */ | 
			
		
	
		
			
				
					|  |  |  |     width: 100%; /* 表格宽度为 100% */ | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | .message-bubble .message-content th, | 
			
		
	
		
			
				
					|  |  |  | .message-bubble .message-content td { | 
			
		
	
		
			
				
					|  |  |  |     border: 1px solid #e0e0e0; /* 单元格边框 */ | 
			
		
	
		
			
				
					|  |  |  |     padding: 8px; /* 单元格内边距 */ | 
			
		
	
		
			
				
					|  |  |  |     text-align: left; /* 文本左对齐 */ | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | .message-bubble .message-content th { | 
			
		
	
		
			
				
					|  |  |  |     background-color: #f1f3f5; /* 表头背景颜色 */ | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | /* 其他样式保持不变 */ | 
			
		
	
		
			
				
					|  |  |  | .message-item.bot { | 
			
		
	
		
			
				
					|  |  |  |     justify-content: flex-start; /* 让机器人消息靠左对齐 */ | 
			
		
	
		
			
				
					|  |  |  |     text-align: left; /* 新增:设置文本左对齐 */ | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | .chat-container { | 
			
		
	
		
			
				
					|  |  |  |     display: flex; | 
			
		
	
	
		
			
				
					|  |  | @ -499,4 +547,7 @@ onMounted(async () => { | 
			
		
	
		
			
				
					|  |  |  |     box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | 
			
		
	
		
			
				
					|  |  |  |     text-align: center; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | </style> |