Commit 25c91e1f by Liu

fix:策略/用户中心近入时隐藏收藏按钮

parent c02dfce9
......@@ -24,9 +24,8 @@
overflow: hidden;
}
.scrollable {
flex-direction: column-reverse;
align-items: center;
justify-content: flex-end;
flex-direction: column;
align-items: stretch;
display: flex;
overflow-x: hidden;
overflow-y: scroll;
......
import { Button, Tooltip } from '@heroui/react'
import { useRef, useState } from 'react'
import { useMemo, useRef, useState } from 'react'
import { useLocation } from 'react-router-dom'
import { useDebounceFn } from 'ahooks'
import type { Answer } from '@/types/chat'
......@@ -21,7 +21,20 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
const showToast = useToast()
const location = useLocation()
const searchParams = new URLSearchParams(location.search)
const isFromTactics = searchParams.get('from') === 'tactics'
// 路由未携带 from=tactics 时,兜底读取缓存的 tacticsMeta
const tacticsMetaFromStorage = useMemo(() => {
const raw = sessionStorage.getItem('tacticsMeta')
if (!raw)
return undefined
try {
return JSON.parse(raw)
}
catch {
return undefined
}
}, [])
const isFromTactics = searchParams.get('from') === 'tactics' || tacticsMetaFromStorage?.from === 'tactics'
const [isCollect, setIsCollect] = useState(answer.collectionFlag)
const [isLike, setIsLike] = useState(answer.feedbackStatus === '01')
const [isUnLike, setIsUnLike] = useState(answer.feedbackStatus === '02')
......@@ -140,7 +153,7 @@ export const ChatAnswerOperate: React.FC<ChatAnswerOperateProps> = ({ answer })
<Tooltip color="foreground" content="复制" className="capitalize">
<Button variant="light" isIconOnly aria-label="CopyIcon" onPress={handleCopy}><CopyIcon /></Button>
</Tooltip>
{/* 收藏(当路由未标记 from=tactics 时展示) */}
{/* 收藏(当路由未标记 from=tactics 时展示) */}
{!isFromTactics && (
<Tooltip color="foreground" content={isCollect ? '取消收藏' : '收藏'} className="capitalize">
<Button variant="light" isIconOnly aria-label="CollectIcon" onPress={handleCollect.run}>
......
......@@ -245,9 +245,19 @@ export const TacticsChat: React.FC = () => {
break
}
}
// eslint-disable-next-line no-console
console.log('[TacticsChat] handleStreamMesageData', {
lastAiIndex,
itemsLength: newItems.length,
msgData: msg.content?.data,
prevItems: prevItems.map(item => ({ role: item.role, hasAnswer: !!item.answerList?.[0]?.answer })),
})
if (lastAiIndex >= 0) {
// 确保 answer 字段存在,如果不存在则使用空字符串
const newAnswer = msg.content?.data?.answer || ''
// 创建最后一项的新对象,合并现有数据和新的 answer
const originalAnswer = (newItems[lastAiIndex].answerList?.[0]?.answer || '') + msg.content.data.answer
const existingAnswer = newItems[lastAiIndex].answerList?.[0]?.answer || ''
const originalAnswer = existingAnswer + newAnswer
// 移除所有括号及其内容
let filteredAnswer = originalAnswer.replace(/\([^)]*\)/g, '').trim()
// 去除 [参考文档《任意内容》 《任意内容》...] 格式的内容
......@@ -264,6 +274,31 @@ export const TacticsChat: React.FC = () => {
},
],
}
// eslint-disable-next-line no-console
console.log('[TacticsChat] handleStreamMesageData:updated', {
filteredAnswer,
answerList: newItems[lastAiIndex].answerList,
updatedItem: newItems[lastAiIndex],
})
}
else {
// 如果没有找到 AI 项,创建一个新的 AI 项
console.warn('[TacticsChat] handleStreamMesageData: no AI item found, creating new one')
const newAnswer = msg.content?.data?.answer || ''
let filteredAnswer = newAnswer.replace(/\([^)]*\)/g, '').trim()
filteredAnswer = filteredAnswer.replace(/\[参考文档(?:[^]*》\s*)+\]/g, '').trim()
newItems.push({
role: 'ai',
question,
answerList: [
{
...msg.content.data,
isShow: false,
answer: filteredAnswer,
},
],
} as ChatRecord)
}
return newItems
})
......@@ -418,6 +453,8 @@ export const TacticsChat: React.FC = () => {
if (msg?.type === 'DATA' && msg?.content?.code === '00000000') {
// eslint-disable-next-line no-console
console.log('[TacticsChat] handleSubmitQuestion:success', msg)
// eslint-disable-next-line no-console
console.log('[TacticsChat] handleSubmitQuestion:data', msg.content?.data)
handleStreamMesageData(msg, question || '')
}
if (msg?.type === 'DATA' && msg?.content?.code === '01010005') {
......@@ -464,12 +501,35 @@ export const TacticsChat: React.FC = () => {
}
return item
})
setAllItems(processedMessages)
// 使用函数式更新,避免覆盖正在进行的流式响应
setAllItems((prevItems) => {
// 如果当前有正在进行的流式响应(存在空的AI项),保留它们
const hasPendingAi = prevItems.some(item => item.role === 'ai' && (!item.answerList?.[0]?.answer || item.answerList[0].answer === ''))
if (hasPendingAi && processedMessages.length > 1) {
// 如果历史记录不为空,合并历史记录和正在进行的响应
const lastPendingAiIndex = prevItems.length - 1
const lastPendingAi = prevItems[lastPendingAiIndex]
if (lastPendingAi?.role === 'ai') {
return [...processedMessages, lastPendingAi]
}
}
return processedMessages
})
setHasCleared(false)
}
catch {
// 如果获取失败,至少显示欢迎语
setAllItems([{ role: 'system' } as ChatRecord])
setAllItems((prevItems) => {
const hasPendingAi = prevItems.some(item => item.role === 'ai' && (!item.answerList?.[0]?.answer || item.answerList[0].answer === ''))
if (hasPendingAi) {
const lastPendingAiIndex = prevItems.length - 1
const lastPendingAi = prevItems[lastPendingAiIndex]
if (lastPendingAi?.role === 'ai') {
return [{ role: 'system' } as ChatRecord, lastPendingAi]
}
}
return [{ role: 'system' } as ChatRecord]
})
setHasCleared(false)
setHistoryDividerIndex(null)
setHistoryDividerTime(null)
......@@ -750,7 +810,7 @@ export const TacticsChat: React.FC = () => {
duration: 0.3,
opacity: { duration: 0.1 },
}}
className={`${styles.scrollable} scrollbar-hide scroll-smooth flex-1 overflow-y-auto px-[16px]`}
className={`${styles.scrollable} scrollbar-hide scroll-smooth flex-1 overflow-y-auto px-[16px] min-h-0`}
>
<div className={`${styles.inter} pt-[8px] pb-[24px]`}>
{allItems.map((record, index) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment