diff --git a/Quartz.NET.Web/Extensions/QuartzNETExtension.cs b/Quartz.NET.Web/Extensions/QuartzNETExtension.cs index bc5674f221a60b45a56e36ca886078108e81a879..b4e3aabf2956978150bcc4f6c48e03dcd649034d 100644 --- a/Quartz.NET.Web/Extensions/QuartzNETExtension.cs +++ b/Quartz.NET.Web/Extensions/QuartzNETExtension.cs @@ -107,6 +107,7 @@ namespace Quartz.NET.Web.Extensions list.Add(taskOptions); } } + list = list.OrderBy(o=>o.Id).ToList(); } catch (Exception ex) { @@ -318,7 +319,7 @@ namespace Quartz.NET.Web.Extensions errorMsg = $"未找到分组[{groupName}]"; return new { status = false, msg = errorMsg }; } - JobKey jobKey = jobKeys.Where(s => scheduler.GetTriggersOfJob(s).Result.Any(x => (x as CronTriggerImpl).Name == taskName)).FirstOrDefault(); + JobKey jobKey = jobKeys.Where(s => scheduler.GetTriggersOfJob(s).Result.Any(x => (x as CronTriggerImpl)?.Name == taskName)).FirstOrDefault(); if (jobKey == null) { errorMsg = $"未找到触发器[{taskName}]"; diff --git a/Quartz.NET.Web/Models/TaskOptions.cs b/Quartz.NET.Web/Models/TaskOptions.cs index 692b2cdedf4e6e143a123899987ffbed9ea8a842..6e9756978d02acd6ebd9cc090f57abf4f8934984 100644 --- a/Quartz.NET.Web/Models/TaskOptions.cs +++ b/Quartz.NET.Web/Models/TaskOptions.cs @@ -4,6 +4,7 @@ namespace Quartz.NET.Web.Models { public class TaskOptions { + public int Id { get; set; } public string TaskName { get; set; } public string GroupName { get; set; } public string Interval { get; set; } diff --git a/Quartz.NET.Web/Utility/FileHelper.cs b/Quartz.NET.Web/Utility/FileHelper.cs index 1af2685f31a33046b70922408d16c9d3fe849b0b..e27c5f732f4d90ced32e35fe6e2ccddb7593b625 100644 --- a/Quartz.NET.Web/Utility/FileHelper.cs +++ b/Quartz.NET.Web/Utility/FileHelper.cs @@ -95,7 +95,7 @@ namespace Quartz.NET.Web.Utility { Directory.CreateDirectory(path); } - using (FileStream stream = File.Open(path + fileName, FileMode.OpenOrCreate, FileAccess.Write)) + using (FileStream stream = File.Open(path + fileName, FileMode.OpenOrCreate, FileAccess.Write,FileShare.ReadWrite)) { byte[] by = Encoding.Default.GetBytes(content); if (appendToLast) diff --git a/Quartz.NET.Web/Utility/FileQuartz.cs b/Quartz.NET.Web/Utility/FileQuartz.cs index 88905e4f577b4038ee6b3f105291827de3b271f4..50db3051d4956fe952d35ad6f043f8eba19643cf 100644 --- a/Quartz.NET.Web/Utility/FileQuartz.cs +++ b/Quartz.NET.Web/Utility/FileQuartz.cs @@ -70,7 +70,8 @@ namespace Quartz.NET.Web.Utility continue; if (arr.Length != 3) { - list.Add(new TaskLog() { Msg = item }); + //list.Add(new TaskLog() { Msg = item }); + list.Add(new TaskLog() { BeginDate = arr[0], EndDate = arr[1], Msg = String.Join('_', arr[^2..]) });//针对返回消息包含"_"的消息 continue; } list.Add(new TaskLog() { BeginDate = arr[0], EndDate = arr[1], Msg = arr[2] }); diff --git a/Quartz.NET.Web/Utility/HttpManager.cs b/Quartz.NET.Web/Utility/HttpManager.cs index be274c2769f02542df3e460b81a605d3d42772d3..6457865d64b6a5d6db768a1d61c86484ad2fa8c8 100644 --- a/Quartz.NET.Web/Utility/HttpManager.cs +++ b/Quartz.NET.Web/Utility/HttpManager.cs @@ -44,6 +44,7 @@ namespace Quartz.NET.Web.Utility { var client = httpClientFactory.CreateClient(); + client.Timeout = TimeSpan.FromSeconds(40 * 60); var content = new StringContent(""); // content.Headers.ContentType = new MediaTypeHeaderValue(contentType); var request = new HttpRequestMessage(method, url) diff --git a/Quartz.NET.Web/Views/TaskBackGround/Index.cshtml b/Quartz.NET.Web/Views/TaskBackGround/Index.cshtml index 89aaa1f158fcbee10055b3923ffb0d231410799f..db04f1aefddc18722c66b12007be9af988129bfd 100644 --- a/Quartz.NET.Web/Views/TaskBackGround/Index.cshtml +++ b/Quartz.NET.Web/Views/TaskBackGround/Index.cshtml @@ -59,11 +59,11 @@ 暂停任务 开启任务 立即执行 - 修改任务 - 删除任务 + @*修改任务*@ + 删除任务 刷新数据 - + diff --git a/Quartz.NET.Web/wwwroot/js/task-index.js b/Quartz.NET.Web/wwwroot/js/task-index.js index bfb77233a62bf532bfe4a383fb24f449888a9f9e..0e2172221d198accc78ae7235a4b6dfd99eb6267 100644 --- a/Quartz.NET.Web/wwwroot/js/task-index.js +++ b/Quartz.NET.Web/wwwroot/js/task-index.js @@ -28,7 +28,7 @@ var $taskVue = new Vue({ modelMessage: '任务管理', activedIndex: 0, taskValidate: { - taskName: '', groupName: '', interval: '', apiUrl: '', authKey: '', authValue: + id: '', taskName: '', groupName: '', interval: '', apiUrl: '', authKey: '', authValue: '', describe: '', requestType: '' }, ruleValidate: { @@ -58,15 +58,24 @@ var $taskVue = new Vue({ key: 'id', width: 120 }, + { + title: '序号', + key: 'id', + width: 70, + align: 'center', + fixed: 'left' + }, { type: 'selection', width: 60, - align: 'center' + align: 'center', + fixed: 'left' }, { title: '作业名称', key: 'taskName', - width: 150 + width: 150, + fixed: 'left' }, { title: '分组', key: 'groupName', @@ -135,7 +144,7 @@ var $taskVue = new Vue({ { title: '描述', key: 'describe', - minWidth: 200 + minWidth: 180 }, { title: 'ApiUrl', @@ -150,23 +159,92 @@ var $taskVue = new Vue({ { title: '操作', key: 'operat', - width: 100, + width: 580, render: (h, params) => { - var style = { 'font-size': '12px' }; + var style = { 'font-size': '12px', 'marginRight': '5px' }; return h('div', [ h('i-button', { props: { //type: 'error', size: 'small' - }, style: style, on: { click: function () { $taskVue.getJobRunLog(params); + console.log(params); + } + } + }, '执行记录'), + h('i-button', { + props: { + type: 'success', + size: 'small', + icon: 'ios-power' + }, style: style, + on: { + click: function () { + $taskVue.tiggerActionLine('pause', params.row); + } + } + }, '暂停任务'), + h('i-button', { + props: { + type: 'warning', + size: 'small', + icon: 'md-arrow-dropright' + }, style: style, + on: { + click: function () { + $taskVue.tiggerActionLine('start', params.row); + } + } + }, '开启任务'), + h('i-button', { + props: { + type: 'primary', + size: 'small', + icon: 'md-open' + }, style: style, + on: { + click: function () { + $taskVue.tiggerActionLine('run', params.row); + } + } + }, '立即执行'), + h('i-button', { + props: { + type: 'error', + size: 'small', + icon: 'md-construct' + }, style: style, + on: { + click: function () { + $taskVue.updateLine(params.row); + } + } + }, '修改任务'), + h('i-button', { + props: { + //type: 'primary', + size: 'small', + icon: 'md-close' + }, style: style, + on: { + click: function () { + $taskVue.$Modal.confirm({ + title: 'Title', + content: '

删除确认

', + onOk: () => { + $taskVue.tiggerActionLine('remove', params.row); + }, + onCancel: () => { + $taskVue.$Message.info('取消操作'); + } + }); } } - }, '执行记录') + }, '删除任务') ]); } } @@ -188,11 +266,10 @@ var $taskVue = new Vue({ return columns; }, selectRow: function (selection, row) { - if (row) { - this.select.currentRow = row; - } else if (selection && selection.length) { - this.select.currentRow = selection[0]; - } + this.select.currentRow = row; + this.select.rows = selection; + }, + selectChange: function (selection) { this.select.rows = selection; }, first: function () { @@ -249,11 +326,36 @@ var $taskVue = new Vue({ this.setFormClass(false); this.model = true; }, + //批量操作 tiggerAction: function (action) { - if (!this.select.rows.length) + if (!this.select.rows.length) { return $taskVue.$Message.success('请选择作业!'); + } + this.ajaxAll('/TaskBackGround/' + action, this.select.rows); + }, + //批量删除 + tiggerActionRemove: function (action) { + if (!this.select.rows.length) { + return $taskVue.$Message.success('请选择作业!'); + } + $taskVue.$Modal.confirm({ + title: 'Title', + content: '

删除确认

', + onOk: () => { + this.ajaxAll('/TaskBackGround/' + action, this.select.rows); + }, + onCancel: () => { + $taskVue.$Message.info('取消操作'); + } + }); + }, + //行内操作 + tiggerActionLine: function (action, row) { + if (!row) { + return $taskVue.$Message.success('请选择作业!'); + } this.ajax('/TaskBackGround/' + action, - this.select.rows[0], function (data) { + row, function (data) { if (data.status) { $taskVue.refresh(true); } @@ -272,6 +374,31 @@ var $taskVue = new Vue({ this.setFormClass(true); //this.taskForm[0] }, + //多行编辑(未改造完成) + updateMulti: function () { + // this.tiggerAction('update'); + if (!this.select.rows.length) + return $taskVue.$Message.success('请选择作业!'); + this.model = true; + //this.taskValidate = this.select.rows.slice(0, 1)[0]; + for (var key in this.select.rows[0]) { + this.taskValidate[key] = this.select.rows[0][key]; + } + this.setFormClass(true); + //this.taskForm[0] + }, + //行内编辑 + updateLine: function (row) { + if (!row) + return $taskVue.$Message.success('请选择作业!'); + this.model = true; + //this.taskValidate = this.select.rows.slice(0, 1)[0]; + for (var key in row) { + this.taskValidate[key] = row[key]; + } + this.setFormClass(true); + //this.taskForm[0] + }, refresh: function (_init) { this.select.currentRow = []; this.select.rows = {}; @@ -293,6 +420,7 @@ var $taskVue = new Vue({ if (!valid) { return this.$Message.error('数据填写不完整!'); } + this.taskValidate.id = this.rows.length; this.ajax("/TaskBackGround/" + (this.isAdd ? 'add' : 'update'), this.taskValidate, function (data) { $taskVue.$Message.success(data.msg || '保存成功'); if (data.status) { @@ -327,6 +455,33 @@ var $taskVue = new Vue({ $taskVue.$Message.success('出错啦!'); console.log(error); }); + }, + ajaxAll: function (url, params) { + let Axioses = []; + params.forEach(param => { + Axioses.push( + axios({ + method: 'post', + url: url, + params: param, + headers: { 'X-Requested-With': 'XMLHttpRequest' }, + timeout: 40 * 60 * 1000 + }) + ); + }); + axios.all(Axioses) + .then(axios.spread((...result) => { + let results = [...result]; + $taskVue.refresh(true); + results.forEach(item => $taskVue.$Message.success(item.data.msg)) + })) + .catch(function (error) { + if (error.response.status === 401) { + return window.location.href = '/home/index'; + } + $taskVue.$Message.success('出错啦!'); + console.log(error); + }); } }, created: function () { this.refresh(true);