一 Activiti-Mpdeler简介
Activiti-Mpdeler是在Activiti-explorer中的,我们可以在Eclipse中设计完成了流程,然后导入流程模型,也可以通过在线流程设计器进行设计,然后部署得到流程模型。然后把流程模型部署得到流程定义。
二. 集成步骤:
1.拷贝资源
在线流程设计器需要一些资源支持
2.流程模型模块
和activiti-explorer一样我们需要实现来管理模块的创建,部署导入等操作
3.在线流程设计器
当创建完模型或修改模型时都应该打开“在线流程设计器”,设计完成后要完成模块的保存。
1.拷贝资源
1.1 准备:
确定activiti-explorer工程地址,以便拷贝资源
1.2 添加activiti-explorer下Modeler资源
1.21后台资源:jar包
activiti-crystalball-5.16.4.jar
activiti-diagram-rest-5.16.4.jar
activiti-explorer-5.16.4.jar
activiti-modeler-5.16.4.jar
拷贝Activiti所有的jar来进行替换
1.22前台资源:js等
1.23添加配置文件
1.24配置Modler控制器支持
2.在crm模型管理模块的开发
1、在菜单中添加一个菜单叫”模型管理”
2、点击该菜单,会通过一个Controller跳转一个模型管理的主界面
Controller直接拷贝以下ModelComtroller.java
package cn.itsource.crm.web.controller;
import java.io.ByteArrayInputStream;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import cn.itsource.crm.utils.AjaxResult;
/**
* 流程模型控制器
*
* @author xx
*/
@Controller
@RequestMapping(value = "/workflow/model")
public class ModelController {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private RepositoryService repositoryService;
/**
* 模型页面
*/
@RequestMapping(value = "/index")
public String model() {
// ModelAndView mav = new ModelAndView("workflow/model");
// List list = repositoryService.createModelQuery().list();
// mav.addObject("list", list);
// return mav;
return "workFlow/model";
}
/**
* 模型列表
*/
@RequestMapping(value = "/list")
@ResponseBody
public List<Model> modelList() {
List<Model> list = repositoryService.createModelQuery().list();
return list;
}
/**
* 创建模型:
* 保存模型数据;
* 调整到在线流程设计器页面
*/
@RequestMapping(value = "/create")
public void create(@RequestParam("name") String name, @RequestParam("key") String key, @RequestParam("description") String description,
HttpServletRequest request, HttpServletResponse response) {
try {
// 创建编辑的节点
ObjectMapper objectMapper = new ObjectMapper();
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);
// 创建模型对象
Model modelData = repositoryService.newModel();
// 封装模型对象
ObjectNode modelObjectNode = objectMapper.createObjectNode();
modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
description = StringUtils.defaultString(description);
modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
modelData.setMetaInfo(modelObjectNode.toString());
modelData.setName(name);
modelData.setKey(StringUtils.defaultString(key));
// 保存模型对象
repositoryService.saveModel(modelData);
// 保存该模型的编辑信息
repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
// response.sendRedirect(request.getContextPath() + "/service/editor?id=" + modelData.getId());
// 使用模型信息,打开Activiti-modeler编辑器
response.sendRedirect(request.getContextPath() + "/js/wf/modeler.html?modelId=" + modelData.getId());
} catch (Exception e) {
logger.error("创建模型失败:", e);
}
}
/**
* 根据Model部署流程
*/
@RequestMapping(value = "/deploy/{modelId}")
@ResponseBody
public AjaxResult deploy(@PathVariable("modelId") String modelId) {
try {
// 获取模型信息
Model modelData = repositoryService.getModel(modelId);
// 读取模型的编辑器内容
ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
byte[] bpmnBytes = null;
// 解析编辑器的内容,把resultful数据转变为一个bpmn模型对象
BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
// 再使用BpmnXML转换器,把内容解析为bpmn结构的xml
bpmnBytes = new BpmnXMLConverter().convertToXML(model);
// 以二进制方式,读取部署信息
String processName = modelData.getName() + ".bpmn20.xml";
repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes)).deploy();
return new AjaxResult("部署成功");
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult("部署失败",-2);
}
}
@RequestMapping("/delete/{modelId}")
@ResponseBody
public AjaxResult delete(@PathVariable("modelId") String modelId){
try {
System.out.println(modelId);
repositoryService.deleteModel(modelId);
return new AjaxResult("删除模型成功");
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult("删除模型失败",-2);
}
}
}
3、在模型管理界面完成模型的管理操作(创建,部署,列表,删除)
界面直接拷贝 拷贝以下model.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>流程模型管理</title>
<!--
统一步骤:
* 引入通用资源"WebContent/WEB-INF/views/common.jsp"
-------在页面加载完毕后----------
1、声明页面中,哪些组件需要获取后,使用的
2、获取需要使用的组件,并缓存
3、初始化
4、创建一个命令对象,来管理页面中,需要调用的方法
5、对页面中所有按钮,统一添加事件(如何区分不同按钮的逻辑??)
-->
<%@ include file="/WEB-INF/views/common.jsp" %>
<script type="text/javascript">
//---页面加载完毕后---
$(function(){
// 1. 声明页面中可能会用到组件
var modelGrid,modelDlg,modelForm;
// 2. 缓存页面组件
modelGrid = $("#modelGrid");
modelDlg = $("#modelDlg");
modelForm = $("#modelForm");
allPermissiongrid = $("#allPermissiongrid");
// 3. 定义一个事件处理对象,把事件相关的逻辑都封装到一个对象上(命令对象)
var cmdObj = {
create:function(){
modelDlg.dialog("open");
},
deploy:function(){
// 获取行选中数据
var rowData = modelGrid.datagrid("getSelected");
// 判断
if(!rowData){
$.messager.alert("温馨提示","请选中一行!!","info");
return;
}
var modelId=rowData.id;
var url="/workflow/model/deploy/"+modelId;
$.get(url,function(data){
if(data.success){
// 提示,刷新
$.messager.alert("温馨提示",data.message,"info",function(){
// 刷新表格数据
modelGrid.datagrid("reload");
});
}else{
$.messager.alert("温馨提示",data.message,"info",function(){
// 根据错误码,定位到单元格
});
}
},"json");
},
edit:function(){
//console.debug('edit:function');
// 获取行选中数据
var rowData = modelGrid.datagrid("getSelected");
// 判断
if(!rowData){
$.messager.alert("温馨提示","请选中一行!!","info");
return;
}
window.open("/js/wf/modeler.html?modelId="+rowData.id);
},
del:function(){
// 获取行选中数据
var rowData = modelGrid.datagrid("getSelected");
// 判断
if(!rowData){
$.messager.alert("温馨提示","请选中一行!!","info");
return;
}
var modelId=rowData.id;
console.debug(modelId)
var url="/workflow/model/delete/"+modelId;
$.get(url,function(data){
if(data.success){
// 提示,刷新
$.messager.alert("温馨提示",data.message,"info",function(){
// 刷新表格数据
modelGrid.datagrid("reload");
});
}else{
$.messager.alert("温馨提示",data.message,"info",function(){
// 根据错误码,定位到单元格
});
}
},"json");
},
refresh : function(){
modelGrid.datagrid("reload");
},
save: function(){
modelForm.submit();
},
cancel : function(){
modelDlg.dialog("close");
}
};
// 4. 初始化组件
modelGrid.datagrid({
url:"/workflow/model/list",
fit:true,
border:false,
fitColumns:true ,
striped:true,
toolbar:[{
text:"新建模型",
iconCls:"icon-add",
plain:true,
handler:cmdObj['create']
},{
text:"编辑模型",
iconCls:"icon-edit",
plain:true,
handler:cmdObj['edit']
},{
text:"删除模型",
iconCls:"icon-remove",
plain:true,
handler:cmdObj['del']
},{
text:"部署流程",
iconCls:"icon-remove",
plain:true,
handler:cmdObj['deploy']
},{
text:"刷新",
iconCls:"icon-reload",
plain:true,
handler:cmdObj['refresh']
}],//"#modelTb",
rownumbers:true,
singleSelect:true,
pagination:true,
columns:[[
{field:'id',title:'ID',width:1},
{field:'name',title:'名称',width:1},
{field:'key',title:'KEY',width:1},
{field:'createTime',title:'创建时间',width:1},
{field:'description',title:'描述',width:1}
]]
});
modelDlg.dialog({
width: 400,
height: 220,
title:"部署新流程",
closed:true,
modal:true,
buttons:[{
text:"创建模型",
iconCls:"icon-save",
handler:cmdObj['save']
},{
text:"取消",
iconCls:"icon-cancel",
handler:cmdObj['cancel']
}]//"#modelDlgBtn"
});
});
</script>
</head>
<body>
<!-- 1. 表格-->
<table id="modelGrid">
</table>
<!-- 2. 对话框-->
<div id="modelDlg" >
<font style="font-weight: bold;"></font>
<form id="modelForm" action="/workflow/model/create" method="post" enctype="application/x-www-form-urlencoded">
<table align="center" style="margin-top: 10px;">
<tr>
<td>模型名称:</td>
<td><input name="name"></td>
</tr>
<tr>
<td>模型KEY:</td>
<td><input name="key"></td>
</tr>
<tr>
<td>描述:</td>
<td><input name="description"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
3.在线流程设计其实现
1. 场景
当“创建”和“修改”模型时,会打开流程设计器,设计完成后序保存模块。
2.实现
添加和修改的url就ok
添加:
修改:
当然这样会报一个404错误,
解决方法:
需要开启:
<!-- 支持MVC的注解 -->
<mvc:annotation-driven/>
另外还会在保存的时候少jar,要导入相应的jar包
以上便是CRM对Activiti-Madeler的集成。