|
@@ -0,0 +1,343 @@
|
|
|
+package com.jiayue.ipfcst.common.data.service;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import com.jiayue.ipfcst.common.core.exception.BusinessException;
|
|
|
+import com.jiayue.ipfcst.common.core.util.NumberUtils;
|
|
|
+import com.jiayue.ipfcst.common.data.entity.ElectricField;
|
|
|
+import com.jiayue.ipfcst.common.data.entity.OverhaulPlan;
|
|
|
+import com.jiayue.ipfcst.common.data.entity.SysParameter;
|
|
|
+import com.jiayue.ipfcst.common.data.job.BaseJob;
|
|
|
+import com.jiayue.ipfcst.common.data.repository.ElectricFieldRepository;
|
|
|
+import com.jiayue.ipfcst.common.data.repository.OverhaulPlanRepository;
|
|
|
+import com.jiayue.ipfcst.common.data.repository.SysParameterRepository;
|
|
|
+import com.sun.istack.internal.NotNull;
|
|
|
+import lombok.NonNull;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.quartz.*;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
|
|
|
+import org.springframework.scheduling.quartz.JobDetailFactoryBean;
|
|
|
+import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Propagation;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 业务基础类
|
|
|
+ *
|
|
|
+ * @author zzy
|
|
|
+ * @version 1.0
|
|
|
+ * @since 2019/8/5 16:02
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class BaseService {
|
|
|
+
|
|
|
+ private SysParameterRepository sysParameterRepository;
|
|
|
+
|
|
|
+ private ElectricFieldRepository electricFieldRepository;
|
|
|
+
|
|
|
+ private OverhaulPlanRepository overhaulPlanRepository;
|
|
|
+
|
|
|
+ private Scheduler scheduler;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setOverhaulPlanRepository(OverhaulPlanRepository overhaulPlanRepository) {
|
|
|
+ this.overhaulPlanRepository = overhaulPlanRepository;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setElectricFieldRepository(ElectricFieldRepository electricFieldRepository) {
|
|
|
+ this.electricFieldRepository = electricFieldRepository;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setSysParameterRepository(SysParameterRepository sysParameterRepository) {
|
|
|
+ this.sysParameterRepository = sysParameterRepository;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ public void setScheduler(Scheduler scheduler) {
|
|
|
+ this.scheduler = scheduler;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取系统参数
|
|
|
+ * bzy 2020.04.13修改添加参数defaultValue,查询不到返回默认值。
|
|
|
+ *
|
|
|
+ * @param key 参数标识
|
|
|
+ * @return 参数值
|
|
|
+ */
|
|
|
+ @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
|
|
|
+ public String getSysParameter(String key,
|
|
|
+ String defaultValue,String stationCode) {
|
|
|
+ Optional<SysParameter> optional = sysParameterRepository.findBySysKeyAndStationCode(key,stationCode);
|
|
|
+ return optional.map(SysParameter::getSysValue).orElse(defaultValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询场站信息
|
|
|
+ *
|
|
|
+ * @return 场站信息
|
|
|
+ */
|
|
|
+ @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
|
|
|
+ public ElectricField getSingleStation(String stationCode) throws BusinessException {
|
|
|
+ Optional<ElectricField> electricFieldOptional = Optional.ofNullable(this.electricFieldRepository.getOne(stationCode));
|
|
|
+ if (electricFieldOptional.isPresent()) {
|
|
|
+ return electricFieldOptional.get();
|
|
|
+ } else {
|
|
|
+ log.error("场站信息未维护!!!");
|
|
|
+ throw new BusinessException("场站信息未维护!!!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询开机容量
|
|
|
+ *
|
|
|
+ * @param startTime 开始时间
|
|
|
+ * @param endTime 结束时间
|
|
|
+ * @return 开始时间-结束时间段内,以开始时间作为第一个时刻标记时间,15分为一个时刻长度,返回开机容量Map集合 key为对应时刻标记时间
|
|
|
+ */
|
|
|
+ public Map<Long, BigDecimal> queryOpenCapacity(Long startTime, Long endTime, BigDecimal capacity,String stationCode) throws BusinessException {
|
|
|
+ // 查询检修计划
|
|
|
+ List<OverhaulPlan> overhaulPlans = this.overhaulPlanRepository.findByEndTimeGreaterThanEqualAndStartTimeLessThanEqualAndStatusAndStationCode(startTime, endTime,1,stationCode);
|
|
|
+
|
|
|
+ Map<Long, BigDecimal> resultMap = new HashMap<>();
|
|
|
+ BigDecimal openCapacity;
|
|
|
+ Date tempTime = new Date(startTime);
|
|
|
+ while (!tempTime.after(new Date(endTime))) {
|
|
|
+ resultMap.put(tempTime.getTime(), capacity);
|
|
|
+ for (OverhaulPlan overhaulPlan : overhaulPlans) {
|
|
|
+ // 当查询时间在检修时间范围内,修正开机容量
|
|
|
+ Date oStartTime = new Date(overhaulPlan.getStartTime());
|
|
|
+ Date oEndTime1 = new Date(overhaulPlan.getEndTime());
|
|
|
+ if (!tempTime.before(oStartTime) && !tempTime.after(oEndTime1)) {
|
|
|
+ openCapacity = NumberUtils.subtract(capacity, overhaulPlan.getOverhaulCapactity(), 2);
|
|
|
+ // 当同一时间段有多条检修纪录时,取检修容量最大值也就是开机容量最小值
|
|
|
+ if (resultMap.get(tempTime.getTime()).compareTo(openCapacity) > 0) {
|
|
|
+ resultMap.put(tempTime.getTime(), openCapacity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tempTime = DateUtil.offsetMinute(tempTime, 15);
|
|
|
+ }
|
|
|
+ return resultMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建或更新定时任务
|
|
|
+ *
|
|
|
+ * @param t 定时任务执行类
|
|
|
+ * @param jobCode 任务标识(每个人任务标识为一)
|
|
|
+ * @param jobRunStartTime 任务执行开始时间,单位:毫秒
|
|
|
+ * @param jobRunRepeatInterval 任务重复执行间隔时间,单位:毫秒
|
|
|
+ * @param paramMap 任务参数
|
|
|
+ * @param <T> 定时任务执行类必须继承BaseJob
|
|
|
+ * @throws SchedulerException 任务创建或更新异常
|
|
|
+ * @throws ParseException cron表达式异常
|
|
|
+ */
|
|
|
+ public <T extends BaseJob> void scheduleJob(@NotNull Class<T> t, @NotNull final String jobCode,
|
|
|
+ @NotNull final Long jobRunStartTime, @NotNull final Long jobRunRepeatInterval,
|
|
|
+ final Map<String, Object> paramMap) throws SchedulerException, ParseException {
|
|
|
+ // 获取触发器
|
|
|
+ SimpleTrigger simpleTrigger = this.getSimpleTrigger(jobCode, jobRunStartTime, jobRunRepeatInterval, paramMap);
|
|
|
+ // 安排任务
|
|
|
+ this.scheduleJob(t, simpleTrigger, jobCode);
|
|
|
+ this.resumeJob(jobCode);// 启动任务
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建或更新定时任务
|
|
|
+ *
|
|
|
+ * @param t 定时任务执行类
|
|
|
+ * @param jobCode 任务标识(每个人任务标识为一)
|
|
|
+ * @param jobRunStartTime 任务执行开始时间,单位:毫秒
|
|
|
+ * @param cronExpression 任务执行策略
|
|
|
+ * @param paramMap 任务参数
|
|
|
+ * @param <T> 定时任务执行类必须继承BaseJob
|
|
|
+ * @throws SchedulerException 任务创建或更新异常
|
|
|
+ * @throws ParseException cron表达式异常
|
|
|
+ */
|
|
|
+ public <T extends BaseJob> void scheduleJob(@NotNull Class<T> t, @NotNull final String jobCode,
|
|
|
+ @NotNull final Long jobRunStartTime, @NotNull final String cronExpression, final Map<String, Object> paramMap)
|
|
|
+ throws SchedulerException, ParseException {
|
|
|
+ // 获取触发器
|
|
|
+ CronTrigger cronTrigger = this.getCronTrigger(jobCode, jobRunStartTime, cronExpression, paramMap);
|
|
|
+ // 安排任务
|
|
|
+ this.scheduleJob(t, cronTrigger, jobCode);
|
|
|
+ this.resumeJob(jobCode);// 启动任务
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 安排定时任务
|
|
|
+ *
|
|
|
+ * @param t 定时任务执行类
|
|
|
+ * @param e 定时器
|
|
|
+ * @param jobCode 任务标识
|
|
|
+ * @param <T> 定时器实现类
|
|
|
+ * @param <E> 触发器实现类
|
|
|
+ * @throws SchedulerException 安排定时任务异常
|
|
|
+ * @throws ParseException cron表达式异常
|
|
|
+ */
|
|
|
+ public <T extends BaseJob, E extends Trigger> void scheduleJob(@NotNull Class<T> t, @NonNull E e,
|
|
|
+ @NotNull final String jobCode) throws SchedulerException, ParseException {
|
|
|
+ // 如果触发器已存在,则重新安排该任务,否则将创建新的任务安排
|
|
|
+ if (scheduler.checkExists(e.getKey())) {
|
|
|
+ scheduler.rescheduleJob(e.getKey(), e);
|
|
|
+ } else {
|
|
|
+ JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
|
|
|
+ jobDetailFactoryBean.setJobClass(t);
|
|
|
+ jobDetailFactoryBean.setName(jobCode);
|
|
|
+ jobDetailFactoryBean.afterPropertiesSet();
|
|
|
+ JobDetail jobDetail = jobDetailFactoryBean.getObject();
|
|
|
+ scheduler.scheduleJob(jobDetail, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除任务
|
|
|
+ *
|
|
|
+ * @param jobCode 任务标识
|
|
|
+ * @throws SchedulerException 任务删除异常
|
|
|
+ */
|
|
|
+ public void deleteJob(@NotNull final String jobCode) throws SchedulerException {
|
|
|
+ JobKey jobKey = JobKey.jobKey(jobCode);
|
|
|
+ // 如果任务存在,则删除
|
|
|
+ if (scheduler.checkExists(jobKey))
|
|
|
+ scheduler.deleteJob(jobKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 暂停任务
|
|
|
+ *
|
|
|
+ * @param jobCode 任务标识
|
|
|
+ * @throws SchedulerException 任务暂停异常
|
|
|
+ */
|
|
|
+ public void pauseJob(@NotNull final String jobCode) throws SchedulerException {
|
|
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(jobCode);
|
|
|
+ if (scheduler.checkExists(triggerKey))
|
|
|
+ scheduler.pauseTrigger(triggerKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重启任务
|
|
|
+ *
|
|
|
+ * @param jobCode 任务标识
|
|
|
+ * @throws SchedulerException 任务重启异常
|
|
|
+ */
|
|
|
+ public void resumeJob(@NotNull final String jobCode) throws SchedulerException {
|
|
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(jobCode);
|
|
|
+ if (scheduler.checkExists(triggerKey))
|
|
|
+ scheduler.resumeTrigger(triggerKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取触发器
|
|
|
+ *
|
|
|
+ * @param jobCode 触发器标识
|
|
|
+ * @param jobRunStartTime 开始执行时间, 单位:毫秒
|
|
|
+ * @param jobRunRepeatInterval 重复执行间隔, 单位:毫秒
|
|
|
+ * @param paramMap 触发器参数
|
|
|
+ * @return 触发器
|
|
|
+ * @throws SchedulerException 获取触发器异常
|
|
|
+ */
|
|
|
+ private SimpleTrigger getSimpleTrigger(@NotNull final String jobCode, @NotNull final Long jobRunStartTime,
|
|
|
+ @NotNull final Long jobRunRepeatInterval, final Map<String, Object> paramMap) throws SchedulerException {
|
|
|
+ SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean();
|
|
|
+ if (paramMap != null)
|
|
|
+ simpleTriggerFactoryBean.setJobDataAsMap(paramMap);// 设置任务执行参数
|
|
|
+ simpleTriggerFactoryBean.setStartTime(new Date(jobRunStartTime));// 开始执行时间
|
|
|
+ simpleTriggerFactoryBean.setRepeatInterval(jobRunRepeatInterval);//重复执行间隔时间 单位毫秒
|
|
|
+ simpleTriggerFactoryBean.setName(jobCode);
|
|
|
+ simpleTriggerFactoryBean.setMisfireInstruction(
|
|
|
+ SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);// 定时任务失火后,将忽略未执行任务,继续下一次任务
|
|
|
+ simpleTriggerFactoryBean.afterPropertiesSet();
|
|
|
+ return simpleTriggerFactoryBean.getObject();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取触发器
|
|
|
+ *
|
|
|
+ * @param jobCode 触发器标识
|
|
|
+ * @param jobRunStartTime 开始执行时间,单位:毫秒
|
|
|
+ * @param cronExpression 执行策略表达式
|
|
|
+ * @param paramMap 触发器参数
|
|
|
+ * @return 触发器
|
|
|
+ * @throws SchedulerException 获取触发器异常
|
|
|
+ * @throws ParseException 执行策略表达式异常
|
|
|
+ */
|
|
|
+ private CronTrigger getCronTrigger(@NotNull final String jobCode, @NotNull final Long jobRunStartTime,
|
|
|
+ @NotNull final String cronExpression, final Map<String, Object> paramMap)
|
|
|
+ throws SchedulerException, ParseException {
|
|
|
+ CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
|
|
|
+ if (paramMap != null)
|
|
|
+ cronTriggerFactoryBean.setJobDataAsMap(paramMap);// 设置任务执行参数
|
|
|
+ cronTriggerFactoryBean.setStartTime(new Date(jobRunStartTime));// 开始执行时间
|
|
|
+ cronTriggerFactoryBean.setCronExpression(cronExpression);// 执行策略
|
|
|
+ cronTriggerFactoryBean.setName(jobCode);
|
|
|
+ cronTriggerFactoryBean
|
|
|
+ .setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);// 定时任务失火后,目前不执行,然后就按照正常的计划执行。
|
|
|
+ cronTriggerFactoryBean.afterPropertiesSet();
|
|
|
+ return cronTriggerFactoryBean.getObject();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取任务最后执行时间
|
|
|
+ *
|
|
|
+ * @param jobCode 任务标识
|
|
|
+ * @return 任务最后执行时间
|
|
|
+ * @throws SchedulerException 获取任务最后执行时间异常
|
|
|
+ */
|
|
|
+ public Date getJobPreviousFireTime(@NotNull final String jobCode) throws SchedulerException {
|
|
|
+ TriggerKey triggerKey = new TriggerKey(jobCode);
|
|
|
+ Trigger trigger = this.scheduler.getTrigger(triggerKey);
|
|
|
+ if (trigger == null)
|
|
|
+ throw new SchedulerException(jobCode + "任务不存在!");
|
|
|
+ return trigger.getPreviousFireTime();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取任务下次执行时间
|
|
|
+ *
|
|
|
+ * @param jobCode 任务标识
|
|
|
+ * @return 任务下次执行时间
|
|
|
+ * @throws SchedulerException 获取任务下次执行时间异常
|
|
|
+ */
|
|
|
+ Date getJobNextFireTime(@NotNull final String jobCode) throws SchedulerException {
|
|
|
+ TriggerKey triggerKey = new TriggerKey(jobCode);
|
|
|
+ Trigger trigger = this.scheduler.getTrigger(triggerKey);
|
|
|
+ if (trigger == null)
|
|
|
+ throw new SchedulerException(jobCode + "任务不存在!");
|
|
|
+ return trigger.getNextFireTime();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取任务状态
|
|
|
+ *
|
|
|
+ * @param jobCode 任务标识
|
|
|
+ * @return 任务状态,中文描述
|
|
|
+ * @throws SchedulerException 获取任务状态异常
|
|
|
+ */
|
|
|
+ public String getJobStatus(@NotNull final String jobCode) throws SchedulerException {
|
|
|
+ TriggerKey triggerKey = new TriggerKey(jobCode);
|
|
|
+ String triggerStateName = this.scheduler.getTriggerState(triggerKey).name();
|
|
|
+ if ("NONE".equals(triggerStateName)) {// 不存在
|
|
|
+ return "不存在";
|
|
|
+ } else if ("NORMAL".equals(triggerStateName)) {// 正常
|
|
|
+ return "正常";
|
|
|
+ } else if ("PAUSED".equals(triggerStateName)) {// 暂停
|
|
|
+ return "暂停";
|
|
|
+ } else if ("COMPLETE".equals(triggerStateName)) {// 完成
|
|
|
+ return "完成";
|
|
|
+ } else if ("ERROR".equals(triggerStateName)) {// 错误
|
|
|
+ return "错误";
|
|
|
+ } else if ("BLOCKED".equals(triggerStateName)) {// 阻塞
|
|
|
+ return "阻塞";
|
|
|
+ }
|
|
|
+ return triggerStateName;
|
|
|
+ }
|
|
|
+}
|