|
@@ -46,10 +46,16 @@
|
|
|
<template v-for="(block, blockIndex) in parseMessage(
|
|
|
message.isTyping ? message.displayContent : message.content
|
|
|
)" >
|
|
|
- <code-block :key="blockIndex" v-if="block.type === 'code'"
|
|
|
- :language="block.language"
|
|
|
- :code="block.content" />
|
|
|
- <div :key="blockIndex" v-else v-html="renderMarkdown(block.content)"></div>
|
|
|
+ <code-block
|
|
|
+ :key="`code-${blockIndex}`"
|
|
|
+ v-if="block.type === 'code'"
|
|
|
+ :language="block.language"
|
|
|
+ :code="block.content" />
|
|
|
+ <div
|
|
|
+ :key="`text-${blockIndex}`"
|
|
|
+ v-else
|
|
|
+ v-html="renderMarkdown(block.content)">
|
|
|
+ </div>
|
|
|
</template>
|
|
|
</div>
|
|
|
<div class="message-time">{{ message.timestamp }}</div>
|
|
@@ -121,6 +127,7 @@ export default {
|
|
|
typingSpeed: 20, // 打字机效果的速度(毫秒)
|
|
|
scrollLock:true,
|
|
|
md: null,
|
|
|
+ startCode:false
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -327,14 +334,28 @@ export default {
|
|
|
|
|
|
async typeWriter(message, newContent,formattedContent) {
|
|
|
const currentLength = message.displayContent.length;
|
|
|
- const targetLength = message.content.length;
|
|
|
+ // const targetLength = message.content.length;
|
|
|
+
|
|
|
+ // message.displayContent = message.content;
|
|
|
+ // // 检查是否包含完整的代码块
|
|
|
+ // const blocks = this.parseMessage(message.content);
|
|
|
+ // const hasCompleteCodeBlock = blocks.some(block => block.type === 'code');
|
|
|
|
|
|
- if (currentLength < targetLength) {
|
|
|
- message.displayContent = message.content.substring(0, currentLength + newContent.length);
|
|
|
- this.$nextTick(() => {
|
|
|
- this.scrollToBottom();
|
|
|
- });
|
|
|
- }
|
|
|
+ // if (!hasCompleteCodeBlock) {
|
|
|
+ // // 如果没有完整的代码块,使用逐字显示
|
|
|
+ // message.displayContent = message.content.substring(0, currentLength + newContent.length);
|
|
|
+ // }
|
|
|
+ message.displayContent = message.content.substring(0, currentLength + newContent.length);
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.scrollToBottom();
|
|
|
+ });
|
|
|
+
|
|
|
+ // if (currentLength < targetLength) {
|
|
|
+ // message.displayContent = message.content.substring(0, currentLength + newContent.length);
|
|
|
+ // this.$nextTick(() => {
|
|
|
+ // this.scrollToBottom();
|
|
|
+ // });
|
|
|
+ // }
|
|
|
},
|
|
|
|
|
|
async finishTypingEffect(message) {
|
|
@@ -445,16 +466,18 @@ export default {
|
|
|
let currentText = '';
|
|
|
|
|
|
// 使用正则表达式匹配代码块
|
|
|
- const regex = /```(\w*)\n([\s\S]+?)```/g;
|
|
|
+ let regex = /```(\w*)\n([\s\S]+?)```/g;
|
|
|
+ // regex = /```(\w*)\n|([\s\S]+?)```/g
|
|
|
let lastIndex = 0;
|
|
|
let match;
|
|
|
-
|
|
|
while ((match = regex.exec(text)) !== null) {
|
|
|
// 添加代码块之前的文本
|
|
|
+ console.log(match.index,match)
|
|
|
if (match.index > lastIndex) {
|
|
|
blocks.push({
|
|
|
type: 'text',
|
|
|
- content: text.slice(lastIndex, match.index)
|
|
|
+ content: text.slice(lastIndex, match.index),
|
|
|
+ isComplete: false
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -462,7 +485,8 @@ export default {
|
|
|
blocks.push({
|
|
|
type: 'code',
|
|
|
language: match[1] || '',
|
|
|
- content: match[2].trim()
|
|
|
+ content: match[2].trim(),
|
|
|
+ isComplete: true // 代码块总是完整显示
|
|
|
});
|
|
|
|
|
|
lastIndex = regex.lastIndex;
|
|
@@ -472,13 +496,36 @@ export default {
|
|
|
if (lastIndex < text.length) {
|
|
|
blocks.push({
|
|
|
type: 'text',
|
|
|
- content: text.slice(lastIndex)
|
|
|
+ content: text.slice(lastIndex),
|
|
|
+ isComplete: false
|
|
|
});
|
|
|
}
|
|
|
+ // let currentIndex = text.length;
|
|
|
+ // let lastIndex = 0
|
|
|
+ // var startCode = text.slice(currentIndex).startsWith('```')
|
|
|
+ // if(!this.startCode && startCode){
|
|
|
+ // this.startCode = true
|
|
|
+ // blocks.push({
|
|
|
+ // type: 'code',
|
|
|
+ // content: text.slice(currentIndex),
|
|
|
+ // isComplete: false
|
|
|
+ // });
|
|
|
+ // }else if(this.startCode && startCode){
|
|
|
+ // this.startCode = false
|
|
|
+ // }else{
|
|
|
+ // blocks.push({
|
|
|
+ // type: 'text',
|
|
|
+ // content: text.slice(currentIndex),
|
|
|
+ // isComplete: false
|
|
|
+ // });
|
|
|
+ // }
|
|
|
|
|
|
return blocks;
|
|
|
},
|
|
|
renderMarkdown(text) {
|
|
|
+ if(!text){
|
|
|
+ return '';
|
|
|
+ }
|
|
|
// 只渲染非代码块的文本
|
|
|
return this.md.render(text);
|
|
|
},
|