SpringBoot整合Flowable快速实现工作流(高考最后一天,高考加油)

最后

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书+2021年最新大厂面试题。
在这里插入图片描述

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • Task

Task 就是当前要做的工作。

实际上这里涉及到的东西比较多,不过我们今天先整一个简单的例子,所以上面这些知识点暂时够用了。

4.2 查看流程图

在正式开始之前,我们先准备一个接口,用来查看流程图的实时执行情况,这样方便我们查看流程到底执行到哪一步了。

具体的代码如下:


@RestController

public class HelloController {



    @Autowired

    RuntimeService runtimeService;



    @Autowired

    TaskService taskService;



    @Autowired

    RepositoryService repositoryService;



    @Autowired

    ProcessEngine processEngine;



    @GetMapping("/pic")

    public void showPic(HttpServletResponse resp, String processId) throws Exception {

        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();

        if (pi == null) {

            return;

        }

        List<Execution> executions = runtimeService

                .createExecutionQuery()

                .processInstanceId(processId)

                .list();



        List<String> activityIds = new ArrayList<>();

        List<String> flows = new ArrayList<>();

        for (Execution exe : executions) {

            List<String> ids = runtimeService.getActiveActivityIds(exe.getId());

            activityIds.addAll(ids);

        }



        /**

         * 生成流程图

         */

        BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());

        ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();

        ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();

        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0, false);

        OutputStream out = null;

        byte[] buf = new byte[1024];

        int legth = 0;

        try {

            out = resp.getOutputStream();

            while ((legth = in.read(buf)) != -1) {

                out.write(buf, 0, legth);

            }

        } finally {

            if (in != null) {

                in.close();

            }

            if (out != null) {

                out.close();

            }

        }

    }

}



这就一个工具,没啥好说的,一会大家看完后面的代码,再回过头来看这个接口,很多地方就都懂了。

4.3 开启一个流程

为了方便,接下来的代码我们都在单元测试中完成。

首先我们来开启一个流程,代码如下:


String staffId = "1000";

/**

 * 开启一个流程

 */

@Test

void askForLeave() {

    HashMap<String, Object> map = new HashMap<>();

    map.put("leaveTask", staffId);

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ask_for_leave", map);

    runtimeService.setVariable(processInstance.getId(), "name", "javaboy");

    runtimeService.setVariable(processInstance.getId(), "reason", "休息一下");

    runtimeService.setVariable(processInstance.getId(), "days", 10);

    logger.info("创建请假流程 processId:{}", processInstance.getId());

}



首先由员工发起一个请假流程,map 中存放的 leaveTask 是我们在 XML 流程文件中提前定义好的,提前定义好当前这个任务创建之后,该由谁来处理,这里我们是假设由工号为 1000 的员工来发起这样一个请假流程。同时,我们还设置了一些额外信息。ask_for_leave 是我们在 XML 文件中定义的一个 process 的名称。

好啦,现在我们执行这个单元测试方法,执行完成后,控制台会打印出当前这个流程的 id,我们拿着这个 id 去访问 4.2 小节的接口,结果如下:

可以看到,请假用红色的框框起来了,说明当前流程走到了这一步。

4.4 将请求提交给组长

接下来,我们就需要将这个请假流程向后推进一步,将请假事务提交给组长,代码如下:


String zuzhangId = "90";

/**

 * 提交给组长审批

 */

@Test

void submitToZuzhang() {

    //员工查找到自己的任务,然后提交给组长审批

    List<Task> list = taskService.createTaskQuery().taskAssignee(staffId).orderByTaskId().desc().list();

    for (Task task : list) {

        logger.info("任务 ID:{};任务处理人:{};任务是否挂起:{}", task.getId(), task.getAssignee(), task.isSuspended());

        Map<String, Object> map = new HashMap<>();

        //提交给组长的时候,需要指定组长的 id

        map.put("zuzhangTask", zuzhangId);

        taskService.complete(task.getId(), map);

    }

}



首先我们利用 staffId 查找到当前员工的 id,进而找到当前员工需要执行的任务,遍历这个任务,调用 taskService.complete 方法将任务提交给组长,注意在 map 中指定组长的 id。

提交完成后,我们再去看流程图片,如下:

可以看到,流程图走到组长审批了。

4.5 组长审批

组长现在有两种选择,同意或者拒绝,同意的代码如下:


/**

 * 组长审批-批准

 */

@Test

void zuZhangApprove() {

    List<Task> list = taskService.createTaskQuery().taskAssignee(zuzhangId).orderByTaskId().desc().list();

    for (Task task : list) {

        logger.info("组长 {} 在审批 {} 任务", task.getAssignee(), task.getId());

        Map<String, Object> map = new HashMap<>();

        //组长审批的时候,如果是同意,需要指定经理的 id

        map.put("managerTask", managerId);

        map.put("checkResult", "通过");

        taskService.complete(task.getId(), map);

    }

}



通过组长的 id 查询组长的任务,同意的话,需要指定经理,也就是这个流程下一步该由谁来处理。

拒绝的代码如下:


/**

 * 组长审批-拒绝

 */

@Test

void zuZhangReject() {

    List<Task> list = taskService.createTaskQuery().taskAssignee(zuzhangId).orderByTaskId().desc().list();

    for (Task task : list) {

        logger.info("组长 {} 在审批 {} 任务", task.getAssignee(), task.getId());

        Map<String, Object> map = new HashMap<>();

        //组长审批的时候,如果是拒绝,就不需要指定经理的 id

        map.put("checkResult", "拒绝");

        taskService.complete(task.getId(), map);

    }

}



拒绝的话,就没那么多事了,直接设置 checkResult 为拒绝即可。

假设这里执行了同意,那么流程图如下:

4.6 经理审批

经理审批和组长审批差不多,只不过经理这里是最后一步了,不需要再指定下一位处理人了,同意的代码如下:


/**

 * 经理审批自己的任务-批准

 */

@Test

void managerApprove() {

    List<Task> list = taskService.createTaskQuery().taskAssignee(managerId).orderByTaskId().desc().list();

    for (Task task : list) {

        logger.info("经理 {} 在审批 {} 任务", task.getAssignee(), task.getId());

        Map<String, Object> map = new HashMap<>();

        map.put("checkResult", "通过");

        taskService.complete(task.getId(), map);

    }

}



拒绝代码如下:


/**

 * 经理审批自己的任务-拒绝

 */

@Test

void managerReject() {

    List<Task> list = taskService.createTaskQuery().taskAssignee(managerId).orderByTaskId().desc().list();

    for (Task task : list) {

        logger.info("经理 {} 在审批 {} 任务", task.getAssignee(), task.getId());

        Map<String, Object> map = new HashMap<>();

        map.put("checkResult", "拒绝");

        taskService.complete(task.getId(), map);

    }

}



4.7 拒绝流程

如果组长拒绝了或者经理拒绝了,我们也有相应的处理方案,首先在 XML 流程文件定义时,如下:


<serviceTask id="sendMail" flowable:exclusive="true" name="发送失败提示" isForCompensation="true" flowable:class="org.javaboy.flowable.AskForLeaveFail"/>



如果请假被拒绝,会进入到这个 serviceTask,serviceTask 对应的处理类是 org.javaboy.flowable.AskForLeaveFail,该类的代码如下:


public class AskForLeaveFail implements JavaDelegate {

    @Override

    public void execute(DelegateExecution execution) {

        System.out.println("请假失败。。。");

    }


# 总结

蚂蚁面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。

* * *

**经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有**:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。

![蚂蚁金服5面,总结了49个面试题,遇到的面试官都是P7级别以上](https://img-blog.csdnimg.cn/img_convert/ddbd189396cd4a385c8467088a05d98b.webp?x-oss-process=image/format,png)

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

面试比较重视基础,所以Java那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年1班,很有青春的感觉。面试官基本水平都比较高,基本都P7以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。

* * *

**经历这次面试我还通过一些渠道发现了需要大厂真实面试主要有**:蚂蚁金服、拼多多、阿里云、百度、唯品会、携程、丰巢科技、乐信、软通动力、OPPO、银盛支付、中国平安等初,中级,高级Java面试题集合,附带超详细答案,希望能帮助到大家。

[外链图片转存中...(img-vidxNPQk-1715468177695)]

> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)收录**

**[需要这份系统化的资料的朋友,可以点击这里获取](https://bbs.csdn.net/forums/4f45ff00ff254613a03fab5e56a57acb)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值