SSH与工作流Activiti的集成开发

Activiti 数据库表结构说明:

数据库表结构说明:

·ACT_GE_PROPERTY:属性数据表。存储整个流程引擎级别的数据。

1.NAME_:属性名称

2.VALUE_:属性值

3.REV_INT:版本号?

·ACT_GE_BYTEARRAY:用来保存部署文件的大文本数据的。

1.ID_:资源文件编号,自增长

2.REV_INT:版本号?

3.NAME_:资源文件名称

4.DEPLOYMENT_ID_:来自于父表ACT_RE_DEPLOYMENT中的主键

5.BYTES_:大文本类型,存储文本字节流

·ACT_RE_DEPLOYMENT:用来存储部署时需要被持久化保存下来的信息。

1.ID_:部署编号,自增长

2.NAME_:部署的包名称

3.DEPLOY_TIME_:部署时间

·ACT_RE_PROCDEF:业务流程定义数据表。

1.ID_:流程ID,由“流程编号:流程版本号:自增长ID”组成

2.CATEGORY_:流程命令空间(该编号就是流程文件targetNamespace的属性值)

3.NAME_:流程名称(该编号就是流程文件process元素的name属性值)

4.KEY_:流程编号(该编号就是流程文件process元素的id属性值)

5.VERSION_:流程版本号(由程序控制,新增即为1,修改后依次加1来完成的)

6.DEPLOYMENT_ID_:部署编号

7.RESOURCE_NAME_:资源文件名称

8.DGRM_RESOURCE_NAME_:图片资源文件名称

9.HAS_START_FORM_KEY_:是否有Start Form Key。

注意:此表与ACT_RE_DEPLOYMENT是多对一的关系,即,一个部署的bar包里可能包含多个流程定义文件,每个流程定义文件都会有一条记录在ACT_RE_PROCDEF表内,每条流程定义的数据,都会对应ACT_GE_BYTEARRAY表内的一个资源文件和PNG图片文件。与ACT_GE_BYTEARRAY的关联是通过程序用ACT_GE_BYTEARRAY.NAME_与ACT_RE_PROCDEF.RESOURCE_NAME_完成的,在数据库表结构内没有体现。

·ACT_ID_GROUP:用来保存用户组信息。

1.ID_:用户组名

2.REV_INT:版本号?

3.NAME_:用户组描述信息

4.TYPE_:用户组类型

·ACT_ID_MEMBERSHIP:用来保存用户分组信息。

1.USER_ID_:用户名

2.GROUP_ID_:用户组名

·ACT_ID_USER:用来保存用户信息。

1.ID_:用户名

2.REV_INT:版本号?

3.FIRST_:用户名称

4.LAST_:用户姓氏

5.EMAIL_:邮箱

6.PWD_:登录密码

·ACT_RU_EXECUTION:

1.ID_:

2.REV_:版本号?

3.PROC_INST_ID_:流程实例编号

4.BUSINESS_KEY_:业务编号

5.PARENT_ID_:

6.PROC_DEF_ID_:流程ID

7.SUPER_EXEC_:

8.ACT_ID_:

9.IS_ACTIVE_:

10.IS_CONCURRENT_:

11.IS_SCOPE_:

·ACT_RU_JOB:运行时定时任务数据表。

1.ID_:

2.REV_:

3.TYPE_:

4.LOCK_EXP_TIME_:

5.LOCK_OWNER_:

6.EXCLUSIVE_:

7.EXECUTION_ID_:

8.PROCESS_INSTANCE_ID_:

9.RETRIES_:

10.EXCEPTION_STACK_ID_:

11.EXCEPTION_MSG_:

12.DUEDATE_:

13.REPEAT_:

14.HANDLER_TYPE_:

15.HANDLER_CFG_:

·ACT_RU_TASK:运行时任务数据表。

1.ID_:

2.REV_:

3.EXECUTION_ID_:

4.PROC_INST_ID_:

5.PROC_DEF_ID_:

6.NAME_:

7.DESCRIPTION_:

8.TASK_DEF_KEY_:

9.ASSIGNEE_:

10.PRIORITY_:

11.CREATE_TIME_:

·ACT_RU_IDENTITYLINK:任务参与者数据表。主要存储当前节点参与者的信息。

1.ID_:

2.REV_:

3.GROUP_ID_:

4.TYPE_:

5.USER_ID_:

6.TASK_ID_:

·ACT_RU_VARIABLE:运行时流程变量数据表。

1.ID_:

2.REV_:

3.TYPE_:

4.NAME_:

5.EXECUTION_ID_:

6.PROC_INST_ID_:

7.TASK_ID_:

8.BYTEARRAY_ID_:

9.DOUBLE_:

10.LONG_:

11.TEXT_:

12.TEXT2_:

·ACT_HI_PROCINST:

·ACT_HI_ACTINST:

·ACT_HI_TASKINST:

·ACT_HI_DETAIL:

3、结论及改造建议

    • 流程文件部署主要涉及到3个表,分别是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。主要完成“部署包”-->“流程定义文件”-->“所有包内文件”的解析部署关系。从表结构中可以看出,流程定义的元素需要每次从数据库加载并解析,因为流程定义的元素没有转化成数据库表来完成,当然流程元素解析后是放在缓存中的,具体的还需要后面详细研究。
    • 流程定义中的java类文件不保存在数据库里。
    • 组织机构的管理相对较弱,如果要纳入单点登录体系内还需要改造完成,具体改造方法有待研究。
    • 运行时对象的执行与数据库记录之间的关系需要继续研究
    • 历史数据的保存及作用需要继续研究。

  • 集成到SSH中所需jar包:

mybatis最新jar包+

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
">

<!-- Activiti Configcation -->
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="databaseType" value="mysql" />
<property name="jobExecutorActivate" value="false" />
<property name="history" value="full" />

<property name="beans">
<map>
<entry key="ITResReqsProcess_CurrentDepartmentApproval" value="DevDepartment"/>
<entry key="ITResReqsProcess_ITDepartmentApprova" value="ITDepartment"/>
<entry key="ITResReqsProcess_OperationMaintenanceDepartmentApproval" value="OperationMaintenanceDepartment"/>
</map>
</property>
</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="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
<!--<bean id="userBean" class="org.activiti.spring.test.UserBean">
<property name="runtimeService" ref="runtimeService" />
</bean>
<bean id="printer" class="org.activiti.spring.test.Printer" />-->

</beans>

工作流查询代码(仅选取可关键部分的代码),如需全部源码,请发送邮件到我的邮箱索取(903960907@qq.com):

package com.workflow.service.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.jeecg.pageModel.DataGrid;
import com.jeecg.service.impl.BaseServiceImpl;
import com.workflow.pageModel.Activiti;
import com.workflow.pageModel.ActivitiInstance;
import com.workflow.service.ActivitiServiceI;

/**
* Activiti Service 工作流
* <p>
* ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
* RuntimeService runtimeService = processEngine.getRuntimeService();
* RepositoryService repositoryService = processEngine.getRepositoryService();
* TaskService taskService = processEngine.getTaskService(); ManagementService
* managementService = processEngine.getManagementService(); IdentityService
* identityService = processEngine.getIdentityService(); HistoryService
* historyService = processEngine.getHistoryService(); FormService formService =
* processEngine.getFormService();
* 这些服务的名称是相当一目了然的。更多关于服务和引擎 API
* </p>
*
* @author HurryJiang
*
*/
@Service("activitiService")
public class ActivitiServiceImpl extends BaseServiceImpl implements
ActivitiServiceI {
private static final Logger logger = Logger.getLogger(ActivitiServiceImpl.class);
private static final String SORTBY_ID = "id";
private static final String SORTBY_INSTANCEID = "processInstanceId";
private static final String SORTBY_DEPLOYEMENTID = "deploymentId";
private static final String SORTBY_NAME = "name";
private static final String SORTBY_VERSION = "version";
private static final String SORTBY_KEY = "key";
private static final String SORTBY_CATEGORY = "category";

private static final String ORDERBY_ASC = "asc";
private static final String ORDERBY_DESC = "desc";

private ProcessEngineFactoryBean processEngine;
private RepositoryService repositoryService;
private RuntimeService runtimeService;
private FormService formService;
private IdentityService identityService;
private TaskService taskService;
private WorkflowTraceService traceService;
private HistoryService historyService;
private ManagementService managementService;

public ActivitiServiceImpl(){

}
/**
* Get ActivitiEngine
*
* @return
*/
public ProcessEngineFactoryBean getProcessEngine() {
return processEngine;
}

@Autowired
public void setProcessEngine(ProcessEngineFactoryBean processEngine) {
this.processEngine = processEngine;
}

public RuntimeService getRuntimeService() {
return runtimeService;
}

@Autowired
public void setRuntimeService(RuntimeService runtimeService) {
this.runtimeService = runtimeService;
}

public FormService getFormService() {
return formService;
}

@Autowired
public void setFormService(FormService formService) {
this.formService = formService;
}

public IdentityService getIdentityService() {
return identityService;
}

@Autowired
public void setIdentityService(IdentityService identityService) {
this.identityService = identityService;
}

public TaskService getTaskService() {
return taskService;
}

@Autowired
public void setTaskService(TaskService taskService) {
this.taskService = taskService;
}

public HistoryService getHistoryService() {
return historyService;
}

@Autowired
public void setHistoryService(HistoryService historyService) {
this.historyService = historyService;
}

public ManagementService getManagementService() {
return managementService;
}

@Autowired
public void setManagementService(ManagementService managementService) {
this.managementService = managementService;
}

public RepositoryService getRepositoryService() {
return repositoryService;
}
@Autowired
public void setRepositoryService(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}

@Transactional(propagation = Propagation.SUPPORTS)
public DataGrid datagrid(Activiti entity) {
DataGrid j = new DataGrid();
/*
* 查询两个对象,一个是ProcessDefinition(流程定义),一个是Deployment(流程部署)
*/
ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
//查询总数
long total = query.count();
//查询分页记录(根据条件)
if(entity.getSort()!=null){
if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_ID)){
query = query.orderByProcessDefinitionId();
}else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_NAME)){
query = query.orderByProcessDefinitionName();
}else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_CATEGORY)){
query = query.orderByProcessDefinitionCategory();
}else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_KEY)){
query = query.orderByProcessDefinitionKey();
}else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_VERSION)){
query = query.orderByProcessDefinitionVersion();
}else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_DEPLOYEMENTID)){
query = query.orderByDeploymentId();
}
}
if(entity.getOrder()!=null){
if( entity.equals(ActivitiServiceImpl.ORDERBY_DESC)){
query = query.desc();
}else{
query = query.asc();
}
}
if(entity.getRows()>0 && entity.getPage()>=0){//分页查询
query.listPage((entity.getPage() - 1) * entity.getRows(), entity.getRows() );//listPage(int firstResult, int maxResults);
}
List<ProcessDefinition> processDefinitionList = query.list();

j.setRows(getActivitisFromProcessDefinitions(processDefinitionList));
j.setTotal(total);
return j;
}

private List<Activiti> getActivitisFromProcessDefinitions(List<ProcessDefinition> defs) {
List<Activiti> acts = new ArrayList<Activiti>();
if (defs != null && defs.size() > 0) {
for (ProcessDefinition tb : defs) {
Activiti b = new Activiti();
BeanUtils.copyProperties(tb, b);
String deploymentId = tb.getDeploymentId();
Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
if(deployment!=null){
b.setDeploymentTime(deployment.getDeploymentTime());
b.setCategory(deployment.getCategory());
}
acts.add(b);
}
}
return acts;
}

private String addWhere(Activiti entity, String hql, List<Object> values) {
return hql;
}

public void add(Activiti entity) {
logger.debug("add...");
}

public void update(Activiti entity) {
logger.debug("update...");
}

/**
* 可选择级联删除
* @param ids
*/
public void deleteByCascade(String ids,boolean cascade) {
if (ids != null) {
for (String id : ids.split(",")) {
ProcessDefinition def = repositoryService.getProcessDefinition(id);
if (def != null) {
repositoryService.deleteDeployment(id,cascade);
logger.debug("delete..."+id);
}
}
}
}
/**
* 强制级联删除已部署的流程(非流程定义)
* @param ids
*/
public void deleteDeployment(String ids) {
if (ids != null) {
for (String id : ids.split(",")) {
DeploymentQuery depQuery = repositoryService.createDeploymentQuery().deploymentId(id);
if (depQuery != null && depQuery.list()!=null) {
repositoryService.deleteDeployment(id,true);
logger.debug("delete..."+id);
}
}
}
}
/**
* 强制级联删除已上传的流程定义(ProcessDefinition)
* @param ids
*/
public void deleteProcdef(String ids) {
if (ids != null) {
for (String id : ids.split(",")) {
ProcessDefinition def = repositoryService.getProcessDefinition(id);
if (def != null) {
repositoryService.deleteDeployment(id,true);
logger.debug("delete..."+id);
}
}
}
}

@Override
public ProcessDefinition get(Activiti entity) {
if(entity!=null){
ProcessDefinition def = repositoryService.getProcessDefinition(entity.getId());
return def;
}
return null;
}
@Override
public void deploy(InputStream fileInputStream,String fileName) {
try {
String extension = FilenameUtils.getExtension(fileName);
logger.info("File extension:"+extension);
if (extension.equals("zip") || extension.equals("bar")) {
ZipInputStream zip = new ZipInputStream(fileInputStream);
repositoryService.createDeployment().addZipInputStream(zip).deploy();
} else if (extension.equals("png")) {
repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy();
} else if (fileName.indexOf("bpmn20.xml") != -1) {
repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy();
} else if (extension.equals("bpmn")) {
/*
* bpmn扩展名特殊处理,转换为bpmn20.xml
*/
String baseName = FilenameUtils.getBaseName(fileName);
repositoryService.createDeployment().addInputStream(baseName + ".bpmn20.xml", fileInputStream).deploy();
} else if (extension.equals("tmp")) {
ZipInputStream zip = new ZipInputStream(fileInputStream);
repositoryService.createDeployment().addZipInputStream(zip).deploy();
}else {
throw new ActivitiException("no support file type of " + extension);
}
} catch (Exception e) {
logger.error("error on deploy process, because of file input stream", e);
}
}

@Override
public InputStream getResourceAsStreamByDeployment(String deploymentId,
String resourceName) {
return repositoryService.getResourceAsStream(deploymentId, resourceName);
}

@Override
public InputStream getResourceAsStreamByProcessInstance(
String processInstanceId, String resourceType) {
InputStream resourceAsStream = null;
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId())
.singleResult();

String resourceName = "";
if (resourceType.equals("image")) {
resourceName = processDefinition.getDiagramResourceName();
} else if (resourceType.equals("xml")) {
resourceName = processDefinition.getResourceName();
}
resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
return resourceAsStream;
}

@Override
public List<Map<String, Object>> traceProcess(String processInstanceId) throws Exception {
return traceService.traceProcess(processInstanceId);
}
public WorkflowTraceService getTraceService() {
return traceService;
}
public void setTraceService(WorkflowTraceService traceService) {
this.traceService = traceService;
}
@Override
public DataGrid datagridForInstance(ActivitiInstance entity) {
DataGrid j = new DataGrid();
ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery();
//查询总数
long total = query.count();
//查询分页记录(根据条件)
if(entity.getSort()!=null){
if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_ID)){
query = query.orderByProcessDefinitionId();
}else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_INSTANCEID)){
query = query.orderByProcessInstanceId();
}else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_KEY)){
query = query.orderByProcessDefinitionKey();
}
}
if(entity.getOrder()!=null){
if( entity.equals(ActivitiServiceImpl.ORDERBY_DESC)){
query = query.desc();
}else{
query = query.asc();
}
}
if(entity.getRows()>0 && entity.getPage()>=0){//分页查询
query.listPage((entity.getPage() - 1) * entity.getRows(), entity.getRows() );//listPage(int firstResult, int maxResults);
}
List<ProcessInstance> processInstanceList = query.list();

j.setRows(getActivitisFromProcessInstances(processInstanceList));
j.setTotal(total);
return j;
}
private List<ActivitiInstance> getActivitisFromProcessInstances(List<ProcessInstance> ins) {
List<ActivitiInstance> acts = new ArrayList<ActivitiInstance>();
if (ins != null && ins.size() > 0) {
for (ProcessInstance tb : ins) {
ActivitiInstance b = new ActivitiInstance();
BeanUtils.copyProperties(tb, b);
String deploymentId = tb.getProcessDefinitionId();
Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
if(deployment!=null){
b.setName(deployment.getName());
b.setDeploymentTime(deployment.getDeploymentTime());
b.setCategory(deployment.getCategory());
}
acts.add(b);
}
}
return acts;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值