Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/develop' into develop

linhuili 2 gadi atpakaļ
vecāks
revīzija
5eb409a47f
46 mainītis faili ar 2105 papildinājumiem un 1319 dzēšanām
  1. 8 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/controller/DemoDiagramController.java
  2. 11 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/controller/DiagramController.java
  3. 1 1
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/ContentParser.java
  4. 8 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DataStrategy.java
  5. 0 466
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramBuilder.java
  6. 73 6
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/CalcContext.java
  7. 108 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/build/CalcGroup.java
  8. 722 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/build/DiagramBuilder.java
  9. 13 13
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramDataLoader.java
  10. 98 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/build/LegendLoader.java
  11. 17 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/impl/DataStrategyImpl.java
  12. 1 1
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/line/LineLayoutManager.java
  13. 7 5
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/line/PathBuilder.java
  14. 1 2
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/ConnectPoint.java
  15. 1 1
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/Diagram.java
  16. 3 3
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/AbstractComponent.java
  17. 57 17
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/Container.java
  18. 2 2
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/IComponent.java
  19. 10 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/IEquipHolder.java
  20. 2 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/AndFilter.java
  21. 1 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/DataFilter.java
  22. 14 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/DynGroup.java
  23. 2 1
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/MatchFilter.java
  24. 2 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/OrFilter.java
  25. 8 19
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/RelationFilter.java
  26. 29 1
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/style/BaseStyle.java
  27. 3 13
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/DiagramTemplate.java
  28. 26 55
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/MainPipe.java
  29. 8 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/dao/DiagramMapper.java
  30. 5 0
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/demo/DemoDataStrategy.java
  31. 10 5
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/DemoDiagramManager.java
  32. 2 2
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/DiagramManager.java
  33. 5 2
      adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/TemplateManager.java
  34. 7 0
      adm-business/adm-diagram/src/main/resources/mapper/Diagram.xml
  35. 9 9
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/migration/service/Impl/ObjectRelationMigration.java
  36. 7 6
      adm-business/adm-server/src/main/java/com/persagy/adm/server/backstage/jobhandler/CommonTimeRuleJob.java
  37. 1 1
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/controller/AppController.java
  38. 1 1
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/entity/BuildingData.java
  39. 7 0
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/entity/DownLoadData.java
  40. 2 1
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/ISyncApp.java
  41. 692 685
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/SyncAppImpl.java
  42. 2 1
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/check_update/CheckUpdateChain.java
  43. 36 0
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillBuildingDataChain.java
  44. 34 0
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillCad.java
  45. 9 0
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillData.java
  46. 40 0
      adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillProblem.java

+ 8 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/controller/DemoDiagramController.java

@@ -42,6 +42,14 @@ public class DemoDiagramController {
     }
 
     /**
+     * 读取系统图内容
+     */
+    @GetMapping("getDiagram")
+    public CommonResult<Diagram> getDiagram(@RequestParam String id) {
+        return ResultHelper.single(diagramManager.getDiagram(id));
+    }
+
+    /**
      * 新建系统图
      *
      * @param params    新建参数,对象类型,包含字段 name:名称, type:系统图类型编码

+ 11 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/controller/DiagramController.java

@@ -303,4 +303,15 @@ public class DiagramController {
     public CommonResult<Map<String, Boolean>> querySystemInstanceDiagramList() {
         return ResultHelper.single(dataStrategy.querySystemInstanceDiagramList());
     }
+
+    /**
+     * 判断系统图名称是否重复  true:重复,false:不重复
+     *
+     * @return 是否成功
+     */
+    @ApiOperation("判断系统图名称是否重复")
+    @PostMapping("/judge/name/duplicate")
+    public CommonResult<Boolean> judgeNameDuplicate(@RequestBody Map<String, String> params) {
+        return ResultHelper.single(dataStrategy.judgeNameDuplicate(params.get("name")));
+    }
 }

+ 1 - 1
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/ContentParser.java

@@ -8,7 +8,7 @@ import org.springframework.stereotype.Service;
  * json对象解析工具
  * @author zhaoyk
  */
-@Service
+@Service("diagramContentParser")
 public class ContentParser {
 
 	/**

+ 8 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DataStrategy.java

@@ -248,4 +248,12 @@ public interface DataStrategy {
      * @return 是否成功
      */
     boolean updateName(String name, String id);
+
+    /**
+     * 判断系统图名称是否重复
+     *
+     * @param name 系统图名称
+     * @return 是否重复
+     */
+    boolean judgeNameDuplicate(String name);
 }

+ 0 - 466
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramBuilder.java

@@ -1,466 +0,0 @@
-package com.persagy.adm.diagram.core;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.IdUtil;
-import cn.hutool.core.util.StrUtil;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.persagy.adm.diagram.core.model.*;
-import com.persagy.adm.diagram.core.model.base.Container;
-import com.persagy.adm.diagram.core.model.base.IComponent;
-import com.persagy.adm.diagram.core.model.base.IDataBind;
-import com.persagy.adm.diagram.core.model.base.IEquipHolder;
-import com.persagy.adm.diagram.core.model.legend.Anchor;
-import com.persagy.adm.diagram.core.model.legend.Legend;
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
-import com.persagy.adm.diagram.core.model.logic.DataFilter;
-import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
-import com.persagy.adm.diagram.core.model.template.MainPipe;
-import com.persagy.adm.diagram.core.model.virtual.PackNode;
-import com.persagy.dmp.digital.entity.ObjectRelation;
-
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * 处理系统图的计算逻辑
- * @author zhaoyk
- */
-public class DiagramBuilder {
-
-	/**
-	 * 设备容器限制,避免模板设置不当导致过多节点
-	 */
-	public static int equipLimit = 50;
-
-	private CalcContext context;
-
-	private Diagram diagram;
-
-	private DiagramTemplate template;
-
-	private DataStrategy dataStrategy;
-
-	private HashMap<String, List<Legend>> legendsCache = new HashMap<>();
-
-	private HashSet<String> refRelTypes = new HashSet<>();
-
-	public DiagramBuilder(CalcContext context, DataStrategy dataStrategy) {
-		this.context = context;
-		this.diagram = context.getDiagram();
-		this.template = context.getTemplate();
-		this.dataStrategy = dataStrategy;
-
-		this.context.setDataStrategy(dataStrategy);
-	}
-
-	private boolean hasDynGroup(List<Container> containers) {
-		for(Container con : containers) {
-			if(con.getDynGroup() != null){
-				return true;
-			}
-		}
-		return false;
-	}
-
-	//加载设备数据,并进行计算处理
-	public void buildEquipNodeAndContainer(List<Container> containers, List<ObjectNode> optionalObjs){
-		//去掉已经使用的数据项
-		if(context.getEquipMap().size() > 0) {
-			optionalObjs = optionalObjs.stream().filter(obj -> !context.getEquipMap().containsKey(obj.get("id").asText())).collect(Collectors.toList());
-		} else {
-			optionalObjs = new ArrayList<>(optionalObjs);
-		}
-
-		if(hasDynGroup(containers)) {
-			//TODO 动态组计算
-		}
-
-		if(template.getMainPipes() != null) {
-			for(MainPipe mainPipe : template.getMainPipes()) {
-				if (mainPipe.isBindEquipment() && mainPipe.getDataObject() == null){
-					Iterator<ObjectNode> iter = optionalObjs.iterator();
-					while (iter.hasNext()) {
-						ObjectNode obj = iter.next();
-						if(match(obj, mainPipe)) {
-							mainPipe.setDataObject(obj);
-							mainPipe.setDataObjectId(obj.get("id").asText());
-
-							context.getEquipMap().put(mainPipe.getDataObjectId(), mainPipe);
-
-							iter.remove();
-							break;
-						}
-					}
-				}
-			}
-		}
-		for(Container con : containers) {
-			if(con.isEquipmentBox()) {
-				Iterator<ObjectNode> iter = optionalObjs.iterator();
-				while (iter.hasNext()) {
-					ObjectNode obj = iter.next();
-					if (match(obj, con)) {
-						if(con.getEquipPack() != null) {
-							addPackData(con, obj);
-						} else {
-							addEquipNode(con, obj);
-						}
-
-						iter.remove();
-					}
-				}
-			}
-		}
-
-		handleNodes();
-
-		handleContainers(containers);
-	}
-
-	private void buildMainPipe(){
-
-	}
-
-	private void addEquipNode(Container con, ObjectNode obj){
-		if(con.getChildren().size() > equipLimit) {
-			return;
-		}
-
-		EquipmentNode node = new EquipmentNode();
-		node.setId(IdUtil.fastSimpleUUID());
-		node.setDataObjectId(obj.get("id").asText());
-		node.setObjClassCode(DiagramBuilder.getClassCode(obj));
-		node.setDataObject(obj);
-
-		initNode(node, DiagramBuilder.getName(obj), con);
-
-		Legend legend = findLegend(node.getObjClassCode(), obj);
-		node.setLegendId(legend.getId());
-		node.setLegend(legend);
-	}
-
-	private void initNode(EquipmentNode node, String name, Container con){
-		con.addComp(node);
-		node.setContainerId(con.getId());
-		node.setLayoutIndex(con.getChildren().size() - 1);
-
-		Label label = new Label();
-		label.setId(IdUtil.fastSimpleUUID());
-		label.setContent(name);
-		node.setLabel(label);
-
-		diagram.getNodes().add(node);
-		context.getEquipMap().put(node.getDataObjectId(), node);
-	}
-
-	private void addPackData(Container con, ObjectNode obj){
-		PackNode pn = null;
-		String classCode = getClassCode(obj);
-		Legend legend = null;
-		//single
-		if(!con.getEquipPack().isPackByType()) {
-			String packName = con.getEquipPack().getPackName();
-			if(StrUtil.isBlank(packName)) {
-				packName = getTypeName(classCode);
-			}
-			if(con.getChildren().size() == 0) {
-				pn = newPackNode(PackNode.SINGLE_PACK, con, packName);
-			} else {
-				pn = (PackNode) con.getChildren().get(0);
-			}
-		} else { //group
-			for(IComponent comp : con.getChildren()) {
-				PackNode item = (PackNode) comp;
-				if(item.getObjClassCode().equals(classCode)){
-					pn = item;
-					break;
-				}
-			}
-			if(pn == null) {
-				pn = newPackNode(classCode, con, getTypeName(classCode));
-			}
-		}
-
-		if (pn.getLegend() == null) {
-			if(con.getEquipPack().getLegendId() != null) {
-				legend = dataStrategy.getLegend(con.getEquipPack().getLegendId(), classCode.substring(0, 4));
-			}
-			if(legend == null) {
-				legend = findLegend(classCode, null);
-			}
-
-			pn.setLegendId(legend.getId());
-			pn.setLegend(legend);
-		}
-
-		pn.add(classCode);
-	}
-
-	private PackNode newPackNode(String objClsCode, Container con, String packName){
-		PackNode pn = new PackNode();
-		pn.setId(IdUtil.fastSimpleUUID());
-		pn.setObjClassCode(objClsCode);
-
-		initNode(pn, packName, con);
-
-		return pn;
-	}
-
-	private boolean match(ObjectNode obj, IEquipHolder equipHolder) {
-		String classCode = DiagramBuilder.getClassCode(obj);
-		if(equipHolder.getEquipmentTypes() != null && equipHolder.getEquipmentTypes().contains(classCode)) {
-			DataFilter filter = equipHolder.getDataFilter();
-			if(filter != null) {
-				return filter.filter(obj, context);
-			}
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * 对节点进行处理,并返回图例锚点会使用到的关系类型
-	 */
-	private void handleNodes() {
-		for(DiagramNode node : diagram.getNodes()) {
-			if(PackNode.TYPE.equals(node.getCompType())) {
-				PackNode pn = (PackNode)node;
-				pn.getLabel().setContent(pn.getLabel().getContent() + ":" + pn.totalCount());
-				statRelTypes(pn);
-			} else if(EquipmentNode.TYPE.equals(node.getCompType())) {
-				statRelTypes((EquipmentNode)node);
-			}
-		}
-	}
-
-	private void statRelTypes(EquipmentNode equipmentNode){
-		List<Anchor> anchors = equipmentNode.getLegend().getAnchors();
-		if(anchors != null) {
-			for(Anchor anchor : anchors) {
-				if(anchor.getAcceptRelations() != null) {
-					anchor.getAcceptRelations().forEach(rel -> refRelTypes.add(rel));
-				}
-			}
-		}
-	}
-
-	private void handleContainers(List<Container> containers) {
-		for(Container con : containers) {
-			if(con.isEquipmentBox()) {
-				if(Boolean.TRUE.equals(con.getProp(Container.PROP_AUTO_HIDDEN)) && CollUtil.isEmpty(con.getChildren())) {
-					con.setHidden(true);
-				}
-			}
-		}
-	}
-
-	private String getTypeName(String classCode){
-		//TODO
-		return classCode;
-	}
-
-	private Legend findLegend(String classCode, ObjectNode obj){
-		List<Legend> legends = legendsCache.get(classCode);
-		if (legends == null) {
-			legends = dataStrategy.getLegendsForEquipment(classCode);
-			if (legends == null) {
-				legends = new ArrayList<>();
-			}
-			legendsCache.put(classCode, legends);
-		}
-		if(legends.size() > 0) {
-			Legend l0 = null, l1 = null;
-			for(Legend legend : legends) {
-				//系统图类型匹配
-				boolean typeMatch = CollUtil.isNotEmpty(legend.getDiagramTypes()) && legend.getDiagramTypes().contains(diagram.getType());
-				//过滤条件匹配
-				boolean filterMatch;
-				if(obj != null && legend.getDataFilter() != null) {
-					filterMatch = legend.getDataFilter().filter(obj, context);
-				} else {
-					filterMatch = true;
-				}
-
-				if(typeMatch && filterMatch) {
-					return legend;
-				}
-
-				if(typeMatch && l0 == null) {
-					l0 = legend;
-				}
-				if(filterMatch && l1 == null) {
-					l1 = legend;
-				}
-			}
-			if(l0 != null) {
-				return l0;
-			}
-			if(l1 != null) {
-				return l1;
-			}
-			//没有优先匹配的话取第一个
-			return legends.get(0);
-		}
-
-		//返回一个缺省图例
-		return emptyLegend();
-	}
-	
-	public void buildLines(List<ObjectNode> optionalRels){
-		//去掉已经使用的关系项
-		if(context.getLineMap().size() > 0) {
-			optionalRels = optionalRels.stream().filter(obj -> !context.getLineMap().containsKey(obj.get("id").asText())).collect(Collectors.toList());
-		}
-
-		for(ObjectNode rel : optionalRels) {
-			IDataBind fromObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_FROM_HUM).asText());
-			IDataBind toObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_TO_HUM).asText());
-
-			if(fromObj != null && toObj != null) {
-				String relType = rel.get(ObjectRelation.GRAPH_CODE_HUM).asText() + '/' + rel.get(ObjectRelation.REL_CODE_HUM).asText();
-				ConnectPoint from = getConnectPoint(fromObj, relType, toObj);
-				if(from != null) {
-					ConnectPoint to = getConnectPoint(toObj, relType, fromObj);
-					if(to != null) {
-						Line line = new Line();
-						line.setFrom(from);
-						line.setTo(to);
-						line.setRelType(relType);
-						line.setDataObject(rel);
-						line.setDataObjectId(rel.get("id").asText());
-
-						addLine(line);
-					}
-				}
-			}
-		}
-
-	}
-
-	private ConnectPoint getConnectPoint(IDataBind obj, String  relType, IDataBind theOtherEnd){
-		ObjectNode theOtherData = (ObjectNode) theOtherEnd.getDataObject();
-		String theOtherType = getClassCode(theOtherData);
-
-		if(obj instanceof EquipmentNode) {
-			EquipmentNode en = (EquipmentNode)obj;
-			Anchor anchor = null;
-			List<Anchor> anchors = en.getLegend().getAnchors();
-			if(CollUtil.isNotEmpty(anchors)) {
-				Anchor anchor1 = null; //部分匹配
-				for (Anchor a : anchors) {
-					Boolean relMatch = null; //关系匹配
-					Boolean equipMatch = null; //另一端设备匹配
-
-					if(CollUtil.isNotEmpty(a.getAcceptRelations())) {
-						relMatch = a.getAcceptRelations().contains(relType);
-					}
-
-					if(!Boolean.FALSE.equals(relMatch)) {
-						if(CollUtil.isNotEmpty(a.getToEquipmentTypes())) {
-							equipMatch = a.getToEquipmentTypes().contains(theOtherType);
-						}
-						if(!Boolean.FALSE.equals(equipMatch) && a.getToDataFilter() != null) {
-							equipMatch = a.getToDataFilter().filter(theOtherData, context);
-						}
-					}
-
-					if(!Boolean.FALSE.equals(relMatch) && !Boolean.FALSE.equals(equipMatch)) {
-						if(relMatch == null || equipMatch == null) {
-							//部分匹配
-							if(anchor1 == null) {
-								anchor1 = a;
-							} else if(CollUtil.isNotEmpty(anchor1.getLines()) && CollUtil.isEmpty(a.getLines())) {
-								anchor1 = a;
-							}
-						} else {
-							//完全匹配
-							if(CollUtil.isEmpty(a.getLines())) { //优先每个锚点只有一条连线
-								anchor = a;
-								break;
-							} else if(anchor == null) {
-								anchor = a;
-							}
-						}
-					}
-				}
-				if(anchor == null && anchor1 != null) {
-					anchor = anchor1;
-				}
-			}
-
-			if(anchor != null) {
-				ConnectPoint cp = new ConnectPoint();
-				cp.setHostType(EquipmentNode.TYPE);
-				cp.setHostId(en.getId());
-				cp.setAnchorCode(anchor.getCode());
-				cp.setHostObj(en);
-				return cp;
-			}
-		} else if(obj instanceof MainPipe) {
-			MainPipe mp = (MainPipe)obj;
-			if(CollUtil.isEmpty(mp.getConnectEquips()) || mp.getConnectEquips().contains(theOtherType)) {
-				ConnectPoint cp = new ConnectPoint();
-				cp.setHostType(MainPipe.TYPE);
-				cp.setHostId(mp.getId());
-				cp.setHostObj(mp);
-				return cp;
-			}
-		}
-		return null;
-	}
-
-	private void addLine(Line line) {
-		line.setId(IdUtil.fastSimpleUUID());
-		markAnchorLine(line.getFrom(), line);
-		markAnchorLine(line.getTo(), line);
-		diagram.getLines().add(line);
-	}
-
-	private void markAnchorLine(ConnectPoint p, Line line){
-		EquipmentNode en = p.getEquipmentNode();
-		if (en != null) {
-			Anchor anchor = en.getLegend().getAnchor(p.getAnchorCode());
-			anchor.addLine(line);
-		}
-	}
-
-	public HashSet<String> getRefRelTypes() {
-		return refRelTypes;
-	}
-
-	public Diagram getDiagram() {
-		return diagram;
-	}
-
-	public DataStrategy getDataStrategy() {
-		return dataStrategy;
-	}
-
-	public static String getName(ObjectNode obj){
-		String name = null;
-		if(obj.get("localName") != null) {
-			name = obj.get("localName").asText();
-		}
-		if(StrUtil.isBlank(name) && obj.get("name") != null) {
-			name = obj.get("name").asText();
-		}
-		if(name == null)
-			System.out.println();
-		return name;
-	}
-
-	public static String getClassCode(ObjectNode obj){
-		if(obj != null && obj.get("classCode") != null) {
-			return obj.get("classCode").asText();
-		}
-		return null;
-	}
-
-	public static Legend emptyLegend(){
-		Legend l = new Legend();
-		l.setWidth(100);
-		l.setHeight(100);
-		return l;
-	}
-
-}

+ 73 - 6
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/CalcContext.java

@@ -1,6 +1,7 @@
-package com.persagy.adm.diagram.core.model.logic;
+package com.persagy.adm.diagram.core.build;
 
 import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.adm.diagram.core.DataStrategy;
 import com.persagy.adm.diagram.core.model.Diagram;
 import com.persagy.adm.diagram.core.model.DiagramNode;
@@ -11,7 +12,10 @@ import com.persagy.adm.diagram.core.model.base.IDataBind;
 import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 系统图计算上下文
@@ -25,10 +29,16 @@ public class CalcContext {
 
 	private DataStrategy dataStrategy;
 
+	private DiagramBuilder diagramBuilder;
+
+	private List<ObjectNode> optionalObjs;
+
+	private List<ObjectNode> optionalRels;
+
 	/**
 	 * 当前动态组
 	 */
-	private Object currentGroup;
+	private CalcGroup currentGroup;
 
 	/**
 	 * 记录已经使用的数据id和对应的组件
@@ -70,9 +80,38 @@ public class CalcContext {
 		});
 	}
 
+	public DiagramBuilder getDiagramBuilder() {
+		return diagramBuilder;
+	}
+
+	public void setDiagramBuilder(DiagramBuilder diagramBuilder) {
+		this.diagramBuilder = diagramBuilder;
+	}
+
+	public void setCurrentGroup(CalcGroup calcGroup) {
+		if(currentGroup != null){
+			calcGroup.setParent(currentGroup);
+		}
+		currentGroup = calcGroup;
+	}
+
+	public void clearCurrentGroup(){
+		if (currentGroup != null) {
+			currentGroup = currentGroup.getParent();
+		}
+	}
+
 	public <T> T getComp(String id, String type) {
-		//TODO 按动态组获取
-		if(MainPipe.TYPE.equals(type)) {
+		if(currentGroup != null){
+			Object comp = currentGroup.getComp(id);
+			if(comp != null) {
+				return (T)comp;
+			}
+		}
+
+		if(Container.TYPE.equals(type)) {
+			return (T)template.getContainerById(id);
+		} else if(MainPipe.TYPE.equals(type)) {
 			return (T)template.getMainPipeById(id);
 		} else if(EquipmentNode.TYPE.equals(type)) {
 			for(DiagramNode node : diagram.getNodes()) {
@@ -80,14 +119,20 @@ public class CalcContext {
 					return (T)node;
 				}
 			}
-		} else if(Container.TYPE.equals(type)) {
-			return (T)template.getContainerById(id);
 		} else {
 			//TODO 其他类型
 		}
 		return null;
 	}
 
+	public ObjectNode getFloor(){
+		return currentGroup != null ? currentGroup.getFloor() : null;
+	}
+
+	public ObjectNode getBuilding(){
+		return currentGroup != null ? currentGroup.getBuilding() : null;
+	}
+
 	public DataStrategy getDataStrategy() {
 		return dataStrategy;
 	}
@@ -112,6 +157,28 @@ public class CalcContext {
 		return lineMap;
 	}
 
+	public List<ObjectNode> getOptionalObjs() {
+		return optionalObjs;
+	}
+
+	public void setOptionalObjs(List<ObjectNode> optionalObjs) {
+		if (optionalObjs == null) {
+			optionalObjs = new ArrayList<>(0);
+		} else if (equipMap.size() > 0) {
+			//去掉已经使用的数据项
+			optionalObjs = optionalObjs.stream().filter(obj -> !equipMap.containsKey(obj.get("id").asText())).collect(Collectors.toList());
+		}
+		this.optionalObjs = optionalObjs;
+	}
+
+	public List<ObjectNode> getOptionalRels() {
+		return optionalRels;
+	}
+
+	public void setOptionalRels(List<ObjectNode> optionalRels) {
+		this.optionalRels = optionalRels;
+	}
+
 	public String getProjectId() {
 		return diagram.getProjectId();
 	}

+ 108 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/build/CalcGroup.java

@@ -0,0 +1,108 @@
+package com.persagy.adm.diagram.core.build;
+
+import cn.hutool.core.collection.CollUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.adm.diagram.core.model.base.IEquipHolder;
+
+import java.util.*;
+
+/**
+ * 计算时的数据组
+ * @author zhaoyk
+ */
+public class CalcGroup {
+
+	private CalcGroup parent;
+
+	private int currentIdx;
+
+	private Map<String, Object> currentComps = new HashMap<>();
+
+	private IEquipHolder dynSrcComp;
+
+	private ObjectNode building;
+
+	private ObjectNode floor;
+
+	public CalcGroup() {
+
+	}
+
+	public void setDynSrcComp(IEquipHolder dynSrcComp, Object bindData) {
+		this.dynSrcComp = dynSrcComp;
+		this.dynSrcComp.setMatchedData(CollUtil.newArrayList(bindData));
+	}
+
+	public IEquipHolder getDynSrcComp() {
+		return dynSrcComp;
+	}
+
+	public ObjectNode getBuilding() {
+		CalcGroup g = this;
+		while (g != null){
+			if(g.building != null) {
+				return g.building;
+			}
+			g = g.parent;
+		}
+		return null;
+	}
+
+	public void setBuilding(ObjectNode building) {
+		this.building = building;
+	}
+
+	public ObjectNode getFloor() {
+		CalcGroup g = this;
+		while (g != null){
+			if(g.floor != null) {
+				return g.floor;
+			}
+			g = g.parent;
+		}
+		return null;
+	}
+
+	public void setFloor(ObjectNode floor) {
+		this.floor = floor;
+	}
+
+	public void setCurrentIdx(int currentIdx) {
+		this.currentIdx = currentIdx;
+	}
+
+	public void setParent(CalcGroup parent) {
+		this.parent = parent;
+	}
+
+	public CalcGroup getParent() {
+		return parent;
+	}
+
+	public Object getComp(String id) {
+		CalcGroup g = this;
+		while (g != null){
+			Object comp = g.currentComps.get(id);
+			if(comp != null) {
+				return comp;
+			}
+			g = g.parent;
+		}
+		return null;
+	}
+
+	public void addComp(String id, Object comp) {
+		currentComps.put(id, comp);
+	}
+
+	public List<Integer> getIdx(){
+		LinkedList<Integer> list = new LinkedList<>();
+		CalcGroup g = this;
+		while (g != null){
+			list.addFirst(g.currentIdx);
+			g = g.parent;
+		}
+		return list;
+	}
+
+}

+ 722 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/build/DiagramBuilder.java

@@ -0,0 +1,722 @@
+package com.persagy.adm.diagram.core.build;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.adm.diagram.core.ContentParser;
+import com.persagy.adm.diagram.core.model.*;
+import com.persagy.adm.diagram.core.model.base.Container;
+import com.persagy.adm.diagram.core.model.base.IComponent;
+import com.persagy.adm.diagram.core.model.base.IDataBind;
+import com.persagy.adm.diagram.core.model.base.IEquipHolder;
+import com.persagy.adm.diagram.core.model.legend.Anchor;
+import com.persagy.adm.diagram.core.model.legend.Legend;
+import com.persagy.adm.diagram.core.model.logic.DataFilter;
+import com.persagy.adm.diagram.core.model.logic.DynGroup;
+import com.persagy.adm.diagram.core.model.logic.LogicFilter;
+import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
+import com.persagy.adm.diagram.core.model.template.MainPipe;
+import com.persagy.adm.diagram.core.model.template.MainPipePoint;
+import com.persagy.adm.diagram.core.model.virtual.PackNode;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 处理系统图的计算逻辑
+ * @author zhaoyk
+ */
+public class DiagramBuilder {
+
+	public static final Object DATA_NULL = new Object();
+
+	/**
+	 * 设备容器限制,避免模板设置不当导致过多节点
+	 */
+	public static int equipLimit = 50;
+
+	private CalcContext context;
+
+	private Diagram diagram;
+
+	private DiagramTemplate template;
+
+	/**
+	 * template.mainPipes引用,避免空指针
+	 */
+	private List<MainPipe> mainPipes;
+
+	private LegendLoader legendLoader;
+
+	private ContentParser contentParser;
+
+	private HashSet<String> refRelTypes = new HashSet<>();
+
+	public DiagramBuilder(CalcContext context, LegendLoader legendLoader) {
+		this.context = context;
+		this.legendLoader = legendLoader;
+
+		this.diagram = context.getDiagram();
+		this.template = context.getTemplate();
+		this.mainPipes = template.getMainPipes() != null ? template.getMainPipes() : new ArrayList<>();
+
+		this.context.setDiagramBuilder(this);
+
+		this.contentParser = SpringUtil.getBean("diagramContentParser");
+	}
+
+	/**
+	 * 加载设备数据,构建系统图结构
+	 */
+	public void buildStructure(){
+		calcContainerAndMainPipes(template.getFrame());
+
+		buildMainPipeAndNodes();
+
+		handleNodes();
+		handleContainers();
+	}
+
+	/**
+	 * 对容器和相关的干管进行计算和数据加载
+	 */
+	private void calcContainerAndMainPipes(Container container){
+		List<Container> subEquipBoxes = new ArrayList<>();
+		List<Container> subDynCons = new ArrayList<>();
+		container.readSubContainers(subEquipBoxes, subDynCons);
+
+		List<MainPipe> relMainPipes = getRelMainPipes(container, subEquipBoxes);
+
+		DynGroup dynGroup = container.getDynGroup();
+		if (dynGroup != null) {
+			List<ObjectNode> dynData;
+			CalcGroup group;
+			int pos = container.getParent().getChildren().indexOf(container);
+
+			boolean isCompSrc = dynGroup.isCompSrc();
+			boolean isBuildingSrc = DynGroup.SRC_BUILDING.equals(dynGroup.getDynSource());
+			boolean isFloorSrc = DynGroup.SRC_FLOOR.equals(dynGroup.getDynSource());
+			if(isCompSrc) {
+				IEquipHolder srcComp = context.getComp(dynGroup.getDynSource(), dynGroup.getDynSourceType());
+				dynData = findMatchedData(srcComp);
+			} else {
+				dynData = getGroupList(dynGroup);
+			}
+
+			if (CollUtil.isEmpty(dynData)) {
+				return;
+			}
+
+			group = new CalcGroup();
+			context.setCurrentGroup(group);
+
+			String containerJson = null;
+			String mainPipesJson = null;
+
+			for (int i = 0; i < dynData.size(); i++) {
+				group.setCurrentIdx(i);
+
+				if(i == 0){
+					setGroupContainer(container, group);
+					setGroupMainPipes(relMainPipes, group);
+
+					if(isCompSrc) {
+						group.setDynSrcComp(context.getComp(dynGroup.getDynSource(), dynGroup.getDynSourceType()), dynData.get(i));
+					} else if(isFloorSrc) {
+						group.setFloor(dynData.get(i));
+					} else if(isBuildingSrc) {
+						group.setBuilding(dynData.get(i));
+					}
+
+					loadEquipsData(subEquipBoxes, subDynCons, relMainPipes);
+				} else {
+					if(containerJson == null) {
+						containerJson = contentParser.toJson(container);
+					}
+					if(mainPipesJson == null) {
+						mainPipesJson = contentParser.toJson(relMainPipes);
+					}
+
+					String idLabel = StrUtil.join("_", group.getIdx());
+
+					Container newCon = copyContainer(containerJson, idLabel);
+					container.getParent().addComp(newCon, pos + i);
+					setGroupContainer(newCon, group);
+
+					List<MainPipe> newMps = copyRelMainPipes(mainPipesJson, idLabel);
+					mainPipes.addAll(newMps);
+					setGroupMainPipes(newMps, group);
+
+					List<Container> newSubEquipBoxes = new ArrayList<>();
+					List<Container> newSubDynCons = new ArrayList<>();
+					newCon.readSubContainers(newSubEquipBoxes, newSubDynCons);
+
+					if(isCompSrc) {
+						group.setDynSrcComp(context.getComp(dynGroup.getDynSource(), dynGroup.getDynSourceType()), dynData.get(i));
+					} else if(isFloorSrc) {
+						group.setFloor(dynData.get(i));
+					} else if(isBuildingSrc) {
+						group.setBuilding(dynData.get(i));
+					}
+
+					loadEquipsData(newSubEquipBoxes, newSubDynCons, newMps);
+				}
+
+			}
+
+			//清除当前计算组
+			context.clearCurrentGroup();
+		} else {
+			loadEquipsData(subEquipBoxes, subDynCons, relMainPipes);
+		}
+	}
+
+	private List<ObjectNode> getGroupList(DynGroup dynGroup){
+		if(DynGroup.SRC_TYPE_GROUP.equals(dynGroup.getDynSourceType())) {
+			//按设备统计
+			return getGroupList(dynGroup.getDynSource());
+		} else if(DynGroup.SRC_TYPE_DATA.equals(dynGroup.getDynSourceType())) {
+			//TODO 数据查询
+
+		}
+		return null;
+	}
+
+	private List<ObjectNode> getGroupList(String group){
+		ObjectMapper mapper = new ObjectMapper();
+		HashMap<String, ObjectNode> map = new HashMap<>();
+		//TODO 楼层和建筑对象
+		for(ObjectNode obj : context.getOptionalObjs()) {
+			if(DynGroup.SRC_FLOOR.equals(group)) {
+				String key = getFloorId(obj);
+				if(StrUtil.isNotBlank(key) && !map.containsKey(key)){
+					map.put(key, mapper.createObjectNode().put("id", key));
+				}
+			} else if(DynGroup.SRC_BUILDING.equals(group)) {
+				String key = getBuildingId(obj);
+				if(StrUtil.isNotBlank(key) && !map.containsKey(key)){
+					map.put(key, mapper.createObjectNode().put("id", key));
+				}
+			}
+		}
+
+		List<ObjectNode> list = new ArrayList<>(map.values());
+		sortBdFlList(list);
+
+		return list;
+	}
+
+	private void sortBdFlList(List<ObjectNode> list){
+
+	}
+
+	private void setGroupContainer(Container con, CalcGroup currentGroup) {
+		for (Container item : con.listContainers()) {
+			currentGroup.addComp(getSrcId(item.getId()), item);
+		}
+	}
+
+	private void setGroupMainPipes(List<MainPipe> mps,  CalcGroup currentGroup){
+		for(MainPipe mp : mps){
+			currentGroup.addComp(getSrcId(mp.getId()), mp);
+		}
+	}
+
+	private Container copyContainer(String containerJson, String idLabel) {
+		Container container = contentParser.parseContent(containerJson, Container.class);
+		for (Container con : container.listContainers()) {
+			con.setId(getSrcId(con.getId()) + ":" + idLabel);
+		}
+		container.initParent();
+
+		return container;
+	}
+
+	private List<MainPipe> copyRelMainPipes(String mainPipesJson, String idLabel){
+		List<MainPipe> mainPipes = new ArrayList<>();
+		Collections.addAll(mainPipes, contentParser.parseContent(mainPipesJson, MainPipe[].class));
+		for(MainPipe mp : mainPipes){
+			mp.setId(getSrcId(mp.getId()) + ":" + idLabel);
+			changeMainPipeRefIds(mp);
+
+			mp.init(template);
+		}
+		return mainPipes;
+	}
+
+	private void changeMainPipeRefIds(MainPipe mp){
+		List<String> relConIds = mp.getRelatedContainers();
+		if(relConIds != null){
+			for (int i = 0; i < relConIds.size(); i++) {
+				Container con = context.getComp(relConIds.get(i), Container.TYPE);
+				if(con != null) {
+					relConIds.set(i, con.getId());
+				}
+			}
+		}
+
+		for(List<MainPipePoint> line : mp.getPath()){
+			for (MainPipePoint p : line) {
+				Container con = context.getComp(p.getContainerId(), Container.TYPE);
+				if(con != null) {
+					p.setContainerId(con.getId());
+				}
+			}
+		}
+	}
+
+	private String getSrcId(String id){
+		int pos = id.indexOf(':');
+		if(pos > 0){
+			return id.substring(0, pos);
+		}
+		return id;
+	}
+
+	private List<MainPipe> getRelMainPipes(Container container, List<Container> subEquipBoxes){
+		List<MainPipe> relMainPipes = new ArrayList<>();
+		boolean isFrame = template.isFrameContainer(container);
+		for(MainPipe mainPipe : mainPipes) {
+			List<Container> relCons = mainPipe.getRelatedContainerList();
+			boolean relWithMe;
+			if(isFrame){
+				relWithMe = CollUtil.isEmpty(relCons);
+			} else {
+				relWithMe = relCons != null && relCons.contains(container);
+			}
+			if(relWithMe){
+				relMainPipes.add(mainPipe);
+			} else {
+				for(Container subEq : subEquipBoxes) {
+					if(relCons != null && relCons.contains(subEq)){
+						relMainPipes.add(mainPipe);
+						break;
+					}
+				}
+			}
+		}
+		return relMainPipes;
+	}
+
+	private void loadEquipsData(List<Container> subEquipBoxes, List<Container> subDynCons, List<MainPipe> relMainPipes){
+		for(MainPipe mainPipe : relMainPipes) {
+			if (mainPipe.isBindEquipment()){
+				loadMatchedData(mainPipe);
+			}
+		}
+		for(Container subCon : subEquipBoxes) {
+			loadMatchedData(subCon);
+		}
+
+		if (subDynCons.size() > 0) {
+			for(Container subDyn : subDynCons) {
+				calcContainerAndMainPipes(subDyn);
+			}
+		}
+	}
+
+	public List<ObjectNode> loadMatchedData(IEquipHolder equipHolder){
+		List<ObjectNode> matchedData = equipHolder.getMatchedData();
+		if(matchedData == null){
+			matchedData = findMatchedData(equipHolder);
+			if(matchedData == null) {
+				matchedData = Collections.EMPTY_LIST;
+			}
+			equipHolder.setMatchedData(matchedData);
+		}
+		return matchedData;
+	}
+
+	private List<ObjectNode> findMatchedData(IEquipHolder equipHolder){
+		ArrayList<ObjectNode> data = null;
+		for(ObjectNode obj : context.getOptionalObjs()) {
+			if (match(obj, equipHolder)){
+				if(data == null){
+					data = new ArrayList<>();
+				}
+				data.add(obj);
+			}
+		}
+		return data;
+	}
+
+	private void buildMainPipeAndNodes(){
+		for(MainPipe mainPipe : mainPipes) {
+			if (mainPipe.isBindEquipment()) {
+				List<ObjectNode> matchedData = mainPipe.getMatchedData();
+				if(CollUtil.isNotEmpty(matchedData)) {
+					sortDataList(matchedData);
+
+					ObjectNode obj = (ObjectNode)mainPipe.getMatchedData().get(0);
+					mainPipe.setDataObject(obj);
+					mainPipe.setDataObjectId(obj.get("id").asText());
+
+					context.getEquipMap().put(mainPipe.getDataObjectId(), mainPipe);
+				}
+			}
+		}
+		for(Container con : template.getContainers()) {
+			if(con.isEquipmentBox()) {
+				List<ObjectNode> matchedData = con.getMatchedData();
+				if(CollUtil.isNotEmpty(matchedData)) {
+					sortDataList(matchedData);
+
+					for(ObjectNode obj : matchedData) {
+						if(con.getEquipPack() != null) {
+							addPackData(con, obj);
+						} else {
+							addEquipNode(con, obj);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	private void sortDataList(List<ObjectNode> dataList){
+		//TODO 对设备数据进行排序操作
+	}
+
+	private void addEquipNode(Container con, ObjectNode obj){
+		if(con.getChildren().size() > equipLimit) {
+			return;
+		}
+
+		EquipmentNode node = new EquipmentNode();
+		node.setId(IdUtil.fastSimpleUUID());
+		node.setDataObjectId(obj.get("id").asText());
+		node.setObjClassCode(DiagramBuilder.getClassCode(obj));
+		node.setDataObject(obj);
+
+		initNode(node, DiagramBuilder.getName(obj), con);
+
+		Legend legend = legendLoader.findLegend(node.getObjClassCode(), obj);
+		node.setLegendId(legend.getId());
+		node.setLegend(legend);
+	}
+
+	private void initNode(EquipmentNode node, String name, Container con){
+		con.addComp(node);
+		node.setContainerId(con.getId());
+		node.setLayoutIndex(con.getChildren().size() - 1);
+
+		Label label = new Label();
+		label.setId(IdUtil.fastSimpleUUID());
+		label.setContent(name);
+		node.setLabel(label);
+
+		diagram.getNodes().add(node);
+		context.getEquipMap().put(node.getDataObjectId(), node);
+	}
+
+	private void addPackData(Container con, ObjectNode obj){
+		PackNode pn = null;
+		String classCode = getClassCode(obj);
+		Legend legend = null;
+		//single
+		if(!con.getEquipPack().isPackByType()) {
+			String packName = con.getEquipPack().getPackName();
+			if(StrUtil.isBlank(packName)) {
+				packName = getTypeName(classCode);
+			}
+			if(con.getChildren().size() == 0) {
+				pn = newPackNode(PackNode.SINGLE_PACK, con, packName);
+			} else {
+				pn = (PackNode) con.getChildren().get(0);
+			}
+		} else { //group
+			for(IComponent comp : con.getChildren()) {
+				PackNode item = (PackNode) comp;
+				if(item.getObjClassCode().equals(classCode)){
+					pn = item;
+					break;
+				}
+			}
+			if(pn == null) {
+				pn = newPackNode(classCode, con, getTypeName(classCode));
+			}
+		}
+
+		if (pn.getLegend() == null) {
+			if(con.getEquipPack().getLegendId() != null) {
+				legend = legendLoader.findLegendById(con.getEquipPack().getLegendId(), classCode.substring(0, 4));
+			}
+			if(legend == null) {
+				legend = legendLoader.findLegend(classCode, null);
+			}
+
+			pn.setLegendId(legend.getId());
+			pn.setLegend(legend);
+		}
+
+		pn.add(classCode);
+	}
+
+	private PackNode newPackNode(String objClsCode, Container con, String packName){
+		PackNode pn = new PackNode();
+		pn.setId(IdUtil.fastSimpleUUID());
+		pn.setObjClassCode(objClsCode);
+
+		initNode(pn, packName, con);
+
+		return pn;
+	}
+
+	private boolean match(ObjectNode obj, IEquipHolder equipHolder) {
+		String classCode = DiagramBuilder.getClassCode(obj);
+		if(equipHolder.getEquipmentTypes() != null && equipHolder.getEquipmentTypes().contains(classCode)) {
+			if(checkBdFl(obj)){
+				DataFilter filter = equipHolder.getDataFilter();
+				if(filter != null) {
+					return filter.filter(obj, context);
+				}
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean checkBdFl(ObjectNode obj){
+		ObjectNode bd = context.getBuilding();
+		ObjectNode fl = context.getFloor();
+		if(bd != null){
+			String bdId = getBuildingId(obj);
+			if(!bd.get("id").asText().equals(bdId)){
+				return false;
+			}
+		}
+		if(fl != null){
+			String flId = getFloorId(obj);
+			if(!fl.get("id").asText().equals(flId)){
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * 对节点进行处理,并返回图例锚点会使用到的关系类型
+	 */
+	private void handleNodes() {
+		for(DiagramNode node : diagram.getNodes()) {
+			if(PackNode.TYPE.equals(node.getCompType())) {
+				PackNode pn = (PackNode)node;
+				pn.getLabel().setContent(pn.getLabel().getContent() + ":" + pn.totalCount());
+				statRelTypes(pn);
+			} else if(EquipmentNode.TYPE.equals(node.getCompType())) {
+				statRelTypes((EquipmentNode)node);
+			}
+		}
+	}
+
+	private void statRelTypes(EquipmentNode equipmentNode){
+		List<Anchor> anchors = equipmentNode.getLegend().getAnchors();
+		if(anchors != null) {
+			for(Anchor anchor : anchors) {
+				if(anchor.getAcceptRelations() != null) {
+					anchor.getAcceptRelations().forEach(rel -> refRelTypes.add(rel));
+				}
+			}
+		}
+	}
+
+	private void handleContainers() {
+		for(Container con : template.getContainers()) {
+			if(con.isEquipmentBox()) {
+				if(Boolean.TRUE.equals(con.getProp(Container.PROP_AUTO_HIDDEN)) && CollUtil.isEmpty(con.getChildren())) {
+					con.setHidden(true);
+				}
+			}
+		}
+	}
+
+	private String getTypeName(String classCode){
+		//TODO
+		return classCode;
+	}
+
+	public void buildLines(List<ObjectNode> optionalRels){
+		//去掉已经使用的关系项
+		if(context.getLineMap().size() > 0) {
+			optionalRels = optionalRels.stream().filter(obj -> !context.getLineMap().containsKey(obj.get("id").asText())).collect(Collectors.toList());
+		}
+
+		for(ObjectNode rel : optionalRels) {
+			IDataBind fromObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_FROM_HUM).asText());
+			IDataBind toObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_TO_HUM).asText());
+
+			if(fromObj != null && toObj != null) {
+				String relType = rel.get(ObjectRelation.GRAPH_CODE_HUM).asText() + '/' + rel.get(ObjectRelation.REL_CODE_HUM).asText();
+				ConnectPoint from = getConnectPoint(fromObj, relType, toObj);
+				if(from != null) {
+					ConnectPoint to = getConnectPoint(toObj, relType, fromObj);
+					if(to != null) {
+						Line line = new Line();
+						line.setFrom(from);
+						line.setTo(to);
+						line.setRelType(relType);
+						line.setDataObject(rel);
+						line.setDataObjectId(rel.get("id").asText());
+
+						addLine(line);
+					}
+				}
+			}
+		}
+
+	}
+
+	private ConnectPoint getConnectPoint(IDataBind obj, String  relType, IDataBind theOtherEnd){
+		ObjectNode theOtherData = (ObjectNode) theOtherEnd.getDataObject();
+		String theOtherType = getClassCode(theOtherData);
+
+		if(obj instanceof EquipmentNode) {
+			EquipmentNode en = (EquipmentNode)obj;
+			Anchor anchor = null;
+			List<Anchor> anchors = en.getLegend().getAnchors();
+			if(CollUtil.isNotEmpty(anchors)) {
+				Anchor anchor1 = null; //部分匹配
+				for (Anchor a : anchors) {
+					Boolean relMatch = null; //关系匹配
+					Boolean equipMatch = null; //另一端设备匹配
+
+					if(CollUtil.isNotEmpty(a.getAcceptRelations())) {
+						relMatch = a.getAcceptRelations().contains(relType);
+					}
+
+					if(!Boolean.FALSE.equals(relMatch)) {
+						if(CollUtil.isNotEmpty(a.getToEquipmentTypes())) {
+							equipMatch = a.getToEquipmentTypes().contains(theOtherType);
+						}
+						if(!Boolean.FALSE.equals(equipMatch) && a.getToDataFilter() != null) {
+							equipMatch = a.getToDataFilter().filter(theOtherData, context);
+						}
+					}
+
+					if(!Boolean.FALSE.equals(relMatch) && !Boolean.FALSE.equals(equipMatch)) {
+						if(relMatch == null || equipMatch == null) {
+							//部分匹配
+							if(anchor1 == null) {
+								anchor1 = a;
+							} else if(CollUtil.isNotEmpty(anchor1.getLines()) && CollUtil.isEmpty(a.getLines())) {
+								anchor1 = a;
+							}
+						} else {
+							//完全匹配
+							if(CollUtil.isEmpty(a.getLines())) { //优先每个锚点只有一条连线
+								anchor = a;
+								break;
+							} else if(anchor == null) {
+								anchor = a;
+							}
+						}
+					}
+				}
+				if(anchor == null && anchor1 != null) {
+					anchor = anchor1;
+				}
+			}
+
+			if(anchor != null) {
+				ConnectPoint cp = new ConnectPoint();
+				cp.setHostType(EquipmentNode.TYPE);
+				cp.setHostId(en.getId());
+				cp.setAnchorCode(anchor.getCode());
+				cp.setHostObj(en);
+				return cp;
+			}
+		} else if(obj instanceof MainPipe) {
+			MainPipe mp = (MainPipe)obj;
+			if(CollUtil.isEmpty(mp.getConnectEquips()) || mp.getConnectEquips().contains(theOtherType)) {
+				ConnectPoint cp = new ConnectPoint();
+				cp.setHostType(MainPipe.TYPE);
+				cp.setHostId(mp.getId());
+				cp.setHostObj(mp);
+				return cp;
+			}
+		}
+		return null;
+	}
+
+	private void addLine(Line line) {
+		line.setId(IdUtil.fastSimpleUUID());
+		markAnchorLine(line.getFrom(), line);
+		markAnchorLine(line.getTo(), line);
+		diagram.getLines().add(line);
+	}
+
+	private void markAnchorLine(ConnectPoint p, Line line){
+		EquipmentNode en = p.getEquipmentNode();
+		if (en != null) {
+			Anchor anchor = en.getLegend().getAnchor(p.getAnchorCode());
+			anchor.addLine(line);
+		}
+	}
+
+	public HashSet<String> getRefRelTypes() {
+		return refRelTypes;
+	}
+
+	public Diagram getDiagram() {
+		return diagram;
+	}
+
+	public static boolean hasRelationFilter(IEquipHolder equipHolder) {
+		DataFilter filter = equipHolder.getDataFilter();
+		if(filter != null) {
+			if (filter.getType() == DataFilter.TYPE_RELATION) {
+				return true;
+			}
+			if (filter instanceof LogicFilter) {
+				LinkedList<DataFilter> list = new LinkedList<>();
+				list.addAll(((LogicFilter) filter).getItems());
+
+				while (list.size() > 0) {
+					DataFilter item = list.removeFirst();
+					if(item.getType() == DataFilter.TYPE_RELATION){
+						return true;
+					} else if(item instanceof LogicFilter) {
+						list.addAll(((LogicFilter) item).getItems());
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	public static String getName(ObjectNode obj){
+		String name = null;
+		if(obj.get("localName") != null) {
+			name = obj.get("localName").asText();
+		}
+		if(StrUtil.isBlank(name) && obj.get("name") != null) {
+			name = obj.get("name").asText();
+		}
+		return name;
+	}
+
+	public static String getClassCode(ObjectNode obj){
+		return getInfo(obj, "classCode");
+	}
+
+	private static String getInfo(ObjectNode obj, String infoCode){
+		if(obj != null && obj.get(infoCode) != null) {
+			return obj.get(infoCode).asText();
+		}
+		return null;
+	}
+
+	private static String getBuildingId(ObjectNode obj){
+		return getInfo(obj, "buildingId");
+	}
+
+	private static String getFloorId(ObjectNode obj){
+		return getInfo(obj, "floorId");
+	}
+
+
+}

+ 13 - 13
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/DiagramDataLoader.java

@@ -1,13 +1,13 @@
-package com.persagy.adm.diagram.core;
+package com.persagy.adm.diagram.core.build;
 
 import cn.hutool.core.collection.CollUtil;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.adm.diagram.core.DataStrategy;
 import com.persagy.adm.diagram.core.model.Diagram;
 import com.persagy.adm.diagram.core.model.DiagramNode;
 import com.persagy.adm.diagram.core.model.EquipmentNode;
 import com.persagy.adm.diagram.core.model.Line;
 import com.persagy.adm.diagram.core.model.base.Container;
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 import com.persagy.dmp.common.constant.ValidEnum;
 import com.persagy.dmp.digital.entity.ObjectRelation;
@@ -28,9 +28,12 @@ public class DiagramDataLoader {
 
 	private DataStrategy dataStrategy;
 
+	private LegendLoader legendLoader;
+
 	public DiagramDataLoader(Diagram diagram, DataStrategy dataStrategy) {
 		this.diagram = diagram;
 		this.dataStrategy = dataStrategy;
+		this.legendLoader = new LegendLoader(diagram, dataStrategy);
 	}
 
 	/**
@@ -63,11 +66,7 @@ public class DiagramDataLoader {
 				EquipmentNode en = (EquipmentNode) node;
 				obj = objMap.get(en.getDataObjectId());
 
-				if(en.getLegendId() != null) {
-					en.setLegend(dataStrategy.getLegend(en.getLegendId(), en.getObjSystemCode())); //TODO 批量查询优化
-				} else {
-					en.setLegend(DiagramBuilder.emptyLegend());
-				}
+				en.setLegend(legendLoader.findLegendById(en.getLegendId(), en.getObjSystemCode()));
 
 				//设置anchorLocations
 				en.setAnchorLocations();
@@ -136,15 +135,16 @@ public class DiagramDataLoader {
 			optionalObjs = dataStrategy.loadObjectsByType(new ArrayList<>(equipTypes), diagram.getProjectId(), diagram.getSystemId(), diagram.getGroupCode());
 			optionalObjs = filterValid(optionalObjs);
 		}
-		if(optionalObjs == null){
-			optionalObjs = new ArrayList<>();
-		}
+		context.setOptionalObjs(optionalObjs);
+
+		context.setDataStrategy(dataStrategy);
+		legendLoader.setContext(context);
+		DiagramBuilder builder = new DiagramBuilder(context, legendLoader);
 
-		DiagramBuilder builder = new DiagramBuilder(context, dataStrategy);
-		builder.buildEquipNodeAndContainer(containers, optionalObjs);
+		builder.buildStructure();
 		List<String[]> relTypes = builder.getRefRelTypes().stream().map(type -> type.split("/")).collect(Collectors.toList());
 
-		List<String> objIds = optionalObjs.stream().map(obj -> obj.get("id").asText()).collect(Collectors.toList());
+		List<String> objIds = new ArrayList<>(context.getEquipMap().keySet());
 		//TODO 关系查询,需要区分打包设备
 		if(objIds.size() > 0 && relTypes.size() > 0) {
 			optionalRels = dataStrategy.loadRelationsByType(relTypes, objIds, diagram.getProjectId(), diagram.getGroupCode());

+ 98 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/build/LegendLoader.java

@@ -0,0 +1,98 @@
+package com.persagy.adm.diagram.core.build;
+
+import cn.hutool.core.collection.CollUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.adm.diagram.core.DataStrategy;
+import com.persagy.adm.diagram.core.model.Diagram;
+import com.persagy.adm.diagram.core.model.legend.Legend;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * 图例加载
+ * @author zhaoyk
+ */
+public class LegendLoader {
+
+	private Diagram diagram;
+
+	private DataStrategy dataStrategy;
+
+	private CalcContext context;
+
+	private HashMap<String, List<Legend>> legendsCache = new HashMap<>();
+
+	public LegendLoader(Diagram diagram, DataStrategy dataStrategy) {
+		this.diagram = diagram;
+		this.dataStrategy = dataStrategy;
+	}
+
+	public void setContext(CalcContext context) {
+		this.context = context;
+	}
+
+	public Legend findLegend(String classCode, ObjectNode obj){
+		List<Legend> legends = legendsCache.get(classCode);
+		if (legends == null) {
+			legends = dataStrategy.getLegendsForEquipment(classCode);
+			if (legends == null) {
+				legends = new ArrayList<>();
+			}
+			legendsCache.put(classCode, legends);
+		}
+		if(legends.size() > 0) {
+			Legend l0 = null, l1 = null;
+			for(Legend legend : legends) {
+				//系统图类型匹配
+				boolean typeMatch = CollUtil.isNotEmpty(legend.getDiagramTypes()) && legend.getDiagramTypes().contains(diagram.getType());
+				//过滤条件匹配
+				boolean filterMatch;
+				if(obj != null && legend.getDataFilter() != null) {
+					filterMatch = legend.getDataFilter().filter(obj, context);
+				} else {
+					filterMatch = true;
+				}
+
+				if(typeMatch && filterMatch) {
+					return legend;
+				}
+
+				if(typeMatch && l0 == null) {
+					l0 = legend;
+				}
+				if(filterMatch && l1 == null) {
+					l1 = legend;
+				}
+			}
+			if(l0 != null) {
+				return l0;
+			}
+			if(l1 != null) {
+				return l1;
+			}
+			//没有优先匹配的话取第一个
+			return legends.get(0);
+		}
+
+		//返回一个缺省图例
+		return emptyLegend();
+	}
+
+	public Legend findLegendById(String legendId, String systemCode) {
+		Legend legend = null;
+		if(legendId != null) {
+			legend = dataStrategy.getLegend(legendId, systemCode); //TODO 批量查询优化
+		}
+		return legend != null ? legend : emptyLegend();
+	}
+
+	public static Legend emptyLegend(){
+		Legend l = new Legend();
+		l.setWidth(100);
+		l.setHeight(100);
+		return l;
+	}
+
+}

+ 17 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/impl/DataStrategyImpl.java

@@ -715,4 +715,21 @@ public class DataStrategyImpl implements DataStrategy {
         diagramMapper.updateById(entity);
         return true;
     }
+
+    /**
+     * 判断系统图名称是否重复
+     *
+     * @param name 系统图名称
+     * @return 是否重复
+     */
+    @Override
+    public boolean judgeNameDuplicate(String name) {
+        if (StrUtil.isBlank(name)) {
+            throw new BusinessException(ResponseCode.A0400.getCode(), "名称参数为空");
+        }
+        BdtpRequest req = BdtpRequest.getCurrent();
+        String projectId = req.getProjectId();
+        List<DiagramEntity> diagramEntities = diagramMapper.selectByName(projectId, name);
+        return CollectionUtil.isNotEmpty(diagramEntities);
+    }
 }

+ 1 - 1
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/line/LineLayoutManager.java

@@ -5,7 +5,7 @@ import com.persagy.adm.diagram.core.model.DiagramNode;
 import com.persagy.adm.diagram.core.model.EquipmentNode;
 import com.persagy.adm.diagram.core.model.Line;
 import com.persagy.adm.diagram.core.model.base.XY;
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
+import com.persagy.adm.diagram.core.build.CalcContext;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 import com.persagy.adm.diagram.core.util.GeomUtil;
 import org.locationtech.jts.geom.Point;

+ 7 - 5
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/line/PathBuilder.java

@@ -526,12 +526,14 @@ public class PathBuilder {
 
             if (vDirection == vEndNbr) { //当前方向与终点通道方向相同
                 if (vEndNbr == hLine) { //endLine与通道垂直
+                    int safeOffset = 5;
+                    int[] targetScope = new int[]{Math.max(lineScope[0], endNbr[0] + safeOffset), Math.min(lineScope[1], endNbr[1] - safeOffset)};
+
                     //当前点和线有偏差时,先做调整
-                    int[] targetScope = new int[]{Math.max(lineScope[0], endNbr[0]), Math.min(lineScope[1], endNbr[1])};
                     int pos = vEndNbr ? currentPoint.x : currentPoint.y;
                     if(!(pos > targetScope[0] && pos < targetScope[1])){
-                        int safeOffset = 5;//临时避免和节点边线重合
-                        int target0 = targetScope[0] + safeOffset + random.nextInt(targetScope[1] - targetScope[0] - safeOffset * 2);
+                        //临时避免和节点边线重合
+                        int target0 = targetScope[0] + random.nextInt(targetScope[1] - targetScope[0]);
                         if (vEndNbr) {
                             currentPoint.x = target0;
                         } else {
@@ -555,9 +557,9 @@ public class PathBuilder {
                 }
             } else { //当前方向与终点通道方向垂直,折线连接
                 if (vEndNbr == hLine) { //endLine与通道垂直
-                    int[] targetScope = new int[]{Math.max(lineScope[0], endNbr[0]), Math.min(lineScope[1], endNbr[1])};
                     int safeOffset = 5;//临时避免和节点边线重合
-                    int target0 = targetScope[0] + safeOffset + random.nextInt(targetScope[1] - targetScope[0] - safeOffset * 2); //TODO 调整&避免重叠
+                    int[] targetScope = new int[]{Math.max(lineScope[0], endNbr[0] + safeOffset), Math.min(lineScope[1], endNbr[1] - safeOffset)};
+                    int target0 = targetScope[0] + random.nextInt(targetScope[1] - targetScope[0]); //TODO 调整&避免重叠
                     moveTo(target0, vDirection);
                     moveTo(lineTrackPos, hLine);
                 } else { //endLine与通道平行

+ 1 - 2
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/ConnectPoint.java

@@ -3,8 +3,7 @@ package com.persagy.adm.diagram.core.model;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.gson.annotations.Expose;
 import com.persagy.adm.diagram.core.model.base.XY;
-import com.persagy.adm.diagram.core.model.legend.Anchor;
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
+import com.persagy.adm.diagram.core.build.CalcContext;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 
 import java.util.Objects;

+ 1 - 1
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/Diagram.java

@@ -6,7 +6,7 @@ import com.persagy.adm.diagram.core.line.LineLayoutManager;
 import com.persagy.adm.diagram.core.model.base.Container;
 import com.persagy.adm.diagram.core.model.base.IComponent;
 import com.persagy.adm.diagram.core.model.base.XY;
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
+import com.persagy.adm.diagram.core.build.CalcContext;
 import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
 import com.persagy.adm.diagram.core.model.template.MainPipe;
 

+ 3 - 3
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/AbstractComponent.java

@@ -28,7 +28,7 @@ abstract public class AbstractComponent implements IComponent {
 	 * 使用jackson输出到web端
 	 */
 	@JsonIgnore
-	protected IContainer parent;
+	protected Container parent;
 
 	@Expose
 	protected PositionData position;
@@ -87,12 +87,12 @@ abstract public class AbstractComponent implements IComponent {
 	}
 
 	@Override
-	public IContainer getParent() {
+	public Container getParent() {
 		return parent;
 	}
 
 	@Override
-	public void setParent(IContainer parent) {
+	public void setParent(Container parent) {
 		this.parent = parent;
 	}
 

+ 57 - 17
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/Container.java

@@ -7,7 +7,6 @@ import com.persagy.adm.diagram.core.model.Label;
 import com.persagy.adm.diagram.core.model.logic.DataFilter;
 import com.persagy.adm.diagram.core.model.logic.DynGroup;
 import com.persagy.adm.diagram.core.model.logic.EquipPack;
-import com.persagy.adm.diagram.core.model.template.MainPipe;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -67,10 +66,10 @@ public class Container extends AbstractComponent implements IContainer, IEquipHo
 	private String dynTarget;
 
 	/**
-	 * 直接包含的干管
+	 * 适配的数据,运行时
 	 */
 	@JsonIgnore
-	private List<MainPipe> childMainPipes;
+	private List matchedData;
 
 	public Container() {
 		this.compType = TYPE;
@@ -195,6 +194,15 @@ public class Container extends AbstractComponent implements IContainer, IEquipHo
 		}
 	}
 
+	public void addComp(IComponent child, int pos){
+		children.add(pos, child);
+		child.setParent(this);
+
+		if(child.getPosition() == null) {
+			child.setPosition(child.defaultPosition());
+		}
+	}
+
 	public List<IComponent> getArrangedElements(){
 		return children.stream().filter(comp -> !comp.isAbsolutePosition()).collect(Collectors.toList());
 	}
@@ -212,10 +220,45 @@ public class Container extends AbstractComponent implements IContainer, IEquipHo
 		this.equipmentTypes = equipmentTypes;
 	}
 
+	public List<Container> listContainers(){
+		List<Container> list = new ArrayList<>();
+		getContainers(this, list);
+		return list;
+	}
+
+	private void getContainers(Container con, List<Container> list){
+		list.add(con);
+
+		if(con.getChildren() != null) {
+			for(IComponent comp : con.getChildren()) {
+				if (comp instanceof Container) {
+					getContainers((Container) comp, list);
+				}
+			}
+		}
+	}
+
 	public boolean isEquipmentBox() {
 		return CollUtil.isNotEmpty(equipmentTypes);
 	}
 
+	public void readSubContainers(List<Container> equipBoxes, List<Container> dynCons){
+		for(IComponent comp : children) {
+			if(comp instanceof Container){
+				Container con = (Container) comp;
+				if(con.isEquipmentBox()){
+					equipBoxes.add(con);
+				} else {
+					if(con.getDynGroup() == null){
+						con.readSubContainers(equipBoxes, dynCons);
+					} else {
+						dynCons.add(con);
+					}
+				}
+			}
+		}
+	}
+
 	public String getRemark() {
 		return remark;
 	}
@@ -257,6 +300,16 @@ public class Container extends AbstractComponent implements IContainer, IEquipHo
 		this.groupLabel = groupLabel;
 	}
 
+	@Override
+	public <T> List<T> getMatchedData() {
+		return matchedData;
+	}
+
+	@Override
+	public <T> void setMatchedData(List<T> matchedData) {
+		this.matchedData = matchedData;
+	}
+
 	public void initParent() {
 		List<IComponent> cs = new ArrayList<>(children);
 		children.clear();
@@ -285,7 +338,7 @@ public class Container extends AbstractComponent implements IContainer, IEquipHo
 	}
 
 	public boolean isParentOf(IComponent comp){
-		IContainer p = comp.getParent();
+		Container p = comp.getParent();
 		while (p != null) {
 			if(p == this){
 				return true;
@@ -303,19 +356,6 @@ public class Container extends AbstractComponent implements IContainer, IEquipHo
 		this.dynTarget = dynTarget;
 	}
 
-	public void addChildMainPipe(MainPipe mainPipe) {
-		if(childMainPipes == null) {
-			childMainPipes = new ArrayList<>();
-		}
-		childMainPipes.add(mainPipe);
-	}
-
-	public void removeChildMainPipe(MainPipe mainPipe) {
-		if(childMainPipes != null) {
-			childMainPipes.remove(mainPipe);
-		}
-	}
-
 	@Override
 	public PositionData defaultPosition() {
 		PositionData data = new PositionData();

+ 2 - 2
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/IComponent.java

@@ -16,9 +16,9 @@ public interface IComponent {
 
     String getCompType();
 
-    IContainer getParent();
+    Container getParent();
 
-    void setParent(IContainer parent);
+    void setParent(Container parent);
 
     void layout();
 

+ 10 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/base/IEquipHolder.java

@@ -19,4 +19,14 @@ public interface IEquipHolder {
 	 */
 	DataFilter getDataFilter();
 
+	/**
+	 * 获取适配的数据
+	 */
+	<T> List<T> getMatchedData();
+
+	/**
+	 * 设置适配的数据
+	 */
+	<T> void setMatchedData(List<T> matchedData);
+
 }

+ 2 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/AndFilter.java

@@ -1,5 +1,7 @@
 package com.persagy.adm.diagram.core.model.logic;
 
+import com.persagy.adm.diagram.core.build.CalcContext;
+
 /**
  * and条件
  * @author zhaoyk

+ 1 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/DataFilter.java

@@ -1,6 +1,7 @@
 package com.persagy.adm.diagram.core.model.logic;
 
 import com.google.gson.annotations.Expose;
+import com.persagy.adm.diagram.core.build.CalcContext;
 
 /**
  * 设备数据过滤器

+ 14 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/DynGroup.java

@@ -1,6 +1,8 @@
 package com.persagy.adm.diagram.core.model.logic;
 
 import com.google.gson.annotations.Expose;
+import com.persagy.adm.diagram.core.model.base.Container;
+import com.persagy.adm.diagram.core.model.template.MainPipe;
 
 /**
  * 容器的动态组配置
@@ -8,6 +10,14 @@ import com.google.gson.annotations.Expose;
  */
 public class DynGroup {
 
+	public static final String SRC_TYPE_GROUP = "group";
+
+	public static final String SRC_TYPE_DATA = "data";
+
+	public static final String SRC_BUILDING = "building";
+
+	public static final String SRC_FLOOR = "floor";
+
 	/**
 	 * 动态源(floor | building | mainPipe.id | container.id)
 	 */
@@ -50,4 +60,8 @@ public class DynGroup {
 		this.labelPosition = labelPosition;
 	}
 
+	public boolean isCompSrc(){
+		return Container.TYPE.equals(dynSourceType) || MainPipe.TYPE.equals(dynSourceType);
+	}
+
 }

+ 2 - 1
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/MatchFilter.java

@@ -3,7 +3,8 @@ package com.persagy.adm.diagram.core.model.logic;
 import cn.hutool.core.util.StrUtil;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.gson.annotations.Expose;
-import com.persagy.adm.diagram.core.DiagramBuilder;
+import com.persagy.adm.diagram.core.build.CalcContext;
+import com.persagy.adm.diagram.core.build.DiagramBuilder;
 
 import java.util.Objects;
 

+ 2 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/OrFilter.java

@@ -1,5 +1,7 @@
 package com.persagy.adm.diagram.core.model.logic;
 
+import com.persagy.adm.diagram.core.build.CalcContext;
+
 /**
  * or条件
  * @author zhaoyk

+ 8 - 19
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/logic/RelationFilter.java

@@ -3,10 +3,8 @@ package com.persagy.adm.diagram.core.model.logic;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.gson.annotations.Expose;
-import com.persagy.adm.diagram.core.model.EquipmentNode;
-import com.persagy.adm.diagram.core.model.base.Container;
-import com.persagy.adm.diagram.core.model.base.IComponent;
-import com.persagy.adm.diagram.core.model.template.MainPipe;
+import com.persagy.adm.diagram.core.build.CalcContext;
+import com.persagy.adm.diagram.core.model.base.IEquipHolder;
 import com.persagy.dmp.digital.entity.ObjectRelation;
 
 import java.util.ArrayList;
@@ -58,21 +56,12 @@ public class RelationFilter extends DataFilter {
 	private void initRelations(CalcContext context) {
 		List<String> dataIds = new ArrayList<>();
 		Object o = context.getComp(relObjId, relObjType);
-		if(o instanceof MainPipe) {
-			String dataId = getDataId(((MainPipe) o).getDataObject());
-			if(dataId != null) {
-				dataIds.add(dataId);
-			}
-		} else if(o instanceof Container) {
-			Container con = (Container) o;
-			if(con.isEquipmentBox()) {
-				for(IComponent comp : con.getChildren()) {
-					if(comp instanceof EquipmentNode) {
-						String dataId = getDataId(((EquipmentNode) comp).getDataObject());
-						if(dataId != null) {
-							dataIds.add(dataId);
-						}
-					}
+		if(o instanceof IEquipHolder) {
+			List<ObjectNode> matchedData = context.getDiagramBuilder().loadMatchedData((IEquipHolder) o);
+			for(ObjectNode obj : matchedData) {
+				String dataId = getDataId(obj);
+				if(dataId != null) {
+					dataIds.add(dataId);
 				}
 			}
 		}

+ 29 - 1
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/style/BaseStyle.java

@@ -18,7 +18,7 @@ public class BaseStyle {
 	 * 字体大小
 	 */
 	@Expose
-	protected int fontSize = 10;
+	protected int fontSize = 16;
 
 	/**
 	 * 字体颜色
@@ -27,6 +27,18 @@ public class BaseStyle {
 	protected String fontColor = "#000000";
 
 	/**
+	 * 字体粗细
+	 */
+	@Expose
+	protected int fontWeight = 600;
+
+	/**
+	 * 字体名称
+	 */
+	@Expose
+	protected String fontName;
+
+	/**
 	 * 预定义好的样式类Id
 	 */
 	@Expose
@@ -64,6 +76,22 @@ public class BaseStyle {
 		this.fontColor = fontColor;
 	}
 
+	public int getFontWeight() {
+		return fontWeight;
+	}
+
+	public void setFontWeight(int fontWeight) {
+		this.fontWeight = fontWeight;
+	}
+
+	public String getFontName() {
+		return fontName;
+	}
+
+	public void setFontName(String fontName) {
+		this.fontName = fontName;
+	}
+
 	public String getClassId() {
 		return classId;
 	}

+ 3 - 13
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/DiagramTemplate.java

@@ -276,8 +276,7 @@ public class DiagramTemplate {
 	}
 
 	public List<Container> getContainers() {
-		List<Container> list = new ArrayList<>();
-		getContainers(frame, list);
+		List<Container> list = frame.listContainers();
 
 		if(scatteredContainers != null) {
 			list.addAll(scatteredContainers);
@@ -286,19 +285,10 @@ public class DiagramTemplate {
 		return list;
 	}
 
-	private void getContainers(Container con, List<Container> list){
-		list.add(con);
-
-		if(con.getChildren() != null) {
-			for(IComponent comp : con.getChildren()) {
-				if (comp instanceof Container) {
-					getContainers((Container) comp, list);
-				}
-			}
-		}
+	public boolean isFrameContainer(Container container) {
+		return  container != null && FRAME_ID.equals(container.getId());
 	}
 
-
 	public static DiagramTemplate defaultTemplate() {
 		DiagramTemplate template = new DiagramTemplate();
 

+ 26 - 55
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/core/model/template/MainPipe.java

@@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.gson.annotations.Expose;
 import com.persagy.adm.diagram.core.model.AbstractLine;
 import com.persagy.adm.diagram.core.model.base.Container;
-import com.persagy.adm.diagram.core.model.base.IContainer;
 import com.persagy.adm.diagram.core.model.base.IEquipHolder;
 import com.persagy.adm.diagram.core.model.base.XY;
 import com.persagy.adm.diagram.core.model.logic.DataFilter;
@@ -72,10 +71,10 @@ public class MainPipe extends AbstractLine implements IEquipHolder {
 	private List<Container> relatedContainerList;
 
 	/**
-	 * 父容器对象,运行时
+	 * 适配的数据,运行时
 	 */
 	@JsonIgnore
-	private Container parentContainer;
+	private List matchedData;
 
 	public MainPipe() {
 		this.compType = TYPE;
@@ -89,66 +88,32 @@ public class MainPipe extends AbstractLine implements IEquipHolder {
 				if(con != null)
 					relatedContainerList.add(con);
 			}
-
-			calcParentContainer();
-		}
-	}
-
-	private void calcParentContainer(){
-		IContainer p = null;
-		for(Container con : relatedContainerList) {
-			if (p == null) {
-				p = con.getParent();
-			} else {
-				p = getCommonParent(p, con.getParent());
-				if(p == null){
-					break;
-				}
-			}
-		}
-		if(p instanceof Container && !DiagramTemplate.FRAME_ID.equals(p.getId())) {
-			parentContainer = (Container) p;
-			parentContainer.addChildMainPipe(this);
-		}
-	}
-
-	private IContainer getCommonParent(IContainer p1, IContainer p2){
-		IContainer cp = p1;
-		while (true){
-			IContainer tmp = p2;
-			while (true) {
-				if(cp == tmp){
-					return cp;
-				}
-				tmp = tmp.getParent();
-				if(tmp == null){
-					break;
-				}
-			}
-			cp = cp.getParent();
-			if(cp == null){
-				break;
-			}
 		}
-		return null;
 	}
 
 	public void resetRelatedCons() {
-		if(parentContainer != null) {
-			parentContainer.removeChildMainPipe(this);
-		}
-		parentContainer = null;
 		relatedContainerList = null;
 	}
 
 	public void parseLines(List<List<XY>> lines, DiagramTemplate template) {
-		List<Container> refContainers = relatedContainerList;
-		if(CollUtil.isEmpty(refContainers)) {
+		List<Container> refContainers;
+		if(CollUtil.isEmpty(relatedContainerList)) {
 			refContainers = template.getContainers();
+		} else {
+			refContainers = new ArrayList<>();
+			for(Container con : template.getContainers()) {
+				for(Container relCon : relatedContainerList) {
+					if(relCon == con || relCon.isParentOf(con)){
+						refContainers.add(con);
+						break;
+					}
+				}
+			}
 		}
+
 		List<ContainerRefPoint> allRefPoints = new ArrayList<>();
 		for(Container con : refContainers) {
-			if (!DiagramTemplate.FRAME_ID.equals(con.getId()) && !con.isAbsolutePosition()) {
+			if (!template.isFrameContainer(con) && !con.isAbsolutePosition()) {
 				allRefPoints.addAll(ContainerRefPoint.getRefPoints(con, con.locationToRoot()));
 			}
 		}
@@ -314,10 +279,6 @@ public class MainPipe extends AbstractLine implements IEquipHolder {
 		return relatedContainerList;
 	}
 
-	public Container getParentContainer() {
-		return parentContainer;
-	}
-
 	public List<List<XY>> getLocationPath() {
 		return locationPath;
 	}
@@ -334,4 +295,14 @@ public class MainPipe extends AbstractLine implements IEquipHolder {
 		this.dynTarget = dynTarget;
 	}
 
+	@Override
+	public <T> List<T> getMatchedData() {
+		return matchedData;
+	}
+
+	@Override
+	public <T> void setMatchedData(List<T> matchedData) {
+		this.matchedData = matchedData;
+	}
+
 }

+ 8 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/dao/DiagramMapper.java

@@ -64,4 +64,12 @@ public interface DiagramMapper extends BaseMapper<DiagramEntity> {
      */
     DiagramEntity getDiagram(String diagramId);
 
+    /**
+     * 判断系统图名称是否重复
+     *
+     * @param projectId 项目id
+     * @param name      系统图名称
+     * @return 是否重复
+     */
+    List<DiagramEntity> selectByName( String projectId, String name);
 }

+ 5 - 0
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/demo/DemoDataStrategy.java

@@ -423,4 +423,9 @@ public class DemoDataStrategy implements DataStrategy {
     public boolean updateName(String name, String id) {
         return false;
     }
+
+    @Override
+    public boolean judgeNameDuplicate(String name) {
+        return false;
+    }
 }

+ 10 - 5
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/DemoDiagramManager.java

@@ -2,12 +2,8 @@ package com.persagy.adm.diagram.manage;
 
 import cn.hutool.core.util.IdUtil;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.persagy.adm.diagram.core.ContentParser;
 import com.persagy.adm.diagram.core.DataStrategy;
-import com.persagy.adm.diagram.core.DiagramDataLoader;
 import com.persagy.adm.diagram.core.model.Diagram;
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
-import com.persagy.adm.diagram.core.util.MyObjectMapper;
 import com.persagy.adm.diagram.entity.DiagramType;
 import com.persagy.adm.diagram.frame.BdtpRequest;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -42,7 +38,7 @@ public class DemoDiagramManager {
 		List<DiagramType> types = dataStrategy.getDiagramTypes();
 		List<Diagram> diagrams = dataStrategy.getDiagrams(projectId, systemId, groupCode);
 		for(Diagram diagram : diagrams) {
-			manager.buildDiagram(diagram);
+			diagram.setTemplate(null); //减少传输数据量,并给前端标识
 		}
 
 		BdtpRequest req = BdtpRequest.getCurrent();
@@ -74,6 +70,15 @@ public class DemoDiagramManager {
 	}
 
 	/**
+	 * 获取系统图内容
+	 */
+	public Diagram getDiagram(String diagramId){
+		Diagram diagram = dataStrategy.getDiagram(diagramId);
+		manager.buildDiagram(diagram);
+		return diagram;
+	}
+
+	/**
 	 * 创建新的系统图
 	 */
 	public Diagram createDiagram(String name, String type, String projectId, String systemId, String groupCode){

+ 2 - 2
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/DiagramManager.java

@@ -3,9 +3,9 @@ package com.persagy.adm.diagram.manage;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.persagy.adm.diagram.core.ContentParser;
 import com.persagy.adm.diagram.core.DataStrategy;
-import com.persagy.adm.diagram.core.DiagramDataLoader;
+import com.persagy.adm.diagram.core.build.DiagramDataLoader;
 import com.persagy.adm.diagram.core.model.Diagram;
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
+import com.persagy.adm.diagram.core.build.CalcContext;
 import com.persagy.adm.diagram.core.util.MyObjectMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;

+ 5 - 2
adm-business/adm-diagram/src/main/java/com/persagy/adm/diagram/manage/TemplateManager.java

@@ -6,7 +6,10 @@ import cn.hutool.core.util.StrUtil;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.adm.diagram.core.ContentParser;
 import com.persagy.adm.diagram.core.DataStrategy;
-import com.persagy.adm.diagram.core.model.base.*;
+import com.persagy.adm.diagram.core.model.base.Container;
+import com.persagy.adm.diagram.core.model.base.IComponent;
+import com.persagy.adm.diagram.core.model.base.Layout;
+import com.persagy.adm.diagram.core.model.base.XY;
 import com.persagy.adm.diagram.core.model.logic.DataFilter;
 import com.persagy.adm.diagram.core.model.logic.DynGroup;
 import com.persagy.adm.diagram.core.model.logic.EquipPack;
@@ -201,7 +204,7 @@ public class TemplateManager {
         template.init();
 
         Container con = template.getContainerById(containerId);
-        IContainer parent = con.getParent();
+        Container parent = con.getParent();
         if (parent != null) {
             List<IComponent> list = parent.getChildren();
 

+ 7 - 0
adm-business/adm-diagram/src/main/resources/mapper/Diagram.xml

@@ -87,6 +87,13 @@
         </if>
     </select>
 
+    <select id="selectByName" resultMap="diagramBaseMap">
+        SELECT
+        <include refid="baseSql"/>
+        FROM diagram
+        WHERE project_id=#{projectId} AND name=#{name} AND valid = 1
+    </select>
+
 </mapper>
 
 

+ 9 - 9
adm-business/adm-middleware/src/main/java/com/persagy/proxy/migration/service/Impl/ObjectRelationMigration.java

@@ -320,15 +320,6 @@ public class ObjectRelationMigration extends MigrationAbstractServiceImpl<Object
         List<ObjectNode> objectNodeListAdm = JsonNodeUtils.toListNode(admRelations, null, null);
         Map<String,Object> admDefineMap = toEntityMap(objectNodeListAdm, ObjectRelation.class);
 
-        //差集 新增
-        Map<String,Object> doSubtractFromInsert = doSubtractAdd(admDefineMap, projectDefineMap);
-        if(!CollUtil.isEmpty(doSubtractFromInsert)){
-            List<ObjectRelation> insertData = toList(doSubtractFromInsert, admRelations);
-            DataMigrationResponse dataMigrationResponse = insertBatch(insertData, ObjectRelation.class, insertUrl);
-            //处理并保存日志
-            syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.CREATE.getCode()));
-        }
-
         //差集 删除
         Map<String,Object> doSubtractFromDelete = doSubtractDel(admDefineMap, projectDefineMap);
         if(!CollUtil.isEmpty(doSubtractFromDelete)){
@@ -340,6 +331,15 @@ public class ObjectRelationMigration extends MigrationAbstractServiceImpl<Object
             syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.DELETE.getCode()));
         }
 
+        //差集 新增
+        Map<String,Object> doSubtractFromInsert = doSubtractAdd(admDefineMap, projectDefineMap);
+        if(!CollUtil.isEmpty(doSubtractFromInsert)){
+            List<ObjectRelation> insertData = toList(doSubtractFromInsert, admRelations);
+            DataMigrationResponse dataMigrationResponse = insertBatch(insertData, ObjectRelation.class, insertUrl);
+            //处理并保存日志
+            syncDataList.addAll(processDataForLog(dataMigrationResponse, MigrationType.CREATE.getCode()));
+        }
+
         //交集更新
         Map<String,Object> intersectionUpdateFrom = doIntersectionGetFrom(admDefineMap, projectDefineMap);
         Map<String,Object> intersectionUpdateTo = doIntersectionGetTo(admDefineMap, projectDefineMap);

+ 7 - 6
adm-business/adm-server/src/main/java/com/persagy/adm/server/backstage/jobhandler/CommonTimeRuleJob.java

@@ -1,25 +1,26 @@
 package com.persagy.adm.server.backstage.jobhandler;
 
-import com.alibaba.fastjson.JSONObject;
 import com.persagy.adm.server.algorithm.constant.AdmServerConstant;
 import com.persagy.adm.server.backstage.service.impl.AdmAnalysisFacade;
-import com.persagy.common.util.HttpClientUtil.HttpResult;
-import com.persagy.common.utils.StringUtil;
-import com.persagy.dmp.common.constant.CommonConstant;
 import com.xxl.job.core.context.XxlJobHelper;
 import com.xxl.job.core.handler.annotation.XxlJob;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
 /**
- * 通用的时间规则调度
+ * 执行器类
  * @author : lijie
  * Update By 2022/1/24 20:32
  */
 @Slf4j
 @Component
 public class CommonTimeRuleJob {
-
+	/**
+	 * 模型解析任务
+	 * return : void
+	 * @author : lijie
+	 * Update By 2022/1/25 13:52
+	 */
     @XxlJob(AdmServerConstant.MODEL_ANALYSIS_TIME_RULE_JOB)
     public void modelAnalysisJobHandler() throws Exception {
         XxlJobHelper.log("modelAnalysisTimeRuleJob start ...");

+ 1 - 1
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/controller/AppController.java

@@ -73,7 +73,7 @@ public class AppController {
 		req.setUserId(TokenInterceptor.bossAuthUserThreadLocal.get().getId());
 		DownLoadData data;
 		if(StrUtil.isNotBlank(req.getBuildingId())) {
-			data = syncApp.downloadBuildingData(req.getGroupCode(), req.getProjectId(), req.getUserId(), req.getClientId(), req.getBuildingId(), req.getBdtpDownloadTs(), req.getAdmDownloadTs());
+			data = syncApp.downloadBuildingData(req);
 		}else {
 			throw new BusinessException(ResponseCode.A0400.getCode(),"建筑ID不能为空");
 		}

+ 1 - 1
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/entity/BuildingData.java

@@ -46,7 +46,7 @@ public class BuildingData extends DownLoadData {
 		long ts = getMaxTs(objects, relations);
 		if(ts > 0)
 			bdtpDownloadTs = ts;
-		ts = getMaxTs(pipes, jobSpace, file, qrCode, serveArea);
+		ts = getMaxTs(pipes, jobSpace, file, qrCode, serveArea,problems,admCads);
 		if(ts > 0)
 			admDownloadTs = ts;
 	}

+ 7 - 0
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/entity/DownLoadData.java

@@ -3,10 +3,12 @@ package com.persagy.adm.server.custom.entity;
 import cn.hutool.core.collection.CollUtil;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.adm.server.custom.entity.db.BaseAdmDataEntity;
+import com.persagy.dmp.common.model.entity.AuditableEntity;
 import com.persagy.dmp.common.model.entity.BaseEntity;
 import com.persagy.dmp.digital.entity.ObjectRelation;
 import lombok.Data;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -33,6 +35,11 @@ abstract public class DownLoadData {
 				} else if(data instanceof ObjectNode){
 					if(((ObjectNode) data).get("ts") != null)
 						ts = ((ObjectNode) data).get("ts").asLong();
+				} else if (data instanceof AuditableEntity){
+					Date ts1 = ((AuditableEntity) data).getTs();
+					if (ts1 != null){
+						ts = ts1.getTime();
+					}
 				} else if(data instanceof BaseEntity) {
 					if(((ObjectRelation) data).getTs() != null)
 						ts = ((ObjectRelation) data).getTs().getTime();

+ 2 - 1
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/ISyncApp.java

@@ -1,5 +1,6 @@
 package com.persagy.adm.server.custom.service;
 
+import com.persagy.adm.server.custom.common.AdmRequest;
 import com.persagy.adm.server.custom.dto.HasUpdateReq;
 import com.persagy.adm.server.custom.entity.*;
 
@@ -24,7 +25,7 @@ public interface ISyncApp {
 
 	BuildingData downloadBuildingData(String projectId, String buildingId, String uploadFlag, String lastDownloadTime);
 
-	BuildingData downloadBuildingData(String groupCode, String projectId, String userId, String clientId, String buildingId, Long bdtpDownloadTs, Long admDownloadTs);
+	BuildingData downloadBuildingData(AdmRequest admRequest);
 
 	ProjectData downloadProjectData(String groupCode, String projectId, String userId, String clientId, Long bdtpDownloadTs, Long admDownloadTs);
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 692 - 685
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/SyncAppImpl.java


+ 2 - 1
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/check_update/CheckUpdateChain.java

@@ -7,7 +7,7 @@ import org.springframework.stereotype.Component;
 import javax.annotation.PostConstruct;
 import java.util.List;
 @Component
-public class CheckUpdateChain{
+public class CheckUpdateChain implements CheckUpdate{
     @Autowired
     AdmProblemCheckUpdate admProblemCheck;
     @Autowired
@@ -57,6 +57,7 @@ public class CheckUpdateChain{
         checkUpdates.add(metaSpaceObjRelCheckUpdate);
     }
 
+    @Override
     public boolean doCheck(CheckUpdateContext hasUpdateReq) {
         for (CheckUpdate checkUpdate : checkUpdates){
             if (checkUpdate.doCheck(hasUpdateReq)){

+ 36 - 0
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillBuildingDataChain.java

@@ -0,0 +1,36 @@
+package com.persagy.adm.server.custom.service.impl.offline_data_download;
+
+import com.persagy.adm.server.custom.common.AdmRequest;
+import com.persagy.adm.server.custom.entity.BuildingData;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.compress.utils.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.List;
+
+@Component
+@Slf4j
+public class FillBuildingDataChain implements FillData<BuildingData>{
+    List<FillData<BuildingData>> fillList;
+
+    @Autowired
+    FillProblem fillProblem;
+    @Autowired
+    FillCad fillCad;
+
+    @PostConstruct
+    public void init(){
+        fillList = Lists.newArrayList();
+        // 问题数据
+        fillList.add(fillProblem);
+        // CAD图纸
+        fillList.add(fillCad);
+    }
+
+    @Override
+    public void fill(AdmRequest admRequest, BuildingData downLoadData) {
+        fillList.forEach(buildingDataFillData -> buildingDataFillData.fill(admRequest,downLoadData));
+    }
+}

+ 34 - 0
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillCad.java

@@ -0,0 +1,34 @@
+package com.persagy.adm.server.custom.service.impl.offline_data_download;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.persagy.adm.server.custom.common.AdmRequest;
+import com.persagy.adm.server.custom.dao.AdmCadMapper;
+import com.persagy.adm.server.custom.entity.BuildingData;
+import com.persagy.adm.server.custom.entity.db.AdmCad;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 离线数据下载-CAD图纸数据
+ */
+@Component
+@Slf4j
+public class FillCad implements FillData<BuildingData>{
+    @Autowired
+    AdmCadMapper admCadMapper;
+    @Override
+    public void fill(AdmRequest admRequest, BuildingData buildingData) {
+        log.info("填充CAD图纸数据开始");
+        Long admDownloadTs = buildingData.getAdmDownloadTs();
+        List<AdmCad> admCads = admCadMapper.selectList(new LambdaQueryWrapper<AdmCad>()
+                .eq(AdmCad::getGroupCode,admRequest.getGroupCode())
+                .eq(AdmCad::getProjectId,admRequest.getProjectId())
+                .eq(AdmCad::getBuildingId,admRequest.getBuildingId())
+                .gt(admDownloadTs != null && admDownloadTs != 0,AdmCad::getTs,admDownloadTs));
+        buildingData.setAdmCads(admCads);
+        log.info("填充CAD图纸数据开始");
+    }
+}

+ 9 - 0
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillData.java

@@ -0,0 +1,9 @@
+package com.persagy.adm.server.custom.service.impl.offline_data_download;
+
+import com.persagy.adm.server.custom.common.AdmRequest;
+import com.persagy.adm.server.custom.entity.DownLoadData;
+
+public interface FillData<T extends DownLoadData>{
+
+    void fill(AdmRequest admRequest, T t);
+}

+ 40 - 0
adm-business/adm-server/src/main/java/com/persagy/adm/server/custom/service/impl/offline_data_download/FillProblem.java

@@ -0,0 +1,40 @@
+package com.persagy.adm.server.custom.service.impl.offline_data_download;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.persagy.adm.server.custom.common.AdmRequest;
+import com.persagy.adm.server.custom.dao.AdmProblemMapper;
+import com.persagy.adm.server.custom.entity.BuildingData;
+import com.persagy.adm.server.custom.entity.db.AdmProblem;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 离线数据下载-核查问题数据
+ */
+@Component
+@Slf4j
+public class FillProblem implements FillData<BuildingData>{
+
+    @Autowired
+    AdmProblemMapper problemMapper;
+
+    @Override
+    public void fill(AdmRequest admRequest, BuildingData buildingData) {
+        log.info("填充任务数据开始");
+        String operator = admRequest.getUserId() + ":" + admRequest.getClientId();
+        // 问题相关数据
+        LambdaQueryWrapper<AdmProblem> queryWrapper = new LambdaQueryWrapper<AdmProblem>()
+                .eq(AdmProblem::getGroupCode, admRequest.getGroupCode())
+                .eq(AdmProblem::getProjectId, admRequest.getProjectId())
+                .eq(AdmProblem::getBuildingId, admRequest.getBuildingId())
+                .gt(admRequest.getAdmDownloadTs()!=null && admRequest.getAdmDownloadTs() != 0,AdmProblem::getTs, admRequest.getAdmDownloadTs())
+                .ne(StringUtils.isNotBlank(operator),AdmProblem::getModifier,operator);
+        List<AdmProblem> problems = problemMapper.selectList(queryWrapper);
+        buildingData.setProblems(problems);
+        log.info("填充任务结束");
+    }
+}