ResolveOriginTask 处理基于已有任务的提交(remix / continuation): 查找原始任务、从中提取模型名称、将渠道锁定到原始任务的渠道 (通过 info.LockedChannel,重试时复用同一渠道并轮换 key), 以及提取 OtherRatios(时长、分辨率)。 该函数在控制器的重试循环之前调用一次,其结果通过 info 字段和上下文持久化。
(c *gin.Context, info *relaycommon.RelayInfo)
| 36 | // 以及提取 OtherRatios(时长、分辨率)。 |
| 37 | // 该函数在控制器的重试循环之前调用一次,其结果通过 info 字段和上下文持久化。 |
| 38 | func ResolveOriginTask(c *gin.Context, info *relaycommon.RelayInfo) *dto.TaskError { |
| 39 | // 检测 remix action |
| 40 | path := c.Request.URL.Path |
| 41 | if strings.Contains(path, "/v1/videos/") && strings.HasSuffix(path, "/remix") { |
| 42 | info.Action = constant.TaskActionRemix |
| 43 | } |
| 44 | |
| 45 | // 提取 remix 任务的 video_id |
| 46 | if info.Action == constant.TaskActionRemix { |
| 47 | videoID := c.Param("video_id") |
| 48 | if strings.TrimSpace(videoID) == "" { |
| 49 | return service.TaskErrorWrapperLocal(fmt.Errorf("video_id is required"), "invalid_request", http.StatusBadRequest) |
| 50 | } |
| 51 | info.OriginTaskID = videoID |
| 52 | } |
| 53 | |
| 54 | if info.OriginTaskID == "" { |
| 55 | return nil |
| 56 | } |
| 57 | |
| 58 | // 查找原始任务 |
| 59 | originTask, exist, err := model.GetByTaskId(info.UserId, info.OriginTaskID) |
| 60 | if err != nil { |
| 61 | return service.TaskErrorWrapper(err, "get_origin_task_failed", http.StatusInternalServerError) |
| 62 | } |
| 63 | if !exist { |
| 64 | return service.TaskErrorWrapperLocal(errors.New("task_origin_not_exist"), "task_not_exist", http.StatusBadRequest) |
| 65 | } |
| 66 | |
| 67 | // 从原始任务推导模型名称 |
| 68 | if info.OriginModelName == "" { |
| 69 | if originTask.Properties.OriginModelName != "" { |
| 70 | info.OriginModelName = originTask.Properties.OriginModelName |
| 71 | } else if originTask.Properties.UpstreamModelName != "" { |
| 72 | info.OriginModelName = originTask.Properties.UpstreamModelName |
| 73 | } else { |
| 74 | var taskData map[string]interface{} |
| 75 | _ = common.Unmarshal(originTask.Data, &taskData) |
| 76 | if m, ok := taskData["model"].(string); ok && m != "" { |
| 77 | info.OriginModelName = m |
| 78 | } |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | // 锁定到原始任务的渠道(重试时复用同一渠道,轮换 key) |
| 83 | ch, err := model.GetChannelById(originTask.ChannelId, true) |
| 84 | if err != nil { |
| 85 | return service.TaskErrorWrapperLocal(err, "channel_not_found", http.StatusBadRequest) |
| 86 | } |
| 87 | if ch.Status != common.ChannelStatusEnabled { |
| 88 | return service.TaskErrorWrapperLocal(errors.New("the channel of the origin task is disabled"), "task_channel_disable", http.StatusBadRequest) |
| 89 | } |
| 90 | info.LockedChannel = ch |
| 91 | |
| 92 | if originTask.ChannelId != info.ChannelId { |
| 93 | key, _, newAPIError := ch.GetNextEnabledKey() |
| 94 | if newAPIError != nil { |
| 95 | return service.TaskErrorWrapper(newAPIError, "channel_no_available_key", newAPIError.StatusCode) |
no test coverage detected