Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sdream-ai-fe
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
侯明涛
sdream-ai-fe
Commits
80f578fa
Commit
80f578fa
authored
Dec 05, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: commit staged changes
parent
310b6cca
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
234 additions
and
89 deletions
+234
-89
src/components/ChatEditor/index.tsx
+28
-72
src/lib/utils.ts
+179
-12
src/pages/Chat/Chat.tsx
+23
-1
src/pages/Home/HomeNew.tsx
+4
-4
No files found.
src/components/ChatEditor/index.tsx
View file @
80f578fa
...
...
@@ -2,43 +2,15 @@ import React, { useEffect, useRef, useState } from 'react'
import
{
AnimatePresence
,
motion
}
from
'framer-motion'
import
{
Button
,
Tooltip
}
from
'@heroui/react'
import
{
useLocalStorageState
,
useToggle
}
from
'ahooks'
import
{
useSearchParams
}
from
'react-router-dom'
import
{
use
Location
,
use
SearchParams
}
from
'react-router-dom'
import
{
LoginModal
}
from
'../LoginModal'
import
type
{
RootState
}
from
'@/store'
import
SendIcon
from
'@/assets/svg/send.svg?react'
import
{
type
WithAuthProps
,
withAuth
}
from
'@/auth/withAuth'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
{
clearCurrentToolId
,
createConversation
,
setCurrentToolId
}
from
'@/store/conversationSlice'
// 本地 mock 工具列表,离线/联调阶段用于渲染按钮
const
MOCK_TOOL_LIST
=
[
{
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
import
{
fetchToolList
}
from
'@/api/home'
import
{
getUserRolesForApi
,
safeSessionStorageGetItem
,
safeSessionStorageRemoveItem
,
safeSessionStorageSetItem
}
from
'@/lib/utils'
interface
ChatEditorProps
{
onChange
?:
(
value
:
string
)
=>
void
...
...
@@ -66,12 +38,25 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
[
showToolQuestion
,
setShowToolQuestion
]
=
useState
<
boolean
>
(
false
)
const
[
sessionToolId
,
setSessionToolId
]
=
useState
<
string
|
null
>
(
null
)
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
()
const
location
=
useLocation
()
const
toolIdFromUrl
=
searchParams
.
get
(
'toolId'
)
// 获取工具列表
const
getToolList
=
async
()
=>
{
// 暂时启用本地 mock 数据,确保在无后端接口时也能渲染
setToolList
(
MOCK_TOOL_LIST
.
map
(
tool
=>
({
...
tool
})))
try
{
// 从路由中获取 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 中的记录决定高亮逻辑
...
...
@@ -128,7 +113,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 监听 sessionStorage 中的 currentToolId(历史点击时写入)来辅助高亮逻辑
useEffect
(()
=>
{
const
syncSessionToolId
=
()
=>
{
const
storedToolId
=
s
essionStorage
.
g
etItem
(
'currentToolId'
)
const
storedToolId
=
s
afeSessionStorageG
etItem
(
'currentToolId'
)
// 如果 currentToolId 是空字符串,视为 null,确保通用模式能正确高亮
setSessionToolId
(
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
)
}
...
...
@@ -157,7 +142,7 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 当路由变化时,同步更新 sessionToolId(因为 storage 事件不会在同标签页触发)
useEffect
(()
=>
{
const
storedToolId
=
s
essionStorage
.
g
etItem
(
'currentToolId'
)
const
storedToolId
=
s
afeSessionStorageG
etItem
(
'currentToolId'
)
// 如果 currentToolId 是空字符串,视为 null,确保通用模式能正确高亮
setSessionToolId
(
storedToolId
&&
storedToolId
.
trim
()
?
storedToolId
:
null
)
},
[
toolIdFromUrl
])
...
...
@@ -237,8 +222,8 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 立即更新本地状态,让 UI 立即响应
setIsToolBtnActive
(
true
)
setSelectedToolId
(
null
)
s
essionStorage
.
r
emoveItem
(
'showToolQuestion'
)
s
essionStorage
.
r
emoveItem
(
'currentToolId'
)
s
afeSessionStorageR
emoveItem
(
'showToolQuestion'
)
s
afeSessionStorageR
emoveItem
(
'currentToolId'
)
setSessionToolId
(
null
)
setShowToolQuestion
(
false
)
// 清空路由中的 toolId 参数
...
...
@@ -262,37 +247,19 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 处理工具按钮点击:先创建新会话,再切换工具
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
===
'数据助手'
)
{
s
essionStorage
.
s
etItem
(
'showToolQuestion'
,
'true'
)
s
afeSessionStorageS
etItem
(
'showToolQuestion'
,
'true'
)
setShowToolQuestion
(
true
)
}
else
{
s
essionStorage
.
r
emoveItem
(
'showToolQuestion'
)
s
afeSessionStorageR
emoveItem
(
'showToolQuestion'
)
setShowToolQuestion
(
false
)
}
dispatch
(
setCurrentToolId
(
tool
.
toolId
))
setSelectedToolId
(
tool
.
toolId
)
setIsToolBtnActive
(
false
)
s
essionStorage
.
s
etItem
(
'currentToolId'
,
tool
.
toolId
)
s
afeSessionStorageS
etItem
(
'currentToolId'
,
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
{
await
dispatch
(
createConversation
({
conversationData
:
{
toolId
:
tool
.
toolId
},
...
...
@@ -321,15 +288,15 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
}
},
[
content
])
// 组件加载时获取工具列表
// 组件加载时
和路由参数变化时
获取工具列表
useEffect
(()
=>
{
getToolList
()
},
[])
},
[
location
.
pathname
,
location
.
search
])
// 监听 sessionStorage 中的 showToolQuestion
useEffect
(()
=>
{
const
checkShowToolQuestion
=
()
=>
{
const
value
=
s
essionStorage
.
g
etItem
(
'showToolQuestion'
)
const
value
=
s
afeSessionStorageG
etItem
(
'showToolQuestion'
)
setShowToolQuestion
(
value
===
'true'
)
}
checkShowToolQuestion
()
...
...
@@ -434,17 +401,6 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 通用模式高亮:路由内没有 toolId 或 toolId 为空时默认高亮,点击后也要高亮
const
isGeneralMode
=
tool
.
toolName
===
'通用模式'
&&
isToolBtnActive
&&
!
selectedToolId
&&
!
sessionToolId
&&
!
toolIdFromUrl
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
=
'w-auto h-[32px] px-3 rounded-full shadow-none text-[12px] flex items-center gap-2 transition-all duration-200 border'
...
...
src/lib/utils.ts
View file @
80f578fa
...
...
@@ -7,6 +7,73 @@ export function cn(...inputs: ClassValue[]) {
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__'
/**
...
...
@@ -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)
* 支持两种格式:
* 1. 标准查询参数:/home?userRoles=00&userRoles=01
* 2. 路径参数:/home/userRoles=00&&userRoles=01
* @returns 返回获取到的 userRoles 数组
*/
export
function
getUserRolesFromRoute
():
string
[]
{
try
{
// 首先尝试从标准查询参数获取
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
[]
=
[]
// 如果从标准查询参数中找到了,直接返回
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
)
{
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'
)
if
(
commaSeparated
)
{
const
roles
=
commaSeparated
...
...
@@ -57,8 +209,28 @@ export function getUserRolesFromRoute(): string[] {
.
filter
(
Boolean
)
if
(
roles
.
length
)
{
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
...
...
@@ -78,12 +250,7 @@ export function getUserRolesFromRouteAndStore(): string[] {
// 如果获取到了 userRoles,存储到 localStorage(向后兼容)
if
(
userRoles
.
length
>
0
)
{
try
{
localStorage
.
setItem
(
USER_ROLES_STORAGE_KEY
,
JSON
.
stringify
(
userRoles
))
}
catch
(
error
)
{
console
.
error
(
'存储 userRoles 到 localStorage 失败:'
,
error
)
}
safeLocalStorageSetItem
(
USER_ROLES_STORAGE_KEY
,
JSON
.
stringify
(
userRoles
))
}
return
userRoles
...
...
@@ -95,7 +262,7 @@ export function getUserRolesFromRouteAndStore(): string[] {
*/
export
function
getUserRolesFromStorage
():
string
[]
{
try
{
const
stored
=
localStorage
.
g
etItem
(
USER_ROLES_STORAGE_KEY
)
const
stored
=
safeLocalStorageG
etItem
(
USER_ROLES_STORAGE_KEY
)
if
(
stored
)
{
const
userRoles
=
JSON
.
parse
(
stored
)
if
(
Array
.
isArray
(
userRoles
)
&&
userRoles
.
length
>
0
)
{
...
...
@@ -103,8 +270,8 @@ export function getUserRolesFromStorage(): string[] {
}
}
}
catch
(
error
)
{
console
.
error
(
'从 localStorage 读取 userRoles 失败:'
,
error
)
catch
{
// 静默失败,返回空数组
}
return
[]
}
...
...
src/pages/Chat/Chat.tsx
View file @
80f578fa
...
...
@@ -327,6 +327,8 @@ export const Chat: React.FC = () => {
const
getUserQaRecordPage
=
useCallback
(
async
(
conversationId
:
string
)
=>
{
setIsLoading
(
true
)
try
{
// 检测是否从收藏页返回
const
fromCollect
=
location
.
state
?.
fromCollect
// eslint-disable-next-line no-console
console
.
log
(
'[Chat] 开始获取历史记录:'
,
conversationId
)
const
res
=
await
fetchUserQaRecordPage
(
conversationId
)
...
...
@@ -384,10 +386,18 @@ export const Chat: React.FC = () => {
source
:
'location.state'
,
})
dispatch
(
setCurrentToolId
(
toolIdFromState
))
// 从收藏返回时,同步到 sessionStorage,避免 ChatEditor 清除 toolId
if
(
fromCollect
)
{
sessionStorage
.
setItem
(
'currentToolId'
,
toolIdFromState
)
}
}
else
{
// eslint-disable-next-line no-console
console
.
log
(
'[Chat] toolId 已一致,无需更新:'
,
toolIdFromState
)
// 从收藏返回时,确保 sessionStorage 中有值
if
(
fromCollect
&&
!
sessionStorage
.
getItem
(
'currentToolId'
))
{
sessionStorage
.
setItem
(
'currentToolId'
,
toolIdFromState
)
}
}
}
else
{
...
...
@@ -416,10 +426,18 @@ export const Chat: React.FC = () => {
source
:
latestToolId
?
'qaRecords'
:
'conversation'
,
})
dispatch
(
setCurrentToolId
(
finalToolId
))
// 从收藏返回时,同步到 sessionStorage,避免 ChatEditor 清除 toolId
if
(
fromCollect
)
{
sessionStorage
.
setItem
(
'currentToolId'
,
finalToolId
)
}
}
else
{
// eslint-disable-next-line no-console
console
.
log
(
'[Chat] toolId 已一致,无需更新:'
,
finalToolId
)
// 从收藏返回时,确保 sessionStorage 中有值
if
(
fromCollect
&&
!
sessionStorage
.
getItem
(
'currentToolId'
))
{
sessionStorage
.
setItem
(
'currentToolId'
,
finalToolId
)
}
}
}
else
{
...
...
@@ -435,6 +453,10 @@ export const Chat: React.FC = () => {
else
if
(
!
hasQaRecords
&&
currentToolId
)
{
// eslint-disable-next-line no-console
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 = () => {
finally
{
setIsLoading
(
false
)
}
},
[
dispatch
,
currentToolId
,
conversations
])
},
[
dispatch
,
currentToolId
,
conversations
,
location
.
state
])
/** 点击滚动到底部 */
const
scrollToBottom
=
()
=>
{
...
...
src/pages/Home/HomeNew.tsx
View file @
80f578fa
...
...
@@ -12,7 +12,7 @@ import { useAppDispatch } from '@/store/hook'
import
{
fetchEfficiencyQuestionList
}
from
'@/api/home'
import
SdreamLoading
from
'@/components/SdreamLoading'
import
{
fetchLoginByToken
,
fetchLoginByUid
}
from
'@/api/common'
import
{
getUserRolesFromRoute
}
from
'@/lib/utils'
import
{
getUserRolesFromRoute
,
safeSessionStorageGetItem
,
safeSessionStorageRemoveItem
}
from
'@/lib/utils'
function
getAnimationProps
(
delay
:
number
)
{
return
{
...
...
@@ -86,7 +86,7 @@ export const Home: React.FC = () => {
}))
setIsDataLoaded
(
false
)
// 重置加载状态
try
{
const
storedToolId
=
s
essionStorage
.
g
etItem
(
'currentToolId'
)
||
''
const
storedToolId
=
s
afeSessionStorageG
etItem
(
'currentToolId'
)
||
''
const
searchParams
=
new
URLSearchParams
(
location
.
search
)
// 首页初始化加载常见问题时,允许忽略路由中的 toolId,避免带入上一次的工具 ID
const
urlToolId
=
ignoreUrlToolId
?
''
:
(
searchParams
.
get
(
'toolId'
)
||
''
)
...
...
@@ -180,7 +180,7 @@ export const Home: React.FC = () => {
// 1. 清除 Redux 中的 currentToolId
dispatch
(
clearCurrentToolId
())
// 2. 清除 sessionStorage 中的 currentToolId
s
essionStorage
.
r
emoveItem
(
'currentToolId'
)
s
afeSessionStorageR
emoveItem
(
'currentToolId'
)
// 3. 清除 URL 中的 toolId 参数(如果存在)
const
currentUrl
=
new
URL
(
window
.
location
.
href
)
if
(
currentUrl
.
searchParams
.
has
(
'toolId'
))
{
...
...
@@ -218,7 +218,7 @@ export const Home: React.FC = () => {
// 1. 清除 Redux 中的 currentToolId
dispatch
(
clearCurrentToolId
())
// 2. 清除 sessionStorage 中的 currentToolId
s
essionStorage
.
r
emoveItem
(
'currentToolId'
)
s
afeSessionStorageR
emoveItem
(
'currentToolId'
)
// 3. 清除 URL 中的 toolId 参数(如果存在)
const
currentUrl
=
new
URL
(
window
.
location
.
href
)
if
(
currentUrl
.
searchParams
.
has
(
'toolId'
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment