Kaynağa Gözat

修复定时任务和重复执行bug

pull/5/head
lcr 5 ay önce
ebeveyn
işleme
2b00c0bd0d
14 değiştirilmiş dosya ile 610 ekleme ve 322 silme
  1. +1
    -1
      ruoyi-admin/src/main/resources/application.yml
  2. +6
    -1
      ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java
  3. +78
    -27
      ruoyi-business/src/main/java/com/ruoyi/business/controller/ResourceLibraryController.java
  4. +6
    -6
      ruoyi-business/src/main/java/com/ruoyi/business/domain/ApplyPlan.java
  5. +9
    -3
      ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddApplyPlanBO.java
  6. +54
    -0
      ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddBatchResourceLibraryBO.java
  7. +3
    -2
      ruoyi-business/src/main/java/com/ruoyi/business/mapper/ResourceLibraryMapper.java
  8. +1
    -1
      ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java
  9. +13
    -5
      ruoyi-business/src/main/java/com/ruoyi/business/service/IResourceLibraryService.java
  10. +372
    -258
      ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java
  11. +49
    -8
      ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ResourceLibraryServiceImpl.java
  12. +12
    -9
      ruoyi-business/src/main/resources/mapper/business/ResourceLibraryMapper.xml
  13. +5
    -0
      ruoyi-common/pom.xml
  14. +1
    -1
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java

+ 1
- 1
ruoyi-admin/src/main/resources/application.yml Dosyayı Görüntüle

@@ -52,7 +52,7 @@ spring:
# 国际化资源文件路径
basename: i18n/messages
profiles:
active: dev
active: test
# 文件上传
servlet:
multipart:


+ 6
- 1
ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java Dosyayı Görüntüle

@@ -90,7 +90,8 @@ public class ApplyPlanController extends BaseController {
@ApiOperation(value = "获取应用执行计划管理详细信息", httpMethod = "GET", response = ApplyPlan.class)
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(applyPlanService.getById(id));
ApplyPlan applyPlan = applyPlanService.getById(id);
return success(applyPlan);
}

/**
@@ -100,6 +101,10 @@ public class ApplyPlanController extends BaseController {
@Log(title = "应用执行计划管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody AddApplyPlanBO addApplyPlanBO) {
// 随机分配
addApplyPlanBO.setPlanType("1");
addApplyPlanBO.setWaitTimeout("10m");
addApplyPlanBO.setPriority(0);
return toAjax(applyPlanService.save(addApplyPlanBO));
}



+ 78
- 27
ruoyi-business/src/main/java/com/ruoyi/business/controller/ResourceLibraryController.java Dosyayı Görüntüle

@@ -3,6 +3,14 @@ package com.ruoyi.business.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.stream.Collectors;

import com.ruoyi.business.domain.Apply;
import com.ruoyi.business.domain.bo.AddBatchResourceLibraryBO;
import com.ruoyi.business.service.IApplyService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -35,76 +43,119 @@ import com.ruoyi.common.core.page.TableDataInfo;
@Api(tags = "资源库管理接口")
@RestController
@RequestMapping("/business/ctResourceLibrary")
public class ResourceLibraryController extends BaseController
{
public class ResourceLibraryController extends BaseController {
@Autowired
private IResourceLibraryService resourceLibraryService;

@Autowired
private IApplyService applyService;

/**
* 根据应用查询所需参数
*/
@ApiOperation(value = "根据应用查询所需参数", httpMethod = "GET", response = ResourceLibrary.class)
@GetMapping("/listByAppId")
public AjaxResult listByAppId(String appId) {
List<ResourceLibrary> list = resourceLibraryService.lambdaQuery().eq(ResourceLibrary::getAppId, appId).list();
return AjaxResult.success(list);
}

/**
* 查询资源库管理列表
*/
@ApiOperation(value="查询资源库管理列表", httpMethod = "GET", response = ResourceLibrary.class)
@ApiOperation(value = "查询资源库管理列表", httpMethod = "GET", response = ResourceLibrary.class)
@GetMapping("/list")
public TableDataInfo list(ResourceLibrary resourceLibrary)
{
startPage();
List<ResourceLibrary> list = resourceLibraryService.list(resourceLibrary);
return getDataTable(list);
public TableDataInfo list(ResourceLibrary resourceLibrary) {
// 是否管理员
SysUser user = SecurityUtils.getLoginUser().getUser();
boolean isRole = user.getRoles().stream().filter(e -> e.getRoleId() == 1).count() > 0;

if (!isRole) {
List<String> appIdList = applyService.lambdaQuery().eq(Apply::getDeptId, SecurityUtils.getDeptId()).list().stream().map(Apply::getAppId).collect(Collectors.toList());
startPage();
List<ResourceLibrary> list = resourceLibraryService.list(resourceLibrary, appIdList);
return getDataTable(list);
} else {
startPage();
List<ResourceLibrary> list = resourceLibraryService.list(resourceLibrary, null);
return getDataTable(list);
}

}

/**
* 导出资源库管理列表
*/
@ApiOperation(value="导出资源库管理列表", httpMethod = "POST")
@ApiOperation(value = "导出资源库管理列表", httpMethod = "POST")
@Log(title = "资源库管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, ResourceLibrary resourceLibrary)
{
List<ResourceLibrary> list = resourceLibraryService.list(resourceLibrary);
ExcelUtil<ResourceLibrary> util = new ExcelUtil<ResourceLibrary>(ResourceLibrary.class);
util.exportExcel(response, list, "资源库管理数据");
public void export(HttpServletResponse response, ResourceLibrary resourceLibrary) {
List<String> appIdList = applyService.lambdaQuery().eq(Apply::getDeptId, SecurityUtils.getDeptId()).list().stream().map(Apply::getAppId).collect(Collectors.toList());
// 是否管理员
boolean isRole = Arrays.stream(SecurityUtils.getLoginUser().getUser().getRoleIds()).filter(e -> e == 1).count() > 0;
if (!isRole) {
List<ResourceLibrary> list = resourceLibraryService.list(resourceLibrary, appIdList);
ExcelUtil<ResourceLibrary> util = new ExcelUtil<ResourceLibrary>(ResourceLibrary.class);
util.exportExcel(response, list, "资源库管理数据");
} else {
List<ResourceLibrary> list = resourceLibraryService.list(resourceLibrary, null);
ExcelUtil<ResourceLibrary> util = new ExcelUtil<ResourceLibrary>(ResourceLibrary.class);
util.exportExcel(response, list, "资源库管理数据");
}

}

/**
* 获取资源库管理详细信息
*/
@ApiOperation(value="获取资源库管理详细信息", httpMethod = "GET", response = ResourceLibrary.class)
@ApiOperation(value = "获取资源库管理详细信息", httpMethod = "GET", response = ResourceLibrary.class)
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(resourceLibraryService.getById(id));
}

/**
* 批量新增资源信息
*/
@ApiOperation(value = "批量新增资源信息", httpMethod = "POST")
@Log(title = "批量新增资源信息", businessType = BusinessType.INSERT)
@PostMapping("/addBatch")
public AjaxResult addBatch(@RequestBody AddBatchResourceLibraryBO addBatchResourceLibraryBO) {
return toAjax(resourceLibraryService.addBatch(addBatchResourceLibraryBO));
}


/**
* 新增资源库管理
*/
@ApiOperation(value="新增资源库管理", httpMethod = "POST")
@ApiOperation(value = "新增资源库管理", httpMethod = "POST")
@Log(title = "资源库管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody ResourceLibrary resourceLibrary)
{
public AjaxResult add(@RequestBody ResourceLibrary resourceLibrary) {
Integer count = resourceLibraryService.lambdaQuery().eq(ResourceLibrary::getAppId, resourceLibrary.getAppId()).eq(ResourceLibrary::getResourceName, resourceLibrary.getResourceName()).count();
if (count > 0) {
return AjaxResult.error("已经有相同的资源键,无需重复创建");
}
return toAjax(resourceLibraryService.save(resourceLibrary));
}

/**
* 修改资源库管理
*/
@ApiOperation(value="修改资源库管理", httpMethod = "PUT")
@ApiOperation(value = "修改资源库管理", httpMethod = "PUT")
@Log(title = "资源库管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody ResourceLibrary resourceLibrary)
{
public AjaxResult edit(@RequestBody ResourceLibrary resourceLibrary) {
return toAjax(resourceLibraryService.updateById(resourceLibrary));
}

/**
* 删除资源库管理
*/
@ApiOperation(value="删除资源库管理", httpMethod = "DELETE")
@ApiOperation(value = "删除资源库管理", httpMethod = "DELETE")
@Log(title = "资源库管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(resourceLibraryService.removeByIds(Arrays.asList(ids)));
}
}

+ 6
- 6
ruoyi-business/src/main/java/com/ruoyi/business/domain/ApplyPlan.java Dosyayı Görüntüle

@@ -107,8 +107,8 @@ public class ApplyPlan extends BaseEntity


/** 执行时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "执行时间", width = 30, dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "执行时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(name="excTime",value = "执行时间")
private Date excTime;

@@ -147,15 +147,15 @@ public class ApplyPlan extends BaseEntity


/** 任务开始运行的时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "任务开始运行的时间", width = 30, dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "任务开始运行的时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(name="startTime",value = "任务开始运行的时间")
private Date startTime;


/** 任务结束运行的时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "任务结束运行的时间", width = 30, dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "任务结束运行的时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(name="endTime",value = "任务结束运行的时间")
private Date endTime;



+ 9
- 3
ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddApplyPlanBO.java Dosyayı Görüntüle

@@ -3,6 +3,7 @@ package com.ruoyi.business.domain.bo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.business.domain.ResourceLibrary;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
@@ -64,7 +65,7 @@ public class AddApplyPlanBO extends BaseEntity
/** appid */
@Excel(name = "appid")
@ApiModelProperty(name="appId",value = "appid")
private List<String> appId;
private String appId;


/** 应用类型枚举(app:应用 activity:指令) */
@@ -105,8 +106,8 @@ public class AddApplyPlanBO extends BaseEntity


/** 执行时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "执行时间", width = 30, dateFormat = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "执行时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(name="excTime",value = "执行时间")
private Date excTime;

@@ -115,6 +116,11 @@ public class AddApplyPlanBO extends BaseEntity
@ApiModelProperty(name="cronExpression",value = "执行表达式")
private String cronExpression;


@ApiModelProperty(name="resourceLibrarieList",value = "参数列表")
@TableField(exist = false)
private List<ResourceLibrary> resourceLibrarieList;

@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)


+ 54
- 0
ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddBatchResourceLibraryBO.java Dosyayı Görüntüle

@@ -0,0 +1,54 @@
package com.ruoyi.business.domain.bo;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ruoyi.business.domain.ResourceLibrary;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.List;

/**
* 资源库管理对象 ct_resource_library
*
* @author LiuChengRan
* @date 2024-06-17
*/
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "ResourceLibrary", description = "资源库管理")
public class AddBatchResourceLibraryBO extends BaseEntity {
@TableField(exist = false)
private static final long serialVersionUID = 1L;

@Excel(name = "所属应用id")
@ApiModelProperty(name = "appId", value = "所属应用id")
private String appId;

@Excel(name = "参数集合")
@ApiModelProperty(name = "list", value = "参数集合")
private List<ResourceLibrary> list;

@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.append("deleted", getDeleted())
.toString();
}
}

+ 3
- 2
ruoyi-business/src/main/java/com/ruoyi/business/mapper/ResourceLibraryMapper.java Dosyayı Görüntüle

@@ -3,6 +3,7 @@ package com.ruoyi.business.mapper;
import java.util.List;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.business.domain.ResourceLibrary;
import org.apache.ibatis.annotations.Param;

/**
* 资源库管理Mapper接口
@@ -15,10 +16,10 @@ public interface ResourceLibraryMapper extends BaseMapper<ResourceLibrary>

/**
* 查询资源库管理列表
*
*
* @param resourceLibrary 资源库管理
* @return 资源库管理集合
*/
List<ResourceLibrary> selectResourceLibraryList(ResourceLibrary resourceLibrary);
List<ResourceLibrary> selectResourceLibraryList(@Param("resourceLibrary") ResourceLibrary resourceLibrary, @Param("appIdList") String appIdList);

}

+ 1
- 1
ruoyi-business/src/main/java/com/ruoyi/business/service/IApplyPlanService.java Dosyayı Görüntüle

@@ -47,7 +47,7 @@ public interface IApplyPlanService extends IService<ApplyPlan> {
*
* @return
*/
boolean execPlan(ApplyStartBO applyStartBO) throws IllegalAccessException;
boolean execPlan(ApplyStartBO applyStartBO,ApplyPlan applyPlan) throws IllegalAccessException;

/**
* 定时查询指定时间执行的数据


+ 13
- 5
ruoyi-business/src/main/java/com/ruoyi/business/service/IResourceLibraryService.java Dosyayı Görüntüle

@@ -1,24 +1,32 @@
package com.ruoyi.business.service;

import java.util.List;

import com.ruoyi.business.domain.ResourceLibrary;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.business.domain.bo.AddBatchResourceLibraryBO;

/**
* 资源库管理Service接口
*
*
* @author LiuChengRan
* @date 2024-06-17
*/
public interface IResourceLibraryService extends IService<ResourceLibrary>
{
public interface IResourceLibraryService extends IService<ResourceLibrary> {

/**
* 批量添加参数
*
* @param addBatchResourceLibraryBO
*/
boolean addBatch(AddBatchResourceLibraryBO addBatchResourceLibraryBO);

/**
* 查询资源库管理列表
*
*
* @param resourceLibrary 资源库管理
* @return 资源库管理集合
*/
List<ResourceLibrary> list(ResourceLibrary resourceLibrary);
List<ResourceLibrary> list(ResourceLibrary resourceLibrary, List<String> appIdList);

}

+ 372
- 258
ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyPlanServiceImpl.java Dosyayı Görüntüle

@@ -1,8 +1,10 @@
package com.ruoyi.business.service.impl;

import java.text.ParseException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@@ -23,14 +25,19 @@ import com.ruoyi.business.service.IResourceLibraryService;
import com.ruoyi.business.util.YinDaoHttpUtils;
import com.ruoyi.business.yddoman.BaseDTO;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.ExcTypeStatus;
import com.ruoyi.common.enums.PlanRunStatus;
import com.ruoyi.common.enums.RebotStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.quartz.*;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.support.CronSequenceGenerator;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.ApplyPlanMapper;
@@ -56,6 +63,10 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
@Autowired
private IResourceLibraryService resourceLibraryService;

@Autowired
private RedissonClient redissonClient;


/**
* 重新运行
*
@@ -92,40 +103,168 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
@Override
@Transactional
public boolean runAppBySetTime() throws IllegalAccessException {
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TWO.getKey()).isNull(ApplyPlan::getTaskUuid).orderByAsc(ApplyPlan::getExcTime).list();
if (applyPlanList.isEmpty()) {
return false;
}
RLock lock = redissonClient.getLock("runAppBySetTime");
try {
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒
boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS);
if (isLocked) {
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TWO.getKey()).isNull(ApplyPlan::getTaskUuid).orderByAsc(ApplyPlan::getExcTime).list();
if (applyPlanList.isEmpty()) {
return false;
}

ListRebotBO listRebotBO = new ListRebotBO();
listRebotBO.setStatus(RebotStatus.IDLE.getKey());
listRebotBO.setPage(1);
listRebotBO.setSize(100);
// 只获取空闲的机器人
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
if (listRebotVos.isEmpty()) {
log.debug("暂无空闲机器人");
// 刷新机器人数据
ListRebotBO listRebotBO = new ListRebotBO();
listRebotBO.setStatus(RebotStatus.IDLE.getKey());
listRebotBO.setPage(1);
listRebotBO.setSize(100);
// 只获取空闲的机器人
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
if (listRebotVos.isEmpty()) {
log.debug("暂无空闲机器人");
// 刷新机器人数据
// rebotService.syn(new Rebot());
return false;
return false;
}
List<String> ids = new ArrayList<>();
listRebotVos.forEach(rebot -> {
applyPlanList.forEach(e -> {
log.debug("指定时间执行 执行时间:" + e.getExcTime());
if (ids.contains(e.getId())) {
return;
}
if (e.getExcTime().getTime() <= System.currentTimeMillis() && PlanRunStatus.AWAIT_CREATE.getKey().equals(e.getTaskStatus())) {
ApplyStartBO applyStartBO = new ApplyStartBO();
applyStartBO.setRobotUuid(e.getAppId());
applyStartBO.setAccountName(rebot.getRobotClientName());
applyStartBO.setManualTime(e.getManualTime());
//high 高 middle 中 low 低
applyStartBO.setPriority("high");
// 如果应用支持参数
if (!Objects.isNull(e.getSupportParam()) && e.getSupportParam() == 1) {
if (StringUtils.isNotEmpty(e.getPlanParams())) {
applyStartBO.setPlanParams(e.getPlanParams());
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class);
applyStartBO.setPlanParamsList(paramList);
}
}
try {
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO);
ApplyPlan applyPlan = new ApplyPlan();
applyPlan.setId(e.getId());
applyPlan.setUpdateBy("系统修改");
applyPlan.setUpdateTime(new Date());
applyPlan.setTaskUuid(jobStartVO.getJobUuid());
applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey());
this.updateById(applyPlan);
Rebot updateRebot = new Rebot();
updateRebot.setUpdateBy("系统修改");
updateRebot.setUpdateTime(new Date());
updateRebot.setStatus(RebotStatus.RUNNING.getKey());
if (rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, rebot.getRobotClientName()).update(updateRebot)) {
log.debug("applyPlanList:" + applyPlanList.size());
ids.add(e.getId());
}
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
});
});
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
// 释放锁
lock.unlock();
}
}
listRebotVos.forEach(rebot -> {
applyPlanList.forEach(e -> {
if (e.getExcTime().getTime() <= System.currentTimeMillis() && PlanRunStatus.AWAIT_CREATE.getKey().equals(e.getTaskStatus())) {
return false;
}

/**
* 表达式执行
*/
@Override
public boolean runAppByCron() throws IllegalAccessException {
RLock lock = redissonClient.getLock("runAppByCron");
try {
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒
boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS);
if (isLocked) {
// 先查计划,避免每次命中第三方接口
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TREE.getKey()).ne(ApplyPlan::getTaskStatus, PlanRunStatus.RUNNING.getKey()).ne(ApplyPlan::getTaskStatus, PlanRunStatus.CREATED.getKey()).list();
if (applyPlanList.isEmpty()) {
return false;
}
// 需要执行的计划
List<ApplyPlan> execApplyPlan = new ArrayList<>();
applyPlanList.forEach(e -> {
try {
CronExpression cron = new CronExpression(e.getCronExpression());
// 如果该计划没有执行过
if (Objects.isNull(e.getLastExecTime())) {
// 执行一次
execApplyPlan.add(e);
} else {
// 根据表达式返回下一个执行时间
if (new Date().compareTo(e.getNextExecTime()) > -1) {
execApplyPlan.add(e);
}
}
} catch (ParseException ex) {
log.error(e.getPlanName() + "的时间表达式错误!");
throw new RuntimeException(ex);
}
});
if (execApplyPlan.isEmpty()) {
log.debug("没有待执行的计划");
return false;
}

ListRebotBO listRebotBO = new ListRebotBO();
listRebotBO.setStatus(RebotStatus.IDLE.getKey());
listRebotBO.setPage(1);
listRebotBO.setSize(100);
// 只获取空闲的机器人
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
if (listRebotVos.isEmpty()) {
log.debug("暂无空闲机器人");
// 刷新机器人数据
// rebotService.syn(new Rebot());
return false;
}
List<String> ids = new ArrayList<>();
execApplyPlan.forEach(e -> {
if (listRebotVos.isEmpty()) {
// 刷新机器人数据
// rebotService.syn(new Rebot());
return;
}
ListRebotVO rebot = listRebotVos.get(0);
log.debug("机器人表达式执行调度日志" + rebot.getRobotClientName() + "调度" + e.getAppName() + "应用,排除的应用id为" + ids.toString());
if (ids.contains(e.getId())) {
return;
}
log.debug("机器人表达式成功调度日志" + rebot.getRobotClientName() + "调度" + e.getAppName() + "应用,排除的应用id为" + ids.toString());
// 该计划满足执行条件
ApplyStartBO applyStartBO = new ApplyStartBO();
applyStartBO.setRobotUuid(e.getAppId());
applyStartBO.setAccountName(rebot.getRobotClientName());
applyStartBO.setManualTime(e.getManualTime());
//high 高 middle 中 low 低
applyStartBO.setPriority("high");

// 如果应用支持参数
if (!Objects.isNull(e.getSupportParam()) && e.getSupportParam() == 1) {
// 获取参数
if (StringUtils.isNotEmpty(e.getPlanParams())) {
applyStartBO.setPlanParams(e.getPlanParams());
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class);
applyStartBO.setPlanParamsList(paramList);
}
}

try {
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO);
ApplyPlan applyPlan = new ApplyPlan();
@@ -133,136 +272,69 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
applyPlan.setUpdateBy("系统修改");
applyPlan.setUpdateTime(new Date());
applyPlan.setTaskUuid(jobStartVO.getJobUuid());
applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey());
applyPlan.setTaskStatus(PlanRunStatus.RUNNING.getKey());
// 根据表达式返回下一个执行时间
log.debug("表达式:" + e.getCronExpression());
// 设置时区,例如设置为中国时区
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai").toString());

final CronExpression cron = new CronExpression(e.getCronExpression());
Date nextDate = null;
if (Objects.isNull(e.getLastExecTime())) {
Date date = new Date();
log.debug("当前时间:" + date);
nextDate = cron.getNextValidTimeAfter(date);//下次执行时间
log.debug("下次时间:" + nextDate);
applyPlan.setLastExecTime(date);
applyPlan.setNextExecTime(nextDate);
} else {
applyPlan.setLastExecTime(e.getNextExecTime());
log.debug("当前时间:" + e.getNextExecTime());
nextDate = cron.getNextValidTimeAfter(e.getNextExecTime());//下次执行时间
log.debug("下次时间:" + nextDate);
applyPlan.setNextExecTime(nextDate);
}
this.updateById(applyPlan);
Rebot updateRebot = new Rebot();
updateRebot.setUpdateBy("系统修改");
updateRebot.setUpdateTime(new Date());
updateRebot.setStatus(RebotStatus.RUNNING.getKey());
if (rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, rebot.getRobotClientName()).update(updateRebot)) {
applyPlanList.remove(e);
ids.add(e.getId());
}
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (ParseException ex) {
throw new RuntimeException(ex);
}
}
});
});

return false;
}

/**
* 表达式执行
*/
@Override
public boolean runAppByCron() throws IllegalAccessException {
// 先查计划,避免每次命中第三方接口
List<ApplyPlan> applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TREE.getKey()).list();
if (applyPlanList.isEmpty()) {
return false;
}
// 需要执行的计划
List<ApplyPlan> execApplyPlan = new ArrayList<>();
applyPlanList.forEach(e -> {
try {
CronExpression cron = new CronExpression(e.getCronExpression());
// 如果该计划没有执行过
if (Objects.isNull(e.getLastExecTime())) {
// 判断当前时间是否满足表达式
Date nextDate = cron.getNextValidTimeAfter(new Date());
if (new Date().compareTo(nextDate) > -1) {
execApplyPlan.add(e);
}
} else {
// 根据表达式返回下一个执行时间
Date nextDate = cron.getNextValidTimeAfter(e.getNextExecTime());
if (new Date().compareTo(nextDate) > -1) {
execApplyPlan.add(e);
}
}
} catch (ParseException ex) {
log.error(e.getPlanName() + "的时间表达式错误!");
throw new RuntimeException(ex);
listRebotVos.remove(0);
});
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
// 释放锁
lock.unlock();
}
});
if (execApplyPlan.isEmpty()) {
log.debug("没有待执行的计划");
return false;
}

ListRebotBO listRebotBO = new ListRebotBO();
listRebotBO.setStatus(RebotStatus.IDLE.getKey());
listRebotBO.setPage(1);
listRebotBO.setSize(100);
// 只获取空闲的机器人
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
if (listRebotVos.isEmpty()) {
log.debug("暂无空闲机器人");
// 刷新机器人数据
// rebotService.syn(new Rebot());
return false;
}
listRebotVos.forEach(rebot -> {
execApplyPlan.forEach(e -> {
// 该计划满足执行条件
ApplyStartBO applyStartBO = new ApplyStartBO();
applyStartBO.setRobotUuid(e.getAppId());
applyStartBO.setAccountName(rebot.getRobotClientName());
applyStartBO.setManualTime(e.getManualTime());
//high 高 middle 中 low 低
applyStartBO.setPriority("high");
return false;
}

// 如果应用支持参数
if (!Objects.isNull(e.getSupportParam()) && e.getSupportParam() == 1) {
// 获取参数
if (StringUtils.isNotEmpty(e.getPlanParams())) {
applyStartBO.setPlanParams(e.getPlanParams());
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class);
applyStartBO.setPlanParamsList(paramList);
}
}
String planParams = e.getPlanParams();
if (StringUtils.isNotEmpty(planParams)) {
JSONArray jsonArray = JSON.parseArray(planParams);
// 直接转换成List
List<ApplyStartBO.RobotParam> 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("系统修改");
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("系统修改");
updateRebot.setUpdateTime(new Date());
updateRebot.setStatus(RebotStatus.RUNNING.getKey());
if (rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, rebot.getRobotClientName()).update(updateRebot)) {
applyPlanList.remove(e);
}
} catch (IllegalAccessException | ParseException ex) {
throw new RuntimeException(ex);
}
});
});
public static void main(String[] args) {
String cronExp="0 0/2 * * * ? ";
// 解析cron表达式
final CronSequenceGenerator cronSequenceGenerator = new CronSequenceGenerator(cronExp);
Date now = new Date();
// 任务下次执行时间
Date nextTime = cronSequenceGenerator.next(now);
// 任务下下次执行时间
Date nextNextTime = cronSequenceGenerator.next(nextTime);
}

return false;
private static Date matchDate(Date date, String cron) throws ParseException {
CronExpression cronExpression = new CronExpression(cron);
return cronExpression.getNextValidTimeAfter(date);
}


@@ -283,7 +355,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
noStatus.add(PlanRunStatus.SKIPPED.getKey());
noStatus.add(PlanRunStatus.CANCEL.getKey());
// 查询任务运行状态非空非终态并且已经创建的任务
List<ApplyPlan> list = this.lambdaQuery().notIn(ApplyPlan::getTaskStatus, noStatus).isNotNull(ApplyPlan::getTaskStatus).orderByAsc(ApplyPlan::getPriority).list();
List<ApplyPlan> list = this.lambdaQuery().notIn(ApplyPlan::getTaskStatus, noStatus).isNotNull(ApplyPlan::getTaskUuid).isNotNull(ApplyPlan::getTaskStatus).orderByAsc(ApplyPlan::getPriority).list();
if (list.isEmpty()) {
log.debug("没有需要更新状态的计划任务");
return;
@@ -300,12 +372,13 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
if (null != jobQueryVO.getEndTime()) {
updateApplyPlan.setEndTime(jobQueryVO.getEndTime());
updateApplyPlan.setStartTime(jobQueryVO.getStartTime());
updateApplyPlan.setEndTime(jobQueryVO.getEndTime());
long diff = updateApplyPlan.getEndTime().getTime() - updateApplyPlan.getStartTime().getTime();
long planTime = diff / (60 * 1000);
updateApplyPlan.setPlanTime(planTime + "");
if (!Objects.isNull(applyPlan.getManualTime())) {
updateApplyPlan.setTimeSaving((Long.parseLong(applyPlan.getManualTime()) - planTime) + "");
if (!Objects.isNull(updateApplyPlan.getEndTime()) && !Objects.isNull(updateApplyPlan.getStartTime())) {
long diff = updateApplyPlan.getEndTime().getTime() - updateApplyPlan.getStartTime().getTime();
long planTime = diff / (60 * 1000);
updateApplyPlan.setPlanTime(planTime + "");
if (!Objects.isNull(applyPlan.getManualTime())) {
updateApplyPlan.setTimeSaving((Long.parseLong(applyPlan.getManualTime()) - planTime) + "");
}
}
}
updateApplyPlan.setId(applyPlan.getId());
@@ -351,86 +424,102 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
*/
@Override
@Transactional
public boolean execPlan(ApplyStartBO applyStartBO) throws IllegalAccessException {
// 先查计划 避免每次直接命中第三方接口
Map<Long, List<ApplyPlan>> 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;
}
public boolean execPlan(ApplyStartBO applyStartBO, ApplyPlan applyPlan) throws IllegalAccessException {
RLock lock = redissonClient.getLock("execPlan");
int i = 0;
try {
// 尝试获取锁,最多等待100秒,锁定之后最多持有锁10秒
boolean isLocked = lock.tryLock(2, 20, TimeUnit.SECONDS);
if (isLocked) {
// 先查计划 避免每次直接命中第三方接口
Map<Long, List<ApplyPlan>> 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;
}

ListRebotBO listRebotBO = new ListRebotBO();
listRebotBO.setStatus(RebotStatus.IDLE.getKey());
listRebotBO.setPage(1);
listRebotBO.setSize(100);
// 只获取空闲的机器人
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
if (listRebotVos.isEmpty()) {
log.debug("暂无空闲机器人");
// 刷新机器人数据
ListRebotBO listRebotBO = new ListRebotBO();
listRebotBO.setStatus(RebotStatus.IDLE.getKey());
listRebotBO.setPage(1);
listRebotBO.setSize(100);
// 只获取空闲的机器人
List<ListRebotVO> listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO);
if (listRebotVos.isEmpty()) {
log.debug("暂无空闲机器人");
// 刷新机器人数据
// rebotService.syn(new Rebot());
return false;
}
return false;
}

// 获取每个部门优先级最高的计划
List<ApplyPlan> 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)));
// 获取每个部门优先级最高的计划
List<ApplyPlan> 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;
if (applyPlans.isEmpty()) {
log.debug("没有等待执行的计划!");
continue;
}
if (null == applyStartBO) {
applyPlan = applyPlans.get(0);
applyStartBO = new ApplyStartBO();
applyStartBO.setRobotUuid(applyPlan.getAppId());
//high 高 middle 中 low 低
applyStartBO.setPriority("high");
} else {
applyPlan = new ApplyPlan();
BeanUtils.copyBeanProp(applyPlan, applyStartBO);
// 运行的应用上一步已给值,此处无需再给
}
applyStartBO.setAccountName(listRebotVO.getRobotClientName());
// 如果应用支持参数
if (!Objects.isNull(applyPlan.getSupportParam()) && applyPlan.getSupportParam() == 1) {
if (StringUtils.isNotEmpty(applyPlan.getPlanParams())) {
applyStartBO.setPlanParams(applyPlan.getPlanParams());
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(applyPlan.getPlanParams(), ApplyStartBO.RobotParam.class);
applyStartBO.setPlanParamsList(paramList);
for (ListRebotVO listRebotVO : listRebotVos) {
if (applyPlans.isEmpty() && null == applyStartBO) {
log.debug("没有等待执行的计划!");
continue;
}
if (null == applyStartBO) {
applyPlan = applyPlans.get(0);
applyStartBO = new ApplyStartBO();
applyStartBO.setRobotUuid(applyPlan.getAppId());
//high 高 middle 中 low 低
applyStartBO.setPriority("high");
} else {
applyPlan = new ApplyPlan();
BeanUtils.copyBeanProp(applyPlan, applyStartBO);
// 运行的应用上一步已给值,此处无需再给
}
applyStartBO.setAccountName(listRebotVO.getRobotClientName());
// 如果应用支持参数
if (!Objects.isNull(applyPlan.getSupportParam()) && applyPlan.getSupportParam() == 1) {
if (StringUtils.isNotEmpty(applyPlan.getPlanParams())) {
applyStartBO.setPlanParams(applyPlan.getPlanParams());
List<ApplyStartBO.RobotParam> paramList = JSON.parseArray(applyPlan.getPlanParams(), ApplyStartBO.RobotParam.class);
applyStartBO.setPlanParamsList(paramList);
}
}
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO);
ApplyPlan updateApplyPlan = new ApplyPlan();
updateApplyPlan.setId(applyPlan.getId());
updateApplyPlan.setCreateBy("系统创建");
updateApplyPlan.setCreateTime(new Date());
updateApplyPlan.setUpdateBy("系统修改");
updateApplyPlan.setUpdateTime(new Date());
updateApplyPlan.setStartTime(new Date());
updateApplyPlan.setTaskUuid(jobStartVO.getJobUuid());
updateApplyPlan.setPlanName(applyPlan.getPlanName());
updateApplyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey());
updateApplyPlan.setRobotName(listRebotVO.getRobotClientName());
updateApplyPlan.setManualTime(applyPlan.getManualTime());
updateApplyPlan.setDeptId(applyStartBO.getDeptId());
applyPlan.setTaskUuid(jobStartVO.getJobUuid());
if (this.saveOrUpdate(updateApplyPlan)) {
if (!applyPlans.isEmpty()) {
applyPlans.remove(0);
}
i++;
}
}
}
JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO);
ApplyPlan updateApplyPlan = new ApplyPlan();
updateApplyPlan.setId(applyPlan.getId());
updateApplyPlan.setCreateBy("系统创建");
updateApplyPlan.setCreateTime(new Date());
updateApplyPlan.setUpdateBy("系统修改");
updateApplyPlan.setUpdateTime(new Date());
updateApplyPlan.setStartTime(new Date());
updateApplyPlan.setTaskUuid(jobStartVO.getJobUuid());
updateApplyPlan.setPlanName(applyPlan.getPlanName());
updateApplyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey());
updateApplyPlan.setRobotName(listRebotVO.getRobotClientName());
updateApplyPlan.setManualTime(applyPlan.getManualTime());
updateApplyPlan.setDeptId(applyStartBO.getDeptId());
if (this.saveOrUpdate(updateApplyPlan)) {
applyPlans.remove(0);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
// 释放锁
lock.unlock();
}
}
return i > 0;
@@ -440,71 +529,96 @@ public class ApplyPlanServiceImpl extends ServiceImpl<ApplyPlanMapper, ApplyPlan
@Override
@Transactional
public boolean save(AddApplyPlanBO addApplyPlanBO) {
// 指定时间执行
if (addApplyPlanBO.getExcType().equals("1") && null == addApplyPlanBO.getExcTime()) {
throw new ServiceException("指定时间执行时间不能为空");
}
// 表达式执行
if (addApplyPlanBO.getExcType().equals("2")) {
if (null == addApplyPlanBO.getCronExpression()) {
throw new ServiceException("周期执行表达式不能为空");
}
try {
// cron 验证表达式是否正确
CronExpression.validateExpression(addApplyPlanBO.getCronExpression());
} catch (Exception ex) {
throw new ServiceException("时间表达式错误");
}
}

List<ApplyPlan> applyPlanList = new ArrayList<>();
Map<String, List<Apply>> appMap = applyService.lambdaQuery().in(Apply::getAppId, addApplyPlanBO.getAppId()).list().stream().collect(Collectors.groupingBy(Apply::getAppId));
// 是否有空闲机器人并且创建计划成功
boolean isExec = false;
AtomicBoolean insert = new AtomicBoolean(false);

addApplyPlanBO.getAppId().forEach(e -> {
ApplyPlan applyPlan = new ApplyPlan();
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO);
Apply apply = appMap.get(e).get(0);
applyPlan.setAppName(apply.getAppName());
applyPlan.setAppId(apply.getAppId());
applyPlan.setAppType(apply.getAppType());
applyPlan.setAppTypeName(apply.getAppTypeName());
applyPlan.setManualTime(apply.getManualTime());
if (null != apply.getSupportParam() && apply.getSupportParam() == 1) {
// 获取参数 每一次执行计划的参数都是独立的
List<ApplyStartBO.RobotParam> paramList = resourceLibraryService.lambdaQuery().eq(ResourceLibrary::getAppId, apply.getAppId()).list().stream()
.map(item -> {
ApplyStartBO.RobotParam robotParam = new ApplyStartBO.RobotParam();
robotParam.setName(item.getResourceName());
robotParam.setValue(item.getResourceValue());
robotParam.setType(item.getResourceType());
return robotParam;
}).collect(Collectors.toList());
if (!paramList.isEmpty()) {
// json集合转字符串
applyPlan.setPlanParams(JSONArray.toJSONString(paramList));
}
ApplyPlan applyPlan = new ApplyPlan();
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO);
Apply apply = appMap.get(addApplyPlanBO.getAppId()).get(0);
applyPlan.setAppName(apply.getAppName());
applyPlan.setAppId(apply.getAppId());
applyPlan.setAppType(apply.getAppType());
applyPlan.setAppTypeName(apply.getAppTypeName());
applyPlan.setManualTime(apply.getManualTime());
if (null != apply.getSupportParam() && apply.getSupportParam() == 1) {
// 获取参数 每一次执行计划的参数都是独立的
List<ApplyStartBO.RobotParam> paramList = addApplyPlanBO.getResourceLibrarieList().stream()
.map(item -> {
ApplyStartBO.RobotParam robotParam = new ApplyStartBO.RobotParam();
robotParam.setName(item.getResourceName());
robotParam.setValue(item.getResourceValue());
robotParam.setType(item.getResourceType());
return robotParam;
}).collect(Collectors.toList());
resourceLibraryService.saveOrUpdateBatch(addApplyPlanBO.getResourceLibrarieList());
if (paramList.isEmpty()) {
throw new ServiceException("该应用需要参数,没有检测到参数!");
} else {
// json集合转字符串
applyPlan.setPlanParams(JSONArray.toJSONString(paramList));
}
applyPlan.setDeptId(SecurityUtils.getDeptId());

}
applyPlan.setDeptId(SecurityUtils.getDeptId());
// 立即执行才执行
if (addApplyPlanBO.getExcType().equals("0")) {
// 只指定优先级和应用和人工用时 机器人等下一个阶段判读是否有空闲
ApplyStartBO applyStartBO = new ApplyStartBO();
try {
// 只指定优先级和应用和人工用时 机器人等下一个阶段判读是否有空闲
ApplyStartBO applyStartBO = new ApplyStartBO();
applyStartBO.setRobotUuid(applyPlan.getAppId());
//high 高 middle 中 low 低
applyStartBO.setPriority("high");
applyStartBO.setPlanParams(applyPlan.getPlanParams());
applyStartBO.setManualTime(applyPlan.getManualTime());
applyStartBO.setPlanName(addApplyPlanBO.getPlanName());
insert.set(execPlan(applyStartBO));
ApplyPlan retApplyPlan = new ApplyPlan();
isExec = execPlan(applyStartBO, retApplyPlan);
applyPlan.setTaskUuid(retApplyPlan.getTaskUuid());
} catch (Exception ex) {
log.error("分配机器人异常:" + ex.getMessage());
}
if (!insert.get()) {
applyPlan.setTaskStatus(PlanRunStatus.AWAIT_CREATE.getKey());
applyPlanList.add(applyPlan);
}
});
}

if (isExec) {
applyPlan.setTaskStatus(PlanRunStatus.CREATED.getKey());
} else {
applyPlan.setTaskStatus(PlanRunStatus.AWAIT_CREATE.getKey());
}
applyPlanList.add(applyPlan);
return this.saveBatch(applyPlanList) || insert.get();
}

@Override
public boolean update(AddApplyPlanBO addApplyPlanBO) {
List<ApplyPlan> applyPlanList = new ArrayList<>();
Map<String, List<Apply>> appMap = applyService.lambdaQuery().in(Apply::getAppId, addApplyPlanBO.getAppId()).eq(Apply::getDeptId, SecurityUtils.getDeptId()).list().stream().collect(Collectors.groupingBy(Apply::getAppId));
addApplyPlanBO.getAppId().forEach(e -> {
ApplyPlan applyPlan = new ApplyPlan();
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO);
Apply apply = appMap.get(e).get(0);
applyPlan.setAppName(apply.getAppName());
applyPlan.setAppId(apply.getAppId());
applyPlan.setAppType(apply.getAppType());
applyPlan.setAppTypeName(apply.getAppTypeName());
applyPlanList.add(applyPlan);
});
Map<String, List<Apply>> appMap = applyService.lambdaQuery().in(Apply::getAppId, addApplyPlanBO.getAppId()).list().stream().collect(Collectors.groupingBy(Apply::getAppId));
ApplyPlan applyPlan = new ApplyPlan();
BeanUtils.copyBeanProp(applyPlan, addApplyPlanBO);
Apply apply = appMap.get(addApplyPlanBO.getAppId()).get(0);
applyPlan.setAppName(apply.getAppName());
applyPlan.setAppId(apply.getAppId());
applyPlan.setAppType(apply.getAppType());
applyPlan.setAppTypeName(apply.getAppTypeName());
applyPlanList.add(applyPlan);

return super.updateBatchById(applyPlanList);
}


+ 49
- 8
ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ResourceLibraryServiceImpl.java Dosyayı Görüntüle

@@ -1,10 +1,15 @@
package com.ruoyi.business.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import com.ruoyi.business.domain.Apply;
import com.ruoyi.business.domain.bo.AddBatchResourceLibraryBO;
import com.ruoyi.business.service.IApplyService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -15,33 +20,69 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
* 资源库管理Service业务层处理
*
*
* @author LiuChengRan
* @date 2024-06-17
*/
@Service
public class ResourceLibraryServiceImpl extends ServiceImpl<ResourceLibraryMapper, ResourceLibrary> implements IResourceLibraryService
{
public class ResourceLibraryServiceImpl extends ServiceImpl<ResourceLibraryMapper, ResourceLibrary> implements IResourceLibraryService {

@Autowired
private IApplyService applyService;

/**
* 批量添加参数
*
* @param addBatchResourceLibraryBO
*/
@Override
public boolean addBatch(AddBatchResourceLibraryBO addBatchResourceLibraryBO) {
Apply apply = Optional.ofNullable(applyService.lambdaQuery().eq(Apply::getAppId, addBatchResourceLibraryBO.getAppId()).one())
.orElseThrow(() -> new RuntimeException("应用不存在"));
// 参数集合
List<ResourceLibrary> resourceLibraries = new ArrayList<>();
// stream统计对象里重复的字段
Map<String, Long> mapList = addBatchResourceLibraryBO.getList().stream().collect(Collectors.groupingBy(ResourceLibrary::getResourceName, Collectors.counting()));
mapList.forEach((k, v) -> {
if (v > 1) {
throw new ServiceException(k + "重复,请重新输入");
}
if(this.lambdaQuery().eq(ResourceLibrary::getAppId, addBatchResourceLibraryBO.getAppId()).eq(ResourceLibrary::getResourceName,k).count()>0){
throw new ServiceException(k + "已存在,请重新输入");
}
});
addBatchResourceLibraryBO.getList().forEach(e -> {
ResourceLibrary resourceLibrary = new ResourceLibrary();
resourceLibrary.setAppId(apply.getAppId());
resourceLibrary.setAppName(apply.getAppName());
resourceLibrary.setDeptId(apply.getDeptId());
resourceLibrary.setDeptName(apply.getDeptName());
resourceLibrary.setResource(e.getResource());
resourceLibrary.setResourceName(e.getResourceName());
resourceLibrary.setResourceType(e.getResourceType());
resourceLibrary.setResourceValue(e.getResourceValue());
resourceLibraries.add(resourceLibrary);
});

return super.saveBatch(resourceLibraries);
}

/**
* 查询资源库管理列表
*
*
* @param resourceLibrary 资源库管理
* @return 资源库管理
*/
@Override
public List<ResourceLibrary> list(ResourceLibrary resourceLibrary)
{
return baseMapper.selectResourceLibraryList(resourceLibrary);
public List<ResourceLibrary> list(ResourceLibrary resourceLibrary, List<String> appIdList) {
// appIdList 转,号分隔字符串
return baseMapper.selectResourceLibraryList(resourceLibrary, null != appIdList ? String.join(",", appIdList) : null);
}

@Override
public boolean save(ResourceLibrary entity) {
Apply apply = Optional.ofNullable(applyService.lambdaQuery().eq(Apply::getAppId, entity.getAppId()).one())
.orElseThrow(()->new RuntimeException("应用不存在"));
.orElseThrow(() -> new RuntimeException("应用不存在"));
entity.setAppId(apply.getAppId());
entity.setAppName(apply.getAppName());
entity.setDeptId(apply.getDeptId());


+ 12
- 9
ruoyi-business/src/main/resources/mapper/business/ResourceLibraryMapper.xml Dosyayı Görüntüle

@@ -59,15 +59,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectResourceLibraryVo"/>
from ct_resource_library
<where>
deleted = 0
<if test="resource != null and resource != ''"> and resource like concat(#{resource}, '%')</if>
<if test="resourceValue != null and resourceValue != ''"> and resource_value = #{resourceValue}</if>
<if test="resourceType != null and resourceType != ''"> and resource_type = #{resourceType}</if>
<if test="resourceName != null and resourceName != ''"> and resource_name like concat(#{resourceName}, '%')</if>
<if test="appId != null and appId != ''"> and app_id = #{appId}</if>
<if test="appName != null and appName != ''"> and app_name like concat(#{appName}, '%')</if>
<if test="deptId != null "> and dept_id = #{deptId}</if>
<if test="deptName != null and deptName != ''"> and dept_name like concat(#{deptName}, '%')</if>
deleted = 0
<if test="resourceLibrary.resource != null and resourceLibrary.resource != ''">and resource like concat(#{resourceLibrary.resource}, '%')</if>
<if test="resourceLibrary.resourceValue != null and resourceLibrary.resourceValue != ''">and resource_value = #{resourceLibrary.resourceValue}</if>
<if test="resourceLibrary.resourceType != null and resourceLibrary.resourceType != ''">and resource_type = #{resourceLibrary.resourceType}</if>
<if test="resourceLibrary.resourceName != null and resourceLibrary.resourceName != ''">and resource_name like concat(#{resourceLibrary.resourceName},
'%')
</if>
<if test="resourceLibrary.appId != null and resourceLibrary.appId != ''">and app_id = #{resourceLibrary.appId}</if>
<if test="resourceLibrary.appName != null and resourceLibrary.appName != ''">and app_name like concat(#{resourceLibrary.appName}, '%')</if>
<if test="resourceLibrary.deptId != null ">and dept_id = #{resourceLibrary.deptId}</if>
<if test="resourceLibrary.deptName != null and resourceLibrary.deptName != ''">and dept_name like concat(#{resourceLibrary.deptName}, '%')</if>
<if test="appIdList != null">and find_in_set(app_id,#{appIdList})</if>
</where>
</select>
</mapper>

+ 5
- 0
ruoyi-common/pom.xml Dosyayı Görüntüle

@@ -163,6 +163,11 @@
<version>1.18.10</version>
</dependency>

<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.2</version>
</dependency>

</dependencies>


+ 1
- 1
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java Dosyayı Görüntüle

@@ -37,7 +37,7 @@ public class RyTask {
*/
public void runAppNow() throws IllegalAccessException {
log.debug("执行顺序启动应用开始");
applyPlanService.execPlan(null);
applyPlanService.execPlan(null,null);
log.debug("执行顺序启动应用结束");
}



Yükleniyor…
İptal
Kaydet