Commit 7a18d17c by Liu

fix:登录成功后再调用业务逻辑

parent 984a54ba
...@@ -7,15 +7,14 @@ import styles from './Home.module.less' ...@@ -7,15 +7,14 @@ import styles from './Home.module.less'
import { QuestionList } from './components/QuestionList' 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, createConversation, fetchConversations, setCurrentConversation, setCurrentToolId, setNavigationFlag } from '@/store/conversationSlice' import { clearCurrentToolId, fetchConversations, setCurrentConversation, setCurrentToolId, setNavigationFlag } from '@/store/conversationSlice'
import { useAppDispatch } from '@/store/hook' 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 { fetchSessionConversationId } from '@/api/conversation' import { fetchSessionConversationId } from '@/api/conversation'
import { fetchCheckTokenApi } from '@/api/chat' import { fetchCheckTokenApi } from '@/api/chat'
import { getUserRolesFromRoute, safeLocalStorageGetItem, safeSessionStorageGetItem, safeSessionStorageRemoveItem, safeSessionStorageSetItem } from '@/lib/utils' import { getUserRolesFromRoute, safeLocalStorageGetItem, safeSessionStorageGetItem, safeSessionStorageRemoveItem } from '@/lib/utils'
import type { Conversation } from '@/types/conversation'
// 从 localStorage 获取 token 的辅助函数 // 从 localStorage 获取 token 的辅助函数
function getTokenFromStorage(): string | null { function getTokenFromStorage(): string | null {
...@@ -60,8 +59,7 @@ function getAnimationProps(delay: number) { ...@@ -60,8 +59,7 @@ function getAnimationProps(delay: number) {
} }
} }
// 使用 sessionStorage 作为标志,防止跨组件重复执行 SSO 登录 // 已移除 sessionStorage 标志,改为仅使用组件级保护,确保每次打开链接都能调用 SSO 登录
const SSO_LOGIN_FLAG = 'sso_login_fetched'
export const Home: React.FC = () => { export const Home: React.FC = () => {
const viteOutputObj = import.meta.env.VITE_OUTPUT_OBJ || 'open' const viteOutputObj = import.meta.env.VITE_OUTPUT_OBJ || 'open'
...@@ -86,54 +84,6 @@ export const Home: React.FC = () => { ...@@ -86,54 +84,6 @@ export const Home: React.FC = () => {
defaultValue: '', defaultValue: '',
}) })
const _initConversation = async () => {
const fromCollect = location.state?.fromCollect
// 只有在访问首页时才处理会话,如果已经在聊天页面则不处理
if (!fromCollect && (location.pathname === '/' || location.pathname === '/home')) {
// 从 localStorage 读取上次的 conversationId
const savedConversationId = safeLocalStorageGetItem('currentConversationId')
if (savedConversationId) {
// 如果 localStorage 中有 conversationId,恢复它而不是创建新会话
dispatch(setCurrentConversation(savedConversationId))
// 设置导航标志,触发自动导航到聊天页面
dispatch(setNavigationFlag(true))
// 获取会话列表(用于后续验证和同步 toolId)
const fetchResult = await dispatch(fetchConversations())
const conversationsList = fetchResult.payload as Conversation[]
// 同步会话的 toolId(如果存在)
const restoredConversation = conversationsList?.find((conv: Conversation) => conv.conversationId === savedConversationId)
if (restoredConversation?.toolId) {
dispatch(setCurrentToolId(restoredConversation.toolId))
// 同步到 sessionStorage,确保 ChatEditor 等组件能正确识别 toolId
safeSessionStorageSetItem('currentToolId', restoredConversation.toolId)
}
else {
dispatch(clearCurrentToolId())
// 清除 sessionStorage 中的 toolId
safeSessionStorageRemoveItem('currentToolId')
}
}
else {
// 如果 localStorage 中没有 conversationId,创建新会话
dispatch(fetchConversations())
dispatch(
createConversation({
conversationData: {},
shouldNavigate: true,
shouldSendQuestion: '',
}),
)
}
}
// 清除状态以避免下次影响
if (location.state?.fromCollect) {
// 使用 replace 替换当前历史记录,清除 state
window.history.replaceState({}, document.title, window.location.pathname)
}
}
// 获取会话ID并加载历史记录 // 获取会话ID并加载历史记录
const getSessionConversationId = async (data?: any) => { const getSessionConversationId = async (data?: any) => {
try { try {
...@@ -266,12 +216,7 @@ export const Home: React.FC = () => { ...@@ -266,12 +216,7 @@ export const Home: React.FC = () => {
}, [_handleToolClick, isToolBtnActive, shouldChangeStyle, dispatch]) }, [_handleToolClick, isToolBtnActive, shouldChangeStyle, dispatch])
const login = useCallback(async () => { const login = useCallback(async () => {
// 防止重复调用(使用 sessionStorage,跨组件共享) // 防止重复调用(组件级别保护,每次组件挂载时会重置,确保每次打开链接都能调用)
if (sessionStorage.getItem(SSO_LOGIN_FLAG) === 'true') {
console.log('homeNew sso111111')
return
}
// 防止重复调用(组件级别保护)
if (hasFetched.current) { if (hasFetched.current) {
console.log('homeNew sso222222') console.log('homeNew sso222222')
return return
...@@ -285,8 +230,7 @@ export const Home: React.FC = () => { ...@@ -285,8 +230,7 @@ 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') console.log('homeNew sso333333')
// 立即设置标志,防止重复执行 // 立即设置标志,防止重复执行(仅组件级别,每次组件挂载时会重置)
sessionStorage.setItem(SSO_LOGIN_FLAG, 'true')
hasFetched.current = true hasFetched.current = true
// 每次进入页面调用 sso_login 时,先清空 sessionStorage 中的 currentToolId // 每次进入页面调用 sso_login 时,先清空 sessionStorage 中的 currentToolId
// 避免关闭标签页后再次打开时使用上次的历史 toolId // 避免关闭标签页后再次打开时使用上次的历史 toolId
...@@ -339,7 +283,6 @@ export const Home: React.FC = () => { ...@@ -339,7 +283,6 @@ export const Home: React.FC = () => {
catch (error) { catch (error) {
console.error('SSO 登录失败:', error) console.error('SSO 登录失败:', error)
// 登录失败时清除标志,允许重试 // 登录失败时清除标志,允许重试
sessionStorage.removeItem(SSO_LOGIN_FLAG)
hasFetched.current = false hasFetched.current = false
} }
return return
...@@ -371,44 +314,51 @@ export const Home: React.FC = () => { ...@@ -371,44 +314,51 @@ export const Home: React.FC = () => {
} }
else { else {
// 模拟登录 可以用来测试 // 模拟登录 可以用来测试
const res = await fetchLoginByUid('123123') try {
if (res.data) { const res = await fetchLoginByUid('123123')
// 登录成功后先清理旧状态,避免沿用上一次的工具模式 if (res.data) {
dispatch(clearCurrentToolId()) // 登录成功后先清理旧状态,避免沿用上一次的工具模式
safeSessionStorageRemoveItem('currentToolId') dispatch(clearCurrentToolId())
const currentUrl = new URL(window.location.href) safeSessionStorageRemoveItem('currentToolId')
if (currentUrl.searchParams.has('toolId')) { const currentUrl = new URL(window.location.href)
currentUrl.searchParams.delete('toolId') if (currentUrl.searchParams.has('toolId')) {
window.history.replaceState({}, '', currentUrl.toString()) currentUrl.searchParams.delete('toolId')
} window.history.replaceState({}, '', currentUrl.toString())
setToken(res.data.token) }
if (res.data.userName) { setToken(res.data.token)
setUserName(res.data.userName) if (res.data.userName) {
} setUserName(res.data.userName)
// 确保 token 已写入 localStorage(useLocalStorageState 是同步的,但为了保险起见,使用微任务确保写入完成) }
await new Promise(resolve => setTimeout(resolve, 0)) // 确保 token 已写入 localStorage(useLocalStorageState 是同步的,但为了保险起见,使用微任务确保写入完成)
// 主动触发 storage 事件,确保其他组件能监听到变化 await new Promise(resolve => setTimeout(resolve, 0))
window.dispatchEvent( // 主动触发 storage 事件,确保其他组件能监听到变化
new StorageEvent('storage', { window.dispatchEvent(
key: '__TOKEN__', new StorageEvent('storage', {
oldValue: token, key: '__TOKEN__',
newValue: res.data.token, oldValue: token,
url: window.location.href, newValue: res.data.token,
storageArea: localStorage, url: window.location.href,
}), storageArea: localStorage,
) }),
// 确保 token 已写入 localStorage 后再调用业务接口 )
const actualToken = getTokenFromStorage() || res.data.token // 确保 token 已写入 localStorage 后再调用业务接口
if (actualToken && !hasCalledBusinessApis.current) { const actualToken = getTokenFromStorage() || res.data.token
hasCalledBusinessApis.current = true if (actualToken && !hasCalledBusinessApis.current) {
// 触发自定义事件,通知 ChatEditor 强制重置为制度活化 hasCalledBusinessApis.current = true
window.dispatchEvent(new CustomEvent('forceResetToGeneralMode')) // 触发自定义事件,通知 ChatEditor 强制重置为制度活化
getSessionConversationId() window.dispatchEvent(new CustomEvent('forceResetToGeneralMode'))
dispatch(fetchConversations()) getSessionConversationId()
// 2. 拉取常见问题等业务数据 dispatch(fetchConversations())
_handleToolClick(false, '', true) // 2. 拉取常见问题等业务数据
_handleToolClick(false, '', true)
}
} }
} }
catch (error) {
console.error('Guest 登录失败:', error)
// 登录失败时清除标志,允许重试
hasFetched.current = false
}
} }
} }
}, [setToken, setUserName, dispatch]) }, [setToken, setUserName, dispatch])
...@@ -420,8 +370,6 @@ export const Home: React.FC = () => { ...@@ -420,8 +370,6 @@ export const Home: React.FC = () => {
useEffect(() => { useEffect(() => {
login() login()
console.log('login useEffect11111', token)
}, []) // 依赖数组为空,只在组件挂载时执行一次 }, []) // 依赖数组为空,只在组件挂载时执行一次
useEffect(() => { useEffect(() => {
......
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