activiti工作流探索-学习笔记

经过了长时间的学习和探索,对activiti的工作流有了初步的认识,也积累下了些许经验分享给大家

不足之处以及建议欢迎指正~

开发环境:activiti5.22.0    springboot1.5.4

流程设计使用的是集成的activiti流程设计器

部署流程

	/**
	 * 	发布模型为流程实例
	 */
	@ApiOperation(value = "发布模型为流程定义")
    @PostMapping("{id}/deployment")
    public R deploy(@PathVariable("id") String id) throws Exception {
        //获取模型
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Model modelData = repositoryService.getModel(id);
        byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());

        if (bytes == null) {
            return R.error("模型数据为空,请先设计流程并成功保存,再进行发布。");
        }
        JsonNode modelNode = new ObjectMapper().readTree(bytes);
        BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
        if (model.getProcesses().size() == 0) {
            return R.error("数据模型不符要求,请至少设计一条主线流程。");
        }
        byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);
        //发布流程
        String processName = modelData.getName() + ".bpmn20.xml";
        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
                .name(modelData.getName())
                .addString(processName, new String(bpmnBytes, "UTF-8"));

        Deployment deployment = deploymentBuilder.deploy();
        modelData.setDeploymentId(deployment.getId());
        repositoryService.saveModel(modelData);
        return R.ok();
    }

获取工作流流程模型列表(带分页):

	/**
	 * 	获取流程model列表(分页)
	 */
	@RequestMapping(value = "/list", method = RequestMethod.POST)
	public TableResultResponse<Model> list(@RequestParam Map<String, Object> params) {
		int page = Integer.parseInt((String) params.get("page"));
		int limit = Integer.parseInt((String) params.get("limit"));
		Page<Object> result = PageHelper.startPage(page, limit);
		List<Model> list = repositoryService.createModelQuery().orderByCreateTime().desc().list();
		return new TableResultResponse<Model>(result.getTotal(), list);
	}

删除流程模型:

	 /**
     * 	删除模型
     */
	@DeleteMapping("{id}")
    @ApiOperation(value = "删除模型")
    public Object deleteModel(@PathVariable("id") String id) {
        RepositoryService repositoryService = processEngine.getRepositoryService();
        repositoryService.deleteModel(id);//删除模型
        repositoryService.deleteDeployment(id, true);//如果存在运行中的流程,级联删除设置为true
        return R.ok();
    }

工作流运行

    public R startProcess() {
        String processDefinitionKey = "获取流程设计的key";
        ProcessInstance instance = null;
        //判断是否存在流程部署
        List<ProcessDefinition> list = processEngine.getRepositoryService().createProcessDefinitionQuery()
                    .processDefinitionKey(processDefinitionKey)//根据流程定义的key查询
                    .list();
        if(list != null && list.size() > 0) {
            //启动流程实例(指定下级经办人)
            Map<String, Object> variables = new HashMap<String, Object>();
            variables.put("user", "获取下级经办人");
            instance = processEngine.getRuntimeService()
                      .startProcessInstanceByKey(processDefinitionKey, variables);
        } else {
            //流程未部署,或其他情况
            return R.ok("流程未部署,请检查流程定义").put("code", 500);
        }
        if(instance != null) {
            //流程启动成功
            System.out.println("流程实例id=" + instance.getProcessInstanceId());
            System.out.println("流程实例name=" + instance.getName());
            return R.ok().put("data", "流程启动成功");
        } else {
            return R.ok("未获取到流程实例,请检查是否发布!").put("code", 500);
        }
    }

流程启动的时候,可以动态指定下级经办人,或者不指定下级经办人而在流程设计中设置好,直接启动流程即可:

processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey);

 流程删除

	/**
	 * 	删除流程实例
	 * @param processInstanceId
	 */
	@RequestMapping(value = "/deleteWf/{processInstanceId}", method = RequestMethod.DELETE)
	public void delete(@PathVariable("processInstanceId") String processInstanceId){
		runtimeService.deleteProcessInstance(processInstanceId, "删除流程实例原因");
	}

 根据用户获取待办任务列表,或任务个数(接口中的userID为实际业务中assignee设置的为人员id)

	/**
	 * 	根据用户ID获取用户待办任务个数
	 */
	public int taskCountByUserID(String userID) {
		int count = count = count + taskService.createTaskQuery().taskAssignee(userID).list().size();
		return count;
	}

	/**
	 * 	根据用户ID获取用户待办任务列表
	 */
	public List<Task> taskList(String userID) {
		//查询个人任务列表
		List<Task> taskList = taskService.createTaskQuery().taskAssignee(userID).list();
		return taskList;
	}

审批

	@RequestMapping(value = "/complete/{taskID}", method = RequestMethod.GET)
	@ApiOperation("审批通过,添加信息")
	public R copmlete(@PathVariable("taskID") String taskID) {
		//查询是否有正在审批任务
		Task task = taskService.createTaskQuery().taskId(taskID).singleResult();
        if(task != null) {
            //完成审批任务
			taskService.complete(taskID);
            //如果需要传递参数的话   task.getProcessInstanceId()获取processInstanceId
            //runtimeService.setVariable(processInstanceId, "变量名", 参数);全局变量
            //taskService.setVariableLocal(taskID, "变量名", 参数);局部变量,该task下
            //添加批注的方法
            //taskService.addComment(taskID, processInstanceId, "批注信息"); 
        }
		return R.ok("审批成功");
	}

驳回的流程设计需要节点的流转,设置好条件进行判断流转方向

扫描二维码关注公众号,回复: 11117646 查看本文章

会签(多实例)的设计,在该业务中设计的是多实例并行任务

将多实例任务设置为Parallel并行,设置参数变量,可以通过监听器将会签人员集合传递进来,也可以在上级节点指定参数传递

public class CompleteListener implements TaskListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void notify(DelegateTask delegateTask) {
                List<String> assigneeList = new ArrayList<String>();
                assigneeList.add("部门一");
                assigneeList.add("部门二");
		delegateTask.setVariable("assigneeList", assigneeList);
	}

}

添加监听器设置会签人员集合 

历史记录表的应用:

act_hi_actinst:历史节点信息表,审批节点的历史记录,可以获取历史活动节点的信息

act_hi_comment:历史审批记录表,可以获取审批批注信息

act_hi_procinst:历史流程实例表,可以获取历史流程实例的运行记录如是否结束,开始时间,结束时间等

act_hi_taskinst:历史任务信息表,可以获取历史任务的审批记录信息,审批人,审批时间

act_hi_varinst:历史流程变量表,可以获取历史流程实例下的流程变量信息,如存放的审批信息等

问题汇总

1. 获取审批批注信息问题

开发过程中,添加审批批注成功,但是部署生成环境是CentOS,发现存在获取乱码的情况

//获取批注信息
List<Comment> comments = processEngine.getTaskService()
							.getTaskComments(historicActivityInstance.getTaskId());

Comment对象提供的api获取的是FULL_MSG_字段的blob类型文件信息,存在乱码现象,其中一种解决方式:

定义新的MyCommentEntity接收对象获取message信息

    List<MyCommentEntity> myCommentEntities = new ArrayList<MyCommentEntity>();
	if(comments != null && comments.size() > 0) {
	    //创建我们自己的list集合
		//为每一个查询到接口实现类复制属性到我们自己的类中,解析为前端JSON数据
		for(Comment comment :comments){
		    //创建我们自己的类
			MyCommentEntity myCommentEntity = new MyCommentEntity();
			//属性复制,源属性为commentEntity, 目标属性为myCommentEntity
			BeanUtils.copyProperties(comment, myCommentEntity);
			//添加我们自己的类
			myCommentEntities.add(myCommentEntity);
		}
        //get批注信息即可
        //list.get(0).getMessage();
	}

MyCommentEntity实体类:

@Getter
@Setter
public class MyCommentEntity {
	
    private String id;
 
    private String userId;//用户名,对应的是act_hi_comment表的USER_ID_字段
 
    private Date date;
 
    private String taskId;//任务id
 
    private String processInstanceId;//流程定义id
 
    private String message;//审批信息
 
    private String fullMessage;

}
发布了13 篇原创文章 · 获赞 1 · 访问量 8234

猜你喜欢

转载自blog.csdn.net/romanticRose/article/details/101455479