/// <summary> /// Возвращает форму для заполнения параметров запуска отчетов, устанавливает исполнение задания /// </summary> /// <param name="jobName">Имя задания в Quartz</param> /// <param name="jobGroup">Группа задания в Quartz</param> /// <returns></returns> public ActionResult ScheduleJob(string jobName, string jobGroup) { var jext = GetJobExtend(jobName); if (jext == null) { logger.Error($"Дополнительные параметры отчета {jobName} не найдены"); ErrorMessage("Отчет не найден"); return(RedirectToAction("Index", "Report")); } if (jext.CreatorId != CurrentUser.Id && !CurrentUser.IsAdmin) { ErrorMessage("Вы можете редактировать только свои отчеты"); return(RedirectToAction("Index", "Report")); } // нашли задачу var scheduler = helper.GetScheduler(); var key = JobKey.Create(jobName, jobGroup); var job = scheduler.GetJobDetail(key); if (job == null) { logger.Error($"Отчет {jobName} не найден"); ErrorMessage("Отчет не найден"); return(RedirectToAction("Index", "Report")); } var param = (Report)job.JobDataMap["param"]; ViewBag.Title = $"Установка времени формирования для отчета \"{param.CastomName}\""; CronParam model; if (param is IInterval) { model = new CronIntervalParam(); } else { model = new CronNotIntervalParam(); } // триггер вставлялся с идентификатором задачи var oldTriggerKey = new TriggerKey(key.Name, key.Group); // используются только cron-триггеры var oldTrigger = (ICronTrigger)(scheduler.GetTrigger(oldTriggerKey)); // при GET возвращаем пустую модель для заполнения if (HttpContext.Request.HttpMethod == "GET") { //// если триггер уже был - устанавливаем UI его значением if (oldTrigger != null) { model = (CronParam)oldTrigger.JobDataMap["tparam"]; } SetViewData(model); return(View(model)); } // биндим Bind(model, model.GetType()); model.UserId = CurrentUser.Id; foreach (var error in model.Validate()) { ModelState.AddModelError(error.PropertyName, error.Message); } // если модель невалидна - возвращаем пользователю if (!ModelState.IsValid) { SetViewData(model); return(View(model)); } // новый триггер для этой задачи var trigger = TriggerBuilder.Create() .WithIdentity(key.Name, key.Group) .WithCronSchedule(model.CronExpression) .ForJob(job.Key) .WithDescription(model.CronHumanText) .Build(); trigger.JobDataMap["tparam"] = model; try { if (oldTrigger == null) { scheduler.ScheduleJob(trigger); } else { scheduler.RescheduleJob(oldTriggerKey, trigger); } } catch (Exception e) { logger.Error($"Ошибка при установке расписания отчета {key.Name}", e); ErrorMessage("Непредвиденная ошибка при установке расписания"); return(RedirectToAction("Index", "Report")); } var nextFireTimeUtc = trigger.GetNextFireTimeUtc(); var nextGen = ""; if (nextFireTimeUtc.HasValue) { nextGen = $". Время ближайшей автоматической генерации отчета {nextFireTimeUtc.Value.LocalDateTime}"; } // меняем человекочитаемое описание в доп. параметрах задачи jext.Scheduler = model.CronHumanText; DB.SaveChanges(CurrentUser, "Установка времени формирования отчета"); SuccessMessage($"Время формирования отчета успешно установлено{nextGen}"); return(RedirectToAction("Index", "Report")); }
/// <summary> /// Добавление / обновление задачи для Кварца /// </summary> /// <param name="createJobFunc"></param> /// <param name="guid"></param> /// <param name="desription"></param> /// <param name="cronExpressionInterval"></param> /// <returns>Успех действия</returns> private bool JobServiceStart(string guid, string desription, string cronExpressionInterval) { var scheduler = GetScheduler(); var key = new JobKey(guid); // group можно привязать к типу сервиса, но название типа может изменится. var job = scheduler.GetJobDetail(key); if (job == null) { job = JobBuilder.Create <TaskManagerJob>() .WithIdentity(key) .StoreDurably() .WithDescription(desription) .Build(); } try { scheduler.AddJob(job, true); } catch (Exception e) { logger.Error("Ошибка при добавлении задачи для Scheduler", e); return(false); } //job.JobDataMap["param"] = model; CronParam triggerModel = new CronIntervalParam(); ///////Оставил, т.к. будет удобно крепить к UI // триггер вставлялся с идентификатором задачи var oldTriggerKey = new TriggerKey(key.Name); // используются только cron-триггеры var oldTrigger = (ICronTrigger)(scheduler.GetTrigger(oldTriggerKey)); //// если триггер уже был - устанавливаем UI его значением if (oldTrigger != null) { triggerModel = (CronParam)oldTrigger.JobDataMap["tparam"]; } //интервал triggerModel.CronExpression = cronExpressionInterval; //triggerModel.CronHumanText = ""; // новый триггер для этой задачи var trigger = TriggerBuilder.Create() .WithIdentity(key.Name) .WithCronSchedule(triggerModel.CronExpression) .ForJob(job.Key) .WithDescription(triggerModel.CronHumanText) .Build(); trigger.JobDataMap["tparam"] = triggerModel; try { if (oldTrigger == null) { scheduler.ScheduleJob(trigger); } else { scheduler.RescheduleJob(oldTriggerKey, trigger); } } catch (Exception e) { logger.Error($"Ошибка при добавлении расписания задачи {key.Name} для Scheduler", e); return(false); } return(true); }