目录
前言:本章节讲述前端,后端没兴趣可以跳过
8.1 BPMNJS扩展 - BPMN下载
8.1.1 启动前端项目
启动后,会弹出 “http://localhost:9013/” 地址,但是因为端口与后端端口不一致,会产生跨域问题。所以我们使用后端启动项目,然后使用 “http://localhost:8080/bpmnjs/dist/index.html” 地址来访问前端项目,记得不能关闭 npm
- 启动步骤
- 使用 npm run dev 启动前端项目 (Don’t shut down)
- http://localhost:9013/
- IDEA 启动 ActivityApplication 的SpringBoot项目
- http://localhost:8080/bpmnjs/dist/index.html
- 使用 npm run dev 启动前端项目 (Don’t shut down)
8.1.2 在 index.html 添加导出按钮
src/main/resources/resources/bpmnjs/app/index.html
<!-- </ul>前面添加 -->
<li>
<a id="downloadBPMN" href>
导出
</a>
</li>
src/main/resources/resources/bpmnjs/resources/tools.js
import $ from 'jquery';
const proHost = window.location.protocol + "//" + window.location.host;
const href = window.location.href.split("bpmnjs")[0];
const key = href.split(window.location.host)[1];
const publicurl = proHost + key;
const tools = {
/**
* 下载bpmn
* @param {object} bpmnModeler bpmn对象
*/
download(bpmnModeler) {
const downloadLink = $("#downloadBPMN");
bpmnModeler.saveXML({format: true}, function (err, xml) {
if (err) {
return console.error('could not save BPMN 2.0 diagram', err);
}
tools.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml);
});
// alert("2222")
},
setEncoded(link, name, data) {
const encodedData = encodeURIComponent(data);
if (data) {
link.addClass('active').attr({
'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData,
'download': name
});
} else {
link.removeClass('active');
}
}
}
export default tools
src/main/resources/resources/bpmnjs/app/index.js
import tools from "../resources/tools";
// 导出BPMN
$("#downloadBPMN").on("click", function () {
tools.download(bpmnModeler);
// alert("1111")
})
8.1.3 效果图
http://localhost:8080/bpmnjs/dist/index.html
8.3 BPMNJS扩展 - BPMN在线部署
8.3.1 在 index.html 添加部署按钮
src/main/resources/resources/bpmnjs/app/index.html
<li>
<a id="saveBPMN" href>
部署
</a>
</li>
src/main/resources/resources/bpmnjs/resources/tools.js
saveBpmn(bpmnModeler) {
bpmnModeler.saveXML({format: true}, function (err, xml) {
if (err) {
return console.error('could not save bpmn', err);
}
console.log(xml)
var param = {
"stringBPMN": xml
}
$.ajax({
url: publicurl + 'processDefinition/addDeploymentByString',
type: 'POST',
dataType: "json",
data: param,
success: function (result) {
if (result.status === '0') {
alert('BPMN部署成功');
} else {
alert(result.msg);
}
},
error: function (err) {
alert(err);
}
});
});
},
http://localhost:8080/processDefinition/addDeploymentByString?stringBPMN=xxxxx
src/main/resources/resources/bpmnjs/app/index.js
$("#saveBPMN").on("click", function () {
tools.saveBpmn(bpmnModeler);
// alert("1111")
})
8.3.2 效果说明
- 随意画个 BPMN 图
- 然后点击“部署”按钮
- 复制控制台输出的 xml
PostMan 部署 XML
查看流程定义列表,看是否部署成功
8.4 BPMNJS扩展 - BPMN导入(后端方法)
8.4.1 后端编写上传文件的方法
src/main/java/com/edcode/activiti/controller/ProcessDefinitionController.java
/**
* 上传文件
* @param request
* @param multipartFile
* @return
*/
@PostMapping(value = "/upload")
public AjaxResponse upload(HttpServletRequest request,
@RequestParam("processFile") MultipartFile multipartFile) {
try {
// 判断是否有文件传入
if (multipartFile.isEmpty()) {
System.out.println("文件为空");
}
// 文件名
String fileName = multipartFile.getOriginalFilename();
// 后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
// 存储上传的 bpmn 文件路径
String filePath = "D:/Develop/Mine/IdeaProjects/springboot-activiti7/src/main/resources/resources/bpmn/";
// 新的文件名称
fileName = UUID.randomUUID() + suffixName;
// 如果配置文件指定目录,就可以直接这样写(不指定路径的,就需要自己填充保存路径)
File file = new File(filePath + fileName);
// 判断文件夹是否存在,不存在就创建
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try {
// 使用此方法保存必须要绝对路径且文件夹必须已存在,否则报错
multipartFile.transferTo(file);
} catch (IOException e) {
System.out.println("上传失败:" + e.getMessage());
}
return AjaxResponse.AjaxData(
GlobalConfig.ResponseCode.SUCCESS.getCode(),
GlobalConfig.ResponseCode.SUCCESS.getDesc(),
fileName);
} catch (Exception e) {
return AjaxResponse.AjaxData(
GlobalConfig.ResponseCode.ERROR.getCode(),
"上传文件失败",
e.toString());
}
}
8.4.1.1 使用 PostMan 测试上传
POST http://localhost:8080/processDefinition/upload
会发现项目里面有两个 1c64d01f-f89c-40ef-b778-cfd4798f48d6.bpmn
其中一个是刚刚吃上传的文件,另外一个 target 是 IDEA 在部署的时候出现的,如果你在浏览器输入 上传的文件路径,就会打开 target 目录下的 bpmn 文件
8.5 BPMNJS扩展-BPMN导入(前端Ajax)
8.5.1 在 index.html 添加导入按钮
src/main/resources/resources/bpmnjs/app/index.html
<li>
<form id="form1" name="myForm" onsubmit="return false" method="post" enctype="multipart/form-data" title="上传文件">
<input type="file" name="uploadFile" id="uploadFile" accept=".bpmn" style="display: none">
<label class="label" for="uploadFile" >导入</label>
</form>
</li>
src/main/resources/resources/bpmnjs/app/index.js
// 导入BPMN,浏览器查看
$("#uploadFile").on("change", function () {
// alert("1111")
tools.uploadBPMN(bpmnModeler);
})
src/main/resources/resources/bpmnjs/resources/tools.js
/**
* 上传bpmn
* @param {object} bpmnModeler bpmn对象
*/
uploadBPMN(bpmnModeler) {
const FileUpload = document.myForm.uploadFile.files[0];
const fm = new FormData();
fm.append('processFile', FileUpload);
console.log("2222")
$.ajax({
url: publicurl + 'processDefinition/upload',
type: 'POST',
data: fm,
async: false,
contentType: false, //禁止设置请求类型
processData: false, //禁止jquery对DAta数据的处理,默认会处理
success: function (result) {
const url = publicurl + 'bpmn/' + result.obj; //路径+文件名
tools.openFromUrl(bpmnModeler, url)
},
error: function (err) {
console.log(err)
}
});
},
openFromUrl(bpmnModeler, url) {
$.ajax(url, {
dataType: 'text'
}).done(async function (xml) {
try {
await bpmnModeler.importXML(xml);
} catch (e) {
console.error(e);
}
})
},
8.5.2 效果说明
点击“导入”按钮,选择需要打开的BPMN文件
上传完成后,web页面就会显示BPMN图
> src/main/resources/resources/bpmn/xxx.bpmn 也会出现对应的bpmn文件
8.6 BPMNJS扩展-查看与高亮历史
前端童靴可以研究下,也是调用后端高亮接口
8.7 layuimini部署 (后端管理)
- GitHub发版地址:https://github.com/zhongshaofa/layuimini/releases
- Gitee发版地址:https://gitee.com/zhongshaofa/layuimini/releases
8.7.1 layuimini 操作流程
- 从 github 或 gitee 下载 (gitee下载更快)
- 解压后文件夹目录叫 layuimini
- http://localhost:8080/layuimini/page/login-1.html
- 登录页面修改
- 在js/lay-config.js配置全局变量html页面引入
- lnit.json菜单
- 创建菜单对应页面
- 页面功能开发
8.7.2 layuimini 下载与初次启动
- 解压后,layuimini-v2 文件夹,需要改名:layuimini
- 拖动到 src/main/resources/resources/ 目录下
- 访问:http://localhost:8080/layuimini/page/login-1.html
8.8 重置登录页面
8.8.1 获取URL地址
src/main/resources/resources/layuimini/js/lay-config.js
const proHost = window.location.protocol + "//" + window.location.host;
const href = window.location.href.split("layuimini")[0];
const key = href.split(window.location.host)[1];
const publicurl = proHost + key;
var userName = localStorage.getItem('userName')
8.8.2 通过 Ajax 请求后端
src/main/resources/resources/layuimini/page/login-1.html
// layer.msg('登录成功', function () {
// window.location = '../index.html';
// });
const fd = new FormData();
fd.append('username', data.username)
fd.append('password', data.password)
$.ajax({
cache: true,
type: "post",
url: '' + publicurl + 'login',
async: false,
data: fd,
contentType: false,
processData: false,
success: function (res) {
layer.msg('登录成功', function () {
localStorage.setItem('userName', res.obj);
window.location = '../index.html'
});
},
error: function (err) {
layer.alert(err.responseJSON.obj, {
icon: 2,
title: "提示"
});
}
});
请求 spring security 的 /login 登录的方法
com.edcode.activiti.controller.ActivitiSecurityController#requireAuthentication
8.8.3 使用浏览器测试
输入错误的用户
输入正确的用户
8.9 新增左则的列表页面
8.9.1 修改退出登录成功显示页面
src/main/resources/resources/layuimini/index.html
$('.login-out').on("click", function () {
layer.msg('退出登录成功', function () {
window.location = 'page/login-1.html';
});
});
8.9.2 创建流程部署列表的Sheet
左则列表,都是使用json格式存放在这个路径下
src/main/resources/resources/layuimini/api/init.json
// 省略...
"menuInfo": [
{
"title": "常规管理",
"icon": "fa fa-address-book",
"href": "",
"target": "_self",
"child": [
{
"title": "流程部署列表",
"href": "page/ProcessDeployments.html",
"icon": "fa fa-file-text",
"target": "_self"
},
// 省略...
8.9.3 新建 ProcessDeployments.html
- 复制 src/main/resources/resources/layuimini/page/table.html
- 拷贝改名 src/main/resources/resources/layuimini/page/ProcessDeployments.html
引入依赖
<script src="../lib/jquery-3.4.1/jquery-3.4.1.min.js" charset="utf-8"></script>
<script src="../js/lay-config.js?v=2.0.0" charset="utf-8"></script>
table 标签 60行, currentTableId 修改 ProcessDeploymentsTableID
<table class="layui-hide" id="ProcessDeploymentsTableID" lay-filter="currentTableFilter"></table>
88 行,currentTableId 修改 ProcessDeploymentsTableID,并且把请求获取流程定义列表
// 省略...
table.render({
elem: '#ProcessDeploymentsTableID',
url: '' + publicurl + 'processDefinition/getDefinitions', // 获取流程定义列表
toolbar: '#toolbarDemo',
defaultToolbar: [],
parseData: function (res) {
return {
"code": res.status,
"msg": res.msg,
"count": res.obj.length,
"data": res.obj
};
},
cols: [[
{type: "checkbox", width: '5%'},
{field: 'deploymentID', width: '20%', title: '编号', sort: true},
{field: 'name', width: '20%', title: '流程名称'},
{field: 'resourceName', width: '20%', title: '文件名称', sort: true},
{field: 'key', width: '20%', title: 'Key'},
{field: 'version', title: '版本', width: '10%'},
{title: '操作', minWidth: '20%', toolbar: '#currentTableBar', align: "center"}
]],
// 省略...
全局查询搜索“toolbar监听事件”找到 add 方法,修改成如下
// 省略...
/**
* toolbar监听事件
*/
table.on('toolbar(currentTableFilter)', function (obj) {
if (obj.event === 'add') { // 监听添加操作
window.open(''+publicurl+'bpmnjs/dist/index.html?type=addBpmn') // 跳转到 BPMN-JS 页面
} else if (obj.event === 'delete') { // 监听删除操作
var checkStatus = table.checkStatus('currentTableId')
, data = checkStatus.data;
layer.alert(JSON.stringify(data));
}
});
// 省略...
8.9.4 效果图
如果不显示左边sheet的显示问题,是因为读取的是 target 目录下的文件,解决方法:可以停止项目,使用Maven clean, 然后在启动