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
ea35ad21
authored
Jul 23, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: quote modal
parent
1ffe1be5
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
188 additions
and
209 deletions
+188
-209
client/src/components/ChatBox/QuoteModal.tsx
+11
-56
client/src/components/ChatBox/ResponseDetailModal.tsx
+92
-3
client/src/components/ChatBox/index.tsx
+66
-89
client/src/components/MyTooltip/index.tsx
+10
-2
client/src/pages/api/chat/history/getHistoryQuote.ts
+0
-52
client/src/pages/api/chat/init.ts
+2
-2
client/src/pages/api/openapi/v1/chat/getHistory.ts
+2
-2
client/src/pages/app/detail/components/BasicEdit/index.tsx
+1
-1
client/src/pages/chat/index.tsx
+1
-1
client/src/pages/chat/share.tsx
+3
-1
No files found.
client/src/components/ChatBox/QuoteModal.tsx
View file @
ea35ad21
...
...
@@ -13,21 +13,17 @@ import MyIcon from '@/components/Icon';
import
InputDataModal
from
'@/pages/kb/detail/components/InputDataModal'
;
import
{
getKbDataItemById
}
from
'@/api/plugins/kb'
;
import
{
useLoading
}
from
'@/hooks/useLoading'
;
import
{
useQuery
}
from
'@tanstack/react-query'
;
import
{
getHistoryQuote
,
updateHistoryQuote
}
from
'@/api/chat'
;
import
{
useToast
}
from
'@/hooks/useToast'
;
import
{
getErrText
}
from
'@/utils/tools'
;
import
{
QuoteItemType
}
from
'@/types/chat'
;
const
QuoteModal
=
({
chatId
,
contentId
,
onUpdateQuote
,
rawSearch
=
[],
onClose
}:
{
chatId
?:
string
;
contentId
?:
string
;
rawSearch
?:
QuoteItemType
[];
onUpdateQuote
:
(
quoteId
:
string
,
sourceText
:
string
)
=>
Promise
<
void
>
;
rawSearch
:
QuoteItemType
[];
onClose
:
()
=>
void
;
})
=>
{
const
theme
=
useTheme
();
...
...
@@ -40,47 +36,6 @@ const QuoteModal = ({
q
:
string
;
}
>
();
const
{
data
:
quote
=
[],
refetch
,
isLoading
}
=
useQuery
([
'getHistoryQuote'
],
()
=>
{
if
(
chatId
&&
contentId
)
{
return
getHistoryQuote
({
chatId
,
contentId
});
}
if
(
rawSearch
.
length
>
0
)
{
return
rawSearch
;
}
return
[];
});
/**
* update kbData, update mongo status and reload quotes
*/
const
updateQuoteStatus
=
useCallback
(
async
(
quoteId
:
string
,
sourceText
:
string
)
=>
{
if
(
!
chatId
||
!
contentId
)
return
;
setIsLoading
(
true
);
try
{
await
updateHistoryQuote
({
contentId
,
chatId
,
quoteId
,
sourceText
});
// reload quote
refetch
();
}
catch
(
err
)
{
toast
({
status
:
'warning'
,
title
:
getErrText
(
err
)
});
}
setIsLoading
(
false
);
},
[
contentId
,
chatId
,
refetch
,
setIsLoading
,
toast
]
);
/**
* click edit, get new kbDataItem
*/
...
...
@@ -91,7 +46,7 @@ const QuoteModal = ({
const
data
=
(
await
getKbDataItemById
(
item
.
id
))
as
QuoteItemType
;
if
(
!
data
)
{
updateQuoteStatus
(
item
.
id
,
'已删除'
);
onUpdateQuote
(
item
.
id
,
'已删除'
);
throw
new
Error
(
'该数据已被删除'
);
}
...
...
@@ -109,7 +64,7 @@ const QuoteModal = ({
}
setIsLoading
(
false
);
},
[
setIsLoading
,
toast
,
updateQuoteStatus
]
[
setIsLoading
,
toast
,
onUpdateQuote
]
);
return
(
...
...
@@ -123,14 +78,14 @@ const QuoteModal = ({
overflow=
{
'overlay'
}
>
<
ModalHeader
>
知识库引用(
{
quote
.
length
}
条)
知识库引用(
{
rawSearch
.
length
}
条)
<
Box
fontSize=
{
'sm'
}
fontWeight=
{
'normal'
}
>
注意: 修改知识库内容成功后,此处不会显示
。点击编辑后,才是显示
最新的内容。
注意: 修改知识库内容成功后,此处不会显示
变更情况。点击编辑后,会显示知识库
最新的内容。
</
Box
>
</
ModalHeader
>
<
ModalCloseButton
/>
<
ModalBody
pt=
{
0
}
whiteSpace=
{
'pre-wrap'
}
textAlign=
{
'justify'
}
fontSize=
{
'sm'
}
>
{
quote
.
map
((
item
)
=>
(
{
rawSearch
.
map
((
item
)
=>
(
<
Box
key=
{
item
.
id
}
flex=
{
'1 0 0'
}
...
...
@@ -172,14 +127,14 @@ const QuoteModal = ({
</
Box
>
))
}
</
ModalBody
>
<
Loading
loading=
{
isLoading
}
fixed=
{
false
}
/>
<
Loading
fixed=
{
false
}
/>
</
ModalContent
>
</
Modal
>
{
editDataItem
&&
(
<
InputDataModal
onClose=
{
()
=>
setEditDataItem
(
undefined
)
}
onSuccess=
{
()
=>
updateQuoteStatus
(
editDataItem
.
dataId
,
'手动修改'
)
}
onDelete=
{
()
=>
updateQuoteStatus
(
editDataItem
.
dataId
,
'已删除'
)
}
onSuccess=
{
()
=>
onUpdateQuote
(
editDataItem
.
dataId
,
'手动修改'
)
}
onDelete=
{
()
=>
onUpdateQuote
(
editDataItem
.
dataId
,
'已删除'
)
}
kbId=
{
editDataItem
.
kbId
}
defaultValues=
{
editDataItem
}
/>
...
...
client/src/components/ChatBox/ResponseDetailModal.tsx
View file @
ea35ad21
import
React
from
'react'
;
import
React
,
{
useCallback
,
useMemo
,
useState
}
from
'react'
;
import
{
ChatModuleEnum
}
from
'@/constants/chat'
;
import
{
ChatHistoryItemResType
,
QuoteItemType
}
from
'@/types/chat'
;
import
{
Flex
,
BoxProps
}
from
'@chakra-ui/react'
;
import
{
updateHistoryQuote
}
from
'@/api/chat'
;
import
dynamic
from
'next/dynamic'
;
import
Tag
from
'../Tag'
;
import
MyTooltip
from
'../MyTooltip'
;
const
QuoteModal
=
dynamic
(()
=>
import
(
'./QuoteModal'
),
{
ssr
:
false
});
const
ResponseDetailModal
=
()
=>
{
return
<
div
>
ResponseDetailModal
</
div
>;
const
ResponseDetailModal
=
({
chatId
,
contentId
,
responseData
=
[]
}:
{
chatId
?:
string
;
contentId
?:
string
;
responseData
?:
ChatHistoryItemResType
[];
})
=>
{
console
.
log
(
responseData
);
const
[
quoteModalData
,
setQuoteModalData
]
=
useState
<
QuoteItemType
[]
>
();
const
{
tokens
=
0
,
quoteList
=
[],
completeMessages
=
[]
}
=
useMemo
(()
=>
{
const
chatData
=
responseData
.
find
((
item
)
=>
item
.
moduleName
===
ChatModuleEnum
.
AIChat
);
if
(
!
chatData
)
return
{};
return
{
tokens
:
chatData
.
tokens
,
quoteList
:
chatData
.
quoteList
,
completeMessages
:
chatData
.
completeMessages
};
},
[
responseData
]);
const
isEmpty
=
useMemo
(
()
=>
quoteList
.
length
===
0
&&
completeMessages
.
length
===
0
&&
tokens
===
0
,
[
completeMessages
.
length
,
quoteList
.
length
,
tokens
]
);
const
updateQuote
=
useCallback
(
async
(
quoteId
:
string
,
sourceText
:
string
)
=>
{},
[]);
const
TagStyles
:
BoxProps
=
{
mr
:
2
,
bg
:
'transparent'
};
return
isEmpty
?
null
:
(
<
Flex
alignItems=
{
'center'
}
mt=
{
2
}
flexWrap=
{
'wrap'
}
>
{
quoteList
.
length
>
0
&&
(
<
MyTooltip
label=
"查看引用"
>
<
Tag
colorSchema=
"blue"
cursor=
{
'pointer'
}
{
...
TagStyles
}
onClick=
{
()
=>
setQuoteModalData
(
quoteList
)
}
>
{
quoteList
.
length
}
条引用
</
Tag
>
</
MyTooltip
>
)
}
{
completeMessages
.
length
>
0
&&
(
<
Tag
colorSchema=
"green"
cursor=
{
'default'
}
{
...
TagStyles
}
>
{
completeMessages
.
length
}
条上下文
</
Tag
>
)
}
{
tokens
>
0
&&
(
<
Tag
colorSchema=
"gray"
cursor=
{
'default'
}
{
...
TagStyles
}
>
{
tokens
}
tokens
</
Tag
>
)
}
{
/* <Button
size={'sm'}
variant={'base'}
borderRadius={'md'}
fontSize={'xs'}
px={2}
lineHeight={1}
py={1}
>
完整参数
</Button> */
}
{
!!
quoteModalData
&&
(
<
QuoteModal
rawSearch=
{
quoteModalData
}
onUpdateQuote=
{
updateQuote
}
onClose=
{
()
=>
setQuoteModalData
(
undefined
)
}
/>
)
}
</
Flex
>
);
};
export
default
ResponseDetailModal
;
client/src/components/ChatBox/index.tsx
View file @
ea35ad21
...
...
@@ -23,7 +23,7 @@ import {
hasVoiceApi
,
getErrText
}
from
'@/utils/tools'
;
import
{
Box
,
Card
,
Flex
,
Input
,
Textarea
,
Button
,
useTheme
}
from
'@chakra-ui/react'
;
import
{
Box
,
Card
,
Flex
,
Input
,
Textarea
,
Button
,
useTheme
,
BoxProps
}
from
'@chakra-ui/react'
;
import
{
feConfigs
}
from
'@/store/static'
;
import
{
Types
}
from
'mongoose'
;
import
{
EventNameEnum
}
from
'../Markdown/constant'
;
...
...
@@ -38,12 +38,11 @@ import { fileDownload } from '@/utils/file';
import
{
htmlTemplate
}
from
'@/constants/common'
;
import
{
useRouter
}
from
'next/router'
;
import
{
useGlobalStore
}
from
'@/store/global'
;
import
{
QuoteItemType
}
from
'@/types/chat'
;
import
{
FlowModuleTypeEnum
}
from
'@/constants/flow'
;
import
{
TaskResponseKeyEnum
}
from
'@/constants/chat'
;
import
dynamic
from
'next/dynamic'
;
const
QuoteModal
=
dynamic
(()
=>
import
(
'./Quote
Modal'
));
const
ResponseDetailModal
=
dynamic
(()
=>
import
(
'./ResponseDetail
Modal'
));
import
MyIcon
from
'@/components/Icon'
;
import
Avatar
from
'@/components/Avatar'
;
...
...
@@ -108,15 +107,22 @@ const Empty = () => {
);
};
const
ChatAvatar
=
({
src
,
ml
,
mr
}:
{
src
?:
string
;
ml
?:
(
string
|
number
)
|
(
string
|
number
)[];
mr
?:
(
string
|
number
)
|
(
string
|
number
)[];
})
=>
<
Avatar
src=
{
src
}
w=
{
[
'24px'
,
'34px'
]
}
h=
{
[
'24px'
,
'34px'
]
}
ml=
{
ml
}
mr=
{
mr
}
/>;
const
ChatAvatar
=
({
src
,
type
}:
{
src
?:
string
;
type
:
'Human'
|
'AI'
})
=>
{
const
theme
=
useTheme
();
return
(
<
Box
w=
{
[
'28px'
,
'34px'
]
}
h=
{
[
'28px'
,
'34px'
]
}
p=
{
'2px'
}
borderRadius=
{
'lg'
}
border=
{
theme
.
borders
.
base
}
boxShadow=
{
'0 0 5px rgba(0,0,0,0.1)'
}
bg=
{
type
===
'Human'
?
'white'
:
'myBlue.100'
}
>
<
Avatar
src=
{
src
}
w=
{
'100%'
}
h=
{
'100%'
}
/>
</
Box
>
);
};
const
ChatBox
=
(
{
...
...
@@ -157,10 +163,6 @@ const ChatBox = (
const
[
refresh
,
setRefresh
]
=
useState
(
false
);
const
[
variables
,
setVariables
]
=
useState
<
Record
<
string
,
any
>>
({});
const
[
chatHistory
,
setChatHistory
]
=
useState
<
ChatSiteItemType
[]
>
([]);
const
[
quoteModalData
,
setQuoteModalData
]
=
useState
<
{
contentId
?:
string
;
rawSearch
?:
QuoteItemType
[];
}
>
();
const
isChatting
=
useMemo
(
()
=>
chatHistory
[
chatHistory
.
length
-
1
]?.
status
===
'loading'
,
...
...
@@ -394,13 +396,16 @@ const ChatBox = (
color
:
'myGray.400'
,
display
:
[
'flex'
,
'none'
],
pl
:
1
,
mt
:
2
,
position
:
'absolute'
as
any
,
zIndex
:
1
,
w
:
'100%'
mt
:
2
};
const
MessageCardStyle
:
BoxProps
=
{
px
:
4
,
py
:
3
,
borderRadius
:
'0 8px 8px 8px'
,
boxShadow
:
'0 0 8px rgba(0,0,0,0.15)'
};
const
messageCardMaxW
=
[
'calc(100% -
48px)'
,
'calc(100% - 65
px)'
];
const
messageCardMaxW
=
[
'calc(100% -
25px)'
,
'calc(100% - 40
px)'
];
const
showEmpty
=
useMemo
(
()
=>
...
...
@@ -439,27 +444,19 @@ const ChatBox = (
h=
{
0
}
w=
{
'100%'
}
overflow=
{
'overlay'
}
px=
{
[
2
,
5
]
}
px=
{
[
4
,
0
]
}
mt=
{
[
0
,
5
]
}
pb=
{
3
}
>
<
Box
maxW=
{
[
'100%'
,
'
1000px'
,
'1200px
'
]
}
h=
{
'100%'
}
mx=
{
'auto'
}
>
<
Box
maxW=
{
[
'100%'
,
'
92%
'
]
}
h=
{
'100%'
}
mx=
{
'auto'
}
>
{
showEmpty
&&
<
Empty
/>
}
{
!!
welcomeText
&&
(
<
Flex
alignItems=
{
'flex-start'
}
py=
{
2
}
>
<
Flex
flexDirection=
{
'column'
}
alignItems=
{
'flex-start'
}
py=
{
2
}
>
{
/* avatar */
}
<
ChatAvatar
src=
{
appAvatar
}
mr=
{
[
'6px'
,
2
]
}
/>
<
ChatAvatar
src=
{
appAvatar
}
type=
{
'AI'
}
/>
{
/* message */
}
<
Card
order=
{
2
}
mt=
{
2
}
px=
{
4
}
py=
{
3
}
bg=
{
'white'
}
maxW=
{
messageCardMaxW
}
borderRadius=
{
'0 8px 8px 8px'
}
>
<
Card
order=
{
2
}
mt=
{
2
}
{
...
MessageCardStyle
}
bg=
{
'white'
}
maxW=
{
messageCardMaxW
}
>
<
Markdown
source=
{
`~~~guide \n${welcomeText}`
}
isChatting=
{
false
}
...
...
@@ -474,19 +471,17 @@ const ChatBox = (
)
}
{
/* variable input */
}
{
!!
variableModules
?.
length
&&
(
<
Flex
alignItems=
{
'flex-start'
}
py=
{
2
}
>
<
Flex
flexDirection=
{
'column'
}
alignItems=
{
'flex-start'
}
py=
{
2
}
>
{
/* avatar */
}
<
ChatAvatar
src=
{
appAvatar
}
mr=
{
[
'6px'
,
2
]
}
/>
<
ChatAvatar
src=
{
appAvatar
}
type=
{
'AI'
}
/>
{
/* message */
}
<
Card
order=
{
2
}
mt=
{
2
}
bg=
{
'white'
}
px=
{
4
}
py=
{
3
}
borderRadius=
{
'0 8px 8px 8px'
}
flex=
{
'0 0 400px'
}
w=
{
'400px'
}
maxW=
{
messageCardMaxW
}
{
...
MessageCardStyle
}
>
{
variableModules
.
map
((
item
)
=>
(
<
Box
key=
{
item
.
id
}
mb=
{
4
}
>
...
...
@@ -540,8 +535,8 @@ const ChatBox = (
<
Flex
position=
{
'relative'
}
key=
{
item
.
_id
}
alignItems=
{
'flex-start
'
}
justifyContent
=
{
item
.
obj
===
'Human'
?
'flex-end'
:
'flex-start'
}
flexDirection=
{
'column
'
}
alignItems
=
{
item
.
obj
===
'Human'
?
'flex-end'
:
'flex-start'
}
py=
{
5
}
_hover=
{
{
'& .control'
:
{
...
...
@@ -551,18 +546,8 @@ const ChatBox = (
>
{
item
.
obj
===
'Human'
&&
(
<>
<
Box
position=
{
'relative'
}
maxW=
{
messageCardMaxW
}
>
<
Card
className=
"markdown"
whiteSpace=
{
'pre-wrap'
}
px=
{
4
}
py=
{
3
}
borderRadius=
{
'8px 0 8px 8px'
}
bg=
{
'myBlue.300'
}
>
<
Box
as=
{
'p'
}
>
{
item
.
value
}
</
Box
>
</
Card
>
<
Flex
{
...
controlContainerStyle
}
justifyContent=
{
'flex-end'
}
>
<
Flex
w=
{
'100%'
}
alignItems=
{
'center'
}
justifyContent=
{
'flex-end'
}
>
<
Flex
{
...
controlContainerStyle
}
justifyContent=
{
'flex-end'
}
mr=
{
3
}
>
<
MyTooltip
label=
{
'复制'
}
>
<
MyIcon
{
...
controlIconStyle
}
...
...
@@ -591,38 +576,25 @@ const ChatBox = (
</
MyTooltip
>
)
}
</
Flex
>
<
ChatAvatar
src=
{
userAvatar
}
type=
{
'Human'
}
/>
</
Flex
>
<
Box
position=
{
'relative'
}
maxW=
{
messageCardMaxW
}
mt=
{
[
'6px'
,
2
]
}
>
<
Card
className=
"markdown"
whiteSpace=
{
'pre-wrap'
}
{
...
MessageCardStyle
}
bg=
{
'myBlue.300'
}
>
<
Box
as=
{
'p'
}
>
{
item
.
value
}
</
Box
>
</
Card
>
</
Box
>
<
ChatAvatar
src=
{
userAvatar
}
ml=
{
[
'6px'
,
2
]
}
/>
</>
)
}
{
item
.
obj
===
'AI'
&&
(
<>
<
ChatAvatar
src=
{
appAvatar
}
mr=
{
[
'6px'
,
2
]
}
/>
<
Box
position=
{
'relative'
}
maxW=
{
messageCardMaxW
}
>
<
Card
bg=
{
'white'
}
px=
{
4
}
py=
{
3
}
borderRadius=
{
'0 8px 8px 8px'
}
>
<
Markdown
source=
{
item
.
value
}
isChatting=
{
index
===
chatHistory
.
length
-
1
&&
isChatting
}
/>
{
/* {(!!item[quoteLenKey] || !!item[rawSearchKey]?.length) && (
<Button
size={'xs'}
variant={'base'}
mt={2}
w={'80px'}
onClick={() => {
setQuoteModalData({
contentId: item._id,
rawSearch: item[rawSearchKey]
});
}}
>
{item[quoteLenKey] || item[rawSearchKey]?.length}条引用
</Button>
)} */
}
</
Card
>
<
Flex
{
...
controlContainerStyle
}
>
<
Flex
w=
{
'100%'
}
alignItems=
{
'center'
}
>
<
ChatAvatar
src=
{
appAvatar
}
type=
{
'AI'
}
/>
<
Flex
{
...
controlContainerStyle
}
ml=
{
3
}
>
<
MyTooltip
label=
{
'复制'
}
>
<
MyIcon
{
...
controlIconStyle
}
...
...
@@ -660,6 +632,19 @@ const ChatBox = (
</
MyTooltip
>
)
}
</
Flex
>
</
Flex
>
<
Box
position=
{
'relative'
}
maxW=
{
messageCardMaxW
}
mt=
{
[
'6px'
,
2
]
}
>
<
Card
bg=
{
'white'
}
{
...
MessageCardStyle
}
>
<
Markdown
source=
{
item
.
value
}
isChatting=
{
index
===
chatHistory
.
length
-
1
&&
isChatting
}
/>
<
ResponseDetailModal
chatId=
{
chatId
}
contentId=
{
item
.
_id
}
responseData=
{
item
.
responseData
}
/>
</
Card
>
</
Box
>
</>
)
}
...
...
@@ -753,14 +738,6 @@ const ChatBox = (
</
Box
>
</
Box
>
)
:
null
}
{
/* quote modal */
}
{
!!
quoteModalData
&&
(
<
QuoteModal
chatId=
{
chatId
}
{
...
quoteModalData
}
onClose=
{
()
=>
setQuoteModalData
(
undefined
)
}
/>
)
}
</
Flex
>
);
};
...
...
client/src/components/MyTooltip/index.tsx
View file @
ea35ad21
import
React
from
'react'
;
import
{
Tooltip
,
TooltipProps
}
from
'@chakra-ui/react'
;
import
{
useGlobalStore
}
from
'@/store/global'
;
const
MyTooltip
=
({
children
,
...
props
}:
TooltipProps
)
=>
{
return
(
interface
Props
extends
TooltipProps
{
forceShow
?:
boolean
;
}
const
MyTooltip
=
({
children
,
forceShow
=
false
,
...
props
}:
Props
)
=>
{
const
{
isPc
}
=
useGlobalStore
();
return
isPc
||
forceShow
?
(
<
Tooltip
bg=
{
'white'
}
arrowShadowColor=
{
' rgba(0,0,0,0.1)'
}
...
...
@@ -19,6 +25,8 @@ const MyTooltip = ({ children, ...props }: TooltipProps) => {
>
{
children
}
</
Tooltip
>
)
:
(
<>
{
children
}
</>
);
};
...
...
client/src/pages/api/chat/history/getHistoryQuote.ts
deleted
100644 → 0
View file @
1ffe1be5
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
jsonRes
}
from
'@/service/response'
;
import
{
connectToDatabase
,
Chat
}
from
'@/service/mongo'
;
import
{
authUser
}
from
'@/service/utils/auth'
;
import
{
Types
}
from
'mongoose'
;
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
chatId
,
contentId
}
=
req
.
query
as
{
chatId
:
string
;
contentId
:
string
;
};
await
connectToDatabase
();
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
if
(
!
chatId
||
!
contentId
)
{
throw
new
Error
(
'params is error'
);
}
const
history
=
await
Chat
.
aggregate
([
{
$match
:
{
_id
:
new
Types
.
ObjectId
(
chatId
),
userId
:
new
Types
.
ObjectId
(
userId
)
}
},
{
$unwind
:
'$content'
},
{
$match
:
{
'content._id'
:
new
Types
.
ObjectId
(
contentId
)
}
},
{
$project
:
{
// [rawSearchKey]: `$content.${rawSearchKey}`
}
}
]);
jsonRes
(
res
,
{
// data: history[0]?.[rawSearchKey] || []
});
}
catch
(
err
)
{
jsonRes
(
res
,
{
code
:
500
,
error
:
err
});
}
}
client/src/pages/api/chat/init.ts
View file @
ea35ad21
import
type
{
NextApiRequest
,
NextApiResponse
}
from
'next'
;
import
{
jsonRes
}
from
'@/service/response'
;
import
{
connectToDatabase
,
Chat
,
App
}
from
'@/service/mongo'
;
import
{
connectToDatabase
,
Chat
}
from
'@/service/mongo'
;
import
type
{
InitChatResponse
}
from
'@/api/response/chat'
;
import
{
authUser
}
from
'@/service/utils/auth'
;
import
{
ChatItemType
}
from
'@/types/chat'
;
...
...
@@ -59,7 +59,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
{
$project
:
{
content
:
{
$slice
:
[
'$content'
,
-
50
]
// 返回 content 数组的最后50
个元素
$slice
:
[
'$content'
,
-
30
]
// 返回 content 数组的最后 30
个元素
}
}
},
...
...
client/src/pages/api/openapi/v1/chat/getHistory.ts
View file @
ea35ad21
...
...
@@ -36,7 +36,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
export
async
function
getChatHistory
({
chatId
,
userId
,
limit
=
5
0
limit
=
2
0
}:
Props
&
{
userId
:
string
}):
Promise
<
Response
>
{
if
(
!
chatId
)
{
return
{
history
:
[]
};
...
...
@@ -47,7 +47,7 @@ export async function getChatHistory({
{
$project
:
{
content
:
{
$slice
:
[
'$content'
,
-
limit
]
// 返回 content 数组的最后
5
0个元素
$slice
:
[
'$content'
,
-
limit
]
// 返回 content 数组的最后
2
0个元素
}
}
},
...
...
client/src/pages/app/detail/components/BasicEdit/index.tsx
View file @
ea35ad21
...
...
@@ -140,7 +140,7 @@ const Settings = ({ appId }: { appId: string }) => {
},
[
appModule2Form
]);
const
BoxStyles
:
BoxProps
=
{
bg
:
'myWhite.
3
00'
,
bg
:
'myWhite.
2
00'
,
px
:
4
,
py
:
3
,
borderRadius
:
'lg'
,
...
...
client/src/pages/chat/index.tsx
View file @
ea35ad21
...
...
@@ -159,7 +159,7 @@ const Chat = ({ appId, chatId }: { appId: string; chatId: string }) => {
if
(
res
.
history
.
length
>
0
)
{
setTimeout
(()
=>
{
ChatBoxRef
.
current
?.
scrollToBottom
(
'auto'
);
},
2
00
);
},
5
00
);
}
}
catch
(
e
:
any
)
{
// reset all chat tore
...
...
client/src/pages/chat/share.tsx
View file @
ea35ad21
...
...
@@ -131,7 +131,9 @@ const ShareChat = ({ shareId, chatId }: { shareId: string; chatId: string }) =>
}
if
(
history
.
chats
.
length
>
0
)
{
ChatBoxRef
.
current
?.
scrollToBottom
(
'auto'
);
setTimeout
(()
=>
{
ChatBoxRef
.
current
?.
scrollToBottom
(
'auto'
);
},
500
);
}
return
history
;
...
...
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