重构第一版
continuous-integration/drone/push Build is passing Details

dev
Kelvin 3 years ago
parent 0bb8284216
commit 2277732de9

4
.gitignore vendored

@ -1,2 +1,4 @@
gin.log gin.log
/logs /logs
.idea
.vscode

@ -7,9 +7,6 @@ docker build -t api2gpt-mid .
docker run -d -p 8081:8080 --name=api2gpt-mid --env REDIS_ADDRESS=172.17.0.1:6379 api2gpt-mid docker run -d -p 8081:8080 --name=api2gpt-mid --env REDIS_ADDRESS=172.17.0.1:6379 api2gpt-mid
docker run -p 8081:8080 --name=api2gpt-mid --env REDIS_ADDRESS=172.17.0.1:6379 api2gpt-mid docker run -p 8081:8080 --name=api2gpt-mid --env REDIS_ADDRESS=172.17.0.1:6379 api2gpt-mid
## nginx 配置 ## nginx 配置
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
@ -19,4 +16,8 @@ proxy_cache_bypass $http_pragam;
proxy_cache_revalidate on; proxy_cache_revalidate on;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_buffering off; proxy_buffering off;
proxy_pass http://localhost:8081/; proxy_pass http://localhost:8081/;
## degug
go run api2gpt-mid --port 8080 --log-dir ./logs

@ -0,0 +1,12 @@
package common
import (
"os"
"time"
)
var StartTime = time.Now().Unix()
var Version = "v0.0.0"
var SystemName = "Api2gpt Mid"
var DebugEnabled = os.Getenv("DEBUG") == "true"

@ -0,0 +1,51 @@
package common
import (
"flag"
"fmt"
"log"
"os"
"path/filepath"
)
var (
Port = flag.Int("port", 8080, "the listening port")
PrintVersion = flag.Bool("version", false, "print version and exit")
PrintHelp = flag.Bool("help", false, "print help and exit")
LogDir = flag.String("log-dir", "", "specify the log directory")
)
func printHelp() {
fmt.Println("Api2gpt " + Version + " - Mid Service.")
fmt.Println("Copyright (C) 2023 api2gpt. All rights reserved.")
fmt.Println("WebSite: https://www.api2gpt.com")
fmt.Println("Usage: one-api [--port <port>] [--log-dir <log directory>] [--version] [--help]")
}
func init() {
flag.Parse()
if *PrintVersion {
fmt.Println(Version)
os.Exit(0)
}
if *PrintHelp {
printHelp()
os.Exit(0)
}
if *LogDir != "" {
var err error
*LogDir, err = filepath.Abs(*LogDir)
if err != nil {
log.Fatal(err)
}
if _, err := os.Stat(*LogDir); os.IsNotExist(err) {
err = os.Mkdir(*LogDir, 0777)
if err != nil {
log.Fatal(err)
}
}
}
}

@ -0,0 +1,44 @@
package common
import (
"fmt"
"github.com/gin-gonic/gin"
"io"
"log"
"os"
"path/filepath"
"time"
)
func SetupGinLog() {
if *LogDir != "" {
commonLogPath := filepath.Join(*LogDir, "common.log")
errorLogPath := filepath.Join(*LogDir, "error.log")
commonFd, err := os.OpenFile(commonLogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal("failed to open log file")
}
errorFd, err := os.OpenFile(errorLogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal("failed to open log file")
}
gin.DefaultWriter = io.MultiWriter(os.Stdout, commonFd)
gin.DefaultErrorWriter = io.MultiWriter(os.Stderr, errorFd)
}
}
func SysLog(s string) {
t := time.Now()
_, _ = fmt.Fprintf(gin.DefaultWriter, "[SYS] %v | %s \n", t.Format("2006/01/02 - 15:04:05"), s)
}
func SysError(s string) {
t := time.Now()
_, _ = fmt.Fprintf(gin.DefaultErrorWriter, "[SYS] %v | %s \n", t.Format("2006/01/02 - 15:04:05"), s)
}
func FatalLog(v ...any) {
t := time.Now()
_, _ = fmt.Fprintf(gin.DefaultErrorWriter, "[FATAL] %v | %v \n", t.Format("2006/01/02 - 15:04:05"), v)
os.Exit(1)
}

@ -0,0 +1,73 @@
package common
import (
"context"
"github.com/redis/go-redis/v9"
"os"
"time"
)
var RDB *redis.Client
// InitRedisClient This function is called after init()
func InitRedisClient() (err error) {
SysLog("Redis start connection")
opt, err := redis.ParseURL("redis://@localhost:6379/0?dial_timeout=5s")
//opt, err := redis.ParseURL(os.Getenv("REDIS_CONN_STRING"))
if err != nil {
FatalLog("failed to parse Redis connection string: " + err.Error())
}
RDB = redis.NewClient(opt)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err = RDB.Ping(ctx).Result()
if err != nil {
FatalLog("Redis ping test failed: " + err.Error())
}
return err
}
func ParseRedisOption() *redis.Options {
opt, err := redis.ParseURL(os.Getenv("REDIS_CONN_STRING"))
if err != nil {
FatalLog("failed to parse Redis connection string: " + err.Error())
}
return opt
}
func RedisSet(key string, value string, expiration time.Duration) error {
ctx := context.Background()
return RDB.Set(ctx, key, value, expiration).Err()
}
func RedisGet(key string) (string, error) {
ctx := context.Background()
return RDB.Get(ctx, key).Result()
}
func RedisDel(key string) error {
ctx := context.Background()
return RDB.Del(ctx, key).Err()
}
func RedisDecrease(key string, value int64) error {
ctx := context.Background()
return RDB.DecrBy(ctx, key, value).Err()
}
func RedisIncrByFloat(key string, value float64) (float64, error) {
ctx := context.Background()
return RDB.IncrByFloat(ctx, key, value).Result()
}
func RedisIncr(key string) (int64, error) {
ctx := context.Background()
return RDB.Incr(ctx, key).Result()
}
func RedisExpire(key string, timeOut time.Duration) (bool, error) {
ctx := context.Background()
return RDB.Expire(ctx, key, timeOut).Result()
}

@ -1,37 +1,40 @@
module main module api2gpt-mid
go 1.20 go 1.20
require ( require (
github.com/bytedance/sonic v1.8.0 // indirect github.com/gin-gonic/gin v1.9.1
github.com/pkoukk/tiktoken-go v0.1.0
github.com/redis/go-redis/v9 v9.0.3
)
require (
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/dlclark/regexp2 v1.8.1 // indirect github.com/dlclark/regexp2 v1.8.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect
github.com/gin-gonic/gin v1.9.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.11.2 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-redis/redis v6.15.9+incompatible // indirect github.com/goccy/go-json v0.10.2 // indirect
github.com/goccy/go-json v0.10.0 // indirect
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.3.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/leodido/go-urn v1.2.1 // indirect github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkoukk/tiktoken-go v0.1.0 // indirect
github.com/redis/go-redis/v9 v9.0.3 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.9 // indirect github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/arch v0.3.0 // indirect
golang.org/x/crypto v0.5.0 // indirect golang.org/x/crypto v0.9.0 // indirect
golang.org/x/net v0.7.0 // indirect golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.5.0 // indirect golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

@ -1,85 +1,97 @@
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dlclark/regexp2 v1.8.1 h1:6Lcdwya6GjPUNsBct8Lg/yRPwMhABj269AAzdGSiR+0= github.com/dlclark/regexp2 v1.8.1 h1:6Lcdwya6GjPUNsBct8Lg/yRPwMhABj269AAzdGSiR+0=
github.com/dlclark/regexp2 v1.8.1/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.8.1/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA=
github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/pkoukk/tiktoken-go v0.1.0 h1:X1uP3+Nd8C3xe6AIGRWjchrylyaye0FDDTG22cxNQZs= github.com/pkoukk/tiktoken-go v0.1.0 h1:X1uP3+Nd8C3xe6AIGRWjchrylyaye0FDDTG22cxNQZs=
github.com/pkoukk/tiktoken-go v0.1.0/go.mod h1:BijIqAP84FMYC4XbdJgjyMpiSjusU8x0Y0W9K2t0QtU= github.com/pkoukk/tiktoken-go v0.1.0/go.mod h1:BijIqAP84FMYC4XbdJgjyMpiSjusU8x0Y0W9K2t0QtU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis v6.15.9+incompatible h1:F+tnlesQSl3h9V8DdmtcYFdvkHLhbb7AgcLW6UJxnC4=
github.com/redis/go-redis v6.15.9+incompatible/go.mod h1:ic6dLmR0d9rkHSzaa0Ab3QVRZcjopJ9hSSPCrecj/+s=
github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k= github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k=
github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

@ -1,9 +1,10 @@
package main package main
import ( import (
"api2gpt-mid/common"
"api2gpt-mid/middleware"
"bufio" "bufio"
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -14,12 +15,12 @@ import (
"net/http/httputil" "net/http/httputil"
"net/url" "net/url"
"os" "os"
"strconv"
"strings" "strings"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/pkoukk/tiktoken-go" "github.com/pkoukk/tiktoken-go"
"github.com/redis/go-redis/v9"
) )
type Message struct { type Message struct {
@ -137,36 +138,6 @@ type ModelInfo struct {
ServerId int `json:"server_id"` ServerId int `json:"server_id"`
} }
var (
Redis *redis.Client
RedisAddress = "localhost:6379"
)
func init() {
//gin.SetMode(gin.ReleaseMode)
if v := os.Getenv("REDIS_ADDRESS"); v != "" {
RedisAddress = v
}
log.Printf("loading redis address: %s", RedisAddress)
}
// redis 初始化
func InitRedis() *redis.Client {
rdb := redis.NewClient(&redis.Options{
Addr: RedisAddress,
Password: "", // no password set
DB: 0, // use default DB
PoolSize: 10,
})
result := rdb.Ping(context.Background())
fmt.Println("redis ping:", result.Val())
if result.Val() != "PONG" {
// 连接有问题
return nil
}
return rdb
}
// 计算Messages中的token数量 // 计算Messages中的token数量
func numTokensFromMessages(messages []Message, model string) int { func numTokensFromMessages(messages []Message, model string) int {
if strings.Contains(model, "gpt-3.5") { if strings.Contains(model, "gpt-3.5") {
@ -694,24 +665,6 @@ func checkKeyMid() gin.HandlerFunc {
} }
} }
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
if origin != "" {
c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
}
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
c.Next()
}
}
func test_redis() { func test_redis() {
//添加reids测试数据 //添加reids测试数据
//var serverInfo ServerInfo = ServerInfo{ //var serverInfo ServerInfo = ServerInfo{
@ -782,55 +735,60 @@ func test_redis() {
// } // }
userInfoStr, _ := json.Marshal(&userInfo) userInfoStr, _ := json.Marshal(&userInfo)
// userInfoStr2, _ := json.Marshal(&userInfo2) // userInfoStr2, _ := json.Marshal(&userInfo2)
Redis.Set(context.Background(), "user:key0", userInfoStr, 0) common.RedisSet("user:key0", string(userInfoStr), 0)
//Redis.Set(context.Background(), "user:key0", userInfoStr, 0)
// Redis.Set(context.Background(), "user:AK-7d8ab782-a152-4cc1-9972-568713465c96", userInfoStr2, 0) // Redis.Set(context.Background(), "user:AK-7d8ab782-a152-4cc1-9972-568713465c96", userInfoStr2, 0)
common.RedisIncrByFloat("user:0:balance", 1000)
Redis.IncrByFloat(context.Background(), "user:0:balance", 1000).Result() //Redis.IncrByFloat(context.Background(), "user:0:balance", 1000).Result()
// Redis.IncrByFloat(context.Background(), "user:2:balance", 1000).Result() // Redis.IncrByFloat(context.Background(), "user:2:balance", 1000).Result()
} }
func main() { func main() {
common.SetupGinLog()
common.SysLog("Api2gpt Mid Service " + common.Version + " started")
if os.Getenv("GIN_MODE") != "debug" {
gin.SetMode(gin.ReleaseMode)
}
if common.DebugEnabled {
common.SysLog("running in debug mode")
}
// 禁用控制台颜色,将日志写入文件时不需要控制台颜色。 // Initialize Redis
gin.DisableConsoleColor() err := common.InitRedisClient()
if err != nil {
// 记录到文件。 common.FatalLog("failed to initialize Redis: " + err.Error())
filename := time.Now().Format("20060102150405") + ".log" }
f, _ := os.Create("logs/gin" + filename)
//gin.DefaultWriter = io.MultiWriter(f)
// 如果需要同时将日志写入文件和控制台,请使用以下代码。
gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
log.SetOutput(gin.DefaultWriter)
r := gin.Default()
//添加跨域支持
r.Use(Cors())
r.GET("/dashboard/billing/credit_grants", checkKeyMid(), balance) // Initialize HTTP server
server := gin.Default()
server.Use(middleware.CORS())
r.GET("/v1/models", handleGetModels) server.GET("/dashboard/billing/credit_grants", checkKeyMid(), balance)
r.OPTIONS("/v1/*path", handleOptions)
r.POST("/v1/chat/completions", checkKeyMid(), completions)
r.POST("/v1/completions", checkKeyMid(), completions)
r.POST("/v1/embeddings", checkKeyMid(), embeddings)
r.POST("/v1/edits", checkKeyMid(), edit)
r.POST("/v1/images/generations", checkKeyMid(), images)
//r.POST("/mock1", mockBalanceInquiry) server.GET("/v1/models", handleGetModels)
//r.POST("/mock2", mockBalanceConsumption) server.OPTIONS("/v1/*path", handleOptions)
server.POST("/v1/chat/completions", checkKeyMid(), completions)
server.POST("/v1/completions", checkKeyMid(), completions)
server.POST("/v1/embeddings", checkKeyMid(), embeddings)
server.POST("/v1/edits", checkKeyMid(), edit)
server.POST("/v1/images/generations", checkKeyMid(), images)
// 定义一个GET请求测试接口 // 定义一个GET请求测试接口
r.GET("/ping", func(c *gin.Context) { server.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{ c.JSON(200, gin.H{
"message": "pong from api2gpt", "message": "pong from api2gpt",
}) })
}) })
Redis = InitRedis()
//添加测试数据 //添加测试数据
//test_redis() //test_redis()
r.Run("0.0.0.0:8080") var port = os.Getenv("PORT")
if port == "" {
port = strconv.Itoa(*common.Port)
}
err = server.Run(":" + port)
if err != nil {
common.FatalLog("failed to start HTTP server: " + err.Error())
}
} }

@ -0,0 +1,24 @@
package middleware
import (
"github.com/gin-gonic/gin"
"net/http"
)
func CORS() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
if origin != "" {
c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
c.Header("Access-Control-Allow-Credentials", "true")
}
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
c.Next()
}
}

@ -0,0 +1,7 @@
package router
import "github.com/gin-gonic/gin"
func SetApiRouter(router *gin.Engine) {
}

@ -0,0 +1,7 @@
package router
import "github.com/gin-gonic/gin"
func SetRouter(router *gin.Engine) {
SetApiRouter(router)
}

@ -1,7 +1,7 @@
package main package main
import ( import (
"context" "api2gpt-mid/common"
"encoding/json" "encoding/json"
"errors" "errors"
"log" "log"
@ -13,7 +13,7 @@ import (
func checkKeyAndTimeCount(key string) (int, error) { func checkKeyAndTimeCount(key string) (int, error) {
var timeOut = 60 * time.Second var timeOut = 60 * time.Second
var timeCount = 30 var timeCount = 30
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
log.Printf("用户信息 %s", userInfoStr) log.Printf("用户信息 %s", userInfoStr)
if err != nil { if err != nil {
//用户不存在 //用户不存在
@ -25,14 +25,14 @@ func checkKeyAndTimeCount(key string) (int, error) {
//用户状态异常 //用户状态异常
return 401, errors.New("40004") return 401, errors.New("40004")
} }
count, err := Redis.Incr(context.Background(), "user:count:"+key).Result() count, err := common.RedisIncr("user:count:" + key)
log.Printf("用户请求次数 %d", count) log.Printf("用户请求次数 %d", count)
if err != nil { if err != nil {
log.Printf("系统计数器设置异常 %s", err.Error()) log.Printf("系统计数器设置异常 %s", err.Error())
return 500, errors.New("系统计数器设置异常") return 500, errors.New("系统计数器设置异常")
} }
if count == 1 { if count == 1 {
_, err := Redis.Expire(context.Background(), "user:count:"+key, timeOut).Result() _, err := common.RedisExpire("user:count:"+key, timeOut)
if err != nil { if err != nil {
log.Printf("系统计数器异常 %s", err.Error()) log.Printf("系统计数器异常 %s", err.Error())
return 500, errors.New("系统计数器异常") return 500, errors.New("系统计数器异常")
@ -47,10 +47,10 @@ func checkKeyAndTimeCount(key string) (int, error) {
} }
func queryBlance(key string) (float64, error) { func queryBlance(key string) (float64, error) {
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
var userInfo UserInfo var userInfo UserInfo
err = json.Unmarshal([]byte(userInfoStr), &userInfo) err = json.Unmarshal([]byte(userInfoStr), &userInfo)
balance, err := Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", 0).Result() balance, err := common.RedisIncrByFloat("user:"+userInfo.UID+":balance", 0)
if err != nil { if err != nil {
return 0, errors.New("余额计算失败") return 0, errors.New("余额计算失败")
} }
@ -62,7 +62,7 @@ func checkBlance(key string, model string) (ServerInfo, error) {
var serverInfo ServerInfo var serverInfo ServerInfo
//获取模型价格 //获取模型价格
modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() modelPriceStr, err := common.RedisGet("model:" + model)
if err != nil { if err != nil {
return serverInfo, errors.New("模型信息不存在") return serverInfo, errors.New("模型信息不存在")
} }
@ -73,11 +73,11 @@ func checkBlance(key string, model string) (ServerInfo, error) {
} }
//获取用户信息 //获取用户信息
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
var userInfo UserInfo var userInfo UserInfo
err = json.Unmarshal([]byte(userInfoStr), &userInfo) err = json.Unmarshal([]byte(userInfoStr), &userInfo)
//获取服务器信息 //获取服务器信息
serverInfoStr, err := Redis.Get(context.Background(), "server:"+strconv.Itoa(modelInfo.ServerId)).Result() serverInfoStr, err := common.RedisGet("server:" + strconv.Itoa(modelInfo.ServerId))
if err != nil { if err != nil {
return serverInfo, errors.New("服务器信息不存在") return serverInfo, errors.New("服务器信息不存在")
} }
@ -87,13 +87,13 @@ func checkBlance(key string, model string) (ServerInfo, error) {
} }
//计算余额-先扣除指定金额 //计算余额-先扣除指定金额
balance, err := Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", -(float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice)).Result() balance, err := common.RedisIncrByFloat("user:"+userInfo.UID+":balance", -(float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice))
if err != nil { if err != nil {
return serverInfo, errors.New("余额计算失败") return serverInfo, errors.New("余额计算失败")
} }
log.Printf("用户余额 %f key: %v 预扣了:%f", balance, key, (float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice)) log.Printf("用户余额 %f key: %v 预扣了:%f", balance, key, (float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice))
if balance < 0 { if balance < 0 {
Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment)*modelInfo.ModelPrice).Result() common.RedisIncrByFloat("user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment)*modelInfo.ModelPrice)
return serverInfo, errors.New("用户余额不足") return serverInfo, errors.New("用户余额不足")
} }
@ -105,7 +105,7 @@ func checkBlanceForImages(key string, model string, n int) (ServerInfo, error) {
var serverInfo ServerInfo var serverInfo ServerInfo
//获取模型价格 //获取模型价格
modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() modelPriceStr, err := common.RedisGet("model:" + model)
if err != nil { if err != nil {
return serverInfo, errors.New("模型信息不存在") return serverInfo, errors.New("模型信息不存在")
} }
@ -116,11 +116,11 @@ func checkBlanceForImages(key string, model string, n int) (ServerInfo, error) {
} }
//获取用户信息 //获取用户信息
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
var userInfo UserInfo var userInfo UserInfo
err = json.Unmarshal([]byte(userInfoStr), &userInfo) err = json.Unmarshal([]byte(userInfoStr), &userInfo)
//获取服务器信息 //获取服务器信息
serverInfoStr, err := Redis.Get(context.Background(), "server:"+strconv.Itoa(modelInfo.ServerId)).Result() serverInfoStr, err := common.RedisGet("server:" + strconv.Itoa(modelInfo.ServerId))
if err != nil { if err != nil {
return serverInfo, errors.New("服务器信息不存在") return serverInfo, errors.New("服务器信息不存在")
} }
@ -130,13 +130,13 @@ func checkBlanceForImages(key string, model string, n int) (ServerInfo, error) {
} }
//计算余额-先扣除指定金额 //计算余额-先扣除指定金额
balance, err := Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", -(float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice)).Result() balance, err := common.RedisIncrByFloat("user:"+userInfo.UID+":balance", -(float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice))
if err != nil { if err != nil {
return serverInfo, errors.New("余额计算失败") return serverInfo, errors.New("余额计算失败")
} }
log.Printf("用户余额 %f key: %v 预扣了:%f", balance, key, (float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice)) log.Printf("用户余额 %f key: %v 预扣了:%f", balance, key, (float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice))
if balance < 0 { if balance < 0 {
Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment*n)*modelInfo.ModelPrice).Result() common.RedisIncrByFloat("user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment*n)*modelInfo.ModelPrice)
return serverInfo, errors.New("用户余额不足") return serverInfo, errors.New("用户余额不足")
} }
@ -146,12 +146,12 @@ func checkBlanceForImages(key string, model string, n int) (ServerInfo, error) {
// 预扣返还 // 预扣返还
func checkBlanceReturn(key string, model string) error { func checkBlanceReturn(key string, model string) error {
//获取用户信息 //获取用户信息
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
var userInfo UserInfo var userInfo UserInfo
err = json.Unmarshal([]byte(userInfoStr), &userInfo) err = json.Unmarshal([]byte(userInfoStr), &userInfo)
//获取模型价格 //获取模型价格
modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() modelPriceStr, err := common.RedisGet("model:" + model)
if err != nil { if err != nil {
return errors.New("模型信息不存在") return errors.New("模型信息不存在")
} }
@ -160,7 +160,7 @@ func checkBlanceReturn(key string, model string) error {
if err != nil { if err != nil {
return errors.New("模型信息解析失败") return errors.New("模型信息解析失败")
} }
balance, err := Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", (float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice)).Result() balance, err := common.RedisIncrByFloat("user:"+userInfo.UID+":balance", (float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice))
log.Printf("用户余额 %f key: %v 返还预扣:%f", balance, key, (float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice)) log.Printf("用户余额 %f key: %v 返还预扣:%f", balance, key, (float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice))
return nil return nil
} }
@ -168,11 +168,11 @@ func checkBlanceReturn(key string, model string) error {
// 预扣返还 for images // 预扣返还 for images
func checkBlanceReturnForImages(key string, model string, n int) error { func checkBlanceReturnForImages(key string, model string, n int) error {
//获取用户信息 //获取用户信息
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
var userInfo UserInfo var userInfo UserInfo
err = json.Unmarshal([]byte(userInfoStr), &userInfo) err = json.Unmarshal([]byte(userInfoStr), &userInfo)
//获取模型价格 //获取模型价格
modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() modelPriceStr, err := common.RedisGet("model:" + model)
if err != nil { if err != nil {
return errors.New("模型信息不存在") return errors.New("模型信息不存在")
} }
@ -181,7 +181,7 @@ func checkBlanceReturnForImages(key string, model string, n int) error {
if err != nil { if err != nil {
return errors.New("模型信息解析失败") return errors.New("模型信息解析失败")
} }
balance, err := Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", (float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice)).Result() balance, err := common.RedisIncrByFloat("user:"+userInfo.UID+":balance", (float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice))
log.Printf("用户余额 %f key: %v 返还预扣:%f", balance, key, (float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice)) log.Printf("用户余额 %f key: %v 返还预扣:%f", balance, key, (float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice))
return nil return nil
} }
@ -189,7 +189,7 @@ func checkBlanceReturnForImages(key string, model string, n int) error {
// 余额消费 // 余额消费
func consumption(key string, model string, prompt_tokens int, completion_tokens int, total_tokens int, msg_id string) (string, error) { func consumption(key string, model string, prompt_tokens int, completion_tokens int, total_tokens int, msg_id string) (string, error) {
//获取用户信息 //获取用户信息
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
if err != nil { if err != nil {
return "", errors.New("用户信息不存在") return "", errors.New("用户信息不存在")
} }
@ -199,7 +199,7 @@ func consumption(key string, model string, prompt_tokens int, completion_tokens
return "", errors.New("用户信息解析失败") return "", errors.New("用户信息解析失败")
} }
//获取模型价格 //获取模型价格
modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() modelPriceStr, err := common.RedisGet("model:" + model)
if err != nil { if err != nil {
return "", errors.New("模型信息不存在") return "", errors.New("模型信息不存在")
} }
@ -208,7 +208,7 @@ func consumption(key string, model string, prompt_tokens int, completion_tokens
if err != nil { if err != nil {
return "", errors.New("模型信息解析失败") return "", errors.New("模型信息解析失败")
} }
balance, err := Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment)*modelInfo.ModelPrice-(float64(prompt_tokens)*modelInfo.ModelPrice+float64(completion_tokens)*modelInfo.ModelPrice2)).Result() balance, err := common.RedisIncrByFloat("user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment)*modelInfo.ModelPrice-(float64(prompt_tokens)*modelInfo.ModelPrice+float64(completion_tokens)*modelInfo.ModelPrice2))
// 余额消费日志请求 // 余额消费日志请求
result, err := balanceConsumption(key, model, prompt_tokens, completion_tokens, total_tokens, msg_id) result, err := balanceConsumption(key, model, prompt_tokens, completion_tokens, total_tokens, msg_id)
@ -223,7 +223,7 @@ func consumption(key string, model string, prompt_tokens int, completion_tokens
// 余额消费 for images // 余额消费 for images
func consumptionForImages(key string, model string, n int, dataNum int, msg_id string) (string, error) { func consumptionForImages(key string, model string, n int, dataNum int, msg_id string) (string, error) {
//获取用户信息 //获取用户信息
userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() userInfoStr, err := common.RedisGet("user:" + key)
if err != nil { if err != nil {
return "", errors.New("用户信息不存在") return "", errors.New("用户信息不存在")
} }
@ -233,7 +233,7 @@ func consumptionForImages(key string, model string, n int, dataNum int, msg_id s
return "", errors.New("用户信息解析失败") return "", errors.New("用户信息解析失败")
} }
//获取模型价格 //获取模型价格
modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() modelPriceStr, err := common.RedisGet("model:" + model)
if err != nil { if err != nil {
return "", errors.New("模型信息不存在") return "", errors.New("模型信息不存在")
} }
@ -242,7 +242,7 @@ func consumptionForImages(key string, model string, n int, dataNum int, msg_id s
if err != nil { if err != nil {
return "", errors.New("模型信息解析失败") return "", errors.New("模型信息解析失败")
} }
balance, err := Redis.IncrByFloat(context.Background(), "user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment*n)*modelInfo.ModelPrice-(float64(1000*dataNum)*modelInfo.ModelPrice)).Result() balance, err := common.RedisIncrByFloat("user:"+userInfo.UID+":balance", float64(modelInfo.ModelPrepayment*n)*modelInfo.ModelPrice-(float64(1000*dataNum)*modelInfo.ModelPrice))
// 余额消费日志请求 // 余额消费日志请求
result, err := balanceConsumption(key, model, 0, 1000*dataNum, 1000*dataNum, msg_id) result, err := balanceConsumption(key, model, 0, 1000*dataNum, 1000*dataNum, msg_id)

Loading…
Cancel
Save