xyc
2024-03-01 9476a12cf725a13aa927278df6e3fc18fe9e80d1
新增RBD
1个文件已修改
25个文件已添加
1个文件已删除
2781 ■■■■■ 已修改文件
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/controller/ModelLineController.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelLineDao.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelNodeDao.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelRbdDao.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelLine.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelNode.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelRbd.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/service/ModelLineService.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/resources/mapper/taskReliability/ModelLineDao.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/resources/mapper/taskReliability/ModelNodeDao.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/resources/mapper/taskReliability/ModelRbdDao.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
starter/src/main/java/com/zt/security/controller/CasSsoController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
starter/src/main/resources/META-INF/MANIFEST.MF 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/end.png 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/parallelLeft.png 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/parallelRight.png 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/start.png 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/switchRight.png 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/voteRight.png 补丁 | 查看 | 原始文档 | blame | 历史
web/public/modelImg/xianhao.png 补丁 | 查看 | 原始文档 | blame | 历史
web/src/views/modules/taskReliability/ConfigEdge/index.vue 204 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web/src/views/modules/taskReliability/ConfigNode/index.vue 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web/src/views/modules/taskReliability/ConfigNode/project-list-select.vue 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web/src/views/modules/taskReliability/ModelLine-AddOrUpdate.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web/src/views/modules/taskReliability/ModelLine.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
web/src/views/modules/taskReliability/RBD-edit-img.vue 1355 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/controller/ModelLineController.java
New file
@@ -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();
    }
}
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelLineDao.java
New file
@@ -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);
}
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelNodeDao.java
New file
@@ -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);
}
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/dao/ModelRbdDao.java
New file
@@ -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);
}
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelLine.java
New file
@@ -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;
}
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelNode.java
New file
@@ -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;
}
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/model/ModelRbd.java
New file
@@ -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;
}
modules/mainPart/src/main/java/com/zt/life/modules/taskReliability/service/ModelLineService.java
New file
@@ -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());
            }
        }
    }
}
modules/mainPart/src/main/resources/mapper/taskReliability/ModelLineDao.xml
New file
@@ -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>
modules/mainPart/src/main/resources/mapper/taskReliability/ModelNodeDao.xml
New file
@@ -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>
modules/mainPart/src/main/resources/mapper/taskReliability/ModelRbdDao.xml
New file
@@ -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>
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;
starter/src/main/resources/META-INF/MANIFEST.MF
File was deleted
web/public/modelImg/end.png
web/public/modelImg/logo.png
web/public/modelImg/parallelLeft.png
web/public/modelImg/parallelRight.png
web/public/modelImg/start.png
web/public/modelImg/switchRight.png
web/public/modelImg/voteRight.png
web/public/modelImg/xianhao.png
web/src/views/modules/taskReliability/ConfigEdge/index.vue
New file
@@ -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>
web/src/views/modules/taskReliability/ConfigNode/index.vue
New file
@@ -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>
web/src/views/modules/taskReliability/ConfigNode/project-list-select.vue
New file
@@ -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>
web/src/views/modules/taskReliability/ModelLine-AddOrUpdate.vue
New file
@@ -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>
web/src/views/modules/taskReliability/ModelLine.vue
New file
@@ -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>
web/src/views/modules/taskReliability/RBD-edit-img.vue
New file
@@ -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图标的class名称
                  'xlink:href': '', // 如果需要使用SVG图标,请设置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>