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())) // 判断任务状态,轮询等待