模型定价: 悬空模型标记 + 一键清除 + 允许渠道只读
- 无渠道绑定的模型以「悬空」琥珀色徽标 + 卡片着色标记 - 新增「清除悬空」一键删除未绑定渠道的模型(DELETE /models/unused) - 移除页面内「绑定渠道」弹窗与 chips 的解除按钮,渠道支持列表只在渠道抽屉管理 - 缺失提示带上渠道真实模型名(upstream_model) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -45,19 +45,22 @@ func (h *Handler) AdminModels(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// 渠道提供了但目录中缺失的模型(孤儿绑定,数据不一致时出现)
|
||||
// 渠道选中但目录中缺失的模型(孤儿绑定:渠道绑定指向已被删除的模型)
|
||||
var orphans []struct {
|
||||
ChannelName string
|
||||
ModelID uint64
|
||||
ChannelName string
|
||||
UpstreamModel string
|
||||
ModelID uint64
|
||||
}
|
||||
h.a.DB.Raw(`SELECT c.name as channel_name, b.model_id
|
||||
h.a.DB.Raw(`SELECT c.name as channel_name, b.model_id, b.upstream_model
|
||||
FROM channel_model_bindings b
|
||||
LEFT JOIN models m ON m.id = b.model_id
|
||||
LEFT JOIN channels c ON c.id = b.channel_id
|
||||
WHERE m.id IS NULL`).Scan(&orphans)
|
||||
missing := make([]gin.H, 0, len(orphans))
|
||||
for _, o := range orphans {
|
||||
missing = append(missing, gin.H{"channel": o.ChannelName, "model_id": o.ModelID})
|
||||
missing = append(missing, gin.H{
|
||||
"channel": o.ChannelName, "model_id": o.ModelID, "upstream_model": o.UpstreamModel,
|
||||
})
|
||||
}
|
||||
|
||||
// 在用但未定价的模型数(渠道已提供、需定价)
|
||||
@@ -210,6 +213,29 @@ func (h *Handler) AdminDeleteModel(c *gin.Context) {
|
||||
resp.OK(c, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
// AdminDeleteUnusedModels DELETE /api/v1/admin/models/unused — 一键清除未绑定任何渠道的模型。
|
||||
// 这些通常是渠道抽屉里选中过、后来又取消绑定留下的目录条目,客户端无法调用。
|
||||
func (h *Handler) AdminDeleteUnusedModels(c *gin.Context) {
|
||||
var orphans []store.Model
|
||||
if err := h.a.DB.Where("id NOT IN (SELECT DISTINCT model_id FROM channel_model_bindings)").Find(&orphans).Error; err != nil {
|
||||
resp.Fail(c, http.StatusInternalServerError, "failed to load models")
|
||||
return
|
||||
}
|
||||
names := make([]string, 0, len(orphans))
|
||||
ids := make([]uint64, 0, len(orphans))
|
||||
for _, m := range orphans {
|
||||
names = append(names, m.Name)
|
||||
ids = append(ids, m.ID)
|
||||
}
|
||||
if len(ids) > 0 {
|
||||
if err := h.a.DB.Delete(&store.Model{}, ids).Error; err != nil {
|
||||
resp.Fail(c, http.StatusInternalServerError, "failed to delete models")
|
||||
return
|
||||
}
|
||||
}
|
||||
resp.OK(c, gin.H{"deleted": names, "count": len(names)})
|
||||
}
|
||||
|
||||
// AdminCreateModelBinding POST /api/v1/admin/models/:id/bindings
|
||||
func (h *Handler) AdminCreateModelBinding(c *gin.Context) {
|
||||
modelID, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
|
||||
Reference in New Issue
Block a user