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