Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
8767c576
authored
Apr 25, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: stop chat
parent
fb08f61e
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
50 additions
and
44 deletions
+50
-44
public/docs/versionIntro.md
+1
-0
src/api/fetch.ts
+9
-5
src/components/Icon/icons/chatting.svg
+0
-20
src/components/Icon/icons/stop.svg
+2
-0
src/components/Icon/index.tsx
+2
-2
src/pages/chat/index.module.scss
+11
-0
src/pages/chat/index.tsx
+25
-17
No files found.
public/docs/versionIntro.md
View file @
8767c576
### Fast GPT V2.8.1
### Fast GPT V2.8.1
*
新增 - 暂停聊天。
*
优化 - 知识库升级,内容条数不上限!
*
优化 - 知识库升级,内容条数不上限!
*
优化 - 导入去重效果,可防止导出后的 csv 重复导入。
*
优化 - 导入去重效果,可防止导出后的 csv 重复导入。
*
优化 - 聊天框,电脑端复制删除图标。
*
优化 - 聊天框,电脑端复制删除图标。
...
...
src/api/fetch.ts
View file @
8767c576
...
@@ -6,7 +6,7 @@ interface StreamFetchProps {
...
@@ -6,7 +6,7 @@ interface StreamFetchProps {
abortSignal
:
AbortController
;
abortSignal
:
AbortController
;
}
}
export
const
streamFetch
=
({
url
,
data
,
onMessage
,
abortSignal
}:
StreamFetchProps
)
=>
export
const
streamFetch
=
({
url
,
data
,
onMessage
,
abortSignal
}:
StreamFetchProps
)
=>
new
Promise
(
async
(
resolve
,
reject
)
=>
{
new
Promise
<
string
>
(
async
(
resolve
,
reject
)
=>
{
try
{
try
{
const
res
=
await
fetch
(
url
,
{
const
res
=
await
fetch
(
url
,
{
method
:
'POST'
,
method
:
'POST'
,
...
@@ -23,17 +23,14 @@ export const streamFetch = ({ url, data, onMessage, abortSignal }: StreamFetchPr
...
@@ -23,17 +23,14 @@ export const streamFetch = ({ url, data, onMessage, abortSignal }: StreamFetchPr
let
responseText
=
''
;
let
responseText
=
''
;
const
read
=
async
()
=>
{
const
read
=
async
()
=>
{
try
{
const
{
done
,
value
}
=
await
reader
?.
read
();
const
{
done
,
value
}
=
await
reader
?.
read
();
if
(
done
)
{
if
(
done
)
{
if
(
res
.
status
===
200
)
{
if
(
res
.
status
===
200
)
{
resolve
(
responseText
);
resolve
(
responseText
);
}
else
{
}
else
{
try
{
const
parseError
=
JSON
.
parse
(
responseText
);
const
parseError
=
JSON
.
parse
(
responseText
);
reject
(
parseError
?.
message
||
'请求异常'
);
reject
(
parseError
?.
message
||
'请求异常'
);
}
catch
(
err
)
{
reject
(
'请求异常'
);
}
}
}
return
;
return
;
...
@@ -42,7 +39,14 @@ export const streamFetch = ({ url, data, onMessage, abortSignal }: StreamFetchPr
...
@@ -42,7 +39,14 @@ export const streamFetch = ({ url, data, onMessage, abortSignal }: StreamFetchPr
res
.
status
===
200
&&
onMessage
(
text
);
res
.
status
===
200
&&
onMessage
(
text
);
responseText
+=
text
;
responseText
+=
text
;
read
();
read
();
}
catch
(
err
:
any
)
{
if
(
err
?.
message
===
'The user aborted a request.'
)
{
return
resolve
(
responseText
);
}
reject
(
typeof
err
===
'string'
?
err
:
err
?.
message
||
'请求异常'
);
}
};
};
read
();
read
();
}
catch
(
err
:
any
)
{
}
catch
(
err
:
any
)
{
console
.
log
(
err
,
'===='
);
console
.
log
(
err
,
'===='
);
...
...
src/components/Icon/icons/chatting.svg
deleted
100644 → 0
View file @
fb08f61e
<?xml version="1.0" encoding="utf-8"?>
<svg
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
style=
"margin: auto; background: none; display: block; shape-rendering: auto;"
width=
"204px"
height=
"204px"
viewBox=
"0 0 100 100"
preserveAspectRatio=
"xMidYMid"
>
<circle
cx=
"84"
cy=
"50"
r=
"10"
fill=
"#e15b64"
>
<animate
attributeName=
"r"
repeatCount=
"indefinite"
dur=
"0.5681818181818182s"
calcMode=
"spline"
keyTimes=
"0;1"
values=
"15;0"
keySplines=
"0 0.5 0.5 1"
begin=
"0s"
></animate>
<animate
attributeName=
"fill"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"discrete"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"#e15b64;#abbd81;#f8b26a;#f47e60;#e15b64"
begin=
"0s"
></animate>
</circle><circle
cx=
"16"
cy=
"50"
r=
"10"
fill=
"#e15b64"
>
<animate
attributeName=
"r"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"0;0;15;15;15"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"0s"
></animate>
<animate
attributeName=
"cx"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"16;16;16;50;84"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"0s"
></animate>
</circle><circle
cx=
"50"
cy=
"50"
r=
"10"
fill=
"#f47e60"
>
<animate
attributeName=
"r"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"0;0;15;15;15"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"-0.5681818181818182s"
></animate>
<animate
attributeName=
"cx"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"16;16;16;50;84"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"-0.5681818181818182s"
></animate>
</circle><circle
cx=
"84"
cy=
"50"
r=
"10"
fill=
"#f8b26a"
>
<animate
attributeName=
"r"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"0;0;15;15;15"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"-1.1363636363636365s"
></animate>
<animate
attributeName=
"cx"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"16;16;16;50;84"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"-1.1363636363636365s"
></animate>
</circle><circle
cx=
"16"
cy=
"50"
r=
"10"
fill=
"#abbd81"
>
<animate
attributeName=
"r"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"0;0;15;15;15"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"-1.7045454545454546s"
></animate>
<animate
attributeName=
"cx"
repeatCount=
"indefinite"
dur=
"2.272727272727273s"
calcMode=
"spline"
keyTimes=
"0;0.25;0.5;0.75;1"
values=
"16;16;16;50;84"
keySplines=
"0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1;0 0.5 0.5 1"
begin=
"-1.7045454545454546s"
></animate>
</circle>
<!-- [ldio] generated by https://loading.io/ -->
</svg>
\ No newline at end of file
src/components/Icon/icons/stop.svg
0 → 100644
View file @
8767c576
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
t=
"1682424901088"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"3662"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
width=
"32"
height=
"32"
><path
d=
"M885.333333 85.333333H138.666667a53.393333 53.393333 0 0 0-53.333334 53.333334v746.666666a53.393333 53.393333 0 0 0 53.333334 53.333334h746.666666a53.393333 53.393333 0 0 0 53.333334-53.333334V138.666667a53.393333 53.393333 0 0 0-53.333334-53.333334z m-160 602.666667a37.373333 37.373333 0 0 1-37.333333 37.333333H336a37.373333 37.373333 0 0 1-37.333333-37.333333V336a37.373333 37.373333 0 0 1 37.333333-37.333333h352a37.373333 37.373333 0 0 1 37.333333 37.333333z"
p-id=
"3663"
></path></svg>
\ No newline at end of file
src/components/Icon/index.tsx
View file @
8767c576
...
@@ -13,12 +13,12 @@ const map = {
...
@@ -13,12 +13,12 @@ const map = {
board
:
require
(
'./icons/board.svg'
).
default
,
board
:
require
(
'./icons/board.svg'
).
default
,
develop
:
require
(
'./icons/develop.svg'
).
default
,
develop
:
require
(
'./icons/develop.svg'
).
default
,
user
:
require
(
'./icons/user.svg'
).
default
,
user
:
require
(
'./icons/user.svg'
).
default
,
chatting
:
require
(
'./icons/chatting.svg'
).
default
,
promotion
:
require
(
'./icons/promotion.svg'
).
default
,
promotion
:
require
(
'./icons/promotion.svg'
).
default
,
delete
:
require
(
'./icons/delete.svg'
).
default
,
delete
:
require
(
'./icons/delete.svg'
).
default
,
withdraw
:
require
(
'./icons/withdraw.svg'
).
default
,
withdraw
:
require
(
'./icons/withdraw.svg'
).
default
,
dbModel
:
require
(
'./icons/dbModel.svg'
).
default
,
dbModel
:
require
(
'./icons/dbModel.svg'
).
default
,
history
:
require
(
'./icons/history.svg'
).
default
history
:
require
(
'./icons/history.svg'
).
default
,
stop
:
require
(
'./icons/stop.svg'
).
default
};
};
export
type
IconName
=
keyof
typeof
map
;
export
type
IconName
=
keyof
typeof
map
;
...
...
src/pages/chat/index.module.scss
0 → 100644
View file @
8767c576
.stopIcon
{
animation
:
zoomStopIcon
0
.4s
infinite
alternate
;
}
@keyframes
zoomStopIcon
{
0
%
{
transform
:
scale
(
0
.8
);
}
100
%
{
transform
:
scale
(
1
.2
);
}
}
src/pages/chat/index.tsx
View file @
8767c576
...
@@ -36,6 +36,8 @@ const SlideBar = dynamic(() => import('./components/SlideBar'));
...
@@ -36,6 +36,8 @@ const SlideBar = dynamic(() => import('./components/SlideBar'));
const
Empty
=
dynamic
(()
=>
import
(
'./components/Empty'
));
const
Empty
=
dynamic
(()
=>
import
(
'./components/Empty'
));
const
Markdown
=
dynamic
(()
=>
import
(
'@/components/Markdown'
));
const
Markdown
=
dynamic
(()
=>
import
(
'@/components/Markdown'
));
import
styles
from
'./index.module.scss'
;
const
textareaMinH
=
'22px'
;
const
textareaMinH
=
'22px'
;
export
type
ChatSiteItemType
=
{
export
type
ChatSiteItemType
=
{
...
@@ -202,8 +204,9 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
...
@@ -202,8 +204,9 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
obj
:
prompts
.
obj
,
obj
:
prompts
.
obj
,
value
:
prompts
.
value
value
:
prompts
.
value
};
};
// 流请求,获取数据
// 流请求,获取数据
const
res
=
await
streamFetch
({
const
res
ponseText
=
await
streamFetch
({
url
:
urlMap
[
chatData
.
modelName
],
url
:
urlMap
[
chatData
.
modelName
],
data
:
{
data
:
{
prompt
,
prompt
,
...
@@ -226,22 +229,22 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
...
@@ -226,22 +229,22 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
abortSignal
abortSignal
});
});
let
i
d
=
''
;
let
newChatI
d
=
''
;
// 保存对话信息
// 保存对话信息
try
{
try
{
i
d
=
await
postSaveChat
({
newChatI
d
=
await
postSaveChat
({
modelId
,
modelId
,
chatId
,
chatId
,
prompts
:
[
prompts
:
[
prompt
,
prompt
,
{
{
obj
:
'AI'
,
obj
:
'AI'
,
value
:
res
as
string
value
:
res
ponseText
}
}
]
]
});
});
if
(
i
d
)
{
if
(
newChatI
d
)
{
router
.
replace
(
`/chat?modelId=
${
modelId
}
&chatId=
${
i
d
}
`
);
router
.
replace
(
`/chat?modelId=
${
modelId
}
&chatId=
${
newChatI
d
}
`
);
}
}
}
catch
(
err
)
{
}
catch
(
err
)
{
toast
({
toast
({
...
@@ -252,10 +255,10 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
...
@@ -252,10 +255,10 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
});
});
}
}
// 设置完成状态
// 设置
聊天内容为
完成状态
setChatData
((
state
)
=>
({
setChatData
((
state
)
=>
({
...
state
,
...
state
,
chatId
:
i
d
||
state
.
chatId
,
// 如果有 Id,说明是新创建的对话
chatId
:
newChatI
d
||
state
.
chatId
,
// 如果有 Id,说明是新创建的对话
history
:
state
.
history
.
map
((
item
,
index
)
=>
{
history
:
state
.
history
.
map
((
item
,
index
)
=>
{
if
(
index
!==
state
.
history
.
length
-
1
)
return
item
;
if
(
index
!==
state
.
history
.
length
-
1
)
return
item
;
return
{
return
{
...
@@ -559,19 +562,23 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
...
@@ -559,19 +562,23 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
<
Flex
<
Flex
alignItems=
{
'center'
}
alignItems=
{
'center'
}
justifyContent=
{
'center'
}
justifyContent=
{
'center'
}
h=
{
'
30
px'
}
h=
{
'
25
px'
}
w=
{
'
30
px'
}
w=
{
'
25
px'
}
position=
{
'absolute'
}
position=
{
'absolute'
}
right=
{
[
'12px'
,
'20px'
]
}
right=
{
[
'12px'
,
'20px'
]
}
bottom=
{
'15px'
}
bottom=
{
'15px'
}
onClick=
{
sendPrompt
}
>
>
{
isChatting
?
(
{
isChatting
?
(
<
Icon
<
Icon
style=
{
{
transform
:
'translateY(4px)'
}
}
className=
{
styles
.
stopIcon
}
h=
{
'30px'
}
width=
{
[
'22px'
,
'25px'
]
}
w=
{
'30px'
}
height=
{
[
'22px'
,
'25px'
]
}
name=
{
'chatting'
}
cursor=
{
'pointer'
}
name=
{
'stop'
}
color=
{
useColorModeValue
(
'gray.500'
,
'white'
)
}
onClick=
{
()
=>
{
controller
.
current
?.
abort
();
}
}
/>
/>
)
:
(
)
:
(
<
Icon
<
Icon
...
@@ -579,8 +586,9 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
...
@@ -579,8 +586,9 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => {
width=
{
[
'18px'
,
'20px'
]
}
width=
{
[
'18px'
,
'20px'
]
}
height=
{
[
'18px'
,
'20px'
]
}
height=
{
[
'18px'
,
'20px'
]
}
cursor=
{
'pointer'
}
cursor=
{
'pointer'
}
fill=
{
useColorModeValue
(
'#718096'
,
'white'
)
}
color=
{
useColorModeValue
(
'gray.500'
,
'white'
)
}
></
Icon
>
onClick=
{
sendPrompt
}
/>
)
}
)
}
</
Flex
>
</
Flex
>
</
Box
>
</
Box
>
...
...
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