From 9476a12cf725a13aa927278df6e3fc18fe9e80d1 Mon Sep 17 00:00:00 2001
From: xyc <jc_xiong@hotmail.com>
Date: 星期五, 01 三月 2024 11:58:29 +0800
Subject: [PATCH] 新增RBD

---
 modules/mainPart/src/main/resources/mapper/taskReliability/ModelLineDao.xml                            |   24 
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/controller/ModelLineController.java |   97 ++
 web/src/views/modules/taskReliability/ConfigEdge/index.vue                                             |  204 ++++
 web/public/modelImg/voteRight.png                                                                      |    0 
 starter/src/main/java/com/zt/security/controller/CasSsoController.java                                 |    2 
 web/src/views/modules/taskReliability/RBD-edit-img.vue                                                 | 1355 ++++++++++++++++++++++++++++
 web/public/modelImg/end.png                                                                            |    0 
 modules/mainPart/src/main/resources/mapper/taskReliability/ModelRbdDao.xml                             |   10 
 web/src/views/modules/taskReliability/ConfigNode/index.vue                                             |  256 +++++
 modules/mainPart/src/main/resources/mapper/taskReliability/ModelNodeDao.xml                            |   24 
 web/public/modelImg/start.png                                                                          |    0 
 web/public/modelImg/logo.png                                                                           |    0 
 web/public/modelImg/xianhao.png                                                                        |    0 
 web/public/modelImg/parallelRight.png                                                                  |    0 
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelRbdDao.java                |   22 
 web/src/views/modules/taskReliability/ModelLine-AddOrUpdate.vue                                        |   65 +
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelNodeDao.java               |   23 
 web/src/views/modules/taskReliability/ConfigNode/project-list-select.vue                               |  273 +++++
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/service/ModelLineService.java       |  172 +++
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelRbd.java                 |   27 
 /dev/null                                                                                              |   71 -
 web/public/modelImg/switchRight.png                                                                    |    0 
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelLineDao.java               |   24 
 web/public/modelImg/parallelLeft.png                                                                   |    0 
 web/src/views/modules/taskReliability/ModelLine.vue                                                    |   45 
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelNode.java                |   39 
 modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelLine.java                |   48 +
 27 files changed, 2,709 insertions(+), 72 deletions(-)

diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/controller/ModelLineController.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/controller/ModelLineController.java
new file mode 100644
index 0000000..8ca15aa
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/controller/ModelLineController.java
@@ -0,0 +1,97 @@
+package com.zt.life.modules.taskReliability.controller;
+
+
+import com.zt.common.annotation.LogOperation;
+import com.zt.common.constant.Constant;
+import com.zt.common.annotation.QueryParam;
+import com.zt.common.db.query.QueryFilter;
+import com.zt.common.servlet.Result;
+import com.zt.common.servlet.PageResult;
+import com.zt.common.validator.AssertUtils;
+import com.zt.common.validator.ValidatorUtils;
+import com.zt.common.validator.group.AddGroup;
+import com.zt.common.validator.group.DefaultGroup;
+import com.zt.common.validator.group.UpdateGroup;
+import com.zt.life.modules.taskReliability.model.ModelLine;
+import com.zt.life.modules.taskReliability.model.ModelRbd;
+import com.zt.life.modules.taskReliability.service.ModelLineService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@RestController
+@RequestMapping("/taskReliability/ModelLine/")
+@Api(tags="model_line")
+public class ModelLineController {
+    @Autowired
+    private ModelLineService modelLineService;
+
+    @GetMapping("page")
+    @ApiOperation("鍒嗛〉")
+    @ApiImplicitParams({
+        @ApiImplicitParam(name = Constant.Q.PAGE, value = Constant.QV.PAGE, required = true, dataType = Constant.QT.INT),
+        @ApiImplicitParam(name = Constant.Q.LIMIT, value = Constant.QV.LIMIT, required = true, dataType = Constant.QT.INT),
+        @ApiImplicitParam(name = Constant.Q.ORDER_FIELD, value = Constant.QV.ORDER_FIELD, dataType = Constant.QT.STRING),
+        @ApiImplicitParam(name = Constant.Q.ORDER, value = Constant.QV.ORDER, dataType = Constant.QT.STRING),
+    })
+    public PageResult<ModelLine> page(@ApiIgnore @QueryParam QueryFilter queryFilter){
+
+        return PageResult.ok(modelLineService.page(queryFilter));
+    }
+
+    @GetMapping("{id}")
+    @ApiOperation("淇℃伅")
+    public Result<ModelLine> get(@PathVariable("id") Long id){
+        ModelLine data = modelLineService.get(id);
+
+        return Result.ok(data);
+    }
+
+    @PostMapping
+    @ApiOperation("鏂板")
+    @LogOperation("鏂板")
+    public Result insert(@RequestBody ModelRbd modelRbd){
+        //鏁堥獙鏁版嵁
+        ValidatorUtils.validateEntity(modelRbd, AddGroup.class, DefaultGroup.class);
+        modelLineService.insert(modelRbd);
+
+        return Result.ok();
+    }
+
+    @PutMapping
+    @ApiOperation("淇敼")
+    @LogOperation("淇敼")
+    public Result update(@RequestBody ModelLine modelLine){
+        //鏁堥獙鏁版嵁
+        ValidatorUtils.validateEntity(modelLine, UpdateGroup.class, DefaultGroup.class);
+        modelLineService.update(modelLine);
+
+        return Result.ok();
+    }
+
+    @DeleteMapping
+    @ApiOperation("鍒犻櫎")
+    @LogOperation("鍒犻櫎")
+    public Result delete(@RequestBody Long[] ids){
+        //鏁堥獙鏁版嵁
+        AssertUtils.isArrayEmpty(ids, "id");
+        modelLineService.delete(ids);
+
+        return Result.ok();
+    }
+
+}
diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelLineDao.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelLineDao.java
new file mode 100644
index 0000000..328a86d
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelLineDao.java
@@ -0,0 +1,24 @@
+package com.zt.life.modules.taskReliability.dao;
+
+import com.zt.common.dao.BaseDao;
+import com.zt.life.modules.taskReliability.model.ModelLine;
+import org.apache.ibatis.annotations.Mapper;
+
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@Mapper
+public interface ModelLineDao extends BaseDao<ModelLine> {
+
+    List<ModelLine> getList(Map<String, Object> params);
+    void deleteByModelId(Long modelId);
+
+}
diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelNodeDao.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelNodeDao.java
new file mode 100644
index 0000000..4d7d814
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelNodeDao.java
@@ -0,0 +1,23 @@
+package com.zt.life.modules.taskReliability.dao;
+
+import com.zt.common.dao.BaseDao;
+import com.zt.life.modules.taskReliability.model.ModelNode;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@Mapper
+public interface ModelNodeDao extends BaseDao<ModelNode> {
+
+    List<ModelNode> getList(Map<String, Object> params);
+    void deleteByModelId(Long modelId);
+
+}
diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelRbdDao.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelRbdDao.java
new file mode 100644
index 0000000..b6e0697
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelRbdDao.java
@@ -0,0 +1,22 @@
+package com.zt.life.modules.taskReliability.dao;
+
+import com.zt.common.dao.BaseDao;
+import com.zt.life.modules.taskReliability.model.ModelNode;
+import com.zt.life.modules.taskReliability.model.ModelRbd;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@Mapper
+public interface ModelRbdDao extends BaseDao<ModelRbd> {
+
+    void deleteByModelId(Long modelId);
+}
diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelLine.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelLine.java
new file mode 100644
index 0000000..878d906
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelLine.java
@@ -0,0 +1,48 @@
+package com.zt.life.modules.taskReliability.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.zt.common.entity.BusiEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@Data
+@EqualsAndHashCode(callSuper=false)
+@TableName("model_line")
+public class ModelLine extends BusiEntity {
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty(value = "")
+	private String picId;
+
+	@ApiModelProperty(value = "")
+	private Long modelId;
+
+	@ApiModelProperty(value = "")
+	private String beginCell;
+
+	@ApiModelProperty(value = "")
+	private Long beginNode;
+
+	@ApiModelProperty(value = "")
+	private String endCell;
+
+	@ApiModelProperty(value = "")
+	private Long endNode;
+
+	@ApiModelProperty(value = "")
+	private Integer lineSort;
+
+	@ApiModelProperty(value = "")
+	private String remark;
+
+}
diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelNode.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelNode.java
new file mode 100644
index 0000000..680906f
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelNode.java
@@ -0,0 +1,39 @@
+package com.zt.life.modules.taskReliability.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.zt.common.entity.BusiEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@Data
+@EqualsAndHashCode(callSuper=false)
+@TableName("model_node")
+public class ModelNode extends BusiEntity {
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty(value = "")
+	private String picId;
+
+	@ApiModelProperty(value = "")
+	private Long modelId;
+
+	@ApiModelProperty(value = "")
+	private Long dataId;
+
+	@ApiModelProperty(value = "")
+	private String nodeType;
+
+	@ApiModelProperty(value = "")
+	private String nodeTypeExt;
+
+	@ApiModelProperty(value = "")
+	private String remark;
+
+}
diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelRbd.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelRbd.java
new file mode 100644
index 0000000..9e0f902
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelRbd.java
@@ -0,0 +1,27 @@
+package com.zt.life.modules.taskReliability.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.zt.common.entity.BusiEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@Data
+@EqualsAndHashCode(callSuper=false)
+@TableName("model_rbd")
+public class ModelRbd extends BusiEntity {
+	private static final long serialVersionUID = 1L;
+
+	@ApiModelProperty(value = "")
+	private Long modelId;
+
+	@ApiModelProperty(value = "")
+	private String content;
+
+}
diff --git a/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/service/ModelLineService.java b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/service/ModelLineService.java
new file mode 100644
index 0000000..3e24702
--- /dev/null
+++ b/modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/service/ModelLineService.java
@@ -0,0 +1,172 @@
+package com.zt.life.modules.taskReliability.service;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.alibaba.excel.util.DateUtils;
+import com.spire.pdf.tables.table.convert.Convert;
+import com.zt.common.service.BaseService;
+import com.zt.common.utils.JsonUtils2;
+import com.zt.common.utils.UUIDUtil;
+import com.zt.life.modules.taskReliability.dao.ModelLineDao;
+import com.zt.life.modules.taskReliability.dao.ModelNodeDao;
+import com.zt.life.modules.taskReliability.dao.ModelRbdDao;
+import com.zt.life.modules.taskReliability.model.ModelLine;
+import com.zt.life.modules.taskReliability.model.ModelNode;
+import com.zt.life.modules.taskReliability.model.ModelRbd;
+import org.apache.commons.lang3.StringUtils;
+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 javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * model_line
+ *
+ * @author zt generator 
+ * @since 1.0.0 2024-02-28
+ */
+@Service
+public class ModelLineService  extends BaseService<ModelLineDao, ModelLine> {
+    @Autowired
+    private ModelLineDao modelLineDao;
+    @Autowired
+    private ModelNodeDao modelNodeDao;
+    @Autowired
+    private ModelRbdDao modelRbdDao;
+
+    /**
+     * 鍒嗛〉鏌ヨ
+     *
+     * @param queryFilter
+     * @return
+     */
+    public List<ModelLine> page(QueryFilter queryFilter) {
+        return baseDao.getList(queryFilter.getQueryParams());
+    }
+
+    /**
+     * 鍒犻櫎
+     *
+     * @param ids
+     */
+    public void delete(Long[] ids) {
+        super.deleteLogic(ids);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public void insert(ModelRbd modelRbd) {
+        if (modelRbd==null) return;
+        if (modelRbd.getModelId()==null) return;
+        Long modelId = modelRbd.getModelId();
+
+        // 鍒犻櫎鏃㈡湁鏁版嵁
+        modelRbdDao.deleteByModelId(modelId);
+        modelNodeDao.deleteByModelId(modelId);
+        modelLineDao.deleteByModelId(modelId);
+
+        // 鎻掑叆鏁版嵁
+        modelRbd.setId(UUIDUtil.generateId());
+        modelRbdDao.insert(modelRbd);
+        analyzeRbdAndSave(modelId, modelRbd.getContent());
+    }
+
+    public void analyzeRbdAndSave(Long modelId, String content) {
+        String diagramJsonStr = "{\"cells\":[{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"26d1a5a6-0be8-4890-86a0-a33d429e6673\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"f91765b1-af48-4396-84ba-eb16e3476aa5\",\"port\":\"839cb2d9-59ca-4a39-a63c-26bf60cc6989\"},\"target\":{\"cell\":\"31585e99-58c7-4a98-8824-8000743b364d\",\"port\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"f2286e46-84c7-4702-8670-d7cda22c34e5\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"f91765b1-af48-4396-84ba-eb16e3476aa5\",\"port\":\"839cb2d9-59ca-4a39-a63c-26bf60cc6989\"},\"target\":{\"cell\":\"5123ad82-18bb-46fe-9d93-138b24b54a15\",\"port\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"2ab8b7f8-7fe2-490f-89c5-4250d4a62a78\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"31585e99-58c7-4a98-8824-8000743b364d\",\"port\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},\"target\":{\"cell\":\"6df9adc8-cb83-405c-8482-633db0f3644f\",\"port\":\"f93ccd2f-dedd-47b1-9ad0-9be20c5db8a4\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"700c05a5-f151-4b28-8135-705ccf013522\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"5123ad82-18bb-46fe-9d93-138b24b54a15\",\"port\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},\"target\":{\"cell\":\"6df9adc8-cb83-405c-8482-633db0f3644f\",\"port\":\"f93ccd2f-dedd-47b1-9ad0-9be20c5db8a4\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"feef2a57-3c72-4d69-92a6-c828c736b61a\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"6df9adc8-cb83-405c-8482-633db0f3644f\",\"port\":\"80d3bd61-1ed3-493a-b4e8-d4576e6fbfda\"},\"target\":{\"cell\":\"da634b2e-5ffc-4e1b-a636-f86ace9eb082\",\"port\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"49e36d6f-6a94-4edc-9894-6dd825091706\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"f91765b1-af48-4396-84ba-eb16e3476aa5\",\"port\":\"839cb2d9-59ca-4a39-a63c-26bf60cc6989\"},\"target\":{\"cell\":\"2b6df966-4e19-4055-bb13-c4c083b18e58\",\"port\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"ed8c1bfa-c0a6-4e9b-8697-862aef109bcf\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"f91765b1-af48-4396-84ba-eb16e3476aa5\",\"port\":\"839cb2d9-59ca-4a39-a63c-26bf60cc6989\"},\"target\":{\"cell\":\"323f5abe-05ed-419d-9d81-d25c7d3b19f3\",\"port\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"70c6b5fb-1b48-4a2f-bacd-be0284134818\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"2b6df966-4e19-4055-bb13-c4c083b18e58\",\"port\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},\"target\":{\"cell\":\"1f378f5e-066d-49bb-a6cc-de24a8882d65\",\"port\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"6a134969-623b-428e-9b0c-436bae2d6608\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"323f5abe-05ed-419d-9d81-d25c7d3b19f3\",\"port\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},\"target\":{\"cell\":\"1f378f5e-066d-49bb-a6cc-de24a8882d65\",\"port\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#5F95FF\"}},\"id\":\"51de5faf-1766-4dd1-abd0-eec2e867a322\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"1f378f5e-066d-49bb-a6cc-de24a8882d65\",\"port\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},\"target\":{\"cell\":\"0bb2ba89-a92d-4b32-b3cd-45df2300fa34\",\"port\":\"61eaafd2-095b-41d6-8e34-862fb470b7a6\"}},{\"shape\":\"edge\",\"attrs\":{\"line\":{\"stroke\":\"#A2B1C3\"}},\"id\":\"161f78dc-1f44-4e43-9ced-e39d345aac78\",\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"#5F95FF\"},\"text\":{\"text\":\"\"}},\"position\":{\"distance\":0.5,\"angle\":180,\"options\":{\"keepGradient\":true,\"ensureLegibility\":true}}}],\"zIndex\":0,\"source\":{\"cell\":\"da634b2e-5ffc-4e1b-a636-f86ace9eb082\",\"port\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},\"target\":{\"cell\":\"0bb2ba89-a92d-4b32-b3cd-45df2300fa34\",\"port\":\"61eaafd2-095b-41d6-8e34-862fb470b7a6\"}},{\"position\":{\"x\":-350,\"y\":-280},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"logo\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/logo.36cbc06d.png\"},\"body\":{\"stroke\":\"#5F95FF\"},\"line\":{\"stroke\":\"orange\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"31585e99-58c7-4a98-8824-8000743b364d\",\"data\":{\"dataId\":\"123456\",\"nodeType\":\"node\",\"nodeTypeExt\":\"aaa\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"bc0336ec-7912-4720-aea7-e5869de77692\"},{\"group\":\"right\",\"id\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},{\"group\":\"bottom\",\"id\":\"fef0f533-9581-4831-ba65-427f097a3d17\"},{\"group\":\"left\",\"id\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}]},\"zIndex\":1,\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"orange\"}}}]},{\"position\":{\"x\":-350,\"y\":-180},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"logo\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/logo.36cbc06d.png\"},\"body\":{\"stroke\":\"#5F95FF\"},\"line\":{\"stroke\":\"orange\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"5123ad82-18bb-46fe-9d93-138b24b54a15\",\"data\":{\"dataId\":\"123456\",\"nodeType\":\"node\",\"nodeTypeExt\":\"aaa\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"bc0336ec-7912-4720-aea7-e5869de77692\"},{\"group\":\"right\",\"id\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},{\"group\":\"bottom\",\"id\":\"fef0f533-9581-4831-ba65-427f097a3d17\"},{\"group\":\"left\",\"id\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}]},\"zIndex\":2,\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"orange\"}}}]},{\"position\":{\"x\":-620,\"y\":-200},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"start\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/start.88f586e1.png\"},\"body\":{\"stroke\":\"#5F95FF\"},\"line\":{\"stroke\":\"orange\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"f91765b1-af48-4396-84ba-eb16e3476aa5\",\"data\":{\"dataId\":\"\",\"nodeType\":\"start\",\"nodeTypeExt\":\"\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"2ad6a8d5-d86d-49e6-908a-d317b61997c1\"},{\"group\":\"right\",\"id\":\"839cb2d9-59ca-4a39-a63c-26bf60cc6989\"},{\"group\":\"bottom\",\"id\":\"7048578f-94d9-4f75-b653-eb5f43ff55db\"},{\"group\":\"left\",\"id\":\"e7bb1134-4b4c-401d-89ea-e77ae24cbd03\"}]},\"zIndex\":3,\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"orange\"}}}]},{\"position\":{\"x\":-153,\"y\":-240},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"switchRight\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/switchRight.74768797.png\"},\"body\":{\"stroke\":\"#5F95FF\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"6df9adc8-cb83-405c-8482-633db0f3644f\",\"data\":{\"dataId\":\"\",\"nodeType\":\"switchRight\",\"nodeTypeExt\":\"\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"adceedb7-f842-4d1e-be3a-8b3cb0a7e3ce\"},{\"group\":\"right\",\"id\":\"80d3bd61-1ed3-493a-b4e8-d4576e6fbfda\"},{\"group\":\"bottom\",\"id\":\"8fa84779-80b2-4c91-8366-7dd4fa0d93ff\"},{\"group\":\"left\",\"id\":\"f93ccd2f-dedd-47b1-9ad0-9be20c5db8a4\"}]},\"zIndex\":4},{\"position\":{\"x\":-21,\"y\":-240},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"logo\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/logo.36cbc06d.png\"},\"body\":{\"stroke\":\"#5F95FF\"},\"line\":{\"stroke\":\"orange\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"da634b2e-5ffc-4e1b-a636-f86ace9eb082\",\"data\":{\"dataId\":\"123456\",\"nodeType\":\"node\",\"nodeTypeExt\":\"aaa\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"bc0336ec-7912-4720-aea7-e5869de77692\"},{\"group\":\"right\",\"id\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},{\"group\":\"bottom\",\"id\":\"fef0f533-9581-4831-ba65-427f097a3d17\"},{\"group\":\"left\",\"id\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}]},\"zIndex\":5,\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"orange\"}}}]},{\"position\":{\"x\":170,\"y\":-100},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"end\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/end.814a7041.png\"},\"body\":{\"stroke\":\"#5F95FF\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"0bb2ba89-a92d-4b32-b3cd-45df2300fa34\",\"data\":{\"dataId\":\"\",\"nodeType\":\"end\",\"nodeTypeExt\":\"\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"223c9b3a-6baa-4bb8-99ba-c3300db9a942\"},{\"group\":\"right\",\"id\":\"2806bc8a-4e11-4657-9af9-089907985671\"},{\"group\":\"bottom\",\"id\":\"c56eed35-95fa-4e3c-adba-9847ef705e1c\"},{\"group\":\"left\",\"id\":\"61eaafd2-095b-41d6-8e34-862fb470b7a6\"}]},\"zIndex\":6},{\"position\":{\"x\":-350,\"y\":-54},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"logo\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/logo.36cbc06d.png\"},\"body\":{\"stroke\":\"#5F95FF\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"2b6df966-4e19-4055-bb13-c4c083b18e58\",\"data\":{\"dataId\":\"123456\",\"nodeType\":\"node\",\"nodeTypeExt\":\"aaa\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"bc0336ec-7912-4720-aea7-e5869de77692\"},{\"group\":\"right\",\"id\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},{\"group\":\"bottom\",\"id\":\"fef0f533-9581-4831-ba65-427f097a3d17\"},{\"group\":\"left\",\"id\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}]},\"zIndex\":7},{\"position\":{\"x\":-330,\"y\":40},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"logo\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/logo.36cbc06d.png\"},\"body\":{\"stroke\":\"#5F95FF\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"323f5abe-05ed-419d-9d81-d25c7d3b19f3\",\"data\":{\"dataId\":\"123456\",\"nodeType\":\"node\",\"nodeTypeExt\":\"aaa\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"bc0336ec-7912-4720-aea7-e5869de77692\"},{\"group\":\"right\",\"id\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},{\"group\":\"bottom\",\"id\":\"fef0f533-9581-4831-ba65-427f097a3d17\"},{\"group\":\"left\",\"id\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}]},\"zIndex\":8},{\"position\":{\"x\":-153,\"y\":-20},\"size\":{\"width\":60,\"height\":60},\"attrs\":{\"text\":{\"refY\":\"100%\",\"textVerticalAnchor\":\"top\",\"text\":\"logo\",\"style\":{\"color\":\"#080808\"},\"refY2\":4},\"image\":{\"xlink:href\":\"dist/img/logo.36cbc06d.png\"},\"body\":{\"stroke\":\"#5F95FF\"},\"line\":{\"stroke\":\"orange\"}},\"visible\":true,\"shape\":\"image\",\"id\":\"1f378f5e-066d-49bb-a6cc-de24a8882d65\",\"data\":{\"dataId\":\"123456\",\"nodeType\":\"node\",\"nodeTypeExt\":\"aaa\"},\"ports\":{\"groups\":{\"top\":{\"position\":\"top\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"right\":{\"position\":\"right\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"bottom\":{\"position\":\"bottom\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}},\"left\":{\"position\":\"left\",\"attrs\":{\"circle\":{\"r\":4,\"magnet\":true,\"stroke\":\"#5F95FF\",\"strokeWidth\":1,\"fill\":\"#fff\",\"style\":{\"visibility\":\"hidden\"}}}}},\"items\":[{\"group\":\"top\",\"id\":\"bc0336ec-7912-4720-aea7-e5869de77692\"},{\"group\":\"right\",\"id\":\"a977d555-b8c8-4578-9a8b-3097c405c1a8\"},{\"group\":\"bottom\",\"id\":\"fef0f533-9581-4831-ba65-427f097a3d17\"},{\"group\":\"left\",\"id\":\"01eb49d9-4b1c-466f-8263-935542436c7e\"}]},\"zIndex\":9,\"labels\":[{\"attrs\":{\"body\":{\"stroke\":\"orange\"}}}]}]}";
+
+        JSONObject diagramJson = new JSONObject(diagramJsonStr);
+        JSONArray diagramJsonArray = diagramJson.getJSONArray("cells");
+        List<ModelLine> nodelLineList = new ArrayList<>();
+        List<ModelNode> nodelNodeList = new ArrayList<>();
+
+        if (diagramJsonArray != null) {
+            for (int i = 0; i < diagramJsonArray.size(); i++) {
+                JSONObject jsonObject = diagramJsonArray.getJSONObject(i);
+                String shape = jsonObject.get("shape").toString();
+                if (shape.equals("edge")) {
+                    ModelLine modelLine = new ModelLine();
+                    modelLine.setId(UUIDUtil.generateId());
+                    modelLine.setPicId(jsonObject.get("id").toString());
+                    modelLine.setModelId(modelId);
+                    modelLine.setBeginCell(JsonUtils2.getJsonValueByPath(jsonObject, "source/cell".split("/")).toString());
+                    modelLine.setEndCell(JsonUtils2.getJsonValueByPath(jsonObject, "target/cell".split("/")).toString());
+                    //modelLineDao.insert(modelLine);
+                    nodelLineList.add(modelLine);
+                } else if (shape.equals("image")){
+                    ModelNode modelNode = new ModelNode();
+                    modelNode.setId(UUIDUtil.generateId());
+                    modelNode.setPicId(jsonObject.get("id").toString());
+                    modelNode.setModelId(modelId);
+                    modelNode.setNodeType(JsonUtils2.getJsonValueByPath(jsonObject, "data/nodeType".split("/")).toString());
+                    if ("node".equals(modelNode.getNodeType())) {
+                        modelNode.setDataId(Long.valueOf(JsonUtils2.getJsonValueByPath(jsonObject, "data/dataId".split("/")).toString()));
+                        modelNode.setNodeTypeExt(JsonUtils2.getJsonValueByPath(jsonObject, "data/nodeTypeExt".split("/")).toString());
+                    }
+                    nodelNodeList.add(modelNode);
+                    //modelNodeDao.insert(modelNode);
+                }
+            }
+        }
+        for (ModelLine line : nodelLineList) {
+            String beginCell = line.getBeginCell();
+            String endCell = line.getEndCell();
+            List<ModelNode> nodelNodeList2 = nodelNodeList.stream().filter(item->item.getPicId().equals(beginCell)).collect(Collectors.toList());
+            if (nodelNodeList2.size()>0){
+                line.setBeginNode(nodelNodeList2.get(0).getDataId());
+            }
+            List<ModelNode> nodelNodeList3 = nodelNodeList.stream().filter(item->item.getPicId().equals(endCell)).collect(Collectors.toList());
+            if (nodelNodeList3.size()>0){
+                line.setEndNode(nodelNodeList3.get(0).getDataId());
+            }
+        }
+
+        for (ModelNode modelNode : nodelNodeList) {
+            String picId = modelNode.getPicId();
+            List<ModelLine> lineList = nodelLineList.stream().filter(item->item.getEndCell().equals(picId)).collect(Collectors.toList());
+            if (lineList.size()>1){
+                if ("node".contains(modelNode.getNodeType())){
+                    String nodeTypeExt = modelNode.getNodeTypeExt();
+                    if (StringUtils.isNotBlank(nodeTypeExt)){
+                        ModelNode modelNodeNew =  new ModelNode();
+                        Long dataId = UUIDUtil.generateId()
+                        modelNodeNew.setId(dataId);
+                        modelNodeNew.setPicId(dataId.toString());
+                        modelNodeNew.setModelId(modelId);
+                        modelNodeNew.setNodeType(nodeTypeExt);
+                        nodelNodeList.add(modelNode);
+
+                        ModelLine modelLineNew = new ModelLine();
+                        Long picId2 = UUIDUtil.generateId()
+                        modelLineNew.setId(picId2);
+                        modelLineNew.setPicId(picId2.toString());
+                        modelLineNew.setModelId(modelId);
+                        modelLineNew.setBeginCell(dataId.toString());
+                        modelLineNew.setEndCell(modelNode.getPicId());
+                        modelLineNew.setBeginNode(null);
+                        modelLineNew.setEndNode(modelNode.getDataId());
+                        nodelLineList.add(modelLineNew);
+
+                        for(ModelLine nodelLine: lineList){
+                            nodelLine.setEndCell(dataId.toString());
+                            //nodelLine.setEndNode(dataId);
+                        }
+                    }
+                }
+            }
+            List<ModelNode> nodelNodeList3 = nodelNodeList.stream().filter(item->item.getPicId().equals(endCell)).collect(Collectors.toList());
+            if (nodelNodeList3.size()>0){
+                line.setEndNode(nodelNodeList3.get(0).getDataId());
+            }
+        }
+
+
+    }
+
+}
diff --git a/modules/mainPart/src/main/resources/mapper/taskReliability/ModelLineDao.xml b/modules/mainPart/src/main/resources/mapper/taskReliability/ModelLineDao.xml
new file mode 100644
index 0000000..95eab9d
--- /dev/null
+++ b/modules/mainPart/src/main/resources/mapper/taskReliability/ModelLineDao.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.zt.life.modules.taskReliability.dao.ModelLineDao">
+
+    <select id="getList" resultType="com.zt.life.modules.taskReliability.model.ModelLine">
+        select a.*
+        from model_line a
+        <where>
+            a.is_delete = 0
+            <if test="whereSql!=null">
+                and ${whereSql}
+            </if>
+        </where>
+        <if test="orderBySql!=null">
+            ORDER BY ${orderBySql}
+        </if>
+    </select>
+
+    <update id="deleteByModelId">
+        delete from model_line where model_id=#{modelId}
+    </update>
+
+</mapper>
diff --git a/modules/mainPart/src/main/resources/mapper/taskReliability/ModelNodeDao.xml b/modules/mainPart/src/main/resources/mapper/taskReliability/ModelNodeDao.xml
new file mode 100644
index 0000000..26aedf0
--- /dev/null
+++ b/modules/mainPart/src/main/resources/mapper/taskReliability/ModelNodeDao.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.zt.life.modules.taskReliability.dao.ModelNodeDao">
+
+    <select id="getList" resultType="com.zt.life.modules.taskReliability.model.ModelNode">
+        select a.*
+        from model_node a
+        <where>
+            a.is_delete = 0
+            <if test="whereSql!=null">
+                and ${whereSql}
+            </if>
+        </where>
+        <if test="orderBySql!=null">
+            ORDER BY ${orderBySql}
+        </if>
+    </select>
+
+    <update id="deleteByModelId">
+        delete from model_node where model_id=#{modelId}
+    </update>
+
+</mapper>
diff --git a/modules/mainPart/src/main/resources/mapper/taskReliability/ModelRbdDao.xml b/modules/mainPart/src/main/resources/mapper/taskReliability/ModelRbdDao.xml
new file mode 100644
index 0000000..6832632
--- /dev/null
+++ b/modules/mainPart/src/main/resources/mapper/taskReliability/ModelRbdDao.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.zt.life.modules.taskReliability.dao.ModelRbdDao">
+
+    <update id="deleteByModelId">
+        delete from model_rbd where model_id=#{modelId}
+    </update>
+
+</mapper>
diff --git a/starter/src/main/java/com/zt/security/controller/CasSsoController.java b/starter/src/main/java/com/zt/security/controller/CasSsoController.java
index 8401e14..18ea37b 100644
--- a/starter/src/main/java/com/zt/security/controller/CasSsoController.java
+++ b/starter/src/main/java/com/zt/security/controller/CasSsoController.java
@@ -8,7 +8,7 @@
 
 package com.zt.security.controller;
 
-import com.sun.deploy.net.URLEncoder;
+//import com.sun.deploy.net.URLEncoder;
 import com.zt.common.exception.ErrorCode;
 import com.zt.common.exception.RenException;
 import com.zt.common.servlet.Result;
diff --git a/starter/src/main/resources/META-INF/MANIFEST.MF b/starter/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 5aa8eae..0000000
--- a/starter/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,71 +0,0 @@
-Manifest-Version: 1.0
-Class-Path: spring-context-5.2.3.RELEASE.jar jsoup-1.11.3.jar spring-c
- ore-5.2.3.RELEASE.jar commons-compress-1.18.jar spring-websocket-5.2.
- 3.RELEASE.jar mysql-connector-java-8.0.19.jar shiro-cache-1.4.0.jar p
- oi-ooxml-4.1.0.jar cas-client-integration-tomcat-v7-3.4.1.jar mapstru
- ct-processor-1.3.1.Final.jar velocity-1.7.jar commons-io-2.5.jar spri
- ng-context-support-5.2.3.RELEASE.jar logback-core-1.2.3.jar commons-l
- ang3-3.9.jar netty-buffer-4.1.45.Final.jar xmlbeans-3.1.0.jar commons
- -lang-2.4.jar spring-webmvc-5.2.3.RELEASE.jar activation-1.1.jar drui
- d-1.1.13.jar spring-boot-starter-jdbc-2.2.4.RELEASE.jar knife4j-sprin
- g-boot-starter-2.0.1.jar spring-boot-starter-validation-2.2.4.RELEASE
- .jar fst-2.57.jar shiro-crypto-hash-1.4.0.jar netty-codec-4.1.45.Fina
- l.jar jackson-datatype-jdk8-2.10.2.jar jackson-datatype-jsr310-2.10.2
- .jar spring-aop-5.2.3.RELEASE.jar spring-data-keyvalue-2.2.4.RELEASE.
- jar commons-math3-3.6.1.jar netty-handler-4.1.45.Final.jar knife4j-co
- re-2.0.1.jar mapstruct-1.3.1.Final.jar javax.mail-1.6.2.jar commons-p
- ool2-2.7.0.jar ehcache-3.8.1.jar spring-oxm-5.2.3.RELEASE.jar spring-
- boot-autoconfigure-2.2.4.RELEASE.jar curvesapi-1.06.jar log4j-api-2.1
- 2.1.jar spring-boot-starter-json-2.2.4.RELEASE.jar hutool-all-5.1.2.j
- ar spring-web-5.2.3.RELEASE.jar knife4j-annotations-2.0.1.jar easypoi
- -annotation-4.1.0.jar jakarta.activation-api-1.2.1.jar joda-time-2.10
- .5.jar jackson-databind-2.10.2.jar spring-jcl-5.2.3.RELEASE.jar lombo
- k-1.18.4.jar reactor-core-3.3.2.RELEASE.jar spring-boot-2.2.4.RELEASE
- .jar spring-plugin-metadata-1.2.0.RELEASE.jar classmate-1.5.1.jar shi
- ro-lang-1.4.0.jar poi-tl-1.7.3.jar lettuce-core-5.2.1.RELEASE.jar com
- mons-collections4-4.3.jar jedis-3.1.0.jar mybatis-plus-boot-starter-3
- .3.1.jar spring-boot-starter-aop-2.2.4.RELEASE.jar spring-beans-5.2.3
- .RELEASE.jar asm-4.2.jar spring-jdbc-5.2.3.RELEASE.jar jsqlparser-3.1
- .jar jboss-logging-3.4.1.Final.jar spring-boot-starter-logging-2.2.4.
- RELEASE.jar netty-resolver-4.1.45.Final.jar jackson-annotations-2.10.
- 2.jar druid-spring-boot-starter-1.1.13.jar knife4j-spring-2.0.1.jar j
- ackson-core-2.10.2.jar shiro-config-ogdl-1.4.0.jar shiro-config-core-
- 1.4.0.jar error_prone_annotations-2.3.3.jar shiro-web-1.4.0.jar shiro
- -crypto-core-1.4.0.jar mybatis-3.5.3.jar commons-codec-1.13.jar shiro
- -event-1.4.0.jar easyexcel-2.2.6.jar snakeyaml-1.25.jar spring-data-c
- ommons-2.2.4.RELEASE.jar jul-to-slf4j-1.7.30.jar jjwt-0.9.1.jar j2cac
- he-core-2.8.0-release.jar mybatis-plus-annotation-3.3.1.jar tomcat-em
- bed-el-9.0.30.jar jakarta.annotation-api-1.3.5.jar netty-common-4.1.4
- 5.Final.jar jaxb-runtime-2.3.2.jar springfox-swagger-common-2.9.2.jar
-  spring-boot-starter-data-redis-2.2.4.RELEASE.jar hibernate-validator
- -6.0.18.Final.jar mybatis-plus-core-3.3.1.jar txw2-2.3.2.jar spring-p
- lugin-core-1.2.0.RELEASE.jar spring-messaging-5.2.3.RELEASE.jar jakar
- ta.validation-api-2.0.2.jar jackson-module-parameter-names-2.10.2.jar
-  mybatis-plus-extension-3.3.1.jar tomcat-embed-core-9.0.30.jar poi-4.
- 1.0.jar log4j-to-slf4j-2.12.1.jar HikariCP-3.4.2.jar checker-qual-2.1
- 0.0.jar commons-beanutils-1.9.3.jar jsqlparser-2.0.jar javassist-3.20
- .0-GA.jar javassist-3.21.0-GA.jar swagger-models-1.5.22.jar netty-tra
- nsport-4.1.45.Final.jar springfox-schema-2.9.2.jar fastjson-1.2.62.ja
- r commons-collections-3.2.1.jar knife4j-spring-ui-2.0.1.jar stax-ex-1
- .8.1.jar springfox-bean-validators-2.9.2.jar byte-buddy-1.10.6.jar cg
- lib-3.1.jar freemarker-2.3.29.jar spring-boot-starter-web-2.2.4.RELEA
- SE.jar logback-classic-1.2.3.jar cas-client-integration-tomcat-common
- -3.4.1.jar spring-boot-starter-2.2.4.RELEASE.jar lombok-1.18.10.jar s
- pringfox-spi-2.9.2.jar istack-commons-runtime-3.0.8.jar spring-boot-s
- tarter-websocket-2.2.4.RELEASE.jar spring-boot-starter-tomcat-2.2.4.R
- ELEASE.jar guava-16.0.1.jar jedis-2.9.0.jar aspectjweaver-1.9.5.jar p
- agehelper-5.1.11.jar springfox-swagger2-2.9.2.jar cas-client-core-3.4
- .1.jar reactive-streams-1.0.3.jar shiro-core-1.4.0.jar easy-captcha-1
- .6.2.jar spring-expression-5.2.3.RELEASE.jar springfox-core-2.9.2.jar
-  kingbase8-8.2.0.jar swagger-annotations-1.5.22.jar httpclient-4.5.10
- .jar guava-20.0.jar spring-tx-5.2.3.RELEASE.jar shiro-spring-1.4.0.ja
- r spring-data-redis-2.2.4.RELEASE.jar j2cache-spring-boot2-starter-2.
- 8.0-release.jar objenesis-2.5.1.jar jline-2.14.2.jar jakarta.xml.bind
- -api-2.3.2.jar mybatis-spring-2.0.3.jar httpcore-4.4.13.jar mybatis-p
- lus-3.3.1.jar validation-api-2.0.1.Final.jar poi-ooxml-schemas-4.1.0.
- jar knife4j-spring-boot-autoconfigure-2.0.1.jar commons-collections-3
- .2.2.jar slf4j-api-1.7.30.jar easypoi-base-4.1.0.jar springfox-spring
- -web-2.9.2.jar FastInfoset-1.2.16.jar caffeine-2.8.0.jar shiro-crypto
- -cipher-1.4.0.jar tomcat-embed-websocket-9.0.30.jar ognl-3.2.6.jar
-Main-Class: com.zt.life.AdminApplication
-
diff --git a/web/public/modelImg/end.png b/web/public/modelImg/end.png
new file mode 100644
index 0000000..b993674
--- /dev/null
+++ b/web/public/modelImg/end.png
Binary files differ
diff --git a/web/public/modelImg/logo.png b/web/public/modelImg/logo.png
new file mode 100644
index 0000000..e154da0
--- /dev/null
+++ b/web/public/modelImg/logo.png
Binary files differ
diff --git a/web/public/modelImg/parallelLeft.png b/web/public/modelImg/parallelLeft.png
new file mode 100644
index 0000000..4491155
--- /dev/null
+++ b/web/public/modelImg/parallelLeft.png
Binary files differ
diff --git a/web/public/modelImg/parallelRight.png b/web/public/modelImg/parallelRight.png
new file mode 100644
index 0000000..41e41fd
--- /dev/null
+++ b/web/public/modelImg/parallelRight.png
Binary files differ
diff --git a/web/public/modelImg/start.png b/web/public/modelImg/start.png
new file mode 100644
index 0000000..11ac8b4
--- /dev/null
+++ b/web/public/modelImg/start.png
Binary files differ
diff --git a/web/public/modelImg/switchRight.png b/web/public/modelImg/switchRight.png
new file mode 100644
index 0000000..a8d1967
--- /dev/null
+++ b/web/public/modelImg/switchRight.png
Binary files differ
diff --git a/web/public/modelImg/voteRight.png b/web/public/modelImg/voteRight.png
new file mode 100644
index 0000000..55d7a48
--- /dev/null
+++ b/web/public/modelImg/voteRight.png
Binary files differ
diff --git a/web/public/modelImg/xianhao.png b/web/public/modelImg/xianhao.png
new file mode 100644
index 0000000..59612b7
--- /dev/null
+++ b/web/public/modelImg/xianhao.png
Binary files differ
diff --git a/web/src/views/modules/taskReliability/ConfigEdge/index.vue b/web/src/views/modules/taskReliability/ConfigEdge/index.vue
new file mode 100644
index 0000000..593ebcf
--- /dev/null
+++ b/web/src/views/modules/taskReliability/ConfigEdge/index.vue
@@ -0,0 +1,204 @@
+<template>
+  <div style="position: absolute;top:6%;right:0;z-index:1000;background:#cccccc;width: 300px;" :style="'height:'+ left_p + 'px'">
+  <el-card style="height: 100%">
+    <el-tabs v-model="activeName" id="EdgeTabPane">
+      <el-tab-pane label="绾挎潯"  name="first">
+        <el-row :gutter="5" align="middle" style="margin-top:20px;">
+          <el-col :span=8 style="font-size: 16px;line-height: 38px">瀹藉害</el-col>
+          <el-col :span=16>
+            <el-slider :min=1 :max=20 :step=1 v-model="globalGridAttr.strokeWidth" @change="onStrokeWidthChange"></el-slider>
+          </el-col>
+        </el-row>
+        <el-row :gutter="5" align="middle" style="margin-top:20px;">
+          <el-col :span=8 style="font-size: 16px;line-height: 38px">棰滆壊</el-col>
+          <el-col :span=16>
+            <el-color-picker  v-model="globalGridAttr.stroke" style="width: 100%" @change="onStrokeChange"></el-color-picker>
+          </el-col>
+        </el-row>
+        <el-row :gutter="5" align="middle" style="margin-top:20px;">
+          <el-col :span=8 style="font-size: 16px;line-height: 32px">绫诲瀷</el-col>
+          <el-col :span=16>
+            <el-select style="width: 100%" v-model="globalGridAttr.connector" @change="onConnectorChange">
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+<!--              <el-option value="normal">榛樿</el-option>-->
+<!--              <el-option value="smooth">骞虫粦</el-option>-->
+<!--              <el-option value="rounded">鍦嗗舰</el-option>-->
+<!--              <el-option value="jumpover">鎶樼嚎</el-option>-->
+            </el-select>
+          </el-col>
+        </el-row>
+        <el-row :gutter="5" align="middle" style="margin-top:20px;">
+          <el-col :span=8 style="font-size: 16px;line-height: 32px">鏍囩</el-col>
+          <el-col :span=16>
+            <el-input v-model="globalGridAttr.label" style="width: 100%" @change="onLabelChange"/>
+          </el-col>
+        </el-row>
+        <el-row v-show="globalGridAttr.label!==''" :gutter="5" align="middle" style="margin-top:20px;">
+          <el-col :span=8 style="font-size: 16px;line-height: 32px">鍋忕Щ</el-col>
+          <el-col :span=16>
+            <el-slider :min=0.1 :max=1 :step=0.1 v-model="globalGridAttr.distance" @change="onLabelDistanceChange"></el-slider>
+<!--            <el-input v-model="globalGridAttr.distance" style="width: 100%" @change="onLabelDistanceChange"/>-->
+          </el-col>
+        </el-row>
+<!--        <el-row v-show="globalGridAttr.label!==''" :gutter="5" align="middle" style="margin-top:20px;">-->
+<!--          <el-col :span=8 style="font-size: 16px;line-height: 32px">瑙掑害</el-col>-->
+<!--          <el-col :span=16>-->
+<!--            <el-slider :min=-360 :max=360 :step=1 v-model="globalGridAttr.angle" @change="onLabelAngleChange"></el-slider>-->
+<!--          </el-col>-->
+<!--        </el-row>-->
+      </el-tab-pane>
+    </el-tabs>
+  </el-card>
+  </div>
+</template>
+
+<script>
+import { Edge} from '@antv/x6';
+export default {
+  name: "index",
+  data(){
+    return{
+      left_p:document.documentElement.clientHeight*0.9,
+      activeName: 'first',
+      // globalGridAttr:{},
+      curCell:Edge,
+      options: [{
+        value: 'normal',
+        label: '榛樿'
+      }, {
+        value: 'smooth',
+        label: '骞虫粦杩炵嚎'
+      }]
+    }
+  },
+  props:{
+    id: {
+      type: String,
+    },
+    globalGridAttr:{
+      type: Object,
+    },
+    graph:{
+      type: String,
+    }
+  },
+  watch:{
+    'id'(val,oldVal){
+      const cell = this.graph.getCellById(this.id)
+      if(!cell || !cell.isEdge()){
+        return
+      }
+      this.curCell = cell
+      let connector = cell.getConnector() || {
+        name:'榛樿'
+      }
+      this.globalGridAttr.stroke = cell.attr('line/stroke')
+      this.globalGridAttr.strokeWidth = cell.attr('line/strokeWidth')
+      this.globalGridAttr.connector = connector.name
+      this.globalGridAttr.label = cell.getLabels()[0].attrs.text? cell.getLabels()[0].attrs.text.text:''
+      this.globalGridAttr.distance =cell.getLabels()[0].position.distance
+      // this.globalGridAttr.angle =cell.getLabels()[0].position.angle
+      console.log(cell.getLabels(),'cell.getLabels()')
+      // console.log(cell.getLabels()[0],'cell.getLabels()[0]')
+      //  this.globalGridAttr.label = (cell.getLabels()[0].attrs).text.text||''
+    }
+  },
+  methods:{
+    onStrokeWidthChange(val) {
+
+      this.globalGridAttr.strokeWidth = val
+      this.curCell.attr('line/strokeWidth', val)
+    },
+
+    onStrokeChange(e) {
+      const val = e
+      this.globalGridAttr.stroke = val
+      this.curCell.attr('line/stroke', val)
+    },
+    onConnectorChange(val){
+      this.globalGridAttr.connector = val
+      this.curCell.setConnector(val)
+    },
+    onLabelChange(e) {
+      const val = e
+      this.globalGridAttr.label = val
+
+      this.curCell.setLabels([
+        {
+          attrs: {
+            text: {
+              text: val,
+            },
+          },
+          position:{
+            distance:0.5,
+            angle: 180,
+            options: {
+              keepGradient: true,
+              ensureLegibility: true
+            }
+          }
+        }
+      ])
+    },
+    onLabelDistanceChange(e){
+      const val = e
+      this.globalGridAttr.distance = val
+      console.log(val)
+      this.curCell.setLabels([
+        {
+          attrs: {
+            text: {
+              text: this.globalGridAttr.label,
+            },
+          },
+          position: {
+            distance: val,
+            angle: 180,
+            options: {
+              keepGradient: true,
+              ensureLegibility: true
+            }
+          },
+        }
+      ])
+    },
+    // onLabelAngleChange(e){
+    //   const val = e
+    //   // this.globalGridAttr.angle = val
+    //   this.curCell.setLabels([
+    //     {
+    //       attrs: {
+    //         text: {
+    //           text: this.globalGridAttr.label,
+    //         },
+    //       },
+    //       position: {
+    //         distance:this.globalGridAttr.distance,
+    //         options: {
+    //           keepGradient: true
+    //         }
+    //       },
+    //     }
+    //   ])
+    // }
+  }
+}
+</script>
+
+<style >
+#EdgeTabPane .el-tabs__header.is-top .el-tabs__nav-scroll{
+  width: 100% !important;
+}
+#EdgeTabPane .el-tabs__nav.is-top{
+  -webkit-transform: translateX(35px) !important
+}
+#EdgeTabPane .el-color-picker__trigger{
+  width: 100%;
+}
+</style>
diff --git a/web/src/views/modules/taskReliability/ConfigNode/index.vue b/web/src/views/modules/taskReliability/ConfigNode/index.vue
new file mode 100644
index 0000000..ebf59e9
--- /dev/null
+++ b/web/src/views/modules/taskReliability/ConfigNode/index.vue
@@ -0,0 +1,256 @@
+<template>
+  <div style="position: absolute;top:6%;right:0;background:#cccccc;width: 300px;" :style="'height:'+ left_p + 'px'">
+  <el-card style="height: 100%">
+    <el-tabs v-model="activeName" id="tabPane">
+      <el-tab-pane label="鏂囨湰"  name="first">
+        <el-row :gutter="5" align="middle" style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 38px">鏂囨湰澶у皬</el-col>
+          <el-col :span=16>
+            <el-slider :min=8 :max=20 :step=1 v-model="globalGridAttr.nodeFontSize" @change="onFontSizeChange"></el-slider>
+          </el-col>
+        </el-row>
+        <el-row :gutter="5" align="middle" style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 40px">瀛椾綋棰滆壊</el-col>
+          <el-col :span=16>
+            <el-color-picker  v-model="globalGridAttr.nodeColor" style="width: 100%" @change="onColorChange"></el-color-picker>
+          </el-col>
+        </el-row>
+        <el-row v-show="shape!=='custom-text' || shape!=='custom-circle1'" :gutter="5" align="middle" style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 32px">椤圭洰鍚嶇О</el-col>
+          <el-col :span=16 >
+            <el-input  @click.native='showDialog' v-model="globalGridAttr.inspectName" style="width:100%"></el-input>
+          </el-col>
+        </el-row>
+        <el-row :gutter="5" v-show="shape!=='custom-circle1'"  align="middle" style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 32px">杩囩▼鍚嶇О</el-col>
+          <el-col :span=16 >
+            <el-input  v-model="globalGridAttr.nodeText" style="width:100%" @change="onTextChange"></el-input>
+          </el-col>
+        </el-row>
+        <el-row v-show="shape!=='custom-text'" :gutter="5" align="middle" style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 32px">鏃ユ湡</el-col>
+          <el-col :span=16 >
+            <el-date-picker v-model="globalGridAttr.nodeDate" type="date" placeholder="閫夋嫨鏃ユ湡" value-format="yyyy-MM-dd"
+                            style="width: 100%" @change="onDateChange">
+            </el-date-picker>
+          </el-col>
+        </el-row>
+      </el-tab-pane>
+      <el-tab-pane label="鑺傜偣"  name="second">
+        <el-row align="middle" style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 40px">杈规棰滆壊</el-col>
+          <el-col :span=16>
+            <el-color-picker v-model="globalGridAttr.nodeStroke" style="width: 100%" @change="onStrokeChange"></el-color-picker>
+          </el-col>
+        </el-row>
+        <el-row align="middle"style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 38px">杈规瀹藉害</el-col>
+          <el-col :span=16>
+            <el-slider :min=1 :max=20 :step=1 v-model="globalGridAttr.nodeStrokeWidth" @change="onStrokeWidthChange"></el-slider>
+          </el-col>
+        </el-row>
+        <el-row align="middle" style="margin-top:20px">
+          <el-col :span=8 style="font-size: 16px;line-height: 40px">棰滆壊</el-col>
+          <el-col :span=16>
+            <el-color-picker  v-model="globalGridAttr.nodeFill" style="width: 100%" @change="onFillChange"></el-color-picker>
+          </el-col>
+        </el-row>
+      </el-tab-pane>
+    </el-tabs>
+  </el-card>
+    <el-dialog ref="detailedDialog"  title="閫夋嫨椤圭洰" width='85%' :visible.sync="dialogVisible ">
+      <Inspection @func="procResult" ref="inspectionNode" />
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { Graph, Shape, Node, Addon, Cell,FunctionExt} from '@antv/x6';
+import Inspection from './project-list-select'
+// const {inject} = require("vue");
+export default {
+  name: "index",
+  data(){
+    return{
+      data:{
+        dataId:'',
+        finishDate: '',
+        inspectName:''
+      },
+      date:'',
+      text:'',
+      dateId:'',
+      content:'',
+      dialogVisible:false,
+      activeName: 'first',
+      // globalGridAttr:{},
+      curCel:Cell,
+      left_p:document.documentElement.clientHeight*0.9,
+    }
+  },
+  components:{
+    Inspection
+  },
+  props:{
+    id: {
+      type: String,
+    },
+    shape:{
+      type: String
+    },
+    refY2:{
+      type: Number
+    },
+    globalGridAttr:{
+      type: Object,
+    },
+    graph:{
+      type: String,
+    },
+    projectId:{
+      type: String,
+    },
+    diagramId:{
+      type: String,
+    }
+  },
+  watch:{
+    'id'(val,oldVal){
+      this.curCel = this.nodeOpt(this.id,this.globalGridAttr)
+    }
+  },
+  mounted() {
+    // this.curCel = this.nodeOpt(this.id,this.globalGridAttr)
+  },
+  methods:{
+    showDialog() {
+      let param = {projectId:this.projectId,diagramId:this.diagramId}
+      console.log(param, 'dialog init param')
+      this.dialogVisible = true;
+      this.$nextTick(()=>{
+        this.$refs.inspectionNode.init(param)
+      })
+    },
+    procResult(node) {
+      // console.log(node,'node')
+      this.text =node.nodeName
+      this.dateId = node.nodeId
+      this.globalGridAttr.dataId = this.dateId
+      this.globalGridAttr.inspectName = this.text
+      this.globalGridAttr.nodeText = this.text
+      this.data={
+        dataId:this.dateId,
+        inspectName:this.text
+      }
+      this.curCel.setData(this.data)
+      this.curCel.attr('text/text', this.text)
+      this.curCel.attr('data/dataId', this.dateId)
+      this.curCel.attr('data/inspectName', this.text)
+      this.curCel = this.nodeOpt(this.id,this.globalGridAttr)
+      this.dialogVisible = false
+      // console.log(node,'dialog绐楀彛杩斿洖鍊�')
+    },
+    // 鏀瑰彉杈规棰滆壊
+    onStrokeChange(e){
+      let val = e
+      this.globalGridAttr.nodeStroke = val
+     this.curCel.attr('body/stroke', val)
+    },
+    //鏀瑰彉杈规澶у皬
+    onStrokeWidthChange(e){
+      let val =e
+      this.globalGridAttr.nodeStrokeWidth = val
+      this.curCel.attr('body/strokeWidth', val)
+    },
+    //鏀瑰彉鏂囨湰棰滆壊
+    onFillChange(e){
+      let val = e
+      this.globalGridAttr.nodeFill=val
+      this.curCel.attr('body/fill', val)
+      // this.curCel.attr('title/fill', val)
+    },
+    // 鏀瑰彉瀛椾綋澶у皬
+    onFontSizeChange(e){
+      let val =e
+      this.globalGridAttr.nodeFontSize = val
+      this.curCel.attr('text/fontSize', val)
+      this.curCel.attr('title/fontSize', val)
+    },
+    // 鏀瑰彉瀛椾綋棰滆壊
+    onColorChange(e){
+      let val =e
+      this.globalGridAttr.nodeColor = val
+      this.curCel.attr('text/fill', val)
+      this.curCel.attr('title/fill', val)
+      this.curCel.attr('text/style/color', val)
+      this.curCel.attr('title/style/color', val)
+      this.curCel = this.nodeOpt(this.id,this.globalGridAttr)
+    },
+    // 鏀瑰彉鏂囨湰
+    onTextChange(e){
+      this.text =e
+      this.globalGridAttr.nodeText = this.text
+      this.curCel.attr('label/textWrap/text', this.text)
+      this.curCel = this.nodeOpt(this.id,this.globalGridAttr)
+
+    },
+    onDateChange(e){
+      this.date =e
+       this.globalGridAttr.nodeDate = this.date
+       this.data={
+        finishDate:this.date,
+      }
+      this.curCel.setData(this.data)
+      if(this.shape=='custom-circle1'){
+        this.curCel.attr('text/text', this.date)
+      }
+      this.curCel.attr('title/text', this.date)
+      this.curCel = this.nodeOpt(this.id,this.globalGridAttr)
+    },
+    nodeOpt(id, globalGridAttr){
+      this.curCel=null
+      if(id){
+        let cell =  this.graph.getCellById(id)
+        // console.log(cell,'let cell 123456')
+        if (!cell || !cell.isNode()) {
+          return
+        }
+        this.curCel = cell
+        globalGridAttr.nodeStroke = cell.attr('body/stroke')
+        globalGridAttr.nodeStrokeWidth = cell.attr('body/strokeWidth')
+        globalGridAttr.nodeFill = cell.attr('body/fill')
+        // globalGridAttr.nodeFontSize = cell.attr('text/fontSize')
+        // globalGridAttr.nodeFontSize = cell.attr('title/fontSize')
+        globalGridAttr.nodeFontSize = cell.attr('text/fontSize')?cell.attr('text/fontSize'):cell.attr('title/fontSize')
+        globalGridAttr.nodeColor = cell.attr('text/fill') ? cell.attr('text/fill'):cell.attr('title/fill')?cell.attr('title/fill'):cell.attr('label/text/fill')
+        // globalGridAttr.nodeColor = cell.attr('text/fill')
+        // globalGridAttr.nodeColor = cell.attr('title/fill')
+        // globalGridAttr.nodeColor = cell.attr('text/style/color')
+        // globalGridAttr.nodeColor =  cell.attr('title/style/color')
+        globalGridAttr.nodeUsers = cell.attr('approve/users')
+        globalGridAttr.nodeText = cell.attr('label/textWrap/text')
+        if(this.shape=='custom-circle1'){
+          globalGridAttr.nodeDate = cell.attr('text/text')
+        }
+        globalGridAttr.nodeDate = cell.attr('title/text')
+        globalGridAttr.dataId = cell.getData().dataId
+        globalGridAttr.inspectName =cell.getData().inspectName
+        // console.log(globalGridAttr.inspectName,globalGridAttr.dataId,globalGridAttr.nodeDate,'globalGridAttr.inspectName,globalGridAttr.dataId,globalGridAttr.nodeDate 789')
+        cell.getData()
+        // console.log( cell.getData(),' cell.getData() 909')
+      }
+      return this.curCel;
+    }
+  }
+}
+</script>
+
+<style >
+#tabPane .el-tabs__header.is-top .el-tabs__nav-scroll{
+width: 100% !important;
+}
+
+#tabPane .el-color-picker__trigger{
+  width: 100%;
+}
+</style>
diff --git a/web/src/views/modules/taskReliability/ConfigNode/project-list-select.vue b/web/src/views/modules/taskReliability/ConfigNode/project-list-select.vue
new file mode 100644
index 0000000..063761e
--- /dev/null
+++ b/web/src/views/modules/taskReliability/ConfigNode/project-list-select.vue
@@ -0,0 +1,273 @@
+<template>
+  <div class="v-service-user">
+    <zt-table-wraper ref="tableObj" query-url="/maintain/projectNetworkDiagram/getInspectionPage" :lazy="true" :paging='true'
+                     delete-url="/project/inspection" v-slot="{ table }">
+      <el-form :inline="true" :model="dataForm" @keyup.enter.native="table.query()">
+        <el-form-item class="toolbar">
+          <el-form-item prop="projectId" style="margin-top: 2px;width: 150px;">
+            <zt-select v-model="dataForm.projectId" :datas="model" placeholder="宸ョ▼椤圭洰" clearable></zt-select>
+          </el-form-item>
+          <el-form-item style="margin-top: 2px;" v-show="selectProjectFlag">
+            <el-input v-model="dataForm.userKey" placeholder="鍏抽敭瀛�" style="width: 150px;" clearable></el-input>
+          </el-form-item>
+          <!--<el-form-item prop="projectMajor" style="margin-top: 2px;width: 150px;">-->
+          <!--<zt-dict v-model="dataForm.projectMajor" dict="project_major" placeholder="宸ョ▼涓撲笟" clearable></zt-dict>-->
+          <!--</el-form-item>-->
+          <el-form-item prop="reconditionMajor" style="margin-top: 2px;width: 120px;" v-show="selectProjectFlag">
+            <zt-dict v-model="dataForm.reconditionMajor" dict="recondition_major" placeholder="鐩戜慨涓撲笟"
+                     clearable></zt-dict>
+          </el-form-item>
+          <el-form-item style="width:130px;margin-top: 2px;" v-show="selectProjectFlag">
+            <zt-dict v-model="dataForm.projectType" dict="project_type" placeholder="椤圭洰绫诲瀷"
+                     @keyup.enter.native="table.query()" clearable></zt-dict>
+          </el-form-item>
+          <el-form-item style="width:120px;margin-top: 2px;" v-show="selectProjectFlag">
+            <el-select v-model="dataForm.planStatus" placeholder="椤圭洰鐘舵��" @change="table.query()" clearable>
+              <el-option label="鏈畬宸�" value="0"></el-option>
+              <el-option label="宸插畬宸�" value="1"></el-option>
+              <el-option label="宸插彇娑�" value="2"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item class="message-btn" style="margin-top: 2px;">
+            <el-button type="primary" size="medium" icon="el-icon-search" @click="table.query()">鎼滅储
+            </el-button>
+          </el-form-item>
+        </el-form-item>
+      </el-form>
+      <!--{{ table }}-->
+      <el-table id="table" ref="table" v-adaptive="{bottomOffset:120}" height="650px" v-loading="table.dataLoading"
+                :data="table.dataList" :default-expand-all="false" :paging="true" @current-change="showProjectList"
+                border  align-text="left"
+                @selection-change="table.selectionChangeHandle" row-key="id" width="100%" lazy :load="load"
+                class="repair_button"
+                @row-dblclick="rowDblclick"
+                :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
+        <el-table-column type="selection" width="40" v-show="!isShow"/>
+        <el-table-column prop="projectListCode" label="缂栧彿" width="160" v-if="showColumn.projectListCode" sortable show-overflow-tooltip >
+        </el-table-column>
+        <el-table-column prop="projectListName" label="宸ョ▼鍚嶇О"  v-if="showColumn.projectListName" show-overflow-tooltip/>
+        <el-table-column prop="examineConcat" label="妫�楠屽唴瀹�"  v-if="showColumn.examineConcat" show-overflow-tooltip/>
+        <el-table-column prop="maintainUnitName" label="鎵夸慨鍗曚綅" v-if="showColumn.maintainUnit" show-overflow-tooltip/>
+      </el-table>
+    </zt-table-wraper>
+  </div>
+</template>
+
+<script>
+  export default {
+    props: {
+      noImportCodes: {
+        type: Object
+      },
+      isShow: {
+        type: Number
+      },
+      projectTypeName: {
+        type: String
+      }
+    },
+    data() {
+      return {
+        timeNodeArr: [{projectType: '', projectTypeName: '', timeNode: ''}],
+        timeNodesForm: {
+          timeNodes: ''
+        },
+        isShowColumn: '',
+        dialogFormVisible: false,
+        checkList: {},
+        showColumn: {
+          projectListCode: true,
+          projectListName: true,
+          examineConcat: true,
+          maintainUnit: true,
+          gmtFinish: true,
+          reconditionMajor: true,
+          isSpecial: true,
+          armyType: true,
+          isCheck: true,
+          files: true,
+          projectTypeName: true,
+          planStatus: true,
+          timeRemaining: true,
+          deadline: true,
+          cause: true,
+        },
+        fullHeight: (document.documentElement.clientHeight - 210) - 120,
+        word: {},
+        dataForm: {
+          projectId: '',
+          diagramId:'',
+          reconditionMajor: '',
+          projectTypeName: '',
+          productId: '', // 閫夋嫨鐨勪骇鍝佽妭鐐�
+          userKey: '', // 鐢ㄦ埛杈撳叆鍏抽敭瀛�
+          projectMajor: '', // 宸ョ▼涓撲笟
+          id: '',
+          projectName: '',
+          planStatus: '',
+          type: '',
+          projectNode: '',
+          floatTime: '',
+          typeStr: '',
+          maxDate: '',
+          minDate: '',
+          options: [],
+        },
+        constructionOrInspection: 1,
+        model: '',
+        timeNodeArr: [],
+        options: [{value: 0, label: '鍚�'}, {value: 1, label: '鏄�'}],
+        postList: [{id: '0', name: '鏈畬宸�'}, {id: '1', name: '宸插畬宸�'}, {id: '2', name: '宸插彇娑�'}],
+        equipments: {
+          equipments: []
+        },
+        parts: {
+          parts: []
+        },
+        stateFrom: {
+          id: '',
+          planStatus: ''
+        },
+        oldDataForm: {
+          productId: '',
+          projectId: '',
+          maintainLevel: ''
+        },
+        queryForm: {
+          productId: '',
+          projectId: '',
+          maintainLevel: ''
+        },
+        technologyData: {
+          equipmentData: [],
+          unitData: []
+        },
+        // postList: [{id: '3', name: '鏈鎵�'}, {id: '0', name: '宸查┏鍥�'}, {id: '1', name: '宸插悓鎰�'}],
+        twoPostList: [{id: '3', name: '鏈鎵�'}, {id: '0', name: '宸查┏鍥�'}, {id: '1', name: '宸插悓鎰�'}],
+        isStyle: "margin-top:-10px",
+        ids: [],
+        productId: '',
+        armyCheckNo: '',
+        selectProjectFlag: false,
+        timeNodes: false
+      }
+    },
+    components: {
+    },
+    computed: {
+    },
+    created() {
+    },
+    mounted() {
+      this.getInfo()
+    },
+    watch: {
+    },
+    methods: {
+      init(item) {
+        // this.$nextTick(()=>{
+        console.log(item, "dialog init param.....................")
+        this.dataForm.projectId = item.projectId
+        this.dataForm.diagramId = item.diagramId
+        this.selectProjectFlag = true
+        console.log(this.dataForm, ' init this.dataForm')
+        this.$refs.tableObj.query()
+        // })
+      },
+      rowDblclick(row) {
+        console.log(row.id,'鍙屽嚮琛岀殑id')
+        console.log(row.name,'鍙屽嚮琛岀殑鏁版嵁')
+        this.$emit('func',{nodeId:row.id,nodeName:row.projectListName})
+      },
+      async getInfo(){
+        if (this.$store.state.user.localShip) {
+          this.dataForm.productId = this.$store.state.user.localShip
+        }
+        let res = await this.$http.get(`/homeFunction/projectSelect?productId=${this.dataForm.productId}`)
+        this.model = res.data
+        if (this.model.length > 0 && !this.dataForm.projectId) {
+          this.dataForm.projectId = this.model[0].id
+        }
+      }
+    }
+  }
+</script>
+<style lang="less" >
+  #columnOption {
+    position: fixed;
+    z-index: 20;
+    top: 15%;
+    left: 80%;
+    width: 10%;
+    height: 60%;
+    background-color: rgba(0, 0, 0, 0.3);
+    display: flex;
+    flex-direction: row-reverse;
+    .content {
+      width: 100%;
+      height: 100%;
+      .head {
+        width: 100%;
+        height: 44px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        font-size: 15px;
+      }
+      .body {
+        width: 88%;
+        height: calc(100% - 88px);
+        box-sizing: border-box;
+        margin-left:20px;
+        padding-top: 10px;
+        overflow-y: auto;
+        .items {
+          width: 100%;
+          height: 100%;
+          overflow-y: auto;
+          display: flex;
+          flex-direction: column;
+          .el-checkbox__label {
+            width: 100%;
+            height: 28px;
+            line-height: 28px;
+            margin-bottom: 14px;
+            display: inline-block;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 14px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+            box-sizing: border-box;
+            padding-left: 14px;
+          }
+          .el-checkbox:hover {
+            background-color: #f5f7fa;
+          }
+        }
+      }
+      #footer {
+        width: 100%;
+        height: 44px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        size: 20px;
+      }
+    }
+  }
+  // 鎺у埗娣″叆娣″嚭鏁堟灉
+  .fade-enter-active,
+  .fade-leave-active {
+    transition: opacity 0.3s;
+  }
+  .fade-enter,
+  .fade-leave-to {
+    opacity: 0;
+  }
+  #columnOption .el-checkbox{
+    display: block;
+    margin-top:10px;
+  }
+</style>
diff --git a/web/src/views/modules/taskReliability/ModelLine-AddOrUpdate.vue b/web/src/views/modules/taskReliability/ModelLine-AddOrUpdate.vue
new file mode 100644
index 0000000..1283cf7
--- /dev/null
+++ b/web/src/views/modules/taskReliability/ModelLine-AddOrUpdate.vue
@@ -0,0 +1,65 @@
+<template>
+  <zt-dialog ref="dialog"  @confirm="formSubmit">
+    <el-form :model="dataForm" ref="dataForm" :disabled="dataForm.disabled" label-width="120px">
+      <zt-form-item label="" prop="picId" rules="required">
+                        <el-input v-model="dataForm.picId"></el-input>
+                </zt-form-item>
+      <zt-form-item label="" prop="modelId" rules="required">
+                        <el-input v-model="dataForm.modelId"></el-input>
+                </zt-form-item>
+      <zt-form-item label="" prop="beginCell" rules="required">
+                        <el-input v-model="dataForm.beginCell"></el-input>
+                </zt-form-item>
+      <zt-form-item label="" prop="beginNode" rules="required">
+                        <el-input v-model="dataForm.beginNode"></el-input>
+                </zt-form-item>
+      <zt-form-item label="" prop="endCell" rules="required">
+                        <el-input v-model="dataForm.endCell"></el-input>
+                </zt-form-item>
+      <zt-form-item label="" prop="endNode" rules="required">
+                        <el-input v-model="dataForm.endNode"></el-input>
+                </zt-form-item>
+      <zt-form-item label="" prop="lineSort" rules="required">
+                        <el-input v-model="dataForm.lineSort"></el-input>
+                </zt-form-item>
+    </el-form>
+  </zt-dialog>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        dataForm: {
+          id: '',
+          picId: '',
+          modelId: '',
+          beginCell: '',
+          beginNode: '',
+          endCell: '',
+          endNode: '',
+          lineSort: ''
+        }
+      }
+    },
+    methods: {
+      // 鑾峰彇淇℃伅
+      async getInfo() {
+        let res = await this.$http.get(`/taskReliability/ModelLine/${this.dataForm.id}`)
+        this.dataForm = {
+          ...this.dataForm,
+          ...res.data
+        }
+      },
+      // 琛ㄥ崟鎻愪氦
+      async formSubmit() {
+        let res = await this.$http[!this.dataForm.id ? 'post' : 'put']('/taskReliability/ModelLine/', this.dataForm)
+        if (res.success) {
+          await this.$tip.success()
+          this.$refs.dialog.close()
+          this.$emit('refreshDataList')
+        }
+      }
+    }
+  }
+</script>
diff --git a/web/src/views/modules/taskReliability/ModelLine.vue b/web/src/views/modules/taskReliability/ModelLine.vue
new file mode 100644
index 0000000..d3f30da
--- /dev/null
+++ b/web/src/views/modules/taskReliability/ModelLine.vue
@@ -0,0 +1,45 @@
+<template>
+  <el-card shadow="never" class="aui-card--fill">
+    <div class="mod-taskReliability-modelLine}">
+      <zt-table-wraper query-url="/taskReliability/ModelLine/page" delete-url="/taskReliability/ModelLine" v-slot="{ table }">
+        <el-form :inline="true" :model="dataForm" @keyup.enter.native="table.query()">
+          <el-form-item>
+            <el-button type="primary" @click="drawRBD()">鐢诲彲闈犳�ф鍥�</el-button>
+<!--            <zt-button type="add"  @click="table.editHandle()"/>-->
+<!--            <zt-button type="delete"  @click="table.deleteHandle()"/>-->
+          </el-form-item>
+        </el-form>
+        <!-- 寮圭獥, 鏂板 / 淇敼 -->
+        <add-or-update @refreshDataList="table.query"/>
+        <el-dialog v-dialogDrag title="鍙潬鎬ф鍥�" top="10vh" width='85%' :visible.sync="dialogVisible2">
+          <RBDEditImg ref="RBDEditImg"></RBDEditImg>
+        </el-dialog>
+      </zt-table-wraper>
+    </div>
+  </el-card>
+</template>
+
+<script>
+  import AddOrUpdate from './ModelLine-AddOrUpdate'
+  import RBDEditImg from './RBD-edit-img'
+
+  export default {
+    data() {
+      return {
+        dataForm: {
+        },
+        dialogVisible2: false,
+      }
+    },
+    components: {
+      AddOrUpdate,
+      RBDEditImg
+    },
+    methods: {
+      drawRBD(modelId) {
+        this.dialogVisible2 = true
+        // this.$router.push({path: 'taskReliability-RBD-edit-img', query: {modelId: modelId}})
+      },
+    },
+  }
+</script>
diff --git a/web/src/views/modules/taskReliability/RBD-edit-img.vue b/web/src/views/modules/taskReliability/RBD-edit-img.vue
new file mode 100644
index 0000000..1991943
--- /dev/null
+++ b/web/src/views/modules/taskReliability/RBD-edit-img.vue
@@ -0,0 +1,1355 @@
+<template>
+  <div>
+    <el-row :gutter="[8,8]">
+      <el-col :span="5">
+        <div :style="'height:' +left_p+'px'">
+          <div class="fa-card-a" style="height: 100%">
+            <div id="stencilImg"></div>
+          </div>
+        </div>
+      </el-col>
+      <el-col :span="19">
+        <div class="fa-card-a">
+          <el-form :inline="true">
+            <el-form-item prop="projectId" style="margin-left:10px;width: 180px;">
+              <zt-select v-model="projectId" :datas="projectList" clearable placeholder="宸ョ▼椤圭洰"
+                         @change="projectChange"></zt-select>
+            </el-form-item>
+            <el-form-item>
+              <el-select v-model="diagramId" :disabled="diagramIdDisabled" placeholder="璇烽�夋嫨"
+                         @change="diagramIdChanges">
+                <el-option v-for="item in diagramList"
+                           :key="item.diagramId"
+                           :label="item.diagramName"
+                           :value="item.diagramId">
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="saveDiagram()">淇濆瓨</el-button>
+              <!--            <zt-button type="primary" v-show="pageCode === 'wlt_sp' && flowInfo.myStatus ===1"  @click="reject()">椹冲洖</zt-button>-->
+              <el-button v-show="pageCode === 'wlt_pz' && flowInfo.myStatus ===1" type="warning" @click="finish">瀹屾垚
+              </el-button>
+            </el-form-item>
+            <el-form-item>
+                <el-tooltip class="item" effect="dark" content="宸﹀榻�" placement="left">
+                  <el-button class="" style="margin-left: 0;padding: 2px;border: 1px solid #5F95FF;"
+                             @click="leftAlign()"><i style="font-size: 2rem;"
+                                                     class="wt-iconfont icon-zuoduiqi"></i></el-button>
+                </el-tooltip>
+            </el-form-item>
+            <el-form-item>
+                <el-tooltip class="item" effect="dark" content="灞呬腑瀵归綈" placement="left">
+                  <el-button style="margin-left: 0;padding: 2px;border: 1px solid #5F95FF"
+                             @click="centerAlign()"><i style="font-size: 2rem;"
+                                                       class="wt-iconfont icon-chuizhiduiqi"></i></el-button>
+                </el-tooltip>
+            </el-form-item>
+            <el-form-item>
+                <el-tooltip class="item" effect="dark" content="鍙冲榻�" placement="left">
+                  <el-button style="margin-left: 0;padding: 2px;border: 1px solid #5F95FF"
+                             @click="rightAlign()"><i style="font-size: 2rem;"
+                                                      class="wt-iconfont icon-youduiqi"></i></el-button>
+                </el-tooltip>
+            </el-form-item>
+            <el-form-item>
+                <el-tooltip class="item" effect="dark" content="椤堕儴瀵归綈" placement="left">
+                  <el-button style="margin-left: 0;padding: 2px;border: 1px solid #5F95FF"
+                             @click="topAlign()"><i style="font-size: 2rem;"
+                                                    class="wt-iconfont icon-dingduiqi"></i></el-button>
+                </el-tooltip>
+            </el-form-item>
+            <el-form-item>
+                <el-tooltip class="item" effect="dark" content="姘村钩瀵归綈" placement="left">
+                  <el-button style="margin-left: 0;padding: 2px;border: 1px solid #5F95FF"
+                             @click="shuipingAlign()"><i style="font-size: 2rem;"
+                                                         class="wt-iconfont icon-shuipingduiqi"></i></el-button>
+                </el-tooltip>
+            </el-form-item>
+            <el-form-item>
+                <el-tooltip class="item" effect="dark" content="搴曢儴瀵归綈" placement="left">
+                  <el-button style="margin-left: 0;padding: 2px;border: 1px solid #5F95FF"
+                             @click="bottomAlign()"><i style="font-size: 2rem;"
+                                                       class="wt-iconfont icon-diduiqi"></i></el-button>
+                </el-tooltip>
+            </el-form-item>
+          </el-form>
+          <div id="containerImg" style="border: 1px solid #EAEBEE;border-radius: 6px;
+        box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);">
+          </div>
+          <config-node v-show="type === 'node'" :id="id" :diagramId="diagramId" :globalGridAttr="globalGridAttr"
+                       :graph="graph"
+                       :projectId="projectId"
+                       :shape="shape"/>
+          <config-edge v-show="type === 'edge'" :id="id" :globalGridAttr="globalGridAttr" :graph="graph"/>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+  import {Graph, Shape, Addon, Cell} from '@antv/x6'
+  import ConfigNode from './ConfigNode/index.vue'
+  import ConfigEdge from './ConfigEdge/index.vue'
+  import {removeCurrentTabHandle} from '@/commonJS/common'
+  import {setHartBeat} from '@/commonJS/common';
+
+  export default {
+    name: 'RBD-edit-img',
+    /*props: {
+
+    },*/
+    props: {
+      projectId: {
+        type: String
+      },
+      diagarmId: {
+        type: String
+      },
+      pageCode: {
+        default: 'wlt_pz'
+      },
+      flowCode: {
+        type: String,
+        default: 'wltFlow'
+      },
+    },
+    components: {
+      ConfigNode,
+      ConfigEdge
+    },
+    data() {
+      return {
+        timer: null,
+        imgsList:[
+          {imgPath:'start',imgName:'start',nodeType:'start',imgWidth:60,imgHeight:60,imgId:'1',data:{}},
+          {imgPath:'end',imgName:'end',nodeType:'end',imgWidth:60,imgHeight:60,imgId:'2',data:{}},
+          {imgPath:'parallelLeft',imgName:'parallelLeft',nodeType:'parallelLeft',imgWidth:60,imgHeight:60,imgId:'3',data:{}},
+          {imgPath:'parallelRight',imgName:'parallelRight',nodeType:'parallelRight',imgWidth:60,imgHeight:60,imgId:'4',data:{}},
+          {imgPath:'switchRight',imgName:'switchRight',nodeType:'switchRight',imgWidth:60,imgHeight:60,imgId:'5',data:{}},
+          {imgPath:'voteRight',imgName:'voteRight',nodeType:'voteRight',imgWidth:60,imgHeight:60,imgId:'6',data:{}},
+        ],
+        imgsList2:[
+          {imgPath:'logo',imgName:'logo',nodeType:'node',imgWidth:60,imgHeight:60,imgId:'100',data:{dataId:'123456',nodeTypeExt:'aaa'}},
+        ],
+        first: true,
+        shape: '',
+        projectList: [],
+        diagramList: [],
+        diagramId: '',
+        projectId: '',
+        diagramJson: '',
+        diagramIdDisabled: false,
+        dataForm: {
+          id: null,
+          projectId: null,
+          diagramId: null,
+          content: null,
+          publishContent: null,
+          hasPublish: 0,
+          modelId: 1,
+        },
+        flowInfo: {
+          bizId: '',
+          bizGroupId: '',
+          flowCode: '',
+          flowStepMark: '',
+          status: 0,
+          myStatus: 0
+        },
+        // emptyJson: {
+        //   // 鑺傜偣
+        //   nodes: [
+        //     {
+        //       id: 'node1', // String锛屽彲閫夛紝鑺傜偣鐨勫敮涓�鏍囪瘑
+        //       width: 500,   // Number锛屽彲閫夛紝鑺傜偣澶у皬鐨� width 鍊�
+        //       height: 300,  // Number锛屽彲閫夛紝鑺傜偣澶у皬鐨� height 鍊�
+        //       label: '璇ラ」鐩繕鏈厤缃巶瀹剁綉缁滃浘',
+        //       attrs: {
+        //         body: {
+        //           strokeWidth: 0
+        //         },
+        //       }
+        //       //   text: {
+        //       //     text: '璇ラ」鐩繕鏈紪鍒剁綉缁滃浘',
+        //       //     // fontSize: 56,
+        //       //     fill: 'rgba(0,0,0,0.7)'
+        //       //   },
+        //       // },
+        //     }
+        //   ],
+        // },
+        type: '',
+        id: '',
+        graph: null,
+        globalGridAttr: {
+          type: 'mesh',
+          size: 10,
+          color: '#e5e5e5',
+          thickness: 1,
+          colorSecond: '#d0d0d0',
+          thicknessSecond: 1,
+          factor: 4,
+          bgColor: '#e5e5e5',
+          showImage: true,
+          repeat: 'watermark',
+          position: 'center',
+          bgSize: JSON.stringify({width: 150, height: 150}),
+          opacity: 0.1,
+
+          stroke: '#5F95FF',
+          strokeWidth: 1,
+          connector: 'normal',
+          label: '',
+          nodeStroke: '#5F95FF',
+          nodeStrokeWidth: 1,
+          nodeFill: '#ffffff',
+          nodeFontSize: 12,
+          nodeColor: '#080808',
+          nodeText: '',
+          nodeDate: '',
+          nodeUsers: '',
+          nodeDataDate: '',
+          nodeDataText: '',
+          dataId: '',
+          inspectName: '',
+          distance: 0.5,
+          angle: 0,
+        },
+        isReady: false,
+        curCel: Cell,
+        left_p: document.documentElement.clientHeight-220,
+        ports: {
+          groups: {
+            top: {
+              position: 'top',
+              attrs: {
+                circle: {
+                  r: 4,
+                  magnet: true,
+                  stroke: '#5F95FF',
+                  strokeWidth: 1,
+                  fill: '#fff',
+                  style: {
+                    visibility: 'hidden',
+                  },
+                },
+              },
+            },
+            right: {
+              position: 'right',
+              attrs: {
+                circle: {
+                  r: 4,
+                  magnet: true,
+                  stroke: '#5F95FF',
+                  strokeWidth: 1,
+                  fill: '#fff',
+                  style: {
+                    visibility: 'hidden',
+                  },
+                },
+              },
+            },
+            bottom: {
+              position: 'bottom',
+              attrs: {
+                circle: {
+                  r: 4,
+                  magnet: true,
+                  stroke: '#5F95FF',
+                  strokeWidth: 1,
+                  fill: '#fff',
+                  style: {
+                    visibility: 'hidden',
+                  },
+                },
+              },
+            },
+            left: {
+              position: 'left',
+              attrs: {
+                circle: {
+                  r: 4,
+                  magnet: true,
+                  stroke: '#5F95FF',
+                  strokeWidth: 1,
+                  fill: '#fff',
+                  style: {
+                    visibility: 'hidden',
+                  },
+                },
+              },
+            },
+          },
+          items: [
+            {
+              group: 'top',
+            },
+            {
+              group: 'right',
+            },
+            {
+              group: 'bottom',
+            },
+            {
+              group: 'left',
+            },
+          ],
+        }
+      }
+    },
+    watch: {
+      '$route.params.configId'() {
+        // alert('$route.params.projectId change')
+        this.projectId = this.$route.params.projectId
+        //this.diagramId = this.$route.params.diagramId
+        console.log(this.$route.params.projectId, 'this.$route.params.projectId')
+        console.log(this.$route.params.diagramId, 'this.$route.params.diagramId')
+        this.projectChange2(this.$route.params.diagramId)
+      }
+    },
+    mounted() {
+      this.getProject()
+      this.init()
+      this.type = 'grid'
+    },
+    methods: {
+      async finish() {
+        if (await this.$tip.confirm('纭畾瑕佽繘琛屾彁浜ゆ搷绾靛悧?')) {
+          let submitForm = {
+            params: {
+              wfIdCode: 'wltFlow',
+              bizId: this.dataForm.projectId,
+              stepIdMark: this.pageCode
+            }
+          }
+          let res = await this.$http.get('/wf/approvePass', submitForm)
+          if (res.success) {
+            await this.$alert('鎻愪氦鎴愬姛', '鍙嬫儏鎻愮ず')
+            removeCurrentTabHandle(this)
+            this.$EventBus.$emit('taskRefeshEvent', '缃戠粶鍥�')
+          }
+        }
+      },
+      async getProject() {
+        //let res = await this.$http.get(`/maintain/projectNetworkDiagram/getProjectList`)
+        let res = await this.$http.get(`/homeFunction/projectSelect`)
+
+        this.projectList = res.data
+        if (this.$store.state.user.isAdmin || this.$store.state.user.isAssistant) {
+          this.projectList.push({id: '10000', name: '鏍峰紡妯℃澘'})
+        }
+        if (this.$route.params.projectId) {
+          this.projectId = this.$route.params.projectId
+          this.diagramId = this.$route.params.diagramId
+        } else {
+          if (this.projectList.length > 0) {
+            this.projectId = this.projectList[0].id
+            this.diagramId = this.projectId
+            console.log(this.diagramId, '123456789')
+          }
+        }
+        await this.projectChange2(this.diagramId)
+      },
+
+      projectChange() {
+        // alert(555)
+        this.projectChange2(this.projectId)
+      },
+
+      async projectChange2(diagramId) {
+        // alert(1)
+        let params = {
+          wfIdCodes: 'wltFlow',
+          bizId: this.projectId,
+          stepIdMark: 'wlt_pz'
+        }
+        this.$http.get(`/wf/getFlowStepStatus`, {params: params}).then(res => {
+          console.log(res, 'getFlowStepStatus res')
+          if (res.data) {
+            this.flowInfo = res.data
+          }
+        })
+
+        this.diagramName = ''
+        this.dataForm.projectId = this.projectId
+        this.dataForm.diagramId = diagramId
+        this.diagramId = diagramId
+        if (!this.$store.state.user.isZcRole && !this.$store.state.user.isAdmin) {
+          this.diagramIdDisabled = true
+          console.log(this.$store.state.user.deptId, 'this.$store.state.user.deptId')
+          this.diagramId = this.$store.state.user.deptId
+          this.dataForm.diagramId = this.diagramId
+        } else {
+          this.diagramIdDisabled = false
+        }
+        //this.getDiagramIdList(this.projectId)
+        let res = await this.$http.get(`/maintain/projectNetworkDiagram/getDiagramCjList?projectId=${this.projectId}`)
+        this.diagramList = res.data
+        console.log(this.diagramList, 'this.diagramId asdfgh')
+        if (this.diagramList.length > 0) {
+          this.diagramId = this.diagramList[0].diagramId
+          console.log(this.dataForm.diagramId, 'this.dataForm.diagramId.........................')
+        }
+        await this.getDiagram()
+      },
+
+      diagramIdChanges() {
+        this.dataForm.diagramId = this.diagramId
+        // this.diagramIdChange(this.diagramId)
+        this.getDiagram()
+      },
+      async getDiagram() {
+        let includeCj = false
+        console.log(this.diagramList, 'this.diagramList')
+        console.log(this.diagramId, 'this.diagramId')
+        for (let val of this.diagramList) {
+          if (val.diagramId == this.diagramId) {
+            includeCj = true
+            break
+          }
+        }
+        console.log(includeCj, 'includeCj')
+        if (includeCj) {
+          // alert(3)
+          let params = {
+            projectId: this.dataForm.projectId,
+            diagramId: this.dataForm.diagramId,
+            isShow: 'edit'
+          }
+          console.log(params, 'params')
+          let res = await this.$http.get(`/maintain/projectNetworkDiagram/getDiagram`, {params: params})
+          if (res.data !== null && res.data.content != null) {
+            this.dataForm = res.data
+            this.diagramJson = JSON.parse(this.dataForm.content)
+            // console.log(this.dataForm.content,'this.Diagram content')
+            console.log(this.diagramJson, 'this.Diagram json')
+            this.graph.fromJSON(this.diagramJson)
+            this.graph.centerContent()
+            this.graph.zoomToFit()
+          } else {
+            this.dataForm.id = null
+            // this.graph.fromJSON(this.emptyJson)
+            this.graph.centerContent()
+            this.graph.zoomToFit()
+            // this.graph.freeze()
+          }
+        } else {
+          this.dataForm.id = null
+          console.log(this.data, 'this.data asdfg')
+          // this.graph.fromJSON(this.emptyJson)
+          this.graph.positionContent('left',{ padding: { left: 200 }})
+          // this.graph.centerContent()
+          // this.graph.zoomToFit()
+        }
+      },
+      init() {
+        this.timer = setHartBeat(10, 240);
+
+        console.log(document.documentElement.clientWidth, 'document.documentElement.clientWidth')
+        console.log(document.documentElement.clientHeight, 'document.documentElement.clientHeight')
+        this.graph = new Graph({
+          container: document.getElementById('containerImg'),
+          width: document.documentElement.clientWidth,
+          height: document.documentElement.clientHeight - 220,
+          // async: true,
+          grid: {
+            visible: true,
+          },
+          onToolItemCreated({tool}) {
+            const handle = tool
+            const options = handle.options
+            if (options && options.index % 2 === 1) {
+              tool.setAttrs({fill: 'red'})
+            }
+          },
+          autoResize: true,
+          history: true,
+          // panning: {
+          //   enabled: true,
+          // },
+          scroller: {
+            enabled: true,
+            pageVisible: true,
+            pageBreak: true,
+            pannable: true,
+          },
+          mousewheel: {
+            enabled: true,
+            zoomAtMousePosition: true,
+            modifiers: 'ctrl',
+            minScale: 0.1,
+            maxScale: 10,
+          },
+          connecting: {
+            router: {
+              name: 'normal',
+              // args: {
+              //   padding: 1,
+              // },
+            },
+            connector: {
+              name: 'rounded',
+              args: {
+                radius: 8,
+              },
+            },
+            // anchor: 'center',
+            connectionPoint: 'anchor',
+            allowBlank: false,
+            snap: {
+              radius: 20,
+            },
+            createEdge() {
+              return new Shape.Edge({
+                attrs: {
+                  line: {
+                    stroke: '#A2B1C3',
+                    strokeWidth: 2,
+                    targetMarker: 'classic'
+                  }
+                },
+                labels: [{
+                  attrs: {
+                    body: {
+                      stroke: '#5F95FF',
+                    },
+                    text: {
+                      text: ''
+                    }
+                  },
+                  position: {
+                    distance: 0.5,
+                    angle: 180,
+                    options: {
+                      keepGradient: true,
+                      ensureLegibility: true
+                    }
+                  }
+                }],
+                zIndex: 0,
+              })
+            },
+            validateConnection({targetMagnet}) {
+              return !!targetMagnet
+            },
+          },
+          highlighting: {
+            magnetAdsorbed: {
+              name: 'stroke',
+              args: {
+                attrs: {
+                  fill: '#5F95FF',
+                  stroke: '#5F95FF',
+                },
+              },
+            },
+          },
+          resizing: {
+            enabled: true,
+            restricted: true
+          },
+          rotating: true,
+          selecting: {
+            enabled: true,
+            rubberband: true,
+            rubberEdge: true,
+            showNodeSelectionBox: true,
+          },
+          snapline: true,
+          keyboard: true,
+          clipboard: true,
+        })
+        this.graph.centerContent()
+        const stencil = new Addon.Stencil({
+          title: '',
+          target: this.graph,
+          stencilGraphWidth: 230,
+          stencilGraphHeight: 300,
+          collapsable: false,
+          groups: [
+            {
+              title: '杩愮畻绗﹀彿',
+              name: 'group1',
+              collapsable: false
+            },
+            {
+              title: '璁惧鑺傜偣',
+              name: 'group2',
+              collapsable: false
+            }
+          ],
+          layoutOptions: {
+            columns: 2,
+            columnWidth: 110,
+            // rowHeight: 75,
+          },
+        })
+        document.getElementById('stencilImg').appendChild(stencil.container)
+
+        Graph.registerNode(
+            'custom-rect',
+            {
+              inherit: 'rect',
+              width: 86,
+              height: 26,
+              zIndex: 10,
+              data: {
+                dataId: '',
+                finishDate: '',
+                inspectName: ''
+              },
+              attrs: {
+                body: {
+                  strokeWidth: 1,
+                  stroke: 'none',
+                  fill: 'none',
+                },
+                text: {
+                  // fontFamily: '浠垮畫',
+                  fontSize: 20,
+                  fill: '#000',
+                },
+                label: {
+                  refX: 0,
+                  refY: 0.5,
+                  textAnchor: 'start',
+                  textVerticalAnchor: 'middle',
+                  textWrap: {
+                    text: '鏂囧瓧妯℃澘',
+                    width: -10,      // 瀹藉害鍑忓皯 10px
+                    ellipsis: false,  // 鏂囨湰瓒呭嚭鏄剧ず鑼冨洿鏃讹紝鑷姩娣诲姞鐪佺暐鍙�
+                    breakWord: true, // 鏄惁鎴柇鍗曡瘝
+                  }
+                },
+              },
+              ports: {...this.ports},
+            },
+            true,
+        )
+
+        Graph.registerNode(
+            'custom-polygon',
+            {
+              inherit: 'polygon',
+              width: 86,
+              height: 56,
+              attrs: {
+                body: {
+                  strokeWidth: 1,
+                  stroke: '#5F95FF',
+                  fill: '#EFF4FF',
+                },
+                // title:{
+                //   text:'',
+                //   refX: 40,
+                //   refY: 38,
+                //   fontSize: 20,
+                //   fill: '#262626',
+                //   'text-anchor': 'start',
+                // },
+                text: {
+                  // refX: 40,
+                  // refY: 20,
+                  fontSize: 20,
+                  fill: '#262626',
+                  // 'text-anchor': 'start',
+                },
+              },
+              // markup: [
+              //   {
+              //     tagName: 'polygon',
+              //     selector: 'body',
+              //   },
+              //   {
+              //     tagName: 'text',
+              //     selector: 'title',
+              //   },
+              //   {
+              //     tagName: 'text',
+              //     selector: 'text',
+              //   },
+              // ],
+              ports: {
+                ...this.ports
+                // items: [
+                //   {
+                //     group: 'top',
+                //   },
+                //   {
+                //     group: 'bottom',
+                //   },
+                // ],
+              },
+            },
+            true,
+        )
+        //
+        Graph.registerNode(
+            'custom-circle',
+            {
+              inherit: 'ellipse',
+              width: 120,
+              height: 120,
+              data: {
+                dataId: '',
+                finishDate: ''
+              },
+              attrs: {
+                body: {
+                  strokeWidth: 1,
+                  stroke: '#5F95FF',
+                  fill: '#EFF4FF',
+                },
+                //鏃ユ湡
+                title: {
+                  text: '',
+                  fontSize: 12,
+                  fill: '#262626',
+                  refX: 0.5,
+                  refY: '100%',
+                  refY2: -10,
+                  textAnchor: 'middle',
+                  textVerticalAnchor: 'bottom',
+                },
+                // 鍚嶇О
+                text: {
+                  // fontFamily: '浠垮畫',
+                  fontSize: 20,
+                  fill: '#262626',
+                  textWrap: {
+                    width: 80,      // 瀹藉害涓� 80px鎹㈣
+                    ellipsis: false,  // 鏂囨湰瓒呭嚭鏄剧ず鑼冨洿鏃讹紝鑷姩娣诲姞鐪佺暐鍙�
+                    breakWord: true, // 鏄惁鎴柇鍗曡瘝
+                  }
+                },
+              },
+              markup: [
+                {
+                  tagName: 'ellipse',
+                  selector: 'body',
+                },
+                {
+                  tagName: 'text',
+                  selector: 'title',
+                },
+                {
+                  tagName: 'text',
+                  selector: 'text',
+                },
+              ],
+              ports: {...this.ports},
+            },
+            true,
+        )
+        Graph.registerNode(
+            'custom-circle1',
+            {
+              inherit: 'ellipse',
+              width: 65,
+              height: 65,
+              data: {
+                dataId: '',
+                finishDate: ''
+              },
+              attrs: {
+                body: {
+                  strokeWidth: 1,
+                  stroke: '#5F95FF',
+                  fill: '#EFF4FF',
+                },
+                //鏃ユ湡
+                text: {
+                  // fontFamily: '浠垮畫',
+                  fontSize: 12,
+                  text: '鏃ユ湡鑺傜偣',
+                  fill: '#262626',
+                },
+              },
+              ports: {...this.ports},
+            },
+            true,
+        )
+        Graph.registerNode(
+            'custom-text',
+            {
+              inherit: 'text-block',
+              width: 86,
+              height: 56,
+              attrs: {
+                body: {
+                  strokeWidth: 1,
+                  stroke: '#5F95FF',
+                  fill: '#EFF4FF',
+                },
+                text: {
+                  text: '涓撲笟',
+                  fontSize: 20,
+                  style: {
+                    color: this.globalGridAttr.nodeColor
+                  },
+                  refX: '0',
+                  refY: -0.5,
+                  refY2: 1,
+                  textAnchor: 'middle',
+                  textVerticalAnchor: 'middle',
+                },
+              },
+              markup: [
+                {
+                  tagName: 'rect',
+                  selector: 'body',
+                },
+                {
+                  tagName: 'text',
+                  selector: 'text',
+                },
+              ],
+              ports: {...this.ports},
+            },
+            true,
+        )
+        Graph.registerNode(
+            'rectangle',
+            {
+              width: 86,
+              height: 56,
+              attrs: {
+                body: {
+                  fill: '#FFF',
+                  stroke: '#000',
+                  strokeWidth: 1,
+                },
+                icon: {
+                  class: 'el-icon-refresh', // Element UI鍥炬爣鐨刢lass鍚嶇О
+                  'xlink:href': '', // 濡傛灉闇�瑕佷娇鐢⊿VG鍥炬爣锛岃璁剧疆xlink:href灞炴�ф潵寮曞叆SVG鏂囦欢
+                  refX: '50%',
+                  refY: '50%',
+                  yAlignment: 'middle',
+                  xAlignment: 'middle',
+                },
+              },
+              markup: [
+                {
+                  tagName: 'rect',
+                  selector: 'body',
+                },
+                {
+                  tagName: 'i',
+                  selector: 'icon',
+                },
+              ],
+              ports: {...this.ports},
+            },
+            true
+        )
+        // 涓�绾х綉缁滃浘鐨勬棩鏈熸枃瀛楄妭鐐�
+        const r5 = this.graph.createNode({
+          shape: 'custom-circle',
+          data: {
+            dataId: '',
+            finishDate: '',
+            inspectName: ''
+          },
+          label: '闃舵',
+        })
+
+        // 浜岀骇缃戠粶鍥炬棩鏈熻妭鐐�
+        const r6 = this.graph.createNode({
+          shape: 'custom-circle1',
+          data: {
+            dataId: '',
+            finishDate: '',
+            inspectName: ''
+          },
+        })
+        // 浜岀骇缃戠粶鍥炬枃瀛楄妭鐐�
+        const r9 = this.graph.createNode({
+          shape: 'custom-rect'
+        })
+        const imageNodes = this.imgsList.map((item) =>
+            this.graph.createNode({
+              shape: 'image',
+              imageUrl: require('/public/modelImg/'+item.imgPath+'.png'),
+              width: item.imgWidth,
+              height: item.imgHeight,
+              x: item.imgWidth,
+              y: item.imgHeight,
+              data: {
+                dataId: '',
+                nodeType: item.nodeType,
+                nodeTypeExt: ''
+              },
+              attrs: {
+                text:{
+                  text: item.imgName,
+                  fontSize: 14,
+                  style: {
+                    color: this.globalGridAttr.nodeColor
+                  },
+                  refX: 0.5,
+                  refY: '100%',
+                  refY2: 4,
+                  textAnchor: 'middle',
+                  textVerticalAnchor: 'top',
+                },
+              },
+              ports: {...this.ports},
+            }),
+        )
+        const imageNodes2 = this.imgsList2.map((item) =>
+            this.graph.createNode({
+              shape: 'image',
+              imageUrl: require('/public/modelImg/'+item.imgPath+'.png'),
+              width:item.imgWidth,
+              height:item.imgHeight,
+              x:item.imgWidth,
+              y:item.imgHeight,
+              data: {
+                dataId: item.data.dataId,
+                nodeType: item.nodeType,
+                nodeTypeExt: item.data.nodeTypeExt
+              },
+              attrs: {
+                text:{
+                  text: item.imgName,
+                  fontSize: 14,
+                  style: {
+                    color: this.globalGridAttr.nodeColor
+                  },
+                  refX: 0.5,
+                  refY: '100%',
+                  refY2: 4,
+                  textAnchor: 'middle',
+                  textVerticalAnchor: 'top',
+                },
+              },
+              ports: {...this.ports},
+            }),
+        )
+        // r1.push(r5,r6,r9)
+        console.log(imageNodes,'group1')
+        stencil.load(imageNodes, 'group1')
+        stencil.load(imageNodes2, 'group2')
+
+        this.graph.bindKey(['meta+c', 'ctrl+c'], () => {
+          const cells = this.graph.getSelectedCells()
+          if (cells.length) {
+            this.graph.copy(cells)
+          }
+          return false
+        })
+
+        this.graph.bindKey(['meta+x', 'ctrl+x'], () => {
+          const cells = this.graph.getSelectedCells()
+          if (cells.length) {
+            this.graph.cut(cells)
+          }
+          return false
+        })
+        this.graph.bindKey(['meta+v', 'ctrl+v'], () => {
+          if (!this.graph.isClipboardEmpty()) {
+            const cells = this.graph.paste({offset: 32})
+            this.graph.cleanSelection()
+            this.graph.select(cells)
+          }
+          return false
+        })
+//undo redo
+        this.graph.bindKey(['meta+z', 'ctrl+z'], () => {
+          if (this.graph.history.canUndo()) {
+            this.graph.history.undo()
+          }
+          return false
+        })
+
+        this.graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
+          if (this.graph.history.canRedo()) {
+            this.graph.history.redo()
+          }
+          return false
+        })
+
+// select all
+        this.graph.bindKey(['meta+a', 'ctrl+a'], () => {
+          const nodes = this.graph.getNodes()
+          if (nodes) {
+            this.graph.select(nodes)
+          }
+        })
+//delete
+        this.graph.bindKey('delete', () => {
+          const cells = this.graph.getSelectedCells()
+          if (cells.length) {
+            this.$confirm('鏄惁鍒犻櫎璇ヨ妭鐐�?', '鎻愮ず', {
+              confirmButtonText: '纭畾',
+              cancelButtonText: '鍙栨秷',
+              type: 'warning'
+            }).then(() => {
+              this.$message({
+                type: 'success',
+                message: '鍒犻櫎鎴愬姛!'
+              })
+              this.graph.removeCells(cells)
+            }).catch(() => {
+              this.$message({
+                type: 'info',
+                message: '宸插彇娑堝垹闄�'
+              })
+            })
+          }
+        })
+// zoom
+        this.graph.bindKey(['ctrl+1', 'meta+1'], () => {
+          const zoom = this.graph.zoom()
+          if (zoom < 1.5) {
+            this.graph.zoom(0.1)
+          }
+        })
+
+        this.graph.bindKey(['ctrl+2', 'meta+2'], () => {
+          const zoom = this.graph.zoom()
+          if (zoom > 0.5) {
+            this.graph.zoom(-0.1)
+          }
+        })
+
+        this.graph.on('blank:click', ({cell}) => {
+          this.reset()
+          // this.type.value = "grid"
+          this.type = 'grid'
+          // this.id = cell.id
+        })
+
+        this.graph.on('cell:click', ({cell}) => {
+          // this.type.value = cell.isNode() ? "node" : "edge"
+          this.type = cell.isNode() ? 'node' : 'edge'
+          this.shape = cell.shape
+          this.id = cell.id
+          console.log(this.shape, 'this.shape')
+          // this.nodeOpt(this.id, this.globalGridAttr)
+        })
+        //鍗曞嚮杈硅妭鐐�
+        this.graph.on('edge:click', ({edge}) => {
+          this.reset()
+          edge.attr('line/stroke', 'orange')
+          edge.prop('labels/0', {
+            attrs: {
+              body: {
+                stroke: 'orange',
+              },
+            },
+
+          })
+        })
+        // 鍗曞嚮node鑺傜偣
+        this.graph.on('node:click', ({node}) => {
+          this.reset()
+          node.attr('line/stroke', 'orange')
+          node.prop('labels/0', {
+            attrs: {
+              body: {
+                stroke: 'orange',
+              },
+            },
+          })
+        })
+        // 鎺у埗杩炴帴妗╂樉绀�/闅愯棌
+        this.graph.on('node:delete', ({view, e}) => {
+          e.stopPropagation()
+          view.cell.remove()
+        })
+
+        this.graph.on('node:customevent', ({name, view, e}) => {
+          if (name === 'node:delete') {
+            e.stopPropagation()
+            view.cell.remove()
+          }
+        })
+        // 鍙屽嚮缂栬緫
+        this.graph.on('cell:dblclick', ({cell, e}) => {
+          const isNode = cell.isNode()
+          const name = cell.isNode() ? 'node-editor' : 'edge-editor'
+          cell.removeTool(name)
+          cell.addTools({
+            name,
+            args: {
+              event: e,
+              attrs: {
+                backgroundColor: isNode ? '#EFF4FF' : '#FFF',
+                text: {
+                  fontSize: 16,
+                  fill: '#262626',
+                },
+              },
+            },
+          })
+        })
+
+        this.graph.on('node:mouseenter', ({node}) => {
+          const container = document.getElementById('containerImg')
+          const ports = container.querySelectorAll(
+            '.x6-port-body',
+          )
+          this.showPorts(ports, true)
+        })
+
+        this.graph.on('node:mouseleave', ({node}) => {
+          // if (node.hasTool('button-remove')) {
+          //   node.removeTool('button-remove')
+          // }
+          const container = document.getElementById('containerImg')
+          const ports = container.querySelectorAll(
+            '.x6-port-body',
+          )
+          this.showPorts(ports, false)
+        })
+
+        this.graph.on('edge:mouseenter', ({cell, view}) => {
+          // alert(123)
+          cell.addTools([
+            {
+              name: 'source-arrowhead',
+            },
+            {
+              name: 'target-arrowhead',
+              args: {
+                attrs: {
+                  fill: 'red',
+                },
+              },
+            },
+          ])
+          cell.addTools(
+            [
+              {
+                name: 'segments',
+                args: {snapRadius: 20, attrs: {fill: '#444'}}
+              }
+            ]
+          )
+        })
+
+        this.graph.on('edge:mouseleave', ({cell}) => {
+          cell.removeTools()
+        })
+      },
+      showPorts(ports, show) {
+        for (let i = 0, len = ports.length; i < len; i = i + 1) {
+          ports[i].style.visibility = show ? 'visible' : 'hidden'
+        }
+      },
+      reset() {
+        this.graph.drawBackground({color: '#fff'})
+        const nodes = this.graph.getNodes()
+        const edges = this.graph.getEdges()
+        nodes.forEach((node) => {
+          node.attr('body/stroke', '#5F95FF')
+        })
+        edges.forEach((edge) => {
+          edge.attr('line/stroke', '#5F95FF')
+          edge.prop('labels/0', {
+            attrs: {
+              body: {
+                stroke: '#5F95FF',
+              },
+            },
+          })
+        })
+      },
+      // nodeOpt(id, globalGridAttr) {
+      //   this.curCel = null
+      //   if (id) {
+      //     let cell = this.graph.getCellById(id)
+      //     console.log(cell, 'let cell 123456')
+      //     if (!cell || !cell.isNode()) {
+      //       return
+      //     }
+      //     this.curCel = cell
+      //     globalGridAttr.nodeStroke = cell.attr('body/stroke')
+      //     globalGridAttr.nodeStrokeWidth = cell.attr('body/strokeWidth')
+      //     globalGridAttr.nodeFill = cell.attr('body/fill')
+      //     globalGridAttr.nodeFontSize = cell.attr('text/fontSize')
+      //     globalGridAttr.nodeFontSize = cell.attr('title/fontSize')
+      //     globalGridAttr.nodeColor = cell.attr('text/fill')
+      //     globalGridAttr.nodeColor = cell.attr('title/fill')
+      //     globalGridAttr.nodeColor = cell.attr('text/style/color')
+      //     globalGridAttr.nodeColor =  cell.attr('title/style/color')
+      //     globalGridAttr.nodeUsers = cell.attr('approve/users')
+      //     globalGridAttr.nodeText = cell.attr('text/text')
+      //     globalGridAttr.nodeDate = cell.attr('title/text')
+      //     // let data={
+      //     //   dataId:this.projectId,
+      //     //   finishDate: globalGridAttr.nodeDate,
+      //     // }
+      //     cell.getData()
+      //     console.log( cell.getData(),' cell.getData() 909')
+      //   }
+      //   return this.curCel;
+      // },
+      async saveDiagram() {
+        console.log(JSON.stringify(this.graph.toJSON()), 'graph.toJSON()')
+        this.dataForm.content = JSON.stringify(this.graph.toJSON())
+        console.log(this.dataForm, 'dataFrom')
+        await this.$http[this.dataForm.id === null ? 'post' : 'put'](`/taskReliability/ModelLine/`, this.dataForm).then(async res => {
+          if (res.msg === 'success') {
+            this.$alert('淇濆瓨鎴愬姛', '鎻愮ず', {
+              confirmButtonText: '纭畾'
+            })
+          }
+        })
+      },
+      // AlignmentsChanges(val){
+      //   console.log(val,'align.value')
+      //     if(val ==='閫夐」1'){
+      //       console.log(val,'align.value')
+      //        this.leftAlign()
+      //     }
+      //     if(val ==='閫夐」2') {
+      //       console.log('鍙冲榻�','align.value')
+      //        this.rightAlign()
+      //     }
+      // },
+      leftAlign() {
+        const NODE = this.graph.getSelectedCells()
+        let leftX = null
+        for (let a of NODE) {
+          if (leftX == null || a.getBBox().x < leftX) {
+            leftX = a.getBBox().x
+          }
+        }
+        for (let a of NODE) {
+          let y = a.getBBox().y
+          a.position(leftX, y)
+          // console.log(leftX, ':', y, '  x:y')
+        }
+      },
+      topAlign() {
+        const NODE = this.graph.getSelectedCells()
+        let topY = null
+        for (let a of NODE) {
+          console.log(a.getBBox(), 'a.getBBox()')
+          if (topY == null || a.getBBox().y < topY) {
+            topY = a.getBBox().y
+          }
+        }
+        for (let a of NODE) {
+          let x = a.getBBox().x
+          a.position(x, topY)
+          // console.log(leftX, ':', y, '  x:y')
+        }
+      },
+      centerAlign() {
+        const NODE = this.graph.getSelectedCells()
+        let rightX = null
+        let leftX = null
+        for (let a of NODE) {
+          if (leftX == null || a.getBBox().x < leftX) {
+            leftX = a.getBBox().x
+          }
+        }
+        for (let a of NODE) {
+          if (rightX == null || a.getBBox().x + a.getBBox().width > rightX) {
+            rightX = a.getBBox().x + a.getBBox().width
+          }
+        }
+
+        let centerX = leftX + (rightX - leftX) / 2
+
+        for (let a of NODE) {
+          let y = a.getBBox().y
+          a.position(centerX - a.getBBox().width / 2, y)
+          // console.log(leftX, ':', y, '  x:y')
+        }
+      },
+      shuipingAlign() {
+        const NODE = this.graph.getSelectedCells()
+        let bottomY = null
+        let topY = null
+        for (let a of NODE) {
+          if (topY == null || a.getBBox().y || 0 < topY) {
+            topY = a.getBBox().y
+          }
+        }
+        for (let a of NODE) {
+          if (bottomY == null || a.getBBox().y + a.getBBox().height > bottomY) {
+            bottomY = a.getBBox().y + a.getBBox().height
+          }
+        }
+
+        let centerY = topY + (bottomY - topY) / 2
+        for (let a of NODE) {
+          let x = a.getBBox().x
+          let centerHei = a.getBBox().height / 2
+          a.position(x, centerY - centerHei)
+        }
+      },
+      rightAlign() {
+        const NODE = this.graph.getSelectedCells()
+        let rightX = null
+        for (let a of NODE) {
+          if (rightX == null || a.getBBox().x + a.getBBox().width > rightX) {
+            rightX = a.getBBox().x + a.getBBox().width
+          }
+        }
+        for (let a of NODE) {
+          let y = a.getBBox().y
+          a.position(rightX - a.getBBox().width, y)
+        }
+      },
+      bottomAlign() {
+        const NODE = this.graph.getSelectedCells()
+        let bottomY = null
+        for (let a of NODE) {
+          if (bottomY == null || (a.getBBox().y + a.getBBox().height) > bottomY) {
+            bottomY = a.getBBox().y + a.getBBox().height
+          }
+        }
+
+        for (let a of NODE) {
+          let x = a.getBBox().x
+          a.position(x, bottomY - a.getBBox().height)
+        }
+      },
+      close() {
+        if (this.timer){
+          window.clearInterval(this.timer)
+        }
+      },
+    },
+
+  }
+</script>
+
+<style>
+#containerImg {
+  display: flex;
+  border: 1px solid #dfe3e8;
+  height:400px ;
+  width: 100% !important;
+}
+
+.x6-graph-scroller.x6-graph-scroller-pannable {
+  width: 100% !important;
+}
+
+#stencilImg {
+  width: 100%;
+  height: 100%;
+  position: relative;
+  border-right: 1px solid #dfe3e8;
+}
+
+.x6-widget-stencil {
+  position: relative;
+  height: 100%;
+}
+
+.x6-widget-stencil-content {
+  position: relative;
+  height: 100%;
+}
+
+</style>

--
Gitblit v1.9.1