由于工作需要,新接到一个小项目,什么?项目,ofbiz走起!项目中需要用到两个小流程,什么?流程 activiti5走起~
activiti5 是原生支持spring 的,可是怎么能让它与ofbiz整合到一块呢,ofbiz确实有自己的sharp 啥的,可是弄不懂啊,资料太少了。可是ofbiz与activiti5整合的资料更少啊,没办法,面对activii5的流程编辑器的诱惑,自己想招吧!
其实整合起来并不复杂,代码量也不多,我就来一步一步说具体操作
1.下载activiti5,我是从官网下的最新版 下载下来解压,我了个去这么些jar ,其实用到的也不多,主要用的有
activiti-bpmn-converter-5.17.0.jar
activiti-bpmn-layout-5.17.0.jar
activiti-bpmn-model-5.17.0.jar
activiti-common-rest-5.17.0.jar
activiti-crystalball-5.17.0.jar
activiti-diagram-rest-5.17.0.jar
activiti-engine-5.17.0.jar
activiti-explorer-5.17.0.jar
activiti-image-generator-5.17.0.jar
activiti-json-converter-5.17.0.jar
activiti-modeler-5.17.0.jar
activiti-process-validation-5.17.0.jar
activiti-simple-workflow-5.17.0.jar
commons-lang3-3.3.2.jar
jackson-annotations-2.2.3.jar
jackson-core-2.2.3.jar
jackson-databind-2.2.3.jar
javaGeom-0.11.1.jar
joda-time-2.6.jar
mybatis-3.2.5.jar
2.我使用的是ofbiz13就是最新版本那个,下一步就是新建一个component 叫做workflow模块
我是建在了framework 下面的,架构级么哈哈,新建component 我就不多介绍了,很多资料可以参考,我新建的component 包含了一下内容:
3 导入jar 包 并且添加classpath中(也就是说在ofbiz-component.xml中包含workflow的lib文件夹),如果component创建的配置都对的话,把你新建的component 加入到component-loader中,启动一下不报错说明你添加jar包成功了。
4.我的整合思路是通过ofbiz 启动加载 acitiviti 的processEngine 并且提供一个processEngineFactory 来获取activiti 的主要接口,那么在我们业务中随时都可以调用工作流引擎了.所以第一步要正确的加载ProcessEngine
ofbiz 强大之处就体现出来了,可以使用它的container 来加载我们的processEngine,我们创建一个workflowcontainer,并实现ofbiz 的container 接口:
package com.ly.workflow; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.ofbiz.base.container.Container; import org.ofbiz.base.container.ContainerException; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilProperties; import java.util.Properties; /** * Created by bo on 15/4/14. */ public class WorkflowContainer implements Container { private String name; private String dbFile= "workflow.db.properties"; @Override public void init(String[] args, String name, String configFile) throws ContainerException { this.name = name; Debug.log("---启动工作流模块---"); //获取工作流数据库配置文件 Properties jdbc=UtilProperties.getProperties(dbFile); //配置工作流引擎 ProcessEngineConfiguration pecfg = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); pecfg.setJdbcUsername(jdbc.getProperty("username")); pecfg.setJdbcPassword(jdbc.getProperty("password")); pecfg.setJdbcUrl(jdbc.getProperty("url")); pecfg.setJdbcDriver(jdbc.getProperty("driver")); //连接池设置 pecfg.setJdbcMaxActiveConnections(Integer.valueOf(jdbc.getProperty("jdbcMaxActiveConnections"))); pecfg.setJdbcMaxIdleConnections(Integer.valueOf(jdbc.getProperty("jdbcMaxIdleConnections"))); pecfg.setJdbcMaxCheckoutTime(Integer.valueOf(jdbc.getProperty("jdbcMaxCheckoutTime"))); pecfg.setJdbcMaxWaitTime(Integer.valueOf(jdbc.getProperty("jdbcMaxWaitTime"))); //设置启动检查数据表 pecfg.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); //创建表并获取流程引擎 ProcessEngine pe = pecfg.buildProcessEngine(); //todo 加载初始化流程 //初始化工作流引擎工厂 WorkflowProcessEngineFactory.init(pe,"default"); Debug.log("---工作流引擎加载成功---"); } @Override public boolean start() throws ContainerException { Debug.log("workflow-start"); return false; } @Override public void stop() throws ContainerException { Debug.log("workflow-stop"); } @Override public String getName() { return null; } }
这里需要注意的是我们要写一个配置文件来配置工作流引擎的数据库, activiti 是有自己的一套数据库框架的,也不是他的就是ibatis。。我们就创建一个配置文件来保存工作流引擎的数据库配置,其实也可以用ofbiz自己的连接池的,如果你需要可以自己配置,我是想把ofbiz本身的业务和工作流分开放不同的数据里。
之后我们就新建一个工厂类来保存我们创建的 processEngine:
package com.ly.workflow; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngineConfiguration; import org.activiti.engine.RepositoryService; import org.activiti.workflow.simple.converter.WorkflowDefinitionConversionFactory; import org.activiti.workflow.simple.converter.json.SimpleWorkflowJsonConverter; import org.ofbiz.base.lang.Factory; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilObject; import org.ofbiz.entity.Delegator; import java.util.concurrent.ConcurrentHashMap; /** * Created by bo on 15/4/14. */ public abstract class WorkflowProcessEngineFactory implements Factory<ProcessEngine,String> { public static final String module = WorkflowProcessEngineFactory.class.getName(); private static ProcessEngineConfiguration pecfg = null; private static final ConcurrentHashMap<String, ProcessEngine> processEngineCache = new ConcurrentHashMap<String, ProcessEngine>(); public static ProcessEngine getProcessEngine(String processEngineName){ if (processEngineName == null) { processEngineName = "default"; } ProcessEngine processEngine = processEngineCache.get(processEngineName); if (processEngine == null) { Debug.logInfo("没有找到工作流引擎", module); } return processEngine; } public static ProcessEngine getProcessEngine(){ return getProcessEngine("default"); } public static RepositoryService getRepositoryService(String processEngineName){ return getProcessEngine(processEngineName).getRepositoryService(); } public static RepositoryService getRepositoryService(){ return getRepositoryService("default"); } public static void init(ProcessEngine pe,String name){ WorkflowProcessEngineFactory.processEngineCache.put(name,pe); } }
如果你有对acitiviti 的借口需求的话,可以在工厂类中添加不同的获取方法,静态方法么,那块你想用取一下就行了,当然你也可以把processEngine 放到Context 里面方便获取。
4.之后你就可以把container 放在ofbiz 启动配置里面了,我觉得ofbiz的container 就相当于spring 一样,都是容器么,但是我觉得spring把简单的东西复杂化了,用的这个费劲,ofbiz 这点要强不少哦。
启动配置的位置在framework/base/config/ofbiz-containers.xml 中,添加一条你的工作流container:
<container name="workflow-container" loaders="main" class="com.ly.workflow.WorkflowContainer"/>
这样的话你启动ofbiz 就会帮你检查是否有activiti 的数据库和表,没有的话会帮你创建出来
如果没抱错,你现在的工作流引擎就可以使用了。。。
5.当然了,光有这些远远不够,activiti 的modeler 流程编辑器才是重点,它可以让你在线定义流程,图形化,可拖动,用户不就是喜欢这种傻瓜式的么,那么我们也吧流程编辑器也整合过来
其实acitiviti 的流程编辑器就是一大堆html 和js 啥的,通过ajax 请求与后台通讯,我们可以用ofbiz自己些逻辑,而前台交给他的编辑器,首先把activiti 的流程编辑器加进来,解压下载的activiti中 的activiti-explorer.war
编辑器其实就是上图的editor-app文件夹,把它拷贝到framwork/images/web-app/images下面
之后我们需要写一个screen 用来包含编辑器需要的js css 啥的,还有要给编辑器一个流程定义ID,
其实这个页面acitivity 中也有,就是上面那个modeler.html,那简单了拷~~~
新建 一个controller
<request-map uri="ProcessDefineModeler"> <security https="true" auth="true"/> <response name="success" type="view" value="ProcessDefineModeler"/> </request-map>
放在你能访问的WEB-INF/controller.xml中
之后建一个screen 来显示我们要的编辑器
<view-map name="ProcessDefineModeler" type="screen" page="component://workflow/widget/CommonScreens.xml#ProcessDefineModeler"/>
<screen name="ProcessDefineModeler"> <section> <actions> <set field="titleProperty" value="cache"/> <set field="headerItem" value="define"/> <set field="tabButtonItem" value="ProcessDefineEditor"/> </actions> <widgets> <platform-specific> <html> <html-template location="component://workflow/templates/processDefine/ProcessDefineModeler.ftl"/> </html> </platform-specific> </widgets> </section> </screen>
把ftl 创建出来,然后把modeler.html的内容拷贝进去(注意要把引用的js 还有css 还有 angelar js 的东西改成images/editor-app路径,确保里面的文件都能通过你的ofbiz服务器找到)
<div id="main" class="wrapper full clearfix" ng-style="{height: window.height + 'px'}" ng-app="activitiModeler" ng-include="'<@ofbizContentUrl>/images/editor-app/editor.html</@ofbizContentUrl>'"> </div>
主要是个,这个其实才是真正的编辑器。。这里可能要改的东西比较多,慢慢来吧,改到你看到的页面没有错误位置, 还有就是这里要有一个必要参数传进来,就是你的流程定义ID,修改引用路径使用ofbizcontenturl
like this:
<script src="<@ofbizContentUrl>/images/editor-app/libs/es5-shim-15.3.4.5/es5-shim.js</@ofbizContentUrl>"></script>
这里做完之后我们需要一个已有流程定义ID 来进入这个页面,这样才不会抱错,所以我们先来做一个流程管理页面
用semantic ui 加上w2ui 做了一个哈。左侧读出流程定义列表,右边显示流程具体信息和对流程定义的操作
这里的一些东西可以参考 activiti 自带的explore,其实说白了就是把他的explore 给弄成ofbiz版本的了,我的方法比较笨吧。。。但是集成度比较高
让编辑流程按钮 导向我们 流程定义页面跳转
哈哈流程定义图出来了,都是应文的,现在还没空翻译它讲究看吧
现在其实你们显示的还是一堆错误,是因为流程编辑器显示出来需要我们后台提供几个服务接口的,都是ajax json 调用,我们可以用ofbiz 来写后台返回个json 数据给他
修改 editor-app/config.js 把它请求服务的路径改为我们自己的
KISBPM.URL = { getModel: function(modelId) { return ACTIVITI.CONFIG.contextRoot + '/GetProcessModelById?modelId=' + modelId; }, getStencilSet: function() { //return ACTIVITI.CONFIG.contextRoot + '/editor/stencilset?version=' + Date.now(); return '/images/editor-app/stencilset.json'; }, putModel: function(modelId) { return ACTIVITI.CONFIG.contextRoot + '/SaveProcessModelById?modelId=' + modelId+"&" ; } };
还有app-cfg,js
'use strict'; var ACTIVITI = ACTIVITI || {}; ACTIVITI.CONFIG = { 'contextRoot' : '/workflow/control' };
你可能注意到了,编辑器还有保存功能,上面配置的一个路径就是保存功能的路径
之后你可以写一个service 还是别的什么,来处理保存逻辑
我的是这样的
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.node.ObjectNode import com.ly.workflow.WorkflowProcessEngineFactory import org.activiti.engine.ActivitiException import org.activiti.engine.RepositoryService import org.activiti.engine.repository.Model import org.apache.batik.transcoder.TranscoderInput import org.apache.batik.transcoder.TranscoderOutput import org.apache.batik.transcoder.image.PNGTranscoder import org.ofbiz.base.util.Debug String modelId = parameters.modelId; String name = parameters.name; String des = parameters.description; String svgXml = parameters.svg_xml; String jsonXml = parameters.json_xml; RepositoryService repositoryService = WorkflowProcessEngineFactory.getRepositoryService(); ObjectMapper objectMapper = new ObjectMapper(); try { Model model = repositoryService.getModel(modelId); ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo()); modelJson.put("name", name); modelJson.put("description", des); model.setMetaInfo(modelJson.toString()); model.setName(name); repositoryService.saveModel(model); repositoryService.addModelEditorSource(model.getId(), jsonXml.getBytes("utf-8")); InputStream svgStream = new ByteArrayInputStream(svgXml.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) { Debug.logError(e.getMessage(),"SaveProcessModelById.groovy"); }
因为流程图是生成出来的,所以调用activiti的接口比较多,具体的查一下activiti 的官方文档 或者是 看看一个叫咖啡兔的微博,很简单。
至此 整合完毕,其实还可以进一步进行封装与优化,并且把activiti explore 中的相关功能完善进去,这是一个整合其他框架的一个思路而已,其实spring 能整合的,ofbiz都能整合。这里不得不感叹ofbiz的强大。
相关推荐
主要目的是利用Spring的出色集成能力,使OFBiz能够与各种目标系统,特别是Activiti 5.9版本,进行无缝整合。这有助于扩展OFBiz的功能,使其能够支持复杂的业务流程管理。 2. **系统版本** - OFBiz版本为11.04,但...
基于万能逼近原理的自适应模糊控制算法在多自由度AUV运动控制中的应用与抗干扰补偿Simulink仿真研究,自适应模糊控制算法的万能逼近原理与多自由度AUV运动控制的抗干扰补偿技术——基于Simulink的仿真研究,万能逼近原理自适应模糊控制算法的多自由度AUV运动控制抗干扰补偿simulink仿真 ,核心关键词:万能逼近原理; 自适应模糊控制算法; 多自由度AUV运动控制; 抗干扰补偿; Simulink仿真。,基于万能逼近的模糊控制算法多自由度AUV抗干扰补偿Simulink仿真
deepseek最新资讯、配置方法、使用技巧,持续更新中
deepseek最新资讯、配置方法、使用技巧,持续更新中
结合扩展卡尔曼滤波与滑模观测器的策略:优化电角度估计,反电势波形逼近完美正弦波,结合扩展卡尔曼滤波与滑模观测器的反电势波形优化:正弦波形展现近乎完美精度,电角度估算与实际应用差异微小,扩展卡尔曼滤波与滑模观测器的结合,反电势波形近乎完美的正弦波形,观测器估算转子电角度与实际电角度相差0.3弧度左右,转速跟随效果较好。 ,核心关键词:扩展卡尔曼滤波; 滑模观测器; 反电势波形; 转子电角度估算; 转速跟随效果。,卡尔曼滑模观测器:优化正弦波转子角度与转速估算
毕业设计_基于springboot+vue的**学生公寓管理系统**【源码+sql+可运行】【**50217**】.zip 全部代码均可运行,亲测可用,尽我所能,为你服务; 1.代码压缩包内容 代码:springboo后端代码+vue前端页面代码; 脚本:数据库SQL脚本 效果图:运行结果请看资源详情效果图 2.环境准备: - JDK1.8+ - maven3.6+ - nodejs14+ - mysql5.6+ - redis 3.技术栈 - 后台:springboot+mybatisPlus+Shiro - 前台:vue+iview+Vuex+Axios - 开发工具: idea、navicate 4.功能列表 - 系统设置:用户管理、角色管理、资源管理、系统日志 - **业务管理:业务管理:公寓信息、房间信息、入住记录、学生信息** 3.运行步骤: 步骤一:修改数据库连接信息(ip、port修改) 步骤二:找到启动类xxxApplication启动 4.若不会,可私信博主!!!
1、文件内容:xorg-x11-server-source-1.20.4-29.el7_9.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/xorg-x11-server-source-1.20.4-29.el7_9.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
1、文件内容:yum-plugin-ps-1.1.31-54.el7_8.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/yum-plugin-ps-1.1.31-54.el7_8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊
基于模型预测控制(MPC)的无人船与无人车编队一致性协同控制研究(附原文献),基于模型预测控制(MPC)的无人船与无人车编队一致性协同控制研究(附原文献),无人船编队 无人车编队 MPC 模型预测控制 多智能体协同控制 一致性 MATLAB 无人车 USV 带原文献 ,无人船编队; 无人车编队; MPC 模型预测控制; 多智能体协同控制; 一致性; MATLAB; USV; 原文献,无人系统协同控制:MPC模型预测控制下的多智能体编队与一致性研究(原文献支撑)
4套中级通信工程师综合真题及答案(2019,2020,2021,2023),适用于需要考中级通信工程师的人群
deepseek最新资讯,配置方法,使用技巧,持续更新中
基于matlab的锁相环PLL相位噪声拟合仿真代码集合:多个版本建模与仿真,高质量的锁相环PLL仿真代码集合:Matlab与Simulink建模研究,[1]锁相环 PLL 几个版本的matlab相位噪声拟合仿真代码,质量杠杠的,都是好东西 [2]锁相环matlab建模稳定性仿真,好几个版本 [3]锁相环2.4G小数分频 simulink建模仿真 ,PLL; Matlab相位噪声拟合仿真; Matlab建模稳定性仿真; 锁相环2.4G小数分频Simulink建模仿真,MATLAB仿真系列:锁相环PLL及分频器建模仿真
exceptionLogs.zip
基于光伏微网的经济性与并网负荷波动率双目标优化调度策略:蓄电池与V2G协同管理策略仿真研究,MATLAB下光储充微网结合电动汽车V2G的多目标协同调度策略研究:经济性与并网负荷波动性的对比分析,MATLAB代码:考虑V2G的光储充一体化微网多目标优化调度策略 关键词:光储充微网 电电汽车V2G 多目标优化 蓄电池优化 调度 参考文档:《光伏微网下考虑V2G补偿蓄电池容量的双目标优化调度策略》,已经投稿EI会议,中文说明文档可联系我咨询 仿真平台:MATLAB 平台 优势:代码注释详实,适合参考学习,相关成果已经采用,程序非常精品,请仔细辨识 主要内容:过建立光伏微网中以经济性和并网负荷波动率为双目标的蓄电池和V2G的协同调度模型。 采用粒子群算法,对电网、微网调度中心和电动汽车用户三方在无、无序、转移和调度V2G电动汽车负荷四种运行模式下的经济和安全影响进行对比。 最后,根据算例分析,求解四种模式下两级负荷曲线及经济收益表。 对比分析得出,引入V2G可以替代部分容量的蓄电池,使光伏微网在负荷峰谷平抑、三方经济和安全等方面进一步优化。 求解采用的是PSO算法(粒子群算法),求解效果极
javascript 动态网页设计期末大作业(自己手写的,高分期末作业),含有代码注释,新手也可看懂,个人手打98分项目,导师非常认可的高分项目,毕业设计、期末大作业和课程设计高分必看,下载下来,简单部署,就可以使用。该项目可以直接作为毕设、期末大作业使用,代码都在里面,系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值,项目都经过严格调试,确保可以运行! javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期末大作业(自己手写的,高分期末作业)javascript 动态网页设计期
混合智能体系统编队控制:分布式优化与15异构混合阶的挑战,异构混合阶智能体系统编队控制的分布式优化策略研究,15异构混合阶多智能体系统编队控制的分布式优化(无参考文献) ,核心关键词:15异构混合阶; 多智能体系统; 编队控制; 分布式优化; 无参考文献。,15混合阶多智能体系统编队分布式优化控制
javascript 动态网页设计期末大作业(自己手写的,很适合期末作业),含有代码注释,新手也可看懂,个人手打98分项目,导师非常认可的高分项目,毕业设计、期末大作业和课程设计高分必看,下载下来,简单部署,就可以使用。该项目可以直接作为毕设、期末大作业使用,代码都在里面,系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值,项目都经过严格调试,确保可以运行! javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascript 动态网页设计期末大作业(自己手写的,很适合期末作业)javascrip
X光安检OPIXray数据集已经转换为VOC格式,可直接转换为为YOLO
DataX--Web:图形化界面简化大数据任务管理_datax-web