diff --git a/API.md b/API.md deleted file mode 100644 index f64706c..0000000 --- a/API.md +++ /dev/null @@ -1,7 +0,0 @@ -| 平台 | 端点(Endpoint) | 参考文档 | -|------------|-----------------------------------|-------------------------| -| OpenAI | `https://api.openai.com/v1/chat/completions` | https://openai.apifox.cn/ | -| 通义千问 | `https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions` |https://www.alibabacloud.com/help/zh/model-studio/use-qwen-by-calling-api#a25484c79d1ca| -| 智谱 | `https://open.bigmodel.cn/api/paas/v4/chat/completions` | https://docs.bigmodel.cn/api-reference/%E6%A8%A1%E5%9E%8B-api/%E5%AF%B9%E8%AF%9D%E8%A1%A5%E5%85%A8 | -| DeepSeek | `https://api.deepseek.com/chat/completions` | https://api-docs.deepseek.com/zh-cn/api/create-chat-completion| -| 硅基流动 | `https://api.siliconflow.cn/v1/chat/completions` | https://docs.siliconflow.cn/cn/api-reference/chat-completions/chat-completions | \ No newline at end of file diff --git a/PRD.md b/PRD.md deleted file mode 100644 index 29978c3..0000000 --- a/PRD.md +++ /dev/null @@ -1,122 +0,0 @@ -## 产品需求文档 (PRD):AI API 配置与对话简易工具 - ---- - -### **1. 背景** -随着大模型应用普及,开发者需频繁切换不同厂商的API(如 OpenAI、通义千问、硅基流动)。现有方案操作繁琐(需手动修改代码/环境变量),缺乏统一配置入口。本工具旨在提供**轻量级 Web 界面**,支持快速配置主流厂商 API 并进行简单对话,提升开发效率。 - ---- - -### **2. 目标** -- ✅ **核心目标**:用户通过 1 个页面完成所有厂商 API 配置与对话测试 -- ✅ **关键指标**: - - 配置操作简易(选厂商 → 输入密钥/接入点 → 保存) - - 支持主流厂商 - ---- - -### **3. 项目范围** -| **范围** | **包含** | **不包含** | -|-------------------|---------------------------------------------|------------------------------------| -| **功能** | - 厂商配置管理(密钥/接入点)
- 多厂商对话界面
- 安全存储密钥 | - 用户认证/权限管理
- 聊天历史记录
- 复杂对话逻辑(如 multi-turn) | -| **支持厂商** | OpenAI, Anthropic, Google (Gemini), 阿里云(通义千问), 百度(文心一言) | 本地模型(如 Llama)、定制化厂商 API | -| **安全** | 密钥加密存储、禁止明文展示 | 无 Key 管理后台(纯客户端安全) | -| **平台** | 现代浏览器(Chrome/Firefox/Safari) | 移动端适配、桌面应用 | - -> ✨ **附录:厂商支持列表** -> | 厂商 | 接入点示例 | 密钥类型 | -> |--------------|-------------------------------------|-------------| -> | OpenAI | `https://api.openai.com/v1/chat/completions` | `sk-...` | -> | Anthropic | `https://api.anthropic.com/v1/messages` | `sk-...` | -> | Google | `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent` | `AIza...` | -> | 阿里云通义 | `https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation` | `sk-...` | -> | 百度文心 | `https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie\_bot` | `your_api_key` | - ---- - -### **4. 功能需求** -#### **4.1 厂商配置管理(核心功能)** -| 功能 | 说明 | 用户操作流 | -|---------------------|----------------------------------------------------------------------|-------------------------------------| -| **厂商下拉选择** | - 预置 5 个厂商(见附录表格),下拉菜单中**自动隐藏**未启用的厂商 | 1. 点击下拉框 → 2. 选中目标厂商 | -| **密钥/接入点输入** | - 动态显示对应字段(OpenAI 需输入 `密钥`+`接入点`,通义需输入 `API Key`) | 1. 填写密钥(如 `sk-abc123`)
2. 填写接入点(默认预填) | -| **保存与验证** | - 保存时**自动校验密钥格式**(如 OpenAI 密钥以 `sk-` 开头)
- **不存储明文**,使用 AES-256 加密后存入浏览器 `localStorage` | 1. 点击「保存配置」→ 2. 成功提示
→ 3. 即时生效(无需刷新) | - -> ⚠️ **安全设计**: -> - 密钥在客户端加密存储,**服务端不接触密钥** -> - 配置页面关闭后,密钥不可恢复(用户需重新配置) - -#### **4.2 AI 对话界面(核心功能)** -| 功能 | 说明 | -|---------------------|----------------------------------------------------------------------| -| **对话输入框** | 单行文本输入,支持中文/英文提问(示例:`“解释量子计算”`) | -| **厂商选择器** | **对话前必选**:从已配置的厂商列表中选(默认显示按配置顺序排序) | -| **发送与响应** | - 点击「发送」按钮 → 显示加载状态 → 厂商 API 返回结果显示在底部 | -| **错误处理** | - 密钥错误 → 提示 `“厂商 [X] 密钥无效”`
- 服务端错误 → 提示 `“[厂商] API 调用失败 (错误码: 500)”` | - -> 🌰 **示例流程**: -> 1. 用户在配置页为 OpenAI 保存密钥 `sk-test123` -> 2. 进入对话页 → 选 OpenAI → 输入 `“写首关于AI的诗”` → 点击发送 -> 3. 即时显示 OpenAI 返回的诗句 - ---- - -### **5. 非功能需求** -| 类别 | 要求 | -|---------------|---------------------------------------| -| **性能** | 配置保存响应时间 ≤ 500ms;对话响应 ≤ 3s(依赖厂商) | -| **可用性** | 0 学习成本:所有操作 ≤ 3 步,无复杂菜单 | -| **可扩展性** | 新增厂商仅需修改前端配置表(无需改代码) | -| **安全** | 100% 避免明文密钥存储,废弃旧配置自动清除 | -| **兼容性** | 支持 Chrome/Firefox/Safari 最新版,不兼容 IE | - ---- - -### **6. 应用流程图** -```mermaid -graph TD - A[访问主页] --> B[配置厂商] - B --> C{是否选择新厂商} - C -- 是 --> D[填写厂商/密钥/接入点] - D --> E[保存加密] - E --> B - C -- 否 --> F[对话界面] - F --> G[选厂商 + 输入提问] - G --> H[调用厂商 API] - H --> I{成功} - I -- 是 --> J[显示结果] - I -- 否 --> K[显示错误提示] -``` - ---- - -### **7. 紧急问题处理** -| 问题场景 | 解决方案 | -|--------------------------|------------------------------------------| -| 用户误填错误密钥 | 配置页右侧显示“密钥验证失败”提醒 | -| 厂商 API 调用超时 | 支持重试(1 次),超时后提示“服务不可用” | -| 首次使用无任何厂商配置 | 顶部显示提示“请先配置厂商:OpenAI/通义千问” | - ---- - -### **8. 附录:厂商配置预设** -```javascript -// 前端配置表(示例,可增加新厂商) -const PLATFORMS = [ - { - id: 'openai', - name: 'OpenAI', - endpoint: 'https://api.openai.com/v1/chat/completions', - keyPlaceholder: 'sk-...', - keyType: 'api_key' - }, - { - id: 'qwen', - name: '通义千问(阿里云)', - endpoint: 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation', - keyPlaceholder: 'sk-...', - keyType: 'api_key' - }, - // 其他厂商... -]; -``` \ No newline at end of file diff --git a/README.md b/README.md index 49e909c..64b4f40 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,12 @@ 🔩 各大 LLM 厂商的 API 服务聚合 -## 任务清单 +| 平台 | 端点(Endpoint) | 参考文档 | +|------------|-----------------------------------|-------------------------| +| OpenAI | `https://api.openai.com/v1/chat/completions` | https://openai.apifox.cn/ | +| 通义千问 | `https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions` |https://www.alibabacloud.com/help/zh/model-studio/use-qwen-by-calling-api#a25484c79d1ca| +| 智谱 | `https://open.bigmodel.cn/api/paas/v4/chat/completions` | https://docs.bigmodel.cn/api-reference/%E6%A8%A1%E5%9E%8B-api/%E5%AF%B9%E8%AF%9D%E8%A1%A5%E5%85%A8 | +| DeepSeek | `https://api.deepseek.com/chat/completions` | https://api-docs.deepseek.com/zh-cn/api/create-chat-completion| +| 硅基流动 | `https://api.siliconflow.cn/v1/chat/completions` | https://docs.siliconflow.cn/cn/api-reference/chat-completions/chat-completions | -| 任务编号 | 任务名称 | 优先级 | 说明 | 负责人 | 交付成果 | -|----------|---------------------------------------|--------|----------------------------------------------------------------------|----------|--------------------------------| -| T1 | 明确需求并撰写 PRD 文档 | 高 | 完成产品需求文档,明确功能及非功能需求 | 产品 | 🟢 PRD 文档(含厂商列表、功能说明等) | -| T2 | 确定支持厂商并获取 API 信息 | 高 | 确认 5 个主流 AI API 厂商的端点、密钥类型和请求格式 | 产品 | 🟢 完整厂商支持列表(含 API 示例) | -| T3 | 搭建 Web 应用的基础架构(前端 VUE + 后端 SpringWEB) | 中 | 创建 Web 首页和配置页、对话页,切换页面(可使用单页应用) | 开发 | 🟢 项目框架 | -| T4 | 实现厂商下拉选择功能 | 高 | 列出厂商选项,用户可选当前要配置的厂商 | 开发 | 🟢 下拉菜单 | -| T5 | 实现 API 配置输入界面 | 高 | 根据所选厂商显示对应输入项(如密钥 + 接入点) | 开发 | 🟢 动态表单(密钥/接入点输入) | -| T6 | 实现密钥输入验证 | 高 | 检查输入格式是否符合厂商要求(如 OpenAI 密钥以 `sk-` 开头) | 开发 | 🟢 格式校验 + 错误提示 | -| T7 | 实现配置保存与加密存储 | 高 | 加密存储用户输入的密钥和接入点,使用 localStorage 或 indexedDB | 开发 | 🟢 安全存储实现(AES 加密) | -| T8 | 创建厂商配置数据结构 | 中 | 在前端代码中定义厂商配置信息(如 ID、名称、端点、字段等) | 开发 | 🟢 `PLATFORMS` 配置数组(如 JS 对象结构) | -| T9 | 实现对话页界面 | 中 | 输入框 + 厂商选择器 + 发送按钮 + 响应展示区 | 开发 | 🟢 对话页面设计 + 基本交互 | -| T10 | 实现对话 API 调用逻辑 | 高 | 根据用户选择的厂商,使用对应密钥调用 AI API 并返回结果 | 开发 | 🔵 厂商 API 通信逻辑(POST 请求) | -| T11 | 实现响应展示与错误处理 | 高 | 显示 API 返回内容,处理 401、500 等错误信息 | 开发 | 🔵 响应展示模块 + 错误页/提示 | -| T12 | 添加「重试」机制(可选) | 中 | 对于调用失败的情况提供一键重试功能 | 开发 | 🔵 调用失败后支持重试按钮 | -| T13 | 构建配置页与对话页的切换逻辑 | 中 | 用户可切换配置页和对话页,保证数据在页面间同步(如密钥已保存则自动填充) | 开发 | 🟢 页面切换功能 + 自动填充已有配置 | -| T14 | 添加「首次未配置提醒」 | 中 | 如果没有配置任何厂商,引导用户进行配置 | 开发 | 🟢 首页友好提示信息 | -| T15 | 添加厂商配置删除功能 | 中 | 允许用户删除已有配置,避免冗余数据 | 开发 | 🟢 删除配置按钮 + localStorage 清理 | -| T16 | 添加厂商默认配置(可选) | 中 | 预设 OpenAI、通义等厂商的默认接入点和字段提示 | 开发 | 🟢 配置页面默认值设置 | -| T17 | 构建完整 UI 界面(风格统一) | 中 | 确保配置页和对话页操作一致、视觉统一 | UI / 前端 | 🔵 响应式设计 + 现代化界面 | -| T18 | 进行基本可用性测试 | 中 | 验证主要功能是否可用(配置保存、API 调用、错误提示等) | QA | 🔵 功能测试报告(手动/自动) | -| T19 | 添加部署方案(如 GitHub Pages) | 低 | 配置前端静态部署,便于快速访问 | 产品 | 🔵 部署文档 + 示例部署链接 | -| T20 | 撰写项目说明文档和使用教程 | 低 | 提供给用户快速上手的说明,包含配置方法和常见问题 | 产品 | 🔵 README 或使用指南文档 | -| T21 | 优化体验(如加载提示、输入缓存) | 低 | 提升用户体验,如加载动画、输入自动保存(可选) | 开发 | 🔵 更流畅、更友好的 UI 交互 | -| T22 | 收集用户反馈并迭代设计 | 低 | 收集可用性数据、建议,优化方案(可选) | 产品 | 🔵 用户反馈记录 + 迭代计划 | \ No newline at end of file +![img.png](img.png) \ No newline at end of file diff --git a/backend/src/main/java/cn/hezhaohui/backend/config/RestTmplateConfig.java b/backend/src/main/java/cn/hezhaohui/backend/config/RestTmplateConfig.java new file mode 100644 index 0000000..74156d8 --- /dev/null +++ b/backend/src/main/java/cn/hezhaohui/backend/config/RestTmplateConfig.java @@ -0,0 +1,13 @@ +package cn.hezhaohui.backend.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTmplateConfig { + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +} diff --git a/backend/src/main/java/cn/hezhaohui/backend/controller/ChatController.java b/backend/src/main/java/cn/hezhaohui/backend/controller/ChatController.java index 0b8e34d..630836d 100644 --- a/backend/src/main/java/cn/hezhaohui/backend/controller/ChatController.java +++ b/backend/src/main/java/cn/hezhaohui/backend/controller/ChatController.java @@ -1,6 +1,7 @@ package cn.hezhaohui.backend.controller; import cn.hezhaohui.backend.entity.ChatRequest; +import cn.hezhaohui.backend.entity.ChatResponse; import cn.hezhaohui.backend.service.ChatService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -14,7 +15,7 @@ public class ChatController { private ChatService chatService; @PostMapping("/api/chat") - public String chat(@RequestBody ChatRequest request) { + public ChatResponse chat(@RequestBody ChatRequest request) { return chatService.chat(request); } } diff --git a/backend/src/main/java/cn/hezhaohui/backend/entity/ChatResponse.java b/backend/src/main/java/cn/hezhaohui/backend/entity/ChatResponse.java new file mode 100644 index 0000000..c3298a7 --- /dev/null +++ b/backend/src/main/java/cn/hezhaohui/backend/entity/ChatResponse.java @@ -0,0 +1,10 @@ +package cn.hezhaohui.backend.entity; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ChatResponse { + private String response; +} diff --git a/backend/src/main/java/cn/hezhaohui/backend/service/ChatService.java b/backend/src/main/java/cn/hezhaohui/backend/service/ChatService.java index eaa7450..d880a52 100644 --- a/backend/src/main/java/cn/hezhaohui/backend/service/ChatService.java +++ b/backend/src/main/java/cn/hezhaohui/backend/service/ChatService.java @@ -1,13 +1,33 @@ package cn.hezhaohui.backend.service; import cn.hezhaohui.backend.entity.ChatRequest; +import cn.hezhaohui.backend.entity.ChatResponse; +import jakarta.annotation.Resource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; @Service public class ChatService { - public String chat(ChatRequest request) { - System.out.println(request); - return " "; + @Resource + private RestTemplate restTemplate; + + + + public ChatResponse chat(ChatRequest req) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Bearer " + req.getApiKey()); + headers.set("Content-Type", "application/json"); + String requestBody = String.format( + "{\"model\": \"Qwen/Qwen3-30B-A3B\", \"messages\": [{\"role\": \"user\", \"content\": \"%s\"}]}", + req.getMessage() + ); + HttpEntity stringHttpEntity = new HttpEntity<>(requestBody, headers); + ResponseEntity response = restTemplate.postForEntity(req.getEndpoint(), stringHttpEntity, String.class); + System.out.println(response.getBody()); + return ChatResponse.builder().response(response.getBody()).build(); } } diff --git a/img.png b/img.png new file mode 100644 index 0000000..524d3b4 Binary files /dev/null and b/img.png differ