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 7d9c5ecc..4b64f56c 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/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 2d3b237c..59e9b577 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 @@ -3,6 +3,9 @@ package com.actionsoft.apps.coe.method.process.subprocess.graph; 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; +import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractDefinitionHandle; +import com.actionsoft.apps.coe.method.process.subprocess.graph.util.DefinitionThreadUnSafe; +import com.actionsoft.apps.coe.method.process.subprocess.graph.util.SubProcessNodeDefineUtil; import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache; import com.actionsoft.apps.coe.pal.pal.repository.designer.manage.CoeDesignerAPIManager; import com.actionsoft.apps.coe.pal.pal.repository.designer.model.BaseModel; @@ -31,6 +34,8 @@ public class GraphNodeCloseHandle { private JSONObject childProcessDefine; // 要关闭的子流程模型信息 private JSONObject endToEndProcessDefine; // 总图的模型信息 private JSONObject scopeLimitationShape; // 范围标注框 + private AbstractDefinitionHandle definitionHandle; + private AbstractDefinitionHandle subProcessNodeDefineHandle; private final ReentrantLock lock = new ReentrantLock(); @@ -40,7 +45,14 @@ public class GraphNodeCloseHandle { apiManager = CoeDesignerAPIManager.getInstance(); + definitionHandle = new DefinitionThreadUnSafe(endToEndProcessDefineStr); + try { + + relationFileId = SubProcessNodeDefineUtil.getSubProcessNodeRelationFileId(repositoryId, shapeId); + + subProcessNodeDefineHandle = new DefinitionThreadUnSafe(SubProcessNodeDefineUtil.readSubProcessNodeDefine(repositoryId, shapeId)); + readChildProcessDefine(); readCurrentProcessDefine(endToEndProcessDefineStr); } catch (AWSException e) { @@ -105,14 +117,17 @@ public class GraphNodeCloseHandle { // 2、根据现有连线关系创建邻接矩阵 NodeCloseAdjMatrix closeAdjMatrix = buildEndToEndGraphAdjMatrix(); closeAdjMatrix.buildAdjMatrix(); - // 3、收集现有元素坐标 + JSONObject elements = readEndToEndGraphElements(); + // 更新因节点展开后 坐标发生变化的节点坐标 + String direction = definitionHandle.getProcessProperties().getString("direction"); + graphPartNodePoiRenderAgain(elements, direction, subProcessNode); + // 3、收集现有元素坐标 + double[][] vertexPosition = closeAdjMatrix.getVertexPosition(elements); // 4、删除现有连线 removeEndToEndGraphOldLinker(); // 5、构建新的连线 - JSONObject processProperties = endToEndProcessDefine.getJSONObject("processProperties"); - String direction = processProperties.getString("direction"); NodeCloseLinkerRender linkerRender = new NodeCloseLinkerRender(vertexPosition, closeAdjMatrix, scopeLimitationShape); JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId); for (Object o : linkers) { @@ -136,6 +151,48 @@ public class GraphNodeCloseHandle { } + /** + * 节点闭合 部分节点坐标再次更新 + */ + private void graphPartNodePoiRenderAgain(JSONObject elements, String direction, JSONObject subProcessNode){ + // 闭合节点的位置 及大小 + JSONObject props = subProcessNode.getJSONObject("props"); + double x = props.getDoubleValue("x"); + double y = props.getDoubleValue("y"); + + // 当前关闭的节点范围标识框的位置与大小 + double[] scope = SubProcessNodeDefineUtil.calculateSubProcessNodeExpandScope(subProcessNodeDefineHandle); + + for (String key : elements.keySet()) { + JSONObject ele = elements.getJSONObject(key); + if ("linker".equals(ele.getString("name"))) continue; + if (ele.getString("id").equals(subProcessNode.getString("id"))) continue; + JSONObject eleProps = ele.getJSONObject("props"); + if ("vertically".equals(direction)){ // 垂直布局 + if (x + scope[0] < eleProps.getDoubleValue("x")) { + eleProps.put("x", eleProps.getDoubleValue("x") - scope[0] + SubProcessConst.SUB_PROCESS_SHAPE_W); + } + if (y +scope[1] < eleProps.getDoubleValue("y")){ + eleProps.put("y", eleProps.getDoubleValue("y") - scope[1] + SubProcessConst.SUB_PROCESS_SHAPE_H); + }else if (y < eleProps.getDoubleValue("y") && eleProps.getDoubleValue("y") < y + scope[1]){ + eleProps.put("y", y); + } + }else { // 横向布局 + if (x + scope[0] < eleProps.getDoubleValue("x")){ // 节点在范围框右侧的节点 + eleProps.put("x", eleProps.getDoubleValue("x") - scope[0] + SubProcessConst.SUB_PROCESS_SHAPE_W); + }else if (x < eleProps.getDoubleValue("x") + && eleProps.getDoubleValue("x") < x + scope[0] + && y + scope[1] < eleProps.getDoubleValue("y")){ + eleProps.put("x", x); + } + if (y + scope[1] < eleProps.getDoubleValue("y")){ // 节点在范围框下方的节点 + eleProps.put("y", eleProps.getDoubleValue("y") - scope[1] + SubProcessConst.SUB_PROCESS_SHAPE_H); + } + } + } + } + + /** * 删除总图中节点展开前的连线 */ 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 70739396..9ca6ebab 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 @@ -90,7 +90,6 @@ public class GraphNodeExpandHandle { */ private void toAssembleScopeLimitationShape() throws AWSException{ JSONObject scopeLimitationShape = ShapeUtil.getProcessShapeDefinition(SubProcessConst.SUB_PROCESS_METHOD_ID, "展开范围标注"); - JSONObject childProcessPage = childProcessDefine.getJSONObject("page"); JSONObject childProcessElements = childProcessDefine.getJSONObject("elements"); JSONObject childProcessEleMaxX = childProcessElements.keySet() .stream() @@ -113,8 +112,6 @@ public class GraphNodeExpandHandle { .map(key -> childProcessElements.getJSONObject(key).getJSONObject("props")) .min((o1, o2) -> Double.compare(o1.getDoubleValue("y"), o2.getDoubleValue("y"))).get(); // 当前节点所标识的子流程文件的 画布宽度与高度 减去边距 - // double childProcessPageWidth = childProcessPage.getDoubleValue("width") - childProcessPage.getDoubleValue("padding") * 2; - // double childProcessPageHeight = childProcessPage.getDoubleValue("height") - childProcessPage.getDoubleValue("padding") * 2; double scopeShapeW = childProcessEleMaxX.getDoubleValue("x") + childProcessEleMaxX.getDoubleValue("w") - childProcessEleMixX.getDoubleValue("x") + SubProcessConst.SCOPE_SHAPE_PADDING; double scopeShapeH = childProcessEleMaxY.getDoubleValue("y") + childProcessEleMaxY.getDoubleValue("h") - childProcessEleMinY.getDoubleValue("y") + SubProcessConst.SCOPE_SHAPE_PADDING; diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/component/AbstractDefinitionHandle.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/component/AbstractDefinitionHandle.java index 11cebea7..f3b6f6a0 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/component/AbstractDefinitionHandle.java +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/component/AbstractDefinitionHandle.java @@ -24,24 +24,24 @@ public abstract class AbstractDefinitionHandle { * 获取 elements 属性 * @return */ - protected abstract JSONObject getElements(); + public abstract JSONObject getElements(); /** * 获取 processProperties 属性 * @return */ - protected abstract JSONObject getProcessProperties(); + public abstract JSONObject getProcessProperties(); /** * 删除 elements 属性中元素 * @param key */ - protected abstract void removeShape(String key); + public abstract void removeShape(String key); /** * 添加元素到 elements * @param key * @param ele */ - protected abstract void addEle(String key, JSONObject ele); + public abstract void addEle(String key, JSONObject ele); } diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/DefinitionThreadUnSafe.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/DefinitionThreadUnSafe.java index 533508e2..041fa037 100644 --- a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/DefinitionThreadUnSafe.java +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/DefinitionThreadUnSafe.java @@ -15,22 +15,22 @@ public class DefinitionThreadUnSafe extends AbstractDefinitionHandle { } @Override - protected JSONObject getElements() { + public JSONObject getElements() { return getDefine().getJSONObject("elements"); } @Override - protected JSONObject getProcessProperties() { + public JSONObject getProcessProperties() { return getDefine().getJSONObject("processProperties"); } @Override - protected void removeShape(String key) { + public void removeShape(String key) { getElements().remove(key); } @Override - protected void addEle(String key, JSONObject ele) { + public void addEle(String key, JSONObject ele) { getElements().put(key, ele); } } diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/GraphNodeCloseUtil.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/GraphNodeCloseUtil.java new file mode 100644 index 00000000..fd915eef --- /dev/null +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/GraphNodeCloseUtil.java @@ -0,0 +1,9 @@ +package com.actionsoft.apps.coe.method.process.subprocess.graph.util; + +/** + * @author oYang + * @Description TODO + * @createTime 2023年06月09日 16:26:00 + */ +public class GraphNodeCloseUtil { +} diff --git a/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/SubProcessNodeDefineUtil.java b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/SubProcessNodeDefineUtil.java new file mode 100644 index 00000000..4690cdb4 --- /dev/null +++ b/com.actionsoft.apps.coe.method.process.subprocess/src/com/actionsoft/apps/coe/method/process/subprocess/graph/util/SubProcessNodeDefineUtil.java @@ -0,0 +1,90 @@ +package com.actionsoft.apps.coe.method.process.subprocess.graph.util; + +import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst; +import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractDefinitionHandle; +import com.actionsoft.apps.coe.pal.pal.repository.designer.manage.CoeDesignerAPIManager; +import com.actionsoft.apps.coe.pal.pal.repository.designer.model.BaseModel; +import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache; +import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.model.DesignerShapeRelationModel; +import com.actionsoft.bpms.util.UtilString; +import com.actionsoft.exception.AWSException; +import com.alibaba.fastjson.JSONObject; + +import java.util.List; + +/** + * @author oYang + * @Description 子流程节点所关联的 define 工具类 + * @createTime 2023年06月09日 16:54:00 + */ +public class SubProcessNodeDefineUtil { + + /** + * 读取子流程节点 所关联的文件的 define + * @param repositoryId + * @param shapeId + * @return + */ + public static String readSubProcessNodeDefine(String repositoryId, String shapeId) throws AWSException{ + String relationFileId = getSubProcessNodeRelationFileId(repositoryId, shapeId); + // 先去与总图存储的同级目录下读取 如果为空说明是初次读取 + String subProcessNodeDefineStr = CoeDesignerAPIManager.getInstance().getChildProcessDefine(repositoryId, 0, relationFileId); + if (UtilString.isEmpty(subProcessNodeDefineStr)){ // 初次读取 去源文件目录读取 + BaseModel childProcessBaseModel = CoeDesignerAPIManager.getInstance().getDefinition(relationFileId, 0); + if (childProcessBaseModel == null) + throw new AWSException("当前子流程节点内部可能没有图形元素,可以去添加后展开"); + subProcessNodeDefineStr = childProcessBaseModel.getDefinition(); + } + return subProcessNodeDefineStr; + } + + /** + * 获取子流程节点 所关联的文件ID + * @param repositoryId + * @param shapeId + * @return + * @throws AWSException + */ + public static String getSubProcessNodeRelationFileId(String repositoryId, String shapeId) throws AWSException{ + List relationModelList = DesignerShapeRelationCache.getListByAttrId(repositoryId, shapeId, SubProcessConst.CHILD_PROCESS); + + DesignerShapeRelationModel relationModel = relationModelList.stream().findFirst().orElse(null); + if (relationModel == null) + throw new AWSException("未找到当前节点所标识的子流程文件信息"); + + return relationModel.getRelationFileId(); + } + + /** + * 计算子流程节点 展开后的宽度与高度 + * @param definitionHandle + * @return double[]{w, h} + */ + public static double[] calculateSubProcessNodeExpandScope(AbstractDefinitionHandle definitionHandle){ + JSONObject childProcessElements = definitionHandle.getElements(); + JSONObject childProcessEleMaxX = childProcessElements.keySet() + .stream() + .filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name"))) + .map(key -> childProcessElements.getJSONObject(key).getJSONObject("props")) + .max((o1, o2) -> Double.compare(o1.getDoubleValue("x"), o2.getDoubleValue("x"))).get(); + JSONObject childProcessEleMixX = childProcessElements.keySet() + .stream() + .filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name"))) + .map(key -> childProcessElements.getJSONObject(key).getJSONObject("props")) + .min((o1, o2) -> Double.compare(o1.getDoubleValue("x"), o2.getDoubleValue("x"))).get(); + JSONObject childProcessEleMaxY = childProcessElements.keySet() + .stream() + .filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name"))) + .map(key -> childProcessElements.getJSONObject(key).getJSONObject("props")) + .max((o1, o2) -> Double.compare(o1.getDoubleValue("y"), o2.getDoubleValue("y"))).get(); + JSONObject childProcessEleMinY = childProcessElements.keySet() + .stream() + .filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name"))) + .map(key -> childProcessElements.getJSONObject(key).getJSONObject("props")) + .min((o1, o2) -> Double.compare(o1.getDoubleValue("y"), o2.getDoubleValue("y"))).get(); + // 当前节点所标识的子流程文件的 画布宽度与高度 减去边距 + double scopeShapeW = childProcessEleMaxX.getDoubleValue("x") + childProcessEleMaxX.getDoubleValue("w") - childProcessEleMixX.getDoubleValue("x") + SubProcessConst.SCOPE_SHAPE_PADDING; + double scopeShapeH = childProcessEleMaxY.getDoubleValue("y") + childProcessEleMaxY.getDoubleValue("h") - childProcessEleMinY.getDoubleValue("y") + SubProcessConst.SCOPE_SHAPE_PADDING; + return new double[]{scopeShapeW, scopeShapeH}; + } +}