流程开发Activiti 与SpringMVC整合实例

流程(Activiti)

 

流程是完成一系列有序动作的概述。每一个节点动作的结果将对后面的具体操作步骤产生影响。信息化系统中流程的功能完全等同于纸上办公的层级审批,尤其在oa系统中各类电子流提现较为明显。一般的步骤为:

 

①   申请者发起申请。

②   各级领导审批。一般由低级别往高级别审批。

③   每一级别审批结果将影响或者决定申请结果。若下一节点非结束节点,此节点若审批通过将转给下一节点审批;若此节点审批不通过此次审批将被驳回修改申请或者直接结束。

                                                    图1  流程图实例

 

④   当流程审批结束或者中途某节点审批不通过,在达到结束节点时,可以根据具体审批结果进行相关的业务操作。 如通过审批进行虚拟机资源分配;没通过审批则不予以分配。

 

业务场景:

完成某业务需经过多个步骤处理每个步骤处理人或处理人角色不同。

 

流程优势:

①   业务逻辑容易理解。

流程的执行逻辑和纸上办公层级审批一致,可以轻松设计出适合各业务的流程实例。

②   使用灵活。

流程在配置时,可以在执行过程中动态的将某个节点指定给具体人或者具有某种角色的人(某部门人员)。若指定的是具体的某人,则该人员登陆后即可查看到自己相关的任务进行直接办理;若指定的含有某角色的人,则含有该角色的人登陆后都能查看到该任务,可以根据个人情况,选择性的对某条审批进行签收后进行审批。

③   与代码低耦合

在不是用流程而采用传统if else判断也可实现流程功能,但相对而言操作较为复杂,代码量较多,尤其是在后期逻辑较复杂情况下,需要增加审批节点或者修改现有逻辑,将会造成大量的改动,且不易于测试,容易产生未知bug。

流程的引入将有效规避上述问题。流程本身提供了众多接口以便用户使用,同时可以根据具体业务需要进行有效扩展。可以在较少代码量基础上实现相同的业务功能。设计流程时也相对简单,通过拖拽配置即可完成。所有流程方法都可共用,不同流程根据流程名字进行区分,仅在流程启动时用于判断,待启动后所有流程操作都一样。在对现有流程增加或者删除审批节点时无需修改任何java代码,简单修改流程xml即可,即便是对复杂节点的增加或者修改,也仅需要修改简单代码即可。

④   直观展示。

流程可以根据流程图直观展示流程某时刻具体处于哪一个审批节点,以及具体的审批路径,每个节点的审批信息,历史信息等。

 

activiti中最重要的就是org.activiti.spring.ProcessEngineFactoryBean,好比汽车的发动车,没有它什么也干不了

开发步骤:

① 引入相关包,增加配置文件 applicationContext-activiti.xml,配置文件中jpa相关我都注释了,采用的mybatis,使用jpa的朋友直接放开就好了

<?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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">


    <!-- Jpa Entity Manager 配置 -->
<!--     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> -->
<!--         <property name="dataSource" ref="masterDataSource"/> -->
<!--         <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/> -->
<!--         <property name="packagesToScan" value="com.wish.wishstack.web.activiti"/> -->
<!--         <property name="jpaProperties"> -->
<!--             <props> -->
<!--                 <prop key="hibernate.dialect">${hibernate.dialect}</prop> -->
<!--                 <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> -->
<!--                 <prop key="hibernate.hbm2ddl.auto">update</prop> -->
<!--             </props> -->
<!--         </property> -->
<!--     </bean> -->

<!--     <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> -->

    <!-- Spring Data Jpa配置 -->
<!--     <jpa:repositories base-package="com.wish.wishstack.web.activiti" transaction-manager-ref="transactionManager" -->
<!--                       entity-manager-factory-ref="entityManagerFactory"/> -->

    <!-- Jpa 事务配置 -->
<!--     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> -->
<!--         <property name="entityManagerFactory" ref="entityManagerFactory"/> -->
<!--     </bean> -->

    <!-- 使用annotation定义事务 -->
<!--     <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> -->

    <!-- Activiti begin -->
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
        
        <property name="dataSource" ref="masterDataSource" />  
        <property name="transactionManager" ref="transactionManager" />  
        <property name="databaseSchemaUpdate" value="true" />  
        <property name="jobExecutorActivate" value="false" />  
        <property name="activityFontName" value="宋体"/>  
        <property name="labelFontName" value="宋体"/>  

        <!-- mail -->
        <property name="mailServerHost" value="localhost"/>
        <property name="mailServerUsername" value="kafeitu"/>
        <property name="mailServerPassword" value="000000"/>
        <property name="mailServerPort" value="2025"/>

        <!-- UUID作为主键生成策略
        <property name="idGenerator" ref="uuidGenerator" />
        -->

        <!-- 生成流程图的字体 -->
<!--         <property name="activityFontName" value="${diagram.activityFontName}"/> -->
<!--         <property name="labelFontName" value="${diagram.labelFontName}"/> -->

        <!-- 缓存支持
        <property name="processDefinitionCache">
            <bean class="me.kafeitu.demo.activiti.util.cache.DistributedCache" />
        </property>-->

        <!-- 自动部署 -->
        <property name="deploymentResources">
            <list>
                <value>classpath*:/deployments/*.bpmn20.xml</value>
            </list>
        </property>

        <!-- 自定义表单字段类型 -->
        <property name="customFormTypes">
            <list>
<!--                 <bean class="me.kafeitu.demo.activiti.activiti.form.UsersFormType"/> -->
            </list>
        </property>

        <!-- JPA -->
<!--         <property name="jpaEntityManagerFactory" ref="entityManagerFactory" /> -->
<!--         <property name="jpaHandleTransaction" value="false" /> -->
<!--         <property name="jpaCloseEntityManager" value="false" /> -->

        <!-- 全局事件 -->
        <property name="typedEventListeners">
            <map>
                <entry key="VARIABLE_CREATED" >
                    <list>
<!--                         <ref bean="variableCreateListener"/> -->
                    </list>
                </entry>
            </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"/>
    <!-- Activiti end -->

<!--     <jaxws:endpoint id="leaveWebService" implementor="me.kafeitu.demo.activiti.webservice.LeaveWebServiceImpl" address="/leave"/> -->
</beans>

 

②开发页面, 所有的业务逻辑和标准springMVC一致,只是后台在处理的时候调用了activiti相关接口进行处理, activiti自带了15+—张表

核心service类如下,为了通用性,需要根据情况再次封装

package xiaochangwei.zicp.net.service.activity.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.activiti.bpmn.constants.BpmnXMLConstants;


@Service("leaveWorkFlowService")
public class LeaveWorkflowServiceImpl implements LeaveWorkflowService {

    private static Logger logger = LoggerFactory.getLogger(LeaveWorkflowServiceImpl.class);

    @Resource
    private LeaveDao leaveDao;

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private IdentityService identityService;

    /**
     * 启动流程
     *
     * @param entity
     */
    public ProcessInstance startWorkflow(Leave entity, Map<String, Object> variables) {
        leaveDao.saveLeave(entity);
        logger.debug("save entity: {}", entity);
        String businessKey = entity.getId().toString();

        ProcessInstance processInstance = null;
        try {
            // 用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
            identityService.setAuthenticatedUserId(entity.getUserId());

            processInstance = runtimeService.startProcessInstanceByKey("leave", businessKey, variables);
            String processInstanceId = processInstance.getId();
            entity.setProcessInstanceId(processInstanceId);
            leaveDao.update(entity);
            logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}",
                    new Object[] { "leave", businessKey, processInstanceId, variables });
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
        return processInstance;
    }

    /**
     * 查询待办任务
     *
     * @param userId
     *            用户ID
     * @return
     */
    @Transactional(readOnly = true)
    public List<Leave> findTodoTasks(String userId, Page<Leave> page) {
        List<Leave> results = new ArrayList<Leave>();

        // 根据当前人的ID查询
        TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
        List<Task> tasks = taskQuery.list();

        // 根据流程的业务ID查询实体并关联
        for (Task task : tasks) {
            String processInstanceId = task.getProcessInstanceId();
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(processInstanceId).active().singleResult();
            String businessKey = processInstance.getBusinessKey();
            if (businessKey == null) {
                continue;
            }
            Leave leave = leaveDao.getLeave(new Long(businessKey));
            leave.setTask(task);
            leave.setProcessInstance(processInstance);
            leave.setProcessDefinition(getProcessDefinition(processInstance.getProcessDefinitionId()));
            results.add(leave);
        }

        page.setTotalCount((int) taskQuery.count());
        page.setResult(results);
        return results;
    }

    /**
     * 读取运行中的流程
     *
     * @return
     */
    @Transactional(readOnly = true)
    public List<Leave> findRunningProcessInstaces(Page<Leave> page) {
        List<Leave> results = new ArrayList<Leave>();
        
        ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery().processDefinitionKey("leave").active()
                .orderByProcessInstanceId().desc();
        List<ProcessInstance> list = query.listPage(page.getStartIndex(), page.getEndIndex());

        // 关联业务实体
        for (ProcessInstance processInstance : list) {
            String businessKey = processInstance.getBusinessKey();
            if (businessKey == null) {
                continue;
            }
            Leave leave = leaveDao.getLeave(new Long(businessKey));
            if (leave != null) {
                leave.setProcessInstance(processInstance);
                leave.setProcessDefinition(getProcessDefinition(processInstance.getProcessDefinitionId()));
                
                // 设置当前任务信息
                List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).active()
                        .orderByTaskCreateTime().desc().listPage(0, 1);
                leave.setTask(tasks.get(0));
                
                results.add(leave);
            }

        }

        page.setTotalCount((int) query.count());
        page.setResult(results);
        return results;
    }

    /**
     * 读取已结束中的流程
     *
     * @return
     */
    @Transactional(readOnly = true)
    public List<Leave> findFinishedProcessInstaces(Page<Leave> page) {
        List<Leave> results = new ArrayList<Leave>();
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey("leave").finished().orderByProcessInstanceEndTime().desc();
        List<HistoricProcessInstance> list = query.listPage(page.getStartIndex(), page.getEndIndex());

        // 关联业务实体
        for (HistoricProcessInstance historicProcessInstance : list) {
            String businessKey = historicProcessInstance.getBusinessKey();
            Leave leave = leaveDao.getLeave(new Long(businessKey));
            leave.setProcessDefinition(getProcessDefinition(historicProcessInstance.getProcessDefinitionId()));
            leave.setHistoricProcessInstance(historicProcessInstance);
            results.add(leave);
        }
        page.setTotalCount((int) query.count());
        page.setResult(results);
        return results;
    }

    /**
     * 查询流程定义对象
     *
     * @param processDefinitionId
     *            流程定义ID
     * @return
     */
    public ProcessDefinition getProcessDefinition(String processDefinitionId) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId).singleResult();
        return processDefinition;
    }

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

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

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

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

}

 

同时还有很多接口用于如流程图。xml展示,或者流程轨迹展示等

package com.wish.wishstack.web.activiti;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

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.ManagementService;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.apache.commons.io.FilenameUtils;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

/**
 * 流程管理控制器
 *
 */
@Controller
@RequestMapping(value = "/workflow")
public class ActivitiController {

    protected Logger logger = LoggerFactory.getLogger(getClass());

//    protected WorkflowProcessDefinitionService workflowProcessDefinitionService;

    protected RepositoryService repositoryService;

    protected RuntimeService runtimeService;

    protected TaskService taskService;

//    protected WorkflowTraceService traceService;

    @Autowired
    ManagementService managementService;

    protected static Map<String, ProcessDefinition> PROCESS_DEFINITION_CACHE = new HashMap<String, ProcessDefinition>();

    @Autowired
    ProcessEngineFactoryBean processEngine;

    @Autowired
    ProcessEngineConfiguration processEngineConfiguration;

    /**
     * 流程定义列表
     *
     * @return
     */
//    @RequestMapping(value = "/process-list")
//    public ModelAndView processList(HttpServletRequest request) {
//        ModelAndView mav = new ModelAndView("workflow/process-list");
//
//    /*
//     * 保存两个对象,一个是ProcessDefinition(流程定义),一个是Deployment(流程部署)
//     */
//        List<Object[]> objects = new ArrayList<Object[]>();
//
//        Page<Object[]> page = new Page<Object[]>(PageUtil.PAGE_SIZE);
//        int[] pageParams = PageUtil.init(page, request);
//
//        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery().orderByDeploymentId().desc();
//        List<ProcessDefinition> processDefinitionList = processDefinitionQuery.listPage(pageParams[0], pageParams[1]);
//        for (ProcessDefinition processDefinition : processDefinitionList) {
//            String deploymentId = processDefinition.getDeploymentId();
//            Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
//            objects.add(new Object[]{processDefinition, deployment});
//        }
//
//        page.setTotalCount(processDefinitionQuery.count());
//        page.setResult(objects);
//        mav.addObject("page", page);
//
//        return mav;
//    }

    /**
     * 部署全部流程
     *
     * @return
     * @throws Exception
     */
//    @RequestMapping(value = "/redeploy/all")
//    public String redeployAll(@Value("#{APP_PROPERTIES['export.diagram.path']}") String exportDir) throws Exception {
//        workflowProcessDefinitionService.deployAllFromClasspath(exportDir);
//        return "redirect:/workflow/process-list";
//    }

    /**
     * 读取资源,通过部署ID
     *
     * @param processDefinitionId 流程定义
     * @param resourceType        资源类型(xml|image)
     * @throws Exception
     */
//    @RequestMapping(value = "/resource/read")
//    public void loadByDeployment(@RequestParam("processDefinitionId") String processDefinitionId, @RequestParam("resourceType") String resourceType,
//                                 HttpServletResponse response) throws Exception {
//        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
//        String resourceName = "";
//        if (resourceType.equals("image")) {
//            resourceName = processDefinition.getDiagramResourceName();
//        } else if (resourceType.equals("xml")) {
//            resourceName = processDefinition.getResourceName();
//        }
//        InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
//        byte[] b = new byte[1024];
//        int len = -1;
//        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
//            response.getOutputStream().write(b, 0, len);
//        }
//    }

    /**
     * 读取资源,通过流程ID
     *
     * @param resourceType      资源类型(xml|image)
     * @param processInstanceId 流程实例ID
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/resource/process-instance")
    public void loadByProcessInstance(@RequestParam("type") String resourceType, @RequestParam("pid") String processInstanceId, HttpServletResponse response)
            throws Exception {
        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);
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

//    /**
//     * 删除部署的流程,级联删除流程实例
//     *
//     * @param deploymentId 流程部署ID
//     */
//    @RequestMapping(value = "/process/delete")
//    public String delete(@RequestParam("deploymentId") String deploymentId) {
//        repositoryService.deleteDeployment(deploymentId, true);
//        return "redirect:/workflow/process-list";
//    }
//
//    /**
//     * 输出跟踪流程信息
//     *
//     * @param processInstanceId
//     * @return
//     * @throws Exception
//     */
//    @RequestMapping(value = "/process/trace")
//    @ResponseBody
//    public List<Map<String, Object>> traceProcess(@RequestParam("pid") String processInstanceId) throws Exception {
//        List<Map<String, Object>> activityInfos = traceService.traceProcess(processInstanceId);
//        return activityInfos;
//    }
//
    /**
     * 读取带跟踪的图片
     */
    @RequestMapping(value = "/process/trace/auto/{executionId}")
    public void readResource(@PathVariable("executionId") String executionId, HttpServletResponse response)
            throws Exception {
        response.setHeader("Cache-Control", "no-store");    //禁止浏览器缓存 
        response.setHeader("Pragrma", "no-cache");    //禁止浏览器缓存 
        response.setDateHeader("Expires", 0);    //禁止浏览器缓存 
        response.setCharacterEncoding("UTF-8"); 
        
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(executionId).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        List<String> activeActivityIds = runtimeService.getActiveActivityIds(executionId);
        // 不使用spring请使用下面的两行代码
//    ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl) ProcessEngines.getDefaultProcessEngine();
//    Context.setProcessEngineConfiguration(defaultProcessEngine.getProcessEngineConfiguration());

        // 使用spring注入引擎请使用下面的这行代码
        processEngineConfiguration = processEngine.getProcessEngineConfiguration();
        Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);

        ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
//        InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds);
        InputStream imageStream = new DefaultProcessDiagramGenerator().generateDiagram(
                bpmnModel, "png",
                activeActivityIds, Collections.<String>emptyList(), 
                processEngine.getProcessEngineConfiguration().getActivityFontName(), 
                processEngine.getProcessEngineConfiguration().getLabelFontName(), 
                null, 1.0);
        // 输出资源内容到相应对象
        byte[] b = new byte[1024];
        int len;
        while ((len = imageStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

//    @RequestMapping(value = "/deploy")
//    public String deploy(@Value("#{APP_PROPERTIES['export.diagram.path']}") String exportDir, @RequestParam(value = "file", required = false) MultipartFile file) {
//
//        String fileName = file.getOriginalFilename();
//
//        try {
//            InputStream fileInputStream = file.getInputStream();
//            Deployment deployment = null;
//
//            String extension = FilenameUtils.getExtension(fileName);
//            if (extension.equals("zip") || extension.equals("bar")) {
//                ZipInputStream zip = new ZipInputStream(fileInputStream);
//                deployment = repositoryService.createDeployment().addZipInputStream(zip).deploy();
//            } else {
//                deployment = repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy();
//            }
//
//            List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
//
//            for (ProcessDefinition processDefinition : list) {
//                WorkflowUtils.exportDiagramToFile(repositoryService, processDefinition, exportDir);
//            }
//
//        } catch (Exception e) {
//            logger.error("error on deploy process, because of file input stream", e);
//        }
//
//        return "redirect:/workflow/process-list";
//    }
//
//    @RequestMapping(value = "/process/convert-to-model/{processDefinitionId}")
//    public String convertToModel(@PathVariable("processDefinitionId") String processDefinitionId)
//            throws UnsupportedEncodingException, XMLStreamException {
//        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
//                .processDefinitionId(processDefinitionId).singleResult();
//        InputStream bpmnStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),
//                processDefinition.getResourceName());
//        XMLInputFactory xif = XMLInputFactory.newInstance();
//        InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
//        XMLStreamReader xtr = xif.createXMLStreamReader(in);
//        BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
//
//        BpmnJsonConverter converter = new BpmnJsonConverter();
//        com.fasterxml.jackson.databind.node.ObjectNode modelNode = converter.convertToJson(bpmnModel);
//        Model modelData = repositoryService.newModel();
//        modelData.setKey(processDefinition.getKey());
//        modelData.setName(processDefinition.getResourceName());
//        modelData.setCategory(processDefinition.getDeploymentId());
//
//        ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
//        modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName());
//        modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
//        modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription());
//        modelData.setMetaInfo(modelObjectNode.toString());
//
//        repositoryService.saveModel(modelData);
//
//        repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));
//
//        return "redirect:/workflow/model/list";
//    }
//
//    /**
//     * 待办任务--Portlet
//     */
//    @RequestMapping(value = "/task/todo/list")
//    @ResponseBody
//    public List<Map<String, Object>> todoList(HttpSession session) throws Exception {
//        User user = UserUtil.getUserFromSession(session);
//        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");
//
//        // 已经签收的任务
//        List<Task> todoList = taskService.createTaskQuery().taskAssignee(user.getId()).active().list();
//        for (Task task : todoList) {
//            String processDefinitionId = task.getProcessDefinitionId();
//            ProcessDefinition processDefinition = getProcessDefinition(processDefinitionId);
//
//            Map<String, Object> singleTask = packageTaskInfo(sdf, task, processDefinition);
//            singleTask.put("status", "todo");
//            result.add(singleTask);
//        }
//
//        // 等待签收的任务
//        List<Task> toClaimList = taskService.createTaskQuery().taskCandidateUser(user.getId()).active().list();
//        for (Task task : toClaimList) {
//            String processDefinitionId = task.getProcessDefinitionId();
//            ProcessDefinition processDefinition = getProcessDefinition(processDefinitionId);
//
//            Map<String, Object> singleTask = packageTaskInfo(sdf, task, processDefinition);
//            singleTask.put("status", "claim");
//            result.add(singleTask);
//        }
//
//        return result;
//    }

//    private Map<String, Object> packageTaskInfo(SimpleDateFormat sdf, Task task, ProcessDefinition processDefinition) {
//        Map<String, Object> singleTask = new HashMap<String, Object>();
//        singleTask.put("id", task.getId());
//        singleTask.put("name", task.getName());
//        singleTask.put("createTime", sdf.format(task.getCreateTime()));
//        singleTask.put("pdname", processDefinition.getName());
//        singleTask.put("pdversion", processDefinition.getVersion());
//        singleTask.put("pid", task.getProcessInstanceId());
//        return singleTask;
//    }
//
//    private ProcessDefinition getProcessDefinition(String processDefinitionId) {
//        ProcessDefinition processDefinition = PROCESS_DEFINITION_CACHE.get(processDefinitionId);
//        if (processDefinition == null) {
//            processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
//            PROCESS_DEFINITION_CACHE.put(processDefinitionId, processDefinition);
//        }
//        return processDefinition;
//    }
//
//    /**
//     * 挂起、激活流程实例
//     */
//    @RequestMapping(value = "processdefinition/update/{state}/{processDefinitionId}")
//    public String updateState(@PathVariable("state") String state, @PathVariable("processDefinitionId") String processDefinitionId,
//                              RedirectAttributes redirectAttributes) {
//        if (state.equals("active")) {
//            redirectAttributes.addFlashAttribute("message", "已激活ID为[" + processDefinitionId + "]的流程定义。");
//            repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
//        } else if (state.equals("suspend")) {
//            repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
//            redirectAttributes.addFlashAttribute("message", "已挂起ID为[" + processDefinitionId + "]的流程定义。");
//        }
//        return "redirect:/workflow/process-list";
//    }
//
//    /**
//     * 导出图片文件到硬盘
//     *
//     * @return
//     */
//    @RequestMapping(value = "export/diagrams")
//    @ResponseBody
//    public List<String> exportDiagrams(@Value("#{APP_PROPERTIES['export.diagram.path']}") String exportDir) throws IOException {
//        List<String> files = new ArrayList<String>();
//        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
//
//        for (ProcessDefinition processDefinition : list) {
//            files.add(WorkflowUtils.exportDiagramToFile(repositoryService, processDefinition, exportDir));
//        }
//
//        return files;
//    }
//
//    @RequestMapping(value = "activity/jump")
//    @ResponseBody
//    public boolean jump(@RequestParam("executionId") String executionId,
//                        @RequestParam("activityId") String activityId) {
//        Command<Object> cmd = new JumpActivityCmd(executionId, activityId);
//        managementService.executeCommand(cmd);
//        return true;
//    }
//
//    @RequestMapping(value = "bpmn/model/{processDefinitionId}")
//    @ResponseBody
//    public BpmnModel queryBpmnModel(@PathVariable("processDefinitionId") String processDefinitionId) {
//        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//        return bpmnModel;
//    }

//    @Autowired
//    public void setWorkflowProcessDefinitionService(WorkflowProcessDefinitionService workflowProcessDefinitionService) {
//        this.workflowProcessDefinitionService = workflowProcessDefinitionService;
//    }

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

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

//    @Autowired
//    public void setTraceService(WorkflowTraceService traceService) {
//        this.traceService = traceService;
//    }

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

}

 

 

根据需要自己整理吧,因代码涉及到公司机密,就不展示了

 

posted @ 2016-04-28 16:32  肖哥哥  阅读(39705)  评论(2编辑  收藏  举报
生命不息  奋斗不止  每天进步一点点