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
505aff3d
authored
Jul 18, 2023
by
archer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
perf: ui
parent
f9d83c48
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
216 additions
and
210 deletions
+216
-210
client/src/api/chat.ts
+4
-4
client/src/api/fetch.ts
+4
-4
client/src/api/response/chat.d.ts
+0
-1
client/src/components/ChatBox/QuoteModal.tsx
+7
-7
client/src/components/ChatBox/index.tsx
+12
-14
client/src/components/Layout/navbar.tsx
+3
-3
client/src/components/Layout/navbarPhone.tsx
+3
-3
client/src/components/Markdown/index.tsx
+1
-0
client/src/pages/api/chat/delChatRecordByContentId.ts
+4
-5
client/src/pages/api/chat/history/getHistory.ts
+2
-1
client/src/pages/api/chat/history/getHistoryQuote.ts
+4
-4
client/src/pages/api/chat/history/updateChatHistory.ts
+3
-3
client/src/pages/api/chat/history/updateHistoryQuote.ts
+4
-4
client/src/pages/api/chat/init.ts
+1
-2
client/src/pages/api/chat/saveChat.ts
+12
-12
client/src/pages/api/openapi/v1/chat/completions.ts
+11
-18
client/src/pages/api/openapi/v1/chat/getHistory.ts
+6
-6
client/src/pages/chat/components/ChatHistorySlider.tsx
+31
-19
client/src/pages/chat/index.tsx
+39
-38
client/src/pages/chat/share.tsx
+17
-17
client/src/pages/kb/detail/components/DataCard.tsx
+1
-1
client/src/pages/login/index.tsx
+3
-3
client/src/service/utils/chat/index.ts
+2
-9
client/src/store/chat.ts
+31
-20
client/src/store/shareChat.ts
+10
-12
client/src/types/chat.d.ts
+1
-0
No files found.
client/src/api/chat.ts
View file @
505aff3d
...
...
@@ -10,7 +10,7 @@ import type { Props as UpdateHistoryProps } from '@/pages/api/chat/history/updat
/**
* 获取初始化聊天内容
*/
export
const
getInitChatSiteInfo
=
(
data
:
{
appId
:
string
;
history
Id
?:
string
})
=>
export
const
getInitChatSiteInfo
=
(
data
:
{
appId
:
string
;
chat
Id
?:
string
})
=>
GET
<
InitChatResponse
>
(
`/chat/init`
,
data
);
/**
...
...
@@ -27,14 +27,14 @@ export const delChatHistoryById = (id: string) => GET(`/chat/removeHistory?id=${
/**
* get history quotes
*/
export
const
getHistoryQuote
=
(
params
:
{
history
Id
:
string
;
contentId
:
string
})
=>
export
const
getHistoryQuote
=
(
params
:
{
chat
Id
:
string
;
contentId
:
string
})
=>
GET
<
(
QuoteItemType
&
{
_id
:
string
})[]
>
(
`/chat/history/getHistoryQuote`
,
params
);
/**
* update history quote status
*/
export
const
updateHistoryQuote
=
(
params
:
{
history
Id
:
string
;
chat
Id
:
string
;
contentId
:
string
;
quoteId
:
string
;
sourceText
:
string
;
...
...
@@ -43,7 +43,7 @@ export const updateHistoryQuote = (params: {
/**
* 删除一句对话
*/
export
const
delChatRecordByIndex
=
(
data
:
{
history
Id
:
string
;
contentId
:
string
})
=>
export
const
delChatRecordByIndex
=
(
data
:
{
chat
Id
:
string
;
contentId
:
string
})
=>
DELETE
(
`/chat/delChatRecordByContentId`
,
data
);
/**
...
...
client/src/api/fetch.ts
View file @
505aff3d
...
...
@@ -19,7 +19,7 @@ export const streamFetch = ({
new
Promise
<
{
responseText
:
string
;
errMsg
:
string
;
new
History
Id
:
string
|
null
;
new
Chat
Id
:
string
|
null
;
[
rawSearchKey
]:
QuoteItemType
[];
}
>
(
async
(
resolve
,
reject
)
=>
{
try
{
...
...
@@ -45,7 +45,7 @@ export const streamFetch = ({
let
responseText
=
''
;
let
rawSearch
:
QuoteItemType
[]
=
[];
let
errMsg
=
''
;
const
new
HistoryId
=
response
.
headers
.
get
(
'newHistory
Id'
);
const
new
ChatId
=
response
.
headers
.
get
(
'newChat
Id'
);
const
read
=
async
()
=>
{
try
{
...
...
@@ -55,7 +55,7 @@ export const streamFetch = ({
return
resolve
({
responseText
,
errMsg
,
new
History
Id
,
new
Chat
Id
,
rawSearch
});
}
else
{
...
...
@@ -95,7 +95,7 @@ export const streamFetch = ({
return
resolve
({
responseText
,
errMsg
,
new
History
Id
,
new
Chat
Id
,
rawSearch
});
}
...
...
client/src/api/response/chat.d.ts
View file @
505aff3d
...
...
@@ -13,7 +13,6 @@ export interface InitChatResponse {
intro
:
string
;
canUse
:
boolean
;
};
customTitle
?:
string
;
title
:
string
;
variables
:
Record
<
string
,
any
>
;
history
:
ChatItemType
[];
...
...
client/src/components/ChatBox/QuoteModal.tsx
View file @
505aff3d
...
...
@@ -20,12 +20,12 @@ import { getErrText } from '@/utils/tools';
import
{
QuoteItemType
}
from
'@/pages/api/app/modules/kb/search'
;
const
QuoteModal
=
({
history
Id
,
chat
Id
,
contentId
,
rawSearch
=
[],
onClose
}:
{
history
Id
?:
string
;
chat
Id
?:
string
;
contentId
?:
string
;
rawSearch
?:
QuoteItemType
[];
onClose
:
()
=>
void
;
...
...
@@ -45,8 +45,8 @@ const QuoteModal = ({
refetch
,
isLoading
}
=
useQuery
([
'getHistoryQuote'
],
()
=>
{
if
(
history
Id
&&
contentId
)
{
return
getHistoryQuote
({
history
Id
,
contentId
});
if
(
chat
Id
&&
contentId
)
{
return
getHistoryQuote
({
chat
Id
,
contentId
});
}
if
(
rawSearch
.
length
>
0
)
{
return
rawSearch
;
...
...
@@ -59,12 +59,12 @@ const QuoteModal = ({
*/
const
updateQuoteStatus
=
useCallback
(
async
(
quoteId
:
string
,
sourceText
:
string
)
=>
{
if
(
!
history
Id
||
!
contentId
)
return
;
if
(
!
chat
Id
||
!
contentId
)
return
;
setIsLoading
(
true
);
try
{
await
updateHistoryQuote
({
contentId
,
history
Id
,
chat
Id
,
quoteId
,
sourceText
});
...
...
@@ -78,7 +78,7 @@ const QuoteModal = ({
}
setIsLoading
(
false
);
},
[
contentId
,
history
Id
,
refetch
,
setIsLoading
,
toast
]
[
contentId
,
chat
Id
,
refetch
,
setIsLoading
,
toast
]
);
/**
...
...
client/src/components/ChatBox/index.tsx
View file @
505aff3d
...
...
@@ -49,7 +49,7 @@ export type StartChatFnProps = {
export
type
ComponentRef
=
{
getChatHistory
:
()
=>
ChatSiteItemType
[];
resetVariables
:
(
data
?:
Record
<
string
,
any
>
)
=>
void
;
resetHistory
:
(
history
:
ChatSiteItemType
[])
=>
void
;
resetHistory
:
(
chatId
:
ChatSiteItemType
[])
=>
void
;
scrollToBottom
:
(
behavior
?:
'smooth'
|
'auto'
)
=>
void
;
};
...
...
@@ -76,11 +76,10 @@ const Empty = () => {
return
(
<
Box
minH=
{
'100%'
}
pt=
{
[
6
,
0
]
}
w=
{
'85%'
}
maxW=
{
'600px'
}
m=
{
'auto'
}
py=
{
'5vh'
}
alignItems=
{
'center'
}
justifyContent=
{
'center'
}
>
...
...
@@ -110,7 +109,7 @@ const ChatAvatar = ({
const
ChatBox
=
(
{
showEmptyIntro
=
false
,
history
Id
,
chat
Id
,
appAvatar
,
variableModules
,
welcomeText
,
...
...
@@ -119,7 +118,7 @@ const ChatBox = (
onDelMessage
}:
{
showEmptyIntro
?:
boolean
;
history
Id
?:
string
;
chat
Id
?:
string
;
appAvatar
:
string
;
variableModules
?:
VariableItemType
[];
welcomeText
?:
string
;
...
...
@@ -389,14 +388,16 @@ const ChatBox = (
};
const
showEmpty
=
useMemo
(
()
=>
showEmptyIntro
&&
chatHistory
.
length
===
0
&&
!
(
variableModules
||
welcomeText
)
,
()
=>
showEmptyIntro
&&
chatHistory
.
length
===
0
&&
!
variableModules
?.
length
&&
!
welcomeText
,
[
chatHistory
.
length
,
showEmptyIntro
,
variableModules
,
welcomeText
]
);
return
(
<
Flex
flexDirection=
{
'column'
}
h=
{
'100%'
}
>
<
Box
ref=
{
ChatBoxRef
}
flex=
{
'1 0 0'
}
h=
{
0
}
overflow=
{
'overlay'
}
px=
{
[
2
,
5
,
7
]
}
p
y
=
{
[
0
,
5
]
}
>
<
Box
ref=
{
ChatBoxRef
}
flex=
{
'1 0 0'
}
h=
{
0
}
overflow=
{
'overlay'
}
px=
{
[
2
,
5
,
7
]
}
p
t
=
{
[
0
,
5
]
}
>
<
Box
maxW=
{
[
'100%'
,
'1000px'
,
'1200px'
]
}
h=
{
'100%'
}
mx=
{
'auto'
}
>
{
showEmpty
&&
<
Empty
/>
}
{
!!
welcomeText
&&
(
<
Flex
alignItems=
{
'flex-start'
}
py=
{
2
}
>
{
/* avatar */
}
...
...
@@ -410,7 +411,7 @@ const ChatBox = (
</
Flex
>
)
}
{
/* variable input */
}
{
variableModules
&&
(
{
!!
variableModules
?.
length
&&
(
<
Flex
alignItems=
{
'flex-start'
}
py=
{
2
}
>
{
/* avatar */
}
<
ChatAvatar
src=
{
appAvatar
}
order=
{
1
}
mr=
{
[
'6px'
,
2
]
}
/>
...
...
@@ -467,7 +468,7 @@ const ChatBox = (
)
}
{
/* chat history */
}
<
Box
id=
{
'history'
}
pb=
{
[
8
,
2
]
}
>
<
Box
id=
{
'history'
}
pb=
{
8
}
>
{
chatHistory
.
map
((
item
,
index
)
=>
(
<
Flex
key=
{
item
.
_id
}
...
...
@@ -606,13 +607,11 @@ const ChatBox = (
</
Flex
>
))
}
</
Box
>
{
showEmpty
&&
<
Empty
/>
}
</
Box
>
</
Box
>
{
/* input */
}
{
variableIsFinish
?
(
<
Box
m=
{
[
'0 auto'
,
'
2
0px auto'
]
}
w=
{
'100%'
}
maxW=
{
[
'auto'
,
'min(750px, 100%)'
]
}
px=
{
[
0
,
5
]
}
>
<
Box
m=
{
[
'0 auto'
,
'
1
0px auto'
]
}
w=
{
'100%'
}
maxW=
{
[
'auto'
,
'min(750px, 100%)'
]
}
px=
{
[
0
,
5
]
}
>
<
Box
py=
{
'18px'
}
position=
{
'relative'
}
...
...
@@ -696,12 +695,11 @@ const ChatBox = (
{
/* quote modal */
}
{
!!
quoteModalData
&&
(
<
QuoteModal
historyId=
{
history
Id
}
chatId=
{
chat
Id
}
{
...
quoteModalData
}
onClose=
{
()
=>
setQuoteModalData
(
undefined
)
}
/>
)
}
{
/* quote modal */
}
</
Flex
>
);
};
...
...
client/src/components/Layout/navbar.tsx
View file @
505aff3d
...
...
@@ -17,14 +17,14 @@ export enum NavbarTypeEnum {
const
Navbar
=
({
unread
}:
{
unread
:
number
})
=>
{
const
router
=
useRouter
();
const
{
userInfo
}
=
useUserStore
();
const
{
lastChatAppId
,
last
History
Id
}
=
useChatStore
();
const
{
lastChatAppId
,
last
Chat
Id
}
=
useChatStore
();
const
navbarList
=
useMemo
(
()
=>
[
{
label
:
'聊天'
,
icon
:
'chatLight'
,
activeIcon
:
'chatFill'
,
link
:
`/chat?appId=
${
lastChatAppId
}
&
historyId=
${
lastHistory
Id
}
`
,
link
:
`/chat?appId=
${
lastChatAppId
}
&
chatId=
${
lastChat
Id
}
`
,
activeLink
:
[
'/chat'
]
},
{
...
...
@@ -56,7 +56,7 @@ const Navbar = ({ unread }: { unread: number }) => {
activeLink
:
[
'/number'
]
}
],
[
last
History
Id
,
lastChatAppId
]
[
last
Chat
Id
,
lastChatAppId
]
);
const
itemStyles
:
any
=
{
...
...
client/src/components/Layout/navbarPhone.tsx
View file @
505aff3d
...
...
@@ -7,13 +7,13 @@ import Badge from '../Badge';
const
NavbarPhone
=
({
unread
}:
{
unread
:
number
})
=>
{
const
router
=
useRouter
();
const
{
lastChatAppId
,
last
History
Id
}
=
useChatStore
();
const
{
lastChatAppId
,
last
Chat
Id
}
=
useChatStore
();
const
navbarList
=
useMemo
(
()
=>
[
{
label
:
'聊天'
,
icon
:
'chatLight'
,
link
:
`/chat?appId=
${
lastChatAppId
}
&
historyId=
${
lastHistory
Id
}
`
,
link
:
`/chat?appId=
${
lastChatAppId
}
&
chatId=
${
lastChat
Id
}
`
,
activeLink
:
[
'/chat'
],
unread
:
0
},
...
...
@@ -39,7 +39,7 @@ const NavbarPhone = ({ unread }: { unread: number }) => {
unread
}
],
[
last
History
Id
,
lastChatAppId
,
unread
]
[
last
Chat
Id
,
lastChatAppId
,
unread
]
);
return
(
...
...
client/src/components/Markdown/index.tsx
View file @
505aff3d
...
...
@@ -43,6 +43,7 @@ const Markdown = ({ source, isChatting = false }: { source: string; isChatting?:
a
:
Link
,
img
:
Image
,
pre
:
'div'
,
p
:
'div'
,
code
:
Code
}
}
>
...
...
client/src/pages/api/chat/delChatRecordByContentId.ts
View file @
505aff3d
...
...
@@ -5,10 +5,9 @@ import { authUser } from '@/service/utils/auth';
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
historyId
,
contentId
}
=
req
.
query
as
{
historyId
:
string
;
contentId
:
string
};
console
.
log
(
historyId
,
contentId
);
const
{
chatId
,
contentId
}
=
req
.
query
as
{
chatId
:
string
;
contentId
:
string
};
if
(
!
history
Id
||
!
contentId
)
{
if
(
!
chat
Id
||
!
contentId
)
{
throw
new
Error
(
'缺少参数'
);
}
...
...
@@ -17,7 +16,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
// 凭证校验
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
const
chatRecord
=
await
Chat
.
findById
(
history
Id
);
const
chatRecord
=
await
Chat
.
findById
(
chat
Id
);
if
(
!
chatRecord
)
{
throw
new
Error
(
'找不到对话'
);
...
...
@@ -26,7 +25,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
// 删除一条数据库记录
await
Chat
.
updateOne
(
{
_id
:
history
Id
,
_id
:
chat
Id
,
userId
},
{
$pull
:
{
content
:
{
_id
:
contentId
}
}
}
...
...
client/src/pages/api/chat/history/getHistory.ts
View file @
505aff3d
...
...
@@ -27,7 +27,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
_id
:
item
.
_id
,
updateTime
:
item
.
updateTime
,
appId
:
item
.
appId
,
title
:
item
.
customTitle
||
item
.
title
,
customTitle
:
item
.
customTitle
,
title
:
item
.
title
,
top
:
item
.
top
}))
});
...
...
client/src/pages/api/chat/history/getHistoryQuote.ts
View file @
505aff3d
...
...
@@ -7,22 +7,22 @@ import { rawSearchKey } from '@/constants/chat';
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
history
Id
,
contentId
}
=
req
.
query
as
{
history
Id
:
string
;
const
{
chat
Id
,
contentId
}
=
req
.
query
as
{
chat
Id
:
string
;
contentId
:
string
;
};
await
connectToDatabase
();
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
if
(
!
history
Id
||
!
contentId
)
{
if
(
!
chat
Id
||
!
contentId
)
{
throw
new
Error
(
'params is error'
);
}
const
history
=
await
Chat
.
aggregate
([
{
$match
:
{
_id
:
new
Types
.
ObjectId
(
history
Id
),
_id
:
new
Types
.
ObjectId
(
chat
Id
),
userId
:
new
Types
.
ObjectId
(
userId
)
}
},
...
...
client/src/pages/api/chat/history/updateChatHistory.ts
View file @
505aff3d
...
...
@@ -4,7 +4,7 @@ import { connectToDatabase, Chat } from '@/service/mongo';
import
{
authUser
}
from
'@/service/utils/auth'
;
export
type
Props
=
{
history
Id
:
string
;
chat
Id
:
string
;
customTitle
?:
string
;
top
?:
boolean
;
};
...
...
@@ -12,7 +12,7 @@ export type Props = {
/* 更新聊天标题 */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
history
Id
,
customTitle
,
top
}
=
req
.
body
as
Props
;
const
{
chat
Id
,
customTitle
,
top
}
=
req
.
body
as
Props
;
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
...
...
@@ -20,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await
Chat
.
findOneAndUpdate
(
{
_id
:
history
Id
,
_id
:
chat
Id
,
userId
},
{
...
...
client/src/pages/api/chat/history/updateHistoryQuote.ts
View file @
505aff3d
...
...
@@ -7,12 +7,12 @@ import { Types } from 'mongoose';
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
let
{
history
Id
,
chat
Id
,
contentId
,
quoteId
,
sourceText
=
''
}
=
req
.
body
as
{
history
Id
:
string
;
chat
Id
:
string
;
contentId
:
string
;
quoteId
:
string
;
sourceText
:
string
;
...
...
@@ -21,13 +21,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
if
(
!
contentId
||
!
history
Id
||
!
quoteId
)
{
if
(
!
contentId
||
!
chat
Id
||
!
quoteId
)
{
throw
new
Error
(
'params is error'
);
}
await
Chat
.
updateOne
(
{
_id
:
new
Types
.
ObjectId
(
history
Id
),
_id
:
new
Types
.
ObjectId
(
chat
Id
),
userId
:
new
Types
.
ObjectId
(
userId
),
'content._id'
:
new
Types
.
ObjectId
(
contentId
)
},
...
...
client/src/pages/api/chat/init.ts
View file @
505aff3d
...
...
@@ -53,7 +53,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const
{
chat
,
history
=
[]
}:
{
chat
?:
ChatSchema
;
history
?:
ChatItemType
[]
}
=
await
(
async
()
=>
{
if
(
chatId
)
{
// auth
history
Id
// auth
chat
Id
const
chat
=
await
Chat
.
findOne
({
_id
:
chatId
,
userId
...
...
@@ -104,7 +104,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
intro
:
app
.
intro
,
canUse
:
app
.
share
.
isShare
||
isOwner
},
customTitle
:
chat
?.
customTitle
,
title
:
chat
?.
title
||
'新对话'
,
variables
:
chat
?.
variables
||
{},
history
...
...
client/src/pages/api/chat/saveChat.ts
View file @
505aff3d
...
...
@@ -7,7 +7,7 @@ import { authUser } from '@/service/utils/auth';
import
{
Types
}
from
'mongoose'
;
type
Props
=
{
history
Id
?:
string
;
chat
Id
?:
string
;
appId
:
string
;
variables
?:
Record
<
string
,
any
>
;
prompts
:
[
ChatItemType
,
ChatItemType
];
...
...
@@ -16,7 +16,7 @@ type Props = {
/* 聊天内容存存储 */
export
default
async
function
handler
(
req
:
NextApiRequest
,
res
:
NextApiResponse
)
{
try
{
const
{
history
Id
,
appId
,
prompts
}
=
req
.
body
as
Props
;
const
{
chat
Id
,
appId
,
prompts
}
=
req
.
body
as
Props
;
if
(
!
prompts
)
{
throw
new
Error
(
'缺少参数'
);
...
...
@@ -25,7 +25,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const
{
userId
}
=
await
authUser
({
req
,
authToken
:
true
});
const
response
=
await
saveChat
({
history
Id
,
chat
Id
,
appId
,
prompts
,
userId
...
...
@@ -43,13 +43,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
export
async
function
saveChat
({
new
History
Id
,
history
Id
,
new
Chat
Id
,
chat
Id
,
appId
,
prompts
,
variables
,
userId
}:
Props
&
{
new
HistoryId
?:
Types
.
ObjectId
;
userId
:
string
}):
Promise
<
{
newHistory
Id
:
string
}
>
{
}:
Props
&
{
new
ChatId
?:
Types
.
ObjectId
;
userId
:
string
}):
Promise
<
{
newChat
Id
:
string
}
>
{
await
connectToDatabase
();
const
{
app
}
=
await
authApp
({
appId
,
userId
,
authOwner
:
false
});
...
...
@@ -60,9 +60,9 @@ export async function saveChat({
}
const
[
response
]
=
await
Promise
.
all
([
...(
history
Id
...(
chat
Id
?
[
Chat
.
findByIdAndUpdate
(
history
Id
,
{
Chat
.
findByIdAndUpdate
(
chat
Id
,
{
$push
:
{
content
:
{
$each
:
prompts
...
...
@@ -72,19 +72,19 @@ export async function saveChat({
title
:
prompts
[
0
].
value
.
slice
(
0
,
20
),
updateTime
:
new
Date
()
}).
then
(()
=>
({
new
History
Id
:
''
new
Chat
Id
:
''
}))
]
:
[
Chat
.
create
({
_id
:
new
History
Id
,
_id
:
new
Chat
Id
,
userId
,
appId
,
variables
,
content
:
prompts
,
title
:
prompts
[
0
].
value
.
slice
(
0
,
20
)
}).
then
((
res
)
=>
({
new
History
Id
:
String
(
res
.
_id
)
new
Chat
Id
:
String
(
res
.
_id
)
}))
]),
// update app
...
...
@@ -99,6 +99,6 @@ export async function saveChat({
return
{
// @ts-ignore
new
HistoryId
:
response
?.
newHistory
Id
||
''
new
ChatId
:
response
?.
newChat
Id
||
''
};
}
client/src/pages/api/openapi/v1/chat/completions.ts
View file @
505aff3d
...
...
@@ -20,7 +20,7 @@ import { BillSourceEnum } from '@/constants/user';
export
type
MessageItemType
=
ChatCompletionRequestMessage
&
{
_id
?:
string
};
type
FastGptWebChatProps
=
{
history
Id
?:
string
;
// undefined: nonuse history, '': new chat, 'xxxxx': use history
chat
Id
?:
string
;
// undefined: nonuse history, '': new chat, 'xxxxx': use history
appId
?:
string
;
};
type
FastGptShareChatProps
=
{
...
...
@@ -47,14 +47,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
res
.
end
();
});
let
{
historyId
,
appId
,
shareId
,
stream
=
false
,
messages
=
[],
variables
=
{}
}
=
req
.
body
as
Props
;
let
{
chatId
,
appId
,
shareId
,
stream
=
false
,
messages
=
[],
variables
=
{}
}
=
req
.
body
as
Props
;
let
billId
=
''
;
...
...
@@ -91,7 +84,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
appId
,
userId
}),
getChatHistory
({
history
Id
,
userId
})
getChatHistory
({
chat
Id
,
userId
})
]);
const
isOwner
=
!
shareId
&&
userId
===
String
(
app
.
userId
);
...
...
@@ -107,9 +100,9 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
throw
new
Error
(
'Question is empty'
);
}
const
new
HistoryId
=
history
Id
===
''
?
new
Types
.
ObjectId
()
:
undefined
;
if
(
stream
&&
new
History
Id
)
{
res
.
setHeader
(
'new
HistoryId'
,
String
(
newHistory
Id
));
const
new
ChatId
=
chat
Id
===
''
?
new
Types
.
ObjectId
()
:
undefined
;
if
(
stream
&&
new
Chat
Id
)
{
res
.
setHeader
(
'new
ChatId'
,
String
(
newChat
Id
));
}
billId
=
await
createTaskBill
({
...
...
@@ -133,10 +126,10 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
});
// save chat
if
(
typeof
history
Id
===
'string'
)
{
if
(
typeof
chat
Id
===
'string'
)
{
await
saveChat
({
history
Id
,
new
History
Id
,
chat
Id
,
new
Chat
Id
,
appId
,
variables
,
prompts
:
[
...
...
@@ -173,10 +166,10 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
}
else
{
res
.
json
({
data
:
{
new
History
Id
,
new
Chat
Id
,
...
responseData
},
id
:
history
Id
||
''
,
id
:
chat
Id
||
''
,
model
:
''
,
usage
:
{
prompt_tokens
:
0
,
completion_tokens
:
0
,
total_tokens
:
0
},
choices
:
[
...
...
client/src/pages/api/openapi/v1/chat/getHistory.ts
View file @
505aff3d
...
...
@@ -7,7 +7,7 @@ import { Types } from 'mongoose';
import
type
{
ChatItemType
}
from
'@/types/chat'
;
export
type
Props
=
{
history
Id
?:
string
;
chat
Id
?:
string
;
limit
?:
number
;
};
export
type
Response
=
{
history
:
ChatItemType
[]
};
...
...
@@ -16,11 +16,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
try
{
await
connectToDatabase
();
const
{
userId
}
=
await
authUser
({
req
});
const
{
history
Id
,
limit
}
=
req
.
body
as
Props
;
const
{
chat
Id
,
limit
}
=
req
.
body
as
Props
;
jsonRes
<
Response
>
(
res
,
{
data
:
await
getChatHistory
({
history
Id
,
chat
Id
,
userId
,
limit
})
...
...
@@ -34,16 +34,16 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
export
async
function
getChatHistory
({
history
Id
,
chat
Id
,
userId
,
limit
=
50
}:
Props
&
{
userId
:
string
}):
Promise
<
Response
>
{
if
(
!
history
Id
)
{
if
(
!
chat
Id
)
{
return
{
history
:
[]
};
}
const
history
=
await
Chat
.
aggregate
([
{
$match
:
{
_id
:
new
Types
.
ObjectId
(
history
Id
),
userId
:
new
Types
.
ObjectId
(
userId
)
}
},
{
$match
:
{
_id
:
new
Types
.
ObjectId
(
chat
Id
),
userId
:
new
Types
.
ObjectId
(
userId
)
}
},
{
$project
:
{
content
:
{
...
...
client/src/pages/chat/components/ChatHistorySlider.tsx
View file @
505aff3d
import
React
,
{
useMemo
}
from
'react'
;
import
React
,
{
useMemo
,
useState
}
from
'react'
;
import
{
Box
,
Button
,
...
...
@@ -11,6 +11,7 @@ import {
IconButton
}
from
'@chakra-ui/react'
;
import
{
useGlobalStore
}
from
'@/store/global'
;
import
{
useEditInfo
}
from
'@/hooks/useEditInfo'
;
import
{
useRouter
}
from
'next/router'
;
import
Avatar
from
'@/components/Avatar'
;
import
MyTooltip
from
'@/components/MyTooltip'
;
...
...
@@ -19,6 +20,7 @@ import MyIcon from '@/components/Icon';
type
HistoryItemType
=
{
id
:
string
;
title
:
string
;
customTitle
?:
string
;
top
?:
boolean
;
};
...
...
@@ -27,29 +29,34 @@ const ChatHistorySlider = ({
appName
,
appAvatar
,
history
,
active
History
Id
,
active
Chat
Id
,
onChangeChat
,
onDelHistory
,
onSetHistoryTop
,
on
Update
Title
on
SetCustom
Title
}:
{
appId
?:
string
;
appName
:
string
;
appAvatar
:
string
;
history
:
HistoryItemType
[];
active
History
Id
:
string
;
onChangeChat
:
(
history
Id
?:
string
)
=>
void
;
onDelHistory
:
(
history
Id
:
string
)
=>
void
;
onSetHistoryTop
?:
(
e
:
{
history
Id
:
string
;
top
:
boolean
})
=>
void
;
on
UpdateTitle
?:
(
e
:
{
history
Id
:
string
;
title
:
string
})
=>
void
;
active
Chat
Id
:
string
;
onChangeChat
:
(
chat
Id
?:
string
)
=>
void
;
onDelHistory
:
(
chat
Id
:
string
)
=>
void
;
onSetHistoryTop
?:
(
e
:
{
chat
Id
:
string
;
top
:
boolean
})
=>
void
;
on
SetCustomTitle
?:
(
e
:
{
chat
Id
:
string
;
title
:
string
})
=>
void
;
})
=>
{
const
theme
=
useTheme
();
const
router
=
useRouter
();
const
{
isPc
}
=
useGlobalStore
();
// custom title edit
const
{
onOpenModal
,
EditModal
:
EditTitleModal
}
=
useEditInfo
({
title
:
'自定义历史记录标题'
,
placeholder
:
'如果设置为空,会自动跟随聊天记录。'
});
const
concatHistory
=
useMemo
<
HistoryItemType
[]
>
(
()
=>
(
!
active
HistoryId
?
[{
id
:
activeHistory
Id
,
title
:
'新对话'
}].
concat
(
history
)
:
history
),
[
active
History
Id
,
history
]
()
=>
(
!
active
ChatId
?
[{
id
:
activeChat
Id
,
title
:
'新对话'
}].
concat
(
history
)
:
history
),
[
active
Chat
Id
,
history
]
);
return
(
...
...
@@ -121,7 +128,7 @@ const ChatHistorySlider = ({
}
}
}
bg=
{
item
.
top
?
'#E6F6F6 !important'
:
''
}
{
...
(
item
.
id
===
active
History
Id
{
...
(
item
.
id
===
active
Chat
Id
?
{
backgroundColor
:
'
myBlue
.
100
!
important
',
color
:
'
myBlue
.
700'
...
...
@@ -132,9 +139,9 @@ const ChatHistorySlider = ({
}
})}
>
<
MyIcon
name=
{
item
.
id
===
active
History
Id
?
'chatFill'
:
'chatLight'
}
w=
{
'16px'
}
/>
<
MyIcon
name=
{
item
.
id
===
active
Chat
Id
?
'chatFill'
:
'chatLight'
}
w=
{
'16px'
}
/>
<
Box
flex=
{
'1 0 0'
}
ml=
{
3
}
className=
"textEllipsis"
>
{
item
.
title
}
{
item
.
customTitle
||
item
.
title
}
</
Box
>
{
!!
item
.
id
&&
(
<
Box
className=
"more"
display=
{
[
'block'
,
'none'
]
}
>
...
...
@@ -154,20 +161,24 @@ const ChatHistorySlider = ({
<
MenuItem
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
onSetHistoryTop
({
history
Id
:
item
.
id
,
top
:
!
item
.
top
});
onSetHistoryTop
({
chat
Id
:
item
.
id
,
top
:
!
item
.
top
});
}
}
>
<
MyIcon
mr=
{
2
}
name=
{
'setTop'
}
w=
{
'16px'
}
></
MyIcon
>
{
item
.
top
?
'取消置顶'
:
'置顶'
}
</
MenuItem
>
)
}
{
on
Update
Title
&&
(
{
on
SetCustom
Title
&&
(
<
MenuItem
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
onUpdateTitle
({
historyId
:
item
.
id
,
title
:
'是是是'
onOpenModal
({
defaultVal
:
item
.
customTitle
||
item
.
title
,
onSuccess
:
(
e
)
=>
onSetCustomTitle
({
chatId
:
item
.
id
,
title
:
e
})
});
}
}
>
...
...
@@ -180,7 +191,7 @@ const ChatHistorySlider = ({
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
();
onDelHistory
(
item
.
id
);
if
(
item
.
id
===
active
History
Id
)
{
if
(
item
.
id
===
active
Chat
Id
)
{
onChangeChat
();
}
}
}
...
...
@@ -218,6 +229,7 @@ const ChatHistorySlider = ({
切换应用
</
Flex
>
)
}
<
EditTitleModal
/>
</
Flex
>
);
};
...
...
client/src/pages/chat/index.tsx
View file @
505aff3d
...
...
@@ -26,7 +26,7 @@ import ChatHeader from './components/ChatHeader';
const
Chat
=
()
=>
{
const
router
=
useRouter
();
const
{
appId
=
''
,
historyId
=
''
}
=
router
.
query
as
{
appId
:
string
;
history
Id
:
string
};
const
{
appId
=
''
,
chatId
=
''
}
=
router
.
query
as
{
appId
:
string
;
chat
Id
:
string
};
const
theme
=
useTheme
();
const
ChatBoxRef
=
useRef
<
ComponentRef
>
(
null
);
...
...
@@ -35,8 +35,8 @@ const Chat = () => {
const
{
lastChatAppId
,
setLastChatAppId
,
last
History
Id
,
setLast
History
Id
,
last
Chat
Id
,
setLast
Chat
Id
,
history
,
loadHistory
,
updateHistory
,
...
...
@@ -52,12 +52,12 @@ const Chat = () => {
const
startChat
=
useCallback
(
async
({
messages
,
controller
,
generatingMessage
,
variables
}:
StartChatFnProps
)
=>
{
const
prompts
=
messages
.
slice
(
-
2
);
const
{
responseText
,
new
History
Id
,
rawSearch
}
=
await
streamFetch
({
const
{
responseText
,
new
Chat
Id
,
rawSearch
}
=
await
streamFetch
({
data
:
{
messages
:
prompts
,
variables
,
appId
,
history
Id
chat
Id
},
onMessage
:
generatingMessage
,
abortSignal
:
controller
...
...
@@ -66,27 +66,27 @@ const Chat = () => {
const
newTitle
=
prompts
[
0
].
content
?.
slice
(
0
,
20
)
||
'新对话'
;
// update history
if
(
new
History
Id
)
{
if
(
new
Chat
Id
)
{
forbidRefresh
.
current
=
true
;
router
.
replace
({
query
:
{
historyId
:
newHistoryId
,
appId
}
});
const
newHistory
:
ChatHistoryItemType
=
{
_id
:
new
History
Id
,
_id
:
new
Chat
Id
,
updateTime
:
new
Date
(),
title
:
newTitle
,
appId
,
top
:
false
};
updateHistory
(
newHistory
);
router
.
replace
({
query
:
{
chatId
:
newChatId
,
appId
}
});
}
else
{
const
current
History
=
history
.
find
((
item
)
=>
item
.
_id
===
history
Id
);
current
History
&&
const
current
Chat
=
history
.
find
((
item
)
=>
item
.
_id
===
chat
Id
);
current
Chat
&&
updateHistory
({
...
current
History
,
...
current
Chat
,
updateTime
:
new
Date
(),
title
:
newTitle
});
...
...
@@ -100,41 +100,41 @@ const Chat = () => {
return
{
responseText
,
rawSearch
};
},
[
appId
,
history
,
historyId
,
router
,
setChatData
,
updateHistory
]
[
appId
,
chatId
,
history
,
router
,
setChatData
,
updateHistory
]
);
// 删除一句话
const
delOneHistoryItem
=
useCallback
(
async
({
contentId
,
index
}:
{
contentId
?:
string
;
index
:
number
})
=>
{
if
(
!
history
Id
||
!
contentId
)
return
;
if
(
!
chat
Id
||
!
contentId
)
return
;
try
{
setChatData
((
state
)
=>
({
...
state
,
history
:
state
.
history
.
filter
((
_
,
i
)
=>
i
!==
index
)
}));
await
delChatRecordByIndex
({
history
Id
,
contentId
});
await
delChatRecordByIndex
({
chat
Id
,
contentId
});
}
catch
(
err
)
{
console
.
log
(
err
);
}
},
[
history
Id
,
setChatData
]
[
chat
Id
,
setChatData
]
);
// get chat app info
const
loadChatInfo
=
useCallback
(
async
({
appId
,
history
Id
,
chat
Id
,
loading
=
false
}:
{
appId
:
string
;
history
Id
:
string
;
chat
Id
:
string
;
loading
?:
boolean
;
})
=>
{
try
{
loading
&&
setIsLoading
(
true
);
const
res
=
await
getInitChatSiteInfo
({
appId
,
history
Id
});
const
res
=
await
getInitChatSiteInfo
({
appId
,
chat
Id
});
const
history
=
res
.
history
.
map
((
item
)
=>
({
...
item
,
status
:
'finish'
as
any
...
...
@@ -166,22 +166,22 @@ const Chat = () => {
}
catch
(
e
:
any
)
{
// reset all chat tore
setLastChatAppId
(
''
);
setLast
History
Id
(
''
);
setLast
Chat
Id
(
''
);
router
.
replace
(
'/chat'
);
}
setIsLoading
(
false
);
return
null
;
},
[
setIsLoading
,
setChatData
,
router
,
setLastChatAppId
,
setLast
History
Id
]
[
setIsLoading
,
setChatData
,
router
,
setLastChatAppId
,
setLast
Chat
Id
]
);
// 初始化聊天框
useQuery
([
'init'
,
appId
,
history
Id
],
()
=>
{
useQuery
([
'init'
,
appId
,
chat
Id
],
()
=>
{
// pc: redirect to latest model chat
if
(
!
appId
&&
lastChatAppId
)
{
router
.
replace
({
query
:
{
appId
:
lastChatAppId
,
historyId
:
lastHistory
Id
chatId
:
lastChat
Id
}
});
return
null
;
...
...
@@ -189,7 +189,7 @@ const Chat = () => {
// store id
appId
&&
setLastChatAppId
(
appId
);
setLast
HistoryId
(
history
Id
);
setLast
ChatId
(
chat
Id
);
if
(
forbidRefresh
.
current
)
{
forbidRefresh
.
current
=
false
;
...
...
@@ -198,7 +198,7 @@ const Chat = () => {
return
loadChatInfo
({
appId
,
history
Id
,
chat
Id
,
loading
:
appId
!==
chatData
.
appId
});
});
...
...
@@ -231,16 +231,17 @@ const Chat = () => {
appId=
{
appId
}
appName=
{
chatData
.
app
.
name
}
appAvatar=
{
chatData
.
app
.
avatar
}
active
HistoryId=
{
history
Id
}
active
ChatId=
{
chat
Id
}
history=
{
history
.
map
((
item
)
=>
({
id
:
item
.
_id
,
title
:
item
.
title
,
customTitle
:
item
.
customTitle
,
top
:
item
.
top
}))
}
onChangeChat=
{
(
history
Id
)
=>
{
onChangeChat=
{
(
chat
Id
)
=>
{
router
.
push
({
query
:
{
historyId
:
history
Id
||
''
,
chatId
:
chat
Id
||
''
,
appId
}
});
...
...
@@ -252,7 +253,7 @@ const Chat = () => {
onSetHistoryTop=
{
async
(
e
)
=>
{
try
{
await
putChatHistory
(
e
);
const
historyItem
=
history
.
find
((
item
)
=>
item
.
_id
===
e
.
history
Id
);
const
historyItem
=
history
.
find
((
item
)
=>
item
.
_id
===
e
.
chat
Id
);
if
(
!
historyItem
)
return
;
updateHistory
({
...
historyItem
,
...
...
@@ -260,17 +261,17 @@ const Chat = () => {
});
}
catch
(
error
)
{}
}
}
on
Update
Title=
{
async
(
e
)
=>
{
on
SetCustom
Title=
{
async
(
e
)
=>
{
try
{
await
putChatHistory
({
historyId
:
e
.
history
Id
,
chatId
:
e
.
chat
Id
,
customTitle
:
e
.
title
});
const
historyItem
=
history
.
find
((
item
)
=>
item
.
_id
===
e
.
history
Id
);
const
historyItem
=
history
.
find
((
item
)
=>
item
.
_id
===
e
.
chat
Id
);
if
(
!
historyItem
)
return
;
updateHistory
({
...
historyItem
,
t
itle
:
e
.
title
customT
itle
:
e
.
title
});
}
catch
(
error
)
{}
}
}
...
...
@@ -297,7 +298,7 @@ const Chat = () => {
<
ChatBox
ref=
{
ChatBoxRef
}
showEmptyIntro
historyId=
{
history
Id
}
chatId=
{
chat
Id
}
appAvatar=
{
chatData
.
app
.
avatar
}
variableModules=
{
chatData
.
app
.
variableModules
}
welcomeText=
{
chatData
.
app
.
welcomeText
}
...
...
client/src/pages/chat/share.tsx
View file @
505aff3d
...
...
@@ -19,7 +19,7 @@ const ChatHistorySlider = dynamic(() => import('./components/ChatHistorySlider')
ssr
:
false
});
const
ShareChat
=
({
shareId
,
historyId
}:
{
shareId
:
string
;
history
Id
:
string
})
=>
{
const
ShareChat
=
({
shareId
,
chatId
}:
{
shareId
:
string
;
chat
Id
:
string
})
=>
{
const
router
=
useRouter
();
const
{
toast
}
=
useToast
();
const
{
isOpen
:
isOpenSlider
,
onClose
:
onCloseSlider
,
onOpen
:
onOpenSlider
}
=
useDisclosure
();
...
...
@@ -33,7 +33,7 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
shareChatHistory
,
saveChatResponse
,
delShareChatHistoryItemById
,
delOneShareHistoryBy
History
Id
,
delOneShareHistoryBy
Chat
Id
,
delManyShareChatHistoryByShareId
}
=
useShareChatStore
();
...
...
@@ -60,7 +60,7 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
/* save chat */
const
{
newChatId
}
=
saveChatResponse
({
history
Id
,
chat
Id
,
prompts
:
gptMessage2ChatType
(
prompts
).
map
((
item
)
=>
({
...
item
,
status
:
'finish'
...
...
@@ -73,7 +73,7 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
router
.
replace
({
query
:
{
shareId
,
history
Id
:
newChatId
chat
Id
:
newChatId
}
});
}
...
...
@@ -88,15 +88,15 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
return
{
responseText
};
},
[
history
Id
,
router
,
saveChatResponse
,
shareChatData
.
maxContext
,
shareId
]
[
chat
Id
,
router
,
saveChatResponse
,
shareChatData
.
maxContext
,
shareId
]
);
const
loadAppInfo
=
useCallback
(
async
(
shareId
:
string
,
history
Id
:
string
)
=>
{
console
.
log
(
shareId
,
history
Id
);
async
(
shareId
:
string
,
chat
Id
:
string
)
=>
{
console
.
log
(
shareId
,
chat
Id
);
if
(
!
shareId
)
return
null
;
const
history
=
shareChatHistory
.
find
((
item
)
=>
item
.
_id
===
history
Id
)
||
defaultHistory
;
const
history
=
shareChatHistory
.
find
((
item
)
=>
item
.
_id
===
chat
Id
)
||
defaultHistory
;
ChatBoxRef
.
current
?.
resetHistory
(
history
.
chats
);
ChatBoxRef
.
current
?.
resetVariables
(
history
.
variables
);
...
...
@@ -134,8 +134,8 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
[
delManyShareChatHistoryByShareId
,
setShareChatData
,
shareChatData
,
shareChatHistory
,
toast
]
);
useQuery
([
'init'
,
shareId
,
history
Id
],
()
=>
{
return
loadAppInfo
(
shareId
,
history
Id
);
useQuery
([
'init'
,
shareId
,
chat
Id
],
()
=>
{
return
loadAppInfo
(
shareId
,
chat
Id
);
});
return
(
...
...
@@ -156,15 +156,15 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
<
ChatHistorySlider
appName=
{
shareChatData
.
app
.
name
}
appAvatar=
{
shareChatData
.
app
.
avatar
}
active
HistoryId=
{
history
Id
}
active
ChatId=
{
chat
Id
}
history=
{
shareChatHistory
.
map
((
item
)
=>
({
id
:
item
.
_id
,
title
:
item
.
title
}))
}
onChangeChat=
{
(
history
Id
)
=>
{
onChangeChat=
{
(
chat
Id
)
=>
{
router
.
push
({
query
:
{
historyId
:
history
Id
||
''
,
chatId
:
chat
Id
||
''
,
shareId
}
});
...
...
@@ -172,7 +172,7 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
onCloseSlider
();
}
}
}
onDelHistory=
{
delOneShareHistoryBy
History
Id
}
onDelHistory=
{
delOneShareHistoryBy
Chat
Id
}
/>
)
}
...
...
@@ -208,7 +208,7 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
}));
}
}
onStartChat=
{
startChat
}
onDelMessage=
{
({
index
})
=>
delShareChatHistoryItemById
({
history
Id
,
index
})
}
onDelMessage=
{
({
index
})
=>
delShareChatHistoryItemById
({
chat
Id
,
index
})
}
/>
</
Box
>
</
Flex
>
...
...
@@ -219,10 +219,10 @@ const ShareChat = ({ shareId, historyId }: { shareId: string; historyId: string
export
async
function
getServerSideProps
(
context
:
any
)
{
const
shareId
=
context
?.
query
?.
shareId
||
''
;
const
historyId
=
context
?.
query
?.
history
Id
||
''
;
const
chatId
=
context
?.
query
?.
chat
Id
||
''
;
return
{
props
:
{
shareId
,
history
Id
}
props
:
{
shareId
,
chat
Id
}
};
}
...
...
client/src/pages/kb/detail/components/DataCard.tsx
View file @
505aff3d
...
...
@@ -253,7 +253,7 @@ const DataCard = ({ kbId }: { kbId: string }) => {
</
Flex
>
)
}
{
total
===
0
&&
(
<
Flex
h=
{
'100%'
}
flexDirection=
{
'column'
}
alignItems=
{
'center'
}
pt=
{
'10vh'
}
>
<
Flex
flexDirection=
{
'column'
}
alignItems=
{
'center'
}
pt=
{
'10vh'
}
>
<
MyIcon
name=
"empty"
w=
{
'48px'
}
h=
{
'48px'
}
color=
{
'transparent'
}
/>
<
Box
mt=
{
2
}
color=
{
'myGray.500'
}
>
知识库空空如也
...
...
client/src/pages/login/index.tsx
View file @
505aff3d
...
...
@@ -18,12 +18,12 @@ const Login = () => {
const
{
isPc
}
=
useGlobalStore
();
const
[
pageType
,
setPageType
]
=
useState
<
`
${
PageTypeEnum
}
`
>
(
PageTypeEnum
.
login
);
const
{
setUserInfo
}
=
useUserStore
();
const
{
setLast
History
Id
,
setLastChatAppId
}
=
useChatStore
();
const
{
setLast
Chat
Id
,
setLastChatAppId
}
=
useChatStore
();
const
loginSuccess
=
useCallback
(
(
res
:
ResLogin
)
=>
{
// init store
setLast
History
Id
(
''
);
setLast
Chat
Id
(
''
);
setLastChatAppId
(
''
);
setUserInfo
(
res
.
user
);
...
...
@@ -31,7 +31,7 @@ const Login = () => {
router
.
push
(
lastRoute
?
decodeURIComponent
(
lastRoute
)
:
'/app/list'
);
},
100
);
},
[
lastRoute
,
router
,
setLast
History
Id
,
setLastChatAppId
,
setUserInfo
]
[
lastRoute
,
router
,
setLast
Chat
Id
,
setLastChatAppId
,
setUserInfo
]
);
function
DynamicComponent
({
type
}:
{
type
:
`
${
PageTypeEnum
}
`
})
{
...
...
client/src/service/utils/chat/index.ts
View file @
505aff3d
import
{
ChatItemType
}
from
'@/types/chat'
;
import
{
modelToolMap
}
from
'@/utils/plugin'
;
import
{
ChatRoleEnum
}
from
'@/constants/chat'
;
import
{
ChatRoleEnum
,
sseResponseEventEnum
}
from
'@/constants/chat'
;
import
{
sseResponse
}
from
'../tools'
;
import
{
OpenAiChatEnum
}
from
'@/constants/model'
;
import
type
{
NextApiResponse
}
from
'next'
;
export
type
ChatCompletionType
=
{
apiKey
:
string
;
temperature
:
number
;
maxToken
?:
number
;
messages
:
ChatItemType
[];
historyId
?:
string
;
[
key
:
string
]:
any
;
};
export
type
ChatCompletionResponseType
=
{
streamResponse
:
any
;
responseMessages
:
ChatItemType
[];
...
...
client/src/store/chat.ts
View file @
505aff3d
...
...
@@ -15,12 +15,12 @@ type State = {
setChatData
:
(
e
:
InitChatResponse
|
((
e
:
InitChatResponse
)
=>
InitChatResponse
))
=>
void
;
lastChatAppId
:
string
;
setLastChatAppId
:
(
id
:
string
)
=>
void
;
last
History
Id
:
string
;
setLast
History
Id
:
(
id
:
string
)
=>
void
;
last
Chat
Id
:
string
;
setLast
Chat
Id
:
(
id
:
string
)
=>
void
;
};
const
defaultChatData
:
InitChatResponse
=
{
history
Id
:
''
,
chat
Id
:
''
,
appId
:
''
,
app
:
{
name
:
''
,
...
...
@@ -43,10 +43,10 @@ export const useChatStore = create<State>()(
state
.
lastChatAppId
=
id
;
});
},
last
History
Id
:
''
,
setLast
History
Id
(
id
:
string
)
{
last
Chat
Id
:
''
,
setLast
Chat
Id
(
id
:
string
)
{
set
((
state
)
=>
{
state
.
last
History
Id
=
id
;
state
.
last
Chat
Id
=
id
;
});
},
history
:
[],
...
...
@@ -63,25 +63,36 @@ export const useChatStore = create<State>()(
});
return
null
;
},
async
delHistory
(
history
Id
)
{
async
delHistory
(
chat
Id
)
{
set
((
state
)
=>
{
state
.
history
=
state
.
history
.
filter
((
item
)
=>
item
.
_id
!==
history
Id
);
state
.
history
=
state
.
history
.
filter
((
item
)
=>
item
.
_id
!==
chat
Id
);
});
await
delChatHistoryById
(
history
Id
);
await
delChatHistoryById
(
chat
Id
);
},
updateHistory
(
history
)
{
const
index
=
get
().
history
.
findIndex
((
item
)
=>
item
.
_id
===
history
.
_id
);
set
((
state
)
=>
{
if
(
index
>
-
1
)
{
const
newHistory
=
[
history
,
...
get
().
history
.
slice
(
0
,
index
),
...
get
().
history
.
slice
(
index
+
1
)
];
state
.
history
=
newHistory
;
}
else
{
state
.
history
=
[
history
,
...
state
.
history
];
}
const
newHistory
=
(()
=>
{
if
(
index
>
-
1
)
{
return
[
history
,
...
get
().
history
.
slice
(
0
,
index
),
...
get
().
history
.
slice
(
index
+
1
)
];
}
else
{
return
[
history
,
...
state
.
history
];
}
})();
// newHistory.sort(function (a, b) {
// if (a.top === true && b.top === false) {
// return -1;
// } else if (a.top === false && b.top === true) {
// return 1;
// } else {
// return 0;
// }
// });
state
.
history
=
newHistory
;
});
},
chatData
:
defaultChatData
,
...
...
@@ -101,7 +112,7 @@ export const useChatStore = create<State>()(
name
:
'chatStore'
,
partialize
:
(
state
)
=>
({
lastChatAppId
:
state
.
lastChatAppId
,
last
HistoryId
:
state
.
lastHistory
Id
last
ChatId
:
state
.
lastChat
Id
})
}
)
...
...
client/src/store/shareChat.ts
View file @
505aff3d
...
...
@@ -12,13 +12,13 @@ type State = {
setShareChatData
:
(
e
:
ShareChatType
|
((
e
:
ShareChatType
)
=>
ShareChatType
))
=>
void
;
shareChatHistory
:
ShareChatHistoryItemType
[];
saveChatResponse
:
(
e
:
{
history
Id
:
string
;
chat
Id
:
string
;
prompts
:
ChatSiteItemType
[];
variables
:
Record
<
string
,
any
>
;
shareId
:
string
;
})
=>
{
newChatId
:
string
};
delOneShareHistoryBy
HistoryId
:
(
history
Id
:
string
)
=>
void
;
delShareChatHistoryItemById
:
(
e
:
{
history
Id
:
string
;
index
:
number
})
=>
void
;
delOneShareHistoryBy
ChatId
:
(
chat
Id
:
string
)
=>
void
;
delShareChatHistoryItemById
:
(
e
:
{
chat
Id
:
string
;
index
:
number
})
=>
void
;
delManyShareChatHistoryByShareId
:
(
shareId
?:
string
)
=>
void
;
};
...
...
@@ -62,15 +62,15 @@ export const useShareChatStore = create<State>()(
});
},
shareChatHistory
:
[],
saveChatResponse
({
history
Id
,
prompts
,
variables
,
shareId
})
{
const
history
=
get
().
shareChatHistory
.
find
((
item
)
=>
item
.
_id
===
history
Id
);
saveChatResponse
({
chat
Id
,
prompts
,
variables
,
shareId
})
{
const
history
=
get
().
shareChatHistory
.
find
((
item
)
=>
item
.
_id
===
chat
Id
);
const
newChatId
=
history
?
''
:
nanoid
();
const
historyList
=
(()
=>
{
if
(
history
)
{
return
get
().
shareChatHistory
.
map
((
item
)
=>
item
.
_id
===
history
Id
item
.
_id
===
chat
Id
?
{
...
item
,
title
:
prompts
[
prompts
.
length
-
2
]?.
value
,
...
...
@@ -102,18 +102,16 @@ export const useShareChatStore = create<State>()(
newChatId
};
},
delOneShareHistoryBy
HistoryId
(
history
Id
:
string
)
{
delOneShareHistoryBy
ChatId
(
chat
Id
:
string
)
{
set
((
state
)
=>
{
state
.
shareChatHistory
=
state
.
shareChatHistory
.
filter
(
(
item
)
=>
item
.
_id
!==
historyId
);
state
.
shareChatHistory
=
state
.
shareChatHistory
.
filter
((
item
)
=>
item
.
_id
!==
chatId
);
});
},
delShareChatHistoryItemById
({
history
Id
,
index
})
{
delShareChatHistoryItemById
({
chat
Id
,
index
})
{
set
((
state
)
=>
{
// update history store
const
newHistoryList
=
state
.
shareChatHistory
.
map
((
item
)
=>
item
.
_id
===
history
Id
item
.
_id
===
chat
Id
?
{
...
item
,
chats
:
[...
item
.
chats
.
slice
(
0
,
index
),
...
item
.
chats
.
slice
(
index
+
1
)]
...
...
client/src/types/chat.d.ts
View file @
505aff3d
...
...
@@ -20,6 +20,7 @@ export type ChatSiteItemType = {
export
type
HistoryItemType
=
{
_id
:
string
;
updateTime
:
Date
;
customTitle
?:
string
;
title
:
string
;
};
export
type
ChatHistoryItemType
=
HistoryItemType
&
{
...
...
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