Activti项目实战一

一、项目需求
在现有的Crm项目中,集成Activiti工作流框架,实现一个“客户报备”流程管理。
为了确保录入的客户信息都是有效的,防止市场人员作假。对于录入的客户信息需要进行报备审批,也就是需要通过部门经理审批。
具体流程如下:
在这里插入图片描述
二、项目分析

1、准备一个现有的(可以正常运行的)CRM项目。
导入项目Activiti-CRM.rar
创建数据库activiti-crm
导入sql脚本itsource_crm.sql
部署crm到tomcat
确保CRM中,需要加入流程管理的业务模块(客户管理)能够正常运行
2、把Activiti集成到Crm项目中
3、流程定义(规则)管理
虽然当前分析出来只有一个客户报备流程,但是后面可能会集成其他流程(报销流程等),所以需要一个管理各种流程规则的模块.具体需要的流程如下:
1) 部署新流程
2) 查看(列表)流程
3) 删除流程
4) 查看规则流程图
4、流程实例和流程任务管理(运行时管理)
1)启动流程
2)查看任务
3)办理任务
4)使用流程监听器,修改业务对象状态。
扩展:
1、多出口任务
2、流程批注管理

三、集成Activiti框架

Activiti集成CRM

框架集成的核心??
Spring框架叫做项目(资源)的管家。
如果待集成项目中,有Spring框架,那么主要就是和“Spring框架”做集成。

把Activiti框架的“核心类”交给Spring管理;-- Activiti的核心类,引擎配置对象,引擎对象,三大服务对象
如果框架有事务,也要把“事务”交给Spring管理。

集成步骤:
1、导入activiti jar包
activiti-5.16.4\wars\activiti-rest\WEB-INF\lib\activiti*.jar
mybatis-3.2.5.jar (尽量使用高版本)
joda-time-2.1.jar

有可能会缺失其他包,ClassNotFound 差什么引入什么?
Maven怎么引入? 到中央仓库,搜索Activiti,拷贝pom的的代码端即可
2、添加Activiti配置文件-applicationContext-activiti.xml-配置核心对象
用户手册中,第5章,前两节。
3、把Activiti配置文件-applicationContext-activiti.xml集成到Spring
4、测试
通过Spring容器,注入Activiti核心服务,检测集成是否成功!!
也可以从数据库也能看到是否集成成功,看表是否创建了

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
		<property name="dataSource" ref="dataSource" />
		<property name="transactionManager" ref="transactionManager" />
		<property name="databaseSchemaUpdate" value="true" />
	</bean>

	<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
		<property name="processEngineConfiguration" ref="processEngineConfiguration" />
	</bean>

	<bean id="repositoryService" factory-bean="processEngine"
		factory-method="getRepositoryService" />
	<bean id="runtimeService" factory-bean="processEngine"
		factory-method="getRuntimeService" />
	<bean id="taskService" factory-bean="processEngine"
		factory-method="getTaskService" />
	<bean id="formService" factory-bean="processEngine"
		factory-method="getFormService" />


集成测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
public class ActivitiEnvTest {

	@Autowired
	private RepositoryService repositoryService;
	@Test
	public void test() {
		System.out.println(repositoryService);
	}
}

四、流程定义(流程规则)管理

4.1步骤分析
要想在实现一个能够完成流程定义的crud的功能,也就是在项目中能够对各种流程(客户报备,报销,请假等)进行crud,那就是一个完整的模块,应该单独独立一个菜单。并且完成这个菜单的模块管理。
1)菜单-跳转到管理界面
2)菜单模块管理
i.部署新流程-没有数据
ii.列表/刷新流程
iii.删除/挂起/激活流程
iv.查询流程图

4.2流程定义菜单实现
1 创建菜单
在流程管理下面创建一个流程定义管理的二级菜单 就有url
2 创建一个WorkFlowController要有一个跳转到流程定义管理界面的方法
该方法的映射地址就是菜单里面的url
3 创建流程管理界面
拷贝其他页面修改为流程管理页面

4.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转换结果
	 * @return
	 */
	@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();
				}
			}
		}
	}

4.4列表流程
前台:
修改datagrid的地址为/workFlow/listProcessDefinition
后台:
在WorkFlowController中添加一个返回Json数据的listProcessDefinition方法,
并完成对应地址“/workFlow/listProcessDefinition”的映射,并完成逻辑。

注意:不能直接返回List
1、转换Json失败,原因时报延迟加载错误,事物在Service,但是在Controller中还需要数据库延迟加载,所以有问题。
2、ProcessDefinition有太多不需要的属性,需传递到前台。浪费网络资源。
需要返回一个List< Map<String,Object>>,具体map里面有那些key呢,需要
根据前台展示来。查看ProcessDefinition里面的属性,可以把重要的都展示出来。

	//返回值:流程定义的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"
          });
	}

4.5.删除等操作

@Override
	public void deleteDeployment(String deploymentId) {
		repositoryService.deleteDeployment(deploymentId);
	}

4.6查询流程图
一 点击"查看流程图"按钮,打开一个查询流程图对话框
里面需要展示流程图,先写死路径:/1.png

二 动态发请求到Controller获取流程图

三 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>

此文主要详细得讲解了流程规则得管理,其中面试重要得其中一点是Spring中怎么集成Activiti 可仔细参阅文档了解如何集成Activiti框架

猜你喜欢

转载自blog.csdn.net/weixin_43849591/article/details/84679936