using Hh.Mes.Common.log; using Hh.Mes.Common.Request; using Hh.Mes.POJO.Entity; using Hh.Mes.POJO.Response; using Hh.Mes.Service; using Hh.Mes.Service.Configure; using Hh.Mes.Service.SystemAuth; using Hh.Mes.Service.WebService.Job; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json.Linq; using Org.BouncyCastle.Crypto; using Quartz; using Quartz.Job.Jobs; using Quartz.Spi; using System; using System.Collections.Generic; using System.Reflection; using WebMvc.Aop; namespace WebMvc { /// <summary> /// 定时任务调度表 /// </summary> [Area("job")] public class SysJobController : BaseController { private readonly IScheduler _sched; private readonly JobService service; public SysJobController(IAuth authUtil, JobService service, IScheduler sched) : base(authUtil) { this.service = service; this.service.sysWebUser = authUtil.GetCurrentUser().User; _sched = sched; } #region 视图功能 /// <summary> /// 默认视图Action /// </summary> /// <returns></returns> [Authenticate] [ServiceFilter(typeof(OperLogFilter))] public ActionResult Index() { return View(); } public ActionResult cron() { return View(); } #endregion #region 获取数据 /// <summary> /// 加载及分页查询 /// </summary> /// <param name="pageRequest">表单请求信息</param> /// <param name="entity">请求条件实例</param> /// <returns></returns> [HttpPost] public string Load(PageReq pageRequest, sys_job entity) { return Serialize(service.Load(pageRequest, entity)); } #endregion #region 提交数据 /// <summary> /// 新增数据 /// </summary> /// <param name="entity">新增实例</param> /// <returns></returns> [HttpPost] [ServiceFilter(typeof(OperLogFilter))] public string Ins(sys_job entity) { try { if (string.IsNullOrEmpty(entity.methodParams)) throw new Exception("参数不能为空!"); if (string.IsNullOrEmpty(entity.cronExpression)) throw new Exception("cron表达式不能为空!"); var isExist=service.Context.Queryable<sys_job>().Any(x=>x.methodName == entity.methodName); if (isExist) throw new Exception($"只允许插入一条任务方法为【{entity.methodName}】相关的定时器任务!"); if (entity.status == null) entity.status = "0"; if (entity.status == "0") { var cronExpression = new CronExpression(entity.cronExpression); entity.lastFireTime = DateTime.Now; entity.nextFireTime = cronExpression.GetNextValidTimeAfter(DateTime.Now).Value.ToLocalTime().DateTime; } entity.jobGroup = entity.jobName; AddJob(entity); service.Ins(entity); } catch (Exception ex) { Result.Code = 500; Result.Status = false; Result.Message = ex.Message; } return Serialize(Result); } /// <summary> /// 修改数据 /// </summary> /// <param name="entity">修改实例</param> /// <returns></returns> [HttpPost] [ServiceFilter(typeof(OperLogFilter))] public string Upd(sys_job entity) { try { if (string.IsNullOrEmpty(entity.methodParams)) throw new Exception("参数不能为空!"); if (string.IsNullOrEmpty(entity.cronExpression)) throw new Exception("cron表达式不能为空!"); if (entity.status == "0") { var cronExpression = new CronExpression(entity.cronExpression); entity.lastFireTime = DateTime.Now; entity.nextFireTime = cronExpression.GetNextValidTimeAfter(DateTime.Now).Value.ToLocalTime().DateTime; } if (entity.status == "0") { UpdateJob(entity); } service.Upd(entity); } catch (Exception ex) { Result.Code = 500; Result.Status = false; Result.Message = ex.Message; } return Serialize(Result); } /// <summary> /// 暂停计划/启用计划 /// </summary> /// <param name="entity">暂停计划/启用计划</param> /// <returns></returns> [HttpPost] [ServiceFilter(typeof(OperLogFilter))] public string PauseOrResume(sys_job entity) { try { if (entity.status == "0") { entity.status = "1"; Upd(entity); _sched.PauseJob(new JobKey(entity.jobName)); // DeleteJob(entity); } else { entity.status = "0"; Upd(entity); _sched.ResumeJob(new JobKey(entity.jobName)); // AddJob(entity); } } catch (Exception ex) { Result.Code = 500; Result.Status = false; Result.Message = ex.Message; } return Serialize(Result); } [HttpPost] [ServiceFilter(typeof(OperLogFilter))] public string DelByIds(int[] ids) { try { foreach (var item in ids) { var entity = service.Context.Queryable<sys_job>().First(u => u.id == item); service.DelByIds(item); DeleteJob(entity); } } catch (Exception ex) { Result.Code = 500; Result.Status = false; Result.Message = ex.Message; } return Serialize(Result); } /// <summary> /// 初始化定时器 /// </summary> /// <returns></returns> [HttpGet] [ServiceFilter(typeof(OperLogFilter))] public string ClearQrtz() { try { service.Context.Deleteable<qrtz_blob_triggers>().ExecuteCommand(); service.Context.Deleteable<qrtz_calendars>().ExecuteCommand(); service.Context.Deleteable<qrtz_cron_triggers>().ExecuteCommand(); service.Context.Deleteable<qrtz_fired_triggers>().ExecuteCommand(); service.Context.Deleteable<qrtz_job_details>().ExecuteCommand(); service.Context.Deleteable<qrtz_locks>().ExecuteCommand(); service.Context.Deleteable<qrtz_paused_trigger_grps>().ExecuteCommand(); service.Context.Deleteable<qrtz_scheduler_state>().ExecuteCommand(); service.Context.Deleteable<qrtz_simple_triggers>().ExecuteCommand(); service.Context.Deleteable<qrtz_simprop_triggers>().ExecuteCommand(); service.Context.Deleteable<qrtz_triggers>().ExecuteCommand(); } catch(Exception ex) { Result.Code = 500; Result.Status=false; Result.Message = ex.Message; } return Serialize(Result); } #endregion #region 获取任务在未来周期内哪些时间会运行 [HttpGet] public string GetTaskeFireTime(string cronExpression) { var response = new Response(); return ExceptionsHelp.Instance.ExecuteT(() => { if (string.IsNullOrEmpty(cronExpression)||cronExpression== "? * * * * ? ") { response.ResponseError("请选择正确的Cron表达式"); return Serialize(response); } //运行次数 var numTimes = 10; //时间表达式 ITrigger trigger = TriggerBuilder.Create().WithCronSchedule(cronExpression).Build(); var dates = TriggerUtils.ComputeFireTimes(trigger as IOperableTrigger, null, numTimes); List<string> list = new List<string>(); foreach (DateTimeOffset dtf in dates) { list.Add(TimeZoneInfo.ConvertTimeFromUtc(dtf.DateTime, TimeZoneInfo.Local).ToString()); } response.Result = list; return Serialize(response); }); } #endregion #region 自定义方法 #region 增加计划 private void AddJob(sys_job entity) { try { #region 创建任务 var methodParams = entity.methodParams; var methodName = entity.methodName ?? ""; var jobDataMap = new JobDataMap(); var json = JObject.Parse(methodParams); if (json.Count > 0) { foreach (var item in json) { jobDataMap.Add(item.Key, item.Value.ToString()); } } //https://bbs.csdn.net/topics/390236961 不在同一个解决方案下的不同项目之间操作,classname这个命名空间+类名怎么写 var classType = Assembly.Load(typeof(JobBase).Assembly.FullName).GetType($"{typeof(JobBase).Namespace}.{methodName}"); IJobDetail job = JobBuilder.Create(classType).WithIdentity(entity.jobName).UsingJobData(jobDataMap).Build(); #endregion #region 旧代码 //if (methodName.ToLower().Equals("ClearLogJob".ToLower())) //{ // job = JobBuilder.Create<ClearLogJob>().WithIdentity(entity.JobName).UsingJobData(jobDataMap).Build(); //} //else if (methodName.ToLower().Equals("GetCurrentStockJob".ToLower())) //{ // job = JobBuilder.Create<GetCurrentStockJob>().WithIdentity(entity.JobName).UsingJobData(jobDataMap).Build(); //} #endregion if (job != null) { //创建一个触发器 var trigger = TriggerBuilder.Create().WithIdentity(entity.jobName).WithCronSchedule(entity.cronExpression).Build(); //将触发器和任务器绑定到调度器中 _sched.ScheduleJob(job, trigger).Wait(); } } catch (Exception e) { throw new Exception("请确认定时器命名空间【Program 配置和quartzJobNameSpaceTypeName】是否一致" + e); } } #endregion #region 删除计划 private void DeleteJob(sys_job entity) { _sched.PauseTrigger(new TriggerKey(entity.jobName)).Wait(); _sched.UnscheduleJob(new TriggerKey(entity.jobName)).Wait(); _sched.DeleteJob(new JobKey(entity.jobName)).Wait(); } #endregion #region 修改计划 private void UpdateJob(sys_job entity) { DeleteJob(entity); AddJob(entity); } #endregion #endregion } }