任务调度之持久化(基于Quartz.net)
上一篇我们了解了任务调度及他的远端管理方式,传送门:任务调度及远端管理(基于Quartz.net)
这篇我们要完成任务调度的持久化功能,即新增修改删除之类的功能,这必须得要有的,不然都不知道后台都有什么作业在跑
一、Job的CURD
1.1 、新建Job表
1 CREATE TABLE [dbo].[Job]( 2 [Id] [uniqueidentifier] NOT NULL, 3 [GroupName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 4 [JobName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 5 [TriggerName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 6 [Cron] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL, 7 [TriggerState] [varchar](50) COLLATE Chinese_PRC_CI_AS NULL, 8 [StartTime] [datetime] NULL, 9 [EndTime] [datetime] NULL, 10 [PreTime] [datetime] NULL, 11 [NextTime] [datetime] NULL, 12 [Description] [nvarchar](200) COLLATE Chinese_PRC_CI_AS NULL, 13 [CreateTime] [datetime] NULL, 14 CONSTRAINT [PK_Job] PRIMARY KEY CLUSTERED 15 ( 16 [Id] ASC 17 )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] 18 ) ON [PRIMARY] 19 20 GO
1.2、控制器还是用上一篇的HelloJobController,改一下
1 public class HelloJobController : Controller 2 { 3 private IJobApplication jobApplication; 4 5 public HelloJobController(IJobApplication jobApplication) 6 { 7 this.jobApplication = jobApplication; 8 } 9 10 [Route("Jobs/{PageIndex=1}")] 11 public ActionResult Index(string PageIndex) 12 { 13 Page page = new Page(); 14 page.PageIndex = PageIndex.ToInt(1); 15 16 var model = new JobPageViewModel(); 17 var soure = this.jobApplication.GetPage(page, t => t.CreateTime); 18 19 model.Items = Mapper.Map<List<JobViewModel>>(soure.Item2); 20 model.Total = soure.Item1; 21 model.Page = page; 22 23 return View(model); 24 } 25 26 [HttpPost] 27 [ValidateAntiForgeryToken] 28 public ActionResult Add(JobCURequest entity) 29 { 30 this.jobApplication.Add(new JobCURequest() 31 { 32 Id = Guid.NewGuid(), 33 GroupName = entity.GroupName, 34 JobName = entity.JobName, 35 TriggerName = entity.TriggerName, 36 Cron = entity.Cron, 37 TriggerState = Quartz.TriggerState.None.ToString() 38 }); 39 40 return RedirectToAction("Index"); 41 } 42 43 [HttpGet] 44 public ActionResult Delete(string id) 45 { 46 this.jobApplication.Delete(Guid.Parse(id)); 47 return RedirectToAction("Index"); 48 } 49 50 [HttpGet] 51 public ActionResult Edit(Guid id) 52 { 53 var soure = this.jobApplication.Get(id); 54 return Json(soure, JsonRequestBehavior.AllowGet); 55 } 56 57 [HttpPost] 58 [ValidateAntiForgeryToken] 59 public ActionResult Edit(JobCURequest entity) 60 { 61 this.jobApplication.Update(new JobCURequest() 62 { 63 Id = entity.Id, 64 GroupName = entity.GroupName, 65 JobName = entity.JobName, 66 TriggerName = entity.TriggerName, 67 Cron = entity.Cron, 68 TriggerState = Quartz.TriggerState.None.ToString() 69 }); 70 71 return RedirectToAction("Index"); 72 }73 }
可以看到我们新加了IJobApplication的注入,以及Index、Add、Delete、Edit(2个)5个方法
至于里边的实现就是我们上一个系列写好的功能,详细情况请点击传送门:架构设计
1.3、 视图View也要改一下
1 @model Presentation.MVC.Models.JobPageViewModel 2 @{ 3 ViewBag.Title = "Index"; 4 Layout = "~/Views/Shared/_Bootstrap.cshtml"; 5 } 6 7 <br /> 8 <div class="panel panel-default"> 9 <div class="panel-heading"> 10 <h4 class="panel-title"> 11 <a data-toggle="collapse" data-parent="#accordion" 12 href="#collapseOne" id="actionType"> 13 新增作业 14 </a> 15 </h4> 16 </div> 17 <div id="collapseOne" class="panel-collapse collapse"> 18 <div class="panel-body"> 19 @using (Html.BeginForm("Add", "HelloJob", null, FormMethod.Post, new { @id = "formHelloJob", @class = "form-horizontal", role = "form" })) 20 { 21 @Html.AntiForgeryToken() 22 23 <div class="form-group"> 24 <label for="LoginName" class="col-sm-2 control-label">群组</label> 25 <div class="col-sm-10"> 26 <input type="text" class="form-control" name="GroupName" id="GroupName" 27 placeholder="请输入群组" /> 28 </div> 29 </div> 30 <div class="form-group"> 31 <label for="Password" class="col-sm-2 control-label">作业名称</label> 32 <div class="col-sm-10"> 33 <input type="text" class="form-control" name="JobName" id="JobName" 34 placeholder="请输入作业名称" /> 35 </div> 36 </div> 37 <div class="form-group"> 38 <label for="Password" class="col-sm-2 control-label">触发器名称</label> 39 <div class="col-sm-10"> 40 <input type="text" class="form-control" name="TriggerName" id="TriggerName" 41 placeholder="请输入触发器名称" /> 42 </div> 43 </div> 44 <div class="form-group"> 45 <label for="Password" class="col-sm-2 control-label">执行计划</label> 46 <div class="col-sm-10"> 47 <input type="text" class="form-control" name="Cron" id="Cron" 48 placeholder="请输入执行计划" /> 49 </div> 50 </div> 51 <div class="form-group"> 52 <label for="Password" class="col-sm-2 control-label">描述</label> 53 <div class="col-sm-10"> 54 <input type="text" class="form-control" name="Description" id="Description" 55 placeholder="请输入描述" /> 56 </div> 57 </div> 58 <div class="form-group"> 59 <div class="col-sm-offset-2 col-sm-10"> 60 <input type="hidden" name="Id" id="Id" /> 61 <button type="submit" class="btn btn-default">提交</button> 62 </div> 63 </div> 64 } 65 </div> 66 </div> 67 </div> 68 69 <div style=" margin-bottom:5px;"> 70 <a id="btnRun" class="btn btn-default" href="#" role="button">执行</a> 71 <a id="btnPause" class="btn btn-default" href="#" role="button">暂停</a> 72 <a id="btnResume" class="btn btn-default" href="#" role="button">恢复</a> 73 74 <a id="btnEdit" class="btn btn-default" href="#" role="button" style=" margin-left:10px">修改</a> 75 <a id="btnDel" class="btn btn-default" href="#" role="button">删除</a> 76 </div> 77 <table id="list" class="table table-striped table-bordered table-hover table-condensed"> 78 <thead> 79 <tr> 80 <th><input type="checkbox" class="chkAll" /></th> 81 <th>序号</th> 82 <th>群组</th> 83 <th>作业名称</th> 84 <th>触发器名称</th> 85 <th>执行计划</th> 86 <th>描述</th> 87 <th>开始时间</th> 88 <th>结束时间</th> 89 <th>上次执行</th> 90 <th>下次执行</th> 91 <th>状态</th> 92 </tr> 93 </thead> 94 <tbody> 95 @foreach (var item in Model.Items) 96 { 97 <tr> 98 <td><input type="checkbox" name="subBox" value="@item.Id" /></td> 99 <td>@item.RowNumber</td> 100 <td>@item.GroupName</td> 101 <td>@item.JobName</td> 102 <td>@item.TriggerName</td> 103 <td>@item.Cron</td> 104 <td>@item.Description</td> 105 <td>@item.StartTime</td> 106 <td>@item.EndTime</td> 107 <td>@item.PreTime</td> 108 <td>@item.NextTime</td> 109 <td>@item.TriggerState</td> 110 </tr> 111 } 112 </tbody> 113 </table> 114 115 <ul class="pagination"> 116 <li><a href="/HelloJob/@Model.PrePage">«</a></li> 117 @for (int index = 1; index <= Model.TotalPage; index++) 118 { 119 if (Model.Page.PageIndex == index) 120 { 121 <li class="active"><a href="/HelloJob/@index">@index</a></li> 122 } 123 else 124 { 125 <li><a href="/HelloJob/@index">@index</a></li> 126 } 127 } 128 <li><a href="/HelloJob/@Model.NextPage">»</a></li> 129 </ul> 130 131 <script type="text/javascript"> 132 $(function () { 133 $(".chkAll").click(function () { 134 if (this.checked) { 135 $('input[name="subBox"]').attr("checked", this.checked); 136 } else { 137 $('input[name="subBox"]').removeAttr("checked"); 138 } 139 }); 140 141 $("#btnEdit").click(function () { 142 var id = GetChooseIds(); 143 if (id == undefined || id == null || id == "") return; 144 145 $.ajax({ 146 url: "/HelloJob/Edit/" + id, 147 type: "GET", 148 dataType: 'json', 149 success: function (result) { 150 $("#Id").val(result.Id); 151 $("#GroupName").val(result.GroupName); 152 $("#JobName").val(result.JobName); 153 $("#TriggerName").val(result.TriggerName); 154 $("#Cron").val(result.Cron); 155 $("#Description").val(result.Description); 156 157 $('#collapseOne').collapse('show'); 158 $("#formHelloJob").attr("action", "/HelloJob/Edit"); 159 $("#actionType").html("修改作业"); 160 }, 161 error: function (e) { 162 alert(e); 163 } 164 }); 165 }); 166 167 $("#btnDel").click(function () { 168 var id = GetChooseIds(); 169 if (id == undefined || id == null || id == "") return; 170 171 CreateDeleteWindow(function () { 172 location.href = "/HelloJob/Delete/" + id; 173 }); 174 }); 175 176 $("#btnRun").click(function () { 177 var id = GetChooseIds(); 178 if (id == undefined || id == null || id == "") return; 179 180 CreateRunWindow(function () { 181 location.href = "/HelloJob/Run/" + id; 182 }); 183 }); 184 185 $("#btnPause").click(function () { 186 var id = GetChooseIds(); 187 if (id == undefined || id == null || id == "") return; 188 189 CreatePauseWindow(function () { 190 location.href = "/HelloJob/Pause/" + id; 191 }); 192 }); 193 194 $("#btnResume").click(function () { 195 var id = GetChooseIds(); 196 if (id == undefined || id == null || id == "") return; 197 198 CreateResumeWindow(function () { 199 location.href = "/HelloJob/Resume/" + id; 200 }); 201 }); 202 203 function GetChooseIds() { 204 var id = ""; 205 $('input[name="subBox"]').each(function () { 206 id = $(this).attr("value"); 207 }); 208 209 return id; 210 } 211 }); 212 </script>
1.4、界面代码就完成了,我们去看看
完全没问题,下面我们来完成 执行、暂停、恢复三个操作作业的按钮功能
二、作业管理
2.1、HelloJobHelper改一下,名称我也改了(JobHelper)
2.2、HelloJobController加入上边三个功能
1 public ActionResult Run(Guid id) 2 { 3 var success = this.jobApplication.Update(new JobCURequest() 4 { 5 Id = id, 6 TriggerState = Quartz.TriggerState.Normal.ToString() 7 }); 8 9 if (success) 10 { 11 var entity = this.jobApplication.Get(id); 12 JobHelper.Run(entity); 13 } 14 15 return RedirectToAction("Index", "HelloJob"); 16 } 17 18 public ActionResult Pause(Guid id) 19 { 20 var success = this.jobApplication.Update(new JobCURequest() 21 { 22 Id = id, 23 TriggerState = Quartz.TriggerState.Paused.ToString() 24 }); 25 26 if (success) 27 { 28 29 var entity = this.jobApplication.Get(id); 30 JobHelper.Pause(entity); 31 } 32 return RedirectToAction("Index", "HelloJob"); 33 } 34 35 public ActionResult Resume(Guid id) 36 { 37 var success = this.jobApplication.Update(new JobCURequest() 38 { 39 Id = id, 40 TriggerState = Quartz.TriggerState.Normal.ToString() 41 }); 42 43 if (success) 44 { 45 var entity = this.jobApplication.Get(id); 46 JobHelper.Resume(entity); 47 } 48 49 return RedirectToAction("Index", "HelloJob"); 50 }
2.3、好了,现在开启服务端
2.4、执行
2.5、暂停
2.6、恢复
好了,基本上就是这些了