Activiti6工作流,搞懂模型,流程,任务,项目直接上手就干

Activiti6工作流,搞懂模型,流程,任务,项目直接上手就干

1流程图概述

在这里插入图片描述

Activiti6工作流的流程设计需要经历 1模型的创建与发布 2流程的启用 3对于流程相关发起的节点任务进行申请,审批等操作

2管理模型说明

2.1创建/更新模型

1逻辑说明:

​ 1新建一个空模型(默认后台创建,然后前端修改模型信息)

​ 2然后页面展示绘制流程图,页面返回重定向地址:” /static/modeler.html?modelId=”(参数是返回的),默认修改后关闭自动保存)

2代码实现:
	/**
	 * 新建一个空模型
	 */
	@RequestMapping("/create")
	public void newModel(HttpServletRequest request, HttpServletResponse response) throws IOException {
		RepositoryService repositoryService = processEngine.getRepositoryService();
		// 初始化一个空模型
		Model model = repositoryService.newModel();

		// 设置一些默认信息
		String name = "";
		String description = "";
		int revision = 1;
		String key = "m_" + CreatedTools.getCreated();
		// 设置子系统
		model.setTenantId("子系统1");

		ObjectNode modelNode = objectMapper.createObjectNode();
		modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
		modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
		modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);

		model.setName(name);
		model.setKey(key);
		model.setMetaInfo(modelNode.toString());

		repositoryService.saveModel(model);
		String id = model.getId();

		// 完善ModelEditorSource
		ObjectNode editorNode = objectMapper.createObjectNode();
		editorNode.put("id", "canvas");
		editorNode.put("resourceId", "canvas");
		ObjectNode stencilSetNode = objectMapper.createObjectNode();
		stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
		editorNode.put("stencilset", stencilSetNode);
		repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
		response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=" + id);
	}
	
	/**
	 * 保存一个模型
	 */
	@RequestMapping(value = "/model/{modelId}/save", method = RequestMethod.PUT)
    @ResponseStatus(value = HttpStatus.OK)
    public void saveModel(@PathVariable String modelId, String name, String description, String json_xml,
                          String svg_xml) {
        try {
            Model model = repositoryService.getModel(modelId);

            ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());

            modelJson.put(MODEL_NAME, name);
            modelJson.put(MODEL_DESCRIPTION, description);
            model.setMetaInfo(modelJson.toString());
            model.setName(name);

            repositoryService.saveModel(model);

            repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8"));

            InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes("utf-8"));
            TranscoderInput input = new TranscoderInput(svgStream);

            PNGTranscoder transcoder = new PNGTranscoder();
            // Setup output
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            TranscoderOutput output = new TranscoderOutput(outStream);

            // Do the transformation
            transcoder.transcode(input, output);
            final byte[] result = outStream.toByteArray();
            repositoryService.addModelEditorSourceExtra(model.getId(), result);
            outStream.close();

        } catch (Exception e) {
            LOGGER.error("Error saving model", e);
            throw new ActivitiException("Error saving model", e);
        }
    }
3可视化页面

​ 1.模型新增页面

​ 2模型编辑页面
在这里插入图片描述

4涉及的表结构信息
表名表说明
act_ge_bytearray#二进制文件表
字段名字段说明
ID_唯一标识
REV_
NAME_
DEPLOYMENT_ID_
BYTES_文件流
GENERATED_

2.2发布模型

1逻辑说明:

​ 1选择模型进行发布操作

​ 注意:1每次更改后需要重新发布,否则模型未更新;

​ 2根据模型Id判断模型是否发布(已经发布的模型存在运行中的流程,需要先处理流程然后再发布);

​ 3模型设计需要有主线流程(开始结束任务否则提示修改重新发布),在部署表中创建部署的信息,同时在二进制文件表中存储模型的信息

2代码实现:
	/**
	 * 发布模型为流程定义
	 */
	@RequestMapping("/deploy")
	@ResponseBody
	public Object deploy(String modelId) throws Exception {

		// 获取模型
		RepositoryService repositoryService = processEngine.getRepositoryService();
		Model modelData = repositoryService.getModel(modelId);
		byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());

		if (bytes == null) {
			return "模型数据为空,请先设计流程并成功保存,再进行发布。";
		}

		JsonNode modelNode = new ObjectMapper().readTree(bytes);
		BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
		model.setTargetNamespace(modelData.getCategory());

		if (model.getProcesses().size() == 0) {
			return "数据模型不符要求,请至少设计一条主线流程。";
		}
		byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);

		// 发布流程
		String processName = modelData.getName() + ".bpmn20.xml";
		Deployment deployment = repositoryService.createDeployment().name(modelData.getName())
				.category(modelData.getCategory()).addString(processName, new String(bpmnBytes, "UTF-8")).deploy();
		modelData.setDeploymentId(deployment.getId());
		repositoryService.saveModel(modelData);

		return "SUCCESS";
	}
3可视化页面

在这里插入图片描述

4涉及的表结构信息
表名表说明
act_re_deployment#流程部署表

2.3查询模型

1逻辑说明:

​ 1查询模型

2代码实现:
	/**
	 * 获取所有模型
	 */
	@RequestMapping("/modelList")
	@ResponseBody
	public Object modelList(String name) {
		if (name == null) {
			name = "";
		}
		RepositoryService repositoryService = processEngine.getRepositoryService();
		return repositoryService.createModelQuery().modelNameLike("%" + name + "%").modelTenantId("子系统1").list();
	}
	
	
	/**
	 * 分页查询
	 */
	@RequestMapping("/modelListPage")
	@ResponseBody
	public Object modelListPage(String name,int page, int limit) {
		if (name == null) {
			name = "";
		}
		RepositoryService repositoryService = processEngine.getRepositoryService();
		int totalCount = (int) repositoryService.createModelQuery().modelNameLike("%" + name + "%").modelTenantId("子系统1").count();
		List<Model> list = repositoryService.createModelQuery().modelNameLike("%" + name + "%").modelTenantId("子系统1").listPage((page - 1) * limit, page * limit);
		Map<String, Object> map = new HashMap<>();
		map.put("list", list);
		map.put("page", page);
		map.put("limit", limit);
		map.put("totalRow", totalCount);
		return map;
	}
3可视化页面

在这里插入图片描述

4涉及的表结构信息
表名表说明
act_ge_bytearray#二进制文件表
字段名字段说明
ID_唯一标识
REV_
NAME_
DEPLOYMENT_ID_
BYTES_文件流
GENERATED_

2.4删除模型

1逻辑说明:

​ 1删除模型前需要判断是否存在正在执行的流程,存在需要先处理流程,硬删除,删除表act_ge_bytearry模型信息(为发布的模型)1

2代码实现:
	/**
	 * 删除工作流模型
	 */
	@RequestMapping("/deleteModel")
	@ResponseBody
	public Object deleteModel(String modelId) {
		RepositoryService repositoryService = processEngine.getRepositoryService();
		repositoryService.deleteModel(modelId);
		return "SUCCESS";
	}
3可视化页面

在这里插入图片描述

4涉及的表结构信息
表名表说明
act_re_procdef;#流程定义

3管理流程说明

3.1启动流程型

1逻辑说明:

​ 1.首先需要确定根据流程部署Id获取流程定义

​ 2.可以自定义对象进行配置

​ 3.启动流程

2代码实现:
		// 启动一个流程实例
	@GetMapping("/activiti_define_start")
	@ResponseBody
	public Wrapper<String> activiti_define_start(@Valid String id) {
		ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();

		Map<String, Object> varaiables = new HashMap<>();
		// ...此处可注入变量
		varaiables.put("username", "111");
		varaiables.put("userNames", "111,222");
		ProcessInstance pi = runtimeService.startProcessInstanceById(id, varaiables);
		runtimeService.setProcessInstanceName(pi.getId(), pd.getName());

		logger.info("启动流程实例,获取id-->{},实例名称-->{}", pi.getId(), pd.getName());
		return WrapMapper.ok(pi.getId());
	}

3可视化页面

在这里插入图片描述

4涉及的表结构信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xpuO0LZB-1648536054227)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220329111617246.png)]

表名表说明
act_ru_execution#流程启动一次只要没有执行完就会有一条数据
act_ru_task#可能记录多条数据
act_ru_variable#记录流程运行时的流程变量
act_ru_identitylink#存放流程办理人的信息
act_hi_procinst#历史流程实例
act_hi_taskinst#历史任务实例
act_hi_actinst#历史活动节点表
act_hi_varinst#历史流程变量表
act_hi_identitylink#历史办理人表
act_hi_comment#批注表
act_hi_attachment#附件表

3.2查询流程

逻辑:根据流程实例查询获取流程图信息

/**
	 * 查询流程定义列表
	 *
	 * @return
	 */
	@RequestMapping("/activitDefineList")
	@ResponseBody
	public List<Map<String, Object>> activitDefineList(String name) {
		// 创建查询对象
		ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
		// 使用部署对象ID查询
		// processDefinitionQuery.deploymentId(deploymentId);
		// 使用流程定义ID查询
		// processDefinitionQuery.processDefinitionId(processDefinitionId)
		// 使用流程定义的KEY查询
		// processDefinitionQuery.processDefinitionKey(processDefinitionKey)

		// 使用流程定义的名称模糊查询
		if (name == null || "".equals(name.trim())) {
		} else {
			processDefinitionQuery.processDefinitionNameLike("%" + name + "%");
		}
		List<ProcessDefinition> list = processDefinitionQuery.list();
		return ActivitiTools.turnProcessDefinitions(list);
	}
	
	@RequestMapping("/activitiInstanceList")
	public List<Map<String, Object>> activitiInstanceList(String name) {
		// 创建查询对象
		ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
		if (name != null && !"".equals(name)) {
			processInstanceQuery.processInstanceNameLike("%" + name + "%");
		}

		List<ProcessInstance> list = processInstanceQuery.list();
		return ActivitiTools.turnProcessInstances(list);
	}

4管理任务说明

4.1申请的任务

1逻辑说明:

​ 1.查询申请的任务清单

2代码实现:
		@RequestMapping("/todoTaskList")
	@ResponseBody
	public List<Map<String, Object>> todoTaskList(String name) {
		// 创建查询对象
		TaskQuery taskQuery = taskService.createTaskQuery();
		if (name != null && !"".equals(name)) {
			taskQuery.processDefinitionNameLike("%" + name + "%");
		}
		// 设置查询条件
		// 根据任务的办理人查询
		// taskQuery.taskAssignee(assignee);
		// 指定流程定义key,只查询某个流程的任务
		// taskQuery.processDefinitionKey(processDefinitionKey);
		// 获取查询列表
		List<Task> list = taskQuery.list();
		List<Map<String, Object>> listEnd = ActivitiTools.turnTasks(list);

		// 分页时用,非分页慎用
		/*
		 * ProcessInstanceQuery instanceQuery =
		 * runtimeService.createProcessInstanceQuery(); for (Map<String, Object> map :
		 * listEnd) { String processDefinitionId = (String)
		 * map.get("processDefinitionId"); if (processDefinitionId != null) {
		 * List<ProcessInstance> processInstanceList =
		 * instanceQuery.processDefinitionId(processDefinitionId).list(); if
		 * (processInstanceList != null) { for (ProcessInstance processInstance :
		 * processInstanceList) { map.put("processInstanceName",
		 * processInstance.getName()); } } } }
		 */
		return listEnd;
	}

3可视化页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1F8ORKbC-1648536054228)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220329133347924.png)]

4涉及的表结构信息

在这里插入图片描述

4.2审批的任务

1逻辑说明:

​ 1.查询待审批的任务清单

2代码实现:
@RequestMapping("/mineTodoTaskList")
@ResponseBody
public List<Map<String, Object>> todoTaskList(String name, String user_id, String depart_id) {
   // 创建查询对象
   TaskQuery taskQuery = taskService.createTaskQuery();
   TaskQuery taskQuery1 = taskService.createTaskQuery();
   if (name != null && !"".equals(name)) {
      taskQuery.processDefinitionNameLike("%" + name + "%");
      taskQuery1.processDefinitionNameLike("%" + name + "%");
   }
   taskQuery.taskCandidateOrAssigned(user_id);
   taskQuery1.taskCandidateOrAssigned(depart_id);
   // 设置查询条件
   // 根据任务的办理人查询
   // taskQuery.taskAssignee(assignee);
   // 指定流程定义key,只查询某个流程的任务
   // taskQuery.processDefinitionKey(processDefinitionKey);
   // 获取查询列表
   List<Task> list = taskQuery.list();
   List<Task> list1 = taskQuery1.list();
   list.addAll(list1);
   List<Map<String, Object>> listEnd = ActivitiTools.turnTasks(list);
   return listEnd;
}

4.3提交申请

1逻辑说明:

​ 1.提交审批任务

​ 2.更新form表单信息

2代码实现:
@PostMapping("/submit")
	public Wrapper<String> submit(@Valid @RequestBody FormSubmitDto formSubmitDto) {
		String task_id = formSubmitDto.getTask_id();
		String form = formSubmitDto.getForm();

		Task task = taskService.createTaskQuery().taskId(task_id).singleResult();
		if (task == null) {
			return WrapMapper.ok("您已提交成功!");
		}

		logger.info("表单提交...");
		JSONObject formJson = JsonUtil.jsonStrToJsonObject(form);
		logger.info("formJson--{}", formJson);
		Set<String> keySet = formJson.keySet();
		for (String key : keySet) {
			Object val = formJson.getString(key);
			logger.info("{}:{}", key, val);
			taskService.setVariable(task.getId(), key, val);
			taskService.setVariableLocal(task.getId(), key, val);
		}
		// 保存表单以及表单的值
		formValsService.saveFormVals(formSubmitDto);

		logger.info("表单相关操作完成!");

		taskService.complete(task.getId());

		logger.info("检查重复审批人, 自动去重.");
		// formDuplicateService.doDuplicateTask(task.getProcessInstanceId());
		logger.info("根据完成时间,自动设置提醒方式.");
		modelJsonService.dueNextTaskPushHandle(task.getProcessInstanceId());

		return WrapMapper.ok("提交成功!");
	}

4.4提交审批

1逻辑说明:

​ 1.提交审批任务

​ 2.更新form表单信息

2代码实现:
@PostMapping("/submit")
	public Wrapper<String> submit(@Valid @RequestBody FormSubmitDto formSubmitDto) {
		String task_id = formSubmitDto.getTask_id();
		String form = formSubmitDto.getForm();

		Task task = taskService.createTaskQuery().taskId(task_id).singleResult();
		if (task == null) {
			return WrapMapper.ok("您已提交成功!");
		}

		logger.info("表单提交...");
		JSONObject formJson = JsonUtil.jsonStrToJsonObject(form);
		logger.info("formJson--{}", formJson);
		Set<String> keySet = formJson.keySet();
		for (String key : keySet) {
			Object val = formJson.getString(key);
			logger.info("{}:{}", key, val);
			taskService.setVariable(task.getId(), key, val);
			taskService.setVariableLocal(task.getId(), key, val);
		}
		// 保存表单以及表单的值
		formValsService.saveFormVals(formSubmitDto);

		logger.info("表单相关操作完成!");

		taskService.complete(task.getId());

		logger.info("检查重复审批人, 自动去重.");
		// formDuplicateService.doDuplicateTask(task.getProcessInstanceId());
		logger.info("根据完成时间,自动设置提醒方式.");
		modelJsonService.dueNextTaskPushHandle(task.getProcessInstanceId());

		return WrapMapper.ok("提交成功!");
	}

五额外说明

1关于受理人概念

​ 当一个流程被启动的时候,我们可以在节点上选择受理人是谁,如果选择并且填写了受理人

​ 1受理人有值,XML流程里面定义的受理人,TASK会直接填入这个人

​ 2受理人无值,可以使用签收功能去指定受理人,就是候选组里面谁签收谁就成了受理人

Task task=taskService.createTaskQuery().singleResult();
//签收
taskService.claim(task.getId(), "billy");
logger.info(taskService.createTaskQuery().singleResult().getAssignee());

2关于委托人概念

​ 受理人委托其他人操作该TASK的时候,受理人就成了委托人OWNER_,其他人就成了受理人ASSIGNEE_

Task task=taskService.createTaskQuery().singleResult();
//委托
taskService.delegateTask(task.getId(), "cc");
logger.info(taskService.createTaskQuery().singleResult().getOwner());
logger.info(taskService.createTaskQuery().singleResult().getAssignee());
//结果:owner是Billy,assignee是cc

​ 2受理人无值,可以使用签收功能去指定受理人,就是候选组里面谁签收谁就成了受理人

Task task=taskService.createTaskQuery().singleResult();
//签收
taskService.claim(task.getId(), "billy");
logger.info(taskService.createTaskQuery().singleResult().getAssignee());

2关于委托人概念

​ 受理人委托其他人操作该TASK的时候,受理人就成了委托人OWNER_,其他人就成了受理人ASSIGNEE_

Task task=taskService.createTaskQuery().singleResult();
//委托
taskService.delegateTask(task.getId(), "cc");
logger.info(taskService.createTaskQuery().singleResult().getOwner());
logger.info(taskService.createTaskQuery().singleResult().getAssignee());
//结果:owner是Billy,assignee是cc
  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值