xyc
2024-10-12 1ab5999f546adcca439eb32ea5ecd34819a13ff6
modules/mainPart/src/main/java/com/zt/life/modules/mainPart/taskReliability/service/ModelLineService.java
@@ -8,14 +8,11 @@
import com.zt.common.utils.UUIDUtil;
import com.zt.life.modules.mainPart.basicInfo.dao.ParamDataDao;
import com.zt.life.modules.mainPart.basicInfo.dao.XhProductModelDao;
import com.zt.life.modules.mainPart.basicInfo.model.ParamData;
import com.zt.life.modules.mainPart.basicInfo.model.ProductImg;
import com.zt.life.modules.mainPart.basicInfo.model.XhProductModel;
import com.zt.life.modules.mainPart.taskReliability.dao.*;
import com.zt.life.modules.mainPart.taskReliability.dto.ModelLinePairDto;
import com.zt.life.modules.mainPart.taskReliability.model.*;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -161,15 +158,17 @@
        // 1. 解析出节点与边
        getNodeAndLineFromRbd(modelRbd.getId(), rbdJsonArray, modelNodeList, modelLineList, productImgList);
        // 2. 对于有多根入口线的产品节点,将其上的表决、旁联关系剥离成运算符节点,添加到该节点的前面,并添加相应的边
        peelOperationFromProductNode(modelRbd.getId(), modelNodeList, modelLineList);
        // 3. 计算所有节点的入口线数及出口线数
        // 2. 计算所有节点的入口线数及出口线数
        calcInOutLineNumAllNode(modelNodeList, modelLineList);
        // 4. 复制产品节点(node)到list
        RbdTreeNode root = recognizeRbd(modelNodeList, modelLineList);
/*
        // 3. 复制产品节点(node)到list
        List<ModelNode> modelNodeAndVnodeList = modelNodeList.stream().filter(item ->
                "node".equals(item.getNodeType())).collect(Collectors.toList());
        // 5. 不断将基本模型(串联、并联、旁联、表决、桥联)替换为虚节点而简化图形,直至无法简化为止。
        result = getAlgorithmFromRbd(modelRbd, modelNodeList, modelLineList, algorithmList, modelNodeAndVnodeList);
        // 4. 不断将基本模型(串联、并联、旁联、表决、桥联)替换为虚节点而简化图形,直至无法简化为止。
//        result = getAlgorithmFromRbd(modelRbd, modelNodeList, modelLineList, algorithmList, modelNodeAndVnodeList);
        // 6. 递归计算RBD的布局空间大小
        calcLayoutSize(modelRbd, algorithmList, modelNodeAndVnodeList);
@@ -193,7 +192,11 @@
        // 7. 递归计算RBD的布局空间参数(x、y坐标)
        root.setBlockX(0);
        root.setBlockY(0);
        calcPosition(rbdJsonArray, root);
        Map<String, RbdTreeNode> nodeMap = new HashMap<>();
        calcPosition(rbdJsonArray, root, nodeMap);
        setEdgeRouter(rbdJsonArray, nodeMap);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("cells", rbdJsonArray);
        modelRbd.setContent(jsonObject.toString());
@@ -203,19 +206,275 @@
        // 更新RBD数据
//        modelRbd.setAutoLayoutContent("测试文字");
//        modelRbdDao.updateById(modelRbd);
*/
        return result;
    }
    private void setNodePositionXY(JSONArray rbdJsonArray, RbdTreeNode block) {
    private RbdTreeNode recognizeRbd(List<ModelNode> modelNodeList,
                              List<ModelLine> modelLineList) {
        Map<String, Integer> vnodeCounter = new HashMap<>();
        vnodeCounter.put("vnodeCounter", 0);
        RbdTreeNode root = new RbdTreeNode();
        root.setAlgorithmType("series");
        root.setId(UUIDUtil.generateId());
        int counter = vnodeCounter.get("vnodeCounter");
        root.setName("v" + counter);
        counter++;
        vnodeCounter.put("vnodeCounter", counter);
        root.setNodeType("vnode");
        ModelNode end = modelNodeList.stream().filter(item ->
                "end".equals(item.getNodeType())).collect(Collectors.toList()).get(0);
        RbdTreeNode endNode = new RbdTreeNode();
        endNode.setId(end.getId());
        endNode.setName("end");
        endNode.setNodeType("end");
        endNode.setPicId(end.getPicId());
        endNode.setPairStartNodeId(end.getPairStartNodeId());
        endNode.setMyWidth(end.getWidth());
        endNode.setMyHeight(end.getHeight());
        root.getChildren().add(endNode);
        ModelLine lineRight = modelLineList.stream().filter(item ->
                item.getEndCell().equals(end.getPicId())).collect(Collectors.toList()).get(0);
        recognizeOneBranch(root,
                lineRight,
                null,
                modelNodeList,
                modelLineList,
                vnodeCounter);
        return root;
    }
    private void recognizeOneBranch(RbdTreeNode parent,
                                 ModelLine lineRight, // 串联的起始线(右边)
                                 ModelLine lineLeft, // 串联的结束线(左边)
                                 List<ModelNode> modelNodeList,
                                 List<ModelLine> modelLineList,
                                 Map<String, Integer> vnodeCounter) {
        ModelLine inLine = lineRight;
        for (;;) {
            ModelLine searchLine = inLine;
            ModelNode node = modelNodeList.stream().filter(item ->
                    searchLine.getBeginCell().equals(item.getPicId())).collect(Collectors.toList()).get(0);
            if ("node".equals(node.getNodeType())) {
                RbdTreeNode treeNode = new RbdTreeNode();
                treeNode.setId(node.getId());
                treeNode.setName(node.getName());
                treeNode.setNodeType(node.getNodeType());
                treeNode.setPicId(node.getPicId());
                treeNode.setMyWidth(node.getWidth());
                treeNode.setMyHeight(node.getHeight());
                parent.getChildren().add(treeNode);
                inLine = modelLineList.stream().filter(item ->
                        item.getEndCell().equals(node.getPicId())).collect(Collectors.toList()).get(0);
            } else if ("start".equals(node.getNodeType())) {
                RbdTreeNode treeNode = new RbdTreeNode();
                treeNode.setId(node.getId());
                treeNode.setName(node.getNodeType());
                treeNode.setNodeType(node.getNodeType());
                treeNode.setPicId(node.getPicId());
                treeNode.setMyWidth(node.getWidth());
                treeNode.setMyHeight(node.getHeight());
                parent.getChildren().add(treeNode);
                break;
            } else if ("connect".equals(node.getNodeType())) {
                break;
            } else if ("parallel,vote,switch,bridge".contains(node.getNodeType())) {
                RbdTreeNode subNode = new RbdTreeNode();
                subNode.setAlgorithmType("series");
                subNode.setId(UUIDUtil.generateId());
                int counter = vnodeCounter.get("vnodeCounter");
                subNode.setName("v" + counter);
                counter++;
                vnodeCounter.put("vnodeCounter", counter);
                subNode.setNodeType("vnode");
                parent.getChildren().add(subNode);
                ModelNode connect = modelNodeList.stream().filter(item ->
                        node.getPairStartNodeId().equals(item.getPicId())).collect(Collectors.toList()).get(0);
                RbdTreeNode treeNode = new RbdTreeNode();
                treeNode.setId(connect.getId());
                treeNode.setName(connect.getNodeType());
                treeNode.setNodeType(connect.getNodeType());
                treeNode.setPicId(connect.getPicId());
                treeNode.setMyWidth(connect.getWidth());
                treeNode.setMyHeight(connect.getHeight());
                subNode.getChildren().add(treeNode);
                RbdTreeNode subNodeOpe = new RbdTreeNode();
                subNodeOpe.setAlgorithmType(node.getNodeType());
                subNodeOpe.setId(UUIDUtil.generateId());
                counter = vnodeCounter.get("vnodeCounter");
                subNodeOpe.setName("v" + counter);
                counter++;
                vnodeCounter.put("vnodeCounter", counter);
                subNodeOpe.setNodeType("vnode");
                subNode.getChildren().add(subNodeOpe);
                treeNode = new RbdTreeNode();
                treeNode.setId(node.getId());
                treeNode.setName(node.getNodeType());
                treeNode.setNodeType(node.getNodeType());
                treeNode.setPicId(node.getPicId());
                treeNode.setPairStartNodeId(node.getPairStartNodeId());
                treeNode.setMyWidth(node.getWidth());
                treeNode.setMyHeight(node.getHeight());
                subNode.getChildren().add(treeNode);
                recognizeOpeBlock(subNodeOpe,
                        node,
                        modelNodeList,
                        modelLineList,
                        vnodeCounter);
                inLine = modelLineList.stream().filter(item ->
                        item.getEndCell().equals(connect.getPicId())).collect(Collectors.toList()).get(0);
            }
            if (null != lineLeft) {
                if (inLine.getPicId().equals(lineLeft.getPicId())) break;
            }
        }
        if ("series".equals(parent.getAlgorithmType())) Collections.reverse(parent.getChildren());
    }
    private void recognizeOpeBlock(RbdTreeNode parent,
                                        ModelNode rightNode, // rbd中的右节点(包括end及4种运算符)
                                        List<ModelNode> modelNodeList,
                                        List<ModelLine> modelLineList,
                                        Map<String, Integer> vnodeCounter) {
        if ("parallel,vote,switch".contains(parent.getAlgorithmType())) {
            ModelNode searchNode = rightNode;
            List<ModelLine> lines = modelLineList.stream().filter(item ->
                    item.getEndCell().equals(searchNode.getPicId())).collect(Collectors.toList());
            List<ModelLine> sortedLines = sortLine(lines, modelNodeList);
            for (ModelLine line : sortedLines) {
                boolean isSeries = isSeriesBranch(rightNode, line, modelNodeList, modelLineList);
                if (isSeries) {
                    RbdTreeNode subNode = new RbdTreeNode();
                    subNode.setAlgorithmType("series");
                    subNode.setId(UUIDUtil.generateId());
                    int counter = vnodeCounter.get("vnodeCounter");
                    subNode.setName("v" + counter);
                    counter++;
                    vnodeCounter.put("vnodeCounter", counter);
                    subNode.setNodeType("vnode");
                    parent.getChildren().add(subNode);
                    recognizeOneBranch(subNode, line, null, modelNodeList, modelLineList, vnodeCounter);
                } else {
                    recognizeOneBranch(parent, line,null, modelNodeList, modelLineList, vnodeCounter);
                }
            }
        } else if ("bridge".contains(parent.getAlgorithmType())) {
            // 将桥联看成2支路并联+桥接支路的组合
        }
    }
    /**
     * 按自上而下的顺序排序
      */
    private List<ModelLine> sortLine(List<ModelLine> lines,
                                     List<ModelNode> modelNodeList) {
        for (ModelLine line : lines) {
            ModelNode node = modelNodeList.stream().filter(item ->
                    line.getBeginCell().equals(item.getPicId())).collect(Collectors.toList()).get(0);
            line.setBeginY(node.getPositionY());
        }
        lines.sort(Comparator.comparing(ModelLine::getBeginY));
        return lines;
    }
    private boolean isSingleNode(List<ModelNode> modelNodeList,
                                 List<ModelLine> modelLineList) {
        boolean result = false;
        ModelNode start = modelNodeList.stream().filter(item ->
                "start".equals(item.getNodeType())).collect(Collectors.toList()).get(0);
        ModelNode end = modelNodeList.stream().filter(item ->
                "end".equals(item.getNodeType())).collect(Collectors.toList()).get(0);
        ModelLine line1 = modelLineList.stream().filter(item ->
                item.getBeginCell().equals(start.getPicId())).collect(Collectors.toList()).get(0);
        ModelNode node1 = modelNodeList.stream().filter(item ->
                line1.getEndCell().equals(item.getPicId())).collect(Collectors.toList()).get(0);
        ModelLine line2 = modelLineList.stream().filter(item ->
                item.getEndCell().equals(end.getPicId())).collect(Collectors.toList()).get(0);
        ModelNode node2 = modelNodeList.stream().filter(item ->
                line2.getBeginCell().equals(item.getPicId())).collect(Collectors.toList()).get(0);
        if (node1.getPicId().equals(node2.getPicId()) && "node".equals(node1.getNodeType())) result = true;
        return result;
    }
    private boolean isSeriesBranch(ModelNode rightNode, // rbd中的右节点(包括end及4种运算符)
                                   ModelLine line, // 右节点的入口线
                                   List<ModelNode> modelNodeList,
                                   List<ModelLine> modelLineList) {
        boolean result = false;
        ModelNode node = modelNodeList.stream().filter(item ->
                line.getBeginCell().equals(item.getPicId())).collect(Collectors.toList()).get(0);
        if ("node".equals(node.getNodeType())) {
            ModelLine line1 = modelLineList.stream().filter(item ->
                    item.getEndCell().equals(node.getPicId())).collect(Collectors.toList()).get(0);
            ModelNode node1 = modelNodeList.stream().filter(item ->
                    line1.getBeginCell().equals(item.getPicId())).collect(Collectors.toList()).get(0);
            result = !node1.getPicId().equals(rightNode.getPairStartNodeId());
        } else {
            ModelNode node2 = modelNodeList.stream().filter(item ->
                    node.getPairStartNodeId().equals(item.getPicId())).collect(Collectors.toList()).get(0);
            ModelLine line2 = modelLineList.stream().filter(item ->
                    item.getEndCell().equals(node2.getPicId())).collect(Collectors.toList()).get(0);
            ModelNode node3 = modelNodeList.stream().filter(item ->
                    line2.getBeginCell().equals(item.getPicId())).collect(Collectors.toList()).get(0);
            result = !node3.getPicId().equals(rightNode.getPairStartNodeId());
        }
        return result;
    }
    private void setEdgeRouter(JSONArray rbdJsonArray, Map<String, RbdTreeNode> nodeMap) {
        for (int i = 0; i < rbdJsonArray.size(); i++
        ) {
            JSONObject jsonObject = rbdJsonArray.getJSONObject(i);
            if (jsonObject.get("shape").equals("edge")) {
                String sourceId = JsonUtils2.getJsonValueByPath(jsonObject, "source/cell".split("/")).toString();
                String targetId = JsonUtils2.getJsonValueByPath(jsonObject, "target/cell".split("/")).toString();
                RbdTreeNode sourceNode = nodeMap.get(sourceId);
                RbdTreeNode targetNode = nodeMap.get(targetId);
                if (sourceNode != null) {
                    if ("connect".equals(sourceNode.getNodeType()) && !"10000".equals(sourceId)){
                        if (sourceNode.getY()+sourceNode.getMyHeight()/2 == targetNode.getY()+targetNode.getMyHeight()/2){
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"right".split(","));
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"left".split(","));
                        }else{
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"top,bottom".split(","));
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"left".split(","));
                        }
                    }
                }
                if (targetNode != null) {
                    if ("parallel,vote".contains(targetNode.getNodeType())){
                        if (sourceNode.getY()+sourceNode.getMyHeight()/2 == targetNode.getY()+targetNode.getMyHeight()/2){
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"right".split(""));
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"left".split(""));
                        }else{
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"right".split(""));
                            JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"top,bottom".split(""));
                        }
                    }
                }
            }
        }
    }
    private void setNodePositionXY(JSONArray rbdJsonArray, RbdTreeNode block, Map<String, RbdTreeNode> nodeMap) {
        Double x = block.getBlockX() + (block.getBlockWidth() - block.getMyWidth()) / 2;
        Double y = block.getBlockY() + (block.getBlockHeight() - block.getMyHeight()) / 2;
        block.setX(x);
        block.setY(y);
        nodeMap.put(block.getPicId(),block);
        setRbdNodePosition(rbdJsonArray, block.getPicId(), x, y);
    }
    private void calcPosition(JSONArray rbdJsonArray, RbdTreeNode block) {
    private void calcPosition(JSONArray rbdJsonArray, RbdTreeNode block, Map<String, RbdTreeNode> nodeMap) {
        if (block.getNodeType().equals("node")) {
            setNodePositionXY(rbdJsonArray, block);
            setNodePositionXY(rbdJsonArray, block,nodeMap);
        } else {
            double blockWidth = block.getBlockWidthNum() * LAYOUT_CELL_SIZE_X;
            double blockHeight = block.getBlockHeightNum() * LAYOUT_CELL_SIZE_Y;
@@ -246,25 +505,26 @@
                    child.setBlockY(block.getBlockY());
                    child.setBlockX(subBlockX);
                    calcPosition(rbdJsonArray, child);
                    calcPosition(rbdJsonArray, child, nodeMap);
                    subBlockX = subBlockX + selfWidth;
                }
            } else {
                Double subBlockY = block.getBlockY()+(descentHeight-blockHeight)/2;
                Double subBlockY = block.getBlockY() + (descentHeight - blockHeight) / 2;
                Double firstSubBlockY = subBlockY;
                // 设置connect的位置
                RbdTreeNode connectBlock = new RbdTreeNode();
                connectBlock.setMyWidth(getRbdNodeInfo(rbdJsonArray, block.getPairStartNodeId(), "size/width"));
                connectBlock.setMyHeight(getRbdNodeInfo(rbdJsonArray, block.getPairStartNodeId(), "size/height"));
                connectBlock.setNodeType("connect");
                connectBlock.setPicId(block.getPairStartNodeId());
                connectBlock.setBlockX(block.getBlockX());
                connectBlock.setBlockY(firstSubBlockY);
                connectBlock.setBlockWidth(LAYOUT_CELL_SIZE_X);
                connectBlock.setBlockHeight(blockHeight);
                setNodePositionXY(rbdJsonArray, connectBlock);
                setNodePositionXY(rbdJsonArray, connectBlock, nodeMap);
                for (RbdTreeNode child : children) {
                    child.setDescentWidth(block.getBlockWidth() - 2 * LAYOUT_CELL_SIZE_X);
@@ -276,20 +536,21 @@
                    child.setBlockX(block.getBlockX() + LAYOUT_CELL_SIZE_X);
                    child.setBlockY(subBlockY);
                    subBlockY = subBlockY + child.getBlockHeightNum() * LAYOUT_CELL_SIZE_Y;
                    calcPosition(rbdJsonArray, child);
                    calcPosition(rbdJsonArray, child, nodeMap);
                }
                // 设置运算符的位置
                RbdTreeNode opeBlock = new RbdTreeNode();
                opeBlock.setPicId(block.getPicId());
                opeBlock.setNodeType("parallel");
                opeBlock.setMyWidth(getRbdNodeInfo(rbdJsonArray, block.getPicId(), "size/width"));
                opeBlock.setMyHeight(getRbdNodeInfo(rbdJsonArray, block.getPicId(), "size/height"));
                opeBlock.setBlockX(block.getBlockX() + blockWidth - LAYOUT_CELL_SIZE_X);
                opeBlock.setBlockY(firstSubBlockY);
                opeBlock.setBlockWidth(LAYOUT_CELL_SIZE_X);
                opeBlock.setBlockHeight(blockHeight);
                setNodePositionXY(rbdJsonArray, opeBlock);
                setNodePositionXY(rbdJsonArray, opeBlock, nodeMap);
            }
        }
@@ -1756,7 +2017,9 @@
                if (jsonValue != null && StringUtils.isNotBlank(jsonValue.toString())) {
                    modelNode.setPairEndNodeId(jsonValue.toString());
                }
                if ("node".equals(modelNode.getNodeType())) {
                if ("dashedBox".equals(modelNode.getNodeType())) {
                    modelNode.setNodeType("node");
                } else if ("node".equals(modelNode.getNodeType())) {
                    ProductImg productImg = new ProductImg();
                    String dataId = JsonUtils2.getJsonValueByPath(jsonObject, "data/dataId".split("/")).toString();
                    modelNode.setDataId(Long.valueOf(dataId));