diff --git a/.gitignore b/.gitignore index 8dc8474..9311471 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ gin.log -/logs \ No newline at end of file +/logs +.idea +.vscode \ No newline at end of file diff --git a/README.md b/README.md index 11d3b64..0652608 100644 --- a/README.md +++ b/README.md @@ -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 -p 8081:8080 --name=api2gpt-mid --env REDIS_ADDRESS=172.17.0.1:6379 api2gpt-mid - - - ## nginx 配置 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -19,4 +16,8 @@ proxy_cache_bypass $http_pragam; proxy_cache_revalidate on; proxy_http_version 1.1; proxy_buffering off; -proxy_pass http://localhost:8081/; \ No newline at end of file +proxy_pass http://localhost:8081/; + + +## degug +go run api2gpt-mid --port 8080 --log-dir ./logs diff --git a/common/constants.go b/common/constants.go new file mode 100644 index 0000000..0e6958a --- /dev/null +++ b/common/constants.go @@ -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" diff --git a/common/init.go b/common/init.go new file mode 100644 index 0000000..fe3827f --- /dev/null +++ b/common/init.go @@ -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 ] [--log-dir ] [--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) + } + } + } +} diff --git a/common/logger.go b/common/logger.go new file mode 100644 index 0000000..0b8b2cf --- /dev/null +++ b/common/logger.go @@ -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) +} diff --git a/common/redis.go b/common/redis.go new file mode 100644 index 0000000..eedbfd9 --- /dev/null +++ b/common/redis.go @@ -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() +} diff --git a/go.mod b/go.mod index 44d03b7..18000ff 100644 --- a/go.mod +++ b/go.mod @@ -1,37 +1,40 @@ -module main +module api2gpt-mid go 1.20 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/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // 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-gonic/gin v1.9.0 // indirect github.com/go-playground/locales v0.14.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-redis/redis v6.15.9+incompatible // indirect - github.com/goccy/go-json v0.10.0 // indirect + github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect github.com/google/uuid v1.3.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.0.9 // indirect - github.com/leodido/go-urn v1.2.1 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect - github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/leodido/go-urn v1.2.4 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.6 // indirect - github.com/pkoukk/tiktoken-go v0.1.0 // indirect - github.com/redis/go-redis/v9 v9.0.3 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.9 // indirect - golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect - golang.org/x/crypto v0.5.0 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + golang.org/x/arch v0.3.0 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 920c395..6471080 100644 --- a/go.sum +++ b/go.sum @@ -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.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA= -github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= +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/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-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= 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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 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/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dlclark/regexp2 v1.8.1 h1:6Lcdwya6GjPUNsBct8Lg/yRPwMhABj269AAzdGSiR+0= 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/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.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +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/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/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= -github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= -github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= -github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -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/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= +github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 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/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/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/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/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +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-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/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.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +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/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/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/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= 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.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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.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.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/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.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 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/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= +golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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= 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.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +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/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/main.go b/main.go index 7fe5d8f..d0b600e 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,10 @@ package main import ( + "api2gpt-mid/common" + "api2gpt-mid/middleware" "bufio" "bytes" - "context" "encoding/json" "fmt" "io" @@ -14,12 +15,12 @@ import ( "net/http/httputil" "net/url" "os" + "strconv" "strings" "time" "github.com/gin-gonic/gin" "github.com/pkoukk/tiktoken-go" - "github.com/redis/go-redis/v9" ) type Message struct { @@ -137,36 +138,6 @@ type ModelInfo struct { 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数量 func numTokensFromMessages(messages []Message, model string) int { 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() { //添加reids测试数据 //var serverInfo ServerInfo = ServerInfo{ @@ -782,55 +735,60 @@ func test_redis() { // } userInfoStr, _ := json.Marshal(&userInfo) // 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.IncrByFloat(context.Background(), "user:0:balance", 1000).Result() + common.RedisIncrByFloat("user:0:balance", 1000) + //Redis.IncrByFloat(context.Background(), "user:0:balance", 1000).Result() // Redis.IncrByFloat(context.Background(), "user:2:balance", 1000).Result() } 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") + } - // 禁用控制台颜色,将日志写入文件时不需要控制台颜色。 - gin.DisableConsoleColor() - - // 记录到文件。 - 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()) + // Initialize Redis + err := common.InitRedisClient() + if err != nil { + common.FatalLog("failed to initialize Redis: " + err.Error()) + } - r.GET("/dashboard/billing/credit_grants", checkKeyMid(), balance) + // Initialize HTTP server + server := gin.Default() + server.Use(middleware.CORS()) - r.GET("/v1/models", handleGetModels) - 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) + server.GET("/dashboard/billing/credit_grants", checkKeyMid(), balance) - //r.POST("/mock1", mockBalanceInquiry) - //r.POST("/mock2", mockBalanceConsumption) + server.GET("/v1/models", handleGetModels) + 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请求测试接口 - r.GET("/ping", func(c *gin.Context) { + server.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong from api2gpt", }) }) - Redis = InitRedis() //添加测试数据 //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()) + } } diff --git a/middleware/cors.go b/middleware/cors.go new file mode 100644 index 0000000..81f8135 --- /dev/null +++ b/middleware/cors.go @@ -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() + } +} diff --git a/router/api-router.go b/router/api-router.go new file mode 100644 index 0000000..21d76a8 --- /dev/null +++ b/router/api-router.go @@ -0,0 +1,7 @@ +package router + +import "github.com/gin-gonic/gin" + +func SetApiRouter(router *gin.Engine) { + +} diff --git a/router/main.go b/router/main.go new file mode 100644 index 0000000..8abbb24 --- /dev/null +++ b/router/main.go @@ -0,0 +1,7 @@ +package router + +import "github.com/gin-gonic/gin" + +func SetRouter(router *gin.Engine) { + SetApiRouter(router) +} diff --git a/service.go b/service.go index 8b82a09..dae2595 100644 --- a/service.go +++ b/service.go @@ -1,7 +1,7 @@ package main import ( - "context" + "api2gpt-mid/common" "encoding/json" "errors" "log" @@ -13,7 +13,7 @@ import ( func checkKeyAndTimeCount(key string) (int, error) { var timeOut = 60 * time.Second var timeCount = 30 - userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() + userInfoStr, err := common.RedisGet("user:" + key) log.Printf("用户信息 %s", userInfoStr) if err != nil { //用户不存在 @@ -25,14 +25,14 @@ func checkKeyAndTimeCount(key string) (int, error) { //用户状态异常 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) if err != nil { log.Printf("系统计数器设置异常 %s", err.Error()) return 500, errors.New("系统计数器设置异常") } if count == 1 { - _, err := Redis.Expire(context.Background(), "user:count:"+key, timeOut).Result() + _, err := common.RedisExpire("user:count:"+key, timeOut) if err != nil { log.Printf("系统计数器异常 %s", err.Error()) return 500, errors.New("系统计数器异常") @@ -47,10 +47,10 @@ func checkKeyAndTimeCount(key string) (int, 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 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 { return 0, errors.New("余额计算失败") } @@ -62,7 +62,7 @@ func checkBlance(key string, model string) (ServerInfo, error) { var serverInfo ServerInfo //获取模型价格 - modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() + modelPriceStr, err := common.RedisGet("model:" + model) if err != nil { 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 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 { 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 { return serverInfo, errors.New("余额计算失败") } log.Printf("用户余额 %f key: %v 预扣了:%f", balance, key, (float64(modelInfo.ModelPrepayment) * modelInfo.ModelPrice)) 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("用户余额不足") } @@ -105,7 +105,7 @@ func checkBlanceForImages(key string, model string, n int) (ServerInfo, error) { var serverInfo ServerInfo //获取模型价格 - modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() + modelPriceStr, err := common.RedisGet("model:" + model) if err != nil { 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 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 { 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 { return serverInfo, errors.New("余额计算失败") } log.Printf("用户余额 %f key: %v 预扣了:%f", balance, key, (float64(modelInfo.ModelPrepayment*n) * modelInfo.ModelPrice)) 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("用户余额不足") } @@ -146,12 +146,12 @@ func checkBlanceForImages(key string, model string, n int) (ServerInfo, 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 err = json.Unmarshal([]byte(userInfoStr), &userInfo) //获取模型价格 - modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() + modelPriceStr, err := common.RedisGet("model:" + model) if err != nil { return errors.New("模型信息不存在") } @@ -160,7 +160,7 @@ func checkBlanceReturn(key string, model string) error { if err != nil { 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)) return nil } @@ -168,11 +168,11 @@ func checkBlanceReturn(key string, model string) error { // 预扣返还 for images 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 err = json.Unmarshal([]byte(userInfoStr), &userInfo) //获取模型价格 - modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() + modelPriceStr, err := common.RedisGet("model:" + model) if err != nil { return errors.New("模型信息不存在") } @@ -181,7 +181,7 @@ func checkBlanceReturnForImages(key string, model string, n int) error { if err != nil { 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)) 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) { //获取用户信息 - userInfoStr, err := Redis.Get(context.Background(), "user:"+key).Result() + userInfoStr, err := common.RedisGet("user:" + key) if err != nil { return "", errors.New("用户信息不存在") } @@ -199,7 +199,7 @@ func consumption(key string, model string, prompt_tokens int, completion_tokens return "", errors.New("用户信息解析失败") } //获取模型价格 - modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() + modelPriceStr, err := common.RedisGet("model:" + model) if err != nil { return "", errors.New("模型信息不存在") } @@ -208,7 +208,7 @@ func consumption(key string, model string, prompt_tokens int, completion_tokens if err != nil { 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) @@ -223,7 +223,7 @@ func consumption(key string, model string, prompt_tokens int, completion_tokens // 余额消费 for images 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 { return "", errors.New("用户信息不存在") } @@ -233,7 +233,7 @@ func consumptionForImages(key string, model string, n int, dataNum int, msg_id s return "", errors.New("用户信息解析失败") } //获取模型价格 - modelPriceStr, err := Redis.Get(context.Background(), "model:"+model).Result() + modelPriceStr, err := common.RedisGet("model:" + model) if err != nil { return "", errors.New("模型信息不存在") } @@ -242,7 +242,7 @@ func consumptionForImages(key string, model string, n int, dataNum int, msg_id s if err != nil { 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)