feat: 停止的时候处理

This commit is contained in:
2025-09-09 23:13:33 +08:00
parent 6fc01a1bd5
commit 35abfea922
2 changed files with 62 additions and 35 deletions

View File

@@ -256,8 +256,9 @@ const handleScrollToLower = () => {};
// 滚动到底部 - 优化版本,确保打字机效果始终可见 // 滚动到底部 - 优化版本,确保打字机效果始终可见
const scrollToBottom = () => { const scrollToBottom = () => {
nextTick(() => { nextTick(() => {
// 使用更大的值确保滚动到真正的底部
scrollTop.value = 99999; scrollTop.value = 99999;
// 强制触发滚动更新 // 强制触发滚动更新增加延迟确保DOM更新完成
setTimeout(() => { setTimeout(() => {
scrollTop.value = scrollTop.value + Math.random(); scrollTop.value = scrollTop.value + Math.random();
}, 10); }, 10);
@@ -538,7 +539,6 @@ const initTypewriterManager = () => {
typewriterManager.setCallbacks({ typewriterManager.setCallbacks({
// 每个字符打字时的回调 // 每个字符打字时的回调
onCharacterTyped: (displayedContent) => { onCharacterTyped: (displayedContent) => {
// 只有在用户没有滚动时才自动滚动到底部
scrollToBottom(); scrollToBottom();
}, },
// 内容更新时的回调 // 内容更新时的回调
@@ -671,30 +671,38 @@ const stopRequest = () => {
// 发送中断消息给服务器 (messageType=2) // 发送中断消息给服务器 (messageType=2)
sendWebSocketMessage(2, "stop_request", { silent: true }); sendWebSocketMessage(2, "stop_request", { silent: true });
// 停止打字机效果 // 停止打字机效果并保留当前内容
if (typewriterManager) { if (typewriterManager) {
typewriterManager.stopTypewriter(); // 获取当前已显示的内容
} const currentStatus = typewriterManager.getStatus();
const currentDisplayedContent = currentStatus.displayedContent;
// 重置会话状态和消息状态 // 使用新的方法停止并保留当前内容
isSessionActive.value = false; typewriterManager.stopAndKeepCurrent();
resetMessageState();
// 更新最后一条AI消息的状态 // 更新最后一条AI消息的状态
const aiMsgIndex = chatMsgList.value.length - 1; const aiMsgIndex = chatMsgList.value.length - 1;
if (
chatMsgList.value[aiMsgIndex] &&
chatMsgList.value[aiMsgIndex].msgType === MessageRole.AI
) {
chatMsgList.value[aiMsgIndex].isLoading = false;
if ( if (
!chatMsgList.value[aiMsgIndex].msg || chatMsgList.value[aiMsgIndex] &&
chatMsgList.value[aiMsgIndex].msg.startsWith("加载中") chatMsgList.value[aiMsgIndex].msgType === MessageRole.AI
) { ) {
chatMsgList.value[aiMsgIndex].msg = "请求已停止"; chatMsgList.value[aiMsgIndex].isLoading = false;
// 如果有已显示的内容,使用已显示的内容,否则显示停止消息
if (
currentDisplayedContent &&
currentDisplayedContent.trim() &&
!currentDisplayedContent.startsWith("加载中")
) {
chatMsgList.value[aiMsgIndex].msg = currentDisplayedContent;
} else {
chatMsgList.value[aiMsgIndex].msg = "请求已停止";
}
} }
} }
// 重置会话状态(但不重置消息状态,保留已显示内容)
isSessionActive.value = false;
console.log("请求已停止,状态已重置"); console.log("请求已停止,状态已重置");
setTimeoutScrollToBottom(); setTimeoutScrollToBottom();

View File

@@ -7,8 +7,8 @@ class TypewriterManager {
// 配置选项 // 配置选项
this.options = { this.options = {
typingSpeed: 50, // 打字速度(毫秒) typingSpeed: 50, // 打字速度(毫秒)
cursorText: '', // 光标样式 cursorText: "", // 光标样式
...options ...options,
}; };
// 状态变量 // 状态变量
@@ -41,11 +41,11 @@ class TypewriterManager {
* @param {string} content - 要添加的内容 * @param {string} content - 要添加的内容
*/ */
addContent(content) { addContent(content) {
if (typeof content !== 'string') { if (typeof content !== "string") {
content = String(content); content = String(content);
} }
this.currentMessageContent += content; this.currentMessageContent += content;
// 如果没有在打字,启动打字机效果 // 如果没有在打字,启动打字机效果
if (!this.isTyping) { if (!this.isTyping) {
this.startTypewriter(); this.startTypewriter();
@@ -70,18 +70,22 @@ class TypewriterManager {
_typeNextChar() { _typeNextChar() {
// 如果已显示内容长度小于完整内容长度,继续打字 // 如果已显示内容长度小于完整内容长度,继续打字
if (this.displayedContent.length < this.currentMessageContent.length) { if (this.displayedContent.length < this.currentMessageContent.length) {
const nextLength = Math.min(
this.displayedContent.length + 1,
this.currentMessageContent.length
);
this.displayedContent = this.currentMessageContent.substring( this.displayedContent = this.currentMessageContent.substring(
0, 0,
this.displayedContent.length + 1 nextLength
); );
const displayContent = this.displayedContent; const displayContent = this.displayedContent;
// 调用内容更新回调 // 调用内容更新回调
if (this.onContentUpdate) { if (this.onContentUpdate) {
this.onContentUpdate(displayContent); this.onContentUpdate(displayContent);
} }
// 调用字符打字回调 // 调用字符打字回调
if (this.onCharacterTyped) { if (this.onCharacterTyped) {
this.onCharacterTyped(this.displayedContent); this.onCharacterTyped(this.displayedContent);
@@ -92,18 +96,17 @@ class TypewriterManager {
this.typewriterTimer = setTimeout(() => { this.typewriterTimer = setTimeout(() => {
this._typeNextChar(); this._typeNextChar();
}, delay); }, delay);
} else { } else {
// 打字完成,移除光标 // 打字完成,移除光标
if (this.onContentUpdate) { if (this.onContentUpdate) {
this.onContentUpdate(this.currentMessageContent); this.onContentUpdate(this.currentMessageContent);
} }
// 调用打字完成回调 // 调用打字完成回调
if (this.onTypingComplete) { if (this.onTypingComplete) {
this.onTypingComplete(this.currentMessageContent); this.onTypingComplete(this.currentMessageContent);
} }
this.stopTypewriter(); this.stopTypewriter();
} }
} }
@@ -119,6 +122,21 @@ class TypewriterManager {
this.isTyping = false; this.isTyping = false;
} }
/**
* 停止打字机效果并保留当前显示的内容
* 与stopTypewriter不同这个方法会将当前显示的内容设为最终内容
*/
stopAndKeepCurrent() {
this.stopTypewriter();
// 将当前显示的内容设为完整内容,避免后续添加更多内容
this.currentMessageContent = this.displayedContent;
// 调用完成回调
if (this.onTypingComplete) {
this.onTypingComplete(this.displayedContent);
}
}
/** /**
* 重置打字机状态 * 重置打字机状态
*/ */
@@ -137,9 +155,10 @@ class TypewriterManager {
isTyping: this.isTyping, isTyping: this.isTyping,
currentContent: this.currentMessageContent, currentContent: this.currentMessageContent,
displayedContent: this.displayedContent, displayedContent: this.displayedContent,
progress: this.currentMessageContent.length > 0 progress:
? this.displayedContent.length / this.currentMessageContent.length this.currentMessageContent.length > 0
: 0 ? this.displayedContent.length / this.currentMessageContent.length
: 0,
}; };
} }
@@ -149,11 +168,11 @@ class TypewriterManager {
completeImmediately() { completeImmediately() {
this.stopTypewriter(); this.stopTypewriter();
this.displayedContent = this.currentMessageContent; this.displayedContent = this.currentMessageContent;
if (this.onContentUpdate) { if (this.onContentUpdate) {
this.onContentUpdate(this.currentMessageContent); this.onContentUpdate(this.currentMessageContent);
} }
if (this.onTypingComplete) { if (this.onTypingComplete) {
this.onTypingComplete(this.currentMessageContent); this.onTypingComplete(this.currentMessageContent);
} }
@@ -171,4 +190,4 @@ class TypewriterManager {
} }
} }
export default TypewriterManager; export default TypewriterManager;