feat(channel): enhance AddChannel functionality with structured request handling

This commit is contained in:
CaIon
2025-06-16 00:37:22 +08:00
parent d2b47969da
commit 0089157b83
3 changed files with 94 additions and 24 deletions

View File

@@ -250,9 +250,14 @@ func GetChannel(c *gin.Context) {
return return
} }
type AddChannelRequest struct {
Mode string `json:"mode"`
Channel *model.Channel `json:"channel"`
}
func AddChannel(c *gin.Context) { func AddChannel(c *gin.Context) {
channel := model.Channel{} addChannelRequest := AddChannelRequest{}
err := c.ShouldBindJSON(&channel) err := c.ShouldBindJSON(&addChannelRequest)
if err != nil { if err != nil {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
@@ -260,19 +265,35 @@ func AddChannel(c *gin.Context) {
}) })
return return
} }
channel.CreatedTime = common.GetTimestamp() if addChannelRequest.Channel == nil || addChannelRequest.Channel.Key == "" {
keys := strings.Split(channel.Key, "\n") c.JSON(http.StatusOK, gin.H{
if channel.Type == common.ChannelTypeVertexAi { "success": false,
if channel.Other == "" { "message": "channel cannot be empty",
})
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 == common.ChannelTypeVertexAi {
if addChannelRequest.Channel.Other == "" {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
"message": "部署地区不能为空", "message": "部署地区不能为空",
}) })
return return
} else { } else {
if common.IsJsonStr(channel.Other) { if common.IsJsonStr(addChannelRequest.Channel.Other) {
// must have default // must have default
regionMap := common.StrToMap(channel.Other) regionMap := common.StrToMap(addChannelRequest.Channel.Other)
if regionMap["default"] == nil { if regionMap["default"] == nil {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"success": false, "success": false,
@@ -282,27 +303,69 @@ func AddChannel(c *gin.Context) {
} }
} }
} }
keys = []string{channel.Key}
} }
addChannelRequest.Channel.CreatedTime = common.GetTimestamp()
keys := make([]string, 0)
switch addChannelRequest.Mode {
case "multi_to_single":
addChannelRequest.Channel.ChannelInfo.MultiKeyMode = true
if addChannelRequest.Channel.Type == common.ChannelTypeVertexAi {
if !common.IsJsonStr(addChannelRequest.Channel.Key) {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "Vertex AI 批量添加模式必须使用标准的JsonArray格式例如[{key1}, {key2}...],请检查输入",
})
return
}
}
keys = []string{addChannelRequest.Channel.Key}
case "batch":
if addChannelRequest.Channel.Type == common.ChannelTypeVertexAi {
// multi json
if !common.IsJsonStr(addChannelRequest.Channel.Key) {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "Vertex AI 批量添加模式必须使用标准的JsonArray格式例如[{key1}, {key2}...],请检查输入",
})
return
}
toMap := common.StrToMap(addChannelRequest.Channel.Key)
if toMap == nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "Vertex AI 批量添加模式必须使用标准的JsonArray格式例如[{key1}, {key2}...],请检查输入",
})
return
}
keys = make([]string, 0, len(toMap))
for k := range toMap {
if k == "" {
continue
}
keys = append(keys, k)
}
} else {
keys = strings.Split(addChannelRequest.Channel.Key, "\n")
}
case "single":
keys = []string{addChannelRequest.Channel.Key}
default:
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "不支持的添加模式",
})
return
}
channels := make([]model.Channel, 0, len(keys)) channels := make([]model.Channel, 0, len(keys))
for _, key := range keys { for _, key := range keys {
if key == "" { if key == "" {
continue continue
} }
localChannel := channel localChannel := addChannelRequest.Channel
localChannel.Key = key localChannel.Key = key
// Validate the length of the model name channels = append(channels, *localChannel)
models := strings.Split(localChannel.Models, ",")
for _, model := range models {
if len(model) > 255 {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": fmt.Sprintf("模型名称过长: %s", model),
})
return
}
}
channels = append(channels, localChannel)
} }
err = model.BatchInsertChannels(channels) err = model.BatchInsertChannels(channels)
if err != nil { if err != nil {

View File

@@ -9,6 +9,11 @@ import (
"gorm.io/gorm" "gorm.io/gorm"
) )
type ChannelInfo struct {
MultiKeyMode bool `json:"multi_key_mode"` // 是否多Key模式
MultiKeyStatusList map[int]int `json:"multi_key_status_list"` // key状态列表key index -> status
}
type Channel struct { type Channel struct {
Id int `json:"id"` Id int `json:"id"`
Type int `json:"type" gorm:"default:0"` Type int `json:"type" gorm:"default:0"`
@@ -35,8 +40,10 @@ type Channel struct {
AutoBan *int `json:"auto_ban" gorm:"default:1"` AutoBan *int `json:"auto_ban" gorm:"default:1"`
OtherInfo string `json:"other_info"` OtherInfo string `json:"other_info"`
Tag *string `json:"tag" gorm:"index"` Tag *string `json:"tag" gorm:"index"`
Setting *string `json:"setting" gorm:"type:text"` Setting *string `json:"setting" gorm:"type:text"` // 渠道额外设置
ParamOverride *string `json:"param_override" gorm:"type:text"` ParamOverride *string `json:"param_override" gorm:"type:text"`
// add after v0.8.5
ChannelInfo ChannelInfo `json:"channel_info" gorm:"type:json"`
} }
func (channel *Channel) GetModels() []string { func (channel *Channel) GetModels() []string {

View File

@@ -48,7 +48,7 @@ func initCol() {
} }
} }
// log sql type and database type // log sql type and database type
common.SysLog("Using Log SQL Type: " + common.LogSqlType) //common.SysLog("Using Log SQL Type: " + common.LogSqlType)
} }
var DB *gorm.DB var DB *gorm.DB