first commit: one-api base code + SAAS plan document
This commit is contained in:
53
docs/API.md
Normal file
53
docs/API.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 使用 API 操控 & 扩展 One API
|
||||
> 欢迎提交 PR 在此放上你的拓展项目。
|
||||
|
||||
例如,虽然 One API 本身没有直接支持支付,但是你可以通过系统扩展的 API 来实现支付功能。
|
||||
|
||||
又或者你想自定义渠道管理策略,也可以通过 API 来实现渠道的禁用与启用。
|
||||
|
||||
## 鉴权
|
||||
One API 支持两种鉴权方式:Cookie 和 Token,对于 Token,参照下图获取:
|
||||
|
||||

|
||||
|
||||
之后,将 Token 作为请求头的 Authorization 字段的值即可,例如下面使用 Token 调用测试渠道的 API:
|
||||

|
||||
|
||||
## 请求格式与响应格式
|
||||
One API 使用 JSON 格式进行请求和响应。
|
||||
|
||||
对于响应体,一般格式如下:
|
||||
```json
|
||||
{
|
||||
"message": "请求信息",
|
||||
"success": true,
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
|
||||
## API 列表
|
||||
> 当前 API 列表不全,请自行通过浏览器抓取前端请求
|
||||
|
||||
如果现有的 API 没有办法满足你的需求,欢迎提交 issue 讨论。
|
||||
|
||||
### 获取当前登录用户信息
|
||||
**GET** `/api/user/self`
|
||||
|
||||
### 为给定用户充值额度
|
||||
**POST** `/api/topup`
|
||||
```json
|
||||
{
|
||||
"user_id": 1,
|
||||
"quota": 100000,
|
||||
"remark": "充值 100000 额度"
|
||||
}
|
||||
```
|
||||
|
||||
## 其他
|
||||
### 充值链接上的附加参数
|
||||
One API 会在用户点击充值按钮的时候,将用户的信息和充值信息附加在链接上,例如:
|
||||
`https://example.com?username=root&user_id=1&transaction_id=4b3eed80-55d5-443f-bd44-fb18c648c837`
|
||||
|
||||
你可以通过解析链接上的参数来获取用户信息和充值信息,然后调用 API 来为用户充值。
|
||||
|
||||
注意,不是所有主题都支持该功能,欢迎 PR 补齐。
|
||||
539
docs/SAAS-PLAN.md
Normal file
539
docs/SAAS-PLAN.md
Normal file
@@ -0,0 +1,539 @@
|
||||
# One-API 多租户 SaaS 系统二开方案
|
||||
|
||||
## 📋 项目概述
|
||||
|
||||
### 目标
|
||||
在 one-api 基础上进行二次开发,构建多租户 SaaS 系统,支持:
|
||||
- 主系统统一管理上游 API 渠道
|
||||
- 多个代理站点独立部署(独立数据库)
|
||||
- 月套餐令牌系统(日限/周限/月限额度控制)
|
||||
- 主系统统一计费扣费
|
||||
|
||||
### 核心原则
|
||||
1. **保持可升级性**:插件化开发,最小化核心代码改动
|
||||
2. **完全独立部署**:每个代理站点独立运行,互不影响
|
||||
3. **统一计费管理**:主系统集中管理渠道和计费
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 系统架构设计
|
||||
|
||||
### 整体架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 主系统 (Master) │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ 上游渠道池 │ │ 计费中心 │ │ 代理管理 │ │
|
||||
│ │ OpenAI/Claude│ │ 统计报表 │ │ 额度分配 │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ ▲ ▲ ▲ │
|
||||
└─────────┼──────────────────┼──────────────────┼──────────────┘
|
||||
│ │ │
|
||||
│ 渠道请求 │ 计费回传 │ 配置同步
|
||||
│ │ │
|
||||
┌─────┴──────────────────┴──────────────────┴─────┐
|
||||
│ │
|
||||
┌───▼────────┐ ┌─────────────┐ ┌─────────▼────┐
|
||||
│代理站点 A │ │ 代理站点 B │ │ 代理站点 C │
|
||||
│独立数据库 │ │ 独立数据库 │ │ 独立数据库 │
|
||||
│独立域名 │ │ 独立域名 │ │ 独立域名 │
|
||||
└────────────┘ └─────────────┘ └──────────────┘
|
||||
▲ ▲ ▲
|
||||
│ │ │
|
||||
终端用户 终端用户 终端用户
|
||||
```
|
||||
|
||||
### 核心交互流程
|
||||
|
||||
```
|
||||
1. 用户请求 → 代理站点
|
||||
2. 代理站点验证令牌(本地)
|
||||
3. 代理站点 → 主系统(请求渠道服务)
|
||||
4. 主系统验证额度 → 转发上游 API
|
||||
5. 主系统记录消耗 → 返回结果
|
||||
6. 代理站点 → 返回用户
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💾 数据库设计
|
||||
|
||||
### 主系统新增表
|
||||
|
||||
#### 1. agent_sites(代理站点表)
|
||||
```sql
|
||||
CREATE TABLE agent_sites (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(100) NOT NULL, -- 站点名称
|
||||
domain VARCHAR(255) UNIQUE, -- 站点域名
|
||||
api_key VARCHAR(64) UNIQUE NOT NULL, -- 站点 API 密钥(用于主从通信)
|
||||
status INT DEFAULT 1, -- 状态:1启用 2禁用
|
||||
total_quota BIGINT DEFAULT 0, -- 总分配额度
|
||||
used_quota BIGINT DEFAULT 0, -- 已使用额度
|
||||
created_time BIGINT,
|
||||
updated_time BIGINT,
|
||||
INDEX idx_api_key (api_key),
|
||||
INDEX idx_status (status)
|
||||
);
|
||||
```
|
||||
|
||||
#### 2. agent_billing_logs(代理计费日志)
|
||||
```sql
|
||||
CREATE TABLE agent_billing_logs (
|
||||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||||
agent_site_id INT NOT NULL, -- 代理站点ID
|
||||
user_id INT, -- 代理站点的用户ID
|
||||
token_name VARCHAR(100), -- 令牌名称
|
||||
model_name VARCHAR(100), -- 模型名称
|
||||
prompt_tokens INT, -- 输入token数
|
||||
completion_tokens INT, -- 输出token数
|
||||
quota INT, -- 消耗额度
|
||||
channel_id INT, -- 使用的渠道ID
|
||||
created_time BIGINT,
|
||||
INDEX idx_agent_site (agent_site_id),
|
||||
INDEX idx_created_time (created_time)
|
||||
);
|
||||
```
|
||||
|
||||
### 代理站点扩展字段
|
||||
|
||||
#### 扩展 tokens 表(月套餐令牌)
|
||||
```sql
|
||||
-- 在现有 tokens 表基础上新增字段
|
||||
ALTER TABLE tokens ADD COLUMN subscription_type VARCHAR(20); -- 套餐类型:daily/weekly/monthly
|
||||
ALTER TABLE tokens ADD COLUMN daily_quota_limit BIGINT DEFAULT 0; -- 日额度限制
|
||||
ALTER TABLE tokens ADD COLUMN weekly_quota_limit BIGINT DEFAULT 0; -- 周额度限制
|
||||
ALTER TABLE tokens ADD COLUMN monthly_quota_limit BIGINT DEFAULT 0; -- 月额度限制
|
||||
ALTER TABLE tokens ADD COLUMN daily_used_quota BIGINT DEFAULT 0; -- 日已用额度
|
||||
ALTER TABLE tokens ADD COLUMN weekly_used_quota BIGINT DEFAULT 0; -- 周已用额度
|
||||
ALTER TABLE tokens ADD COLUMN monthly_used_quota BIGINT DEFAULT 0; -- 月已用额度
|
||||
ALTER TABLE tokens ADD COLUMN last_reset_daily BIGINT DEFAULT 0; -- 上次日重置时间
|
||||
ALTER TABLE tokens ADD COLUMN last_reset_weekly BIGINT DEFAULT 0; -- 上次周重置时间
|
||||
ALTER TABLE tokens ADD COLUMN last_reset_monthly BIGINT DEFAULT 0; -- 上次月重置时间
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 核心功能实现
|
||||
|
||||
### 1. 月套餐令牌系统
|
||||
|
||||
#### 套餐定义
|
||||
```go
|
||||
// common/subscription/plans.go (新文件)
|
||||
package subscription
|
||||
|
||||
const (
|
||||
PlanBasic = "basic" // 100美金/月
|
||||
PlanStandard = "standard" // 200美金/月
|
||||
PlanPremium = "premium" // 500美金/月
|
||||
)
|
||||
|
||||
type SubscriptionPlan struct {
|
||||
Name string
|
||||
MonthlyQuota int64 // 月总额度(点数)
|
||||
DailyQuota int64 // 日额度限制
|
||||
WeeklyQuota int64 // 周额度限制
|
||||
}
|
||||
|
||||
var Plans = map[string]SubscriptionPlan{
|
||||
PlanBasic: {
|
||||
Name: "基础版",
|
||||
MonthlyQuota: 50000000, // 100美金 * 500,000
|
||||
DailyQuota: 2000000, // ~4美金/天
|
||||
WeeklyQuota: 15000000, // ~30美金/周
|
||||
},
|
||||
PlanStandard: {
|
||||
Name: "标准版",
|
||||
MonthlyQuota: 100000000, // 200美金 * 500,000
|
||||
DailyQuota: 5000000, // ~10美金/天
|
||||
WeeklyQuota: 35000000, // ~70美金/周
|
||||
},
|
||||
PlanPremium: {
|
||||
Name: "高级版",
|
||||
MonthlyQuota: 250000000, // 500美金 * 500,000
|
||||
DailyQuota: 15000000, // ~30美金/天
|
||||
WeeklyQuota: 90000000, // ~180美金/周
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
#### 额度检查逻辑
|
||||
```go
|
||||
// model/token.go 扩展
|
||||
func (token *Token) CheckSubscriptionQuota() error {
|
||||
now := time.Now().Unix()
|
||||
|
||||
// 1. 检查并重置日额度
|
||||
if shouldResetDaily(token.LastResetDaily, now) {
|
||||
token.DailyUsedQuota = 0
|
||||
token.LastResetDaily = getDayStart(now)
|
||||
}
|
||||
|
||||
// 2. 检查并重置周额度
|
||||
if shouldResetWeekly(token.LastResetWeekly, now) {
|
||||
token.WeeklyUsedQuota = 0
|
||||
token.LastResetWeekly = getWeekStart(now)
|
||||
}
|
||||
|
||||
// 3. 检查并重置月额度
|
||||
if shouldResetMonthly(token.LastResetMonthly, now) {
|
||||
token.MonthlyUsedQuota = 0
|
||||
token.LastResetMonthly = getMonthStart(now)
|
||||
}
|
||||
|
||||
// 4. 验证额度
|
||||
if token.DailyQuotaLimit > 0 && token.DailyUsedQuota >= token.DailyQuotaLimit {
|
||||
return errors.New("日额度已用尽")
|
||||
}
|
||||
if token.WeeklyQuotaLimit > 0 && token.WeeklyUsedQuota >= token.WeeklyQuotaLimit {
|
||||
return errors.New("周额度已用尽")
|
||||
}
|
||||
if token.MonthlyQuotaLimit > 0 && token.MonthlyUsedQuota >= token.MonthlyQuotaLimit {
|
||||
return errors.New("月额度已用尽")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
#### 消费扣费
|
||||
```go
|
||||
// model/token.go 扩展
|
||||
func (token *Token) ConsumeSubscriptionQuota(quota int64) error {
|
||||
token.DailyUsedQuota += quota
|
||||
token.WeeklyUsedQuota += quota
|
||||
token.MonthlyUsedQuota += quota
|
||||
token.UsedQuota += quota
|
||||
|
||||
return DB.Model(token).Updates(map[string]interface{}{
|
||||
"daily_used_quota": token.DailyUsedQuota,
|
||||
"weekly_used_quota": token.WeeklyUsedQuota,
|
||||
"monthly_used_quota": token.MonthlyUsedQuota,
|
||||
"used_quota": token.UsedQuota,
|
||||
}).Error
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 主从计费系统
|
||||
|
||||
#### 代理站点配置
|
||||
```go
|
||||
// common/config/agent.go (新文件)
|
||||
package config
|
||||
|
||||
var (
|
||||
IsAgentSite = os.Getenv("AGENT_MODE") == "true"
|
||||
MasterSystemURL = os.Getenv("MASTER_SYSTEM_URL") // 主系统地址
|
||||
AgentSiteAPIKey = os.Getenv("AGENT_SITE_API_KEY") // 站点密钥
|
||||
)
|
||||
```
|
||||
|
||||
#### 代理站点中继拦截
|
||||
```go
|
||||
// relay/proxy/master_proxy.go (新文件)
|
||||
package proxy
|
||||
|
||||
// 拦截所有中继请求,转发到主系统
|
||||
func RelayToMaster(c *gin.Context, meta *relay.RelayMeta) (*http.Response, error) {
|
||||
// 1. 构造请求到主系统
|
||||
masterURL := config.MasterSystemURL + "/api/agent/relay"
|
||||
|
||||
req, _ := http.NewRequest(c.Request.Method, masterURL, c.Request.Body)
|
||||
|
||||
// 2. 添加认证头
|
||||
req.Header.Set("X-Agent-Site-Key", config.AgentSiteAPIKey)
|
||||
req.Header.Set("X-Agent-User-Id", strconv.Itoa(meta.UserId))
|
||||
req.Header.Set("X-Agent-Token-Name", meta.TokenName)
|
||||
|
||||
// 3. 转发原始请求头
|
||||
for k, v := range c.Request.Header {
|
||||
req.Header[k] = v
|
||||
}
|
||||
|
||||
// 4. 发送请求
|
||||
client := &http.Client{Timeout: 5 * time.Minute}
|
||||
resp, err := client.Do(req)
|
||||
|
||||
return resp, err
|
||||
}
|
||||
```
|
||||
|
||||
#### 主系统代理中继接口
|
||||
```go
|
||||
// controller/agent_relay.go (新文件)
|
||||
package controller
|
||||
|
||||
func AgentRelay(c *gin.Context) {
|
||||
// 1. 验证代理站点身份
|
||||
agentKey := c.GetHeader("X-Agent-Site-Key")
|
||||
agentSite, err := model.GetAgentSiteByKey(agentKey)
|
||||
if err != nil {
|
||||
c.JSON(403, gin.H{"error": "invalid agent site"})
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 检查代理站点额度
|
||||
if agentSite.UsedQuota >= agentSite.TotalQuota {
|
||||
c.JSON(403, gin.H{"error": "agent quota exhausted"})
|
||||
return
|
||||
}
|
||||
|
||||
// 3. 选择渠道并转发请求
|
||||
modelName := c.GetString("model")
|
||||
channel, err := model.CacheGetRandomSatisfiedChannel("default", modelName, false)
|
||||
|
||||
// 4. 调用正常的 relay 流程
|
||||
relayRequest(c, channel, agentSite)
|
||||
}
|
||||
|
||||
func relayRequest(c *gin.Context, channel *model.Channel, agentSite *model.AgentSite) {
|
||||
// ... 使用现有的 relay 逻辑
|
||||
// 计费时记录到 agent_billing_logs 表
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 文件结构(插件化设计)
|
||||
|
||||
```
|
||||
one-api/
|
||||
├── common/
|
||||
│ ├── subscription/ # 新增:套餐管理
|
||||
│ │ ├── plans.go # 套餐定义
|
||||
│ │ └── quota.go # 额度计算
|
||||
│ └── config/
|
||||
│ └── agent.go # 新增:代理站点配置
|
||||
├── model/
|
||||
│ ├── agent_site.go # 新增:代理站点模型
|
||||
│ ├── agent_billing.go # 新增:代理计费日志
|
||||
│ └── token.go # 扩展:添加套餐相关方法
|
||||
├── controller/
|
||||
│ ├── agent_site.go # 新增:代理站点管理接口
|
||||
│ ├── agent_relay.go # 新增:代理中继接口
|
||||
│ └── subscription.go # 新增:套餐管理接口
|
||||
├── middleware/
|
||||
│ └── subscription_check.go # 新增:套餐额度检查中间件
|
||||
├── relay/
|
||||
│ └── proxy/
|
||||
│ └── master_proxy.go # 新增:主系统代理转发
|
||||
└── docs/
|
||||
└── SAAS-PLAN.md # 本文档
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 工作流程
|
||||
|
||||
### 代理站点请求流程
|
||||
|
||||
```
|
||||
1. 用户 → 代理站点 /v1/chat/completions
|
||||
↓
|
||||
2. 代理站点中间件验证 Token
|
||||
- 检查 Token 状态
|
||||
- 检查套餐额度(日/周/月)
|
||||
↓
|
||||
3. 通过 → 转发到主系统 /api/agent/relay
|
||||
Header: X-Agent-Site-Key, X-Agent-User-Id
|
||||
↓
|
||||
4. 主系统验证代理站点身份和额度
|
||||
↓
|
||||
5. 主系统选择渠道 → 调用上游 API
|
||||
↓
|
||||
6. 主系统计费
|
||||
- 扣除代理站点额度
|
||||
- 记录到 agent_billing_logs
|
||||
↓
|
||||
7. 返回结果 → 代理站点 → 用户
|
||||
↓
|
||||
8. 代理站点更新本地 Token 统计
|
||||
- 更新 daily/weekly/monthly_used_quota
|
||||
```
|
||||
|
||||
### 代理站点部署配置
|
||||
|
||||
**环境变量:**
|
||||
```bash
|
||||
# .env
|
||||
AGENT_MODE=true
|
||||
MASTER_SYSTEM_URL=https://master.example.com
|
||||
AGENT_SITE_API_KEY=ask-xxxxxxxxxxxx
|
||||
SQL_DSN=agent_user:password@tcp(localhost:3306)/agent_db
|
||||
PORT=3000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 实施步骤
|
||||
|
||||
### 阶段一:基础架构(Week 1-2)
|
||||
- [ ] 创建 agent_sites 表和模型
|
||||
- [ ] 实现代理站点注册和管理接口
|
||||
- [ ] 开发主系统代理中继接口
|
||||
- [ ] 实现代理站点转发逻辑
|
||||
|
||||
### 阶段二:套餐系统(Week 3-4)
|
||||
- [ ] 扩展 tokens 表字段
|
||||
- [ ] 实现套餐定义和管理
|
||||
- [ ] 开发套餐额度检查逻辑
|
||||
- [ ] 实现日/周/月自动重置
|
||||
|
||||
### 阶段三:计费系统(Week 5-6)
|
||||
- [ ] 创建 agent_billing_logs 表
|
||||
- [ ] 实现主系统计费记录
|
||||
- [ ] 开发代理站点额度同步
|
||||
- [ ] 实现统计报表接口
|
||||
|
||||
### 阶段四:前端界面(Week 7-8)
|
||||
- [ ] 主系统:代理站点管理页面
|
||||
- [ ] 主系统:计费统计报表
|
||||
- [ ] 代理站点:套餐令牌管理页面
|
||||
- [ ] 代理站点:使用统计页面
|
||||
|
||||
### 阶段五:测试优化(Week 9-10)
|
||||
- [ ] 单元测试
|
||||
- [ ] 压力测试
|
||||
- [ ] 安全测试
|
||||
- [ ] 性能优化
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 技术难点与解决方案
|
||||
|
||||
### 1. 如何保持可升级性?
|
||||
|
||||
**问题:** 二次开发后如何继续跟随 one-api 上游更新?
|
||||
|
||||
**解决方案:**
|
||||
- **插件化设计**:新功能尽量在新文件中实现,减少修改核心文件
|
||||
- **扩展而非修改**:使用 Go 的组合而非继承,扩展现有结构体
|
||||
- **Hook 机制**:在关键位置注入 Hook,避免修改主流程
|
||||
- **独立分支管理**:
|
||||
```bash
|
||||
# 主分支跟随上游
|
||||
git remote add upstream https://github.com/songquanpeng/one-api.git
|
||||
|
||||
# 开发分支
|
||||
git checkout -b saas-dev
|
||||
|
||||
# 定期合并上游
|
||||
git fetch upstream
|
||||
git merge upstream/main
|
||||
```
|
||||
|
||||
### 2. 额度透支问题
|
||||
|
||||
**问题:** 代理站点可能恶意超额使用
|
||||
|
||||
**解决方案:**
|
||||
- **预扣费机制**:主系统在转发前先扣除预估额度
|
||||
- **实时额度检查**:每次请求都验证代理站点剩余额度
|
||||
- **熔断机制**:超额后立即停止服务
|
||||
- **告警通知**:额度接近用尽时提前通知
|
||||
|
||||
### 3. 性能问题
|
||||
|
||||
**问题:** 每次请求都要经过主系统,增加延迟
|
||||
|
||||
**解决方案:**
|
||||
- **连接池**:复用 HTTP 连接
|
||||
- **异步计费**:返回结果后异步记录日志
|
||||
- **批量提交**:计费数据批量写入
|
||||
- **Redis 缓存**:缓存代理站点信息和额度
|
||||
|
||||
### 4. 高可用性
|
||||
|
||||
**问题:** 主系统故障影响所有代理站点
|
||||
|
||||
**解决方案:**
|
||||
- **主系统多节点部署**:负载均衡
|
||||
- **降级策略**:主系统故障时代理站点使用本地渠道(如果配置)
|
||||
- **健康检查**:定期检查主系统状态
|
||||
- **限流保护**:防止单个代理站点占用过多资源
|
||||
|
||||
---
|
||||
|
||||
## 🔐 安全考虑
|
||||
|
||||
### 1. 认证安全
|
||||
- 代理站点 API Key 使用强随机生成
|
||||
- 通信使用 HTTPS 加密
|
||||
- API Key 定期轮换
|
||||
|
||||
### 2. 防刷防滥用
|
||||
- 请求频率限制(Rate Limit)
|
||||
- 异常流量检测
|
||||
- IP 白名单
|
||||
|
||||
### 3. 数据安全
|
||||
- 敏感数据加密存储
|
||||
- 日志脱敏处理
|
||||
- 定期备份
|
||||
|
||||
---
|
||||
|
||||
## 📊 监控与运维
|
||||
|
||||
### 关键指标
|
||||
- 代理站点请求量
|
||||
- 渠道使用分布
|
||||
- 额度消耗趋势
|
||||
- 错误率
|
||||
- 响应时间
|
||||
|
||||
### 告警规则
|
||||
- 代理站点额度不足(< 10%)
|
||||
- 请求失败率异常(> 5%)
|
||||
- 主系统响应超时
|
||||
- 数据库连接数过高
|
||||
|
||||
---
|
||||
|
||||
## 💰 成本估算
|
||||
|
||||
### 开发成本
|
||||
- 后端开发:6-8 周
|
||||
- 前端开发:2-3 周
|
||||
- 测试优化:2 周
|
||||
- 总计:10-13 周
|
||||
|
||||
### 运维成本(月)
|
||||
- 主系统服务器:$50-100
|
||||
- 数据库:$30-50
|
||||
- Redis:$20-30
|
||||
- 带宽:$50-100
|
||||
- 总计:$150-280/月
|
||||
|
||||
---
|
||||
|
||||
## 📚 参考资料
|
||||
|
||||
### One-API 原项目
|
||||
- GitHub: https://github.com/songquanpeng/one-api
|
||||
- 文档: README.md
|
||||
|
||||
### 关键代码位置
|
||||
- 令牌管理:`model/token.go`
|
||||
- 计费逻辑:`relay/billing/billing.go`
|
||||
- 渠道分发:`middleware/distributor.go`
|
||||
- 认证中间件:`middleware/auth.go`
|
||||
|
||||
---
|
||||
|
||||
## 🎯 下一步行动
|
||||
|
||||
1. **确认方案**:与团队评审本方案
|
||||
2. **环境准备**:搭建开发测试环境
|
||||
3. **数据库设计**:创建数据表和索引
|
||||
4. **接口设计**:定义 API 接口规范
|
||||
5. **开始编码**:按阶段实施开发
|
||||
|
||||
---
|
||||
|
||||
**文档版本:** v1.0
|
||||
**创建时间:** 2025-12-29
|
||||
**作者:** Claude
|
||||
**状态:** 待评审
|
||||
Reference in New Issue
Block a user