diff --git a/src/components/Markdown/index.module.scss b/src/components/Markdown/index.module.scss index 3c69ddae0..8b89f1f5c 100644 --- a/src/components/Markdown/index.module.scss +++ b/src/components/Markdown/index.module.scss @@ -8,7 +8,7 @@ animation: blink 0.6s infinite; } .animation { - :last-child::after { + > :last-child::after { display: inline-block; content: ''; width: 4px; diff --git a/src/pages/api/chat/chatGpt.ts b/src/pages/api/chat/chatGpt.ts index 5917c50f1..775fd3dba 100644 --- a/src/pages/api/chat/chatGpt.ts +++ b/src/pages/api/chat/chatGpt.ts @@ -69,56 +69,51 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) stream: true }, { + timeout: 20000, responseType: 'stream', httpsAgent: openaiProxy?.httpsAgent } ); + console.log('response success'); let AIResponse = ''; // 解析数据 const decoder = new TextDecoder(); - new ReadableStream({ - async start(controller) { - // callback - async function onParse(event: ParsedEvent | ReconnectInterval) { - if (event.type === 'event') { - const data = event.data; - if (data === '[DONE]') { - controller.close(); - res.write('event: done\ndata: \n\n'); - res.end(); - // 存入库 - await ChatWindow.findByIdAndUpdate(windowId, { - $push: { - content: { - obj: 'AI', - value: AIResponse - } - }, - updateTime: Date.now() - }); - return; - } - try { - const json = JSON.parse(data); - const content: string = json.choices[0].delta.content || ''; - res.write(`event: responseData\ndata: ${content.replace(/\n/g, '
')}\n\n`); - AIResponse += content; - } catch (e) { - // maybe parse error - controller.error(e); - res.end(); - } - } + const onParse = async (event: ParsedEvent | ReconnectInterval) => { + if (event.type === 'event') { + const data = event.data; + if (data === '[DONE]') { + // 存入库 + await ChatWindow.findByIdAndUpdate(windowId, { + $push: { + content: { + obj: 'AI', + value: AIResponse + } + }, + updateTime: Date.now() + }); + res.write('event: done\ndata: \n\n'); + res.end(); + return; } - - const parser = createParser(onParse); - for await (const chunk of chatResponse.data as any) { - parser.feed(decoder.decode(chunk)); + try { + const json = JSON.parse(data); + const content: string = json.choices[0].delta.content || ''; + // console.log('content:', content) + res.write(`event: responseData\ndata: ${content.replace(/\n/g, '
')}\n\n`); + AIResponse += content; + } catch (e) { + res.end(); } } - }); + }; + + const parser = createParser(onParse); + for await (const chunk of chatResponse.data as any) { + parser.feed(decoder.decode(chunk)); + } } catch (err: any) { let errorText = err; if (err.code === 'ECONNRESET') { diff --git a/src/pages/chat/index.tsx b/src/pages/chat/index.tsx index 86da56d36..c9cc2941d 100644 --- a/src/pages/chat/index.tsx +++ b/src/pages/chat/index.tsx @@ -127,14 +127,14 @@ const Chat = () => { let timer = setTimeout(() => { event.close(); reject('服务器超时'); - }, 300000); + }, 30000); event.addEventListener('responseData', ({ data }) => { /* 重置定时器 */ clearTimeout(timer); timer = setTimeout(() => { event.close(); reject('服务器超时'); - }, 300000); + }, 30000); const msg = data.replace(//g, '\n'); setChatList((state) => @@ -264,7 +264,7 @@ const Chat = () => { const reEdit = useCallback(async () => { if (chatList[chatList.length - 1]?.obj !== 'Human') return; // 删除数据库最后一句 - delLastMessage(windowId); + await delLastMessage(windowId); const val = chatList[chatList.length - 1].value; setInputVal(val); diff --git a/src/service/mongo.ts b/src/service/mongo.ts index e68deb885..80a8b3016 100644 --- a/src/service/mongo.ts +++ b/src/service/mongo.ts @@ -1,18 +1,28 @@ import mongoose from 'mongoose'; -import type { Mongoose } from 'mongoose'; -let cachedClient: Mongoose; - -export async function connectToDatabase() { - if (cachedClient && cachedClient.connection.readyState === 1) { - return cachedClient; +/** + * 连接 MongoDB 数据库 + */ +export async function connectToDatabase(): Promise { + // @ts-ignore + if (global.mongodb) { + return; + } + // @ts-ignore + global.mongodb = 'connecting'; + console.log('connect mongo'); + try { + // @ts-ignore + global.mongodb = await mongoose.connect(process.env.MONGODB_URI as string, { + dbName: 'doc_gpt', + maxPoolSize: 10, + minPoolSize: 1 + }); + } catch (error) { + console.error('mongo connect error'); + // @ts-ignore + global.mongodb = null; } - - cachedClient = await mongoose.connect(process.env.MONGODB_URI as string, { - dbName: 'doc_gpt' - }); - - return cachedClient; } export * from './models/authCode'; diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 000000000..2a2aedcda --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,9 @@ +import type { Mongoose } from 'mongoose'; + +declare global { + interface Global { + mongodb: Mongoose; + } +} + +export type a = string; diff --git a/tsconfig.json b/tsconfig.json index 2159bf45c..c193e0a06 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,6 @@ "@/*": ["./src/*"] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts"], "exclude": ["node_modules"] }