package com.zml.oa.action;
import java.io.ByteArrayInputStream;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ModelQuery;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.zml.oa.entity.Datagrid;
import com.zml.oa.entity.Message;
import com.zml.oa.pagination.Page;
@Controller
@RequiresPermissions("admin:*")
@RequestMapping("/modelAction")
public class ProcessModelAction {
private static final Logger logger = Logger.getLogger(ProcessModelAction.class);
@Autowired
private RepositoryService repositoryService;
/**
* 跳转模型列表
* @return
*/
@RequestMapping(value = "/toListModel")
public String toListModel(){
return "workflow/list_model";
}
/**
* 模型列表
* @return
*/
@RequestMapping(value = "/listModel")
@ResponseBody
public Datagrid<Model> modelList(
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "rows", required = false) Integer rows) {
ModelQuery modelQuery = repositoryService.createModelQuery();
Page<Model> p = new Page<Model>(page, rows);
int[] pageParams = p.getPageParams(modelQuery.list().size());
List<Model> list = modelQuery.listPage(pageParams[0], pageParams[1]);
return new Datagrid<Model>(p.getTotal(), list);
}
/**
* 跳转创建模型页面
* @return
*/
@RequestMapping(value = "/toAddModel")
public String toCreateModel(){
return "workflow/add_model";
}
/**
* 创建模型
* @param name
* @param key
* @param description
* @param request
* @param response
*/
@RequestMapping(value = "/create", method = RequestMethod.POST)
public void create(@RequestParam("name") String name, @RequestParam("key") String key, @RequestParam("description") String description,
HttpServletRequest request, HttpServletResponse response) {
logger.info("name: "+name+" key: "+key+" des: "+description);
try {
ObjectMapper objectMapper = new ObjectMapper();
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);
Model modelData = repositoryService.newModel();
ObjectNode modelObjectNode = objectMapper.createObjectNode();
modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
description = StringUtils.defaultString(description);
modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
modelData.setMetaInfo(modelObjectNode.toString());
modelData.setName(name);
modelData.setKey(StringUtils.defaultString(key));
repositoryService.saveModel(modelData);
repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
String path = request.getContextPath();
response.sendRedirect(request.getContextPath() + "/modeler/service/editor?id=" + modelData.getId());
return;
} catch (Exception e) {
logger.error("创建模型失败:", e);
}
}
/**
* 根据Model部署流程
* @param modelId
* @param redirectAttributes
* @return
*/
@RequestMapping(value = "deploy/{modelId}")
@ResponseBody
public Message deploy(@PathVariable("modelId") String modelId) {
Message message = new Message();
try {
//根据id获取model
Model modelData = repositoryService.getModel(modelId);
//repositoryService获取字节数组
ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
byte[] bpmnBytes = null;
//获取BpmnModel
BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
//获取xml.bpmn
bpmnBytes = new BpmnXMLConverter().convertToXML(model);
//获取名称
String processName = modelData.getName() + ".bpmn20.xml";
//部署
Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes)).deploy();
message.setStatus(Boolean.TRUE);
message.setMessage("部署成功,部署ID=" + deployment.getId()+" 请到【流程定义】菜单中查看!");
} catch (Exception e) {
message.setStatus(Boolean.FALSE);
message.setMessage("根据模型部署流程失败:modelId="+modelId);
logger.error("根据模型部署流程失败:modelId={}" + modelId, e);
}
return message;
}
/**
* 导出model的xml文件
* @param modelId
* @param response
*/
@RequestMapping(value = "export/{modelId}")
public void export(@PathVariable("modelId") String modelId, HttpServletResponse response) {
try {
Model modelData = repositoryService.getModel(modelId);
BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel);
ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes);
IOUtils.copy(in, response.getOutputStream());
String filename = bpmnModel.getMainProcess().getId() + ".bpmn20.xml";
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
response.flushBuffer();
} catch (Exception e) {
logger.error("导出model的xml文件失败:modelId={}" + modelId, e);
}
}
/**
* 删除模型
* @param modelId
* @return
*/
@RequestMapping(value = "delete/{modelId}")
@ResponseBody
public Message delete(@PathVariable("modelId") String modelId) {
Message message = new Message();
try {
repositoryService.deleteModel(modelId);
message.setStatus(Boolean.TRUE);
message.setMessage("删除成功!");
} catch (Exception e) {
message.setStatus(Boolean.FALSE);
message.setMessage("删除失败!");
}
return message;
}
}
/**
* 激活、挂起流程定义-根据processDefinitionId
* @param status
* @param processInstanceId
* @param redirectAttributes
* @return
* @throws Exception
*/
@RequiresPermissions("admin:process:suspend,active")
@RequestMapping(value = "/process/updateProcessStatusByProDefinitionId")
@ResponseBody
public Message updateProcessStatusByProDefinitionId(
@RequestParam("status") String status,
@RequestParam("processDefinitionId") String processDefinitionId) throws Exception{
//如果用/{status}/{processDefinitionId} rest风格,@PathVariable获取的processDefinitionId 为com.zml.oa,实际是com.zml.oa.vacation:1:32529.难道是BUG?
Message message = new Message();
if (status.equals("active")) {
repositoryService.activateProcessDefinitionById(processDefinitionId, true, null);
message.setStatus(Boolean.TRUE);
message.setMessage("已激活ID为[" + processDefinitionId + "]的流程定义。");
} else if (status.equals("suspend")) {
repositoryService.suspendProcessDefinitionById(processDefinitionId, true, null);
message.setStatus(Boolean.TRUE);
message.setMessage("已挂起ID为[" + processDefinitionId + "]的流程定义。");
}
return message;
}
/**
* 激活、挂起流程实例-根据processInstanceId
* @param status
* @param processInstanceId
* @param redirectAttributes
* @return
* @throws Exception
*/
@RequiresPermissions("admin:process:suspend,active")
@RequestMapping(value = "/process/updateProcessStatusByProInstanceId/{status}/{processInstanceId}")
@ResponseBody
public Message updateProcessStatusByProInstanceId(
@PathVariable("status") String status,
@PathVariable("processInstanceId") String processInstanceId,
RedirectAttributes redirectAttributes) throws Exception{
Message message = new Message();
if (status.equals("active")) {
this.processService.activateProcessInstance(processInstanceId);
// redirectAttributes.addFlashAttribute("message", "已激活ID为[ " + processInstanceId + " ]的流程实例。");
message.setStatus(Boolean.TRUE);
message.setMessage("已激活ID为[" + processInstanceId + "]的流程实例。");
} else if (status.equals("suspend")) {
this.processService.suspendProcessInstance(processInstanceId);
// redirectAttributes.addFlashAttribute("message", "已挂起ID为[ " + processInstanceId + " ]的流程实例。");
message.setStatus(Boolean.TRUE);
message.setMessage("已挂起ID为[" + processInstanceId + "]的流程实例。");
}
return message;
}
/**
* 转换为model
* @param processDefinitionId
* @return
* @throws UnsupportedEncodingException
* @throws XMLStreamException
*/
@RequiresPermissions("admin:process:*")
@RequestMapping(value = "/process/convert_to_model")
@ResponseBody
public Message convertToModel(@RequestParam("processDefinitionId") String processDefinitionId)
throws UnsupportedEncodingException, XMLStreamException {
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(processDefinitionId).singleResult();
InputStream bpmnStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),
processDefinition.getResourceName());
XMLInputFactory xif = XMLInputFactory.newInstance();
InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
XMLStreamReader xtr = xif.createXMLStreamReader(in);
BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
BpmnJsonConverter converter = new BpmnJsonConverter();
com.fasterxml.jackson.databind.node.ObjectNode modelNode = converter.convertToJson(bpmnModel);
org.activiti.engine.repository.Model modelData = repositoryService.newModel();
modelData.setKey(processDefinition.getKey());
modelData.setName(processDefinition.getResourceName());
modelData.setCategory(processDefinition.getDeploymentId());
ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName());
modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription());
modelData.setMetaInfo(modelObjectNode.toString());
repositoryService.saveModel(modelData);
repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));
return new Message(Boolean.TRUE, "转换成功!请到[ 流程设计模型 ]菜单中查看!");
}