// Package handler provides HTTP handlers for various endpoints. package handler import ( "net/http" "modelRT/database" "modelRT/logger" "modelRT/network" "modelRT/orm" "github.com/gin-gonic/gin" "github.com/gofrs/uuid" ) // AsyncTaskResultQueryHandler handles querying of asynchronous task results // @Summary 查询异步任务结果 // @Description 根据任务ID列表查询异步任务的状态和结果 // @Tags AsyncTask // @Accept json // @Produce json // @Param task_ids query string true "任务ID列表,用逗号分隔" // @Success 200 {object} network.SuccessResponse{payload=network.AsyncTaskResultQueryResponse} "查询成功" // @Failure 400 {object} network.FailureResponse "请求参数错误" // @Failure 500 {object} network.FailureResponse "服务器内部错误" // @Router /task/async/results [get] func AsyncTaskResultQueryHandler(c *gin.Context) { ctx := c.Request.Context() // Parse task IDs from query parameter taskIDsParam := c.Query("task_ids") if taskIDsParam == "" { logger.Error(ctx, "task_ids parameter is required") c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: "task_ids parameter is required", }) return } // Parse comma-separated task IDs var taskIDs []uuid.UUID taskIDStrs := splitCommaSeparated(taskIDsParam) for _, taskIDStr := range taskIDStrs { taskID, err := uuid.FromString(taskIDStr) if err != nil { logger.Error(ctx, "invalid task ID format", "task_id", taskIDStr, "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: "invalid task ID format", }) return } taskIDs = append(taskIDs, taskID) } if len(taskIDs) == 0 { logger.Error(ctx, "no valid task IDs provided") c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: "no valid task IDs provided", }) return } pgClient := database.GetPostgresDBClient() if pgClient == nil { logger.Error(ctx, "database connection not found in context") c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusInternalServerError, Msg: "database connection error", }) return } // Query tasks from database asyncTasks, err := database.GetAsyncTasksByIDs(ctx, pgClient, taskIDs) if err != nil { logger.Error(ctx, "failed to query async tasks from database", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusInternalServerError, Msg: "failed to query tasks", }) return } // Query task results from database taskResults, err := database.GetAsyncTaskResults(ctx, pgClient, taskIDs) if err != nil { logger.Error(ctx, "failed to query async task results from database", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusInternalServerError, Msg: "failed to query task results", }) return } // Create a map of task results for easy lookup taskResultMap := make(map[uuid.UUID]orm.AsyncTaskResult) for _, result := range taskResults { taskResultMap[result.TaskID] = result } // Convert to response format var responseTasks []network.AsyncTaskResult for _, asyncTask := range asyncTasks { taskResult := network.AsyncTaskResult{ TaskID: asyncTask.TaskID, TaskType: string(asyncTask.TaskType), Status: string(asyncTask.Status), CreatedAt: asyncTask.CreatedAt, FinishedAt: asyncTask.FinishedAt, Progress: asyncTask.Progress, } // Add result or error information if available if result, exists := taskResultMap[asyncTask.TaskID]; exists { if result.Result != nil { taskResult.Result = map[string]any(result.Result) } if result.ErrorCode != nil { taskResult.ErrorCode = result.ErrorCode } if result.ErrorMessage != nil { taskResult.ErrorMessage = result.ErrorMessage } if result.ErrorDetail != nil { taskResult.ErrorDetail = map[string]any(result.ErrorDetail) } } responseTasks = append(responseTasks, taskResult) } // Return success response c.JSON(http.StatusOK, network.SuccessResponse{ Code: 2000, Msg: "query completed", Payload: network.AsyncTaskResultQueryResponse{ Total: len(responseTasks), Tasks: responseTasks, }, }) }