From 91b80ae87945ed1a77b3507dd277ee9cdddaa0b4 Mon Sep 17 00:00:00 2001 From: JustSong Date: Tue, 7 May 2024 23:57:34 +0800 Subject: [PATCH 01/49] fix: remove extra space --- relay/billing/ratio/model.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay/billing/ratio/model.go b/relay/billing/ratio/model.go index f87e7742..04579d52 100644 --- a/relay/billing/ratio/model.go +++ b/relay/billing/ratio/model.go @@ -171,7 +171,7 @@ var ModelRatio = map[string]float64{ "command-light": 0.5, "command-light-nightly": 0.5, "command-r": 0.5 / 1000 * USD, - "command-r-plus ": 3.0 / 1000 * USD, + "command-r-plus": 3.0 / 1000 * USD, // https://platform.deepseek.com/api-docs/pricing/ "deepseek-chat": 1.0 / 1000 * RMB, "deepseek-coder": 1.0 / 1000 * RMB, From 2457d00afb5a66fade9f4dd3b0ad48c60579f049 Mon Sep 17 00:00:00 2001 From: Qiying Wang <781345688@qq.com> Date: Tue, 21 May 2024 01:14:22 +0800 Subject: [PATCH 02/49] feat: support gpt-4o (#1431) --- relay/adaptor/openai/constants.go | 1 + relay/billing/ratio/model.go | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/relay/adaptor/openai/constants.go b/relay/adaptor/openai/constants.go index 2ffff007..924f4b2a 100644 --- a/relay/adaptor/openai/constants.go +++ b/relay/adaptor/openai/constants.go @@ -7,6 +7,7 @@ var ModelList = []string{ "gpt-4", "gpt-4-0314", "gpt-4-0613", "gpt-4-1106-preview", "gpt-4-0125-preview", "gpt-4-32k", "gpt-4-32k-0314", "gpt-4-32k-0613", "gpt-4-turbo-preview", "gpt-4-turbo", "gpt-4-turbo-2024-04-09", + "gpt-4o", "gpt-4o-2024-05-13", "gpt-4-vision-preview", "text-embedding-ada-002", "text-embedding-3-small", "text-embedding-3-large", "text-curie-001", "text-babbage-001", "text-ada-001", "text-davinci-002", "text-davinci-003", diff --git a/relay/billing/ratio/model.go b/relay/billing/ratio/model.go index 04579d52..3b289499 100644 --- a/relay/billing/ratio/model.go +++ b/relay/billing/ratio/model.go @@ -32,6 +32,8 @@ var ModelRatio = map[string]float64{ "gpt-4-turbo-preview": 5, // $0.01 / 1K tokens "gpt-4-turbo": 5, // $0.01 / 1K tokens "gpt-4-turbo-2024-04-09": 5, // $0.01 / 1K tokens + "gpt-4o": 2.5, // $0.005 / 1K tokens + "gpt-4o-2024-05-13": 2.5, // $0.005 / 1K tokens "gpt-4-vision-preview": 5, // $0.01 / 1K tokens "gpt-3.5-turbo": 0.25, // $0.0005 / 1K tokens "gpt-3.5-turbo-0301": 0.75, @@ -280,7 +282,9 @@ func GetCompletionRatio(name string) float64 { return 4.0 / 3.0 } if strings.HasPrefix(name, "gpt-4") { - if strings.HasPrefix(name, "gpt-4-turbo") || strings.HasSuffix(name, "preview") { + if strings.HasPrefix(name, "gpt-4-turbo") || + strings.HasPrefix(name, "gpt-4o") || + strings.HasSuffix(name, "preview") { return 3 } return 2 From 03ea60532aec4c950ffa14e8916d6f8bb6ccfad9 Mon Sep 17 00:00:00 2001 From: JustSong Date: Tue, 21 May 2024 01:20:26 +0800 Subject: [PATCH 03/49] fix: fix html lang attribute (close #1433) --- web/air/public/index.html | 2 +- web/berry/public/index.html | 2 +- web/default/public/index.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/air/public/index.html b/web/air/public/index.html index 36365c7e..e0de002d 100644 --- a/web/air/public/index.html +++ b/web/air/public/index.html @@ -1,5 +1,5 @@ - + diff --git a/web/berry/public/index.html b/web/berry/public/index.html index abd079e1..9a2457e2 100644 --- a/web/berry/public/index.html +++ b/web/berry/public/index.html @@ -1,5 +1,5 @@ - + One API diff --git a/web/default/public/index.html b/web/default/public/index.html index b8e324d2..f22b8843 100644 --- a/web/default/public/index.html +++ b/web/default/public/index.html @@ -1,5 +1,5 @@ - + From f965469e8a683d1cf05ddbe1fd5ed21dacd8fe70 Mon Sep 17 00:00:00 2001 From: JustSong Date: Wed, 22 May 2024 00:52:23 +0800 Subject: [PATCH 04/49] chore: update dependencies version --- go.mod | 48 ++++++++++++++++++++++++------------------------ go.sum | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 24 deletions(-) diff --git a/go.mod b/go.mod index 1754ea58..1ed937ae 100644 --- a/go.mod +++ b/go.mod @@ -4,42 +4,42 @@ module github.com/songquanpeng/one-api go 1.20 require ( - github.com/aws/aws-sdk-go-v2 v1.26.1 - github.com/aws/aws-sdk-go-v2/credentials v1.17.11 - github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.7.4 - github.com/gin-contrib/cors v1.7.1 - github.com/gin-contrib/gzip v1.0.0 - github.com/gin-contrib/sessions v1.0.0 - github.com/gin-contrib/static v1.1.1 - github.com/gin-gonic/gin v1.9.1 - github.com/go-playground/validator/v10 v10.19.0 + github.com/aws/aws-sdk-go-v2 v1.27.0 + github.com/aws/aws-sdk-go-v2/credentials v1.17.15 + github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.8.3 + github.com/gin-contrib/cors v1.7.2 + github.com/gin-contrib/gzip v1.0.1 + github.com/gin-contrib/sessions v1.0.1 + github.com/gin-contrib/static v1.1.2 + github.com/gin-gonic/gin v1.10.0 + github.com/go-playground/validator/v10 v10.20.0 github.com/go-redis/redis/v8 v8.11.5 github.com/golang-jwt/jwt v3.2.2+incompatible github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.1 github.com/jinzhu/copier v0.4.0 github.com/pkg/errors v0.9.1 - github.com/pkoukk/tiktoken-go v0.1.6 + github.com/pkoukk/tiktoken-go v0.1.7 github.com/smartystreets/goconvey v1.8.1 github.com/stretchr/testify v1.9.0 - golang.org/x/crypto v0.22.0 - golang.org/x/image v0.15.0 + golang.org/x/crypto v0.23.0 + golang.org/x/image v0.16.0 gorm.io/driver/mysql v1.5.6 gorm.io/driver/postgres v1.5.7 gorm.io/driver/sqlite v1.5.5 - gorm.io/gorm v1.25.9 + gorm.io/gorm v1.25.10 ) require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 // indirect github.com/aws/smithy-go v1.20.2 // indirect - github.com/bytedance/sonic v1.11.5 // indirect + github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudwego/base64x v0.1.3 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect @@ -50,7 +50,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/gorilla/context v1.1.2 // indirect github.com/gorilla/securecookie v1.1.2 // indirect @@ -70,16 +70,16 @@ require ( github.com/mattn/go-sqlite3 v2.0.3+incompatible // 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.2.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/smarty/assertions v1.15.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect - golang.org/x/arch v0.7.0 // indirect - golang.org/x/net v0.24.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/net v0.25.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b98b377a..a5aede95 100644 --- a/go.sum +++ b/go.sum @@ -2,20 +2,32 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= +github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgiLlo= +github.com/aws/aws-sdk-go-v2 v1.27.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg= github.com/aws/aws-sdk-go-v2/credentials v1.17.11 h1:YuIB1dJNf1Re822rriUOTxopaHHvIq0l/pX3fwO+Tzs= github.com/aws/aws-sdk-go-v2/credentials v1.17.11/go.mod h1:AQtFPsDH9bI2O+71anW6EKL+NcD7LG3dpKGMV4SShgo= +github.com/aws/aws-sdk-go-v2/credentials v1.17.15 h1:YDexlvDRCA8ems2T5IP1xkMtOZ1uLJOCJdTr0igs5zo= +github.com/aws/aws-sdk-go-v2/credentials v1.17.15/go.mod h1:vxHggqW6hFNaeNC0WyXS3VdyjcV0a4KMUY4dKJ96buU= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 h1:lf/8VTF2cM+N4SLzaYJERKEWAXq8MOMpZfU6wEPWsPk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7/go.mod h1:4SjkU7QiqK2M9oozyMzfZ/23LmUY+h3oFqhdeP5OMiI= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7 h1:4OYVp0705xu8yjdyoWix0r9wPIRXnIzzOoUpQVHIJ/g= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.7/go.mod h1:vd7ESTEvI76T2Na050gODNmNU7+OyKrIKroYTu4ABiI= github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.7.4 h1:JgHnonzbnA3pbqj76wYsSZIZZQYBxkmMEjvL6GHy8XU= github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.7.4/go.mod h1:nZspkhg+9p8iApLFoyAqfyuMP0F38acy2Hm3r5r95Cg= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.8.3 h1:Fihjyd6DeNjcawBEGLH9dkIEUi6AdhucDKPE9nJ4QiY= +github.com/aws/aws-sdk-go-v2/service/bedrockruntime v1.8.3/go.mod h1:opvUj3ismqSCxYc+m4WIjPL0ewZGtvp0ess7cKvBPOQ= github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/bytedance/sonic v1.11.5 h1:G00FYjjqll5iQ1PYXynbg/hyzqBqavH8Mo9/oTopd9k= github.com/bytedance/sonic v1.11.5/go.mod h1:X2PC2giUdj/Cv2lliWFLk6c/DUQok5rViJSemeB0wDw= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.0/go.mod h1:UmRT+IRTGKz/DAkzcEGzyVqQFJ7H9BqwBO3pm9H/+HY= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= @@ -23,6 +35,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudwego/base64x v0.1.3 h1:b5J/l8xolB7dyDTTmhJP2oTs5LdrjyrUFuNxdfq5hAg= github.com/cloudwego/base64x v0.1.3/go.mod h1:1+1K5BUHIQzyapgpF7LwvOGAEDicKtt1umPV+aN8pi8= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -39,16 +53,26 @@ github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uq github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/gin-contrib/cors v1.7.1 h1:s9SIppU/rk8enVvkzwiC2VK3UZ/0NNGsWfUKvV55rqs= github.com/gin-contrib/cors v1.7.1/go.mod h1:n/Zj7B4xyrgk/cX1WCX2dkzFfaNm/xJb6oIUk7WTtps= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= github.com/gin-contrib/gzip v1.0.0 h1:UKN586Po/92IDX6ie5CWLgMI81obiIp5nSP85T3wlTk= github.com/gin-contrib/gzip v1.0.0/go.mod h1:CtG7tQrPB3vIBo6Gat9FVUsis+1emjvQqd66ME5TdnE= +github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE= +github.com/gin-contrib/gzip v1.0.1/go.mod h1:njt428fdUNRvjuJf16tZMYZ2Yl+WQB53X5wmhDwXvC4= github.com/gin-contrib/sessions v1.0.0 h1:r5GLta4Oy5xo9rAwMHx8B4wLpeRGHMdz9NafzJAdP8Y= github.com/gin-contrib/sessions v1.0.0/go.mod h1:DN0f4bvpqMQElDdi+gNGScrP2QEI04IErRyMFyorUOI= +github.com/gin-contrib/sessions v1.0.1 h1:3hsJyNs7v7N8OtelFmYXFrulAf6zSR7nW/putcPEHxI= +github.com/gin-contrib/sessions v1.0.1/go.mod h1:ouxSFM24/OgIud5MJYQJLpy6AwxQ5EYO9yLhbtObGkM= 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/static v1.1.1 h1:XEvBd4DDLG1HBlyPBQU1XO8NlTpw6mgdqcPteetYA5k= github.com/gin-contrib/static v1.1.1/go.mod h1:yRGmar7+JYvbMLRPIi4H5TVVSBwULfT9vetnVD0IO74= +github.com/gin-contrib/static v1.1.2 h1:c3kT4bFkUJn2aoRU3s6XnMjJT8J6nNWJkR0NglqmlZ4= +github.com/gin-contrib/static v1.1.2/go.mod h1:Fw90ozjHCmZBWbgrsqrDvO28YbhKEKzKp8GixhR4yLw= 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/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= 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= @@ -56,6 +80,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= @@ -63,6 +89,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= 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/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= @@ -121,10 +149,14 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw= github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg= +github.com/pkoukk/tiktoken-go v0.1.7 h1:qOBHXX4PHtvIvmOtyg1EeKlwFRiMKAcoMp4Q+bLQDmw= +github.com/pkoukk/tiktoken-go v0.1.7/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg= 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/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= @@ -151,23 +183,37 @@ github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw= +golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -184,5 +230,7 @@ gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATa gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8= gorm.io/gorm v1.25.9/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= From 0acee9a0655aa84a81b346a23ad3ae5b3781fb15 Mon Sep 17 00:00:00 2001 From: JustSong Date: Wed, 22 May 2024 01:00:00 +0800 Subject: [PATCH 05/49] fix: fix berry error (close #1445) --- web/berry/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/berry/package.json b/web/berry/package.json index f428fd9c..2edb2355 100644 --- a/web/berry/package.json +++ b/web/berry/package.json @@ -15,7 +15,7 @@ "@mui/utils": "^5.8.6", "@mui/x-date-pickers": "^6.18.5", "@tabler/icons-react": "^2.44.0", - "apexcharts": "^3.35.3", + "apexcharts": "3.35.3", "axios": "^0.27.2", "dayjs": "^1.11.10", "formik": "^2.2.9", From 07b2fd58d646817e597bd6edceabb1c12e57ed38 Mon Sep 17 00:00:00 2001 From: Buer <42402987+MartialBE@users.noreply.github.com> Date: Tue, 28 May 2024 01:22:40 +0800 Subject: [PATCH 06/49] feat: berry theme update & bug fix (#1471) * feat: load channel models from server * chore: support AWS Claude/Cloudflare/Coze * fix: Popup message when copying fails * chore: Optimize tips --- web/berry/src/constants/ChannelConstants.js | 30 +- web/berry/src/constants/SnackbarConstants.js | 42 +- web/berry/src/utils/common.js | 37 ++ .../AuthForms/ResetPasswordForm.js | 43 +- .../src/views/Channel/component/EditModal.js | 502 +++++++----------- .../src/views/Channel/component/NameLabel.js | 27 +- web/berry/src/views/Channel/index.js | 8 +- web/berry/src/views/Channel/type/Config.js | 196 ++++--- web/berry/src/views/Profile/index.js | 5 +- .../views/Redemption/component/TableRow.js | 5 +- .../src/views/Token/component/TableRow.js | 14 +- .../src/views/Topup/component/InviteCard.js | 8 +- 12 files changed, 448 insertions(+), 469 deletions(-) diff --git a/web/berry/src/constants/ChannelConstants.js b/web/berry/src/constants/ChannelConstants.js index e6b0aed5..589ef1fb 100644 --- a/web/berry/src/constants/ChannelConstants.js +++ b/web/berry/src/constants/ChannelConstants.js @@ -11,12 +11,18 @@ export const CHANNEL_OPTIONS = { value: 14, color: 'primary' }, - // 33: { - // key: 33, - // text: 'AWS Claude', - // value: 33, - // color: 'primary' - // }, + 33: { + key: 33, + text: 'AWS Claude', + value: 33, + color: 'primary' + }, + 37: { + key: 37, + text: 'Cloudflare', + value: 37, + color: 'success' + }, 3: { key: 3, text: 'Azure OpenAI', @@ -119,12 +125,12 @@ export const CHANNEL_OPTIONS = { value: 32, color: 'primary' }, - // 34: { - // key: 34, - // text: 'Coze', - // value: 34, - // color: 'primary' - // }, + 34: { + key: 34, + text: 'Coze', + value: 34, + color: 'primary' + }, 35: { key: 35, text: 'Cohere', diff --git a/web/berry/src/constants/SnackbarConstants.js b/web/berry/src/constants/SnackbarConstants.js index 19523da1..05f79231 100644 --- a/web/berry/src/constants/SnackbarConstants.js +++ b/web/berry/src/constants/SnackbarConstants.js @@ -1,24 +1,56 @@ +import { closeSnackbar } from 'notistack'; +import { IconX } from '@tabler/icons-react'; +import { IconButton } from '@mui/material'; +const action = (snackbarId) => ( + <> + { + closeSnackbar(snackbarId); + }} + > + + + +); + export const snackbarConstants = { Common: { ERROR: { variant: 'error', - autoHideDuration: 5000 + autoHideDuration: 5000, + preventDuplicate: true, + action }, WARNING: { variant: 'warning', - autoHideDuration: 10000 + autoHideDuration: 10000, + preventDuplicate: true, + action }, SUCCESS: { variant: 'success', - autoHideDuration: 1500 + autoHideDuration: 1500, + preventDuplicate: true, + action }, INFO: { variant: 'info', - autoHideDuration: 3000 + autoHideDuration: 3000, + preventDuplicate: true, + action }, NOTICE: { variant: 'info', - autoHideDuration: 7000 + autoHideDuration: 20000, + preventDuplicate: true, + action + }, + COPY: { + variant: 'copy', + persist: true, + preventDuplicate: true, + allowDownload: true, + action } }, Mobile: { diff --git a/web/berry/src/utils/common.js b/web/berry/src/utils/common.js index 947df3bf..d74d032e 100644 --- a/web/berry/src/utils/common.js +++ b/web/berry/src/utils/common.js @@ -193,3 +193,40 @@ export function removeTrailingSlash(url) { return url; } } + +let channelModels = undefined; +export async function loadChannelModels() { + const res = await API.get('/api/models'); + const { success, data } = res.data; + if (!success) { + return; + } + channelModels = data; + localStorage.setItem('channel_models', JSON.stringify(data)); +} + +export function getChannelModels(type) { + if (channelModels !== undefined && type in channelModels) { + return channelModels[type]; + } + let models = localStorage.getItem('channel_models'); + if (!models) { + return []; + } + channelModels = JSON.parse(models); + if (type in channelModels) { + return channelModels[type]; + } + return []; +} + +export function copy(text, name = '') { + try { + navigator.clipboard.writeText(text); + } catch (error) { + text = `复制${name}失败,请手动复制:

${text}`; + enqueueSnackbar(, getSnackbarOptions('COPY')); + return; + } + showSuccess(`复制${name}成功!`); +} diff --git a/web/berry/src/views/Authentication/AuthForms/ResetPasswordForm.js b/web/berry/src/views/Authentication/AuthForms/ResetPasswordForm.js index eaa8dc95..a9f0f9e3 100644 --- a/web/berry/src/views/Authentication/AuthForms/ResetPasswordForm.js +++ b/web/berry/src/views/Authentication/AuthForms/ResetPasswordForm.js @@ -1,22 +1,22 @@ -import { useState, useEffect } from "react"; -import { useSearchParams } from "react-router-dom"; +import { useState, useEffect } from 'react'; +import { useSearchParams } from 'react-router-dom'; // material-ui -import { Button, Stack, Typography, Alert } from "@mui/material"; +import { Button, Stack, Typography, Alert } from '@mui/material'; // assets -import { showError, showInfo } from "utils/common"; -import { API } from "utils/api"; +import { showError, copy } from 'utils/common'; +import { API } from 'utils/api'; // ===========================|| FIREBASE - REGISTER ||=========================== // const ResetPasswordForm = () => { const [searchParams] = useSearchParams(); const [inputs, setInputs] = useState({ - email: "", - token: "", + email: '', + token: '' }); - const [newPassword, setNewPassword] = useState(""); + const [newPassword, setNewPassword] = useState(''); const submit = async () => { const res = await API.post(`/api/user/reset`, inputs); @@ -24,31 +24,25 @@ const ResetPasswordForm = () => { if (success) { let password = res.data.data; setNewPassword(password); - navigator.clipboard.writeText(password); - showInfo(`新密码已复制到剪贴板:${password}`); + copy(password, '新密码'); } else { showError(message); } }; useEffect(() => { - let email = searchParams.get("email"); - let token = searchParams.get("token"); + let email = searchParams.get('email'); + let token = searchParams.get('token'); setInputs({ token, - email, + email }); }, []); return ( - + {!inputs.email || !inputs.token ? ( - + 无效的链接 ) : newPassword ? ( @@ -57,14 +51,7 @@ const ResetPasswordForm = () => { 请登录后及时修改密码 ) : ( - )} diff --git a/web/berry/src/views/Channel/component/EditModal.js b/web/berry/src/views/Channel/component/EditModal.js index 03b4df57..4f7f216d 100644 --- a/web/berry/src/views/Channel/component/EditModal.js +++ b/web/berry/src/views/Channel/component/EditModal.js @@ -1,9 +1,9 @@ -import PropTypes from "prop-types"; -import { useState, useEffect } from "react"; -import { CHANNEL_OPTIONS } from "constants/ChannelConstants"; -import { useTheme } from "@mui/material/styles"; -import { API } from "utils/api"; -import { showError, showSuccess } from "utils/common"; +import PropTypes from 'prop-types'; +import { useState, useEffect } from 'react'; +import { CHANNEL_OPTIONS } from 'constants/ChannelConstants'; +import { useTheme } from '@mui/material/styles'; +import { API } from 'utils/api'; +import { showError, showSuccess, getChannelModels } from 'utils/common'; import { Dialog, DialogTitle, @@ -22,15 +22,15 @@ import { Autocomplete, FormHelperText, Switch, - Checkbox, -} from "@mui/material"; + Checkbox +} from '@mui/material'; -import { Formik } from "formik"; -import * as Yup from "yup"; -import { defaultConfig, typeConfig } from "../type/Config"; //typeConfig -import { createFilterOptions } from "@mui/material/Autocomplete"; -import CheckBoxOutlineBlankIcon from "@mui/icons-material/CheckBoxOutlineBlank"; -import CheckBoxIcon from "@mui/icons-material/CheckBox"; +import { Formik } from 'formik'; +import * as Yup from 'yup'; +import { defaultConfig, typeConfig } from '../type/Config'; //typeConfig +import { createFilterOptions } from '@mui/material/Autocomplete'; +import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank'; +import CheckBoxIcon from '@mui/icons-material/CheckBox'; const icon = ; const checkedIcon = ; @@ -38,38 +38,34 @@ const checkedIcon = ; const filter = createFilterOptions(); const validationSchema = Yup.object().shape({ is_edit: Yup.boolean(), - name: Yup.string().required("名称 不能为空"), - type: Yup.number().required("渠道 不能为空"), - key: Yup.string().when("is_edit", { - is: false, - then: Yup.string().required("密钥 不能为空"), + name: Yup.string().required('名称 不能为空'), + type: Yup.number().required('渠道 不能为空'), + key: Yup.string().when(['is_edit', 'type'], { + is: (is_edit, type) => !is_edit && type !== 33, + then: Yup.string().required('密钥 不能为空') }), other: Yup.string(), - models: Yup.array().min(1, "模型 不能为空"), - groups: Yup.array().min(1, "用户组 不能为空"), - base_url: Yup.string().when("type", { + models: Yup.array().min(1, '模型 不能为空'), + groups: Yup.array().min(1, '用户组 不能为空'), + base_url: Yup.string().when('type', { is: (value) => [3, 8].includes(value), - then: Yup.string().required("渠道API地址 不能为空"), // base_url 是必需的 - otherwise: Yup.string(), // 在其他情况下,base_url 可以是任意字符串 + then: Yup.string().required('渠道API地址 不能为空'), // base_url 是必需的 + otherwise: Yup.string() // 在其他情况下,base_url 可以是任意字符串 }), - model_mapping: Yup.string().test( - "is-json", - "必须是有效的JSON字符串", - function (value) { - try { - if (value === "" || value === null || value === undefined) { - return true; - } - const parsedValue = JSON.parse(value); - if (typeof parsedValue === "object") { - return true; - } - } catch (e) { - return false; + model_mapping: Yup.string().test('is-json', '必须是有效的JSON字符串', function (value) { + try { + if (value === '' || value === null || value === undefined) { + return true; } + const parsedValue = JSON.parse(value); + if (typeof parsedValue === 'object') { + return true; + } + } catch (e) { return false; } - ), + return false; + }) }); const EditModal = ({ open, channelId, onCancel, onOk }) => { @@ -81,12 +77,13 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { const [groupOptions, setGroupOptions] = useState([]); const [modelOptions, setModelOptions] = useState([]); const [batchAdd, setBatchAdd] = useState(false); + const [basicModels, setBasicModels] = useState([]); const initChannel = (typeValue) => { if (typeConfig[typeValue]?.inputLabel) { setInputLabel({ ...defaultConfig.inputLabel, - ...typeConfig[typeValue].inputLabel, + ...typeConfig[typeValue].inputLabel }); } else { setInputLabel(defaultConfig.inputLabel); @@ -95,7 +92,7 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { if (typeConfig[typeValue]?.prompt) { setInputPrompt({ ...defaultConfig.prompt, - ...typeConfig[typeValue].prompt, + ...typeConfig[typeValue].prompt }); } else { setInputPrompt(defaultConfig.prompt); @@ -104,40 +101,14 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { return typeConfig[typeValue]?.input; }; const handleTypeChange = (setFieldValue, typeValue, values) => { - const newInput = initChannel(typeValue); - - if (newInput) { - Object.keys(newInput).forEach((key) => { - if ( - (!Array.isArray(values[key]) && - values[key] !== null && - values[key] !== undefined && - values[key] !== "") || - (Array.isArray(values[key]) && values[key].length > 0) - ) { - return; - } - - if (key === "models") { - setFieldValue(key, initialModel(newInput[key])); - return; - } - setFieldValue(key, newInput[key]); - }); + initChannel(typeValue); + let localModels = getChannelModels(typeValue); + setBasicModels(localModels); + if (localModels.length > 0 && Array.isArray(values['models']) && values['models'].length == 0) { + setFieldValue('models', initialModel(localModels)); } - }; - const basicModels = (channelType) => { - let modelGroup = - typeConfig[channelType]?.modelGroup || defaultConfig.modelGroup; - // 循环 modelOptions,找到 modelGroup 对应的模型 - let modelList = []; - modelOptions.forEach((model) => { - if (model.group === modelGroup) { - modelList.push(model); - } - }); - return modelList; + setFieldValue('config', {}); }; const fetchGroups = async () => { @@ -155,7 +126,7 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { const { data } = res.data; data.forEach((item) => { if (!item.owned_by) { - item.owned_by = "未知"; + item.owned_by = '未知'; } }); // 先对data排序 @@ -171,7 +142,7 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { data.map((model) => { return { id: model.id, - group: model.owned_by, + group: model.owned_by }; }) ); @@ -182,33 +153,41 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { const submit = async (values, { setErrors, setStatus, setSubmitting }) => { setSubmitting(true); - if (values.base_url && values.base_url.endsWith("/")) { + if (values.base_url && values.base_url.endsWith('/')) { values.base_url = values.base_url.slice(0, values.base_url.length - 1); } - if (values.type === 3 && values.other === "") { - values.other = "2023-09-01-preview"; + if (values.type === 3 && values.other === '') { + values.other = '2023-09-01-preview'; } - if (values.type === 18 && values.other === "") { - values.other = "v2.1"; + if (values.type === 18 && values.other === '') { + values.other = 'v2.1'; } + if (values.key === '') { + if (values.config.ak !== '' && values.config.sk !== '' && values.config.region !== '') { + values.key = `${values.config.ak}|${values.config.sk}|${values.config.region}`; + } + } + let res; - const modelsStr = values.models.map((model) => model.id).join(","); - values.group = values.groups.join(","); + const modelsStr = values.models.map((model) => model.id).join(','); + const configStr = JSON.stringify(values.config); + values.group = values.groups.join(','); if (channelId) { res = await API.put(`/api/channel/`, { ...values, id: parseInt(channelId), models: modelsStr, + config: configStr }); } else { - res = await API.post(`/api/channel/`, { ...values, models: modelsStr }); + res = await API.post(`/api/channel/`, { ...values, models: modelsStr, config: configStr }); } const { success, message } = res.data; if (success) { if (channelId) { - showSuccess("渠道更新成功!"); + showSuccess('渠道更新成功!'); } else { - showSuccess("渠道创建成功!"); + showSuccess('渠道创建成功!'); } setSubmitting(false); setStatus({ success: true }); @@ -226,15 +205,15 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { } // 如果 channelModel 是一个字符串 - if (typeof channelModel === "string") { - channelModel = channelModel.split(","); + if (typeof channelModel === 'string') { + channelModel = channelModel.split(','); } let modelList = channelModel.map((model) => { const modelOption = modelOptions.find((option) => option.id === model); if (modelOption) { return modelOption; } - return { id: model, group: "自定义:点击或回车输入" }; + return { id: model, group: '自定义:点击或回车输入' }; }); return modelList; } @@ -243,24 +222,24 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { let res = await API.get(`/api/channel/${channelId}`); const { success, message, data } = res.data; if (success) { - if (data.models === "") { + if (data.models === '') { data.models = []; } else { data.models = initialModel(data.models); } - if (data.group === "") { + if (data.group === '') { data.groups = []; } else { - data.groups = data.group.split(","); + data.groups = data.group.split(','); } - if (data.model_mapping !== "") { - data.model_mapping = JSON.stringify( - JSON.parse(data.model_mapping), - null, - 2 - ); + if (data.model_mapping !== '') { + data.model_mapping = JSON.stringify(JSON.parse(data.model_mapping), null, 2); } - data.base_url = data.base_url ?? ""; + if (data.config !== '') { + data.config = JSON.parse(data.config); + } + + data.base_url = data.base_url ?? ''; data.is_edit = true; initChannel(data.type); setInitialInput(data); @@ -286,45 +265,25 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { }, [channelId]); return ( - + - {channelId ? "编辑渠道" : "新建渠道"} + {channelId ? '编辑渠道' : '新建渠道'} - - {({ - errors, - handleBlur, - handleChange, - handleSubmit, - isSubmitting, - touched, - values, - setFieldValue, - }) => ( + + {({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, values, setFieldValue }) => (
- - - {inputLabel.type} - + + {inputLabel.type}