feat(dev_1.0.0_beta3):

1、工作流定时任务导入导出提交
This commit is contained in:
wodeyangzipingpingwuqi 2024-05-29 17:34:14 +08:00 committed by opensnail
parent 99cf046138
commit ae6f427d89
3 changed files with 81 additions and 4 deletions

View File

@ -1,6 +1,8 @@
package com.aizuda.snailjob.server.web.controller;
import cn.hutool.core.lang.Pair;
import com.aizuda.snailjob.common.core.annotation.OriginalControllerReturnValue;
import com.aizuda.snailjob.common.core.exception.SnailJobCommonException;
import com.aizuda.snailjob.server.common.dto.DecisionConfig;
import com.aizuda.snailjob.server.web.annotation.LoginRequired;
import com.aizuda.snailjob.server.web.annotation.RoleEnum;
@ -10,12 +12,18 @@ import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO;
import com.aizuda.snailjob.server.web.model.response.WorkflowDetailResponseVO;
import com.aizuda.snailjob.server.web.model.response.WorkflowResponseVO;
import com.aizuda.snailjob.server.web.service.WorkflowService;
import com.aizuda.snailjob.server.web.util.ExportUtils;
import com.aizuda.snailjob.server.web.util.ImportUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* @author xiaowoniu
@ -85,4 +93,22 @@ public class WorkflowController {
return workflowService.checkNodeExpression(decisionConfig);
}
@LoginRequired
@PostMapping(value = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public void importScene(@RequestPart("file") MultipartFile file) throws IOException {
if (file.isEmpty()) {
throw new SnailJobCommonException("请选择一个文件上传");
}
// 写入数据
workflowService.importWorkflowTask(ImportUtils.parseList(file, WorkflowRequestVO.class));
}
@LoginRequired
@PostMapping("/export")
@OriginalControllerReturnValue
public ResponseEntity<String> export(@RequestBody Set<Long> workflowIds) {
return ExportUtils.doExport(workflowService.exportWorkflowTask(workflowIds));
}
}

View File

@ -7,9 +7,12 @@ import com.aizuda.snailjob.server.web.model.request.WorkflowQueryVO;
import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO;
import com.aizuda.snailjob.server.web.model.response.WorkflowDetailResponseVO;
import com.aizuda.snailjob.server.web.model.response.WorkflowResponseVO;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import java.io.IOException;
import java.util.List;
import java.util.Set;
/**
* @author xiaowoniu
@ -35,4 +38,8 @@ public interface WorkflowService {
List<WorkflowResponseVO> getWorkflowNameList(String keywords, Long workflowId);
Pair<Integer, String> checkNodeExpression(DecisionConfig decisionConfig);
void importWorkflowTask(@Valid @NotEmpty(message = "导入数据不能为空") List<WorkflowRequestVO> requests);
String exportWorkflowTask(Set<Long> workflowIds);
}

View File

@ -1,5 +1,6 @@
package com.aizuda.snailjob.server.web.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.HashUtil;
@ -27,6 +28,7 @@ import com.aizuda.snailjob.server.job.task.support.WorkflowPrePareHandler;
import com.aizuda.snailjob.server.job.task.support.WorkflowTaskConverter;
import com.aizuda.snailjob.server.job.task.support.expression.ExpressionInvocationHandler;
import com.aizuda.snailjob.server.web.model.base.PageResult;
import com.aizuda.snailjob.server.web.model.request.SceneConfigRequestVO;
import com.aizuda.snailjob.server.web.model.request.UserSessionVO;
import com.aizuda.snailjob.server.web.model.request.WorkflowQueryVO;
import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO;
@ -34,20 +36,20 @@ import com.aizuda.snailjob.server.web.model.request.WorkflowRequestVO.NodeConfig
import com.aizuda.snailjob.server.web.model.response.WorkflowDetailResponseVO;
import com.aizuda.snailjob.server.web.model.response.WorkflowResponseVO;
import com.aizuda.snailjob.server.web.service.WorkflowService;
import com.aizuda.snailjob.server.web.service.convert.SceneConfigConverter;
import com.aizuda.snailjob.server.web.service.convert.WorkflowConverter;
import com.aizuda.snailjob.server.web.service.handler.WorkflowHandler;
import com.aizuda.snailjob.server.web.util.UserSessionUtils;
import com.aizuda.snailjob.template.datasource.access.AccessTemplate;
import com.aizuda.snailjob.template.datasource.access.ConfigAccess;
import com.aizuda.snailjob.template.datasource.persistence.mapper.JobMapper;
import com.aizuda.snailjob.template.datasource.persistence.mapper.WorkflowMapper;
import com.aizuda.snailjob.template.datasource.persistence.mapper.WorkflowNodeMapper;
import com.aizuda.snailjob.template.datasource.persistence.po.GroupConfig;
import com.aizuda.snailjob.template.datasource.persistence.po.Job;
import com.aizuda.snailjob.template.datasource.persistence.po.Workflow;
import com.aizuda.snailjob.template.datasource.persistence.po.WorkflowNode;
import com.aizuda.snailjob.template.datasource.persistence.po.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.graph.ElementOrder;
import com.google.common.graph.GraphBuilder;
import com.google.common.graph.MutableGraph;
@ -57,6 +59,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.stream.Collectors;
@ -339,4 +342,45 @@ public class WorkflowServiceImpl implements WorkflowService {
return Pair.of(StatusEnum.YES.getStatus(), StrUtil.EMPTY);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void importWorkflowTask(List<WorkflowRequestVO> requests) {
batchSaveWorkflowTask(requests, UserSessionUtils.currentUserSession().getNamespaceId());
}
@Override
public String exportWorkflowTask(Set<Long> workflowIds) {
List<Workflow> workflowList = workflowMapper.selectList(new LambdaQueryWrapper<Workflow>()
.eq(Workflow::getNamespaceId, UserSessionUtils.currentUserSession().getNamespaceId())
.eq(Workflow::getDeleted, StatusEnum.NO.getStatus())
// TODO 若导出全部需要分页查询避免一次拉取太多数据
.in(CollUtil.isNotEmpty(workflowIds), Workflow::getId, workflowIds)
);
List<WorkflowDetailResponseVO> workflowDetailResponseVOList = workflowList.stream().map(i -> getWorkflowDetail(i.getId())).collect(Collectors.toList());
return JsonUtil.toJsonString(workflowDetailResponseVOList);
}
private void batchSaveWorkflowTask(final List<WorkflowRequestVO> workflowRequestVOList, final String namespaceId) {
Set<String> groupNameSet = workflowRequestVOList.stream().map(i -> i.getGroupName()).collect(Collectors.toSet());
List<GroupConfig> groupConfigs = accessTemplate.getGroupConfigAccess()
.list(new LambdaQueryWrapper<GroupConfig>()
.select(GroupConfig::getGroupName)
.eq(GroupConfig::getNamespaceId, namespaceId)
.in(GroupConfig::getGroupName, groupNameSet)
);
Sets.SetView<String> notExistedGroupNameSet = Sets.difference(groupNameSet,
StreamUtils.toSet(groupConfigs, GroupConfig::getGroupName));
Assert.isTrue(CollUtil.isEmpty(notExistedGroupNameSet),
() -> new SnailJobServerException("导入失败. 原因: 组{}不存在", notExistedGroupNameSet));
for (final WorkflowRequestVO workflowRequestVO : workflowRequestVOList) {
checkExecuteInterval(workflowRequestVO);
workflowRequestVO.setId(null);
saveWorkflow(workflowRequestVO);
}
}
}