mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-03-30 02:25:00 +00:00
refactor(task): extract billing and polling logic from controller to service layer
Restructure the task relay system for better separation of concerns: - Extract task billing into service/task_billing.go with unified settlement flow - Move task polling loop from controller to service/task_polling.go (supports Suno + video platforms) - Split RelayTask into fetch/submit paths with dedicated retry logic (taskSubmitWithRetry) - Add TaskDto, TaskResponse generics, and FetchReq to dto/task.go - Add taskcommon/helpers.go for shared task adaptor utilities - Remove controller/task_video.go (logic consolidated into service layer) - Update all task adaptors (ali, doubao, gemini, hailuo, jimeng, kling, sora, suno, vertex, vidu) - Simplify frontend task logs to use new TaskDto response format
This commit is contained in:
@@ -118,8 +118,12 @@ type RelayInfo struct {
|
||||
SendResponseCount int
|
||||
ReceivedResponseCount int
|
||||
FinalPreConsumedQuota int // 最终预消耗的配额
|
||||
// ForcePreConsume 为 true 时禁用 BillingSession 的信任额度旁路,
|
||||
// 强制预扣全额。用于异步任务(视频/音乐生成等),因为请求返回后任务仍在运行,
|
||||
// 必须在提交前锁定全额。
|
||||
ForcePreConsume bool
|
||||
// Billing 是计费会话,封装了预扣费/结算/退款的统一生命周期。
|
||||
// 免费模型和按次计费(MJ/Task)时为 nil。
|
||||
// 免费模型时为 nil。
|
||||
Billing BillingSettler
|
||||
// BillingSource indicates whether this request is billed from wallet quota or subscription.
|
||||
// "" or "wallet" => wallet; "subscription" => subscription
|
||||
@@ -525,8 +529,10 @@ func GenRelayInfo(c *gin.Context, relayFormat types.RelayFormat, request dto.Req
|
||||
return nil, errors.New("request is not a OpenAIResponsesCompactionRequest")
|
||||
case types.RelayFormatTask:
|
||||
info = genBaseRelayInfo(c, nil)
|
||||
info.TaskRelayInfo = &TaskRelayInfo{}
|
||||
case types.RelayFormatMjProxy:
|
||||
info = genBaseRelayInfo(c, nil)
|
||||
info.TaskRelayInfo = &TaskRelayInfo{}
|
||||
default:
|
||||
err = errors.New("invalid relay format")
|
||||
}
|
||||
@@ -608,6 +614,9 @@ func (info *RelayInfo) HasSendResponse() bool {
|
||||
type TaskRelayInfo struct {
|
||||
Action string
|
||||
OriginTaskID string
|
||||
// PublicTaskID 是提交时预生成的 task_xxxx 格式公开 ID,
|
||||
// 供 DoResponse 在返回给客户端时使用(避免暴露上游真实 ID)。
|
||||
PublicTaskID string
|
||||
|
||||
ConsumeQuota bool
|
||||
}
|
||||
@@ -667,11 +676,11 @@ func (t *TaskSubmitReq) UnmarshalJSON(data []byte) error {
|
||||
func (t *TaskSubmitReq) UnmarshalMetadata(v any) error {
|
||||
metadata := t.Metadata
|
||||
if metadata != nil {
|
||||
metadataBytes, err := json.Marshal(metadata)
|
||||
metadataBytes, err := common.Marshal(metadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal metadata failed: %w", err)
|
||||
}
|
||||
err = json.Unmarshal(metadataBytes, v)
|
||||
err = common.Unmarshal(metadataBytes, v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unmarshal metadata to target failed: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user