feat(channel): 对齐 vivid 最新渠道/模型管理设计
渠道管理(对齐 9db9971/9f6eeca/b607a8d/268a8f7/7f8a87e): - 列表新增「运行中」(Redis 并发槽位实时计数,与调度同源)和「失败数」 (event_logs 按渠道聚合)两列 - 行内「同步上游模型」恢复弹窗:默认全开、右侧开关、彩点+单行别名, 底部「同步模型」批量导入;编辑表单去掉获取模型列表按钮(保存已自动 全量同步);去掉勾选即解绑语义与 unbind-model 端点 - 导入加固:别名与上游同名报错、同批别名复用拒绝、本地类型冲突拒绝、 单次上限 50 模型管理(对齐 5545195): - 模型表单/CreateModel 补齐 max_reference_videos/audios 与 max_ref_video/audio_seconds 透传 产物(对齐 2253e58): - 下载结果仅信任 image/*/video/* 响应头,text/plain 等乱报一律按魔数 嗅探定 MIME Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
@@ -125,24 +125,6 @@ func (h *ChannelAdminHandler) ImportModels(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
// UnbindModel detaches one upstream model from a channel; the local model row
|
||||
// is deleted too when no other channel still binds it.
|
||||
func (h *ChannelAdminHandler) UnbindModel(c *gin.Context) {
|
||||
var body struct {
|
||||
ID string `json:"id"`
|
||||
Model string `json:"model"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&body); err != nil || strings.TrimSpace(body.ID) == "" || strings.TrimSpace(body.Model) == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"detail": "id and model required"})
|
||||
return
|
||||
}
|
||||
if err := h.channels.UnbindModel(c.Request.Context(), body.ID, body.Model); err != nil {
|
||||
writeUpstreamErr(c, err)
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
// writeUpstreamErr translates upstream-protocol errors into sensible admin
|
||||
// responses (auth → 400 with the upstream's message, temporary → 502).
|
||||
func writeUpstreamErr(c *gin.Context, err error) {
|
||||
|
||||
Reference in New Issue
Block a user