fix: 引用行查询 Get 合入系统模型配置返回

引用行(ref_system_model_id>0)在 DB 只存个人字段(apiKey/enabled/chatModel),
Get 之前返回空配置,前端编辑表单无法补全。新增 mergeReferenceConfigForQuery:
以引用行身份字段为基底,把系统行配置列合入返回(不替换 {apiKey} 占位、
不做 enabled AND 门禁,区别于调用时 mergeReferenceConfig)。
保留引用行自身 id,Update/Delete 仍命中引用行。
This commit is contained in:
2026-08-29 16:59:05 +08:00
parent b165ef4f3e
commit 7dcfb6744d
3 changed files with 83 additions and 0 deletions
+10
View File
@@ -261,6 +261,16 @@ func (s *modelManageService) Get(ctx context.Context, req *dto.GetModelManageReq
if get == nil {
return new(dto.GetModelManageRes), nil
}
// 引用行 → 合入系统模型配置返回(前端展示/编辑需要完整配置;保留引用行自身 id 供更新/删除)
if get.RefSystemModelId > 0 {
sys, e := dao.ModelManage.GetNotTenantId(ctx, &dto.GetModelManageReq{Id: get.RefSystemModelId})
if e != nil {
return nil, e
}
if sys != nil {
get = mergeReferenceConfigForQuery(get, sys)
}
}
// 系统模型 apiKey 对非创建者脱敏(引用行/自有行仅本人可见)
user, err := utils.GetUserInfo(ctx)
if err != nil {
+28
View File
@@ -96,6 +96,34 @@ func mergeReferenceConfig(stub, sys *entity.ModelManage) *entity.ModelManage {
return &out
}
// mergeReferenceConfigForQuery 管理端 Get 查询展示用:以引用行为基底,把系统行的配置列合入,
// 保留引用行自身 Id/RefSystemModelId/SystemModel/Creator/时间戳与个人字段(apiKey/enabled/chatModel)。
// 与 mergeReferenceConfig 的区别:不替换 {apiKey}(Get 非引用行也不替换,展示模板),
// enabled 不做 AND(展示引用行个人开关,调用时才按系统行生效状态门禁)。
func mergeReferenceConfigForQuery(stub, sys *entity.ModelManage) *entity.ModelManage {
out := *stub
out.BaseURL = sys.BaseURL
out.HttpMethod = sys.HttpMethod
out.ResponseType = sys.ResponseType
out.RequestHeadMapping = sys.RequestHeadMapping
out.RequestBodyMapping = sys.RequestBodyMapping
out.RequestBusinessFieldMapping = sys.RequestBusinessFieldMapping
out.ResponseMapping = sys.ResponseMapping
out.ResponseBodyMapping = sys.ResponseBodyMapping
out.ResponseBusinessFieldMapping = sys.ResponseBusinessFieldMapping
out.MaxConcurrency = sys.MaxConcurrency
out.TokenMapping = sys.TokenMapping
out.AsyncTaskMapping = sys.AsyncTaskMapping
out.TokenPredictPrice = sys.TokenPredictPrice
out.TokenPredictPriceUnit = sys.TokenPredictPriceUnit
out.MaxTokens = sys.MaxTokens
out.MinDuration = sys.MinDuration
out.MaxDuration = sys.MaxDuration
out.LastFrame = sys.LastFrame
out.ErrorMessageMapping = sys.ErrorMessageMapping
return &out
}
// resolveModelConfig 把请求命中的模型行解析为可执行配置:
// 引用行 → 系统行配置 + 引用行 apiKey(Id 覆盖为系统模型 id);非引用行 → 原配置 + 自身 apiKey 替换占位。
// 引用系统模型已删除 → 报错(调用方阻塞)。
+45
View File
@@ -107,6 +107,51 @@ func TestMergeReferenceConfig(t *testing.T) {
}
}
func TestMergeReferenceConfigForQuery(t *testing.T) {
sys := &entity.ModelManage{
SQLBaseDO: beans.SQLBaseDO{Id: 100, Creator: "admin"}, BaseURL: "https://sys",
SystemModel: gconv.PtrBool(true), Enabled: gconv.PtrBool(false),
RequestHeadMapping: map[string]string{"Authorization": "Bearer {apiKey}"},
TokenMapping: &entity.TokenMapping{PromptTokens: "a"},
}
stub := &entity.ModelManage{
SQLBaseDO: beans.SQLBaseDO{Id: 200, Creator: "user"}, RefSystemModelId: 100,
SystemModel: gconv.PtrBool(false), Enabled: gconv.PtrBool(true), ApiKey: "sk-user",
}
out := mergeReferenceConfigForQuery(stub, sys)
// 保留引用行自身身份字段
if out.Id != 200 {
t.Fatalf("id should keep stub: %d", out.Id)
}
if out.RefSystemModelId != 100 {
t.Fatalf("refSystemModelId should keep stub: %d", out.RefSystemModelId)
}
if out.Creator != "user" {
t.Fatalf("creator should keep stub: %s", out.Creator)
}
if out.SystemModel == nil || *out.SystemModel {
t.Fatalf("systemModel should keep stub (false)")
}
// 配置列合入系统行
if out.BaseURL != "https://sys" {
t.Fatalf("baseURL should follow sys: %s", out.BaseURL)
}
if out.RequestHeadMapping["Authorization"] != "Bearer {apiKey}" {
t.Fatalf("head mapping should follow sys template (不替换占位): %v", out.RequestHeadMapping)
}
if out.TokenMapping == nil || out.TokenMapping.PromptTokens != "a" {
t.Fatalf("tokenMapping should follow sys")
}
// 个人字段保留引用行(不做系统 enabled 的 AND 门禁)
if out.ApiKey != "sk-user" {
t.Fatalf("apiKey should keep stub: %s", out.ApiKey)
}
if out.Enabled == nil || !*out.Enabled {
t.Fatalf("enabled should keep stub (系统停用不在此门禁)")
}
}
func TestResolveModelConfigNonReference(t *testing.T) {
m := &entity.ModelManage{SQLBaseDO: beans.SQLBaseDO{Id: 5}, BaseURL: "https://x?key={apiKey}", ApiKey: "sk-sys"}
out, err := resolveModelConfig(nil, m) // 非引用路径不触 DB,ctx 可为 nil