365 lines
15 KiB
JavaScript
365 lines
15 KiB
JavaScript
$(function(){
|
|
if (methodId != 'process.subprocess') { // 如果当前打开的模型不是端到端总图 那么整个js也没有执行的必要
|
|
return;
|
|
}
|
|
// 1. 子流程展开 事件:获取当前子流程所代表的模型文件
|
|
// (function (Model, ruuid, sid) {
|
|
// })(Model, ruuid, sid);
|
|
|
|
const subProcess = new SubProcess(Model, ruuid, sid);
|
|
|
|
subProcess.init();
|
|
|
|
window.subProcess = subProcess;
|
|
});
|
|
|
|
class SubProcess {
|
|
// 构造函数
|
|
constructor(Model, ruuid, sid){
|
|
this.Model = Model;
|
|
this.repositoryId = ruuid;
|
|
this.sid = sid;
|
|
this.scopeEle = {}; // 范围框元素以及其内部元素
|
|
this.movingEle = null; // 范围框内移动中的元素
|
|
this.scopeRang = null; // 范围限制框左右两边以及上下两边的坐标 x1 x2 y1 y2
|
|
}
|
|
|
|
init(){
|
|
this.shapeIconRender();
|
|
this.handleScopeShapeEvent();
|
|
this.linkerBoxPointerEvent();
|
|
this.scopeShapeRenderTitle(this.Model.define.elements)
|
|
}
|
|
|
|
linkerBoxPointerEvent(){
|
|
// 连线框 鼠标指针样式设置 防止因为连线z-index层级较高 会导致节点展开图标点击不到
|
|
$('.shape_box.linker_box').css({
|
|
'pointer-events': 'none'
|
|
});
|
|
}
|
|
|
|
// 图形图标渲染 并绑定节点展开或者关闭事件
|
|
shapeIconRender(){
|
|
let elements = this.Model.define.elements;
|
|
for (let shapeId in elements) {
|
|
let shape = elements[shapeId];
|
|
if (shape.name == 'linker') continue; // 当前元素为连线的话 直接略过
|
|
if (shape.name == 'scopeLimitation' || shape.name == 'subProcess'){ // 只有子流程或者范围选择框才有对应的图标渲染
|
|
if (shape.name == 'subProcess') { // 当前元素为子流程节点 渲染展开图标 并绑定展开事件
|
|
let expandIcon = "<span id='icon_"+shapeId+"' class='iconfont icon-zhankaishousuo' style='position: absolute;cursor: pointer;'></span>";
|
|
$('#'+shapeId).append(expandIcon);
|
|
$('#icon_'+shapeId).on('click', '', {shapeId: shapeId, Model: this.Model, repositoryId: this.repositoryId, sid: this.sid}, this.shapeExpand);
|
|
}else { // 当前元素为虚线范围限制框的话 渲染关闭图标 并绑定关闭事件
|
|
let closeIcon = "<span id='icon_"+shapeId+"' class='iconfont icon-quanpingshouqi' style='position: absolute;cursor: pointer;'></span>";
|
|
$('#'+shapeId).append(closeIcon);
|
|
$('#icon_'+shapeId).on('click', '', {shapeId: shapeId, Model: this.Model, repositoryId: this.repositoryId, sid: this.sid}, this.shapeClose);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 子流程节点拖拽到画布后 渲染展开按钮
|
|
shapeOpenIconRender(ele){
|
|
if (ele.name != 'subProcess'){
|
|
return;
|
|
}
|
|
let shapeId = ele.id;
|
|
let expandIcon = "<span id='icon_"+shapeId+"' class='iconfont icon-zhankaishousuo' style='position: absolute;cursor: pointer;'></span>";
|
|
$('#'+shapeId).append(expandIcon);
|
|
$('#icon_'+shapeId).on('click', '', {shapeId: shapeId, Model: this.Model, repositoryId: this.repositoryId, sid: this.sid}, this.shapeExpand);
|
|
}
|
|
|
|
// 范围选择框的事件绑定处理
|
|
handleScopeShapeEvent(){
|
|
let c = $("#designer_canvas");
|
|
c.off("mousemove").on("mousemove",function (a) {
|
|
let b = Utils.getRelativePos(a.pageX, a.pageY, c); // 实时获取鼠标移动的坐标
|
|
let j = Utils.getShapeByPosition(b.x, b.y); // 根据鼠标当前移动的位置获取当前图形 如果有的话
|
|
// console.log("当前图形", j);
|
|
if (j != null) {
|
|
if (j.shape.name == 'scopeLimitation'){
|
|
let range = {
|
|
x: j.shape.props.x,
|
|
y: j.shape.props.y,
|
|
w: j.shape.props.w,
|
|
h: j.shape.props.h
|
|
};
|
|
let e = Utils.getShapesByRange(range);
|
|
e = e.filter(id => Model.getShapeById(id).elementType !== "OUTER_NODE").filter(id => Model.getShapeById(id).elementType !== "OUTER_LINKER"); // 因为范围框人工改变大小后 可能包含外部元素
|
|
// 将当前范围选择框元素以及范围内的元素 存储到subProcess中 方便后续 范围框内的元素移动时做范围框限制
|
|
window.subProcess.scopeEle[j.shape.id] = e;
|
|
$('#'+j.shape.id).off("mousedown").on("mousedown", function (f) {
|
|
Utils.unselect();
|
|
Utils.selectShape(e);
|
|
});
|
|
}else {
|
|
// console.log('范围标注框的图形是否存了下来', window.subProcess.scopeEle);
|
|
let scopeEle = window.subProcess.scopeEle;
|
|
for (const scopeShapeId in scopeEle) {
|
|
let inRangeEles = scopeEle[scopeShapeId];
|
|
if (inRangeEles.indexOf(j.shape.id) != -1){ // 当前鼠标所在位置为范围选择框范围内
|
|
Utils.unselect();
|
|
let currentScopeEle = Model.getShapeById(scopeShapeId); // 获取当前范围选择框
|
|
let bound = {
|
|
x: currentScopeEle.props.x,
|
|
y: currentScopeEle.props.y,
|
|
w: currentScopeEle.props.w,
|
|
h: currentScopeEle.props.h
|
|
};
|
|
let rang = {
|
|
x1: bound.x,
|
|
y1: bound.y,
|
|
x2: bound.x + bound.w,
|
|
y2: bound.y + bound.h
|
|
};
|
|
|
|
window.subProcess.scopeRang = rang;
|
|
window.subProcess.movingEle = Model.getShapeById(j.shape.id);
|
|
}
|
|
}
|
|
}
|
|
}else {
|
|
window.subProcess.movingEle = null;
|
|
window.subProcess.scopeRang = null;
|
|
}
|
|
});
|
|
}
|
|
|
|
// 节点展开事件
|
|
shapeExpand(event){
|
|
let param = event.data;
|
|
// alert('节点展开事件 ' + param.Model.define.elements[event.data.shapeId].text);
|
|
// 1、同时只能支持一个子流程节点展开
|
|
let elements = param.Model.define.elements;
|
|
let shapeText = ''; // 当前要展开的节点文本
|
|
for (let key in elements) {
|
|
let shape = elements[key];
|
|
if (shape.name == 'linker') continue;
|
|
if (key == param.shapeId){
|
|
shapeText = shape.text;
|
|
}
|
|
}
|
|
if (window.subProcess.checkLayoutIsReasonable()){
|
|
return;
|
|
}
|
|
// 2、传递当前模型文件ID、子流程节点ID
|
|
awsui.ajax.request({
|
|
url: './jd',
|
|
method: 'POST',
|
|
data: {
|
|
cmd: 'com.actionsoft.apps.coe.method.process.subprocess.shape_expand',
|
|
sid: param.sid,
|
|
repositoryId: param.repositoryId,
|
|
shapeId: param.shapeId,
|
|
endToEndProcessDefineStr: JSON.stringify(param.Model.define)
|
|
},
|
|
ok: function(r){
|
|
// console.log(JSON.stringify(r.data));
|
|
definition.elements = r.data.elements;
|
|
definition.page = r.data.page;
|
|
Designer.open(definition); // 节点重新渲染
|
|
// 针对范围标识框渲染 节点关闭按钮
|
|
window.subProcess.shapeIconRender();
|
|
window.subProcess.linkerBoxPointerEvent();
|
|
window.subProcess.scopeShapeRenderTitle(r.data.elements);
|
|
// 提示用户文件已修改
|
|
window.subProcess.fileModifiedTip();
|
|
},
|
|
err: function(r){
|
|
}
|
|
});
|
|
// 3、刷新当前画布
|
|
}
|
|
|
|
scopeShapeRenderTitle(elements){
|
|
for (let key in elements) {
|
|
let element = elements[key];
|
|
if (element.name == 'linker') continue;
|
|
if (element.name == 'scopeLimitation'){ // 范围标识框
|
|
let titleHtml = "<span style='position: absolute; left: 35px; top: 25px;'>"+element.relationFileName+"</span>";
|
|
$('#'+key).prepend(titleHtml);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 节点关闭事件
|
|
shapeClose(event){
|
|
// console.log('sss');
|
|
if (window.subProcess.checkLayoutIsReasonable()){
|
|
return;
|
|
}
|
|
let param = event.data;
|
|
awsui.ajax.request({
|
|
url: './jd',
|
|
method: 'POST',
|
|
data: {
|
|
cmd: 'com.actionsoft.apps.coe.method.process.subprocess.shape_close',
|
|
sid: param.sid,
|
|
repositoryId: param.repositoryId,
|
|
shapeId: param.shapeId,
|
|
endToEndProcessDefineStr: JSON.stringify(param.Model.define)
|
|
},
|
|
ok: function (r) {
|
|
definition.elements = r.data.elements;
|
|
definition.page = r.data.page;
|
|
Designer.open(definition); // 节点重新渲染
|
|
|
|
// 针对范围标识框渲染 节点关闭按钮
|
|
window.subProcess.shapeIconRender();
|
|
window.subProcess.linkerBoxPointerEvent();
|
|
// 提示用户文件已修改
|
|
window.subProcess.fileModifiedTip();
|
|
},
|
|
err: function (r) {
|
|
|
|
}
|
|
});
|
|
}
|
|
|
|
// 一键展开或闭合
|
|
oneClickOperate(action){
|
|
if (window.subProcess.checkLayoutIsReasonable()){
|
|
return;
|
|
}
|
|
// console.log('oneClickExpand',this);
|
|
awsui.ajax.request({
|
|
url: './jd',
|
|
method: 'POST',
|
|
data: {
|
|
cmd: 'com.actionsoft.apps.coe.method.process.subprocess.shape_one_click',
|
|
sid: this.sid,
|
|
action: action,
|
|
repositoryId: this.repositoryId,
|
|
define: JSON.stringify(this.Model.define)
|
|
},
|
|
ok: function (r){
|
|
definition.elements = r.data.elements;
|
|
definition.page = r.data.page;
|
|
Designer.open(definition); // 节点重新渲染
|
|
|
|
// 针对范围标识框渲染 节点关闭按钮
|
|
window.subProcess.shapeIconRender();
|
|
window.subProcess.linkerBoxPointerEvent();
|
|
if (action == 'expand') {
|
|
window.subProcess.scopeShapeRenderTitle(r.data.elements);
|
|
}
|
|
// 提示用户文件已修改
|
|
window.subProcess.fileModifiedTip();
|
|
}
|
|
});
|
|
}
|
|
|
|
// 是否显示一键展开或者一键关闭
|
|
oneClickExpandAndCloseIconShow(){
|
|
let showExpandFlag = false;
|
|
let showCloseFlag = false;
|
|
let elements = this.Model.define.elements;
|
|
awsui.ajax.request({
|
|
url: './jd',
|
|
method: 'POST',
|
|
async: false,
|
|
data: {
|
|
cmd: 'com.actionsoft.apps.coe.method.process.subprocess.shape_expand_and_close_icon_show',
|
|
sid: this.sid,
|
|
repositoryId: this.repositoryId,
|
|
elements: JSON.stringify(elements)
|
|
},
|
|
ok: function (r) {
|
|
let menu = $("#designer_contextmenu");
|
|
if (r.data.showExpandFlag){
|
|
menu.children("li[ac=oneClickExpand]").show();
|
|
}
|
|
if (r.data.showCloseFlag){
|
|
menu.children("li[ac=oneClickClose]").show();
|
|
}
|
|
},
|
|
err: function (r) {
|
|
$.simpleAlert(r.msg);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 文件修改提示
|
|
fileModifiedTip(){
|
|
if (isAutoSave == "0") {
|
|
$("#saving_tip").css("color", "rgb(255, 0, 0)");
|
|
$("#saving_tip").text("文件已修改,未保存");
|
|
}
|
|
}
|
|
|
|
// 节点展开或者闭合前 检查布局是否合理
|
|
checkLayoutIsReasonable(){
|
|
let result = false;
|
|
let elements = Model.define.elements;
|
|
for (let key in elements) {
|
|
let ele = elements[key];
|
|
if (ele.elementType == "SCOPE_NODE"){ // 如果存在范围框
|
|
let eleInRange = this.getShapesByRange(ele.props); // 获取此时范围框内部元素
|
|
if (eleInRange.length > 0){
|
|
let outerNodeIndex = eleInRange.findIndex(id => Model.getShapeById(id).elementType == "OUTER_NODE");
|
|
let outerLinerIndex = eleInRange.findIndex(id => Model.getShapeById(id).elementType == "OUTER_LINKER");
|
|
if (outerLinerIndex != -1 || outerNodeIndex != -1){
|
|
$.simpleAlert("当前布局不合理,范围框内包含了外部元素!");
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// 获取范围内元素 只要部分包含也算在内
|
|
getShapesByRange(range, elements){
|
|
let g = [];
|
|
for (let h in Model.define.elements) {
|
|
let f = Model.getShapeById(h);
|
|
let i = [];
|
|
if (f.name == "linker") {
|
|
i = [...f.points];
|
|
i.push({x: f.from.x, y: f.from.y});
|
|
i.push({x: f.to.x, y: f.to.y});
|
|
} else {
|
|
i.push({x: f.props.x, y: f.props.y});
|
|
i.push({x: f.props.x + f.props.w, y: f.props.y});
|
|
i.push({x: f.props.x + f.props.w, y: f.props.y + f.props.h});
|
|
i.push({x: f.props.x, y: f.props.y + f.props.h});
|
|
}
|
|
if (this.pointInRect(i, range)) {
|
|
g.push(f.id)
|
|
}
|
|
}
|
|
return g
|
|
}
|
|
|
|
pointInRect(points, range){
|
|
for (let point of points) {
|
|
if (range.x < point.x && point.x < range.x + range.w && range.y < point.y && point.y < range.y + range.h) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 根据当前元素的坐标设置元素类型
|
|
calculateShapeElementType(shape){
|
|
let elementType = "OUTER_NODE"; // 默认指定外部节点
|
|
let props = shape.props;
|
|
let elements = Model.define.elements;
|
|
for (let key in elements) {
|
|
let ele = elements[key];
|
|
if (ele.elementType == "SCOPE_NODE"){ // 查找范围框元素
|
|
let scopeX = ele.props.x;
|
|
let scopeY = ele.props.y;
|
|
let scopeW = ele.props.w;
|
|
let scopeH = ele.props.h;
|
|
if (scopeX < props.x && props.x < scopeX + scopeW && scopeY < props.y && props.y < scopeY + scopeH){
|
|
elementType = "INNER_NODE";
|
|
}
|
|
}
|
|
}
|
|
return elementType;
|
|
}
|
|
}
|
|
|