mirror of
				https://github.com/songquanpeng/one-api.git
				synced 2025-11-04 15:53:42 +08:00 
			
		
		
		
	chore: reorganize helper related package
This commit is contained in:
		@@ -2,16 +2,14 @@ package helper
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"html/template"
 | 
			
		||||
	"log"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func OpenBrowser(url string) {
 | 
			
		||||
@@ -79,31 +77,6 @@ func Bytes2Size(num int64) string {
 | 
			
		||||
	return numStr + " " + unit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Seconds2Time(num int) (time string) {
 | 
			
		||||
	if num/31104000 > 0 {
 | 
			
		||||
		time += strconv.Itoa(num/31104000) + " 年 "
 | 
			
		||||
		num %= 31104000
 | 
			
		||||
	}
 | 
			
		||||
	if num/2592000 > 0 {
 | 
			
		||||
		time += strconv.Itoa(num/2592000) + " 个月 "
 | 
			
		||||
		num %= 2592000
 | 
			
		||||
	}
 | 
			
		||||
	if num/86400 > 0 {
 | 
			
		||||
		time += strconv.Itoa(num/86400) + " 天 "
 | 
			
		||||
		num %= 86400
 | 
			
		||||
	}
 | 
			
		||||
	if num/3600 > 0 {
 | 
			
		||||
		time += strconv.Itoa(num/3600) + " 小时 "
 | 
			
		||||
		num %= 3600
 | 
			
		||||
	}
 | 
			
		||||
	if num/60 > 0 {
 | 
			
		||||
		time += strconv.Itoa(num/60) + " 分钟 "
 | 
			
		||||
		num %= 60
 | 
			
		||||
	}
 | 
			
		||||
	time += strconv.Itoa(num) + " 秒"
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Interface2String(inter interface{}) string {
 | 
			
		||||
	switch inter := inter.(type) {
 | 
			
		||||
	case string:
 | 
			
		||||
@@ -128,65 +101,8 @@ func IntMax(a int, b int) int {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetUUID() string {
 | 
			
		||||
	code := uuid.New().String()
 | 
			
		||||
	code = strings.Replace(code, "-", "", -1)
 | 
			
		||||
	return code
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const keyChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
			
		||||
const keyNumbers = "0123456789"
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GenerateKey() string {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	key := make([]byte, 48)
 | 
			
		||||
	for i := 0; i < 16; i++ {
 | 
			
		||||
		key[i] = keyChars[rand.Intn(len(keyChars))]
 | 
			
		||||
	}
 | 
			
		||||
	uuid_ := GetUUID()
 | 
			
		||||
	for i := 0; i < 32; i++ {
 | 
			
		||||
		c := uuid_[i]
 | 
			
		||||
		if i%2 == 0 && c >= 'a' && c <= 'z' {
 | 
			
		||||
			c = c - 'a' + 'A'
 | 
			
		||||
		}
 | 
			
		||||
		key[i+16] = c
 | 
			
		||||
	}
 | 
			
		||||
	return string(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetRandomString(length int) string {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	key := make([]byte, length)
 | 
			
		||||
	for i := 0; i < length; i++ {
 | 
			
		||||
		key[i] = keyChars[rand.Intn(len(keyChars))]
 | 
			
		||||
	}
 | 
			
		||||
	return string(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetRandomNumberString(length int) string {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	key := make([]byte, length)
 | 
			
		||||
	for i := 0; i < length; i++ {
 | 
			
		||||
		key[i] = keyNumbers[rand.Intn(len(keyNumbers))]
 | 
			
		||||
	}
 | 
			
		||||
	return string(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetTimestamp() int64 {
 | 
			
		||||
	return time.Now().Unix()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetTimeString() string {
 | 
			
		||||
	now := time.Now()
 | 
			
		||||
	return fmt.Sprintf("%s%d", now.Format("20060102150405"), now.UnixNano()%1e9)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GenRequestID() string {
 | 
			
		||||
	return GetTimeString() + GetRandomNumberString(8)
 | 
			
		||||
	return GetTimeString() + random.GetRandomNumberString(8)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Max(a int, b int) int {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								common/helper/time.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								common/helper/time.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package helper
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func GetTimestamp() int64 {
 | 
			
		||||
	return time.Now().Unix()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetTimeString() string {
 | 
			
		||||
	now := time.Now()
 | 
			
		||||
	return fmt.Sprintf("%s%d", now.Format("20060102150405"), now.UnixNano()%1e9)
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
package common
 | 
			
		||||
 | 
			
		||||
import "math/rand"
 | 
			
		||||
 | 
			
		||||
// RandRange returns a random number between min and max (max is not included)
 | 
			
		||||
func RandRange(min, max int) int {
 | 
			
		||||
	return min + rand.Intn(max-min)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										61
									
								
								common/random/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								common/random/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
package random
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func GetUUID() string {
 | 
			
		||||
	code := uuid.New().String()
 | 
			
		||||
	code = strings.Replace(code, "-", "", -1)
 | 
			
		||||
	return code
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const keyChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
			
		||||
const keyNumbers = "0123456789"
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GenerateKey() string {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	key := make([]byte, 48)
 | 
			
		||||
	for i := 0; i < 16; i++ {
 | 
			
		||||
		key[i] = keyChars[rand.Intn(len(keyChars))]
 | 
			
		||||
	}
 | 
			
		||||
	uuid_ := GetUUID()
 | 
			
		||||
	for i := 0; i < 32; i++ {
 | 
			
		||||
		c := uuid_[i]
 | 
			
		||||
		if i%2 == 0 && c >= 'a' && c <= 'z' {
 | 
			
		||||
			c = c - 'a' + 'A'
 | 
			
		||||
		}
 | 
			
		||||
		key[i+16] = c
 | 
			
		||||
	}
 | 
			
		||||
	return string(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetRandomString(length int) string {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	key := make([]byte, length)
 | 
			
		||||
	for i := 0; i < length; i++ {
 | 
			
		||||
		key[i] = keyChars[rand.Intn(len(keyChars))]
 | 
			
		||||
	}
 | 
			
		||||
	return string(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetRandomNumberString(length int) string {
 | 
			
		||||
	rand.Seed(time.Now().UnixNano())
 | 
			
		||||
	key := make([]byte, length)
 | 
			
		||||
	for i := 0; i < length; i++ {
 | 
			
		||||
		key[i] = keyNumbers[rand.Intn(len(keyNumbers))]
 | 
			
		||||
	}
 | 
			
		||||
	return string(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RandRange returns a random number between min and max (max is not included)
 | 
			
		||||
func RandRange(min, max int) int {
 | 
			
		||||
	return min + rand.Intn(max-min)
 | 
			
		||||
}
 | 
			
		||||
@@ -9,8 +9,8 @@ import (
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/controller"
 | 
			
		||||
	"github.com/songquanpeng/one-api/model"
 | 
			
		||||
	"net/http"
 | 
			
		||||
@@ -220,7 +220,7 @@ func GitHubBind(c *gin.Context) {
 | 
			
		||||
 | 
			
		||||
func GenerateOAuthCode(c *gin.Context) {
 | 
			
		||||
	session := sessions.Default(c)
 | 
			
		||||
	state := helper.GetRandomString(12)
 | 
			
		||||
	state := random.GetRandomString(12)
 | 
			
		||||
	session.Set("oauth_state", state)
 | 
			
		||||
	err := session.Save()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,13 +2,13 @@ package controller
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/billing"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func GetGroups(c *gin.Context) {
 | 
			
		||||
	groupNames := make([]string, 0)
 | 
			
		||||
	for groupName := range common.GroupRatio {
 | 
			
		||||
	for groupName := range billing.GroupRatio {
 | 
			
		||||
		groupNames = append(groupNames, groupName)
 | 
			
		||||
	}
 | 
			
		||||
	c.JSON(http.StatusOK, gin.H{
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/model"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
@@ -106,7 +107,7 @@ func AddRedemption(c *gin.Context) {
 | 
			
		||||
	}
 | 
			
		||||
	var keys []string
 | 
			
		||||
	for i := 0; i < redemption.Count; i++ {
 | 
			
		||||
		key := helper.GetUUID()
 | 
			
		||||
		key := random.GetUUID()
 | 
			
		||||
		cleanRedemption := model.Redemption{
 | 
			
		||||
			UserId:      c.GetInt("id"),
 | 
			
		||||
			Name:        redemption.Name,
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/network"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/model"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
@@ -141,7 +142,7 @@ func AddToken(c *gin.Context) {
 | 
			
		||||
	cleanToken := model.Token{
 | 
			
		||||
		UserId:         c.GetInt("id"),
 | 
			
		||||
		Name:           token.Name,
 | 
			
		||||
		Key:            helper.GenerateKey(),
 | 
			
		||||
		Key:            random.GenerateKey(),
 | 
			
		||||
		CreatedTime:    helper.GetTimestamp(),
 | 
			
		||||
		AccessedTime:   helper.GetTimestamp(),
 | 
			
		||||
		ExpiredTime:    token.ExpiredTime,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/model"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
@@ -287,7 +287,7 @@ func GenerateAccessToken(c *gin.Context) {
 | 
			
		||||
		})
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	user.AccessToken = helper.GetUUID()
 | 
			
		||||
	user.AccessToken = random.GetUUID()
 | 
			
		||||
 | 
			
		||||
	if model.DB.Where("access_token = ?", user.AccessToken).First(user).RowsAffected != 0 {
 | 
			
		||||
		c.JSON(http.StatusOK, gin.H{
 | 
			
		||||
@@ -324,7 +324,7 @@ func GetAffCode(c *gin.Context) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if user.AffCode == "" {
 | 
			
		||||
		user.AffCode = helper.GetRandomString(4)
 | 
			
		||||
		user.AffCode = random.GetRandomString(4)
 | 
			
		||||
		if err := user.Update(false); err != nil {
 | 
			
		||||
			c.JSON(http.StatusOK, gin.H{
 | 
			
		||||
				"success": false,
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"math/rand"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
@@ -247,7 +248,7 @@ func CacheGetRandomSatisfiedChannel(group string, model string, ignoreFirstPrior
 | 
			
		||||
	idx := rand.Intn(endIdx)
 | 
			
		||||
	if ignoreFirstPriority {
 | 
			
		||||
		if endIdx < len(channels) { // which means there are more than one priority
 | 
			
		||||
			idx = common.RandRange(endIdx, len(channels))
 | 
			
		||||
			idx = random.RandRange(endIdx, len(channels))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return channels[idx], nil
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/env"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"gorm.io/driver/mysql"
 | 
			
		||||
	"gorm.io/driver/postgres"
 | 
			
		||||
	"gorm.io/driver/sqlite"
 | 
			
		||||
@@ -34,7 +35,7 @@ func CreateRootAccountIfNeed() error {
 | 
			
		||||
			Role:        common.RoleRootUser,
 | 
			
		||||
			Status:      common.UserStatusEnabled,
 | 
			
		||||
			DisplayName: "Root User",
 | 
			
		||||
			AccessToken: helper.GetUUID(),
 | 
			
		||||
			AccessToken: random.GetUUID(),
 | 
			
		||||
			Quota:       500000000000000,
 | 
			
		||||
		}
 | 
			
		||||
		DB.Create(&rootUser)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
package model
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/billing"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
@@ -66,9 +66,9 @@ func InitOptionMap() {
 | 
			
		||||
	config.OptionMap["QuotaForInvitee"] = strconv.FormatInt(config.QuotaForInvitee, 10)
 | 
			
		||||
	config.OptionMap["QuotaRemindThreshold"] = strconv.FormatInt(config.QuotaRemindThreshold, 10)
 | 
			
		||||
	config.OptionMap["PreConsumedQuota"] = strconv.FormatInt(config.PreConsumedQuota, 10)
 | 
			
		||||
	config.OptionMap["ModelRatio"] = common.ModelRatio2JSONString()
 | 
			
		||||
	config.OptionMap["GroupRatio"] = common.GroupRatio2JSONString()
 | 
			
		||||
	config.OptionMap["CompletionRatio"] = common.CompletionRatio2JSONString()
 | 
			
		||||
	config.OptionMap["ModelRatio"] = billing.ModelRatio2JSONString()
 | 
			
		||||
	config.OptionMap["GroupRatio"] = billing.GroupRatio2JSONString()
 | 
			
		||||
	config.OptionMap["CompletionRatio"] = billing.CompletionRatio2JSONString()
 | 
			
		||||
	config.OptionMap["TopUpLink"] = config.TopUpLink
 | 
			
		||||
	config.OptionMap["ChatLink"] = config.ChatLink
 | 
			
		||||
	config.OptionMap["QuotaPerUnit"] = strconv.FormatFloat(config.QuotaPerUnit, 'f', -1, 64)
 | 
			
		||||
@@ -82,7 +82,7 @@ func loadOptionsFromDatabase() {
 | 
			
		||||
	options, _ := AllOption()
 | 
			
		||||
	for _, option := range options {
 | 
			
		||||
		if option.Key == "ModelRatio" {
 | 
			
		||||
			option.Value = common.AddNewMissingRatio(option.Value)
 | 
			
		||||
			option.Value = billing.AddNewMissingRatio(option.Value)
 | 
			
		||||
		}
 | 
			
		||||
		err := updateOptionMap(option.Key, option.Value)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -209,11 +209,11 @@ func updateOptionMap(key string, value string) (err error) {
 | 
			
		||||
	case "RetryTimes":
 | 
			
		||||
		config.RetryTimes, _ = strconv.Atoi(value)
 | 
			
		||||
	case "ModelRatio":
 | 
			
		||||
		err = common.UpdateModelRatioByJSONString(value)
 | 
			
		||||
		err = billing.UpdateModelRatioByJSONString(value)
 | 
			
		||||
	case "GroupRatio":
 | 
			
		||||
		err = common.UpdateGroupRatioByJSONString(value)
 | 
			
		||||
		err = billing.UpdateGroupRatioByJSONString(value)
 | 
			
		||||
	case "CompletionRatio":
 | 
			
		||||
		err = common.UpdateCompletionRatioByJSONString(value)
 | 
			
		||||
		err = billing.UpdateCompletionRatioByJSONString(value)
 | 
			
		||||
	case "TopUpLink":
 | 
			
		||||
		config.TopUpLink = value
 | 
			
		||||
	case "ChatLink":
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/blacklist"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
@@ -108,8 +108,8 @@ func (user *User) Insert(inviterId int) error {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	user.Quota = config.QuotaForNewUser
 | 
			
		||||
	user.AccessToken = helper.GetUUID()
 | 
			
		||||
	user.AffCode = helper.GetRandomString(4)
 | 
			
		||||
	user.AccessToken = random.GetUUID()
 | 
			
		||||
	user.AffCode = random.GetRandomString(4)
 | 
			
		||||
	result := DB.Create(user)
 | 
			
		||||
	if result.Error != nil {
 | 
			
		||||
		return result.Error
 | 
			
		||||
@@ -152,7 +152,7 @@ func (user *User) Delete() error {
 | 
			
		||||
		return errors.New("id 为空!")
 | 
			
		||||
	}
 | 
			
		||||
	blacklist.BanUser(user.Id)
 | 
			
		||||
	user.Username = fmt.Sprintf("deleted_%s", helper.GetUUID())
 | 
			
		||||
	user.Username = fmt.Sprintf("deleted_%s", random.GetUUID())
 | 
			
		||||
	user.Status = common.UserStatusDeleted
 | 
			
		||||
	err := DB.Model(user).Updates(user).Error
 | 
			
		||||
	return err
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package common
 | 
			
		||||
package billing
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
package common
 | 
			
		||||
package billing
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
@@ -8,6 +8,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/model"
 | 
			
		||||
@@ -53,7 +54,7 @@ func responseAIProxyLibrary2OpenAI(response *LibraryResponse) *openai.TextRespon
 | 
			
		||||
		FinishReason: "stop",
 | 
			
		||||
	}
 | 
			
		||||
	fullTextResponse := openai.TextResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Choices: []openai.TextResponseChoice{choice},
 | 
			
		||||
@@ -66,7 +67,7 @@ func documentsAIProxyLibrary(documents []LibraryDocument) *openai.ChatCompletion
 | 
			
		||||
	choice.Delta.Content = aiProxyDocuments2Markdown(documents)
 | 
			
		||||
	choice.FinishReason = &constant.StopFinishReason
 | 
			
		||||
	return &openai.ChatCompletionsStreamResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion.chunk",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Model:   "",
 | 
			
		||||
@@ -78,7 +79,7 @@ func streamResponseAIProxyLibrary2OpenAI(response *LibraryStreamResponse) *opena
 | 
			
		||||
	var choice openai.ChatCompletionsStreamResponseChoice
 | 
			
		||||
	choice.Delta.Content = response.Content
 | 
			
		||||
	return &openai.ChatCompletionsStreamResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion.chunk",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Model:   response.Model,
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/image"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/model"
 | 
			
		||||
@@ -155,7 +156,7 @@ type ChatPromptFeedback struct {
 | 
			
		||||
 | 
			
		||||
func responseGeminiChat2OpenAI(response *ChatResponse) *openai.TextResponse {
 | 
			
		||||
	fullTextResponse := openai.TextResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Choices: make([]openai.TextResponseChoice, 0, len(response.Candidates)),
 | 
			
		||||
@@ -233,7 +234,7 @@ func StreamHandler(c *gin.Context, resp *http.Response) (*model.ErrorWithStatusC
 | 
			
		||||
			var choice openai.ChatCompletionsStreamResponseChoice
 | 
			
		||||
			choice.Delta.Content = dummy.Content
 | 
			
		||||
			response := openai.ChatCompletionsStreamResponse{
 | 
			
		||||
				Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
				Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
				Object:  "chat.completion.chunk",
 | 
			
		||||
				Created: helper.GetTimestamp(),
 | 
			
		||||
				Model:   "gemini-pro",
 | 
			
		||||
 
 | 
			
		||||
@@ -5,13 +5,14 @@ import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
@@ -51,7 +52,7 @@ func responseOllama2OpenAI(response *ChatResponse) *openai.TextResponse {
 | 
			
		||||
		choice.FinishReason = "stop"
 | 
			
		||||
	}
 | 
			
		||||
	fullTextResponse := openai.TextResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Choices: []openai.TextResponseChoice{choice},
 | 
			
		||||
@@ -72,7 +73,7 @@ func streamResponseOllama2OpenAI(ollamaResponse *ChatResponse) *openai.ChatCompl
 | 
			
		||||
		choice.FinishReason = &constant.StopFinishReason
 | 
			
		||||
	}
 | 
			
		||||
	response := openai.ChatCompletionsStreamResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion.chunk",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Model:   ollamaResponse.Model,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,10 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/pkoukk/tiktoken-go"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/image"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/billing"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/model"
 | 
			
		||||
	"math"
 | 
			
		||||
	"strings"
 | 
			
		||||
@@ -28,7 +28,7 @@ func InitTokenEncoders() {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.FatalLog(fmt.Sprintf("failed to get gpt-4 token encoder: %s", err.Error()))
 | 
			
		||||
	}
 | 
			
		||||
	for model := range common.ModelRatio {
 | 
			
		||||
	for model := range billing.ModelRatio {
 | 
			
		||||
		if strings.HasPrefix(model, "gpt-3.5") {
 | 
			
		||||
			tokenEncoderMap[model] = gpt35TokenEncoder
 | 
			
		||||
		} else if strings.HasPrefix(model, "gpt-4") {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/model"
 | 
			
		||||
@@ -74,7 +75,7 @@ func streamResponsePaLM2OpenAI(palmResponse *ChatResponse) *openai.ChatCompletio
 | 
			
		||||
 | 
			
		||||
func StreamHandler(c *gin.Context, resp *http.Response) (*model.ErrorWithStatusCode, string) {
 | 
			
		||||
	responseText := ""
 | 
			
		||||
	responseId := fmt.Sprintf("chatcmpl-%s", helper.GetUUID())
 | 
			
		||||
	responseId := fmt.Sprintf("chatcmpl-%s", random.GetUUID())
 | 
			
		||||
	createdTime := helper.GetTimestamp()
 | 
			
		||||
	dataChan := make(chan string)
 | 
			
		||||
	stopChan := make(chan bool)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/conv"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/model"
 | 
			
		||||
@@ -41,7 +42,7 @@ func ConvertRequest(request model.GeneralOpenAIRequest) *ChatRequest {
 | 
			
		||||
	return &ChatRequest{
 | 
			
		||||
		Timestamp:   helper.GetTimestamp(),
 | 
			
		||||
		Expired:     helper.GetTimestamp() + 24*60*60,
 | 
			
		||||
		QueryID:     helper.GetUUID(),
 | 
			
		||||
		QueryID:     random.GetUUID(),
 | 
			
		||||
		Temperature: request.Temperature,
 | 
			
		||||
		TopP:        request.TopP,
 | 
			
		||||
		Stream:      stream,
 | 
			
		||||
@@ -71,7 +72,7 @@ func responseTencent2OpenAI(response *ChatResponse) *openai.TextResponse {
 | 
			
		||||
 | 
			
		||||
func streamResponseTencent2OpenAI(TencentResponse *ChatResponse) *openai.ChatCompletionsStreamResponse {
 | 
			
		||||
	response := openai.ChatCompletionsStreamResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion.chunk",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Model:   "tencent-hunyuan",
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/helper"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/random"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/model"
 | 
			
		||||
@@ -62,7 +63,7 @@ func getToolCalls(response *ChatResponse) []model.Tool {
 | 
			
		||||
		return toolCalls
 | 
			
		||||
	}
 | 
			
		||||
	toolCall := model.Tool{
 | 
			
		||||
		Id:       fmt.Sprintf("call_%s", helper.GetUUID()),
 | 
			
		||||
		Id:       fmt.Sprintf("call_%s", random.GetUUID()),
 | 
			
		||||
		Type:     "function",
 | 
			
		||||
		Function: *item.FunctionCall,
 | 
			
		||||
	}
 | 
			
		||||
@@ -88,7 +89,7 @@ func responseXunfei2OpenAI(response *ChatResponse) *openai.TextResponse {
 | 
			
		||||
		FinishReason: constant.StopFinishReason,
 | 
			
		||||
	}
 | 
			
		||||
	fullTextResponse := openai.TextResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Choices: []openai.TextResponseChoice{choice},
 | 
			
		||||
@@ -112,7 +113,7 @@ func streamResponseXunfei2OpenAI(xunfeiResponse *ChatResponse) *openai.ChatCompl
 | 
			
		||||
		choice.FinishReason = &constant.StopFinishReason
 | 
			
		||||
	}
 | 
			
		||||
	response := openai.ChatCompletionsStreamResponse{
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", helper.GetUUID()),
 | 
			
		||||
		Id:      fmt.Sprintf("chatcmpl-%s", random.GetUUID()),
 | 
			
		||||
		Object:  "chat.completion.chunk",
 | 
			
		||||
		Created: helper.GetTimestamp(),
 | 
			
		||||
		Model:   "SparkDesk",
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/model"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/billing"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channeltype"
 | 
			
		||||
	relaymodel "github.com/songquanpeng/one-api/relay/model"
 | 
			
		||||
@@ -48,8 +49,8 @@ func RelayAudioHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatus
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	modelRatio := common.GetModelRatio(audioModel)
 | 
			
		||||
	groupRatio := common.GetGroupRatio(group)
 | 
			
		||||
	modelRatio := billing.GetModelRatio(audioModel)
 | 
			
		||||
	groupRatio := billing.GetGroupRatio(group)
 | 
			
		||||
	ratio := modelRatio * groupRatio
 | 
			
		||||
	var quota int64
 | 
			
		||||
	var preConsumedQuota int64
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import (
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/config"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/model"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/billing"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channeltype"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
@@ -165,7 +166,7 @@ func postConsumeQuota(ctx context.Context, usage *relaymodel.Usage, meta *util.R
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var quota int64
 | 
			
		||||
	completionRatio := common.GetCompletionRatio(textRequest.Model)
 | 
			
		||||
	completionRatio := billing.GetCompletionRatio(textRequest.Model)
 | 
			
		||||
	promptTokens := usage.PromptTokens
 | 
			
		||||
	completionTokens := usage.CompletionTokens
 | 
			
		||||
	quota = int64(math.Ceil((float64(promptTokens) + float64(completionTokens)*completionRatio) * ratio))
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,9 @@ import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/model"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/billing"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channeltype"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/constant"
 | 
			
		||||
@@ -88,8 +88,8 @@ func RelayImageHelper(c *gin.Context, relayMode int) *relaymodel.ErrorWithStatus
 | 
			
		||||
		requestBody = bytes.NewBuffer(jsonStr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	modelRatio := common.GetModelRatio(imageRequest.Model)
 | 
			
		||||
	groupRatio := common.GetGroupRatio(meta.Group)
 | 
			
		||||
	modelRatio := billing.GetModelRatio(imageRequest.Model)
 | 
			
		||||
	groupRatio := billing.GetGroupRatio(meta.Group)
 | 
			
		||||
	ratio := modelRatio * groupRatio
 | 
			
		||||
	userQuota, err := model.CacheGetUserQuota(ctx, meta.UserId)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@ import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/gin-gonic/gin"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common"
 | 
			
		||||
	"github.com/songquanpeng/one-api/common/logger"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/apitype"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/billing"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channel/openai"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/channeltype"
 | 
			
		||||
	"github.com/songquanpeng/one-api/relay/helper"
 | 
			
		||||
@@ -35,8 +35,8 @@ func RelayTextHelper(c *gin.Context) *model.ErrorWithStatusCode {
 | 
			
		||||
	textRequest.Model, isModelMapped = util.GetMappedModelName(textRequest.Model, meta.ModelMapping)
 | 
			
		||||
	meta.ActualModelName = textRequest.Model
 | 
			
		||||
	// get model ratio & group ratio
 | 
			
		||||
	modelRatio := common.GetModelRatio(textRequest.Model)
 | 
			
		||||
	groupRatio := common.GetGroupRatio(meta.Group)
 | 
			
		||||
	modelRatio := billing.GetModelRatio(textRequest.Model)
 | 
			
		||||
	groupRatio := billing.GetGroupRatio(meta.Group)
 | 
			
		||||
	ratio := modelRatio * groupRatio
 | 
			
		||||
	// pre-consume quota
 | 
			
		||||
	promptTokens := getPromptTokens(textRequest, meta.Mode)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user