Camunda工作流项目实战

文章结尾有项目实际设计的流程

微信搜索公众号:【小小技术宅】关注回复:camunda工作流sql自动获取

1.camunda需要引入的依赖

       <dependency>
            <groupId>org.camunda.bpm</groupId>
            <artifactId>camunda-external-task-client</artifactId>
            <version>7.17.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.camunda.bpm/camunda-engine -->
        <dependency>
            <groupId>org.camunda.bpm</groupId>
            <artifactId>camunda-engine</artifactId>
            <version>7.17.0</version>
        </dependency>

2.camunda初始化

  private static ProcessEngine processEngine;
    /**
     * 单例创建processEngine
     *
     * @return
     */
    public static ProcessEngine createProcessEngine() {
        if(processEngine == null) {
            try {
                ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
                cfg.setJdbcUrl(FileOper.getPropertyValueByKey("Camunda_JdbcUrl"))
                        .setJdbcUsername(FileOper.getPropertyValueByKey("Camunda_JdbcUsername"))
                        .setJdbcPassword(FileOper.getPropertyValueByKey("Camunda_JdbcPassword"))
                        .setJdbcDriver(FileOper.getPropertyValueByKey("Camunda_JdbcDriver"))
                        .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
                        .setHistory("full");
                processEngine =  cfg.buildProcessEngine();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return processEngine;
    }

jdbcurl、jdbcusername、password、jdbcdriver我都在外部配置文件中进行的配置,各位同僚可以直接在上属代码中进行配置

camunda是一个第三方的工具,有自己的数据库,

3.camunda中的各类服务

在本人项目中主要使用的是RuntimeService(运行服务)、TaskService(任务服务)、RepositoryService(存储服务)、HistoryService(历史信息服务)

  /**
     * 获取运行时服务--RuntimeService
     * @return
     */
    public static RuntimeService getRuntimeService(){
        ProcessEngine processEngine = createProcessEngine();
        if (processEngine!=null){
            return processEngine.getRuntimeService();
        }
        return null;
    }

    /**
     * 获取任务服务--TaskService
     * @return
     */
    public static TaskService getTaskService(){
        ProcessEngine processEngine = createProcessEngine();
        return processEngine.getTaskService();
    }

    /**
     * 获取存储服务--RepositoryService
     * @return
     */
    public static RepositoryService getRepositoryService(){
        ProcessEngine processEngine = createProcessEngine();
        if (processEngine==null){
            return null;
        }
        return processEngine.getRepositoryService();
    }

    /**
     * 获取历史信息服务--HistoryService
     * @return
     */
    public static HistoryService getHistoryService(){
        ProcessEngine processEngine = createProcessEngine();
        if (processEngine==null){
            return null;
        }
        return processEngine.getHistoryService();
    }

4.camunda流程部署

由于本项目不是springboot项目,所以无法使用camunda的原有部署方法

由于struts中不存在resources这个文件夹,流程文件也无法直接存放到该位置,所以改为xml的方式进行项目部署

  /**
     * 部署流程
     * @param processName
     * @param xmlStr
     * @return
     */
    public static Deployment deploy(String processName, String xmlStr) {
        try {
            ProcessEngine processEngine = createProcessEngine();
            if (processEngine!=null){
                RepositoryService repositoryService = processEngine.getRepositoryService();
                Deployment deploy = repositoryService.createDeployment()
                        .addString(processName+".bpmn",xmlStr)
                        .deploy();
                return deploy;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

5.第一次获取流程时节点的获取

当第一次选择流程并进行获取当前流程的下一个审批节点或者审批走向

   /**
     * 获取开始节点key(即Model中的id,注意与实例id区分)
     * @param procDefId
     * @return
     */
    public static String getSingleStartEventKey(String procDefId){
        String startKey = "";
        if (procDefId!=null&&!procDefId.equals("")){
            BpmnModelInstance bpmnModelInstance = getBpmnModelInstance(procDefId);
            StartEvent startEvent = null;
            if (bpmnModelInstance != null) {
                startEvent = bpmnModelInstance.getModelElementsByType(StartEvent.class).stream().findFirst().orElse(null);
            }

            if(startEvent != null) startKey = startEvent.getId();
        }

        return startKey;
    }
 /**
     * 获取指定节点之后的走向
     * @param procDefId 流程定义id
     * @param nodeModelId 指定的节点 Model Id
     * @return 走向的集合
     */
    public static List<SequenceFlow> getNextSequenceFlows(String procDefId, String nodeModelId){
        List<SequenceFlow> sequenceFlows = new ArrayList<>();
        BpmnModelInstance bpmnModelInstance = getBpmnModelInstance(procDefId);
        if (bpmnModelInstance==null){
            return sequenceFlows;
        }
        // 获取指定节点的流向
        SequenceFlow sequenceFlow = bpmnModelInstance.getModelElementsByType(SequenceFlow.class)
                .stream()
                .filter(it -> nodeModelId.equals(it.getSource().getId()))
                .findFirst()
                .orElse(null);
//        SequenceFlow sequenceFlow = bpmnModelInstance.getModelElementsByType(SequenceFlow.class).stream().findAny().orElse(null);
        // 如果流向线指向的是互斥网关,则获取网关后的指向
        FlowNode target = sequenceFlow.getTarget();
        if(target.getClass().equals(ExclusiveGatewayImpl.class)){
            sequenceFlows.addAll(target.getOutgoing());

        } else {
            sequenceFlows.add(sequenceFlow);
        }

        return sequenceFlows;
    }

6.根据走向获取下一个节点的数据

    /**
     * 获取指定流向的目标节点
     * @param procDefId 流程定义id
     * @param flowModelId 走向的Model id
     * @return 目标节点
     */
    public static FlowNode getTargetNode(String procDefId, String flowModelId){
        FlowNode target = null;
        BpmnModelInstance bpmnModelInstance = getBpmnModelInstance(procDefId);
        if (bpmnModelInstance==null){
            return null;
        }
        SequenceFlow sequenceFlow = bpmnModelInstance.getModelElementById(flowModelId);
        if(sequenceFlow!= null){
            target = sequenceFlow.getTarget();
        }
        return  target;
    }

7.camunda流程开始

  /**
     * 启动流程
     * @param procDefId 流程定义id
     * @return 流程实例id
     */
    public static String startFlow(String procDefId, Map<String,Object> variableMap){
        RuntimeService runtimeService = getRuntimeService();
        if (runtimeService==null){
            return null;
        }
        ProcessInstance processInstance = null;
        try {

            processInstance = runtimeService.startProcessInstanceById(procDefId,variableMap);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return processInstance.getId();
    }

返回当前流程实例的任务id,也就是每启动一次流程都会生成一个任务

8.流程部署成功后前端回显方法

前端根据流程定义的id获取流程的xml返回前端进行回显

 /**
     * 获取流程定义的xml
     */
    public static String getBpmnXml(String procDefId){
        RepositoryService repositoryService = getRepositoryService();
        if (repositoryService==null){
            return null;
        }

        //根据流程id查询流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(procDefId)
                .singleResult();

        // 如果找到了流程定义
        if (processDefinition != null) {
            // 获取流程定义的BPMN 2.0 XML的InputStream
            InputStream inputStream = repositoryService.getResourceAsStream(
                    processDefinition.getDeploymentId(),
                    processDefinition.getResourceName()
            );

            // 将InputStream转换为String
            String bpmnXml = convertInputStreamToString(inputStream);

            // 记得关闭InputStream
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                return "";
            }
            return bpmnXml;
        } else {
            System.out.println("No process definition found with key: " + procDefId);
        }
        return "";
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写bug的程序员m

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值