当前位置: 首页 > news >正文

深圳网站建设服务找哪家上海建设工程交易中心网站

深圳网站建设服务找哪家,上海建设工程交易中心网站,佛山网站建设培训,新网站如何做排在前面目录 一、以一个处理流程开始1.1 后端1.2 前端1.3 执行 二、Camunda的补充2.1 使用方式2.2 可视化平台的Cockpit2.3 流程相关数据2.4 表介绍2.5 前端集成Modeler 三、用Java集成Camunda3.1 集成配置3.2 自动部署3.2.1 修改process.xml位置3.2.2 多进程引擎配置与多租户 3.3 历史… 目录 一、以一个处理流程开始1.1 后端1.2 前端1.3 执行 二、Camunda的补充2.1 使用方式2.2 可视化平台的Cockpit2.3 流程相关数据2.4 表介绍2.5 前端集成Modeler 三、用Java集成Camunda3.1 集成配置3.2 自动部署3.2.1 修改process.xml位置3.2.2 多进程引擎配置与多租户 3.3 历史事件配置3.3.1 查询3.3.2 任务报告 3.4 Service3.5 用户业务3.6 流程启动Controller3.7 业务任务-内部任务3.7.1 Java Class实现3.7.2 Delegate Expression实现3.7.3 Express实现3.7.4 流程的回退与重启与暂停回退重启暂停 3.8 业务任务-外部任务3.8.1 异步响应长轮询Long Polling3.8.2 注解方式配置与依赖写一个外部任务重试方式优先级 3.9 任务监听器引擎端3.10 鉴权3.11 多实例任务3.11.1 顺序执行3.11.2 多实例内置变量3.11.3 并行执行 3.12 脚本任务 附录 集成与简单的使用请参看前文。camunda流程引擎基本使用笔记 流程活动可参考-流程引擎实施参考 例子学习于blibli-camunda工作流实战课程,该视频简介者有一些地方是错的谨慎观看。 一、以一个处理流程开始 我们建立如下流程安排 后端加入购物车与物流发货。使用SpringBoot配合Camunda的包前端付款只有逻辑。使用nodejs代码配合Camuanda的包也可以用VUE等方式 1.1 后端 后端配置如下内容 server:port: 8081camunda:connect:url: http://localhost:8080/engine-resttimeout: 10000注意笔者现在使用的是7.2版本和上篇文章版本不同可不替换。 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdCamudaDemo/artifactIdversion1.0-SNAPSHOT/versionpropertiesmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.target/propertiesparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.6/version/parentdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdjavax.xml.bind/groupIdartifactIdjaxb-api/artifactId/dependencydependencygroupIdorg.camunda.bpm/groupIdartifactIdcamunda-external-task-client/artifactIdversion7.20.0/version/dependency/dependencies /project创建一个config配置Camunda连接 package com.camunda.demo.config;import lombok.Data; import org.camunda.bpm.client.ExternalTaskClient; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration Data public class CamundaConfig {/*** platform地址* */Value(${camunda.connect.url})private String CAMUNDA_URL;/*** 超时时间* */Value(${camunda.connect.timeout})private Integer TIME_OUT;Beanpublic ExternalTaskClient getExternalTaskClient(){return ExternalTaskClient.create().baseUrl(CAMUNDA_URL).asyncResponseTimeout(TIME_OUT).build();} } package com.camunda.demo.shopping;import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.client.ExternalTaskClient; import org.camunda.bpm.engine.variable.Variables; import org.springframework.stereotype.Component;import javax.annotation.Resource; import java.util.Map;Slf4j Component(value shoppingTask) public class ShoppingTask {Resourceprivate ExternalTaskClient externalTaskClient;/*** 订阅一个Serviceexternal类型* */public void handleShoppingCart(){/*** 订阅服务* */externalTaskClient.subscribe(add_card)/*** 流程定义即所属流程不* */.processDefinitionKey(Process_11089zy)/*** 最长加锁时间* */.lockDuration(2000)/*** 订阅配置* * 处理区域** externalTask 外部传参相关** externalTaskService 流程执行相关* */.handler((externalTask,externalTaskService)-{/*** 处理逻辑* */log.info(开始加入到购物车);MapString,Object goodVariable Variables.createVariables().putValue(size,xl).putValue(count,2);log.info(已加入到购物车\n{},goodVariable);/*** 执行完成* */externalTaskService.complete(externalTask,goodVariable);}).open();}public void handleDelivery(){externalTaskClient.subscribe(delivery).processDefinitionKey(Process_11089zy).lockDuration(2000).handler(((externalTask, externalTaskService) - {Object toWhere externalTask.getVariable(toWhere);log.info(即将发往目的地:{},toWhere);externalTaskService.complete(externalTask);})).open();}} 可以临时写一个启动类 SpringBootApplication public class MainApplication {public static void main(String[] args) {ConfigurableApplicationContext configurableApplicationContext SpringApplication.run(MainApplication.class,args);ShoppingTask shoppingTask (ShoppingTask)configurableApplicationContext.getBean(shoppingTask);shoppingTask.handleShoppingCart();shoppingTask.handleDelivery();} }注解方式也类似见后文 外部任务。 1.2 前端 使用如下命令初始化前端 npm init -y使用如下命令安装依赖如果有版本问题可以加–force要注意找一个低版本的高版本不支持直接启动笔者使用2.2.0 可以参考-camunda-external-task-client-js npm install camunda-external-task-client-js npm install -D open直接写一个subscribe.js const { Client, logger ,Variables} require(camunda-external-task-client-js);/*** 流程包* * 配置项* */ const config {baseUrl: http://localhost:8080/engine-rest,use:logger,asyncResponseTimeout: 10000}const client new Client(config);/*** 配置项* * 流程处理** 订阅服务-同后端代码* */ client.subscribe(pay,{processDefinitionKey:Process_11089zy},async function({task,taskService}){/*** 读取我们加入购物车流程中的变量* */const size task.variables.get(size);const count task.variables.get(count);console.log(顾客下单尺寸:${size},数量${count});/*** 添加新的变量* 订单送往哪里* */const processVariables new Variables().set(toWhere,shanghai China)try{/*** 处理完成* 查看源码可知:compelete 返回的是Promise因此需要await来等待* */await taskService.complete(task,processVariables);console.log(完成);}catch (e){console.error(异常${e});}})通过如下代码直接启动 node .\subscribe.js1.3 执行 完成后我们部署这个流程 登录可以看到我们的流程已经部署上去了启动它。基本使用见上一篇 二、Camunda的补充 2.1 使用方式 嵌入式及整合进项目如上篇中的Java整合Camunda。代码与流程解耦。组件式被所有程序共有类似一个消息队列。它将任务指派给不同程序。一个调度组件。代码与流程耦合。中间件做成一个平台单独部署第一部分就是这种方式SAAS平台。代码与流程解耦。集群camunda8中间件集群。云原生camunda8部署于k8s中elasticsearch存储方式以支持大型微服务。 2.2 可视化平台的Cockpit 可参考官方文档-Web Applications 我们启动platform平台时可以进入到该页面。 Cockpit监控中心驾驶舱Tasklist有权限可看到的任务Admin权限信息 点击进入Cockpit Running Process Instance流程实例Open Incidents异常Open Human Task人工任务Deployed部署的流程流程定义 Process DefinitionsBPMN相关(流程。 Cockpit 允许监控 BPMN 流程。仪表板是 BPMN 监视功能的入口点。选择已部署的流程定义或搜索流程实例。这将带您进入流程定义视图或流程实例视图。Decision DefinitionsDMN相关决策。Cockpit 允许监控 DMN 决策。仪表板是 DMN 监控功能的入口点。选择已部署的决策定义以访问决策定义视图。显示的有关决策定义和决策实例的所有数据都基于历史数据。与流程定义和流程实例不同没有运行时数据因为决策是即时执行的没有中间等待状态或保存点。Case Definitions: CMMN相关案例此功能仅包含在 Camunda 平台的企业版中在社区版中不可用。Cockpit允许监控CMMN案例。仪表板是 CMMN 监视功能的入口点。选择已部署的案例定义或搜索案例实例。这将分别将您带到案例定义视图或案例实例视图。Deployments总部署多版本前面的多版本统一模型算一个。显示所有部署、其资源以及这些资源的内容的概述。它允许删除现有部署以及重新部署旧资源和创建新部署。可以显示部署中的资源内容。也可以从此视图下载单个资源 2.3 流程相关数据 进入某一个流程定义我们是可以看到下列数据 Deinition Version 版本,默认每次修改再部署时都会提高一个版本Version Tag版本标签用户自定义版本Definition Key流程图的唯一ID。Definition ID Definition Key:Deinition Version:随机乱码。流程图下各个版本的唯一ID。 Definition ID 与 Definition Key 为 多 对 1 乱码的作用同一流程图的同一版本可以交给不同租户理解为公司乱码就是为了区分不同租户避免区分不开。History Time to LIve历史数据保存时间Tenant ID租户IDDeployment ID该Definition ID对应在数据库中的主键ID。Definition Name流程名称 流程实例 ID为流程实例的instance ID 我们点进去 Instance ID实例IDBusiness Key业务Key流水号之类的 其他部分 Variable流程变量以Map的形式我们之前也操作过的Incidents异常Called Process Instance跨流程调用调用其他实例User Tasks用户任务Jobs定时任务可重做External Task外部任务 2.4 表介绍 关于Camunda的表可以参考camunda数据库表结构介绍 以及官方文档Database Schema 2.5 前端集成Modeler 参考官网-基于 Web 的 BPMN、DMN 和表单工具 三、用Java集成Camunda 集成可以参考 Spring Boot 集成 流程引擎配置 3.1 集成配置 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdCamundaEngine/artifactIdversion1.0-SNAPSHOT/versionpropertiesmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.target/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion3.1.1/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdscoperuntime/scope/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.1/version/dependencydependencygroupIdorg.camunda.bpm.springboot/groupIdartifactIdcamunda-bpm-spring-boot-starter/artifactIdversion7.20.0/versionexclusionsexclusiongroupIdorg.camunda.bpm.model/groupIdartifactIdcamunda-cmmn-model/artifactId/exclusion/exclusions/dependencydependencygroupIdorg.camunda.bpm.model/groupIdartifactIdcamunda-cmmn-model/artifactIdversion7.18.0/version/dependencydependencygroupIdorg.camunda.bpm.springboot/groupIdartifactIdcamunda-bpm-spring-boot-starter-webapp/artifactIdversion7.20.0/version/dependencydependencygroupIdorg.camunda.bpm.springboot/groupIdartifactIdcamunda-bpm-spring-boot-starter-rest/artifactIdversion7.20.0/version/dependency/dependencies /project注意 7.20.0版本中camunda-cmmn-model这个包笔者导不进来因此另外导入了一个版本导入了webapp前端方便操作页面默认位置如下 http://localhost:8080/camunda/app/welcome/default/#!/login引入了RestAPI。相关文档可参考REST API Reference yml文件配置可以参考官方给出的 server:port: 8080 spring:datasource:url: jdbc:mysql://localhost:3306/camunda?useUnicodetrueNamePatternMatchesAlltruecharacterEncodingUTF-8allowPublicKeyRetrievaltrueuseSSLfalseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverapplication:name: work-engine camunda:bpm:admin-user:id: demopassword: demo mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl3.2 自动部署 启动时自动扫描文件 参考-官方文档-The processes.xml Deployment Descriptor 自定义部署运行中添加可以参考:【Camunda 三】Camunda模型文件部署 resources下创建如下文件 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/c189109a043f4314b797049c9f671bc8.png#pic_center) process.xml默认配置如下 ?xml version1.0 encodingUTF-8? process-applicationxmlnshttp://www.camunda.org/schema/1.0/ProcessApplicationxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance process-archive nameloan-approvalprocess-enginedefault/process-enginepropertiesproperty nameisDeleteUponUndeployfalse/propertyproperty nameisScanForProcessDefinitionstrue/property/properties/process-archive/process-applicationprocess-archive name这个是归档名称可以为空process-engine部署到的流程引擎名称 可不填写默认多引擎时需要isDeleteUponUndeploy此属性控制取消部署流程应用程序是否应导致从数据库中删除流程引擎部署。默认设置为 false。如果此属性设置为 true那么取消部署流程应用程序将导致从数据库中删除部署包括流程实例。isScanForProcessDefinitions如果此属性设置为 true那么将自动扫描流程应用程序的类路径以查找可部署资源。 可以参考Camunda动态生成工作流流程定义并部署更新流程新手上路版 3.2.1 修改process.xml位置 如果需要修改process.xml位置可以使用官方给出代码如下 ProcessApplication(namemy-app,deploymentDescriptors{path/to/my/processes.xml} ) public class MyProcessApp extends ServletProcessApplication {}3.2.2 多进程引擎配置与多租户 如何创建多进程引擎可以参考The Process Application class有多种配置方式 process-application xmlnshttp://www.camunda.org/schema/1.0/ProcessApplication xmlns:xsihttp://www.w3.org/2001/XMLSchema-instanceprocess-engine namemy-engineconfigurationorg.camunda.bpm.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration/configuration/process-engineprocess-archive nameloan-approval tenantIdtenant1process-enginemy-engine/process-enginepropertiesproperty nameisDeleteUponUndeployfalse/propertyproperty nameisScanForProcessDefinitionstrue/property/properties/process-archive/process-application3.3 历史事件配置 可参考-历史记录和审核事件日志 通过配置该项决定记录的日志颗粒度。 NONE不触发任何历史记录事件ACTIVITY触发以下事件 流程实例 START、UPDATE、END、MIGRATE在流程实例启动、更新、结束和迁移时触发案例实例 CREATE、UPDATE、CLOSE在创建、更新和关闭案例实例时触发活动实例 START、UPDATE、END、MIGRATE在活动实例启动、更新、结束和迁移时触发案例活动实例 CREATE、UPDATE、END在创建、更新和结束案例活动实例时触发任务实例 CREATE、UPDATE、COMPLETE、DELETE、MIGRATE在创建、更新即重新分配、委派等、完成、删除和迁移任务实例时触发。 AUDIT除了 history level 提供的事件外还会触发以下事件ACTIVITY 变量实例 CREATE、UPDATE、DELETE、MIGRATE在创建、更新、删除和迁移流程变量时触发。默认历史记录后端 DbHistoryEventHandler 将变量实例事件写入历史变量实例数据库表。此表中的行会随着变量实例的更新而更新这意味着只有流程变量的最后一个值可用。FULL除了 history level 提供的事件外还会触发以下事件AUDIT 表单属性 UPDATE在创建和/或更新表单属性时触发。 默认历史记录后端 DbHistoryEventHandler 将历史变量更新写入数据库。这样就可以使用历史记录服务检查过程变量的中间值。 用户操作日志更新当用户执行声明用户任务、委派用户任务等操作时触发。事件创建、删除、解决、迁移在创建、删除、解决和迁移事件时触发历史作业日志 CREATE、FAILED、SUCCESSFUL、DELETED在创建作业、作业执行失败或成功或作业已删除时触发决策实例 EVALUATE当 DMN 引擎评估决策时触发。Batch START、END在批处理开始和结束时触发标识链接 ADD、DELETE在添加、删除标识链接时或者在设置或更改用户任务的受托人时以及设置或更改用户任务的所有者时触发。历史外部任务日志 CREATED DELETED FAILED SUCCESSFUL在已创建、删除外部任务或外部任务执行已报告失败或成功时触发。 AUTO如果您计划在同一数据库上运行多个引擎则该级别非常有用。在这种情况下所有引擎都必须使用相同的历史记录级别。与其手动保持配置同步不如使用级别引擎会自动确定数据库中已配置的级别。如果未找到则使用默认值。 请记住如果您计划使用自定义历史记录级别则必须为每个配置注册自定义级别否则会引发异常。 请注意使用默认历史记录后端时历史记录级别存储在数据库中以后无法更改。 设置方式 ProcessEngine processEngine ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault().setHistory(ProcessEngineConfiguration.HISTORY_FULL).buildProcessEngine();使用Spring XML或部署描述符bpm-platform.xmlprocesses.xml进行设置。 使用 Camunda Wildfly 子系统时可以通过 Wildfly 配置独立 .xml、domain.xml设置属性。 总之只需要在xm中添加如下成员变量即可 property namehistoryaudit/property3.3.1 查询 使用HistoryService可创建如下查询 HistoricProcessInstanceQuery历史进程实例查询HistoricCaseInstanceQuery历史案例实例查询HistoricActivityInstanceQuery历史活动实例查询HistoricCaseActivityInstanceQuery历史案例活动查询HistoricVariableInstanceQuery历史变量查询HistoricDetailQuery历史细节查询,记录变量更新等信息HistoricTaskInstanceQuery任务实例查询HistoricIncidentQuery历史事件异常查询UserOperationLogQuery用户操作日志查询HistoricJobLogQuery历史作业日志查询HistoricDecisionInstanceQuery历史决策实例查询HistoricBatchQuery历史批量处理查询HistoricIdentityLinkLogQuery与用户关联的日志查询HistoricExternalTaskLogQuery外部日志查询 3.3.2 任务报告 检索已完成任务的报告。 对于任务报告有两种可能的报告类型 计数持续时间。 3.4 Service Camunda提供各类Service以便使用。 ProcessEngine第一次调用流程引擎时初始化并构建流程引擎之后总是返回相同的流程引擎 可以使用ProcessEngines.init() 和 ProcessEngines.destroy()来正确地创建和关闭所有的流程引擎通过ProcessEngine.XXService 来获取ServiceSpringBoot中不需要如此 RepositoryService用于管理和操作部署和流程定义的操作 RuntimeService流程实例相关操作 TaskServiceActivity也就是对各个节点的相关操作含挂起激活等 IdentityService用户管理等相关操作 FormService表单相关操作 启动表单是在流程实例启动之前向用户显示的表单任务表单是在用户希望完成表单时显示的表单 HistoryService历史记录相关 ManagementService它允许检索关于数据库表和表元数据的信息。此外它还公开了作业的查询功能和管理操作。作业在引擎中用于各种用途如计时器、异步延续、延迟挂起/激活等 FilterService允许创建和管理过滤器。过滤器是像任务查询一样存储的查询。Tasklist自带的页面使用过滤器来过滤用户任务。 Filter相关说明 ExternalTaskService提供对外部任务实例的访问。见第一部分 CaseService同RunService不过用于案例 DecisionService决策相关服务 3.5 用户业务 Modeler可参考 前置工作使用平台自行创建一个员工 我们接下来创建一个请假流程员工请假上级审批。 创建如下审批流程 初始化变量 starter,流程引擎将在流程发起时自动将发起人信息填入。 指派给starter即发起者可以指派给人、组、用户组、以及设置有效期 在员工请假处添加一个基础表单 在领导审批处添加另一个用户此处直接指派给我们的管理员也可以 完成后部署即可。 package com.engine.controller;import jakarta.annotation.Resource; import org.camunda.bpm.engine.IdentityService; import org.camunda.bpm.engine.RuntimeService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController RequestMapping(/leave) public class LeaveController {/*** 用户、组、租户等相关* */Resourceprivate IdentityService identityService;/*** 流程实例操作* */Resourceprivate RuntimeService runtimeService;GetMapping(/start/{user})public void startProcess(PathVariable(user)String user){/*** 表act_id_user** 在此处我们设置发起人信息对象存储在了如下类型中* ThreadLocalAuthentication currentAuthentication new ThreadLocal();* 因此线程之间是隔离的不会造成混用情况* */identityService.setAuthenticatedUserId(user);/*** 表* act_re_procdef BPMN定义* act_re_deployment流程部署信息* act_ge_bytearray 部署的实际内容* 开启一个流程实例** 开启后的实例存放于* 表act_run_execution 以及 act_run_task* act_run_execution BPMN运行时记录包含到那个节点了* act_run_task 流程总的记录记录了执行到哪个节点了指派给了谁等信息* 多个版本默认使用最新版本* 启动加入流程变量时需要加入startProcessInstanceByKey中* */runtimeService.startProcessInstanceByKey(Process_0pzlxi8);} } 启动后调用接口可以看到确实有一个流程并且参数已经有了 我们使用页面去处理后完成该流程。 3.6 流程启动Controller 可以做一个简单的启动类帮助我们启动 package com.engine.controller;import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.engine.IdentityService; import org.camunda.bpm.engine.RuntimeService; import org.camunda.bpm.engine.runtime.ProcessInstance; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController Slf4j RequestMapping(/process) public class ProcessController {Resourceprivate IdentityService identityService;Resourceprivate RuntimeService runtimeService;GetMapping(value { /start/{processKey}/user/{user},/start/{processKey},/start/{processKey}/businessKey/{businessKey},/start/{processKey}/{businessKey}/{user}})public void startProcess(PathVariable(processKey) String processKey,PathVariable(value user,required false)String user,PathVariable(value businessKey,required false)String businessKey){if(user ! null)identityService.setAuthenticatedUserId(user);ProcessInstance processInstance null;if(businessKey ! null)processInstance runtimeService.startProcessInstanceByKey(processKey,businessKey);else processInstance runtimeService.startProcessInstanceByKey(processKey);log.info(启动成功\nInstanceId:{}\nDefinitionId:{}\nInstanceId:{}\nstarter:{},processInstance.getRootProcessInstanceId(),processInstance.getProcessDefinitionId(),processInstance.getProcessInstanceId(),identityService.getCurrentAuthentication() null?null:identityService.getCurrentAuthentication().getUserId());} } 3.7 业务任务-内部任务 创建如下结构 3.7.1 Java Class实现 在预约修理家电实现处选择java class表示以流程引擎自己的Java服务实现。随后我们在集成的服务里面新建一个ReserveRepairService 服务并把路径添加进去。 package com.engine.serviceTask;import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.camunda.bpm.engine.delegate.JavaDelegate;Slf4j public class ReserveRepairService implements JavaDelegate {Overridepublic void execute(DelegateExecution execution) throws Exception {log.info(\n当前流程实例-{}\n执行-{}\n事件名称-{},execution.getProcessInstanceId(),execution.getCurrentActivityName(),execution.getEventName());} } 3.7.2 Delegate Expression实现 使用Delegate表达式可以让流程引擎直接调用自己的Bean我们需要让这个bean实现Camunda提供的包默认调用execute。 package com.engine.serviceTask;import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.camunda.bpm.engine.delegate.JavaDelegate; import org.springframework.stereotype.Service;Service(doRepair) Slf4j public class DoRepairService implements JavaDelegate {Overridepublic void execute(DelegateExecution execution) throws Exception {log.info(\n当前流程实例-{}\n执行-{}\n事件名称-{},execution.getProcessInstanceId(),execution.getCurrentActivityName(),execution.getEventName());execution.setVariable(repairManName,打工人A);} } 3.7.3 Express实现 该方式让流程引擎调用指定Bean的方法。需要指定接收返回的变量 package com.engine.serviceTask;import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.springframework.stereotype.Service;Service(telCall) Slf4j public class TelCallService {public Integer doCall(DelegateExecution execution){log.info(\n当前流程实例-{}\n执行-{}\n事件名称-{},execution.getProcessInstanceId(),execution.getCurrentActivityName(),execution.getEventName());/*** VariablesLocal 是该活动的变量生命周期与活动一致。* Variables 是流程变量生命周期与流程一致。当设置同名变量时会进行覆盖。* 所有变量会* 保存在表 act_ru_variable中当有Task_ID时代表是Local* act_hi_varinst 为历史变量表* */String repairManName String.valueOf(execution.getVariable(repairManName));log.info(请对-{}的服务打分,repairManName);return 10;} } 我们也可以用#号表达式 public void getScore(DelegateExecution execution){log.info(\n当前流程实例-{}\n执行-{}\n事件名称-{},execution.getProcessInstanceId(),execution.getCurrentActivityName(),execution.getEventName());log.info(员工-{}的服务得分是{},execution.getVariable(repairManName),execution.getVariable(score));}执行结果 可以发现这个我们启动的log在最后才打出来是同步执行的。 3.7.4 流程的回退与重启与暂停 回退 可以参考Process Instance Modification 继续上述逻辑我们想要在回访后重新设置评分。 ResourceRuntimeService runtimeService;ResourceRepositoryService repositoryService;public Integer doCall(DelegateExecution execution){log.info(\n当前流程实例-{}\n执行-{}\n事件名称-{},execution.getProcessInstanceId(),execution.getCurrentActivityName(),execution.getEventName());if(execution.getVariable(redo) ! null (Boolean) execution.getVariable(redo) ){log.info(重新打分6分);execution.setVariable(rescore,6);return (Integer) execution.getVariable(score);}String repairManName String.valueOf(execution.getVariable(repairManName));log.info(请对-{}的服务打分,repairManName);return 10;}public void getScore(DelegateExecution execution){log.info(\n当前流程实例-{}\n执行-{}\n事件名称-{},execution.getProcessInstanceId(),execution.getCurrentActivityName(),execution.getEventName());if(execution.getVariable(rescore) null){ProcessDefinitionEntity processDefinitionEntity (ProcessDefinitionEntity)repositoryService.getProcessDefinition(execution.getProcessDefinitionId());ListActivityImpl activityList processDefinitionEntity.getActivities();log.info(该流程的所有活动\n{}\n,activityList);int target -1;int i 0;for(;i activityList.size(); i,target){if(activityList.get(i).getActivityId() execution.getCurrentActivityId()){break;}}if(target 0){target 0;}log.info(\n当前节点位置:{}id:{},name:{}\n回退节点位置:{}id:{},name:{},i,activityList.get(i).getActivityId(),activityList.get(i).getName(),target,activityList.get(target).getActivityId(),activityList.get(target).getName());log.info(想要重新打分);// 修改当前流程至上一流程前runtimeService.createProcessInstanceModification(execution.getProcessInstanceId()).startBeforeActivity(activityList.get(target).getActivityId(),execution.getActivityInstanceId()).setVariable(redo,true).cancelActivityInstance(execution.getActivityInstanceId()).execute();return;}log.info(员工-{}的服务得分是{}修改得分是{},execution.getVariable(repairManName),execution.getVariable(score),execution.getVariable(rescore));}重启 依据官方例子流程重启动 直接删除实例 ProcessInstance processInstance runtimeService.createProcessInstanceQuery().singleResult(); runtimeService.deleteProcessInstance(processInstance.getId(), any reason);然后重新启动即可 runtimeService.restartProcessInstance(processInstance.getProcessDefinitionId()).startBeforeActivity(receivePayment).startBeforeActivity(shipOrder).processInstanceIds(processInstance.getId()).execute();重启后全局变量将会带入重启流程。需手动设置局部变量例如通过调用 。RuntimeService.setVariableLocal(…) 从技术上讲已创建一个新的流程实例。历史进程实例和重新启动的进程实例的 ID 不同。 也可以使用-RESTAPI 暂停 使用如下方法即可 runtimeService.suspendProcessInstanceById();runtimeService.startProcessInstanceById();3.8 业务任务-外部任务 可参考-外部任务 外部任务的执行流程 #mermaid-svg-W1UcekBAGo0NvNUv {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-W1UcekBAGo0NvNUv .error-icon{fill:#552222;}#mermaid-svg-W1UcekBAGo0NvNUv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-W1UcekBAGo0NvNUv .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-W1UcekBAGo0NvNUv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-W1UcekBAGo0NvNUv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-W1UcekBAGo0NvNUv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-W1UcekBAGo0NvNUv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-W1UcekBAGo0NvNUv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-W1UcekBAGo0NvNUv .marker.cross{stroke:#333333;}#mermaid-svg-W1UcekBAGo0NvNUv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-W1UcekBAGo0NvNUv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-W1UcekBAGo0NvNUv .cluster-label text{fill:#333;}#mermaid-svg-W1UcekBAGo0NvNUv .cluster-label span{color:#333;}#mermaid-svg-W1UcekBAGo0NvNUv .label text,#mermaid-svg-W1UcekBAGo0NvNUv span{fill:#333;color:#333;}#mermaid-svg-W1UcekBAGo0NvNUv .node rect,#mermaid-svg-W1UcekBAGo0NvNUv .node circle,#mermaid-svg-W1UcekBAGo0NvNUv .node ellipse,#mermaid-svg-W1UcekBAGo0NvNUv .node polygon,#mermaid-svg-W1UcekBAGo0NvNUv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-W1UcekBAGo0NvNUv .node .label{text-align:center;}#mermaid-svg-W1UcekBAGo0NvNUv .node.clickable{cursor:pointer;}#mermaid-svg-W1UcekBAGo0NvNUv .arrowheadPath{fill:#333333;}#mermaid-svg-W1UcekBAGo0NvNUv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-W1UcekBAGo0NvNUv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-W1UcekBAGo0NvNUv .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-W1UcekBAGo0NvNUv .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-W1UcekBAGo0NvNUv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-W1UcekBAGo0NvNUv .cluster text{fill:#333;}#mermaid-svg-W1UcekBAGo0NvNUv .cluster span{color:#333;}#mermaid-svg-W1UcekBAGo0NvNUv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-W1UcekBAGo0NvNUv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 4.complete() 2.fetchAndLock() 3.handle 1.subscribe(topic) register(handler) Custom(Task)Handler External Task Client Camunda Rest API 外部任务注册至External Task Client有实例任务时由External Task Client抓取任务并锁定避免重复消费分发至对应外部任务外部任务完成后告知External Task Client失败时上报异常流程会卡在该节点可重试。 3.8.1 异步响应长轮询Long Polling 流程引擎对于客户端设计为长轮询模式拉取任务。可参考长轮询的实现方式 当没有外部任务可以用的时候请求会被服务器挂起并加锁防止重复消费一旦有新的外部任务可以执行时就会重新激活请求并执行响应设置超时时间可以在超时后释放该锁并不在挂起该任务 3.8.2 注解方式 非注解方式见第一部分。 官方文档 spring-boot-starter外部任务配置项 7.20 配置与依赖 此处可以另起一个项目。 引入如下同版本包 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdCamudaDemo/artifactIdversion1.0-SNAPSHOT/versionpropertiesmaven.compiler.source17/maven.compiler.sourcemaven.compiler.target17/maven.compiler.target/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion3.1.1/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdorg.camunda.bpm.springboot/groupIdartifactIdcamunda-bpm-spring-boot-starter-external-task-client/artifactIdversion7.20.0/version/dependency/dependencies /project配置 server:port: 8081 camunda:bpm:client:# 流程引擎地址base-url: http://localhost:8080/engine-rest# 长轮询持续时间异步响应超时时间默认为null# 设置后开启长轮询async-response-timeout: 20000# 一次最多拉取任务数量默认10max-tasks: 1# 订阅topic的上锁时间,超时后其他外部任务才能获取# 优先级小余直接在接口上配置,默认20,000lock-duration: 10000# 当前工作节点的IDworker-id: camunda-demo spring:application:name: camunda demo 写一个外部任务 沿用上述流程添加如下配置 package com.camunda.demo.camundaSubscribe;import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.client.spring.annotation.ExternalTaskSubscription; import org.camunda.bpm.client.task.ExternalTaskHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration Slf4j public class RepairSubscribe { //全局配置优先级小余私有配置因此超时会以此处为准BeanExternalTaskSubscription(topicName try_self_repair,processDefinitionKeyIn {Process_10qrmih},lockDuration 2000)public ExternalTaskHandler TrySelfRepair(){return ((externalTask, externalTaskService) - {/*** 是否免费修* */Boolean isFree true;if(isFree){log.info(免费维修);externalTaskService.complete(externalTask);}else{log.info(自己修);/*** message stacktrace 重试次数 重试超时时间* 重试次数为0时会创建一个异常事件* */externalTaskService.handleFailure(externalTask,message-自己修不好,stacktrace,0,5000);}});} } 为了方便我们手动调整truefalse来看一下效果。 true时 可以看到转为外部服务时就不再是同步等待了。 false时 可以看到创建了一个异常 重试方式 需要设置重试时可以用如下格式 Integer retries 3 if (externaltask.getRetries() ! null) {retries externaltask.getRetries() - 1; } externaltaskService.failure(Reason, retries);优先级 在一个流程中各个节点可以设置优先级通过优先级来让哪个流程实先执行。 优先级越高越先执行默认都为0 3.9 任务监听器引擎端 在引擎端使用监听器 添加如下配置在结束时判断用户是否添写上门修理的地址没有则使用默认地址 同理于上门修理处添加一个监听器,在开始时监测 package com.engine.listener;import io.micrometer.common.util.StringUtils; import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.camunda.bpm.engine.delegate.ExecutionListener; import org.springframework.stereotype.Component;Component(checkHomeAddress) Slf4j public class CheckHomeAddressListener implements ExecutionListener {Overridepublic void notify(DelegateExecution execution) throws Exception {log.info(校验用户);String homeAddress (String) execution.getVariable(homeAddress);if(StringUtils.isBlank(homeAddress)){log.info(未获取到地址);execution.setVariable(homeAddress,默认地址);}} }package com.engine.listener;import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.camunda.bpm.engine.delegate.ExecutionListener; import org.springframework.stereotype.Component;Component(noticeCustomer) Slf4j public class NoticeCustomerListener implements ExecutionListener {Overridepublic void notify(DelegateExecution execution) throws Exception {log.info(开始通知客户);String homeAddress (String) execution.getVariable(homeAddress);log.info(尊敬的客户您好维修师傅正在前往{},请耐心等候,homeAddress);} } 3.10 鉴权 官方可以用web.xml配置建议使用另外实现。 比如整合SpringSecurity等。 3.11 多实例任务 当需要执行一个循环的流程时可以让其作为多实例任务。 多实例任务分为 - 串行多实例任务 - 并行多实例任务 修改前面的请假流程让它变为多实例任务。 下图中可以看到 三根竖线异步执行三根横线顺序执行 可以看到上图可以添加多实例 Loop cardinality执行循环次数Completion condition循环跳出条件当满足时可以提前结束循环collection不指定循环次数直接循环对象listElementList 中的EAsynchronous before/after异步前/异步后操作 3.11.1 顺序执行 我们先做顺序执行 另外写一个启动类并提前添加用户:testzhangsan,lisi,wangwu GetMapping(/start/multi)public void startProcess(){identityService.setAuthenticatedUserId(test);ListString leaders new ArrayList();leaders.add(zhangsan);leaders.add(lisi);leaders.add(wangwu);VariableMap variableMap Variables.createVariables();variableMap.put(leaders,leaders);ProcessInstance processInstance runtimeService.startProcessInstanceByKey(Process_multi_task,variableMap);log.info(启动成功\nInstanceId:{}\nDefinitionId:{}\nInstanceId:{}\nstarter:{},processInstance.getRootProcessInstanceId(),processInstance.getProcessDefinitionId(),processInstance.getProcessInstanceId(),identityService.getCurrentAuthentication() null ? null : identityService.getCurrentAuthentication().getUserId());}如果我们在使用张三前先用李四的账号会发现虽然有但不能评价。 3.11.2 多实例内置变量 同init的时候后可以直接用内置变量starter多任务中可以使用如下内置变量 nrOfActiveInstances当前活动的实例数量loopCounter循环计数器办理人在列表中的索引nrOfInstances多实例任务中总共的实例数目nrOfCompletedInstances已经完成的实例数量 3.11.3 并行执行 如下图修改只要有两个人同意就可以。 此时评价将不分先后此外可以看到同时开始了循流程 3.12 脚本任务 Camunda支持大多是JSR-223的脚本引擎。比如JavaScript、Groovy等。 对前面请假流程增加扣年假这个操作。 innline 即在如下图中写入 External则是外部通过路径引用需要给出返回变量名。 需要用如下前缀 classpath:// 也就是需要放置于工程目录下通过Springboot的逻辑加载 deployment:// 也就是需要放置于模型扫描目录下一同部署于数据库附录 camunda中文-官方文档 camunda内部构造 camunda英文-官方文档 blibli-camunda工作流实战课程 camunda数据库表结构介绍
http://wiki.neutronadmin.com/news/292352/

相关文章:

  • 产业园门户网站建设方案网站建设微分销
  • c 网站开发 vs2012开发平台游戏
  • 火车票网站建设多少网站seo的主要优化内容
  • 多语言外贸网站源码深圳建站公司优化
  • 个人做网站和百家号赚钱vps主机上搭建网站
  • 盐城网站建设0515icp深圳商城网站
  • 江苏做网站价格万界商城系统
  • dw做网站表格插不到右边公司网站的建设怎么做
  • 动态域名做网站中网互联网站建设
  • 各种大型网站公司注册地址查询系统
  • 制作网页怎样添加背景音乐北京网站优化提供商
  • 网站强制使用极速模式安卓商店
  • 域名哪个网站好企业网站可以做商城类
  • 徐闻网站建设公司asp网站上传
  • 搜启网站建设如何建网站教程
  • 网站建设 趋势wordpress电商插件下载
  • 女孩做网站运营好吗滁州市工程建设网站
  • 苏州区建设局网站做网站的公司现在还 赚钱吗6
  • 免费做苗木网站精品课程网站开发关键技术
  • 国外外贸网站阿里云部署网站教程
  • 重庆做网站公司有哪些定制网络接口报警灯生产厂商
  • 温州做网站中国城乡住建部建设部网站
  • 访问不到自己做的网站生态农庄网站建设
  • 中英文网站源码php电子商务网站建设参考文献2018
  • 搭建一个网站需要多久游戏代理免费
  • 天津做网站制作公司中国建筑股票
  • seo建站是什么wordpress收录查询
  • 长沙门户网站有哪些企业网站建设一站式服务
  • 惠州行业网站设计方案广州越秀发布
  • 网站维护 html跨境电商到什么网站做