activiti自定义流程之Spring整合activiti-modeler5.16实例(八):完成个人任务

简介: <span style="font-family:Arial; font-size:14px; line-height:26px"></span><span style="font-family:Arial; font-size:14px; line-height:26px">注:(1)环境搭建:<a target="_blank" href="http://blog.csdn.net/t
注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建
        (2)创建流程模型:activiti自定义流程之Spring整合activiti-modeler5.16实例(二):创建流程模型 
        (3)流程模型列表展示:activiti自定义流程之Spring整合activiti-modeler5.16实例(三):流程模型列表展示
        (4)部署流程定义:activiti自定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义

        (5)流程定义列表:activiti自定义流程之Spring整合activiti-modeler5.16实例(五):流程定义列表

        (6)启动流程:activiti自定义流程之Spring整合activiti-modeler5.16实例(六):启动流程

        (7)任务列表展示:activiti自定义流程之Spring整合activiti-modeler5.16实例(七):任务列表展示




1.完成个人任务依旧是使用taskService操作,调用complete方法,需要传入任务id,同时还可以传入流程变量。


2.后台业务代码,
  (1)自定义的任务实体类(使用之前自定义的taskModel)

  (2)业务逻辑:
完成任务使用taskService调用complete方法来完成,一旦正确调用了这个方法,当前任务就会结束,进入到下一个任务,如果当前任务已经是最后一个任务,则整个流程结束。
对于已经结束的任务,act_ru_task中所存在的那条对应数据会被删除,取而代之的是,对应的act_hi_taskinst中的那条数据会增加结束时间。

上边所说的正确调用是指,如果当前任务的下一个任务设有个人任务变量或者组任务变量,那么提交的时候必须有对应的变量数据,否则会抛出异常,完成任务失败。(但是,如果下一个任务没有设置这些,提交时依旧填了流程变量是不会出错的)

下边的例子中,之所以还查询了流程节点的信息,并做了相关的处理,是为了实现针对任意数量任务的流程都能正常运行,否则不需要这么麻烦。

/**
	 * @throws XMLStreamException
	 *             完成个人任务
	 * 
	 * @author:tuzongxun
	 * @Title: completeTask
	 * @param @return
	 * @return Object
	 * @date Mar 17, 2016 4:55:31 PM
	 * @throws
	 */
	@RequestMapping(value = "/completeTask.do", method = RequestMethod.POST, produces = "application/json;charset=utf-8")
	@ResponseBody
	public Object completeTask(@RequestBody TaskModel taskModel,
			HttpServletRequest req) throws XMLStreamException {
		boolean isLogin = this.isLogin(req);
		if (isLogin) {
			String taskId = taskModel.getId();
			// 1、查task
			Task task = taskService.createTaskQuery().taskId(taskId)
					.singleResult();
			// 2、查variables
			Map<String, Object> variables = runtimeService.getVariables(task
					.getProcessInstanceId());
			Set<String> keysSet = variables.keySet();
			Iterator<String> keySet = keysSet.iterator();
			Map<String, Object> variables1 = new HashMap<String, Object>();
			String assignee = task.getAssignee();
			// 判断之后是否还有任务
			// ////////////////
			while (keySet.hasNext()) {
				String key = keySet.next();
				if (key.equals("cause") || key.equals("content")
						|| key.equals("taskType")) {
					continue;
				} else if (!(assignee.equals(variables.get(key)))) {
					// 3、查flowElement
					Iterator<FlowElement> iterator = this.findFlow(task
							.getProcessDefinitionId());
					while (iterator.hasNext()) {
						FlowElement flowElement = iterator.next();
						String classNames = flowElement.getClass()
								.getSimpleName();
						if (classNames.equals("UserTask")) {
							UserTask userTask = (UserTask) flowElement;
							String assginee11 = userTask.getAssignee();
							String assginee12 = assginee11.substring(
									assginee11.indexOf("{") + 1,
									assginee11.indexOf("}"));
							String assignee13 = (String) variables
									.get(assginee12);
							if (assignee.equals(assignee13)) {
								// 看下下一个节点是什么
								iterator.next();
								FlowElement flowElement2 = iterator.next();
								String classNames1 = flowElement2.getClass()
										.getSimpleName();
								// 设置下一个任务人
								if (!(classNames1.equals("EndEvent"))) {
									UserTask userTask2 = (UserTask) flowElement2;
									String assginee21 = userTask2.getAssignee();
									String assginee22 = assginee21.substring(
											assginee21.indexOf("{") + 1,
											assginee21.indexOf("}"));
									// String assignee23 = (String) variables
									// .get(assginee22);
									String assignee23 = taskModel
											.getNextPerson();
									variables1.put(assginee22, assignee23);
								}
							}
						}
					}
				}
			}
			taskService.complete(taskId, variables1);


		}
		return null;
	}




3.angular js前台代码(前台只是做简单的展示,不多讲):
  (1)app.js中配置路由:
 
  $stateProvider  
   .state('completeTaskTo', {  
   url: "/completeTaskTo",  
   views: {  
      'view': {  
       templateUrl: 'activi_views/completeTask.html',  
       controller: 'completeTaskCtr'  
      }  
   }  
  });  
   


  (2)逻辑相关代码:


   
angular.module('activitiApp')  
.controller('completeTaskCtr', ['$rootScope','$scope','$http','$location','$state', function($rootScope,$scope,$http,$location,$state){  


	$http.post("createFlush.do").success(function(result){
		if(result.isLogin==="yes"){
			$rootScope.userName=result.userName;
			if($rootScope.task==null||$rootScope.task.id==null){
				$location.path("/taskList");
			}else{
				$scope.task=$rootScope.task;
			}
		}else{
			$location.path("/login");
		}
	});


        $scope.completeTask=function(task){
        	console.log(task);
        	$rootScope.task=task;
        	$http.post("./completeTask.do",task).success(function(taskResult){
        		$location.path("/taskList");
        	});
        }
      
  
}])  




4.对应的填写相关信息的页面:


<div style="margin-top:20px;margin-left:200px;background-color:#ccf;height:550px;width:50%;font-size:18px;position:relative;float:left;">  
   <center> 
   <p style="font-size:24px;margin-top:10px">处理当前任务</p>
               类      型:<input ng-model="task.taskType" readonly="readonly" style="background-color:#9cf"></input>
      </br>  
      </br>
      NAME      :<input ng-model="task.name" readonly="readonly" style="background-color:#9cf"></input>
      </br>  
      </br>
               任  务  ID :<input ng-model="task.id" readonly="readonly" style="background-color:#9cf"></input>
      </br>  
      </br>  
      ProcessIntanceId:<input ng-model="task.processInstanceId" readonly="readonly" style="background-color:#9cf"></input>
      </br>  
      </br>
      ProcessDefId   :<input ng-model="task.processDefId" readonly="readonly" style="background-color:#9cf"></input>
      </br>  
      </br>
               创 建 时 间 :<input ng-model="task.createTime" readonly="readonly" style="background-color:#9cf"></input>
      </br>  
      </br>
               申  请  人 :<input ng-model="task.assignee" readonly="readonly" style="background-color:#9cf"></input>
      </br>  
      </br>
               受  理  人 :<input ng-model="task.nextPerson"></input>
      </br>  
      </br>
               申 请 原 因 :<input ng-model="task.cause"></input>
      </br>  
      </br>
               申 请 内 容 :<input ng-model="task.content"></input>
      </br>  
      </br>
      <input style="font-size:22px;cursor:pointer" type="button" value="处理任务" ng-click="completeTask(task);">  
           
      <input style="font-size:22px;cursor:pointer" type="button" value="返回"> 
   </center> 
</div>  
 


目录
相关文章
|
人工智能 Java Serverless
【MCP教程系列】搭建基于 Spring AI 的 SSE 模式 MCP 服务并自定义部署至阿里云百炼
本文详细介绍了如何基于Spring AI搭建支持SSE模式的MCP服务,并成功集成至阿里云百炼大模型平台。通过四个步骤实现从零到Agent的构建,包括项目创建、工具开发、服务测试与部署。文章还提供了具体代码示例和操作截图,帮助读者快速上手。最终,将自定义SSE MCP服务集成到百炼平台,完成智能体应用的创建与测试。适合希望了解SSE实时交互及大模型集成的开发者参考。
10229 60
|
1月前
|
监控 安全 Java
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
Spring Boot 通过 Actuator 模块提供了强大的健康检查功能,帮助开发者快速了解应用程序的运行状态。默认健康检查可检测数据库连接、依赖服务、资源可用性等,但在实际应用中,业务需求和依赖关系各不相同,因此需要实现自定义健康检查来更精确地监控关键组件。本文介绍了如何使用 @HealthEndpoint 注解及实现 HealthIndicator 接口来扩展 Spring Boot 的健康检查功能,从而提升系统的可观测性与稳定性。
112 0
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
|
7月前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器使用实例
本文主要讲解了Spring Boot中拦截器的使用实例,包括判断用户是否登录和取消特定拦截操作两大场景。通过token验证实现登录状态检查,未登录则拦截请求;定义自定义注解@UnInterception实现灵活取消拦截功能。最后总结了拦截器的创建、配置及对静态资源的影响,并提供两种配置方式供选择,帮助读者掌握拦截器的实际应用。
242 0
|
7月前
|
JSON Java 数据格式
微服务——SpringBoot使用归纳——Spring Boot中的全局异常处理——拦截自定义异常
本文介绍了在实际项目中如何拦截自定义异常。首先,通过定义异常信息枚举类 `BusinessMsgEnum`,统一管理业务异常的代码和消息。接着,创建自定义业务异常类 `BusinessErrorException`,并在其构造方法中传入枚举类以实现异常信息的封装。最后,利用 `GlobalExceptionHandler` 拦截并处理自定义异常,返回标准的 JSON 响应格式。文章还提供了示例代码和测试方法,展示了全局异常处理在 Spring Boot 项目中的应用价值。
315 0
|
8月前
|
IDE Java 应用服务中间件
spring boot 启动流程
Spring Boot 启动流程简介: 在使用 Spring Boot 之前,启动 Java Web 应用需要配置 Web 容器(如 Tomcat),并将应用打包放入容器目录。而使用 Spring Boot,只需运行 main() 方法即可启动 Web 应用。Spring Boot 的核心启动方法是 SpringApplication.run(),它负责初始化和启动应用上下文。 主要步骤包括: 1. **应用启动计时**:使用 StopWatch 记录启动时间。 2. **打印 Banner**:显示 Spring Boot 的 LOGO。 3. **创建上下文实例**:通过反射创建
445 5
|
10月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
10月前
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
3月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
782 0
|
10天前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
125 3
|
10天前
|
Java 测试技术 数据库连接
【SpringBoot(四)】还不懂文件上传?JUnit使用?本文带你了解SpringBoot的文件上传、异常处理、组件注入等知识!并且带你领悟JUnit单元测试的使用!
Spring专栏第四章,本文带你上手 SpringBoot 的文件上传、异常处理、组件注入等功能 并且为你演示Junit5的基础上手体验
291 2