1、部署流程定义
1.1画图
上文我们提到一个Camunda Modeler,安装一下,方便我们获取xml文件,下载地址:流程设计器
对发起人节点的任务代理人这里设置变量
在经理审批节点也设置一个任务代理人变量
一个简单的流程图画好之后,在面板左下角可以看见有XML,点击它,在这里就可以获取到所需要的bpmn了。
在项目的resources文件夹下新建一个以bpmn结尾的文件【一定要以.bpmn结尾】,把刚刚获取到的bpmn内容复制过来。
1.2编码
这里直接给出实现类的代码,接口代码就省略了。这里仅给出两种部署方式,其他方法就不提了,不常用。【ResultReturn是自定义的返回值类,有需要的可以私信我获取,返回值改一下,这部分代码与本文无关就不贴出来了】
package com.lonewalker.snail.core.service.impl;
import com.lonewalker.snail.common.constant.ProcessConstant;
import com.lonewalker.snail.common.entity.ResultReturn;
import com.lonewalker.snail.common.utils.ResultReturnUtil;
import com.lonewalker.snail.core.service.ProcessDefinitionService;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.repository.Deployment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @description: 流程定义相关服务
* @author: LoneWalker
* @create: 2021-12-26
**/
@Service("processDefService")
public class ProcessDefinitionServiceImpl implements ProcessDefinitionService {
public final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
RepositoryService repositoryService;
@Override
public ResultReturn deployDefinitionByResource(String name,String resource) {
Deployment deploy = repositoryService.createDeployment()
.name(name)
.addClasspathResource(resource)
.deploy();
logger.info("流程Id:" + deploy.getId());
logger.info("流程Name:" + deploy.getName());
return ResultReturnUtil.success(ProcessConstant.DEPLOY_PROCESS_DEFINITION_SUCCESS);
}
@Override
public ResultReturn deployDefinitionByString(String definitionName,String resourceName,String resource) {
Deployment deploy = repositoryService.createDeployment()
.name(definitionName)
.addString(resourceName+".bpmn",resource)
.deploy();
logger.info("流程Id:" + deploy.getId());
logger.info("流程Name:" + deploy.getName());
return ResultReturnUtil.success(ProcessConstant.DEPLOY_PROCESS_DEFINITION_SUCCESS);
}
}
本文使用第一种,加载classpath下的资源文件来演示,后续会使用第二种
贴一下Controller的代码和Entity
@RestController
@RequestMapping("/processDefinition")
public class ProcessDefinitionController {
@Autowired
ProcessDefinitionService processDefService;
@PostMapping("/deploy")
public ResultReturn deployProcessDefinition(@RequestBody ProcessDefinition processDefinition){
String definitionName = processDefinition.getDefinitionName();
String resourceName = processDefinition.getResourceName();
return processDefService.deployDefinitionByResource(definitionName,resourceName);
}
}
@Data
public class ProcessDefinition implements Serializable {
private String definitionName;
private String resourceName;
private String resource;
}
行了,直接使用postman测试一下吧。
1.3查看部署的流程定义
控制台也是之前提到过的,不赘述。从界面上可以简单看出有一条定义,一次部署。
2、发起流程实例
**注意:****如果bpmn文件中的这个id没有改变,则重新部署流程定义后,流程引擎会认为是版本迭代,并取最新版本来发起流程实例,**这个id也就是下文中的processDefinitionKey。
2.1开启流程实例的代码
首先创建一个流程实例服务接口
public interface ProcessInstanceService {
public ResultReturn startProcessInstanceByKey(String processDefinitionKey, String businessKey);
}
其实现类:【这里可以看出在开启流程实例时已经对两个参数进行赋值了】
@Service("processInstanceService")
public class ProcessInstanceServiceImpl implements ProcessInstanceService {
@Autowired
private RuntimeService runtimeService;
@Autowired
private IdentityService identityService;
@Override
public ResultReturn startProcessInstanceByKey(String processDefinitionKey, String businessKey,String initiator) {
Map<String,Object> map = new HashMap<>();
map.put("userOne","userOne");
map.put("userTwo","userTwo");
//设置流程发起人
identityService.setAuthenticatedUserId("initiator");
ProcessInstance processInstance=runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey,map);
}
}
流程实例接口类
@RestController
@RequestMapping("/processInstance")
public class ProcessInstanceController {
@Autowired
ProcessInstanceService processInstanceService;
@PostMapping("/startProcess")
public ResultReturn startProcess(String processDefinitionKey,String businessKey,String initiator){
return processInstanceService.startProcessInstanceByKey(processDefinitionKey,businessKey,initiator);
}
}
然后发起流程:
在控制台查看 有我们开启流程时设置的业务ID、流程定义版本号、当前节点的任务处理人。
其实完成任务和处理人没关系,处理人的设置是用来查询待办,能看见才有机会完成。
2.2查询待办的代码
所以接下来写个查询待办服务。首先创建一个任务服务接口
public interface ProcessTaskService {
public ResultReturn queryMyToDo(String userId);
}
其实现类
@Service
public class ProcessTaskServiceImpl implements ProcessTaskService {
@Autowired
private TaskService taskService;
@Autowired
private IdentityService identityService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private HistoryService historyService;
@Override
public ResultReturn queryMyToDo(String userId) {
try {
List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).list();
return ResultReturnUtil.success(tasks);
}catch(Exception e){
e.printStackTrace();
throw new ProcessException(ResponseEnums.QUERY_TASK_MY_TO_DO_FAIL.getMsg());
}
}
}
controller
@RestController
@RequestMapping("/processTask")
public class ProcessTaskController {
@Autowired
ProcessTaskService processTaskService;
@GetMapping("/queryMyToDo")
public ResultReturn queryMyToDo(String userId){
return processTaskService.queryMyToDo(userId);
}
}
请求后
此时也就可以控制谁可以看见哪些任务,有了待办就需要去完成,再来写一个完成任务的接口
2.3审批通过
还是在ProcessTaskService中来写,很简单哈,传一个任务ID即可。
@Override
public ResultReturn taskPass(String taskId) {
taskService.complete(taskId);
return ResultReturnUtil.success("审批通过");
}
@PostMapping("/taskPass")
public ResultReturn taskPass(String taskId){
return processTaskService.taskPass(taskId);
}
在刚刚查询待办的返回数据中就可以获取到TaskId
拿到这个值就可以测试一下审批通过是否可以使用
此时再去看一下,camunda view,说明确实审批通过了
同样的步骤完成【经理审批】节点,也就结束了本条简单的流程。