package apis import ( "errors" "net/http" "strconv" "strings" "time" "github.com/gin-gonic/gin" jobservice "go-admin/app/jobs/service" ) func (e SysJob) ListExecutionLogs(c *gin.Context) { jobID, err := strconv.Atoi(c.Param("id")) if err != nil || jobID < 1 { c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 400, "msg": "jobId 无效"}) return } page, err := positiveQueryInt(c.Query("pageIndex"), 1) if err != nil { c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 400, "msg": "pageIndex 必须是正整数"}) return } pageSize, err := positiveQueryInt(c.Query("pageSize"), 20) if err != nil || pageSize > 100 { c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 400, "msg": "pageSize 必须是 1 到 100 的整数"}) return } startedFrom, err := optionalTime(c.Query("startedFrom")) if err != nil { c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 400, "msg": "startedFrom 必须是 RFC3339 时间"}) return } startedTo, err := optionalTime(c.Query("startedTo")) if err != nil { c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 400, "msg": "startedTo 必须是 RFC3339 时间"}) return } e.MakeContext(c) db, err := e.GetOrm() if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": "服务端处理失败"}) return } response, err := jobservice.NewExecutionLogService(db).List(c.Request.Context(), jobID, jobservice.ExecutionLogListRequest{ Page: page, PageSize: pageSize, Status: strings.TrimSpace(c.Query("status")), StartedFrom: startedFrom, StartedTo: startedTo, }) if err != nil { switch { case errors.Is(err, jobservice.ErrExecutionLogInvalidRequest): c.JSON(http.StatusUnprocessableEntity, gin.H{"code": 400, "msg": err.Error()}) case errors.Is(err, jobservice.ErrExecutionLogJobNotFound): c.JSON(http.StatusNotFound, gin.H{"code": 404, "msg": "定时任务不存在"}) default: e.GetLogger().Errorf("list scheduled job execution logs failed job_id=%d: %v", jobID, err) c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "msg": "服务端处理失败"}) } return } c.JSON(http.StatusOK, gin.H{"code": 200, "data": response}) } func positiveQueryInt(value string, fallback int) (int, error) { if strings.TrimSpace(value) == "" { return fallback, nil } parsed, err := strconv.Atoi(value) if err != nil || parsed < 1 { return 0, errors.New("invalid positive integer") } return parsed, nil } func optionalTime(value string) (*time.Time, error) { if strings.TrimSpace(value) == "" { return nil, nil } parsed, err := time.Parse(time.RFC3339, value) if err != nil { return nil, err } return &parsed, nil }