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
49fe1fae
Commit
49fe1fae
authored
Aug 25, 2025
by
weiyudumei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 修复历史记录切换和字体大小问题
parent
7f5041ba
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
145 additions
and
89 deletions
+145
-89
src/assets/svg/collect.svg
+3
-3
src/assets/svg/empty.svg
+1
-1
src/assets/svg/historyChat.svg
+2
-2
src/assets/svg/historyMenu.svg
+1
-1
src/assets/svg/search.svg
+1
-1
src/components/ChatEditor/index.tsx
+14
-2
src/config/nav.ts
+1
-1
src/layouts/HistoryBar/components/HistoryBarList/index.tsx
+73
-47
src/pages/Chat/Chat.tsx
+23
-18
src/pages/Chat/components/ChatWelcome/index.tsx
+6
-1
src/pages/Chat/helper.ts
+2
-1
src/pages/Home/HomeNew.tsx
+8
-7
src/pages/Protocol/Protocol.tsx
+2
-2
src/store/conversationSlice.ts
+8
-2
No files found.
src/assets/svg/collect.svg
View file @
49fe1fae
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"26px"
height=
"26px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<svg
width=
"26px"
height=
"26px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
历史
对话
</title>
<title>
历史
记录
</title>
<defs>
<defs>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"24"
height=
"24"
></rect>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"24"
height=
"24"
></rect>
</defs>
</defs>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得-PC端---默认页"
transform=
"translate(-32.000000, -601.000000)"
>
<g
id=
"晓得-PC端---默认页"
transform=
"translate(-32.000000, -601.000000)"
>
<g
id=
"左侧导航栏"
transform=
"translate(12.000000, 290.000000)"
>
<g
id=
"左侧导航栏"
transform=
"translate(12.000000, 290.000000)"
>
<g
id=
"历史
对话
备份"
transform=
"translate(12.000000, 303.000000)"
>
<g
id=
"历史
记录
备份"
transform=
"translate(12.000000, 303.000000)"
>
<rect
id=
"矩形"
x=
"0"
y=
"0"
width=
"40"
height=
"40"
rx=
"14.2857143"
></rect>
<rect
id=
"矩形"
x=
"0"
y=
"0"
width=
"40"
height=
"40"
rx=
"14.2857143"
></rect>
<g
id=
"历史
对话
"
transform=
"translate(8.000000, 8.000000)"
>
<g
id=
"历史
记录
"
transform=
"translate(8.000000, 8.000000)"
>
<mask
id=
"mask-2"
fill=
"white"
>
<mask
id=
"mask-2"
fill=
"white"
>
<use
xlink:href=
"#path-1"
></use>
<use
xlink:href=
"#path-1"
></use>
</mask>
</mask>
...
...
src/assets/svg/empty.svg
View file @
49fe1fae
...
@@ -68,7 +68,7 @@
...
@@ -68,7 +68,7 @@
</filter>
</filter>
</defs>
</defs>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得-PC端---历史
对话
-空"
transform=
"translate(-146.000000, -462.000000)"
>
<g
id=
"晓得-PC端---历史
记录
-空"
transform=
"translate(-146.000000, -462.000000)"
>
<g
id=
"编组-2"
transform=
"translate(80.000000, 152.000000)"
>
<g
id=
"编组-2"
transform=
"translate(80.000000, 152.000000)"
>
<g
id=
"编组-10"
transform=
"translate(66.000000, 310.000000)"
>
<g
id=
"编组-10"
transform=
"translate(66.000000, 310.000000)"
>
<mask
id=
"mask-2"
fill=
"white"
>
<mask
id=
"mask-2"
fill=
"white"
>
...
...
src/assets/svg/historyChat.svg
View file @
49fe1fae
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"24px"
height=
"24px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<svg
width=
"24px"
height=
"24px"
viewBox=
"0 0 24 24"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<title>
历史
对话
</title>
<title>
历史
记录
</title>
<defs>
<defs>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"24"
height=
"24"
></rect>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"24"
height=
"24"
></rect>
</defs>
</defs>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得-PC端---默认页"
transform=
"translate(-32.000000, -507.000000)"
>
<g
id=
"晓得-PC端---默认页"
transform=
"translate(-32.000000, -507.000000)"
>
<g
id=
"左侧导航栏"
transform=
"translate(12.000000, 290.000000)"
>
<g
id=
"左侧导航栏"
transform=
"translate(12.000000, 290.000000)"
>
<g
id=
"历史
对话
"
transform=
"translate(8.000000, 209.000000)"
>
<g
id=
"历史
记录
"
transform=
"translate(8.000000, 209.000000)"
>
<rect
id=
"矩形"
x=
"4"
y=
"0"
width=
"40"
height=
"40"
rx=
"14.2857143"
></rect>
<rect
id=
"矩形"
x=
"4"
y=
"0"
width=
"40"
height=
"40"
rx=
"14.2857143"
></rect>
<g
transform=
"translate(12.000000, 8.000000)"
>
<g
transform=
"translate(12.000000, 8.000000)"
>
<mask
id=
"mask-2"
fill=
"white"
>
<mask
id=
"mask-2"
fill=
"white"
>
...
...
src/assets/svg/historyMenu.svg
View file @
49fe1fae
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
></rect>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
></rect>
</defs>
</defs>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得-PC端---历史
对话
"
transform=
"translate(-162.000000, -920.000000)"
>
<g
id=
"晓得-PC端---历史
记录
"
transform=
"translate(-162.000000, -920.000000)"
>
<g
id=
"编组-2"
transform=
"translate(80.000000, 152.000000)"
>
<g
id=
"编组-2"
transform=
"translate(80.000000, 152.000000)"
>
<g
id=
"编组-13"
transform=
"translate(8.000000, 751.000000)"
>
<g
id=
"编组-13"
transform=
"translate(8.000000, 751.000000)"
>
<g
id=
"形状结合"
transform=
"translate(74.000000, 17.000000)"
>
<g
id=
"形状结合"
transform=
"translate(74.000000, 17.000000)"
>
...
...
src/assets/svg/search.svg
View file @
49fe1fae
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
></rect>
<rect
id=
"path-1"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
></rect>
</defs>
</defs>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得---PC端页面-草稿"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"晓得-PC端---历史
对话
"
transform=
"translate(-132.000000, -186.000000)"
>
<g
id=
"晓得-PC端---历史
记录
"
transform=
"translate(-132.000000, -186.000000)"
>
<g
id=
"编组-2"
transform=
"translate(80.000000, 152.000000)"
>
<g
id=
"编组-2"
transform=
"translate(80.000000, 152.000000)"
>
<g
id=
"编组-5"
transform=
"translate(32.000000, 24.000000)"
>
<g
id=
"编组-5"
transform=
"translate(32.000000, 24.000000)"
>
<g
id=
"编组-4"
transform=
"translate(20.000000, 8.000000)"
>
<g
id=
"编组-4"
transform=
"translate(20.000000, 8.000000)"
>
...
...
src/components/ChatEditor/index.tsx
View file @
49fe1fae
...
@@ -14,11 +14,12 @@ interface ChatEditorProps {
...
@@ -14,11 +14,12 @@ interface ChatEditorProps {
onSubmit
?:
(
value
:
string
)
=>
void
onSubmit
?:
(
value
:
string
)
=>
void
placeholders
:
string
[]
placeholders
:
string
[]
showContentTips
?:
boolean
showContentTips
?:
boolean
initialValue
?:
string
}
}
const
ChatEditorBase
:
React
.
FC
<
ChatEditorProps
&
WithAuthProps
>
=
({
checkAuth
,
onChange
,
onFocus
,
onSubmit
,
placeholders
,
showContentTips
=
false
})
=>
{
const
ChatEditorBase
:
React
.
FC
<
ChatEditorProps
&
WithAuthProps
>
=
({
checkAuth
,
onChange
,
onFocus
,
onSubmit
,
placeholders
,
showContentTips
=
false
,
initialValue
=
''
})
=>
{
// const dispatch = useAppDispatch()
// const dispatch = useAppDispatch()
const
[
content
,
setContent
]
=
useState
(
''
)
const
[
content
,
setContent
]
=
useState
(
initialValue
)
const
editorRef
=
useRef
<
HTMLDivElement
>
(
null
)
const
editorRef
=
useRef
<
HTMLDivElement
>
(
null
)
const
[
currentPlaceholder
,
setCurrentPlaceholder
]
=
useState
(
0
)
const
[
currentPlaceholder
,
setCurrentPlaceholder
]
=
useState
(
0
)
const
intervalRef
=
useRef
<
NodeJS
.
Timeout
|
null
>
(
null
)
const
intervalRef
=
useRef
<
NodeJS
.
Timeout
|
null
>
(
null
)
...
@@ -99,6 +100,17 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
...
@@ -99,6 +100,17 @@ const ChatEditorBase: React.FC<ChatEditorProps & WithAuthProps> = ({ checkAuth,
}
}
},
[
content
])
},
[
content
])
// 处理initialValue的变化
useEffect
(()
=>
{
if
(
initialValue
&&
editorRef
.
current
)
{
setContent
(
initialValue
)
editorRef
.
current
.
textContent
=
initialValue
// 触发高度调整
editorRef
.
current
.
style
.
height
=
'auto'
editorRef
.
current
.
style
.
height
=
`
${
editorRef
.
current
.
scrollHeight
}
px`
}
},
[
initialValue
])
const
[
token
]
=
useLocalStorageState
<
string
|
undefined
>
(
const
[
token
]
=
useLocalStorageState
<
string
|
undefined
>
(
'__TOKEN__'
,
'__TOKEN__'
,
{
{
...
...
src/config/nav.ts
View file @
49fe1fae
...
@@ -6,7 +6,7 @@ export const NAV_BAR_ITEMS = [
...
@@ -6,7 +6,7 @@ export const NAV_BAR_ITEMS = [
// { icon: Logo, label: '', key: 'logo' },
// { icon: Logo, label: '', key: 'logo' },
// { icon: '', label: '', key: 'line1' },
// { icon: '', label: '', key: 'line1' },
{
icon
:
AddNewChat
,
label
:
'新建对话'
,
key
:
'add'
},
{
icon
:
AddNewChat
,
label
:
'新建对话'
,
key
:
'add'
},
{
icon
:
HistoryChat
,
label
:
'历史
对话
'
,
key
:
'history'
},
{
icon
:
HistoryChat
,
label
:
'历史
记录
'
,
key
:
'history'
},
{
icon
:
Collect
,
label
:
'收藏'
,
key
:
'collect'
},
{
icon
:
Collect
,
label
:
'收藏'
,
key
:
'collect'
},
// { icon: '', label: '', key: 'line2' },
// { icon: '', label: '', key: 'line2' },
// { icon: Tools, label: '工具', key: 'tools' },
// { icon: Tools, label: '工具', key: 'tools' },
...
...
src/layouts/HistoryBar/components/HistoryBarList/index.tsx
View file @
49fe1fae
...
@@ -5,10 +5,12 @@ import { useEffect, useState } from 'react'
...
@@ -5,10 +5,12 @@ import { useEffect, useState } from 'react'
import
{
useDebounceFn
}
from
'ahooks'
import
{
useDebounceFn
}
from
'ahooks'
import
{
containerVariants
,
itemVariants
}
from
'../../motionAnimate'
import
{
containerVariants
,
itemVariants
}
from
'../../motionAnimate'
import
EmptyIcon
from
'@/assets/svg/empty.svg?react'
import
EmptyIcon
from
'@/assets/svg/empty.svg?react'
import
{
useAppSelector
}
from
'@/store/hook'
import
{
useApp
Dispatch
,
useApp
Selector
}
from
'@/store/hook'
import
type
{
Conversation
}
from
'@/types/conversation'
import
type
{
Conversation
}
from
'@/types/conversation'
import
{
processConversationData
}
from
'@/store/conversationSlice.helper'
import
{
processConversationData
}
from
'@/store/conversationSlice.helper'
import
{
setShouldSendQuestion
}
from
'@/store/conversationSlice'
import
{
isMobile
}
from
'@/utils'
import
{
isMobile
}
from
'@/utils'
import
{
fetchUserQaRecordPage
}
from
'@/api/conversation'
interface
HistoryBarListProps
{
interface
HistoryBarListProps
{
searchValue
:
string
searchValue
:
string
...
@@ -17,12 +19,36 @@ interface HistoryBarListProps {
...
@@ -17,12 +19,36 @@ interface HistoryBarListProps {
export
const
HistoryBarList
:
React
.
FC
<
HistoryBarListProps
>
=
({
searchValue
,
onSetHistoryVisible
})
=>
{
export
const
HistoryBarList
:
React
.
FC
<
HistoryBarListProps
>
=
({
searchValue
,
onSetHistoryVisible
})
=>
{
const
navigate
=
useNavigate
()
const
navigate
=
useNavigate
()
const
dispatch
=
useAppDispatch
()
const
{
currentConversationId
,
conversations
}
=
useAppSelector
(
state
=>
state
.
conversation
)
const
{
currentConversationId
,
conversations
}
=
useAppSelector
(
state
=>
state
.
conversation
)
const
[
allItems
,
setAllItems
]
=
useState
<
Conversation
[]
>
([])
const
[
allItems
,
setAllItems
]
=
useState
<
Conversation
[]
>
([])
const
handleClick
=
(
conversation
:
Conversation
)
=>
{
const
handleClick
=
async
(
conversation
:
Conversation
)
=>
{
if
(
isMobile
())
{
if
(
isMobile
())
{
onSetHistoryVisible
(
false
)
onSetHistoryVisible
(
false
)
}
}
try
{
// 获取该对话的详细记录
const
res
=
await
fetchUserQaRecordPage
(
conversation
.
conversationId
)
if
(
res
&&
res
.
data
&&
res
.
data
.
length
>
0
)
{
// 获取最后一条用户问题
const
lastRecord
=
res
.
data
[
res
.
data
.
length
-
1
]
if
(
lastRecord
.
question
)
{
// 设置shouldSendQuestion,这样用户就可以继续对话
dispatch
(
setShouldSendQuestion
(
lastRecord
.
question
))
// 等待状态设置完成后再导航
setTimeout
(()
=>
{
navigate
(
`/chat/
${
conversation
.
conversationId
}
`
)
},
50
)
return
}
}
}
catch
(
error
)
{
console
.
error
(
'Failed to fetch conversation details:'
,
error
)
}
navigate
(
`/chat/
${
conversation
.
conversationId
}
`
)
navigate
(
`/chat/
${
conversation
.
conversationId
}
`
)
}
}
...
@@ -38,52 +64,52 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
...
@@ -38,52 +64,52 @@ export const HistoryBarList: React.FC<HistoryBarListProps> = ({ searchValue, onS
return
(
return
(
allItems
.
length
!==
0
allItems
.
length
!==
0
?
(
?
(
<
motion
.
ul
<
motion
.
ul
variants=
{
containerVariants
}
variants=
{
containerVariants
}
initial=
"hidden"
initial=
"hidden"
animate=
"visible"
animate=
"visible"
className=
"w-full flex flex-col gap-[6px]"
className=
"w-full flex flex-col gap-[6px]"
>
>
{
{
allItems
.
map
((
item
,
index
)
=>
(
allItems
.
map
((
item
,
index
)
=>
(
<
motion
.
li
<
motion
.
li
key=
{
`${item.conversationId}-${index
}`
}
key=
{
item
.
conversationId
||
`item-${item.conversationTitle
}`
}
custom=
{
index
}
custom=
{
index
}
variants=
{
itemVariants
}
variants=
{
itemVariants
}
initial=
"hidden"
initial=
"hidden"
animate=
"visible"
animate=
"visible"
exit=
"exit"
exit=
"exit"
layout
layout
>
>
{
{
item
.
conversationId
item
.
conversationId
?
(
?
(
<
Button
<
Button
color=
"primary"
color=
"primary"
variant=
"light"
variant=
"light"
className=
{
`text-left w-full text-[#333] rounded-[23px] data-[hover=true]:bg-[#E5F6FF] data-[hover=true]:text-primary ${currentConversationId === item.conversationId ? 'bg-[#E5F6FF] text-primary' : ''}`
}
className=
{
`text-left w-full text-[#333] rounded-[23px] data-[hover=true]:bg-[#E5F6FF] data-[hover=true]:text-primary ${currentConversationId === item.conversationId ? 'bg-[#E5F6FF] text-primary' : ''}`
}
onPress=
{
()
=>
handleClick
(
item
)
}
onPress=
{
()
=>
handleClick
(
item
)
}
>
>
<
div
className=
"w-full text-nowrap text-ellipsis overflow-hidden"
>
<
div
className=
"w-full text-nowrap text-ellipsis overflow-hidden"
>
<
span
>
{
item
.
conversationTitle
}
</
span
>
<
span
>
{
item
.
conversationTitle
}
</
span
>
</
div
>
</
div
>
</
Button
>
</
Button
>
)
)
:
(
:
(
<
div
className=
"mt-[32px] text-[13px] text-[#B1C6D2]"
>
{
item
.
conversationTitle
}
</
div
>
<
div
className=
"mt-[32px] text-[13px] text-[#B1C6D2]"
>
{
item
.
conversationTitle
}
</
div
>
)
)
}
}
</
motion
.
li
>
</
motion
.
li
>
))
))
}
}
</
motion
.
ul
>
</
motion
.
ul
>
)
)
:
(
:
(
<
div
className=
"flex w-full h-full items-center justify-center flex-col"
>
<
div
className=
"flex w-full h-full items-center justify-center flex-col"
>
<
EmptyIcon
/>
<
EmptyIcon
/>
<
p
className=
"text-[13px] text-[#27353C] mt-[16px]"
>
暂无历史对话
</
p
>
<
p
className=
"text-[13px] text-[#27353C] mt-[16px]"
>
暂无历史记录
</
p
>
</
div
>
</
div
>
)
)
)
)
}
}
src/pages/Chat/Chat.tsx
View file @
49fe1fae
...
@@ -27,6 +27,7 @@ export const Chat: React.FC = () => {
...
@@ -27,6 +27,7 @@ export const Chat: React.FC = () => {
const
{
shouldSendQuestion
}
=
useAppSelector
((
state
:
RootState
)
=>
state
.
conversation
)
const
{
shouldSendQuestion
}
=
useAppSelector
((
state
:
RootState
)
=>
state
.
conversation
)
const
scrollableRef
=
useRef
<
HTMLDivElement
|
any
>
(
null
)
const
scrollableRef
=
useRef
<
HTMLDivElement
|
any
>
(
null
)
const
position
=
useScroll
(
scrollableRef
)
const
position
=
useScroll
(
scrollableRef
)
const
currentIdRef
=
useRef
<
string
|
undefined
>
(
id
)
/** 处理正常stream的数据 */
/** 处理正常stream的数据 */
const
handleStreamMesageData
=
(
msg
:
any
,
question
:
string
)
=>
{
const
handleStreamMesageData
=
(
msg
:
any
,
question
:
string
)
=>
{
...
@@ -42,7 +43,7 @@ export const Chat: React.FC = () => {
...
@@ -42,7 +43,7 @@ export const Chat: React.FC = () => {
{
{
...
msg
.
content
.
data
,
...
msg
.
content
.
data
,
isShow
:
false
,
isShow
:
false
,
answer
:
(
newItems
[
lastIndex
].
answerList
[
0
]
.
answer
||
''
)
+
msg
.
content
.
data
.
answer
,
answer
:
(
newItems
[
lastIndex
].
answerList
?.[
0
]?
.
answer
||
''
)
+
msg
.
content
.
data
.
answer
,
},
},
],
],
}
}
...
@@ -107,24 +108,20 @@ export const Chat: React.FC = () => {
...
@@ -107,24 +108,20 @@ export const Chat: React.FC = () => {
const
handleSubmitQuestion
=
async
(
question
:
string
,
productCode
?:
string
)
=>
{
const
handleSubmitQuestion
=
async
(
question
:
string
,
productCode
?:
string
)
=>
{
const
isNew
=
allItems
.
length
<=
1
const
isNew
=
allItems
.
length
<=
1
dispatch
(
setIsAsking
(
true
))
dispatch
(
setIsAsking
(
true
))
// 添加用户提问的问题
setAllItems
(
prevItems
=>
[
...
prevItems
,
{
role
:
'user'
,
question
,
}
as
ChatRecord
,
])
// 检查token
// 检查token
await
fetchCheckTokenApi
()
await
fetchCheckTokenApi
()
//
添加一条空的ai问题
//
一次性添加用户问题和空的AI回答
setAllItems
(
prevItems
=>
[
setAllItems
(
prevItems
=>
[
...
prevItems
,
...
prevItems
,
{
{
role
:
'user'
,
question
,
}
as
ChatRecord
,
{
role
:
'ai'
,
role
:
'ai'
,
answerList
:
[{}],
answerList
:
[{
answer
:
''
}],
}
as
ChatRecord
,
}
as
ChatRecord
,
])
])
let
fetchUrl
=
`/conversation/api/conversation/mobile/v1/submit_question_stream`
let
fetchUrl
=
`/conversation/api/conversation/mobile/v1/submit_question_stream`
...
@@ -135,7 +132,7 @@ export const Chat: React.FC = () => {
...
@@ -135,7 +132,7 @@ export const Chat: React.FC = () => {
fetchUrl
,
fetchUrl
,
{
{
question
,
question
,
conversationId
:
id
,
conversationId
:
currentIdRef
.
current
,
stream
:
true
,
stream
:
true
,
productCode
,
productCode
,
},
},
...
@@ -166,10 +163,6 @@ export const Chat: React.FC = () => {
...
@@ -166,10 +163,6 @@ export const Chat: React.FC = () => {
const
res
=
await
fetchUserQaRecordPage
(
conversationId
)
const
res
=
await
fetchUserQaRecordPage
(
conversationId
)
const
messages
=
[{
role
:
'system'
}
as
ChatRecord
,
...
processApiResponse
(
res
.
data
)]
const
messages
=
[{
role
:
'system'
}
as
ChatRecord
,
...
processApiResponse
(
res
.
data
)]
setAllItems
(
messages
)
// 假设 API 返回的数据结构符合 ChatRecord[]
setAllItems
(
messages
)
// 假设 API 返回的数据结构符合 ChatRecord[]
if
(
shouldSendQuestion
)
{
handleSubmitQuestion
(
shouldSendQuestion
)
dispatch
(
clearShouldSendQuestion
())
}
}
}
catch
(
error
)
{
catch
(
error
)
{
console
.
error
(
'Failed to fetch chat records:'
,
error
)
console
.
error
(
'Failed to fetch chat records:'
,
error
)
...
@@ -178,7 +171,7 @@ export const Chat: React.FC = () => {
...
@@ -178,7 +171,7 @@ export const Chat: React.FC = () => {
finally
{
finally
{
setIsLoading
(
false
)
setIsLoading
(
false
)
}
}
},
[
shouldSendQuestion
])
},
[])
/** 点击滚动到底部 */
/** 点击滚动到底部 */
const
scrollToBottom
=
()
=>
{
const
scrollToBottom
=
()
=>
{
...
@@ -187,10 +180,22 @@ export const Chat: React.FC = () => {
...
@@ -187,10 +180,22 @@ export const Chat: React.FC = () => {
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
id
)
{
if
(
id
)
{
currentIdRef
.
current
=
id
getUserQaRecordPage
(
id
)
getUserQaRecordPage
(
id
)
}
}
},
[
id
])
},
[
id
])
// 处理shouldSendQuestion的变化 - 自动发送问题
useEffect
(()
=>
{
if
(
shouldSendQuestion
&&
currentIdRef
.
current
&&
!
isLoading
)
{
// 确保历史记录加载完成后再发送问题
setTimeout
(()
=>
{
handleSubmitQuestion
(
shouldSendQuestion
)
dispatch
(
clearShouldSendQuestion
())
},
100
)
}
},
[
shouldSendQuestion
,
isLoading
])
return
(
return
(
<
div
className=
{
styles
.
scrollView
}
>
<
div
className=
{
styles
.
scrollView
}
>
<
div
className=
{
`${styles.chatPage} relative`
}
>
<
div
className=
{
`${styles.chatPage} relative`
}
>
...
@@ -211,7 +216,7 @@ export const Chat: React.FC = () => {
...
@@ -211,7 +216,7 @@ export const Chat: React.FC = () => {
>
>
<
div
className=
{
styles
.
inter
}
>
<
div
className=
{
styles
.
inter
}
>
{
allItems
.
map
((
record
,
index
)
=>
(
{
allItems
.
map
((
record
,
index
)
=>
(
<
div
className=
"w-full chatItem max-w-[912px] mx-auto"
key=
{
index
}
>
<
div
className=
"w-full chatItem max-w-[912px] mx-auto"
key=
{
`${record.role}-${index}-${record.question || record.answerList?.[0]?.answer || ''}`
}
>
{
record
.
role
===
'system'
&&
<
ChatWelcome
/>
}
{
record
.
role
===
'system'
&&
<
ChatWelcome
/>
}
{
record
.
role
===
'user'
&&
<
ChatItemUser
record=
{
record
}
/>
}
{
record
.
role
===
'user'
&&
<
ChatItemUser
record=
{
record
}
/>
}
{
record
.
role
===
'ai'
&&
<
ChatAnswerBox
onSubmitQuestion=
{
handleSubmitQuestion
}
isLastAnswer=
{
index
===
allItems
.
length
-
1
}
showIndex=
{
0
}
record=
{
record
}
index=
{
index
}
/>
}
{
record
.
role
===
'ai'
&&
<
ChatAnswerBox
onSubmitQuestion=
{
handleSubmitQuestion
}
isLastAnswer=
{
index
===
allItems
.
length
-
1
}
showIndex=
{
0
}
record=
{
record
}
index=
{
index
}
/>
}
...
...
src/pages/Chat/components/ChatWelcome/index.tsx
View file @
49fe1fae
...
@@ -13,7 +13,12 @@ export const ChatWelcome: React.FC = () => {
...
@@ -13,7 +13,12 @@ export const ChatWelcome: React.FC = () => {
style=
{
{
background
:
'#F7FAFD'
}
}
style=
{
{
background
:
'#F7FAFD'
}
}
>
>
<
div
className=
"content"
>
<
div
className=
"content"
>
<
p
className=
"text-[16px] sm:text-[18px] font-medium text-[#333]"
>
您好,有什么我可以帮您的吗?
</
p
>
<
p
className=
"font-medium text-[#333]"
style=
{
{
fontSize
:
'16px'
}
}
>
您好,有什么我可以帮您的吗?
</
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
>
</
motion
.
div
>
</
motion
.
div
>
...
...
src/pages/Chat/helper.ts
View file @
49fe1fae
...
@@ -16,7 +16,8 @@ export function processApiResponse(data: OriginalRecord[]): ChatRecord[] {
...
@@ -16,7 +16,8 @@ export function processApiResponse(data: OriginalRecord[]): ChatRecord[] {
})
})
chatRecord
.
push
({
chatRecord
.
push
({
role
:
'ai'
,
role
:
'ai'
,
...
record
,
answerList
:
record
.
answerList
,
question
:
record
.
question
,
})
})
}
}
})
})
...
...
src/pages/Home/HomeNew.tsx
View file @
49fe1fae
...
@@ -11,7 +11,8 @@ import { createConversation, fetchConversations } from '@/store/conversationSlic
...
@@ -11,7 +11,8 @@ import { createConversation, fetchConversations } from '@/store/conversationSlic
import
{
useAppDispatch
}
from
'@/store/hook'
import
{
useAppDispatch
}
from
'@/store/hook'
import
{
fetchQuestionList
}
from
'@/api/home'
import
{
fetchQuestionList
}
from
'@/api/home'
import
SdreamLoading
from
'@/components/SdreamLoading'
import
SdreamLoading
from
'@/components/SdreamLoading'
import
{
fetchLoginByToken
}
from
'@/api/common'
// import { fetchLoginByToken } from '@/api/common'
import
{
fetchLoginByUid
}
from
'@/api/common'
function
getAnimationProps
(
delay
:
number
)
{
function
getAnimationProps
(
delay
:
number
)
{
return
{
return
{
...
@@ -71,7 +72,7 @@ export const Home: React.FC = () => {
...
@@ -71,7 +72,7 @@ export const Home: React.FC = () => {
configTypeList
:
[
'06'
,
'07'
],
configTypeList
:
[
'06'
,
'07'
],
}
}
const
res
=
await
fetchQuestionList
(
param
)
const
res
=
await
fetchQuestionList
(
param
)
if
(
res
.
ok
)
{
if
(
res
&&
res
.
data
)
{
for
(
let
index
=
0
;
index
<
res
.
data
.
length
;
index
++
)
{
for
(
let
index
=
0
;
index
<
res
.
data
.
length
;
index
++
)
{
const
element
=
res
.
data
[
index
]
const
element
=
res
.
data
[
index
]
if
(
element
.
configType
===
'06'
)
{
if
(
element
.
configType
===
'06'
)
{
...
@@ -96,8 +97,8 @@ export const Home: React.FC = () => {
...
@@ -96,8 +97,8 @@ export const Home: React.FC = () => {
const
initConversation
=
()
=>
{
const
initConversation
=
()
=>
{
const
fromCollect
=
location
.
state
?.
fromCollect
const
fromCollect
=
location
.
state
?.
fromCollect
//
在组件挂载时执行dispatch,但只执行一次
//
只有在访问首页时才创建新对话,如果已经在聊天页面则不创建
if
(
!
fromCollect
)
{
if
(
!
fromCollect
&&
location
.
pathname
===
'/'
)
{
dispatch
(
dispatch
(
createConversation
({
createConversation
({
conversationData
:
{},
conversationData
:
{},
...
@@ -123,11 +124,11 @@ export const Home: React.FC = () => {
...
@@ -123,11 +124,11 @@ export const Home: React.FC = () => {
const
url
=
new
URL
(
window
.
location
.
href
)
const
url
=
new
URL
(
window
.
location
.
href
)
// 获取查询参数
// 获取查询参数
const
searchParams
=
new
URLSearchParams
(
url
.
search
)
const
searchParams
=
new
URLSearchParams
(
url
.
search
)
const
loginCode
=
searchParams
.
get
(
'loginCode'
)
const
_
loginCode
=
searchParams
.
get
(
'loginCode'
)
const
res
=
await
fetchLoginByToken
(
loginCode
)
//
const res = await fetchLoginByToken(loginCode)
// 模拟登录 可以用来测试
// 模拟登录 可以用来测试
//
const res = await fetchLoginByUid('123123')
const
res
=
await
fetchLoginByUid
(
'123123'
)
if
(
res
.
data
)
{
if
(
res
.
data
)
{
setToken
(
res
.
data
.
token
)
setToken
(
res
.
data
.
token
)
...
...
src/pages/Protocol/Protocol.tsx
View file @
49fe1fae
...
@@ -303,7 +303,7 @@ const dummyContent02 = [
...
@@ -303,7 +303,7 @@ const dummyContent02 = [
<
br
/>
<
br
/>
您有权查询、复制、更正或补充您的个人信息。您可以通过以下方式进行:
您有权查询、复制、更正或补充您的个人信息。您可以通过以下方式进行:
<
br
/>
<
br
/>
(1)您可以通过点击页面左侧导航键进入“历史会话”板块,查询您的历史
对话
信息。
(1)您可以通过点击页面左侧导航键进入“历史会话”板块,查询您的历史
记录
信息。
<
br
/>
<
br
/>
(2)您可以点击会话输入框底部的“会话收藏”按键,查询您收藏的会话信息。
(2)您可以点击会话输入框底部的“会话收藏”按键,查询您收藏的会话信息。
<
br
/>
<
br
/>
...
@@ -313,7 +313,7 @@ const dummyContent02 = [
...
@@ -313,7 +313,7 @@ const dummyContent02 = [
<
br
/>
<
br
/>
您有权删除您的个人信息。您可以通过以下方式进行:
您有权删除您的个人信息。您可以通过以下方式进行:
<
br
/>
<
br
/>
(1)您可以通过点击页面左侧导航键进入“历史会话”板块,删除您的历史
对话
信息。
(1)您可以通过点击页面左侧导航键进入“历史会话”板块,删除您的历史
记录
信息。
<
br
/>
<
br
/>
(2)如您无法通过服务页面删除您的个人信息,您可以拨打“(一)查询、复制、更正和补充您的信息”中列明的联系电话,联系我们协助删除您的个人信息。
(2)如您无法通过服务页面删除您的个人信息,您可以拨打“(一)查询、复制、更正和补充您的信息”中列明的联系电话,联系我们协助删除您的个人信息。
<
br
/>
<
br
/>
...
...
src/store/conversationSlice.ts
View file @
49fe1fae
...
@@ -84,6 +84,9 @@ const conversationSlice = createSlice({
...
@@ -84,6 +84,9 @@ const conversationSlice = createSlice({
clearShouldSendQuestion
:
(
state
)
=>
{
clearShouldSendQuestion
:
(
state
)
=>
{
state
.
shouldSendQuestion
=
''
state
.
shouldSendQuestion
=
''
},
},
setShouldSendQuestion
:
(
state
,
action
:
PayloadAction
<
string
>
)
=>
{
state
.
shouldSendQuestion
=
action
.
payload
},
addConversation
:
(
state
,
action
:
PayloadAction
<
Conversation
>
)
=>
{
addConversation
:
(
state
,
action
:
PayloadAction
<
Conversation
>
)
=>
{
state
.
conversations
.
unshift
(
action
.
payload
)
state
.
conversations
.
unshift
(
action
.
payload
)
},
},
...
@@ -117,7 +120,10 @@ const conversationSlice = createSlice({
...
@@ -117,7 +120,10 @@ const conversationSlice = createSlice({
})
})
.
addCase
(
createConversation
.
fulfilled
,
(
state
,
action
)
=>
{
.
addCase
(
createConversation
.
fulfilled
,
(
state
,
action
)
=>
{
state
.
isLoading
=
false
state
.
isLoading
=
false
state
.
currentConversationId
=
action
.
payload
.
conversation
.
conversationId
// 只有在需要导航到新对话时才更新currentConversationId
if
(
action
.
payload
.
shouldNavigate
)
{
state
.
currentConversationId
=
action
.
payload
.
conversation
.
conversationId
}
state
.
shouldNavigateToNewConversation
=
action
.
payload
.
shouldNavigate
state
.
shouldNavigateToNewConversation
=
action
.
payload
.
shouldNavigate
state
.
shouldSendQuestion
=
action
.
payload
.
shouldSendQuestion
state
.
shouldSendQuestion
=
action
.
payload
.
shouldSendQuestion
})
})
...
@@ -132,6 +138,6 @@ const conversationSlice = createSlice({
...
@@ -132,6 +138,6 @@ const conversationSlice = createSlice({
},
},
})
})
export
const
{
setCurrentConversation
,
clearCurrentConversation
,
clearNavigationFlag
,
clearShouldSendQuestion
}
=
conversationSlice
.
actions
export
const
{
setCurrentConversation
,
clearCurrentConversation
,
clearNavigationFlag
,
clearShouldSendQuestion
,
setShouldSendQuestion
}
=
conversationSlice
.
actions
export
default
conversationSlice
.
reducer
export
default
conversationSlice
.
reducer
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