|
@@ -26,7 +26,14 @@
|
|
|
<div class="message_wrapper">
|
|
|
<div class="message">
|
|
|
<div v-for="(item,index) in formateAIAnswer(chat)" :key="index">
|
|
|
- <div :id="'answer_'+chat.id" v-if="item.type == 'text'" v-html="renderMarkdown(item.content)"></div>
|
|
|
+ <div :id="'answer_'+chat.id" v-if="item.type == 'text'" >
|
|
|
+ <!-- v-html="renderMarkdown(item.content)" -->
|
|
|
+ <div v-for="(item1,inde) in parseMessage(item.content)" :key="`n_${inde}`">
|
|
|
+ <div v-if="item1.type == 'text'" v-html="renderMarkdown(item1.content)"></div>
|
|
|
+ <code-block v-if="item1.type == 'code'" :language="item1.language" :code="item1.content"></code-block>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
<div v-if="item.type == 'think'" class="think" :id="'think_'+chat.id">
|
|
|
<div>
|
|
|
<span @click="changeShowThink(chat,item)">
|
|
@@ -35,7 +42,13 @@
|
|
|
</span>
|
|
|
think...
|
|
|
</div>
|
|
|
- <div class="thinkContent" v-show="item.show" v-html="renderMarkdown(item.content)"></div>
|
|
|
+ <div class="thinkContent" v-show="item.show">
|
|
|
+ <!-- v-html="renderMarkdown(item.content)" -->
|
|
|
+ <div v-for="(item1,inde) in parseMessage(item.content)" :key="`n_${inde}`">
|
|
|
+ <div v-if="item1.type == 'text'" v-html="renderMarkdown(item1.content)"></div>
|
|
|
+ <code-block v-if="item1.type == 'code'" :language="item1.language" :code="item1.content"></code-block>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -75,11 +88,15 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+let StartCode = false
|
|
|
import 'highlight.js/styles/github.css'; // 或其他主题样式
|
|
|
import 'github-markdown-css/github-markdown.css';
|
|
|
import {renderMarkdown} from '@/utils/markdown'
|
|
|
+import CodeBlock from './CodeBlock.vue';
|
|
|
export default {
|
|
|
- components: {},
|
|
|
+ components: {
|
|
|
+ 'code-block':CodeBlock
|
|
|
+ },
|
|
|
props: {
|
|
|
params:{
|
|
|
type:Object,
|
|
@@ -126,6 +143,8 @@ export default {
|
|
|
if(val){
|
|
|
this.queryChatHistory.has_more = true
|
|
|
this.getChatHistory(1)
|
|
|
+ }else{
|
|
|
+ this.chatHistory = []
|
|
|
}
|
|
|
}
|
|
|
},
|
|
@@ -224,6 +243,7 @@ export default {
|
|
|
if (event.keyCode == 13) {
|
|
|
if (!event.ctrlKey) {
|
|
|
event.preventDefault();
|
|
|
+ event.stopPropagation();
|
|
|
this.sendMessage()
|
|
|
} else {
|
|
|
this.userInput += "\n";
|
|
@@ -291,6 +311,7 @@ export default {
|
|
|
conversationId:this.conversationId,
|
|
|
...this.params
|
|
|
}
|
|
|
+ this.userInput = ''
|
|
|
const response = await fetch('/api/xiaoshi/dify/chatMessage', {
|
|
|
method: 'POST',
|
|
|
headers: {
|
|
@@ -457,6 +478,71 @@ export default {
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
+ //获取代码文本
|
|
|
+ parseMessage(text) {
|
|
|
+ const blocks = [];
|
|
|
+
|
|
|
+ // 使用正则表达式匹配代码块
|
|
|
+ let regex = /```(\s*|\w*)\n([\s\S]+?)```/g;
|
|
|
+ let lastIndex = 0;
|
|
|
+ let match;
|
|
|
+ // console.log(regex.exec(text))
|
|
|
+ while ((match = regex.exec(text)) !== null) {
|
|
|
+ StartCode = false
|
|
|
+ // 添加代码块之前的文本
|
|
|
+ if (match.index > lastIndex) {
|
|
|
+ blocks.push({
|
|
|
+ type: 'text',
|
|
|
+ content: text.slice(lastIndex, match.index),
|
|
|
+ isComplete: false
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加代码块
|
|
|
+ blocks.push({
|
|
|
+ type: 'code',
|
|
|
+ language: match[1] || '',
|
|
|
+ content: match[2].trim(),
|
|
|
+ isComplete: true // 代码块总是完整显示
|
|
|
+ });
|
|
|
+
|
|
|
+ lastIndex = regex.lastIndex;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加剩余的文本
|
|
|
+ if (lastIndex < text.length) {
|
|
|
+ let lastContent = text.slice(lastIndex)
|
|
|
+ let regex2 = /```(\w*)\n([\s\S]+)/g;
|
|
|
+ let lastResult
|
|
|
+ let index1 = 0
|
|
|
+ while((lastResult = regex2.exec(lastContent)) !== null){
|
|
|
+ StartCode = true
|
|
|
+ if(lastResult.index > index1){
|
|
|
+ blocks.push({
|
|
|
+ type: 'text',
|
|
|
+ content: lastContent.slice(index1, lastResult.index),
|
|
|
+ isComplete: false
|
|
|
+ });
|
|
|
+ }
|
|
|
+ blocks.push({
|
|
|
+ type: 'code',
|
|
|
+ language: lastResult[1] || '',
|
|
|
+ content: lastResult[2].trim(),
|
|
|
+ isComplete: true // 代码块总是完整显示
|
|
|
+ });
|
|
|
+ index1 = regex2.lastIndex;
|
|
|
+ }
|
|
|
+ lastIndex = lastIndex + index1
|
|
|
+ }
|
|
|
+ if(lastIndex < text.length && !StartCode){
|
|
|
+ blocks.push({
|
|
|
+ type: 'text',
|
|
|
+ content: text.slice(lastIndex),
|
|
|
+ isComplete: false
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return blocks;
|
|
|
+ },
|
|
|
//格式化AI答复
|
|
|
formateAIAnswer(chat){
|
|
|
let answer = chat.answer
|
|
@@ -618,7 +704,8 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
.message{
|
|
|
- width:fit-content;
|
|
|
+ width: fit-content;
|
|
|
+ max-width: calc(100% - 1px);
|
|
|
border-radius: 1rem;
|
|
|
padding-top: .75rem;
|
|
|
padding-bottom: .75rem;
|