diff --git a/com.actionsoft.apps.coe.method.process.subprocess/lib/com.actionsoft.apps.coe.method.process.subprocess.jar b/com.actionsoft.apps.coe.method.process.subprocess/lib/com.actionsoft.apps.coe.method.process.subprocess.jar index bcfd6f8b..3b6cf982 100644 Binary files a/com.actionsoft.apps.coe.method.process.subprocess/lib/com.actionsoft.apps.coe.method.process.subprocess.jar and b/com.actionsoft.apps.coe.method.process.subprocess/lib/com.actionsoft.apps.coe.method.process.subprocess.jar differ diff --git a/com.actionsoft.apps.coe.method.process.subprocess/method/process.subprocess/diagram.attribute.xml b/com.actionsoft.apps.coe.method.process.subprocess/method/process.subprocess/diagram.attribute.xml index 06aa21e8..82a67e0c 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/method/process.subprocess/diagram.attribute.xml +++ b/com.actionsoft.apps.coe.method.process.subprocess/method/process.subprocess/diagram.attribute.xml @@ -51,4 +51,5 @@ + diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/ElementType.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/ElementType.java new file mode 100644 index 00000000..f1402402 --- /dev/null +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/ElementType.java @@ -0,0 +1,28 @@ +package com.actionsoft.apps.coe.method.process.subprocess.constant; + +/** + * @author oYang + * @Description 端到端模型中 用来区分元素类别是外部元素还是内部元素 + * @createTime 2023年06月26日 14:36:00 + */ +public enum ElementType { + + SCOPE_NODE("scopeNode", "范围标识框节点"), + INNER_NODE("innerNode","内部节点"), + OUTER_NODE("outerNode","外部节点"), + INNER_LINKER("innerLinker","内部连线"), + OUTER_LINKER("outerLinker","外部连线"), + CROSS_LINKER("crossLinker","跨越范围标识框的连线"); + + private final String value; + private final String label; + + ElementType(String value, String label) { + this.value = value; + this.label = label; + } + + public String getValue() { + return value; + } +} diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/LinkerDefConstant.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/LinkerDefConstant.java index 302da2e3..05d0bc6c 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/LinkerDefConstant.java +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/LinkerDefConstant.java @@ -10,4 +10,9 @@ public class LinkerDefConstant { public static final String linker = "{\"fontStyle\":{\"fontFamily\":\"Arial\",\"size\":13,\"color\":\"50,50,50\",\"underline\":false,\"textAlign\":\"center\",\"bold\":false,\"italic\":false},\"points\":[],\"dataAttributes\":[{\"shapeDesc\":\"\",\"name\":\"AWSProperties\",\"id\":\"AWSPropertiesID\",\"type\":\"string\",\"category\":\"default\",\"value\":\"\"}],\"props\":{\"zindex\":0},\"linkerType\":\"broken\",\"lineStyle\":{\"lineStyle\":\"solid\",\"lineColor\":\"50,50,50\",\"beginArrowStyle\":\"none\",\"endArrowStyle\":\"solidArrow\",\"lineWidth\":1},\"name\":\"linker\",\"orderIndex\":0,\"from\":{\"x\":0,\"y\":0,\"angle\":0,\"id\":\"\"},\"id\":\"\",\"text\":\"\",\"to\":{\"x\":0,\"y\":0,\"angle\":0,\"id\":\"\"},\"locked\":false,\"group\":\"\"}"; + + // 总图中节点展开后的连线分类标识 节点展开后的内部连线元素 + public static final String LINKER_CATEGORY_INNER = "inner"; + // 总图中节点展开后的连线分类标识 节点展开后的外部连线元素 + public static final String LINKER_CATEGORY_OUTER = "outer"; } diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/SubProcessConst.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/SubProcessConst.java index 0c773c73..b2d0510c 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/SubProcessConst.java +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/constant/SubProcessConst.java @@ -23,6 +23,8 @@ public interface SubProcessConst { // 形状属性 子流程模型节点 String CHILD_PROCESS = "child_process"; + // 形状属性 关联架构 + String RELATION_FRAMEWORK = "relation_framework"; // 子流程图形宽度 double SUB_PROCESS_SHAPE_W = 100.0; diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeCloseHandle.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeCloseHandle.java index 3230a2c3..60c07541 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeCloseHandle.java +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeCloseHandle.java @@ -1,5 +1,6 @@ package com.actionsoft.apps.coe.method.process.subprocess.graph; +import com.actionsoft.apps.coe.method.process.subprocess.constant.ElementType; import com.actionsoft.apps.coe.method.process.subprocess.constant.LinkerDefConstant; import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst; import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractAdjMatrix; @@ -111,6 +112,7 @@ public class GraphNodeCloseHandle { JSONArray linkers = linkerRender.toAssembleLinker(direction); for (Object o : linkers) { JSONObject linker = (JSONObject) o; + linker.put("elementType", ElementType.OUTER_LINKER.name()); definitionHandle.addEle(linker.getString("id"), linker); } @@ -299,6 +301,8 @@ public class GraphNodeCloseHandle { subProcessNodeProps.put("zindex", scopeLimitationShape.getJSONObject("props").getIntValue("zindex")); subProcessNode.put("text", PALRepositoryCache.getCache().get(relationFileId).getName()); + subProcessNode.put("elementType", ElementType.OUTER_NODE.name()); + subProcessNode.put("dataAttributes", scopeLimitationShape.getJSONArray("dataAttributes")); return subProcessNode; } diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeExpandHandle.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeExpandHandle.java index 06636587..7f04417a 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeExpandHandle.java +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphNodeExpandHandle.java @@ -1,5 +1,6 @@ package com.actionsoft.apps.coe.method.process.subprocess.graph; +import com.actionsoft.apps.coe.method.process.subprocess.constant.ElementType; import com.actionsoft.apps.coe.method.process.subprocess.constant.LinkerDefConstant; import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst; import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractAdjMatrix; @@ -102,6 +103,16 @@ public class GraphNodeExpandHandle { scopeLimitationShape.put("relationFileName", PALRepositoryCache.getCache().get(relationFileId).getName()); + scopeLimitationShape.put("elementType", ElementType.SCOPE_NODE.name()); + + // 计算当前范围框的最小范围 方便在设计器画布中 针对范围框大小改变做判断 + JSONObject minRange = new JSONObject(); + minRange.put("x1", x); + minRange.put("y1", y); + minRange.put("x2", x + scope[2]); + minRange.put("y2", y + scope[3]); + scopeLimitationShape.put("minRange", minRange); + this.scopeLimitationShape = scopeLimitationShape; // 通知其它节点位置更新 @@ -165,6 +176,7 @@ public class GraphNodeExpandHandle { JSONArray linkers = linkerRender.toAssembleLinker(direction); for (Object o : linkers) { JSONObject linker = (JSONObject) o; + linker.put("elementType", ElementType.OUTER_LINKER.name()); definitionHandle.addEle(linker.getString("id"), linker); } @@ -209,10 +221,14 @@ public class GraphNodeExpandHandle { point.put("x", point.getDoubleValue("x") + distanceX); point.put("y", point.getDoubleValue("y") + distanceY); } + + ele.put("elementType", ElementType.INNER_LINKER.name()); }else { // 图形 JSONObject props = ele.getJSONObject("props"); props.put("x", distanceX + props.getDoubleValue("x")); props.put("y", distanceY + props.getDoubleValue("y")); + + ele.put("elementType", ElementType.INNER_NODE.name()); } definitionHandle.addEle(key, ele); diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphRender.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphRender.java index 7122ff6d..8ce372f3 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphRender.java +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/GraphRender.java @@ -1,5 +1,6 @@ package com.actionsoft.apps.coe.method.process.subprocess.graph; +import com.actionsoft.apps.coe.method.process.subprocess.constant.ElementType; import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst; import com.actionsoft.apps.coe.method.process.subprocess.mode.Node; import com.actionsoft.apps.coe.pal.pal.method.PALMethodManager; @@ -76,6 +77,8 @@ public class GraphRender { subProcessNodeProps.put("y", position[i][1]); subProcessNodeProps.put("zindex", zIndex++); subProcessNode.put("text", repositoryModel.getName()); + // 增加元素类型属性 + subProcessNode.put("elementType", ElementType.OUTER_NODE.name()); // 处理子流程模型节点形状属性 JSONArray dataAttributes = subProcessNode.getJSONArray("dataAttributes"); @@ -86,7 +89,7 @@ public class GraphRender { List attributes = PALMethodCache.getPALMethodModelById(SubProcessConst.SUB_PROCESS_METHOD_ID).getAttributes(); Optional optional = attributes.stream().filter(attr -> attr.getKey().equals(SubProcessConst.CHILD_PROCESS)).findFirst(); if (!optional.isPresent()) - throw new AWSException("端到端总图中子流程节点上需配置子流程标识属性"); + throw new AWSException("端到端总图中子流程节点上需配置【子流程模型】形状属性"); PALMethodAttributeModel attributeModel = optional.get(); JSONObject data = new JSONObject(); data.put("isRequired", attributeModel.getIsRequired()); @@ -101,9 +104,33 @@ public class GraphRender { data.put("key", attributeModel.getKey()); data.put("desc", attributeModel.getDesc()); attributesJsonArr.add(data); + + PALMethodAttributeModel relaionFrameAttributeModel = attributes.stream().filter(attr -> attr.getKey().equals(SubProcessConst.RELATION_FRAMEWORK)).findFirst().orElse(null); + if (relaionFrameAttributeModel == null) + throw new AWSException("端到端总图中子流程节点上需配置【关联架构】形状属性"); + JSONObject dataFrame = new JSONObject(); + dataFrame.put("isRequired", relaionFrameAttributeModel.getIsRequired()); + dataFrame.put("ref", relaionFrameAttributeModel.getRef()); + dataFrame.put("readonly", relaionFrameAttributeModel.getReadonly()); + dataFrame.put("scope", relaionFrameAttributeModel.getScope()); + dataFrame.put("name", relaionFrameAttributeModel.getNewTitle()); + dataFrame.put("id", relaionFrameAttributeModel.getKey()); + dataFrame.put("type", relaionFrameAttributeModel.getType()); + dataFrame.put("value", ""); + dataFrame.put("groupPath", relaionFrameAttributeModel.getGroupPath()); + dataFrame.put("key", relaionFrameAttributeModel.getKey()); + dataFrame.put("desc", relaionFrameAttributeModel.getDesc()); + attributesJsonArr.add(dataFrame); } } - handleShapeAttrChildSubProcess(nodeId, repositoryModel.getName(), nodeList.get(i).getId()); + + // 处理总图中子流程节点的形状属性【子流程模型】 + handleShapeAttrChildSubProcess(nodeId, repositoryModel.getName(), nodeList.get(i).getId(), SubProcessConst.CHILD_PROCESS); + + // 处理总图中子流程节点的形状属性【关联架构】 + if (repositoryModel.getParentId().length() == 36){ + handleShapeAttrChildSubProcess(nodeId, repositoryModel.getName(), repositoryModel.getParentId(), SubProcessConst.RELATION_FRAMEWORK); + } elements.put(nodeId, subProcessNode); } @@ -112,14 +139,14 @@ public class GraphRender { CoeDesignerAPIManager.getInstance().storeDefinition(this.baseModel); } - private void handleShapeAttrChildSubProcess(String shapeId, String shapeText, String relationFileId){ + private void handleShapeAttrChildSubProcess(String shapeId, String shapeText, String relationFileId, String arrtId){ DesignerShapeRelationDao shapeRelationDao = new DesignerShapeRelationDao(); DesignerShapeRelationModel relationModel = new DesignerShapeRelationModel(); relationModel.setId(UUIDGener.getUUID()); relationModel.setFileId(repositoryModel.getId()); relationModel.setShapeId(shapeId); relationModel.setShapeText(shapeText); - relationModel.setAttrId(SubProcessConst.CHILD_PROCESS); + relationModel.setAttrId(arrtId); relationModel.setRelationFileId(relationFileId); shapeRelationDao.insert(relationModel); } @@ -143,6 +170,9 @@ public class GraphRender { String toId = idMap.get(toObj.getString("id")); toObj.put("id", toId); String linkerId = linker.getString("id"); + + linker.put("elementType", ElementType.OUTER_LINKER.name()); + elements.put(linkerId, linker); } diff --git a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.core.js b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.core.js index 7d1ba52f..7a09958e 100755 --- a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.core.js +++ b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.core.js @@ -1407,11 +1407,39 @@ var Designer = { shapes: W, dir: N }); + // 端到端功能 start + let currentEleIsScope = false; // 当前元素是否为范围框 + let eleInRange = []; // 存储当前范围框内部元素 + let currentScopeRange = {}; + if (methodId == 'process.subprocess'){ // 当前建模类型为端到端 + let index = W.findIndex(ele => ele.elementType == "SCOPE_NODE"); + if (index != -1){ + currentEleIsScope = true; + let scopeShape = W[index]; + currentScopeRange = { // 获取范围框初始范围大小 + x: scopeShape.minRange.x1, + y: scopeShape.minRange.y1, + w: scopeShape.minRange.x2 - scopeShape.minRange.x1, + h: scopeShape.minRange.y2 - scopeShape.minRange.y1 + }; + eleInRange = Utils.getShapesByRange(currentScopeRange); + eleInRange = eleInRange.filter(id => id != scopeShape.id); // 过滤掉范围框本身 + } + } + // 端到端功能 end S.bind("mousemove.resize", function (a) { F = []; var t = Utils.getRelativePos(a.pageX, a.pageY, Y); t = Utils.restoreScale(t); + // 端到端功能 start + if (methodId == 'process.subprocess' && currentScopeRange){ // 如果是端到端建模方法 并且选中的是范围框 + if ((currentScopeRange.x < t.x && t.x < currentScopeRange.x + currentScopeRange.w) || (currentScopeRange.y < t.y && t.y < currentScopeRange.y + currentScopeRange.h)){ + $.simpleAlert("当前范围标识框已是最小范围!"); + return; + } + } + // 端到端功能 end var k = Utils.getRotated(E, t, -M.angle); var w = Utils.copy(M); if (N.indexOf("r") >= 0) { @@ -1500,6 +1528,14 @@ var Designer = { Utils.removeAnchors(); for (var e = 0; e < W.length; e++) { var u = W[e]; + // 端到端功能 start + if (currentEleIsScope){ // 如果当前元素为范围框的话 + // 找到范围框内部元素 跳过不处理 + if (eleInRange.indexOf(u.id) != -1){ + continue; + } + } + // 端到端功能 end var j = ac[u.id]; if (u.name == "linker") { if (j.from.type == "box") { @@ -1846,8 +1882,23 @@ var Designer = { var k = Utils.getSelectedIds(); Utils.mergeArray(e, k) } + let flag = false; + if (methodId == "process.subprocess" && e.length > 0){ + let scopeIndex = e.findIndex(shapeId => Model.getShapeById(shapeId).elementType == "SCOPE_NODE"); + let innerNodeIndex = e.findIndex(shapeId => Model.getShapeById(shapeId).elementType == "INNER_NODE"); + let innerLinkerIndex = e.findIndex(shapeId => Model.getShapeById(shapeId).elementType == "INNER_LINKER"); + let outerNodeIndex = e.findIndex(shapeId => Model.getShapeById(shapeId).elementType == "OUTER_NODE"); + let outerLinkerIndex = e.findIndex(shapeId => Model.getShapeById(shapeId).elementType == "OUTER_LINKER"); + // 选中的元素中 同时出现范围框或者其内部元素以及外部元素 + if ((scopeIndex != -1 || innerNodeIndex != -1 || innerLinkerIndex != -1) && (outerNodeIndex != -1 || outerLinkerIndex != -1)){ + flag = true; + $.simpleAlert("范围框以及其内部元素不能与范围框外部元素同时被选中!"); + } + } Utils.unselect(); - Utils.selectShape(e); + if (!flag){ + Utils.selectShape(e); + } b.remove() } Designer.op.resetState(); @@ -2113,6 +2164,24 @@ var Designer = { Designer.op.resetState(); if (methodId == 'process.subprocess') { // 如果建模为端到端 连线样式调整 防止因层级原因 子流程展开或者关闭按钮 点击不到 window.subProcess.linkerBoxPointerEvent(); + // 判断新建的连线是什么类型 INNER_LINKER OUTER_LINKER CROSS_LINKER + if (d != null){ + let from = d.from; + let to = d.to; + if (from.id != null && to.id != null){ + let fromObj = Model.getShapeById(from.id); + let toObj = Model.getShapeById(to.id); + if (fromObj.elementType == "OUTER_NODE" && toObj.elementType == "OUTER_NODE"){ + d.elementType = "OUTER_LINKER"; + }else if (fromObj.elementType == "INNER_NODE" && toObj.elementType == "INNER_NODE"){ + d.elementType = "INNER_LINKER"; + }else { + d.elementType = "CROSS_LINKER"; + } + }else { + $.simpleAlert("当前创建的连线缺少连接点,请谨慎操作!"); + } + } } f.unbind("mousedown.link"); f.unbind("mousemove.link"); diff --git a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.method.subprocess.js b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.method.subprocess.js index d0be9366..d1fa97b9 100644 --- a/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.method.subprocess.js +++ b/com.actionsoft.apps.coe.pal/web/com.actionsoft.apps.coe.pal/lib/designer/scripts/diagraming/designer.method.subprocess.js @@ -28,6 +28,7 @@ class SubProcess { this.shapeIconRender(); this.handleScopeShapeEvent(); this.linkerBoxPointerEvent(); + this.scopeShapeRenderTitle(this.Model.define.elements) } linkerBoxPointerEvent(){ @@ -75,7 +76,7 @@ class SubProcess { let b = Utils.getRelativePos(a.pageX, a.pageY, c); // 实时获取鼠标移动的坐标 let j = Utils.getShapeByPosition(b.x, b.y); // 根据鼠标当前移动的位置获取当前图形 如果有的话 // console.log("当前图形", j); - if (j != null && j.shape.name != 'subProcess') { // 当前鼠标所在位置为范围选择框范围内 + if (j != null) { if (j.shape.name == 'scopeLimitation'){ let range = { x: j.shape.props.x, @@ -84,19 +85,20 @@ class SubProcess { 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 { // 范围选择框内的元素 - Utils.unselect(); + }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){ + if (inRangeEles.indexOf(j.shape.id) != -1){ // 当前鼠标所在位置为范围选择框范围内 + Utils.unselect(); let currentScopeEle = Model.getShapeById(scopeShapeId); // 获取当前范围选择框 let bound = { x: currentScopeEle.props.x, @@ -137,6 +139,9 @@ class SubProcess { shapeText = shape.text; } } + if (window.subProcess.checkLayoutIsReasonable()){ + return; + } // 2、传递当前模型文件ID、子流程节点ID awsui.ajax.request({ url: './jd', @@ -180,6 +185,9 @@ class SubProcess { // 节点关闭事件 shapeClose(event){ // console.log('sss'); + if (window.subProcess.checkLayoutIsReasonable()){ + return; + } let param = event.data; awsui.ajax.request({ url: './jd', @@ -210,6 +218,9 @@ class SubProcess { // 一键展开或闭合 oneClickOperate(action){ + if (window.subProcess.checkLayoutIsReasonable()){ + return; + } // console.log('oneClickExpand',this); awsui.ajax.request({ url: './jd', @@ -275,5 +286,59 @@ class SubProcess { $("#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 + } }