Flowable工作流的实现方案


话不多说直接上代码,GOGO

Flowable文档地址:https://tkjohn.github.io/flowable-userguide/

工作流的启动-审核

@Api(value = "FlowableApi", tags = "flow基础api")
@RestController
@RequestMapping("/flow/base")
public class FlowableApi {

    public static final Logger logger = LogManager.getLogger(FlowableApi.class);

    // 用户以及组管理服务
    @Resource
    private IdentityService identityService;

    // 模型服务
    @Resource
    private ModelService modelService;

    // 部署服务
    @Resource
    private RepositoryService repositoryService;

    @Autowired
    protected ManagementService managementService;
    // 流程实例服务
    @Resource
    private RuntimeService runtimeService;

    // 流程节点任务服务
    @Resource
    private TaskService taskService;

    // 历史数据服务
    @Resource
    private HistoryService historyService;

	//下面三个是业务类,根据自己的业务来引入
    @Autowired
    private SysServerFeign sysServerFeign;
    @Autowired
    private BusinessFeignClient businessFeignClient;
    @Autowired
    private BusinessCallBackService businessCallBackService;

	@ApiOperation(value = "启动流程")
    @Transactional
    @RequestMapping(value = "/startProcess", method = RequestMethod.POST)
    public String startProcess(@RequestBody ProcessInitParams processInitParams) {
        logger.info("审核流----进来了");
        // 设置发起人
        identityService.setAuthenticatedUserId(processInitParams.getOriginator());
        logger.info("审核流----发起人:" + processInitParams.getOriginator());
        //根据发起人判断业务条线设置参数  (业务块根据自己的业务来做)
        String userCode = processInitParams.getOriginator();
        Map<String, Object> variables = processInitParams.getVariables();
        String comCode = businessFeignClient.detailComCode(userCode);//根据用户编码查询归属机构的
        String userSource = "";
        if (StringUtils.isNotEmpty(userCode)) {
            userSource = sysServerFeign.getUserSourceLine(userCode);
            variables.put("line", userSource);
            processInitParams.setVariables(variables);
        } else {
            variables.put("line", "Car");
            processInitParams.setVariables(variables);
        }
        if(StringUtils.isNotEmpty(comCode)){
            variables.put("comCode", comCode);
            processInitParams.setVariables(variables);
        }
        logger.info("审核流----流转条件:" + userSource+"---------------"+comCode);

//        启动流程方式一
//        ProcessInstance instance = runtimeService.startProcessInstanceByKey(
//                processInitParams.getProcessDefinitionKey(),
//                processInitParams.getBusinessKey() + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()),
//                processInitParams.getVariables());
//        //启动流程方式二
        ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
                .processDefinitionKey(processInitParams.getProcessDefinitionKey().trim())
                .name(processInitParams.getFormName().trim() + ":" + processInitParams.getFormType())
                .businessKey(processInitParams.getBusinessKey() + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()).trim() + ":"
                        + processInitParams.getOriginator() + ":"
                        + processInitParams.getBusinessType().trim()
                        + ":" + System.currentTimeMillis())
                .variables(processInitParams.getVariables())
                .start();
        String processInstanceId = processInstance.getProcessInstanceId();
        //获取当前节点审核人编码目前只支持单个人
        String nameType = processInitParams.getFormName();
        String businessCode = processInitParams.getBusinessKey().substring(processInitParams.getBusinessKey().indexOf(":")+1);
        List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();//获取审核人
        logger.info("开始发送邮件+++++"+taskList.get(0));
        if (!ObjectUtils.isEmpty(taskList)){
            String templateId ="234123119";
            logger.info("开始发送邮件:");
            businessCallBackService.EmailMap(taskList,userCode,nameType, businessCode,templateId);
        }
        /**
         * 审核开始添加发送邮件目前只支持单个人
         * */
        logger.info("审核流----启动流程ProcessInstance instance:" + processInstance.getProcessInstanceId());
        return processInstance.getProcessInstanceId().toString();
    }

/**
     * 任务处理1
     *
     * @param params 任务 taskId,来自 ACT_RU_TASK
     * @return
     */
    @ApiOperation(value = "任务处理")
    @Transactional
    @RequestMapping(value = "/task/complete", method = RequestMethod.POST)
    public R task(@RequestBody CompleteTaskVo params) {
        if (StringUtils.isNotBlank(params.getProcessInstanceId())
                && StringUtils.isNotBlank(params.getTaskId())) {
            if(params.getVariables() == null){
                params.setVariables(new HashMap<>());
            }
            //进行控制流程的走向条件
            params.getVariables().put("coreSalesChannelDockedHisType", params.getCoreSalesChannelDockedHisType());
            params.getVariables().put("coreSalespeopleDockedHisType", params.getCoreSalespeopleDockedHisType());
            params.getVariables().put("coreSalesChanneType", params.getCoreSalesChanneType());
            if (StringUtils.isBlank(params.getUserCode())) {
                params.setUserCode(JwtTokenUtil.getUserCode());
            }
            //审核状态 自己定义 通过  不通过  之类的
            params.setVerifyStatus(VerifyStatus.VERIFY_STATUS_PASS.getKey());
            //1.查看当前任务是存在
            TaskEntity taskEntity = (TaskEntity) taskService.createTaskQuery().taskId(params.getTaskId()).singleResult();
            runtimeService.setVariable(taskEntity.getProcessInstanceId(), "verifyStatus", SysCode.VERIFY.OK);
             if (taskEntity != null) {
                String taskId = params.getTaskId();
                //2.委派处理
                if (DelegationState.PENDING.equals(taskEntity.getDelegationState())) {
                    //2.1生成历史记录
                    TaskEntity task = this.createSubTask(taskEntity, taskEntity.getId(), params.getUserCode());
                    taskService.complete(task.getId());
                    taskId = task.getId();
                    //2.2执行委派
                    taskService.resolveTask(params.getTaskId(), params.getVariables());
                } else {
                    //3.1修改执行人 其实我这里就相当于签收了
                    taskService.setAssignee(params.getTaskId(), params.getUserCode());
                    //List<Task> tasks = taskService.createTaskQuery().taskAssignee(params.getTaskId()).list();
                    taskEntity.getAssignee();
                    //3.2执行任务
//                    params.getVariables().put("verfiyStatus","1");
                    taskService.complete(params.getTaskId(), params.getVariables());
                    //修改业务数据
//                    businessCallBackService.updateBusinessData(params.getVariables());
                    String processInstanceId = taskEntity.getProcessInstanceId();
                    //发送短信
                    HistoricProcessInstance hi = historyService.createHistoricProcessInstanceQuery() //获取流程发起人
                      .processInstanceId(processInstanceId)
                            .singleResult();
                    String taskInitiator = hi.getStartUserId();//任务发起人
                    String typeName =  hi.getName().substring(0,hi.getName().indexOf(":"));//任务名称类型
                    String str = hi.getBusinessKey();
                    String businessCode = str.substring(str.indexOf(":")+1, str.indexOf(":",str.indexOf(":")+1)-12);//获取业务号
                    List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();//获取审核人
                    if (!ObjectUtils.isEmpty(taskList)){
                        String templateId= "234123119";
                        businessCallBackService.EmailMap(taskList,taskInitiator,typeName,businessCode,templateId);
                    }
                   /* Map<String, Object> variablesLocal = taskEntity.getVariablesLocal();
                    Object businessCode = variablesLocal.get("businessCode");*/
                    //4.处理加签父任务
                    String parentTaskId = taskEntity.getParentTaskId();
                    //获取下一节点审核人

                    if (StringUtils.isNotBlank(parentTaskId)) {
                        String tableName = managementService.getTableName(TaskEntity.class);
                        String sql = "select count(1) from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
                        long subTaskCount = taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).count();
                        if (subTaskCount == 0) {
                            Task task = taskService.createTaskQuery().taskId(parentTaskId).singleResult();
                            //处理前后加签的任务
                            taskService.resolveTask(parentTaskId);
                            if (FlowConstant.AFTER_ADDSIGN.equals(task.getScopeType())) {
                                taskService.complete(parentTaskId);
                            }
                        }
                    }
                }
                //String type = params.getType() == null ? CommentTypeEnum.SP.toString() : params.getType();
                String userName = sysServerFeign.getUserName(params.getUserCode());
                System.out.println(userName);
                //5.生成审批意见
                this.addComment(taskId, params.getUserCode(),userName, params.getProcessInstanceId(), CommentTypeEnum.SP.toString(), params.getMessage());
            } else {
                return R.ok("没有此任务,请确认!");
            }
        } else {
            return R.err("请输入正确的参数!");
        }
        return R.ok("审批成功");
    }
    
    /**
     * 批量任务处理
     * 任务 taskId,来自 ACT_RU_TASK
     *
     * @return
     */
    @ApiOperation(value = "任务批量处理")
    @Transactional
    @RequestMapping(value = "/task/batchComplete", method = RequestMethod.POST)
    public R batchTask(@RequestBody List<CompleteTaskVo> paramslist) {
        for (CompleteTaskVo params : paramslist) {
            task(params);
        }
        return R.ok("审批成功");
    }
}
    

ProcessInitParams 启动工作流的实体类,根据具体的业务进行创建


@Data
public class ProcessInitParams {
	/**
	 * 发起人 必填
	 */
	private String originator;
	
	/**
	 * 业务模型类型 选填
	 * 参数key,通过参数key获取参数,并转换为相应的实体对象
	 */
	private String businessModelType;
	
	/**
	 * 业务参数 选填
	 * 需要审核的数据
	 */
	private Map<String, Object> variables;
	
	/**
	 * 模型定义Key 必填
	 * 设计流程图时填写的模型标识
	 */
	private String processDefinitionKey;

	/**
	 * 表单显示名称 必填
	 */
	private String formName;

	/**
	 * 表单显示类型 必填
	 */
	private String formType;

	/**
	 * 业务系统id 必填
	 */
	private String businessKey;
	/**
	 * 任务号
	 */
	private String taskNo;

	/**
	 * 业务必填
	 */
	private String businessType;

	/**
	 * 流程实例id
	 */
	private String processInstanceId;
	/**
	 * 流程定义id
	 */
	private String processDefinitionId;
	/**
	 * 激活状态 1激活 2挂起
	 */
	private int suspensionState;
	/**
	 * 开始时间
	 */
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
	private Date startTime;
	/**
	 * 结束时间
	 */
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
	private Date endTime;
	/**
	 * 审批人
	 */
	private String approver;
	/**
	 * 发起人
	 */
	private String starter;
	/**
	 * 任务提交人
	 */
	private String startUser;
	private String starterName;

	private String taskName;
	/**
	 * 系统标识
	 */
	private String systemSn;
	/**
	 * 审核状态
	 */
	private String verifyStatus;
	/**
	 * 险种类别  car group personal oth
	 */
	private String dangerPlanted;
	/**
	 * 团队 人员 协议 合作方
	 */
	private String operation;
}

工作流执行完成后的监听


@Component
public class EventListener implements FlowableEventListener {


	@Autowired
	private BusinessCallBackService businessCallBackService;
	@Override
	public void onEvent(FlowableEvent event) {
		FlowableEngineEventType type = (FlowableEngineEventType) event.getType();
		try {
			switch (type) {
				case PROCESS_COMPLETED:
					FlowableEntityEventImpl flowableEntityEventImpl=(FlowableEntityEventImpl) event;
					Object entity = flowableEntityEventImpl.getEntity();
					Map<String,Object> map = JSONObject.parseObject(JSON.toJSONString(entity));
					//TODO 回写业务数据
					businessCallBackService.updateVerifyStatus(map);
					break;
				default:
					break;
			}
		}catch (Exception e){
			throw new RuntimeException("审核异常信息-->"+e.getMessage());
		}
	}

	@Override
	public boolean isFailOnException() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isFireOnTransactionLifecycleEvent() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public String getOnTransaction() {
		// TODO Auto-generated method stub
		return null;
	}
}

Flowable流的一些工具类

工具类仅供参考

/**
 *
 */

public class Flowable {
    // 用户以及组管理服务
    @Resource
    private IdentityService identityService;

    // 模型服务
    @Resource
    private ModelService modelService;

    // 部署服务
    @Resource
    private RepositoryService repositoryService;

    @Autowired
    protected ManagementService managementService;
    // 流程实例服务
    @Resource
    private RuntimeService runtimeService;

    // 流程节点任务服务
    @Resource
    private TaskService taskService;

    // 历史数据服务
    @Resource
    private HistoryService historyService;

    
    /**
     * 生成自定义的任务序号
     *
     * @param businessType
     * @return
     * @author liyun
     */
    private String createComTaskId(String businessType) {
        StringBuffer sb = new StringBuffer();
        //生成随机位数
        int random = (int) (Math.random() * 90000) + 10000;
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        sb.append(businessType);
        sb.append(sdf.format(date));
        sb.append(random);
        return sb.toString();
    }

    /**
     * 获取当前候选组
     *
     * @param taskId 任务 Id,来自 ACT_RU_TASK
     * @return
     */
    @ApiOperation(value = "获取当前候选组")
    @RequestMapping(value = "/taskInfo/{taskId}", method = RequestMethod.GET)
    public List<String> taskInfo(@PathVariable(value = "taskId") String taskId) {
        List<String> group = new ArrayList<>();
        List<IdentityLink> taskName = taskService.getIdentityLinksForTask(taskId);
        taskName.forEach(identityLink -> {
            group.add(identityLink.getGroupId());
        });
        return group;
    }

    /**
     * 设置任务参数
     *
     * @param taskId 任务ID
     * @param map    用户列表
     * @return
     */
    @ApiOperation(value = "设置任务参数")
    @RequestMapping(value = "/setVariables", method = RequestMethod.POST)
    public void setVariables(@RequestParam(value = "taskId") String taskId, @RequestBody Map<String, Object> map) {
        String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();
        runtimeService.setVariables(processInstanceId, map);
    }

    /**
     * 设置任务参数
     *
     * @param taskId 任务ID
     * @param key    键
     * @param value  值
     * @return
     */
    @RequestMapping(value = "/setVariable", method = RequestMethod.POST)
    public void setVariable(@RequestParam(value = "taskId") String taskId, @RequestParam(value = "key") String key, @RequestParam(value = "value") Object value) {
        String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();
        runtimeService.setVariable(processInstanceId, key, value);
    }

    /**
     * 设置任务参数,List 使用
     *
     * @param taskId 任务ID
     * @param key    键
     * @param value  值
     * @return
     */
    @RequestMapping(value = "/setListVariable", method = RequestMethod.POST)
    public void setListVariable(@RequestParam(value = "taskId") String taskId, @RequestParam(value = "key") String key, @RequestParam(value = "value") List<String> value) {
        String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();
        runtimeService.setVariable(processInstanceId, key, value);
    }

    /**
     * 添加审批意见
     *
     * @param userCode          处理人工号
     * @param processInstanceId 流程实例id
     * @param type              审批类型
     * @param message           审批意见
     */
    protected void addComment(String userCode,String userName, String processInstanceId, String type, String message) {
        this.addComment(null, userCode,userName, processInstanceId, type, message);
    }

    /**
     * 添加审批意见
     *
     * @param taskId            任务id
     * @param userCode          处理人工号
     * @param processInstanceId 流程实例id
     * @param type              审批类型
     * @param message           审批意见
     */
    protected void addComment(String taskId, String userCode,String userName, String processInstanceId, String type, String message) {
        //1.添加备注
        CommentVo comment = new CommentVo(taskId, userCode,userName, processInstanceId, type, message);
        managementService.executeCommand(new AddHisCommentCmd(comment.getTaskId(), comment.getUserId(), comment.getProcessInstanceId(),
                comment.getType(), comment.getMessage()));
        //TODO 2.修改扩展的流程实例表的状态以备查询待办的时候能带出来状态
        //TODO 3.发送mongodb的数据到消息队列里面
    }

    protected TaskEntity createSubTask(TaskEntity ptask, String assignee) {
        return this.createSubTask(ptask, ptask.getId(), assignee);
    }

    /**
     * 创建子任务
     *
     * @param ptask    创建子任务
     * @param assignee 子任务的执行人
     * @return
     */
    protected TaskEntity createSubTask(TaskEntity ptask, String ptaskId, String assignee) {
        TaskEntity task = null;
        if (ptask != null) {
            //1.生成子任务
            task = (TaskEntity) taskService.newTask(UUID.randomUUID().toString());
            task.setCategory(ptask.getCategory());
            task.setDescription(ptask.getDescription());
            task.setTenantId(ptask.getTenantId());
            task.setAssignee(assignee);
            task.setName(ptask.getName());
            task.setParentTaskId(ptaskId);
            task.setProcessDefinitionId(ptask.getProcessDefinitionId());
            task.setProcessInstanceId(ptask.getProcessInstanceId());
            task.setTaskDefinitionKey(ptask.getTaskDefinitionKey());
            task.setTaskDefinitionId(ptask.getTaskDefinitionId());
            task.setPriority(ptask.getPriority());
            task.setCreateTime(new Date());
            taskService.saveTask(task);
        }
        return task;
    }

    /**
     * 任务处理
     *
     * @param taskId   任务 Id,来自 ACT_RU_TASK
     * @param assignee 设置审核人,替换
     * @param map      完成任务需要的条件参数
     * @return
     */
    @RequestMapping(value = "/task", method = RequestMethod.POST)
    public void taskByAssignee(@RequestParam(value = "taskId") String taskId, @RequestParam(value = "assignee") String assignee, @RequestBody Map<String, Object> map) {
        // 设置审核人
        taskService.setAssignee(taskId, assignee);

        // 设置任务参数,也可不设置:key value,只是示例
        // 带 Local 为局部参数,只适用于本任务,不带 Local 为全局任务,可在其他任务调用参数
        taskService.setVariableLocal(taskId, "status", true);

        // 完成任务
        taskService.complete(taskId, map);
        logger.info("任务完成:" + taskId + " " + new Date());
    }

    /**
     * 中止流程
     *
     * @param processId 流程ID
     * @return
     */
    @ApiOperation(value = "中止流程")
    @Transactional
    @RequestMapping(value = "/deleteProcess/{processId}", method = RequestMethod.GET)
    public void deleteProcess(@PathVariable(value = "processId") String processId) {
        runtimeService.deleteProcessInstance(processId, "中止流程");
    }

    /**
     * 获取正在运行的数据 Id 列表
     *
     * @return
     */
    @ApiOperation(value = "获取正在运行的数据 Id 列表")
    @RequestMapping(value = "/getRuntimeDataId", method = RequestMethod.GET)
    public List<String> getRuntimeDataId() {
        List<String> idList = new ArrayList<>();
        // 获取正在执行的任务列表
        List<Execution> list = runtimeService.createExecutionQuery().onlyProcessInstanceExecutions().list();
        list.forEach(execution -> {
            // 根据任务获取流程实例
            // 获取流程实例种的业务 key
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(execution.getProcessInstanceId()).singleResult();
            idList.add(pi.getBusinessKey());
        });
        return idList;
    }

    /**
     * 根据用户,获取需要审核的业务键 business_key 列表
     *
     * @param userId 用户 Id
     * @return
     */
    @ApiOperation(value = "根据用户,获取需要审核的业务键 business_key 列表")
    @RequestMapping(value = "/getRuntimeBusinessKeyByUser/{userId}", method = RequestMethod.GET)
    public List<Map<String, Object>> getRuntimeBusinessKeyByUser(@PathVariable(value = "userId") String userId) {
        List<Map<String, Object>> idList = new ArrayList<>();
        // 根据用户获取正在进行的任务
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).list();
        tasks.forEach(task -> {
            Map<String, Object> data = new HashMap<>();
            // 根据任务获取流程实例
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            // 获取流程实例中的业务键
            data.put("businessKey", processInstance.getBusinessKey());
            // 获取任务 Id
            data.put("taskId", task.getId());
            // 流程定义名称
            data.put("processInstanceName", processInstance.getProcessDefinitionName());
            // 流程开始时间
            data.put("startTime", processInstance.getStartTime());
            idList.add(data);
        });
        return idList;
    }

    /**
     * 获取组,获取需要审核的业务键 business_key 列表
     *
     * @param groupIds 组 Id
     * @return
     */
    @ApiOperation(value = "获取组,获取需要审核的业务键 business_key 列表")
    @RequestMapping(value = "/getRuntimeBusinessKeyByGroup", method = RequestMethod.POST)
    public List<Map<String, Object>> getRuntimeBusinessKeyByGroup(@RequestBody List<String> groupIds) {
        List<Map<String, Object>> idList = new ArrayList<>();
        // 判断是否有组信息
        if (groupIds != null && groupIds.size() > 0) {
            // 根据发起人获取正在执行的任务列表
            List<Task> tasks = taskService.createTaskQuery().taskCandidateGroupIn(groupIds).list();
            tasks.forEach(task -> {
                Map<String, Object> data = new HashMap<>();
                // 根据任务获取流程实例
                ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
                // 获取流程实例中的业务键
                data.put("businessKey", processInstance.getBusinessKey());
                // 获取任务 Id
                data.put("taskId", task.getId());
                // 流程定义名称
                data.put("processInstanceName", processInstance.getProcessDefinitionName());
                // 流程开始时间
                data.put("startTime", processInstance.getStartTime());
                idList.add(data);
            });
        }
        return idList;
    }

    /**
     * 获取用户审核历史
     *
     * @param userId 发起人 Id
     * @return
     */
    @ApiOperation(value = "获取用户审核历史")
    @RequestMapping(value = "/getHistoryByUser/{userId}", method = RequestMethod.GET)
    public List<Map<String, Object>> getHistoryByUser(@PathVariable(value = "userId") String userId) {
        List<Map<String, Object>> historyList = new ArrayList<>();
        // 根据用户,查询任务实例历史
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().taskAssignee(userId).finished().orderByHistoricTaskInstanceEndTime().desc().list();
        list.forEach(historicTaskInstance -> {
            // 历史流程实例
            HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
            // 获取需要的历史数据
            Map<String, Object> historyInfo = new HashMap<>();
            historyInfo.put("assignee", historicTaskInstance.getAssignee());
            // 节点名称
            historyInfo.put("nodeName", historicTaskInstance.getName());
            // 流程开始时间
            historyInfo.put("startTime", historicTaskInstance.getCreateTime());
            // 节点操作时间(本流程节点结束时间)
            historyInfo.put("endTime", historicTaskInstance.getEndTime());
            // 流程定义名称
            historyInfo.put("processName", hpi.getProcessDefinitionName());
            // 流程实例 ID
            historyInfo.put("processInstanceId", historicTaskInstance.getProcessInstanceId());
            // 业务键
            historyInfo.put("businessKey", hpi.getBusinessKey());
            historyList.add(historyInfo);
        });
        return historyList;
    }

    /**
     * 通过流程实例 Id,判断流程是否结束
     *
     * @param processInstanceId 流程实例 Id
     * @return true 结束,false 未结束
     */
    @ApiOperation(value = "通过流程实例 Id,判断流程是否结束")
    @RequestMapping(value = "/checkProcessInstanceFinish/{processInstanceId}", method = RequestMethod.GET)
    public boolean checkProcessInstanceFinish(@PathVariable(value = "processInstanceId") String processInstanceId) {
        boolean isFinish = false;
        // 根据流程 ID 获取未完成的流程中是否存在此流程
        long count = historyService.createHistoricProcessInstanceQuery().unfinished().processInstanceId(processInstanceId).count();
        // 不存在说明没有结束
        if (count == 0) {
            isFinish = true;
        }
        return isFinish;
    }


    /**
     * 根据任务节点获取流程实例 Id
     *
     * @param taskId 任务节点 Id
     * @return
     */
    @ApiOperation(value = "根据任务节点获取流程实例id")
    @RequestMapping(value = "/getTaskInfo/{taskId}", method = RequestMethod.GET)
    public String getTaskInfo(@PathVariable(value = "taskId") String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        return task.getProcessInstanceId();
    }


//    /**
//     * 监听器
//     *
//     * @param execution 分配执行实例
//     */
//    public boolean accessCondition(DelegateExecution execution) {
//
//        // 已完成的实例数
//        int completedInstance = (int) execution.getVariable("nrOfCompletedInstances");
//        // 实例总数
//        int totalInstance = (int) execution.getVariable("nrOfInstances");
//
            if (execution.getVariable("sum") == null) {
                execution.setVariable("sum", 0);
            }
            // 计算已完成多少
            int sum = (int) execution.getVariable("sum");
//
//        // 已完成的实例数 * 2 >= 实例总数,说明完成
//        if (completedInstance * 2  >= totalInstance) {
//            // 完成
//            return true;
//        } else {
//            // 未完成
//            return false;
//        }
//    }

//    /**
//     * 据任务节点id判断该节点是否为会签节点
//     *
//     * @param taskId 任务节点id
//     */
//    public boolean isMultiInstance(String taskId) {
//        boolean flag = false;
//        Task task=processEngine.getTaskService().createTaskQuery() // 创建任务查询
//                .taskId(taskId) // 根据任务id查询
//                .singleResult();
//        if(task != null){
//            // 获取流程定义id
//            String processDefinitionId=task.getProcessDefinitionId();
//
//            ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) processEngine.getRepositoryService()
//                    .getProcessDefinition(processDefinitionId);
//
//            // 根据活动id获取活动实例
//            HistoricActivityInstance activityInstance = historyService.createHistoricActivityInstanceQuery().processDefinitionId(processDefinitionId).unfinished().singleResult();
//
//            activityInstance.getActivityType()
//
//            if(((ActivityImpl) activityImpl).getActivityBehavior() instanceof ParallelMultiInstanceBehavior){
//                ParallelMultiInstanceBehavior behavior = (ParallelMultiInstanceBehavior)activityImpl.getActivityBehavior();
//                if(behavior != null && behavior.getCollectionExpression() != null){
//                    flag = true;
//                }
//            }
//        }
//
//        return flag;
//    }

}

Flowable 流程连线多扭转条件设置

1.扭转条件常用表达式:

  • ${var:get(myparam) == “1”}
  • ${myparam !=“123”}
  • ${var:eq(myparam,“same”)} – 两个值是否相等
  • ${var:containsAny(myparam, 1, 2)} – 判断list中是否存在该1,2变量
  • ${var:contains(myparam, 1)} – 判断参数是否包含该1变量
  • ${var:gt(myparam, 10)
  • ${var:gte(myparam, 10)}–变量值是否大于或大于等于
  • ${var:empty(myparam)} – 变量是否为空
  • ${var:isNotEmpty(myparam) - - 变量不为空
  • ${var:lt(myparam, 10) --变量是否小于
  • ${var:lte(myparam, 10) --变量是否小于等于
  • ${var:ne(myparam, “123”) --不等于
  • ${var:getOrDefault(myparam, 123) > 100}变量是否大于给定的值,不大于取默认值然后与给定的值比较;判断myVar是否大于123 大于则取myVar 否则取默认值 与100比较

2.Flowable支持条件表达式转化方式(Flowable版本是6.4.2,调试是发现支持13中条件表达,按照下图中的规则写条件表达式,否则转化时会报错):
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
3.设置多条件demo:
在这里插入图片描述

4.bumn.xml样式:
在这里插入图片描述

5.bumn.xml and test code:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1599529605337" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="myProcess_1" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_2" name="StartEvent"/>
    <userTask activiti:assignee="张三" activiti:exclusive="true" id="_3" name="UserTask"/>
    <userTask activiti:assignee="李四" activiti:exclusive="true" id="_4" name="UserTask"/>
    <sequenceFlow id="_5" sourceRef="_2" targetRef="_3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${var:equals(name,"张三") && var:gt(money, 100)}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="_6" sourceRef="_2" targetRef="_4">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${var:equals(name,"李四") && var:lt(money, 100)}]]></conditionExpression>
    </sequenceFlow>
    <endEvent id="_7" name="EndEvent"/>
    <sequenceFlow id="_8" sourceRef="_3" targetRef="_7"/>
    <sequenceFlow id="_9" sourceRef="_4" targetRef="_7"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
    <bpmndi:BPMNPlane bpmnElement="myProcess_1">
      <bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
        <omgdc:Bounds height="32.0" width="32.0" x="25.0" y="225.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
        <omgdc:Bounds height="55.0" width="85.0" x="115.0" y="120.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
        <omgdc:Bounds height="55.0" width="85.0" x="105.0" y="300.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="_7" id="Shape-_7">
        <omgdc:Bounds height="32.0" width="32.0" x="330.0" y="230.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="_5" id="BPMNEdge__5" sourceElement="_2" targetElement="_3">
        <omgdi:waypoint x="57.0" y="241.0"/>
        <omgdi:waypoint x="115.0" y="147.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_6" id="BPMNEdge__6" sourceElement="_2" targetElement="_4">
        <omgdi:waypoint x="57.0" y="241.0"/>
        <omgdi:waypoint x="105.0" y="327.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_3" targetElement="_7">
        <omgdi:waypoint x="200.0" y="147.5"/>
        <omgdi:waypoint x="330.0" y="246.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_4" targetElement="_7">
        <omgdi:waypoint x="190.0" y="327.5"/>
        <omgdi:waypoint x="330.0" y="246.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

@Test
    public void deploy() throws Exception {
        InputStream in = this.getClass().getResourceAsStream("/processes/multi-condition.bpmn");
        Deployment deployment = repositoryService.createDeployment()
                .name("多条件测试")
                .addInputStream("multi-condition.bpmn", in)
                .deploy();
        System.out.println(deployment.getId());
    }
 
 
    @Test
    public void start() {
        Map<String, Object> var = new HashMap<>();
        //${var.eq(name,"李四") && var:lt('money', 100)}
        var.put("name", "张三");
        var.put("money", 101);
        var.put("test", "test");
        ProcessInstance processInstance = runtimeService.
                startProcessInstanceById("myProcess_1:8:fd010351-f193-11ea-9686-e0d55e5900cd", var);
        System.out.println(processInstance.getId() + "====" + processInstance.getName());
    }

——————————————————————
版权声明:本文为博主原创文章,循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Boy_Martin/article/details/126104042

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flowable是一个开源的工作流引擎,它提供了一套完整的工作流管理解决方案。下面是Flowable工作流完成流程的简要介绍: 1. 建模:首先,你需要使用Flowable提供的建模工具(如Flowable Modeler)来设计和建立你的工作流模型。在建模过程中,你可以定义流程中的各个环节、任务、条件等。 2. 部署:完成建模后,你需要将工作流模型部署到Flowable引擎中。部署过程会将模型转化为可执行的流程定义,并将其存储在Flowable引擎的数据库中。 3. 启动流程实例:一旦流程定义被部署,你可以通过调用Flowable API来启动一个流程实例。流程实例代表了一个具体的工作流程,它会根据流程定义中的规则和条件进行执行。 4. 执行任务:在流程实例运行过程中,各个环节的任务会被分配给相应的参与者。参与者可以通过Flowable提供的任务管理API来查看和执行自己的任务。 5. 流程控制:Flowable支持各种类型的流程控制,如并行网关、条件网关等。这些控制节点可以根据流程中的条件和规则来决定流程的走向。 6. 监控和管理:Flowable提供了丰富的监控和管理功能,可以帮助你实时监控流程的执行情况、查看流程历史记录、进行性能优化等。 总的来说,Flowable工作流通过建模、部署、启动流程实例、执行任务、流程控制以及监控和管理等步骤,实现了一个完整的工作流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值