Package com.thinkgem.jeesite.modules.sys.web

Source Code of com.thinkgem.jeesite.modules.sys.web.WorkflowController

package com.thinkgem.jeesite.modules.sys.web;

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

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.workflow.Variable;
import com.thinkgem.jeesite.common.workflow.WorkflowEntity;
import com.thinkgem.jeesite.common.workflow.WorkflowUtils;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.workflow.WorkflowProcessDefinitionService;
import com.thinkgem.jeesite.modules.sys.service.workflow.WorkflowTraceService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;

@Controller
@RequestMapping(value = "${adminPath}/sys/workflow")
public class WorkflowController {

  protected Logger logger = LoggerFactory.getLogger(getClass());
  @Autowired
  protected WorkflowProcessDefinitionService workflowProcessDefinitionService;
  @Autowired
  protected RepositoryService repositoryService;
  @Autowired
  protected RuntimeService runtimeService;
  @Autowired
  protected TaskService taskService;
  @Autowired
  protected WorkflowTraceService traceService;
  protected static Map<String, ProcessDefinition> PROCESS_DEFINITION_CACHE = new HashMap<String, ProcessDefinition>();

  /**
   * 流程定义列表
   *
   * @return
   */
  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "/processList")
  public ModelAndView processList() {
    ModelAndView mav = new ModelAndView("modules/sys/processList");

    /*
     * 保存两个对象,一个是ProcessDefinition(流程定义),一个是Deployment(流程部署)
     */
    List<Object[]> objects = new ArrayList<Object[]>();

    List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().list();
    for (ProcessDefinition processDefinition : processDefinitionList) {
      String deploymentId = processDefinition.getDeploymentId();
      Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
      objects.add(new Object[] { processDefinition, deployment });
    }

    mav.addObject("objects", objects);

    return mav;
  }

  /**
   * 部署全部流程
   *
   * @return
   * @throws Exception
   */
  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "/redeploy/all")
  public String redeployAll() throws Exception {
    workflowProcessDefinitionService.deployAllFromClasspath();
    return "redirect:" + Global.getAdminPath() + "/sys/workflow/processList";
  }

  /**
   * 读取资源,通过部署ID
   *
   * @param deploymentId
   *            流程部署的ID
   * @param resourceName
   *            资源名称(foo.xml|foo.png)
   * @param response
   * @throws Exception
   */
  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "/resource/deployment")
  public void loadByDeployment(@RequestParam("deploymentId") String deploymentId, @RequestParam("resourceName") String resourceName, HttpServletResponse response)
      throws Exception {
    InputStream resourceAsStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
    byte[] b = new byte[1024];
    int len = -1;
    while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
      response.getOutputStream().write(b, 0, len);
    }
  }

  /**
   * 读取资源,通过流程ID
   *
   * @param resourceType
   *            资源类型(xml|image)
   * @param processInstanceId
   *            流程实例ID
   * @param response
   * @throws Exception
   */
  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "/resource/process-instance")
  public void loadByProcessInstance(@RequestParam("type") String resourceType, @RequestParam("pid") String processInstanceId, HttpServletResponse response) throws Exception {
    InputStream resourceAsStream = null;
    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult();
    String resourceName = "";
    if (resourceType.equals("image")) {
      resourceName = processDefinition.getDiagramResourceName();
    } else if (resourceType.equals("xml")) {
      resourceName = processDefinition.getResourceName();
    }
    resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
    byte[] b = new byte[1024];
    int len = -1;
    while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
      response.getOutputStream().write(b, 0, len);
    }
  }

  /**
   * 删除部署的流程,级联删除流程实例
   *
   * @param deploymentId
   *            流程部署ID
   */
  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "/process/delete")
  public String delete(@RequestParam("deploymentId") String deploymentId) {
    repositoryService.deleteDeployment(deploymentId, true);
    return "redirect:" + Global.getAdminPath() + "/sys/workflow/processList";
  }

  /**
   * 输出跟踪流程信息
   *
   * @param processInstanceId
   * @return
   * @throws Exception
   */
  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "/process/trace")
  @ResponseBody
  public List<Map<String, Object>> traceProcess(@RequestParam("pid") String processInstanceId) throws Exception {
    List<Map<String, Object>> activityInfos = traceService.traceProcess(processInstanceId);
    return activityInfos;
  }

  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "/deploy")
  public String deploy(@RequestParam(value = "file", required = false) MultipartFile file) {

    String fileName = file.getOriginalFilename();

    try {
      InputStream fileInputStream = file.getInputStream();

      String extension = FilenameUtils.getExtension(fileName);
      if (extension.equals("zip") || extension.equals("bar")) {
        ZipInputStream zip = new ZipInputStream(fileInputStream);
        repositoryService.createDeployment().addZipInputStream(zip).deploy();
      } else if (extension.equals("png")) {
        repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy();
      } else if (fileName.indexOf("bpmn20.xml") != -1) {
        repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy();
      } else if (extension.equals("bpmn")) {
        /*
         * bpmn扩展名特殊处理,转换为bpmn20.xml
         */
        String baseName = FilenameUtils.getBaseName(fileName);
        repositoryService.createDeployment().addInputStream(baseName + ".bpmn20.xml", fileInputStream).deploy();
      } else {
        throw new ActivitiException("no support file type of " + extension);
      }
    } catch (Exception e) {
      logger.error("error on deploy process, because of file input stream", e);
    }

    return "redirect:" + Global.getAdminPath() + "/sys/workflow/processList";
  }

  /**
   * 待办任务--Portlet
   */
  @RequestMapping(value = "/task/todo/list")
  @ResponseBody
  public List<Map<String, Object>> todoList(HttpSession session) throws Exception {
    User user = UserUtils.getUser();
    String userId = ObjectUtils.toString(user.getId());
    List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");

    // 已经签收的任务
    List<Task> todoList = taskService.createTaskQuery().taskAssignee(userId).active().list();
    for (Task task : todoList) {
      String processDefinitionId = task.getProcessDefinitionId();
      ProcessDefinition processDefinition = getProcessDefinition(processDefinitionId);

      Map<String, Object> singleTask = packageTaskInfo(sdf, task, processDefinition);
      singleTask.put("status", "todo");
      result.add(singleTask);
    }

    // 等待签收的任务
    List<Task> toClaimList = taskService.createTaskQuery().taskCandidateUser(userId).active().list();
    for (Task task : toClaimList) {
      String processDefinitionId = task.getProcessDefinitionId();
      ProcessDefinition processDefinition = getProcessDefinition(processDefinitionId);

      Map<String, Object> singleTask = packageTaskInfo(sdf, task, processDefinition);
      singleTask.put("status", "claim");
      result.add(singleTask);
    }

    return result;
  }

  private Map<String, Object> packageTaskInfo(SimpleDateFormat sdf, Task task, ProcessDefinition processDefinition) {
    Map<String, Object> singleTask = new HashMap<String, Object>();
    singleTask.put("id", task.getId());
    singleTask.put("name", task.getName());
    singleTask.put("createTime", sdf.format(task.getCreateTime()));
    singleTask.put("pdname", processDefinition.getName());
    singleTask.put("pdversion", processDefinition.getVersion());
    singleTask.put("pid", task.getProcessInstanceId());
    return singleTask;
  }

  private ProcessDefinition getProcessDefinition(String processDefinitionId) {
    ProcessDefinition processDefinition = PROCESS_DEFINITION_CACHE.get(processDefinitionId);
    if (processDefinition == null) {
      processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
      PROCESS_DEFINITION_CACHE.put(processDefinitionId, processDefinition);
    }
    return processDefinition;
  }

  /**
   * 挂起、激活流程实例
   */
  @RequiresPermissions("sys:workflow:edit")
  @RequestMapping(value = "processdefinition/update/{state}/{processDefinitionId}")
  public String updateState(@PathVariable("state") String state, @PathVariable("processDefinitionId") String processDefinitionId, RedirectAttributes redirectAttributes) {
    if (state.equals("active")) {
      redirectAttributes.addFlashAttribute("message", "已激活ID为[" + processDefinitionId + "]的流程定义。");
      repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
    } else if (state.equals("suspend")) {
      repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
      redirectAttributes.addFlashAttribute("message", "已挂起ID为[" + processDefinitionId + "]的流程定义。");
    }
    return "redirect:" + Global.getAdminPath() + "/sys/workflow/processList";
  }

  /**
   * 完成任务
   *
   * @param id
   * @return
   */
  @RequestMapping(value = "complete/{id}", method = { RequestMethod.POST, RequestMethod.GET })
  @ResponseBody
  public String complete(@PathVariable("id") String taskId, Variable var) {
    try {
      Map<String, Object> variables = var.getVariableMap();
      taskService.complete(taskId, variables);
      return "success";
    } catch (Exception e) {
      logger.error("error on complete task {}, variables={}", new Object[] { taskId, var.getVariableMap(), e });
      return "error";
    }
  }

  /**
   * 签收任务
   */
  @RequestMapping(value = "claim/{id}")
  @ResponseBody
  public String claim(@PathVariable("id") String taskId, HttpSession session, RedirectAttributes redirectAttributes) {
    String userId = ObjectUtils.toString(UserUtils.getUser().getId());
    taskService.claim(taskId, userId);
    return "success";
  }

  /**
   * 显示流程图
   */
  @RequestMapping(value = "processPic")
  public void processPic(String procDefId, HttpServletResponse response) throws Exception {
    ProcessDefinition procDef = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();
    String diagramResourceName = procDef.getDiagramResourceName();
    InputStream imageStream = repositoryService.getResourceAsStream(procDef.getDeploymentId(), diagramResourceName);
    byte[] b = new byte[1024];
    int len = -1;
    while ((len = imageStream.read(b, 0, 1024)) != -1) {
      response.getOutputStream().write(b, 0, len);
    }
  }

  /**
   * 获取跟踪信息
   */
  @RequestMapping(value = "processMap")
  public String processMap(String processInstanceId, Model model) throws Exception {
    WorkflowEntity  workflowEntity = WorkflowUtils.getWorkflowEntity(processInstanceId);
    String procDefId = workflowEntity.getProcessDefinition().getId();
    List<ActivityImpl> actImpls = new ArrayList<ActivityImpl>();
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();
    ProcessDefinitionImpl pdImpl = (ProcessDefinitionImpl) processDefinition;
    String processDefinitionId = pdImpl.getId();// 流程标识
    ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(processDefinitionId);
    List<ActivityImpl> activitiList = def.getActivities();// 获得当前任务的所有节点
    List<String> activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
    for (String activeId : activeActivityIds) {
      for (ActivityImpl activityImpl : activitiList) {
        String id = activityImpl.getId();
        if (activityImpl.isScope()) {
          if (activityImpl.getActivities().size() > 1) {
            List<ActivityImpl> subAcList = activityImpl.getActivities();
            for (ActivityImpl subActImpl : subAcList) {
              String subid = subActImpl.getId();
              if (activeId.equals(subid)) {// 获得执行到那个节点
                actImpls.add(subActImpl);
                break;
              }
            }
          }
        }
        if (activeId.equals(id)) {// 获得执行到那个节点
          actImpls.add(activityImpl);
          System.out.println(id);
        }
      }
    }
    model.addAttribute("procDefId", procDefId);
    model.addAttribute("proInstId", processInstanceId);
    model.addAttribute("actImpls", actImpls);
    return "modules/sys/processMap";
  }
}
TOP

Related Classes of com.thinkgem.jeesite.modules.sys.web.WorkflowController

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.