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
7594fa09
Commit
7594fa09
authored
Dec 11, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:对话样式
parent
e3e83b1c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
8 deletions
+65
-8
src/pages/ChatTactics/TacticsChat.tsx
+30
-6
src/pages/ChatTactics/TacticsHome.tsx
+2
-2
src/pages/ChatTactics/components/TacticsWelcome/index.tsx
+33
-0
No files found.
src/pages/ChatTactics/TacticsChat.tsx
View file @
7594fa09
// 问答功能独立聊天页
// 问答功能独立聊天页
import
React
,
{
useCallback
,
useEffect
,
useRef
,
useState
}
from
'react'
import
React
,
{
useCallback
,
useEffect
,
useRef
,
useState
}
from
'react'
import
{
useLocation
,
useParams
}
from
'react-router-dom'
import
{
useLocation
,
use
Navigate
,
use
Params
}
from
'react-router-dom'
import
{
Button
}
from
'@heroui/react'
import
{
Button
}
from
'@heroui/react'
import
{
motion
}
from
'framer-motion'
import
{
motion
}
from
'framer-motion'
import
{
useScroll
}
from
'ahooks'
import
{
useScroll
}
from
'ahooks'
import
styles
from
'../Chat/Chat.module.less'
import
styles
from
'../Chat/Chat.module.less'
import
{
processApiResponse
}
from
'../Chat/helper'
import
{
processApiResponse
}
from
'../Chat/helper'
import
{
ChatWelcome
}
from
'../Chat/components/ChatWelcome'
import
{
ChatItemUser
}
from
'../Chat/components/ChatItem/ChatItemUser'
import
{
ChatItemUser
}
from
'../Chat/components/ChatItem/ChatItemUser'
import
{
ChatAnswerBox
}
from
'../Chat/components/ChatItem/ChatAnswerBox'
import
{
ChatAnswerBox
}
from
'../Chat/components/ChatItem/ChatAnswerBox'
import
{
TacticsWelcome
}
from
'./components/TacticsWelcome'
import
{
ChatEditor
}
from
'@/components/ChatEditor'
import
{
ChatEditor
}
from
'@/components/ChatEditor'
import
type
{
ChatRecord
}
from
'@/types/chat'
import
type
{
ChatRecord
}
from
'@/types/chat'
import
{
fetchTacticsQaRecordPage
}
from
'@/api/tactics'
import
{
fetchTacticsQaRecordPage
}
from
'@/api/tactics'
import
{
fetchCheckTokenApi
,
fetchStreamResponse
}
from
'@/api/chat'
import
{
fetchCheckTokenApi
,
fetchStreamResponse
}
from
'@/api/chat'
import
{
clearTactics
ShouldSendQues
tion
}
from
'@/store/tacticsSlice'
import
{
clearTactics
NavigationFlag
,
clearTacticsShouldSendQuestion
,
createTacticsConversa
tion
}
from
'@/store/tacticsSlice'
import
type
{
RootState
}
from
'@/store'
import
type
{
RootState
}
from
'@/store'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
ScrollBtoIcon
from
'@/assets/svg/scrollBto.svg?react'
import
ScrollBtoIcon
from
'@/assets/svg/scrollBto.svg?react'
...
@@ -23,10 +23,15 @@ import SdreamLoading from '@/components/SdreamLoading'
...
@@ -23,10 +23,15 @@ import SdreamLoading from '@/components/SdreamLoading'
export
const
TacticsChat
:
React
.
FC
=
()
=>
{
export
const
TacticsChat
:
React
.
FC
=
()
=>
{
const
{
id
}
=
useParams
<
{
id
:
string
}
>
()
const
{
id
}
=
useParams
<
{
id
:
string
}
>
()
const
location
=
useLocation
()
const
location
=
useLocation
()
const
navigate
=
useNavigate
()
const
[
isLoading
,
setIsLoading
]
=
useState
(
false
)
const
[
isLoading
,
setIsLoading
]
=
useState
(
false
)
const
[
allItems
,
setAllItems
]
=
useState
<
ChatRecord
[]
>
([])
const
[
allItems
,
setAllItems
]
=
useState
<
ChatRecord
[]
>
([])
const
dispatch
=
useAppDispatch
()
const
dispatch
=
useAppDispatch
()
const
{
shouldSendQuestion
:
shouldSendQuestionFromState
}
=
useAppSelector
((
state
:
RootState
)
=>
state
.
tactics
)
const
{
shouldSendQuestion
:
shouldSendQuestionFromState
,
shouldNavigateToNewConversation
,
currentConversationId
,
}
=
useAppSelector
((
state
:
RootState
)
=>
state
.
tactics
)
// 优先从 location.state 获取,其次从 Redux state 获取
// 优先从 location.state 获取,其次从 Redux state 获取
const
shouldSendQuestion
=
(
location
.
state
as
{
shouldSendQuestion
?:
string
}
|
null
)?.
shouldSendQuestion
||
shouldSendQuestionFromState
const
shouldSendQuestion
=
(
location
.
state
as
{
shouldSendQuestion
?:
string
}
|
null
)?.
shouldSendQuestion
||
shouldSendQuestionFromState
const
scrollableRef
=
useRef
<
HTMLDivElement
|
any
>
(
null
)
const
scrollableRef
=
useRef
<
HTMLDivElement
|
any
>
(
null
)
...
@@ -34,6 +39,7 @@ export const TacticsChat: React.FC = () => {
...
@@ -34,6 +39,7 @@ export const TacticsChat: React.FC = () => {
const
currentIdRef
=
useRef
<
string
|
undefined
>
(
id
)
const
currentIdRef
=
useRef
<
string
|
undefined
>
(
id
)
const
lastSentQuestionRef
=
useRef
<
string
>
(
''
)
const
lastSentQuestionRef
=
useRef
<
string
>
(
''
)
const
abortControllerRef
=
useRef
<
AbortController
|
null
>
(
null
)
const
abortControllerRef
=
useRef
<
AbortController
|
null
>
(
null
)
const
hasCreatedRef
=
useRef
(
false
)
/** 处理正常stream的数据 */
/** 处理正常stream的数据 */
const
handleStreamMesageData
=
(
msg
:
any
,
question
:
string
)
=>
{
const
handleStreamMesageData
=
(
msg
:
any
,
question
:
string
)
=>
{
...
@@ -223,12 +229,30 @@ export const TacticsChat: React.FC = () => {
...
@@ -223,12 +229,30 @@ export const TacticsChat: React.FC = () => {
getUserQaRecordPage
(
id
)
getUserQaRecordPage
(
id
)
}
}
else
{
else
{
// 如果没有 id,显示欢迎语
// 如果没有 id,进入页面时创建新会话
if
(
!
hasCreatedRef
.
current
)
{
hasCreatedRef
.
current
=
true
dispatch
(
createTacticsConversation
({
conversationData
:
{},
shouldNavigate
:
true
,
shouldSendQuestion
:
''
,
}),
)
}
setAllItems
([{
role
:
'system'
}
as
ChatRecord
])
setAllItems
([{
role
:
'system'
}
as
ChatRecord
])
setIsLoading
(
false
)
setIsLoading
(
false
)
}
}
},
[
id
,
getUserQaRecordPage
,
dispatch
])
},
[
id
,
getUserQaRecordPage
,
dispatch
])
// 创建新会话成功后跳转到新会话页面
useEffect
(()
=>
{
if
(
shouldNavigateToNewConversation
&&
currentConversationId
)
{
navigate
(
`/tactics/chat/
${
currentConversationId
}
`
)
dispatch
(
clearTacticsNavigationFlag
())
}
},
[
shouldNavigateToNewConversation
,
currentConversationId
,
navigate
,
dispatch
])
// 处理shouldSendQuestion的变化 - 自动发送问题
// 处理shouldSendQuestion的变化 - 自动发送问题
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
if
(
...
@@ -291,7 +315,7 @@ export const TacticsChat: React.FC = () => {
...
@@ -291,7 +315,7 @@ export const TacticsChat: React.FC = () => {
className=
"w-full chatItem mx-auto"
className=
"w-full chatItem mx-auto"
key=
{
uniqueKey
}
key=
{
uniqueKey
}
>
>
{
record
.
role
===
'system'
&&
<
ChatWelcome
toolName=
"问答功能"
/>
}
{
record
.
role
===
'system'
&&
<
TacticsWelcome
/>
}
{
record
.
role
===
'user'
&&
<
ChatItemUser
record=
{
record
}
/>
}
{
record
.
role
===
'user'
&&
<
ChatItemUser
record=
{
record
}
/>
}
{
record
.
role
===
'ai'
&&
(
{
record
.
role
===
'ai'
&&
(
<
ChatAnswerBox
<
ChatAnswerBox
...
...
src/pages/ChatTactics/TacticsHome.tsx
View file @
7594fa09
...
@@ -4,7 +4,7 @@ import { useCallback, useEffect, useRef } from 'react'
...
@@ -4,7 +4,7 @@ import { useCallback, useEffect, useRef } from 'react'
import
{
useLocation
,
useNavigate
}
from
'react-router-dom'
import
{
useLocation
,
useNavigate
}
from
'react-router-dom'
import
{
useLocalStorageState
}
from
'ahooks'
import
{
useLocalStorageState
}
from
'ahooks'
import
styles
from
'../Home/Home.module.less'
import
styles
from
'../Home/Home.module.less'
import
{
ChatWelcome
}
from
'../Chat/components/Chat
Welcome'
import
{
TacticsWelcome
}
from
'./components/Tactics
Welcome'
import
{
clearTacticsNavigationFlag
,
createTacticsConversation
,
fetchTacticsConversations
}
from
'@/store/tacticsSlice'
import
{
clearTacticsNavigationFlag
,
createTacticsConversation
,
fetchTacticsConversations
}
from
'@/store/tacticsSlice'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
{
useAppDispatch
,
useAppSelector
}
from
'@/store/hook'
import
type
{
RootState
}
from
'@/store'
import
type
{
RootState
}
from
'@/store'
...
@@ -149,7 +149,7 @@ export const TacticsHome: React.FC = () => {
...
@@ -149,7 +149,7 @@ export const TacticsHome: React.FC = () => {
<
div
className=
"flex-1 overflow-hidden flex flex-col"
>
<
div
className=
"flex-1 overflow-hidden flex flex-col"
>
{
/* 欢迎语区域 */
}
{
/* 欢迎语区域 */
}
<
div
className=
"flex-1 overflow-y-auto scrollbar-hide px-[16px] pt-[24px]"
>
<
div
className=
"flex-1 overflow-y-auto scrollbar-hide px-[16px] pt-[24px]"
>
<
Chat
Welcome
/>
<
Tactics
Welcome
/>
</
div
>
</
div
>
{
/* 底部输入框 */
}
{
/* 底部输入框 */
}
<
div
className=
"box-border px-[16px] pb-[18px] pt-[12px] bg-white border-t border-gray-100"
>
<
div
className=
"box-border px-[16px] pb-[18px] pt-[12px] bg-white border-t border-gray-100"
>
...
...
src/pages/ChatTactics/components/TacticsWelcome/index.tsx
0 → 100644
View file @
7594fa09
import
type
React
from
'react'
import
{
Avatar
}
from
'@heroui/react'
import
{
motion
}
from
'framer-motion'
import
AvatarBot
from
'@/assets/avatarBot.png'
import
AIIcon
from
'@/assets/ai-icon.png'
export
const
TacticsWelcome
:
React
.
FC
=
()
=>
{
const
viteOutputObj
=
import
.
meta
.
env
.
VITE_OUTPUT_OBJ
||
'open'
const
welcomeText
=
'正在为您分析策略,请耐心等待一会儿哦~'
return
(
<
div
className=
"chatWelcomeContainer w-full"
>
<
div
className=
"h-[20px] sm:h-[32px] w-full"
></
div
>
<
div
className=
"flex items-start"
>
<
Avatar
className=
"mr-[12px] flex-shrink-0"
src=
{
viteOutputObj
===
'inner'
?
AIIcon
:
AvatarBot
}
/>
<
motion
.
div
className=
"rounded-[20px] box-border px-[16px] py-[16px] sm:px-[24px] sm:py-[20px]"
style=
{
{
background
:
'#F7FAFD'
}
}
>
<
div
className=
"content"
>
<
p
className=
"font-medium text-[#333]"
style=
{
{
fontSize
:
'16px'
}
}
>
{
welcomeText
}
</
p
>
</
div
>
</
motion
.
div
>
</
div
>
<
div
className=
"h-[20px] sm:h-[32px] w-full"
></
div
>
</
div
>
)
}
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