`

spring2.5+jbpm4.3会签例子

阅读更多

导入jbpm4.3所有包,我用的mysql,c3数据源


jar包加上,可以直接跑测试类,源码带注释,我变懒了。
 项目中的CountersignActivity类更新为如下代码,之前的有点问题:

package com.bjhy.oa.service.workflow.util;

import java.util.HashMap;
import java.util.Map;

import org.jbpm.api.ExecutionService;
import org.jbpm.api.JbpmException;
import org.jbpm.api.TaskService;
import org.jbpm.api.activity.ActivityExecution;
import org.jbpm.api.task.Task;
import org.jbpm.jpdl.internal.activity.JpdlExternalActivity;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.history.HistoryEvent;
import org.jbpm.pvm.internal.history.events.TaskActivityStart;
import org.jbpm.pvm.internal.history.model.HistoryTaskImpl;
import org.jbpm.pvm.internal.model.Activity;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.model.Transition;
import org.jbpm.pvm.internal.script.ScriptManager;
import org.jbpm.pvm.internal.session.DbSession;
import org.jbpm.pvm.internal.task.TaskImpl;

import com.bjhy.oa.service.workflow.util.CountersignUser.Conclusion;

/**
 * 定制会签元素标签
 * 
 */
public class CountersignActivity extends JpdlExternalActivity {

	private static final long serialVersionUID = 1673162002085098868L;

	/**
	 * 默认的会签信息在上下文中的名字
	 */
	public static final String DEFAULT_COUNTERSIGN_VAR_NAME = "COUNTERSIGN";

	/**
	 * 任务的参与者,多个参与者用;号隔开
	 */
	private String assignees;

	/**
	 * Task的名字,可以不设置,不设置时将采用Activity的名字
	 */
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAssignees() {
		return assignees;
	}

	public void setAssignees(String assignees) {
		this.assignees = assignees;
	}

	/**
	 * 执行表达式语句获取结果
	 * 
	 * @param express
	 * @return
	 * @throws JbpmException
	 */
	protected String evaluateExpression(String express) throws JbpmException {
		if (express != null) {
			express = express.trim();
			if (express.length() > 0) {
				ScriptManager scriptManager = ScriptManager.getScriptManager();
				Object result = scriptManager.evaluateExpression(express, null);
				if (result != null) {
					express = result.toString();
				}
			}
		}
		return express;
	}

	/**
	 * 创建新的任务
	 * 
	 * @return
	 */
	private TaskImpl createCounterSignTask(DbSession dbsession,
			ExecutionImpl execution) {
		TaskImpl task = dbsession.createTask();
		String taskName = name == null ? execution.getActivityName() : name;
		task.setName(taskName);
		task.setExecution(execution);
		task.setProcessInstance(execution.getProcessInstance());
		task.setSignalling(false);
		dbsession.save(task);
		HistoryEvent.fire(new TaskActivityStart(task), execution);
		return task;
	}

	/**
	 * 创建会签子任务
	 * 
	 * @param dbsession
	 * @param execution
	 * @param task
	 * @param user
	 * @param ht
	 */
	public void newCounterSignSubTask(DbSession dbsession,
			ExecutionImpl execution, TaskImpl task, String user,
			HistoryTaskImpl ht) {
		TaskImpl subtask = task.createSubTask();
		subtask.setName(task + "_" + user);
		subtask.setAssignee(user);
		subtask.setSignalling(false);
		dbsession.save(subtask);
		ht.addSubTask(dbsession.get(HistoryTaskImpl.class, subtask.getDbid()));
	}

	/**
	 * 实例创建的时候会调用该方法
	 */
	public void execute(ActivityExecution activityExecution) {
		ExecutionImpl execution = (ExecutionImpl) activityExecution;
		// 创建当前任务
		DbSession dbsession = EnvironmentImpl.getFromCurrent(DbSession.class);
		ExecutionService executionService = EnvironmentImpl
				.getFromCurrent(ExecutionService.class);
		TaskImpl taskImpl = createCounterSignTask(dbsession, execution);
		HistoryTaskImpl ht = dbsession.get(HistoryTaskImpl.class, taskImpl
				.getDbid());

		CountersignInfo countersignInfo = new CountersignInfo();// 处理会签过程的类
		Map<String, CountersignUser> users = new HashMap<String, CountersignUser>();

		// 创建子任务
		for (String assignee : assignees.split(";")) {
			newCounterSignSubTask(dbsession, execution, taskImpl, assignee, ht);
			CountersignUser user = new CountersignUser(assignee);
			users.put(assignee, user);
		}

		countersignInfo.setUsers(users);// 保存所有用户
		countersignInfo.setCountersignStrategy(new AllAgreeStrategy());// 设置会签策略
		String name = activityExecution.getActivityName();
		dbsession.flush();
		executionService.setVariable(activityExecution.getId(), name
				+ "_COUNTERSIGN_INFO", countersignInfo);

		execution.waitForSignal();
	}

	/**
	 * 流程执行的时候会调用该方法
	 */
	public void signal(ActivityExecution activityExecution, String signalName,
			Map<String, ?> parameters) throws Exception {
		ExecutionImpl execution = (ExecutionImpl) activityExecution;
		ExecutionService executionService = EnvironmentImpl
				.getFromCurrent(ExecutionService.class);
		TaskService taskService = EnvironmentImpl
				.getFromCurrent(TaskService.class);
		String executionId = activityExecution.getId();
		Activity activity = execution.getActivity();
		Map<String, Object> variables = executionService.getVariables(
				executionId, executionService.getVariableNames(executionId));
		// 获取子任务
		Task subTask = (Task) parameters.get("subTask");
		Task superTask = ((TaskImpl) subTask).getSuperTask();
		taskService.completeTask(subTask.getId());// 结束子任务

		// 收集会签意见
		String countersignAgree = (String) parameters.get("countersignAgree");// 会签意见内容
		Conclusion conclusion = (Conclusion) parameters.get("conclusion");// 会签选择
		String assignee = subTask.getAssignee();// 会签人
		
		
		// 更新集合信息
		CountersignInfo countersignInfo = (CountersignInfo) variables
				.get(superTask.getActivityName() + "_COUNTERSIGN_INFO");

		Map<String, CountersignUser> users = countersignInfo.getUsers();
		CountersignUser countersignUser = users.get(assignee);
		countersignUser.setConclusion(conclusion);
		countersignUser.setCountersignAgree(countersignAgree);

		boolean allSign = true;

		// 遍历是否会签完毕
		for (CountersignUser item : users.values()) {
			if (item.getConclusion() == Conclusion.NOSTART) {
				allSign = false;
			}
		}
		countersignInfo.setAllSign(allSign);
		// 如果会签完毕,计算结果
		if (allSign) {
			countersignInfo.calculate();
			String agree = "同意";
			// 如果结果为否决
			if (countersignInfo.getConclusion() == Conclusion.DENED) {
				agree = "不同意";
			}
			variables.put("agree", agree);
			// 更新集合信息
			executionService.setVariables(executionId, variables);
			// 提交父任务
			// 会签完毕,删除父任务
			
			taskService.completeTask(superTask.getId());// 结束子任务
			Transition transition = null;
			if ((signalName == null)
					|| ((Task.STATE_COMPLETED.equals(signalName))
							&& (activity.getOutgoingTransitions() != null) && (activity
							.getOutgoingTransitions().size() == 1))) {
				transition = activity.getOutgoingTransitions().get(0);
			} else {
				transition = activity.findOutgoingTransition(signalName);
			}

			execution.take(transition);
			return;
		} else {
			// 否则继续等待
			execution.waitForSignal();
		}

	}

}

 CountersignUser类:

/**
 * 每个会签人的信息(可以根据需求写到数据库中)
 * 
 */
public class CountersignUser implements Serializable {

	private static final long serialVersionUID = -555010710697671504L;

	public enum Conclusion implements Serializable {
		/** 通过 */
		AGREE("同意"),
		/** 否决 */
		DENED("不同意"),
		/** 弃权 */
		ABSTAIN("弃权"),
		/** 还未查阅 */
		NOSTART("未查阅");
		
		private String desc;
		
		private Conclusion(String desc){
			this.desc = desc;
		}

		public String getDesc(){
			return desc;
		}
		
		
		
		
	}
	
	private Integer id;// 主键id
	private String assignee;// 参与者名字,唯一的
	private Conclusion conclusion = Conclusion.NOSTART;// 每个人的选择
	private String countersignAgree;// 意见内容

	public CountersignUser() {
		super();
	}

	public CountersignUser(String assignee) {
		super();
		this.assignee = assignee;
	}

	public Integer getId() {
		return id;
	}

	public String getCountersignAgree() {
		return countersignAgree;
	}

	public void setCountersignAgree(String countersignAgree) {
		this.countersignAgree = countersignAgree;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getAssignee() {
		return assignee;
	}

	public void setAssignee(String assignee) {
		this.assignee = assignee;
	}

	public Conclusion getConclusion() {
		return conclusion;
	}

	public void setConclusion(Conclusion conclusion) {
		this.conclusion = conclusion;
	}

}

 

  • 大小: 5.1 KB
分享到:
评论
2 楼 zhangyg 2010-12-20  
示例代码和文章中的代码不一致,请问以哪个为准。
示例中在子任务都结束后,没有删除父任务,请问是不是有问题。
没有这个代码:taskService.completeTask(superTask.getId());
1 楼 guofengcn 2010-07-20  
我过来支持来了!

相关推荐

    JBPM4工作流应用开始指南.rar

    26 2.3 安装脚本详解 27 2.3.1 关于配置文件 30 2.3.2 关于依赖库 31 2.4 安装到JBoss 31 2.5 安装到Tomcat 32 2.6 基于Web的Signavio流程设计器 33 2.6.1 jBPM Web流程设计器简介 33 2.6.2 独立安装Signavio 34 ...

    安川MP7系列工控系统源码解析:关键算法与硬件交互揭秘

    内容概要:本文深入剖析了安川MP7系列工业控制系统的关键源码,重点介绍了运动轨迹规划、通信协议处理以及故障处理机制等方面的技术细节。通过对实际代码片段的解读,揭示了该系统在硬件寄存器直接访问、特殊功能码处理等方面的独特之处。同时,文中还分享了一些基于实践经验得出的重要参数设置及其背后的故事,如特定摩擦补偿系数的选择原因等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对安川产品有一定了解并希望深入了解其内部工作机制的专业人士。 使用场景及目标:帮助读者掌握安川MP7系列控制器的工作原理,提高对类似系统的维护能力和故障排查效率。对于想要进一步研究或二次开发该系统的开发者来说,也能提供宝贵的参考资料。 其他说明:文章不仅限于理论讲解,还包括了许多来自一线的实际案例和经验教训,使读者能够更好地理解和应用所学知识。

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_.zip

    自动化测试与脚本开发_Python3_pynput_键盘鼠标操作录制执行代码生成工具_用于自动化测试_脚本录制_重复操作模拟_宏命令生成_提高工作效率_支持GUI界面_跨平台兼容_

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-深入分析Windows和Linux动态库应用异同.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    嵌入式八股文面试题库资料知识宝典-C语言总结.zip

    风储直流微电网母线电压控制策略与双闭环MPPT技术研究

    内容概要:本文详细探讨了风储直流微电网中母线电压控制的关键技术。首先介绍了风储直流微电网的背景和发展现状,强调了母线电压控制的重要性。接着阐述了永磁风机储能并网技术,解释了永磁风机如何通过直接驱动发电机将风能转化为电能,并确保与电网的同步性和稳定性。然后深入讨论了双闭环控制MPPT技术,这是一种通过内外两个闭环控制系统来实现实时调整发电机运行参数的技术,确保风机始终处于最大功率点附近。最后,文章探讨了储能控制母线电压平衡的方法,即通过储能系统的充放电操作来维持母线电压的稳定。结论部分指出,通过这些技术的有机结合,可以实现对风储直流微电网的有效管理和优化控制。 适合人群:从事新能源技术研发的专业人士、电气工程研究人员、风电系统工程师。 使用场景及目标:适用于希望深入了解风储直流微电网母线电压控制策略的研究人员和技术人员,旨在帮助他们掌握最新的控制技术和方法,以提高系统的稳定性和效率。 其他说明:文章还对未来风储直流微电网的发展进行了展望,指出了智能化和自动化的趋势,以及储能技术的进步对系统性能的影响。

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    嵌入式八股文面试题库资料知识宝典-C++object-oriented.zip

    【操作系统开发】HarmonyOS目录结构详解:构建高效开发环境与跨设备协同应用

    内容概要:文章详细介绍了HarmonyOS的目录结构及其重要性,从整体框架到核心目录的具体功能进行了全面剖析。HarmonyOS凭借其分布式架构和跨设备协同能力迅速崛起,成为全球操作系统领域的重要力量。文章首先概述了HarmonyOS的背景和发展现状,强调了目录结构对开发的重要性。接着,具体介绍了根目录文件、AppScope、entry和oh_modules等核心目录的功能和作用。例如,AppScope作为全局资源配置中心,存放应用级的配置文件和公共资源;entry目录是应用的核心入口,负责源代码和界面开发。此外,文章还对比了HarmonyOS与Android、iOS目录结构的异同,突出了HarmonyOS的独特优势。最后,通过旅游应用和电商应用的实际案例,展示了HarmonyOS目录结构在资源管理和代码组织方面的应用效果。; 适合人群:具备一定编程基础,尤其是对移动操作系统开发感兴趣的开发者,包括初学者和有一定经验的研发人员。; 使用场景及目标:①帮助开发者快速理解HarmonyOS的目录结构,提高开发效率;②为跨设备应用开发提供理论和技术支持;③通过实际案例学习资源管理和代码组织的最佳实践。; 其他说明:HarmonyOS的目录结构设计简洁明了,模块职责划分明确,有助于开发者更好地管理和组织代码和资源。随着万物互联时代的到来,HarmonyOS有望在开发便利性和生态建设方面取得更大进展,吸引更多开发者加入其生态系统。

    飞轮储能充放电控制Simulink仿真模型:基于永磁同步电机的矢量控制与dq轴解耦

    内容概要:本文详细介绍了飞轮储能充放电控制的Simulink仿真模型,重点在于采用永磁同步电机的矢量控制和dq轴解耦控制策略。充电时,外环控制转速,内环控制dq轴电流;放电时,外环控制直流母线电压,内环同样控制dq轴电流。文中还讨论了硬件与软件环境的选择,以及仿真模型的调试与运行情况,最终得出该模型具有良好的跟随性能和波形完美度。 适用人群:从事电力电子系统、储能技术和Simulink仿真的研究人员和技术人员。 使用场景及目标:适用于需要对飞轮储能系统进行深入研究和仿真的场合,旨在提高充放电效率和稳定性,满足不同应用场景的需求。 其他说明:该仿真模型已调试完成,可以直接用于进一步的研究和实际应用,为未来的飞轮储能技术研发提供了有价值的参考。

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-北京瑞德方科技.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    嵌入式八股文面试题库资料知识宝典-同方万维硬件测试工程师.zip

    1_15套python PDF格式.zip

    1_15套python PDF格式.zip

    三相三电平整流器仿真:基于电压电流双闭环控制与SPWM调制的性能分析

    内容概要:本文详细介绍了三相三电平整流器的仿真过程及其性能分析。文中首先概述了三相三电平整流器的基本概念及其在电力系统中的重要作用,接着重点探讨了电压电流双闭环控制方式的工作原理和优势,以及SPWM调制技术的具体应用。通过仿真文件展示了整流器在不同条件下的响应情况,验证了这两种技术的有效性和优越性。最后,作者表达了对未来实际应用的期望。 适合人群:从事电力电子研究的技术人员、高校相关专业师生、对电力控制系统感兴趣的工程爱好者。 使用场景及目标:适用于希望深入了解三相三电平整流器工作原理和技术细节的研究人员;目标是在理论基础上掌握电压电流双闭环控制和SPWM调制的实际应用方法。 其他说明:本文提供的仅为仿真文件,未涉及实物实验数据。

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-恒光科技.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-北京天华威视科技有限公司面试题.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    嵌入式八股文面试题库资料知识宝典-微软研究院笔试题目的答案.zip

    Arduino UART实验例程【正点原子EPS32S3】

    Arduino UART实验例程,开发板:正点原子EPS32S3,本人主页有详细实验说明可供参考。

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-朝歌数码.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

    嵌入式八股文面试题库资料知识宝典-Cortex系列.zip

    嵌入式八股文面试题库资料知识宝典-中科中科长青笔试题.zip

    嵌入式八股文面试题库资料知识宝典-中科中科长青笔试题.zip

Global site tag (gtag.js) - Google Analytics