一、camunda modeler流程设计器
想要开发工作流hello world ,首先得要有一个流程设计器来设计流程 camunda 提供了流程设计程序 camunda modeler 下载地址: Download The Camunda BPMN / DMN Process Modeler | Camunda
下载完成直接解压到本地就可以用啦 。
二、部署一个流程定义
1、设计一个简单的请假流程图 test_1 并保存。
2 点击下方部署
3 填写好流程定义名称 以及地址
地址为: http://localhost:8088/ak/engine-rest/engine/camundaEngine/deployment/create (为什么是这个地址后面会提到)
4 点击 deploy 发布 显示发布成功!
5、访问本机地址进入camunda自带的后台
6、点击cockpit看到有一个已经发布的流程定义
7、点击 taskList---start process启动一个流程实例
完成后刷新页面查看任务列表
点击Claim领取任务 走完流程
到这里的话,一个流程就走完了,但是看似简单实际没啥卵用,因为根本用不到,接下来说点有用的 。
8、camunda 的核心服务
RepositoryService 存储流程定义
RuntimeService 管理运行实例,用事件来trigger流程往后走
TaskService 人员需要处理的任务
IdentityService 身份验证
FormService 前端接口
HistoryService 历史数据的统处理
ManagementService 数据库操作
FilterService 筛选
ExternalTaskService 外部任务
camunda有两种执行方式 一种是通过restApi方式,也就是上面发布的模式,都是走的restApi接口
详情请查看官方文档。Rest Api Reference | docs.camunda.org
如果后端自己想要写的话 ,就需要通过camunda 核心服务来实现了
9、部署一个流程定义
@GetMapping(value ="/createDefinition" )
public boolean createDefinition(String name ,String url) throws IOException {
File f = new File(url);
InputStream inputStreambpmn=new FileInputStream(f);
Deployment deployment = repositoryService// 与流程定义和部署对象相关的sevices
.createDeployment()// 创建一个部署对象
.name(name)// 添加部署名称
.addInputStream("test.bpmn", inputStreambpmn)
.deploy();// 完成部署
System.out.println("部署ID:" + deployment.getId());
System.out.println("部署名称" + deployment.getName());
inputStreambpmn.close();
return true;
}
个人觉得这种传地址的方式比较好一点还有其他的部署方式 详情请见自定义节点样例
ProcessDefinitionController
10、添加完成之后当然就是查询啦
@GetMapping("/getDefinitionList")
public List<ProcessDefinition> getDefinitionList(){
DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
List<Deployment> list = deploymentQuery.list();
for (Deployment deployment : list) {
System.out.println("sss"+deployment.toString());
}
System.out.println("---------------------------------------------------------------------");
List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery()
.latestVersion()//最新结果
//添加查询条件
//.processDefinitionName("流程定义的name")
//.processDefinitionId("流程定义的id")
//.processDefinitionKey("流程定义的key")
//排序
.orderByProcessDefinitionVersion().asc()
//查询结果
//.count() //返回结果集数量
//.listPage(firstResult, maxResults)//分页查询
//.singleResult() //唯一结果
.list();//总的结果集数量
for(ProcessDefinition processDefinition:processDefinitionList){
System.out.println("id:" +processDefinition.getId());
System.out.println("name:" +processDefinition.getName());
System.out.println("key:" +processDefinition.getKey());
System.out.println("version:" +processDefinition.getVersion());
System.out.println("resourceName:" +processDefinition.getDiagramResourceName());
}
return null;
}
11、查询之后 就是走流程啦、启动一个流程实例
@GetMapping(value = "/startInstance")
public boolean startInstance(String key){
//根据key启动流程实例 这个KEY可以在数据库表 ACT_RE_PROCDEF 的KEY_字段查看到,当然也可以在流程文件中查到,或者通过查询接口查到。
//开启流程 需要指定当前用户
// 设置当前用户为操作人
identityService.setAuthenticatedUserId("admin");
ProcessInstance simpleTest = runtimeService.startProcessInstanceByKey(key);
System.out.println("流程实例的ProcessInstanceId: " + simpleTest.getId());
System.out.println("流程实例的ProcessDefinitionId: " + simpleTest.getProcessDefinitionId());
System.out.println("————————————————————————————————————————————————————");
//指定变量启动
/* Map<String, Object> variables = new HashMap<String, Object>();
variables.put("userId", "张翠山");
runtimeService.startProcessInstanceByKey("leave", variables);*/
//根据消息启动
/* String messageName = "msg1";//或 String messageName = "msg2";
runtimeService.startProcessInstanceByMessage(messageName);*/
if (simpleTest != null && StringUtils.isNotBlank(simpleTest.getProcessDefinitionId())) {
List<Task> list = taskService.createTaskQuery().processInstanceId(simpleTest.getProcessInstanceId())
.active()
.list();
for (Task task:list){
System.out.println("name:"+task.getName());
System.out.println("id:"+task.getId());
System.out.println("ProcessDefinitionId"+task.getProcessDefinitionId());
System.out.println("taskDefinitionKey"+task.getTaskDefinitionKey());
System.out.println("当前任务执行人:"+task.getAssignee());
}
}
return true;
}
12、根据进程实例id获取当前任务id(获取当前实例的任务进度)
因为流程图里没有指定任务处理人,所以需要添加处理人,根据进程实例id获取当前任务id
@RequestMapping("/getActivityTask")
public void getActivityTask(String processInstanceId){
//processInstanceId 为条件 进程实例id 如果没有是全部
List<Task> list = taskService.createTaskQuery().processInstanceId(processInstanceId)
.active()
.list();
for (Task task:list){
System.out.println("name:"+task.getName());
System.out.println("id:"+task.getId());
System.out.println("ProcessDefinitionId"+task.getProcessDefinitionId());
System.out.println("taskDefinitionKey"+task.getTaskDefinitionKey());
System.out.println("当前任务执行人:"+task.getAssignee());
}
}
13、添加任务处理人
知道了任务id 就可以给任务添加处理人了
@GetMapping("/addCandidateUser")
public void candidateUser(String taskId,String userId){
taskService.addCandidateUser(taskId,userId);
//taskService.addCandidateGroup(taskId,groupId); 添加组
System.out.println("ok");
}
14、完成当前任务
@GetMapping("/completeTask")
public void completeTask(String taskId){
/* Map<String, Object> paramMap=new HashMap<>();
paramMap.put("approve",true);
paramMap.put("userName","userName");
paramMap.put("userId","userName");*/
taskService.complete(taskId);
System.out.println("ok");
}
这样一个hello world 就差不多了。