package org.jeecg.modules.activiti.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; 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.activiti.engine.repository.ProcessDefinition; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.jeecg.common.base.entity.ActZprocess; import org.jeecg.modules.activiti.mapper.ReModelMapper; import org.jeecg.modules.activiti.model.entity.ReModelEntity; import org.jeecg.modules.activiti.service.IActZprocessService; import org.jeecg.modules.activiti.service.ReModelService; import org.jeecg.common.Constant; import org.jeecg.common.api.vo.Result; import org.jeecg.common.exception.CustomException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.List; import java.util.Map; /** * 模型实现类 * * @author len * @date 2019/06/12 */ @Service public class ReModelServiceImpl extends ServiceImpl implements ReModelService { @Autowired private RepositoryService repositoryService; @Autowired private ActZprocessServiceImpl actZprocessService; @Override public IPage queryPage(Integer pageNo, Integer pageSize, HttpServletRequest req) { // String tenantId = req.getHeader("tenant-id"); // .modelTenantId(tenantId) ModelQuery modelQuery = repositoryService.createModelQuery() .orderByLastUpdateTime() .desc() .orderByModelVersion().desc(); String[] keys = req.getParameterMap().get("key"); if (!"".equals(keys) && keys != null) { String key = keys[0]; modelQuery.modelKey(key); } String[] names = req.getParameterMap().get("name"); if (!"".equals(names) && names != null) { String name = names[0]; modelQuery.modelName(name); } List list = modelQuery.listPage((pageNo - 1) * pageSize, pageSize); IPage page = new Page<>(pageNo, pageSize); page.setTotal((int) modelQuery.count()); return page.setRecords(list); } @Override public Model add(ReModelEntity actReModel) throws UnsupportedEncodingException { String description = actReModel.getDescription(); String key = actReModel.getKey(); String name = actReModel.getName(); String tenantId = actReModel.getTenantId(); 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.set("stencilset", stencilSetNode); Model modelData = repositoryService.newModel(); description = StringUtils.defaultString(description); modelData.setKey(StringUtils.defaultString(key)); modelData.setName(name); modelData.setVersion(Integer .parseInt(String.valueOf(repositoryService.createModelQuery().modelKey(modelData.getKey()).count() + 1))); ObjectNode modelObjectNode = objectMapper.createObjectNode(); modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name); modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, modelData.getVersion()); modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description); modelData.setMetaInfo(modelObjectNode.toString()); modelData.setTenantId(tenantId); repositoryService.saveModel(modelData); repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8")); return modelData; } @Override @Transactional(rollbackFor = Exception.class) public Result deploy(String id,HttpServletRequest request) { String message = ""; try { Model modelData = repositoryService.getModel(id); if(StringUtils.isEmpty(modelData.getTenantId())){ String tenantId = request.getHeader("tenant-id"); modelData.setTenantId(tenantId); } byte[] bytes = repositoryService.getModelEditorSource(modelData.getId()); if (bytes == null) { return Result.error("模型为空"); } BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); JsonNode editor = new ObjectMapper().readTree(bytes); BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editor); if (bpmnModel.getProcesses().size() == 0) { return Result.error("部署失败,没有设计流程"); } BpmnXMLConverter xmlConverter = new BpmnXMLConverter(); byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel); String processName = modelData.getName(); if (!StringUtils.endsWith(processName, Constant.ACT_BPMN20)) { processName += Constant.ACT_BPMN20; } ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes); Deployment deployment = repositoryService.createDeployment() .name(modelData.getName()) .addInputStream(processName, in) .tenantId(modelData.getTenantId()) .deploy(); // 设置流程分类 modelData.setDeploymentId(deployment.getId()); repositoryService.saveModel(modelData); 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); } return Result.OK("部署成功,流程ID=" + modelData.getId()); } catch (Exception e) { throw new CustomException("部署失败", e); } } @Override public void export(String id, HttpServletResponse response) { try { Model modelData = repositoryService.getModel(id); BpmnJsonConverter jsonConverter = new BpmnJsonConverter(); JsonNode editor = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId())); BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editor); BpmnXMLConverter xmlConverter = new BpmnXMLConverter(); byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel); ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes); IOUtils.copy(in, response.getOutputStream()); String filename = URLEncoder.encode(modelData.getName() + ".bpmn20.xml", "UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + filename); response.flushBuffer(); } catch (Exception e) { throw new CustomException("导出model的xml文件失败,模型ID=" + id, e); } } @Override public void delete(String id) { repositoryService.deleteModel(id); } @Override @Transactional(rollbackFor = Exception.class) public void deleteBatch(String[] ids) { for (String id : ids) { repositoryService.deleteModel(id); } } }