# localDeploym-deepSeek **Repository Path**: lileijiang/local-deploym-deep-seek ## Basic Information - **Project Name**: localDeploym-deepSeek - **Description**: 本地部署DeepSeek 学习 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-12 - **Last Updated**: 2025-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 基于 Vue3 + TypeScript + Element Plus 实现 DeepSeek AI 对话界面(流式输出) ## 📖 前言 最近在开发一个后台管理系统时,需要集成 AI 对话功能。经过调研,选择了 DeepSeek API 作为后端服务,使用 Vue3 + TypeScript + Element Plus 实现了一个功能完善的对话界面。本文将详细介绍实现过程,包括流式输出、思考模式、对话历史管理等核心功能。 ## 🎯 项目概述 本项目实现了一个完整的 DeepSeek AI 对话界面,支持: - ✅ 流式回答(逐字显示) - ✅ 思考模式切换 - ✅ 对话历史管理 - ✅ 用户信息展示 - ✅ 账户余额查询 - ✅ 模型切换 - ✅ 美观的 UI 界面 ## 🛠️ 技术栈 - **前端框架**: Vue 3.5.13 (Composition API) - **类型系统**: TypeScript 5.8.3 - **UI 组件库**: Element Plus 2.11.9 - **HTTP 客户端**: Axios 1.13.2 - **AI SDK**: OpenAI SDK 6.10.0 (兼容 DeepSeek API) - **构建工具**: Vite 6.3.5 - **样式预处理**: Less 4.3.0 ## 📦 项目结构 ``` src/views/index/ ├── index.vue # 主组件(UI 界面) ├── index.ts # 业务逻辑(API 调用、对话管理) └── index.scss # 样式文件 ``` ## 🚀 核心功能实现 ### 1. 流式回答实现 流式回答是核心功能之一,让 AI 的回答能够逐字显示,提升用户体验。 #### 1.1 API 调用层(index.ts) ```typescript // 聊天 - 支持流式和思考模式 export async function main( userMessage?: string, model: string = "deepseek-chat", options?: { stream?: boolean; // 是否流式输出 thinkingMode?: boolean; // 是否思考模式 onStreamChunk?: (chunk: string) => void; // 流式数据回调 } ) { try { // 如果提供了用户消息,添加到历史 if (userMessage) { addMessageToHistory({ role: "user", content: userMessage }); } // 构建消息数组,包含系统提示和对话历史 const conversation = conversations.find((c) => c.id === currentConversationId); const historyMessages = conversation?.messages || []; const messages: Message[] = [ { role: "system", content: "You are a helpful assistant." }, ...historyMessages, ]; // 流式模式 if (options?.stream) { const stream = await openai.chat.completions.create({ messages: messages as any, model: model, stream: true, }); let fullContent = ""; for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content || ""; if (content) { fullContent += content; // 调用回调函数,实时更新UI options?.onStreamChunk?.(fullContent); } } // 将完整回复添加到历史 addMessageToHistory({ role: "assistant", content: fullContent }); return fullContent; } // 非流式模式... } catch (error: any) { // 错误处理... } } ``` **关键点**: - 使用 `stream: true` 启用流式输出 - 通过 `for await...of` 遍历流数据 - 使用回调函数 `onStreamChunk` 实时更新 UI - `chunk.choices[0]?.delta?.content` 获取增量内容 #### 1.2 UI 层实现(index.vue) ```vue ``` **关键点**: - 先创建空的助手消息,用于流式更新 - `chunk` 参数是完整的累积内容,直接赋值(不要累加) - 实时更新消息内容并自动滚动 ### 2. 思考模式实现 思考模式允许用户切换 AI 的思考方式,通过开关控制。 ```vue ``` ### 3. 对话历史管理 实现了多对话管理,支持创建、切换、删除对话。 ```typescript // 对话历史管理 interface Conversation { id: string; title: string; messages: Message[]; createdAt: number; updatedAt: number; } let conversations: Conversation[] = []; let currentConversationId: string | null = null; // 创建新对话 export function createNewConversation(): string { const id = `conv_${Date.now()}`; const newConversation: Conversation = { id, title: "新对话", messages: [], createdAt: Date.now(), updatedAt: Date.now(), }; conversations.unshift(newConversation); currentConversationId = id; return id; } // 切换到指定对话 export function switchConversation(conversationId: string) { currentConversationId = conversationId; const conversation = conversations.find((c) => c.id === conversationId); return conversation?.messages || []; } ``` ### 4. 用户信息展示 在侧边栏展示用户头像、姓名和账户余额。 ```vue {{ userInfo.accountBalance.name || "用户" }} 总额: ¥{{ formatBalance(userInfo.accountBalance.total_balance) }} ``` ### 5. 键盘快捷键 实现了便捷的键盘操作: - **Enter**: 发送消息 - **Shift + Enter**: 换行 - **Ctrl + Enter / Cmd + Enter**: 发送消息 ```typescript // 处理回车键 const handleEnterKey = (event: Event) => { const keyboardEvent = event as KeyboardEvent; // 如果按了 Shift+Enter,允许换行(默认行为) if (keyboardEvent.shiftKey) { return; } // 如果按了 Ctrl+Enter 或 Cmd+Enter,发送消息 if (keyboardEvent.ctrlKey || keyboardEvent.metaKey) { handleSend(); return; } // 单独按 Enter,发送消息并阻止默认换行 keyboardEvent.preventDefault(); handleSend(); }; ``` ## 🎨 UI 设计亮点 ### 1. 左侧可折叠侧边栏 - 支持折叠/展开,节省空间 - 显示用户信息和对话历史 - 流畅的动画过渡 ### 2. 消息气泡设计 - 用户消息:右侧显示,渐变紫色背景 - AI 消息:左侧显示,白色背景 - 加载状态:在消息气泡内显示"正在思考..." ### 3. 响应式布局 - 适配不同屏幕尺寸 - 优雅的滚动条样式 - 流畅的交互体验 ## 📸 效果展示 ### 图片位置 1:整体界面效果 **请在此处插入整体界面截图** - 展示左侧侧边栏、主对话区域、输入框的完整布局 ### 图片位置 2:流式回答效果 **请在此处插入流式回答动图或截图** - 展示 AI 回答逐字显示的效果 ### 图片位置 3:思考模式切换 **请在此处插入思考模式开关截图** - 展示顶部工具栏的思考模式开关 ### 图片位置 4:对话历史管理 **请在此处插入对话历史列表截图** - 展示左侧侧边栏的对话历史列表 ### 图片位置 5:用户信息卡片 **请在此处插入用户信息卡片截图** - 展示用户头像、姓名、余额信息 ## 📦 环境要求与安装 ### 环境要求 - **Node.js**: >= 16.0.0 - **npm**: >= 7.0.0 或 **pnpm**: >= 7.0.0 - **TypeScript**: >= 5.0.0 ### 完整依赖包列表 **核心依赖包**: - `@element-plus/icons-vue`: ^2.3.2 - Element Plus 图标库 - `axios`: ^1.13.2 - HTTP 请求库 - `element-plus`: ^2.11.9 - UI 组件库 - `openai`: ^6.10.0 - OpenAI SDK(兼容 DeepSeek API) - `vue`: ^3.5.13 - Vue 3 框架 - `less`: ^4.3.0 - Less 预处理器 - `less-loader`: ^12.3.0 - Less 加载器 **开发依赖包**: - `@vitejs/plugin-vue`: ^5.2.3 - Vite Vue 插件 - `@vue/tsconfig`: ^0.7.0 - Vue TypeScript 配置 - `typescript`: ~5.8.3 - TypeScript 编译器 - `vite`: ^6.3.5 - 构建工具 - `vue-tsc`: ^2.2.8 - Vue TypeScript 类型检查 ### 安装步骤 #### 方式一:使用 npm ```bash # 1. 创建项目(如果还没有) npm create vite@latest my-deepseek-chat -- --template vue-ts # 2. 进入项目目录 cd my-deepseek-chat # 3. 安装所有依赖 npm install # 4. 安装核心依赖包 npm install openai axios element-plus @element-plus/icons-vue less less-loader # 5. 安装开发依赖(如果还没有) npm install -D @vitejs/plugin-vue typescript vue-tsc vite ``` #### 方式二:使用 pnpm(推荐) ```bash # 1. 创建项目 pnpm create vite my-deepseek-chat --template vue-ts # 2. 进入项目目录 cd my-deepseek-chat # 3. 安装所有依赖 pnpm install # 4. 安装核心依赖包 pnpm add openai axios element-plus @element-plus/icons-vue less less-loader # 5. 安装开发依赖 pnpm add -D @vitejs/plugin-vue typescript vue-tsc vite ``` #### 方式三:使用 yarn ```bash # 1. 创建项目 yarn create vite my-deepseek-chat --template vue-ts # 2. 进入项目目录 cd my-deepseek-chat # 3. 安装所有依赖 yarn install # 4. 安装核心依赖包 yarn add openai axios element-plus @element-plus/icons-vue less less-loader # 5. 安装开发依赖 yarn add -D @vitejs/plugin-vue typescript vue-tsc vite ``` ### 完整 package.json 配置示例 ```json { "name": "deepseek-chat", "version": "1.0.0", "type": "module", "scripts": { "dev": "vite --open", "build": "vue-tsc -b && vite build", "preview": "vite preview" }, "dependencies": { "@element-plus/icons-vue": "^2.3.2", "axios": "^1.13.2", "element-plus": "^2.11.9", "openai": "^6.10.0", "vue": "^3.5.13", "less": "^4.3.0", "less-loader": "^12.3.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.2.3", "@vue/tsconfig": "^0.7.0", "typescript": "~5.8.3", "vite": "^6.3.5", "vue-tsc": "^2.2.8" } } ``` > **提示**:可以直接复制上面的配置到你的 `package.json` 文件中,然后运行 `npm install` 或 `pnpm install` 安装所有依赖。 ### 启动项目 安装完成后,运行以下命令启动开发服务器: ```bash # npm npm run dev # pnpm pnpm dev # yarn yarn dev ``` 项目将在 `http://localhost:5173` 启动(端口可能不同,请查看终端输出)。 ## 🔧 配置说明 ### DeepSeek API 配置 在 `src/views/index/index.ts` 文件中配置你的 DeepSeek API Key: ```typescript const openaiProps: openaiProps = { baseURL: "https://api.deepseek.com", apiKey: "***", // 替换为你的 API Key dangerouslyAllowBrowser: true, // 允许在浏览器中使用 stream: true, }; ``` **⚠️ 安全提示**:在生产环境中,建议将 API Key 放在后端,通过代理调用 API,避免在前端暴露密钥。 ### Element Plus 全局配置 在 `src/main.ts` 中引入 Element Plus: ```typescript import { createApp } from 'vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import * as ElementPlusIconsVue from '@element-plus/icons-vue' import App from './App.vue' const app = createApp(App) // 注册 Element Plus app.use(ElementPlus) // 注册所有图标 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } app.mount('#app') ``` ### Vite 配置(vite.config.ts) 确保配置了 Vue 插件和 Less 支持: ```typescript import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], css: { preprocessorOptions: { less: { javascriptEnabled: true, }, }, }, }) ``` ## 🐛 常见问题 ### 1. 流式回答重复显示 **问题**:流式回答时内容重复显示 **解决**:确保在回调函数中直接赋值,不要累加: ```typescript onStreamChunk: (chunk) => { // ✅ 正确:直接赋值 messages.value[index].content = chunk; // ❌ 错误:不要累加 // messages.value[index].content += chunk; } ``` ### 2. 余额不足错误 **问题**:API 返回 402 错误 **解决**:检查账户余额,前往 DeepSeek 官网充值。 ### 3. API 密钥无效 **问题**:API 返回 401 错误 **解决**:检查 API Key 是否正确,确保有访问权限。 ## 📝 核心代码文件 ### index.ts - API 调用和对话管理 主要功能: - DeepSeek API 配置 - 流式对话实现 - 对话历史管理 - 错误处理 - 账户余额查询 - 模型列表获取 ### index.vue - UI 组件 主要功能: - 界面布局 - 消息展示 - 用户交互 - 状态管理 ### index.scss - 样式文件 主要功能: - 响应式布局 - 动画效果 - 主题样式 ## 🎯 功能特性总结 | 功能 | 状态 | 说明 | |------|------|------| | 流式回答 | ✅ | 逐字显示 AI 回答 | | 思考模式 | ✅ | 可切换思考模式 | | 对话历史 | ✅ | 多对话管理 | | 用户信息 | ✅ | 头像、姓名、余额 | | 模型切换 | ✅ | 支持切换不同模型 | | 键盘快捷键 | ✅ | Enter 发送,Shift+Enter 换行 | | 错误处理 | ✅ | 完善的错误提示 | | 响应式设计 | ✅ | 适配不同屏幕 | ## 🚀 未来优化方向 1. **后端代理**:将 API 调用移到后端,提高安全性 2. **消息持久化**:使用 IndexedDB 或后端存储对话历史 3. **Markdown 渲染**:支持 Markdown 格式的消息显示 4. **代码高亮**:代码块语法高亮 5. **文件上传**:支持图片、文件上传 6. **语音输入**:集成语音识别功能 ## 📚 参考资源 - [DeepSeek API 文档](https://platform.deepseek.com/api-docs/) - [OpenAI SDK 文档](https://github.com/openai/openai-node) - [Vue 3 官方文档](https://cn.vuejs.org/) - [Element Plus 文档](https://element-plus.org/zh-CN/) ## 💡 总结 本文详细介绍了一个基于 Vue3 + TypeScript + Element Plus 的 DeepSeek AI 对话界面实现。核心功能包括流式回答、思考模式、对话历史管理等。通过合理的架构设计和代码组织,实现了一个功能完善、用户体验良好的对话界面。 **关键实现点**: 1. 使用 OpenAI SDK 的流式 API 实现逐字显示 2. 通过回调函数实时更新 UI 3. 完善的错误处理和用户提示 4. 优雅的 UI 设计和交互体验 希望本文对正在开发类似功能的开发者有所帮助!如有问题,欢迎在评论区交流讨论。 --- **作者**: [li-lei] **日期**: 2025年1月 **标签**: #Vue3 #TypeScript #DeepSeek #AI对话 #流式输出 #Element Plus