From b99f43b31fa84e5e42544bcd15f20883a64aa98b Mon Sep 17 00:00:00 2001 From: qhd <1766646056@qq.com> Date: Sat, 29 Aug 2026 14:37:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=B0=83=E7=94=A8=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E5=BC=95=E7=94=A8=E8=A7=A3=E6=9E=90=EF=BC=8C=E8=AE=A1?= =?UTF-8?q?=E4=BB=B7=E6=8C=89=E7=B3=BB=E7=BB=9F=E6=A8=A1=E5=9E=8B=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ModelCall/ModelCallStream:GetNotTenantId 后 resolveModelConfig,modelBillable 改 modelInfo.Id - 异步 task_end:轮询/计价用解析后系统模型配置,calcModelCost 改 modelInfo.Id Co-Authored-By: Claude --- service/model_call_service.go | 28 ++++++++++++++++++++++------ service/model_task_end_service.go | 13 +++++++++++-- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/service/model_call_service.go b/service/model_call_service.go index 2993aea..de45342 100644 --- a/service/model_call_service.go +++ b/service/model_call_service.go @@ -30,7 +30,15 @@ func (s *modelCallService) ModelCall(ctx context.Context, req *dto.ModelCallReq) if err != nil { return nil, fmt.Errorf("获取模型配置失败: %v", err) } - if modelInfo == nil || (modelInfo.Enabled != nil && !*modelInfo.Enabled) { + if modelInfo == nil { + return nil, fmt.Errorf("模型不存在") + } + // 引用行 → 解析为系统模型配置+本人 apiKey;系统模型已删除等解析失败 → 阻塞调用 + modelInfo, err = resolveModelConfig(ctx, modelInfo) + if err != nil { + return nil, err + } + if modelInfo.Enabled != nil && !*modelInfo.Enabled { return nil, fmt.Errorf("模型不存在或未启用") } @@ -39,8 +47,8 @@ func (s *modelCallService) ModelCall(ctx context.Context, req *dto.ModelCallReq) if err != nil { return } - // 调用前检查模型计价配置(shop-user-trade):未配置/未启用 → 阻塞调用 - if err = modelBillable(ctx, req.ModelId); err != nil { + // 调用前检查模型计价配置(shop-user-trade):未配置/未启用 → 阻塞调用(subject=解析后的系统模型 id) + if err = modelBillable(ctx, modelInfo.Id); err != nil { return nil, err } err = queue(ctx, modelInfo.ModelName, userInfo.TenantId, gconv.Int64(modelInfo.MaxConcurrency), func(ctx context.Context) (err error) { @@ -101,7 +109,15 @@ func (s *modelCallService) ModelCallStream(ctx context.Context, w http.ResponseW if err != nil { return fmt.Errorf("获取模型配置失败: %v", err) } - if modelInfo == nil || (modelInfo.Enabled != nil && !*modelInfo.Enabled) { + if modelInfo == nil { + return fmt.Errorf("模型不存在") + } + // 引用行 → 解析为系统模型配置+本人 apiKey;系统模型已删除等解析失败 → 阻塞调用 + modelInfo, err = resolveModelConfig(ctx, modelInfo) + if err != nil { + return err + } + if modelInfo.Enabled != nil && !*modelInfo.Enabled { return fmt.Errorf("模型不存在或未启用") } if *modelInfo.ResponseType == *model.ResponseTypeStream.Code() { @@ -110,8 +126,8 @@ func (s *modelCallService) ModelCallStream(ctx context.Context, w http.ResponseW if err != nil { return err } - // 调用前检查模型计价配置(shop-user-trade):未配置/未启用 → 阻塞调用 - if err = modelBillable(ctx, req.ModelId); err != nil { + // 调用前检查模型计价配置(shop-user-trade):未配置/未启用 → 阻塞调用(subject=解析后的系统模型 id) + if err = modelBillable(ctx, modelInfo.Id); err != nil { return err } err = queue(ctx, modelInfo.ModelName, userInfo.TenantId, gconv.Int64(modelInfo.MaxConcurrency), func(ctx context.Context) (err error) { diff --git a/service/model_task_end_service.go b/service/model_task_end_service.go index 33895e4..e8ff345 100644 --- a/service/model_task_end_service.go +++ b/service/model_task_end_service.go @@ -198,6 +198,15 @@ func (s *modelTaskEndService) processClaimedTask(asyncCtx context.Context, item return nil } + // 引用行 → 解析为系统模型配置+本人 apiKey(轮询/计价均用系统模型) + modelInfo, err = resolveModelConfig(asyncCtx, modelInfo) + if err != nil { + g.Log().Errorf(asyncCtx, "模型配置解析失败: modelId=%d err=%v", item.ModelId, err) + docMsg.ErrorMsg = fmt.Sprintf("模型配置解析失败: %v", err) + finalize() + return nil + } + // 连续轮询失败上限:瞬时抖动(HTTP 错/空响应/解析失败)先有限重试,超限按终态错误落库 const maxPollErrRetries = 3 pollErrCnt := 0 @@ -281,8 +290,8 @@ LOOP: docMsg.PromptTokens = gconv.Int64(modelUtils.GetByPathValue(respObj, promptTokPath)) docMsg.CompletionTokens = gconv.Int64(modelUtils.GetByPathValue(respObj, compTokPath)) - // 调 shop-user-trade 按用量算费(媒体类型取任务创建时的快照) - docMsg.Cost = calcModelCost(asyncCtx, item.ModelId, + // 调 shop-user-trade 按用量算费(媒体类型取任务创建时的快照;subject=解析后的系统模型 id) + docMsg.Cost = calcModelCost(asyncCtx, modelInfo.Id, buildModelUsage(docMsg.PromptTokens, docMsg.CompletionTokens, 0, item.MediaType, time.Since(startTime).Seconds())) // 判断任务状态,轮询等待