Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
c5b9d713
authored
Jul 17, 2025
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 修复vertex渠道编辑密钥功能失效
parent
fd3fe7fe
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
54 additions
and
78 deletions
+54
-78
controller/channel.go
+54
-78
No files found.
controller/channel.go
View file @
c5b9d713
...
@@ -350,6 +350,46 @@ func GetChannel(c *gin.Context) {
...
@@ -350,6 +350,46 @@ func GetChannel(c *gin.Context) {
return
return
}
}
// validateChannel 通用的渠道校验函数
func
validateChannel
(
channel
*
model
.
Channel
,
isAdd
bool
)
error
{
// 校验 channel settings
if
err
:=
channel
.
ValidateSettings
();
err
!=
nil
{
return
fmt
.
Errorf
(
"渠道额外设置[channel setting] 格式错误:%s"
,
err
.
Error
())
}
// 如果是添加操作,检查 channel 和 key 是否为空
if
isAdd
{
if
channel
==
nil
||
channel
.
Key
==
""
{
return
fmt
.
Errorf
(
"channel cannot be empty"
)
}
// 检查模型名称长度是否超过 255
for
_
,
m
:=
range
channel
.
GetModels
()
{
if
len
(
m
)
>
255
{
return
fmt
.
Errorf
(
"模型名称过长: %s"
,
m
)
}
}
}
// VertexAI 特殊校验
if
channel
.
Type
==
constant
.
ChannelTypeVertexAi
{
if
channel
.
Other
==
""
{
return
fmt
.
Errorf
(
"部署地区不能为空"
)
}
regionMap
,
err
:=
common
.
StrToMap
(
channel
.
Other
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"部署地区必须是标准的Json格式,例如{
\"
default
\"
:
\"
us-central1
\"
,
\"
region2
\"
:
\"
us-east1
\"
}"
)
}
if
regionMap
[
"default"
]
==
nil
{
return
fmt
.
Errorf
(
"部署地区必须包含default字段"
)
}
}
return
nil
}
type
AddChannelRequest
struct
{
type
AddChannelRequest
struct
{
Mode
string
`json:"mode"`
Mode
string
`json:"mode"`
MultiKeyMode
constant
.
MultiKeyMode
`json:"multi_key_mode"`
MultiKeyMode
constant
.
MultiKeyMode
`json:"multi_key_mode"`
...
@@ -396,59 +436,15 @@ func AddChannel(c *gin.Context) {
...
@@ -396,59 +436,15 @@ func AddChannel(c *gin.Context) {
return
return
}
}
err
=
addChannelRequest
.
Channel
.
ValidateSettings
()
// 使用统一的校验函数
if
err
!=
nil
{
if
err
:=
validateChannel
(
addChannelRequest
.
Channel
,
true
);
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"channel setting 格式错误:"
+
err
.
Error
(),
})
return
}
if
addChannelRequest
.
Channel
==
nil
||
addChannelRequest
.
Channel
.
Key
==
""
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"success"
:
false
,
"message"
:
"channel cannot be empty"
,
"message"
:
err
.
Error
()
,
})
})
return
return
}
}
// Validate the length of the model name
for
_
,
m
:=
range
addChannelRequest
.
Channel
.
GetModels
()
{
if
len
(
m
)
>
255
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
fmt
.
Sprintf
(
"模型名称过长: %s"
,
m
),
})
return
}
}
if
addChannelRequest
.
Channel
.
Type
==
constant
.
ChannelTypeVertexAi
{
if
addChannelRequest
.
Channel
.
Other
==
""
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"部署地区不能为空"
,
})
return
}
else
{
regionMap
,
err
:=
common
.
StrToMap
(
addChannelRequest
.
Channel
.
Other
)
if
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"部署地区必须是标准的Json格式,例如{
\"
default
\"
:
\"
us-central1
\"
,
\"
region2
\"
:
\"
us-east1
\"
}"
,
})
return
}
if
regionMap
[
"default"
]
==
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"部署地区必须包含default字段"
,
})
return
}
}
}
addChannelRequest
.
Channel
.
CreatedTime
=
common
.
GetTimestamp
()
addChannelRequest
.
Channel
.
CreatedTime
=
common
.
GetTimestamp
()
keys
:=
make
([]
string
,
0
)
keys
:=
make
([]
string
,
0
)
switch
addChannelRequest
.
Mode
{
switch
addChannelRequest
.
Mode
{
...
@@ -676,39 +672,15 @@ func UpdateChannel(c *gin.Context) {
...
@@ -676,39 +672,15 @@ func UpdateChannel(c *gin.Context) {
common
.
ApiError
(
c
,
err
)
common
.
ApiError
(
c
,
err
)
return
return
}
}
err
=
channel
.
ValidateSettings
()
if
err
!=
nil
{
// 使用统一的校验函数
if
err
:=
validateChannel
(
&
channel
.
Channel
,
false
);
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"success"
:
false
,
"message"
:
"channel setting 格式错误:"
+
err
.
Error
(),
"message"
:
err
.
Error
(),
})
})
return
return
}
}
if
channel
.
Type
==
constant
.
ChannelTypeVertexAi
{
if
channel
.
Other
==
""
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"部署地区不能为空"
,
})
return
}
else
{
regionMap
,
err
:=
common
.
StrToMap
(
channel
.
Other
)
if
err
!=
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"部署地区必须是标准的Json格式,例如{
\"
default
\"
:
\"
us-central1
\"
,
\"
region2
\"
:
\"
us-east1
\"
}"
,
})
return
}
if
regionMap
[
"default"
]
==
nil
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
false
,
"message"
:
"部署地区必须包含default字段"
,
})
return
}
}
}
// Preserve existing ChannelInfo to ensure multi-key channels keep correct state even if the client does not send ChannelInfo in the request.
// Preserve existing ChannelInfo to ensure multi-key channels keep correct state even if the client does not send ChannelInfo in the request.
originChannel
,
err
:=
model
.
GetChannelById
(
channel
.
Id
,
false
)
originChannel
,
err
:=
model
.
GetChannelById
(
channel
.
Id
,
false
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -731,6 +703,9 @@ func UpdateChannel(c *gin.Context) {
...
@@ -731,6 +703,9 @@ func UpdateChannel(c *gin.Context) {
common
.
ApiError
(
c
,
err
)
common
.
ApiError
(
c
,
err
)
return
return
}
}
if
common
.
MemoryCacheEnabled
{
model
.
InitChannelCache
()
}
channel
.
Key
=
""
channel
.
Key
=
""
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
c
.
JSON
(
http
.
StatusOK
,
gin
.
H
{
"success"
:
true
,
"success"
:
true
,
...
@@ -888,8 +863,9 @@ func GetTagModels(c *gin.Context) {
...
@@ -888,8 +863,9 @@ func GetTagModels(c *gin.Context) {
// CopyChannel handles cloning an existing channel with its key.
// CopyChannel handles cloning an existing channel with its key.
// POST /api/channel/copy/:id
// POST /api/channel/copy/:id
// Optional query params:
// Optional query params:
// suffix - string appended to the original name (default "_复制")
//
// reset_balance - bool, when true will reset balance & used_quota to 0 (default true)
// suffix - string appended to the original name (default "_复制")
// reset_balance - bool, when true will reset balance & used_quota to 0 (default true)
func
CopyChannel
(
c
*
gin
.
Context
)
{
func
CopyChannel
(
c
*
gin
.
Context
)
{
id
,
err
:=
strconv
.
Atoi
(
c
.
Param
(
"id"
))
id
,
err
:=
strconv
.
Atoi
(
c
.
Param
(
"id"
))
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -914,7 +890,7 @@ func CopyChannel(c *gin.Context) {
...
@@ -914,7 +890,7 @@ func CopyChannel(c *gin.Context) {
// clone channel
// clone channel
clone
:=
*
origin
// shallow copy is sufficient as we will overwrite primitives
clone
:=
*
origin
// shallow copy is sufficient as we will overwrite primitives
clone
.
Id
=
0
// let DB auto-generate
clone
.
Id
=
0
// let DB auto-generate
clone
.
CreatedTime
=
common
.
GetTimestamp
()
clone
.
CreatedTime
=
common
.
GetTimestamp
()
clone
.
Name
=
origin
.
Name
+
suffix
clone
.
Name
=
origin
.
Name
+
suffix
clone
.
TestTime
=
0
clone
.
TestTime
=
0
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment