Commit 1d2038af by Liu

fix:流式输出null处理为\n

parent 84d29dc3
...@@ -142,7 +142,7 @@ export const Chat: React.FC = () => { ...@@ -142,7 +142,7 @@ export const Chat: React.FC = () => {
const lastIndex = newItems.length - 1 const lastIndex = newItems.length - 1
if (lastIndex >= 0) { if (lastIndex >= 0) {
// 创建最后一项的新对象,合并现有数据和新的 answer // 创建最后一项的新对象,合并现有数据和新的 answer
const originalAnswer = (newItems[lastIndex].answerList?.[0]?.answer || '') + msg.content.data.answer const originalAnswer = (newItems[lastIndex].answerList?.[0]?.answer || '') + (msg.content.data.answer ?? '\n')
// 移除所有括号及其内容 // 移除所有括号及其内容
let filteredAnswer = originalAnswer.replace(/\([^)]*\)/g, '') let filteredAnswer = originalAnswer.replace(/\([^)]*\)/g, '')
// 去除 [参考文档《任意内容》 《任意内容》...] 格式的内容 // 去除 [参考文档《任意内容》 《任意内容》...] 格式的内容
......
...@@ -236,8 +236,8 @@ export const TacticsChat: React.FC = () => { ...@@ -236,8 +236,8 @@ export const TacticsChat: React.FC = () => {
prevItems: prevItems.map(item => ({ role: item.role, hasAnswer: !!item.answerList?.[0]?.answer })), prevItems: prevItems.map(item => ({ role: item.role, hasAnswer: !!item.answerList?.[0]?.answer })),
}) })
if (lastAiIndex >= 0) { if (lastAiIndex >= 0) {
// 确保 answer 字段存在,如果不存在则使用空字符串 // 确保 answer 字段存在,如果不存在则使用空字符串,null 替换为 \n
const newAnswer = msg.content?.data?.answer || '' const newAnswer = msg.content?.data?.answer ?? '\n'
// 创建最后一项的新对象,合并现有数据和新的 answer // 创建最后一项的新对象,合并现有数据和新的 answer
const existingAnswer = newItems[lastAiIndex].answerList?.[0]?.answer || '' const existingAnswer = newItems[lastAiIndex].answerList?.[0]?.answer || ''
const originalAnswer = existingAnswer + newAnswer const originalAnswer = existingAnswer + newAnswer
...@@ -272,7 +272,7 @@ export const TacticsChat: React.FC = () => { ...@@ -272,7 +272,7 @@ export const TacticsChat: React.FC = () => {
// 如果没有找到 AI 项,创建一个新的 AI 项 // 如果没有找到 AI 项,创建一个新的 AI 项
console.warn('[TacticsChat] handleStreamMesageData: no AI item found, creating new one') console.warn('[TacticsChat] handleStreamMesageData: no AI item found, creating new one')
const newAnswer = msg.content?.data?.answer || '' const newAnswer = msg.content?.data?.answer ?? '\n'
// 移除 ♪ 符号之后的所有文本(与历史记录保持一致) // 移除 ♪ 符号之后的所有文本(与历史记录保持一致)
let filteredAnswer = newAnswer.split('♪')[0] let filteredAnswer = newAnswer.split('♪')[0]
// 移除所有括号及其内容 // 移除所有括号及其内容
......
...@@ -8,7 +8,7 @@ import { QuestionList } from './components/QuestionList' ...@@ -8,7 +8,7 @@ import { QuestionList } from './components/QuestionList'
import HomeIcon2 from '@/assets/homeIcon2.png' import HomeIcon2 from '@/assets/homeIcon2.png'
import SmartIce from '@/assets/smart-ice.png' import SmartIce from '@/assets/smart-ice.png'
import { clearCurrentToolId, fetchConversations, setCurrentConversation, setCurrentToolId, setNavigationFlag } from '@/store/conversationSlice' import { clearCurrentToolId, fetchConversations, setCurrentConversation, setCurrentToolId, setNavigationFlag } from '@/store/conversationSlice'
import { useAppDispatch } from '@/store/hook' import { useAppDispatch, useAppSelector } from '@/store/hook'
import { fetchEfficiencyQuestionList } from '@/api/home' import { fetchEfficiencyQuestionList } from '@/api/home'
import SdreamLoading from '@/components/SdreamLoading' import SdreamLoading from '@/components/SdreamLoading'
import { fetchLoginByToken, fetchLoginByUid } from '@/api/common' import { fetchLoginByToken, fetchLoginByUid } from '@/api/common'
...@@ -67,6 +67,7 @@ export const Home: React.FC = () => { ...@@ -67,6 +67,7 @@ export const Home: React.FC = () => {
const [isDataLoaded, setIsDataLoaded] = useState(false) const [isDataLoaded, setIsDataLoaded] = useState(false)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const location = useLocation() const location = useLocation()
const currentConversationId = useAppSelector(state => state.conversation.currentConversationId)
const hasFetched = useRef(false) const hasFetched = useRef(false)
const hasCalledBusinessApis = useRef(false) // 防止业务接口重复调用 const hasCalledBusinessApis = useRef(false) // 防止业务接口重复调用
const prevPathRef = useRef<string>(location.pathname) // 记录上一次路径,用于检测从收藏页面返回 const prevPathRef = useRef<string>(location.pathname) // 记录上一次路径,用于检测从收藏页面返回
...@@ -86,7 +87,7 @@ export const Home: React.FC = () => { ...@@ -86,7 +87,7 @@ export const Home: React.FC = () => {
}) })
// 获取会话ID并加载历史记录 // 获取会话ID并加载历史记录
const getSessionConversationId = async (data?: any) => { const getSessionConversationId = async (data?: any): Promise<string | null> => {
try { try {
// 等待 token 就绪后再调用接口 // 等待 token 就绪后再调用接口
await waitForToken() await waitForToken()
...@@ -104,16 +105,18 @@ export const Home: React.FC = () => { ...@@ -104,16 +105,18 @@ export const Home: React.FC = () => {
// 历史记录会在 Chat 页面自动渲染,不需要在这里获取 // 历史记录会在 Chat 页面自动渲染,不需要在这里获取
// 移除重复调用,避免接口被调用两次 // 移除重复调用,避免接口被调用两次
return conversationId
} }
return null
} }
catch (error) { catch (error) {
console.error('获取会话ID失败:', error) console.error('获取会话ID失败:', error)
return null
} }
} }
// 刷新问题列表 // 刷新问题列表
const handleRefreshQuestions = useCallback(async () => { const handleRefreshQuestions = useCallback(async () => {
console.log('[HomeNew] handleRefreshQuestions 开始调用 - 刷新常见问题列表')
// 先清空旧数据 // 先清空旧数据
setOtherQuestions((prev: any) => ({ setOtherQuestions((prev: any) => ({
...prev, ...prev,
...@@ -126,10 +129,8 @@ export const Home: React.FC = () => { ...@@ -126,10 +129,8 @@ export const Home: React.FC = () => {
const conversationId = location.pathname.startsWith('/chat/') const conversationId = location.pathname.startsWith('/chat/')
? location.pathname.split('/')[2] ? location.pathname.split('/')[2]
: null : null
console.log('[HomeNew] handleRefreshQuestions - 当前 conversationId:', conversationId)
if (!conversationId) { if (!conversationId) {
console.warn('[HomeNew] handleRefreshQuestions - conversationId 不存在,跳过接口调用')
setIsDataLoaded(true) setIsDataLoaded(true)
return return
} }
...@@ -140,15 +141,11 @@ export const Home: React.FC = () => { ...@@ -140,15 +141,11 @@ export const Home: React.FC = () => {
recordType: 'A14', recordType: 'A14',
}) })
if (res && res.data && res.data.questions) { if (res && res.data && res.data.questions) {
console.log('[HomeNew] handleRefreshQuestions - 获取到问题数量:', res.data.questions.length)
setOtherQuestions((prev: any) => ({ setOtherQuestions((prev: any) => ({
...prev, ...prev,
content: res.data.questions || [], content: res.data.questions || [],
})) }))
} }
else {
console.log('[HomeNew] handleRefreshQuestions - 未获取到问题数据')
}
} }
catch (error) { catch (error) {
console.error('[HomeNew] handleRefreshQuestions - 刷新问题列表失败:', error) console.error('[HomeNew] handleRefreshQuestions - 刷新问题列表失败:', error)
...@@ -156,12 +153,11 @@ export const Home: React.FC = () => { ...@@ -156,12 +153,11 @@ export const Home: React.FC = () => {
} }
finally { finally {
setIsDataLoaded(true) // 无论成功失败都标记为已加载 setIsDataLoaded(true) // 无论成功失败都标记为已加载
console.log('[HomeNew] handleRefreshQuestions - 调用完成')
} }
}, [location.search]) }, [location.search])
// 处理工具按钮点击 // 处理工具按钮点击
const _handleToolClick = useCallback(async (isToolBtn: boolean, toolId?: string, ignoreUrlToolId?: boolean) => { const _handleToolClick = useCallback(async (isToolBtn: boolean, toolId?: string, ignoreUrlToolId?: boolean, conversationIdParam?: string | null) => {
// 提质增效模式 / 数据助手 / 制度活化:都先清空数据,重新拉常见问题 // 提质增效模式 / 数据助手 / 制度活化:都先清空数据,重新拉常见问题
setOtherQuestions((prev: any) => ({ setOtherQuestions((prev: any) => ({
...prev, ...prev,
...@@ -188,13 +184,12 @@ export const Home: React.FC = () => { ...@@ -188,13 +184,12 @@ export const Home: React.FC = () => {
finalToolId = storedToolId finalToolId = storedToolId
} }
// 从路由中获取 conversationId // 优先使用传入的 conversationId,其次从 Redux 获取,最后从路由中获取
const conversationId = location.pathname.startsWith('/chat/') const conversationId = conversationIdParam || currentConversationId || (location.pathname.startsWith('/chat/')
? location.pathname.split('/')[2] ? location.pathname.split('/')[2]
: null : null)
if (!conversationId) { if (!conversationId) {
console.warn('[HomeNew] _handleToolClick - conversationId 不存在,跳过接口调用')
setIsDataLoaded(true) setIsDataLoaded(true)
return return
} }
...@@ -218,7 +213,7 @@ export const Home: React.FC = () => { ...@@ -218,7 +213,7 @@ export const Home: React.FC = () => {
finally { finally {
setIsDataLoaded(true) // 无论成功失败都标记为已加载 setIsDataLoaded(true) // 无论成功失败都标记为已加载
} }
}, [originalOtherQuestions, location.search, location.pathname]) }, [originalOtherQuestions, location.search, location.pathname, currentConversationId])
// 监听工具按钮点击事件 // 监听工具按钮点击事件
useEffect(() => { useEffect(() => {
...@@ -249,16 +244,12 @@ export const Home: React.FC = () => { ...@@ -249,16 +244,12 @@ export const Home: React.FC = () => {
// 监听从收藏返回时刷新问题列表的事件 // 监听从收藏返回时刷新问题列表的事件
useEffect(() => { useEffect(() => {
const handleRefreshQuestionsFromCollect = (event: CustomEvent) => { const handleRefreshQuestionsFromCollect = (event: CustomEvent) => {
console.log('[HomeNew] 监听到 refreshQuestionsFromCollect 事件 - 从收藏页面返回')
const { toolId } = event.detail const { toolId } = event.detail
console.log('[HomeNew] refreshQuestionsFromCollect - 接收到的 toolId:', toolId)
// 如果传递了 toolId,先更新 sessionStorage,确保刷新时使用正确的 toolId // 如果传递了 toolId,先更新 sessionStorage,确保刷新时使用正确的 toolId
if (toolId) { if (toolId) {
console.log('[HomeNew] refreshQuestionsFromCollect - 更新 sessionStorage 中的 currentToolId:', toolId)
safeSessionStorageSetItem('currentToolId', toolId) safeSessionStorageSetItem('currentToolId', toolId)
} }
// 刷新问题列表,会调用 generate_question 接口 // 刷新问题列表,会调用 generate_question 接口
console.log('[HomeNew] refreshQuestionsFromCollect - 开始调用 handleRefreshQuestions')
handleRefreshQuestions() handleRefreshQuestions()
} }
window.addEventListener('refreshQuestionsFromCollect', handleRefreshQuestionsFromCollect as EventListener) window.addEventListener('refreshQuestionsFromCollect', handleRefreshQuestionsFromCollect as EventListener)
...@@ -270,7 +261,6 @@ export const Home: React.FC = () => { ...@@ -270,7 +261,6 @@ export const Home: React.FC = () => {
const login = useCallback(async () => { const login = useCallback(async () => {
// 防止重复调用(组件级别保护,每次组件挂载时会重置,确保每次打开链接都能调用) // 防止重复调用(组件级别保护,每次组件挂载时会重置,确保每次打开链接都能调用)
if (hasFetched.current) { if (hasFetched.current) {
console.log('homeNew sso222222')
return return
} }
const url = new URL(window.location.href) const url = new URL(window.location.href)
...@@ -281,7 +271,6 @@ export const Home: React.FC = () => { ...@@ -281,7 +271,6 @@ export const Home: React.FC = () => {
// 如果有 loginCode,执行 SSO 登录(包括 from=tactics 的情况) // 如果有 loginCode,执行 SSO 登录(包括 from=tactics 的情况)
if (_loginCode && viteOutputObj === 'inner') { if (_loginCode && viteOutputObj === 'inner') {
console.log('homeNew sso333333')
// 立即设置标志,防止重复执行(仅组件级别,每次组件挂载时会重置) // 立即设置标志,防止重复执行(仅组件级别,每次组件挂载时会重置)
hasFetched.current = true hasFetched.current = true
// 每次进入页面调用 sso_login 时,先清空 sessionStorage 中的 currentToolId // 每次进入页面调用 sso_login 时,先清空 sessionStorage 中的 currentToolId
...@@ -290,7 +279,6 @@ export const Home: React.FC = () => { ...@@ -290,7 +279,6 @@ export const Home: React.FC = () => {
try { try {
const res = await fetchLoginByToken(_loginCode) const res = await fetchLoginByToken(_loginCode)
if (res.data) { if (res.data) {
console.log('homeNew sso444444')
// 登录成功后先清理旧状态,避免沿用上一次的工具模式 // 登录成功后先清理旧状态,避免沿用上一次的工具模式
dispatch(clearCurrentToolId()) dispatch(clearCurrentToolId())
safeSessionStorageRemoveItem('currentToolId') safeSessionStorageRemoveItem('currentToolId')
...@@ -359,10 +347,10 @@ export const Home: React.FC = () => { ...@@ -359,10 +347,10 @@ export const Home: React.FC = () => {
hasCalledBusinessApis.current = true hasCalledBusinessApis.current = true
// 触发自定义事件,通知 ChatEditor 强制重置为制度活化 // 触发自定义事件,通知 ChatEditor 强制重置为制度活化
window.dispatchEvent(new CustomEvent('forceResetToGeneralMode')) window.dispatchEvent(new CustomEvent('forceResetToGeneralMode'))
getSessionConversationId() const conversationId = await getSessionConversationId()
dispatch(fetchConversations()) dispatch(fetchConversations())
// 2. 拉取常见问题等业务数据 // 2. 拉取常见问题等业务数据
_handleToolClick(false, '', true) _handleToolClick(false, '', true, conversationId)
} }
} }
} }
...@@ -389,8 +377,11 @@ export const Home: React.FC = () => { ...@@ -389,8 +377,11 @@ export const Home: React.FC = () => {
await fetchCheckTokenApi() await fetchCheckTokenApi()
// token 验证成功,调用业务接口 // token 验证成功,调用业务接口
hasCalledBusinessApis.current = true hasCalledBusinessApis.current = true
getSessionConversationId() // 等待获取会话ID后再调用 _handleToolClick
const conversationId = await getSessionConversationId()
dispatch(fetchConversations()) dispatch(fetchConversations())
// 拉取常见问题等业务数据
_handleToolClick(false, '', true, conversationId)
} }
catch (error) { catch (error) {
// token 验证失败,不调用业务接口 // token 验证失败,不调用业务接口
...@@ -469,10 +460,10 @@ export const Home: React.FC = () => { ...@@ -469,10 +460,10 @@ export const Home: React.FC = () => {
hasCalledBusinessApis.current = true hasCalledBusinessApis.current = true
// 触发自定义事件,通知 ChatEditor 强制重置为制度活化 // 触发自定义事件,通知 ChatEditor 强制重置为制度活化
window.dispatchEvent(new CustomEvent('forceResetToGeneralMode')) window.dispatchEvent(new CustomEvent('forceResetToGeneralMode'))
getSessionConversationId() const conversationId = await getSessionConversationId()
dispatch(fetchConversations()) dispatch(fetchConversations())
// 2. 拉取常见问题等业务数据 // 2. 拉取常见问题等业务数据
_handleToolClick(false, '', true) _handleToolClick(false, '', true, conversationId)
} }
} }
} }
......
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