refactor: 引用系统模型并入 Update,删除 /referenceSystemModel 端点
非超管 updateModelManage 编辑系统模型时直接插引用行(apiKey 必填、同名唯一、 不拷贝配置),前端继续走 updateModelManage 即可引用,无需换接口。 - 删 service.ReferenceSystemModel / controller.ReferenceModel / ReferenceSystemModelReq/Res - Update:恢复引用行(refSystemModelId>0)个人字段分支(只改 apiKey/enabled/chatModel) - 修复同名唯一性检查丢失自排除(exist.Id != req.Id),允许不改名编辑 - 非超管建引用行补 apiKey 必填校验 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -18,11 +18,6 @@ func (c *modelManage) CreateModel(ctx context.Context, req *dto.CreateModelManag
|
||||
return service.ModelManage.Create(ctx, req)
|
||||
}
|
||||
|
||||
// ReferenceModel 引用系统模型
|
||||
func (c *modelManage) ReferenceModel(ctx context.Context, req *dto.ReferenceSystemModelReq) (res *dto.ReferenceSystemModelRes, err error) {
|
||||
return service.ModelManage.ReferenceSystemModel(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateModel 更改配置
|
||||
func (c *modelManage) UpdateModel(ctx context.Context, req *dto.UpdateModelManageReq) (res *dto.GetModelManageRes, err error) {
|
||||
return service.ModelManage.Update(ctx, req)
|
||||
|
||||
@@ -155,15 +155,3 @@ type BuildSchemaMappingRes struct {
|
||||
SchemaMapping map[string]any `json:"schemaMapping" dc:"生成的 Schema 映射 JSON"`
|
||||
}
|
||||
|
||||
// ReferenceSystemModelReq 引用系统模型请求:用户只填 apiKey + 个人开关,配置实时跟随系统模型
|
||||
type ReferenceSystemModelReq struct {
|
||||
g.Meta `path:"/referenceSystemModel" method:"post" tags:"模型管理" summary:"引用系统模型" dc:"用户引用系统模型,只填 apiKey 等个人字段,配置实时跟随系统模型(不再全量拷贝)"`
|
||||
SystemModelId int64 `json:"systemModelId" v:"required#系统模型ID不能为空" dc:"被引用的系统模型ID"`
|
||||
ApiKey string `json:"apiKey" v:"required#apiKey不能为空" dc:"调用凭证/密钥"`
|
||||
ChatModel *bool `json:"chatModel" dc:"设为我的会话模型"`
|
||||
Enabled *bool `json:"enabled" dc:"启用(默认启用)"`
|
||||
}
|
||||
|
||||
type ReferenceSystemModelRes struct {
|
||||
Id int64 `json:"id,string" dc:"引用行ID"`
|
||||
}
|
||||
|
||||
@@ -63,67 +63,10 @@ func (s *modelManageService) Create(ctx context.Context, req *dto.CreateModelMan
|
||||
return
|
||||
}
|
||||
|
||||
// ReferenceSystemModel 用户引用系统模型:只填 apiKey + 个人开关,配置实时跟随系统模型。
|
||||
// 不拷贝配置(解析层实时取系统行);同名唯一(复用 Create 语义);会话模型开关复用 CancelChatModel。
|
||||
func (s *modelManageService) ReferenceSystemModel(ctx context.Context, req *dto.ReferenceSystemModelReq) (res *dto.ReferenceSystemModelRes, err error) {
|
||||
err = gfdb.DB(ctx, public.DbNameModelGateway).Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 1)目标必须是系统模型
|
||||
sys, err := dao.ModelManage.GetNotTenantId(ctx, &dto.GetModelManageReq{Id: req.SystemModelId})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sys == nil || sys.SystemModel == nil || !*sys.SystemModel {
|
||||
return fmt.Errorf("被引用的模型不存在或不是系统模型")
|
||||
}
|
||||
// 2)同名唯一:同一用户下不允许重复(引用行与自有模型同名同样拒绝)
|
||||
exist, err := dao.ModelManage.GetByCreatorAndName(ctx, user.UserName, sys.ModelName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exist != nil {
|
||||
return fmt.Errorf("模型名称 [%s] 已存在,同一用户下不能重复添加同名模型", sys.ModelName)
|
||||
}
|
||||
// 3)设为会话模型 → 先取消旧会话模型(isSuperAdmin 语义与 Create 一致)
|
||||
var isSuperAdmin bool
|
||||
isSuperAdmin, err = IsSuperAdmin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = s.CancelChatModel(ctx, sys.ModelType, req.ChatModel, isSuperAdmin); err != nil {
|
||||
return err
|
||||
}
|
||||
// 4)插引用行(配置列零值即可,解析层只读系统行配置)
|
||||
enabled := true
|
||||
if req.Enabled != nil {
|
||||
enabled = *req.Enabled
|
||||
}
|
||||
id, err := dao.ModelManage.Insert(ctx, &dto.CreateModelManageReq{
|
||||
ModelSupplier: sys.ModelSupplier,
|
||||
ModelName: sys.ModelName,
|
||||
ModelType: sys.ModelType,
|
||||
SystemModel: gconv.PtrBool(false),
|
||||
ChatModel: req.ChatModel,
|
||||
ApiKey: req.ApiKey,
|
||||
Enabled: gconv.PtrBool(enabled),
|
||||
RefSystemModelId: sys.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res = &dto.ReferenceSystemModelRes{Id: id}
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Update 更新模型配置
|
||||
// 引用行:只改 apiKey/enabled/chatModel,配置锁定跟随系统模型(其余字段忽略);
|
||||
// 系统模型:仅创建者(超管)可改配置,改名时同步引用行 model_name;
|
||||
// 用户自有模型:创建者可改全配置。非创建者操作他人行 → 无权限(引用不再靠"编辑系统模型"触发拷贝,改走 referenceSystemModel)。
|
||||
// 非超管编辑系统模型 → 建引用行(不拷贝配置,apiKey 必填);用户自有模型:创建者可改全配置。非创建者操作他人行 → 无权限。
|
||||
func (s *modelManageService) Update(ctx context.Context, req *dto.UpdateModelManageReq) (res *dto.GetModelManageRes, err error) {
|
||||
err = gfdb.DB(ctx, public.DbNameModelGateway).Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) {
|
||||
var get *entity.ModelManage
|
||||
@@ -142,8 +85,11 @@ func (s *modelManageService) Update(ctx context.Context, req *dto.UpdateModelMan
|
||||
return
|
||||
}
|
||||
|
||||
// 引用行:只应用个人字段,配置忽略(跟随系统模型;isSuperAdmin=false=个人会话模型开关)
|
||||
// 引用行:只改 apiKey/enabled/chatModel,配置锁定跟随系统模型(其余字段忽略;isSuperAdmin=false=个人会话模型开关)
|
||||
if get.RefSystemModelId > 0 {
|
||||
if get.Creator != user.UserName {
|
||||
return fmt.Errorf("无权限操作")
|
||||
}
|
||||
if err = s.CancelChatModel(ctx, get.ModelType, req.ChatModel, false); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -156,27 +102,7 @@ func (s *modelManageService) Update(ctx context.Context, req *dto.UpdateModelMan
|
||||
return
|
||||
}
|
||||
|
||||
// 非创建者 → 无权限(引用已由 referenceSystemModel 端点管理,不再拷贝)
|
||||
if get.Creator != user.UserName {
|
||||
return fmt.Errorf("无权限操作")
|
||||
}
|
||||
|
||||
// 1)检查是否是超管
|
||||
var isSuperAdmin bool
|
||||
isSuperAdmin, err = IsSuperAdmin(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
modelType := req.ModelType
|
||||
if g.IsEmpty(modelType) {
|
||||
modelType = get.ModelType
|
||||
}
|
||||
// 1)如果设为会话模型,先把该用户旧会话模型取消
|
||||
err = s.CancelChatModel(ctx, modelType, req.ChatModel, isSuperAdmin)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 2)模型名称唯一性:同一用户下不允许同名模型(排除自身)
|
||||
// 同名唯一性:同一用户下不允许同名模型(排除自身,允许不改名编辑)
|
||||
if !g.IsEmpty(req.ModelName) {
|
||||
var exist *entity.ModelManage
|
||||
exist, err = dao.ModelManage.GetByCreatorAndName(ctx, user.UserName, req.ModelName)
|
||||
@@ -187,10 +113,66 @@ func (s *modelManageService) Update(ctx context.Context, req *dto.UpdateModelMan
|
||||
return fmt.Errorf("模型名称 [%s] 已存在,同一用户下不能重复添加同名模型", req.ModelName)
|
||||
}
|
||||
}
|
||||
// 3)系统模型改名 → 同步引用行 model_name(保列表 DISTINCT ON 去重正确)
|
||||
if get.SystemModel != nil && *get.SystemModel && req.ModelName != "" && req.ModelName != get.ModelName {
|
||||
if _, err = dao.ModelManage.UpdateReferencesName(ctx, get.Id, req.ModelName); err != nil {
|
||||
return err
|
||||
|
||||
// 1)检查是否是超管
|
||||
var isSuperAdmin bool
|
||||
isSuperAdmin, err = IsSuperAdmin(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = s.CancelChatModel(ctx, get.ModelType, req.ChatModel, isSuperAdmin); err != nil {
|
||||
return err
|
||||
}
|
||||
if isSuperAdmin {
|
||||
if get.Creator != user.UserName {
|
||||
return fmt.Errorf("无权限操作")
|
||||
}
|
||||
// 3)系统模型改名 → 同步引用行 model_name(保列表 DISTINCT ON 去重正确)
|
||||
if get.SystemModel != nil && *get.SystemModel && req.ModelName != "" && req.ModelName != get.ModelName {
|
||||
if _, err = dao.ModelManage.UpdateReferencesName(ctx, get.Id, req.ModelName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if get.SystemModel != nil && *get.SystemModel {
|
||||
// 用户引用系统模型:apiKey 必填(与旧拷贝分支一致,空 key 引用行无意义)
|
||||
if g.IsEmpty(req.ApiKey) {
|
||||
return fmt.Errorf("模型apiKey不能为空")
|
||||
}
|
||||
var exist *entity.ModelManage
|
||||
exist, err = dao.ModelManage.GetByCreatorAndName(ctx, user.UserName, get.ModelName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if exist != nil {
|
||||
return fmt.Errorf("模型名称 [%s] 已存在,同一用户下不能重复添加同名模型", get.ModelName)
|
||||
}
|
||||
// 4)插引用行(配置列零值即可,解析层只读系统行配置)
|
||||
enabled := true
|
||||
if req.Enabled != nil {
|
||||
enabled = *req.Enabled
|
||||
}
|
||||
var id int64
|
||||
id, err = dao.ModelManage.Insert(ctx, &dto.CreateModelManageReq{
|
||||
ModelSupplier: get.ModelSupplier,
|
||||
ModelName: get.ModelName,
|
||||
ModelType: get.ModelType,
|
||||
SystemModel: gconv.PtrBool(false),
|
||||
ChatModel: req.ChatModel,
|
||||
ApiKey: req.ApiKey,
|
||||
Enabled: gconv.PtrBool(enabled),
|
||||
RefSystemModelId: get.Id,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err = s.Get(ctx, &dto.GetModelManageReq{
|
||||
Id: id,
|
||||
})
|
||||
return
|
||||
}
|
||||
if get.Creator != user.UserName {
|
||||
return fmt.Errorf("无权限操作")
|
||||
}
|
||||
}
|
||||
// 4)更新数据
|
||||
|
||||
Reference in New Issue
Block a user