mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-11-01 06:13:43 +08:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			v0.3.2-alp
			...
			v0.3.2-alp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 2779d6629c | ||
|  | e509899daf | ||
|  | b53cdbaf05 | ||
|  | ced89398a5 | ||
|  | 09c2e3bcec | ||
|  | 5cba800fa6 | ||
|  | 2d39a135f2 | 
							
								
								
									
										36
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								README.md
									
									
									
									
									
								
							| @@ -38,6 +38,8 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用 | |||||||
|   <a href="https://github.com/songquanpeng/one-api#截图展示">截图展示</a> |   <a href="https://github.com/songquanpeng/one-api#截图展示">截图展示</a> | ||||||
|   · |   · | ||||||
|   <a href="https://openai.justsong.cn/">在线演示</a> |   <a href="https://openai.justsong.cn/">在线演示</a> | ||||||
|  |   · | ||||||
|  |   <a href="https://github.com/songquanpeng/one-api#常见问题">常见问题</a> | ||||||
| </p> | </p> | ||||||
|  |  | ||||||
| > **Warning**:从 `v0.2` 版本升级到 `v0.3` 版本需要手动迁移数据库,请手动执行[数据库迁移脚本](./bin/migration_v0.2-v0.3.sql)。 | > **Warning**:从 `v0.2` 版本升级到 `v0.3` 版本需要手动迁移数据库,请手动执行[数据库迁移脚本](./bin/migration_v0.2-v0.3.sql)。 | ||||||
| @@ -55,19 +57,20 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用 | |||||||
|    + [x] 自定义渠道:例如使用自行搭建的 OpenAI 代理 |    + [x] 自定义渠道:例如使用自行搭建的 OpenAI 代理 | ||||||
| 2. 支持通过**负载均衡**的方式访问多个渠道。 | 2. 支持通过**负载均衡**的方式访问多个渠道。 | ||||||
| 3. 支持 **stream 模式**,可以通过流式传输实现打字机效果。 | 3. 支持 **stream 模式**,可以通过流式传输实现打字机效果。 | ||||||
| 4. 支持**令牌管理**,设置令牌的过期时间和使用次数。 | 4. 支持**多机部署**,[详见此处](#多机部署)。 | ||||||
| 5. 支持**兑换码管理**,支持批量生成和导出兑换码,可使用兑换码为令牌进行充值。 | 5. 支持**令牌管理**,设置令牌的过期时间和使用次数。 | ||||||
| 6. 支持**通道管理**,批量创建通道。 | 6. 支持**兑换码管理**,支持批量生成和导出兑换码,可使用兑换码为令牌进行充值。 | ||||||
| 7. 支持发布公告,设置充值链接,设置新用户初始额度。 | 7. 支持**通道管理**,批量创建通道。 | ||||||
| 8. 支持丰富的**自定义**设置, | 8. 支持发布公告,设置充值链接,设置新用户初始额度。 | ||||||
|  | 9. 支持丰富的**自定义**设置, | ||||||
|    1. 支持自定义系统名称,logo 以及页脚。 |    1. 支持自定义系统名称,logo 以及页脚。 | ||||||
|    2. 支持自定义首页和关于页面,可以选择使用 HTML & Markdown 代码进行自定义,或者使用一个单独的网页通过 iframe 嵌入。 |    2. 支持自定义首页和关于页面,可以选择使用 HTML & Markdown 代码进行自定义,或者使用一个单独的网页通过 iframe 嵌入。 | ||||||
| 9. 支持通过系统访问令牌访问管理 API。 | 10. 支持通过系统访问令牌访问管理 API。 | ||||||
| 10. 支持用户管理,支持**多种用户登录注册方式**: | 11. 支持用户管理,支持**多种用户登录注册方式**: | ||||||
|     + 邮箱登录注册以及通过邮箱进行密码重置。 |     + 邮箱登录注册以及通过邮箱进行密码重置。 | ||||||
|     + [GitHub 开放授权](https://github.com/settings/applications/new)。 |     + [GitHub 开放授权](https://github.com/settings/applications/new)。 | ||||||
|     + 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。 |     + 微信公众号授权(需要额外部署 [WeChat Server](https://github.com/songquanpeng/wechat-server))。 | ||||||
| 11. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。 | 12. 未来其他大模型开放 API 后,将第一时间支持,并将其封装成同样的 API 访问方式。 | ||||||
|  |  | ||||||
| ## 部署 | ## 部署 | ||||||
| ### 基于 Docker 进行部署 | ### 基于 Docker 进行部署 | ||||||
| @@ -133,6 +136,14 @@ sudo service nginx restart | |||||||
|  |  | ||||||
| 更加详细的部署教程[参见此处](https://iamazing.cn/page/how-to-deploy-a-website)。 | 更加详细的部署教程[参见此处](https://iamazing.cn/page/how-to-deploy-a-website)。 | ||||||
|  |  | ||||||
|  | ### 多机部署 | ||||||
|  | 1. 所有服务器 `SESSION_SECRET` 设置一样的值。 | ||||||
|  | 2. 必须设置 `SQL_DSN`,使用 MySQL 数据库而非 SQLite,请自行配置主备数据库同步。 | ||||||
|  | 3. 所有从服务器必须设置 `SYNC_FREQUENCY`,以定期从数据库同步配置。 | ||||||
|  | 4. 从服务器可以选择设置 `FRONTEND_BASE_URL`,以重定向页面请求到主服务器。 | ||||||
|  |  | ||||||
|  | 环境变量的具体使用方法详见[此处](#环境变量)。 | ||||||
|  |  | ||||||
| ## 配置 | ## 配置 | ||||||
| 系统本身开箱即用。 | 系统本身开箱即用。 | ||||||
|  |  | ||||||
| @@ -159,6 +170,8 @@ sudo service nginx restart | |||||||
|    + 例子:`SQL_DSN=root:123456@tcp(localhost:3306)/one-api` |    + 例子:`SQL_DSN=root:123456@tcp(localhost:3306)/one-api` | ||||||
| 4. `FRONTEND_BASE_URL`:设置之后将使用指定的前端地址,而非后端地址。 | 4. `FRONTEND_BASE_URL`:设置之后将使用指定的前端地址,而非后端地址。 | ||||||
|    + 例子:`FRONTEND_BASE_URL=https://openai.justsong.cn` |    + 例子:`FRONTEND_BASE_URL=https://openai.justsong.cn` | ||||||
|  | 5. `SYNC_FREQUENCY`:设置之后将定期与数据库同步配置,单位为秒,未设置则不进行同步。 | ||||||
|  |    + 例子:`SYNC_FREQUENCY=60` | ||||||
|  |  | ||||||
| ### 命令行参数 | ### 命令行参数 | ||||||
| 1. `--port <port_number>`: 指定服务器监听的端口号,默认为 `3000`。 | 1. `--port <port_number>`: 指定服务器监听的端口号,默认为 `3000`。 | ||||||
| @@ -176,3 +189,10 @@ https://openai.justsong.cn | |||||||
| ### 截图展示 | ### 截图展示 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## 常见问题 | ||||||
|  | 1. 账户额度足够为什么提示额度不足? | ||||||
|  |    + 请检查你的令牌额度是否足够,这个和账户额度是分开的。 | ||||||
|  |    + 令牌额度仅供用户设置最大使用量,用户可自由设置。 | ||||||
|  | 2. 宝塔部署后访问出现空白页面? | ||||||
|  |    + 自动配置的问题,详见[#97](https://github.com/songquanpeng/one-api/issues/97)。 | ||||||
| @@ -75,6 +75,9 @@ func countToken(text string) int { | |||||||
| func Relay(c *gin.Context) { | func Relay(c *gin.Context) { | ||||||
| 	err := relayHelper(c) | 	err := relayHelper(c) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | 		if err.StatusCode == http.StatusTooManyRequests { | ||||||
|  | 			err.OpenAIError.Message = "负载已满,请稍后再试,或升级账户以提升服务质量。" | ||||||
|  | 		} | ||||||
| 		c.JSON(err.StatusCode, gin.H{ | 		c.JSON(err.StatusCode, gin.H{ | ||||||
| 			"error": err.OpenAIError, | 			"error": err.OpenAIError, | ||||||
| 		}) | 		}) | ||||||
| @@ -259,6 +262,7 @@ func relayHelper(c *gin.Context) *OpenAIErrorWithStatusCode { | |||||||
| 		c.Writer.Header().Set("Cache-Control", "no-cache") | 		c.Writer.Header().Set("Cache-Control", "no-cache") | ||||||
| 		c.Writer.Header().Set("Connection", "keep-alive") | 		c.Writer.Header().Set("Connection", "keep-alive") | ||||||
| 		c.Writer.Header().Set("Transfer-Encoding", "chunked") | 		c.Writer.Header().Set("Transfer-Encoding", "chunked") | ||||||
|  | 		c.Writer.Header().Set("X-Accel-Buffering", "no") | ||||||
| 		c.Stream(func(w io.Writer) bool { | 		c.Stream(func(w io.Writer) bool { | ||||||
| 			select { | 			select { | ||||||
| 			case data := <-dataChan: | 			case data := <-dataChan: | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								main.go
									
									
									
									
									
								
							| @@ -47,6 +47,13 @@ func main() { | |||||||
|  |  | ||||||
| 	// Initialize options | 	// Initialize options | ||||||
| 	model.InitOptionMap() | 	model.InitOptionMap() | ||||||
|  | 	if os.Getenv("SYNC_FREQUENCY") != "" { | ||||||
|  | 		frequency, err := strconv.Atoi(os.Getenv("SYNC_FREQUENCY")) | ||||||
|  | 		if err != nil { | ||||||
|  | 			common.FatalLog(err) | ||||||
|  | 		} | ||||||
|  | 		go model.SyncOptions(frequency) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Initialize HTTP server | 	// Initialize HTTP server | ||||||
| 	server := gin.Default() | 	server := gin.Default() | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import ( | |||||||
| 	"one-api/common" | 	"one-api/common" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type Option struct { | type Option struct { | ||||||
| @@ -59,6 +60,10 @@ func InitOptionMap() { | |||||||
| 	common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString() | 	common.OptionMap["ModelRatio"] = common.ModelRatio2JSONString() | ||||||
| 	common.OptionMap["TopUpLink"] = common.TopUpLink | 	common.OptionMap["TopUpLink"] = common.TopUpLink | ||||||
| 	common.OptionMapRWMutex.Unlock() | 	common.OptionMapRWMutex.Unlock() | ||||||
|  | 	loadOptionsFromDatabase() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func loadOptionsFromDatabase() { | ||||||
| 	options, _ := AllOption() | 	options, _ := AllOption() | ||||||
| 	for _, option := range options { | 	for _, option := range options { | ||||||
| 		err := updateOptionMap(option.Key, option.Value) | 		err := updateOptionMap(option.Key, option.Value) | ||||||
| @@ -68,6 +73,14 @@ func InitOptionMap() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func SyncOptions(frequency int) { | ||||||
|  | 	for { | ||||||
|  | 		time.Sleep(time.Duration(frequency) * time.Second) | ||||||
|  | 		common.SysLog("Syncing options from database") | ||||||
|  | 		loadOptionsFromDatabase() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func UpdateOption(key string, value string) error { | func UpdateOption(key string, value string) error { | ||||||
| 	// Save to database first | 	// Save to database first | ||||||
| 	option := Option{ | 	option := Option{ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user