基于【2】中的项目将流程图设计相关页面拷贝迁移到项目中。
<properties>
<java.version>1.8java.version>
<apache.xmlgraphics.version>1.7apache.xmlgraphics.version>
properties>
<dependencies>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-spring-boot-starter-basicartifactId>
<version>6.0.0version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.activitigroupId>
<artifactId>activiti-json-converterartifactId>
<version>6.0.0version>
<exclusions>
<exclusion>
<groupId>org.activitigroupId>
<artifactId>activiti-bpmn-modelartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.apache.xmlgraphicsgroupId>
<artifactId>batik-codecartifactId>
<version>${apache.xmlgraphics.version}version>
dependency>
<dependency>
<groupId>org.apache.xmlgraphicsgroupId>
<artifactId>batik-cssartifactId>
<version>${apache.xmlgraphics.version}version>
dependency>
<dependency>
<groupId>org.apache.xmlgraphicsgroupId>
<artifactId>batik-svg-domartifactId>
<version>${apache.xmlgraphics.version}version>
dependency>
<dependency>
<groupId>org.apache.xmlgraphicsgroupId>
<artifactId>batik-svggenartifactId>
<version>${apache.xmlgraphics.version}version>
dependency>
dependencies>
路径:activiti-6.0.0 > wars > activiti-app > editor > editor-app
将activiti-app中的libs拷贝到项目中静态资源的libs中
【1】将activiti-app下的styles下的资源拷贝到css文件夹中
【2】拷贝style-editor.css到css文件夹中
【3】拷贝scripts到editor-app
<html class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Activiti Editortitle>
<link rel="icon" type="image/ico" href="favicon.ico">
<meta name="description" content="">
<meta name="viewport"
content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, width=device-width">
<link rel="Stylesheet" href="editor-app/libs/ui-grid_3.0.0/ui-grid.css" type="text/css"/>
<link rel="stylesheet" href="editor-app/libs/bootstrap_3.1.1/css/bootstrap.min.css"/>
<link rel="stylesheet" href="editor-app/libs/bootstrap-tour_0.9.1/bootstrap-tour.min.css"/>
<link rel="stylesheet" href="editor-app/libs/angular-spectrum-colorpicker_1.0.13/spectrum.css"/>
<link rel="Stylesheet" media="screen" href="editor-app/editor/css/editor.css?v=2" type="text/css"/>
<link rel="stylesheet" href="editor-app/css/style.css?v=2" type="text/css"/>
<link href="editor-app/css/common/style.css" rel="stylesheet">
<link href="editor-app/css/common/style-retina.css" rel="stylesheet">
<link rel="stylesheet" href="editor-app/css/style-editor.css">
head>
<body ng-app="activitiModeler" ng-cloak>
<div class="navbar navbar-fixed-top navbar-inverse" role="navigation" id="main-header">
<div class="fixed-container">
<div class="navbar-header">
<a ng-click="backToLanding()" class="landing-logo" ng-if="account != null && account != undefined" title="{{'GENERAL.MAIN-TITLE' | translate}}">
<img ng-if="account.tenantPictureId && account.tenantId"
ng-src="{{restRootUrl()}}/app/rest/tenants/{{account.tenantId}}/logo">
<img ng-if="!account.tenantPictureId" ng-src="{{appResourceRoot}}../images/activiti-logo.png">
a>
<ul class="nav navbar-nav" id="main-nav" ng-show="authenticated">
<li ng-class="{'active' : item.id == mainPage.id}" ng-repeat="item in mainNavigation"
ng-show="(authenticated && !item.unauthenticated) || (item.unauthenticated && !authenticated)">
<a ng-click="setMainPage(item)">{{item.title | translate}}a>
li>
ul>
div>
<div class="pull-right {{currentAppDefinition.definition.theme}}"
ng-class="{'app-indicator': currentAppDefinition}" ng-if="authenticated" ng-cloack>
<span ng-if="currentAppDefinition.definition.theme">
{{currentAppDefinition.name}}
span>
<i class="glyphicon {{currentAppDefinition.definition.icon}}">i>
<div class="dropdown btn-group btn-group-sm" activiti-fix-dropdown-bug>
<button type="button" class="btn btn-default dropdown-toggle"
data-toggle="dropdown">{{account.firstName}} {{account.lastName}}
<span class="glyphicon glyphicon-chevron-down" style="font-size: 10px" aria-hidden="true">span>
button>
<ul class="dropdown-menu pull-right">
<li><a href="" ng-click="logout()" translate>GENERAL.ACTION.LOGOUTa>li>
ul>
div>
div>
div>
div>
<div class="alert-wrapper" ng-cloak>
<div class="alert fadein {{alerts.current.type}}" ng-show="alerts.current" ng-click="dismissAlert()">
<i class="glyphicon"
ng-class="{'glyphicon-ok': alerts.current.type == 'info', 'glyphicon-remove': alerts.current.type == 'error'}">i>
<span>{{alerts.current.message}}span>
<div class="pull-right" ng-show="alerts.queue.length > 0">
<span class="badge">{{alerts.queue.length + 1}}span>
div>
div>
div>
<div id="main" class="wrapper full clearfix" ng-view="" ng-cloak ng-style="{height: window.height + 'px'}">
div>
<script src="editor-app/libs/jquery_1.11.0/jquery.min.js">script>
<script src="editor-app/libs/jquery-ui-1.10.3.custom.min.js">script>
<script src="editor-app/libs/angular_1.3.13/angular.min.js">script>
<script src="editor-app/libs/angular-animate_1.3.13/angular-animate.min.js">script>
<script src="editor-app/libs/bootstrap_3.1.1/js/bootstrap.min.js">script>
<script src="editor-app/libs/angular-resource_1.3.13/angular-resource.min.js">script>
<script src="editor-app/libs/angular-cookies_1.3.13/angular-cookies.min.js">script>
<script src="editor-app/libs/angular-sanitize_1.3.13/angular-sanitize.min.js">script>
<script src="editor-app/libs/angular-route_1.3.13/angular-route.min.js">script>
<script src="editor-app/libs/angular-translate_2.4.2/angular-translate.min.js">script>
<script src="editor-app/libs/angular-translate-storage-cookie/angular-translate-storage-cookie.js">script>
<script src="editor-app/libs/angular-translate-loader-static-files/angular-translate-loader-static-files.js">script>
<script src="editor-app/libs/angular-strap_2.1.6/angular-strap.min.js">script>
<script src="editor-app/libs/angular-strap_2.1.6/angular-strap.tpl.min.js">script>
<script src="editor-app/libs/momentjs_2.5.1/momentjs.min.js">script>
<script src="editor-app/libs/bootstrap-tour_0.9.1/bootstrap-tour.min.js">script>
<script src="editor-app/libs/ng-file-upload/ng-file-upload-shim.min.js">script>
<script src="editor-app/libs/ng-file-upload/ng-file-upload.min.js">script>
<script src="editor-app/libs/ui-utils.min-0.2.1.js" type="text/javascript">script>
<script src="editor-app/libs/ui-grid_3.0.0/ui-grid.js" type="text/javascript">script>
<script src="editor-app/libs/angular-dragdrop_1.0.11/angular-dragdrop.min.js" type="text/javascript">script>
<script src="editor-app/libs/mousetrap-1.4.5.min.js" type="text/javascript">script>
<script src="editor-app/libs/jquery.autogrow-textarea.js" type="text/javascript">script>
<script src="editor-app/libs/prototype-1.5.1.js" type="text/javascript">script>
<script src="editor-app/libs/path_parser.js" type="text/javascript">script>
<script src="editor-app/libs/angular-spectrum-colorpicker_1.0.13/spectrum.js" type="text/javascript">script>
<script src="editor-app/libs/angular-spectrum-colorpicker_1.0.13/angular-spectrum-colorpicker.min.js" type="text/javascript">script>
<script src="editor-app/libs/angular-scroll_0.5.7/angular-scroll.min.js" type="text/javascript">script>
<script src="editor-app/libs/angular-drag-and-drop-lists_1.2.0/angular-drag-and-drop-lists.js" type="text/javascript">script>
<script src="editor-app/libs/html2canvas_0.4.1/html2canvas.js">script>
<script src="editor-app/app-cfg.js?v=2">script>
<script src="editor-app/editor/i18n/translation_en_us.js" type="text/javascript">script>
<script src="editor-app/editor/i18n/translation_signavio_en_us.js" type="text/javascript">script>
<script src="editor-app/editor/oryx.js" type="text/javascript">script>
<script src="editor-app/common/http-auth-interceptor.js">script>
<script src="editor-app/common/services/auth-services.js">script>
<script src="editor-app/common/app.js">script>
<script src="editor-app/common/editor-directives.js">script>
<script src="editor-app/common/controllers/processes.js">script>
<script src="editor-app/common/controllers/process.js">script>
<script src="editor-app/common/controllers/forms.js">script>
<script src="editor-app/common/controllers/form.js">script>
<script src="editor-app/common/controllers/decision-tables.js">script>
<script src="editor-app/common/controllers/decision-table.js">script>
<script src="editor-app/common/controllers/app-definitions.js">script>
<script src="editor-app/common/controllers/app-definition.js">script>
<script src="editor-app/common/controllers/model-common-actions.js">script>
<script src="editor-app/common/services/util-services.js">script>
<script src="editor-app/common/services/identity-services.js">script>
<script src="editor-app/common/services/form-services.js">script>
<script src="editor-app/common/controllers/form-builder.js">script>
<script src="editor-app/configuration/form-builder-toolbar-default-actions.js" type="text/javascript">script>
<script src="editor-app/configuration/form-builder-toolbar.js" type="text/javascript">script>
<script src="editor-app/common/controllers/form-toolbar-controller.js" type="text/javascript">script>
<script src="editor-app/common/controllers/form-readonly-view.js">script>
<script src="editor-app/common/services/decision-table-service.js">script>
<script src="editor-app/common/controllers/decision-table-editor.js">script>
<script src="editor-app/configuration/decision-table-toolbar-default-actions.js" type="text/javascript">script>
<script src="editor-app/configuration/decision-table-toolbar.js" type="text/javascript">script>
<script src="editor-app/common/controllers/decision-table-toolbar-controller.js" type="text/javascript">script>
<script src="editor-app/common/controllers/app-definition-builder.js">script>
<script src="editor-app/configuration/app-definition-toolbar-default-actions.js" type="text/javascript">script>
<script src="editor-app/configuration/app-definition-toolbar.js" type="text/javascript">script>
<script src="editor-app/common/controllers/app-definition-toolbar-controller.js" type="text/javascript">script>
<script src="editor-app/eventbus.js" type="text/javascript">script>
<script src="editor-app/editor-controller.js" type="text/javascript">script>
<script src="editor-app/stencil-controller.js" type="text/javascript">script>
<script src="editor-app/toolbar-controller.js" type="text/javascript">script>
<script src="editor-app/header-controller.js" type="text/javascript">script>
<script src="editor-app/select-shape-controller.js" type="text/javascript">script>
<script src="editor-app/define-data-controller.js" type="text/javascript">script>
<script src="editor-app/tour.js" type="text/javascript">script>
<script src="editor-app/editor-utils.js" type="text/javascript">script>
<script src="editor-app/configuration/toolbar-default-actions.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-default-controllers.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-execution-listeners-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-event-listeners-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-assignment-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-fields-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-form-properties-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-in-parameters-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-multiinstance-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-out-parameters-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-task-listeners-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-collapsed-subprocess-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-form-reference-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-sequenceflow-order-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-condition-expression-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-signal-definitions-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-signal-scope-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-message-definitions-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-message-scope-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-duedate-controller.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-decisiontable-reference-controller.js" type="text/javascript">script>
<script src="editor-app/editor-config.js" type="text/javascript">script>
<script src="editor-app/configuration/url-config.js" type="text/javascript">script>
<script src="editor-app/configuration/toolbar.js" type="text/javascript">script>
<script src="editor-app/configuration/toolbar-custom-actions.js" type="text/javascript">script>
<script src="editor-app/configuration/properties.js" type="text/javascript">script>
<script src="editor-app/configuration/properties-custom-controllers.js" type="text/javascript">script>
<script src="editor-app/configuration/kis-header-custom.js" type="text/javascript">script>
<script src="editor-app/configuration/kis-toolbar-custom-actions.js" type="text/javascript">script>
<script src="editor-app/common/services/related-content-service.js">script>
<script src="editor-app/common/directives.js">script>
<script src="editor-app/common/providers-config.js">script>
<script src="editor-app/common/services/resource-service.js">script>
<script src="editor-app/common/services/recursion-helper.js">script>
<script src="editor-app/common/services/authentication-service.js">script>
<script src="editor-app/common/services/runtime-app-definition-service.js">script>
<script src="editor-app/common/controllers/about.js">script>
<script src="editor-app/resource-loader.js?v=2" app="editor">script>
body>
html>
访问会出现报错,经【5】问题解决后,再继续下面的测试。
【1】先创建模型,拿到模型id然后访问以下地址即可
【2】访问http://localhost:8083/index.html#/editor/模型id
例如:http://localhost:8083/index.html#/editor/45001
package com.ft.spring.activiti.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author luobaimang
* @date 2019/11/28
*/
@Controller
public class ModelController {
private static final Logger logger = LoggerFactory.getLogger(ModelController.class);
@Autowired
private RepositoryService repositoryService;
@Autowired
private ObjectMapper objectMapper;
/**
* 创建模型
* @param response
* @param name 模型名称
* @param key 模型key
*/
@RequestMapping("/create")
@ResponseBody
public String create(HttpServletResponse response, String name, String key) throws IOException {
logger.info("创建模型入参name:{},key:{}",name,key);
Model model = repositoryService.newModel();
ObjectNode modelNode = objectMapper.createObjectNode();
modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, "");
modelNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
model.setName(name);
model.setKey(key);
model.setMetaInfo(modelNode.toString());
repositoryService.saveModel(model);
createObjectNode(model.getId());
logger.info("创建模型结束,返回模型ID:{}",model.getId());
return model.getId();
}
/**
* 创建模型时完善ModelEditorSource
* @param modelId
*/
@SuppressWarnings("deprecation")
private void createObjectNode(String modelId){
logger.info("创建模型完善ModelEditorSource入参模型ID:{}",modelId);
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);
try {
repositoryService.addModelEditorSource(modelId,editorNode.toString().getBytes("utf-8"));
} catch (Exception e) {
logger.info("创建模型时完善ModelEditorSource服务异常:{}",e);
}
logger.info("创建模型完善ModelEditorSource结束");
}
}
package com.ft.spring.activiti.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.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 org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
/**
* @author luobaimang
* @date 2019/11/28
*/
@RestController
@RequestMapping("service")
public class ModelRestController implements ModelDataJsonConstants {
protected static final Logger LOGGER = LoggerFactory.getLogger(ModelRestController.class);
@Autowired
private RepositoryService repositoryService;
@Autowired
private ObjectMapper objectMapper;
/**
* 更新流程
*
* @param modelId 模型ID
* @param name 流程模型名称
* @param description
* @param json_xml 流程文件
* @param svg_xml 图片
*/
@RequestMapping(value = "/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);
modelJson.put(ModelDataJsonConstants.MODEL_REVISION, model.getVersion() + 1);
model.setMetaInfo(modelJson.toString());
model.setName(name);
repositoryService.saveModel(model);
repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8"));
InputStream svgStream = new ByteArrayInputStream(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();
} catch (Exception e) {
LOGGER.error("Error saving model", e);
throw new ActivitiException("Error saving model", e);
}
}
/**
* 获取model的节点信息,编辑器根据返回的json进行绘图
*
* @param modelId
* @return
*/
@SuppressWarnings("deprecation")
@RequestMapping(value = "/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()), "utf-8"));
modelNode.put("model", editorJsonNode);
} catch (Exception e) {
LOGGER.error("Error creating model JSON", e);
throw new ActivitiException("Error creating model JSON", e);
}
}
return modelNode;
}
/**
* 获取编辑器组件及配置项信息
* 获取流程json文件
*
* @return
*/
@RequestMapping(value = "/editor/stencilset", method = RequestMethod.GET, produces = "application/json;charset=utf-8")
@ResponseBody
public String getStencilset() {
InputStream stencilsetStream = this.getClass().getClassLoader().getResourceAsStream("stencilset.json");
try {
return IOUtils.toString(stencilsetStream, "utf-8");
} catch (Exception e) {
throw new ActivitiException("Error while loading stencil set", e);
}
}
}
原因访问index.html重定向到登陆界面
http://localhost:8083/#/login?redirectUrl=http:%2F%2Flocalhost:8083%2Findex.html%23%2Fprocesses
【1】修改app.js
根据5.1.2 修改成以下访问地址
var KISBPM = KISBPM || {};
KISBPM.URL = {
getModel: function(modelId) {
return ACTIVITI.CONFIG.contextRoot + '/model/' + modelId + '/json';
},
getStencilSet: function() {
return ACTIVITI.CONFIG.contextRoot + '/editor/stencilset?version=' + Date.now();
},
putModel: function(modelId) {
return ACTIVITI.CONFIG.contextRoot + '/model/' + modelId + '/save';
}
};
ACTIVITI.CONFIG = {
'onPremise' : true,
'contextRoot' : '/service',
'webContextRoot' : '/activiti-app'
};
因访问报错404:http://localhost:8083/service/app/rest/stencil-sets/editor?version=1574941194439
因访问地址改了,故需要访问请求地址,让其能正确访问。修改如下:
报:TypeError: Cannot read property ‘firstName’ of undefined
at Object.gettingStarted
注释掉该行。
报:http://localhost:8083/editor-app/fonts/lato-bold-webfont.woff net::ERR_ABORTED 404
jquery.min.js:4 GET http://localhost:8083/editor-app/fonts/lato-regular-webfont.woff net::ERR_ABORTED 404
GET http://localhost:8083/editor-app/fonts/lato-bold-webfont.ttf net::ERR_ABORTED 404
editor-app/fonts/lato-regular-webfont.ttf:1 GET http://localhost:8083/editor-app/fonts/lato-regular-webfont.ttf net::ERR_ABORTED 404
https://gitee.com/idcory/ft-spring-demo/tree/master/ft-demo-activiti