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
9336bcb8
Commit
9336bcb8
authored
Dec 08, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:策略分析时展示效果
parent
a3dec971
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
101 additions
and
66 deletions
+101
-66
src/components/ChatEditor/index.tsx
+5
-0
src/components/ChatEditorTactics/index.tsx
+8
-1
src/layouts/MainLayout/MainLayout.tsx
+29
-27
src/pages/ChatTactics/Chat.tsx
+4
-1
src/pages/Home/HomeNew.tsx
+46
-35
src/routes/AppRoutes.tsx
+9
-2
No files found.
src/components/ChatEditor/index.tsx
View file @
9336bcb8
...
...
@@ -40,11 +40,16 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
()
const
location
=
useLocation
()
const
toolIdFromUrl
=
searchParams
.
get
(
'toolId'
)
const
isFromTactics
=
searchParams
.
get
(
'from'
)
===
'tactics'
const
fromCollect
=
location
.
state
?.
fromCollect
// 获取工具列表
const
getToolList
=
async
()
=>
{
try
{
if
(
isFromTactics
)
{
setToolList
([])
return
}
// 从路由中获取 userRoles 参数
const
userRoles
=
getUserRolesForApi
()
// 调用真实 API 获取工具列表
...
...
src/components/ChatEditorTactics/index.tsx
View file @
9336bcb8
...
...
@@ -40,10 +40,15 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
()
const
location
=
useLocation
()
const
toolIdFromUrl
=
searchParams
.
get
(
'toolId'
)
const
isFromTactics
=
searchParams
.
get
(
'from'
)
===
'tactics'
const
fromCollect
=
location
.
state
?.
fromCollect
// 获取工具列表
const
getToolList
=
async
()
=>
{
if
(
isFromTactics
)
{
setToolList
([])
return
}
try
{
// 从路由中获取 userRoles 参数
const
userRoles
=
getUserRolesForApi
()
...
...
@@ -291,8 +296,10 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
// 组件加载时和路由参数变化时获取工具列表
useEffect
(()
=>
{
if
(
isFromTactics
)
return
getToolList
()
},
[
location
.
pathname
,
location
.
search
])
},
[
isFromTactics
,
location
.
pathname
,
location
.
search
])
// 监听 sessionStorage 中的 showToolQuestion
useEffect
(()
=>
{
...
...
src/layouts/MainLayout/MainLayout.tsx
View file @
9336bcb8
...
...
@@ -43,6 +43,7 @@ export const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
const
[
isHistoryVisible
,
setHistoryVisible
]
=
useState
(
false
)
const
location
=
useLocation
()
const
dispatch
=
useAppDispatch
()
const
isFromTactics
=
new
URLSearchParams
(
location
.
search
).
get
(
'from'
)
===
'tactics'
const
[
navBarVisibleLocal
]
=
useSessionStorageState
<
string
|
undefined
>
(
'__NAV_BAR_VISIBLE_LOCAL__'
,
{
...
...
@@ -64,34 +65,35 @@ export const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
return
(
<
motion
.
main
className=
{
styles
.
layoutMain
}
>
{
/* hidden */
}
<
motion
.
div
animate=
{
navBarVisibleLocal
===
'0'
?
isHistoryVisible
?
'shrunk'
:
'expanded'
:
'navTween'
}
variants=
{
contentVariants
}
className=
{
`fixed right-[-12px] top-[10px] z-[49] h-auto sm:relative flex sm:h-full items-center ${isHistoryVisible && !isMobile() ? 'w-[340px]' : 'w-[90px]'} box-border`
}
>
{
!
isFromTactics
&&
(
<
motion
.
div
animate=
{
navBarVisibleLocal
===
'0'
?
isHistoryVisible
?
'shrunk'
:
'expanded'
:
'navTween'
}
variants=
{
contentVariants
}
className=
{
`fixed right-[-12px] top-[10px] z-[49] h-auto sm:relative flex sm:h-full items-center ${isHistoryVisible && !isMobile() ? 'w-[340px]' : 'w-[90px]'} box-border`
}
>
<
Navbar
isHistoryVisible=
{
isHistoryVisible
}
onSetHistoryVisible=
{
setHistoryVisible
}
/>
<
Navbar
isHistoryVisible=
{
isHistoryVisible
}
onSetHistoryVisible=
{
setHistoryVisible
}
/>
<
HistoryBar
isVisible=
{
isHistoryVisible
}
onSetHistoryVisible=
{
setHistoryVisible
}
/>
{
!
isHistoryVisible
&&
(
<
motion
.
div
initial=
"hidden"
animate=
"visible"
variants=
{
{
hidden
:
{
x
:
-
5
,
opacity
:
0
,
},
}
}
className=
{
`${styles.sidebarArrow} side-bar-arrow h-[42px] flex items-center`
}
>
<
MingcuteArrowsRightFill
className=
"text-[#818d91]"
/>
</
motion
.
div
>
)
}
</
motion
.
div
>
<
HistoryBar
isVisible=
{
isHistoryVisible
}
onSetHistoryVisible=
{
setHistoryVisible
}
/>
{
!
isHistoryVisible
&&
(
<
motion
.
div
initial=
"hidden"
animate=
"visible"
variants=
{
{
hidden
:
{
x
:
-
5
,
opacity
:
0
,
},
}
}
className=
{
`${styles.sidebarArrow} side-bar-arrow h-[42px] flex items-center`
}
>
<
MingcuteArrowsRightFill
className=
"text-[#818d91]"
/>
</
motion
.
div
>
)
}
</
motion
.
div
>
)
}
<
motion
.
div
variants=
{
contentVariants
}
animate=
{
navBarVisibleLocal
===
'0'
?
''
:
'mainTween'
}
...
...
src/pages/ChatTactics/Chat.tsx
View file @
9336bcb8
...
...
@@ -55,6 +55,7 @@ export const Chat: React.FC = () => {
const
[
currentToolName
,
setCurrentToolName
]
=
useState
<
string
|
undefined
>
(
undefined
)
// 使用 ref 保存从 location.state 传递的 toolId,避免被异步操作覆盖
const
toolIdFromStateRef
=
useRef
<
string
|
null
|
undefined
>
(
undefined
)
const
isFromTactics
=
searchParams
.
get
(
'from'
)
===
'tactics'
// 当外部系统直接以 /chat/:id 链接进入(没有 location.state,且 URL 中也没有 toolId)时,
// 视为一次新的会话入口:重置为通用模式,清除历史遗留的工具模式状态
...
...
@@ -510,6 +511,8 @@ export const Chat: React.FC = () => {
// 根据 currentToolId 获取对应的 toolName
useEffect
(()
=>
{
const
getToolNameFromToolId
=
async
()
=>
{
if
(
isFromTactics
)
return
if
(
currentToolId
)
{
try
{
// 使用mock数据(已注释)
...
...
@@ -534,7 +537,7 @@ export const Chat: React.FC = () => {
}
}
getToolNameFromToolId
()
},
[
currentToolId
])
},
[
currentToolId
,
isFromTactics
])
// 监听工具按钮点击事件,更新 ChatWelcome 提示语和 toolId
useEffect
(()
=>
{
...
...
src/pages/Home/HomeNew.tsx
View file @
9336bcb8
...
...
@@ -46,6 +46,7 @@ export const Home: React.FC = () => {
const
[
isDataLoaded
,
setIsDataLoaded
]
=
useState
(
false
)
const
dispatch
=
useAppDispatch
()
const
location
=
useLocation
()
const
isFromTactics
=
new
URLSearchParams
(
location
.
search
).
get
(
'from'
)
===
'tactics'
const
hasFetched
=
useRef
(
false
)
// 使用 useState
const
[
otherQuestions
,
setOtherQuestions
]
=
useState
<
any
>
({
content
:
[]
})
...
...
@@ -262,44 +263,54 @@ export const Home: React.FC = () => {
<
div
className=
"h-full w-full"
>
<
div
className=
"box flex flex-col h-full w-full"
>
<
div
className=
"flex-1 items-center pt-[24px] sm:pt-[32px] scrollbar-hide"
>
{
isFromTactics
&&
(
<
div
className=
"flex items-center text-right justify-end"
>
<
div
>
清空历史
</
div
>
<
div
>
重新分析
</
div
>
</
div
>
)
}
<
div
className=
"w-full"
>
<
div
className=
"flex justify-center gap-[20px]"
>
{
/* 左侧区域 - 产品问答和您可以试着问我 */
}
<
div
className=
"flex flex-col gap-[20px] items-center overflow-y-auto scrollbar-hide"
style=
{
{
height
:
shouldChangeStyle
?
'calc(-64px + 100vh)'
:
'500px'
,
background
:
shouldChangeStyle
?
'linear-gradient(180deg, #DEF6FF 0%, #FFFFFF 50%, #FFFFFF 100%)'
:
''
,
borderRadius
:
'24px'
}
}
>
{
/* {!shouldChangeStyle && (
<motion.div className="w-full sm:w-auto" {...getAnimationProps(2)}>
<QuestionList
questions={productQuestions.content}
dotColor="#D4CCFF"
background="linear-gradient(180deg, #EBE6FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
title={productQuestions.configName}
iconImg={HomeIcon1}
isToolBtn={shouldChangeStyle}
isLoaded={isDataLoaded}
/>
</motion.div>
)} */
}
<
motion
.
div
className=
"w-full sm:w-auto"
{
...
getAnimationProps
(3)}
>
<
QuestionList
questions=
{
otherQuestions
.
content
}
dotColor=
"#CBECFF"
background=
"linear-gradient(180deg, #DEF6FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
height=
{
shouldChangeStyle
?
'288px'
:
'auto'
}
title=
{
otherQuestions
.
configName
}
iconImg=
{
HomeIcon2
}
isToolBtn=
{
shouldChangeStyle
}
isLoaded=
{
isDataLoaded
}
/>
</
motion
.
div
>
{
shouldChangeStyle
&&
(
<
div
className=
"w-full flex justify-center mt-auto pb-[24px]"
>
<
img
src=
{
SmartIce
}
alt=
"Smart Ice"
className=
"w-[260px] h-[218px] mt-[-12px] object-contain"
/>
{
!
isFromTactics
&&
(
<>
{
/* 左侧区域 - 产品问答和您可以试着问我 */
}
<
div
className=
"flex flex-col gap-[20px] items-center overflow-y-auto scrollbar-hide"
style=
{
{
height
:
shouldChangeStyle
?
'calc(-64px + 100vh)'
:
'500px'
,
background
:
shouldChangeStyle
?
'linear-gradient(180deg, #DEF6FF 0%, #FFFFFF 50%, #FFFFFF 100%)'
:
''
,
borderRadius
:
'24px'
}
}
>
{
/* {!shouldChangeStyle && (
<motion.div className="w-full sm:w-auto" {...getAnimationProps(2)}>
<QuestionList
questions={productQuestions.content}
dotColor="#D4CCFF"
background="linear-gradient(180deg, #EBE6FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
title={productQuestions.configName}
iconImg={HomeIcon1}
isToolBtn={shouldChangeStyle}
isLoaded={isDataLoaded}
/>
</motion.div>
)} */
}
<
motion
.
div
className=
"w-full sm:w-auto"
{
...
getAnimationProps
(3)}
>
<
QuestionList
questions=
{
otherQuestions
.
content
}
dotColor=
"#CBECFF"
background=
"linear-gradient(180deg, #DEF6FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
height=
{
shouldChangeStyle
?
'288px'
:
'auto'
}
title=
{
otherQuestions
.
configName
}
iconImg=
{
HomeIcon2
}
isToolBtn=
{
shouldChangeStyle
}
isLoaded=
{
isDataLoaded
}
/>
</
motion
.
div
>
{
shouldChangeStyle
&&
(
<
div
className=
"w-full flex justify-center mt-auto pb-[24px]"
>
<
img
src=
{
SmartIce
}
alt=
"Smart Ice"
className=
"w-[260px] h-[218px] mt-[-12px] object-contain"
/>
</
div
>
)
}
</
div
>
)
}
</
div
>
</>
)
}
{
/* 右侧区域 */
}
<
div
className=
"hidden sm:flex flex-1 h-full"
>
<
div
...
...
src/routes/AppRoutes.tsx
View file @
9336bcb8
import
React
from
'react'
import
{
Route
,
Routes
}
from
'react-router-dom'
import
{
Home
}
from
'../pages/Home'
import
{
Chat
}
from
'../pages/Chat'
import
{
Chat
as
ChatDefault
}
from
'../pages/Chat'
import
{
Chat
as
ChatTactics
}
from
'../pages/ChatTactics'
import
{
Collect
}
from
'../pages/Collect'
import
{
Tools
}
from
'../pages/Tools'
import
{
Protocol
}
from
'../pages/Protocol'
import
{
withRouteChangeHandler
}
from
'./RouteChangeHandler'
const
ChatEntry
:
React
.
FC
=
()
=>
{
const
params
=
new
URLSearchParams
(
window
.
location
.
search
)
const
isFromTactics
=
params
.
get
(
'from'
)
===
'tactics'
return
isFromTactics
?
<
ChatTactics
/>
:
<
ChatDefault
/>
}
const
AppRoutesComponent
:
React
.
FC
=
()
=>
{
return
(
<
Routes
>
<
Route
path=
"/"
element=
{
<
Home
/>
}
>
<
Route
path=
"/chat/:id"
element=
{
<
Chat
/>
}
/>
<
Route
path=
"/chat/:id"
element=
{
<
Chat
Entry
/>
}
/>
</
Route
>
<
Route
path=
"/home"
element=
{
<
Home
/>
}
></
Route
>
<
Route
path=
"/collect"
element=
{
<
Collect
/>
}
/>
...
...
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