接本专题上一篇
问题描述
集成后新增模型可以直接访问“modeler.html”进行编辑保存。但是在修改已保存模型的时候怎么也没法初始化,带上modelId参数也没用。
解决方法
activiti model 编辑需要提供editor方法,再返回 modeler.html,代码如下,要注意这里不是REST接口,需要使用到模板框架,我这里使用了freemarker将页面返回。
/**
* @author czj
*/
@Controller
public class ActivitiPageController {
/**
* 主要为异步调用而写,若访问地址为editor则页面载入后会
* 同时调用/model/{modelId}/json 对模型进行初始化
*
* @return
*/
@RequestMapping("editor")
public String editor() {
return "modeler.html";
}
}
当页面载入后,会再次调用/service/model/{modelId}/json 获取模板信息,完整controller如下。
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import
import
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import static org.activiti.editor.constants.ModelDataJsonConstants.*;
/**
* 调出流程图绘制界面
*/
@RestController
public class ActivitiModelController {
private static final Logger LOGGER = LoggerFactory.getLogger(ActivitiModelController.class);
@Resource
private RepositoryService repositoryService;
/** 定义流程引擎 */
@Resource
private ProcessEngine processEngine;
@Resource
private ObjectMapper objectMapper;
/** 模型的版本 */
private final static Integer MODEL_REVISION = 1;
/** modeler.html页面地址 */
private final static String ACTIVITI_REDIRECT_MODELER_INDEX = "/modeler.html?modelId=";
/** 默认的空间值 */
private final static String ACTIVITI_NAMESPACE_VALUE = "http://b3mn.org/stencilset/bpmn2.0#";
/** 默认ID值 */
private final static String ACTIVITI_ID_VALUE = "canvas";
/**
* 新建一个模型
*
* @param response
* @throws IOException
*/
@RequestMapping("/activiti-ui.html")
public void newModel(HttpServletResponse response) throws IOException {
RepositoryService repositoryService = processEngine.getRepositoryService();
// 初始化空的流程资源模型,填充信息并持久化模型
Model model = repositoryService.newModel();
String uuid = UUID.randomUUID().toString();
ObjectNode modelNode = objectMapper.createObjectNode();
modelNode.put(MODEL_NAME, uuid);
modelNode.put(MODEL_DESCRIPTION, "");
modelNode.put(ModelDataJsonConstants.MODEL_REVISION, MODEL_REVISION);
model.setName(uuid);
model.setKey(uuid);
model.setMetaInfo(modelNode.toString());
repositoryService.saveModel(model);
// 将 editorNode 数据填充到模型中, 并做页面的重定向
ObjectNode editorNode = objectMapper.createObjectNode();
editorNode.put("id", ACTIVITI_ID_VALUE);
editorNode.put("resourceId", ACTIVITI_ID_VALUE);
ObjectNode stencilSetNode = objectMapper.createObjectNode();
stencilSetNode.put("namespace", ACTIVITI_NAMESPACE_VALUE);
editorNode.set("stencilset", stencilSetNode);
repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes(StandardCharsets.UTF_8));
response.sendRedirect(ACTIVITI_REDIRECT_MODELER_INDEX + model.getId());
}
/**
* 保存模型
*
* @param modelId
* @param name
* @param description
* @param json_xml
* @param svg_xml
*/
@RequestMapping(value = "/service/model/{modelId}/save", method = RequestMethod.PUT)
@ResponseStatus(value = HttpStatus.OK)
public void saveModel(@PathVariable String modelId
, String name, String description
, String json_xml, String svg_xml) {
try {
Model model = repositoryService.getModel(modelId);
ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
modelJson.put(MODEL_NAME, name);
modelJson.put(MODEL_DESCRIPTION, description);
model.setMetaInfo(modelJson.toString());
model.setName(name);
repositoryService.saveModel(model);
repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes(StandardCharsets.UTF_8));
InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes(StandardCharsets.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();
} catch (Exception e) {
LOGGER.error("Error saving model", e);
throw new ActivitiException("Error saving model", e);
}
}
/**
* 获取模板编辑信息
*
* @param modelId
* @return
*/
@RequestMapping(value = "/service/model/{modelId}/json", method = RequestMethod.GET, produces = "application/json")
public ObjectNode getEditorJson(@PathVariable String modelId) {
ObjectNode modelNode = null;
Model model = repositoryService.getModel(modelId);
if (model != null) {
try {
if (StringUtils.isNotEmpty(model.getMetaInfo())) {
modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
} else {
modelNode = objectMapper.createObjectNode();
modelNode.put(MODEL_NAME, model.getName());
}
modelNode.put(MODEL_ID, model.getId());
ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(
new String(repositoryService.getModelEditorSource(model.getId()), StandardCharsets.UTF_8));
modelNode.put("model", editorJsonNode);
} catch (Exception e) {
LOGGER.error("获取模板JSON失败", e);
throw new ActivitiException("获取模板JSON失败", e);
}
}
return modelNode;
}
/**
* 加载模板集配置
*
* @return
*/
@RequestMapping(value = "/service/editor/stencilset", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
public @ResponseBody
String getStencilset() {
try {
InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("static/stencilset.json");
return IOUtils.toString(stencilsetStream, "utf-8");
} catch (Exception e) {
throw new ActivitiException("加载模板集配置失败", e);
}
}
}
可能你的地址不一样,修改对应前端调用地址配置文件在 editor-app\app-cfg.js
'use strict';
var ACTIVITI = ACTIVITI || {};
ACTIVITI.CONFIG = {
// 我是配置的以service开头,不建议使用activiti开头,防止和activiti提供的rest接口冲突。
'contextRoot' : '/service',
};