package org.jeecg.modules.activiti.controller; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.activiti.bpmn.converter.BpmnXMLConverter; import org.activiti.bpmn.model.BpmnModel; import org.activiti.editor.constants.ModelDataJsonConstants; import org.activiti.editor.language.json.converter.BpmnJsonConverter; import org.activiti.engine.*; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.repository.Deployment; import org.activiti.engine.repository.Model; import org.activiti.engine.repository.ModelQuery; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.activiti.image.ProcessDiagramGenerator; import org.jeecg.common.api.vo.Result; import org.jeecg.common.base.entity.ActZprocess; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.modules.activiti.service.impl.ActZprocessServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; @Controller @RequestMapping("/activiti/models") @Slf4j public class ActivitiModelController { @Autowired private RepositoryService repositoryService; @Autowired private HistoryService historyService; @Autowired private RuntimeService runtimeService; @Autowired private ProcessEngine processEngine; @Autowired private TaskService taskService; @Autowired private ObjectMapper objectMapper; @Autowired private ActZprocessServiceImpl actZprocessService; @RequestMapping("/modelListData") @ResponseBody public Result modelListData( HttpServletRequest request){ log.info("-------------模型列表-------------"); ModelQuery modelQuery = repositoryService.createModelQuery(); String keyWord = request.getParameter("keyWord");//搜索关键字 if (StrUtil.isNotBlank(keyWord)){ modelQuery.modelNameLike("%"+keyWord+"%"); } List models = modelQuery.orderByCreateTime().desc().list(); return Result.ok(models); } @RequestMapping("/create") public void newModel(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException { try { //初始化一个空模型 Model model = repositoryService.newModel(); //设置一些默认信息 int revision = 1; String name = request.getParameter("name"); String description = request.getParameter("description"); String key = request.getParameter("key"); if (StrUtil.isBlank(name)){ name = "new-process"; } if (StrUtil.isBlank(description)){ description = "description"; } if (StrUtil.isBlank(key)){ key = "processKey"; } ObjectNode modelNode = objectMapper.createObjectNode(); modelNode.put(ModelDataJsonConstants.MODEL_NAME, name); modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description); modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision); model.setName(name); model.setKey(key); model.setMetaInfo(modelNode.toString()); repositoryService.saveModel(model); String id = model.getId(); //完善ModelEditorSource ObjectNode editorNode = objectMapper.createObjectNode(); editorNode.put("id", "canvas"); editorNode.put("resourceId", "canvas"); ObjectNode stencilSetNode = objectMapper.createObjectNode(); stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#"); editorNode.put("stencilset", stencilSetNode); repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8")); response.sendRedirect(request.getContextPath() + "/activiti/modeler.html?modelId=" + id); }catch (IOException e){ e.printStackTrace(); log.info("模型创建失败!"); } } @RequestMapping("/delete/{id}") public @ResponseBody Result deleteModel(@PathVariable("id")String id){ repositoryService.deleteModel(id); return Result.ok("删除成功。"); } @RequestMapping("/deployment/{id}") public @ResponseBody Result deploy(@PathVariable("id")String id) { // 获取模型 Model modelData = repositoryService.getModel(id); byte[] bytes = repositoryService.getModelEditorSource(modelData.getId()); if (bytes == null) { return Result.error("模型数据为空,请先成功设计流程并保存"); } try { JsonNode modelNode = new ObjectMapper().readTree(bytes); BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode); if(model.getProcesses().size()==0){ return Result.error("模型不符要求,请至少设计一条主线流程"); } byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model); // 部署发布模型流程 String processName = modelData.getName() + ".bpmn20.xml"; Deployment deployment = repositoryService.createDeployment() .name(modelData.getName()) .addString(processName, new String(bpmnBytes, "UTF-8")) .deploy(); String metaInfo = modelData.getMetaInfo(); JSONObject metaInfoMap = JSON.parseObject(metaInfo); // 设置流程分类 保存扩展流程至数据库 List list = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list(); for (ProcessDefinition pd : list) { ActZprocess actZprocess = new ActZprocess(); actZprocess.setId(pd.getId()); actZprocess.setName(modelData.getName()); actZprocess.setProcessKey(modelData.getKey()); actZprocess.setDeploymentId(deployment.getId()); actZprocess.setDescription(metaInfoMap.getString(ModelDataJsonConstants.MODEL_DESCRIPTION)); actZprocess.setVersion(pd.getVersion()); actZprocess.setDiagramName(pd.getDiagramResourceName()); actZprocessService.setAllOldByProcessKey(modelData.getKey()); actZprocess.setLatest(true); actZprocessService.save(actZprocess); } }catch (Exception e){ String err = e.toString(); log.error(e.getMessage(),e); if (err.indexOf("NCName")>-1){ return Result.error("部署失败:流程设计中的流程名称不能为空,不能为数字以及特殊字符开头!"); } if (err.indexOf("PRIMARY")>-1){ return Result.error("部署失败:该模型已发布,key唯一!"); } return Result.error("部署失败!"); } return Result.ok("部署成功"); } /*获取高亮实时流程图*/ @RequestMapping(value = "/getHighlightImg/{id}", method = RequestMethod.GET) public void getHighlightImg(@PathVariable String id, HttpServletResponse response){ InputStream inputStream = null; ProcessInstance pi = null; String picName = ""; // 查询历史 HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult(); if (hpi.getEndTime() != null) { // 已经结束流程获取原图 ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(hpi.getProcessDefinitionId()).singleResult(); picName = pd.getDiagramResourceName(); inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getDiagramResourceName()); } else { pi = runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult(); BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId()); List highLightedActivities = new ArrayList(); // 高亮任务节点 List tasks = taskService.createTaskQuery().processInstanceId(id).list(); for (Task task : tasks) { highLightedActivities.add(task.getTaskDefinitionKey()); } List highLightedFlows = new ArrayList(); ProcessDiagramGenerator diagramGenerator = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator(); //ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator(); //"宋体" inputStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivities, highLightedFlows, "宋体", "宋体", "宋体",null, 1.0); picName = pi.getName()+".png"; } try { response.setContentType("application/octet-stream;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(picName, "UTF-8")); byte[] b = new byte[1024]; int len = -1; while ((len = inputStream.read(b, 0, 1024)) != -1) { response.getOutputStream().write(b, 0, len); } response.flushBuffer(); } catch (IOException e) { log.error(e.toString()); throw new JeecgBootException("读取流程图片失败"); } } /**导出部署流程资源*/ @RequestMapping(value = "/export", method = RequestMethod.GET) public void exportResource(@RequestParam String id, HttpServletResponse response){ ProcessDefinition pd = repositoryService.createProcessDefinitionQuery() .processDefinitionId(id).singleResult(); String resourceName = pd.getDiagramResourceName(); InputStream inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), resourceName); try { response.setContentType("application/octet-stream;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(resourceName, "UTF-8")); byte[] b = new byte[1024]; int len = -1; while ((len = inputStream.read(b, 0, 1024)) != -1) { response.getOutputStream().write(b, 0, len); } response.flushBuffer(); } catch (IOException e) { log.error(e.toString()); } } }