Package com.google.code.lightssh.project.workflow.service

Source Code of com.google.code.lightssh.project.workflow.service.WorkflowManagerImpl

package com.google.code.lightssh.project.workflow.service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.FormData;
import org.activiti.engine.form.StartFormData;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricDetail;
import org.activiti.engine.history.HistoricDetailQuery;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.history.NativeHistoricProcessInstanceQuery;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.query.NativeQuery;
import org.activiti.engine.query.Query;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.NativeTaskQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.google.code.lightssh.common.ApplicationException;
import com.google.code.lightssh.common.model.page.ListPage;
import com.google.code.lightssh.common.model.page.ListPage.OrderType;
import com.google.code.lightssh.common.model.page.OrderBy;
import com.google.code.lightssh.common.util.StringUtil;
import com.google.code.lightssh.project.util.constant.WorkflowConstant;
import com.google.code.lightssh.project.workflow.model.ExecutionType;
import com.google.code.lightssh.project.workflow.model.MyProcess;
import com.google.code.lightssh.project.workflow.model.MyTask;

/**
* 工作流业务实现
*
*/
@Component("workflowManager")
public class WorkflowManagerImpl implements WorkflowManager{

  private static final long serialVersionUID = -263409561222061490L;
 
  private static Logger log = LoggerFactory.getLogger(WorkflowManagerImpl.class);
 
  private static final String SQL_SELECT_COUNT = "SELECT COUNT(1) ";
 
  private static final String SQL_SELECT_DATA = "SELECT * ";
 
  private static String ORACLE_PAGINATION_SQL = " SELECT * FROM ( SELECT A.*, ROWNUM RN FROM ( #{SQL}) A WHERE ROWNUM <= #{row_end} ) WHERE RN >= #{row_start}";
 
  @Resource(name="runtimeService")
  private RuntimeService runtimeService;
 
  @Resource(name="taskService")
  private TaskService taskService;
 
  @Resource(name="repositoryService")
  private RepositoryService repositoryService;
 
  @Resource(name="identityService")
  private IdentityService identityService;
 
  @Resource(name="historyService")
  private HistoryService historyService;
 
  @Resource(name="formService")
  private FormService formService;
 
  @Resource(name="managementService")
  private ManagementService managementService;
 
  @Resource(name="taskLogManager")
  private TaskLogManager taskLogManager;
 
  @Resource(name="processAttributeManager")
  private ProcessAttributeManager processAttributeManager;
 
  /**
   * 本地查询
   * TODO 考虑其它数据库
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  protected ListPage<?> query(String from_sql,NativeQuery query, ListPage<?> page ){
    if( page == null )
      page = new ListPage();
   
    //TODO 只实现oracle,待完善
    String pagenation_sql = ORACLE_PAGINATION_SQL.replace("#{SQL}"
        ,SQL_SELECT_DATA + from_sql + addOrderBy(page));
   
    int count = (int)query.sql( SQL_SELECT_COUNT + from_sql.toString() ).count();
    int start = page.getStart();
    if( page.getStart() > count ){
      start = (page.getAllPage()-1)*page.getSize()
        + ((count>page.getSize())?((count%page.getSize())-1):0);
      page.setNumber( page.getAllPage() );
    }
   
    query.parameter("row_start", start );
    query.parameter("row_end", page.getEnd() - 1 );
   
    page.setAllSize( count  );
    page.setList( query.sql( pagenation_sql ).list() );
   
    return page;
  }
 
  protected String addOrderBy( ListPage<?> page ){
    //add order
    StringBuffer orderby = new StringBuffer("");
    List<OrderBy> orderByList = page.listAllOrderBy();
    if( orderByList != null && !orderByList.isEmpty() ){
      for(OrderBy each:orderByList ){
        if( each == null )
          continue;
        orderby.append("".equals(orderby.toString())?" ORDER BY ":" ,");
        orderby.append( " " + each.getProperty()
          + (OrderType.ASCENDING.equals( each.getType() )?" ASC ":" DESC ") );
      }
    }
   
    return orderby.toString();
  }
 
  /**
   * 查询
   */
  @SuppressWarnings({ "unchecked", "rawtypes" })
  protected ListPage<?> query(Query query, ListPage<?> page ){
    if( page == null )
      page = new ListPage();
   
    OrderBy orderBy = page.getOrderBy();
    if( orderBy != null ){
      if( ListPage.OrderType.DESCENDING.equals(orderBy.getType()) )
        query.desc();
      else
        query.asc();
    }
   
    int count = (int)query.count();
    page.setAllSize(count);
    int start = page.getStart()-1;
    if( start > count ){
      start = (page.getAllPage()-1)*page.getSize()
        + ((count>page.getSize())?((count%page.getSize())-1):0);
      page.setNumber( page.getAllPage() );
    }
   
    page.setList( query.listPage(start,page.getSize()) );
   
    return page;
  }
 
  /**
   * 查询部署信息
   */
  @SuppressWarnings("unchecked")
  public ListPage<Deployment> listDeployment( ListPage<Deployment> page ){
    if( page == null )
      page = new ListPage<Deployment>();
   
    DeploymentQuery query = repositoryService.createDeploymentQuery();
   
    OrderBy orderBy = page.getOrderBy();
    if( orderBy != null ){
      if( "id".equals(orderBy.getProperty()) )
        query.orderByDeploymentId();
      else if( "deploymentTime".equals(orderBy.getProperty()) )
        query.orderByDeploymenTime();
      else if( "name".equals(orderBy.getProperty()) )
        query.orderByDeploymentName();
    }
   
    return (ListPage<Deployment>)query(query,page);
  }
 
  /**
   * 部署流程
   */
  public void deploy( String resourceName,InputStream inputStream){
    repositoryService.createDeployment()
      .addInputStream(resourceName, inputStream)
      .enableDuplicateFiltering()
      .name( "lightssh" ).deploy();
  }
 
  /**
   * 取消部署
   */
  public void undeploy( String deploymentId ){
    this.repositoryService.deleteDeployment(deploymentId,true);
  }
 
  /**
   * 查询流程定义
   */
  @SuppressWarnings("unchecked")
  public ListPage<ProcessDefinition> listProcessDefinition( ListPage<ProcessDefinition> page ){
    if( page == null )
      page = new ListPage<ProcessDefinition>();
   
    ProcessDefinitionQuery query = repositoryService
      .createProcessDefinitionQuery().latestVersion();
   
    OrderBy orderBy = page.getOrderBy();
    if( orderBy != null ){
      if( "name".equals(orderBy.getProperty()) )
        query.orderByProcessDefinitionName();
      else if( "key".equals(orderBy.getProperty()) )
        query.orderByProcessDefinitionKey();
      else if( "id".equals(orderBy.getProperty()) )
        query.orderByProcessDefinitionId();
      else if( "category".equals(orderBy.getProperty()) )
        query.orderByProcessDefinitionCategory();
      else if( "version".equals(orderBy.getProperty()) )
        query.orderByProcessDefinitionVersion();
      else if( "deploymentId".equals(orderBy.getProperty()) )
        query.orderByDeploymentId();
    }
   
    return (ListPage<ProcessDefinition>)query(query,page);
  }
 
  /**
   * 查询流程定义
   * @param ID 流程定义Id
   */
  public ProcessDefinition getProcessDefinition( String id ){
    ProcessDefinitionQuery query = repositoryService
        .createProcessDefinitionQuery();
   
    query.processDefinitionId(id);
   
    return query.singleResult();
  }

  /**
   * 获取BpmnModel 通过流程定义ID
   */
  public BpmnModel getBpmnModel(String procDefId ){
    return repositoryService.getBpmnModel(procDefId);
  }
 
  /**
   * 根据流程实例ID查询活动的Activity ID
   */
  public List<String> getActiveActivityIds(String procInstId ){
    return this.runtimeService.getActiveActivityIds( procInstId );
  }
 
  /**
   * 根据流程实例ID查询结束的Activity ID
   */
  public List<String> getHighLightedFlows(String procInstId ){
    //流程实例
    HistoricProcessInstance procInst = this.getProcessHistory(procInstId);
    if( procInst == null )
      return null;
   
    //流程定义
    ProcessDefinitionEntity procDef = (ProcessDefinitionEntity)
        ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition( procInst.getProcessDefinitionId() );
    if( procDef == null )
      return null;
   
    List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
        .processInstanceId(procInstId)
        .orderByHistoricActivityInstanceStartTime().asc()
        .list();
   
    Map<String,HistoricActivityInstance> haiMap = new HashMap<String,HistoricActivityInstance>();
    for (HistoricActivityInstance hai : haiList) {
      haiMap.put(hai.getActivityId(),hai);
    }
   
    return getHighLightedFlows(haiMap,procDef.getActivities() );
  }
 
  /**
   * 获取高亮流程节点
   */
  protected List<String> getHighLightedFlows(Map<String,HistoricActivityInstance> haiMap,List<ActivityImpl> activities ){
    if( activities == null || activities.isEmpty()
        || haiMap == null || haiMap.isEmpty() )
      return null;
   
    List<String> results = new ArrayList<String>();
   
    for(ActivityImpl item:activities){
      Object type = item.getProperty("type");
      if( type.equals("subProcess") ){
        List<String> subs = getHighLightedFlows(haiMap,item.getActivities() );
        if( subs != null && !subs.isEmpty() )
          results.addAll(subs);
      }
     
      String srcId = item.getId();
      if( haiMap.containsKey( srcId ) ){
        List<PvmTransition> pvmTrans = item.getOutgoingTransitions(); //某个节点出来的所有线路
        if( pvmTrans == null || pvmTrans.isEmpty() )
          continue;
       
        for( PvmTransition pvm:pvmTrans){
          String destFlowId = pvm.getDestination().getId();
          if( haiMap.containsKey( destFlowId ) ){
            //判断进入了哪个节点
                      if ("exclusiveGateway".equals( type )){
                        //TODO 待实现
                      }else{
                        results.add( pvm.getId() );
                      }
          }
        }
      }//end if
    }
   
    return results;
  }
 
  /**
   * 查询流程实例
   */
  @SuppressWarnings("unchecked")
  public ListPage<ProcessInstance> listProcessInstance( ListPage<ProcessInstance> page ){
    if( page == null )
      page = new ListPage<ProcessInstance>();
   
    ProcessInstanceQuery query = runtimeService
      .createProcessInstanceQuery();
   
    OrderBy orderBy = page.getOrderBy();
    if( orderBy != null ){
      if( "businessKey".equals(orderBy.getProperty()) )
        query.orderByProcessDefinitionKey();
      else if( "processDefinitionId".equals(orderBy.getProperty()) )
        query.orderByProcessDefinitionId();
      else if( "processInstanceId".equals(orderBy.getProperty()) )
        query.orderByProcessInstanceId();
    }
   
    return (ListPage<ProcessInstance>)query(query,page);
  }
 
  /**
   * 查询流程实例
   */
  public ProcessInstance getProcessInstance( String id ){
    ProcessInstanceQuery query = runtimeService
      .createProcessInstanceQuery();
   
    query.processInstanceId(id);
   
    return query.singleResult();
  }
 
  /**
   * 历史流程实例
   */
  public HistoricProcessInstance getProcessHistory(String procId ){
    if( StringUtils.isEmpty(procId) )
      return null;
   
    return historyService.createHistoricProcessInstanceQuery()
        .processInstanceId(procId).singleResult();
  }
 
  /**
   * 查询与我相关的流程
   */
  @SuppressWarnings("unchecked")
  public ListPage<HistoricProcessInstance> listProcess(MyProcess process,ListPage<HistoricProcessInstance> page ){
    if( page == null )
      page = new ListPage<HistoricProcessInstance>();
   
    NativeHistoricProcessInstanceQuery query = historyService.createNativeHistoricProcessInstanceQuery();
    StringBuffer sql = new StringBuffer(" FROM " + managementService.getTableName(HistoricProcessInstance.class) + " t where 1=1 ");
    if( process != null ){
     
      //流程实例ID
      if( StringUtils.isNotEmpty(process.getProcessInstanceId()) ){
        sql.append(" AND t.PROC_INST_ID_ = #{proc_inst_id}");
        query.parameter("proc_inst_id", process.getProcessInstanceId().trim());
      }
     
      //流程属性名称
      if( StringUtils.isNotEmpty(process.getProcessAttributeName()) ){
        sql.append(" AND t.PROC_INST_ID_ IN ( ");
        sql.append(" SELECT DISTINCT ACT_PROC_INST_ID FROM T_FLOW_PROCESS_ATTR ");
        sql.append(" WHERE BIZ_NAME LIKE #{proc_attr_name} )");
        query.parameter("proc_attr_name", "%"+process.getProcessAttributeName().trim()+"%");
      }
     
      //流程类型ID
      if( StringUtils.isNotEmpty(process.getProcessDefinitionId()) ){
        sql.append(" AND t.PROC_DEF_ID_ = #{proc_def_id}");
        query.parameter("proc_def_id", process.getProcessDefinitionId().trim());
      }
     
      //流程类型Key
      if( StringUtils.isNotEmpty(process.getProcessDefinitionKey()) ){
        sql.append(" AND t.PROC_DEF_ID_ IN ( ");
        sql.append(" SELECT DISTINCT ID_ FROM ");
        sql.append( managementService.getTableName( ProcessDefinition.class) );
        sql.append(" WHERE KEY_ = #{proc_def_key} )");
        query.parameter("proc_def_key", process.getProcessDefinitionKey().trim());
      }
     
      boolean includeOwner = StringUtils.isNotEmpty(process.getOwner());
      String assignee = process.getAssignee()==null?null:process.getAssignee().trim();
      String owner = process.getOwner()==null?null:process.getOwner().trim();
     
      //与“操作人”相关的流水
      if( StringUtils.isNotEmpty( assignee ) &&
          !assignee.equals( owner ) ){ //优化,与owner相同时,不执行子查询
        sql.append( " AND ( t.PROC_INST_ID_ IN( SELECT DISTINCT PROC_INST_ID_ FROM ");
        sql.append( managementService.getTableName(HistoricTaskInstance.class) );
        sql.append(" WHERE ASSIGNEE_ = #{assignee}");
       
        sql.append( " ) "+(includeOwner?" ":" OR t.START_USER_ID_ = #{owner} " )+")" );
        if(!includeOwner)
          query.parameter("owner", assignee);
       
        query.parameter("assignee", assignee);
      }
     
      //流程创建者
      if( includeOwner ){
        sql.append(" AND t.START_USER_ID_ = #{owner}");
        query.parameter("owner", owner );
      }
     
      //是否完成
      if( process.getFinish() != null ){
        if( process.getFinish() )
          sql.append(" AND t.END_TIME_ IS NOT NULL ");
        else
          sql.append(" AND t.END_TIME_ IS NULL ");
      }
     
      //流程开始时间
      if( process.getStartPeriod() != null ){
        Date start = process.getStartPeriod().getStart();
        Date end = process.getStartPeriod().getEnd();
       
        if( start != null ){
          sql.append(" AND t.START_TIME_ >= #{st_start} ");
          query.parameter("st_start", start);
        }
       
        if( end != null ){
          Calendar cal_end = Calendar.getInstance();
          cal_end.setTime(end);
          cal_end.add(Calendar.DAY_OF_MONTH, 1);
          cal_end.add(Calendar.SECOND, -1);
         
          sql.append(" AND t.START_TIME_ <= #{st_end} ");
          query.parameter("st_end", cal_end.getTime());
        }
      }
    }
   
    if( page.getOrderByList() != null && !page.getOrderByList().isEmpty() ){
     
    }
   
    //page.setAllSize( (int)query.sql( SQL_SELECT_COUNT + sql.toString() ).count() );
    //page.setList( query.sql( SQL_SELECT + sql.toString() ).list() );
   
    return (ListPage<HistoricProcessInstance>) query(sql.toString(),query,page);
  }
 
  /**
   * 启动流程
   * @param processKey 流程key
   */
  public ProcessInstance start( String processKey){
    return runtimeService.startProcessInstanceByKey( processKey );
  }
 
  /**
   * 启动流程
   * @param procDefKey 流程定义key
   * @param bizKey 业务key
   * @param bizName 业务名称
   * @param userId 用户ID
   */
  public ProcessInstance start( String procDefKey,String bizKey,String bizName
      ,String userId,Map<String,Object> variables){
   
    if( StringUtils.isEmpty(bizKey) )
      throw new ApplicationException("业务关键字(bizKey)为空!");
   
    //用来设置启动流程的人员ID,引擎会自动把用户ID保存到activiti:initiator中
    if( !StringUtils.isEmpty(userId) )
      identityService.setAuthenticatedUserId(userId);
   
    ProcessInstance procInst = runtimeService.startProcessInstanceByKey(
        procDefKey,bizKey,variables );
   
    if( StringUtils.isNotEmpty(bizName) ){
      processAttributeManager.save(procDefKey,procInst.getId()
          ,bizKey, bizName, userId);//TODO保存流程属性
     
      log.debug("保存流程属性:ProcDefKey[{}],BizKey[{}],BizName[{}]"
          ,new Object[]{procDefKey,bizKey,bizName});
    }
   
    //保存操作日志
    taskLogManager.save(procInst.getId()
        ,procInst.getActivityId(),ExecutionType.SUBMIT,userId,"启动流程");
     
    return procInst;
  }
 
  /**
   * 查询任务
   */
  public Task getTask( String taskId ){
    return taskService.createTaskQuery().taskId(taskId).singleResult();
  }
 
  /**
   * 查询流程中活动的任务
   */
  @SuppressWarnings("unchecked")
  public ListPage<HistoricTaskInstance> listHistoricTask(
      MyTask task,ListPage<HistoricTaskInstance> page){
    if( page == null )
      page = new ListPage<HistoricTaskInstance>();
   
    HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery();
    if( task != null ){
      //流程实例ID
      if( StringUtils.isNotEmpty(task.getProcessInstanceId()) ){
        query.processInstanceId(task.getProcessInstanceId().trim());
      }
     
      //流程定义ID
      if( StringUtils.isNotEmpty(task.getProcessDefinitionId()) ){
        query.processDefinitionId(task.getProcessDefinitionId().trim());
      }
     
      //签收人
      if( !StringUtils.isEmpty(task.getAssignee()) )
        query.taskAssignee(task.getAssignee());
     
      //任务是否完成
      if( task.getFinish() != null ){
        if( task.getFinish() )
          query.finished();
        else
          query.unfinished();
      }
    }
   
    return (ListPage<HistoricTaskInstance>) query(query,page);
  }
 
  /**
   * 查询流程中活动的任务
   */
  public List<Task> listTaskByProcessId( String processId ){
    TaskQuery query = taskService.createTaskQuery();
    query.active();
    query.processInstanceId(processId);
   
    return query.list();
  }
 
  /**
   * 当前活动Task
   * @param processId 流程实例ID
   */
  protected Task getCurrentTask( String processId ){
    TaskQuery query = taskService.createTaskQuery();
    query.active();
    query.processInstanceId(processId).listPage(0,1);
   
    return query.singleResult();
  }
 
  /**
   * 查询任务
   */
  @SuppressWarnings("unchecked")
  public ListPage<Task> listTask(MyTask task, ListPage<Task> page ){
    if( page == null )
      page = new ListPage<Task>();
   
    NativeTaskQuery query = taskService.createNativeTaskQuery();
    StringBuffer sql = new StringBuffer(" FROM " + managementService.getTableName(Task.class) + " t ");
   
    if( task != null ){
      //连接T_ACT_RU_IDENTITYLINK
      if( StringUtils.isNotEmpty(task.getCandidateUser()) ){
        sql.append(" INNER JOIN T_ACT_RU_IDENTITYLINK i on i.TASK_ID_ = t.ID_ ");
        sql.append(" ");
      }
    }
   
    sql.append(" WHERE 1=1 ");
   
    if( task != null ){
      //任务候选者
      if( StringUtils.isNotEmpty(task.getCandidateUser()) ){
        sql.append(" AND t.ASSIGNEE_ IS NULL "); //未签收
        sql.append(" AND i.TYPE_ = 'candidate'");
        sql.append(" AND i.USER_ID_ = #{candidate_user}");
        query.parameter("candidate_user", task.getCandidateUser().trim());
      }
     
      //任务签收人
      if( StringUtils.isNotEmpty(task.getAssignee()) ){
        sql.append(" AND t.ASSIGNEE_ = #{assignee}");
        query.parameter("assignee", task.getAssignee().trim());
      }
     
      //任务拥有者
      if( StringUtils.isNotEmpty(task.getOwner()) ){
        sql.append(" AND t.OWNER_ = #{owner}");
        query.parameter("owner", task.getOwner().trim());
      }
     
      //任务到达时间
      if( task.getStartPeriod() != null ){
        Date start = task.getStartPeriod().getStart();
        Date end = task.getStartPeriod().getEnd();
       
        if( start != null ){
          sql.append(" AND t.CREATE_TIME_ >= #{st_start} ");
          query.parameter("st_start", start);
        }
       
        if( end != null ){
          Calendar cal_end = Calendar.getInstance();
          cal_end.setTime(end);
          cal_end.add(Calendar.DAY_OF_MONTH, 1);
          cal_end.add(Calendar.SECOND, -1);
         
          sql.append(" AND t.CREATE_TIME_ <= #{st_end} ");
          query.parameter("st_end", cal_end.getTime());
        }
      }
     
      //流程
      if( StringUtils.isNotEmpty(task.getProcInstStartUser())
          || task.getProcStartPeriod() != null ){
        sql.append(" AND t.PROC_INST_ID_ IN ( "); //start in
        sql.append(" SELECT PROC_INST_ID_ FROM ");
        sql.append( managementService.getTableName(HistoricProcessInstance.class) );
        sql.append(" WHERE 1=1 ");
       
        //流程创建人
        if( StringUtils.isNotEmpty(task.getProcInstStartUser() ) ){
          sql.append(" AND START_USER_ID_ = #{proc_inst_owner} ");
          query.parameter("proc_inst_owner", task.getProcInstStartUser() );
        }
       
        //流程开始时间
        if( task.getProcStartPeriod() != null ){
          Date start = task.getProcStartPeriod() .getStart();
          Date end = task.getProcStartPeriod() .getEnd();
         
          if( start != null ){
            sql.append(" AND START_TIME_ >= #{proc_st_start} ");
            query.parameter("proc_st_start", start);
          }
         
          if( end != null ){
            Calendar cal_end = Calendar.getInstance();
            cal_end.setTime(end);
            cal_end.add(Calendar.DAY_OF_MONTH, 1);
            cal_end.add(Calendar.SECOND, -1);
           
            sql.append(" AND START_TIME_ <= #{proc_st_end} ");
            query.parameter("proc_st_end", cal_end.getTime());
          }
        }
       
        sql.append(" ) "); //end in
      }
     
      //流程实例编号
      if( StringUtils.isNotEmpty(task.getProcessInstanceId()) ){
        sql.append(" AND t.PROC_INST_ID_ = #{proc_inst_id}");
        query.parameter("proc_inst_id", task.getProcessInstanceId().trim());
      }
     
      //流程属性名称
      if( StringUtils.isNotEmpty(task.getProcessAttributeName()) ){
        sql.append(" AND t.PROC_INST_ID_ IN ( ");
        sql.append(" SELECT DISTINCT ACT_PROC_INST_ID FROM T_FLOW_PROCESS_ATTR ");
        sql.append(" WHERE BIZ_NAME LIKE #{proc_attr_name} )");
        query.parameter("proc_attr_name", "%"+task.getProcessAttributeName().trim()+"%");
      }
     
      //流程类型Key
      if( StringUtils.isNotEmpty(task.getProcessDefinitionKey()) ){
        sql.append(" AND t.PROC_DEF_ID_ IN ( ");
        sql.append(" SELECT DISTINCT ID_ FROM ");
        sql.append( managementService.getTableName( ProcessDefinition.class) );
        sql.append(" WHERE KEY_ = #{proc_def_key} )");
        query.parameter("proc_def_key", task.getProcessDefinitionKey().trim());
      }
     
    }
   
    return (ListPage<Task>) query(sql.toString(),query,page);
  }
 
  /**
   * 查询历史任务
   */
  @SuppressWarnings("unchecked")
  public ListPage<HistoricTaskInstance> listHistoryTask( ListPage<HistoricTaskInstance> page ){
    if( page == null )
      page = new ListPage<HistoricTaskInstance>();
   
    HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery();
   
    query.finished(); //已完成任务
   
    OrderBy orderBy = page.getOrderBy();
    if( orderBy != null ){
      if( "endTime".equals(orderBy.getProperty()) )
        query.orderByHistoricTaskInstanceEndTime();
      else if( "startTime".equals(orderBy.getProperty()) )
        query.orderByHistoricTaskInstanceStartTime();
    }
   
    return (ListPage<HistoricTaskInstance>)query(query,page);
  }
 
  /**
   * 查询流程的上一执行任务
   * @param processInstanceId 流程实例
   */
  @SuppressWarnings("unchecked")
  public HistoricTaskInstance getLastTask(String processInstanceId){
    ListPage<HistoricTaskInstance> page = new ListPage<HistoricTaskInstance>(1);
    HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery();
    query.finished(); //已完成任务
    query.processInstanceId(processInstanceId);
    query.orderByHistoricTaskInstanceEndTime().desc();
   
    return ((ListPage<HistoricTaskInstance>)query(query,page)).getFirst();
  }
 
  /**
   * 查询任务之前表单数据
   */
  public List<HistoricDetail> listHistoricDetail( String taskId ){
    Task task = this.getTask(taskId);
    if( task == null )
      return null;
   
    List<HistoricTaskInstance> historyTaskList = historyService.createHistoricTaskInstanceQuery()
      .processInstanceId(task.getProcessInstanceId())
      .finished()
      .orderByTaskId().desc()
      .listPage(0,1);
   
    if( historyTaskList == null || historyTaskList.isEmpty() )
      return null;
    HistoricTaskInstance historyTask = historyTaskList.get(0);
   
    HistoricDetailQuery query = historyService.createHistoricDetailQuery().formProperties();
    query.taskId( historyTask.getId() );
   
    return query.list();
  }
 
  /**
   * 认领流程
   */
  public void claim( String taskId,String userId ){
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    if( task == null )
      throw new ApplicationException("任务["+taskId+"]不存在!");
   
    if( StringUtil.hasText( task.getAssignee() ) )
      throw new ApplicationException("任务["+taskId+"]已被用户["+task.getAssignee()+"]认领!");
   
    this.taskLogManager.save(task.getProcessInstanceId(),task.getId()
        ,ExecutionType.CLAIM, userId, "用户["+userId+"]签收任务");
   
    taskService.claim(taskId, userId);
  }
 
  /**
   * 认领并提交当前活动的流程
   * @param procInstId 流程实例ID
   * @param operator 操作人
   */
  public void claimAndComplete(String procInstId,String operator){
    if( StringUtils.isEmpty(operator) )
      throw new ApplicationException("操作人不能为空!");
   
    Task task = this.getCurrentTask( procInstId );
   
    if( task == null )
      throw new ApplicationException("无法获取活动的任务[流程实例ID="+procInstId+"]");
   
    taskService.claim( task.getId(), operator );
    taskService.complete(task.getId());
  }
 
  /**
   * 变更认领人
   */
  public void changeAssignee( String taskId,String userId ){
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    if( task == null )
      throw new ApplicationException("任务["+taskId+"]不存在!");
   
    taskService.setAssignee(taskId, userId);
  }
 
  /**
   * 添加会签人
   */
  @Deprecated
  public void addAssignee( String taskId,List<String> userIds ){
    if( userIds == null || userIds.isEmpty() )
      throw new ApplicationException("添加的会签人不能为空!");
   
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    if( task == null )
      throw new ApplicationException("任务["+taskId+"]不存在!");
   
    if( StringUtils.isNotEmpty(task.getParentTaskId()) )
      throw new ApplicationException("任务["+task.getName()+"]已是会签任务!");
   
    //taskService.
   
    for( String user:userIds ){
      TaskEntity newTask = (TaskEntity) taskService.newTask(); //TODO 更改ID规则
     
      newTask.setAssignee(user)
      newTask.setName( task.getName() + "-[会签]")
      newTask.setProcessDefinitionId(task.getProcessDefinitionId())
      newTask.setProcessInstanceId(task.getProcessInstanceId() )
      newTask.setParentTaskId(taskId)
      newTask.setDescription( task.getName() + "-添加会签人["+user+"]")
            taskService.saveTask(newTask);
    }
  }
 
  /**
   * 完成任务
   */
  public void complete( String taskId ){
    taskService.complete(taskId);
  }
 
  /**
   * 完成任务
   */
  public void complete( MyTask myTask,String user ){
    if( myTask == null || StringUtils.isEmpty(user) )
      throw new ApplicationException("参数为空!");
   
    String taskId = myTask.getId();
    if( StringUtils.isEmpty(taskId) )
      throw new ApplicationException("任务编号不能为空!");
   
    ExecutionType type = myTask.getType();
    if( type == null )
      throw new ApplicationException("任务操作类型不能为空!");
   
    String message = myTask.getMessage();
    if( StringUtils.isEmpty(message)  )
      throw new ApplicationException("流转意见不能为空!");
   
    Task task = taskService.createTaskQuery().taskId(myTask.getId()).singleResult();
    if( task == null )
      throw new ApplicationException("任务["+myTask.getId()+"]不存在!");
   
    //task.getParentTaskId();
    //identityService.setAuthenticatedUserId( user );
   
    //保存操作日志
    taskLogManager.save(task.getProcessInstanceId(),task.getId(),type,user, message);
   
    Map<String,Object> variables = new HashMap<String,Object>();
    variables.put(WorkflowConstant.TASK_ACTIOIN_VARIABLE_NAME,type.name());
    variables.put("passed", ExecutionType.SUBMIT.equals(type)); //TODO
   
    taskService.complete(taskId,variables); //提交
  }
 
  /**
   * 终止流程
   */
  public void terminate( String procInstId,String user,String reason ){
    //保存操作日志
    taskLogManager.save(procInstId,procInstId,ExecutionType.TERMINATE,user, reason);
    this.runtimeService.deleteProcessInstance(procInstId, reason);
  }
 
  /**
   * 流程注释
   */
  public List<Comment> getProcessInstanceComments(String processInstanceId){
    return taskService.getProcessInstanceComments(processInstanceId);
  }
 
  /**
   * 任务注释
   */
  public List<Comment> getTaskComments(String taskId){
    return taskService.getTaskComments(taskId);
  }
 
  /**
   * 提交数据
   */
  public ProcessInstance submitStartFormData(String processDefinitionId,String businessKey,Map<String,String> properties  ){
    return formService.submitStartFormData(processDefinitionId,businessKey,properties);
  }
 
  /**
   * 提交数据
   */
  public void submitFormData(String taskId,Map<String,String> properties ){
    this.formService.submitTaskFormData(taskId, properties);
  }
 
  /**
   * 任务表单数据
   */
  public TaskFormData getTaskFormData(String taskId ){
    return formService.getTaskFormData(taskId);
  }
 
  /**
   * 开始事件表单数据
   */
  public StartFormData getStartFormData(String processDefinitionId ){
    return formService.getStartFormData(processDefinitionId);
  }
 
  /**
   * 表单数据
   * @param id 流程类型ID 或  任务ID
   * @return FormData
   */
  public FormData getFormData(String id ){
    HistoricTaskInstance task = historyService
      .createHistoricTaskInstanceQuery().taskId(id).singleResult();
    if( task != null )
      return getTaskFormData(id);
    return getStartFormData(id);
  }
 
  /**
     * 流程转向操作
     * 
     * @param task Task 当前任务
     * @param targetActivityId 目标节点任务ID
     * @param variables 流程变量
     */ 
    protected void turnTransition(ExecutionType type,String user,Task task
        ,HistoricTaskInstance histTask, Map<String, Object> variables){ 
     
    if( task == null || !(task instanceof TaskEntity))
      throw new ApplicationException("当前任务为空或类型不正确!");
   
        // 当前节点 
        ActivityImpl currActivity = getActivityImpl(task, null)
        // 清空当前流向 
        List<PvmTransition> oriPvmTransitionList = clearTransition(currActivity)
 
        // 创建新流向 
        TransitionImpl newTransition = currActivity.createOutgoingTransition()
        // 目标节点 
        ActivityImpl targetActivity = getActivityImpl(task, histTask.getTaskDefinitionKey())
        // 设置新流向的目标节点 
        newTransition.setDestination( targetActivity )
 
        // 执行转向任务 
        taskService.complete(task.getId(), variables)
        //获取新Task
        Task newTask = getCurrentTask( task.getProcessInstanceId() );
        if( newTask != null ){
          //新任务从流程定义恢复,原签收人从历史任务中得到
          taskService.claim(newTask.getId(), histTask.getAssignee() );
        }
        // 删除目标节点新流入 
        targetActivity.getIncomingTransitions().remove(newTransition)
 
        // 还原以前流向 
        restoreTransition(currActivity, oriPvmTransitionList)
       
        //保存操作日志
        String message = "流程转向:"+task.getName()+"-->"+histTask.getName();
        taskLogManager.save(task.getProcessInstanceId(),task.getId(),type,user, message);
   
   
    /**
     * 还原指定活动节点流向
     * 
     * @param activityImpl 活动节点
     * @param oriPvmTransitionList 原有节点流向集合
     */ 
    private void restoreTransition(ActivityImpl activityImpl, 
            List<PvmTransition> oriPvmTransitionList) { 
        // 清空现有流向 
        List<PvmTransition> pvmTransitionList = activityImpl.getOutgoingTransitions()
        pvmTransitionList.clear()
       
        // 还原以前流向 
        for (PvmTransition pvmTransition : oriPvmTransitionList) { 
            pvmTransitionList.add(pvmTransition)
       
    }
   
    /**
     * 活动节点
     */
    protected ActivityImpl getActivityImpl(Task task, String activityId ){
      if( task == null )
        return null;
     
      if( StringUtils.isEmpty(activityId) )
        activityId = task.getTaskDefinitionKey();
     
      //流程定义
    ProcessDefinitionEntity processDef = (ProcessDefinitionEntity)
        ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition( task.getProcessDefinitionId()  );
    if( processDef == null )
      return null;
   
    return ((ProcessDefinitionImpl)processDef).findActivity(activityId);
    }
   
    /**
     * 清空指定活动节点流向
     * 
     * @param activityImpl 活动节点
     * @return 节点流向集合
     */ 
    protected List<PvmTransition> clearTransition(ActivityImpl activityImpl) { 
        // 存储当前节点所有流向临时变量 
        List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();
       
        // 获取当前节点所有流向,存储到临时变量,然后清空 
        List<PvmTransition> pvmTransitionList = activityImpl.getOutgoingTransitions()
        for (PvmTransition pvmTransition : pvmTransitionList)
            oriPvmTransitionList.add(pvmTransition)
       
        pvmTransitionList.clear()
 
        return oriPvmTransitionList; 
   
 
  /**
   * 回退到上一步
   * @param procInstId 流程实例ID
   */
  public void undoTask( String procInstId,String user){
   
    List<Task> activeTasks = taskService.createTaskQuery()
        .processInstanceId(procInstId).active().list();
    if( activeTasks == null || activeTasks.size() != 1 )
      throw new ApplicationException("流程活动任务不存在或存在多个,无法回退!");
   
    Task task = activeTasks.get(0); //当前任务节点
    if( task == null )
      throw new ApplicationException("无法获取当前任务,无法回退!");
   
    List<HistoricTaskInstance> histTaskList = historyService
        .createHistoricTaskInstanceQuery().finished()
        .orderByHistoricTaskInstanceEndTime().desc()
        .listPage(0, 1);
    HistoricTaskInstance histTask = (histTaskList==null
        ||histTaskList.isEmpty())?null:histTaskList.get(0);
   
    if( histTask == null )
      throw new ApplicationException("历史任务不存在,无法回退!");
   
    if( histTask.getAssignee() == null || !histTask.getAssignee().equals(user) )
      throw new ApplicationException("其它操作用户已完成了新任务,无法回退!");
   
    //流程转向
    turnTransition(ExecutionType.FALLBACK,user,task,histTask,null);
  }
 
  /**
   * 会签
   * @param operator 操作人
   * @param taskId 任务ID
   * @param users 会签用户
   */
  public void countersignTask(String operator,String taskId,String[] users){
    if( StringUtils.isEmpty(taskId) )
      throw new ApplicationException("会签任务ID不能为空!");
   
    if( users == null )
      throw new ApplicationException("会签用户不能为空!");
   
    Task task = getTask(taskId);
    if( task == null )
      throw new ApplicationException("任务ID["+taskId+"]不存在!");
   
    if( StringUtils.isEmpty(operator) ){
      operator = task.getAssignee();
      log.warn("会签操作人为空,使用任务签收人[{}]",task.getAssignee());
    }
   
    StringBuffer message = new StringBuffer("添加会签人[");
    int i = 0;
   
    //对用户不能重复添加会签
    List<Task> subTasks = taskService.getSubTasks(taskId); //子任务
    Map<String,Task> subTaskMap = new HashMap<String,Task>();
    if( subTasks != null && subTasks.size() > 0 ){
      for(Task item: subTasks){
        subTaskMap.put(item.getAssignee(), item);
      }
    }
   
    for( String user:users ){
      if( task.getAssignee().equals(user) )
        throw new ApplicationException("不能添加自己["+user+"]为会签人");
       
      if( subTaskMap.get(user) != null )
        throw new ApplicationException("任务已添加会签人["+user+"]");
     
      TaskEntity subTask = (TaskEntity)taskService.newTask();
      subTask.setParentTaskId(taskId); //上级Task
      subTask.setName( task.getName() + "-["+user+"]会签");
      subTask.setAssignee( user ); //会签用户
      subTask.setProcessDefinitionId( task.getProcessDefinitionId() );
      subTask.setProcessInstanceId( task.getProcessInstanceId() );
      subTask.setDescription("会签");
     
      taskService.saveTask(subTask);
     
      message.append((i==0?"":",") +user);
      ++i;
    }
    message.append("]");
   
    taskLogManager.save(task.getProcessInstanceId(),task.getId()
        ,ExecutionType.SIGN, operator, message.toString());
   
  }
 
}
TOP

Related Classes of com.google.code.lightssh.project.workflow.service.WorkflowManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.