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

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

    本章主要介绍:

    • quartz在asp.net core中的使用

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

    废话不说开始介绍

    一.基础类配置

      在domain里定义IJobCenter接口

      

      代码如下:

      

    public interface IJobCenter
        {
            /// <summary>
            /// 添加定时任务
            /// </summary>
            /// <param name="m"></param>
            /// <returns></returns>
            Task<Result> AddScheduleJobAsync(TaskScheduleModel m);
    
            /// <summary>
            /// 暂停定时任务
            /// </summary>
            /// <param name="jobGroup"></param>
            /// <param name="jobName"></param>
            /// <returns></returns>
            Task<Result> StopScheduleJobAsync(string jobGroup, string jobName);
    
            /// <summary>
            /// 恢复定时任务
            /// </summary>
            /// <param name="jobGroup"></param>
            /// <param name="jobName"></param>
            /// <returns></returns>
            Task<Result> RunScheduleJobAsync(TaskScheduleModel m);
        }

      infrastructure里实现IJobCenter

      

      记得引入quartz的nuget

      

      代码如下:

      

    /// <summary>
        /// 任务调度中心
        /// </summary>
        public class JobCenter:IJobCenter
        {
            
            public static IScheduler scheduler = null;
            public static async Task<IScheduler> GetSchedulerAsync()
            {
                if (scheduler != null)
                {
                    return scheduler;
                }
                else
                {
                    ISchedulerFactory schedf = new StdSchedulerFactory();
                    IScheduler sched = await schedf.GetScheduler();
                    return sched;
                }
            }
            /// <summary>
            /// 添加任务计划//或者进程终止后的开启
            /// </summary>
            /// <returns></returns>
            public async Task<Result> 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<HttpJob>()
                          .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);
                }
            }
    
            /// <summary>
            /// 暂停指定任务计划
            /// </summary>
            /// <returns></returns>
            public async Task<Result> 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;
                }
            }
            /// <summary>
            /// 恢复指定的任务计划**恢复的是暂停后的任务计划,如果是程序奔溃后 或者是进程杀死后的恢复,此方法无效
            /// </summary>
            /// <returns></returns>
            public async Task<Result> 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<HttpJob>()
                    //  .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里添加启动服务

      

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

      表结构大致如下:

      

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

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

      

      代码很简单:如下

      

    public class HttpJob : IJob
        {
            
            /// <summary>
            /// 通过group和name判断是要执行哪个任务  具体(任务执行逻辑)业务逻辑写后面
            /// </summary>
            /// <param name="context"></param>
            /// <returns></returns>
            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接口,如下

      

      代码如下:

      

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

      在application 里实现这个接口

      

      代码如下:  

    public class TaskService : BaseService, ITaskService
        {
            private IJobCenter jobCenter = ServiceCollectionExtension.Get<IJobCenter>();
            private MvcIdentity identity = (ServiceCollectionExtension.HttpContext.User.Identity as MvcIdentity);
    
            public async Task<Result> 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<Result> 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<TaskSchedule>(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<TaskSchedule>(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<TaskScheduleModel> _list = new List<TaskScheduleModel>();
                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<Result> 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<TaskSchedule>(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控制器

      

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

      

      创建视图

      

      代码如下:  

    @{
        ViewData["title"] = "定时任务管理";
    }
    <div class="row search">
        <div class="form-inline">
            <input type="text" class="form-control" placeholder="任务名称" ng-model="search.username" />
        </div>
    
        <button class="btn btn-primary" type="button" ng-click="pagechanged(true)">搜索</button>
        <button class="btn btn-primary" type="button" ng-click="addTask()">添加任务</button>
        <button class="btn btn-primary" type="button" csv-header="getHeader()" ng-csv="_getCsv()" filename="taskList.csv" add-bom="true">导出</button>
    </div>
    @*弹出框*@
    <div class="modal fade in" id="addmodel" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="mymodallabel">
        <div class="modal-dialog modal-lg" role="document" style="height:100%">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">close</span></button>
                    <h4>计划任务管理</h4>
                </div>
                <div class="modal-body" ng-form="mymodel">
                    <div class="row">
                        <div class="form-group col-sm-6">
                            <label class="control-label col-sm-4">任务组:</label>
                            <div class="col-sm-8">
                                <input type="text" class="form-control" ng-model="task.jobGroup" required placeholder="任务组" />
                            </div>
                        </div>
                        <div class="form-group col-sm-6">
                            <label class="control-label col-sm-4">任务名称:</label>
                            <div class="col-sm-8">
                                <input type="text" class="form-control" ng-model="task.jobName" required placeholder="任务名称" />
                            </div>
                        </div>
                        <div class="form-group col-sm-6">
                            <label class="control-label col-sm-4">CronExpress:</label>
                            <div class="col-sm-8">
                                <input type="text" class="form-control" ng-model="task.cronExpress" required placeholder="CronExpress" />
                            </div>
                        </div>
                        <div class="form-group col-sm-6">
                            <label class="control-label col-sm-4">运行状态:</label>
                            <div class="col-sm-8">
                                <select class="form-control" required ng-model="task.runStatus">
                                    @*<option value="1">全部</option>*@
                                    <option value="1" selected>执行任务中</option>
                                    <option value="2">暂停任务中</option>
                                    <option value="4">任务关闭</option>
                                </select>
                            </div>
                        </div>
                        <div class="form-group col-sm-6">
                            <label class="control-label col-sm-4">开始时间:</label>
                            <div class="col-sm-8">
                                <input type="text" class="form-control mydatetimepicker" ng-model="task.starRunTime" ng-max-date="task.starRunTime||defaultDate" placeholder="开始日期" />
    
                            </div>
                        </div>
                        <div class="form-group col-sm-6">
                            <label class="control-label col-sm-4">结束时间:</label>
                            <div class="col-sm-8">
                                <input type="text" class="form-control mydatetimepicker" ng-model="task.endRunTime" ng-min-date="task.starRunTime" ng-max-date="defaultDate" placeholder="结束日期" />
    
                            </div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-success" ng-disabled="mymodel.$invalid" ng-click="saveTask()">保 存</button>
                </div>
            </div>
        </div>
    </div>
    
    
    <table class="table table-hover table-condensed table-bordered" style="auto;">
        <thead>
            <tr style="height: 35px;">
                <th>任务组</th>
                <th>任务</th>
                <th>CronExpress</th>
                <th>开始时间</th>
                <th>结束时间</th>
                <th>运行状态</th>
                <th>创建时间</th>
                <th>修改时间</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody class="wait-loaded">
            <tr ng-repeat="m in list track by m.id">
                <td>{{m.jobGroup}}</td>
                <td>{{m.jobName}}</td>
                <td>{{m.cronExpress}}</td>
                <td>{{m.starRunTime}}</td>
                <td>{{m.endRunTime}}</td>
                <td>{{m._RunStatus}}</td>
                <td>{{m.createTime}}</td>
                <td>{{m.updateTime}}</td>
                <td>
                    <button class="btn btn-success" ng-click="edit(m)">编辑</button>
                    <button class="btn btn-danger" ng-click="delete(m)">删除</button>
                </td>
            </tr>
        </tbody>
    </table>
    <div class="mypager wait-loaded">
        <ul uib-pagination total-items="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="下一页"></ul>
        <div class="recordcount">共 {{search.recordcount}} 条</div>
    </div>
    @section scripts{
        <script type="text/javascript">
            $angular.add(function ($scope, $query, $timeout, $sce) {
                $scope.getHeader = function () { return ["任务组", "任务", "CronExpress", "开始时间", "结束时间", "运行状态", "创建时间", "修改时间"] };
    
    
                $scope._getCsv = function () {
                    var model = _.cloneDeep($scope.search);
                    model.pageSize = 10000000;
                    var promise = $query.post("/webapi/GetTaskList", model, function (response) {
                        var objList = angular.fromJson(response.data);
                        var getArray = [];
                        _.forEach(objList, function (item) {
                            getArray.push({
                                "jobGroup": item.jobGroup,
                                "jobName": item.jobName,
                                "cronExpress": item.cronExpress,
                                "starRunTime": item.starRunTime,
                                "endRunTime": item.endRunTime,
                                "_RunStatus": item._RunStatus,
                                "createTime": item.createTime,
                                "updateTime": item.updateTime
                            });
                        });
                        return getArray;
                    });
                    return promise;
                };
                $scope.search = { pageindex: 1, pagesize: 10, gender: "-1", order: 1, status: "-1" };
                $scope.setorder = function (index) {
                    if (index == math.abs($scope.search.order)) {
                        index = -$scope.search.order;
                    }
                    $scope.search.order = index;
                    $scope.pagechanged(true);
                };
                //查询
                $scope.pagechanged = function (reindex) {
                    if (reindex) {
                        $scope.search.pageindex = 1;
                    }
                    $query.post("/webapi/GetTaskList", $scope.search, function (response) {
                        if (response.status === 200) {
                            $scope.list = response.data;
                            $scope.search.recordcount = response.recordcount;
                        } else {
                            $alert(response.message);
                        }
                    });
                };
    
    
                $scope.pagechanged();
    
                //添加任务
                $scope.addTask = function () {
                    $("#addmodel").modal("show");
                    $scope.task = { id: -1 };
                };
                //保存
                $scope.saveTask = function () {
                    $query.post("/webapi/AddTaskAsync", $scope.task, function (response) {
                        $("#addmodel").modal("hide");
                        $scope.pagechanged();
                    });
                };
                $scope.edit = function (m) {
                    $("#addmodel").modal("show");
                    m.id = m.id;
                    $scope.task = m;
    
                }
    
                //删除类型
                $scope.delete = function (m) {
                    m.id = m.id;
                    $scope.task = m;
                    $Confirm("你确认删除吗?该操作不可恢复!", function () {
                        $query.post("/webapi/DelTaskAsync", $scope.task, function (response) {
                            $scope.pagechanged();
                        });
                    });
                }
            });
        </script>
    }
    View Code

      之后效果就出来了

      

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

      

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

      

      这里代码如下:

      

    #region 计划任务模块
            [HttpPost]
            public Result GetTaskList()
            {
                return _taskService.GetTaskList();
            }
            [HttpPost]
            public async Task<Result> 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<Result> DelTaskAsync([FromBody]TaskScheduleModel model)
            {
                return await _taskService.DelTaskAsync(model);
            }
            #endregion

      二.运行测试

      换得添加服务哦

      

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

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

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

      

      

  • 相关阅读:
    题解 P3709 【大爷的字符串题】
    题解P2730 [USACO3.2]魔板 Magic Squares
    二维凸包
    题解 P2158 [SDOI2008]仪仗队
    搜索专题——DFS A1103 Integer Factorization(30)
    数据结构专题——链表处理A1097.Deduplication on a Linked List(25) (静态链表)
    数据结构专题——链表处理A1052.Linked List Sorting(25) (静态链表)
    数据结构专题——链表处理 A1032.Sharing (静态链表)
    数据结构专题——队列的应用 A1056.Mice and Rice ( 25)
    数据结构专题 ——栈的应用 A1051.Pop Sequence(25)
  • 原文地址:https://www.cnblogs.com/gdsblog/p/10010132.html
Copyright © 2011-2022 走看看