Commit 80f578fa by Liu

chore: commit staged changes

parent 310b6cca
...@@ -2,43 +2,15 @@ import React, { useEffect, useRef, useState } from 'react' ...@@ -2,43 +2,15 @@ import React, { useEffect, useRef, useState } from 'react'
import { AnimatePresence, motion } from 'framer-motion' import { AnimatePresence, motion } from 'framer-motion'
import { Button, Tooltip } from '@heroui/react' import { Button, Tooltip } from '@heroui/react'
import { useLocalStorageState, useToggle } from 'ahooks' import { useLocalStorageState, useToggle } from 'ahooks'
import { useSearchParams } from 'react-router-dom' import { useLocation, useSearchParams } from 'react-router-dom'
import { LoginModal } from '../LoginModal' import { LoginModal } from '../LoginModal'
import type { RootState } from '@/store' import type { RootState } from '@/store'
import SendIcon from '@/assets/svg/send.svg?react' import SendIcon from '@/assets/svg/send.svg?react'
import { type WithAuthProps, withAuth } from '@/auth/withAuth' import { type WithAuthProps, withAuth } from '@/auth/withAuth'
import { useAppDispatch, useAppSelector } from '@/store/hook' import { useAppDispatch, useAppSelector } from '@/store/hook'
import { clearCurrentToolId, createConversation, setCurrentToolId } from '@/store/conversationSlice' import { clearCurrentToolId, createConversation, setCurrentToolId } from '@/store/conversationSlice'
// 本地 mock 工具列表,离线/联调阶段用于渲染按钮 import { fetchToolList } from '@/api/home'
const MOCK_TOOL_LIST = [ import { getUserRolesForApi, safeSessionStorageGetItem, safeSessionStorageRemoveItem, safeSessionStorageSetItem } from '@/lib/utils'
{
toolId: '6712395743241',
toolName: '提质增效',
toolContent: 'https://sit-wechat.guominpension.com/underwrite',
toolIcon: 'http://p-cf-co-1255000025.cos.bj.csyun001.ccbcos.co/tool-increase.svg',
toolType: '03',
userRole: '02',
showOrder: 8,
},
{
toolId: '6712395743240',
toolName: '数据助手',
toolContent: 'https://sit-wechat.guominpension.com/underwrite',
toolIcon: 'http://p-cf-co-1255000025.cos.bj.csyun001.ccbcos.co/tool-data.svg',
toolType: '03',
userRole: '01',
showOrder: 8,
},
{
toolId: 'general-mode',
toolName: '通用模式',
toolContent: 'https://sit-wechat.guominpension.com/underwrite',
toolIcon: 'http://p-cf-co-1255000025.cos.bj.csyun001.ccbcos.co/tool-normal.svg',
toolType: '01',
userRole: '00',
showOrder: 8,
},
] as const
interface ChatEditorProps { interface ChatEditorProps {
onChange?: (value: string) => void onChange?: (value: string) => void
...@@ -66,12 +38,25 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth, ...@@ -66,12 +38,25 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const [showToolQuestion, setShowToolQuestion] = useState<boolean>(false) const [showToolQuestion, setShowToolQuestion] = useState<boolean>(false)
const [sessionToolId, setSessionToolId] = useState<string | null>(null) const [sessionToolId, setSessionToolId] = useState<string | null>(null)
const [searchParams, setSearchParams] = useSearchParams() const [searchParams, setSearchParams] = useSearchParams()
const location = useLocation()
const toolIdFromUrl = searchParams.get('toolId') const toolIdFromUrl = searchParams.get('toolId')
// 获取工具列表 // 获取工具列表
const getToolList = async () => { const getToolList = async () => {
// 暂时启用本地 mock 数据,确保在无后端接口时也能渲染 try {
setToolList(MOCK_TOOL_LIST.map(tool => ({ ...tool }))) // 从路由中获取 userRoles 参数
const userRoles = getUserRolesForApi()
// eslint-disable-next-line no-console
console.log('[ChatEditor] 获取到的 userRoles 参数:', userRoles, '类型:', Array.isArray(userRoles) ? 'array' : typeof userRoles)
// 调用真实 API 获取工具列表
const res = await fetchToolList({ userRoles })
if (res?.data && Array.isArray(res.data) && res.data.length > 0) {
setToolList(res.data)
}
}
catch (error) {
console.error('获取工具列表失败:', error)
}
} }
// 根据 currentToolId 以及 sessionStorage 中的记录决定高亮逻辑 // 根据 currentToolId 以及 sessionStorage 中的记录决定高亮逻辑
...@@ -128,7 +113,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth, ...@@ -128,7 +113,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 监听 sessionStorage 中的 currentToolId(历史点击时写入)来辅助高亮逻辑 // 监听 sessionStorage 中的 currentToolId(历史点击时写入)来辅助高亮逻辑
useEffect(() => { useEffect(() => {
const syncSessionToolId = () => { const syncSessionToolId = () => {
const storedToolId = sessionStorage.getItem('currentToolId') const storedToolId = safeSessionStorageGetItem('currentToolId')
// 如果 currentToolId 是空字符串,视为 null,确保通用模式能正确高亮 // 如果 currentToolId 是空字符串,视为 null,确保通用模式能正确高亮
setSessionToolId(storedToolId && storedToolId.trim() ? storedToolId : null) setSessionToolId(storedToolId && storedToolId.trim() ? storedToolId : null)
} }
...@@ -157,7 +142,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth, ...@@ -157,7 +142,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 当路由变化时,同步更新 sessionToolId(因为 storage 事件不会在同标签页触发) // 当路由变化时,同步更新 sessionToolId(因为 storage 事件不会在同标签页触发)
useEffect(() => { useEffect(() => {
const storedToolId = sessionStorage.getItem('currentToolId') const storedToolId = safeSessionStorageGetItem('currentToolId')
// 如果 currentToolId 是空字符串,视为 null,确保通用模式能正确高亮 // 如果 currentToolId 是空字符串,视为 null,确保通用模式能正确高亮
setSessionToolId(storedToolId && storedToolId.trim() ? storedToolId : null) setSessionToolId(storedToolId && storedToolId.trim() ? storedToolId : null)
}, [toolIdFromUrl]) }, [toolIdFromUrl])
...@@ -237,8 +222,8 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth, ...@@ -237,8 +222,8 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 立即更新本地状态,让 UI 立即响应 // 立即更新本地状态,让 UI 立即响应
setIsToolBtnActive(true) setIsToolBtnActive(true)
setSelectedToolId(null) setSelectedToolId(null)
sessionStorage.removeItem('showToolQuestion') safeSessionStorageRemoveItem('showToolQuestion')
sessionStorage.removeItem('currentToolId') safeSessionStorageRemoveItem('currentToolId')
setSessionToolId(null) setSessionToolId(null)
setShowToolQuestion(false) setShowToolQuestion(false)
// 清空路由中的 toolId 参数 // 清空路由中的 toolId 参数
...@@ -262,37 +247,19 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth, ...@@ -262,37 +247,19 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 处理工具按钮点击:先创建新会话,再切换工具 // 处理工具按钮点击:先创建新会话,再切换工具
const handleToolClick = async (tool: any) => { const handleToolClick = async (tool: any) => {
// if (!checkAuth())
// return
// 调试:点击时记录当前与将要设置的 toolId,排查选中状态是否被覆盖
// eslint-disable-next-line no-console
console.log('[ChatEditor] handleToolClick 点击前:', {
clickToolId: tool.toolId,
toolName: tool.toolName,
selectedToolId,
sessionToolId,
currentToolIdInRedux: currentToolId,
})
if (tool.toolName === '数据助手') { if (tool.toolName === '数据助手') {
sessionStorage.setItem('showToolQuestion', 'true') safeSessionStorageSetItem('showToolQuestion', 'true')
setShowToolQuestion(true) setShowToolQuestion(true)
} }
else { else {
sessionStorage.removeItem('showToolQuestion') safeSessionStorageRemoveItem('showToolQuestion')
setShowToolQuestion(false) setShowToolQuestion(false)
} }
dispatch(setCurrentToolId(tool.toolId)) dispatch(setCurrentToolId(tool.toolId))
setSelectedToolId(tool.toolId) setSelectedToolId(tool.toolId)
setIsToolBtnActive(false) setIsToolBtnActive(false)
sessionStorage.setItem('currentToolId', tool.toolId) safeSessionStorageSetItem('currentToolId', tool.toolId)
setSessionToolId(tool.toolId) setSessionToolId(tool.toolId)
// eslint-disable-next-line no-console
console.log('[ChatEditor] handleToolClick 点击后(已设置选中):', {
clickToolId: tool.toolId,
toolName: tool.toolName,
selectedToolIdAfterSet: tool.toolId,
sessionToolIdAfterSet: tool.toolId,
})
try { try {
await dispatch(createConversation({ await dispatch(createConversation({
conversationData: { toolId: tool.toolId }, conversationData: { toolId: tool.toolId },
...@@ -321,15 +288,15 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth, ...@@ -321,15 +288,15 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
} }
}, [content]) }, [content])
// 组件加载时获取工具列表 // 组件加载时和路由参数变化时获取工具列表
useEffect(() => { useEffect(() => {
getToolList() getToolList()
}, []) }, [location.pathname, location.search])
// 监听 sessionStorage 中的 showToolQuestion // 监听 sessionStorage 中的 showToolQuestion
useEffect(() => { useEffect(() => {
const checkShowToolQuestion = () => { const checkShowToolQuestion = () => {
const value = sessionStorage.getItem('showToolQuestion') const value = safeSessionStorageGetItem('showToolQuestion')
setShowToolQuestion(value === 'true') setShowToolQuestion(value === 'true')
} }
checkShowToolQuestion() checkShowToolQuestion()
...@@ -434,17 +401,6 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth, ...@@ -434,17 +401,6 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 通用模式高亮:路由内没有 toolId 或 toolId 为空时默认高亮,点击后也要高亮 // 通用模式高亮:路由内没有 toolId 或 toolId 为空时默认高亮,点击后也要高亮
const isGeneralMode = tool.toolName === '通用模式' && isToolBtnActive && !selectedToolId && !sessionToolId && !toolIdFromUrl const isGeneralMode = tool.toolName === '通用模式' && isToolBtnActive && !selectedToolId && !sessionToolId && !toolIdFromUrl
const isSelected = isSelectedByState || isSelectedBySession || isSelectedByUrl || isGeneralMode const isSelected = isSelectedByState || isSelectedBySession || isSelectedByUrl || isGeneralMode
// 调试打印
if (index === 0 || selectedToolId === tool.toolId) {
// eslint-disable-next-line no-console
console.log('[ChatEditor] 按钮渲染:', {
toolName: tool.toolName,
toolId: tool.toolId,
selectedToolId,
isSelected,
isToolBtnActive,
})
}
const baseBtnClass const baseBtnClass
= 'w-auto h-[32px] px-3 rounded-full shadow-none text-[12px] flex items-center gap-2 transition-all duration-200 border' = 'w-auto h-[32px] px-3 rounded-full shadow-none text-[12px] flex items-center gap-2 transition-all duration-200 border'
......
...@@ -7,6 +7,73 @@ export function cn(...inputs: ClassValue[]) { ...@@ -7,6 +7,73 @@ export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)) return twMerge(clsx(inputs))
} }
/**
* 安全地访问 sessionStorage
* 在无痕模式或存储被禁用时返回 null,避免抛出错误
*/
export function safeSessionStorageGetItem(key: string): string | null {
try {
return sessionStorage.getItem(key)
}
catch {
// 在无痕模式或存储被禁用时,静默失败
return null
}
}
/**
* 安全地设置 sessionStorage
* 在无痕模式或存储被禁用时静默失败
*/
export function safeSessionStorageSetItem(key: string, value: string): void {
try {
sessionStorage.setItem(key, value)
}
catch {
// 在无痕模式或存储被禁用时,静默失败
}
}
/**
* 安全地删除 sessionStorage
* 在无痕模式或存储被禁用时静默失败
*/
export function safeSessionStorageRemoveItem(key: string): void {
try {
sessionStorage.removeItem(key)
}
catch {
// 在无痕模式或存储被禁用时,静默失败
}
}
/**
* 安全地访问 localStorage
* 在无痕模式或存储被禁用时返回 null,避免抛出错误
*/
export function safeLocalStorageGetItem(key: string): string | null {
try {
return localStorage.getItem(key)
}
catch {
// 在无痕模式或存储被禁用时,静默失败
return null
}
}
/**
* 安全地设置 localStorage
* 在无痕模式或存储被禁用时静默失败
*/
export function safeLocalStorageSetItem(key: string, value: string): void {
try {
localStorage.setItem(key, value)
}
catch {
// 在无痕模式或存储被禁用时,静默失败
}
}
const USER_ROLES_STORAGE_KEY = '__USER_ROLES__' const USER_ROLES_STORAGE_KEY = '__USER_ROLES__'
/** /**
...@@ -35,20 +102,105 @@ function getQueryBeforeSecondQuestion(): string { ...@@ -35,20 +102,105 @@ function getQueryBeforeSecondQuestion(): string {
} }
/** /**
* 从路径中提取查询字符串(支持参数作为路径一部分的情况)
* 例如:/home/userRoles=00&&userRoles=01&&loginCode=2392039
* @returns 返回查询字符串,格式为 key=value&key=value
*/
function extractQueryStringFromPath(): string {
try {
const pathname = window.location.pathname || ''
// 如果路径中包含 = 符号,说明参数可能作为路径的一部分
if (pathname.includes('=')) {
// 找到最后一个 / 之后的内容
// 例如:/home/userRoles=00&&userRoles=01 提取 userRoles=00&&userRoles=01
const lastSlashIndex = pathname.lastIndexOf('/')
if (lastSlashIndex !== -1 && lastSlashIndex < pathname.length - 1) {
const pathAfterLastSlash = pathname.substring(lastSlashIndex + 1)
if (pathAfterLastSlash.includes('=')) {
// 兼容 && 作为分隔符的情况,统一替换成单个 &
return pathAfterLastSlash.replace(/&{2,}/g, '&')
}
}
}
return ''
}
catch {
return ''
}
}
/**
* 从路由获取 userRoles(不存储到 localStorage) * 从路由获取 userRoles(不存储到 localStorage)
* 支持两种格式:
* 1. 标准查询参数:/home?userRoles=00&userRoles=01
* 2. 路径参数:/home/userRoles=00&&userRoles=01
* @returns 返回获取到的 userRoles 数组 * @returns 返回获取到的 userRoles 数组
*/ */
export function getUserRolesFromRoute(): string[] { export function getUserRolesFromRoute(): string[] {
try { try {
// 首先尝试从标准查询参数获取
const sanitizedSearch = getQueryBeforeSecondQuestion() const sanitizedSearch = getQueryBeforeSecondQuestion()
const searchParams = new URLSearchParams(sanitizedSearch || window.location.search) // 兜底:兼容 && 拼接
const rolesFromRepeatedKeys = searchParams.getAll('userRoles').filter(Boolean) const normalizedSearch = (sanitizedSearch || window.location.search).replace(/&{2,}/g, '&')
let searchParams = new URLSearchParams(normalizedSearch)
let rolesFromRepeatedKeys = searchParams.getAll('userRoles').filter(Boolean)
let userRoles: string[] = [] let userRoles: string[] = []
// 如果从标准查询参数中找到了,直接返回
if (rolesFromRepeatedKeys.length) {
userRoles = Array.from(new Set(rolesFromRepeatedKeys))
// 首次获取到时写入 sessionStorage 兜底
try {
safeSessionStorageSetItem(USER_ROLES_STORAGE_KEY, JSON.stringify(userRoles))
}
catch {
// 无痕模式或被禁用时静默
}
return userRoles
}
// 如果标准查询参数中没有,尝试从路径中解析
const pathQueryString = extractQueryStringFromPath()
if (pathQueryString) {
// 将路径参数转换为标准查询字符串格式
// 例如:userRoles=00&&userRoles=01 转换为 userRoles=00&userRoles=01
const normalizedQuery = pathQueryString.replace(/&{2,}/g, '&')
searchParams = new URLSearchParams(normalizedQuery)
rolesFromRepeatedKeys = searchParams.getAll('userRoles').filter(Boolean)
if (rolesFromRepeatedKeys.length) { if (rolesFromRepeatedKeys.length) {
userRoles = Array.from(new Set(rolesFromRepeatedKeys)) userRoles = Array.from(new Set(rolesFromRepeatedKeys))
try {
safeSessionStorageSetItem(USER_ROLES_STORAGE_KEY, JSON.stringify(userRoles))
}
catch {
}
return userRoles
}
// 尝试逗号分隔的格式
const commaSeparated = searchParams.get('userRoles')
if (commaSeparated) {
const roles = commaSeparated
.split(',')
.map(role => role.trim())
.filter(Boolean)
if (roles.length) {
userRoles = Array.from(new Set(roles))
try {
safeSessionStorageSetItem(USER_ROLES_STORAGE_KEY, JSON.stringify(userRoles))
}
catch {
}
return userRoles
} }
else { }
}
// 最后尝试从标准查询参数中获取逗号分隔的格式
if (!userRoles.length) {
const commaSeparated = searchParams.get('userRoles') const commaSeparated = searchParams.get('userRoles')
if (commaSeparated) { if (commaSeparated) {
const roles = commaSeparated const roles = commaSeparated
...@@ -57,10 +209,30 @@ export function getUserRolesFromRoute(): string[] { ...@@ -57,10 +209,30 @@ export function getUserRolesFromRoute(): string[] {
.filter(Boolean) .filter(Boolean)
if (roles.length) { if (roles.length) {
userRoles = Array.from(new Set(roles)) userRoles = Array.from(new Set(roles))
try {
safeSessionStorageSetItem(USER_ROLES_STORAGE_KEY, JSON.stringify(userRoles))
}
catch {
}
} }
} }
} }
// 兜底:从 sessionStorage 读取(同一标签页有效)
if (!userRoles.length) {
try {
const stored = safeSessionStorageGetItem(USER_ROLES_STORAGE_KEY)
if (stored) {
const parsed = JSON.parse(stored)
if (Array.isArray(parsed) && parsed.length)
return Array.from(new Set(parsed.filter(Boolean)))
}
}
catch {
// 静默
}
}
return userRoles return userRoles
} }
catch { catch {
...@@ -78,12 +250,7 @@ export function getUserRolesFromRouteAndStore(): string[] { ...@@ -78,12 +250,7 @@ export function getUserRolesFromRouteAndStore(): string[] {
// 如果获取到了 userRoles,存储到 localStorage(向后兼容) // 如果获取到了 userRoles,存储到 localStorage(向后兼容)
if (userRoles.length > 0) { if (userRoles.length > 0) {
try { safeLocalStorageSetItem(USER_ROLES_STORAGE_KEY, JSON.stringify(userRoles))
localStorage.setItem(USER_ROLES_STORAGE_KEY, JSON.stringify(userRoles))
}
catch (error) {
console.error('存储 userRoles 到 localStorage 失败:', error)
}
} }
return userRoles return userRoles
...@@ -95,7 +262,7 @@ export function getUserRolesFromRouteAndStore(): string[] { ...@@ -95,7 +262,7 @@ export function getUserRolesFromRouteAndStore(): string[] {
*/ */
export function getUserRolesFromStorage(): string[] { export function getUserRolesFromStorage(): string[] {
try { try {
const stored = localStorage.getItem(USER_ROLES_STORAGE_KEY) const stored = safeLocalStorageGetItem(USER_ROLES_STORAGE_KEY)
if (stored) { if (stored) {
const userRoles = JSON.parse(stored) const userRoles = JSON.parse(stored)
if (Array.isArray(userRoles) && userRoles.length > 0) { if (Array.isArray(userRoles) && userRoles.length > 0) {
...@@ -103,8 +270,8 @@ export function getUserRolesFromStorage(): string[] { ...@@ -103,8 +270,8 @@ export function getUserRolesFromStorage(): string[] {
} }
} }
} }
catch (error) { catch {
console.error('从 localStorage 读取 userRoles 失败:', error) // 静默失败,返回空数组
} }
return [] return []
} }
......
...@@ -327,6 +327,8 @@ export const Chat: React.FC = () => { ...@@ -327,6 +327,8 @@ export const Chat: React.FC = () => {
const getUserQaRecordPage = useCallback(async (conversationId: string) => { const getUserQaRecordPage = useCallback(async (conversationId: string) => {
setIsLoading(true) setIsLoading(true)
try { try {
// 检测是否从收藏页返回
const fromCollect = location.state?.fromCollect
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('[Chat] 开始获取历史记录:', conversationId) console.log('[Chat] 开始获取历史记录:', conversationId)
const res = await fetchUserQaRecordPage(conversationId) const res = await fetchUserQaRecordPage(conversationId)
...@@ -384,10 +386,18 @@ export const Chat: React.FC = () => { ...@@ -384,10 +386,18 @@ export const Chat: React.FC = () => {
source: 'location.state', source: 'location.state',
}) })
dispatch(setCurrentToolId(toolIdFromState)) dispatch(setCurrentToolId(toolIdFromState))
// 从收藏返回时,同步到 sessionStorage,避免 ChatEditor 清除 toolId
if (fromCollect) {
sessionStorage.setItem('currentToolId', toolIdFromState)
}
} }
else { else {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('[Chat] toolId 已一致,无需更新:', toolIdFromState) console.log('[Chat] toolId 已一致,无需更新:', toolIdFromState)
// 从收藏返回时,确保 sessionStorage 中有值
if (fromCollect && !sessionStorage.getItem('currentToolId')) {
sessionStorage.setItem('currentToolId', toolIdFromState)
}
} }
} }
else { else {
...@@ -416,10 +426,18 @@ export const Chat: React.FC = () => { ...@@ -416,10 +426,18 @@ export const Chat: React.FC = () => {
source: latestToolId ? 'qaRecords' : 'conversation', source: latestToolId ? 'qaRecords' : 'conversation',
}) })
dispatch(setCurrentToolId(finalToolId)) dispatch(setCurrentToolId(finalToolId))
// 从收藏返回时,同步到 sessionStorage,避免 ChatEditor 清除 toolId
if (fromCollect) {
sessionStorage.setItem('currentToolId', finalToolId)
}
} }
else { else {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('[Chat] toolId 已一致,无需更新:', finalToolId) console.log('[Chat] toolId 已一致,无需更新:', finalToolId)
// 从收藏返回时,确保 sessionStorage 中有值
if (fromCollect && !sessionStorage.getItem('currentToolId')) {
sessionStorage.setItem('currentToolId', finalToolId)
}
} }
} }
else { else {
...@@ -435,6 +453,10 @@ export const Chat: React.FC = () => { ...@@ -435,6 +453,10 @@ export const Chat: React.FC = () => {
else if (!hasQaRecords && currentToolId) { else if (!hasQaRecords && currentToolId) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('[Chat] 没有历史记录,保留 Redux 中的 toolId (可能是 location.state 传递失败):', currentToolId) console.log('[Chat] 没有历史记录,保留 Redux 中的 toolId (可能是 location.state 传递失败):', currentToolId)
// 从收藏返回时,确保 sessionStorage 中有值
if (fromCollect && !sessionStorage.getItem('currentToolId')) {
sessionStorage.setItem('currentToolId', currentToolId)
}
} }
} }
} }
...@@ -445,7 +467,7 @@ export const Chat: React.FC = () => { ...@@ -445,7 +467,7 @@ export const Chat: React.FC = () => {
finally { finally {
setIsLoading(false) setIsLoading(false)
} }
}, [dispatch, currentToolId, conversations]) }, [dispatch, currentToolId, conversations, location.state])
/** 点击滚动到底部 */ /** 点击滚动到底部 */
const scrollToBottom = () => { const scrollToBottom = () => {
......
...@@ -12,7 +12,7 @@ import { useAppDispatch } from '@/store/hook' ...@@ -12,7 +12,7 @@ import { useAppDispatch } 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'
import { getUserRolesFromRoute } from '@/lib/utils' import { getUserRolesFromRoute, safeSessionStorageGetItem, safeSessionStorageRemoveItem } from '@/lib/utils'
function getAnimationProps(delay: number) { function getAnimationProps(delay: number) {
return { return {
...@@ -86,7 +86,7 @@ export const Home: React.FC = () => { ...@@ -86,7 +86,7 @@ export const Home: React.FC = () => {
})) }))
setIsDataLoaded(false) // 重置加载状态 setIsDataLoaded(false) // 重置加载状态
try { try {
const storedToolId = sessionStorage.getItem('currentToolId') || '' const storedToolId = safeSessionStorageGetItem('currentToolId') || ''
const searchParams = new URLSearchParams(location.search) const searchParams = new URLSearchParams(location.search)
// 首页初始化加载常见问题时,允许忽略路由中的 toolId,避免带入上一次的工具 ID // 首页初始化加载常见问题时,允许忽略路由中的 toolId,避免带入上一次的工具 ID
const urlToolId = ignoreUrlToolId ? '' : (searchParams.get('toolId') || '') const urlToolId = ignoreUrlToolId ? '' : (searchParams.get('toolId') || '')
...@@ -180,7 +180,7 @@ export const Home: React.FC = () => { ...@@ -180,7 +180,7 @@ export const Home: React.FC = () => {
// 1. 清除 Redux 中的 currentToolId // 1. 清除 Redux 中的 currentToolId
dispatch(clearCurrentToolId()) dispatch(clearCurrentToolId())
// 2. 清除 sessionStorage 中的 currentToolId // 2. 清除 sessionStorage 中的 currentToolId
sessionStorage.removeItem('currentToolId') safeSessionStorageRemoveItem('currentToolId')
// 3. 清除 URL 中的 toolId 参数(如果存在) // 3. 清除 URL 中的 toolId 参数(如果存在)
const currentUrl = new URL(window.location.href) const currentUrl = new URL(window.location.href)
if (currentUrl.searchParams.has('toolId')) { if (currentUrl.searchParams.has('toolId')) {
...@@ -218,7 +218,7 @@ export const Home: React.FC = () => { ...@@ -218,7 +218,7 @@ export const Home: React.FC = () => {
// 1. 清除 Redux 中的 currentToolId // 1. 清除 Redux 中的 currentToolId
dispatch(clearCurrentToolId()) dispatch(clearCurrentToolId())
// 2. 清除 sessionStorage 中的 currentToolId // 2. 清除 sessionStorage 中的 currentToolId
sessionStorage.removeItem('currentToolId') safeSessionStorageRemoveItem('currentToolId')
// 3. 清除 URL 中的 toolId 参数(如果存在) // 3. 清除 URL 中的 toolId 参数(如果存在)
const currentUrl = new URL(window.location.href) const currentUrl = new URL(window.location.href)
if (currentUrl.searchParams.has('toolId')) { if (currentUrl.searchParams.has('toolId')) {
......
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