// Package handler provides HTTP handlers for various endpoints. package handler import ( "net/http" "modelRT/database" "modelRT/logger" "modelRT/network" "github.com/gin-gonic/gin" "github.com/gofrs/uuid" "gorm.io/gorm" ) // AsyncTaskResultDetailHandler handles detailed query of a single async task result // @Summary 查询异步任务详情 // @Description 根据任务ID查询异步任务的详细状态和结果 // @Tags AsyncTask // @Accept json // @Produce json // @Param task_id path string true "任务ID" // @Success 200 {object} network.SuccessResponse{payload=network.AsyncTaskResult} "查询成功" // @Failure 400 {object} network.FailureResponse "请求参数错误" // @Failure 404 {object} network.FailureResponse "任务不存在" // @Failure 500 {object} network.FailureResponse "服务器内部错误" // @Router /task/async/{task_id} [get] func AsyncTaskResultDetailHandler(c *gin.Context) { ctx := c.Request.Context() // Parse task ID from path parameter taskIDStr := c.Param("task_id") if taskIDStr == "" { logger.Error(ctx, "task_id parameter is required") c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: "task_id parameter is required", }) return } 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 } 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 task from database asyncTask, err := database.GetAsyncTaskByID(ctx, pgClient, taskID) if err != nil { if err == gorm.ErrRecordNotFound { logger.Error(ctx, "async task not found", "task_id", taskID) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusNotFound, Msg: "task not found", }) return } logger.Error(ctx, "failed to query async task from database", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusInternalServerError, Msg: "failed to query task", }) return } // Query task result from database taskResult, err := database.GetAsyncTaskResult(ctx, pgClient, taskID) if err != nil { logger.Error(ctx, "failed to query async task result from database", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusInternalServerError, Msg: "failed to query task result", }) return } // Convert to response format responseTask := 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 taskResult != nil { if taskResult.Result != nil { responseTask.Result = map[string]any(taskResult.Result) } if taskResult.ErrorCode != nil { responseTask.ErrorCode = taskResult.ErrorCode } if taskResult.ErrorMessage != nil { responseTask.ErrorMessage = taskResult.ErrorMessage } if taskResult.ErrorDetail != nil { responseTask.ErrorDetail = map[string]any(taskResult.ErrorDetail) } } // Return success response c.JSON(http.StatusOK, network.SuccessResponse{ Code: 2000, Msg: "query completed", Payload: responseTask, }) }