Compare commits
5 Commits
main
...
8d4bdacca2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d4bdacca2 | ||
|
|
b25f1f8634 | ||
|
|
c826d06d2c | ||
|
|
7c058bfee3 | ||
|
|
b5e55c81d4 |
24
README.en.md
24
README.en.md
@@ -40,6 +40,28 @@
|
||||
> - Users must comply with OpenAI's [Terms of Use](https://openai.com/policies/terms-of-use) and **applicable laws and regulations**, and must not use it for illegal purposes.
|
||||
> - According to the [《Interim Measures for the Management of Generative Artificial Intelligence Services》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm), please do not provide any unregistered generative AI services to the public in China.
|
||||
|
||||
<h2>🤝 Trusted Partners</h2>
|
||||
<p id="premium-sponsors"> </p>
|
||||
<p align="center"><strong>No particular order</strong></p>
|
||||
<p align="center">
|
||||
<a href="https://www.cherry-ai.com/" target=_blank><img
|
||||
src="./docs/images/cherry-studio.png" alt="Cherry Studio" height="120"
|
||||
/></a>
|
||||
<a href="https://bda.pku.edu.cn/" target=_blank><img
|
||||
src="./docs/images/pku.png" alt="Peking University" height="120"
|
||||
/></a>
|
||||
<a href="https://www.compshare.cn/?ytag=GPU_yy_gh_newapi" target=_blank><img
|
||||
src="./docs/images/ucloud.png" alt="UCloud" height="120"
|
||||
/></a>
|
||||
<a href="https://www.aliyun.com/" target=_blank><img
|
||||
src="./docs/images/aliyun.png" alt="Alibaba Cloud" height="120"
|
||||
/></a>
|
||||
<a href="https://io.net/" target=_blank><img
|
||||
src="./docs/images/io-net.png" alt="IO.NET" height="120"
|
||||
/></a>
|
||||
</p>
|
||||
<p> </p>
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
For detailed documentation, please visit our official Wiki: [https://docs.newapi.pro/](https://docs.newapi.pro/)
|
||||
@@ -100,7 +122,7 @@ This version supports multiple models, please refer to [API Documentation-Relay
|
||||
For detailed configuration instructions, please refer to [Installation Guide-Environment Variables Configuration](https://docs.newapi.pro/installation/environment-variables):
|
||||
|
||||
- `GENERATE_DEFAULT_TOKEN`: Whether to generate initial tokens for newly registered users, default is `false`
|
||||
- `STREAMING_TIMEOUT`: Streaming response timeout, default is 120 seconds
|
||||
- `STREAMING_TIMEOUT`: Streaming response timeout, default is 300 seconds
|
||||
- `DIFY_DEBUG`: Whether to output workflow and node information for Dify channels, default is `true`
|
||||
- `FORCE_STREAM_OPTION`: Whether to override client stream_options parameter, default is `true`
|
||||
- `GET_MEDIA_TOKEN`: Whether to count image tokens, default is `true`
|
||||
|
||||
24
README.md
24
README.md
@@ -40,6 +40,28 @@
|
||||
> - 使用者必须在遵循 OpenAI 的[使用条款](https://openai.com/policies/terms-of-use)以及**法律法规**的情况下使用,不得用于非法用途。
|
||||
> - 根据[《生成式人工智能服务管理暂行办法》](http://www.cac.gov.cn/2023-07/13/c_1690898327029107.htm)的要求,请勿对中国地区公众提供一切未经备案的生成式人工智能服务。
|
||||
|
||||
<h2>🤝 我们信任的合作伙伴</h2>
|
||||
<p id="premium-sponsors"> </p>
|
||||
<p align="center"><strong>排名不分先后</strong></p>
|
||||
<p align="center">
|
||||
<a href="https://www.cherry-ai.com/" target=_blank><img
|
||||
src="./docs/images/cherry-studio.png" alt="Cherry Studio" height="120"
|
||||
/></a>
|
||||
<a href="https://bda.pku.edu.cn/" target=_blank><img
|
||||
src="./docs/images/pku.png" alt="北京大学" height="120"
|
||||
/></a>
|
||||
<a href="https://www.compshare.cn/?ytag=GPU_yy_gh_newapi" target=_blank><img
|
||||
src="./docs/images/ucloud.png" alt="UCloud 优刻得" height="120"
|
||||
/></a>
|
||||
<a href="https://www.aliyun.com/" target=_blank><img
|
||||
src="./docs/images/aliyun.png" alt="阿里云" height="120"
|
||||
/></a>
|
||||
<a href="https://io.net/" target=_blank><img
|
||||
src="./docs/images/io-net.png" alt="IO.NET" height="120"
|
||||
/></a>
|
||||
</p>
|
||||
<p> </p>
|
||||
|
||||
## 📚 文档
|
||||
|
||||
详细文档请访问我们的官方Wiki:[https://docs.newapi.pro/](https://docs.newapi.pro/)
|
||||
@@ -100,7 +122,7 @@ New API提供了丰富的功能,详细特性请参考[特性说明](https://do
|
||||
详细配置说明请参考[安装指南-环境变量配置](https://docs.newapi.pro/installation/environment-variables):
|
||||
|
||||
- `GENERATE_DEFAULT_TOKEN`:是否为新注册用户生成初始令牌,默认为 `false`
|
||||
- `STREAMING_TIMEOUT`:流式回复超时时间,默认120秒
|
||||
- `STREAMING_TIMEOUT`:流式回复超时时间,默认300秒
|
||||
- `DIFY_DEBUG`:Dify渠道是否输出工作流和节点信息,默认 `true`
|
||||
- `FORCE_STREAM_OPTION`:是否覆盖客户端stream_options参数,默认 `true`
|
||||
- `GET_MEDIA_TOKEN`:是否统计图片token,默认 `true`
|
||||
|
||||
@@ -483,10 +483,24 @@ func UpdateAllChannelsBalance(c *gin.Context) {
|
||||
}
|
||||
|
||||
func AutomaticallyUpdateChannels(frequency int) {
|
||||
reportCounter := 0
|
||||
reportInterval := 60 / frequency
|
||||
if reportInterval <= 0 {
|
||||
reportInterval = 1
|
||||
}
|
||||
|
||||
for {
|
||||
time.Sleep(time.Duration(frequency) * time.Minute)
|
||||
common.SysLog("updating all channels")
|
||||
_ = updateAllChannelsBalance()
|
||||
common.SysLog("channels update done")
|
||||
|
||||
reportCounter++
|
||||
if reportCounter >= reportInterval {
|
||||
reportCounter = 0
|
||||
go func() {
|
||||
service.ReportChannelState()
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
docker-compose-custom.yml
Normal file
34
docker-compose-custom.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
version: '3.4'
|
||||
|
||||
services:
|
||||
new-api-custom:
|
||||
image: new-api-custom:latest
|
||||
container_name: new-api-custom
|
||||
restart: always
|
||||
command: --log-dir /app/logs
|
||||
ports:
|
||||
- "3099:3000" # 使用3099端口
|
||||
volumes:
|
||||
- ./data:/data # 共享相同数据目录
|
||||
- ./logs-custom:/app/logs # 使用独立日志目录
|
||||
environment:
|
||||
- SQL_DSN=root:123456@tcp(mysql:3306)/new-api # 连接现有的mysql容器
|
||||
- REDIS_CONN_STRING=redis://redis # 连接现有的redis容器
|
||||
- TZ=Asia/Shanghai
|
||||
- ERROR_LOG_ENABLED=true
|
||||
# - STREAMING_TIMEOUT=120
|
||||
# - SESSION_SECRET=random_string # 如果需要多机部署
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget -q -O - http://localhost:3000/api/status | grep -o '\"success\":\\s*true' | awk -F: '{print $$2}'"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
networks:
|
||||
- new-api_default # 连接到现有的网络,复用现有的 redis 和 mysql
|
||||
|
||||
# 不定义 redis 和 mysql 服务,直接使用现有运行的容器
|
||||
# 只需要连接到相同的网络即可访问
|
||||
|
||||
networks:
|
||||
new-api_default:
|
||||
external: true # 使用现有的网络
|
||||
@@ -1,6 +1,6 @@
|
||||
# One API – Web 界面后端接口文档
|
||||
# New API – Web 界面后端接口文档
|
||||
|
||||
> 本文档汇总了 **One API** 后端提供给前端 Web 界面的全部 REST 接口(不含 *Relay* 相关接口)。
|
||||
> 本文档汇总了 **New API** 后端提供给前端 Web 界面的全部 REST 接口(不含 *Relay* 相关接口)。
|
||||
>
|
||||
> 接口前缀统一为 `https://<your-domain>`,以下仅列出 **路径**、**HTTP 方法**、**鉴权要求** 与 **功能简介**。
|
||||
>
|
||||
@@ -62,6 +62,8 @@
|
||||
| GET | /api/user/groups | 公开 | 列出所有分组(无鉴权版) |
|
||||
|
||||
### 5.2 用户自身操作 (需登录)
|
||||
| 方法 | 路径 | 鉴权 | 说明 |
|
||||
|------|------|------|------|
|
||||
| GET | /api/user/self/groups | 用户 | 获取自己所在分组 |
|
||||
| GET | /api/user/self | 用户 | 获取个人资料 |
|
||||
| GET | /api/user/models | 用户 | 获取模型可见性 |
|
||||
@@ -192,4 +194,4 @@
|
||||
|
||||
---
|
||||
|
||||
> **更新日期**:2025.07.17
|
||||
> **更新日期**:2025.07.17
|
||||
|
||||
BIN
docs/images/aliyun.png
Normal file
BIN
docs/images/aliyun.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.0 KiB |
BIN
docs/images/cherry-studio.png
Normal file
BIN
docs/images/cherry-studio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
docs/images/io-net.png
Normal file
BIN
docs/images/io-net.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
BIN
docs/images/pku.png
Normal file
BIN
docs/images/pku.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
docs/images/ucloud.png
Normal file
BIN
docs/images/ucloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
45
patches/claude-passthrough.patch
Normal file
45
patches/claude-passthrough.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
diff --git a/relay/channel/claude/adaptor.go b/relay/channel/claude/adaptor.go
|
||||
index 540742d6..c715c0c9 100644
|
||||
--- a/relay/channel/claude/adaptor.go
|
||||
+++ b/relay/channel/claude/adaptor.go
|
||||
@@ -55,14 +55,34 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
|
||||
}
|
||||
|
||||
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error {
|
||||
- channel.SetupApiRequestHeader(info, c, req)
|
||||
+ if model_setting.GetGlobalSettings().PassThroughRequestEnabled {
|
||||
+ // 穿透模式:直接复制原始请求头,但跳过系统级头信息
|
||||
+ for key, values := range c.Request.Header {
|
||||
+ keyLower := strings.ToLower(key)
|
||||
+ if keyLower == "host" || keyLower == "content-length" || keyLower == "connection" {
|
||||
+ continue
|
||||
+ }
|
||||
+ for _, value := range values {
|
||||
+ req.Add(key, value)
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ // 非穿透模式:使用通用设置
|
||||
+ channel.SetupApiRequestHeader(info, c, req)
|
||||
+ }
|
||||
+
|
||||
+ // 无论哪种模式都需要设置正确的API密钥
|
||||
req.Set("x-api-key", info.ApiKey)
|
||||
- anthropicVersion := c.Request.Header.Get("anthropic-version")
|
||||
- if anthropicVersion == "" {
|
||||
- anthropicVersion = "2023-06-01"
|
||||
+
|
||||
+ if !model_setting.GetGlobalSettings().PassThroughRequestEnabled {
|
||||
+ // 非穿透模式才强制设置这些头
|
||||
+ anthropicVersion := c.Request.Header.Get("anthropic-version")
|
||||
+ if anthropicVersion == "" {
|
||||
+ anthropicVersion = "2023-06-01"
|
||||
+ }
|
||||
+ req.Set("anthropic-version", anthropicVersion)
|
||||
+ model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req)
|
||||
}
|
||||
- req.Set("anthropic-version", anthropicVersion)
|
||||
- model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req)
|
||||
return nil
|
||||
}
|
||||
|
||||
17
patches/footer-custom.patch
Normal file
17
patches/footer-custom.patch
Normal file
@@ -0,0 +1,17 @@
|
||||
diff --git a/web/src/components/layout/Footer.js b/web/src/components/layout/Footer.js
|
||||
index d380e574..d20e6328 100644
|
||||
--- a/web/src/components/layout/Footer.js
|
||||
+++ b/web/src/components/layout/Footer.js
|
||||
@@ -82,10 +82,8 @@ const FooterBar = () => {
|
||||
</div>
|
||||
|
||||
<div className="text-sm">
|
||||
- <span className="!text-semi-color-text-1">{t('设计与开发由')} </span>
|
||||
- <a href="https://github.com/QuantumNous/new-api" target="_blank" rel="noopener noreferrer" className="!text-semi-color-primary font-medium">New API</a>
|
||||
- <span className="!text-semi-color-text-1"> & </span>
|
||||
- <a href="https://github.com/songquanpeng/one-api" target="_blank" rel="noopener noreferrer" className="!text-semi-color-primary font-medium">One API</a>
|
||||
+ <span className="!text-semi-color-text-1">全栈服务提供商 </span>
|
||||
+ <a href="https://hk.claude.cursorpro.com.cn" title="代理开设分销站" target="_blank" rel="noopener noreferrer" className="!text-semi-color-primary font-medium">听泉claude提供</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -55,14 +55,34 @@ func (a *Adaptor) GetRequestURL(info *relaycommon.RelayInfo) (string, error) {
|
||||
}
|
||||
|
||||
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error {
|
||||
channel.SetupApiRequestHeader(info, c, req)
|
||||
req.Set("x-api-key", info.ApiKey)
|
||||
anthropicVersion := c.Request.Header.Get("anthropic-version")
|
||||
if anthropicVersion == "" {
|
||||
anthropicVersion = "2023-06-01"
|
||||
if model_setting.GetGlobalSettings().PassThroughRequestEnabled {
|
||||
// 穿透模式:直接复制原始请求头,但跳过系统级头信息
|
||||
for key, values := range c.Request.Header {
|
||||
keyLower := strings.ToLower(key)
|
||||
if keyLower == "host" || keyLower == "content-length" || keyLower == "connection" {
|
||||
continue
|
||||
}
|
||||
for _, value := range values {
|
||||
req.Add(key, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 非穿透模式:使用通用设置
|
||||
channel.SetupApiRequestHeader(info, c, req)
|
||||
}
|
||||
|
||||
// 无论哪种模式都需要设置正确的API密钥
|
||||
req.Set("x-api-key", info.ApiKey)
|
||||
|
||||
if !model_setting.GetGlobalSettings().PassThroughRequestEnabled {
|
||||
// 非穿透模式才强制设置这些头
|
||||
anthropicVersion := c.Request.Header.Get("anthropic-version")
|
||||
if anthropicVersion == "" {
|
||||
anthropicVersion = "2023-06-01"
|
||||
}
|
||||
req.Set("anthropic-version", anthropicVersion)
|
||||
model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req)
|
||||
}
|
||||
req.Set("anthropic-version", anthropicVersion)
|
||||
model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
197
temp/DEPLOY_GUIDE.md
Normal file
197
temp/DEPLOY_GUIDE.md
Normal file
@@ -0,0 +1,197 @@
|
||||
# New-API 服务器部署指南
|
||||
|
||||
## 📦 部署准备
|
||||
|
||||
### 1. 提交所有修改
|
||||
```bash
|
||||
# 添加恢复的配置文件
|
||||
git add docker-compose-custom.yml docker-compose-tq.yml controller/channel-billing.go temp/
|
||||
|
||||
# 提交完整的更新
|
||||
git commit -m "完整更新:恢复所有自定义配置
|
||||
|
||||
✅ 已同步官方 v0.9.0-alpha.8
|
||||
✅ 已恢复 Footer 自定义页脚
|
||||
✅ 已恢复 Claude 穿透功能
|
||||
✅ 已恢复 Docker 自定义配置
|
||||
✅ 已恢复 Channel 计费逻辑
|
||||
✅ 已创建更新手册
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.ai/code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
# 推送到远程仓库
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 2. 服务器环境要求
|
||||
- Docker & Docker Compose
|
||||
- Go 1.19+ (如果需要本地编译)
|
||||
- Node.js 16+ & Bun/npm (前端编译)
|
||||
|
||||
## 🚀 部署方案
|
||||
|
||||
### 方案1:Docker直接部署 (推荐)
|
||||
|
||||
#### 1.1 拉取最新代码到服务器
|
||||
```bash
|
||||
# 在服务器上
|
||||
cd /path/to/your/new-api
|
||||
git pull origin main
|
||||
```
|
||||
|
||||
#### 1.2 使用你们的自定义配置启动
|
||||
```bash
|
||||
# 使用 docker-compose-custom.yml
|
||||
docker-compose -f docker-compose-custom.yml down
|
||||
docker-compose -f docker-compose-custom.yml up -d --build
|
||||
|
||||
# 或使用 docker-compose-tq.yml
|
||||
docker-compose -f docker-compose-tq.yml down
|
||||
docker-compose -f docker-compose-tq.yml up -d --build
|
||||
```
|
||||
|
||||
### 方案2:本地编译后部署
|
||||
|
||||
#### 2.1 本地编译
|
||||
```bash
|
||||
# 前端编译
|
||||
cd web
|
||||
npm install # 或 bun install
|
||||
npm run build # 或 bun run build
|
||||
|
||||
# 后端编译
|
||||
cd ..
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o new-api
|
||||
|
||||
# 打包
|
||||
tar -czf new-api-release.tar.gz new-api web/build/ docker-compose-custom.yml
|
||||
```
|
||||
|
||||
#### 2.2 服务器部署
|
||||
```bash
|
||||
# 上传到服务器
|
||||
scp new-api-release.tar.gz user@server:/path/to/deploy/
|
||||
|
||||
# 服务器上解压
|
||||
tar -xzf new-api-release.tar.gz
|
||||
|
||||
# 启动服务
|
||||
docker-compose -f docker-compose-custom.yml up -d
|
||||
```
|
||||
|
||||
## 📋 部署检查清单
|
||||
|
||||
### ✅ 功能验证
|
||||
- [ ] 服务正常启动
|
||||
- [ ] Web界面可访问
|
||||
- [ ] Footer显示"听泉claude提供"
|
||||
- [ ] Claude模型可正常调用
|
||||
- [ ] 穿透功能工作正常
|
||||
- [ ] 计费逻辑正确
|
||||
- [ ] 新增功能测试
|
||||
|
||||
### ✅ 配置检查
|
||||
- [ ] 数据库连接正常
|
||||
- [ ] Redis连接正常
|
||||
- [ ] 环境变量配置
|
||||
- [ ] SSL证书有效
|
||||
- [ ] 日志输出正常
|
||||
|
||||
## 🔧 常用维护命令
|
||||
|
||||
### 查看服务状态
|
||||
```bash
|
||||
docker-compose -f docker-compose-custom.yml ps
|
||||
docker-compose -f docker-compose-custom.yml logs -f new-api
|
||||
```
|
||||
|
||||
### 重启服务
|
||||
```bash
|
||||
docker-compose -f docker-compose-custom.yml restart
|
||||
```
|
||||
|
||||
### 备份数据
|
||||
```bash
|
||||
# 数据库备份
|
||||
docker exec -t new-api-mysql mysqldump -u root -p新密码 new-api > backup_$(date +%Y%m%d).sql
|
||||
|
||||
# 配置文件备份
|
||||
tar -czf config-backup-$(date +%Y%m%d).tar.gz docker-compose-custom.yml .env
|
||||
```
|
||||
|
||||
### 查看资源使用
|
||||
```bash
|
||||
docker stats
|
||||
```
|
||||
|
||||
## 🎯 版本更新流程
|
||||
|
||||
当需要后续更新时:
|
||||
|
||||
1. **本地更新**:按照 `temp/UPDATE_MANUAL.md` 执行
|
||||
2. **测试验证**:本地启动测试所有功能
|
||||
3. **服务器部署**:
|
||||
```bash
|
||||
git pull origin main
|
||||
docker-compose -f docker-compose-custom.yml up -d --build
|
||||
```
|
||||
4. **功能验证**:检查上述清单
|
||||
|
||||
## 📞 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
**问题1:服务启动失败**
|
||||
```bash
|
||||
# 查看详细日志
|
||||
docker-compose -f docker-compose-custom.yml logs --tail=100 new-api
|
||||
|
||||
# 检查端口占用
|
||||
netstat -tulpn | grep :3000
|
||||
```
|
||||
|
||||
**问题2:Claude穿透不工作**
|
||||
- 检查 `PassThroughRequestEnabled` 设置
|
||||
- 查看 `relay/channel/claude/adaptor.go` 是否包含穿透代码
|
||||
|
||||
**问题3:前端显示异常**
|
||||
```bash
|
||||
# 重新构建前端
|
||||
docker-compose -f docker-compose-custom.yml exec new-api sh
|
||||
cd web && npm run build
|
||||
exit
|
||||
docker-compose -f docker-compose-custom.yml restart
|
||||
```
|
||||
|
||||
## 🔒 安全建议
|
||||
|
||||
1. **定期备份**:数据库+配置文件
|
||||
2. **监控日志**:异常访问和错误
|
||||
3. **更新依赖**:定期更新Docker镜像
|
||||
4. **访问控制**:限制管理后台访问IP
|
||||
|
||||
---
|
||||
|
||||
## 📋 本次更新内容摘要
|
||||
|
||||
### ✅ 已完成
|
||||
- [x] 同步官方 v0.9.0-alpha.8 (3378个提交)
|
||||
- [x] 保留 Footer 自定义 ("听泉claude提供")
|
||||
- [x] 保留 Claude 穿透功能
|
||||
- [x] 恢复 Docker 自定义配置
|
||||
- [x] 恢复 Channel 计费逻辑修改
|
||||
- [x] 创建维护文档和部署脚本
|
||||
|
||||
### 🎯 关键文件
|
||||
- `web/src/components/layout/Footer.js` - 自定义页脚
|
||||
- `relay/channel/claude/adaptor.go` - Claude穿透
|
||||
- `controller/channel-billing.go` - 计费逻辑
|
||||
- `docker-compose-custom.yml` - 部署配置
|
||||
- `temp/UPDATE_MANUAL.md` - 更新手册
|
||||
|
||||
现在可以安全地部署到生产服务器了!
|
||||
|
||||
---
|
||||
*部署手册 - 最后更新:2025-08-25*
|
||||
214
temp/UPDATE_MANUAL.md
Normal file
214
temp/UPDATE_MANUAL.md
Normal file
@@ -0,0 +1,214 @@
|
||||
# New-API 官方更新适配手册
|
||||
|
||||
## 概述
|
||||
本手册用于指导如何安全地将官方 GitHub 更新同步到我们的自定义版本,同时保留关键的自定义功能。
|
||||
|
||||
## 准备工作
|
||||
|
||||
### 远程仓库配置
|
||||
确保已正确配置远程仓库:
|
||||
```bash
|
||||
# 检查远程仓库
|
||||
git remote -v
|
||||
|
||||
# 应该看到:
|
||||
# origin https://git.586vip.cn/oadmin/new-api.git (自己的仓库)
|
||||
# upstream https://github.com/QuantumNous/new-api.git (官方仓库)
|
||||
```
|
||||
|
||||
如果没有 upstream,添加官方仓库:
|
||||
```bash
|
||||
git remote add upstream https://github.com/QuantumNous/new-api.git
|
||||
```
|
||||
|
||||
## 更新流程
|
||||
|
||||
### 1. 获取官方最新更新
|
||||
```bash
|
||||
# 获取官方最新代码
|
||||
git fetch upstream
|
||||
|
||||
# 查看最新版本标签
|
||||
git tag -l | grep "^v" | sort -V | tail -10
|
||||
|
||||
# 查看官方最新提交
|
||||
git log upstream/main --oneline -10
|
||||
```
|
||||
|
||||
### 2. 备份当前分支
|
||||
```bash
|
||||
# 创建备份分支(包含时间戳)
|
||||
git checkout -b backup/before-sync-$(powershell -Command "Get-Date -Format 'yyyyMMdd-HHmm'")
|
||||
|
||||
# 提交当前所有修改
|
||||
git add -A
|
||||
git commit -m "备份:同步官方更新前的完整状态"
|
||||
|
||||
# 切换回主分支
|
||||
git checkout main
|
||||
```
|
||||
|
||||
### 3. 更新到官方最新版本
|
||||
```bash
|
||||
# 硬重置到官方最新版本(⚠️ 会覆盖所有本地修改)
|
||||
git reset --hard upstream/main
|
||||
```
|
||||
|
||||
### 4. 应用自定义功能
|
||||
#### 4.1 恢复 Footer 自定义
|
||||
```bash
|
||||
# 方法1:使用补丁(如果存在)
|
||||
git apply -R patches/footer-custom.patch
|
||||
|
||||
# 方法2:手动编辑
|
||||
# 编辑 web/src/components/layout/Footer.js
|
||||
# 将第85-88行的官方链接替换为:
|
||||
```
|
||||
```javascript
|
||||
<span className="!text-semi-color-text-1">全栈服务提供商 </span>
|
||||
<a href="https://hk.claude.cursorpro.com.cn" title="代理开设分销站" target="_blank" rel="noopener noreferrer" className="!text-semi-color-primary font-medium">听泉claude提供</a>
|
||||
```
|
||||
|
||||
#### 4.2 恢复 Claude 穿透功能
|
||||
编辑 `relay/channel/claude/adaptor.go`,将 `SetupRequestHeader` 函数替换为:
|
||||
|
||||
```go
|
||||
func (a *Adaptor) SetupRequestHeader(c *gin.Context, req *http.Header, info *relaycommon.RelayInfo) error {
|
||||
if model_setting.GetGlobalSettings().PassThroughRequestEnabled {
|
||||
// 穿透模式:直接复制原始请求头,但跳过系统级头信息
|
||||
for key, values := range c.Request.Header {
|
||||
keyLower := strings.ToLower(key)
|
||||
if keyLower == "host" || keyLower == "content-length" || keyLower == "connection" {
|
||||
continue
|
||||
}
|
||||
for _, value := range values {
|
||||
req.Add(key, value)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 非穿透模式:使用通用设置
|
||||
channel.SetupApiRequestHeader(info, c, req)
|
||||
}
|
||||
|
||||
// 无论哪种模式都需要设置正确的API密钥
|
||||
req.Set("x-api-key", info.ApiKey)
|
||||
|
||||
if !model_setting.GetGlobalSettings().PassThroughRequestEnabled {
|
||||
// 非穿透模式才强制设置这些头
|
||||
anthropicVersion := c.Request.Header.Get("anthropic-version")
|
||||
if anthropicVersion == "" {
|
||||
anthropicVersion = "2023-06-01"
|
||||
}
|
||||
req.Set("anthropic-version", anthropicVersion)
|
||||
model_setting.GetClaudeSettings().WriteHeaders(info.OriginModelName, req)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 检查其他可能的自定义修改
|
||||
检查以下文件是否需要保留自定义修改:
|
||||
- `controller/channel-billing.go` - 计费逻辑
|
||||
- `docker-compose-custom.yml` - 自定义Docker配置
|
||||
- `service/channel_state_reporter.go` - 渠道状态报告
|
||||
- 其他业务相关文件
|
||||
|
||||
### 6. 验证和提交
|
||||
```bash
|
||||
# 检查修改状态
|
||||
git status
|
||||
git diff --name-only
|
||||
|
||||
# 添加修改的文件
|
||||
git add relay/channel/claude/adaptor.go web/src/components/layout/Footer.js
|
||||
git add 其他需要的文件...
|
||||
|
||||
# 提交修改
|
||||
git commit -m "同步官方vX.X.X,保留自定义Footer和Claude穿透功能
|
||||
|
||||
- 更新到官方最新版本 (commit-hash)
|
||||
- 保留自定义页脚品牌信息 (听泉claude提供)
|
||||
- 保留Claude渠道请求穿透功能
|
||||
- [其他自定义功能说明]
|
||||
|
||||
🤖 Generated with [Claude Code](https://claude.ai/code)
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
```
|
||||
|
||||
### 7. 推送到远程仓库
|
||||
```bash
|
||||
# 推送到自己的仓库
|
||||
git push origin main
|
||||
|
||||
# 如果有冲突,可能需要强制推送(谨慎使用)
|
||||
# git push origin main --force-with-lease
|
||||
```
|
||||
|
||||
## 自动化脚本
|
||||
|
||||
创建 `scripts/sync-upstream.sh` 自动化脚本:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "🔄 开始同步官方更新..."
|
||||
|
||||
# 获取最新版本
|
||||
git fetch upstream
|
||||
LATEST_COMMIT=$(git rev-parse upstream/main)
|
||||
LATEST_TAG=$(git describe --tags --abbrev=0 upstream/main 2>/dev/null || echo "No tags")
|
||||
|
||||
echo "📋 准备更新到: $LATEST_TAG ($LATEST_COMMIT)"
|
||||
|
||||
# 备份当前分支
|
||||
BACKUP_BRANCH="backup/before-sync-$(date +%Y%m%d-%H%M)"
|
||||
git checkout -b $BACKUP_BRANCH
|
||||
git add -A && git commit -m "备份:同步官方更新前的完整状态" || true
|
||||
git checkout main
|
||||
|
||||
echo "💾 已创建备份分支: $BACKUP_BRANCH"
|
||||
|
||||
# 更新到官方最新
|
||||
git reset --hard upstream/main
|
||||
|
||||
echo "✅ 已更新到官方最新版本"
|
||||
echo "⚠️ 请手动应用自定义修改:"
|
||||
echo " 1. Footer.js 自定义页脚"
|
||||
echo " 2. Claude adaptor.go 穿透功能"
|
||||
echo " 3. 其他业务相关修改"
|
||||
echo ""
|
||||
echo "🔍 检查修改: git status"
|
||||
echo "💾 提交修改: git add . && git commit -m '更新说明'"
|
||||
echo "🚀 推送远程: git push origin main"
|
||||
```
|
||||
|
||||
## 重要提醒
|
||||
|
||||
### ⚠️ 风险提示
|
||||
- `git reset --hard` 会**完全覆盖**本地修改
|
||||
- 务必在操作前创建备份分支
|
||||
- 推荐在测试环境先验证功能正常
|
||||
|
||||
### 🔍 验证检查清单
|
||||
- [ ] Footer显示"听泉claude提供"
|
||||
- [ ] Claude穿透功能正常工作
|
||||
- [ ] 计费功能未受影响
|
||||
- [ ] Docker配置正确
|
||||
- [ ] 编译无错误
|
||||
- [ ] 基础功能测试通过
|
||||
|
||||
### 📝 维护记录
|
||||
每次更新后记录:
|
||||
- 更新日期:
|
||||
- 官方版本:
|
||||
- 保留的自定义功能:
|
||||
- 遇到的问题和解决方案:
|
||||
|
||||
## 联系信息
|
||||
如有问题,联系技术团队或查看备份分支恢复。
|
||||
|
||||
---
|
||||
*最后更新:2025-08-25*
|
||||
*适用版本:v0.9.0-alpha.8+*
|
||||
220
temp/deploy.sh
Normal file
220
temp/deploy.sh
Normal file
@@ -0,0 +1,220 @@
|
||||
#!/bin/bash
|
||||
|
||||
# =============================================================================
|
||||
# New-API 一键部署脚本
|
||||
# 用于快速部署更新后的 New-API 到生产服务器
|
||||
# =============================================================================
|
||||
|
||||
set -e # 遇到错误立即退出
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 日志函数
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# 检查命令是否存在
|
||||
check_command() {
|
||||
if ! command -v $1 &> /dev/null; then
|
||||
log_error "$1 未安装,请先安装"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 检查环境
|
||||
check_environment() {
|
||||
log_info "检查部署环境..."
|
||||
|
||||
check_command "git"
|
||||
check_command "docker"
|
||||
check_command "docker-compose"
|
||||
|
||||
# 检查Docker服务状态
|
||||
if ! docker info &> /dev/null; then
|
||||
log_error "Docker 服务未运行,请启动 Docker"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "环境检查通过"
|
||||
}
|
||||
|
||||
# 备份当前配置
|
||||
backup_current() {
|
||||
log_info "备份当前配置..."
|
||||
|
||||
BACKUP_DIR="backups/$(date +%Y%m%d-%H%M%S)"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# 备份配置文件
|
||||
if [ -f "docker-compose-custom.yml" ]; then
|
||||
cp docker-compose-custom.yml "$BACKUP_DIR/"
|
||||
fi
|
||||
|
||||
if [ -f ".env" ]; then
|
||||
cp .env "$BACKUP_DIR/"
|
||||
fi
|
||||
|
||||
# 备份数据库(如果本地)
|
||||
if docker ps | grep -q "mysql\|postgres"; then
|
||||
log_info "检测到数据库容器,建议手动备份数据库"
|
||||
fi
|
||||
|
||||
log_success "备份完成:$BACKUP_DIR"
|
||||
}
|
||||
|
||||
# 拉取最新代码
|
||||
pull_latest_code() {
|
||||
log_info "拉取最新代码..."
|
||||
|
||||
# 检查是否有未提交的更改
|
||||
if ! git diff --quiet || ! git diff --cached --quiet; then
|
||||
log_warning "检测到未提交的更改"
|
||||
read -p "是否要stash这些更改? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
git stash
|
||||
log_info "已stash本地更改"
|
||||
fi
|
||||
fi
|
||||
|
||||
git pull origin main
|
||||
log_success "代码更新完成"
|
||||
}
|
||||
|
||||
# 构建和部署
|
||||
build_and_deploy() {
|
||||
log_info "开始构建和部署..."
|
||||
|
||||
# 选择配置文件
|
||||
COMPOSE_FILE=""
|
||||
if [ -f "docker-compose-custom.yml" ]; then
|
||||
COMPOSE_FILE="docker-compose-custom.yml"
|
||||
elif [ -f "docker-compose-tq.yml" ]; then
|
||||
COMPOSE_FILE="docker-compose-tq.yml"
|
||||
else
|
||||
COMPOSE_FILE="docker-compose.yml"
|
||||
fi
|
||||
|
||||
log_info "使用配置文件: $COMPOSE_FILE"
|
||||
|
||||
# 停止现有服务
|
||||
log_info "停止现有服务..."
|
||||
docker-compose -f "$COMPOSE_FILE" down
|
||||
|
||||
# 构建新镜像
|
||||
log_info "构建新镜像..."
|
||||
docker-compose -f "$COMPOSE_FILE" build --no-cache
|
||||
|
||||
# 启动服务
|
||||
log_info "启动服务..."
|
||||
docker-compose -f "$COMPOSE_FILE" up -d
|
||||
|
||||
log_success "部署完成"
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
health_check() {
|
||||
log_info "执行健康检查..."
|
||||
|
||||
# 等待服务启动
|
||||
sleep 10
|
||||
|
||||
# 检查容器状态
|
||||
if docker-compose ps | grep -q "Exit\|unhealthy"; then
|
||||
log_error "检测到容器异常"
|
||||
docker-compose logs --tail=50
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查HTTP响应
|
||||
local max_attempts=30
|
||||
local attempt=1
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
if curl -s -o /dev/null -w "%{http_code}" http://localhost:3000 | grep -q "200\|302"; then
|
||||
log_success "服务健康检查通过"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "等待服务启动... ($attempt/$max_attempts)"
|
||||
sleep 5
|
||||
attempt=$((attempt + 1))
|
||||
done
|
||||
|
||||
log_error "健康检查失败"
|
||||
docker-compose logs --tail=50
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 显示部署信息
|
||||
show_deploy_info() {
|
||||
echo
|
||||
log_success "🎉 部署成功完成!"
|
||||
echo
|
||||
echo "=================== 部署信息 ==================="
|
||||
echo "部署时间: $(date)"
|
||||
echo "Git 提交: $(git rev-parse --short HEAD)"
|
||||
echo "服务地址: http://localhost:3000"
|
||||
echo "=============================================="
|
||||
echo
|
||||
echo "🔧 常用命令:"
|
||||
echo " 查看日志: docker-compose logs -f"
|
||||
echo " 重启服务: docker-compose restart"
|
||||
echo " 停止服务: docker-compose down"
|
||||
echo " 查看状态: docker-compose ps"
|
||||
echo
|
||||
echo "📖 更多信息请查看: temp/DEPLOY_GUIDE.md"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
echo "==============================================="
|
||||
echo "🚀 New-API 自动部署脚本"
|
||||
echo "==============================================="
|
||||
|
||||
# 检查是否在正确目录
|
||||
if [ ! -f "main.go" ] || [ ! -d "web" ]; then
|
||||
log_error "请在 New-API 项目根目录运行此脚本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 确认部署
|
||||
read -p "确认要部署到生产环境吗? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "部署已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 执行部署步骤
|
||||
check_environment
|
||||
backup_current
|
||||
pull_latest_code
|
||||
build_and_deploy
|
||||
health_check
|
||||
show_deploy_info
|
||||
}
|
||||
|
||||
# 错误处理
|
||||
trap 'log_error "部署过程中发生错误,请检查上面的日志信息"' ERR
|
||||
|
||||
# 执行主函数
|
||||
main "$@"
|
||||
@@ -82,10 +82,8 @@ const FooterBar = () => {
|
||||
</div>
|
||||
|
||||
<div className="text-sm">
|
||||
<span className="!text-semi-color-text-1">{t('设计与开发由')} </span>
|
||||
<a href="https://github.com/QuantumNous/new-api" target="_blank" rel="noopener noreferrer" className="!text-semi-color-primary font-medium">New API</a>
|
||||
<span className="!text-semi-color-text-1"> & </span>
|
||||
<a href="https://github.com/songquanpeng/one-api" target="_blank" rel="noopener noreferrer" className="!text-semi-color-primary font-medium">One API</a>
|
||||
<span className="!text-semi-color-text-1">全栈服务提供商 </span>
|
||||
<a href="https://hk.claude.cursorpro.com.cn" title="代理开设分销站" target="_blank" rel="noopener noreferrer" className="!text-semi-color-primary font-medium">听泉claude提供</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
Reference in New Issue
Block a user