golang实现【任务调度管理系统】开发流程详解

75 阅读18分钟

golang实现【任务调度管理系统】开发流程详解

一、系统概述

本任务调度管理系统是基于Go语言开发的一个完整的任务调度平台,采用前后端分离架构,后端使用Go语言的Iris框架,前端使用Vue3+HTML5实现。系统主要功能包括:

  • 任务的创建、编辑、删除、启动/终止、暂停/继续等基本操作
  • 支持一次性任务和周期性任务两种类型
  • 周期性任务支持Cron表达式配置执行时间
  • 任务执行状态实时监控(等待执行、正在执行、已完成、已超期)
  • 任务执行结果记录与展示
  • 超期任务自动处理
  • 任务执行统计分析
  • 任务执行日志查询
  • 高频执行任务识别与监控

系统架构清晰,代码组织合理,具有良好的可扩展性和可维护性,可应用于各种需要自动化任务调度的场景。

二、运行效果图片展示

1. 任务列表页面

image.png

image.png

2. 新增任务页面

image.png image.png

3. 修改任务页面

image.png

4. 任务日志页面

image.png

5. Cron表达式设置

image.png

6. 任务统计页面

image.png

三、项目结构

本项目采用典型的Go语言项目结构,遵循MVC架构模式,代码组织清晰合理。主要目录结构如下:

TaskSchedulingService/
├── controller/         # 控制器层,处理HTTP请求
│   └── task_controller.go
├── core/               # 核心功能模块
│   └── cron.go
├── external_call_result/  # 外部调用结果存储
├── global/             # 全局变量和配置
│   └── global.go
├── initialize/         # 初始化模块
│   ├── initDatabase.go
│   └── timer.go
├── middleware/         # 中间件
│   └── cors.go
├── model/              # 数据模型
│   └── task_model.go
├── router/             # 路由配置
│   └── router.go
├── scripts/            # 脚本工具
│   ├── add_cron_expressions.go
│   └── verify_cron_expressions.go
├── service/            # 业务逻辑层
│   └── task_service.go
├── static/             # 静态资源
│   └── js/
│       ├── axios.min.js
│       ├── echarts.min.js
│       └── vue.global.js
├── template/           # 前端模板
│   └── index.html
├── timer/              # 任务定时器
│   ├── dynamic_task.go
│   ├── scenario_tasks.go
│   └── simple_task.go
├── utils/              # 工具函数
│   └── port_utils.go
├── config.json         # 配置文件
├── go.mod              # Go模块定义
├── go.sum              # Go依赖校验
└── main.go             # 项目入口

核心目录说明:

  • controller/: 控制器层,处理HTTP请求,实现RESTful API接口
  • model/: 数据模型层,定义任务和执行日志的数据结构
  • service/: 业务逻辑层,实现任务执行和管理的核心逻辑
  • timer/: 任务定时器,负责任务的调度和执行
  • initialize/: 初始化模块,负责数据库连接和任务加载
  • template/: 前端模板,实现用户界面
  • static/: 静态资源,包括Vue.js、Axios等前端库

四、项目开发流程图

1. 后端服务流程图

sequenceDiagram
    participant Client as 前端
    participant API as API层
    participant Controller as 控制器层
    participant Service as 服务层
    participant Timer as 定时器
    participant DB as 数据库

    Client->>API: HTTP请求
    API->>Controller: 路由分发
    Controller->>DB: 数据操作
    Controller->>Service: 业务逻辑处理
    Controller->>Timer: 任务管理
    Timer->>Service: 任务执行
    Service->>DB: 执行结果存储
    Controller-->>Client: 响应结果

2. 前端与后端交互操作功能流程图

sequenceDiagram
    participant User as 用户
    participant Frontend as 前端
    participant Backend as 后端API
    participant DB as 数据库

    User->>Frontend: 访问系统
    Frontend->>Backend: GET /api/tasks
    Backend->>DB: 查询任务列表
    DB-->>Backend: 返回任务数据
    Backend-->>Frontend: 返回任务列表
    Frontend-->>User: 显示任务列表

    User->>Frontend: 点击新增任务
    Frontend->>User: 显示新增任务表单
    User->>Frontend: 填写任务信息
    Frontend->>Backend: POST /api/tasks
    Backend->>DB: 保存任务
    Backend->>Backend: 注册任务到定时器
    DB-->>Backend: 保存成功
    Backend-->>Frontend: 返回任务信息
    Frontend-->>User: 显示成功提示

    User->>Frontend: 点击查看日志
    Frontend->>Backend: GET /api/tasks/logs?task_id=1
    Backend->>DB: 查询任务日志
    DB-->>Backend: 返回日志数据
    Backend-->>Frontend: 返回日志列表
    Frontend-->>User: 显示任务日志

    User->>Frontend: 点击启动/终止任务
    Frontend->>Backend: POST /api/tasks/{id}/start
    Backend->>DB: 更新任务状态
    Backend->>Backend: 注册/移除任务
    DB-->>Backend: 更新成功
    Backend-->>Frontend: 返回任务信息
    Frontend-->>User: 显示成功提示

五、后端服务结构体、核心包及包内所有函数介绍及核心源代码

1. 核心包介绍

1.1 controller

功能:控制器层,处理HTTP请求,实现RESTful API接口

核心结构体

  • TaskController:任务控制器,处理任务相关的HTTP请求

核心函数

  • NewTaskController():创建任务控制器实例
  • TaskController.BeforeActivation():在激活前配置路由
  • TaskController.ListTasks():列出所有任务
  • TaskController.GetTask():获取任务详情
  • TaskController.CreateTask():创建新任务
  • TaskController.UpdateTask():更新任务信息
  • TaskController.DeleteTask():删除任务
  • TaskController.ListTaskFuncs():列出所有可用的任务函数
  • TaskController.ListTaskLogs():列出任务执行日志
  • TaskController.ListAllTaskLogs():列出所有任务执行日志
  • TaskController.GetTaskStatistics():获取任务统计信息
  • TaskController.StopTask():终止任务
  • TaskController.StartTask():启动任务
  • TaskController.PauseTask():暂停任务
  • TaskController.ResumeTask():继续任务
  • TaskController.ListCronExpressions():列出Cron表达式
  • TaskController.CreateCronExpression():创建Cron表达式
  • TaskController.UpdateCronExpression():更新Cron表达式
  • TaskController.DeleteCronExpression():删除Cron表达式
  • executeTask():执行任务并记录日志
1.2 model

功能:数据模型层,定义任务和执行日志的数据结构

核心结构体

  • Task:任务模型,包含任务的基本信息和状态
  • TaskExecutionLog:任务执行日志模型,记录任务执行的详细信息
  • CronExpression:定时表达式模型,存储常用的Cron表达式

核心函数

  • Task.TableName():设置任务表名
  • TaskExecutionLog.TableName():设置任务执行日志表名
  • CronExpression.TableName():设置Cron表达式表名
  • CreateTable():创建数据库表
1.3 service

功能:业务逻辑层,实现任务执行和管理的核心逻辑

核心结构体

  • TaskFuncInfo:任务函数信息结构体,包含任务函数的名称和描述
  • ExternalAPICallParams:外部API调用参数结构体,包含API调用的相关参数

核心函数

  • InitTaskFuncMap():初始化任务函数注册中心
  • DataBackup():数据备份任务
  • SystemCheck():系统检查任务
  • UserReport():用户报告任务
  • CleanCache():清理缓存任务
  • SyncData():数据同步任务
  • AddCustomTask():添加自定义任务函数
  • RemoveCustomTask():移除自定义任务函数
  • GetTaskFunc():获取任务函数
  • ListTaskFuncs():列出所有可用的任务函数
  • ExecuteExternalAPI():执行外部API调用的万能函数
  • saveResult():保存API调用结果到文件
1.4 initialize

功能:初始化模块,负责数据库连接和任务加载

核心函数

  • InitDatabase():初始化数据库连接
  • Timer():初始化定时任务
  • loadTasksFromDatabase():从数据库加载任务并注册到定时器
1.5 core

功能:核心功能模块,包含Cron定时器的初始化

核心函数

  • InitCron():初始化Cron实例

2. 核心源代码

2.1 项目入口 (main.go)
func main() {
	// 初始化全局日志
	logger, _ := zap.NewProduction()
	defer logger.Sync()
	global.GVA_LOG = logger

	// 初始化数据库
	initialize.InitDatabase()

	// 初始化全局 cron 实例
	global.GVA_CRON = core.InitCron()

	// 初始化定时任务注册
	initialize.Timer()

	// 初始化任务函数注册中心
	service.InitTaskFuncMap()

	// 设置路由
	app := router.SetupRouter()

	// 启动Web服务
	global.GVA_LOG.Info("Web服务启动成功,访问地址:http://localhost:8082")
	port := os.Getenv("PORT")
	if port == "" {
		port = "8082" // 更改端口为8082
	}

	// 检查端口是否可用
	portNum, err := strconv.Atoi(port)
	if err != nil {
		global.GVA_LOG.Fatal("Web服务启动失败", zap.Error(err))
	}

	if utils.IsPortInUse(portNum) {
		global.GVA_LOG.Info("端口 %s 被占用,尝试终止占用进程...", zap.String("port", port))
		err := utils.FindAndKillProcess(portNum)
		if err != nil {
			global.GVA_LOG.Fatal("终止进程失败", zap.Error(err))
		}
	}

	app.Listen(fmt.Sprintf(":%s", port))
}
2.2 任务控制器 (controller/task_controller.go)
// TaskController 任务控制器
type TaskController struct{}

// NewTaskController 创建任务控制器实例
func NewTaskController() *TaskController {
	return &TaskController{}
}

// BeforeActivation 在激活前配置路由
func (c *TaskController) BeforeActivation(b mvc.BeforeActivation) {
	// 配置路由
	b.Handle("GET", "/", "ListTasks")
	b.Handle("GET", "/{id:string}", "GetTask")
	b.Handle("POST", "/", "CreateTask")
	b.Handle("PUT", "/{id:string}", "UpdateTask")
	b.Handle("DELETE", "/{id:string}", "DeleteTask")
	b.Handle("GET", "/funcs", "ListTaskFuncs")
	b.Handle("GET", "/logs", "ListTaskLogs")
	b.Handle("GET", "/logs/all", "ListAllTaskLogs")
	b.Handle("GET", "/statistics", "GetTaskStatistics")
	// 终止/启动和暂停/继续路由
	b.Handle("POST", "/{id:string}/stop", "StopTask")
	b.Handle("POST", "/{id:string}/start", "StartTask")
	b.Handle("POST", "/{id:string}/pause", "PauseTask")
	b.Handle("POST", "/{id:string}/resume", "ResumeTask")
	// cron表达式路由
	b.Handle("GET", "/cron", "ListCronExpressions")
	b.Handle("POST", "/cron", "CreateCronExpression")
	b.Handle("PUT", "/cron/{id:string}", "UpdateCronExpression")
	b.Handle("DELETE", "/cron/{id:string}", "DeleteCronExpression")
}

// ListTasks 列出所有任务
func (c *TaskController) ListTasks(ctx iris.Context) mvc.Result {
	var tasks []*model.Task
	err := global.GVA_DB.Find(&tasks)
	if err != nil {
		global.GVA_LOG.Error("查询任务列表失败", zap.Error(err))
		return mvc.Response{
			Code: iris.StatusInternalServerError,
			Object: iris.Map{
				"code":    iris.StatusInternalServerError,
				"message": "查询任务列表失败",
				"error":   err.Error(),
			},
		}
	}

	// 处理一次性任务超期问题
	now := time.Now()
	for _, task := range tasks {
		if task.Type == "single" && task.ExecuteAt.Before(now) {
			// 将超期的一次性任务更新为已完成状态,并设置为禁用和暂停
			task.Status = "completed"
			task.EnabledStatus = false
			task.PausedStatus = true
			task.UpdateTime = now
			_, err := global.GVA_DB.Where("id = ?", task.ID).Update(task)
			if err != nil {
				global.GVA_LOG.Error("更新超期任务状态失败", zap.Error(err), zap.Int64("task_id", task.ID))
			} else {
				global.GVA_LOG.Info("更新超期任务状态成功", zap.Int64("task_id", task.ID))
			}
		}
	}

	return mvc.Response{
		Code: iris.StatusOK,
		Object: iris.Map{
			"code":    iris.StatusOK,
			"message": "success",
			"data":    tasks,
		},
	}
}

// CreateTask 创建任务
func (c *TaskController) CreateTask(ctx iris.Context) mvc.Result {
	var req struct {
		// ID 由数据库自动生成(bigint 自增),不需要用户输入
		ID           int64     `json:"id"`
		Name         string    `json:"name" binding:"required"`
		Description  string    `json:"description"`
		Type         string    `json:"type" binding:"required,oneof=single recurring"`
		CronExpr     string    `json:"cron_expr"`
		ExecuteAt    time.Time `json:"execute_at"`
		Timeout      int       `json:"timeout" binding:"min=1"`
		TaskFuncName string    `json:"task_func_name" binding:"required"`
		Params       string    `json:"params"`
	}

	if err := ctx.ReadJSON(&req); err != nil {
		return mvc.Response{
			Code: iris.StatusBadRequest,
			Object: iris.Map{
				"code":    iris.StatusBadRequest,
				"message": "参数错误",
				"error":   err.Error(),
			},
		}
	}

	// 检查任务函数是否存在
	_, err := service.GetTaskFunc(req.TaskFuncName)
	if err != nil {
		return mvc.Response{
			Code: iris.StatusBadRequest,
			Object: iris.Map{
				"code":    iris.StatusBadRequest,
				"message": err.Error(),
			},
		}
	}

	// 创建任务
	task := &model.Task{
		Name:          req.Name,
		Description:   req.Description,
		Type:          req.Type,
		CronExpr:      req.CronExpr,
		ExecuteAt:     req.ExecuteAt,
		Timeout:       req.Timeout,
		Status:        "pending",
		TaskFuncName:  req.TaskFuncName,
		Params:        req.Params,
		CreateTime:    time.Now(),
		UpdateTime:    time.Now(),
		ExecuteCount:  0,
		LastExecuteAt: time.Time{},
		NextExecuteAt: req.ExecuteAt,
	}

	// 保存到数据库
	_, err = global.GVA_DB.Insert(task)
	if err != nil {
		global.GVA_LOG.Error("创建任务失败", zap.Error(err), zap.Any("task", task))
		return mvc.Response{
			Code: iris.StatusInternalServerError,
			Object: iris.Map{
				"code":    iris.StatusInternalServerError,
				"message": "创建任务失败",
				"error":   err.Error(),
			},
		}
	}

	// 添加到任务管理器
	taskFunc, _ := service.GetTaskFunc(req.TaskFuncName)
	if req.Type == "single" {
		err = global.GVA_TASK_MANAGER.AddTask(
			fmt.Sprintf("%d", task.ID),
			task.ExecuteAt,
			time.Duration(task.Timeout)*time.Second,
			func() {
				executeTask(task.ID, taskFunc, task)
			},
		)
	} else {
		err = global.GVA_TASK_MANAGER.AddRecurringTask(
			fmt.Sprintf("%d", task.ID),
			task.CronExpr,
			time.Duration(task.Timeout)*time.Second,
			func() {
				executeTask(task.ID, taskFunc, task)
			},
		)
	}

	if err != nil {
		global.GVA_LOG.Error("添加任务到任务管理器失败", zap.Error(err), zap.Int64("id", task.ID))
		return mvc.Response{
			Code: iris.StatusInternalServerError,
			Object: iris.Map{
				"code":    iris.StatusInternalServerError,
				"message": "添加任务到任务管理器失败",
				"error":   err.Error(),
			},
		}
	}

	return mvc.Response{
		Code: iris.StatusOK,
		Object: iris.Map{
			"code":    iris.StatusOK,
			"message": "任务创建成功",
			"data":    task,
		},
	}
}

// executeTask 执行任务并记录日志
func executeTask(taskID int64, taskFunc func(string), task *model.Task) {
	// 检查任务是否被暂停或禁用
	var currentTask model.Task
	has, err := global.GVA_DB.SQL("SELECT enabled_status, paused_status FROM tasks WHERE id = ?", taskID).Get(&currentTask)
	if err != nil {
		global.GVA_LOG.Error("查询任务状态失败", zap.Error(err), zap.Int64("task_id", taskID))
		return
	}

	if !has || !currentTask.EnabledStatus || currentTask.PausedStatus {
		global.GVA_LOG.Info("任务被暂停或禁用,跳过执行", zap.Int64("task_id", taskID))
		return
	}

	// 更新任务状态为运行中
	task.Status = "running"
	task.UpdateTime = time.Now()
	task.LastExecuteAt = time.Now()
	_, err = global.GVA_DB.Exec("UPDATE tasks SET status = ?, update_time = ?, last_execute_at = ? WHERE id = ?", task.Status, task.UpdateTime, task.LastExecuteAt, taskID)
	if err != nil {
		global.GVA_LOG.Error("更新任务状态为运行中失败", zap.Error(err), zap.Int64("task_id", taskID))
	}

	// 创建执行日志
	log := &model.TaskExecutionLog{
		TaskID:    taskID,
		StartTime: time.Now(),
		Status:    "running",
		Message:   "",
	}
	global.GVA_DB.Insert(log)

	// 执行任务
	startTime := time.Now()
	defer func() {
		if r := recover(); r != nil {
			// 任务执行失败
			endTime := time.Now()
			log.EndTime = endTime
			log.Status = "failed"
			log.Message = fmt.Sprintf("任务执行失败: %v", r)
			log.ExecutionTime = endTime.Sub(startTime).Milliseconds()
			_, err = global.GVA_DB.Exec("UPDATE task_execution_logs SET end_time = ?, status = ?, message = ?, execution_time = ? WHERE id = ?", log.EndTime, log.Status, log.Message, log.ExecutionTime, log.ID)
			if err != nil {
				global.GVA_LOG.Error("更新任务执行失败日志失败", zap.Error(err), zap.Int64("log_id", log.ID))
			}

			// 更新任务状态
			task.Status = "completed"
			task.ExecuteCount++
			task.UpdateTime = endTime
			_, err = global.GVA_DB.Exec("UPDATE tasks SET status = ?, execute_count = execute_count + 1, update_time = ? WHERE id = ?", task.Status, task.UpdateTime, taskID)
			if err != nil {
				global.GVA_LOG.Error("更新任务状态为完成失败", zap.Error(err), zap.Int64("task_id", taskID))
			}
		}
	}()

	// 执行任务函数
	taskFunc(fmt.Sprintf("%d", taskID))

	// 任务执行成功
	endTime := time.Now()
	log.EndTime = endTime
	log.Status = "success"
	log.Message = "任务执行成功"
	log.ExecutionTime = endTime.Sub(startTime).Milliseconds()
	_, err = global.GVA_DB.Exec("UPDATE task_execution_logs SET end_time = ?, status = ?, message = ?, execution_time = ? WHERE id = ?", log.EndTime, log.Status, log.Message, log.ExecutionTime, log.ID)
	if err != nil {
		global.GVA_LOG.Error("更新任务执行成功日志失败", zap.Error(err), zap.Int64("log_id", log.ID))
	}

	// 更新任务状态
	task.Status = "completed"
	task.ExecuteCount++
	task.UpdateTime = endTime

	// 如果是一次性任务,不需要更新下次执行时间
	if task.Type == "recurring" {
		// 这里可以根据cron表达式计算下次执行时间
		// 为了简化,这里暂时不实现
	}

	// 更新任务状态和执行次数
	result, err := global.GVA_DB.Exec("UPDATE tasks SET status = ?, execute_count = execute_count + 1, update_time = ? WHERE id = ?", task.Status, task.UpdateTime, taskID)
	if err != nil {
		global.GVA_LOG.Error("更新任务状态为完成失败", zap.Error(err), zap.Int64("task_id", taskID))
	} else {
		// 记录更新结果
		rowsAffected, _ := result.RowsAffected()
		global.GVA_LOG.Info("更新任务状态成功", zap.Int64("task_id", taskID), zap.Int64("rows_affected", rowsAffected))
	}
}
2.3 数据模型 (model/task_model.go)
// Task 任务模型
type Task struct {
	ID            int64     `xorm:"bigint pk autoincr 'id'" json:"id"`
	Name          string    `xorm:"varchar(100) notnull 'name'" json:"name"`
	Description   string    `xorm:"text 'description'" json:"description"`
	Type          string    `xorm:"varchar(20) notnull 'type'" json:"type"` // single, recurring
	CronExpr      string    `xorm:"varchar(50) 'cron_expr'" json:"cron_expr"`
	ExecuteAt     time.Time `xorm:"datetime 'execute_at'" json:"execute_at"`
	Timeout       int       `xorm:"int notnull default(30) 'timeout'" json:"timeout"`
	Status        string    `xorm:"varchar(20) notnull default('pending') 'status'" json:"status"`
	EnabledStatus bool      `xorm:"bool notnull default(true) 'enabled_status'" json:"enabled_status"` // 是否启用(终止/启动)
	PausedStatus  bool      `xorm:"bool notnull default(false) 'paused_status'" json:"paused_status"`  // 是否暂停
	TaskFuncName  string    `xorm:"varchar(100) notnull 'task_func_name'" json:"task_func_name"`
	Params        string    `xorm:"text 'params'" json:"params"`
	CreateTime    time.Time `xorm:"datetime notnull 'create_time'" json:"create_time"`
	UpdateTime    time.Time `xorm:"datetime notnull 'update_time'" json:"update_time"`
	ExecuteCount  int       `xorm:"int notnull default(0) 'execute_count'" json:"execute_count"`
	LastExecuteAt time.Time `xorm:"datetime 'last_execute_at'" json:"last_execute_at"`
	NextExecuteAt time.Time `xorm:"datetime 'next_execute_at'" json:"next_execute_at"`
}

// TaskExecutionLog 任务执行日志模型
type TaskExecutionLog struct {
	ID            int64     `xorm:"bigint pk autoincr 'id'" json:"id"`
	TaskID        int64     `xorm:"bigint notnull 'task_id'" json:"task_id"`
	StartTime     time.Time `xorm:"datetime notnull" json:"start_time"`
	EndTime       time.Time `xorm:"datetime" json:"end_time"`
	Status        string    `xorm:"varchar(20) notnull" json:"status"` // success, failed, timeout
	Message       string    `xorm:"text" json:"message"`
	ExecutionTime int64     `xorm:"bigint" json:"execution_time"` // 执行时间(毫秒)
}

// CronExpression 定时表达式模型
type CronExpression struct {
	ID         int64     `xorm:"bigint pk autoincr 'id'" json:"id"`
	Label      string    `xorm:"varchar(100) notnull 'label'" json:"label"`
	Value      string    `xorm:"varchar(50) notnull 'value'" json:"value"`
	CreateTime time.Time `xorm:"datetime notnull 'create_time'" json:"create_time"`
	UpdateTime time.Time `xorm:"datetime notnull 'update_time'" json:"update_time"`
}

// TableName 设置表名
func (Task) TableName() string {
	return "tasks"
}

// TableName 设置表名
func (TaskExecutionLog) TableName() string {
	return "task_execution_logs"
}

// TableName 设置表名
func (CronExpression) TableName() string {
	return "cron_expressions"
}

// CreateTable 创建表
func CreateTable(engine *xorm.Engine) error {
	// 创建或更新任务执行日志表
	err := engine.Sync2(&TaskExecutionLog{})
	if err != nil {
		return err
	}

	// 创建或更新任务表
	err = engine.Sync2(&Task{})
	if err != nil {
		return err
	}

	// 创建或更新定时表达式表
	err = engine.Sync2(&CronExpression{})
	if err != nil {
		return err
	}

	return nil
}
2.4 任务服务 (service/task_service.go)
// TaskFuncInfo 任务函数信息结构体
type TaskFuncInfo struct {
	Name        string `json:"name"`        // 函数名
	Description string `json:"description"` // 中文功能名称
}

// InitTaskFuncMap 初始化任务函数注册中心
func InitTaskFuncMap() {
	// 注册内置任务函数
	TaskFuncMap["DataBackup"] = DataBackup
	TaskFuncMap["SystemCheck"] = SystemCheck
	TaskFuncMap["UserReport"] = UserReport
	TaskFuncMap["CleanCache"] = CleanCache
	TaskFuncMap["SyncData"] = SyncData
	TaskFuncMap["ExecuteExternalAPI"] = ExecuteExternalAPI

	// 注册场景任务函数
	TaskFuncMap["SyncDataFromExternalSystem"] = timer.SyncDataFromExternalSystem
	TaskFuncMap["BackupDatabase"] = timer.BackupDatabase
	TaskFuncMap["CleanInvalidData"] = timer.CleanInvalidData
	TaskFuncMap["AnalyzeBusinessData"] = timer.AnalyzeBusinessData
	TaskFuncMap["GenerateDailyReport"] = timer.GenerateDailyReport
	TaskFuncMap["SendEmailNotification"] = timer.SendEmailNotification
	TaskFuncMap["CheckSystemStatus"] = timer.CheckSystemStatus
	TaskFuncMap["TriggerBusinessProcess"] = timer.TriggerBusinessProcess
	TaskFuncMap["RotateSystemLogs"] = timer.RotateSystemLogs
	TaskFuncMap["RefreshSystemCache"] = timer.RefreshSystemCache
	TaskFuncMap["CleanupSystemResources"] = timer.CleanupSystemResources
	TaskFuncMap["CollectSystemMetrics"] = timer.CollectSystemMetrics
	TaskFuncMap["ExecuteDelayedBusinessTask"] = timer.ExecuteDelayedBusinessTask
	TaskFuncMap["ExecuteTemporaryTask"] = timer.ExecuteTemporaryTask
	TaskFuncMap["ExecuteEventBasedTask"] = timer.ExecuteEventBasedTask
}

// GetTaskFunc 获取任务函数
func GetTaskFunc(name string) (func(string), error) {
	task, exists := TaskFuncMap[name]
	if !exists {
		return nil, fmt.Errorf("任务函数不存在: %s", name)
	}
	return task, nil
}

// ListTaskFuncs 列出所有可用的任务函数
func ListTaskFuncs() []TaskFuncInfo {
	var funcs []TaskFuncInfo
	for name := range TaskFuncMap {
		description := TaskFuncDescriptions[name]
		if description == "" {
			description = name // 如果没有找到中文描述,使用函数名
		}
		funcs = append(funcs, TaskFuncInfo{
			Name:        name,
			Description: description,
		})
	}
	return funcs
}

// ExecuteExternalAPI 执行外部API调用的万能函数
func ExecuteExternalAPI(taskID string) {
	global.GVA_LOG.Info("执行外部API调用任务", zap.String("taskID", taskID))
	fmt.Println("正在执行外部API调用...")

	// 从数据库读取任务信息
	var task model.Task
	// 将字符串类型的taskID转换为int64类型
	taskIDInt, err := strconv.ParseInt(taskID, 10, 64)
	if err != nil {
		global.GVA_LOG.Error("解析任务ID失败", zap.Error(err), zap.String("taskID", taskID))
		fmt.Printf("解析任务ID失败: %v\n", err)
		return
	}
	// 使用原生SQL语句查询任务,避免XORM生成可能不兼容的SQL
	found, err := global.GVA_DB.SQL("SELECT * FROM tasks WHERE id = ?", taskIDInt).Get(&task)
	if err != nil || !found {
		global.GVA_LOG.Error("从数据库读取任务失败", zap.Error(err), zap.String("taskID", taskID), zap.Bool("found", found))
		fmt.Printf("从数据库读取任务失败: %v\n", err)
		return
	}

	// 检查任务参数
	paramsJSON := task.Params
	if paramsJSON == "" {
		global.GVA_LOG.Error("任务参数为空", zap.String("taskID", taskID))
		fmt.Println("任务参数为空")
		return
	}

	// 解析参数
	var params ExternalAPICallParams
	err = json.Unmarshal([]byte(paramsJSON), &params)
	if err != nil {
		global.GVA_LOG.Error("解析API调用参数失败", zap.Error(err))
		fmt.Printf("解析API调用参数失败: %v\n", err)
		return
	}

	// 确保结果目录存在
	resultDir := "external_call_result"
	if err := os.MkdirAll(resultDir, 0755); err != nil {
		global.GVA_LOG.Error("创建结果目录失败", zap.Error(err))
		fmt.Printf("创建结果目录失败: %v\n", err)
		return
	}

	// 验证API地址
	if params.APIAddress == "" {
		global.GVA_LOG.Error("API地址为空", zap.String("taskID", taskID))
		fmt.Println("API地址为空")
		// 保存失败结果
		saveResult(resultDir, taskID, "API地址为空")
		return
	}

	// 去除API地址中的反引号和空格
	params.APIAddress = strings.Trim(params.APIAddress, "` ")

	// 验证API地址是否包含协议方案
	if !strings.HasPrefix(params.APIAddress, "http://") && !strings.HasPrefix(params.APIAddress, "https://") {
		global.GVA_LOG.Error("API地址缺少协议方案", zap.String("taskID", taskID), zap.String("APIAddress", params.APIAddress))
		fmt.Printf("API地址缺少协议方案: %s\n", params.APIAddress)
		// 保存失败结果
		saveResult(resultDir, taskID, fmt.Sprintf("API地址缺少协议方案: %s", params.APIAddress))
		return
	}

	// 将请求方式转换为大写
	params.RequestMethod = strings.ToUpper(params.RequestMethod)

	// 输出API地址以便调试
	global.GVA_LOG.Info("执行API调用", zap.String("APIAddress", params.APIAddress), zap.String("RequestMethod", params.RequestMethod))
	fmt.Printf("正在调用API: %s\n", params.APIAddress)
	fmt.Printf("请求方式: %s\n", params.RequestMethod)

	// 准备请求
	// 创建自定义TLS配置,跳过证书验证(仅用于开发测试环境)
	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
	}
	transport := &http.Transport{
		TLSClientConfig: tlsConfig,
	}
	client := &http.Client{
		Timeout:   time.Duration(params.Timeout) * time.Second,
		Transport: transport,
	}

	// 准备请求体
	var body []byte
	var bodyReader io.Reader
	if len(params.Data) > 0 {
		body, err = json.Marshal(params.Data)
		if err != nil {
			global.GVA_LOG.Error("序列化请求数据失败", zap.Error(err))
			fmt.Printf("序列化请求数据失败: %v\n", err)
			return
		}
		bodyReader = bytes.NewBuffer(body)
	} else {
		// 当请求体为空时,使用nil
		bodyReader = nil
	}

	// 创建请求
	req, err := http.NewRequest(params.RequestMethod, params.APIAddress, bodyReader)
	if err != nil {
		global.GVA_LOG.Error("创建HTTP请求失败", zap.Error(err))
		fmt.Printf("创建HTTP请求失败: %v\n", err)
		return
	}

	// 设置默认请求头
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")

	// 设置用户指定的请求头
	for key, value := range params.Headers {
		req.Header.Set(key, value)
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		global.GVA_LOG.Error("发送HTTP请求失败", zap.Error(err))
		fmt.Printf("发送HTTP请求失败: %v\n", err)

		// 保存失败结果
		saveResult(resultDir, taskID, fmt.Sprintf("请求失败: %v", err))
		return
	}
	defer resp.Body.Close()

	// 读取响应
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		global.GVA_LOG.Error("读取响应失败", zap.Error(err))
		fmt.Printf("读取响应失败: %v\n", err)

		// 保存失败结果
		saveResult(resultDir, taskID, fmt.Sprintf("读取响应失败: %v", err))
		return
	}

	// 构建结果字符串
	responseBodyStr := string(respBody)
	// 尝试将响应体解析为JSON并格式化
	var jsonObj interface{}
	if err := json.Unmarshal(respBody, &jsonObj); err == nil {
		// 如果是JSON,格式化显示
		formattedJSON, err := json.MarshalIndent(jsonObj, "", "  ")
		if err == nil {
			responseBodyStr = string(formattedJSON)
		}
	}
	result := fmt.Sprintf("状态码: %d\n响应体: \n%s", resp.StatusCode, responseBodyStr)

	// 保存结果
	saveResult(resultDir, taskID, result)

	global.GVA_LOG.Info("外部API调用任务执行完成")
	fmt.Println("外部API调用完成")
}

六、前端html/vue3各功能介绍及核心源代码

1. 核心功能介绍

1.1 任务列表展示

功能:显示所有任务的列表,包括任务ID、名称、类型、执行间隔、执行次数、执行结果等信息

核心功能

  • 分页显示任务列表
  • 任务状态实时更新
  • 执行结果颜色区分
  • 超期任务特殊标记
  • 任务操作按钮
1.2 任务管理操作

功能:提供任务的新增、编辑、删除、启动/终止、暂停/继续等操作

核心功能

  • 新增任务表单
  • 任务类型切换(一次性/周期性)
  • Cron表达式配置
  • 任务状态管理
1.3 任务统计分析

功能:提供任务执行统计和分析图表

核心功能

  • 任务执行趋势图
  • 任务状态分布图
  • 任务类型分布图
  • 任务执行时长分析
  • 高频执行任务列表
1.4 任务日志查询

功能:查询和显示任务的执行日志

核心功能

  • 按任务ID查询日志
  • 日志分页显示
  • 执行状态和时间显示

2. 核心源代码

2.1 任务列表渲染 (template/index.html)
<!-- 任务列表 -->
<div v-if="activeTab === 'tasks'">
    <div class="task-list">
        <table class="task-table">
            <thead>
                <tr>
                    <th>序号</th>
                    <th>任务ID</th>
                    <th>任务名称</th>
                    <th>任务类型</th>
                    <th>执行间隔</th>
                    <th>执行次数</th>
                    <th>执行结果</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr v-if="tasks.length === 0">
                    <td colspan="8" style="text-align: center; color: #666; padding: 20px;">暂无任务</td>
                </tr>
                <tr v-for="(task, index) in paginatedTasks" :key="task.id">
                    <td>{{ (tasksPage - 1) * tasksPageSize + index + 1 }}</td>
                    <td>{{ task.id }}</td>
                    <td>{{ task.name }}</td>
                    <td>{{ task.type === 'single' ? '一次性' : '周期性' }}</td>
                    <td>
                        <span v-if="task.type === 'single'"> {{ formatDateTime(task.execute_at) }}</span>
                        <span v-else>{{ getCronInterval(task.cron_expr) }}</span>
                    </td>
                    <td>{{ task.execute_count }}</td>
                    <td>
                        <span v-if="task.status === 'completed'">
                            <span v-if="task.type === 'single' && new Date(task.execute_at) < new Date()" class="error-result">任务已超期</span>
                            <span v-else :class="allTaskLogs.find(log => log.task_id === task.id)?.status === 'success' ? 'success-result' : 'error-result'>
                                {{ allTaskLogs.find(log => log.task_id === task.id)?.status === 'success' ? '任务执行完成' : '失败' }}
                            </span>
                        </span>
                    </td>
                    <td>
                        <div class="action-buttons">
                            <span :class="['task-status', `status-${task.status}`, task.status !== 'running' && task.type === 'single' && new Date(task.execute_at) < new Date() ? 'status-overdue' : '']">
                                {{ task.status === 'pending' ? '等待执行' : task.status === 'running' ? '正在执行' : task.type === 'single' && new Date(task.execute_at) < new Date() ? '已超期' : '已完成' }}
                            </span>
                            <button :class="['btn', task.enabled_status ? 'btn-danger' : 'btn-success']" @click="toggleTaskStatus(task.id, task.enabled_status)">
                                {{ task.enabled_status ? '终止' : '启动' }}
                            </button>
                            <button :class="['btn', task.paused_status ? 'btn-warning' : 'btn-primary']" :disabled="!task.enabled_status" @click="toggleTaskPause(task.id, task.paused_status)">
                                {{ task.paused_status ? '继续' : '暂停' }}
                            </button>
                            <button class="btn btn-primary" @click="showTaskLogs(task.id)">查看日志</button>
                            <button class="btn btn-warning" @click="editTask(task)">修改</button>
                            <button class="btn btn-danger" @click="deleteTask(task.id)">删除</button>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
    <div class="pagination" v-if="tasksTotal > tasksPageSize">
        <div class="page-item" v-if="tasksPage > 1">
            <a class="page-link" @click="tasksPage--">上一页</a>
        </div>
        <div class="page-item" v-for="page in tasksDisplayedPages" :key="page">
            <a class="page-link" :class="{ active: page === tasksPage }" @click="tasksPage = page">{{ page }}</a>
        </div>
        <div class="page-item" v-if="tasksPage < tasksTotalPages">
            <a class="page-link" @click="tasksPage++">下一页</a>
        </div>
    </div>
</div>
2.2 Vue3 数据管理和方法 (template/index.html)
<script>
    const { createApp, ref, computed, onMounted, watch } = Vue;

    createApp({
        setup() {
            // 状态管理
            const activeTab = ref('tasks');
            const tasks = ref([]);
            const taskLogs = ref([]);
            const allTaskLogs = ref([]);
            const taskFuncs = ref([]);
            const statistics = ref({});
            const failedTasks = ref([]);
            const frequentTasks = ref([]);
            const cronExpressions = ref([]);

            // 分页管理
            const tasksPage = ref(1);
            const tasksPageSize = ref(10);
            const tasksTotal = ref(0);
            const cronPage = ref(1);
            const cronPageSize = ref(10);
            const cronTotal = ref(0);

            // 排序管理
            const sortBy = ref('default');
            const sortOrder = ref('asc');

            // 模态框管理
            const showAddTaskModal = ref(false);
            const showEditTaskModal = ref(false);
            const showLogsModal = ref(false);
            const showCronModal = ref(false);

            // 任务表单
            const newTask = ref({
                name: '',
                description: '',
                type: 'single',
                cron_expr: '',
                execute_at: '',
                timeout: 30,
                task_func_name: '',
                params: ''
            });

            const editingTask = ref({});
            const editingCron = ref({});

            // 任务信息
            const taskName = ref('');
            const taskFuncName = ref('');
            const taskFuncDesc = ref('');

            // 常用Cron表达式
            const commonCronExpressions = [
                { label: '每10秒', value: '*/10 * * * * *' },
                { label: '每分钟', value: '0 * * * * *' },
                { label: '每5分钟', value: '0 */5 * * * *' },
                { label: '每小时', value: '0 0 * * * *' },
                { label: '每天', value: '0 0 0 * * *' },
                { label: '每周', value: '0 0 0 * * 0' },
                { label: '每月', value: '0 0 0 1 * *' }
            ];

            // 加载任务列表
            const loadTasks = async () => {
                try {
                    const response = await axios.get('/api/tasks');
                    if (response.data.code === 200) {
                        tasks.value = response.data.data;
                        tasksTotal.value = tasks.value.length;
                    } else {
                        showToast('加载任务列表失败', 'error');
                    }
                } catch (error) {
                    showToast('加载任务列表失败', 'error');
                    console.error('加载任务列表失败:', error);
                }
            };

            // 加载所有任务日志
            const loadAllTaskLogs = async () => {
                try {
                    const response = await axios.get('/api/tasks/logs/all');
                    if (response.data.code === 200) {
                        allTaskLogs.value = response.data.data;
                    }
                } catch (error) {
                    console.error('加载任务日志失败:', error);
                }
            };

            // 加载任务函数
            const loadTaskFuncs = async () => {
                try {
                    const response = await axios.get('/api/tasks/funcs');
                    if (response.data.code === 200) {
                        taskFuncs.value = response.data.data;
                    }
                } catch (error) {
                    console.error('加载任务函数失败:', error);
                }
            };

            // 加载统计数据
            const loadStatistics = async () => {
                try {
                    const response = await axios.get('/api/tasks/statistics');
                    if (response.data.code === 200) {
                        statistics.value = response.data.data;
                        initCharts();
                    }
                } catch (error) {
                    console.error('加载统计数据失败:', error);
                }
            };

            // 加载失败任务
            const loadFailedTasks = async () => {
                try {
                    const response = await axios.get('/api/tasks/failed');
                    if (response.data.code === 200) {
                        failedTasks.value = response.data.data;
                    }
                } catch (error) {
                    console.error('加载失败任务失败:', error);
                }
            };

            // 加载高频任务
            const loadFrequentTasks = async () => {
                try {
                    const response = await axios.get('/api/tasks/frequent');
                    if (response.data.code === 200) {
                        frequentTasks.value = response.data.data;
                    }
                } catch (error) {
                    console.error('加载高频任务失败:', error);
                }
            };

            // 加载Cron表达式
            const loadCronExpressions = async () => {
                try {
                    const response = await axios.get('/api/tasks/cron');
                    if (response.data.code === 200) {
                        cronExpressions.value = response.data.data;
                        cronTotal.value = cronExpressions.value.length;
                    }
                } catch (error) {
                    console.error('加载Cron表达式失败:', error);
                }
            };

            // 新增任务
            const addTask = async () => {
                try {
                    // 转换日期格式
                    if (newTask.value.type === 'single') {
                        newTask.value.execute_at = new Date(newTask.value.execute_at).toISOString();
                    }

                    const response = await axios.post('/api/tasks', newTask.value);
                    if (response.data.code === 200) {
                        showToast('任务创建成功', 'success');
                        showAddTaskModal.value = false;
                        resetNewTask();
                        loadTasks();
                    } else {
                        showToast('任务创建失败', 'error');
                    }
                } catch (error) {
                    showToast('任务创建失败', 'error');
                    console.error('创建任务失败:', error);
                }
            };

            // 重置新增任务表单
            const resetNewTask = () => {
                newTask.value = {
                    name: '',
                    description: '',
                    type: 'single',
                    cron_expr: '',
                    execute_at: '',
                    timeout: 30,
                    task_func_name: '',
                    params: ''
                };
            };

            // 编辑任务
            const editTask = (task) => {
                editingTask.value = { ...task };
                // 转换日期格式
                if (editingTask.value.type === 'single') {
                    editingTask.value.execute_at = new Date(editingTask.value.execute_at).toISOString().slice(0, 16);
                }
                showEditTaskModal.value = true;
            };

            // 更新任务
            const updateTask = async () => {
                try {
                    // 转换日期格式
                    if (editingTask.value.type === 'single') {
                        editingTask.value.execute_at = new Date(editingTask.value.execute_at).toISOString();
                    }

                    const response = await axios.put(`/api/tasks/${editingTask.value.id}`, editingTask.value);
                    if (response.data.code === 200) {
                        showToast('任务更新成功', 'success');
                        showEditTaskModal.value = false;
                        loadTasks();
                    } else {
                        showToast('任务更新失败', 'error');
                    }
                } catch (error) {
                    showToast('任务更新失败', 'error');
                    console.error('更新任务失败:', error);
                }
            };

            // 删除任务
            const deleteTask = async (id) => {
                if (confirm('确定要删除这个任务吗?')) {
                    try {
                        const response = await axios.delete(`/api/tasks/${id}`);
                        if (response.data.code === 200) {
                            showToast('任务删除成功', 'success');
                            loadTasks();
                        } else {
                            showToast('任务删除失败', 'error');
                        }
                    } catch (error) {
                        showToast('任务删除失败', 'error');
                        console.error('删除任务失败:', error);
                    }
                }
            };

            // 切换任务状态
            const toggleTaskStatus = async (id, enabled) => {
                try {
                    const action = enabled ? 'stop' : 'start';
                    const response = await axios.post(`/api/tasks/${id}/${action}`);
                    if (response.data.code === 200) {
                        showToast(`任务${enabled ? '终止' : '启动'}成功`, 'success');
                        loadTasks();
                    } else {
                        showToast(`任务${enabled ? '终止' : '启动'}失败`, 'error');
                    }
                } catch (error) {
                    showToast(`任务${enabled ? '终止' : '启动'}失败`, 'error');
                    console.error(`${enabled ? '终止' : '启动'}任务失败:`, error);
                }
            };

            // 切换任务暂停状态
            const toggleTaskPause = async (id, paused) => {
                try {
                    const action = paused ? 'resume' : 'pause';
                    const response = await axios.post(`/api/tasks/${id}/${action}`);
                    if (response.data.code === 200) {
                        showToast(`任务${paused ? '继续' : '暂停'}成功`, 'success');
                        loadTasks();
                    } else {
                        showToast(`任务${paused ? '继续' : '暂停'}失败`, 'error');
                    }
                } catch (error) {
                    showToast(`任务${paused ? '继续' : '暂停'}失败`, 'error');
                    console.error(`${paused ? '继续' : '暂停'}任务失败:`, error);
                }
            };

            // 查看任务日志
            const showTaskLogs = async (id) => {
                try {
                    const response = await axios.get(`/api/tasks/logs?task_id=${id}`);
                    if (response.data.code === 200) {
                        taskLogs.value = response.data.data.logs;
                        taskName.value = response.data.data.taskName || '';
                        taskFuncName.value = response.data.data.taskFuncName || '';
                        taskFuncDesc.value = response.data.data.taskFuncDesc || '';
                        showLogsModal.value = true;
                    } else {
                        showToast('加载任务日志失败', 'error');
                    }
                } catch (error) {
                    showToast('加载任务日志失败', 'error');
                    console.error('加载任务日志失败:', error);
                }
            };

            // 选择Cron模板
            const selectCronTemplate = (value) => {
                if (value) {
                    newTask.value.cron_expr = value;
                }
            };

            // 处理任务函数变更
            const handleTaskFuncChange = (funcName) => {
                // 可以在这里添加任务函数变更的处理逻辑
            };

            // 排序任务
            const sortTasks = () => {
                // 实现任务排序逻辑
            };

            // 格式化日期时间
            const formatDateTime = (dateTime) => {
                if (!dateTime) return '';
                const date = new Date(dateTime);
                return date.toLocaleString('zh-CN', {
                    year: 'numeric',
                    month: '2-digit',
                    day: '2-digit',
                    hour: '2-digit',
                    minute: '2-digit',
                    second: '2-digit'
                });
            };

            // 获取Cron间隔描述
            const getCronInterval = (cronExpr) => {
                if (!cronExpr) return '';
                
                // 简单的Cron表达式解析
                if (cronExpr === '*/10 * * * * *') return '每10秒';
                if (cronExpr === '0 * * * * *') return '每分钟';
                if (cronExpr === '0 */5 * * * *') return '每5分钟';
                if (cronExpr === '0 0 * * * *') return '每小时';
                if (cronExpr === '0 0 0 * * *') return '每天';
                if (cronExpr === '0 0 0 * * 0') return '每周';
                if (cronExpr === '0 0 0 1 * *') return '每月';
                
                return cronExpr;
            };

            // 计算分页显示的页码
            const tasksDisplayedPages = computed(() => {
                const totalPages = Math.ceil(tasksTotal.value / tasksPageSize.value);
                const pages = [];
                for (let i = 1; i <= totalPages; i++) {
                    pages.push(i);
                }
                return pages;
            });

            const cronDisplayedPages = computed(() => {
                const totalPages = Math.ceil(cronTotal.value / cronPageSize.value);
                const pages = [];
                for (let i = 1; i <= totalPages; i++) {
                    pages.push(i);
                }
                return pages;
            });

            // 计算分页后的任务
            const paginatedTasks = computed(() => {
                const start = (tasksPage.value - 1) * tasksPageSize.value;
                const end = start + tasksPageSize.value;
                return tasks.value.slice(start, end);
            });

            const paginatedCronExpressions = computed(() => {
                const start = (cronPage.value - 1) * cronPageSize.value;
                const end = start + cronPageSize.value;
                return cronExpressions.value.slice(start, end);
            });

            // 初始化图表
            const initCharts = () => {
                // 实现图表初始化逻辑
            };

            // 显示提示
            const showToast = (message, type = 'info') => {
                // 实现提示功能
            };

            // 生命周期钩子
            onMounted(() => {
                loadTasks();
                loadAllTaskLogs();
                loadTaskFuncs();
                loadCronExpressions();
            });

            watch(activeTab, (newTab) => {
                if (newTab === 'statistics') {
                    loadStatistics();
                    loadFailedTasks();
                    loadFrequentTasks();
                }
            });

            return {
                // 状态
                activeTab,
                tasks,
                taskLogs,
                allTaskLogs,
                taskFuncs,
                statistics,
                failedTasks,
                frequentTasks,
                cronExpressions,
                tasksPage,
                tasksPageSize,
                tasksTotal,
                cronPage,
                cronPageSize,
                cronTotal,
                sortBy,
                sortOrder,
                showAddTaskModal,
                showEditTaskModal,
                showLogsModal,
                showCronModal,
                newTask,
                editingTask,
                editingCron,
                taskName,
                taskFuncName,
                taskFuncDesc,
                commonCronExpressions,
                
                // 方法
                loadTasks,
                addTask,
                editTask,
                updateTask,
                deleteTask,
                toggleTaskStatus,
                toggleTaskPause,
                showTaskLogs,
                selectCronTemplate,
                handleTaskFuncChange,
                sortTasks,
                formatDateTime,
                getCronInterval,
                tasksDisplayedPages,
                cronDisplayedPages,
                paginatedTasks,
                paginatedCronExpressions
            };
        }
    }).mount('#app');
</script>

七、项目应用的第三方包介绍

1. 后端第三方包

包名版本用途来源
github.com/kataras/iris/v1212.2.11Web框架go.mod
go.uber.org/zap1.24.0日志库go.mod
xorm.io/xorm1.3.6ORM框架go.mod
github.com/robfig/cron/v33.0.1Cron表达式解析go.mod

2. 前端第三方库

库名版本用途来源
Vue.js3.x前端框架static/js/vue.global.js
Axios0.27.2HTTP客户端static/js/axios.min.js
ECharts5.4.0图表库static/js/echarts.min.js

八、项目应用场景

1. 系统自动化运维

应用场景:定期执行系统维护任务,如日志清理、数据库备份、系统更新等。

优势

  • 自动化执行,减少人工干预
  • 定时执行,确保任务在合适的时间点运行
  • 执行结果可追踪,便于问题排查

2. 数据处理与分析

应用场景:定期处理和分析业务数据,如销售数据汇总、用户行为分析、报表生成等。

优势

  • 周期性执行,确保数据及时更新
  • 可设置超时时间,避免任务执行过长影响系统性能
  • 执行结果可记录,便于数据追溯

3. 外部系统集成

应用场景:与外部系统进行数据同步,如API调用、数据采集、消息推送等。

优势

  • 可设置执行间隔,控制API调用频率
  • 执行失败可记录,便于问题排查
  • 可暂停和继续任务,灵活控制集成过程

4. 定时任务调度

应用场景:执行各种定时任务,如邮件发送、短信提醒、系统通知等。

优势

  • 支持一次性和周期性任务
  • 可设置执行时间,确保任务在指定时间执行
  • 超期任务自动处理,避免任务堆积

5. 高频任务监控

应用场景:监控高频执行的任务,如实时数据采集、状态检查等。

优势

  • 可识别高频任务,便于资源规划
  • 执行次数统计,便于任务评估
  • 执行状态监控,确保任务正常运行

总结

本任务调度管理系统是一个功能完整、架构清晰的Go语言项目,采用前后端分离架构,后端使用Go语言的Iris框架,前端使用Vue3+HTML5实现。系统支持任务的创建、编辑、删除、启动/终止、暂停/继续等基本操作,支持一次性任务和周期性任务两种类型,具有任务执行状态实时监控、执行结果记录与展示、超期任务自动处理、任务执行统计分析等功能。

项目代码组织合理,核心功能实现完善,具有良好的可扩展性和可维护性,可应用于各种需要自动化任务调度的场景。通过本项目的开发,我们展示了如何使用Go语言构建一个完整的任务调度系统,包括后端API开发、前端界面实现、数据库操作、任务调度和执行等各个方面。

该系统不仅满足了基本的任务调度需求,还提供了丰富的统计分析功能,帮助用户更好地了解任务执行情况,优化任务配置和资源分配。同时,系统的超期任务自动处理功能确保了任务的及时清理,避免了任务堆积和资源浪费。

总之,本任务调度管理系统是一个实用、高效、可靠的自动化任务处理平台,为各种业务场景提供了强大的任务调度能力。