瀏覽代碼

完善单元测试,流程流转,modeller集成

wangwei 7 年之前
父節點
當前提交
7e219bcadd

+ 262 - 0
hsweb-system/hsweb-system-workflow/hsweb-system-workflow-flowable-modeler/src/main/java/org/hswebframework/web/workflow/flowable/modeler/FlowableModelController.java

@@ -0,0 +1,262 @@
+package org.hswebframework.web.workflow.flowable.modeler;
+
+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 org.activiti.bpmn.converter.BpmnXMLConverter;
+import org.activiti.bpmn.model.BpmnModel;
+import org.activiti.editor.language.json.converter.BpmnJsonConverter;
+import org.activiti.engine.ActivitiException;
+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.batik.transcoder.TranscoderException;
+import org.apache.batik.transcoder.TranscoderInput;
+import org.apache.batik.transcoder.TranscoderOutput;
+import org.apache.batik.transcoder.image.PNGTranscoder;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.hsweb.ezorm.core.PropertyWrapper;
+import org.hsweb.ezorm.core.SimplePropertyWrapper;
+import org.hsweb.ezorm.core.param.TermType;
+import org.hswebframework.web.NotFoundException;
+import org.hswebframework.web.commons.entity.PagerResult;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.hswebframework.web.logging.AccessLogger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/workflow")
+public class FlowableModelController {
+
+    @Autowired
+    private RepositoryService repositoryService;
+
+    private final static String MODEL_ID = "modelId";
+    private final static String MODEL_NAME = "name";
+    private final static String MODEL_REVISION = "revision";
+    private final static String MODEL_DESCRIPTION = "description";
+    private final static String MODEL_KEY = "key";
+
+    @RequestMapping(value = "/model/list", method = RequestMethod.GET)
+    public ResponseMessage<PagerResult<Model>> getModelList(QueryParamEntity param) {
+        ModelQuery modelQuery = repositoryService.createModelQuery();
+        param.getTerms().forEach((term) -> {
+
+            PropertyWrapper valueWrapper = new SimplePropertyWrapper(term.getValue());
+            String stringValue = valueWrapper.toString();
+            switch (term.getColumn()) {
+                case "name":
+                    if (term.getTermType().equals(TermType.like))
+                        modelQuery.modelNameLike(stringValue);
+                    else
+                        modelQuery.modelName(stringValue);
+                    break;
+                case "key":
+                    modelQuery.modelKey(stringValue);
+                    break;
+                case "category":
+                    if (term.getTermType().equals(TermType.like)) {
+                        modelQuery.modelCategoryLike(stringValue);
+                    } else if (term.getTermType().equals(TermType.not)) {
+                        modelQuery.modelCategoryNotEquals(stringValue);
+                    } else
+                        modelQuery.modelCategory(stringValue);
+                    break;
+                case "tenantId":
+                    if (term.getTermType().equals(TermType.like))
+                        modelQuery.modelTenantIdLike(stringValue);
+                    else
+                        modelQuery.modelTenantId(stringValue);
+                    break;
+                case "version":
+                    if ("latest".equals(stringValue))
+                        modelQuery.latestVersion();
+                    else
+                        modelQuery.modelVersion(valueWrapper.toInt());
+            }
+        });
+        modelQuery.orderByCreateTime().desc();
+        int total = (int) modelQuery.count();
+        param.rePaging(total);
+        List<Model> models = modelQuery.listPage(param.getPageIndex(), param.getPageSize() * (param.getPageIndex() + 1));
+        return ResponseMessage.ok(new PagerResult<>(total, models))
+                .exclude(Model.class, "metaInfo", "persistentState");
+    }
+
+    @RequestMapping(value = "/model/{modelId}/json", method = RequestMethod.GET)
+    @AccessLogger("获取模型定义json")
+    public Object getEditorJson(@PathVariable String modelId) throws Exception {
+        JSONObject modelNode;
+        Model model = repositoryService.getModel(modelId);
+        if (model == null) throw new NotFoundException("模型不存在");
+        if (StringUtils.isNotEmpty(model.getMetaInfo())) {
+            modelNode = JSON.parseObject(model.getMetaInfo());
+        } else {
+            modelNode = new JSONObject();
+            modelNode.put(MODEL_NAME, model.getName());
+        }
+        modelNode.put(MODEL_ID, model.getId());
+        modelNode.put("model", JSON.parse(new String(repositoryService.getModelEditorSource(model.getId()))));
+        return modelNode;
+    }
+
+    @RequestMapping(value = "/model", method = RequestMethod.POST)
+    @ResponseStatus(value = HttpStatus.CREATED)
+    public ResponseMessage createModel(@RequestBody JSONObject model) throws Exception {
+        JSONObject stencilset = new JSONObject();
+        stencilset.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
+        JSONObject editorNode = new JSONObject();
+        editorNode.put("id", "canvas");
+        editorNode.put("resourceId", "canvas");
+        editorNode.put("stencilset", stencilset);
+        JSONObject modelObjectNode = new JSONObject();
+        modelObjectNode.put(MODEL_REVISION, 1);
+        modelObjectNode.put(MODEL_DESCRIPTION, model.getString(MODEL_DESCRIPTION));
+        modelObjectNode.put(MODEL_KEY, model.getString(MODEL_KEY));
+        modelObjectNode.put(MODEL_NAME, model.getString(MODEL_NAME));
+        modelObjectNode.put(MODEL_DESCRIPTION, model.getString(MODEL_DESCRIPTION));
+
+        Model modelData = repositoryService.newModel();
+        modelData.setMetaInfo(modelObjectNode.toJSONString());
+        modelData.setName(model.getString(MODEL_NAME));
+        modelData.setKey(model.getString(MODEL_KEY));
+        repositoryService.saveModel(modelData);
+        repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
+        return ResponseMessage.ok(modelData);
+    }
+
+    @RequestMapping(value = "/model/{modelId}/deploy", method = RequestMethod.PUT)
+    @ResponseStatus(value = HttpStatus.OK)
+    public ResponseMessage deployModel(@PathVariable String modelId) throws Exception {
+        Model modelData = repositoryService.getModel(modelId);
+        if (modelData == null) throw new NotFoundException("模型不存在!");
+        ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
+        BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
+        byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);
+        String processName = modelData.getName() + ".bpmn20.xml";
+        Deployment deployment = repositoryService.createDeployment()
+                .name(modelData.getName())
+                .addString(processName, new String(bpmnBytes, "utf8"))
+                .deploy();
+        return ResponseMessage.ok(deployment).include(Deployment.class, "id", "name", "new");
+    }
+
+    @RequestMapping(value = "/model/{modelId}/save", method = RequestMethod.PUT)
+    @ResponseStatus(value = HttpStatus.OK)
+    public void saveModel(@PathVariable String modelId,
+                          @RequestParam Map<String, String> values) throws TranscoderException, IOException {
+        Model model = repositoryService.getModel(modelId);
+        JSONObject modelJson = JSON.parseObject(model.getMetaInfo());
+
+        modelJson.put(MODEL_NAME, values.get("name"));
+        modelJson.put(MODEL_DESCRIPTION, values.get("description"));
+
+        model.setMetaInfo(modelJson.toString());
+        model.setName(values.get("name"));
+
+        repositoryService.saveModel(model);
+
+        repositoryService.addModelEditorSource(model.getId(), values.get("json_xml").getBytes("utf-8"));
+
+        InputStream svgStream = new ByteArrayInputStream(values.get("svg_xml").getBytes("utf-8"));
+        TranscoderInput input = new TranscoderInput(svgStream);
+
+        PNGTranscoder transcoder = new PNGTranscoder();
+        // Setup output
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        TranscoderOutput output = new TranscoderOutput(outStream);
+
+        // Do the transformation
+        transcoder.transcode(input, output);
+        final byte[] result = outStream.toByteArray();
+        repositoryService.addModelEditorSourceExtra(model.getId(), result);
+        outStream.close();
+    }
+
+    @GetMapping(value = {"/editor/stencilset"}, produces = {"application/json;charset=utf-8"})
+    public String getStencilset() {
+        InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("stencilset.json");
+
+        try {
+            return IOUtils.toString(stencilsetStream, "utf-8");
+        } catch (Exception var3) {
+            throw new ActivitiException("Error while loading stencil set", var3);
+        }
+    }
+
+    /**
+     * 导出model对象为指定类型
+     *
+     * @param modelId 模型ID
+     * @param type    导出文件类型(bpmn\json)
+     */
+    @RequestMapping(value = "export/{modelId}/{type}", method = RequestMethod.GET)
+    public void export(@PathVariable("modelId") String modelId,
+                       @PathVariable("type") String type,
+                       HttpServletResponse response) {
+        try {
+            Model modelData = repositoryService.getModel(modelId);
+            BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
+            byte[] modelEditorSource = repositoryService.getModelEditorSource(modelData.getId());
+
+            JsonNode editorNode = new ObjectMapper().readTree(modelEditorSource);
+            BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
+
+            // 处理异常
+            if (bpmnModel.getMainProcess() == null) {
+                response.setStatus(HttpStatus.UNPROCESSABLE_ENTITY.value());
+                response.getOutputStream().println("no main process, can't export for type: " + type);
+                response.flushBuffer();
+                return;
+            }
+
+            String filename = "";
+            byte[] exportBytes = null;
+
+            String mainProcessId = bpmnModel.getMainProcess().getId();
+
+            if (type.equals("bpmn")) {
+
+                BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
+                exportBytes = xmlConverter.convertToXML(bpmnModel);
+
+                filename = mainProcessId + ".bpmn20.xml";
+            } else if (type.equals("json")) {
+
+                exportBytes = modelEditorSource;
+                filename = mainProcessId + ".json";
+
+            }
+
+            response.setCharacterEncoding("UTF-8");
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
+
+            /*创建输入流*/
+            ByteArrayInputStream in = new ByteArrayInputStream(exportBytes);
+            IOUtils.copy(in, response.getOutputStream());
+
+            response.flushBuffer();
+            in.close();
+        } catch (Exception e) {
+//            logger.error("导出model的xml文件失败:modelId={}, type={}", modelId, type, e);
+        }
+    }
+
+}