diff --git a/ruoyi-admin/src/main/resources/application-test.yml b/ruoyi-admin/src/main/resources/application-test.yml index fc67ebb..9ceb3de 100644 --- a/ruoyi-admin/src/main/resources/application-test.yml +++ b/ruoyi-admin/src/main/resources/application-test.yml @@ -1,7 +1,7 @@ # 项目相关配置 ruoyi: # 文件路径 示例( Windows配置D:/poject,Linux配置 /home/poject) - profile: /home/pojectFile + profile: /home/pojectFile/ # Spring配置 数据源配置 spring: # redis 配置 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 6dc1481..c832852 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -52,7 +52,7 @@ spring: # 国际化资源文件路径 basename: i18n/messages profiles: - active: dev + active: test # 文件上传 servlet: multipart: diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java b/ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java index cd16db1..a63dffc 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/controller/ApplyPlanController.java @@ -4,23 +4,20 @@ import java.util.List; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import com.ruoyi.business.domain.bo.AddApplyPlanBO; import com.ruoyi.business.domain.bo.JobQueryBO; +import com.ruoyi.business.domain.bo.YinDaoCallBackBO; import com.ruoyi.common.utils.bean.BeanUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; @@ -39,10 +36,33 @@ import com.ruoyi.common.core.page.TableDataInfo; @Api(tags = "应用执行计划管理接口") @RestController @RequestMapping("/business/ctApplyPlan") +@Slf4j public class ApplyPlanController extends BaseController { @Autowired private IApplyPlanService applyPlanService; + + @PostMapping("/callBack/updatePlanStatus") + public void updatePlanStatus(@RequestParam(required = false) String bodyMd5, @RequestParam(required = false) Long timestamp, + @RequestParam(required = false) String sign, @RequestBody String body) { + log.info("fake callback: bodyMd5:{}", bodyMd5); + log.info("fake callback: sign:{}", sign); + log.info("fake callback: timestamp:{}", timestamp); + log.info("fake callback: body:{}", body); + + YinDaoCallBackBO yinDaoCallBackBO = JSONObject.parseObject(body, YinDaoCallBackBO.class); + // 获取应用名称 task_uuid + if (applyPlanService.ydCallBack(yinDaoCallBackBO)) { + log.debug("任务id:" + yinDaoCallBackBO.getJobUuid() + "回调成功,回调状态:" + yinDaoCallBackBO.getStatus()); + }else{ + log.debug("任务id:" + yinDaoCallBackBO.getJobUuid() + "回调失败,回调状态:" + yinDaoCallBackBO.getStatus()); + } + //异步处理业务 + // new Runable() -> { + // do things + // } + } + /** * 重新运行 */ @@ -90,7 +110,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 +121,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)); } diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/controller/ResourceLibraryController.java b/ruoyi-business/src/main/java/com/ruoyi/business/controller/ResourceLibraryController.java index dbfdd13..631bf09 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/controller/ResourceLibraryController.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/controller/ResourceLibraryController.java @@ -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 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 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 appIdList = applyService.lambdaQuery().eq(Apply::getDeptId, SecurityUtils.getDeptId()).list().stream().map(Apply::getAppId).collect(Collectors.toList()); + startPage(); + List list = resourceLibraryService.list(resourceLibrary, appIdList); + return getDataTable(list); + } else { + startPage(); + List 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 list = resourceLibraryService.list(resourceLibrary); - ExcelUtil util = new ExcelUtil(ResourceLibrary.class); - util.exportExcel(response, list, "资源库管理数据"); + public void export(HttpServletResponse response, ResourceLibrary resourceLibrary) { + List 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 list = resourceLibraryService.list(resourceLibrary, appIdList); + ExcelUtil util = new ExcelUtil(ResourceLibrary.class); + util.exportExcel(response, list, "资源库管理数据"); + } else { + List list = resourceLibraryService.list(resourceLibrary, null); + ExcelUtil util = new ExcelUtil(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))); } } 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 146fe8c..c40a396 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 @@ -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; diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddApplyPlanBO.java b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddApplyPlanBO.java index 301be5f..4df8449 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddApplyPlanBO.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddApplyPlanBO.java @@ -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 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 resourceLibrarieList; + @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddBatchResourceLibraryBO.java b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddBatchResourceLibraryBO.java new file mode 100644 index 0000000..07d1a9c --- /dev/null +++ b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/AddBatchResourceLibraryBO.java @@ -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 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(); + } +} diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/ApplyStartBO.java b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/ApplyStartBO.java index cba9d40..b8d085b 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/ApplyStartBO.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/ApplyStartBO.java @@ -65,17 +65,17 @@ public class ApplyStartBO { @Excel(name = "计划参数") @ApiModelProperty(name="planParams",value = "计划参数") private String planParams; + /** * 应用运行参数 - *

+ * * 非必填 */ - private List planParamsList; + private List params; /** * 等待超时时间 * - * @see com.xybot.api.sdk.enums.WaitTimeoutEnum *

* 非必填,不填,默认为10分钟 */ @@ -83,8 +83,6 @@ public class ApplyStartBO { /** * 优先级 - * - * @see com.xybot.api.sdk.enums.PriorityEnum * 非必填,不填,默认为middle */ private String priority; diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/YinDaoCallBackBO.java b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/YinDaoCallBackBO.java new file mode 100644 index 0000000..159b883 --- /dev/null +++ b/ruoyi-business/src/main/java/com/ruoyi/business/domain/bo/YinDaoCallBackBO.java @@ -0,0 +1,69 @@ +package com.ruoyi.business.domain.bo; + +import lombok.Data; + +import java.util.List; + +/** + * 任务结果数据对象 + */ +@Data +public class YinDaoCallBackBO { + /** + * 参考 DataTypeEnum + */ + private String dataType; + + /** + * 应用运行uuid + */ + private String jobUuid; + /** + * @see YinDaoCallBackBO + */ + private String status; + /** + * 运行描述 + */ + private String msg; + /** + * 应用运行参数 + */ + private List result; + /** + * 任务开始运行的时间 + */ + private String startTime; + + /** + * 任务结束运行的时间 + */ + private String endTime; + /** + * 执行的机器人uuid + */ + private String robotClientUuid; + + /** + * 机器人名称 + */ + private String robotClientName; + /** + * 应用名 + */ + private String robotName; + + /** + * 应用运行参数 + */ + @Data + public static class RobotParam { + // 参数名 + private String name; + // 参数值 + private String value; + // 参数类型 + private String type; + + } +} diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/mapper/ResourceLibraryMapper.java b/ruoyi-business/src/main/java/com/ruoyi/business/mapper/ResourceLibraryMapper.java index 441e0f4..2d6517b 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/mapper/ResourceLibraryMapper.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/mapper/ResourceLibraryMapper.java @@ -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 /** * 查询资源库管理列表 - * + * * @param resourceLibrary 资源库管理 * @return 资源库管理集合 */ - List selectResourceLibraryList(ResourceLibrary resourceLibrary); + List selectResourceLibraryList(@Param("resourceLibrary") ResourceLibrary resourceLibrary, @Param("appIdList") String appIdList); } 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 eb30498..8f97fbb 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 @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.business.domain.bo.AddApplyPlanBO; import com.ruoyi.business.domain.bo.ApplyStartBO; import com.ruoyi.business.domain.bo.JobQueryBO; +import com.ruoyi.business.domain.bo.YinDaoCallBackBO; import com.ruoyi.business.domain.vo.JobQueryVO; /** @@ -16,6 +17,14 @@ import com.ruoyi.business.domain.vo.JobQueryVO; * @date 2024-06-14 */ public interface IApplyPlanService extends IService { + /** + * 影刀回调逻辑 + * + * @param + * @return + */ + boolean ydCallBack(YinDaoCallBackBO yinDaoCallBackBO) ; + /** * 重新运行 @@ -47,7 +56,7 @@ public interface IApplyPlanService extends IService { * * @return */ - boolean execPlan(ApplyStartBO applyStartBO) throws IllegalAccessException; + boolean execPlan(ApplyStartBO applyStartBO,ApplyPlan applyPlan) throws IllegalAccessException; /** * 定时查询指定时间执行的数据 diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/service/IResourceLibraryService.java b/ruoyi-business/src/main/java/com/ruoyi/business/service/IResourceLibraryService.java index d762945..aa0c62b 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/service/IResourceLibraryService.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/service/IResourceLibraryService.java @@ -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 -{ +public interface IResourceLibraryService extends IService { + + /** + * 批量添加参数 + * + * @param addBatchResourceLibraryBO + */ + boolean addBatch(AddBatchResourceLibraryBO addBatchResourceLibraryBO); /** * 查询资源库管理列表 - * + * * @param resourceLibrary 资源库管理 * @return 资源库管理集合 */ - List list(ResourceLibrary resourceLibrary); + List list(ResourceLibrary resourceLibrary, List appIdList); } 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 d5bc6ea..9cfe8a8 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,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,20 @@ 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.DateUtils; 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 +64,40 @@ public class ApplyPlanServiceImpl extends ServiceImpl finalState = new ArrayList<>(); + finalState.add(PlanRunStatus.FINISH.getKey()); + finalState.add(PlanRunStatus.STOPPED.getKey()); + finalState.add(PlanRunStatus.ERROR.getKey()); + finalState.add(PlanRunStatus.SKIPPED.getKey()); + finalState.add(PlanRunStatus.CANCEL.getKey()); + // 如果是终态 + if (StringUtils.isNotEmpty(yinDaoCallBackBO.getRobotClientName()) && finalState.contains(yinDaoCallBackBO.getStatus())) { + Rebot rebot = new Rebot(); + rebot.setStatus(RebotStatus.IDLE.getKey()); + return rebotService.lambdaUpdate().eq(Rebot::getRobotClientName, yinDaoCallBackBO.getRobotClientName()).update(rebot); + } else { + return isUpdate; + } + + } + /** * 重新运行 * @@ -92,40 +134,168 @@ public class ApplyPlanServiceImpl extends ServiceImpl 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(2, 10, TimeUnit.SECONDS); + if (isLocked) { + List 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 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 listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); + if (listRebotVos.isEmpty()) { + log.debug("暂无空闲机器人"); + // 刷新机器人数据 // rebotService.syn(new Rebot()); - return false; + return false; + } + List 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 paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class); + applyStartBO.setParams(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(2, 10, TimeUnit.SECONDS); + if (isLocked) { + // 先查计划,避免每次命中第三方接口 + List 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 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 listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); + if (listRebotVos.isEmpty()) { + log.debug("暂无空闲机器人"); + // 刷新机器人数据 +// rebotService.syn(new Rebot()); + return false; + } + List 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 paramList = JSON.parseArray(e.getPlanParams(), ApplyStartBO.RobotParam.class); - applyStartBO.setPlanParamsList(paramList); + applyStartBO.setParams(paramList); } } + try { JobStartVO jobStartVO = YinDaoHttpUtils.appStart(applyStartBO); ApplyPlan applyPlan = new ApplyPlan(); @@ -133,139 +303,55 @@ public class ApplyPlanServiceImpl extends ServiceImpl applyPlanList = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.TREE.getKey()).list(); - if (applyPlanList.isEmpty()) { - return false; - } - // 需要执行的计划 - List 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 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"); - - // 如果应用支持参数 - if (!Objects.isNull(e.getSupportParam()) && e.getSupportParam() == 1) { - // 获取参数 - if (StringUtils.isNotEmpty(e.getPlanParams())) { - applyStartBO.setPlanParams(e.getPlanParams()); - List 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 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); - } - }); - }); - return false; } - /** * 获取应用执行结果 * @@ -283,7 +369,7 @@ public class ApplyPlanServiceImpl extends ServiceImpl list = this.lambdaQuery().notIn(ApplyPlan::getTaskStatus, noStatus).isNotNull(ApplyPlan::getTaskStatus).orderByAsc(ApplyPlan::getPriority).list(); + List 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 +386,13 @@ 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; - } + 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> applyPlanMap = this.lambdaQuery().eq(ApplyPlan::getExcType, ExcTypeStatus.ONE.getKey()).isNull(ApplyPlan::getTaskUuid) + .orderByAsc(ApplyPlan::getPriority).list().stream().collect(Collectors.groupingBy(ApplyPlan::getDeptId)); - ListRebotBO listRebotBO = new ListRebotBO(); - listRebotBO.setStatus(RebotStatus.IDLE.getKey()); - listRebotBO.setPage(1); - listRebotBO.setSize(100); - // 只获取空闲的机器人 - List listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); - if (listRebotVos.isEmpty()) { - log.debug("暂无空闲机器人"); - // 刷新机器人数据 -// rebotService.syn(new Rebot()); - return false; - } + // 查询所有待执行的任务 + if (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))); + ListRebotBO listRebotBO = new ListRebotBO(); + listRebotBO.setStatus(RebotStatus.IDLE.getKey()); + listRebotBO.setPage(1); + listRebotBO.setSize(100); + // 只获取空闲的机器人 + List listRebotVos = YinDaoHttpUtils.listRebot(listRebotBO); + if (listRebotVos.isEmpty()) { + log.debug("暂无空闲机器人"); + return false; + } - 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 paramList = JSON.parseArray(applyPlan.getPlanParams(), ApplyStartBO.RobotParam.class); - applyStartBO.setPlanParamsList(paramList); + // 获取每个部门优先级最高的计划 + List applyPlans = new ArrayList<>(); + applyPlanMap.forEach((k, v) -> { + v.sort((Comparator.comparingInt(ApplyPlan::getPriority))); + applyPlans.add(v.get(0)); + }); + if (applyPlans.isEmpty()) { + log.debug("没有等待执行的计划"); + return false; + } + applyPlans.sort((Comparator.comparingInt(ApplyPlan::getPriority))); + + for (ListRebotVO listRebotVO : listRebotVos) { + if (applyPlans.isEmpty()) { + log.debug("没有等待执行的计划!"); + continue; + } + applyPlan = applyPlans.get(0); + applyStartBO = new ApplyStartBO(); + applyStartBO.setRobotUuid(applyPlan.getAppId()); + //high 高 middle 中 low 低 + applyStartBO.setPriority("high"); + applyStartBO.setAccountName(listRebotVO.getRobotClientName()); + // 如果应用支持参数 + if (!Objects.isNull(applyPlan.getSupportParam()) && applyPlan.getSupportParam() == 1) { + if (StringUtils.isNotEmpty(applyPlan.getPlanParams())) { + applyStartBO.setPlanParams(applyPlan.getPlanParams()); + List paramList = JSON.parseArray(applyPlan.getPlanParams(), ApplyStartBO.RobotParam.class); + applyStartBO.setParams(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)) { + 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 +533,97 @@ public class ApplyPlanServiceImpl extends ServiceImpl applyPlanList = new ArrayList<>(); Map> 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 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) { + applyPlan.setSupportParam(apply.getSupportParam()); + // 获取参数 每一次执行计划的参数都是独立的 + List 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 applyPlanList = new ArrayList<>(); - Map> 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> 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); } diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyServiceImpl.java b/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyServiceImpl.java index 7434828..318b45e 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyServiceImpl.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ApplyServiceImpl.java @@ -5,7 +5,9 @@ import java.util.Map; import java.util.stream.Collectors; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.ruoyi.business.domain.ApplyPlan; import com.ruoyi.business.domain.Rebot; +import com.ruoyi.business.domain.ResourceLibrary; import com.ruoyi.business.domain.bo.ApplyStartBO; import com.ruoyi.business.domain.bo.JobQueryBO; import com.ruoyi.business.domain.bo.ListApplyBO; @@ -14,6 +16,8 @@ import com.ruoyi.business.domain.vo.JobQueryVO; import com.ruoyi.business.domain.vo.JobStartVO; import com.ruoyi.business.domain.vo.ListApplyVO; import com.ruoyi.business.domain.vo.ListRebotVO; +import com.ruoyi.business.service.IApplyPlanService; +import com.ruoyi.business.service.IResourceLibraryService; import com.ruoyi.business.util.YinDaoHttpUtils; import com.ruoyi.common.annotation.DataScope; import com.ruoyi.common.core.domain.entity.SysDept; @@ -40,6 +44,13 @@ public class ApplyServiceImpl extends ServiceImpl implements @Autowired private ISysDeptService sysDeptService; + + @Autowired + private IResourceLibraryService resourceLibraryService; + + @Autowired + private IApplyPlanService applyPlanService; + /** * 启动应用 * @@ -98,7 +109,7 @@ public class ApplyServiceImpl extends ServiceImpl implements BeanUtils.copyBeanProp(newApply, listRebotVO); newApply.setAppCreateTime(listRebotVO.getCreateTime()); newApply.setAppUpdateTime(listRebotVO.getUpdateTime()); - if(null != sysDepts){ + if (null != sysDepts) { newApply.setDeptId(sysDepts.get(0).getDeptId()); newApply.setDeptName(sysDepts.get(0).getDeptName()); } @@ -110,11 +121,21 @@ public class ApplyServiceImpl extends ServiceImpl implements newApply.setAppCreateTime(listRebotVO.getCreateTime()); newApply.setAppUpdateTime(listRebotVO.getUpdateTime()); newApply.setId(apply.getId()); - if(null != sysDepts){ + newApply.setSupportParam(listRebotVO.getSupportParam()); + if (null != sysDepts) { newApply.setDeptId(sysDepts.get(0).getDeptId()); newApply.setDeptName(sysDepts.get(0).getDeptName()); } + // 修改应用名称 updateById(newApply); + // 修改参数里应用名称 + ResourceLibrary resourceLibrary = new ResourceLibrary(); + resourceLibrary.setAppName(listRebotVO.getAppName()); + resourceLibraryService.lambdaUpdate().eq(ResourceLibrary::getAppId, apply.getId()).update(resourceLibrary); + // 修改已执行的计划应用名称 + ApplyPlan applyPlan = new ApplyPlan(); + applyPlan.setAppName(listRebotVO.getAppName()); + applyPlanService.lambdaUpdate().eq(ApplyPlan::getAppId, apply.getId()).update(applyPlan); } }); } diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ResourceLibraryServiceImpl.java b/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ResourceLibraryServiceImpl.java index 6fd5cb2..401b3d3 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ResourceLibraryServiceImpl.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/ResourceLibraryServiceImpl.java @@ -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 implements IResourceLibraryService -{ +public class ResourceLibraryServiceImpl extends ServiceImpl 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 resourceLibraries = new ArrayList<>(); + // stream统计对象里重复的字段 + Map 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 list(ResourceLibrary resourceLibrary) - { - return baseMapper.selectResourceLibraryList(resourceLibrary); + public List list(ResourceLibrary resourceLibrary, List 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()); diff --git a/ruoyi-business/src/main/java/com/ruoyi/business/util/YinDaoHttpUtils.java b/ruoyi-business/src/main/java/com/ruoyi/business/util/YinDaoHttpUtils.java index def2b8f..86f87fb 100644 --- a/ruoyi-business/src/main/java/com/ruoyi/business/util/YinDaoHttpUtils.java +++ b/ruoyi-business/src/main/java/com/ruoyi/business/util/YinDaoHttpUtils.java @@ -2,6 +2,7 @@ package com.ruoyi.business.util; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONArray; import com.ruoyi.business.domain.bo.*; import com.ruoyi.business.domain.vo.*; import com.ruoyi.business.yddoman.BaseDTO; @@ -12,10 +13,8 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpClientUtil; import lombok.extern.slf4j.Slf4j; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * 影刀请求工具类 @@ -44,14 +43,28 @@ public class YinDaoHttpUtils { private static final String QUERY_APP_START_RESULT = REQUEST_PREFIX + "/dispatch/v2/job/query"; // 查询应用运行日志(异常时可以查询原因) private static final String QUERY_APP_START_RESULT_LOG = REQUEST_PREFIX + "/dispatch/v2/job/list"; + // 服务器ip + private static final String SERVER_URL = "http://192.168.10.214:9000"; /** * 启动应用 */ public static JobStartVO appStart(ApplyStartBO applyStartBO) throws IllegalAccessException { + if (!Objects.isNull(applyStartBO.getPlanParams())) { + List robotParams = JSON.parseArray(applyStartBO.getPlanParams(), ApplyStartBO.RobotParam.class); + List newParamList = robotParams.stream().peek(e -> { + if ("file".equals(e.getType())) { + e.setValue(SERVER_URL + e.getValue()); + } + }).collect(Collectors.toList()); + applyStartBO.setParams(newParamList); + log.debug("请求的参数:" + applyStartBO.getParams()); + } + // 实体类转map Map data = BeanToMapUtil.convertEntityToMap(applyStartBO); + BaseDTO baseDTO = sendPost(APP_START, data); return JSON.parseObject(baseDTO.getData().toString(), JobStartVO.class); } @@ -185,7 +198,11 @@ public class YinDaoHttpUtils { headMap.put("Content-Type", "application/json;charset=utf-8"); headMap.put("authorization", "Bearer " + getToken(tokenMap)); + log.debug("请求的url:" + url); + log.debug("请求的参数:" + JSONUtil.toJsonStr(map)); + log.debug("请求头:" + JSONUtil.toJsonStr(headMap)); String returnStr = HttpClientUtil.postJson(url, headMap, JSONUtil.toJsonStr(map), "utf-8"); + if (StringUtils.isEmpty(returnStr)) { throw new ServiceException("请求影刀接口失败"); } diff --git a/ruoyi-business/src/main/resources/mapper/business/ResourceLibraryMapper.xml b/ruoyi-business/src/main/resources/mapper/business/ResourceLibraryMapper.xml index c5f6f38..1479387 100644 --- a/ruoyi-business/src/main/resources/mapper/business/ResourceLibraryMapper.xml +++ b/ruoyi-business/src/main/resources/mapper/business/ResourceLibraryMapper.xml @@ -59,15 +59,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from ct_resource_library - deleted = 0 - and resource like concat(#{resource}, '%') - and resource_value = #{resourceValue} - and resource_type = #{resourceType} - and resource_name like concat(#{resourceName}, '%') - and app_id = #{appId} - and app_name like concat(#{appName}, '%') - and dept_id = #{deptId} - and dept_name like concat(#{deptName}, '%') + deleted = 0 + and resource like concat(#{resourceLibrary.resource}, '%') + and resource_value = #{resourceLibrary.resourceValue} + and resource_type = #{resourceLibrary.resourceType} + and resource_name like concat(#{resourceLibrary.resourceName}, + '%') + + and app_id = #{resourceLibrary.appId} + and app_name like concat(#{resourceLibrary.appName}, '%') + and dept_id = #{resourceLibrary.deptId} + and dept_name like concat(#{resourceLibrary.deptName}, '%') + and find_in_set(app_id,#{appIdList}) \ No newline at end of file diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index 783feac..f39c906 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -163,6 +163,11 @@ 1.18.10 + + org.redisson + redisson-spring-boot-starter + 3.16.2 + diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java index cb303b0..7ea7ec9 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java @@ -117,6 +117,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() // 上传文件 .antMatchers("/common/upload","/dev-api/profile/upload/**").permitAll() + // 影刀回调 + .antMatchers("/business/ctApplyPlan/callBack/updatePlanStatus").permitAll() // 除上面外的所有请求全部需要鉴权认证 .anyRequest().authenticated() .and() 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 8577f96..6d65f97 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 @@ -37,7 +37,7 @@ public class RyTask { */ public void runAppNow() throws IllegalAccessException { log.debug("执行顺序启动应用开始"); - applyPlanService.execPlan(null); + applyPlanService.execPlan(null,null); log.debug("执行顺序启动应用结束"); }