- 流程定义管理
- 步骤分析:
要想在实现一个能够完成流程定义的crud的功能,也就是在项目中能够对各种流程(客户报备,报销,请假等)进行crud,那就是一个完整的模块,应该单独独立一个菜单。并且完成这个菜单的模块管理。
- 菜单-跳转到管理界面
- 菜单模块管理
- 部署新流程-没有数据
- 查询流程图
- 删除/挂起/激活流程
- 列表/刷新流程
- 流程定义菜单实现
1 创建菜单
在流程管理下面创建一个流程定义管理的二级菜单 就有url
2 创建一个WorkFlowController要有一个跳转到流程定义管理界面的方法
该方法的映射地址就是菜单里面的url
3 创建流程管理界面
拷贝其他页面修改为流程管理页面
- 添加流程
1、先让后台能够接受来自前台的数据(/workflow/newDeploy)
2、编写IWorkFlowService完成项目的部署
注意1:
直接在控制器中注入工作流相关服务完成流程部署,还是自己写一个服务进行封装,这样在Controller里面就调用一句就搞定。
注意2:
编写部署方法时,不要传入页面层的API,
MutilpartFile而要传入InputStream 流.
注意3:
通过数据库信息查看是否部署成功。
//跳转到流程定义管理页面
@RequestMapping("/processDefinition/index")
public String processDefiniton() {
//流程定义管理界面路径,默认加上前缀和后缀
return "workFlow/processDefinition";
}
/**
* 参数:
* name:部署名称
* processFile:类型是MultipartFile,是SPringmvc用于文件上传接收的专用类
* 返回值:
* AJaxResult转换结果
*/
@RequestMapping("/newDeploy")
@ResponseBody
public AjaxResult newDeploy(String name,MultipartFile processFile) {
System.out.println(name);
System.out.println(processFile);
//1 不要直接注入RepositoryService来完成部署,应该交给对应Service去做
//2 MultipartFile就是web层api,如果我们直接传入,Service层就强依赖于web层API.也就是咱们这个Service必 须在web才能运行,不能强依赖.
try {
workFlowService.newDeploy(name,processFile.getInputStream());
return new AjaxResult();
} catch (IOException e) {
e.printStackTrace();
return new AjaxResult("部署失败!"+e.getMessage(),-1);
}
}
@Override
public void newDeploy(String name, InputStream inputStream) {
//完成真正部署
//1获取引擎对象
//2获取服务
//3做事情
ZipInputStream zis = null;
try {
zis = new ZipInputStream(inputStream);
//创建配置对象
DeploymentBuilder builder = repositoryService.createDeployment();
//进行配置
builder.name(name)//部署名称
.addZipInputStream(zis); //bpmn和png
//部署
builder.deploy();
} catch (Exception e) {
e.printStackTrace();
}
finally{
if (zis != null) {
try {
zis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 列表流程
前台:
修改datagrid的地址为/workFlow/listProcessDefinition
后台:
在WorkFlowController中添加一个返回Json数据的listProcessDefinition方法,
并完成对应地址“/workFlow/listProcessDefinition”的映射,并完成逻辑。
注意1:不能直接返回List<ProcessDefinition>
1、转换Json失败,原因时报延迟加载错误,事物在Service,但是在Controller中还需要数据库延迟加载,所以有问题。
2、ProcessDefinition有太多不需要的属性,需传递到前台。浪费网络资源。
需要返回一个List< Map<String,Object>>,具体map里面有那些key呢,需要
根据前台展示来。查看ProcessDefinition里面的属性,可以把重要的都展示出来。
注意2:所有的列没有占全整个宽度
注意3:把对象拷贝到map中使用工具类进行拷贝
//返回值:流程定义的list json格式
@RequestMapping("/listProcessDefinitions")
@ResponseBody
public List<Map<String, Object>> listProcessDefinitions() {
return workFlowService.listProcessDefinitions();
}
@Override
public List<Map<String, Object>> listProcessDefinitions() {
//创建查询对象
ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
//设置查询条件
query.orderByProcessDefinitionKey().desc();//相同的流程不同的版本放到一起
query.orderByProcessDefinitionVersion().desc();//版本安倒序排
//做查询
List<ProcessDefinition> list = query.list();
//申明要返回的类型
List<Map<String, Object>> result = new ArrayList<>();
//进行转换
for (ProcessDefinition processDefinition : list) {
//把一个processDefinition转换为一个Map
result.add(processDefinition2map(processDefinition));
}
//返回
return result;
}
private Map<String, Object> processDefinition2map(ProcessDefinition processDefinition) {
//申明要返回的类型
//Map<String, Object> result = new HashMap<>();
//进行转换
//result.put("id", processDefinition.getId());
//返回
// return result;
return CommUtil.obj2map(processDefinition, new String[]{
"id","name","key",
"version","deploymentId","resourceName",
"diagramResourceName","description"
});
}
删除等操作
@Override
public void deleteDeployment(String deploymentId) {
repositoryService.deleteDeployment(deploymentId);
}
查询流程图
一 点击"查看流程图"按钮,打开一个查询流程图对话框
里面需要展示流程图,先写死路径:/1.png
<img src="/1.png"/>
二 动态发请求到Controller获取流程图
<img src="/workFlow/viewDiagram?deploymentId=1&diagarmResoruceName=test.png"/>
三 deploymentId和resoruceName要动态获取
@RequestMapping("/viewProcessDefinitionPng")
public void viewProcessDefinitionPng(String deploymentId,String resourceName,HttpServletRequest request,HttpServletResponse response) throws IOException{
System.out.println("00000");
InputStream inputStream=null;
ServletOutputStream outputStream = null;
try {
System.out.println(resourceName);//MyProcess.myProcess.png
inputStream=definitionService.viewProcessDefinitionPng(deploymentId,resourceName);
outputStream=response.getOutputStream();
IOUtils.copy(inputStream, outputStream);
} catch (Exception e) {
e.printStackTrace();
}finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
public InputStream viewProcessDefinitionPng(String deploymentId, String resourceName) {
return repositoryService.getResourceAsStream(deploymentId, resourceName);
}
view:function(){
///workFlow/viewDiagram?deploymentId=1&diagarmResoruceName=test.png
//打开之前需要动态设置流程图的src地址
// 获取行选中数据
var rowData = processDefinitionGrid.datagrid("getSelected");
// 判断
if(!rowData){
$.messager.alert("温馨提示","请选中一行!!","info");
return;
}
var deploymentId = rowData.deploymentId;
var diagramResourceName = rowData.diagramResourceName;
var src = "/workFlow/viewDiagram?deploymentId="+deploymentId+"&diagarmResoruceName="
+diagramResourceName;
//动态设置src地址
$("#img").attr("src",src);
//打开流程图对话框
viewProcessDiagramDlg.dialog("open");
}
<!-- 2. 查看流程图对话框-->
<div id="viewProcessDiagramDlg" >
<!-- 第一步:写死路径
<img src="/1.png" alt="xxxxx">
-->
<!-- 2 通过Controller来响应 -->
<img id="img" src=""/>
</div>