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
883b6d47
Commit
883b6d47
authored
Oct 27, 2025
by
Liu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix:按钮逻辑分离&&欢迎语
parent
6c761774
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
61 additions
and
18 deletions
+61
-18
src/components/ChatEditor/index.tsx
+5
-5
src/pages/Chat/Chat.tsx
+17
-3
src/pages/Chat/components/ChatWelcome/index.tsx
+14
-2
src/pages/Home/HomeNew.tsx
+25
-8
No files found.
src/components/ChatEditor/index.tsx
View file @
883b6d47
...
@@ -15,7 +15,7 @@ interface ChatEditorProps {
...
@@ -15,7 +15,7 @@ interface ChatEditorProps {
onChange
?:
(
value
:
string
)
=>
void
onChange
?:
(
value
:
string
)
=>
void
onFocus
?:
()
=>
void
onFocus
?:
()
=>
void
onSubmit
?:
(
value
:
string
,
toolId
?:
string
)
=>
void
onSubmit
?:
(
value
:
string
,
toolId
?:
string
)
=>
void
onToolClick
?:
(
isToolBtn
:
boolean
,
toolId
?:
string
)
=>
void
onToolClick
?:
(
isToolBtn
:
boolean
,
toolId
?:
string
,
shouldChangeStyle
?:
boolean
)
=>
void
placeholders
:
string
[]
placeholders
:
string
[]
showContentTips
?:
boolean
showContentTips
?:
boolean
initialValue
?:
string
initialValue
?:
string
...
@@ -130,16 +130,16 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -130,16 +130,16 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
}
}
// 切换到工具模式(false 表示工具模式,会切换左侧展示)
// 切换到工具模式(false 表示工具模式,会切换左侧展示)
setIsToolBtnActive
(
false
)
setIsToolBtnActive
(
false
)
// 调用父组件的回调函数,传递工具模式状态和工具ID
// 调用父组件的回调函数,传递工具模式状态和工具ID
,以及是否需要改变样式
onToolClick
?.(
false
,
currentToolId
)
onToolClick
?.(
false
,
currentToolId
,
true
)
}
}
// 处理通用模式按钮点击
// 处理通用模式按钮点击
const
handleGeneralClick
=
()
=>
{
const
handleGeneralClick
=
()
=>
{
// 切换到通用模式(true 表示通用模式,恢复默认不切换左侧)
// 切换到通用模式(true 表示通用模式,恢复默认不切换左侧)
setIsToolBtnActive
(
true
)
setIsToolBtnActive
(
true
)
// 调用父组件的回调函数,传递通用模式状态和工具ID
// 调用父组件的回调函数,传递通用模式状态和工具ID
,以及是否需要改变样式
onToolClick
?.(
false
,
undefined
)
onToolClick
?.(
true
,
undefined
,
false
)
}
}
useEffect
(()
=>
{
useEffect
(()
=>
{
...
...
src/pages/Chat/Chat.tsx
View file @
883b6d47
...
@@ -30,6 +30,7 @@ export const Chat: React.FC = () => {
...
@@ -30,6 +30,7 @@ export const Chat: 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
[
isEfficiencyMode
,
setIsEfficiencyMode
]
=
useState
(
false
)
/** 处理正常stream的数据 */
/** 处理正常stream的数据 */
const
handleStreamMesageData
=
(
msg
:
any
,
question
:
string
)
=>
{
const
handleStreamMesageData
=
(
msg
:
any
,
question
:
string
)
=>
{
...
@@ -268,6 +269,19 @@ export const Chat: React.FC = () => {
...
@@ -268,6 +269,19 @@ export const Chat: React.FC = () => {
}
}
},
[
shouldSendQuestion
,
isLoading
])
},
[
shouldSendQuestion
,
isLoading
])
// 监听工具按钮点击事件,更新 ChatWelcome 提示语
useEffect
(()
=>
{
const
handleToolClickEvent
=
(
event
:
CustomEvent
)
=>
{
const
{
isToolBtn
}
=
event
.
detail
// isToolBtn = true 表示通用模式,false 表示提质增效模式
setIsEfficiencyMode
(
!
isToolBtn
)
}
window
.
addEventListener
(
'toolButtonClick'
,
handleToolClickEvent
as
EventListener
)
return
()
=>
{
window
.
removeEventListener
(
'toolButtonClick'
,
handleToolClickEvent
as
EventListener
)
}
},
[])
return
(
return
(
<
div
className=
{
styles
.
scrollView
}
>
<
div
className=
{
styles
.
scrollView
}
>
<
div
className=
{
`${styles.chatPage} relative`
}
>
<
div
className=
{
`${styles.chatPage} relative`
}
>
...
@@ -298,7 +312,7 @@ export const Chat: React.FC = () => {
...
@@ -298,7 +312,7 @@ export const Chat: React.FC = () => {
record.question || record.answerList?.[0]?.answer || ''
record.question || record.answerList?.[0]?.answer || ''
}`
}
}`
}
>
>
{
record
.
role
===
'system'
&&
<
ChatWelcome
/>
}
{
record
.
role
===
'system'
&&
<
ChatWelcome
isEfficiencyMode=
{
isEfficiencyMode
}
/>
}
{
record
.
role
===
'user'
&&
<
ChatItemUser
record=
{
record
}
/>
}
{
record
.
role
===
'user'
&&
<
ChatItemUser
record=
{
record
}
/>
}
{
record
.
role
===
'ai'
&&
(
{
record
.
role
===
'ai'
&&
(
<
ChatAnswerBox
<
ChatAnswerBox
...
@@ -333,10 +347,10 @@ export const Chat: React.FC = () => {
...
@@ -333,10 +347,10 @@ export const Chat: React.FC = () => {
</
div
>
</
div
>
<
ChatEditor
<
ChatEditor
onSubmit=
{
(
question
,
toolId
)
=>
handleSubmitQuestion
(
question
,
undefined
,
toolId
)
}
onSubmit=
{
(
question
,
toolId
)
=>
handleSubmitQuestion
(
question
,
undefined
,
toolId
)
}
onToolClick=
{
(
isToolBtn
,
toolId
)
=>
{
onToolClick=
{
(
isToolBtn
,
toolId
,
shouldChangeStyle
)
=>
{
// 发送自定义事件到父组件
// 发送自定义事件到父组件
window
.
dispatchEvent
(
new
CustomEvent
(
'toolButtonClick'
,
{
window
.
dispatchEvent
(
new
CustomEvent
(
'toolButtonClick'
,
{
detail
:
{
isToolBtn
,
toolId
},
detail
:
{
isToolBtn
,
toolId
,
shouldChangeStyle
},
}))
}))
}
}
}
}
placeholders=
{
[]
}
placeholders=
{
[]
}
...
...
src/pages/Chat/components/ChatWelcome/index.tsx
View file @
883b6d47
...
@@ -3,9 +3,21 @@ import { motion } from 'framer-motion'
...
@@ -3,9 +3,21 @@ import { motion } from 'framer-motion'
import
AvatarBot
from
'@/assets/avatarBot.png'
import
AvatarBot
from
'@/assets/avatarBot.png'
import
AIIcon
from
'@/assets/ai-icon.png'
import
AIIcon
from
'@/assets/ai-icon.png'
export
const
ChatWelcome
:
React
.
FC
=
()
=>
{
interface
ChatWelcomeProps
{
isEfficiencyMode
?:
boolean
}
export
const
ChatWelcome
:
React
.
FC
<
ChatWelcomeProps
>
=
({
isEfficiencyMode
=
false
})
=>
{
const
viteOutputObj
=
import
.
meta
.
env
.
VITE_OUTPUT_OBJ
||
'open'
const
viteOutputObj
=
import
.
meta
.
env
.
VITE_OUTPUT_OBJ
||
'open'
// 根据模式显示不同的提示语
const
getWelcomeText
=
()
=>
{
if
(
isEfficiencyMode
)
{
return
'HI~ 我是您的提质增效助手,有什么可以帮您?'
}
return
'您好,有什么我可以帮您的吗?'
}
return
(
return
(
<
div
className=
"chatWelcomeContainer w-full"
>
<
div
className=
"chatWelcomeContainer w-full"
>
<
div
className=
"h-[20px] sm:h-[32px] w-full"
></
div
>
<
div
className=
"h-[20px] sm:h-[32px] w-full"
></
div
>
...
@@ -20,7 +32,7 @@ export const ChatWelcome: React.FC = () => {
...
@@ -20,7 +32,7 @@ export const ChatWelcome: React.FC = () => {
className=
"font-medium text-[#333]"
className=
"font-medium text-[#333]"
style=
{
{
fontSize
:
'16px'
}
}
style=
{
{
fontSize
:
'16px'
}
}
>
>
您好,有什么我可以帮您的吗?
{
getWelcomeText
()
}
</
p
>
</
p
>
{
/* <p className="text-[15px] mt-[4px] sm:mt-[8px] sm:text-13px text-[#27353C] font-300">作为您的智能保险伙伴,您有各类专业相关的问题都可以抛给我哟~让我们互相帮助共同成长吧~</p> */
}
{
/* <p className="text-[15px] mt-[4px] sm:mt-[8px] sm:text-13px text-[#27353C] font-300">作为您的智能保险伙伴,您有各类专业相关的问题都可以抛给我哟~让我们互相帮助共同成长吧~</p> */
}
</
div
>
</
div
>
...
...
src/pages/Home/HomeNew.tsx
View file @
883b6d47
...
@@ -51,6 +51,7 @@ export const Home: React.FC = () => {
...
@@ -51,6 +51,7 @@ export const Home: React.FC = () => {
const
[
productQuestions
,
setProductQuestions
]
=
useState
<
any
>
({
content
:
[]
})
const
[
productQuestions
,
setProductQuestions
]
=
useState
<
any
>
({
content
:
[]
})
const
[
otherQuestions
,
setOtherQuestions
]
=
useState
<
any
>
({
content
:
[]
})
const
[
otherQuestions
,
setOtherQuestions
]
=
useState
<
any
>
({
content
:
[]
})
const
[
isToolBtnActive
,
setIsToolBtnActive
]
=
useState
<
boolean
>
(
false
)
const
[
isToolBtnActive
,
setIsToolBtnActive
]
=
useState
<
boolean
>
(
false
)
const
[
shouldChangeStyle
,
setShouldChangeStyle
]
=
useState
<
boolean
>
(
false
)
// 保存原始的configType为07的数据
// 保存原始的configType为07的数据
const
[
originalOtherQuestions
,
setOriginalOtherQuestions
]
=
useState
<
any
>
({
content
:
[]
})
const
[
originalOtherQuestions
,
setOriginalOtherQuestions
]
=
useState
<
any
>
({
content
:
[]
})
...
@@ -146,15 +147,31 @@ finally {
...
@@ -146,15 +147,31 @@ finally {
// 监听工具按钮点击事件
// 监听工具按钮点击事件
useEffect
(()
=>
{
useEffect
(()
=>
{
const
handleToolClickEvent
=
(
event
:
CustomEvent
)
=>
{
const
handleToolClickEvent
=
(
event
:
CustomEvent
)
=>
{
const
{
isToolBtn
,
toolId
}
=
event
.
detail
const
{
isToolBtn
,
toolId
,
shouldChangeStyle
:
shouldChangeStyleParam
}
=
event
.
detail
// eslint-disable-next-line no-console
console
.
log
(
'🔧 工具按钮点击事件触发:'
,
{
isToolBtn
,
toolId
,
shouldChangeStyle
:
shouldChangeStyleParam
,
当前
isToolBtnActive
:
isToolBtnActive
,
当前
shouldChangeStyle
:
shouldChangeStyle
,
})
setIsToolBtnActive
(
isToolBtn
)
setIsToolBtnActive
(
isToolBtn
)
// 更新样式控制状态
if
(
shouldChangeStyleParam
!==
undefined
)
{
setShouldChangeStyle
(
shouldChangeStyleParam
)
}
// eslint-disable-next-line no-console
console
.
log
(
'✅ isToolBtnActive 已更新为:'
,
isToolBtn
)
// eslint-disable-next-line no-console
console
.
log
(
'🎨 shouldChangeStyle 已更新为:'
,
shouldChangeStyleParam
)
_handleToolClick
(
isToolBtn
,
toolId
)
_handleToolClick
(
isToolBtn
,
toolId
)
}
}
window
.
addEventListener
(
'toolButtonClick'
,
handleToolClickEvent
as
EventListener
)
window
.
addEventListener
(
'toolButtonClick'
,
handleToolClickEvent
as
EventListener
)
return
()
=>
{
return
()
=>
{
window
.
removeEventListener
(
'toolButtonClick'
,
handleToolClickEvent
as
EventListener
)
window
.
removeEventListener
(
'toolButtonClick'
,
handleToolClickEvent
as
EventListener
)
}
}
},
[
_handleToolClick
])
},
[
_handleToolClick
,
isToolBtnActive
,
shouldChangeStyle
])
const
login
=
useCallback
(
async
()
=>
{
const
login
=
useCallback
(
async
()
=>
{
// 防止重复调用
// 防止重复调用
...
@@ -235,9 +252,9 @@ finally {
...
@@ -235,9 +252,9 @@ finally {
{
/* 左侧区域 - 产品问答和您可以试着问我 */
}
{
/* 左侧区域 - 产品问答和您可以试着问我 */
}
<
div
<
div
className=
"flex flex-col gap-[20px] items-center overflow-y-auto scrollbar-hide"
className=
"flex flex-col gap-[20px] items-center overflow-y-auto scrollbar-hide"
style=
{
{
height
:
isToolBtnActive
?
'calc(-64px + 100vh)'
:
'500px'
,
background
:
isToolBtnActiv
e
?
'linear-gradient(180deg, #F0F8FF 0%, #FFFFFF 50%, #FFFFFF 100%)'
:
''
,
borderRadius
:
'24px'
}
}
style=
{
{
height
:
shouldChangeStyle
?
'calc(-64px + 100vh)'
:
'500px'
,
background
:
shouldChangeStyl
e
?
'linear-gradient(180deg, #F0F8FF 0%, #FFFFFF 50%, #FFFFFF 100%)'
:
''
,
borderRadius
:
'24px'
}
}
>
>
{
!
isToolBtnActiv
e
&&
(
{
!
shouldChangeStyl
e
&&
(
<
motion
.
div
className=
"w-full sm:w-auto"
{
...
getAnimationProps
(2)}
>
<
motion
.
div
className=
"w-full sm:w-auto"
{
...
getAnimationProps
(2)}
>
<
QuestionList
<
QuestionList
questions=
{
productQuestions
.
content
}
questions=
{
productQuestions
.
content
}
...
@@ -245,7 +262,7 @@ finally {
...
@@ -245,7 +262,7 @@ finally {
background=
"linear-gradient(180deg, #EBE6FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
background=
"linear-gradient(180deg, #EBE6FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
title=
{
productQuestions
.
configName
}
title=
{
productQuestions
.
configName
}
iconImg=
{
HomeIcon1
}
iconImg=
{
HomeIcon1
}
isToolBtn=
{
isToolBtnActiv
e
}
isToolBtn=
{
shouldChangeStyl
e
}
isLoaded=
{
isDataLoaded
}
isLoaded=
{
isDataLoaded
}
/>
/>
</
motion
.
div
>
</
motion
.
div
>
...
@@ -255,14 +272,14 @@ finally {
...
@@ -255,14 +272,14 @@ finally {
questions=
{
otherQuestions
.
content
}
questions=
{
otherQuestions
.
content
}
dotColor=
"#CBECFF"
dotColor=
"#CBECFF"
background=
"linear-gradient(180deg, #F0F8FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
background=
"linear-gradient(180deg, #F0F8FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
height=
{
isToolBtnActiv
e
?
'288px'
:
'auto'
}
height=
{
shouldChangeStyl
e
?
'288px'
:
'auto'
}
title=
{
otherQuestions
.
configName
}
title=
{
otherQuestions
.
configName
}
iconImg=
{
HomeIcon2
}
iconImg=
{
HomeIcon2
}
isToolBtn=
{
isToolBtnActiv
e
}
isToolBtn=
{
shouldChangeStyl
e
}
isLoaded=
{
isDataLoaded
}
isLoaded=
{
isDataLoaded
}
/>
/>
</
motion
.
div
>
</
motion
.
div
>
{
isToolBtnActiv
e
&&
(
{
shouldChangeStyl
e
&&
(
<
div
>
<
div
>
<
img
src=
{
SmartIce
}
alt=
"Smart Ice"
className=
"w-[260px] h-[218px] mt-[-12px] object-contain"
/>
<
img
src=
{
SmartIce
}
alt=
"Smart Ice"
className=
"w-[260px] h-[218px] mt-[-12px] object-contain"
/>
</
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