diff --git a/ruoyi-business/pom.xml b/ruoyi-business/pom.xml
index 5093bb5..7d201be 100644
--- a/ruoyi-business/pom.xml
+++ b/ruoyi-business/pom.xml
@@ -46,6 +46,10 @@
+
+ org.quartz-scheduler
+ quartz
+
diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/domain/Apply.java b/ruoyi-business/src/main/java/com/ruoyi/business/domain/Apply.java
index a244d6e..31b2cf0 100644
--- a/ruoyi-business/src/main/java/com/ruoyi/business/domain/Apply.java
+++ b/ruoyi-business/src/main/java/com/ruoyi/business/domain/Apply.java
@@ -80,10 +80,7 @@ public class Apply extends BaseEntity
@Excel(name = "是否支持应用参数")
@ApiModelProperty(name="supportParam",value = "是否支持应用参数")
private Integer supportParam;
- /** 应用参数 */
- @Excel(name = "应用参数")
- @ApiModelProperty(name="param",value = "应用参数")
- private String param;
+
/** icon图下载地址 */
@Excel(name = "icon图下载地址")
@ApiModelProperty(name="icon",value = "icon图下载地址")
diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/domain/ApplyPlan.java b/ruoyi-business/src/main/java/com/ruoyi/business/domain/ApplyPlan.java
index 3309ab7..ccaf0e2 100644
--- a/ruoyi-business/src/main/java/com/ruoyi/business/domain/ApplyPlan.java
+++ b/ruoyi-business/src/main/java/com/ruoyi/business/domain/ApplyPlan.java
@@ -112,6 +112,18 @@ public class ApplyPlan extends BaseEntity
@ApiModelProperty(name="cronExpression",value = "执行表达式")
private String cronExpression;
+ /** 上次执行时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "上次执行时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(name="lastExecTime",value = "上次执行时间")
+ private Date lastExecTime;
+
+ /** 下次执行时间 */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+ @Excel(name = "下次执行时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+ @ApiModelProperty(name="nextExecTime",value = "下次执行时间")
+ private Date nextExecTime;
+
/** 任务执行状态 */
@Excel(name = "任务执行状态")
@ApiModelProperty(name="taskStatus",value = "任务执行状态")
diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java b/ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java
index 5ca204c..ecab306 100644
--- a/ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java
+++ b/ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java
@@ -36,6 +36,11 @@ public interface IApplyPlanService extends IService {
*/
boolean runAppBySetTime() throws IllegalAccessException;
+ /**
+ * 表达式执行
+ */
+ boolean runAppByCron() throws IllegalAccessException;
+
/**
* 创建计划
* @param addApplyPlanBO
diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java b/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java
index 6444c59..48d95ee 100644
--- a/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java
+++ b/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java
@@ -1,5 +1,7 @@
package com.ruoyi.business.service.impl;
+import java.text.ParseException;
+import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@@ -22,7 +24,9 @@ import com.ruoyi.common.enums.RebotStatus;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
+import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.support.CronSequenceGenerator;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.ApplyPlanMapper;
import com.ruoyi.business.domain.ApplyPlan;
@@ -53,7 +57,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl list = jsonArray.toJavaList(ApplyStartBO.RobotParam.class);
@@ -92,8 +96,11 @@ public class ApplyPlanServiceImpl extends ServiceImpl listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
+ if (listRebotVos.isEmpty()) {
+ log.error("暂无空闲机器人");
+ // 刷新机器人数据
+// rebotService.syn(new Rebot());
+ return false;
+ }
+ List applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TREE.getKey()).list();
+ listRebotVos.forEach(rebot -> {
+ applyPlanList.forEach(e -> {
+ // 是否满足执行条件
+ boolean isExec = false;
+ try {
+ CronExpression cron = new CronExpression(e.getCronExpression());
+ // 如果该计划没有执行过
+ if (Objects.isNull(e.getLastExecTime())) {
+ // 判断当前时间是否满足表达式
+ Date nextDate = cron.getNextValidTimeAfter(new Date());
+ if (new Date().compareTo(nextDate) > -1) {
+ isExec = true;
+ }
+ } else {
+ // 根据表达式返回下一个执行时间
+ Date nextDate = cron.getNextValidTimeAfter(e.getNextExecTime());
+ if (new Date().compareTo(nextDate) > -1) {
+ isExec = true;
+ }
+ }
+ } catch (ParseException ex) {
+ log.error(e.getPlanName() + "的时间表达式错误!");
+ throw new RuntimeException(ex);
+ }
+
+ // 该计划满足执行条件
+ if (isExec) {
+ ApplyStartBO applyStartBO = new ApplyStartBO();
+ applyStartBO.setRobotUuid(e.getAppId());
+ applyStartBO.setAccountName(rebot.getRobotClientName());
+ applyStartBO.setManualTime(e.getManualTime());
+ //high 高 middle 中 low 低
+ applyStartBO.setPriority("high");
+ String planParams = e.getPlanParams();
+ if (StringUtils.isNotEmpty(planParams)) {
+ JSONArray jsonArray = JSON.parseArray(planParams);
+ // 直接转换成List
+ List list = jsonArray.toJavaList(ApplyStartBO.RobotParam.class);
+ applyStartBO.setPlanParamsList(list);
+ }
+ try {
+ JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO);
+ ApplyPlan applyPlan = new ApplyPlan();
+ applyPlan.setId(e.getId());
+ applyPlan.setUpdateBy("-1");
+ applyPlan.setUpdateTime(new Date());
+ applyPlan.setTaskUuid(jobStartVO.getJobUuid());
+ applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey());
+ // 根据表达式返回下一个执行时间
+ CronExpression cron = new CronExpression(e.getCronExpression());
+ Date nextDate = null;
+ if (Objects.isNull(e.getLastExecTime())) {
+ nextDate = cron.getNextValidTimeAfter(new Date());
+ } else {
+ nextDate = cron.getNextValidTimeAfter(e.getLastExecTime());
+ }
+ Date date = new Date();
+ applyPlan.setLastExecTime(date);
+ applyPlan.setNextExecTime(nextDate);
+ this.updateById(applyPlan);
+ Rebot updateRebot = new Rebot();
+ updateRebot.setUpdateBy("-1");
+ updateRebot.setUpdateTime(new Date());
+ updateRebot.setStatus(RebotStatus.RUNNING.getKey());
+ rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, rebot.getRobotClientName()).update(updateRebot);
+ applyPlanList.remove(e);
+ } catch (IllegalAccessException | ParseException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ });
+ });
+
+ return false;
+ }
+
+ /**
+ * 判断下次执行时间是否满足条件
+ *
+ * @param cronExpression cronExpression
+ * @param lastExecutionTime 上次执行时间
+ * @return
+ * @throws ParseException
+ */
+ private static boolean shouldExecute(String cronExpression, ZonedDateTime lastExecutionTime) throws ParseException {
+ CronExpression cron = new CronExpression(cronExpression);
+ Date now = Date.from(lastExecutionTime.toInstant());
+ return cron.isSatisfiedBy(now);
+ }
+
+
/**
* 获取应用执行结果
*
@@ -193,28 +309,35 @@ public class ApplyPlanServiceImpl extends ServiceImpl> applyPlanMap = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.ONE.getKey()).isNull(ApplyPlan::getTaskUuid)
+ .orderByAsc(ApplyPlan::getPriority).list().stream().collect(Collectors.groupingBy(ApplyPlan::getDeptId));
+
+ // 查询所有待执行的任务
+ if (null == applyStartBO && applyPlanMap.isEmpty()) {
+ log.debug("没有等待执行的计划");
+ return false;
+ }
+
+ // 获取每个部门优先级最高的计划
+ List applyPlans = new ArrayList<>();
+ applyPlanMap.forEach((k, v) -> {
+ v.sort((Comparator.comparingInt(ApplyPlan::getPriority)));
+ applyPlans.add(v.get(0));
+ });
+ if (null == applyStartBO && applyPlans.isEmpty()) {
+ log.debug("没有等待执行的计划");
+ return false;
+ }
+ applyPlans.sort((Comparator.comparingInt(ApplyPlan::getPriority)));
+
int i = 0;
for (ListRebotVO listRebotVO : listRebotVos) {
ApplyPlan applyPlan = null;
- // 查询所有待执行的任务
- Map> applyPlanMap = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.ONE.getKey()).isNull(ApplyPlan::getTaskUuid)
- .orderByAsc(ApplyPlan::getPriority).list().stream().collect(Collectors.groupingBy(ApplyPlan::getDeptId));
- if (null == applyStartBO && applyPlanMap.isEmpty()) {
- log.debug("没有等待执行的计划");
- return false;
- }
- // 获取每个部门优先级最高的计划
- List applyPlans = new ArrayList<>();
- applyPlanMap.forEach((k, v) -> {
- v.sort((Comparator.comparingInt(ApplyPlan::getPriority)));
- applyPlans.add(v.get(0));
- });
- if (null == applyStartBO && applyPlans.isEmpty()) {
- log.debug("没有等待执行的计划");
- return false;
+ if(applyPlans.isEmpty()){
+ log.debug("没有等待执行的计划!");
+ continue;
}
- applyPlans.sort((Comparator.comparingInt(ApplyPlan::getPriority)));
-
if (null == applyStartBO) {
applyPlan = applyPlans.get(0);
applyStartBO = new ApplyStartBO();
@@ -230,7 +353,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl list = jsonArray.toJavaList(ApplyStartBO.RobotParam.class);
@@ -240,6 +363,8 @@ public class ApplyPlanServiceImpl extends ServiceImpl
+
+
+
+
@@ -82,6 +86,8 @@
plan.exc_type,
plan.exc_time,
plan.cron_expression,
+ plan.last_exec_time,
+ plan.next_exec_time,
plan.task_status,
plan.task_uuid,
plan.manual_time,
@@ -117,6 +123,8 @@
and exc_type = #{excType}
and exc_time = #{excTime}
and cron_expression = #{cronExpression}
+ and last_exec_time = #{lastExecTime}
+ and next_exec_time = #{nextExecTime}
and task_status = #{taskStatus}
and task_uuid = #{taskUuid}
and manual_time = #{manualTime}
@@ -129,5 +137,6 @@
${params.dataScope}
+ order by plan.priority asc,plan.create_time desc
\ No newline at end of file
diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
index 39e9682..193a450 100644
--- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
+++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
@@ -50,6 +50,16 @@ public class RyTask {
log.debug("指定时间执行一次结束");
}
+
+ /**
+ * 表达式执行
+ */
+ public void runAppByCron() throws IllegalAccessException {
+ log.debug("表达式执行开始");
+ applyPlanService.runAppByCron();
+ log.debug("表达式执行开始");
+ }
+
/**
* 获取应用执行结果
*/
@@ -63,4 +73,6 @@ public class RyTask {
+
+
}