对话逻辑修复
This commit is contained in:
+13
-20
@@ -173,28 +173,21 @@ export const useChatStore = defineStore('chat', () => {
|
||||
return segments
|
||||
}
|
||||
|
||||
// 添加AI回复消息(支持分段显示)
|
||||
const addAiReplyMessages = (content: string, delay: number = 1000) => {
|
||||
const segments = splitAiReply(content)
|
||||
// 添加AI回复消息(直接显示完整内容)
|
||||
const addAiReplyMessages = (content: string) => {
|
||||
// 停止输入状态
|
||||
isTyping.value = false
|
||||
|
||||
segments.forEach((segment, index) => {
|
||||
setTimeout(() => {
|
||||
const aiMessage = addMessage({
|
||||
content: segment.trim(),
|
||||
type: 'ai',
|
||||
sessionId: currentSession.value?.id
|
||||
})
|
||||
|
||||
// 强制触发响应式更新
|
||||
console.log('AI消息已添加,当前消息总数:', messages.value.length)
|
||||
console.log('最新AI消息:', aiMessage)
|
||||
|
||||
// 最后一条消息后停止输入状态
|
||||
if (index === segments.length - 1) {
|
||||
isTyping.value = false
|
||||
}
|
||||
}, index * delay)
|
||||
// 直接添加完整的AI回复
|
||||
const aiMessage = addMessage({
|
||||
content: content.trim(),
|
||||
type: 'ai',
|
||||
sessionId: currentSession.value?.id
|
||||
})
|
||||
|
||||
// 强制触发响应式更新
|
||||
console.log('AI消息已添加,当前消息总数:', messages.value.length)
|
||||
console.log('最新AI消息:', aiMessage)
|
||||
}
|
||||
|
||||
// WebSocket消息处理
|
||||
|
||||
+169
-11
@@ -31,7 +31,10 @@
|
||||
</div>
|
||||
|
||||
<div class="header-right">
|
||||
<a-button type="text" @click="showHistory = true" class="action-btn">
|
||||
<a-button type="text" @click="testAPI" class="action-btn" style="margin-right: 8px;">
|
||||
测试API
|
||||
</a-button>
|
||||
<a-button type="text" @click="openHistoryDrawer" class="action-btn">
|
||||
<HistoryOutlined />
|
||||
</a-button>
|
||||
<a-button
|
||||
@@ -147,7 +150,7 @@
|
||||
placement="right"
|
||||
:width="400"
|
||||
class="history-drawer"
|
||||
@open="loadHistoryMessages(1)"
|
||||
@open="onHistoryDrawerOpen"
|
||||
>
|
||||
<div class="history-content">
|
||||
<div class="search-section">
|
||||
@@ -344,7 +347,7 @@
|
||||
messageInput.value = ''
|
||||
|
||||
await chatStore.sendMessage(content)
|
||||
scrollToBottom()
|
||||
forceScrollToBottom()
|
||||
}
|
||||
|
||||
// 获取连接状态文本
|
||||
@@ -374,14 +377,55 @@
|
||||
return '和开开说点什么...'
|
||||
}
|
||||
|
||||
const scrollToBottom = () => {
|
||||
const scrollToBottom = (smooth = true) => {
|
||||
nextTick(() => {
|
||||
if (chatMainRef.value) {
|
||||
chatMainRef.value.scrollTop = chatMainRef.value.scrollHeight
|
||||
if (smooth) {
|
||||
// 平滑滚动到底部
|
||||
chatMainRef.value.scrollTo({
|
||||
top: chatMainRef.value.scrollHeight,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
} else {
|
||||
// 立即滚动到底部
|
||||
chatMainRef.value.scrollTop = chatMainRef.value.scrollHeight
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 检查用户是否在聊天底部
|
||||
const isUserAtBottom = () => {
|
||||
if (!chatMainRef.value) return true
|
||||
|
||||
const { scrollTop, scrollHeight, clientHeight } = chatMainRef.value
|
||||
// 允许一些误差(50px),认为用户在底部
|
||||
return scrollHeight - scrollTop - clientHeight < 50
|
||||
}
|
||||
|
||||
// 智能滚动到底部(只有用户在底部时才滚动)
|
||||
const smartScrollToBottom = () => {
|
||||
if (isUserAtBottom()) {
|
||||
scrollToBottom(true)
|
||||
}
|
||||
}
|
||||
|
||||
// 强制滚动到底部(用于发送消息等场景)
|
||||
const forceScrollToBottom = () => {
|
||||
// 立即滚动
|
||||
scrollToBottom(false)
|
||||
|
||||
// 延迟滚动,确保内容完全渲染
|
||||
setTimeout(() => {
|
||||
scrollToBottom(true)
|
||||
}, 100)
|
||||
|
||||
// 再次延迟滚动,处理可能的异步内容
|
||||
setTimeout(() => {
|
||||
scrollToBottom(true)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
// 生成情绪记录总结
|
||||
const generateEmotionSummary = async () => {
|
||||
if (emotionSummaryLoading.value) return
|
||||
@@ -437,9 +481,64 @@
|
||||
})
|
||||
}
|
||||
|
||||
// 打开历史记录抽屉
|
||||
const openHistoryDrawer = async () => {
|
||||
console.log('点击聊天记录按钮')
|
||||
showHistory.value = true
|
||||
|
||||
// 确保抽屉打开后再加载数据
|
||||
await nextTick()
|
||||
await loadHistoryMessages(1)
|
||||
}
|
||||
|
||||
// 抽屉打开事件
|
||||
const onHistoryDrawerOpen = () => {
|
||||
console.log('聊天记录抽屉已打开,开始加载历史记录')
|
||||
loadHistoryMessages(1)
|
||||
}
|
||||
|
||||
// 测试API调用
|
||||
const testAPI = async () => {
|
||||
console.log('=== 开始测试API ===')
|
||||
|
||||
try {
|
||||
// 测试原始API调用
|
||||
console.log('1. 测试原始axios调用...')
|
||||
const token = localStorage.getItem('token')
|
||||
console.log('Token:', token ? `${token.substring(0, 20)}...` : 'null')
|
||||
|
||||
const response = await fetch('/api/message/user/page?current=1&size=5', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
console.log('原始响应状态:', response.status)
|
||||
const rawData = await response.json()
|
||||
console.log('原始响应数据:', rawData)
|
||||
|
||||
// 测试封装的API调用
|
||||
console.log('2. 测试封装的API调用...')
|
||||
const apiData = await messageApi.getUserMessages(1, 5)
|
||||
console.log('封装API返回数据:', apiData)
|
||||
|
||||
} catch (error) {
|
||||
console.error('API测试失败:', error)
|
||||
}
|
||||
|
||||
console.log('=== API测试完成 ===')
|
||||
}
|
||||
|
||||
// 加载历史记录
|
||||
const loadHistoryMessages = async (page = 1) => {
|
||||
if (historyLoading.value) return
|
||||
console.log('loadHistoryMessages 被调用,page:', page)
|
||||
|
||||
if (historyLoading.value) {
|
||||
console.log('已经在加载中,跳过')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
historyLoading.value = true
|
||||
@@ -448,13 +547,17 @@
|
||||
page,
|
||||
pageSize: historyPagination.value.pageSize,
|
||||
token: !!localStorage.getItem('token'),
|
||||
userInfo: userStore.userInfo
|
||||
userInfo: userStore.userInfo,
|
||||
apiUrl: `/message/user/page?current=${page}&size=${historyPagination.value.pageSize}`
|
||||
})
|
||||
|
||||
// 调用API获取用户消息(后端会从token中获取用户信息)
|
||||
console.log('正在调用 messageApi.getUserMessages...')
|
||||
const pageData = await messageApi.getUserMessages(page, historyPagination.value.pageSize)
|
||||
|
||||
console.log('API返回数据:', pageData)
|
||||
console.log('API调用成功,返回数据:', pageData)
|
||||
console.log('API返回数据类型:', typeof pageData)
|
||||
console.log('API返回数据结构:', Object.keys(pageData || {}))
|
||||
|
||||
if (page === 1) {
|
||||
historyMessages.value = pageData.records || []
|
||||
@@ -475,14 +578,24 @@
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载历史记录时发生错误:', error)
|
||||
console.error('错误详情:', {
|
||||
message: error.message,
|
||||
response: error.response,
|
||||
status: error.response?.status,
|
||||
data: error.response?.data
|
||||
})
|
||||
|
||||
// 显示用户友好的错误信息
|
||||
if (error.response?.status === 401) {
|
||||
console.log('认证失败,可能需要重新登录')
|
||||
// 可以在这里添加跳转到登录页的逻辑
|
||||
} else if (error.response?.status === 500) {
|
||||
console.log('服务器错误,请稍后重试')
|
||||
} else {
|
||||
console.log('未知错误:', error.message)
|
||||
}
|
||||
} finally {
|
||||
console.log('加载历史记录完成,设置 loading 为 false')
|
||||
historyLoading.value = false
|
||||
}
|
||||
}
|
||||
@@ -523,11 +636,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 监听消息变化,自动滚动到底部
|
||||
// 监听消息变化,智能滚动到底部
|
||||
watch(
|
||||
() => chatStore.messages.length,
|
||||
(newLength, oldLength) => {
|
||||
// 如果有新消息添加
|
||||
if (newLength > oldLength) {
|
||||
const lastMessage = chatStore.messages[chatStore.messages.length - 1]
|
||||
|
||||
// 如果是用户发送的消息,强制滚动
|
||||
if (lastMessage?.type === 'user') {
|
||||
forceScrollToBottom()
|
||||
} else {
|
||||
// 如果是AI回复,智能滚动(只有用户在底部时才滚动)
|
||||
smartScrollToBottom()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 监听最后一条消息的内容变化(处理AI回复的实时更新)
|
||||
watch(
|
||||
() => {
|
||||
scrollToBottom()
|
||||
const messages = chatStore.messages
|
||||
return messages.length > 0 ? messages[messages.length - 1]?.content : ''
|
||||
},
|
||||
(newContent, oldContent) => {
|
||||
// 如果最后一条消息内容发生变化(AI回复更新),智能滚动
|
||||
if (newContent !== oldContent && newContent) {
|
||||
smartScrollToBottom()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -567,7 +705,7 @@
|
||||
// 加载最近的聊天记录
|
||||
await loadRecentMessages()
|
||||
|
||||
scrollToBottom()
|
||||
forceScrollToBottom()
|
||||
})
|
||||
|
||||
// 组件卸载
|
||||
@@ -720,6 +858,26 @@
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: $spacing-lg;
|
||||
scroll-behavior: smooth; // 启用平滑滚动
|
||||
|
||||
// 确保滚动容器正确工作
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 3px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.messages-container {
|
||||
|
||||
Reference in New Issue
Block a user