| | |
| | | .time { font-size: 12px; color: #909399; text-align: right; margin-top: 6px; } |
| | | .output .el-card__body { height: 100%; padding: 0; } |
| | | .assistant-running { display: flex; align-items: center; gap: 8px; color: #909399; } |
| | | details.think-block { |
| | | border: 1px solid #e4e7ed; |
| | | border-radius: 4px; |
| | | padding: 8px; |
| | | margin: 8px 0; |
| | | background-color: #fcfcfc; |
| | | } |
| | | details.think-block summary { |
| | | cursor: pointer; |
| | | color: #909399; |
| | | font-size: 13px; |
| | | font-weight: bold; |
| | | outline: none; |
| | | } |
| | | details.think-block .content { |
| | | margin-top: 8px; |
| | | color: #606266; |
| | | font-size: 13px; |
| | | white-space: pre-wrap; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | |
| | | } |
| | | }, |
| | | methods: { |
| | | renderMarkdown: function(md, streaming) { |
| | | if (!md) return ''; |
| | | var src = md.replace(/\\n/g, '\n'); |
| | | var openAttr = streaming ? ' open' : ''; |
| | | src = src.replace(/<think>/g, '<details class="think-block"' + openAttr + '><summary>AI深度思考</summary><div class="content">'); |
| | | src = src.replace(/<\/think>/g, '</div></details>'); |
| | | if (streaming && src.indexOf('<details class="think-block"') >= 0 && src.indexOf('</div></details>') < 0) { |
| | | src += '</div></details>'; |
| | | } |
| | | return DOMPurify.sanitize(marked.parse(src)); |
| | | }, |
| | | loadChats: function() { |
| | | var self = this; |
| | | fetch(baseUrl + '/ai/diagnose/chats', { headers: { 'token': localStorage.getItem('token') } }) |
| | |
| | | var msgs = []; |
| | | for (var i=0;i<arr.length;i++) { |
| | | var m = arr[i]; |
| | | if (m.role === 'assistant') msgs.push({ role: 'assistant', md: m.content || '', html: DOMPurify.sanitize(marked.parse((m.content||'').replace(/\\n/g,'\n'))), ts: self.nowStr() }); |
| | | if (m.role === 'assistant') msgs.push({ role: 'assistant', md: m.content || '', html: self.renderMarkdown(m.content || '', false), ts: self.nowStr() }); |
| | | else msgs.push({ role: 'user', text: m.content || '', ts: self.nowStr() }); |
| | | } |
| | | self.messages = msgs; |
| | |
| | | self.lastRenderTs = now; |
| | | var last = self.messages.length > 0 ? self.messages[self.messages.length - 1] : null; |
| | | if (last && last.role === 'assistant') { |
| | | var renderSource = (last.md || '').replace(/\\n/g, '\n'); |
| | | last.html = DOMPurify.sanitize(marked.parse(renderSource)); |
| | | last.html = self.renderMarkdown(last.md || '', true); |
| | | self.$nextTick(function() { self.scrollToBottom(true); }); |
| | | } |
| | | } |
| | |
| | | this.typingTimer = null; |
| | | } |
| | | if (last && last.role === 'assistant') { |
| | | var renderSource = (last.md || '').replace(/\n/g, '\n'); |
| | | last.html = DOMPurify.sanitize(marked.parse(renderSource)); |
| | | last.html = this.renderMarkdown(last.md || '', false); |
| | | } |
| | | this.$nextTick(function() { this.scrollToBottom(true); }.bind(this)); |
| | | this.loadChats(); |