欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Activiti6在Springboot下的使用 2 动态部署流程与通用complete方法

程序员文章站 2022-04-30 23:06:08
...

说明

上一节我们使用Springboot与Activiti6进行整合,介绍了Activiti提供的一些service的使用方法,现在我们来实践一下动态部署流程(BPMN文件),部分为伪代码,请意会

快速开始

1 动态部署

编写一个接收文件的Controller

@RestController
@RequestMapping("/process")
public class ProcessController {

    // 仓库服务类
    @Autowired
    private RepositoryService repositoryService;

    // 上传一个bpmn文件
    @RequestMapping(value = "/uploadOneBpmnFile",method = RequestMethod.POST)
    public void uploadOneBpmnFile(@RequestParam("file") MultipartFile file, HttpServletRequest request){
        String users_id = (String) request.getAttribute("users_id");
//        System.out.println("getOriginalFilename:" + file.getOriginalFilename());
        String originalFilename = file.getOriginalFilename();
        // 后缀
        String suffix = UploadFileMgr.getFileSuffix(originalFilename);
        // 前缀
        String prefix = UploadFileMgr.getFilePrefix(originalFilename);
        String uuidName = UUID.randomUUID().toString();
        if (!file.isEmpty()) {
            try {
//              通过工具类保存文件
                UploadFileMgr.saveFile(file, "bpmn/", uuidName, suffix);
                LOGGER.info("用户:{} 新上传了一个bpmn文件,id:{}.{}", userId, uuidName, suffix);
            } catch (FileNotFoundException e) {
                LOGGER.error("上传失败,{}", e);
            } catch (Exception e) {
                LOGGER.error("上传失败,{}", e);
            }
        } else {
            LOGGER.error("上传失败,因为文件是空的");
        }
    }

    // 部署一个流程bpmn
    @RequestMapping(value = "/deploymentOneProcess",method = RequestMethod.POST)
    public void deploymentOneProcess(@RequestBody ProcessesVO processesVO, HttpServletRequest request){
        String users_id = (String) request.getAttribute("users_id");
        processesVO.setCreateUserName(users_id);
        try {
            Deployment deployment = repositoryService.createDeployment()//创建一个部署对象
                    .name(processesVO.getName())
                    .addInputStream(processesVO.getProcessesId(), ReadFileUtil.readFileByBytesAndFileName("bpmn/", processesVO.getProcessesId()))
                    .deploy();
            LOGGER.info("部署ID:{}  部署名称:{}", deployment.getId(), deployment.getName());
        } catch (Exception e) {
            LOGGER.error("发生异常 msg={}", "原因", e);
        }
    }

}

大致的思想就是先接收前端传来的BPMN文件,保存到指定的目录下,返回给前端生成的UUID(或保存进数据库),然后需要部署的话前端发送需要部署的BPMN的id,后端从目录使用文件流的方式读取文件然后调用repositoryService进行部署。

2 通用complete()

编写通用complete()的难点主要在于同一个流程会存在不同的运行实例,所以我们可以多创建一张apply(申请表),当我们为某个请求指定对应的流程并开启后,将生成的流程实例id存进apply表里,下次直接通过apply表拿到流程实例id,然后直接complete(),例如:

1 开启流程

                ProcessInstance instance = runtimeService.startProcessInstanceByKey(proKey);

                System.out.println("流程实例ID:" + instance.getId());
                System.out.println("流程定义ID:" + instance.getProcessDefinitionId());

                // 记录该请求的实例id
                applyEntity.setProInstanceId(instance.getId());
                applyMapper.updateByPrimaryKey(applyEntity);

2 完成任务

Task task = taskService.createTaskQuery()
                        .processInstanceId(applyEntity.getProInstanceId())
                        .singleResult();
            taskService.complete(task.getId());

到这里我们已经能够完整的动态开启和部署一个流程了,但是实际情况中任务不可能会这么简单ヽ(ー_ー)ノ,我们这么一个通用的complete()方法肯定是不够的用的,比如说我们希望每一个Task都由不同的Service去处理(可以在这里发邮件啊、分并分支啊、驳回请求啊等等操作),下面一节将提供一种动态调用不同Service的思路