xyc
2024-03-28 5f1787f48a5f06812079b87b669b4a3080183c2d
modules/mainPart/src/main/java/com/zt/life/modules/mainPart/taskReliability/service/ModelLineService.java
@@ -5,25 +5,25 @@
import com.zt.common.service.BaseService;
import com.zt.common.utils.JsonUtils2;
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.ModelLinePair;
import com.zt.life.modules.mainPart.taskReliability.model.*;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentHelper;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zt.common.db.query.QueryFilter;
import org.springframework.transaction.annotation.Transactional;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.util.*;
import java.util.stream.Collectors;
@@ -47,6 +47,10 @@
    private AlgorithmDao algorithmDao;
    @Autowired
    private ModelNodeAlgorithmDao modelNodeAlgorithmDao;
    @Autowired
    private XhProductModelDao xhProductModelDao;
    @Autowired
    private ParamDataDao paramDataDao;
    /**
     * 分页查询
@@ -117,7 +121,7 @@
        List<ModelNode> modelNodeList = new ArrayList<>();
        List<ModelLine> modelLineList = new ArrayList<>();
        List<Algorithm> algorithmList = new ArrayList<>();
        List<ProductImg> productImgList = new ArrayList<>();
        List<ProductImg> productImgList = new ArrayList<>();    // 暂不使用(而使用数据库中的可靠性参数)
        // 1. 解析出节点与边
        getNodeAndLineFromRbd(modelRbd.getId(), rbdJsonArray, modelNodeList, modelLineList, productImgList);
@@ -127,11 +131,11 @@
        List<ModelNode> modelNodeAndVnodeList = modelNodeList.stream().filter(item ->
                "node".equals(item.getNodeType())).collect(Collectors.toList());
        // 4. 不断将基本模型(串联、并联、旁联、表决、桥联)替换为虚节点而简化图形,直至无法简化为止。
        result = getAlgorithmFromRbd(modelRbd, modelNodeList, modelLineList, algorithmList, modelNodeAndVnodeList, productImgList);
        result = getAlgorithmFromRbd(modelRbd, modelNodeList, modelLineList, algorithmList, modelNodeAndVnodeList);
        // 5. 转换为算法库接口XML
        if (result) {
            result = createIfXmlFromRbd(modelRbd, algorithmList, modelNodeAndVnodeList, productImgList);
            result = createIfXmlFromRbd(modelRbd, algorithmList, modelNodeAndVnodeList);
        }
        // 6. 保存模型
@@ -142,23 +146,53 @@
    private boolean createIfXmlFromRbd(ModelRbd modelRbd,
                                       List<Algorithm> algorithmList,
                                       List<ModelNode> modelNodeAndVnodeList,
                                       List<ProductImg> productImgList) {
                                       List<ModelNode> modelNodeAndVnodeList) {
        boolean result = true;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.newDocument();
            Element rootElement = doc.createElement("DES");
            doc.appendChild(rootElement);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            StringWriter writer = new StringWriter();
            transformer.transform(new DOMSource(doc), new StreamResult(writer));
            String xmlString = writer.getBuffer().toString();
            modelRbd.setIfXml(xmlString);
        try {
            Document document = DocumentHelper.createDocument();
            // 添加root节点
            Element root = document.addElement("DES");
            root.addAttribute("Name", "A System");
            // 添加terminal节点到root1
            Element terminal = root.addElement("Node");
            terminal.addAttribute("Name", "Terminal");
            terminal.addAttribute("Type", "NODE");
            // 将模型转换为DOM,添加到root
            Algorithm endAlgo = algorithmList.stream().filter(item ->
                    "end".equals(item.getAlgorithmType())).collect(Collectors.toList()).get(0);
            ModelNode computerNode = modelNodeAndVnodeList.stream().filter(item ->
                    endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0);
            node2DOM(algorithmList, modelNodeAndVnodeList, computerNode, root);
            // 添加start节点到root
            Element start = root.addElement("Node");
            start.addAttribute("Name", "Start");
            start.addAttribute("Type", "NODE");
            // 添加link(路径)到root
            Element link = root.addElement("Link");
            Element block = link.addElement("Block");
            block.addAttribute("Name", "Terminal");
            block = link.addElement("Block");
            block.addAttribute("Name", computerNode.getId().toString());
            block = link.addElement("Block");
            block.addAttribute("Name", "Start");
//            document.setXMLEncoding("UTF-8");
//            String xmlString = document.asXML();
            // 输出格式化xml
            XMLWriter xmlWriter = null;
            try {
                OutputFormat format = OutputFormat.createPrettyPrint();
                format.setEncoding("UTF-8");
                StringWriter writer = new StringWriter();
                xmlWriter = new XMLWriter(writer, format);
                xmlWriter.write(document);
                modelRbd.setPublishedXml(writer.toString());
            } finally {
                if (xmlWriter!=null) xmlWriter.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = false;
@@ -167,12 +201,82 @@
        return result;
    }
    // 递归函数
    private void node2DOM(List<Algorithm> algorithmList,
                          List<ModelNode> modelNodeAndVnodeList,
                          ModelNode node,
                          Element parent) {
        if ("node".equals(node.getNodeType())) {
            Long dataId = node.getDataId();
            XhProductModel xhProductModel = xhProductModelDao.getById(dataId);
            if (xhProductModel == null) return;
            if ("1".equals(xhProductModel.getProductType())) {
                // 设备
                ParamData paramData = paramDataDao.getParamData(dataId, "expect");
                if (paramData == null) return;
                Element element = parent.addElement("Node");
                element.addAttribute("Name", dataId.toString());
                element.addAttribute("Type", "NODE");
                Element failureTag = element.addElement("Failure");
                failureTag.addAttribute("Dist", "EXP"); // TODO:需设为具体的分布
                Element argsTag = failureTag.addElement("Args");
                Double value = new Double(paramData.getTaskMtbcfRegulate());
                value = 1.0/value;
                argsTag.addAttribute("value", value.toString());
                if (1==paramData.getRepairable()) {
                    Element repairTag = element.addElement("Repair");
                    repairTag.addAttribute("Dist", "EXP"); // TODO:需设为具体的分布
                    argsTag = repairTag.addElement("Args");
                    value = new Double(paramData.getRepairMttcr());
                    value = 1.0/value;
                    argsTag.addAttribute("value", value.toString());
                    Element repairTimeLimitTag = element.addElement("RepairTimeLimit");
                    repairTimeLimitTag.setText(paramData.getRepairMttcr());
                }
            } else if ("10".equals(xhProductModel.getProductType())) {
                // 虚单位
                ModelRbd rbdXDY = modelRbdDao.getDiagramOfXDY(dataId);
                if (rbdXDY == null) return;
                List<Algorithm> algorithmListXDY = algorithmDao.getListByModelId(rbdXDY.getId());
                List<ModelNode> modelNodeAndVnodeListXDY =modelNodeAlgorithmDao.getListByModelId(rbdXDY.getId());
                Algorithm endAlgo = algorithmListXDY.stream().filter(item ->
                        "end".equals(item.getAlgorithmType())).collect(Collectors.toList()).get(0);
                ModelNode computerNode = modelNodeAndVnodeListXDY.stream().filter(item ->
                        endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0);
                node2DOM(algorithmListXDY, modelNodeAndVnodeListXDY, computerNode, parent);
            }
        } else {
            // vnode(运算节点)
            Algorithm algo = algorithmList.stream().filter(item ->
                    node.getId().equals(item.getId())).collect(Collectors.toList()).get(0);
            Element element = parent.addElement("Logic");
            element.addAttribute("Name", algo.getId().toString());
            if ("series".equals(algo.getAlgorithmType())) {
                element.addAttribute("Type", "SERIES");
            } else if ("parallel".equals(algo.getAlgorithmType())) {
                element.addAttribute("Type", "PARALLEL");
            } else if ("vote".equals(algo.getAlgorithmType())) {
                element.addAttribute("Type", "VOTE");
                element.addAttribute("VoteValue", algo.getVoteNum().toString());
            } else if ("switch".equals(algo.getAlgorithmType())) {
                element.addAttribute("Type", "STANDBY");
            } else if ("bridge".equals(algo.getAlgorithmType())) {
                element.addAttribute("Type", "BRIDGE");
            }
            String[] computerNodeListStr = algo.getComputerList().split(",");
            for (String nodeStr : computerNodeListStr) {
                ModelNode nd = modelNodeAndVnodeList.stream().filter(item ->
                        nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0);
                node2DOM(algorithmList, modelNodeAndVnodeList, nd, element);
            }
        }
    }
    private boolean getAlgorithmFromRbd(ModelRbd modelRbd,
                                        List<ModelNode> modelNodeList,
                                        List<ModelLine> modelLineList,
                                        List<Algorithm> algorithmList,
                                        List<ModelNode> modelNodeAndVnodeList,
                                        List<ProductImg> productImgList) {
                                        List<ModelNode> modelNodeAndVnodeList) {
        // 根据以下的构图规则来进行算法分解:
        // 1、节点的定义
        // 1-1) 运算节点:共2个:旁联、表决,且运算节点需放在被运算节点的右侧。
@@ -592,6 +696,7 @@
                ModelNode endNode = getBranchNodesOneParallel(pathOneGroup, branchNodeList);
                if ("connect".equals(startNode.getNodeType()) && pathOneGroup.size()==lines.size()) {
                    // 替换成虚节点
                    modelNodeAndVnodeList.add(startNode);
                    replaceToVnode("parallel", modelId, modelNodeList, modelLineList,
                            algorithmList, modelNodeAndVnodeList, startNode, endNode, branchNodeList);
                } else {
@@ -787,6 +892,7 @@
        if ("connect".equals(startNode.getNodeType()) && startNode.getInLineNum()==2) {
            // 替换成虚节点
            modelNodeAndVnodeList.add(startNode);
            replaceToVnode("bridge", modelId, modelNodeList, modelLineList,
                    algorithmList, modelNodeAndVnodeList, startNode, endNode, branchNodeList);
        } else {
@@ -882,6 +988,7 @@
                }
            }
            if (thisNodeSuccess) {
                modelNodeAndVnodeList.add(opNode);
                replaceToVnode(opNode.getNodeType(), modelId, modelNodeList, modelLineList,
                        algorithmList, modelNodeAndVnodeList, opNode, endNode, branchNodeList);
                hasSimplified = true;
@@ -911,6 +1018,7 @@
        algorithm.setAlgorithmType(type);
        algorithm.setComputerList(computerList.get(0));
        algorithm.setObjectList(computerList.get(1));
        if ("vote".equals(type)) algorithm.setVoteNum(startNode.getVoteNum());
        algorithm.setStep(algorithmList.size()==0 ? 0 : algorithmList.get(algorithmList.size()-1).getStep()+1);
        algorithmList.add(algorithm);
@@ -997,23 +1105,27 @@
                    modelNode.setName(name==null ? "" : name.toString());
                    productImg.setDataId(dataId);
                    Object obj = JsonUtils2.getJsonValueByPath(jsonObject, "data/reliabDistribType".split("/"));
                    if (obj!=null && StringUtils.isNotBlank(obj.toString())) {
                        productImg.setReliabDistribType(Integer.valueOf(obj.toString()));
                    }
                    productImg.setTaskMtbcf(JsonUtils2.getJsonValueByPath(jsonObject, "data/taskMtbcf".split("/")).toString());
                    productImg.setTaskMtbcfOther(JsonUtils2.getJsonValueByPath(jsonObject, "data/taskMtbcfOther".split("/")).toString());
                    obj = JsonUtils2.getJsonValueByPath(jsonObject, "data/isRepair".split("/"));
                    if (obj!=null && StringUtils.isNotBlank(obj.toString())) {
                        productImg.setIsRepair(Integer.valueOf(obj.toString()));
                    }
                    if (1==productImg.getIsRepair()) {
                        obj = JsonUtils2.getJsonValueByPath(jsonObject, "data/repairDistribType".split("/"));
                        if (obj!=null && StringUtils.isNotBlank(obj.toString())) {
                            productImg.setRepairDistribType(Integer.valueOf(obj.toString()));
                    String productType = JsonUtils2.getJsonValueByPath(jsonObject, "data/productType".split("/")).toString();
                    productImg.setProductType(productType);
                    if ("product_sb".equals(productType)) {
                        Object obj = JsonUtils2.getJsonValueByPath(jsonObject, "data/reliabDistribType".split("/"));
                        if (obj != null && StringUtils.isNotBlank(obj.toString())) {
                            productImg.setReliabDistribType(Integer.valueOf(obj.toString()));
                        }
                        productImg.setRepairMttcr(JsonUtils2.getJsonValueByPath(jsonObject, "data/repairMttcr".split("/")).toString());
                        productImg.setRepairMttcrOther(JsonUtils2.getJsonValueByPath(jsonObject, "data/repairMttcrOther".split("/")).toString());
                        productImg.setTaskMtbcf(JsonUtils2.getJsonValueByPath(jsonObject, "data/taskMtbcf".split("/")).toString());
                        productImg.setTaskMtbcfOther(JsonUtils2.getJsonValueByPath(jsonObject, "data/taskMtbcfOther".split("/")).toString());
                        obj = JsonUtils2.getJsonValueByPath(jsonObject, "data/isRepair".split("/"));
                        if (obj != null && StringUtils.isNotBlank(obj.toString())) {
                            productImg.setIsRepair(Integer.valueOf(obj.toString()));
                        }
                        if (1 == productImg.getIsRepair()) {
                            obj = JsonUtils2.getJsonValueByPath(jsonObject, "data/repairDistribType".split("/"));
                            if (obj != null && StringUtils.isNotBlank(obj.toString())) {
                                productImg.setRepairDistribType(Integer.valueOf(obj.toString()));
                            }
                            productImg.setRepairMttcr(JsonUtils2.getJsonValueByPath(jsonObject, "data/repairMttcr".split("/")).toString());
                            productImg.setRepairMttcrOther(JsonUtils2.getJsonValueByPath(jsonObject, "data/repairMttcrOther".split("/")).toString());
                        }
                    }
                    productImgList.add(productImg);
                }
@@ -1065,6 +1177,7 @@
        }
        // 更新RBD数据
        modelRbd.setPublishedContent(modelRbd.getContent());
        modelRbdDao.updateById(modelRbd);
    }