108 lines
3.4 KiB
Go
108 lines
3.4 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"go-admin/app/jobs/models"
|
|
)
|
|
|
|
var (
|
|
ErrExecutionLogInvalidRequest = errors.New("invalid execution log request")
|
|
ErrExecutionLogJobNotFound = errors.New("scheduled job not found")
|
|
)
|
|
|
|
type ExecutionLogListRequest struct {
|
|
Page int
|
|
PageSize int
|
|
Status string
|
|
StartedFrom *time.Time
|
|
StartedTo *time.Time
|
|
}
|
|
|
|
type ExecutionLogJob struct {
|
|
JobID int `json:"jobId"`
|
|
JobName string `json:"jobName"`
|
|
InvokeTarget string `json:"invokeTarget"`
|
|
Deleted bool `json:"deleted"`
|
|
}
|
|
|
|
type ExecutionLogListResponse struct {
|
|
Job ExecutionLogJob `json:"job"`
|
|
Items []models.SysJobExecutionLog `json:"items"`
|
|
Total int64 `json:"total"`
|
|
Page int `json:"page"`
|
|
PageSize int `json:"pageSize"`
|
|
}
|
|
|
|
type ExecutionLogService struct{ db *gorm.DB }
|
|
|
|
func NewExecutionLogService(db *gorm.DB) *ExecutionLogService {
|
|
return &ExecutionLogService{db: db}
|
|
}
|
|
|
|
func (service *ExecutionLogService) List(ctx context.Context, jobID int, request ExecutionLogListRequest) (ExecutionLogListResponse, error) {
|
|
if service.db == nil || jobID < 1 {
|
|
return ExecutionLogListResponse{}, fmt.Errorf("%w: jobId 无效", ErrExecutionLogInvalidRequest)
|
|
}
|
|
if request.Page < 1 {
|
|
request.Page = 1
|
|
}
|
|
if request.PageSize < 1 {
|
|
request.PageSize = 20
|
|
}
|
|
if request.PageSize > 100 {
|
|
return ExecutionLogListResponse{}, fmt.Errorf("%w: pageSize 必须是 1 到 100 的整数", ErrExecutionLogInvalidRequest)
|
|
}
|
|
if request.Status != "" && !validExecutionStatus(request.Status) {
|
|
return ExecutionLogListResponse{}, fmt.Errorf("%w: status 无效", ErrExecutionLogInvalidRequest)
|
|
}
|
|
if request.StartedFrom != nil && request.StartedTo != nil && request.StartedFrom.After(*request.StartedTo) {
|
|
return ExecutionLogListResponse{}, fmt.Errorf("%w: 开始时间范围无效", ErrExecutionLogInvalidRequest)
|
|
}
|
|
|
|
var job models.SysJob
|
|
if err := service.db.WithContext(ctx).Unscoped().First(&job, jobID).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return ExecutionLogListResponse{}, ErrExecutionLogJobNotFound
|
|
}
|
|
return ExecutionLogListResponse{}, err
|
|
}
|
|
|
|
query := service.db.WithContext(ctx).Model(&models.SysJobExecutionLog{}).Where("job_id = ?", jobID)
|
|
if request.Status != "" {
|
|
query = query.Where("status = ?", request.Status)
|
|
}
|
|
if request.StartedFrom != nil {
|
|
query = query.Where("started_at >= ?", request.StartedFrom.UTC())
|
|
}
|
|
if request.StartedTo != nil {
|
|
query = query.Where("started_at <= ?", request.StartedTo.UTC())
|
|
}
|
|
var total int64
|
|
if err := query.Count(&total).Error; err != nil {
|
|
return ExecutionLogListResponse{}, err
|
|
}
|
|
items := make([]models.SysJobExecutionLog, 0, request.PageSize)
|
|
if err := query.Order("started_at DESC, id DESC").Offset((request.Page - 1) * request.PageSize).Limit(request.PageSize).Find(&items).Error; err != nil {
|
|
return ExecutionLogListResponse{}, err
|
|
}
|
|
return ExecutionLogListResponse{
|
|
Job: ExecutionLogJob{JobID: job.JobId, JobName: job.JobName, InvokeTarget: job.InvokeTarget, Deleted: job.DeletedAt.Valid},
|
|
Items: items, Total: total, Page: request.Page, PageSize: request.PageSize,
|
|
}, nil
|
|
}
|
|
|
|
func validExecutionStatus(status string) bool {
|
|
switch status {
|
|
case models.JobExecutionRunning, models.JobExecutionSucceeded, models.JobExecutionFailed, models.JobExecutionInterrupted:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|