3.创建工单流程

bpmn流程部署,流程列表,不再赘述,直接创建工大,即发起流程。
在发起流程前,需要查询发起该流程的时候需要填写哪些信息,即起始节点绑定的表单需要返回给前端去填写。
查询某个流程起始节点绑定表单的代码如下:

ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId("not_hot_repair_workorder:1:720cbb9a-a1db-11ed-80e3-d41b81b9a72d")
.singleResult();
BpmnModel model = repositoryService.getBpmnModel(definition.getId());
Process process = model.getProcessById(definition.getKey());
FlowElement startElement = process.getInitialFlowElement();
if (startElement instanceof StartEvent) {
StartEvent startEvent = (StartEvent) startElement;
if (StringUtils.isNotEmpty(startEvent.getFormKey())) {
String formKey = startEvent.getFormKey();
//根据formKey去表单表里查询开始节点绑定的动态表单的信息

}
}
执行流程如下:
首先根据前端传递过来的流程id去查询流程信息

2023-02-01 14:10:29.526 DEBUG 35220 --- [ main] .selectProcessDefinitionsByQueryCriteria : ==> Preparing: SELECT RES.* from ACT_RE_PROCDEF RES WHERE RES.ID_ = ? order by RES.ID_ asc
2023-02-01 14:10:29.527 DEBUG 35220 --- [ main] .selectProcessDefinitionsByQueryCriteria : > Parameters: not_hot_repair_workorder:1:720cbb9a-a1db-11ed-80e3-d41b81b9a72d(String)
2023-02-01 14:10:29.537 DEBUG 35220 --- [ main] .selectProcessDefinitionsByQueryCriteria : <
Total: 1
之后查询当时部署时查询到的所有信息

2023-02-01 14:14:29.989 DEBUG 39204 --- [ main] o.f.e.i.p.e.P.selectProcessDefinition : ==> Preparing: select * from ACT_RE_PROCDEF where ID_ = ?
2023-02-01 14:14:29.990 DEBUG 39204 --- [ main] o.f.e.i.p.e.P.selectProcessDefinition : > Parameters: not_hot_repair_workorder:1:720cbb9a-a1db-11ed-80e3-d41b81b9a72d(String)
2023-02-01 14:14:29.994 DEBUG 39204 --- [ main] o.f.e.i.p.e.P.selectProcessDefinition : <
Total: 1
2023-02-01 14:14:29.997 DEBUG 39204 --- [ main] o.f.e.i.p.e.D.selectDeployment : ==> Preparing: select * from ACT_RE_DEPLOYMENT where ID_ = ?
2023-02-01 14:14:29.998 DEBUG 39204 --- [ main] o.f.e.i.p.e.D.selectDeployment : > Parameters: 71adaba7-a1db-11ed-80e3-d41b81b9a72d(String)
2023-02-01 14:14:30.001 DEBUG 39204 --- [ main] o.f.e.i.p.e.D.selectDeployment : <
Total: 1
2023-02-01 14:14:30.001 DEBUG 39204 --- [ main] o.f.e.impl.bpmn.deployer.BpmnDeployer : Processing deployment SpringBootAutoDeployment
2023-02-01 14:14:30.004 DEBUG 39204 --- [ main] .e.i.p.e.R.selectResourcesByDeploymentId : ==> Preparing: select * from ACT_GE_BYTEARRAY where DEPLOYMENT_ID_ = ? order by NAME_ asc
2023-02-01 14:14:30.005 DEBUG 39204 --- [ main] .e.i.p.e.R.selectResourcesByDeploymentId : > Parameters: 71adaba7-a1db-11ed-80e3-d41b81b9a72d(String)
2023-02-01 14:14:30.014 DEBUG 39204 --- [ main] .e.i.p.e.R.selectResourcesByDeploymentId : <
Total: 2
然后调用flowable的API去解析bpmn文件,获得起始节点关联的动态表单的key。
关于动态表单的数据库表我们设计如下:

CREATE TABLE Flowable_Form (
form_key varchar(255) NOT NULL COMMENT 'form_key',
form_name varchar(255) DEFAULT NULL COMMENT '表单名称',
form_content longtext COMMENT '表单内容',
create_time datetime COMMENT '创建时间',
PRIMARY KEY (form_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='动态表单';
将查询到的form_content返回给前端就可以让话务员去填写创建工单的必要信息了。
springMVC中可以直接使用@RequestParam Map<String, Object> maps接收前端传递的参数,这样可以动态获取到前端传递的所有参数。
代码中仍然使用自己创建map的方式进行演示:

Authentication.setAuthenticatedUserId("客服1号");
HashMap<String, Object> maps = new HashMap<>();
maps.put("role_id", "director_role_id");
maps.put("name", "舍得");
maps.put("phone", "13716111111");
maps.put("location", "流星花园二区9号楼1单元101");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("not_hot_repair_workorder", maps);
创建之后,管理员就可以查询自己需要审批的任务,需要查询指定给管理员这个角色和指定给某个管理员的任务,代码如下:

TaskQuery taskQuery = taskService.createTaskQuery();
taskQuery.or()
.active()
.taskAssignee("my_id").endOr();
taskQuery.or()
.taskCandidateGroup("director_role_id")
.active()
.endOr()
.includeProcessVariables()
.orderByTaskCreateTime().desc();
List tasks = taskQuery.listPage(0, 10);//从0开始,查询10条
or()endOr()就像是左括号和右括号,中间用or连接条件,但是实在太复杂的情况,建议不使用flowable的查询 。
管理员查看到自己需要审批的流程后,可以点击查看工单详情,主要查看客服人员填写了哪些信息,这个时候就需要我们查询客服人员填写的信息和上一个节点绑定的动态表单的信息,一块返回给前端,供管理员查看,方便管理员判断应该把工单分配给哪个维修工。
查询客服人员填写信息的代码如下:

Task task = taskService.createTaskQuery()
.taskId("56e86b71-a202-11ed-82c5-d41b81b9a72d")
.includeProcessVariables().singleResult();
Map<String, Object> variables = task.getProcessVariables();
查询上一个节点,这里是开始节点的代码如下:

String taskId = "56e86b71-a202-11ed-82c5-d41b81b9a72d";
Task task = taskService.createTaskQuery()
.taskId(taskId)
.includeProcessVariables().singleResult();
Map<String, Object> variables = task.getProcessVariables();

String formKey = "";
//上一个节点
List list = historyService
.createHistoricTaskInstanceQuery()
.processInstanceId(task.getProcessInstanceId())
.finished()
.orderByHistoricTaskInstanceEndTime()
.desc()
.listPage(0, 1);
//如果上个节点为空,表明为起始节点,需要再去查询第一个节点的动态表单
if (ObjectUtils.isEmpty(list)) {
ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(task.getProcessDefinitionId())
.singleResult();
BpmnModel model = repositoryService.getBpmnModel(definition.getId());
Process process = model.getProcessById(definition.getKey());
FlowElement startElement = process.getInitialFlowElement();
if (startElement instanceof StartEvent) {
StartEvent startEvent = (StartEvent) startElement;
if (StringUtils.isNotEmpty(startEvent.getFormKey())) {
formKey = startEvent.getFormKey();
}
}
} else {
formKey = list.get(0).getFormKey();
}
//根据formKey去表单表里查询开始节点绑定的动态表单的信息
System.out.println(formKey);
//查询上个节点添加的评论信息
HistoricTaskInstance taskInstance = null;
if (!list.isEmpty()) {
if (list.get(0).getEndTime() != null) {
taskInstance = list.get(0);
}
}
if (ObjectUtils.isNotEmpty(taskInstance)) {
List taskComments = taskService.getTaskComments(taskInstance.getId());
}
然后就根据查询到的formKey去查询动态表单的内容就可以了。
将客服之前填写的信息和动态表单的内容一起返回前端给管理员查看,之后管理员做出判断,填写当前节点关联的表单内容,进行工单的指派。
查询当前节点表单的代码如下:

String taskId = "56e86b71-a202-11ed-82c5-d41b81b9a72d";
Task task = taskService.createTaskQuery()
.taskId(taskId)
.includeProcessVariables().singleResult();
String formKey = task.getFormKey();
同理,根据查询到的formKey去查询动态表单的内容返回前端去填写,填写内容包括工单分配给哪个维修工以及分配给这个维修工的原因。
下面是分配给哪个维修工的代码:

HashMap<String, Object> maps = new HashMap<>();
maps.put("repair_man_id", "xiao_wang_user_id");
String taskId = "56e86b71-a202-11ed-82c5-d41b81b9a72d";
Task task = taskService.createTaskQuery()
.taskId(taskId)
.includeProcessVariables().singleResult();
taskService.addComment(task.getId(), task.getProcessInstanceId(), "经过大胆假设,小心论证,选择小王去完成这个工单");
taskService.complete(task.getId(), maps);
之后维修工就可以去查询自己的工单了,代码和管理员查询分配给自己的工单的代码一致,不过这里是按照userId去查询,而是不roleId去查询。

TaskQuery taskQuery = taskService.createTaskQuery();
taskQuery.or()
.active()
.taskAssignee("xiao_wang_user_id").endOr();
taskQuery.or()
.taskCandidateGroup("")
.active()
.endOr()
.includeProcessVariables()
.orderByTaskCreateTime().desc();
List tasks = taskQuery.listPage(0, 10);
之后维修工就可以查看管理员管理员填写的表单内容和评论信息。

随后维修工可以开始维修,假如维修工维修成功,代码如下:

HashMap<String, Object> maps = new HashMap<>();
maps.put("repair_success", true);
String taskId = "676dd2c2-a299-11ed-9550-d41b81b9a72d";
Task task = taskService.createTaskQuery()
.taskId(taskId)
.includeProcessVariables().singleResult();
taskService.addComment(task.getId(), task.getProcessInstanceId(), "我很棒,我一次就修好了");
taskService.complete(task.getId(), maps);
这样,这个流程分支就走完了。

posted @ 2023-02-01 14:41  努力干饭的兔兔  阅读(488)  评论(0)    收藏  举报