• Activity工作流详解和封装(流程定义部署之ZIP方式)


    首先两张图说明Activity的23张表的含义,可去官网获取:(以下代码一些返回格式和数据库查询就不具体说明了

    流程定义部署之ZIP方式可以百度下

    pom.xml

    <!-- activiti -->
    <dependency>
          <groupId>org.activiti</groupId>
          <artifactId>activiti-engine</artifactId>
          <version>5.14</version>
    </dependency>
    
    <dependency>
          <groupId>org.activiti</groupId>
          <artifactId>activiti-json-converter</artifactId>
          <version>5.14</version>
    </dependency>
    
    <dependency>
          <groupId>org.activiti</groupId>
          <artifactId>activiti-spring</artifactId>
          <version>5.14</version>
    </dependency>

    activtiy.xml

    <?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:p="http://www.springframework.org/schema/p"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
        <!-- Activiti配置 -->
        <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
            <property name="dataSource" ref="localDataSource"/>
            <property name="transactionManager" ref="localTransactionManager"/>
            <property name="databaseSchemaUpdate" value="true"/>
            <property name="jobExecutorActivate" value="false"/>
            <property name="activityFontName" value="微软雅黑"/>
            <property name="labelFontName" value="微软雅黑"/>
        </bean>
    
        <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean" destroy-method="destroy">
            <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="historyService" factory-bean="processEngine" factory-method="getHistoryService"/>
        <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService"/>
        <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService"/>
    </beans>

    注意:要在Srping管理文件application.xml用以下方式引入:

    <!-- activiti配置引入 -->
    <import resource="activiti.xml"></import>

    IActivitiService.java

    /**
     * Author:47Gamer
     */import java.io.File;
    import java.io.InputStream;
    import java.util.List;
    import java.util.Map;
    
    import org.activiti.engine.history.HistoricProcessInstance;
    import org.activiti.engine.runtime.ProcessInstance;
    import org.activiti.engine.task.IdentityLink;
    import org.activiti.engine.task.Task;
    
    import com.sckj.base.entity.admin.Person;
    import com.sckj.base.service.IBaseService;
    import com.sckj.base.vo.ComboVo;
    import com.sckj.macb.query.ListVo;
    
    import net.sf.json.JSONObject;
    
    /**
     * Activity相关服务接口
     * @author 47Gamer
     */
    public interface IActivitiService extends IBaseService {
    
        /** 自定义模块的business Key **/
        public static final String DEFINITION_KEY = "definitionKey";
    
    
        /**
         * 部署一个流程定义,传入该流程定义的名称,名称必须唯一
         * 只有被部署过的流程定义才能通过其启动新的流程实例
         *@author 47Gamer
         *@date 2019-3-6
         *@param definitionName
         *@return void
         */
        public void deployProcessDefinition(String definitionName);
    
        /**
         * 获取待部署的流程定义
         *@author 47Gamer
         *@date 2019-3-10
         *@return
         *@return List<ComboVo>
         */
        public List<ComboVo> getWaitDefinition();
    
        /**
         * 获取已发布的流程定义
         *@author 47Gamer
         *@date 2019-3-10
         *@return
         *@return List<Object>
         */
        public List<Object> getProcessDefinitionList();
    
    
        /**
         * 通过自定义流程表id获取对应的流程的流程定义的部署id
         *@author 47Gamer
         *@date 2019-3-14
         *@param processInfoId
         *@return
         *@return String
         */
        public String getDeployIdByProcessInfoId(String processInfoId);
    
        /**
         * 通过一个已发布的部署id来删除流程定义
         * 如果当前存在相关联的并且未结束的流程实例,则该方法不起作用
         *@author 47Gamer
         *@date 2019-3-6
         *@param id
         *@return void
         */
        public void deleteDeployment(String deploymentIds);
    
        /**
         * 通过一个已发布的部署id来级联删除流程定义
         * 级联删除:如果存在与id指向的流程定义的流程实例(包括历史流程与未结束的流程以及相关的job),则一并删除
         * 如果不存在则相当于deleteDeployment()这个方法
         * 该方法请慎用
         *@author 47Gamer
         *@date 2019-3-6
         *@param id
         *@return void
         */
        public void deleteDeploymentCascade(String deploymentIds);
    
        /**
         * 通过一个已发布的流程定义key来启动一个流程,输入业务键
         * params 为启动参数,可以为空
         *@author 47Gamer
         *@date 2019-3-6
         *@param key
         *@return void
         */
        public Integer startProcessInstanceByKey(String key, String businessKey, Map<String, Object> params, Person person);
    
        /**
         * 通过一个已发布的流程定义id来启动一个流程
         * params 为启动参数,可以为空
         *@author 47Gamer
         *@date 2019-3-6
         *@param id
         *@return void
         */
        public Integer startProcessInstanceById(String id, Map<String, Object> params, Person person);
    
        /**
         * 通过流程实例id返回一个历史流程实例,如果不存在则返回null
         *@author 47Gamer
         *@date 2019-3-6
         *@param id
         *@return ProcessInstance
         */
        public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId);
    
        /**
         * 通过流程实例id返回一个正在进行的流程实例,如果流程不存在或者指定的流程已线结束则返回null
         *@author 47Gamer
         *@date 2019-3-6
         *@param id
         *@return ProcessInstance
         */
        public ProcessInstance getProcessInstanceById(String processInstanceId);
    
        /**
         * 通过流程实例id来删除一个正在运流中的流程实例,同时删除T_PROCESSINFO表的数据
         *@author 47Gamer
         *@date 2019-3-6
         *@param processInstanceId
         *@return void
         */
        public void deleteProcessInstance(String processInstanceId, String processInstanceInfoId, String deleteReason);
    
        /**
         * 通过参数分页查询流程实例,包括历史流程
         *@author 47Gamer
         *@date 2019-3-6
         *@param params
         *@return ListVo<Object>
         */
        public ListVo<Object> getProcessInstanceList(Map<String, Object> params);
    
        /**
         * 向执中中发送一个触发器信号,使流程继续向下走
         * 使用该方法的前提是,流程图中有至少有一个state活动节点,当流程流向该节点时会使流程陷入等待
         * 通过调用该方法使流程得以继续
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@return void
         */
        public void signal(String executionId, @SuppressWarnings("unchecked") Map<String, Object>... pamras);
    
        /**
         * 通过变量名获取一个执行上下文中的变量值
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@param variableName
         *@return Object
         */
        public Object getExecutionVariable(String executionId, String variableName);
    
        /**
         * 获取执行上下文的所有变量
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@return Map<String, Object>
         */
        public Map<String, Object> getExecutionVariables(String executionId);
    
        /**
         * 向一个执行上下文中存入一个变量值
         * 如果对应的variableName已存在于执行上下文中,则新赋予的值会覆盖以前的值
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@param variableName
         *@param value
         *@return void
         */
        public void setExecutionVariable(String executionId, String variableName, String value);
    
        /**
         * 向一个执行上下文中批量存入变量值
         * 如果对应的variableName已存在于执行上下文中,则新赋予的值会覆盖以前的值
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@param pamras
         *@return void
         */
        public void setExecutionVariables(String executionId, Map<String, Object> pamras);
    
        /**
         * 签收任务:当一个用户处于一个任务的候选人员中时,在完成任务前需要先将组任务接替为个人任务
         * 调用此方法即可
         * 候选人员:一个任务的候选人员中,或者属于一个任务的分配组中
         *@author 47Gamer
         *@date 2019-3-6
         *@param userId
         *@param taskId
         *@return void
         */
        public void takeTask(String userId, String taskId);
    
        /**
         * 通过变量名获取一个任务上下文中的变量值
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@param variableName
         *@return Object
         */
        public Object getTaskVariable(String taskId, String variableName);
    
        /**
         * 获取任务上下文的所有变量
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@return Map<String, Object>
         */
        public Map<String, Object> getTaskVariables(String taskId);
    
        /**
         * 向一个任务上下文中存入一个变量值
         * 如果对应的variableName已存在于任务上下文中,则新赋予的值会覆盖以前的值
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@param variableName
         *@param value
         *@return void
         */
        public void setTaskVariable(String taskId, String variableName, String value);
    
        /**
         * 向任务上下文中批量存入变量值
         * 如果对应的variableName已存在于执行上下文中,则新赋予的值会覆盖以前的值
         *@author 47Gamer
         *@date 2019-3-6
         *@param executionId
         *@param pamras
         *@return void
         */
        public void setTaskVariables(String taskId, Map<String, Object> pamras);
    
        /**
         * 断言指定的用户是否拥有指定的任务
         *@author 47Gamer
         *@date 2019-3-11
         *@param userId
         *@param taskId
         *@return
         *@return boolean
         */
        public void assertUserTask(String userId, String taskId);
    
        /**
         * 断言流程是否结束,如果结束返回结束结点的名称,否则返回null
         *@author 47Gamer
         *@date 2019-3-13
         *@param taskId
         *@return void
         */
        public String assertProcessInstanceEnd(String processId);
    
        /**
         * 完成任务,将流程从该任务流向下一任务,如果这是最后一个任务,则流程结束
         * 不带参数
         *@author 47Gamer
         *@date 2019-3-6
         *@param taskId
         *@return void
         */
        public String completeTask(String userId, String taskId);
    
        /**
         * 完成任务,将流程从该任务流向下一任务,如果这是最后一个任务,则流程结束
         * params中针对不同的任务会有不同的参数
         *@author 47Gamer
         *@date 2019-3-6
         *@param params
         *@return void
         */
        public String completeTask(String userId, String taskId, Map<String, Object> params);
    
        /**
         * 获取指定用户的个人待办任务
         * params必须包含一个userId
         *@author 47Gamer
         *@date 2019-3-6
         *@param params
         *@return ListVo<Task>
         */
        public List<Task> getPersonalTask(Map<String, Object> params);
    
        /**
         * 通过流程实例id获取流程图,前提是在上传的zip资源包上有
         *@author 47Gamer
         *@date 2019-3-6
         *@param deploymentId
         *@return InputStream
         */
        public InputStream getImage(String processInstanceId);
    
        /**
         * 添加activiti的用户,这里我们将该用户映射为业务系统的User
         * 因为要关联业务系统的用户管理,所以要保证activiti的用户表与业务系统的用户表同步
         * 因此该方法一般是在业务系统addUser方法之后调用,并且必须在一个事务中
         * 备注:因为中文名字不存在firstName,lastName之说,所以这里我们约定
         * firstName存入用户的真实姓名,lastName存入用户的登录名
         * 如果在流程中有事件触发机制,比如启动发邮件,那么email必须传入,如果没有传入空字符串
         * 如果指定的userId已存在则该方法会执行update操作。
         *@author 47Gamer
         *@date 2019-3-6
         *@param id
         *@param firstName
         *@param lastName
         *@param email
         *@param password
         *@return void
         */
        public void saveUser(String id, String firstName, String lastName, String email, String password);
    
        /**
         * 删除一个用户,如果指定的userId不存在,该方法将被ignored
         *@author 47Gamer
         *@date 2019-3-11
         *@param id
         *@return void
         */
        public void deleteUser(String ids);
    
        /**
         * 添加activiti用户组,这里我们将该用户组映射为业务系统的角色Role
         * 如果指定的groupId存在,则执行update操作
         * 该方法一般是在业务系统addRole方法之后调用
         *@author 47Gamer
         *@date 2019-3-6
         *@param id
         *@param name
         *@param type
         *@return void
         */
        public void saveGroup(String id, String name, String type);
    
        /**
         * 删除一个已存在的工作组
         * 如果指定的groupId不存在,指该方法将被ignored
         *@author 47Gamer
         *@date 2019-3-11
         *@param id
         *@return void
         */
        public void deleteGroup(String ids);
    
        /**
         * 添加activiti用户与组的关系,这里我们将该关系映射为业务系统的UserRole
         * 该方法一般是在业务系统addUserRole方法之后
         *@author 47Gamer
         *@date 2019-3-6
         *@param userId
         *@param groupId
         *@return void
         */
        public void createMembership(String userId, String groupId);
    
        /**
         * 删除activiti用户与组的关系
         * 该方法一般是在业务系统deleteUserRole方法之后
         *@author 47Gamer
         *@date 2019-3-6
         *@param userId
         *@param groupId
         *@return void
         */
        public void deleteMembership(String userId, String groupId);
    
        /**
         * 上传新的流程定义模板,当前上传的.zip的名字在存放资源包的路径下存在,则当前上传会覆盖以前的资源包
         *@author 47Gamer
         *@date 2019-3-12
         *@param file
         *@param fileName
         *@return void
         */
        public void uploadProcessInstanceDefinition(File temp, String fileName);
    
        /**
         * 浏览服务器存在的资源包,以树的形式展示
         *@author 47Gamer
         *@date 2019-3-12
         *@return void
         */
        public String viewServerZip();
    
        /**
         * 删除服务器的zip资源包
         *@author 47Gamer
         *@date 2019-3-12
         *@param fileName
         *@return void
         */
        public void deleteServerZip(String fileName);
    
        /**
         * 查看流程定义的png图片
         *@author 47Gamer
         *@date 2019-3-12
         *@return
         *@return InputStream
         */
        public InputStream viewProcessInstancePng(String deployId);
    
        /**
         * 查看流程定义的bpmn定义
         *@author 47Gamer
         *@date 2019-3-12
         *@return
         *@return InputStream
         */
        public InputStream viewProcessInstanceBpmn(String deployId);
    
        /**
         * 获取流程过程
         *@author 47Gamer
         *@date 2019-3-14
         *@param processId
         *@return
         *@return JSONObject
         */
        public JSONObject getProcessIntanceProcedure(String processId);
    
        /**
         * 通过执行上下文id获取自定义流程信息
         * @param executionId
         * @return Object
         */
        public Object getProcessInfoByExecutionId(String executionId);
    
        /**
         * 获取模板名称即中文名
         * @return
         */
        public String getTemplateName(String definitionInfoId);
    
    
        /**
         * 保存流程执行环节的变量,通常是审批意见与审批结果
         * @param processInfoId
         * @param taskId
         * @param variables
         */
        public void saveProcessLinkVariables(String processInfoId, String taskId, Map<String, Object> variables, Person person, String result);
    
        /**
         * 获取流程环节变量
         * @param processId
         * @param taskName
         * @return
         */
        public List<Object> getProcessLinkVariables(String processId, String taskName);
    
        /**
         * 根据taskId获取任务
         *@author 47号Gamer
         *@date 2019-4-17
         *@param taskId
         *@return Task
         */
        public Task getTaskById(String taskId);
    
        public void deleteUserIdentityLink(String taskId, String userIds, String identityLinkType);
    
        public void addUserIdentityLink(String taskId, String userIds, String identityLinkType);
    
        /**
         * 根据processInfoId获取当前task
         *
         *@author 47号Gamer
         *@date 2019-8-27
         *@param processInfoId
         *@return Map<String, Object>
         */
        public Map<String, Object> getTaskByProcessInfoId(int processInfoId);
    
        /**
         * 删除历史流程
         * @author 47Gamer
         * @date 2017-2-24
         * @param processIntanceId
         * void
         *
         */
        public void deleteHistoryProcessIntance(String executionId);
    
        /**
         * 检索与特定任务相关的identitylinks。
         * @param taskId
         * @return
         */
        public List<IdentityLink> getIdentityLinksForTask(String id);
    
        /**
         * 删除的identitylinktype候选组和任务之间的关联
         * @param taskId
         * @param groupIds
         * @param identityLinkType
         */
        public void deleteCandidateGroup(String id, String groupId);
    
        /**
         * 添加的identitylinktype候选用户和任务之间的关联
         * @param taskId
         * @param groupIds
         * @param identityLinkType
         */
        public void addCandidateUser(String id, String ids);
    }

    ActivitiServiceImpl.java

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.zip.ZipInputStream;
    
    import org.activiti.bpmn.model.BpmnModel;
    import org.activiti.engine.ActivitiException;
    import org.activiti.engine.HistoryService;
    import org.activiti.engine.IdentityService;
    import org.activiti.engine.ProcessEngineConfiguration;
    import org.activiti.engine.ProcessEngines;
    import org.activiti.engine.RepositoryService;
    import org.activiti.engine.RuntimeService;
    import org.activiti.engine.TaskService;
    import org.activiti.engine.history.HistoricActivityInstance;
    import org.activiti.engine.history.HistoricActivityInstanceQuery;
    import org.activiti.engine.history.HistoricProcessInstance;
    import org.activiti.engine.history.HistoricTaskInstance;
    import org.activiti.engine.identity.Group;
    import org.activiti.engine.identity.User;
    import org.activiti.engine.impl.ProcessEngineImpl;
    import org.activiti.engine.impl.bpmn.diagram.ProcessDiagramGenerator;
    import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
    import org.activiti.engine.impl.context.Context;
    import org.activiti.engine.impl.persistence.entity.GroupEntity;
    import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
    import org.activiti.engine.impl.persistence.entity.UserEntity;
    import org.activiti.engine.impl.pvm.PvmTransition;
    import org.activiti.engine.impl.pvm.process.ActivityImpl;
    import org.activiti.engine.repository.Deployment;
    import org.activiti.engine.repository.DeploymentBuilder;
    import org.activiti.engine.repository.ProcessDefinition;
    import org.activiti.engine.runtime.ProcessInstance;
    import org.activiti.engine.task.IdentityLink;
    import org.activiti.engine.task.Task;
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.lang3.math.NumberUtils;
    import org.apache.ibatis.session.RowBounds;
    import org.apache.struts2.ServletActionContext;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.sckj.base.common.constant.SystemConstant;
    import com.sckj.base.entity.activiti.ProcessDefinitionInfo;
    import com.sckj.base.entity.activiti.ProcessInfo;
    import com.sckj.base.entity.activiti.ProcessVariable;
    import com.sckj.base.entity.admin.Person;
    import com.sckj.base.exception.ServiceException;
    import com.sckj.base.service.BaseServiceImpl;
    import com.sckj.base.util.DateUtil;
    import com.sckj.base.vo.ComboVo;
    import com.sckj.macb.query.IObjectQuery;
    import com.sckj.macb.query.ListVo;
    import com.sckj.macb.query.ObjectQueryImpl;
    
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    
    /**
     * Activity相关服务实现
     * @author 47Gamer
     */
    @Service(value = "activitiService")
    public class ActivitiServiceImpl extends BaseServiceImpl implements IActivitiService {
    
      

       /**activiti存放资源包的路径,相对于WebContent的相对路径*/
       public static final String ACTIVITI_PATH = "activiti";

    
        @Autowired
        private RepositoryService repositoryService;
    
        @Autowired
        private RuntimeService runtimeService;
    
        @Autowired
        private TaskService taskService;
    
        @Autowired
        private HistoryService historyService;
    
        @Autowired
        private IdentityService identityService;
    
        @Override
        public void deployProcessDefinition(String definitionName) {
            try {
                String definitionNameEn = definitionName.split("[-]")[0];
                String definitionNameCn = definitionName.split("[-]")[1];
                String ACTIVITI_PATH = ServletActionContext.getServletContext().getRealPath(SystemConstant.ACTIVITI_PATH);
                File file = new File(ACTIVITI_PATH + File.separator + definitionName + ".zip");
                InputStream in = new FileInputStream(file);
                ZipInputStream zis = new ZipInputStream(in);
                DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
                deploymentBuilder.addZipInputStream(zis).category(definitionNameEn).name(definitionNameEn);
                Deployment deployment = deploymentBuilder.deploy();
                ProcessDefinitionInfo processDefinitionInfo = new ProcessDefinitionInfo();
                processDefinitionInfo.setDeployId(deployment.getId());
                processDefinitionInfo.setDefinitionName(definitionNameEn);
                processDefinitionInfo.setTemplateName(definitionNameCn);
                ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
                processDefinitionInfo.setKeyVersion(pd.getVersion());
                this.add(processDefinitionInfo);
            } catch (ActivitiException e) {
                throw new ServiceException(e.getMessage());
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException(e);
            }
        }
    
        @Override
        public List<ComboVo> getWaitDefinition() {
            List<ComboVo> list = new ArrayList<ComboVo>();
            String ACTIVITI_PATH = ServletActionContext.getServletContext().getRealPath(SystemConstant.ACTIVITI_PATH);
            File[] fileList = new File(ACTIVITI_PATH).listFiles();
            ComboVo vo = null;
            Integer index = null;
            for (File file : fileList) {
                vo = new ComboVo();
                String name = file.getName();
                index = name.lastIndexOf("-");
                if (index == -1) {
                    continue;
                }
                vo.setValue(name.substring(0, index));
                vo.setDisplayValue(name.substring(index + 1, name.length() - 4));
                list.add(vo);
            }
            return list;
        }
    
        @Override
        public List<Object> getProcessDefinitionList() {
            ListVo<Object> listVo = new ListVo<Object>();
            try {
                IObjectQuery<ProcessDefinitionInfo> query = new ObjectQueryImpl<ProcessDefinitionInfo, Integer>(ProcessDefinitionInfo.class);
                query.orderAsc("templateName").orderAsc("keyVersion");
                listVo = this.mybatisDao.getObjectPage(query.sqlMap(), null);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return listVo.getList();
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public String getDeployIdByProcessInfoId(String processInfoId) {
            try {
                IObjectQuery<ProcessInfo> query = new ObjectQueryImpl<ProcessInfo, Integer>(ProcessInfo.class);
                query.equals("id", processInfoId);
                List<Object> list = this.mybatisDao.getObjectList(query.sqlMap());
                Map<String, Object> map = (Map<String, Object>) list.get(0);
                String processId = map.get("processId") + "";
                String definitionId = this.getHistoricProcessInstanceById(processId).getProcessDefinitionId();
                ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(definitionId).singleResult();
                return pd.getDeploymentId() + "@" + processId;
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void deleteDeployment(String deploymentIds) {
            try {
                Map<String, Object> params = new HashMap<String, Object>();
                String[] idArray = deploymentIds.split(",");
                for (String id : idArray) {
                    repositoryService.deleteDeployment(id);
                    params.put("deployId", id);
                    this.mybatisDao.delete("activiti.deleteSystemDefinition", params);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void deleteDeploymentCascade(String deploymentIds) {
            try {
                Map<String, Object> params = new HashMap<String, Object>();
                String[] idArray = deploymentIds.split(",");
                for (String id : idArray) {
    
                    /** 执行activity的彻底删除流程定义操作 **/
                    repositoryService.deleteDeployment(id, true);
    
                    params.put("deployId", id);
    
                    /** 删除系统表存储的流程实例保存的变量 **/
                    this.mybatisDao.delete("activiti.deleteProcessInstanceVariableByDeployId", params);
    
                    /** 删除系统表存储的流程**/
                    this.mybatisDao.delete("activiti.deleteSystemProcessInstance", params);
    
                    /** 删除系统表存储的流程定义 **/
                    this.mybatisDao.delete("activiti.deleteSystemDefinition", params);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public Integer startProcessInstanceByKey(String key, String businessKey, Map<String, Object> params, Person person) {
            try {
                List<ProcessDefinition> processDefinitions = this.repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).list();
                if (processDefinitions == null || processDefinitions.size() == 0) {
                    throw new ServiceException("流程启动异常,没有找到相关流程定义!");
                }
                ProcessInstance pi = this.runtimeService.startProcessInstanceByKey(key, params);
                ProcessDefinition lastProcessDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).latestVersion().singleResult();
                IObjectQuery<ProcessDefinitionInfo> query = new ObjectQueryImpl<ProcessDefinitionInfo, Integer>(ProcessDefinitionInfo.class);
                query.equals("deployId", lastProcessDefinition.getDeploymentId());
                Map<String, Object> object = (Map<String, Object>) (this.mybatisDao.getObjectList(query.sqlMap()).get(0));
                ProcessInfo processInfo = new ProcessInfo();
                processInfo.setProcessId(pi.getId());
                processInfo.setDefinitionInfoId(NumberUtils.toInt(object.get("id") + ""));
                processInfo.setUserCardId(person.getCard());
                processInfo.setStatus("active");
                processInfo.setProcessType(key);
                processInfo.setCreateDate(new Date());
                processInfo.setUserName(person.getUserName());
                processInfo.setBusinessKey(businessKey);
                this.add(processInfo);
                return processInfo.getId();
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public Integer startProcessInstanceById(String id, Map<String, Object> params, Person person) {
            try {
                ProcessDefinition processDefinition = this.repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
                if (processDefinition == null) {
                    throw new ServiceException("流程启动异常,没有找到相关流程定义!");
                }
                ProcessInstance pi = this.runtimeService.startProcessInstanceById(id, params);
                IObjectQuery<ProcessDefinitionInfo> query = new ObjectQueryImpl<ProcessDefinitionInfo, Integer>(ProcessDefinitionInfo.class);
                query.equals("deployId", processDefinition.getDeploymentId());
                Map<String, Object> object = (Map<String, Object>) (this.mybatisDao.getObjectList(query.sqlMap()).get(0));
                ProcessInfo processInfo = new ProcessInfo();
                processInfo.setProcessId(pi.getId());
                processInfo.setDefinitionInfoId(NumberUtils.toInt(object.get("id") + ""));
                processInfo.setUserCardId(person.getCard());
                processInfo.setStatus("active");
                processInfo.setProcessType(object.get("definitionName") + "");
                processInfo.setCreateDate(new Date());
                processInfo.setUserName(person.getUserName());
                this.add(processInfo);
                return processInfo.getId();
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
            HistoricProcessInstance historicProcessInstance = null;
            try {
                historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return historicProcessInstance;
        }
    
        @Override
        public ProcessInstance getProcessInstanceById(String processInstanceId) {
            ProcessInstance processInstance = null;
            try {
                processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return processInstance;
        }
    
        @Override
        public void deleteProcessInstance(String processInstanceId, String processInstanceInfoId, String deleteReason) {
            try {
                runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("processinfoId", processInstanceInfoId);
                param.put("complateDate", DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                this.mybatisDao.update("activiti.updateProcessInstanceWhenDeleteProcess", param);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public ListVo<Object> getProcessInstanceList(Map<String, Object> params) {
            ListVo<Object> listVo = new ListVo<Object>();
            try {
                String start = params.get("start") + "";
                String limit = params.get("limit") + "";
                Object status = params.get("status");
                IObjectQuery<ProcessInfo> query = new ObjectQueryImpl<ProcessInfo, Integer>(ProcessInfo.class);
                query.equals("status", status).orderDesc("status").orderDesc("id");
                RowBounds rowBounds = new RowBounds(NumberUtils.toInt(start), NumberUtils.toInt(limit));
                listVo = this.mybatisDao.getObjectPage(query.sqlMap(), rowBounds);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return listVo;
        }
    
        public void signal(String executionId, @SuppressWarnings("unchecked") Map<String, Object>... pamras) {
            try {
                if (pamras.length == 0) {
                    runtimeService.signal(executionId);
                    return;
                }
                runtimeService.signal(executionId, pamras[0]);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        public Object getExecutionVariable(String executionId, String variableName) {
            Object object = null;
            try {
                object = runtimeService.getVariable(executionId, variableName);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return object;
        }
    
        public Map<String, Object> getExecutionVariables(String executionId) {
            Map<String, Object> object = null;
            try {
                object = runtimeService.getVariables(executionId);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return object;
        }
    
        public void setExecutionVariable(String executionId, String variableName, String value) {
            try {
                runtimeService.setVariable(executionId, variableName, value);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        public void setExecutionVariables(String executionId, Map<String, Object> pamras) {
            try {
                if (null == pamras)
                    return;
                runtimeService.setVariables(executionId, pamras);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void takeTask(String userId, String taskId) {
            try {
                taskService.claim(taskId, userId);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException(e);
            }
        }
    
        public Object getTaskVariable(String taskId, String variableName) {
            Object object = null;
            try {
                object = taskService.getVariable(taskId, variableName);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException(e);
            }
            return object;
        }
    
        public Map<String, Object> getTaskVariables(String taskId) {
            Map<String, Object> object = null;
            try {
                object = taskService.getVariables(taskId);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return object;
        }
    
        public void setTaskVariable(String taskId, String variableName, String value) {
            try {
                taskService.setVariable(taskId, variableName, value);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        public void setTaskVariables(String taskId, Map<String, Object> pamras) {
            try {
                if (null == pamras)
                    return;
                taskService.setVariables(taskId, pamras);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void assertUserTask(String userId, String taskId) {
            try {
                List<Task> assignTaskList = taskService.createTaskQuery().taskAssignee(userId).list();
                for (Task task : assignTaskList) {
                    if (task.getId().equals(taskId)) {
                        return;
                    }
                }
                throw new ServiceException("候选任务还没有被分配,或者用户不具有该任务!");
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public String assertProcessInstanceEnd(String processId) {
            return this.assertProcessEnd(processId, false);
        }
    
        public String assertProcessEnd(String processId, boolean flag) {
            ProcessInstance pi = this.getProcessInstanceById(processId);
            HistoricProcessInstance hpi = this.getHistoricProcessInstanceById(processId);
            if (null == hpi) {
                throw new ServiceException("指定的流程不存在!");
            }
            if (pi == null) {
                if (flag) {
                    Map<String, Object> params = new HashMap<String, Object>();
                    params.put("processId", processId);
                    params.put("complateDate", DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    this.mybatisDao.update("activiti.updateProcessInfoStatus", params);
                }
                HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
                @SuppressWarnings("deprecation")
                HistoricActivityInstance endActivity = historicActivityInstanceQuery.processInstanceId(processId).activityId(hpi.getEndActivityId()).singleResult();
                return endActivity.getActivityName();
            }
            return null;
        }
    
        @Override
        public String completeTask(String userId, String taskId) {
            return this.complete(userId, taskId, null);
        }
    
        @Override
        public String completeTask(String userId, String taskId, Map<String, Object> params) {
            return this.complete(userId, taskId, params);
        }
    
        public String complete(String userId, String taskId, Map<String, Object> params) {
            try {
                assertUserTask(userId, taskId);
                String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();
                taskService.complete(taskId, params);
                return assertProcessEnd(processInstanceId, true);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException(e.getMessage());
            }
        }
    
        @Override
        public List<Task> getPersonalTask(Map<String, Object> params) {
            List<Task> list = new ArrayList<Task>();
            String userId = params.get("card") + "";
            /** only select tasks which are assigned to the given user.  **/
            list.addAll(taskService.createTaskQuery().taskAssignee(userId).list());
    
            /** only select tasks for which the given user is a candidate.  **/
            list.addAll(taskService.createTaskQuery().taskCandidateUser(userId).list());
            
            /*String userGroupQuerySQL = "SELECT ap.* FROM ACT_ID_MEMBERSHIP am, ACT_ID_GROUP ap WHERE am.GROUP_ID_ = ap.ID_ AND am.USER_ID_ = '"+userId+"'";
            List<Group> userGroups = identityService.createNativeGroupQuery().sql(userGroupQuerySQL).list();
            for(Group g : userGroups){
                obj = taskService.createTaskQuery().taskCandidateGroup(g.getId()).list();
                list.addAll(obj);
            }*/
            return list;
        }
    
        public List<Task> filterTasks(List<Task> taskList, String realId) {
            List<Task> tasks = new ArrayList<Task>();
            for (Task task : taskList) {
                Object unitIds = this.getExecutionVariable(task.getExecutionId(), "orgId");
                String[] unitIdsArray = unitIds.toString().split(",");
                Arrays.sort(unitIdsArray);
                int index = Arrays.binarySearch(unitIdsArray, realId);
                if (index >= 0) {
                    tasks.add(task);
                }
            }
            return tasks;
        }
    
        @Override
        public InputStream getImage(String processInstanceId) {
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            if (null == processInstance) {
                HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                if (null == historicProcessInstance) {
                    throw new ServiceException("没有找到对应的流程实例!");
                }
                String definitionId = historicProcessInstance.getProcessDefinitionId();
                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(definitionId).singleResult();
                return repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
            }
            try {
                BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
                HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
                List<HistoricActivityInstance> activityInstances = historicActivityInstanceQuery.processInstanceId(processInstanceId)
                        .orderByHistoricActivityInstanceStartTime().asc().list();
                List<String> activitiIds = new ArrayList<String>();
                List<String> flowIds = new ArrayList<String>();
                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processInstance.getProcessDefinitionId());
                flowIds = this.getHighLightedFlows(processDefinition, activityInstances);
                for (HistoricActivityInstance hai : activityInstances) {
                    activitiIds.add(hai.getActivityId());
                }
                ProcessEngineImpl defaultProcessEngine = (ProcessEngineImpl) ProcessEngines.getDefaultProcessEngine();
                ProcessEngineConfiguration processEngineConfiguration = defaultProcessEngine.getProcessEngineConfiguration();
                Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngineConfiguration);
                return ProcessDiagramGenerator.generateDiagram(bpmnModel, "png", activitiIds, flowIds);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException(e);
            }
        }
    
        public List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinitionEntity, List<HistoricActivityInstance> historicActivityInstances) {
            List<String> highFlows = new ArrayList<String>();
            for (int i = 0; i < historicActivityInstances.size() - 1; i++) {
                ActivityImpl activityImpl = processDefinitionEntity.findActivity(historicActivityInstances.get(i).getActivityId());
                ActivityImpl nextActivityImpl = processDefinitionEntity.findActivity(historicActivityInstances.get(i + 1).getActivityId());
                List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();
                for (PvmTransition pvmTransition : pvmTransitions) {
                    ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition.getDestination();
                    if (pvmActivityImpl.getId().equals(nextActivityImpl.getId())) {
                        highFlows.add(pvmTransition.getId());
                    }
                }
            }
            return highFlows;
        }
    
        @Override
        public JSONObject getProcessIntanceProcedure(String processId) {
            JSONObject json = new JSONObject();
            try {
                HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
                List<HistoricActivityInstance> activityInstances = historicActivityInstanceQuery.processInstanceId(processId)
                        .orderByHistoricActivityInstanceStartTime().asc().list();
                HistoricProcessInstance historicProcessInstance = this.getHistoricProcessInstanceById(processId);
                ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(historicProcessInstance.getProcessDefinitionId());
                JSONArray arr = new JSONArray();
                for (int i = 0; i < activityInstances.size(); i++) {
                    HistoricActivityInstance activityIntance = activityInstances.get(i);
                    Map<String, Object> map = new HashMap<String, Object>();
                    ActivityImpl activityImpl = processDefinition.findActivity(activityIntance.getActivityId());
                    map.put("activityName", activityIntance.getActivityName());
                    map.put("activityType", activityIntance.getActivityType());
                    map.put("left", activityImpl.getX() - 4);
                    map.put("top", activityImpl.getY() - 4);
                    map.put("width", activityImpl.getWidth());
                    map.put("height", activityImpl.getHeight());
                    map.put("processId", processId);
                    String endActivityName = this.assertProcessInstanceEnd(processId);
                    if (endActivityName != null) {
                        map.put("active", false);
                    } else {
                        ProcessInstance pi = this.getProcessInstanceById(processId);
                        String activitingId = pi.getActivityId();
                        if (activityIntance.getActivityId().equals(activitingId))
                            map.put("active", true);
                        else
                            map.put("active", false);
                    }
                    arr.add(map);
                }
                json.put("data", arr);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
            return json;
        }
    
        @Override
        public void saveUser(String id, String firstName, String lastName, String email, String password) {
            try {
                User user = identityService.createUserQuery().userId(id).singleResult();
                if (user != null) {
                    user.setFirstName(firstName);
                    user.setLastName(lastName);
                    user.setEmail(email);
                    user.setPassword(password);
                    identityService.saveUser(user);
                    return;
                }
                User user1 = new UserEntity();
                user1.setId(id);
                user1.setFirstName(firstName);
                user1.setLastName(lastName);
                user1.setEmail(email);
                user1.setPassword(password);
                identityService.saveUser(user1);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        public void deleteUser(String ids) {
            try {
                String[] idArray = ids.split(",");
                for (String id : idArray) {
                    identityService.deleteUser(id);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void saveGroup(String id, String name, String type) {
            try {
                Group group = identityService.createGroupQuery().groupId(id).singleResult();
                if (group != null) {
                    group.setName(name);
                    group.setType(type);
                    identityService.saveGroup(group);
                    return;
                }
                Group group1 = new GroupEntity();
                group1.setId(id);
                group1.setName(name);
                group1.setType(type);
                identityService.saveGroup(group1);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void deleteGroup(String ids) {
            try {
                String[] idArray = ids.split(",");
                for (String id : idArray) {
                    identityService.deleteGroup(id);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void createMembership(String userId, String groupId) {
            try {
                identityService.createMembership(userId, groupId);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void deleteMembership(String userId, String groupId) {
            try {
                identityService.deleteMembership(userId, groupId);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void uploadProcessInstanceDefinition(File temp, String fileName) {
            try {
                String zipPath = ServletActionContext.getServletContext().getRealPath(SystemConstant.ACTIVITI_PATH);
                File[] fileList = new File(zipPath).listFiles();
                for (File file : fileList) {
                    if (file.getName().equals(fileName)) {
                        file.delete();
                        break;
                    }
                }
                File newTemplate = new File(zipPath, fileName);
                FileUtils.copyFile(temp, newTemplate);
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public String viewServerZip() {
            StringBuffer json = new StringBuffer("[");
            List<ComboVo> list = this.getWaitDefinition();
            for (int i = 0; i < list.size(); i++) {
                StringBuffer child = new StringBuffer("{text:'");
                child.append(list.get(i).getValue() + "-" + list.get(i).getDisplayValue() + ".zip',iconCls:'zip-button',leaf:true}");
                json.append(child);
                if (i != list.size() - 1) {
                    json.append(",");
                }
            }
            json.append("]");
            return json.toString();
        }
    
        @Override
        public void deleteServerZip(String fileName) {
            try {
                String zipPath = ServletActionContext.getServletContext().getRealPath(SystemConstant.ACTIVITI_PATH);
                File file = new File(zipPath + "/" + fileName);
                if (file.exists()) {
                    file.delete();
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public InputStream viewProcessInstancePng(String deployId) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
            return repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getDiagramResourceName());
        }
    
        @Override
        public InputStream viewProcessInstanceBpmn(String deployId) {
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
            return repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
        }
    
        @Override
        public Object getProcessInfoByExecutionId(String executionId) {
            IObjectQuery<ProcessInfo> query = new ObjectQueryImpl<ProcessInfo, Integer>(ProcessInfo.class);
            query.equals("processId", executionId);
            List<Object> list = this.mybatisDao.getObjectList(query.sqlMap());
            if (list != null && list.size() != 0) {
                return list.get(0);
            }
            return null;
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public String getTemplateName(String definitionInfoId) {
            IObjectQuery<ProcessDefinitionInfo> query = new ObjectQueryImpl<ProcessDefinitionInfo, Integer>(ProcessDefinitionInfo.class);
            query.id(definitionInfoId);
            List<Object> list = this.mybatisDao.getObjectList(query.sqlMap());
            if (list != null && list.size() != 0) {
                return ((Map<String, Object>) list.get(0)).get("templateName").toString();
            }
            return "";
        }
    
        @Override
        public void saveProcessLinkVariables(String processInfoId, String taskId, Map<String, Object> variables, Person person, String result) {
            //Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    
            HistoricTaskInstance hti = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
            ProcessVariable pv = null;
            for (Map.Entry<String, Object> entry : variables.entrySet()) {
                pv = new ProcessVariable();
                pv.setExecutionId(hti.getExecutionId());
                pv.setTaskId(taskId);
                pv.setTaskName(hti.getName());
                pv.setProcessInfoId(NumberUtils.toInt(processInfoId));
                pv.setT_key(entry.getKey());
                pv.setT_value(entry.getValue().toString());
                pv.setTime(new Date());
                pv.setUserName(person.getUserName());
                pv.setUserCard(person.getCard());
                pv.setResult(result);//保存审批结果
                pv.setSort(getTaskVariableSort(hti.getName(), entry.getKey(), hti.getExecutionId()));
                this.add(pv);
            }
        }
    
        public Integer getTaskVariableSort(String taskName, String t_key, String executionId) {
            IObjectQuery<ProcessVariable> query = new ObjectQueryImpl<ProcessVariable, Integer>(ProcessVariable.class);
            query.equals("taskName", taskName).equals("t_key", t_key).equals("executionId", executionId);
            List<Object> list = this.mybatisDao.getObjectList(query.sqlMap());
            if (list == null || list.size() == 0) {
                return 0;
            }
            return list.size();
        }
    
        @Override
        public List<Object> getProcessLinkVariables(String processId, String taskName) {
            IObjectQuery<ProcessVariable> query = new ObjectQueryImpl<ProcessVariable, Integer>(ProcessVariable.class);
            query.equals("executionId", processId).equals("taskName", taskName).orderDesc("sort");
            List<Object> list = this.mybatisDao.getObjectList(query.sqlMap());
            return list;
        }
    
        @Override
        public Task getTaskById(String taskId) {
            return this.taskService.createTaskQuery().taskId(taskId).singleResult();
        }
    
        @Override
        public void deleteUserIdentityLink(String taskId, String userIds, String identityLinkType) {
            try {
                String[] ids = userIds.split(",");
                for (String id : ids) {
                    taskService.deleteUserIdentityLink(taskId, id, identityLinkType);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void addUserIdentityLink(String taskId, String userIds, String identityLinkType) {
            try {
                String[] ids = userIds.split(",");
                for (String id : ids) {
                    taskService.addUserIdentityLink(taskId, id, identityLinkType);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public Map<String, Object> getTaskByProcessInfoId(int processInfoId) {
            try {
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("processInfoId", processInfoId);
                return (Map<String, Object>) this.mybatisDao.getUniqueObject("activiti.getTaskByProcessInfoId", params);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void deleteHistoryProcessIntance(String executionId) {
            historyService.deleteHistoricProcessInstance(executionId);
        }
    
        @Override
        public List<IdentityLink> getIdentityLinksForTask(String taskId) {
            return taskService.getIdentityLinksForTask(taskId);
        }
    
        @Override
        public void deleteCandidateGroup(String taskId, String groupIds) {
            String[] groupIdArray = groupIds.split(",");
            try {
                for (String id : groupIdArray) {
                    taskService.deleteCandidateGroup(taskId, id);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
        @Override
        public void addCandidateUser(String taskId, String userIds) {
            String[] userIdArray = userIds.split(",");
            try {
                for (String id : userIdArray) {
                    taskService.addCandidateUser(taskId, id);
                }
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }
    
    }

    Mybatis映射SQL

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "./dtd/mybatis-3-mapper.dtd">
    <mapper namespace="activiti">
        <!-- 根据ProcessInfoId获取任务 -->
        <select id="getTaskByProcessInfoId" parameterType="java.util.HashMap" resultType="java.util.HashMap">
            select
            t.ID_ as taskId,
            t.NAME_ as taskName,
            t.DESCRIPTION_ as description
            from act_ru_task t
            inner join
            t_processinfo t1
            on
            t1.PROCESSID = t.EXECUTION_ID_
            where
            t1.PK_ID = #{processInfoId}
            limit 1
        </select>
    
        <!-- 更新流程状态 -->
        <update id="updateProcessInfoStatus" parameterType="java.util.Map">
            update
            T_PROCESSINFO o set o.STATUS = 'end',o.COMPLATE_DATE =
            #{complateDate}
            where o.PROCESSID = #{processId}
        </update>
    
        <!-- 当删除运行时流程时,更新processInfo表信息 -->
        <update id="updateProcessInstanceWhenDeleteProcess" parameterType="java.util.Map">
            update T_PROCESSINFO o set o.STATUS =
            'delete',o.COMPLATE_DATE = #{complateDate}
            where o.PK_ID =
            #{processinfoId}
        </update>
    
        <!-- 根据部署id删除系统流程定义 -->
        <delete id="deleteSystemDefinition" parameterType="java.util.Map">
            delete from
            T_PROCESSDEFINITIONINFO
            where DEPLOYID = #{deployId}
        </delete>
    
        <!-- 根据部署id删除系统流程 -->
        <delete id="deleteSystemProcessInstance" parameterType="java.util.Map">
            delete t
            from T_PROCESSINFO t
            where t.DEFINITIONINFOID in(
            select t1.PK_ID from
            T_PROCESSDEFINITIONINFO t1
            where t1.DEPLOYID = #{deployId}
            )
        </delete>
    
        <!-- 根据部署id来删除流程变量 -->
        <delete id="deleteProcessInstanceVariableByDeployId" parameterType="java.util.Map">
            delete t from T_PROCESSVARIABLE t
            where t.PROCESSINFOID
            in(
            select t1.PK_ID from T_PROCESSINFO t1
            where t1.DEFINITIONINFOID in(
            select t2.PK_ID from T_PROCESSDEFINITIONINFO t2
            where t2.DEPLOYID =
            #{deployId}
            )
            )
        </delete>
    </mapper>

    大家可以自行测试:(调用上面部署流程的方法)

    用activiti插件生成bpmn和png图片之后,压缩到一个zip格式的压缩包中。

    执行测试用例并查看结果

    • act_re_deployment 流程定义部署表新增一条记录

    • act_re_procdef 流程定义表中VERSION_字段 版本升级了,KEY依然是一样的;

    • act_ge_bytearry 资源文件表,多了两条记录

    • 这里再提一个表 act_ge_property 属性表,这里的next_dbid是主键策略,就是规定好了下一次生成的id就是10001;

    测试:

    import java.io.File;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.activiti.engine.task.Task;
    import org.apache.commons.lang.StringUtils;
    import org.apache.struts2.convention.annotation.Action;
    import org.apache.struts2.convention.annotation.Result;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import com.sckj.base.common.constant.SystemConstant;
    import com.sckj.base.entity.admin.Person;
    import com.sckj.base.exception.ServiceException;
    import com.sckj.base.util.DateUtil;
    import com.sckj.base.vo.ComboVo;
    import com.sckj.macb.query.ListVo;
    import com.sckj.plugins.org.entity.OPerson;
    import com.sckj.plugins.org.service.IOrgService;
    
    import net.sf.json.JSONObject;
    
    
    /**
     * 流程管理action
     * @author LuoYu
     */
    public class ActivitiAction extends ActivitiBaseAction {
    
        /** serialVersionUID **/
        private static final long serialVersionUID = 4022483438757978770L;
    
        private File newTemplate;
    
        private String newTemplateName;
    
        @Autowired
        private IOrgService orgService;
    
        @Override
        @Action(value = "*", results = {@Result(name = "success", location = "/WEB-INF/pages/admin/process/{1}.jsp")})
        public String execute() throws Exception {
            return super.execute();
        }
    
        /**
         * 部署流程定义
         *@return void
         */
        @Action(value = "deployProcessInstanceDefinition")
        public void deployProcessInstanceDefinition() {
            String definitionName = this.getHttpServletRequest().getParameter("definitionName");
            try {
                this.getActivitiService().deployProcessDefinition(definitionName);
                this.outSuccess("部署流程模板成功!");
            } catch (ServiceException e) {
                this.outError("msg:" + e.getMessageKey());
            } catch (Exception e) {
                this.outError("部署流程模板失败!");
            }
        }
    
        /**
         * 获取待部署的流程定义模板
         *@return void
         */
        @Action(value = "getWaitDefinition")
        public void getWaitDefinition() {
            List<ComboVo> list = this.getActivitiService().getWaitDefinition();
            this.out(list);
        }
    
        /**
         * 获取已发布的流程定义模板
         *@return void
         */
        @Action(value = "getProcessDefinitionList")
        public void getProcessDefinitionList() {
            try {
                List<Object> list = this.getActivitiService().getProcessDefinitionList();
                this.out(list);
            } catch (Exception e) {
                this.outError("获取流程定义失败!");
                e.printStackTrace();
            }
        }
    
        /**
         * 删除流程定义
         *@return void
         */
        @Action(value = "deleteProcessInstanceDefinition")
        public void deleteProcessInstanceDefinition() {
            String ids = this.getHttpServletRequest().getParameter("ids");
            String cascade = this.getHttpServletRequest().getParameter("cascade");
            try {
                if (cascade.equals("yes")) {
                    this.getActivitiService().deleteDeploymentCascade(ids);
                } else {
                    this.getActivitiService().deleteDeployment(ids);
                }
                this.outSuccess("删除流程实例成功!");
            } catch (Exception e) {
                this.outError("删除流程实例失败!");
            }
        }
    
        /**
         * 获取所有的流程实例
         *@return void
         */
        @Action(value = "getProcessList")
        public void getProcessList() {
            HttpServletRequest request = this.getHttpServletRequest();
            String start = request.getParameter("start");
            String limit = request.getParameter("limit");
            String status = request.getParameter("status");
            if (null != status && status.equals("")) {
                status = null;
            }
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("start", start);
            params.put("limit", limit);
            params.put("status", status);
            try {
                ListVo<Object> listVo = this.getActivitiService().getProcessInstanceList(params);
                this.out(listVo);
            } catch (Exception e) {
                this.outError("获取流程实例失败!");
                e.printStackTrace();
            }
        }
    
    
        /**
         * 删除流程实例
         *@return void
         */
        @Action(value = "deleteProcessInstance")
        public void deleteProcessInstance() {
            HttpServletRequest request = this.getHttpServletRequest();
            String processInfoId = request.getParameter("processInfoId");
            String processId = request.getParameter("processId");
            String deleteReason = request.getParameter("deleteReason");
            try {
                this.getActivitiService().deleteProcessInstance(processId, processInfoId, deleteReason);
                this.outSuccess("删除流程实例成功!");
            } catch (Exception e) {
                this.outError("删除流程实例失败!");
            }
        }
    
        /**
         * 上传新的流程模板
         *@return void
         */
        @Action(value = "uploadTemplate")
        public void uploadTemplate() {
            try {
                this.getActivitiService().uploadProcessInstanceDefinition(newTemplate, newTemplateName);
                this.outSuccess("上传流程模板成功!");
            } catch (Exception e) {
                this.outError("上传流程模板失败!");
            }
        }
    
        /**
         * 浏览服务器存在的部署资源包
         *@return void
         */
        @Action(value = "viewServerZip")
        public void viewServerZip() {
            this.out(this.getActivitiService().viewServerZip());
        }
    
        /**
         * 删除服务器存在的zip资源包
         *@return void
         */
        @Action(value = "deleteServerZip")
        public void deleteServerZip() {
            String fileName = this.getHttpServletRequest().getParameter("fileName");
            try {
                this.getActivitiService().deleteServerZip(fileName);
                this.outString("删除资源包成功!");
            } catch (Exception e) {
                this.outError("删除资源包失败!");
            }
        }
    
        /**
         * 查看流程定义的png图片
         *@return void
         */
        @Action(value = "viewProcessInstancePng")
        public void viewProcessInstancePng() {
            try {
                String deployId = this.getHttpServletRequest().getParameter("deployId");
                InputStream is = this.getActivitiService().viewProcessInstancePng(deployId);
                byte[] b = new byte[1024];
                int len = 0;
                while ((len = is.read(b, 0, 1024)) != -1) {
                    this.getHttpServletResponse().getOutputStream().write(b, 0, len);
                }
            } catch (Exception e) {
                this.outError("获取图片失败!");
            }
        }
    
        /**
         * 查看流程定义BPMN
         *@return void
         */
        @Action(value = "viewProcessInstanceBpmn")
        public void viewProcessInstanceBpmn() {
            try {
                String deployId = this.getHttpServletRequest().getParameter("deployId");
                InputStream is = this.getActivitiService().viewProcessInstanceBpmn(deployId);
                byte[] b = new byte[1024];
                int len = 0;
                while ((len = is.read(b, 0, 1024)) != -1) {
                    this.getHttpServletResponse().getOutputStream().write(b, 0, len);
                }
            } catch (Exception e) {
                this.outError("获取BPMN文件失败!");
            }
        }
    
        @Action(value = "gotoImage", results = {@Result(location = "/WEB-INF/pages/admin/viewProcessImg.jsp")})
        public String gotoImage() {
            String processInfoId = this.getHttpServletRequest().getParameter("processInfoId");
            String string = this.getActivitiService().getDeployIdByProcessInfoId(processInfoId);
            this.getHttpServletRequest().setAttribute("deployId", string.split("@")[0]);
            this.getHttpServletRequest().setAttribute("processId", string.split("@")[1]);
            return SUCCESS;
        }
    
        /**
         * 获取流程过程流向
         *@return void
         */
        @Action(value = "getProcessIntanceProcedure")
        public void getProcessIntanceProcedure() {
            String processId = this.getHttpServletRequest().getParameter("processId");
            JSONObject jsonObject = this.getActivitiService().getProcessIntanceProcedure(processId);
            this.out(jsonObject);
        }
    
        /**
         * 获取用户待办任务列表
         */
        @SuppressWarnings("unchecked")
        @Action(value = "getPersonalTask")
        public void getPersonalTask() {
            try {
                Map<String, Object> params = new HashMap<String, Object>();
                Person account = this.getCurrentAccount();
                if (!account.isAdmin()) {
                    params.put("card", account.getCard().toString());
                    params.put("dwId", account.getOrgId());
                    List<Task> taskList = this.getActivitiService().getPersonalTask(params);
                    ListVo<Map<String, String>> listVo = new ListVo<Map<String, String>>();
                    List<Map<String, String>> list = new ArrayList<Map<String, String>>();
                    Map<String, String> map = null;
                    JSONObject jsonObject = null;
                    Map<String, Object> processInfo = null;
                    for (Task task : taskList) {
                        map = new HashMap<String, String>();
                        processInfo = (Map<String, Object>) this.getActivitiService().getProcessInfoByExecutionId(task.getExecutionId());
                        String userCard = processInfo.get("userCardId").toString();
                        if (StringUtils.isNotBlank(userCard)) {
                            OPerson person = this.orgService.queryPersonByCard(userCard);
                            if (person != null) {
                                map.put("bmPath", person.getDepartmentId());
                            }
                        }
    
                        map.put("infoId", processInfo.get("id").toString());//流程info的id
                        map.put("sponsor", processInfo.get("userName").toString());//流程发起人
                        map.put("processType", this.getActivitiService().getTemplateName(processInfo.get("definitionInfoId").toString()));//流程类型
                        map.put("createDate", processInfo.get("createDate").toString());//流程创建时间
                        map.put("taskId", task.getId());//任务id
                        map.put("taskName", task.getName());//任务名称
                        map.put("executionId", task.getExecutionId());//执行id
                        Map<String, Object> variables = this.getActivitiService().getExecutionVariables(task.getExecutionId());
                        map.put("variables", JSONObject.fromObject(variables).toString());//流程变量
                        map.put("businessKey", (String) processInfo.get("businessKey"));//业务键
                        jsonObject = JSONObject.fromObject(task.getDescription());
    
                        if (processInfo.get("taskUrl") != null) {
                            map.put("taskUrl", processInfo.get("taskUrl").toString());
                        } else {
                            map.put("taskUrl", jsonObject.get("taskUrl").toString());//处理taskUrl
                        }
    
                        map.put("documentation", jsonObject.get("documentation").toString());//任务备注
    
                        list.add(map);
                    }
                    Collections.sort(list, new Comparator<Map<String, String>>() {
                        @Override
                        public int compare(Map<String, String> o1, Map<String, String> o2) {
                            Date date1 = DateUtil.stringToDate(o1.get("createDate").toString(), SystemConstant.TIME_PATTEN);
                            Date date2 = DateUtil.stringToDate(o2.get("createDate").toString(), SystemConstant.TIME_PATTEN);
                            if (date1.after(date2)) {
                                return -1;
                            } else {
                                return 1;
                            }
                        }
                    });
                    listVo.setList(list);
                    listVo.setTotalSize(taskList.size());
                    this.out(listVo);
                }
            } catch (Exception e) {
                e.printStackTrace();
                this.outError("获取任务信息失败!");
            }
        }
    
        @Action(value = "getActivityVariables")
        @SuppressWarnings("unchecked")
        public void getActivityVariables() {
            try {
                HttpServletRequest request = this.getHttpServletRequest();
                String processId = request.getParameter("processId");
                String taskName = request.getParameter("taskName");
                List<Object> list = this.getActivitiService().getProcessLinkVariables(processId, taskName);
                Map<String, Object> processInfo = (Map<String, Object>) this.getActivitiService().getProcessInfoByExecutionId(processId);
                for (Object variable : list) {
                    Map<String, Object> tempMap = (Map<String, Object>) variable;
    
                    tempMap.put("processType", this.getActivitiService().getTemplateName(processInfo.get("definitionInfoId").toString()));//流程类型
                }
                this.out(list);
            } catch (Exception e) {
                e.printStackTrace();
                this.outError("获取任务信息失败!");
            }
        }
    
        @Action(value = "invoke")
        public void invoke() {
            /*Map<String, Object> map = new HashMap<String, Object>();
            map.put("outcome", "pass");
            this.getActivitiService().startProcessInstanceByKey("TaskTest", map);*/
            /*this.getActivitiService().completeTask("4", "4414");*/
            /*Map<String, Object> map = new HashMap<String, Object>();
            map.put("userId", "4");
            Task task = this.getActivitiService().getPersonalTask(map).get(0);
            JSONObject jsonObject = JSONObject.fromObject(task.getDescription());
            System.out.println(jsonObject.get("taskUrl"));
            System.out.println(jsonObject.get("documentation").equals(""));*/
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("userId", "4");
            Task task = this.getActivitiService().getPersonalTask(map).get(0);
    
        }
    
        public File getNewTemplate() {
            return newTemplate;
        }
    
        public void setNewTemplate(File newTemplate) {
            this.newTemplate = newTemplate;
        }
    
        public String getNewTemplateName() {
            return newTemplateName;
        }
    
        public void setNewTemplateName(String newTemplateName) {
            this.newTemplateName = newTemplateName;
        }
    
    }

    以上就是本人对activity的一些封装和测试~

  • 相关阅读:
    php使用cookie来保存用户登录信息
    Linux下进程操作
    TortoiseSVN无法编辑日志信息的解决方法
    用DIV布局制作公告板
    HashMap的遍历
    实现文本滚动
    子DIV块中设置margintop时影响父DIV块位置的解决办法
    php使用session来保存用户登录信息
    javascript jquery ajax动态提交多个参数 api测试 拂晓风起
    javascript 处理返回json中的\u中文乱码问题(也不是乱码了,就是\u编码) 拂晓风起
  • 原文地址:https://www.cnblogs.com/47Gamer/p/13915773.html
Copyright © 2020-2023  润新知