本文将介绍如何基于 React / Nextjs框架开发一个功能强大的聊天窗口,并集成 deepseek 和 gpt-4o 的 API,实现智能对话功能。免登录。
源码地址:https://github.com/geeeeeeeek/ai-starter
一、技术栈
- 前端框架: React / nextjs
- UI 库: tailwindcss/shadcn
- 状态管理: Redux
- HTTP 请求: fetch
- API 集成: deepseek API, gpt-4o API
二、功能实现
- 聊天窗口界面
使用 React 组件构建聊天窗口界面,包括消息列表、输入框、发送按钮等。
使用 UI 库美化界面,例如 Material-UI 的卡片、按钮等组件。
实现消息的发送和接收功能,并将消息实时显示在消息列表中。
将聊天窗口封装到chatDialog.jsx中(具体代码可参考github里)
return (
<div className="flex-1 flex flex-col h-screen bg-white p-0">
<div className="relative bg-white h-12 shadow">
<SidebarTrigger className="absolute h-12 w-12" />
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 ">AI Chat</div>
</div>
<div className="flex-1 overflow-y-auto mt-4 mb-4 space-y-4 ">
{messages.map((msg, index) => (
<div
key={index} className="w-full max-w-4xl m-auto"
>
{
msg.role === 'user' ? (
<div className="flex justify-end">
<div className="bg-blue-200 p-3 rounded inline-block">{msg.content}</div>
</div>
) : (
<div className="flex gap-4">
<div>
<svg t="1735719680744" className="icon" viewBox="0 0 1024 1024" version="1.1"
xmlns="http://www.w3.org/2000/svg" p-id="20857" width="32" height="32">
<path
d="M509.44 403.2c-26.88 0-48.64 21.76-48.64 48.64s21.76 48.64 48.64 48.64 48.64-21.76 48.64-48.64c1.28-26.88-20.48-48.64-48.64-48.64z m104.96 53.76c0 26.88 21.76 48.64 48.64 48.64s48.64-21.76 48.64-48.64-21.76-48.64-48.64-48.64c-26.88-1.28-48.64 20.48-48.64 48.64zM512 0C229.12 0 0 229.12 0 512s229.12 512 512 512 512-229.12 512-512S794.88 0 512 0z m243.2 509.44c-14.08 117.76-138.24 200.96-267.52 192-14.08-1.28-29.44 1.28-42.24 7.68l-87.04 47.36c-12.8 6.4-23.04 1.28-26.88-1.28s-12.8-10.24-12.8-24.32l2.56-70.4c1.28-19.2 3.84-46.08-12.8-58.88-56.32-44.8-57.6-97.28-51.2-152.32 12.8-111.36 115.2-195.84 234.24-195.84 10.24 0 21.76 1.28 32 2.56 65.28 7.68 128 34.56 167.68 83.2 44.8 46.08 70.4 111.36 64 170.24zM353.28 403.2c-26.88 0-48.64 21.76-48.64 48.64s21.76 48.64 48.64 48.64 48.64-21.76 48.64-48.64-21.76-48.64-48.64-48.64z"
p-id="20858" fill="#1296db"></path>
</svg>
</div>
<div className="pt-1">
<ReactMarkdown components={{
code({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '');
return !inline && match ? (
<SyntaxHighlighter
style={materialDark}
language={match[1]}
PreTag="div"
{...props}
>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
) : (
<code className={className} {...props}>
{children}
</code>
);
},
}}>{msg.content}</ReactMarkdown>
</div>
</div>
)
}
</div>
))}
{/* 用于自动滚动的空 div */}
<div ref={messagesEndRef} />
</div>
<div className="flex w-full max-w-4xl mb-4 m-auto " >
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleSend()}
className="flex-1 h-12 p-4 border border-gray-300 rounded-l-lg focus:outline-none"
placeholder="Send a message to AI...."
/>
<Button onClick={handleSend} disabled={isFetching} className="bg-blue-500 text-white h-12 py-4 px-4 rounded-l-none rounded-r-lg hover:bg-blue-600">
Send
</Button>
</div>
</div>
);
- API 集成
使用了nextjs的api路由功能,提供的服务渲染,创建route.js文件编写api请求方法,并调用openai的sdk。实现了流式获取。
// app/api/chat/route.js
import OpenAI from 'openai';
export async function POST(request) {
const { messages, model } = await request.json();
let baseURL = 'https://api.deepseek.com';
let apiKey = process.env.OPENAI_API_KEY;
if (model === 'gpt-4o-mini' || model === 'gpt-4o') {
baseURL = 'https://models.inference.ai.azure.com';
apiKey = process.env.OPENAI_API_KEY_GPT;
} else {
baseURL = 'https://api.deepseek.com';
apiKey = process.env.OPENAI_API_KEY;
}
const openai = new OpenAI({
baseURL: baseURL,
apiKey: apiKey, // 从环境变量中获取 API Key
});
try {
const response = await openai.chat.completions.create({
model: model,
messages,
stream: true, // 启用流式响应
});
// 创建可读流
const stream = new ReadableStream({
async start(controller) {
for await (const chunk of response) {
const content = chunk.choices[0]?.delta?.content || '';
controller.enqueue(`data: ${JSON.stringify({ content })}\n\n`);
}
controller.close();
},
});
// 返回流式响应
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
},
});
} catch (error) {
console.error('Error calling OpenAI API:', error);
return new Response(JSON.stringify({ error: 'Internal server error' }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
});
}
}
注意:需要开发者去deepseek申请api_key,另外还需要去github申请gpt-4o的api_key
预览结果如下