M0-M4: 推倒重来基线(基建+用户/密钥/核心代理+前端+管理后台+三协议互转)
- 后端 Go+Gin+GORM: 配置(OT_ env)/SQLite/Postgres 双驱动、用户体系(argon2id+JWT access/refresh)、 API Key(sk- 48位, 仅存 SHA-256 哈希) - 代理网关: /v1/chat/completions、/v1/responses、/v1/messages、/v1/models;错误按客户端协议返回 - 三协议互转(convert 包): Chat↔Messages↔Responses 请求/响应 + 流式 SSE 逐事件转换(直通优先) - 用量计费: 异步批量记账、余额扣减、balance_logs、usage_daily 日聚合 - 管理 API: 用户/渠道 CRUD+测试+模型导入/模型定价+绑定/统计/系统配置 - 前端 Vue3+TS+Tailwind(taste-skill 设计 tokens): Landing/登录注册/控制台/管理后台, 自建组件+Phosphor 图标+自建 SVG 趋势图, 已过 web-design-guidelines 复查 - mock 上游: OpenAI+Anthropic 双协议模拟(含流式) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,24 +2,32 @@
|
||||
|
||||
自托管的 LLM API 中转网关,功能对标 OpenRouter / one-api:统一 OpenAI 与 Anthropic 协议入口,背后对接多个上游渠道,内置用户体系、API Key 管理与用量计费。
|
||||
|
||||
> 规划文档见 [PLANNING.md](./PLANNING.md)。当前进度:**M0(基建)+ M1(用户+密钥+核心代理)已完成**。
|
||||
> 规划文档见 [PLANNING.md](./PLANNING.md)。当前进度:**M0-M2 + M4 已完成**(基建 + 用户/密钥/核心代理 + 前端 MVP + 管理后台基础 + 三协议互转)。
|
||||
|
||||
## 功能(当前)
|
||||
|
||||
- **代理端点**(Bearer API Key)
|
||||
- `POST /v1/chat/completions` — OpenAI Chat(非流式 + 流式 SSE)
|
||||
- `POST /v1/responses` — OpenAI Responses API(非流式 + 流式事件)
|
||||
- `POST /v1/messages` — Anthropic Messages API(非流式 + 流式事件)
|
||||
- `GET /v1/models` — 可用模型列表
|
||||
- 错误统一为 OpenAI 格式(401/402/404/429/502…)
|
||||
- **用户体系**:注册(开放/邀请码可切换)、登录(JWT access + HttpOnly refresh cookie)、argon2id 密码
|
||||
- **三协议互转**:客户端协议 × 渠道协议不匹配时自动转换(如 Chat 调用 Claude、Messages 调用 OpenAI、Responses 调用 Claude),流式逐事件转换;协议匹配时直通
|
||||
- 错误按客户端协议返回(OpenAI 格式 / Anthropic 格式)
|
||||
- **用户体系**:注册(开放/邀请码可切换,管理后台可改)、登录(JWT access + HttpOnly refresh cookie)、argon2id 密码
|
||||
- **API Key**:`sk-` 48 位 base62,仅存 SHA-256 哈希,明文一次性展示;支持限额/过期/白名单字段
|
||||
- **用量计费**:请求级 `usage_logs` 异步批量落库,按模型价格扣减余额,日粒度预聚合(`usage_daily`)
|
||||
- **管理 API**:用户列表/角色/状态/余额调整、系统配置
|
||||
- **前端**:Landing / 登录注册 / 控制台(仪表盘 + 密钥管理 + 用量明细)
|
||||
- **管理 API**:渠道 CRUD + 连通测试 + 模型导入、模型管理 + 定价 + 渠道绑定、用户管理、全局用量/统计、系统配置
|
||||
- **前端**(Vue3 + Tailwind,taste-skill 设计,深色优先)
|
||||
- Landing / 登录 / 注册
|
||||
- 控制台:Dashboard(余额/用量/趋势图)、API Keys、用量明细
|
||||
- 管理后台:运营总览、渠道管理、模型与定价、用户管理、系统配置
|
||||
- **后端**:Go + Gin + GORM,SQLite(开发)/ PostgreSQL(生产)
|
||||
|
||||
> 渠道健康检查/负载均衡/重试在 M5(见 PLANNING.md §10)。
|
||||
|
||||
## 快速开始(开发)
|
||||
|
||||
前置:Go 1.23+、Node 20+、pnpm。
|
||||
前置:Go 1.23+。
|
||||
|
||||
```bash
|
||||
# 1. 配置(复制并修改,至少设置上游 key)
|
||||
@@ -29,13 +37,12 @@ cp .env.example .env
|
||||
cd server && go run ./cmd/server
|
||||
# 默认管理员 admin / admin123(生产务必修改)
|
||||
|
||||
# 3. 启动前端
|
||||
cd web && pnpm i && pnpm dev # http://localhost:5173
|
||||
|
||||
# 4. 用 mock 上游联调(无需真实 key)
|
||||
# 3. 用 mock 上游联调(无需真实 key,另开终端)
|
||||
make mock-upstream # :9000 起一个模拟 OpenAI 服务
|
||||
```
|
||||
|
||||
`.env` 中 `OT_PROXY_UPSTREAM_KEY` / `OT_PROXY_UPSTREAM_BASE_URL` 指向 mock 上游时,服务首次启动会自动创建默认渠道与示例模型。
|
||||
|
||||
### 冒烟测试(curl)
|
||||
|
||||
```bash
|
||||
@@ -49,42 +56,48 @@ KEY=$(curl -s -X POST localhost:8080/api/v1/keys -H "Authorization: Bearer $TOKE
|
||||
|
||||
# 对话(非流式 + 流式)
|
||||
curl -s localhost:8080/v1/chat/completions -H "Authorization: Bearer $KEY" \
|
||||
-H 'Content-Type: application/json' -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}'
|
||||
curl -sN localhost:8080/v1/chat/completions -H "Authorization: Bearer $KEY" \
|
||||
-H 'Content-Type: application/json' -d '{"model":"gpt-4o-mini","stream":true,"messages":[{"role":"user","content":"hi"}]}'
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"你好"}],"stream":false}'
|
||||
curl -N localhost:8080/v1/chat/completions -H "Authorization: Bearer $KEY" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"你好"}],"stream":true}'
|
||||
|
||||
# 用量
|
||||
curl -s localhost:8080/api/v1/usage/summary -H "Authorization: Bearer $TOKEN"
|
||||
curl -s "localhost:8080/api/v1/usage/logs?page_size=5" -H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
## 生产部署
|
||||
### 前端(开发)
|
||||
|
||||
```bash
|
||||
cp .env.example .env # 填写 JWT_SECRET / MASTER_KEY / 上游 key
|
||||
docker compose -f deploy/docker-compose.yml up -d --build
|
||||
cd web && pnpm i && pnpm dev # http://localhost:5173(/api、/v1 代理到 8080)
|
||||
```
|
||||
|
||||
`nginx` 托管前端静态资源并反代 `/api` 与 `/v1`(SSE 关闭缓冲)。
|
||||
### 测试
|
||||
|
||||
```bash
|
||||
cd server && go test ./...
|
||||
cd web && pnpm build # vue-tsc 类型检查 + 构建
|
||||
```
|
||||
|
||||
## 仓库结构
|
||||
|
||||
```
|
||||
server/ Go 后端(cmd + internal/{api,proxy,channel,usage,store,pkg})
|
||||
web/ Vue 3 前端(Vite + Tailwind v4 + Pinia + ECharts)
|
||||
deploy/ docker-compose / Dockerfile / nginx
|
||||
scripts/ mock 上游(联调用)
|
||||
docs/ 文档
|
||||
server/ # Go 后端
|
||||
cmd/server/ # 入口
|
||||
internal/
|
||||
config/ # viper + env(OT_ 前缀)
|
||||
store/ # GORM models + 连接
|
||||
pkg/ # apikey / crypto / jwt / resp
|
||||
api/ # 管理 API(认证、用户、密钥、用量、渠道/模型/管理后台)
|
||||
proxy/ # 代理网关(鉴权、直通、流式、记账)
|
||||
channel/ # 渠道选择与密钥解密
|
||||
usage/ # 异步记账
|
||||
web/ # Vue3 前端(Tailwind,taste-skill 设计 tokens)
|
||||
src/
|
||||
views/ # Landing / 登录注册 / console / admin
|
||||
components/ # ui(Button/Input/Modal/Badge/Toast/TrendChart)+ layout
|
||||
stores/ · api/ · router/ · lib/
|
||||
scripts/mockupstream/ # mock 上游(联调)
|
||||
deploy/ # Docker 部署(后续里程碑)
|
||||
```
|
||||
|
||||
## 设计系统(taste-skill)
|
||||
|
||||
深色优先的开发者控制台:石墨墨底 + 暖白文本 + 单一信号铜色强调(信号灯意象);UI 字体 Outfit,数据一律 JetBrains Mono(tabular numerals)。tokens 定义于 `web/src/style.css`(`@theme`),支持 `data-theme="light"` 切换。
|
||||
|
||||
## 路线图
|
||||
|
||||
| 里程碑 | 状态 |
|
||||
| --- | --- |
|
||||
| M0 基建(结构/配置/DB/工具/CI 前身) | ✅ |
|
||||
| M1 用户 + 密钥 + 核心代理(chat/responses 直通) | ✅ |
|
||||
| M2 用量 + 计费(记账/价格/前端图表) | 🟡 后端已备,前端图表就绪 |
|
||||
| M3 跨协议转换(/v1/messages、Responses↔Chat↔Messages) | ⏳ |
|
||||
| M4 渠道系统(导入/绑定/LB/健康检查/重试) | ⏳ |
|
||||
| M5 充值(暂停,表结构已预留) | ⏸ |
|
||||
| M6 打磨上线(限流/监控/审计/全站复查) | ⏳ |
|
||||
|
||||
Reference in New Issue
Block a user