diff --git a/src/api/chat.ts b/src/api/chat.ts index 8367d3614..891ad71d1 100644 --- a/src/api/chat.ts +++ b/src/api/chat.ts @@ -1,5 +1,5 @@ import { GET, POST, DELETE } from './request'; -import type { ChatItemType, ChatSiteItemType } from '@/types/chat'; +import type { ChatItemType } from '@/types/chat'; import type { InitChatResponse } from './response/chat'; /** @@ -8,24 +8,6 @@ import type { InitChatResponse } from './response/chat'; export const getInitChatSiteInfo = (modelId: string, chatId: '' | string) => GET(`/chat/init?modelId=${modelId}&chatId=${chatId}`); -/** - * 发送 GPT3 prompt - */ -export const postGPT3SendPrompt = ({ - chatId, - prompt -}: { - prompt: ChatSiteItemType[]; - chatId: string; -}) => - POST(`/chat/gpt3`, { - chatId, - prompt: prompt.map((item) => ({ - obj: item.obj, - value: item.value - })) - }); - /** * 获取历史记录 */ diff --git a/src/components/Markdown/index.tsx b/src/components/Markdown/index.tsx index 51d6b977d..d5f998c15 100644 --- a/src/components/Markdown/index.tsx +++ b/src/components/Markdown/index.tsx @@ -1,4 +1,4 @@ -import React, { memo, useMemo } from 'react'; +import React, { memo } from 'react'; import ReactMarkdown from 'react-markdown'; import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; import { Box, Flex, useColorModeValue } from '@chakra-ui/react'; @@ -14,7 +14,6 @@ import { codeLight } from './codeLight'; const Markdown = ({ source, isChatting = false }: { source: string; isChatting?: boolean }) => { const { copyData } = useCopyData(); - const formatSource = useMemo(() => source, [source]); return ( - {formatSource} + {source} ); }; diff --git a/src/pages/api/chat/init.ts b/src/pages/api/chat/init.ts index 7d119095a..32939d896 100644 --- a/src/pages/api/chat/init.ts +++ b/src/pages/api/chat/init.ts @@ -1,10 +1,11 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { jsonRes } from '@/service/response'; -import { connectToDatabase, Chat, Model } from '@/service/mongo'; +import { connectToDatabase, Chat } from '@/service/mongo'; import type { InitChatResponse } from '@/api/response/chat'; import { authToken } from '@/service/utils/tools'; import { ChatItemType } from '@/types/chat'; import { authModel } from '@/service/utils/auth'; +import mongoose from 'mongoose'; /* 初始化我的聊天框,需要身份验证 */ export default async function handler(req: NextApiRequest, res: NextApiResponse) { @@ -27,19 +28,23 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) let history: ChatItemType[] = []; if (chatId) { - // 获取 chat 数据 - const chat = await Chat.findOne({ - _id: chatId, - userId, - modelId - }); + // 获取 chat.content 数据 + history = await Chat.aggregate([ + { $match: { _id: new mongoose.Types.ObjectId(chatId) } }, + { $unwind: '$content' }, + { $match: { 'content.deleted': false } }, + { $sort: { 'content._id': -1 } }, + { $limit: 50 }, + { + $project: { + id: '$content._id', + obj: '$content.obj', + value: '$content.value' + } + } + ]); - if (!chat) { - throw new Error('聊天框不存在'); - } - - // filter 被 deleted 的内容 - history = chat.content.filter((item) => item.deleted !== true); + history.reverse(); } jsonRes(res, { diff --git a/src/pages/chat/index.tsx b/src/pages/chat/index.tsx index f8759640e..6580a1de6 100644 --- a/src/pages/chat/index.tsx +++ b/src/pages/chat/index.tsx @@ -3,7 +3,7 @@ import { useRouter } from 'next/router'; import Image from 'next/image'; import { getInitChatSiteInfo, delChatRecordByIndex, postSaveChat } from '@/api/chat'; import type { InitChatResponse } from '@/api/response/chat'; -import { ChatSiteItemType } from '@/types/chat'; +import type { ChatItemType } from '@/types/chat'; import { Textarea, Box, @@ -29,6 +29,8 @@ import { streamFetch } from '@/api/fetch'; import Icon from '@/components/Icon'; import MyIcon from '@/components/Icon'; import { throttle } from 'lodash'; +import { customAlphabet } from 'nanoid'; +const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 5); const SlideBar = dynamic(() => import('./components/SlideBar')); const Empty = dynamic(() => import('./components/Empty')); @@ -36,6 +38,11 @@ const Markdown = dynamic(() => import('@/components/Markdown')); const textareaMinH = '22px'; +export type ChatSiteItemType = { + id: string; + status: 'loading' | 'finish'; +} & ChatItemType; + interface ChatType extends InitChatResponse { history: ChatSiteItemType[]; } @@ -123,10 +130,13 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => { isLoading && setLoading(true); try { const res = await getInitChatSiteInfo(modelId, chatId); + setChatData({ ...res, - history: res.history.map((item) => ({ - ...item, + history: res.history.map((item: any, i) => ({ + obj: item.obj, + value: item.value, + id: item.id || `${nanoid()}-${i}`, status: 'finish' })) }); @@ -284,11 +294,13 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => { const newChatList: ChatSiteItemType[] = [ ...chatData.history, { + id: nanoid(), obj: 'Human', value: val, status: 'finish' }, { + id: nanoid(), obj: 'AI', value: '', status: 'loading' @@ -432,7 +444,7 @@ const Chat = ({ modelId, chatId }: { modelId: string; chatId: string }) => { {chatData.history.map((item, index) => ( { const configuration = new Configuration({ @@ -47,14 +48,17 @@ export const authChat = async ({ if (chatId) { // 获取 chat 数据 - const chat = await Chat.findById(chatId); - - if (!chat) { - return Promise.reject('对话不存在'); - } - - // filter 掉被 deleted 的内容 - content = chat.content.filter((item) => item.deleted !== true); + content = await Chat.aggregate([ + { $match: { _id: new mongoose.Types.ObjectId(chatId) } }, + { $unwind: '$content' }, + { $match: { 'content.deleted': false } }, + { + $project: { + obj: '$content.obj', + value: '$content.value' + } + } + ]); } // 获取 user 的 apiKey diff --git a/src/types/chat.d.ts b/src/types/chat.d.ts index 86731b6a8..3145abbee 100644 --- a/src/types/chat.d.ts +++ b/src/types/chat.d.ts @@ -3,13 +3,3 @@ export type ChatItemType = { value: string; deleted?: boolean; }; - -export type ChatSiteItemType = { - status: 'loading' | 'finish'; -} & ChatItemType; - -export type HistoryItem = { - chatId: string; - title: string; - history?: ChatSiteItemType[]; -};