【代码篇】JBPM4.4结合业务实现简单工作流


继博客【思想篇】工作流技术JBPM开发入门(三)的实现完成!应对业务的变化。

 

其实这次对于工作流的学习大概分了3主要个阶段:

 

1,结合业务开发一个简单的工作流,应对业务的变更

2,结合业务开发业务结点,使流程管理业务

3,抽象实体,使开发出来的业务结点能够复用

 

下面要说的是第一阶段:

 

启动流程实例:

/** 提交申请 */
	public String submit() throws Exception {
		
		// 封装申请信息
		Application application = new Application();
		title=new String(title.getBytes("iso-8859-1"),"utf-8");
		reason=new String(reason.getBytes("iso-8859-1"),"utf-8");
		application.setApplicant(getCurrentUser()); // 申请人,当前用户	
		application.setTitle(title);
		application.setReason(reason);
	 	String processDefinitionKeyStr=new String(processDefinitionKey.getBytes("iso-8859-1"),"utf-8");
		application.setProcessDefinitionKey(processDefinitionKeyStr);

		// 调用业务方法(保存申请信息,并启动流程开始流转)
		applicationService.submit(application);

		return "toMyApplicationList"; // 成功后转到"我的申请查询"
	}

对应的流程代码:

public void submit(Application application) {
		// 1,设置属性并保存application
		application.setApplyTime(sdf.format(new Date())); // 申请时间,当前时间
		application.setStatus(Application.STATUS_RUNNING);		
		

		// 2,启动程程实例开始流转
		// >> 准备流程变量
		Map<String, Object> variablesMap = new HashMap<String, Object>();
		variablesMap.put("application", application);
		// >> 启动流程实例,并带上流程变量(当前的申请信息)
		
		//获取流程定义的key
		
		String pdKey = application.getProcessDefinitionKey();
		
		//根据流程定义的key值和相应的流程变量启动流程		
		ProcessInstance pi = processEngine.getExecutionService()//
				.startProcessInstanceByKey(pdKey, variablesMap);
		application.setExecuteId(pi.getId());
		getSession().save(application); // 保存
		
		// >> 办理完第1个任务“提交申请”
		Task task = processEngine.getTaskService()// 
				.createTaskQuery()// 查询出本流程实例中当前仅有的一个任务“提交申请”
				.processInstanceId(pi.getId())//
				.uniqueResult();
		processEngine.getTaskService().completeTask(task.getId());
	}

审批处理:

/** 审批处理 */
		public String approve() throws Exception {
			// 封装
			ApproveInfo approveInfo = new ApproveInfo();
											
		 	comment=new String(comment.getBytes("iso-8859-1"),"utf-8");
			
			approveInfo.setComment(comment);
			approveInfo.setApproval(approval);
			approveInfo.setApplication(applicationService.getById(applicationId));
			
			
			approveInfo.setApprover(getCurrentUser()); // 审批人,当前登录用户					
			approveInfo.setApproveTime(sdf.format(new Date())); // 当前时间
			if(outcome!=null){
				// 调用用业务方法(保存本次审批信息,并办理完任务,并维护申请的状态)
				outcome=new String(outcome.getBytes("iso-8859-1"),"utf-8");
			}
			applicationService.approve(approveInfo, taskId, outcome);

			return "toMyTaskList"; // 成功后转到待我审批页面
		}

对应的流程代码:

//办理任务
	public void approve(ApproveInfo approveInfo, String taskId, String outcome) {
		// 1,保存本次审批信息
		getSession().save(approveInfo);

		// 2,办理完任务
		Task task = processEngine.getTaskService().getTask(taskId); // 一定要先取出Task对象,再完成任务,否则拿不到,因为执行完就变成历史信息了。
		if (outcome == null) {
			processEngine.getTaskService().completeTask(taskId);
		} else {
			processEngine.getTaskService().completeTask(taskId, outcome);
		}

		// >> 取出所属的流程实例,如果取出的为null,说明流程实例执行完成了,已经变成了历史记录
		ProcessInstance pi = processEngine.getExecutionService().findProcessInstanceById(task.getExecutionId());

		// 3,维护申请的状态
		Application application = approveInfo.getApplication();
		if (!approveInfo.isApproval()) {
			// 如果本环节不同意,则流程实例直接结束,申请的状态为:未通过
			if (pi != null) { // 如果流程还未结束
				processEngine.getExecutionService().endProcessInstance(task.getExecutionId(), ProcessInstance.STATE_ENDED);
			}
			application.setStatus(Application.STATUS_REJECTED);
		} else {
			// 如果本环节同意,而且本环节是最后一个环节,则流程实例正常结束,申请的状态为:已通过
			if (pi == null) { // 本环节是最后一个环节,即流程已经结束了
				application.setStatus(Application.STATUS_APPROVED);
			}
		}
		getSession().update(application);
	}

待我审批:

/** 待我审批(我的任务列表) */
		public String myTaskList() throws Exception {
					
			List<TaskView> taskViewList = applicationService.getMyTaskViewList(getCurrentUser());
			//List<TaskView> taskViewList = applicationService.getMyTaskViewList(user);
			ActionContext.getContext().put("taskViewList", taskViewList);
			return "myTaskList";
		}

对应的流程代码:(此时需要查看流程的数据以及业务数据的共存)

public List<TaskView> getMyTaskViewList(User currentUser) {
		// 查询我的任务列表
		String userId = currentUser.getUsername(); // 约定使用loginName作为JBPM用的用户标识符
		List<Task> taskList = processEngine.getTaskService().findPersonalTasks(userId);
		
		// 找出每个任务对应的申请信息
		List<TaskView> resultList = new ArrayList<TaskView>();
		for (Task task : taskList) {
			
			Application application = (Application) processEngine.getTaskService().getVariable(task.getId(), "application");
			resultList.add(new TaskView(task, application));
		}

		// 返回“任务--申请信息”的结果
		return resultList;
	}

TaskView实体:

public class TaskView {

	private Task task;
	private Application application;

	public TaskView(Task task, Application application) {
		this.task = task;
		this.application = application;
	}

	public Task getTask() {
		return task;
	}

	public void setTask(Task task) {
		this.task = task;
	}

	public Application getApplication() {
		return application;
	}

	public void setApplication(Application application) {
		this.application = application;
	}

}


查询流转记录:此时的这个流转记录其实调用的是自己的业务,跟流程并没有关系,因为在这个业务中我们共建立了两个实体类,申请实体类,办理实体类,一个申请对应多个办理,它们之间是一对多的关系。当然我们也可以不建立办理实体类,而是将所有的办理结果均存到流程变量中,也可以查看申请的流转记录。(多种方式)


通过以上的代码,大家不难发现,所有的业务和工作流紧密结合,这就要求所有的程序员去熟悉工作流的使用,而且它们之间的耦合程度高,这就给维护带来了麻烦,但是即使是这样的实现,它也能应对一些变化。例如:学生申请修改课程的业务,导员审批--教秘审批,最终审批结束。如果我们在导员审批之前要加上班长审批这一环节,对于我们来说代码无需修改就可以实现。但是这样就真的万事大吉了吗?这也就带来了【思想篇】工作流技术JBPM开发入门(四)篇博客的问题所在.




你可能感兴趣的:(【代码篇】JBPM4.4结合业务实现简单工作流)