getXmlUrl () {
const that = this
return new Promise(resolve => {
setTimeout(() => {
//const url = ''
//const url = 'https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/mock1.bpmn'
const url = '/manage/'+that.deploymentId+'/init'
resolve(url)
}, 1000)
})
}
@GetMapping("/{deploymentId}/init")
public void init(@PathVariable("deploymentId") String deploymentId,
HttpServletResponse response) throws IOException {
ByteArrayPO instance = camundaService.getInstance(deploymentId);
// 设置响应
response.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
response.setHeader("Content-Disposition",
"attachment;filename="+ URLEncoder.encode(instance.getName_(), "utf-8"));
try (InputStream is = instance.getBytes_().getBinaryStream();
OutputStream os = response.getOutputStream()) {
// 将blob写入响应流中
byte[] buff = new byte[1024];
int len = -1;
while ((len = is.read(buff)) != -1) {
os.write(buff, 0, len);
}
} catch (Exception e) {
}
}
用于获得blob类的handler,代码很简单。
public class BlobTypeHandler extends BaseTypeHandler<Blob> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Blob blob, JdbcType jdbcType) throws SQLException {
ps.setBlob(i, blob);
}
@Override
public Blob getNullableResult(ResultSet resultSet, String s) throws SQLException {
return resultSet.getBlob(s);
}
@Override
public Blob getNullableResult(ResultSet resultSet, int i) throws SQLException {
return resultSet.getBlob(i);
}
@Override
public Blob getNullableResult(CallableStatement cs, int i) throws SQLException {
return cs.getBlob(i);
}
}
upload() {
const that = this
this.bpmnModeler.saveSVG(function(err, svg) {
if (!err) {
that.bpmnModeler.saveXML({format: true}, function(err2, xml) {
if (!err2) {
axios.post('/manage/camunda/deploy', {
svgStr: svg,
xmlStr: xml
}).then((res) => {
console.log(res)
})
}
})
}
})
}
@PostMapping("/deploy")
public String deploy(@RequestBody Map<String, String> map) {
String str = map.get("xmlStr");
// 正则表达式
String id = "", name = "";
// id和name的获得方法,我是使用了很蹩脚的正则表达式
RepositoryService repositoryService = processEngine.getRepositoryService();
// 部署
Deployment deployment = repositoryService.createDeployment()
.name(name)
.addString(id + ".bpmn20.xml", str).deploy();
// 保存图片到服务器
String svg = map.get("svgStr");
try {
CamundaUtil.savePNG(svg, "E:\\out.png");
} catch (Exception e ) {
}
// 部署成功
System.out.println("部署成功");
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());
return "success";
}
保存图片到指定的路径
public static void savePNG(String svg, String filePath) throws IOException, TranscoderException {
// 输出
File file = new File(filePath);
FileOutputStream fos = new FileOutputStream(file);
TranscoderOutput output = new TranscoderOutput(fos);
// 输入
ByteArrayInputStream bis = new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8));
TranscoderInput input = new TranscoderInput(bis);
PNGTranscoder transcoder = new PNGTranscoder();
// Do the transformation
transcoder.transcode(input, output);
fos.flush();
bis.close();
fos.close();
}
这里我主要用的了两种方法
@font-face {
font-family: 'bpmn';
/** 替换xxx即可 */
src: url('data:application/octet-stream;base64,xxx') format('woff'),
url('data:application/octet-stream;base64,xxx') format('truetype');
}
2. 重写Paletteprovider
vue项目中创建路径
| -- palette
|-- CustomPaletteProvider.js
|-- CustomPalette.js
|-- index.js
node_modules\bpmn-js\lib\features\palette\PaletteProvider.js内代码复制到CustomPaletteProvider.js;
node_modules\diagram-js\lib\features\palette\Palette.js内代码复制到CustomPalette.js
index.js代码
import customPalette from './CustomPalette'
import PaletteProvider from './CustomPaletteProvider'
// 除了引进的模块的名字可以修改,其他的不建议修改,会报错
export default {
__depends__: [
{
__init__: ['customPalette'],
customPalette: ['type', customPalette]
}
], // 依赖于 customPalette 这个模块
__init__: ['customPaletteProvider'], // 调用 customPaletteProvider 来初始化
customPaletteProvider: ['type', PaletteProvider]
}
接下来开始修改CustomPalette.js
// 修改注入需要的数据
Palette.$inject = [
'eventBus',
'canvas',
// 自定义部分
'elementFactory',
'create',
'config.paletteContainer',
'config.paletteEntries'
]
export default function Palette (
eventBus,
canvas,
// 数据赋值
elementFactory,
create,
paletteContainer,
paletteEntries
) {
this._eventBus = eventBus
this._canvas = canvas
// 新增赋值
this._entries = paletteEntries // 传入的工具栏数据
this._paletteContainer = paletteContainer // 传入的工具栏容器
this._elementFactory = elementFactory
this._create = create
// 实现拖拽功能
Palette.prototype.trigger = function (action, event, autoActivate) {
var entries = this._entries
var entry
var handler
var originalEvent
var button = event.delegateTarget || event.target
var elementFactory = this._elementFactory,
create = this._create
if (!button) {
return event.preventDefault()
}
entry = entries[domAttr(button, 'data-action')]
// when user clicks on the palette and not on an action
if (!entry) {
return
}
handler = entry.action
originalEvent = event.originalEvent || event
// simple action (via callback function)
if (isFunction(handler)) {
if (action === 'click') {
handler(originalEvent, autoActivate, elementFactory, create)
}
} else {
if (handler[action]) {
handler[action](originalEvent, autoActivate, elementFactory, create)
}
}
// silence other actions
event.preventDefault()
}
接下来修改paletteProvider.js
import { assign } from 'min-dash'
PaletteProvider.$inject = ['config.paletteEntries', 'customPalette', 'lassoTool', 'translate']
export default function PaletteProvider (paletteEntries, customPalette, lassoTool, translate) {
this._entries = paletteEntries
// 根据需求增加需要注入的工具类
this._lassoTool = lassoTool
this._translate = translate
customPalette.registerProvider(this)
}
PaletteProvider.prototype.getPaletteEntries = function (element) {
var lassoTool = this._lassoTool
var translate = this._translate
// tool图标修改请在此处进行
// 修改参数请参考
// node_modules\bpmn-js\lib\features\palette\PaletteProvider.js的getPaletteEntries()
return assign(this._entries, {
'lasso-tool': {
group: 'tools',
className: 'bpmn-icon-lasso-tool-custom',
title: translate('Activate the lasso tool'),
imageUrl: require('../img/lasso.png'),
action: {
click: function(event) {
lassoTool.activateSelection(event);
}
}
}
})
}
再增加一个paletteEntries.js即可
import { is } from 'bpmn-js/lib/util/ModelUtil'
import { assign } from 'min-dash'
import {
append as svgAppend,
attr as svgAttr,
create as svgCreate,
remove as svgRemove
} from 'tiny-svg'
const TASK_BORDER_RADIUS = 2
export default {
'create.start-event': createAction(
'bpmn:StartEvent',
'event',
'bpmn-icon-start-event-none',
'Create StartEvent',
'',
drawShape
),
'create.intermediate-event': createAction(
'bpmn:IntermediateThrowEvent',
'event',
'bpmn-icon-intermediate-event-none-custom',
'Create Intermediate/Boundary Event',
require('../img/IntermediateBoundaryEvent.png'),
drawShape
),
'create.task': createAction(
'bpmn:Task',
'activity',
'bpmn-icon-task-custom',// 类名应该在原类名后加上后缀保证其不使用原生的icon,但保留其他属性
'创建任务',
require('../img/task.png'),// 在此处可以实现图片
drawShape
),
'create.data-object': createAction(
'bpmn:DataObjectReference',
'data-object',
'bpmn-icon-data-object-custom',
'Create DataObjectReference',
require('../img/file.png'),
drawShape
)
}
function createAction (type, group, className, title, imageUrl = '', drawShape) {
function createListener (event, autoActivate, elementFactory, create) {
var shape = elementFactory.createShape(assign({ type: type }));
create.start(event, shape);
}
const config = {
type,
group: group,
className: className,
title: title,
drawShape: drawShape,
action: {
dragstart: createListener,
click: createListener
}
}
if (imageUrl) {
assign(config, {
imageUrl
}
)
}
if (drawShape) {
assign(config, {
drawShape
}
)
}
return config
}
function drawShape (parentNode, element, bpmnRenderer) {
const shape = bpmnRenderer.drawShape(parentNode, element)
const suitable = element.businessObject.suitable
let color = '#52B415'
if (suitable) {
if (suitable > 50) {
color = 'green'
}
if (suitable === 50) {
color = 'yellow'
}
if (suitable < 50) {
color = 'red'
}
}
if (is(element, 'bpmn:Task')) {
const height = 80
const width = 100
element.width = width
element.height = height
const rect = drawRect(parentNode, width, height, TASK_BORDER_RADIUS, color)
prependTo(rect, parentNode)
svgRemove(shape)
return shape
}
const rect = drawRect(parentNode, 30, 20, TASK_BORDER_RADIUS, color)
svgAttr(rect, {
transform: 'translate(-20, -10)'
})
return shape
}
// helpers //
// copied from https://github.com/bpmn-io/bpmn-js/blob/master/lib/draw/BpmnRenderer.js
function drawRect (parentNode, width, height, borderRadius, strokeColor) {
const rect = svgCreate('rect')
svgAttr(rect, {
width: width,
height: height,
rx: borderRadius,
ry: borderRadius,
stroke: strokeColor || '#000',
strokeWidth: 2,
fill: '#fff'
})
svgAppend(parentNode, rect)
return rect
}
// copied from https://github.com/bpmn-io/diagram-js/blob/master/lib/core/GraphicsFactory.js
function prependTo (newNode, parentNode, siblingNode) {
parentNode.insertBefore(newNode, siblingNode || parentNode.firstChild)
}