mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-10-31 05:43:42 +08:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			v0.4.0-alp
			...
			v0.4.1-alp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 813bf0bd66 | ||
|  | 45e9fd66e7 | ||
|  | e0d0674f81 | 
| @@ -46,6 +46,8 @@ _✨ All in one 的 OpenAI 接口,整合各种 API 访问方式,开箱即用 | |||||||
|  |  | ||||||
| > **Warning**:使用 Docker 拉取的最新镜像可能是 `alpha` 版本,如果追求稳定性请手动指定版本。 | > **Warning**:使用 Docker 拉取的最新镜像可能是 `alpha` 版本,如果追求稳定性请手动指定版本。 | ||||||
|  |  | ||||||
|  | > **Warning**:从 `v0.3` 版本升级到 `v0.4` 版本需要手动迁移数据库,请手动执行[数据库迁移脚本](./bin/migration_v0.3-v0.4.sql)。 | ||||||
|  |  | ||||||
| ## 功能 | ## 功能 | ||||||
| 1. 支持多种 API 访问渠道,欢迎 PR 或提 issue 添加更多渠道: | 1. 支持多种 API 访问渠道,欢迎 PR 或提 issue 添加更多渠道: | ||||||
|    + [x] OpenAI 官方通道 |    + [x] OpenAI 官方通道 | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								bin/migration_v0.3-v0.4.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								bin/migration_v0.3-v0.4.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | INSERT INTO abilities (`group`, model, channel_id, enabled) | ||||||
|  | SELECT c.`group`, m.model, c.id, 1 | ||||||
|  | FROM channels c | ||||||
|  | CROSS JOIN ( | ||||||
|  |     SELECT 'gpt-3.5-turbo' AS model UNION ALL | ||||||
|  |     SELECT 'gpt-3.5-turbo-0301' AS model UNION ALL | ||||||
|  |     SELECT 'gpt-4' AS model UNION ALL | ||||||
|  |     SELECT 'gpt-4-0314' AS model | ||||||
|  | ) AS m | ||||||
|  | WHERE c.status = 1 | ||||||
|  |   AND NOT EXISTS ( | ||||||
|  |     SELECT 1 | ||||||
|  |     FROM abilities a | ||||||
|  |     WHERE a.`group` = c.`group` | ||||||
|  |       AND a.model = m.model | ||||||
|  |       AND a.channel_id = c.id | ||||||
|  | ); | ||||||
| @@ -25,6 +25,7 @@ var OptionMap map[string]string | |||||||
| var OptionMapRWMutex sync.RWMutex | var OptionMapRWMutex sync.RWMutex | ||||||
|  |  | ||||||
| var ItemsPerPage = 10 | var ItemsPerPage = 10 | ||||||
|  | var MaxRecentItems = 100 | ||||||
|  |  | ||||||
| var PasswordLoginEnabled = true | var PasswordLoginEnabled = true | ||||||
| var PasswordRegisterEnabled = true | var PasswordRegisterEnabled = true | ||||||
|   | |||||||
							
								
								
									
										86
									
								
								controller/log.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								controller/log.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | |||||||
|  | package controller | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/gin-gonic/gin" | ||||||
|  | 	"one-api/common" | ||||||
|  | 	"one-api/model" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func GetAllLogs(c *gin.Context) { | ||||||
|  | 	p, _ := strconv.Atoi(c.Query("p")) | ||||||
|  | 	if p < 0 { | ||||||
|  | 		p = 0 | ||||||
|  | 	} | ||||||
|  | 	logType, _ := strconv.Atoi(c.Query("type")) | ||||||
|  | 	logs, err := model.GetAllLogs(logType, p*common.ItemsPerPage, common.ItemsPerPage) | ||||||
|  | 	if err != nil { | ||||||
|  | 		c.JSON(200, gin.H{ | ||||||
|  | 			"success": false, | ||||||
|  | 			"message": err.Error(), | ||||||
|  | 		}) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	c.JSON(200, gin.H{ | ||||||
|  | 		"success": true, | ||||||
|  | 		"message": "", | ||||||
|  | 		"data":    logs, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetUserLogs(c *gin.Context) { | ||||||
|  | 	p, _ := strconv.Atoi(c.Query("p")) | ||||||
|  | 	if p < 0 { | ||||||
|  | 		p = 0 | ||||||
|  | 	} | ||||||
|  | 	userId := c.GetInt("id") | ||||||
|  | 	logType, _ := strconv.Atoi(c.Query("type")) | ||||||
|  | 	logs, err := model.GetUserLogs(userId, logType, p*common.ItemsPerPage, common.ItemsPerPage) | ||||||
|  | 	if err != nil { | ||||||
|  | 		c.JSON(200, gin.H{ | ||||||
|  | 			"success": false, | ||||||
|  | 			"message": err.Error(), | ||||||
|  | 		}) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	c.JSON(200, gin.H{ | ||||||
|  | 		"success": true, | ||||||
|  | 		"message": "", | ||||||
|  | 		"data":    logs, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func SearchAllLogs(c *gin.Context) { | ||||||
|  | 	keyword := c.Query("keyword") | ||||||
|  | 	logs, err := model.SearchAllLogs(keyword) | ||||||
|  | 	if err != nil { | ||||||
|  | 		c.JSON(200, gin.H{ | ||||||
|  | 			"success": false, | ||||||
|  | 			"message": err.Error(), | ||||||
|  | 		}) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	c.JSON(200, gin.H{ | ||||||
|  | 		"success": true, | ||||||
|  | 		"message": "", | ||||||
|  | 		"data":    logs, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func SearchUserLogs(c *gin.Context) { | ||||||
|  | 	keyword := c.Query("keyword") | ||||||
|  | 	userId := c.GetInt("id") | ||||||
|  | 	logs, err := model.SearchUserLogs(userId, keyword) | ||||||
|  | 	if err != nil { | ||||||
|  | 		c.JSON(200, gin.H{ | ||||||
|  | 			"success": false, | ||||||
|  | 			"message": err.Error(), | ||||||
|  | 		}) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	c.JSON(200, gin.H{ | ||||||
|  | 		"success": true, | ||||||
|  | 		"message": "", | ||||||
|  | 		"data":    logs, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
| @@ -13,9 +13,6 @@ type Ability struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| func GetRandomSatisfiedChannel(group string, model string) (*Channel, error) { | func GetRandomSatisfiedChannel(group string, model string) (*Channel, error) { | ||||||
| 	if group == "default" { |  | ||||||
| 		return GetRandomChannel() |  | ||||||
| 	} |  | ||||||
| 	ability := Ability{} | 	ability := Ability{} | ||||||
| 	var err error = nil | 	var err error = nil | ||||||
| 	if common.UsingSQLite { | 	if common.UsingSQLite { | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								model/log.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								model/log.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | package model | ||||||
|  |  | ||||||
|  | import "one-api/common" | ||||||
|  |  | ||||||
|  | type Log struct { | ||||||
|  | 	Id        int    `json:"id"` | ||||||
|  | 	UserId    int    `json:"user_id" gorm:"index"` | ||||||
|  | 	CreatedAt int64  `json:"created_at" gorm:"bigint"` | ||||||
|  | 	Type      int    `json:"type" gorm:"index"` | ||||||
|  | 	Content   string `json:"content"` | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func RecordLog(userId int, logType int, content string) { | ||||||
|  | 	log := &Log{ | ||||||
|  | 		UserId:    userId, | ||||||
|  | 		CreatedAt: common.GetTimestamp(), | ||||||
|  | 		Type:      logType, | ||||||
|  | 		Content:   content, | ||||||
|  | 	} | ||||||
|  | 	err := DB.Create(log).Error | ||||||
|  | 	if err != nil { | ||||||
|  | 		common.SysError("failed to record log: " + err.Error()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetAllLogs(logType int, startIdx int, num int) (logs []*Log, err error) { | ||||||
|  | 	err = DB.Where("type = ?", logType).Order("id desc").Limit(num).Offset(startIdx).Find(&logs).Error | ||||||
|  | 	return logs, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func GetUserLogs(userId int, logType int, startIdx int, num int) (logs []*Log, err error) { | ||||||
|  | 	err = DB.Where("user_id = ? and type = ?", userId, logType).Order("id desc").Limit(num).Offset(startIdx).Find(&logs).Error | ||||||
|  | 	return logs, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func SearchAllLogs(keyword string) (logs []*Log, err error) { | ||||||
|  | 	err = DB.Where("type = ? or content LIKE ?", keyword, keyword+"%").Order("id desc").Limit(common.MaxRecentItems).Find(&logs).Error | ||||||
|  | 	return logs, err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func SearchUserLogs(userId int, keyword string) (logs []*Log, err error) { | ||||||
|  | 	err = DB.Where("user_id = ? and type = ?", userId, keyword).Order("id desc").Limit(common.MaxRecentItems).Find(&logs).Error | ||||||
|  | 	return logs, err | ||||||
|  | } | ||||||
| @@ -83,7 +83,7 @@ func (redemption *Redemption) SelectUpdate() error { | |||||||
| // Update Make sure your token's fields is completed, because this will update non-zero values | // Update Make sure your token's fields is completed, because this will update non-zero values | ||||||
| func (redemption *Redemption) Update() error { | func (redemption *Redemption) Update() error { | ||||||
| 	var err error | 	var err error | ||||||
| 	err = DB.Model(redemption).Select("name", "status", "redeemed_time").Updates(redemption).Error | 	err = DB.Model(redemption).Select("name", "status", "quota", "redeemed_time").Updates(redemption).Error | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -93,5 +93,10 @@ func SetApiRouter(router *gin.Engine) { | |||||||
| 			redemptionRoute.PUT("/", controller.UpdateRedemption) | 			redemptionRoute.PUT("/", controller.UpdateRedemption) | ||||||
| 			redemptionRoute.DELETE("/:id", controller.DeleteRedemption) | 			redemptionRoute.DELETE("/:id", controller.DeleteRedemption) | ||||||
| 		} | 		} | ||||||
|  | 		logRoute := apiRouter.Group("/log") | ||||||
|  | 		logRoute.GET("/", middleware.AdminAuth(), controller.GetAllLogs) | ||||||
|  | 		logRoute.GET("/search", middleware.AdminAuth(), controller.SearchAllLogs) | ||||||
|  | 		logRoute.GET("/self", middleware.UserAuth(), controller.GetUserLogs) | ||||||
|  | 		logRoute.GET("/self/search", middleware.UserAuth(), controller.SearchUserLogs) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user