[外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)

上一章介绍了log4net的简单配置,这一章介绍一下quartz的简单使用,下一章介绍一下我得权限使用,然后就结束

本章主要介绍:

  • quartz在asp.net core中的使用

这个项目虽小,但是及其容易扩展,后面的业务直接能丢进来,使其更加丰富

废话不说开始介绍

一.基础类配置

  在domain里定义IJobCenter接口

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第1张图片

  代码如下:

  

public interface IJobCenter
    {
        /// 
        /// 添加定时任务
        /// 
        /// 
        /// 
        Task AddScheduleJobAsync(TaskScheduleModel m);

        /// 
        /// 暂停定时任务
        /// 
        /// 
        /// 
        /// 
        Task StopScheduleJobAsync(string jobGroup, string jobName);

        /// 
        /// 恢复定时任务
        /// 
        /// 
        /// 
        /// 
        Task RunScheduleJobAsync(TaskScheduleModel m);
    }

  infrastructure里实现IJobCenter

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第2张图片

  记得引入quartz的nuget

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第3张图片

 

  代码如下:

  

/// 
    /// 任务调度中心
    /// 
    public class JobCenter:IJobCenter
    {
        
        public static IScheduler scheduler = null;
        public static async Task GetSchedulerAsync()
        {
            if (scheduler != null)
            {
                return scheduler;
            }
            else
            {
                ISchedulerFactory schedf = new StdSchedulerFactory();
                IScheduler sched = await schedf.GetScheduler();
                return sched;
            }
        }
        /// 
        /// 添加任务计划//或者进程终止后的开启
        /// 
        /// 
        public async Task AddScheduleJobAsync(TaskScheduleModel m)
        {
            Result result = new Result();
            try
            {
                if (m != null)
                {
                    DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(m.StarRunTime, 1);
                    DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(m.EndRunTime, 1);
                    scheduler = await GetSchedulerAsync();
                    IJobDetail job = JobBuilder.Create()
                      .WithIdentity(m.JobName, m.JobGroup)
                      .Build();
                    ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                                                 .StartAt(starRunTime)
                                                 .EndAt(endRunTime)
                                                 .WithIdentity(m.JobName, m.JobGroup)
                                                 .WithCronSchedule(m.CronExpress)
                                                 .Build();
                    await scheduler.ScheduleJob(job, trigger);
                    await scheduler.Start();
                    result.Data = m;
                    return result;
                }
                return result.SetError("传入实体为空");
            }
            catch (Exception ex)
            {
                Log4Net.Error($"[JobCenter_AddScheduleJobAsync]_{ex}");
                return result.SetError(ex.Message);
            }
        }

        /// 
        /// 暂停指定任务计划
        /// 
        /// 
        public async Task StopScheduleJobAsync(string jobGroup, string jobName)
        {
            Result result = new Result();
            try
            {
                scheduler = await GetSchedulerAsync();
                //使任务暂停
                await scheduler.PauseJob(new JobKey(jobName, jobGroup));                
                var status = new StatusViewModel()
                {
                    Status = 0,
                    Msg = "暂停任务计划成功",
                };
                result.Data = status.GetJson();
                return result;
            }
            catch (Exception ex)
            {
                Log4Net.Error($"[JobCenter_StopScheduleJobAsync]_{ex}");
                var status = new StatusViewModel()
                {
                    Status = -1,
                    Msg = "暂停任务计划失败",
                };
                result.Data = status.GetJson();
                return result;
            }
        }
        /// 
        /// 恢复指定的任务计划**恢复的是暂停后的任务计划,如果是程序奔溃后 或者是进程杀死后的恢复,此方法无效
        /// 
        /// 
        public async Task RunScheduleJobAsync(TaskScheduleModel sm)
        {
            Result result = new Result();
            try
            {
                #region 开任务
                //scheduler = await GetSchedulerAsync();
                //DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(sm.StarRunTime, 1);
                //DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(sm.EndRunTime, 1);
                //IJobDetail job = JobBuilder.Create()
                //  .WithIdentity(sm.JobName, sm.JobGroup)
                //  .Build();
                //ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                //                             .StartAt(starRunTime)
                //                             .EndAt(endRunTime)
                //                             .WithIdentity(sm.JobName, sm.JobGroup)
                //                             .WithCronSchedule(sm.CronExpress)
                //                             .Build();
                //await scheduler.ScheduleJob(job, trigger);
                //await scheduler.Start();
                #endregion
                scheduler = await GetSchedulerAsync();
                //resumejob 恢复
                await scheduler.ResumeJob(new JobKey(sm.JobName, sm.JobGroup));

                var status = new StatusViewModel()
                {
                    Status = 0,
                    Msg = "恢复任务计划成功",
                };
                result.Data = status.GetJson();
                return result;
            }
            catch (Exception ex)
            {
                Log4Net.Error($"[JobCenter_RunScheduleJobAsync]_{ex}");
                var status = new StatusViewModel()
                {
                    Status = -1,
                    Msg = "恢复任务计划失败",
                };
                result.Data = status.GetJson();
                return result;
            }
        }
    }

  写一个JobServiceExtensions拓展,其中里面有一个AddJobSerivce,用于在startup里添加启动服务

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第4张图片

  这个拓展的主要作用是:程序启动,自动查询我的任务调度管理表,查询里面的状态是开启中的任务,并将其添加到定时任务中

  表结构大致如下:

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第5张图片

   这里我们主要注意任务组和任务名,这两个何在一起,能顶一个唯一的任务,后面我们会在httpjob里根据不同的的任务组和任务名

    区分他们要执行的不同的逻辑

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第6张图片

  代码很简单:如下

  

public class HttpJob : IJob
    {
        
        /// 
        /// 通过group和name判断是要执行哪个任务  具体(任务执行逻辑)业务逻辑写后面
        /// 
        /// 
        /// 
        public async Task Execute(IJobExecutionContext context)
        {
            await Task.Run(() =>
            {
                var name = context.JobDetail.Key.Name;
                var group = context.JobDetail.Key.Group;
                if (group=="xx1"&&name=="xx2")
                {
                    //do something
                }

                if (group == "xx2" && name == "xx3")
                {
                    //do something also
                }
                Log4Net.Info($"执行任务_Name:{name}_Grop:{group}");
            });
        }
    }

  在domain里新增ITaskService接口,如下

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第7张图片

  代码如下:

  

public interface ITaskService
    {
        //获取任务列表
        Result GetTaskList();
        //添加任务
        Task AddTaskAsync(TaskScheduleModel model);
        //修改任务
        Task ModifyTaskAsync(TaskScheduleModel model);
        //删除任务
        Task DelTaskAsync(TaskScheduleModel model);
        //暂停任务
        Result PauseTask();
        //开启任务
        Result StartTask();
    }

  在application 里实现这个接口

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第8张图片

  代码如下:  

public class TaskService : BaseService, ITaskService
    {
        private IJobCenter jobCenter = ServiceCollectionExtension.Get();
        private MvcIdentity identity = (ServiceCollectionExtension.HttpContext.User.Identity as MvcIdentity);

        public async Task AddTaskAsync(TaskScheduleModel model)
        {
            Result result = new Result();

            if (model == null)
            {
                return result.SetError("Model 不能为空!");
            }
            if (string.IsNullOrEmpty(model.JobName))
            {
                return result.SetError("JobName 不能为空!");
            }
            if (string.IsNullOrEmpty(model.JobGroup))
            {
                return result.SetError("JobGroup 不能为空!");
            }
            if (model.StarRunTime == null)
            {
                model.StarRunTime = DateTime.Now;
            }
            if (model.EndRunTime == null)
            {
                model.EndRunTime = DateTime.MaxValue.AddDays(-1);
            }
            var info = await jobCenter.AddScheduleJobAsync(model);
            if (info.Status != 200)
            {
                return result.SetError(info.Message);
            }
            base.Add(new TaskSchedule
            {
                Id = Guid.NewGuid().ToString("N"),
                CreateAuthr = identity.Name,
                CronExpress = model.CronExpress,
                EndRunTime = model.EndRunTime,
                StarRunTime = model.StarRunTime,
                JobGroup = model.JobGroup,
                JobName = model.JobName,
                RunStatus = model.RunStatus

            }, true);
            return result;
        }

        public async Task DelTaskAsync(TaskScheduleModel model)
        {
            Result result = new Result();
            if (model == null)
            {
                return result.SetError("Model 不能为空!");
            }
            if (string.IsNullOrEmpty(model.JobName))
            {
                return result.SetError("JobName 不能为空!");
            }
            if (string.IsNullOrEmpty(model.JobGroup))
            {
                return result.SetError("JobGroup 不能为空!");
            }
            //search
            var taskInfo = base.Single(t => t.Id.Equals(model.Id));
            var info = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);
            if (!info.Status.Equals(200))
            {
                return result.SetError(info.Message);
            }
            //del
            base.Delete(taskInfo, true);
            return result;
        }

        public Result GetTaskList()
        {
            Result result = new Result();
            var query = base.Where(t => !t.RunStatus.Equals(TaskJobStatus.JobHasDel)).Select(t => new
            {
                t.Id,
                t.JobGroup,
                t.JobName,
                t.RunStatus,
                t.StarRunTime,
                t.UpdateTime,
                t.CronExpress,
                t.EndRunTime,
                t.CreateTime
            }).ToList();
            List _list = new List();
            query.ForEach(t =>
            {
                _list.Add(new TaskScheduleModel()
                {
                    Id = t.Id,
                    JobGroup = t.JobGroup,
                    JobName = t.JobName,
                    _RunStatus = ((TaskJobStatus)t.RunStatus).GetString(),
                    StarRunTime = t.StarRunTime,
                    UpdateTime = t.UpdateTime,
                    CronExpress = t.CronExpress,
                    EndRunTime = t.EndRunTime,
                    CreateTime = t.CreateTime
                });
            });
            result.Data = _list;
            return result;
        }

        public async Task ModifyTaskAsync(TaskScheduleModel model)
        {
            Result result = new Result();

            if (model == null)
            {
                return result.SetError("Model 不能为空!");
            }
            if (string.IsNullOrEmpty(model.JobName))
            {
                return result.SetError("JobName 不能为空!");
            }
            if (string.IsNullOrEmpty(model.JobGroup))
            {
                return result.SetError("JobGroup 不能为空!");
            }
            if (model.StarRunTime == null)
            {
                model.StarRunTime = DateTime.Now;
            }
            if (model.EndRunTime == null)
            {
                model.EndRunTime = DateTime.MaxValue.AddDays(-1);
            }
            //modify
            var taskInfo = base.Single(t => t.Id.Equals(model.Id));

            if (taskInfo == null)
            {
                return result.SetError("无此任务!");
            }
            //cron
            if (!taskInfo.CronExpress.Equals(model.CronExpress))
            {
                taskInfo.CronExpress = model.CronExpress;
                var stopInfo = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);
                if (!stopInfo.Status.Equals(200))
                {
                    return result.SetError(stopInfo.Message);
                }

                var info = await jobCenter.AddScheduleJobAsync(model);
                if (!stopInfo.Status.Equals(200))
                {
                    return result.SetError(info.Message);
                }
            }


            //状态
            if (!taskInfo.RunStatus.Equals(model.RunStatus))
            {
                taskInfo.RunStatus = model.RunStatus;
                if (model.RunStatus != (int)TaskJobStatus.PauseJob)
                {
                    var stopInfo = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);
                    if (!stopInfo.Status.Equals(200))
                    {
                        return result.SetError(stopInfo.Message);
                    }
                    var info = await jobCenter.AddScheduleJobAsync(model);
                    if (!stopInfo.Status.Equals(200))
                    {
                        return result.SetError(info.Message);
                    }
                }
                else
                {
                    var stopInfo = await jobCenter.StopScheduleJobAsync(model.JobGroup, model.JobName);
                    if (!stopInfo.Status.Equals(200))
                    {
                        return result.SetError(stopInfo.Message);
                    }
                }
            }
            //
            taskInfo.CreateAuthr = identity.Name;
            taskInfo.UpdateTime = DateTime.Now;
            taskInfo.EndRunTime = model.EndRunTime;
            taskInfo.StarRunTime = model.StarRunTime;
            taskInfo.JobGroup = model.JobGroup;
            taskInfo.JobName = model.JobName;

            base.Update(taskInfo, true);
            return result;
        }

        public Result PauseTask()
        {
            throw new NotImplementedException();
        }

        public Result StartTask()
        {
            throw new NotImplementedException();
        }
    }
View Code

  接着我们构建web页面

  在website里创建taskinfo控制器

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第9张图片

  代码很简单只是做了一个跳转

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第10张图片

  创建视图

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第11张图片

  代码如下:  

@{
    ViewData["title"] = "定时任务管理";
}
class="row search">
class="form-inline"> "text" class="form-control" placeholder="任务名称" ng-model="search.username" />
@*弹出框*@
class="modal fade in" id="addmodel" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="mymodallabel">
class="modal-dialog modal-lg" role="document" style="height:100%">
class="modal-content">
class="modal-header">

计划任务管理

class="modal-body" ng-form="mymodel">
class="row">
class="form-group col-sm-6">
class="col-sm-8"> "text" class="form-control" ng-model="task.jobGroup" required placeholder="任务组" />
class="form-group col-sm-6">
class="col-sm-8"> "text" class="form-control" ng-model="task.jobName" required placeholder="任务名称" />
class="form-group col-sm-6">
class="col-sm-8"> "text" class="form-control" ng-model="task.cronExpress" required placeholder="CronExpress" />
class="form-group col-sm-6">
class="col-sm-8"> <select class="form-control" required ng-model="task.runStatus"> @**@ select>
class="form-group col-sm-6">
class="col-sm-8"> "text" class="form-control mydatetimepicker" ng-model="task.starRunTime" ng-max-date="task.starRunTime||defaultDate" placeholder="开始日期" />
class="form-group col-sm-6">
class="col-sm-8"> "text" class="form-control mydatetimepicker" ng-model="task.endRunTime" ng-min-date="task.starRunTime" ng-max-date="defaultDate" placeholder="结束日期" />
class="modal-footer">
class="table table-hover table-condensed table-bordered" style="width:auto;"> "height: 35px;"> class="wait-loaded"> "m in list track by m.id">
任务组 任务 CronExpress 开始时间 结束时间 运行状态 创建时间 修改时间 操作
{{m.jobGroup}} {{m.jobName}} {{m.cronExpress}} {{m.starRunTime}} {{m.endRunTime}} {{m._RunStatus}} {{m.createTime}} {{m.updateTime}}
class="mypager wait-loaded">
    "search.recordcount" items-per-page="search.pagesize" ng-change="pagechanged()" ng-model="search.pageindex" max-size="7" class="pagination-sm" boundary-links="true" num-pages="search.numpages" boundary-link-numbers="true" first-text="首页" last-text="末页" previous-text="上一页" next-text="下一页">
class="recordcount">共 {{search.recordcount}} 条
@section scripts{ }
View Code

  之后效果就出来了

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第12张图片

  这个table会调用一个webapi接口获取数据

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第13张图片

  这个webapi里我们直接调用我们改才ITaskService里分装的方法

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第14张图片

  这里代码如下:

  

#region 计划任务模块
        [HttpPost]
        public Result GetTaskList()
        {
            return _taskService.GetTaskList();
        }
        [HttpPost]
        public async Task AddTaskAsync([FromBody]TaskScheduleModel model)
        {
            if (model != null && !string.IsNullOrEmpty(model.Id)&&!model.Id.Equals("-1"))
            {
                return await _taskService.ModifyTaskAsync(model);
            }
            return await _taskService.AddTaskAsync(model);
        }

        public async Task DelTaskAsync([FromBody]TaskScheduleModel model)
        {
            return await _taskService.DelTaskAsync(model);
        }
        #endregion

  二.运行测试

  换得添加服务哦

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第15张图片

  算了,这个运行测试截图不好说明,明天录一个视频说明一下,今天就到这里

  下一章主要说一下权限这块的东西,本来想着今天就写完的,但是有点困了,

  此文章献给我做一年半asp.net core开发的青春岁月,晚安!

  [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)_第16张图片

 

 

 

 

 

 

 

 

 

 

 

  

你可能感兴趣的:([外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用))