Bladeren bron

代码迁移:从adm-middleware应用迁移代码到该项目中

lijie 2 jaren geleden
bovenliggende
commit
47f8db4f74
100 gewijzigde bestanden met toevoegingen van 10148 en 5 verwijderingen
  1. 99 5
      adm-business/adm-middleware/pom.xml
  2. 25 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/annotations/CascadeColumn.java
  3. 77 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmCommonConstant.java
  4. 47 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmDictCategoryEnum.java
  5. 45 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmDictConstant.java
  6. 148 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmObjectInfoConstant.java
  7. 34 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmObjectType.java
  8. 143 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmRelationType.java
  9. 406 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmRelationTypeEnum.java
  10. 45 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/BusinessErrorRwdCode.java
  11. 25 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/FuncidCategory.java
  12. 21 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/GraphCodeEnum.java
  13. 111 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/ObjTypeMapping.java
  14. 24 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/RelCodeEnum.java
  15. 45 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/SpaceTypeEnum.java
  16. 572 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/handler/RelationReportHandler.java
  17. 305 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/handler/SpaceRelationInfoHandler.java
  18. 26 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/model/AdmBaseEntity.java
  19. 26 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/model/AdmPoint.java
  20. 25 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/model/TwicePointDTO.java
  21. 38 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmCountResponse.java
  22. 20 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmCreateRequest.java
  23. 49 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmCreateResponse.java
  24. 34 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmDCSQueryRequest.java
  25. 27 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmDictQueryCriteria.java
  26. 41 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmManualRelCalResponse.java
  27. 110 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmQueryCriteria.java
  28. 28 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmQueryGroup.java
  29. 91 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmResponse.java
  30. 20 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmUpDataFloorAndBuildingRequests.java
  31. 22 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmZoneEquipQueryRequest.java
  32. 85 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/IAdmBaseService.java
  33. 38 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/IAdmRelationService.java
  34. 542 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/impl/AbstractAdmBaseServiceImpl.java
  35. 76 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/impl/AdmRelationServiceImpl.java
  36. 173 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/RelationObjectContext.java
  37. 126 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AbstractRelationObject.java
  38. 355 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AbstractReportRelationObject.java
  39. 86 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AcAirNetworkDischargeRelationObject.java
  40. 86 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AcAirNetworkReturnRelationObject.java
  41. 84 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2BdRelationObject.java
  42. 97 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2FlRelationObject.java
  43. 89 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2ShRelationObject.java
  44. 106 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2SpRelationObject.java
  45. 104 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSp2BdRelationObject.java
  46. 107 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSp2FlRelationObject.java
  47. 110 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSp2SpRelationObject.java
  48. 73 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchSubsetBd2FlRelationObject.java
  49. 101 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ConvectionNetworkMixMechRelationObject.java
  50. 101 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ConvectionNetworkNaturalRelationObject.java
  51. 100 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ConvectionNetworkOnewayMechRelationObject.java
  52. 88 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/DeafultRelationObject.java
  53. 99 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerEqBackupRelationObject.java
  54. 98 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerEqNormalRelationObject.java
  55. 97 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerSyBackupRelationObject.java
  56. 98 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerSyNormalRelationObject.java
  57. 88 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechCtrlEqCtrlRelationObject.java
  58. 86 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechCtrlSyCtrlRelationObject.java
  59. 108 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchEq2BdRelationObject.java
  60. 109 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchEq2FlRelationObject.java
  61. 108 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchEq2ShRelationObject.java
  62. 90 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2BdRelationObject.java
  63. 99 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2FlRelationObject.java
  64. 90 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2ShRelationObject.java
  65. 107 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2SpRelationObject.java
  66. 100 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechInArchEq2BdRelationObject.java
  67. 95 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechInArchEq2FlRelationObject.java
  68. 90 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechInArchEq2SpRelationObject.java
  69. 102 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/RadiationNetworkConnectRelationObject.java
  70. 102 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/RadiationNetworkTransparentRelationObject.java
  71. 122 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/RelationObjectStrategy.java
  72. 99 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/SensorRelationshipSs2EqRelationObject.java
  73. 100 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/SensorRelationshipSs2SpRelationObject.java
  74. 99 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/SensorRelationshipSs2SyRelationObject.java
  75. 102 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/TrafficNetworkFFCloseRelationObject.java
  76. 102 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/TrafficNetworkFFOpenRelationObject.java
  77. 102 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/TrafficNetworkNormalRelationObject.java
  78. 38 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmContextUtil.java
  79. 231 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmEntityTransferUtil.java
  80. 183 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmExcelUtil.java
  81. 345 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmQueryCriteriaHelper.java
  82. 204 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/GeoToolsUtil.java
  83. 208 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/JSONEntityUtil.java
  84. 39 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/ObjectNameUtil.java
  85. 64 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmCalcSpecialController.java
  86. 71 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmManualRelCalController.java
  87. 53 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmMepSystemCalcController.java
  88. 50 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmModelRelController.java
  89. 318 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmRelCalController.java
  90. 27 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmManualRelCalRequest.java
  91. 26 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmManualRelationCalcDel.java
  92. 38 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmMepSourceTypeEntity.java
  93. 40 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmRelationAddRequest.java
  94. 33 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmCalcSpecialService.java
  95. 47 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmManualRelCalService.java
  96. 35 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmMepSystemCalcService.java
  97. 43 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmRelCalService.java
  98. 31 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/IAdmObjectRelationCalService.java
  99. 76 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/impl/AdmCalcSpecialServiceImpl.java
  100. 0 0
      adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/impl/AdmManualRelCalServiceImpl.java

+ 99 - 5
adm-business/adm-middleware/pom.xml

@@ -8,28 +8,122 @@
         <artifactId>adm-business</artifactId>
         <version>1.0.0</version>
     </parent>
-
     <groupId>com.persagy</groupId>
     <artifactId>adm-middleware</artifactId>
 
+    <repositories>
+        <repository>
+            <id>Persagy</id>
+            <name>persagy</name>
+            <url>http://47.93.132.139:8081/nexus/content/groups/public/</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+        <repository>
+            <id>persagy</id>
+            <name>releases Repository</name>
+            <url>http://47.93.132.139:8081/nexus/content/repositories/persagy/</url>
+            <layout>default</layout>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+
+        <repository>
+            <id>osgeo</id>
+            <name>Open Source Geospatial Foundation Repository</name>
+            <url>https://repo.osgeo.org/repository/release/</url>
+        </repository>
+    </repositories>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <easyexcel.version>2.2.8</easyexcel.version>
+    </properties>
     <dependencies>
         <!-- 配置中心(包含注册中心) -->
         <dependency>
             <groupId>com.persagy</groupId>
             <artifactId>integrated-config-client</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>xstream</artifactId>
+                    <groupId>com.thoughtworks.xstream</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- 阿里云扫描漏洞要求版本需>=1.4.18 -->
+        <dependency>
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+            <version>1.4.18</version>
         </dependency>
-        <!-- 项目启动 -->
         <dependency>
             <groupId>com.persagy</groupId>
-            <artifactId>dmp-server</artifactId>
+            <artifactId>dmp-digital-starter</artifactId>
         </dependency>
         <dependency>
             <groupId>com.persagy</groupId>
-            <artifactId>dmp-mybatis</artifactId>
+            <artifactId>dmp-server</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.persagy</groupId>
+                    <artifactId>dmp-auth</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>jsr311-api</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>${easyexcel.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>asm</artifactId>
+                    <groupId>org.ow2.asm</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>poi</artifactId>
+                    <groupId>org.apache.poi</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>poi-ooxml</artifactId>
+                    <groupId>org.apache.poi</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>poi-ooxml-schemas</artifactId>
+                    <groupId>org.apache.poi</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.geotools</groupId>
+            <artifactId>gt-main</artifactId>
+            <version>23.0</version>
         </dependency>
         <dependency>
             <groupId>com.persagy</groupId>
-            <artifactId>dmp-digital-starter</artifactId>
+            <artifactId>dmp-auth-starter</artifactId>
+            <version>1.0.0</version>
         </dependency>
     </dependencies>
 </project>

+ 25 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/annotations/CascadeColumn.java

@@ -0,0 +1,25 @@
+package com.persagy.proxy.adm.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 扩展属性
+ * @author Charlie Yu
+ * @data 2021-08-28
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+public @interface CascadeColumn {
+
+    /** 图编码 */
+    String graphCode() default "";
+    /** 边编码 */
+    String relCode() default "";
+    /** 边值 */
+    String relValue() default "";
+    /** 是否为查询to对象 */
+    boolean selectToObj() default true;
+}

+ 77 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmCommonConstant.java

@@ -0,0 +1,77 @@
+package com.persagy.proxy.adm.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * ADM 通用常量
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+public interface AdmCommonConstant {
+	/** ADM 边类型 -> 枚举类 */
+	static Map<String, AdmRelationTypeEnum> RELATION_TYPE_MAP = AdmRelationTypeEnum.getRelationTypeMap();
+	/** BDTP 图类型_边类型 -> 枚举类 */
+	static Map<String, AdmRelationTypeEnum> GRAPH_RELATION_TYPE_MAP = AdmRelationTypeEnum.getGraphRelTypeMap();
+	
+	/** 项目根路径*/
+	String SERVER_ROOT_PATH = System.getProperty("user.dir");
+	
+	String EMPTY = "";
+	
+    /** appId */
+    String APP_ID = "ADM";
+    
+    /** 默认的userId */
+    String USER_ID = "systemId";
+
+    /** 默认项目id */
+    String PROJECTID = "system";
+
+    /** 集团编码 header key*/
+    String GROUP_CODE_HEADER = "groupCode";
+
+    /** 项目ID header key*/
+    String PROJECT_ID_HEADER = "projectId";
+    
+    /** appID header key*/
+    String APP_ID_HEADER = "appId";
+    
+    /** userID header key*/
+    String USER_ID_HEADER = "userId";
+    
+    /** excel文件后缀*/
+    String EXCEL_SUFFIX_XLSX = ".xlsx";
+    
+    /** 连接符 ? */
+    String WHERE = "?";
+
+    /** 连接符 & */
+    String AND = "&";
+    
+    /** 连接符 _ */
+    String UNDERLINE = "_";
+    
+    /** 连接符 - */
+    String LINE_THROUGH = "-";
+    
+    /** 连接符 → */
+    String RIGHT_ARROW = "→";
+    
+    /** 有效标示*/
+    String VALID = "valid";
+
+    /** 楼层标高 */
+    String FLOOR_ELEVATION = "floorElevation";
+    
+    /** 识别码类型 */
+	Map<String, String> codeColMap = new HashMap<String,String>(){
+		private static final long serialVersionUID = 1L;
+		{
+            put("EquipLocalID", "localId");
+            put("ClassCode", "classCode");
+            put("DigitalDeliveryID", "digitalDeliveryID");
+        }
+    };
+
+}

+ 47 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmDictCategoryEnum.java

@@ -0,0 +1,47 @@
+package com.persagy.proxy.adm.constant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @ClassName DtTypeEnum
+ * @Description: 数据中台类型定义
+ * @Author linhuili
+ * @Date 2021/8/9 16:07
+ * @Version V1.0
+ **/
+public enum AdmDictCategoryEnum {
+    PROJECT("project", "项目"),
+    BUILDING("building", "建筑"),
+    FLOOR("floor", "楼层"),
+    EQUIPMENT("equipment", "设备"),
+    COMPONENT("component", "组件"),
+    SYSTEM("system", "系统"),
+    MAJOR("major", "专业"),
+    SPACE("space", "空间"),
+    PROPRTY("property", "资产"),
+    EQUIPMENT_AND_COMPONENT("equipmentAndComponent", "设备和部件"),
+
+    MAJOR_SYSTEM("majorSystem", "专业下的系统"),
+    SYSTEM_EQUIP("systemEquip", "系统下的设备类"),
+    MAJOR_SYSTEM_EQUIP("majorSystemEquip", "专业下的系统,系统下的设备"),
+
+    EQUIPMENT_COMPONENT("equipmentComponent", "设备类型以及对应的部件"),
+    MAJOR_EQUIPMENT("majorEquipment", "专业下的设备类");
+
+    private String value;
+    private String desc;
+
+    AdmDictCategoryEnum(String value, String desc) {
+        this.value = value;
+        this.desc = desc;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 45 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmDictConstant.java

@@ -0,0 +1,45 @@
+package com.persagy.proxy.adm.constant;
+
+import cn.hutool.core.collection.CollUtil;
+
+import java.util.Set;
+
+/**
+ * @ClassName AdmDictConstant
+ * @Description: 字典常量
+ * @Author linhuili
+ * @Date 2021/9/1 10:07
+ * @Version V1.0
+ **/
+public interface AdmDictConstant {
+
+    /** 类型编码 */
+    String CLASS_CODE ="classCode";
+
+    /** 信息点infos前缀 */
+    String INFOS_EX ="infos.";
+
+    /** 一级标签名称-基本信息 */
+    String FIRST_BASE_TAG ="基本信息";
+
+    /** 一级标签历史名称-基础参数 */
+    String HIS_FIRST_BASE_TAG="基础参数";
+    /** 一级标签历史名称-基本参数 */
+    String HIS_FIRST_BASE_TAG_TWO="基本参数";
+    /** 高度 */
+    String HEIGHT="height";
+    /** 图片 */
+    String PIC="pic";
+    /** 表的信息点 */
+    Set<String> TABLE_INFOS= CollUtil.newHashSet("id","name","localId","localName",
+            "qRCodePic","defaultQRCode","rFID","cADID","bimId","bimTypeId","bimLocation","bimFamilyName",
+            "bimFamilySymbol","equipSerial","modelId","note","introduction","businessFloorNum","officeFloorNum",
+            "shaftSequenceId","outline","buildQRCode","bimIdPre","floorSequenceId","floorSequenceID",
+            "permanentPeopleNum","floorIdentity","depth","width","buildArea","netArea","height","intro",
+            "ratedCoolingP","ratedHeatingP","acType","zoneOrientation","roomFuncType","roomSerial",
+            "projRoomFuncType","ratedLightP","zoneType","tenantType","tenant","elecCap","pollutionDegree",
+            "groupCode","projectId","objType","classCode","grouping","virtualCodes","createApp","updateApp",
+            "creator","creationTime","modifier","modifiedTime","valid");
+    Set<String> SPECIAL_INFOS=CollUtil.newHashSet("cADID","rFID");
+
+}

+ 148 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmObjectInfoConstant.java

@@ -0,0 +1,148 @@
+package com.persagy.proxy.adm.constant;
+
+import cn.hutool.core.collection.CollUtil;
+
+import java.util.Set;
+
+/**
+ * 对象类型
+ * @author Charlie Yu
+ * @date 2021-06-25
+ */
+public interface AdmObjectInfoConstant {
+    /** CADID图纸编码*/
+    String CADID = "cadId";
+    /** CADID图纸编码*/
+    String CADID_INFO = "cADID";
+    /**名称*/
+    String NAME = "name";
+    /**ID*/
+    String ID = "ID";
+    /**本地编码*/
+    String LOCAL_ID = "localId";
+    /**本地名称*/
+    String LOCAL_NAME = "localName";
+    /**模型id*/
+    String MODEL_ID = "modelId";
+    /**是否检查classCode使用的classCodes列表*/
+    Set<String> CHECK_CLASS_CODES= CollUtil.newHashSet("SETDLS","SETDHS","SETDLO","SETDLT");
+    /**是否检查传感器使用的传感器类型*/
+    Set<String> CHECK_SENSOR_CODES= CollUtil.newHashSet("SPVSCM","FFEALS","FFFPSE","FFFASE","SPIASE",
+            "WEGMCM","WEOFCM","WEGMPD","FFGASE","OTSESP","OTSESD","OTSETP","OTSEVD","OTSEPS","OTSEPF","OTSERH",
+            "OTSEIP","OTSEIL","OTSEHT","OTSECB","OTSECT","OTSEEE","OTSEDP","OTSEFL");
+    /**重复检查主对象的type与从对象的type是否重复*/
+    Set<String> CHECK_SPECIAL_TYPES= CollUtil.newHashSet("sp2sp_RadiationNetwork_2","sp2sp_RadiationNetwork_1",
+            "sp2sp_ConvectionNetwork_2","sp2sp_ConvectionNetwork_3","sp2sp_ConvectionNetwork_1",
+            "sp2sp_TrafficNetwork_3","sp2sp_TrafficNetwork_2","sp2sp_TrafficNetwork_1");
+
+    Set<String> SOURCE_FLAG_FALSE=CollUtil.newHashSet("eq2eq_GasNetwork_2", "eq2fl",
+            "sp2sp_SpaceNeighborhood_3", "eq2sp_in", "sh2bd", "sp2sp_SpaceNeighborhood_2", "sp2sp_SpaceNeighborhood_5",
+            "eq2sp_in", "sy2sh_for", "eq2sp_for", "eq2sp_in", "eq2sy", "eq2eq_ChillWaterLoop_4", "eq2bd_for",
+            "sp2sp_SpaceNeighborhood_1", "eq2eq_ValveRelationship_vv2eq", "eq2eq_SensorNetwork_1", "eq2sp_in",
+            "eq2eq_CoolingWaterLoop_3", "eq2fl_for", "eq2eq_EquipPower_3", "eq2sp_for", "eq2eq_ACAirNetwork_3",
+            "eq2sp_for", "eq2eq_SupplyWaterNetwork_2", "eq2sy_ControlRelation_2", "eq2sp_in", "eq2sp_in",
+            "eq2eq_HeatWaterLoop_4", "bd2sp", "sp2sp_TrafficNetwork_2", "fl2sp", "Sh2Sp_ArchSubset", "eq2sp_for",
+            "sp2sp_ConvectionNetwork_2", "sy2sh", "sy2bd_MechInArch", "eq2eq_DHWNetwork_2", "eq2sp_for",
+            "sp2sp_ConvectionNetwork_3", "eq2eq_ControlEquipNetwork", "sy2fl_for", "eq2eq_RecycleWaterNetwork_2",
+            "eq2sy_SensorRelationship_ss2sy", "sp2sp_SpaceNeighborhood_4", "eq2sp_in", "eq2sp_in", "pe2fl",
+            "eq2sp_in", "eq2sp_for", "sh2sh", "eq2eq_LUDistribution_1", "eq2eq_HUDistribution_2",
+            "eq2eq_DrainingWaterNetwork_2", "fl2fl", "eq2eq_LUDistribution_2", "eq2sp_for",
+            "eq2eq_DrinkingWaterNetwork_2", "eq2sp_SensorRelationship_ss2sp", "eq2sp_in", "tn2sp",
+            "eq2eq_ChillWaterLoop_3", "eq2eq_GasNetwork_1", "sy2bd_for", "eq2eq_EquipPower_4", "eq2sp_for",
+            "eq2eq_CoolingWaterLoop_4", "eq2sp_in", "eq2sh", "pe2bd", "eq2sh_for", "eq2eq_EquipPower_2",
+            "eq2sy_ValveRelationship_vv2sy", "sp2sp_TrafficNetwork_1", "eq2sp_in", "eq2sp_in", "eq2sp_in",
+            "eq2sp_in", "sp2sp_RadiationNetwork_2", "eq2eq_FireWaterNetwork_2", "sp2sp_ConvectionNetwork_1",
+            "sp2sp_TrafficNetwork_3", "eq2eq_EquipPower_1", "sy2fl", "eq2sp_for", "eq2eq_SensorRelationship_ss2eq",
+            "eq2sp_for", "pe2sh", "eq2eq_ControlRelation_1", "sp2sp_RadiationNetwork_1", "sh2sp",
+            "eq2eq_HeatWaterLoop_3", "bd2bd_ArchForArch", "sh2fl_ArchForArch", "sh2sh_ArchForArch",
+            "sh2sp_ArchForArch", "sp2bd_ArchForArch", "sp2fl_ArchForArch", "sp2sh_ArchForArch", "sp2sp_ArchForArch",
+            "bd2fl_ArchForArch", "bd2sh_ArchForArch", "bd2sh_ArchSubset", "bd2sp_ArchForArch", "fl2bd_ArchForArch",
+            "fl2fl_ArchForArch", "fl2sh_ArchForArch", "fl2sp_ArchForArch", "sh2bd_ArchForArch", "sy2sp",
+            "syeq2bd", "sy2sp_for", "eq2sp_for", "eq2sp_for", "eq2sp_for", "eq2sp_for", "eq2sp_for",
+            "eq2eq_VentNetwork_3", "eq2eq_HUDistribution_1");
+
+    Set<String> SOURCE_FLAG_TRUE=CollUtil.newHashSet("eq2eq_DrainingWaterNetwork_1",
+            "eq2eq_ACAirNetwork_2", "eq2eq_CondWaterNetwork_1", "eq2eq_HeatWaterLoop_1", "eq2eq_DHWNetwork_1",
+            "eq2eq_RecycleWaterNetwork_1", "eq2eq_FireVentNetwork_1", "eq2eq_FireWaterNetwork_1", "eq2eq_VRFNetwork_1",
+            "eq2eq_ChillWaterLoop_2", "eq2eqFreshAirNetwork_1", "eq2eq_ChillWaterLoop_1",
+            "eq2eq_DrinkingWaterNetwork_2", "eq2eq_CoolingWaterLoop_2", "eq2eq_VentNetwork_1", "eq2eq_HeatWaterLoop_2",
+            "eq2eq_CoolingWaterLoop_1", "eq2eq_ACAirNetwork_1", "eq2eq_SupplyWaterNetwork_1");
+
+    Set<String> AUTOMATIC_FLAG_FALSE=CollUtil.newHashSet("eq2eq_GasNetwork_2", "sp2sp_SpaceNeighborhood_3", "sp2sp_SpaceNeighborhood_2",
+            "sy2sh_for", "eq2sp_for", "eq2sy", "eq2eq_ChillWaterLoop_4", "eq2bd_for", "sp2sp_SpaceNeighborhood_1",
+            "eq2eq_ValveRelationship_vv2eq", "eq2eq_SensorNetwork_1", "eq2eq_CoolingWaterLoop_3", "eq2fl_for",
+            "eq2eq_EquipPower_3", "eq2sp_for", "eq2eq_SupplyWaterNetwork_2", "eq2sy_ControlRelation_2",
+            "sp2sp_TrafficNetwork_2", "Sh2Sp_ArchSubset", "eq2sp_for", "sp2sp_ConvectionNetwork_2",
+            "sy2bd_MechInArch", "eq2eq_DHWNetwork_2", "eq2sp_for", "sp2sp_ConvectionNetwork_3",
+            "eq2eq_ControlEquipNetwork", "sy2fl_for", "eq2eq_RecycleWaterNetwork_2", "eq2sy_SensorRelationship_ss2sy",
+            "sp2sp_SpaceNeighborhood_4", "eq2sp_for", "eq2eq_LUDistribution_1", "eq2eq_HUDistribution_2",
+            "eq2eq_DrainingWaterNetwork_2", "eq2eq_LUDistribution_2", "eq2sp_for", "eq2eq_DrinkingWaterNetwork_2",
+            "tn2sp", "eq2eq_ChillWaterLoop_3", "eq2eq_GasNetwork_1", "sy2bd_for", "eq2eq_EquipPower_4", "eq2sp_for",
+            "eq2eq_CoolingWaterLoop_4", "eq2sh_for", "eq2eq_EquipPower_2", "eq2sy_ValveRelationship_vv2sy",
+            "sp2sp_RadiationNetwork_2", "eq2eq_FireWaterNetwork_2", "sp2sp_TrafficNetwork_3", "eq2eq_EquipPower_1",
+            "eq2eq_SensorRelationship_ss2eq", "eq2sp_for", "eq2eq_ControlRelation_1", "sh2sp", "eq2eq_HeatWaterLoop_3",
+            "bd2bd_ArchForArch", "sh2fl_ArchForArch", "sh2sh_ArchForArch", "sh2sp_ArchForArch", "sp2bd_ArchForArch",
+            "sp2fl_ArchForArch", "sp2sh_ArchForArch", "sp2sp_ArchForArch", "bd2fl_ArchForArch", "bd2sh_ArchForArch",
+            "bd2sh_ArchSubset", "bd2sp_ArchForArch", "fl2bd_ArchForArch", "fl2fl_ArchForArch", "fl2sh_ArchForArch",
+            "fl2sp_ArchForArch", "sh2bd_ArchForArch", "sy2sp_for", "eq2sp_for", "eq2sp_for", "eq2sp_for",
+            "eq2sp_for", "eq2sp_for", "eq2eq_VentNetwork_3", "eq2eq_HUDistribution_1");
+
+    Set<String> AUTOMATIC_FLAG_TRUE=CollUtil.newHashSet("eq2fl", "eq2sp_in", "sh2bd", "sp2sp_SpaceNeighborhood_5",
+            "eq2sp_in", "eq2eq_DrainingWaterNetwork_1", "eq2sp_in", "eq2eq_ACAirNetwork_2",
+            "eq2eq_CondWaterNetwork_1", "pe2sp", "eq2eq_VentNetwork_2", "eq2sp_in", "eq2sp_for",
+            "eq2eq_ACAirNetwork_3", "eq2sp_in", "eq2sp_in", "eq2eq_HeatWaterLoop_4", "bd2sp", "fl2sp",
+            "sy2sh", "eq2eq_HeatWaterLoop_1", "eq2eq_DHWNetwork_1", "eq2sp_in", "eq2sp_in", "pe2fl",
+            "eq2eq_RecycleWaterNetwork_1", "eq2sp_in", "sh2sh", "eq2eq_FireVentNetwork_1", "eq2eq_FireWaterNetwork_1",
+            "fl2fl", "eq2eq_VRFNetwork_1", "eq2sp_SensorRelationship_ss2sp", "eq2sp_in", "eq2eq_ChillWaterLoop_2",
+            "eq2eqFreshAirNetwork_1", "eq2sp_in", "eq2sh", "eq2eq_ChillWaterLoop_1", "eq2eq_DrinkingWaterNetwork_2",
+            "pe2bd", "eq2eq_CoolingWaterLoop_2", "sp2sp_TrafficNetwork_1", "eq2sp_in", "eq2sp_in", "eq2sp_in",
+            "eq2sp_in", "sp2sp_ConvectionNetwork_1", "eq2eq_VentNetwork_1", "sy2fl", "eq2sp_for", "pe2sh",
+            "eq2eq_HeatWaterLoop_2", "sp2sp_RadiationNetwork_1", "eq2eq_CoolingWaterLoop_1", "sy2sp",
+            "syeq2bd", "eq2eq_ACAirNetwork_1", "eq2eq_SupplyWaterNetwork_1");
+
+    Set<String> MANUAL_FLAG_TWO = CollUtil.newHashSet("eq2fl", "eq2sp_in", "sh2bd", "eq2sp_in", "eq2sp_for",
+            "eq2sp_in", "eq2sy", "eq2sp_in", "eq2sp_for", "eq2sp_for", "eq2sp_in", "eq2sp_in", "bd2sp", "fl2sp",
+            "Sh2Sp_ArchSubset", "eq2sp_for", "sy2sh", "sy2bd_MechInArch", "eq2sp_for", "eq2sp_in", "eq2sp_in",
+            "pe2fl", "eq2sp_in", "eq2sp_for", "sh2sh", "fl2fl", "eq2sp_for", "eq2sp_in", "tn2sp", "eq2sp_for",
+            "eq2sp_in", "eq2sh", "pe2bd", "eq2sp_in", "eq2sp_in", "eq2sp_in", "eq2sp_in", "sy2fl", "eq2sp_for",
+            "eq2sp_for", "sh2sp", "bd2sh_ArchSubset", "sy2sp", "syeq2bd", "eq2sp_for", "eq2sp_for", "eq2sp_for",
+            "eq2sp_for", "eq2sp_for");
+
+    Set<String> MANUAL_FLAG_THREE = CollUtil.newHashSet("eq2eq_GasNetwork_2", "sp2sp_SpaceNeighborhood_3",
+            "sp2sp_SpaceNeighborhood_2", "sp2sp_SpaceNeighborhood_5", "sy2sh_for", "eq2eq_DrainingWaterNetwork_1",
+            "eq2eq_ACAirNetwork_2", "eq2eq_ChillWaterLoop_4", "eq2bd_for", "eq2eq_CondWaterNetwork_1",
+            "sp2sp_SpaceNeighborhood_1", "eq2eq_ValveRelationship_vv2eq", "pe2sp", "eq2eq_VentNetwork_2",
+            "eq2eq_SensorNetwork_1", "eq2eq_CoolingWaterLoop_3", "eq2fl_for", "eq2eq_EquipPower_3",
+            "eq2eq_ACAirNetwork_3", "eq2eq_SupplyWaterNetwork_2", "eq2sy_ControlRelation_2", "eq2eq_HeatWaterLoop_4",
+            "sp2sp_TrafficNetwork_2", "sp2sp_ConvectionNetwork_2", "eq2eq_DHWNetwork_2", "eq2eq_HeatWaterLoop_1",
+            "sp2sp_ConvectionNetwork_3", "eq2eq_ControlEquipNetwork", "sy2fl_for", "eq2eq_DHWNetwork_1",
+            "eq2eq_RecycleWaterNetwork_2", "eq2sy_SensorRelationship_ss2sy", "sp2sp_SpaceNeighborhood_4",
+            "eq2eq_RecycleWaterNetwork_1", "eq2eq_LUDistribution_1", "eq2eq_FireVentNetwork_1",
+            "eq2eq_FireWaterNetwork_1", "eq2eq_HUDistribution_2", "eq2eq_DrainingWaterNetwork_2",
+            "eq2eq_VRFNetwork_1", "eq2eq_LUDistribution_2", "eq2eq_DrinkingWaterNetwork_2",
+            "eq2sp_SensorRelationship_ss2sp", "eq2eq_ChillWaterLoop_3", "eq2eq_ChillWaterLoop_2",
+            "eq2eq_GasNetwork_1", "sy2bd_for", "eq2eqFreshAirNetwork_1", "eq2eq_EquipPower_4",
+            "eq2eq_CoolingWaterLoop_4", "eq2eq_ChillWaterLoop_1", "eq2eq_DrinkingWaterNetwork_2", "eq2sh_for",
+            "eq2eq_EquipPower_2", "eq2eq_CoolingWaterLoop_2", "eq2sy_ValveRelationship_vv2sy", "sp2sp_TrafficNetwork_1",
+            "sp2sp_RadiationNetwork_2", "eq2eq_FireWaterNetwork_2", "sp2sp_ConvectionNetwork_1", "eq2eq_VentNetwork_1",
+            "sp2sp_TrafficNetwork_3", "eq2eq_EquipPower_1", "eq2eq_SensorRelationship_ss2eq", "pe2sh",
+            "eq2eq_HeatWaterLoop_2", "eq2eq_ControlRelation_1", "sp2sp_RadiationNetwork_1", "eq2eq_HeatWaterLoop_3",
+            "eq2eq_CoolingWaterLoop_1", "bd2bd_ArchForArch", "sh2fl_ArchForArch", "sh2sh_ArchForArch",
+            "sh2sp_ArchForArch", "sp2bd_ArchForArch", "sp2fl_ArchForArch", "sp2sh_ArchForArch", "sp2sp_ArchForArch",
+            "bd2fl_ArchForArch", "bd2sh_ArchForArch", "bd2sp_ArchForArch", "fl2bd_ArchForArch", "fl2fl_ArchForArch",
+            "fl2sh_ArchForArch", "fl2sp_ArchForArch", "sh2bd_ArchForArch", "sy2sp_for", "eq2eq_ACAirNetwork_1",
+            "eq2eq_SupplyWaterNetwork_1", "eq2eq_VentNetwork_3", "eq2eq_HUDistribution_1");
+    /**系统类型,风系统1,水系统0*/
+    Set<String> SYSTEM_TYPE_FALSE = CollUtil.newHashSet("eq2eq_GasNetwork_2", "eq2eq_DrainingWaterNetwork_1",
+            "eq2eq_CondWaterNetwork_1", "eq2eq_CoolingWaterLoop_3", "eq2eq_SupplyWaterNetwork_2",
+            "eq2eq_HeatWaterLoop_4", "eq2eq_DHWNetwork_2", "eq2eq_HeatWaterLoop_1", "eq2eq_DHWNetwork_1",
+            "eq2eq_RecycleWaterNetwork_2", "eq2eq_RecycleWaterNetwork_1", "eq2eq_FireWaterNetwork_1",
+            "eq2eq_DrainingWaterNetwork_2", "eq2eq_VRFNetwork_1", "eq2eq_DrinkingWaterNetwork_2",
+            "eq2eq_ChillWaterLoop_3", "eq2eq_ChillWaterLoop_2", "eq2eq_GasNetwork_1", "eq2eq_CoolingWaterLoop_4",
+            "eq2eq_ChillWaterLoop_1", "eq2eq_DrinkingWaterNetwork_2", "eq2eq_CoolingWaterLoop_2",
+            "eq2eq_FireWaterNetwork_2", "eq2eq_HeatWaterLoop_2", "eq2eq_HeatWaterLoop_3",
+            "eq2eq_CoolingWaterLoop_1", "eq2eq_SupplyWaterNetwork_1");
+    /**系统类型,风系统1,水系统0*/
+    Set<String> SYSTEM_TYPE_TRUE = CollUtil.newHashSet("eq2eq_VentNetwork_2", "eq2eq_ACAirNetwork_3",
+            "eq2eq_FireVentNetwork_1", "eq2eq_VentNetwork_1", "eq2eq_ACAirNetwork_1", "eq2eq_VentNetwork_3");
+}

+ 34 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmObjectType.java

@@ -0,0 +1,34 @@
+package com.persagy.proxy.adm.constant;
+
+import lombok.Getter;
+
+/**
+ * 对象类型
+ * @author Charlie Yu
+ * @date 2021-06-25
+ */
+@Getter
+public enum AdmObjectType {
+    /** 对象类型 */
+    PROJECT("project", "项目"),
+    BUILDING("building", "楼"),
+    FLOOR("floor", "楼层"),
+    SPACE("space", "空间"),
+    SYSTEM("system", "系统"),
+    EQUIPMENT("equipment", "设备"),
+    EQUIPMENT_SHORT("Eq", "设备"),
+    SHAFT("shaft", "竖井"),
+    COMPONENT("component", "部件"),
+    VIRTUAL("virtual", "虚拟对象"),
+    PROPERTY("property", "资产"),
+    TOOL("tool", "工具"),
+    MATERIAL("material", "耗材");
+
+    private String index;
+    private String name;
+
+    AdmObjectType(String index, String name) {
+        this.index = index;
+        this.name = name;
+    }
+}

+ 143 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmRelationType.java

@@ -0,0 +1,143 @@
+package com.persagy.proxy.adm.constant;
+
+/**
+ * BDTP中台图类型编码和边类型编码的组合名称
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:55:09
+ */
+public interface AdmRelationType {
+
+	/** 默认的处理类 */
+	String DEFAULT_RELATION_OBJECT = "deafultRelationObject";
+	
+	/** MECHINARCH_EQ2BD  设备所在建筑*/
+	String MECHINARCH_EQ2BD = "MechInArch_Eq2Bd";
+	
+	/** MECHINARCH_EQ2FL  设备所在楼层*/
+	String MECHINARCH_EQ2FL = "MechInArch_Eq2Fl";
+	
+	/** MECHINARCH_EQ2SH  设备所在竖井*/
+	String MECHINARCH_EQ2SH = "MechInArch_Eq2Sh";
+	
+	/** MECHINARCH_EQ2BD  设备所在空间*/
+	String MECHINARCH_EQ2SP = "MechInArch_Eq2Sp";
+
+	
+	
+	/** MECHFORARCH_EQ2BD  设备服务于建筑*/
+	String MECHFORARCH_EQ2BD = "MechForArch_Eq2Bd";
+	
+	/** MECHFORARCH_EQ2FL  设备服务于楼层*/
+	String MECHFORARCH_EQ2FL = "MechForArch_Eq2Fl";
+	
+	/** MECHFORARCH_EQ2SH  设备服务于竖井*/
+	String MECHFORARCH_EQ2SH = "MechForArch_Eq2Sh";
+	
+	/** MECHFORARCH_SY2BD  系统服务于建筑*/
+	String MECHFORARCH_SY2BD = "MechForArch_Sy2Bd";
+	
+	/** MECHFORARCH_SY2FL  系统服务于楼层*/
+	String MECHFORARCH_SY2FL = "MechForArch_Sy2Fl";
+	
+	/** MECHFORARCH_SY2SH  系统服务于竖井*/
+	String MECHFORARCH_SY2SH = "MechForArch_Sy2Sh";
+	
+	/** MECHFORARCH_SY2SP  系统服务于空间*/
+	String MECHFORARCH_SY2SP = "MechForArch_Sy2Sp";
+	
+	
+	
+	/** ARCHSUBSET_BD2FL  建筑下的楼层*/
+	String ARCHSUBSET_BD2FL = "ArchSubset_Bd2Fl";
+	
+	
+	
+	/** ARCHFORARCH_SH2BD  竖井服务于建筑*/
+	String ARCHFORARCH_SH2BD = "ArchForArch_Sh2Bd";
+	
+	/** ARCHFORARCH_SH2FL  竖井服务于楼层*/
+	String ARCHFORARCH_SH2FL = "ArchForArch_Sh2Fl";
+	
+	/** ARCHFORARCH_SH2SH  竖井服务于竖井*/
+	String ARCHFORARCH_SH2SH = "ArchForArch_Sh2Sh";
+	
+	/** ARCHFORARCH_SH2SP  竖井服务于空间*/
+	String ARCHFORARCH_SH2SP = "ArchForArch_Sh2Sp";
+	
+	/** ARCHFORARCH_SP2BD  空间服务于建筑*/
+	String ARCHFORARCH_SP2BD = "ArchForArch_Sp2Bd";
+	
+	/** ARCHFORARCH_SP2FL  空间服务于楼层*/
+	String ARCHFORARCH_SP2FL = "ArchForArch_Sp2Fl";
+	/** ARCHFORARCH_SP2SP  空间服务于空间*/
+	String ARCHFORARCH_SP2SP = "ArchForArch_Sp2Sp";
+
+	/** ACAirNetwork_Discharge  空调排风*/
+	String ACAIRNETWORK_DISCHARGE = "ACAirNetwork_Discharge";
+	/** ACAirNetwork_Return  空调回风*/
+	String ACAIRNETWORK_RETURN = "ACAirNetwork_Return";
+
+	
+	
+	/** EQUIPPOWER_EQBACKUP  设备备用电源-低/高压开关柜→用电设备*/
+	String EQUIPPOWER_EQBACKUP = "MechPower_EqBackup";
+	
+	/** EQUIPPOWER_EQNORMAL  设备常规电源-低/高压开关柜→用电设备*/
+	String EQUIPPOWER_EQNORMAL = "MechPower_EqNormal";
+	
+	/** EQUIPPOWER_SYBACKUP  系统备用电源-低/高压开关柜→用电设备*/
+	String EQUIPPOWER_SYBACKUP = "MechPower_SyBackup";
+	
+	/** EQUIPPOWER_SYNORMAL  系统常规电源-低/高压开关柜→用电设备*/
+	String EQUIPPOWER_SYNORMAL = "MechPower_SyNormal";
+
+	/** MechCtrl_EqCtrl  设备控制关系-控制设备→被控设备*/
+	String MECHCTRL_EQCTRL = "MechCtrl_EqCtrl";
+	/** MechCtrl_SyCtrl  系统控制关系-控制设备→被控系统*/
+	String MECHCTRL_SYCTRL = "MechCtrl_SyCtrl";
+
+	
+	
+	/** RADIATIONNETWORK_TRANSPARENT  光照透明隔断-空间-空间*/
+	String RADIATIONNETWORK_TRANSPARENT = "RadiationNetwork_Transparent";
+	
+	/** RADIATIONNETWORK_CONNECT  光照连通-空间-空间*/
+	String RADIATIONNETWORK_CONNECT = "RadiationNetwork_Connect";
+	
+	
+	
+	/** TRAFFICNETWORK_FFCLOSE  消防常关交通-空间-空间*/
+	String TRAFFICNETWORK_FFCLOSE = "TrafficNetwork_FFClose";
+	
+	/** TRAFFICNETWORK_FFOPEN  消防常开交通-业务空间-业务空间*/
+	String TRAFFICNETWORK_FFOPEN = "TrafficNetwork_FFOpen";
+
+	/** TRAFFICNETWORK_NORMAL  普通交通-空间-空间*/
+	String TRAFFICNETWORK_NORMAL = "TrafficNetwork_Normal";
+	
+	
+	
+	/** CONVECTIONNETWORK_MIXMECH  空气混合机械通风-空间-空间*/
+	String CONVECTIONNETWORK_MIXMECH = "ConvectionNetwork_MixMech";
+
+	/** CONVECTIONNETWORK_NATURAL  空气自然对流-空间-空间*/
+	String CONVECTIONNETWORK_NATURAL = "ConvectionNetwork_Natural";
+	
+	/** CONVECTIONNETWORK_ONEWAYMECH  空气单向机械通风-空间→空间*/
+	String CONVECTIONNETWORK_ONEWAYMECH = "ConvectionNetwork_OnewayMech";
+	
+	
+	
+	/** SENSORRELATIONSHIP_SS2EQ  传感器测量设备关系-传感器→被测设备*/
+	String SENSORRELATIONSHIP_SS2EQ = "SensorRelationship_Ss2Eq";
+	
+	/** SENSORRELATIONSHIP_SS2SP  传感器测量空间关系-传感器→被测空间*/
+	String SENSORRELATIONSHIP_SS2SP = "SensorRelationship_Ss2Sp";
+	
+	/** SENSORRELATIONSHIP_SS2SY  传感器测量系统关系-传感器→被测系统*/
+	String SENSORRELATIONSHIP_SS2SY = "SensorRelationship_Ss2Sy";
+	
+}

+ 406 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/AdmRelationTypeEnum.java

@@ -0,0 +1,406 @@
+package com.persagy.proxy.adm.constant;
+
+import cn.hutool.core.collection.CollUtil;
+import lombok.Getter;
+import org.apache.commons.lang3.EnumUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/***
+ * Description: ADM关系类型枚举,直接用枚举类表示,以前是在数据库里存储的
+ * @author : lijie
+ * @date :2021/9/2 14:54
+ * @see [graphtype.graphic_type.relation_type]表
+ * Update By lijie 2021/9/2 14:54
+ */
+@Getter
+public enum AdmRelationTypeEnum {
+
+    /**燃气旁通-气体管道-*/
+    EQ2EQ_GASNETWORK_2("eq2eq_GasNetwork_2","GasNetwork","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备所在楼层-设备→楼层-【设备台账】*/
+    EQ2FL("eq2fl","MechInArch","Eq2Fl",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,false,false),
+    /**空间隔断有窗-空间-空间-【全部关系总览】*/
+    SP2SP_SPACENEIGHBORHOOD_3("sp2sp_SpaceNeighborhood_3","SpaceNeighborhood","Window",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,false),
+    /**设备所在物业分区-设备→业务空间-【业务空间台账】*/
+    EQ2SP_IN("eq2sp_in","MechInArch","Eq2Sp",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**建筑下的竖井-竖井→建筑-【竖井台账】*/
+    SH2BD("sh2bd","ArchSubset","Bd2Sh",AdmObjectType.BUILDING.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,false,false),
+    /**空间隔断有门-空间-空间-【全部关系总览】*/
+    SP2SP_SPACENEIGHBORHOOD_2("sp2sp_SpaceNeighborhood_2","SpaceNeighborhood","Door",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,false),
+    /**空间连通-空间-空间-【全部关系总览】*/
+    SP2SP_SPACENEIGHBORHOOD_5("sp2sp_SpaceNeighborhood_5","SpaceNeighborhood","Connect",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,false),
+    /**系统服务于竖井-系统→竖井-【竖井台账】*/
+    SY2SH_FOR("sy2sh_for","MechForArch","Sy2Sh",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,true,false),
+    /**污水排水-污水排水相关设备,沿水流方向-*/
+    EQ2EQ_DRAININGWATERNETWORK_1("eq2eq_DrainingWaterNetwork_1","DrainingWaterNetwork","Discharge",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备服务于功能分区-设备→业务空间-【业务空间台账】*/
+    EQ2SP_FOR("eq2sp_for","MechForArch","Eq2Sp",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**空调回风-空调回风相关设备,沿气流方向-*/
+    EQ2EQ_ACAIRNETWORK_2("eq2eq_ACAirNetwork_2","ACAirNetwork","Return",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**系统下的设备-系统→设备-【系统台账】,【设备台账】*/
+    EQ2SY("eq2sy","MechSubset","Sy2Eq",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,false,false,false,false,false),
+    /**空调冷冻水补水-空调冷冻水补水相关设备,沿水流方向-*/
+    EQ2EQ_CHILLWATERLOOP_4("eq2eq_ChillWaterLoop_4","ChillWaterLoop","Fill",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备服务于建筑-设备→建筑-【设备台账】*/
+    EQ2BD_FOR("eq2bd_for","MechForArch","Eq2Bd",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,true,false),
+    /**空调冷凝水排水-空调冷凝水排水相关设备,沿水流方向-*/
+    EQ2EQ_CONDWATERNETWORK_1("eq2eq_CondWaterNetwork_1","CondWaterNetwork","Discharge",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**空间隔断无门窗-空间-空间-【全部关系总览】*/
+    SP2SP_SPACENEIGHBORHOOD_1("sp2sp_SpaceNeighborhood_1","SpaceNeighborhood","None",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,false),
+    /**阀门限制设备关系-阀门→被限设备-【全部关系总览】*/
+    EQ2EQ_VALVERELATIONSHIP_VV2EQ("eq2eq_ValveRelationship_vv2eq","ValveRelationship","Vv2Eq",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**资产所在业务空间-资产→业务空间-*/
+    PE2SP("pe2sp","PropertyInArch","Pe2Sp",AdmObjectType.PROPERTY.getIndex(),AdmObjectType.SPACE.getIndex(),true,false,false,false,true,false),
+    /**通风排风-通风排风相关设备,沿气流方向-*/
+    EQ2EQ_VENTNETWORK_2("eq2eq_VentNetwork_2","VentNetwork","Discharge",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**弱电通信连接-上位机→下位机,连接弱电、消防、安防等专业设备-*/
+    EQ2EQ_SENSORNETWORK_1("eq2eq_SensorNetwork_1","SensorNetwork","Normal",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**空调冷却水旁通-液体管道-*/
+    EQ2EQ_COOLINGWATERLOOP_3("eq2eq_CoolingWaterLoop_3","CoolingWaterLoop","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备服务于楼层-设备→楼层-【设备台账】*/
+    EQ2FL_FOR("eq2fl_for","MechForArch","Eq2Fl",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,true,false),
+    /**空调排风-空调排风相关设备,沿气流方向-*/
+    EQ2EQ_ACAIRNETWORK_3("eq2eq_ACAirNetwork_3","ACAirNetwork","Discharge",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**生活给水供水-生活给水供水相关设备,沿水流方向-*/
+    EQ2EQ_SUPPLYWATERNETWORK_1("eq2eq_SupplyWaterNetwork_1","DomesticWaterNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**生活给水旁通-液体管道-*/
+    EQ2EQ_SUPPLYWATERNETWORK_2("eq2eq_SupplyWaterNetwork_2","DomesticWaterNetwork","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**系统控制关系-控制设备→被控系统-【全部关系总览】*/
+    EQ2SY_CONTROLRELATION_2("eq2sy_ControlRelation_2","MechCtrl","SyCtrl",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SYSTEM.getIndex(),false,false,false,false,true,false),
+    /**采暖水补水-采暖水补水相关设备,沿水流方向-*/
+    EQ2EQ_HEATWATERLOOP_4("eq2eq_HeatWaterLoop_4","HeatWaterLoop","Fill",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**建筑下的空间-建筑→空间-【业务空间台账】*/
+    BD2SP("bd2sp","ArchSubset","Bd2Sp",AdmObjectType.BUILDING.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**消防常开交通-业务空间-业务空间-【全部关系总览】*/
+    SP2SP_TRAFFICNETWORK_2("sp2sp_TrafficNetwork_2","TrafficNetwork","FFOpen",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("GeneralZone")),
+    /**楼层下的业务空间-楼层→业务空间-【业务空间台账】*/
+    FL2SP("fl2sp","ArchSubset","Fl2Sp",AdmObjectType.FLOOR.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**竖井下的业务空间-竖井→空间-【竖井台账】*/
+    SH2SP_ARCHSUBSET("Sh2Sp_ArchSubset","ArchSubset","Sh2Sp",AdmObjectType.SHAFT.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**空气混合机械通风-空间-空间-【全部关系总览】*/
+    SP2SP_CONVECTIONNETWORK_2("sp2sp_ConvectionNetwork_2","ConvectionNetwork","MixMech",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("AirConditioningZone")),
+    /**系统所在竖井-系统→竖井-【系统台账】,【竖井台账】*/
+    SY2SH("sy2sh","MechInArch","Sy2Sh",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,false,false),
+    /**系统所在建筑-系统→建筑-【系统台账】*/
+    SY2BD_MECHINARCH("sy2bd_MechInArch","MechInArch","Sy2Bd",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,false,false),
+    /**生活热水旁通-液体管道-*/
+    EQ2EQ_DHWNETWORK_2("eq2eq_DHWNetwork_2","DHWNetwork","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**采暖水供水-采暖水供水相关设备,沿水流方向-*/
+    EQ2EQ_HEATWATERLOOP_1("eq2eq_HeatWaterLoop_1","HeatWaterLoop","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**空气单向机械通风-空间→空间-【全部关系总览】*/
+    SP2SP_CONVECTIONNETWORK_3("sp2sp_ConvectionNetwork_3","ConvectionNetwork","OnewayMech",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("AirConditioningZone")),
+    /**弱电通信连接-弱电通信相关设备,沿弱电信号方向-*/
+    EQ2EQ_CONTROLEQUIPNETWORK("eq2eq_ControlEquipNetwork","ControlEquipNetwork","Normal",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**系统服务于楼层-系统→楼层-【系统台账】*/
+    SY2FL_FOR("sy2fl_for","MechForArch","Sy2Fl",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,true,false),
+    /**生活热水供水-生活热水供水相关设备,沿水流方向-*/
+    EQ2EQ_DHWNETWORK_1("eq2eq_DHWNetwork_1","DHWNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**中水旁通-液体管道-*/
+    EQ2EQ_RECYCLEWATERNETWORK_2("eq2eq_RecycleWaterNetwork_2","RecycleWaterNetwork","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**传感器测量系统关系-传感器→被测系统-【全部关系总览】*/
+    EQ2SY_SENSORRELATIONSHIP_SS2SY("eq2sy_SensorRelationship_ss2sy","SensorRelationship","Ss2Sy",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SYSTEM.getIndex(),false,false,false,true,true,false),
+    /**空间隔断有门窗-空间-空间-【全部关系总览】*/
+    SP2SP_SPACENEIGHBORHOOD_4("sp2sp_SpaceNeighborhood_4","SpaceNeighborhood","DoorWindow",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,false),
+    /**资产所在楼层-楼层→资产-【资产台账】*/
+    PE2FL("pe2fl","PropertyInArch","Pe2Fl",AdmObjectType.PROPERTY.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,false,false),
+    /**中水供水-中水供水相关设备,沿水流方向-*/
+    EQ2EQ_RECYCLEWATERNETWORK_1("eq2eq_RecycleWaterNetwork_1","RecycleWaterNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**竖井贯通关系-竖井-竖井-【竖井台账】*/
+    SH2SH("sh2sh","ThroughRelationship","Sh2Sh",AdmObjectType.SHAFT.getIndex(),AdmObjectType.SHAFT.getIndex(),false,true,false,false,false,false),
+    /**低压配电普通连接-低压配电相关设备,沿电流方向-【调研录入参考资料CAD图纸】*/
+    EQ2EQ_LUDISTRIBUTION_1("eq2eq_LUDistribution_1","LUDistribution","Normal",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**消防排烟-消防排烟相关设备,沿气流方向-*/
+    EQ2EQ_FIREVENTNETWORK_1("eq2eq_FireVentNetwork_1","FireVentNetwork","Discharge",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**消防给水供水-消防给水供水相关设备,沿水流方向-*/
+    EQ2EQ_FIREWATERNETWORK_1("eq2eq_FireWaterNetwork_1","FireWaterNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**高压变配电互备连接-分段主柜,分段辅柜-【调研录入参考资料CAD图纸】*/
+    EQ2EQ_HUDISTRIBUTION_2("eq2eq_HUDistribution_2","HUDistribution","Backup",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**污水旁通-液体管道-*/
+    EQ2EQ_DRAININGWATERNETWORK_2("eq2eq_DrainingWaterNetwork_2","DrainingWaterNetwork","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**楼层贯通关系-楼层-楼层-【建筑楼层管理】*/
+    FL2FL("fl2fl","ThroughRelationship","Fl2Fl",AdmObjectType.FLOOR.getIndex(),AdmObjectType.FLOOR.getIndex(),false,true,false,false,false,false),
+    /**多联机供回制冷剂-多联机室外机→多联机室内机-*/
+    EQ2EQ_VRFNETWORK_1("eq2eq_VRFNetwork_1","VRFNetwork","SupplyReturn",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**低压配电互备连接-低压开关柜-母联柜-【调研录入参考资料CAD图纸】*/
+    EQ2EQ_LUDISTRIBUTION_2("eq2eq_LUDistribution_2","LUDistribution","Backup",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**直饮水旁通-液体管道-*/
+    EQ2EQ_DRINKINGWATERNETWORK_2("eq2eq_DrinkingWaterNetwork_2","DrinkingWaterNetwork","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**传感器测量空间关系-传感器→被测空间-【全部关系总览】*/
+    EQ2SP_SENSORRELATIONSHIP_SS2SP("eq2sp_SensorRelationship_ss2sp","SensorRelationship","Ss2Sp",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SPACE.getIndex(),true,false,false,true,true,false),
+    /**租户租用业务空间-租户→租赁业务空间-【租户台账】*/
+    TN2SP("tn2sp","TenentInArch","Tn2Sp",AdmObjectType.PROPERTY.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**空调冷冻水旁通-供冷集水器-供冷分水器,液体管道-*/
+    EQ2EQ_CHILLWATERLOOP_3("eq2eq_ChillWaterLoop_3","ChillWaterLoop","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**空调冷冻水回水-空调冷冻水回水相关设备,沿水流方向-*/
+    EQ2EQ_CHILLWATERLOOP_2("eq2eq_ChillWaterLoop_2","ChillWaterLoop","Return",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**燃气供气-燃气供气相关设备,沿气流方向-*/
+    EQ2EQ_GASNETWORK_1("eq2eq_GasNetwork_1","GasNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**系统服务于建筑-系统→建筑-【系统台账】*/
+    SY2BD_FOR("sy2bd_for","MechForArch","Sy2Bd",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,true,false),
+    /**新风送风-新风送风相关设备,沿气流方向-*/
+    EQ2EQFRESHAIRNETWORK_1("eq2eqFreshAirNetwork_1","FreshAirNetwork","Fresh",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**空调冷却水补水-空调冷却水补水相关设备,沿水流方向-*/
+    EQ2EQ_COOLINGWATERLOOP_4("eq2eq_CoolingWaterLoop_4","CoolingWaterLoop","Fill",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备所在竖井-设备→竖井-【竖井台账】*/
+    EQ2SH("eq2sh","MechInArch","Eq2Sh",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,false,false),
+    /**空调冷冻水供水-空调冷冻水供水相关设备,沿水流方向-*/
+    EQ2EQ_CHILLWATERLOOP_1("eq2eq_ChillWaterLoop_1","ChillWaterLoop","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**直饮水供水-直饮水供水相关设备,沿水流方向-*/
+    EQ2EQ_DRINKINGWATERNETWORK_1("eq2eq_DrinkingWaterNetwork_1","DrinkingWaterNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**资产属于建筑-建筑→资产-【资产台账】*/
+    PE2BD("pe2bd","PropertyInArch","Pe2Bd",AdmObjectType.PROPERTY.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,false,false),
+    /**设备服务于竖井-设备→竖井-【竖井台账】*/
+    EQ2SH_FOR("eq2sh_for","MechForArch","Eq2Sh",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,true,false),
+    /**空调冷却水回水-空调冷却水回水相关设备,沿水流方向-*/
+    EQ2EQ_COOLINGWATERLOOP_2("eq2eq_CoolingWaterLoop_2","CoolingWaterLoop","Return",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**阀门限制系统关系-阀门→被限系统-【全部关系总览】*/
+    EQ2SY_VALVERELATIONSHIP_VV2SY("eq2sy_ValveRelationship_vv2sy","ValveRelationship","Vv2Sy",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SYSTEM.getIndex(),false,false,false,false,true,false),
+    /**普通交通-空间-空间-【全部关系总览】*/
+    SP2SP_TRAFFICNETWORK_1("sp2sp_TrafficNetwork_1","TrafficNetwork","Normal",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("GeneralZone")),
+    /**光照透明隔断-空间-空间-【全部关系总览】*/
+    SP2SP_RADIATIONNETWORK_2("sp2sp_RadiationNetwork_2","RadiationNetwork","Transparent",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("LightingZone")),
+    /**消防给水旁通-液体管道-*/
+    EQ2EQ_FIREWATERNETWORK_2("eq2eq_FireWaterNetwork_2","FireWaterNetwork","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**空气自然对流-空间-空间-【全部关系总览】*/
+    SP2SP_CONVECTIONNETWORK_1("sp2sp_ConvectionNetwork_1","ConvectionNetwork","Natural",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("AirConditioningZone")),
+    /**通风送风-通风送风相关设备,沿气流方向-*/
+    EQ2EQ_VENTNETWORK_1("eq2eq_VentNetwork_1","VentNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**消防常关交通-空间-空间-【全部关系总览】*/
+    SP2SP_TRAFFICNETWORK_3("sp2sp_TrafficNetwork_3","TrafficNetwork","FFClose",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("GeneralZone")),
+    /**系统所在楼层-系统→楼层-【系统台账】*/
+    SY2FL("sy2fl","MechInArch","Sy2Fl",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,false,false),
+    /**传感器测量设备关系-传感器→被测设备-【全部关系总览】*/
+    EQ2EQ_SENSORRELATIONSHIP_SS2EQ("eq2eq_SensorRelationship_ss2eq","SensorRelationship","Ss2Eq",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,true,false,false),
+    /**资产所在竖井-资产→竖井-*/
+    PE2SH("pe2sh","PropertyInArch","Pe2Sh",AdmObjectType.PROPERTY.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,true,false),
+    /**采暖水回水-采暖水回水相关设备,沿水流方向-*/
+    EQ2EQ_HEATWATERLOOP_2("eq2eq_HeatWaterLoop_2","HeatWaterLoop","Return",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备控制关系-控制设备→被控设备-【全部关系总览】*/
+    EQ2EQ_CONTROLRELATION_1("eq2eq_ControlRelation_1","MechCtrl","EqCtrl",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**光照连通-空间-空间-【全部关系总览】*/
+    SP2SP_RADIATIONNETWORK_1("sp2sp_RadiationNetwork_1","RadiationNetwork","Connect",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,true,false,true,true,CollUtil.newHashSet("LightingZone")),
+    /**竖井下的业务空间-竖井→空间-【竖井台账】*/
+    SH2SP("sh2sp","ArchSubset","Sh2Sp",AdmObjectType.SHAFT.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**采暖水旁通-供暖集水器-供暖分水器,液体管道-*/
+    EQ2EQ_HEATWATERLOOP_3("eq2eq_HeatWaterLoop_3","HeatWaterLoop","Bypass",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**空调冷却水供水-空调冷却水供水相关设备,沿水流方向-*/
+    EQ2EQ_COOLINGWATERLOOP_1("eq2eq_CoolingWaterLoop_1","CoolingWaterLoop","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**建筑服务于建筑-建筑→建筑-*/
+    BD2BD_ARCHFORARCH("bd2bd_ArchForArch","ArchForArch","Bd2Bd",AdmObjectType.BUILDING.getIndex(),AdmObjectType.BUILDING.getIndex(),false,true,false,false,true,false),
+    /**竖井服务于楼层-竖井→楼层-*/
+    SH2FL_ARCHFORARCH("sh2fl_ArchForArch","ArchForArch","Sh2Fl",AdmObjectType.SHAFT.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,true,false),
+    /**竖井服务于竖井-竖井→竖井-*/
+    SH2SH_ARCHFORARCH("sh2sh_ArchForArch","ArchForArch","Sh2Sh",AdmObjectType.SHAFT.getIndex(),AdmObjectType.SHAFT.getIndex(),false,true,false,false,true,false),
+    /**竖井服务于空间-竖井→空间-*/
+    SH2SP_ARCHFORARCH("sh2sp_ArchForArch","ArchForArch","Sh2Sp",AdmObjectType.SHAFT.getIndex(),AdmObjectType.SPACE.getIndex(),true,false,false,false,true,false),
+    /**空间服务于建筑-空间→建筑-*/
+    SP2BD_ARCHFORARCH("sp2bd_ArchForArch","ArchForArch","Sp2Bd",AdmObjectType.SPACE.getIndex(),AdmObjectType.BUILDING.getIndex(),true,false,false,false,true,false),
+    /**空间服务于楼层-空间→楼层-*/
+    SP2FL_ARCHFORARCH("sp2fl_ArchForArch","ArchForArch","Sp2Fl",AdmObjectType.SPACE.getIndex(),AdmObjectType.FLOOR.getIndex(),true,false,false,false,true,false),
+    /**空间服务于竖井-空间→竖井-*/
+    SP2SH_ARCHFORARCH("sp2sh_ArchForArch","ArchForArch","Sp2Sh",AdmObjectType.SPACE.getIndex(),AdmObjectType.SHAFT.getIndex(),true,false,false,false,true,false),
+    /**空间服务于空间-空间→空间-*/
+    SP2SP_ARCHFORARCH("sp2sp_ArchForArch","ArchForArch","Sp2Sp",AdmObjectType.SPACE.getIndex(),AdmObjectType.SPACE.getIndex(),true,true,false,false,true,false),
+    /**建筑服务于楼层-建筑→楼层-*/
+    BD2FL_ARCHFORARCH("bd2fl_ArchForArch","ArchForArch","Bd2Fl",AdmObjectType.BUILDING.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,true,false),
+    /**建筑服务于竖井-建筑→竖井-*/
+    BD2SH_ARCHFORARCH("bd2sh_ArchForArch","ArchForArch","Bd2Sh",AdmObjectType.BUILDING.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,true,false),
+    /**建筑下的楼层-建筑→楼层-*/
+    BD2FL_ARCHSUBSET("bd2fl_ArchSubset","ArchSubset","Bd2Fl",AdmObjectType.BUILDING.getIndex(),AdmObjectType.FLOOR.getIndex(),false,false,false,false,true,false),
+    /**设备设施下的部件-设备设施→部件-*/
+    EQ2EC_MECHSUBSET("eq2ec_MechSubset","MechSubset","Eq2Ec",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.COMPONENT.getIndex(),false,false,false,false,true,false),
+    /**建筑下的竖井-建筑→竖井-【系统台账】*/
+    BD2SH_ARCHSUBSET("bd2sh_ArchSubset","ArchSubset","Bd2Sh",AdmObjectType.BUILDING.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,false,false),
+    /**建筑服务于空间-建筑→空间-*/
+    BD2SP_ARCHFORARCH("bd2sp_ArchForArch","ArchForArch","Bd2Sp",AdmObjectType.BUILDING.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,true,false),
+    /**楼层服务于建筑-楼层→建筑-*/
+    FL2BD_ARCHFORARCH("fl2bd_ArchForArch","ArchForArch","Fl2Bd",AdmObjectType.FLOOR.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,true,false),
+    /**楼层服务于楼层-楼层→楼层-*/
+    FL2FL_ARCHFORARCH("fl2fl_ArchForArch","ArchForArch","Fl2Fl",AdmObjectType.FLOOR.getIndex(),AdmObjectType.FLOOR.getIndex(),false,true,false,false,true,false),
+    /**楼层服务于竖井-楼层→竖井-*/
+    FL2SH_ARCHFORARCH("fl2sh_ArchForArch","ArchForArch","Fl2Sh",AdmObjectType.FLOOR.getIndex(),AdmObjectType.SHAFT.getIndex(),false,false,false,false,true,false),
+    /**楼层服务于空间-楼层→空间-*/
+    FL2SP_ARCHFORARCH("fl2sp_ArchForArch","ArchForArch","Fl2Sp",AdmObjectType.FLOOR.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,true,false),
+    /**竖井服务于建筑-竖井→建筑-*/
+    SH2BD_ARCHFORARCH("sh2bd_ArchForArch","ArchForArch","Sh2Bd",AdmObjectType.SHAFT.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,true,false),
+    /**系统所在空间-系统→业务空间-【系统台账】,【业务空间台账】*/
+    SY2SP("sy2sp","MechInArch","Sy2Sp",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.SPACE.getIndex(),false,false,false,false,false,false),
+    /**设备所在建筑-设备→建筑*/
+    EQ2BD("eq2bd","MechInArch","Eq2Bd",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,false,false),
+    /**设备所在建筑-设备→建筑-【设备台账】*/
+    SYEQ2BD("syeq2bd","MechInArch","Eq2Bd",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.BUILDING.getIndex(),false,false,false,false,false,false),
+    /**系统服务于空间-系统→业务空间-【业务空间台账】*/
+    SY2SP_FOR("sy2sp_for","MechForArch","Sy2Sp",AdmObjectType.SYSTEM.getIndex(),AdmObjectType.SPACE.getIndex(),true,false,false,false,true,false),
+    /**空调送风-空调送风相关设备,沿气流方向-*/
+    EQ2EQ_ACAIRNETWORK_1("eq2eq_ACAirNetwork_1","ACAirNetwork","Supply",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**通风不确定-通风相关设备-*/
+    EQ2EQ_VENTNETWORK_3("eq2eq_VentNetwork_3","VentNetwork","Uncertain",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**高压变配电普通连接-高压变配电相关设备,沿电流方向-【调研录入参考资料CAD图纸】*/
+    EQ2EQ_HUDISTRIBUTION_1("eq2eq_HUDistribution_1","HUDistribution","Normal",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备常规电源-低/高压开关柜→用电设备-【全部关系总览】*/
+    EQ2EQ_EQUIPPOWER_1("eq2eq_EquipPower_1","MechPower","EqNormal",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**设备备用电源-低/高压开关柜→用电设备-【全部关系总览】*/
+    EQ2EQ_EQUIPPOWER_2("eq2eq_EquipPower_2","MechPower","EqBackup",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.EQUIPMENT.getIndex(),false,true,false,false,false,false),
+    /**系统常规电源-低/高压开关柜→用电设备-【全部关系总览】*/
+    EQ2EQ_EQUIPPOWER_3("eq2eq_EquipPower_3","MechPower","SyNormal",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SYSTEM.getIndex(),false,true,false,false,false,false),
+    /**系统备用电源-低/高压开关柜→用电设备-【全部关系总览】*/
+    EQ2EQ_EQUIPPOWER_4("eq2eq_EquipPower_4","MechPower","SyBackup",AdmObjectType.EQUIPMENT.getIndex(),AdmObjectType.SYSTEM.getIndex(),false,true,false,false,false,false),
+    /**
+     *业务空间内的元空间关系 20210914新增-不对请修改
+     */
+    SP2SI("sp2si","MechInArch","Sp2Si","","",false,true,false,false,false,false);
+    /**数据中心的关系类型*/
+    private String relationType;
+    /**图类型编码*/
+    private String graphCode;
+    /**边类型编码*/
+    private String relCode;
+    /**主对象分类*/
+    private String masterObjType;
+    /**从对象分类*/
+    private String slaveObjType;
+    /**拥有关系值的标识,true-有,false-无,一般空间对象分类有,为其class_code*/
+    private Boolean hasRelValue;
+    /**是否过滤主对象id,true-过滤,false-不过滤*/
+    private Boolean hasFilterMasterId;
+    /**是否过滤classCode,true-过滤,false-不过滤*/
+    private Boolean hasFilterClassCode;
+    /**是否检查传感器类型,true-检查,false-不检查*/
+    private Boolean hasCheckSensor;
+    /**是否检查CADID,true-检查,false-不检查*/
+    private Boolean hasCheckCadId;
+    /**是否检查classCode,true-检查,false-不检查*/
+    private Boolean hasCheckClassCode;
+    /**是否检查classCode使用的classCodes列表*/
+    private Set<String> checkClassCodes;
+    /**是否检查传感器使用的传感器类型*/
+    private Set<String> checkSensorCodes;
+    /**是否需要配置源末端,0-不需要,1-需要*/
+    private Integer sourceFlag;
+    /**是否自动计算类型,0-不自动计算,1-自动计算*/
+    private Integer automaticFlag;
+    /**手动计算类型 1 禁用  2提示引导 3手动维护*/
+    private Integer manualFlag;
+    /**风系统1,水系统0*/
+    private Integer systemType;
+    ///**业务分区类型*/
+//    private String zoneType;
+
+    /***
+     * Description: 构造函数
+     * @param relationType : 数据中心的关系类型
+     * @param graphCode : 标准字典定义的图类型编码
+     * @param relCode : 标准字典定义的边类型编码
+     * @param hasRelValue : 拥有关系值的标识,true-有,false-无,一般空间对象分类有,为其class_code
+     * @param hasFilterMasterId : 是否过滤主对象id,true-过滤,false-不过滤
+     * @param hasCheckSensor : 是否检查传感器类型,true-检查,false-不检查
+     * @param hasCheckCadId : 是否检查CADID,true-检查,false-不检查
+     * @param hasCheckClassCode : 是否检查classCode,true-检查,false-不检查
+     * @author : lijie
+     * Update By lijie 2021/9/2 14:53
+     */
+    AdmRelationTypeEnum(String relationType, String graphCode, String relCode, String masterObjType, String slaveObjType,
+                        Boolean hasRelValue, Boolean hasFilterMasterId, Boolean hasFilterClassCode,
+                        Boolean hasCheckSensor, Boolean hasCheckCadId, Boolean hasCheckClassCode) {
+        this.relationType = relationType;
+        this.graphCode = graphCode;
+        this.relCode = relCode;
+        this.masterObjType = masterObjType;
+        this.slaveObjType = slaveObjType;
+        this.hasRelValue = hasRelValue;
+        this.hasFilterMasterId = hasFilterMasterId;
+        this.hasFilterClassCode = hasFilterClassCode;
+        this.hasCheckSensor = hasCheckSensor;
+        this.hasCheckCadId = hasCheckCadId;
+        this.hasCheckClassCode = hasCheckClassCode;
+        this.checkClassCodes = CollUtil.newHashSet(AdmObjectInfoConstant.CHECK_CLASS_CODES);
+        this.checkSensorCodes = CollUtil.newHashSet(AdmObjectInfoConstant.CHECK_SENSOR_CODES);
+        this.sourceFlag=null;
+        if (AdmObjectInfoConstant.SOURCE_FLAG_FALSE.contains(relationType)){
+            this.sourceFlag=0;
+        }
+        if (AdmObjectInfoConstant.SOURCE_FLAG_TRUE.contains(relationType)){
+            this.sourceFlag=1;
+        }
+        this.automaticFlag=null;
+        if (AdmObjectInfoConstant.AUTOMATIC_FLAG_FALSE.contains(relationType)){
+            this.automaticFlag=0;
+        }
+        if (AdmObjectInfoConstant.AUTOMATIC_FLAG_TRUE.contains(relationType)){
+            this.automaticFlag=1;
+        }
+        this.manualFlag=null;
+        if (AdmObjectInfoConstant.MANUAL_FLAG_TWO.contains(relationType)){
+            this.manualFlag=2;
+        }
+        if (AdmObjectInfoConstant.MANUAL_FLAG_THREE.contains(relationType)){
+            this.manualFlag=3;
+        }
+        this.systemType=null;
+        if (AdmObjectInfoConstant.SYSTEM_TYPE_FALSE.contains(relationType)){
+            this.systemType=0;
+        }
+        if (AdmObjectInfoConstant.SYSTEM_TYPE_TRUE.contains(relationType)){
+            this.systemType=1;
+        }
+    }
+    /***
+     * Description: 构造函数
+     * @param relationType : 数据中心的关系类型
+     * @param graphCode : 标准字典定义的图类型编码
+     * @param relCode : 标准字典定义的边类型编码
+     * @param hasRelValue : 拥有关系值的标识,true-有,false-无,一般空间对象分类有,为其class_code
+     * @param hasFilterMasterId : 是否过滤主对象id,true-过滤,false-不过滤
+     * @param hasCheckSensor : 是否检查传感器类型,true-检查,false-不检查
+     * @param hasCheckCadId : 是否检查CADID,true-检查,false-不检查
+     * @param hasCheckClassCode : 是否检查classCode,true-检查,false-不检查
+     * @author : lijie
+     * Update By lijie 2021/9/2 14:53
+     */
+    AdmRelationTypeEnum(String relationType, String graphCode, String relCode, String masterObjType, String slaveObjType,
+                        Boolean hasRelValue, Boolean hasFilterMasterId, Boolean hasFilterClassCode,
+                        Boolean hasCheckSensor, Boolean hasCheckCadId, Boolean hasCheckClassCode,
+                        Set<String> checkClassCodes) {
+        this.relationType = relationType;
+        this.graphCode = graphCode;
+        this.relCode = relCode;
+        this.masterObjType = masterObjType;
+        this.slaveObjType = slaveObjType;
+        this.hasRelValue = hasRelValue;
+        this.hasFilterMasterId = hasFilterMasterId;
+        this.hasFilterClassCode = hasFilterClassCode;
+        this.hasCheckSensor = hasCheckSensor;
+        this.hasCheckCadId = hasCheckCadId;
+        this.hasCheckClassCode = hasCheckClassCode;
+        this.checkClassCodes = checkClassCodes;
+        this.checkSensorCodes = CollUtil.newHashSet(AdmObjectInfoConstant.CHECK_SENSOR_CODES);
+    }
+    /***
+     * Description: 获取枚举类的映射
+     * @return : java.util.Map<java.lang.String,com.persagy.proxy.enumeration.AdmRelationTypeEnum>
+     * @author : lijie
+     * date :2021/9/2 17:22
+     * Update By lijie 2021/9/2 17:22
+     */
+    public static Map<String,AdmRelationTypeEnum> getRelationTypeMap(){
+        List<AdmRelationTypeEnum> enumList = EnumUtils.getEnumList(AdmRelationTypeEnum.class);
+        return enumList.stream().collect(Collectors.toMap(AdmRelationTypeEnum::getRelationType,
+                admRelationTypeEnum -> admRelationTypeEnum,(k1,k2)->k1));
+    }
+    
+    /***
+     * Description: 获取枚举类的映射
+     * key: 图类型_边类型, value: enum
+     * @return : java.util.Map<java.lang.String,com.persagy.proxy.enumeration.AdmRelationTypeEnum>
+     * @author : lijie
+     * date :2021/9/2 17:22
+     * Update By lijie 2021/9/2 17:22
+     */
+    public static Map<String,AdmRelationTypeEnum> getGraphRelTypeMap(){
+        List<AdmRelationTypeEnum> enumList = EnumUtils.getEnumList(AdmRelationTypeEnum.class);
+        return enumList.stream().collect(Collectors.toMap(k -> (k.getGraphCode() + AdmCommonConstant.UNDERLINE + k.getRelCode()),
+        		admRelationTypeEnum -> admRelationTypeEnum,(k1,k2)->k1));
+    }
+}

+ 45 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/BusinessErrorRwdCode.java

@@ -0,0 +1,45 @@
+package com.persagy.proxy.adm.constant;
+
+/***
+ * Description: rwd定制的错误返回码
+ * @author : lijie
+ * @date :2021/9/3 14:25
+ * Update By lijie 2021/9/3 14:25
+ */
+public enum BusinessErrorRwdCode {
+    /**
+     * A73XX:代表关系计算的错误码
+     * A79XX:代表ADM错误码
+     *
+     * */
+    A7201("A7201", "关系不存在"),
+	A7301("A7301", ":不存在"),
+    A7302("A7302", ":存在多个实例"),
+    A7303("A7303", ":不存在"),
+    A7304("A7304", ":存在多个实例"),
+    A7305("A7305", ":错误的类型参考:这里的传感器包含车库摄像头,车位检测器,办公摄像头,火灾探测器,燃气探测器,漏电探测器,消防设备电源传感器,监控摄像头,入侵报警探测器,以及传感器系统下所有设备类型"),
+    A7306("A7306", ":不符合主对象条件限制");
+
+    private String code;
+
+    private String desc;
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    private BusinessErrorRwdCode(String code, String desc) {
+        this.desc = desc;
+        this.code = code;
+    }
+
+    @Override
+    public String toString() {
+        return this.code + "_" + this.desc;
+    }
+
+}

+ 25 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/FuncidCategory.java

@@ -0,0 +1,25 @@
+package com.persagy.proxy.adm.constant;
+
+/**
+ * @author: yaoll
+ * @date: 2020-09-09
+ * @verison: 1.0
+ */
+public enum FuncidCategory {
+	/**
+	 * 静态量
+	 */
+	STATIC,
+	/**
+	 * 脉冲量
+	 */
+	PULSE,
+	/**
+	 * 阶段量
+	 */
+	GRADATION,
+	/**
+	 * 时序量
+	 */
+	SEQUENTIAL
+}

+ 21 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/GraphCodeEnum.java

@@ -0,0 +1,21 @@
+package com.persagy.proxy.adm.constant;
+
+/**
+ * 图类型编码
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月2日 下午4:31:27
+ */
+
+public enum GraphCodeEnum {
+
+	ArchSubset,SpaceNeighborhood,ThroughRelationship,TrafficNetwork,ConvectionNetwork,
+	RadiationNetwork,SpaceCorrespond,ArchForArch,MechInArch,MechForArch,MechSubset,LUDistribution,
+	HUDistribution,ChillWaterLoop,CoolingWaterLoop,HeatWaterLoop,CondWaterNetwork,ACAirNetwork,FreshAirNetwork,
+	VentNetwork,VRFNetwork,DomesticWaterNetwork,DrainingWaterNetwork,RecycleWaterNetwork,DrinkingWaterNetwork,DHWNetwork,
+	GasNetwork,FireWaterNetwork,FireVentNetwork,WENetwork,MechCtrl,MechPower,SensorRelationship,ValveRelationship,
+	EnergySubMeter,ScheduleRelationship,MeteorologyRelationship,TenentInArch,BlocRelationship,Property2Mech,PropertyInArch,
+	
+}

+ 111 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/ObjTypeMapping.java

@@ -0,0 +1,111 @@
+package com.persagy.proxy.adm.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 对象类型的前缀与全名的来回映射,以及根据边类型获取对应的对象类型前缀
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 下午9:16:10
+ */
+public class ObjTypeMapping {
+
+	/** example: Sp -> space */
+	public static final Map<String, String> PREFIX_FULLNAME = new HashMap<String, String>();
+	
+	/** example: space -> Sp */
+	public static final Map<String, String> FULLNAME_PREFIX = new HashMap<String, String>();
+	
+	/** example: space -> 空间 */
+	public static final Map<String, String> FULLNAME_NAME = new HashMap<String, String>();
+	
+	/** example: Sp -> 空间 */
+	public static final Map<String, String> PREFIX_NAME = new HashMap<String, String>();
+	/**楼层-对象类型*/
+	public static final String FLOOR = "floor";
+	
+	static {
+	    
+		PREFIX_FULLNAME.put("Pj", "project");
+		PREFIX_FULLNAME.put("Bd", "building");
+		PREFIX_FULLNAME.put("Fl", "floor");
+		PREFIX_FULLNAME.put("Sp", "space");
+		PREFIX_FULLNAME.put("Sy", "system");
+		PREFIX_FULLNAME.put("Eq", "equipment");
+		PREFIX_FULLNAME.put("Sh", "shaft");
+		PREFIX_FULLNAME.put("Ec", "component");
+		PREFIX_FULLNAME.put("Pe", "property");
+		
+		FULLNAME_PREFIX.put("project", "Pj");
+		FULLNAME_PREFIX.put("building", "Bd");
+		FULLNAME_PREFIX.put("floor", "Fl");
+		FULLNAME_PREFIX.put("space", "Sp");
+		FULLNAME_PREFIX.put("system", "Sy");
+		FULLNAME_PREFIX.put("equipment", "Eq");
+		FULLNAME_PREFIX.put("shaft", "Sh");
+		FULLNAME_PREFIX.put("component", "Ec");
+		FULLNAME_PREFIX.put("property", "Pe");
+		
+		PREFIX_NAME.put("Pj", "项目");
+		PREFIX_NAME.put("Bd", "建筑");
+		PREFIX_NAME.put("Fl", "楼层");
+		PREFIX_NAME.put("Sp", "空间");
+		PREFIX_NAME.put("Sy", "系统");
+		PREFIX_NAME.put("Eq", "设备");
+		PREFIX_NAME.put("Sh", "竖井");
+		PREFIX_NAME.put("Ec", "部件");
+		PREFIX_NAME.put("Pe", "资产");
+		
+		FULLNAME_NAME.put("project", "项目");
+		FULLNAME_NAME.put("building", "建筑");
+		FULLNAME_NAME.put("floor", "楼层");
+		FULLNAME_NAME.put("space", "空间");
+		FULLNAME_NAME.put("system", "系统");
+		FULLNAME_NAME.put("equipment", "设备");
+		FULLNAME_NAME.put("shaft", "竖井");
+		FULLNAME_NAME.put("component", "部件");
+		FULLNAME_NAME.put("property", "资产");
+		
+	}
+	
+	/**
+	 * 获取中台中,边类型编码的前两位
+	 * 
+	 * @param relCode 最低2位,不然抛异常
+	 * @return 空字符串或者对应前缀
+	 */
+	public static String getRelCodePrefix(String relCode) {
+		return StrUtil.isBlank(relCode) ? AdmCommonConstant.EMPTY : relCode.substring(0, 2);
+	}
+	
+	/**
+	 * 获取中台中对象类型的前两位
+	 * 
+	 * @param objType 最低5位,不然抛异常
+	 * @return 空字符串或者对应后缀
+	 */
+	public static String getRelCodeSuffix(String relCode) {
+		return StrUtil.isBlank(relCode) ? AdmCommonConstant.EMPTY : relCode.substring(3, 5);
+	}
+	
+	/**
+	 * 获取中台中边类型对应的描述
+	 * 
+	 * @param objType 最低5位,不然抛异常
+	 * @return 空字符串或者对应后缀
+	 */
+	public static String getConneObject(String relCode) {
+		if (StringUtils.isBlank(relCode) || relCode.length() < 5) {
+			return AdmCommonConstant.EMPTY;
+		}
+		return PREFIX_NAME.get(relCode.substring(0, 2)) + AdmCommonConstant.RIGHT_ARROW +  PREFIX_NAME.get(relCode.substring(3, 5));
+	}
+	
+}

+ 24 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/RelCodeEnum.java

@@ -0,0 +1,24 @@
+package com.persagy.proxy.adm.constant;
+
+/**
+ * 边类型编码
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月2日 下午4:32:28
+ */
+public enum RelCodeEnum {
+	Pj2Bd,Bd2Fl,
+	None,Door,Window,DoorWindow,
+	FFOpen,FFClose,
+	Natural,OnewayMech,MixMech,Connect,Transparent,
+	Fl2Bd,Fl2Fl,Fl2Sh,Fl2Sp,Sh2Bd,Sh2Fl,Sh2Sh,Sh2Sp,Sp2Bd,
+	ExactCorrespond,InexactCorrespond,Bd2Bd,Bd2Sh,Bd2Sp,
+	Sp2Fl,Sp2Sh,Sp2Sp,
+	Sy2Bd,Sy2Fl,Sy2Sh,Sy2Sp,Eq2Bd,Eq2Fl,Eq2Sh,Eq2Sp,Pj2Sy,Pj2Eq,Sy2Eq,Eq2Ec,
+	Backup,Fill,Return,Fresh,
+	Uncertain,SupplyReturn,Supply,Bypass,Discharge,Normal,SyCtrl,EqCtrl,SyNormal,
+	SyBackup,EqNormal,EqBackup,Ss2Eq,Ss2Sy,Ss2Sp,Vv2Eq,Vv2Sy,Vv2Vv,Em2Bd,Sub2Em,SubTree,Br2Sub,
+	Br2Eq,Sch2Pj,Sch2Bd,Sch2Fl,Sch2Sp,Sch2Tn,Ms2Pj,Tn2Sp,Bl2Pj,Pe2Eq,Pe2Ec,Pe2Pj,Pe2Bd,Pe2Fl,Pe2Sh,Pe2Sp;
+}

+ 45 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/constant/SpaceTypeEnum.java

@@ -0,0 +1,45 @@
+package com.persagy.proxy.adm.constant;
+
+import lombok.Getter;
+
+/**
+ * 业务空间类型
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月6日 下午3:43:35
+ */
+@Getter
+public enum SpaceTypeEnum {
+
+	GeneralZone("GeneralZone", "物业分区"),
+	PowerSupplyZone("PowerSupplyZone", "供电分区"),
+	LightingZone("LightingZone", "照明分区"),
+	NetworkZone("NetworkZone", "网络分区"),
+	AirConditioningZone("AirConditioningZone", "空调分区"),
+	HeatingZone("HeatingZone", "采暖分区"),
+	CleanZone("CleanZone", "洁净分区"),
+	DomesticWaterSupplyZone("DomesticWaterSupplyZone", "生活给水分区"),
+	FireZone("FireZone", "防火分区"),
+	SecurityZone("SecurityZone", "安防分区"),
+	TenantZone("TenantZone", "租户分区"),
+	FunctionZone("FunctionZone", "功能分区"),
+	PassengerFlowZone("PassengerFlowZone", "客流分区"),
+	EvacuateZone("EvacuateZone", "疏散分区"),
+	EnvironmentZone("EnvironmentZone", "环境分区"),
+	OtherZone("OtherZone", "其他分区"),
+	MajorOperationZone("MajorOperationZone", "主要功能区"),
+	ParkingZone("ParkingZone", "停车分区");
+
+	private String code;
+    private String desc;
+
+    SpaceTypeEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+
+    
+}

+ 572 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/handler/RelationReportHandler.java

@@ -0,0 +1,572 @@
+package com.persagy.proxy.adm.handler;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.persagy.dmp.define.entity.ObjectInfoDefine;
+import com.persagy.dmp.define.entity.ObjectTypeDefine;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectType;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.adm.strategy.RelationObjectContext;
+import com.persagy.proxy.report.model.EquipmentBindPointExcel;
+import com.persagy.proxy.report.model.EquipmentCountExcel;
+import com.persagy.proxy.report.model.EquipmentExcel;
+import com.persagy.proxy.report.service.IRelationReportService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年10月15日 下午3:09:10
+ */
+@Component
+@RequiredArgsConstructor
+public class RelationReportHandler {
+
+	private final RelationObjectContext relationObjectContext;
+	
+	private final IRelationReportService relationReportService;
+
+	/**
+	 * 查询出不在空间内的设备数据
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 */
+	public List<EquipmentExcel> findEquipByNotSpace(String groupCode, String projectId) {
+		String equipment = AdmObjectType.EQUIPMENT.getIndex();
+		HashSet<String> equipments = Sets.newHashSet(equipment);
+		
+		// 1.获取所有的设备对象数据
+		List<OrderItem> classCodeAsc = Arrays.asList(OrderItem.asc("classCode"));
+		List<ObjectNode> equipList = this.relationReportService.queryObjects(null, groupCode, projectId, null, null, equipments, classCodeAsc);
+		if (CollectionUtil.isEmpty(equipList)) {
+			return Lists.newArrayList();
+		}
+				
+		// 2.获取所有的设备类定义的className
+		List<ObjectTypeDefine> classList = this.relationReportService.queryClassList(groupCode, projectId, null, equipments, null);
+		/** key-classCode, value-className */
+		Map<String, String> classDefine = new HashMap<String, String>();
+		for (ObjectTypeDefine objectTypeDefine : classList) {
+			classDefine.put(objectTypeDefine.getCode(), objectTypeDefine.getName());
+		}
+		
+		// 3.查询出所有的边类型为 Eq2Sp 的关系数据
+		List<ObjectRelation> relationObjects = this.relationReportService.findRelationObjects(groupCode, projectId, null, RelCodeEnum.Eq2Sp.name(), null, null);
+		Set<String> excludeIds = new HashSet<String>();
+		if (CollectionUtil.isNotEmpty(relationObjects)) {
+			for (ObjectRelation relationInfo : relationObjects) {
+				excludeIds.add(relationInfo.getObjFrom());
+			}
+		}
+		
+		return this.exportEquipmentExcel(equipList, classDefine, excludeIds, groupCode, projectId);
+	}
+	
+	/**
+	 * 统计项目下已有的设备,信息点,每个设备
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 * @return
+	 */
+	public List<EquipmentBindPointExcel> queryProjectBindPoint(String groupCode, String projectId) {
+		String equipment = AdmObjectType.EQUIPMENT.getIndex();
+		
+		List<OrderItem> classCodeAsc = Arrays.asList(OrderItem.asc("classCode"));
+		
+		// 1.获取项目名称
+		List<ObjectNode> projects = this.relationReportService.queryObjects(null, groupCode, projectId, Sets.newHashSet(projectId), Sets.newHashSet(AdmObjectType.PROJECT.getIndex()), null, null);
+		if (CollectionUtil.isEmpty(projects)) {
+			return Lists.newArrayList();
+		}
+		String projectName = projects.get(0).has("localName") ? projects.get(0).get("localName").asText() : null;
+		
+		// 2.获取所有的设备对象数据
+		List<ObjectNode> equipList = this.relationReportService.queryObjects(null, groupCode, projectId, null, null, Sets.newHashSet(equipment), classCodeAsc);
+		if (CollectionUtil.isEmpty(equipList)) {
+			return Lists.newArrayList();
+		}
+		
+		// 3.获取所有的设备、系统类定义信息
+		List<ObjectTypeDefine> classInfo = this.relationReportService.queryClassList(groupCode, projectId, null, Sets.newHashSet(equipment, AdmObjectType.SYSTEM.getIndex()), null);
+		/** key-equipCode, value-equipName */
+		Map<String, String> equipTemp = new HashMap<String, String>();
+		/** key-systemCode, value-systemName */
+		Map<String, String> systemTemp = new HashMap<String, String>();
+		for (ObjectTypeDefine info : classInfo) {
+			if (info.getCode().length() > 5) {
+				equipTemp.put(info.getCode(), info.getName());
+			} else {
+				systemTemp.put(info.getCode(), info.getName());
+			}
+		}
+		
+		// 4.获取所有的信息点
+		Set<String> equipCodes = equipTemp.keySet();
+		List<ObjectInfoDefine> funidList = this.relationReportService.queryFunidList(groupCode, projectId, equipCodes, null, null);
+		return this.exportEquipmentBindPointExcel(equipList, equipTemp, systemTemp, funidList, groupCode, projectId, projectName);
+	}
+	
+	/**
+	 * 下载报告-统计项目下已有的设备,以及静态和iot 信息点使用情况,以classCode为维度
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 * @return
+	 */
+	public List<EquipmentCountExcel> countClassCodeEquip(String groupCode, String projectId) {
+		String equipment = AdmObjectType.EQUIPMENT.getIndex();
+		
+		List<OrderItem> classCodeAsc = Collections.singletonList(OrderItem.asc("classCode"));
+		
+		// 1.获取项目名称
+		List<ObjectNode> projects = this.relationReportService.queryObjects(null, groupCode, projectId,
+				Sets.newHashSet(projectId), Sets.newHashSet(AdmObjectType.PROJECT.getIndex()), null, null);
+		if (CollectionUtil.isEmpty(projects)) {
+			return Lists.newArrayList();
+		}
+		String projectName = projects.get(0).has("localName") ? projects.get(0).get("localName").asText() : null;
+		
+		// 2.获取所有的设备对象数据
+		List<ObjectNode> equipList = this.relationReportService.queryObjects(null, groupCode, projectId,
+				null, null, Sets.newHashSet(equipment), classCodeAsc);
+		if (CollectionUtil.isEmpty(equipList)) {
+			return Lists.newArrayList();
+		}
+		
+		// 3.获取所有的设备、系统类定义信息
+		List<ObjectTypeDefine> classInfo = this.relationReportService.queryClassList(groupCode, projectId,
+				null, Sets.newHashSet(equipment, AdmObjectType.SYSTEM.getIndex()), null);
+		/** key-equipCode, value-equipName */
+		Map<String, String> equipTemp = new HashMap<String, String>();
+		/** key-systemCode, value-systemName */
+		Map<String, String> systemTemp = new HashMap<String, String>();
+		for (ObjectTypeDefine info : classInfo) {
+			if (info.getCode().length() > 5) {
+				equipTemp.put(info.getCode(), info.getName());
+			} else {
+				systemTemp.put(info.getCode(), info.getName());
+			}
+		}
+		
+		// 4.获取所有的信息点
+		Set<String> equipCodes = equipTemp.keySet();
+		List<ObjectInfoDefine> funidList = this.relationReportService.queryFunidList(groupCode, projectId, equipCodes, null, null);
+		
+		// 5.导出结果汇总返回
+		return this.exportClassEquipExcel(equipList, equipTemp, systemTemp, funidList, groupCode, projectId, projectName);
+	}
+	
+	/**
+	 * 构造 excel 设备数据--不在空间内的设备数据
+	 * 
+	 * @param equipList 设备数据集合
+	 * @param classDefine 类定义信息
+	 * @param excludeIds 需要剔除的设备ID集合
+	 * @param groupCode 
+	 * @param projectId 
+	 * @return
+	 */
+	private List<EquipmentExcel> exportEquipmentExcel(List<ObjectNode> equipList, Map<String, String> classDefine, Set<String> excludeIds, String groupCode, String projectId) {
+		/** key: 设备ID,value: 楼层名称 */
+		Map<String, String> floorNameTemp = new HashMap<String, String>();
+		this.findFloorName(floorNameTemp, groupCode, projectId);
+		
+		/** key: 设备ID,value: 建筑名称 */
+		Map<String, String> buildNameTemp = new HashMap<String, String>();
+		this.findBuildingName(buildNameTemp, groupCode, projectId);
+		
+		// 结果封装
+		List<EquipmentExcel> excelList = new ArrayList<EquipmentExcel>();
+		for (ObjectNode equip : equipList) {
+			String id = equip.get("id") == null ? null : equip.get("id").asText();
+			if (id != null && !excludeIds.contains(id)) {
+				EquipmentExcel excel = new EquipmentExcel();
+				excel.setId(id);
+				excel.setName(equip.get("name") == null ? null : equip.get("name").asText());
+				excel.setLocalId(equip.get("localId") == null ? null : equip.get("localId").asText());
+				excel.setLocalName(equip.get("localName") == null ? null : equip.get("localName").asText());
+				
+				String infos = equip.get("infos") == null ? null : equip.get("infos").asText();
+				if (StrUtil.isNotBlank(infos)) {
+					JSONObject parseObject = JSONObject.parseObject(infos);
+					excel.setBimId(parseObject.getString("bimId"));
+				}
+				
+				String classCode = equip.get("classCode") == null ? null : equip.get("classCode").asText();
+				excel.setClassCodeName(classCode == null ? null : classDefine.get(classCode));
+				
+				excel.setBuildName(buildNameTemp.get(id));
+				excel.setFloorName(floorNameTemp.get(id));
+				excel.setModelFileName("T1F10模型文件v18.rvt");	// 这里写死是不对的,需要后续再补充改变
+				excelList.add(excel);
+			}
+		}
+		return excelList;
+	}
+
+	/**
+	 * 构造 excel 设备数据--统计项目下已有的设备,信息点,每个设备
+	 * 
+	 * @param equipList
+	 * @param equipTemp
+	 * @param systemTemp
+	 * @param groupCode
+	 * @param projectId
+	 * @param projectName
+	 * @return
+	 */
+	private List<EquipmentBindPointExcel> exportEquipmentBindPointExcel(List<ObjectNode> equipList, Map<String, String> equipTemp, 
+			Map<String, String> systemTemp, List<ObjectInfoDefine> funidList, String groupCode, String projectId, String projectName) {
+		/** key: 设备ID,value: 楼层名称 */
+		Map<String, String> floorNameTemp = new HashMap<String, String>();
+		this.findFloorName(floorNameTemp, groupCode, projectId);
+		
+		/** key: 设备ID,value: 建筑名称 */
+		Map<String, String> buildNameTemp = new HashMap<String, String>();
+		this.findBuildingName(buildNameTemp, groupCode, projectId);
+		
+		// 信息点分类信息统计
+		/** key: classCode, value: 信息点 */
+		Map<String, Set<String>> infoCodes = new HashMap<String, Set<String>>();
+		/** key: classCode, value: 静态信息点的数量  */
+		Map<String, Integer> staticCount = new HashMap<String, Integer>();
+		/** key: classCode, value: 动态信息点的数量  */
+		Map<String, Integer> dynamicCount = new HashMap<String, Integer>();
+		/** key: classCode_infoCode, value: 动静态 */
+		Map<String, String> codeAttrbut = new HashMap<String, String>();
+		for (ObjectInfoDefine infoDefine : funidList) {
+			String classCode = infoDefine.getClassCode();
+			String category = infoDefine.getCategory();
+			if ("STATIC".equals(category)) {
+				int count = (staticCount.get(classCode) == null ? 0 : staticCount.get(classCode)) + 1;
+				staticCount.put(classCode, count);
+			} else {
+				int count = (dynamicCount.get(classCode) == null ? 0 : dynamicCount.get(classCode)) + 1;
+				dynamicCount.put(classCode, count);
+			}
+			
+			codeAttrbut.put(classCode + AdmCommonConstant.UNDERLINE + infoDefine.getCode(), category);
+			if (infoCodes.containsKey(classCode)) {
+				infoCodes.get(classCode).add(infoDefine.getCode());
+			} else {
+				infoCodes.put(classCode, Sets.newHashSet(infoDefine.getCode()));
+			}
+		}
+		
+		// 结果封装
+		List<EquipmentBindPointExcel> excelList = new ArrayList<EquipmentBindPointExcel>();
+		for (int i = 0; i < equipList.size(); i++) {
+			ObjectNode equip = equipList.get(i);
+			String id = equip.get("id") == null ? null : equip.get("id").asText();
+			String equipCode = equip.get("classCode") == null ? null : equip.get("classCode").asText();
+			String systemCode = (equipCode == null || equipCode.length() < 5) ? null : equipCode.substring(0, 4);
+			
+			EquipmentBindPointExcel excel = new EquipmentBindPointExcel();
+			excel.setIndex(i + 1);
+			excel.setProjectName(projectName);
+			excel.setBuildName(buildNameTemp.get(id));
+			excel.setFloorName(floorNameTemp.get(id));
+			excel.setSystemCode(systemCode);
+			excel.setSystemName(systemTemp.get(systemCode));
+			excel.setEquipCode(equipCode);
+			excel.setEquipName(equipTemp.get(equipCode));
+			excel.setEquipId(id);
+			excel.setLocalId(equip.get("localId") == null ? null : equip.get("localId").asText());
+			excel.setLocalName(equip.get("localName") == null ? null : equip.get("localName").asText());
+			
+			// 获取此classCode下有多少信息点、静态信息点、动态信息点
+			
+			// 静态的默认存在4个已绑信息点,ID、name、localId、localName
+			int nowStatic = 4;
+			int nowDynamic = 0;
+			int staticNum = staticCount.get(equipCode) == null ? nowStatic : staticCount.get(equipCode);
+			int dynamicNum = dynamicCount.get(equipCode) == null ? 0 : dynamicCount.get(equipCode);
+			excel.setNeedBindPointCount(staticNum + dynamicNum);
+			excel.setNeedStaticPointCount(staticNum);
+			excel.setNeedDynamicPointCount(dynamicNum);
+			
+			Set<String> needCodes = infoCodes.get(equipCode);
+			String infos = equip.get("infos") == null ? null : equip.get("infos").asText();
+			if (StrUtil.isNotBlank(infos)) {
+				JSONObject parseObject = JSONObject.parseObject(infos);
+				excel.setBimId(parseObject.getString("bimId"));
+				
+				// 判断已绑定多少信息点
+				Set<String> nowCodes = parseObject.keySet();
+				for (String key : nowCodes) {
+					if (needCodes.contains(key)) {
+						if ("STATIC".equals(codeAttrbut.get(equipCode + AdmCommonConstant.UNDERLINE + key))) {
+							nowStatic++;
+						} else {
+							nowDynamic++;
+						}
+					}
+				}
+			}
+			excel.setNowBindPointCount(nowStatic + nowDynamic);
+			excel.setNowStaticPointCount(nowStatic);
+			excel.setNowDynamicPointCount(nowDynamic);
+			excelList.add(excel);
+		}
+		return excelList;
+	}
+	
+	/**
+	 * 大概率不对,后续观察
+	 * 
+	 * @param equipList
+	 * @param equipTemp
+	 * @param systemTemp
+	 * @param funidList
+	 * @param groupCode
+	 * @param projectId
+	 * @param projectName
+	 * @return
+	 */
+	private List<EquipmentCountExcel> exportClassEquipExcel(List<ObjectNode> equipList, Map<String, String> equipTemp,
+			Map<String, String> systemTemp, List<ObjectInfoDefine> funidList, String groupCode, String projectId, String projectName) {
+		
+		/** key: classCode, value: 信息点 */
+		Map<String, Set<String>> infoCodes = new HashMap<String, Set<String>>();
+		/** key: classCode, value: 静态信息点的数量  */
+		Map<String, Integer> staticCount = new HashMap<String, Integer>();
+		/** key: classCode, value: 动态信息点的数量  */
+		Map<String, Integer> dynamicCount = new HashMap<String, Integer>();
+		/** key: classCode_infoCode, value: 动静态 */
+		Map<String, String> codeAttrbut = new HashMap<String, String>();
+		// 信息点数据汇总
+		for (ObjectInfoDefine infoDefine : funidList) {
+			String classCode = infoDefine.getClassCode();
+			String category = infoDefine.getCategory();
+			if ("STATIC".equals(category)) {
+				int count = (staticCount.get(classCode) == null ? 0 : staticCount.get(classCode)) + 1;
+				staticCount.put(classCode, count);
+			} else {
+				int count = (dynamicCount.get(classCode) == null ? 0 : dynamicCount.get(classCode)) + 1;
+				dynamicCount.put(classCode, count);
+			}
+			
+			codeAttrbut.put(classCode + AdmCommonConstant.UNDERLINE + infoDefine.getCode(), category);
+			if (infoCodes.containsKey(classCode)) {
+				infoCodes.get(classCode).add(infoDefine.getCode());
+			} else {
+				infoCodes.put(classCode, Sets.newHashSet(infoDefine.getCode()));
+			}
+		}
+		funidList.clear(); 	//即时清空
+		
+		/** key: 设备ID,value: 建筑Id */
+		Map<String, String> equipId2BuildId = new HashMap<String, String>();
+		/** key: 建筑ID,value: 建筑名称 */
+		Map<String, String> buildNameTemp = new HashMap<String, String>();
+		String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Bd.name();
+		List<ObjectDigital> buildDigitals = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, null, null);
+		if (CollectionUtil.isNotEmpty(buildDigitals)) {
+			for (ObjectDigital master : buildDigitals) {
+				List<ObjectDigital> slaveDigitals = master.getRelObjs();
+				ObjectDigital slave = CollectionUtil.isEmpty(slaveDigitals) ? null : slaveDigitals.get(0);
+				if (slave != null) {
+					equipId2BuildId.put(master.getId(), slave.getId());
+					buildNameTemp.put(slave.getId(), slave.getLocalName());
+				}
+			}
+		}
+		buildDigitals.clear();	// 即时清空
+		
+		/** key: classCode, value: 当BIMID不为空时,建筑ID不为空时,值+1 */
+		Map<String, Integer> equipBimIdByBuild = new HashMap<String, Integer>();
+		/** key: classCode, value: 当BIMID不为空时,建筑ID为空时,值+1 */
+		Map<String, Integer> equipBimIdByBuildNull = new HashMap<String, Integer>();
+		/** key: classCode, value: 当BIMID为空时,建筑ID不为空时,值+1 */
+		Map<String, Integer> equipBimIdNullByBuild = new HashMap<String, Integer>();
+		/** key: classCode, value: 当BIMID为空时,建筑ID为空时,值+1 */
+		Map<String, Integer> equipBimIdNullByBuildNull = new HashMap<String, Integer>();
+		
+		/** key: classCode, value: 已绑定的静态信息点数量 */
+		Map<String, Integer> equipStaticInfoTemp = new HashMap<String, Integer>();
+		/** key: classCode, value: 已绑定的动态信息点数量 */
+		Map<String, Integer> equipDynamicInfoTemp = new HashMap<String, Integer>();
+		
+		/** key: classCode, value: 建筑ID */
+		Map<String, String> classBuildId = new HashMap<String, String>();
+		/** key: classCode_建筑ID, value: infos字段包含信息点的设备数量 */
+		Map<String, Integer> classInfosByBuild = new HashMap<String, Integer>();
+		/** key: classCode, value: infos字段包含信息点且建筑ID为空的设备数量 */
+		Map<String, Integer> classInfosNotBuild = new HashMap<String, Integer>();
+		/** key: classCode, value: 存在建筑的设备数量 */
+		Map<String, Integer> classByBuild = new HashMap<String, Integer>();
+		/** key: classCode, value: 不存在建筑的设备数量 */
+		Map<String, Integer> classNotBuild = new HashMap<String, Integer>();
+		// 总结出如上map所需数据
+		for (int i = 0; i < equipList.size(); i++) {
+			ObjectNode equip = equipList.get(i);
+			String id = equip.get("id") == null ? null : equip.get("id").asText();
+			String classCode = equip.get("classCode") == null ? null : equip.get("classCode").asText();
+			String buildingId = equipId2BuildId.get(id); 	// 获取建筑ID
+			if (StrUtil.isBlank(buildingId)) {
+				classNotBuild.put(classCode, (classNotBuild.get(classCode) == null ? 0 : (classNotBuild.get(classCode) + 1)));
+			} else {
+				classByBuild.put(classCode, (classByBuild.get(classCode) == null ? 0 : (classByBuild.get(classCode) + 1)));
+				classBuildId.put(classCode, buildingId);
+			}
+			
+			int nowStatic = 0;
+			int nowDynamic = 0;
+			Set<String> needCodes = infoCodes.get(classCode);
+			String infos = equip.get("infos") == null ? null : equip.get("infos").asText();
+			if (StrUtil.isNotBlank(infos)) {
+				JSONObject parseObject = JSONObject.parseObject(infos);
+				String bimId = parseObject.getString("bimId");
+				if (StrUtil.isBlank(bimId)) {
+					if (StrUtil.isBlank(buildingId)) {
+						equipBimIdNullByBuildNull.put(id, (equipBimIdNullByBuildNull.get(id) == null ? 1 : (equipBimIdNullByBuildNull.get(id) + 1)));
+					} else {
+						equipBimIdNullByBuild.put(id, (equipBimIdNullByBuild.get(id) == null ? 1 : (equipBimIdNullByBuild.get(id) + 1)));
+					}
+				} else {
+					if (StrUtil.isBlank(buildingId)) {
+						equipBimIdByBuildNull.put(id, (equipBimIdByBuildNull.get(id) == null ? 1 : (equipBimIdByBuildNull.get(id) + 1)));
+					} else {
+						equipBimIdByBuild.put(id, (equipBimIdByBuild.get(id) == null ? 1 : (equipBimIdByBuild.get(id) + 1)));
+					}
+				}
+				
+				if (StrUtil.isBlank(buildingId)) {
+					classInfosNotBuild.put(classCode, (classInfosNotBuild.get(classCode) == null ? 1 : (classInfosNotBuild.get(classCode) + 1)));
+				} else {
+					String key = classCode + AdmCommonConstant.UNDERLINE + buildingId;
+					classInfosByBuild.put(key, (classInfosByBuild.get(key) == null ? 1 : (classInfosByBuild.get(key) + 1)));
+				}
+				// 判断已绑定多少信息点
+				Set<String> nowCodes = parseObject.keySet();
+				for (String key : nowCodes) {
+					if (needCodes.contains(key)) {
+						if ("STATIC".equals(codeAttrbut.get(classCode + AdmCommonConstant.UNDERLINE + key))) {
+							nowStatic++;
+						} else {
+							nowDynamic++;
+						}
+					}
+				}
+			}
+			
+			equipStaticInfoTemp.put(classCode, (equipStaticInfoTemp.get(classCode) == null ? nowStatic : (equipStaticInfoTemp.get(classCode) + nowStatic)));
+			equipDynamicInfoTemp.put(classCode, (equipDynamicInfoTemp.get(classCode) == null ? nowDynamic : (equipDynamicInfoTemp.get(classCode) + nowDynamic)));
+		}
+		equipList.clear();	//即时清空
+		
+		Set<String> classCodes = CollUtil.newHashSet(CollUtil.isNotEmpty(classByBuild.keySet()),classByBuild.keySet());
+		Set<String> keySet = classNotBuild.keySet();
+		classCodes.addAll(keySet);
+		
+		// 结果封装
+		int count = 0;
+		List<EquipmentCountExcel> excelList = new ArrayList<EquipmentCountExcel>();
+		for (String classCode : classCodes) {
+			String systemCode = (classCode == null || classCode.length() < 5) ? null : classCode.substring(0, 4);
+			String buildingId = classBuildId.get(classCode);
+			EquipmentCountExcel excel = new EquipmentCountExcel();
+			excel.setIndex(++count);
+			excel.setProjectName(projectName);
+			excel.setBuildName(buildingId == null ? null : (buildNameTemp.get(buildingId) == null ? null : buildNameTemp.get(buildingId)));
+			excel.setSystemCode(systemCode);
+			excel.setSystemName(systemTemp.get(systemCode));
+			excel.setEquipCode(classCode);
+			excel.setEquipName(equipTemp.get(classCode));
+			
+			if (StrUtil.isBlank(buildingId)) {
+				// 第7列,bimId为空的设备数量
+				excel.setEquipBimIdNullCount(equipBimIdNullByBuildNull.get(classCode) == null ? 0 : equipBimIdNullByBuildNull.get(classCode));
+				// 第8列,bimId不为空的数量 
+				excel.setEquipBimIdCount(equipBimIdByBuildNull.get(classCode) == null ? 0 : equipBimIdByBuildNull.get(classCode));
+				// 第9列,当前classCode下,建筑为空的设备
+				excel.setEquipCountByBuild(classNotBuild.get(classCode) == null ? 0 : classNotBuild.get(classCode));
+				// 第10列,当前classCode下,建筑为空且信息点不为空的设备
+				excel.setEquipBindPointCount(classInfosNotBuild.get(classCode) == null ? 0 : classInfosNotBuild.get(classCode));
+			} else {
+				// 第7列,bimId为空的设备数量
+				excel.setEquipBimIdNullCount(equipBimIdNullByBuild.get(classCode) == null ? 0 : equipBimIdNullByBuild.get(classCode));
+				// 第8列,bimId不为空的数量 
+				excel.setEquipBimIdCount(equipBimIdByBuild.get(classCode) == null ? 0 : equipBimIdByBuild.get(classCode));
+				// 第9列,当前建筑下的设备数量
+				excel.setEquipCountByBuild(classByBuild.get(classCode) == null ? 0 : classByBuild.get(classCode));
+				// 第10列,当前建筑下的设备且信息点不为空的数量
+				String key = classCode + AdmCommonConstant.UNDERLINE + buildingId;
+				excel.setEquipBindPointCount(classInfosByBuild.get(key) == null ? 0 : classInfosByBuild.get(key));
+			}
+			
+			// 静态的默认存在4个已绑信息点,ID、name、localId、localName
+			int staticNum = (staticCount.get(classCode) == null ? 0 : staticCount.get(classCode)) + 4;
+			int dynamicNum = dynamicCount.get(classCode) == null ? 0 : dynamicCount.get(classCode);
+			excel.setNeedStaticPointCount(staticNum);
+			excel.setNeedDynamicPointCount(dynamicNum);
+			excel.setNowStaticPointCount(equipStaticInfoTemp.get(classCode));
+			excel.setNowDynamicPointCount(equipDynamicInfoTemp.get(classCode));
+			excelList.add(excel);
+		}
+		
+		return excelList;
+	}
+	
+	/**
+	 * 获取建筑的名称
+	 * 
+	 * @param buildNameTemp key: 设备ID,value: 建筑名称
+	 * @param groupCode
+	 * @param projectId
+	 */
+	private void findBuildingName(Map<String, String> buildNameTemp, String groupCode, String projectId) {
+		// 获取建筑名称
+		String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Bd.name();
+		List<ObjectDigital> buildDigitals = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, null, null);
+		if (CollectionUtil.isNotEmpty(buildDigitals)) {
+			for (ObjectDigital master : buildDigitals) {
+				List<ObjectDigital> slaveDigitals = master.getRelObjs();
+				ObjectDigital slave = CollectionUtil.isEmpty(slaveDigitals) ? null : slaveDigitals.get(0);
+				if (slave != null) {
+					buildNameTemp.put(master.getId(), slave.getLocalName());
+				}
+			}
+		}
+	}
+	
+	/**
+	 * 获取楼层的名称
+	 * 
+	 * @param floorNameTemp key: 设备ID,value: 楼层名称
+	 * @param groupCode
+	 * @param projectId
+	 */
+	private void findFloorName(Map<String, String> floorNameTemp, String groupCode, String projectId) {
+		// 获取楼层名称
+		String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Fl.name();
+		List<ObjectDigital> floorDigitals = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, null, null);
+		if (CollectionUtil.isNotEmpty(floorDigitals)) {
+			for (ObjectDigital master : floorDigitals) {
+				List<ObjectDigital> slaveDigitals = master.getRelObjs();
+				ObjectDigital slave = CollectionUtil.isEmpty(slaveDigitals) ? null : slaveDigitals.get(0);
+				if (slave != null) {
+					floorNameTemp.put(master.getId(), slave.getLocalName());
+				}
+			}
+		}
+	}
+	
+}

+ 305 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/handler/SpaceRelationInfoHandler.java

@@ -0,0 +1,305 @@
+package com.persagy.proxy.adm.handler;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.persagy.dmp.common.context.AppContext;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectType;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.adm.request.AdmDCSQueryRequest;
+import com.persagy.proxy.adm.strategy.RelationObjectContext;
+import com.persagy.proxy.report.service.IRelationReportService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年10月18日 下午6:04:24
+ */
+@Component
+@RequiredArgsConstructor
+public class SpaceRelationInfoHandler {
+
+	private final RelationObjectContext relationObjectContext;
+	
+	private final IRelationReportService relationReportService;
+
+	/**
+	 * 查询
+	 *
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	public JSONObject querySpaceInfo(AdmDCSQueryRequest request, ObjectNode criteria, List<OrderItem> orderItem) throws Exception {
+		List<ObjectNode> resultList = null;
+		String groupCode = AppContext.getContext().getGroupCode();
+		String projectId = AppContext.getContext().getProjectId();
+		
+		JSONObject result = new JSONObject();
+		result.put("result", "success");
+		
+		String floorId = request.getFloorId();
+		String buildingId = request.getBuildingId();
+		Set<String> zoneTypeList = StrUtil.isNotEmpty(request.getZoneType()) ? Sets.newHashSet(request.getZoneType()) 
+				: (request.getZoneTypeList() == null ? Sets.newHashSet() : request.getZoneTypeList());
+		
+		if (StrUtil.isNotBlank(buildingId) && StrUtil.isNotBlank(floorId) && !"isnull".equals(floorId)) {
+			// 当建筑ID不为空、楼层ID不为空时
+			String graphAndRelKey = GraphCodeEnum.ArchForArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Sp2Fl.name();
+			List<ObjectDigital> allRelations = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, Sets.newHashSet(buildingId), null);
+			if (CollectionUtil.isNotEmpty(allRelations)) {
+				resultList = this.transferSpaceInfo(allRelations, buildingId, floorId);
+			}
+			
+		} else if (StrUtil.isNotBlank(buildingId) && StrUtil.isNotBlank(floorId) && "isnull".equals(floorId)) {
+			// 当建筑ID不为空、楼层ID为空时
+			this.querySpaceInfo(request, groupCode, projectId, buildingId, zoneTypeList, orderItem);
+			
+		} else if (StrUtil.isNotBlank(buildingId) && StrUtil.isBlank(floorId) && !"isnull".equals(buildingId)) {
+			// 当建筑ID不为空、楼层ID为空时
+			String graphAndRelKey = GraphCodeEnum.ArchForArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Sp2Bd.name();
+			List<ObjectDigital> allRelations = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, Sets.newHashSet(buildingId), null);
+			if (CollectionUtil.isNotEmpty(allRelations)) {
+				resultList = this.transferSpaceInfo(allRelations, buildingId, null);
+			}
+			
+		} else if (StrUtil.isNotBlank(buildingId) && StrUtil.isBlank(floorId) && "isnull".equals(buildingId)) {
+			// 当建筑ID为空、楼层ID为空时
+			resultList = this.querySpaceInfo(request, criteria, groupCode, projectId, zoneTypeList, orderItem);
+			
+		} else if (StrUtil.isBlank(buildingId) && StrUtil.isBlank(floorId)) {
+			// 直接获取所有的空间数据
+			List<ObjectNode> spacelist = this.relationReportService.queryObjects(criteria, groupCode, projectId, null, zoneTypeList, 
+					Sets.newHashSet(AdmObjectType.SPACE.getIndex()), orderItem);
+			resultList = this.fillSpaceInfo(spacelist, null, null);
+		}
+		
+		result.put("zoneType", request.getZoneType());
+		result.put("floorId", request.getFloorId());
+		result.put("total", CollectionUtil.isEmpty(resultList) ? 0 : resultList.size());
+		result.put("content", CollectionUtil.isEmpty(resultList) ? Lists.newArrayList() : resultList);
+		return result;
+	}
+	
+	/**
+	 * 获取空间信息,当楼层ID为空,建筑ID不为空时
+	 * @param request
+	 * @param groupCode
+	 * @param projectId
+	 * @param buildingId
+	 * @param zoneTypeList
+	 * @param orderItem
+	 * @return
+	 */
+	private List<ObjectNode> querySpaceInfo(AdmDCSQueryRequest request, String groupCode, String projectId, String buildingId, 
+			Set<String> zoneTypeList, List<OrderItem> orderItem) {
+		List<ObjectNode> resultList = null;
+		Set<String> spaceIds = new HashSet<String>();
+		Set<String> floorIds = new HashSet<String>();
+		Set<String> notBuildSpace = new HashSet<String>();
+		// 获取所有的楼层ID集合
+		List<ObjectRelation> relationObjects = this.queryObjectRelation(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), RelCodeEnum.Fl2Bd.name(), null, Sets.newHashSet(buildingId));
+		
+		// 获取所有楼层下的空间数据
+		if (CollectionUtil.isNotEmpty(relationObjects)) {
+			for (ObjectRelation objectRelation : relationObjects) {
+				floorIds.add(objectRelation.getObjFrom());
+			}
+			
+			// 根据楼层ID,获取所有的空间ID
+			relationObjects = this.queryObjectRelation(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), RelCodeEnum.Sp2Fl.name(), null, floorIds);
+			for (ObjectRelation objectRelation : relationObjects) {
+				spaceIds.add(objectRelation.getObjFrom());
+			}
+			// 再获取此建筑下,不是这些空间的空间
+			relationObjects = this.queryObjectRelation(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), RelCodeEnum.Sp2Bd.name(), null, Sets.newHashSet(buildingId));
+			for (ObjectRelation objectRelation : relationObjects) {
+				if (!spaceIds.contains(objectRelation.getObjFrom())) {
+					notBuildSpace.add(objectRelation.getObjFrom());
+				}
+			}
+			
+			if (CollectionUtil.isNotEmpty(notBuildSpace)){
+				// 获取所有的对象数据
+				resultList = this.relationReportService.queryObjects(null, groupCode, projectId, notBuildSpace, zoneTypeList, 
+    					Sets.newHashSet(AdmObjectType.SPACE.getIndex()), orderItem);
+    			this.fillSpaceInfo(resultList, buildingId, null);
+            }
+		} else {
+			// 获取所有的空间数据
+			String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Fl.name();
+			List<ObjectDigital> allRelations = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, Sets.newHashSet(buildingId), null);
+			if (CollectionUtil.isNotEmpty(allRelations)) {
+				resultList = this.transferSpaceInfo(allRelations, buildingId, null);
+			}
+		}
+		
+		spaceIds.clear();
+		notBuildSpace.clear();
+		return resultList;
+	}
+	
+
+	/**
+	 * 获取空间信息,当楼层ID为空,建筑ID为空时
+	 * 
+	 * @param request
+	 * @param groupCode
+	 * @param projectId
+	 * @return
+	 */
+	private List<ObjectNode> querySpaceInfo(AdmDCSQueryRequest request, ObjectNode criteria, String groupCode, String projectId, 
+			Set<String> zoneTypeList, List<OrderItem> orderItem) {
+		List<ObjectNode> resultList = null;
+		// 获取所有的建筑ID集合
+		List<ObjectNode> buildList = this.relationReportService.queryObjects(null, groupCode, projectId, null, null, 
+				Sets.newHashSet(AdmObjectType.BUILDING.getIndex()), orderItem);
+		if (CollectionUtil.isNotEmpty(buildList)) {
+			for (ObjectNode objectNode : buildList) {
+				String buildingId = objectNode.get("id").asText();
+				// 获取所有的空间数据
+				String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Fl.name();
+				List<ObjectDigital> allRelations = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, Sets.newHashSet(buildingId), null);
+				if (CollectionUtil.isNotEmpty(allRelations)) {
+					// 获取所有的对象数据
+					resultList = this.transferSpaceInfo(allRelations, buildingId, null);
+				}
+			}
+		} else {
+			// 获取所有的空间数据
+			List<ObjectNode> spacelist = this.relationReportService.queryObjects(criteria, groupCode, projectId, null, zoneTypeList, 
+					Sets.newHashSet(AdmObjectType.SPACE.getIndex()), orderItem);
+			resultList = this.fillSpaceInfo(spacelist, null, null);
+		}
+		
+		return resultList;
+	}
+	
+	/**
+	 * 转换数据
+	 * 
+	 * @param allRelations
+	 * @param buildingId
+	 * @param floorId
+	 * @return
+	 */
+	private List<ObjectNode> transferSpaceInfo(List<ObjectDigital> allRelations, String buildingId, String floorId) {
+		if (CollectionUtil.isEmpty(allRelations)) {
+			return null;
+		}
+		
+		List<ObjectNode> resultList = new ArrayList<ObjectNode>();
+		ObjectMapper objectMapper = SpringHelper.getBean(ObjectMapper.class);
+		for (ObjectDigital objectDigital : allRelations) {
+			ObjectNode result = objectMapper.createObjectNode();
+			
+			ObjectNode infos = objectDigital.getInfos();
+			result.put("bimLocation", infos.has("bimLocation") ? infos.get("bimLocation").asText() : null);
+			result.put("height", infos.has("height") ? infos.get("height").asText() : null);
+			result.put("outline", infos.has("outline") ? infos.get("outline").asText() : null);
+			result.put("floorId", "");
+			result.put("buildingId", buildingId);
+			result.put("classCode", objectDigital.getClassCode());
+			result.put("id", objectDigital.getId());
+			result.put("projectId", objectDigital.getProjectId());
+			result.put("localName", objectDigital.getLocalName());
+			result.put("name", objectDigital.getName());
+			result.putPOJO("infos", new JSONObject());
+			result.putPOJO("statistics", new JSONObject());
+			result.put("state", (objectDigital.getValid() == null || objectDigital.getValid() == 1) ? 0 : 1);
+			result.put("createTime", objectDigital.getCreationTime().toString("yyyy-MM-dd HH:mm:ss"));
+			
+			resultList.add(result);
+		}
+		
+		resultList.sort((r1, r2) -> {
+			return r2.get("createTime").asText().compareTo(r1.get("").asText());
+		});
+		
+		return resultList;
+	}
+
+	/**
+	 * 数据填充
+	 * 
+	 * @param queryObjects
+	 * @param buildingId
+	 * @param floorId
+	 * @return
+	 */
+	private List<ObjectNode> fillSpaceInfo(List<ObjectNode> queryObjects, String buildingId, String floorId) {
+		if (CollectionUtil.isEmpty(queryObjects)) {
+			return null;
+		}
+		
+		List<ObjectNode> resultList = new ArrayList<ObjectNode>();
+		ObjectMapper objectMapper = SpringHelper.getBean(ObjectMapper.class);
+		
+		for (ObjectNode objectNode : queryObjects) {
+			ObjectNode result = objectMapper.createObjectNode();
+			String infos = objectNode.has("infos") ? objectNode.get("infos").asText() : null;
+			if (StrUtil.isNotBlank(infos)) {
+				JSONObject infoObject = JSONObject.parseObject(infos);
+				
+				result.put("bimLocation", infoObject.getString("bimLocation"));
+				result.put("height", infoObject.getDouble("height"));
+				result.put("outline", infoObject.getString("outline"));
+				result.put("floorId", floorId);
+				result.put("buildingId", buildingId);
+			}
+			
+			result.put("classCode", objectNode.has("classCode") ? objectNode.get("classCode").asText() : null);
+			result.put("id", objectNode.has("id") ? objectNode.get("id").asText() : null);
+			result.put("projectId", objectNode.has("projectId") ? objectNode.get("projectId").asText() : null);
+			result.put("localName", objectNode.has("localName") ? objectNode.get("localName").asText() : null);
+			result.put("name", objectNode.has("name") ? objectNode.get("name").asText() : null);
+			
+			Long creationTime = objectNode.has("creationTime") ? objectNode.get("creationTime").asLong() : null;
+			result.put("createTime", creationTime == null ? null : new DateTime(creationTime).toString());
+			result.putPOJO("infos", new JSONObject());
+			result.putPOJO("statistics", new JSONObject());
+			result.put("state", objectNode.has("valid") ? (objectNode.get("valid").asInt(0) == 1 ? 0 : 1) : 0);
+			
+			resultList.add(result);
+		}
+		
+		return queryObjects;
+	}
+	
+	/**
+	 * 获取关系数据
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 * @param graphCode
+	 * @param relCode
+	 * @param objFroms
+	 * @param objTos
+	 * @return
+	 */
+	private List<ObjectRelation> queryObjectRelation(String groupCode, String projectId, String graphCode, String relCode, Set<String> objFroms, Set<String> objTos) {
+		List<ObjectRelation> relationObjects = this.relationReportService.findRelationObjects(groupCode, projectId, graphCode, relCode, objFroms, objTos);
+		return CollectionUtil.isEmpty(relationObjects) ? Lists.newArrayList() : relationObjects;
+	}
+
+}

+ 26 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/model/AdmBaseEntity.java

@@ -0,0 +1,26 @@
+package com.persagy.proxy.adm.model;
+
+import com.persagy.dmp.common.model.entity.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author lvxy
+ * @date 2021/9/13
+ */
+@Data
+@EqualsAndHashCode(callSuper=true)
+public abstract class AdmBaseEntity<T> extends BaseEntity {
+    /** 统计信息 */
+    private Map<String, Object> statistics;
+    /** 信息点 */
+    private Map<String, Object> infos;
+    /** 集团编码 */
+    private String groupCode;
+    /** 需要删除的对象 */
+    private Set<String> nullList;
+
+}

+ 26 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/model/AdmPoint.java

@@ -0,0 +1,26 @@
+package com.persagy.proxy.adm.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.persagy.proxy.relation.model.BaseEntity;
+import lombok.Data;
+
+/**
+ * 点位X 、Y
+ * @author lvxy
+ * @date 2021/8/17
+ */
+@Data
+public class AdmPoint extends BaseEntity {
+
+    /** 坐标x */
+    @JsonProperty("x")
+    private Double x;
+
+    /** 坐标y */
+    @JsonProperty("y")
+    private Double y;
+
+    /** 坐标z */
+    @JsonProperty("z")
+    private Double z;
+}

+ 25 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/model/TwicePointDTO.java

@@ -0,0 +1,25 @@
+package com.persagy.proxy.adm.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/***
+ * Description: 记录两组坐标的DTO类
+ * @author : lijie
+ * @date :2021/10/8 10:01
+ * Update By lijie 2021/10/8 10:01
+ */
+@Builder
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TwicePointDTO {
+
+    private Double x1;
+    private Double y1;
+    private Double x2;
+    private Double y2;
+
+}

+ 38 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmCountResponse.java

@@ -0,0 +1,38 @@
+package com.persagy.proxy.adm.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * ADM 通用返回结果
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdmCountResponse {
+    private final static String SUCCESS = "success";
+    private final static String FAILURE = "failure";
+    
+    /** 结果 */
+    private String result;
+    /** 消息 */
+    private String message;
+    /** 符合条件的总记录数 */
+    private Long count;
+
+    public static AdmCountResponse success() {
+        return new AdmCountResponse(SUCCESS, null, null);
+    }
+    
+    public static AdmCountResponse success(Long count) {
+        return new AdmCountResponse(SUCCESS, null, count);
+    }
+
+    public static AdmCountResponse failure(String message) {
+        return new AdmCountResponse(FAILURE, message, null);
+    }
+
+}

+ 20 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmCreateRequest.java

@@ -0,0 +1,20 @@
+package com.persagy.proxy.adm.request;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * ADM通用新增参数
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Data
+public class AdmCreateRequest<T> {
+    /** 如果对象在库中已存在,是否执行合并操作 */
+    private Boolean isMerge = false;
+    /** 更新内容 */
+    private List<T> content;
+    /** 级联对象列表 */
+    private List<Object> cascade;
+}

+ 49 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmCreateResponse.java

@@ -0,0 +1,49 @@
+package com.persagy.proxy.adm.request;
+
+import cn.hutool.core.collection.CollUtil;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ADM 通用创建返回结果
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdmCreateResponse extends AdmResponse {
+    private final static String SUCCESS = "success";
+    private final static String FAILURE = "failure";
+    /** 错误数据主从对象 1 主对象  2 从对象 */
+    private String errorType;
+    /**
+     * 查询到的数据列表
+     */
+    private List<?> entityList;
+
+    public AdmCreateResponse(String result, String message, Long total, Long count, Integer pageNumber, Integer pageSize, List<?> content, String floorId, String zoneType, List<?> entityList, String errorType) {
+        super(result, message, total, count, pageNumber, pageSize, content, floorId, zoneType);
+        this.entityList = entityList;
+        this.errorType = errorType;
+    }
+    public static AdmCreateResponse failure(String message) {
+        return new AdmCreateResponse(FAILURE, message, null, null, null, null, null, null, null, null, null);
+    }
+    public static AdmCreateResponse failure(String message,String errorType) {
+        return new AdmCreateResponse(FAILURE, message,null, null, null, null, null, null, null, new ArrayList<>(), errorType);
+    }
+    public static AdmCreateResponse success() {
+        return new AdmCreateResponse(SUCCESS, "", 0L,null, 1, 500, null,null,null,null,null);
+    }
+    public static AdmCreateResponse success(String message) {
+        return new AdmCreateResponse(SUCCESS, message, 0L,null, 1, 500, null,null,null,null,null);
+    }
+    public static AdmCreateResponse success(List<?> content) {
+        return new AdmCreateResponse(SUCCESS, "", CollUtil.isEmpty(content) ? 0L :content.size()*1L,null, 1, 50,null ,null,null,CollUtil.isEmpty(content) ? new ArrayList(1): content,null);
+    }
+}

+ 34 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmDCSQueryRequest.java

@@ -0,0 +1,34 @@
+package com.persagy.proxy.adm.request;
+
+import com.fasterxml.jackson.annotation.JsonAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.util.Set;
+
+/**
+ * 业务空间查询请求体
+ * @author lvxy
+ * @date 2021/9/8
+ */
+@Data
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper=true)
+public class AdmDCSQueryRequest extends AdmQueryCriteria {
+    /** 楼层id */
+    @JsonAlias(value = {"FloorId", "floorId"})
+    private String floorId;
+
+    /** 建筑id */
+    @JsonAlias(value = {"BuildingId", "buildingId"})
+    private String buildingId;
+
+    /** 空间类型 */
+    @JsonAlias(value = {"zoneType", "ZoneType"})
+    private String zoneType;
+
+    /** 空间类型 空间类型列表 */
+    @JsonAlias(value = {"zoneTypeList", "ZoneTypeList"})
+    private Set<String> zoneTypeList;
+}

+ 27 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmDictQueryCriteria.java

@@ -0,0 +1,27 @@
+package com.persagy.proxy.adm.request;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @ClassName AdmEquipFamilyCategory
+ * @Description: 字典查询通用条件
+ * @Author linhuili
+ * @Date 2021/9/1 18:05
+ * @Version V1.0
+ **/
+@Data
+@EqualsAndHashCode(callSuper=true)
+public class AdmDictQueryCriteria extends AdmQueryCriteria {
+
+    /** 查询类型 common-平台级,project-项目级 */
+    private String dictType;
+
+    /** 信息点类型 */
+    private String type;
+
+    /** 信息点类型 ,兼容拓扑图查询参数*/
+    @JsonProperty(value = "Type")
+    private String labslType;
+}

+ 41 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmManualRelCalResponse.java

@@ -0,0 +1,41 @@
+package com.persagy.proxy.adm.request;
+
+import lombok.*;
+
+import java.util.List;
+
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class AdmManualRelCalResponse extends AdmResponse {
+
+    private final static String SUCCESS = "success";
+    private final static String FAILURE = "failure";
+
+    /** 方向 Left、right */
+    private String direction;
+
+    public AdmManualRelCalResponse(String result, String message, Long total, Integer pageNumber, Integer pageSize, List<?> content, String direction) {
+        this.setResult(result);
+        this.setMessage(message);
+        this.setTotal(total);
+        this.setPageNumber(pageNumber);
+        this.setPageSize(pageSize);
+        this.setContent(content);
+        this.setDirection(direction);
+    }
+
+    public static AdmResponse success() {
+        return new AdmManualRelCalResponse(SUCCESS, null, null, null, null, null,null);
+    }
+
+    public static AdmResponse failure(String message, String direction) {
+        return new AdmManualRelCalResponse(FAILURE, message, null, null, null, null,direction);
+    }
+
+    public static AdmResponse success(List<?> content, String direction) {
+        return new AdmManualRelCalResponse(SUCCESS, null, null, null, null, content,direction);
+    }
+}

+ 110 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmQueryCriteria.java

@@ -0,0 +1,110 @@
+package com.persagy.proxy.adm.request;
+
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonAlias;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * ADM通用查询条件
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Data
+public class AdmQueryCriteria {
+
+    /** 可取得的最大记录数 */
+    private Integer maxRow = 100000;
+    /** 第几页(从1开始) */
+    private Integer pageNumber;
+    /** 每页记录数(0 < 记录数 < 1000) */
+    private Integer pageSize;
+    /** 查询条件 */
+    @JsonAlias(value = {"filters", "Filters"})
+    private String filters;
+    /** 排序条件 */
+    private String orders;
+    /** 去除重复记录 */
+    private Boolean distinct;
+    /** 级联对象属性名 - 为级联对象时有值 */
+    @JsonAlias(value = {"name", "Name"})
+    private String name;
+    /** 字段影射,空为查询所有字段 */
+    private List<String> projection;
+    /** 级联对象列表 */
+    @JsonAlias(value = {"cascade", "Cascade"})
+    private List<AdmQueryCriteria> cascade;
+    /** 分组统计 */
+    private AdmQueryGroup group;
+    /** 是否只统计总数 */
+    private boolean onlyCount = false;
+    /** 关系查询条件 */
+    private ObjectNode relationFrom;
+    /** 关系查询条件 */
+    private ObjectNode relationTo;
+
+    /**
+     * 拼接条件
+     * @param addFilter
+     */
+    public void addFilters(String addFilter) {
+        if(StrUtil.isBlank(addFilter)) {
+            return;
+        }
+        if(StrUtil.isBlank(filters)) {
+            filters = addFilter;
+            return;
+        }
+        filters = filters + " and " + addFilter;
+    }
+
+    /**
+     * 设置关系条件
+     * @param isFrom 是否查询from结果
+     * @param graphCode
+     * @param relCode
+     * @param objId
+     */
+    public void resetRelationCond(boolean isFrom, String graphCode, String relCode, String objId) {
+        resetRelationCond(isFrom, graphCode, relCode, objId, true);
+    }
+
+    /**
+     * 设置关系条件
+     * @param isFrom 是否查询from结果
+     * @param graphCode
+     * @param relCode
+     * @param objId
+     * @param bindFlag
+     */
+    public void resetRelationCond(boolean isFrom, String graphCode, String relCode, String objId, boolean bindFlag) {
+        resetRelationCond(isFrom, graphCode, relCode, null, objId, bindFlag);
+    }
+
+    /**
+     * 设置关系条件
+     * @param isFrom 是否查询from结果
+     * @param graphCode
+     * @param relCode
+     * @param relValue
+     * @param objId
+     * @param bindFlag
+     */
+    public void resetRelationCond(boolean isFrom, String graphCode, String relCode, String relValue, String objId, boolean bindFlag) {
+        ObjectNode relationCond = JsonNodeFactory.instance.objectNode();
+        relationCond.put("graphCode", graphCode);
+        relationCond.put("relCode", relCode);
+        relationCond.put("relValue", relValue);
+        relationCond.put("$bindFlag", bindFlag);
+        if(isFrom) {
+            relationCond.put("objTo", objId);
+            setRelationFrom(relationCond);
+        } else {
+            relationCond.put("objFrom", objId);
+            setRelationTo(relationCond);
+        }
+    }
+}

+ 28 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmQueryGroup.java

@@ -0,0 +1,28 @@
+package com.persagy.proxy.adm.request;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * ADM通用查询条件 - 分组条件
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Data
+public class AdmQueryGroup {
+
+    /** 统计数量 */
+    private Boolean count;
+    /** 平均值 */
+    private List<String> avgList;
+    /** 最大值 */
+    private List<String> maxList;
+    /** 最小值 */
+    private List<String> minList;
+    /** 名称 */
+    private List<String> nameList;
+    /** 汇总值 */
+    private List<String> sumList;
+
+}

+ 91 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmResponse.java

@@ -0,0 +1,91 @@
+package com.persagy.proxy.adm.request;
+
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.persagy.proxy.adm.utils.AdmEntityTransferUtil;
+import com.persagy.proxy.common.entity.DmpResult;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * ADM 通用返回结果
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdmResponse {
+    private final static String SUCCESS = "success";
+    private final static String FAILURE = "failure";
+    /** 结果 */
+    private String result;
+    /** 消息 */
+    private String message;
+    /** 符合条件的总记录数 */
+    private Long total;
+    private Long count;
+    /** 页码 */
+    private Integer pageNumber;
+    /** 每页条数 */
+    private Integer pageSize;
+    /** 查询到的数据列表 */
+    private List<?> content;
+    /**楼层id*/
+    private String floorId;
+    /**空间功能类型*/
+    private String zoneType;
+
+    public static AdmResponse success() {
+        return new AdmResponse(SUCCESS, "", 0L,null, 1, 500, new ArrayList<>(1),null,null);
+    }
+
+    public static AdmResponse failure(String message) {
+        return new AdmResponse(FAILURE, message, null, null, null, null, new ArrayList<>(1),null,null);
+    }
+
+    public static AdmResponse success(List<?> content) {
+        return new AdmResponse(SUCCESS, "", CollUtil.isEmpty(content) ? 0L :content.size()*1L,null, 1, 50, CollUtil.isEmpty(content) ? new ArrayList<>(1): content,null,null);
+    }
+    public static AdmResponse success(List<?> content, AdmQueryCriteria request) {
+        int pagesize = 50;
+        if(request!= null && request.getPageNumber() != null && request.getPageNumber() > 0)
+            pagesize = request.getPageNumber();
+        int pageNum = 1;
+        if(request!= null && request.getPageSize() != null && request.getPageSize() > 0){
+            pageNum = request.getPageSize();
+        }
+        return new AdmResponse(SUCCESS, "", CollUtil.isEmpty(content) ? 0L :content.size()*1L,CollUtil.isEmpty(content) ? 0L :content.size()*1L, pageNum, pagesize, CollUtil.isEmpty(content) ? new ArrayList<>(1): content,null,null);
+    }
+    public static AdmResponse success(String message) {
+        return new AdmResponse(SUCCESS, message, null,null, null,null,null,null,null);
+    }
+
+    /**
+     * 从数据中台结果转换
+     * @param admRequest
+     * @param dmpResult
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> AdmResponse fromDmp(AdmQueryCriteria admRequest, DmpResult<JSONArray> dmpResult, Class<T> clazz) {
+        if(!DmpResult.SUCCESS.equals(dmpResult.getResult())) {
+            return failure("调用中台查询接口出错:" + dmpResult.getMessage());
+        }
+        // 转换为结果
+        List<T> admVOs = AdmEntityTransferUtil.toAdmMultiEntity(dmpResult.getData(), admRequest.getProjection(), clazz);
+        Long total = dmpResult.getCount() == null ? null : dmpResult.getCount().longValue();
+        Integer pageNo = admRequest == null ? null : admRequest.getPageNumber();
+        Integer pageSize = admRequest == null ? null : admRequest.getPageSize();
+        if(admRequest.isOnlyCount()){
+            return new AdmResponse(SUCCESS, null, null,total, pageNo, pageSize, CollUtil.isEmpty(admVOs) ? new ArrayList<>(1) : admVOs,null,null);
+        }else {
+            return new AdmResponse(SUCCESS, null, total,null, pageNo, pageSize, CollUtil.isEmpty(admVOs) ? new ArrayList<>(1) : admVOs,null,null);
+        }
+    }
+}

+ 20 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmUpDataFloorAndBuildingRequests.java

@@ -0,0 +1,20 @@
+package com.persagy.proxy.adm.request;
+
+import lombok.Data;
+
+/**
+ * 间和楼层建筑的关系
+ * @author lvxy
+ * @date 2021/9/7
+ */
+@Data
+public class AdmUpDataFloorAndBuildingRequests {
+    /** 业务空间id */
+    private String spaceId;
+
+    /** 建筑或楼层id */
+    private String id;
+
+    /** 业务空间类型 */
+    private String type;
+}

+ 22 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/request/AdmZoneEquipQueryRequest.java

@@ -0,0 +1,22 @@
+package com.persagy.proxy.adm.request;
+
+import com.persagy.proxy.adm.request.AdmQueryCriteria;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author lvxy
+ * @date 2021/9/24
+ */
+@Data
+@EqualsAndHashCode(callSuper=true)
+public class AdmZoneEquipQueryRequest extends AdmQueryCriteria {
+    /**所属业务空间类型", example = "TenantZone" */
+    private String zoneType;
+
+    /** "所属业务空间Id", example = "Sp*****" */
+    private String zoneId;
+
+    /**"不在任何业务空间内的设备或部件(true)", example = "true" */
+    private Boolean notInZone = false;
+}

+ 85 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/IAdmBaseService.java

@@ -0,0 +1,85 @@
+package com.persagy.proxy.adm.service;
+
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.proxy.adm.request.AdmQueryCriteria;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+import java.util.List;
+
+/**
+ * ADM 通用接口
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+public interface IAdmBaseService<T> {
+
+    /**
+     * 查询
+     * @param context
+     * @param request
+     * @param clazz
+     * @return
+     */
+    AdmResponse doQuery(InstanceUrlParam context, AdmQueryCriteria request, Class<T> clazz);
+
+    /**
+     * 新增
+     * @param context
+     * @param clazz
+     * @param voList
+     * @return
+     */
+    List<T> doInsert(InstanceUrlParam context, Class<T> clazz, List<T> voList);
+
+    /**
+     * 修改
+     * @param context
+     * @param clazz
+     * @param voList
+     * @return
+     */
+    List<T> doUpdate(InstanceUrlParam context, Class<T> clazz, List<T> voList);
+
+    /**
+     * 删除
+     * @param context
+     * @param voList
+     * @return
+     */
+    void doDelete(InstanceUrlParam context, List<T> voList);
+
+    /**
+     * 根据物理世界对象查询条件查询
+     * @param request
+     * @return
+     */
+    AdmResponse doQuery(InstanceUrlParam context, QueryCriteria request, Class<T> clazz);
+
+    /**
+     * 条件查询标记计算关系
+     * @param context
+     * @param dmpRequest
+     * @param clazz
+     * @return
+     */
+    AdmResponse doQueryRelationProjectCal(InstanceUrlParam context, QueryCriteria dmpRequest, Class<T> clazz);
+
+    /**
+     * 修改标记计算关系
+     * @param context
+     * @param clazz
+     * @param voList
+     * @return
+     */
+    List<T> doUpdateRelationProjectCal(InstanceUrlParam context, Class<T> clazz, List<T> voList);
+
+    /**
+     * 查询对象类型
+     * @param context
+     * @param request
+     * @param clazz
+     * @return
+     */
+    AdmResponse queryObjectClassCode(InstanceUrlParam context, AdmQueryCriteria request, Class<T> clazz);
+}

+ 38 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/IAdmRelationService.java

@@ -0,0 +1,38 @@
+package com.persagy.proxy.adm.service;
+
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+import com.persagy.proxy.common.entity.RelationDTO;
+
+import java.util.List;
+
+/**
+ * ADM 关系 通用 Service
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+public interface IAdmRelationService {
+
+    /**
+     * 保存
+     * @param param 上下文
+     * @param voList 关系对象数组 - 在Controller中直接构建好,参考(datasyn中DataCenterSync.kt)
+     */
+    void doSave(InstanceUrlParam param, List<RelationDTO> voList);
+
+    /**
+     * 删除
+     * @param param 上下文
+     * @param criteria
+     */
+    void doDelete(InstanceUrlParam param, QueryCriteria criteria);
+
+    /**
+     * 通过条件查询
+     * @param param
+     * @param criteria
+     * @return
+     */
+    List<ObjectRelation> queryByCondition(InstanceUrlParam param, QueryCriteria criteria);
+}

+ 542 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/impl/AbstractAdmBaseServiceImpl.java

@@ -0,0 +1,542 @@
+package com.persagy.proxy.adm.service.impl;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import cn.hutool.core.bean.BeanUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.constant.ValidEnum;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.entity.BaseEntity;
+import com.persagy.dmp.common.utils.JsonHelper;
+import com.persagy.dmp.digital.client.DigitalObjectFacade;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.annotations.CascadeColumn;
+import com.persagy.proxy.adm.request.AdmQueryCriteria;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.adm.service.IAdmBaseService;
+import com.persagy.proxy.adm.service.IAdmRelationService;
+import com.persagy.proxy.adm.utils.AdmEntityTransferUtil;
+import com.persagy.proxy.adm.utils.AdmQueryCriteriaHelper;
+import com.persagy.proxy.common.client.DmpRwdClient;
+import com.persagy.proxy.common.entity.DmpResult;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * ADM 抽象实现类
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Slf4j
+public class AbstractAdmBaseServiceImpl<T> implements IAdmBaseService<T> {
+
+    @Autowired
+    private DmpRwdClient rwdClient;
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    /**
+     * 查询
+     * @param request
+     * @return
+     */
+    @Override
+    public AdmResponse doQuery(InstanceUrlParam context, AdmQueryCriteria request, Class<T> clazz) {
+        // 转换为数据中台查询条件
+        QueryCriteria dmpRequest = AdmQueryCriteriaHelper.toDmpCriteria(request);
+        // 提供一个钩子方法用于处理已封装好的中台查询参数(因传参有buildingId而处理)
+        processDmpCriteria(dmpRequest);
+        // 转换参数
+        JSONObject para = null;
+        try {
+            para = JsonHelper.toJsonObject(dmpRequest);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+            return AdmResponse.failure("参数格式有误");
+        }
+        log.info("request:{},dmpRequest:{}, dmp-param: {}", request.toString(), dmpRequest.toString(), para.toString());
+        // 调用中台查询
+        DmpResult<JSONArray> dmpResult = rwdClient.queryObject(context, para);
+        processResultAfterQuery(dmpResult);
+        List<T> admVOs = AdmEntityTransferUtil.toAdmMultiEntity(dmpResult.getData(), request.getProjection(), clazz);
+        //List<T> admVOs = AdmEntityTransferUtil.toAdmMultiEntityExtra(dmpResult.getData(), request.getProjection(), clazz);
+        // 级联查询
+        processCascade(context, admVOs, request.getName(), request.getCascade());
+        // 设置返回值
+        AdmResponse response = AdmResponse.success(admVOs);
+        Long total = dmpResult.getCount() == null ? null : dmpResult.getCount().longValue();
+        if(request.isOnlyCount()){
+            response.setTotal(null);
+            response.setCount(total);
+        }else {
+            response.setTotal(total);
+        }
+        response.setPageNumber(request.getPageNumber());
+        response.setPageSize(request.getPageSize());
+        return response;
+    }
+    /***
+     * Description: 提供一个钩子方法用于处理已封装好的中台查询参数(因传参有buildingId而处理)
+     * @param dmpRequest : 中台查询参数
+     * @return : void
+     * @author : lijie
+     * @date :2021/10/28 20:23
+     * Update By lijie 2021/10/28 20:23
+     */
+    protected void processDmpCriteria(QueryCriteria dmpRequest) {
+        // 空方法,需要时子类重写
+    }
+
+    /**
+     * 处理级联查询
+     * @param context
+     * @param admVOs
+     * @param name
+     * @param cascades
+     */
+    public void processCascade(InstanceUrlParam context, List admVOs, String name, List<AdmQueryCriteria> cascades) {
+        if(CollUtil.isEmpty(admVOs) || CollUtil.isEmpty(cascades)) {
+            return;
+        }
+        Map<String, Object> voMap = CollUtil.fieldValueMap(admVOs, BaseEntity.PROP_ID);
+        Object simpleVO = admVOs.get(0);
+        for(AdmQueryCriteria cascade:cascades) {
+            if(StrUtil.isBlank(cascade.getName())){
+                //处理 级联查询参数name首字母大写cascade": [ {"Name": "property"}]
+                continue;
+            }
+            // 获取关联对象的Class
+            Field casField = ReflectUtil.getField(simpleVO.getClass(), cascade.getName());
+            if(casField == null) {
+                continue;
+            }
+            // 获取级联信息
+            CascadeColumn annotationInfo = casField.getAnnotation(CascadeColumn.class);
+            if(annotationInfo == null) {
+                continue;
+            }
+            Class clazz = getFieldRealClass(casField);
+            // 获取关联对象的类型
+            String objectType = getObjTypeByClass(clazz);
+            if(StrUtil.isBlank(objectType)) {
+                continue;
+            }
+            cascade.setName(objectType);
+            // 转换为数据中台查询条件
+            QueryCriteria dmpRequest = AdmQueryCriteriaHelper.toDmpCriteria(cascade);
+            // 拼接关系条件,得到关系映射
+            Map<String, List<String>> idMap = ensureRelationCond(context, dmpRequest.getCriteria(), voMap.keySet(), annotationInfo);
+            if(MapUtil.isEmpty(idMap)) {
+                continue;
+            }
+            // 查询结果
+            List vos = queryByCondition(context, dmpRequest, cascade.getProjection(), clazz);
+            if(CollUtil.isEmpty(vos)) {
+                continue;
+            }
+            // 写回原对象中
+            writeToVOs(voMap, idMap, vos, casField);
+            // 递归继续处理
+            processCascade(context, vos, objectType, cascade.getCascade());
+        }
+    }
+
+    /**
+     * 拼接关系条件
+     * @param context
+     * @param node
+     * @param idList
+     * @param annotationInfo
+     * @return
+     */
+    private Map<String, List<String>> ensureRelationCond(InstanceUrlParam context, ObjectNode node, Set<String> idList, CascadeColumn annotationInfo) {
+        if(CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        // 查询关系
+        List<ObjectRelation> relations = queryRelations(context, idList, annotationInfo);
+        ArrayNode array = node.putObject(BaseEntity.PROP_ID).putArray("$in");
+        // 拼接查询条件
+        if(CollUtil.isEmpty(relations)) {
+            array.add("0");
+        } else {
+            List<String> relList = CollUtil.getFieldValues(relations, annotationInfo.selectToObj()?"objTo":"objFrom", String.class);
+            relList.forEach(id -> array.add(id));
+        }
+        if(annotationInfo.selectToObj()){
+            return groupMapList(relations, "objFrom", "objTo");
+        }else{
+            return groupMapList(relations, "objTo", "objFrom");
+        }
+
+    }
+
+    /**
+     * 将集合转换为Map
+     * @param list 集合
+     * @param keyField key属性名
+     * @param valueField value属性名
+     * @return
+     */
+    private static Map<String, List<String>> groupMapList(List<?> list, String keyField, String valueField) {
+        if(CollUtil.isEmpty(list)) {
+            return null;
+        }
+        Map<String, List<String>> groupMap = new HashMap<>();
+        for(Object vo:list) {
+            String key = (String) ReflectUtil.getFieldValue(vo, keyField);
+            String value = (String) ReflectUtil.getFieldValue(vo, valueField);
+            if(!StrUtil.isAllNotBlank(key, value)) {
+                continue;
+            }
+            List<String> valueList = groupMap.get(key);
+            if(CollUtil.isEmpty(valueList)) {
+                valueList = new ArrayList<>();
+                groupMap.put(key, valueList);
+            }
+            valueList.add(value);
+        }
+        return groupMap;
+    }
+
+    /**
+     * 查询关系
+     * @param context
+     * @param idList
+     * @param anno
+     * @return
+     */
+    private List<ObjectRelation> queryRelations(InstanceUrlParam context, Set<String>idList, CascadeColumn anno) {
+        // 如果没有任何配置,不处理
+        if(StrUtil.isBlank(anno.graphCode()) && StrUtil.isBlank(anno.relCode()) &&
+                StrUtil.isBlank(anno.relValue())) {
+            return null;
+        }
+        // 查询关系
+        QueryCriteria queryRequest = new QueryCriteria();
+        ObjectNode criteria = JsonNodeFactory.instance.objectNode();
+        queryRequest.setCriteria(criteria);
+        boolean isSelectTo = anno.selectToObj();
+        criteria.put(BaseEntity.PROP_VALID, ValidEnum.TRUE.getType());
+        putString(criteria, "graphCode", anno.graphCode());
+        putString(criteria, "relCode", anno.relCode());
+        putString(criteria, "relValue", anno.relValue());
+        ArrayNode array = criteria.putObject(isSelectTo?"objFrom":"objTo").putArray("$in");
+        idList.forEach(id -> array.add(id));
+        return SpringHelper.getBean(IAdmRelationService.class).queryByCondition(context, queryRequest);
+    }
+
+    /**
+     * 添加字符串条件
+     * @param node
+     * @param key
+     * @param value
+     */
+    private void putString(ObjectNode node, String key, String value) {
+        if(StrUtil.isBlank(value)) {
+            return;
+        }
+        node.put(key, value);
+    }
+
+    /**
+     * 将子集写回到对象中
+     * @param voMap 原始对象Map
+     * @param idMap 主键映射<mainId, List<subId>>
+     * @param vos 子对象
+     * @param casField 子对象对应属性
+     */
+    private <V> void writeToVOs(Map<String, Object> voMap, Map<String, List<String>> idMap, List<V> vos, Field casField) {
+        if(CollUtil.isEmpty(vos) || MapUtil.isEmpty(idMap)) {
+            return;
+        }
+        // 转换为Map
+        Map<String, V> subVOMap = CollUtil.fieldValueMap(vos, BaseEntity.PROP_ID);
+        // 是否为集合
+        boolean isList = List.class.isAssignableFrom(casField.getType());
+        // 按对象循环
+        for(String id:voMap.keySet()) {
+            Object mainVO = voMap.get(id);
+            List<String> subIdList = idMap.get(id);
+            if(CollUtil.isEmpty(subIdList)) {
+                continue;
+            }
+            // 如果是集合
+            if(isList) {
+                // 取出对应的对象集合
+                Map<String, V> currVOMap = MapUtil.filter(subVOMap, subIdList.toArray(new String[0]));
+                // 2021年11月11日17:30:04,by lijie.解决级联查询已经排好序的列表错乱问题
+                List<V> currList = vos.stream().filter(vo -> currVOMap.containsKey(BeanUtil.getFieldValue(vo, BaseEntity.PROP_ID)))
+                        .collect(Collectors.toList());
+                // List<V> voList = CollUtil.newArrayList(currVOMap.values());
+                ReflectUtil.setFieldValue(mainVO, casField, currList);
+            } else {
+                // 非集合取第一个即可
+                String subId = subIdList.get(0);
+                V vo = subVOMap.get(subId);
+                ReflectUtil.setFieldValue(mainVO, casField, vo);
+            }
+        }
+    }
+
+    /**
+     * 调用Client查询
+     * @param context
+     * @param criteria
+     * @param projection
+     * @param clazz
+     * @return
+     */
+    private <V> List<V> queryByCondition(InstanceUrlParam context, QueryCriteria criteria, List<String> projection, Class<V> clazz) {
+        // 转换参数
+        if(criteria == null) {
+            return null;
+        }
+        List<ObjectNode> objects = DigitalObjectFacade.query(context.getGroupCode(), context.getProjectId(),
+                context.getAppId(), null, criteria);
+        return AdmEntityTransferUtil.toAdmMultiEntity(objects, projection, clazz);
+    }
+
+    /**
+     * 获取实际的Class
+     * @param casField
+     * @return
+     */
+    private Class getFieldRealClass(Field casField) {
+        // 取到Field
+        Class clazz = casField.getType();
+        // 如果是集合,则取实际的对象
+        if(List.class.isAssignableFrom(clazz)) {
+            clazz = (Class) ((ParameterizedType) casField.getGenericType()).getActualTypeArguments()[0];
+        }
+        return clazz;
+    }
+
+    /**
+     * 通过Class获取其对象类型
+     * @param clazz
+     * @return
+     */
+    private String getObjTypeByClass(Class clazz) {
+        // 获取关联对象的类型
+        String objectType = null;
+        try {
+            objectType = (String) ReflectUtil.getFieldValue(clazz.newInstance(), "objectType");
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+        return objectType;
+    }
+
+    /**
+     * 新增
+     * @param context
+     * @param clazz
+     * @param voList
+     * @return
+     */
+    @Override
+    public List<T> doInsert(InstanceUrlParam context, Class<T> clazz, List<T> voList) {
+        if(CollUtil.isEmpty(voList)) {
+            return null;
+        }
+        ArrayNode vos = AdmEntityTransferUtil.toDmpMultiEntity(voList);
+        // 调用中台新增
+        DmpResult<JSONArray> response = rwdClient.createObject(context, JSONArray.parseArray(vos.toString()));
+        if(!DmpResult.SUCCESS.equals(response.getResult())) {
+            throw new RuntimeException("调用中台查询接口出错:" + response.getMessage());
+        }
+        // 转换为结果
+        // 2021年11月3日17:45:46 by lijie 新增一个钩子方法,用于处理floor的properties字段,不然转换为对象时会报转换异常
+        processResultAfterQuery(response);
+        return AdmEntityTransferUtil.toAdmMultiEntity(response.getData(), null, clazz);
+    }
+    /***
+     * Description: 一个钩子方法,特殊处理一下楼层对象返回的properties信息点,不然转换为对象时会报转换异常
+     * @param response : 查询结果
+     * @return : void
+     * @author : lijie
+     * @date :2021/11/3 17:47
+     * Update By lijie 2021/11/3 17:47
+     */
+    protected void processResultAfterQuery(DmpResult<JSONArray> response) {
+    }
+
+    /**
+     * 修改
+     * @param context
+     * @param clazz
+     * @param voList
+     * @return
+     */
+    @Override
+    public List<T> doUpdate(InstanceUrlParam context, Class<T> clazz, List<T> voList) {
+        if(CollUtil.isEmpty(voList)) {
+            return null;
+        }
+        ArrayNode vos = AdmEntityTransferUtil.toDmpMultiEntity(voList);
+        // 调用中台修改
+        DmpResult<JSONArray> response = rwdClient.updateObject(context, JSONArray.parseArray(vos.toString()));
+        if(!DmpResult.SUCCESS.equals(response.getResult())) {
+            throw new RuntimeException("调用中台查询接口出错:" + response.getMessage());
+        }
+        // 转换为结果
+        processResultAfterQuery(response);
+        return AdmEntityTransferUtil.toAdmMultiEntity(response.getData(), null, clazz);
+    }
+
+    /**
+     * 删除
+     * @param context
+     * @param voList
+     * @return
+     */
+    @Override
+    public void doDelete(InstanceUrlParam context, List<T> voList) {
+        if(CollUtil.isEmpty(voList)) {
+            return;
+        }
+        List<String> idList = CollUtil.getFieldValues(voList, "id", String.class);
+        // 调用中台修改
+        DmpResult response = rwdClient.deleteObject(context, idList);
+        if(!DmpResult.SUCCESS.equals(response.getResult())) {
+            throw new RuntimeException("调用中台查询接口出错:" + response.getMessage());
+        }
+    }
+
+    /**
+     * 根据物理世界查询条件查询对象信息
+     * @param context
+     * @param dmpRequest
+     * @param clazz
+     * @return
+     */
+    @Override
+    public AdmResponse doQuery(InstanceUrlParam context, QueryCriteria dmpRequest, Class<T> clazz) {
+        // 转换参数
+        JSONObject para = null;
+        try {
+            para = JsonHelper.toJsonObject(dmpRequest);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+            return null;
+        }
+        // 调用中台查询
+        DmpResult<JSONArray> dmpResult = rwdClient.queryObject(context, para);
+        processResultAfterQuery(dmpResult);
+        List<T> admVOs = AdmEntityTransferUtil.toAdmMultiEntity(dmpResult.getData(), null, clazz);
+//        JSONArray data = dmpResult.getData();
+//        List<T> admVOs = new ArrayList<>();
+//        if(CollUtil.isNotEmpty(data)){
+//            admVOs = data.toJavaList(clazz);
+//        }
+        // 设置返回值
+        AdmResponse response = AdmResponse.success(admVOs);
+        Long total = dmpResult.getCount() == null ? null : dmpResult.getCount().longValue();
+        response.setTotal(total);
+        return response;
+    }
+
+    /**
+     * 查询标记计算关系
+     * @param context
+     * @param dmpRequest
+     * @param clazz
+     * @return
+     */
+    @Override
+    public AdmResponse doQueryRelationProjectCal(InstanceUrlParam context, QueryCriteria dmpRequest, Class<T> clazz) {
+        // 转换参数
+        JSONObject para = null;
+        try {
+            para = JsonHelper.toJsonObject(dmpRequest);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+            return null;
+        }
+        // 调用中台查询
+        DmpResult<JSONArray> dmpResult = rwdClient.queryRelationProjectCal(context, para);
+        List<T> admVOs = AdmEntityTransferUtil.toAdmMultiEntity(dmpResult.getData(), null, clazz);
+        // 设置返回值
+        AdmResponse response = AdmResponse.success(admVOs);
+        Long total = dmpResult.getCount() == null ? null : dmpResult.getCount().longValue();
+        response.setTotal(total);
+        return response;
+    }
+
+
+    /**
+     * 修改
+     * @param context
+     * @param clazz
+     * @param voList
+     * @return
+     */
+    @Override
+    public List<T> doUpdateRelationProjectCal(InstanceUrlParam context, Class<T> clazz, List<T> voList) {
+        if(CollUtil.isEmpty(voList)) {
+            return null;
+        }
+        ArrayNode vos = AdmEntityTransferUtil.toDmpMultiEntity(voList);
+        // 调用中台修改
+        DmpResult<JSONArray> response = rwdClient.updateRelationProjectCal(context, JSONArray.parseArray(vos.toString()));
+        if(!DmpResult.SUCCESS.equals(response.getResult())) {
+            throw new RuntimeException("调用中台查询接口出错:" + response.getMessage());
+        }
+        // 转换为结果
+        return AdmEntityTransferUtil.toAdmMultiEntity(response.getData(), null, clazz);
+    }
+
+
+    /**
+     * 查询对象类型
+     * @param request
+     * @return
+     */
+    @Override
+    public AdmResponse queryObjectClassCode(InstanceUrlParam context, AdmQueryCriteria request, Class<T> clazz) {
+        // 转换为数据中台查询条件
+        QueryCriteria dmpRequest = AdmQueryCriteriaHelper.toDmpCriteria(request);
+        //重置分页,查询所有
+        dmpRequest.setSize(null);
+        // 提供一个钩子方法用于处理已封装好的中台查询参数(因传参有buildingId而处理)
+        processDmpCriteria(dmpRequest);
+        // 转换参数
+        JSONObject para = null;
+        try {
+            para = JsonHelper.toJsonObject(dmpRequest);
+        } catch (IOException e) {
+            log.error(e.getMessage(), e);
+            return AdmResponse.failure("参数格式有误");
+        }
+        log.info("request:{},dmpRequest:{}, dmp-param: {}", request.toString(), dmpRequest.toString(), para.toString());
+        // 调用中台查询
+        DmpResult<List<String>> dmpResult = rwdClient.queryObjectClassCode(context, para);
+        // 设置返回值
+        AdmResponse response = AdmResponse.success(dmpResult.getData());
+        Long total = dmpResult.getCount() == null ? null : dmpResult.getCount().longValue();
+        response.setTotal(total);
+        return response;
+    }
+}

+ 76 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/service/impl/AdmRelationServiceImpl.java

@@ -0,0 +1,76 @@
+package com.persagy.proxy.adm.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.basic.utils.JsonNodeUtils;
+import com.persagy.dmp.common.context.AppContext;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.service.IAdmRelationService;
+import com.persagy.proxy.common.client.DmpRwdClient;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+import com.persagy.proxy.common.entity.RelationDTO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * ADM 关系 通用 Service
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+@Slf4j
+@Service
+public class AdmRelationServiceImpl implements IAdmRelationService {
+
+    @Autowired
+    private DmpRwdClient rwdClient;
+    @Autowired
+    private ObjectMapper objectMapper;
+
+    @Override
+    public void doSave(InstanceUrlParam param, List<RelationDTO> voList) {
+        if(CollUtil.isEmpty(voList)) {
+            return;
+        }
+        List<ObjectNode> nodeList = JsonNodeUtils.toListNode(voList, null, null);
+        DigitalRelationFacade.create(param.getGroupCode(), param.getProjectId(),
+                param.getAppId(), null, nodeList);
+    }
+
+    @Override
+    public void doDelete(InstanceUrlParam param, QueryCriteria criteria) {
+    	param.setGroupCode(AppContext.getContext().getGroupCode());
+    	param.setProjectId(AppContext.getContext().getProjectId());
+    	
+        if(criteria == null) {
+            return;
+        }
+        JSONObject cond = null;
+        try {
+            String json = objectMapper.writeValueAsString(criteria);
+            cond = JSONObject.parseObject(json);
+        } catch (JsonProcessingException e) {
+            log.error(e.getMessage(), e);
+        }
+        if(cond == null) {
+            return;
+        }
+        rwdClient.deleteRelation(param, cond);
+    }
+
+    @Override
+    public List<ObjectRelation> queryByCondition(InstanceUrlParam param, QueryCriteria criteria) {
+        if(criteria == null) {
+            return null;
+        }
+        return DigitalRelationFacade.query(param.getGroupCode(), param.getProjectId(),
+                param.getAppId(), null, criteria);
+    }
+}

+ 173 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/RelationObjectContext.java

@@ -0,0 +1,173 @@
+package com.persagy.proxy.adm.strategy;
+
+import java.util.*;
+
+import javax.annotation.Resource;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.strategy.relationdata.RelationObjectStrategy;
+import com.persagy.proxy.report.model.AdmRelationObject;
+
+/**
+ * 获取关系对象的上下文类
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月2日 下午10:44:32
+ */
+@Component
+public class RelationObjectContext {
+
+	/**
+	 * 策略执行类
+	 */
+	private Map<String, RelationObjectStrategy> relationObjectStrategyMap;
+	
+	/**
+	 * @param relationObjectStrategyMap
+	 */
+	@Resource
+	public void relationObjectStrategyMap(Map<String, RelationObjectStrategy> relationObjectStrategyMap) {
+		this.relationObjectStrategyMap = relationObjectStrategyMap;
+	}
+	
+	/**
+	 * 获取关系对象数据
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 * @param relType graphCode_relCode
+	 * @return
+	 */
+	public List<AdmRelationObject> exportRelationObject(String groupCode, String projectId, String relType) {
+		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
+		return strategy == null ? Lists.newArrayList() : strategy.exportRelationObject(groupCode, projectId);
+	}
+	
+	/**
+	 * 检查关联对象的合法性
+	 * 
+	 * @param relationObject 当前需要校验的对象
+	 * @param groupCode
+	 * @param projectId
+	 * @param relType graphCode_relCode
+	 * @param code 获取对象的依据
+	 * @param admRelType ADM定义的类型
+	 * @return String - 校验失败的原因, ObjectNode -- BDTP接口的参数,不会返回null,请用instanceOf 判断返回值
+	 */
+	public Object checkRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String relType, String code, AdmRelationTypeEnum typeEnum) {
+		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
+		if (strategy == null && typeEnum != null) {
+			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
+		}
+		return strategy == null ? "不存在此类型" : strategy.beforeSaveRelationObject(relationObject, groupCode, projectId, code, typeEnum);
+	}
+	/**
+	 * 检查关联对象的合法性
+	 *
+	 * @param relationObjects 当前需要校验的对象
+	 * @param groupCode
+	 * @param projectId
+	 * @param relType graphCode_relCode
+	 * @param code 获取对象的依据
+	 * @param typeEnum ADM定义的类型
+	 * @return String - 校验失败的原因, ObjectNode -- BDTP接口的参数,不会返回null,请用instanceOf 判断返回值
+	 */
+	public Map<String,Object> checkRelationObjects(List<AdmRelationObject> relationObjects, String groupCode,
+												   String projectId, String relType, String code,
+												   AdmRelationTypeEnum typeEnum) {
+		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
+		if (strategy == null && typeEnum != null) {
+			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
+		}
+		if (null==strategy){
+			Map<String,Object> result = new HashMap<>();
+			relationObjects.forEach(obj->{
+						result.put(StrUtil.toString(obj.getMasterCode())+StrUtil.UNDERLINE+StrUtil.toString(obj.getSlaveCode()),"不存在此类型");
+					});
+			return result;
+		}
+		return strategy.beforeSaveRelationObjects(relationObjects, groupCode, projectId, code, typeEnum);
+	}
+
+	/**
+	 * 批量保存对象之间的关系
+	 * 
+	 * @param admRelationObject
+	 * @param groupCode
+	 * @param projectId
+	 * @param relType graphCode_relCode
+	 * @return 
+	 */
+	public boolean saveRelationObjects(List<ObjectNode> relationObjects, String groupCode, String projectId, String relType) {
+		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
+		if (strategy == null) {
+			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
+		}
+		return strategy == null ? false : strategy.saveRelationObjects(relationObjects, groupCode, projectId);
+	}
+
+	/**
+	 * 统计关系总数
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 * @param relType graphCode_relCode
+	 * @return 
+	 */
+	public long countRelationObjects(String groupCode, String projectId, String relType, AdmRelationTypeEnum typeEnum) {
+		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
+		if (strategy == null && typeEnum != null) {
+			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
+		}
+		return strategy == null ? 0 : strategy.countRelationObjects(groupCode, projectId, typeEnum);
+	}
+
+	/**
+	 * 查询全部的关系对象数据
+	 * 
+	 * @param masterObjs 查询的数据集存储地方
+	 * @param requestData 请求参数
+	 * @param groupCode 集团编码
+	 * @param projectId 项目ID
+	 * @param relType  graphCode_relCode
+	 * @param mainContent	主对象的筛选关键字,筛选范围为id,name,local_id,local_name,cADID.为关系左侧对象
+	 * @param slaveContent	从对象的筛选关键字.objTo对应的对象,筛选范围为id,name,local_id,local_name.为关系右侧对象
+	 */
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String relType, String mainContent, Set<String> slaveContent, AdmRelationTypeEnum typeEnum) {
+		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
+		if (strategy == null && typeEnum != null) {
+			strategy = this.relationObjectStrategyMap.get(AdmRelationType.DEFAULT_RELATION_OBJECT);
+		}
+		return strategy == null ? Lists.newArrayList() : strategy.queryAllRelations(groupCode, projectId, mainContent, slaveContent, typeEnum);
+	}
+	
+	/**
+	 * 分页查询关系对象数据
+	 * 
+	 * @param masterObjs 查询的数据集存储地方
+	 * @param requestData 请求参数
+	 * @param groupCode 集团编码
+	 * @param projectId 项目ID
+	 * @param relType  graphCode_relCode
+	 */
+	public List<ObjectDigital> queryPageRelations(RequestData requestData, String groupCode, String projectId, String relType) {
+		List<ObjectDigital> masterObjs = new ArrayList<ObjectDigital>();
+		RelationObjectStrategy strategy = this.relationObjectStrategyMap.get(relType);
+		if (strategy == null) {
+			return masterObjs;
+		}
+		strategy.queryPageRelations(masterObjs, requestData, groupCode, projectId);
+		return masterObjs;
+	}
+	
+}

+ 126 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AbstractRelationObject.java

@@ -0,0 +1,126 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalObjectFacade;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+
+/**
+ * 普通操作抽象类
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月2日 下午11:00:26
+ */
+public abstract class AbstractRelationObject implements RelationObjectStrategy {
+
+	protected IRelationReportService relationReportService;
+	
+	public AbstractRelationObject(IRelationReportService reportDownloadService) {
+		this.relationReportService = reportDownloadService;
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId, AdmRelationTypeEnum typeEnum) {
+		return this.countRelationObjects(groupCode, projectId);
+	}
+	
+	/**
+	 * 统计关系总数
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 * @return
+	 */
+	protected abstract long countRelationObjects(String groupCode, String projectId);
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent, AdmRelationTypeEnum typeEnum) {
+		return this.queryAllRelations(groupCode, projectId, mainContent, slaveContent);
+	}
+	
+	/**
+	 * 查询出所有的关系对象数据
+	 * 
+	 * @param groupCode 集团编码
+	 * @param projectId 项目ID
+	 * @param mainContent	主对象的筛选关键字,筛选范围为id,name,local_id,local_name,cADID.为关系左侧对象
+	 * @param slaveContent	从对象的筛选关键字.objTo对应的对象,筛选范围为id,name,local_id,local_name.为关系右侧对象
+	 * @return 不会返回null
+	 */
+	protected abstract List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent);
+	
+	
+	@Override
+	public void queryPageRelations(List<ObjectDigital> allDigitals, RequestData requestData, String groupCode, String projectId) {
+		CommonResult<List<ObjectDigital>> queryPrototype = DigitalObjectFacade.queryObjectListByGraphCodeAndRelCodePrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, requestData);
+		Long count = queryPrototype.getCount();
+		List<ObjectDigital> infos = queryPrototype.getData();
+		if (count == null || CollectionUtil.isEmpty(infos)) {
+			return;
+		}
+		
+		allDigitals.addAll(infos);
+		if (count < SpringHelper.getLong("persagy.common.sql.limit",500L)) {
+			return;
+		}
+		if ((infos.size()*requestData.getPage()) > count) {
+			return;
+		}
+		requestData.setPage((requestData.getPage() + 1));
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+	}
+	
+	@Override
+	public boolean saveRelationObject(ObjectNode relationObject, String groupCode, String projectId) {
+		ObjectRelation objectRelation = DigitalRelationFacade.createOne(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, relationObject);
+		return objectRelation != null;
+	}
+	
+	@Override
+	public boolean saveRelationObjects(List<ObjectNode> relationObjects, String groupCode, String projectId) {
+		List<ObjectRelation> create = DigitalRelationFacade.create(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, relationObjects);
+		return CollectionUtil.isNotEmpty(create);
+	}
+	
+	/**************************************************** 默认不实现的类 *******************************************************/
+	
+	@Override
+	public List<AdmRelationObject> exportRelationObject(String groupCode, String projectId) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code, AdmRelationTypeEnum typeEnum) {
+		return this.beforeSaveRelationObject(relationObject, groupCode, projectId, code);
+	}
+
+	protected Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code, AdmRelationTypeEnum typeEnum) {
+		return this.beforeSaveRelationObjects(relationObjects, groupCode, projectId, code);
+	}
+
+	protected Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+}

+ 355 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AbstractReportRelationObject.java

@@ -0,0 +1,355 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.*;
+
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.ObjTypeMapping;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import org.json.JSONObject;
+
+/**
+ * 报表数据抽象类
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月2日 下午11:00:26
+ */
+public abstract class AbstractReportRelationObject extends AbstractRelationObject {
+
+	public AbstractReportRelationObject(IRelationReportService reportDownloadService) {
+		super(reportDownloadService);
+	}
+
+	@Override
+	protected long countRelationObjects(String groupCode, String projectId) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+	@Override
+	protected List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+	
+	@Override
+	public List<AdmRelationObject> exportRelationObject(String groupCode, String projectId) {
+		List<ObjectDigital> masterObjs = this.queryAllRelations(groupCode, projectId, null, null);
+		// 转换中台数据
+		return this.handleObjectDigital(masterObjs, groupCode, projectId);
+	}
+	
+	/**
+	 * 处理中台响应数据,转换为ADM所需要的数据
+	 * 
+	 * @param masterObjs
+	 * @param groupCode
+	 * @param projectId
+	 * @return
+	 */
+	protected List<AdmRelationObject> handleObjectDigital(List<ObjectDigital> masterObjs, String groupCode, String projectId) {
+		List<AdmRelationObject> result = new ArrayList<AdmRelationObject>();
+		// 遍历所有主对象
+		for (ObjectDigital master : masterObjs) {
+			List<ObjectDigital> slaveObjs = master.getRelObjs();
+			if (CollectionUtil.isEmpty(slaveObjs)) {
+				continue;	// 从对象不存在的,不再返回主对象数据
+			}
+			
+			// 遍历所有的从对象
+			for (ObjectDigital slave : slaveObjs) {
+				result.add(this.handleObjectDigital(master, slave, groupCode, projectId));
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * 处理中台对象,返回前端所需要的
+	 * 
+	 * @param master
+	 * @param slave
+	 * @param groupCode
+	 * @param projectId
+	 * @return
+	 */
+	protected abstract AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId);
+
+	/**
+	 * 封装响应数据,具体的传值,请仔细侦查,这里仅返回共有字段,特殊字段,自行赋值
+	 * 
+	 * @param master
+	 * @param masterType
+	 * @param slave
+	 * @param slaveType
+	 * @return
+	 */
+	protected AdmRelationObject convertObject(ObjectDigital master, String masterType, ObjectDigital slave, String slaveType) {
+		AdmRelationObject relationObject = new AdmRelationObject();
+		
+		// ID
+		String masterId = master.getId();
+		relationObject.setMasterCode(masterId);
+		relationObject.setMasterId(masterId);
+		// 图纸编码
+		ObjectNode masterInfos = master.getInfos();
+		relationObject.setMasterCadId(masterInfos.get("cADID") == null ? AdmCommonConstant.EMPTY  : masterInfos.get("cADID").asText());
+		// 名称
+		relationObject.setMasterName(master.getName());
+		// 本地ID
+		relationObject.setMasterLocalId(master.getLocalId());
+		// 本地名称
+		relationObject.setMasterLocalName(master.getLocalName());
+		// 类型
+		relationObject.setMasterType(masterType);
+		
+		// ID
+		String slaveId = slave.getId();
+		relationObject.setSlaveCode(slaveId);
+		relationObject.setSlaveId(slaveId);
+		// 图纸编码
+		ObjectNode slaveInfos = slave.getInfos();
+		relationObject.setSlaveCadId(slaveInfos.get("cADID") == null ? AdmCommonConstant.EMPTY  : slaveInfos.get("cADID").asText());
+		// 名称
+		relationObject.setSlaveName(slave.getName());
+		// 本地ID
+		relationObject.setSlaveLocalId(slave.getLocalId());
+		// 本地名称
+		relationObject.setSlaveLocalName(slave.getLocalName());
+		// 类型
+		relationObject.setSlaveType(slaveType);
+		
+		return relationObject;
+	}
+	
+	/**
+	 * 检查关系对象数据的正确性,并完成额外字段的赋值功能
+	 * 
+	 * @param relationObject
+	 * @param relationTypeEnum AdmRelationTypeEnum枚举类
+	 * @param code
+	 * @return String - 校验失败的原因, ObjectNode -- BDTP接口的参数,不会返回null,请用instanceOf 判断返回值
+	 */
+	protected Object beforeSaveRelationObject(AdmRelationObject relationObject, AdmRelationTypeEnum relationTypeEnum,
+			String groupCode, String projectId, String code) {
+		if (!StrUtil.isAllNotBlank(relationObject.getMasterCode(), relationObject.getSlaveCode())) {
+			return "主对象或从对象的识别编码为空";
+		}
+		/*if (!StrUtil.isAllNotBlank(relationObject.getMasterId(), relationObject.getSlaveId())) {
+			return "主对象或从对象的ID为空";
+		}*/
+		
+		// 获取备用的类型
+		String relationType = relationTypeEnum.getRelationType();
+		int indexOf = relationType.indexOf("_");
+		String relCodeBak = indexOf > 0 ? relationType.substring(0, indexOf) : relationType;
+		
+		String relCode = relationTypeEnum.getRelCode();
+		String relCodePrefix = ObjTypeMapping.getRelCodePrefix(relCode);
+		String masterObjType = ObjTypeMapping.PREFIX_FULLNAME.get(relCodePrefix);
+		if (StrUtil.isBlank(masterObjType)) {
+			relCodePrefix = ObjTypeMapping.getRelCodePrefix(relCodeBak);
+			relCodePrefix = StrUtil.upperFirst(relCodePrefix);
+			masterObjType = ObjTypeMapping.PREFIX_FULLNAME.get(relCodePrefix);
+			if (StrUtil.isBlank(masterObjType)) {
+				return "边类型错误";
+			}
+		}
+		String slaveObjType = ObjTypeMapping.PREFIX_FULLNAME.get(ObjTypeMapping.getRelCodeSuffix(relCode));
+		if (StrUtil.isBlank(slaveObjType)) {
+			String relCodeSuffix = StrUtil.upperFirst(ObjTypeMapping.getRelCodeSuffix(relCodeBak));
+			slaveObjType = ObjTypeMapping.PREFIX_FULLNAME.get(relCodeSuffix);
+			if (StrUtil.isBlank(slaveObjType)) {
+				return "边类型错误";
+			}
+		}
+		// 查询出对象信息
+		List<ObjectNode> masters = this.relationReportService.findObjectNodes(groupCode, projectId, masterObjType, code, relationObject.getMasterCode());
+		if (CollectionUtil.isEmpty(masters)) {
+			return "未找到主对象";
+		}
+		if (masters.size() > 1) {
+			return "匹配到多个主对象";
+		}
+		// 查询出从对象
+		List<ObjectNode> slaves = this.relationReportService.findObjectNodes(groupCode, projectId, slaveObjType, code, relationObject.getSlaveCode());
+		if (CollectionUtil.isEmpty(slaves)) {
+			return "未找到从对象";
+		}
+		if (masters.size() > 1) {
+			return "匹配到多个从对象";
+		}
+		
+		// 添加关系数据
+		ObjectNode master = masters.get(0);
+		ObjectNode slave = slaves.get(0);
+		String masterClassCode = master.get("classCode") == null ? AdmCommonConstant.EMPTY : master.get("classCode").asText();
+		String slaveClassCode = slave.get("classCode") == null ? AdmCommonConstant.EMPTY : slave.get("classCode").asText();
+		
+		String result = this.checkRelationObject(master, masterClassCode, slave, slaveClassCode);
+		if (StrUtil.isBlank(result)) {
+			ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+			String graphCode = relationTypeEnum.getGraphCode();
+			objectNode.put("graphId", "Gt" + graphCode + "001");
+			objectNode.put("graphCode", graphCode);
+			objectNode.put("relCode", relCode);
+			if ("Sp".equals(relCodePrefix)) {
+				objectNode.put("relValue", masterClassCode);
+			}
+			objectNode.put("objFrom", master.get("id").asText());
+			objectNode.put("objTo", slave.get("id").asText());
+			return objectNode;
+		}
+		return result; 
+	}
+
+	/**
+	 * 检查关系对象数据的正确性,并完成额外字段的赋值功能
+	 *
+	 * @param relationTypeEnum AdmRelationTypeEnum枚举类
+	 * @param code
+	 * @return String - 校验失败的原因, ObjectNode -- BDTP接口的参数,不会返回null,请用instanceOf 判断返回值
+	 */
+	protected Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, AdmRelationTypeEnum relationTypeEnum,
+														   String groupCode, String projectId, String code) {
+		Map<String, Object> result = new HashMap<>();
+		if (CollUtil.isEmpty(relationObjects)){
+			return CollUtil.newHashMap(0);
+		}
+		// 收集master的识别编码
+		Set<String> masterCodes = new HashSet<>();
+		Set<String> masterObjTypes = new HashSet<>();
+		// 收集slave的识别编码
+		Set<String> slaveCodes = new HashSet<>();
+		Set<String> slaveObjTypes = new HashSet<>();
+		for (AdmRelationObject relationObject : relationObjects) {
+			if (!StrUtil.isAllNotBlank(relationObject.getMasterCode(), relationObject.getSlaveCode())) {
+				result.put(StrUtil.toString(relationObject.getMasterCode())+StrUtil.UNDERLINE
+						+StrUtil.toString(relationObject.getSlaveCode()),"主对象或从对象的识别编码为空");
+				continue;
+			}
+			// 获取备用的类型
+			String relationType = relationTypeEnum.getRelationType();
+			int indexOf = relationType.indexOf("_");
+			String relCodeBak = indexOf > 0 ? relationType.substring(0, indexOf) : relationType;
+			String relCode = relationTypeEnum.getRelCode();
+			String relCodePrefix = ObjTypeMapping.getRelCodePrefix(relCode);
+			String masterObjType = ObjTypeMapping.PREFIX_FULLNAME.get(relCodePrefix);
+			if (StrUtil.isBlank(masterObjType)) {
+				relCodePrefix = ObjTypeMapping.getRelCodePrefix(relCodeBak);
+				relCodePrefix = StrUtil.upperFirst(relCodePrefix);
+				masterObjType = ObjTypeMapping.PREFIX_FULLNAME.get(relCodePrefix);
+				if (StrUtil.isBlank(masterObjType)) {
+					result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),"边类型错误");
+					continue;
+				}
+			}
+			String slaveObjType = ObjTypeMapping.PREFIX_FULLNAME.get(ObjTypeMapping.getRelCodeSuffix(relCode));
+			if (StrUtil.isBlank(slaveObjType)) {
+				String relCodeSuffix = StrUtil.upperFirst(ObjTypeMapping.getRelCodeSuffix(relCodeBak));
+				slaveObjType = ObjTypeMapping.PREFIX_FULLNAME.get(relCodeSuffix);
+				if (StrUtil.isBlank(slaveObjType)) {
+					result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),"边类型错误");
+					continue;
+				}
+			}
+			if (StrUtil.isBlank(code)
+					|| !RelationObjectStrategy.OBJNAME_2_TYPE.containsKey(code)
+					|| StrUtil.isBlank(RelationObjectStrategy.OBJNAME_2_TYPE.get(code))) {
+				result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),"未找到主对象");
+				continue;
+			}
+			masterCodes.add(relationObject.getMasterCode());
+			slaveCodes.add(relationObject.getSlaveCode());
+			masterObjTypes.add(masterObjType);
+			slaveObjTypes.add(slaveObjType);
+		}
+		if (StrUtil.isBlank(code)
+				|| !RelationObjectStrategy.OBJNAME_2_TYPE.containsKey(code)
+				|| StrUtil.isBlank(RelationObjectStrategy.OBJNAME_2_TYPE.get(code))
+				|| CollUtil.isEmpty(masterCodes)
+				|| CollUtil.isEmpty(slaveCodes)
+				|| CollUtil.isEmpty(masterObjTypes)
+				|| CollUtil.isEmpty(slaveObjTypes)) {
+			return result;
+		}
+		// 查询出对象信息
+		Map<String,List<ObjectNode>> masterMap = this.relationReportService.findObjectNodesByPage(groupCode, projectId,
+				masterObjTypes, RelationObjectStrategy.OBJNAME_2_TYPE.get(code), masterCodes);
+		Map<String,List<ObjectNode>> slaveMap = this.relationReportService.findObjectNodesByPage(groupCode, projectId,
+				slaveObjTypes, RelationObjectStrategy.OBJNAME_2_TYPE.get(code), slaveCodes);
+		String relationType = relationTypeEnum.getRelationType();
+		int indexOf = relationType.indexOf("_");
+		String relCodeSuffix = StrUtil.upperFirst(ObjTypeMapping
+				.getRelCodeSuffix(indexOf > 0 ? relationType.substring(0, indexOf) : relationType));
+		for (AdmRelationObject relationObject : relationObjects) {
+			String key = StrUtil.toString(relationObject.getMasterCode())+StrUtil.UNDERLINE
+					+StrUtil.toString(relationObject.getSlaveCode());
+			if (result.containsKey(key)){
+				continue;
+			}
+			List<ObjectNode> masterNodes = masterMap.get(relationObject.getMasterCode());
+			if (CollectionUtil.isEmpty(masterNodes)) {
+				result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),"未找到主对象");
+				continue;
+			}
+			if (masterNodes.size() > 1) {
+				result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),"匹配到多个主对象");
+				continue;
+			}
+			List<ObjectNode> slaveNodes = slaveMap.get(relationObject.getSlaveCode());
+			if (CollectionUtil.isEmpty(slaveNodes)) {
+				result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),"未找到从对象");
+				continue;
+			}
+			if (slaveNodes.size() > 1) {
+				result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),"匹配到多个从对象");
+				continue;
+			}
+			// 添加关系数据
+			ObjectNode master = masterNodes.get(0);
+			ObjectNode slave = slaveNodes.get(0);
+			String masterClassCode = master.get("classCode") == null ? AdmCommonConstant.EMPTY : master.get("classCode").asText();
+			String slaveClassCode = slave.get("classCode") == null ? AdmCommonConstant.EMPTY : slave.get("classCode").asText();
+			String subResult = this.checkRelationObject(master, masterClassCode, slave, slaveClassCode);
+			if (StrUtil.isBlank(subResult)) {
+				ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+				String graphCode = relationTypeEnum.getGraphCode();
+				objectNode.put("graphId", "Gt" + graphCode + "001");
+				objectNode.put("graphCode", graphCode);
+				objectNode.put("relCode", relationTypeEnum.getRelCode());
+				if ("Sp".equals(relCodeSuffix)) {
+					objectNode.put("relValue", masterClassCode);
+				}
+				objectNode.put("objFrom", master.get("id").asText());
+				objectNode.put("objTo", slave.get("id").asText());
+				result.put(relationObject.getMasterCode()+StrUtil.UNDERLINE +relationObject.getSlaveCode(),objectNode);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 检查关系对象数据的正确性,并可完成额外字段的赋值功能
+	 * 默认不实现,由子类实现
+	 * 
+	 * @param master
+	 * @param masterClassCode
+	 * @param slave
+	 * @param slaveClassCode
+	 * @return 当为null时,检查通过,否则失败,返回失败原因
+	 */
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave, String slaveClassCode) {
+		return null;
+	}
+
+}

+ 86 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AcAirNetworkDischargeRelationObject.java

@@ -0,0 +1,86 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ACAIRNETWORK_DISCHARGE)
+public class AcAirNetworkDischargeRelationObject extends AbstractReportRelationObject {
+
+	public AcAirNetworkDischargeRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_3.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_3.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_3.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_3.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "设备");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_3, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_3, groupCode, projectId, code);
+	}
+
+}

+ 86 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/AcAirNetworkReturnRelationObject.java

@@ -0,0 +1,86 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ACAIRNETWORK_RETURN)
+public class AcAirNetworkReturnRelationObject extends AbstractReportRelationObject {
+
+	public AcAirNetworkReturnRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_2.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_2.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_2.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_2.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "设备");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_2, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_ACAIRNETWORK_2, groupCode, projectId, code);
+	}
+	
+}

+ 84 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2BdRelationObject.java

@@ -0,0 +1,84 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.*;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ARCHFORARCH_SH2BD)
+public class ArchForArchSh2BdRelationObject extends AbstractReportRelationObject {
+
+	public ArchForArchSh2BdRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sh2Bd.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sh2Bd.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "空间");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SH2BD_ARCHFORARCH, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SH2BD_ARCHFORARCH, groupCode, projectId, code);
+	}
+	
+}

+ 97 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2FlRelationObject.java

@@ -0,0 +1,97 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ARCHFORARCH_SH2FL)
+public class ArchForArchSh2FlRelationObject extends AbstractReportRelationObject {
+
+	public ArchForArchSh2FlRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sh2Fl.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sh2Fl.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取建筑的信息
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), 
+				RelCodeEnum.Sh2Bd.name(), master.getId(), null);
+
+		AdmRelationObject convertObject = this.convertObject(master, "竖井", slave, "楼层");
+		String buildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		convertObject.setSlaveBuildingName(buildingName);
+		convertObject.setSlaveBelong(buildingName);
+		
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SH2FL_ARCHFORARCH, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SH2FL_ARCHFORARCH, groupCode, projectId, code);
+	}
+}

+ 89 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2ShRelationObject.java

@@ -0,0 +1,89 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ARCHFORARCH_SH2SH)
+public class ArchForArchSh2ShRelationObject extends AbstractReportRelationObject {
+
+	public ArchForArchSh2ShRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sh2Sh.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sh2Sh.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "竖井", slave, "竖井");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SH2SH_ARCHFORARCH, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SH2SH_ARCHFORARCH, groupCode, projectId, code);
+	}
+}

+ 106 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSh2SpRelationObject.java

@@ -0,0 +1,106 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ARCHFORARCH_SH2SP)
+public class ArchForArchSh2SpRelationObject extends AbstractReportRelationObject {
+
+	public ArchForArchSh2SpRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sh2Sp.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sh2Sp.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取建筑的信息
+		ObjectNode floorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), 
+				RelCodeEnum.Sh2Fl.name(), master.getId(), null);
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), 
+				RelCodeEnum.Sh2Bd.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "竖井", slave, "空间");
+		String buildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		String floorName = floorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : floorInfo.get("localName").asText();
+		convertObject.setSlaveBuildingName(buildingName);
+		convertObject.setSlaveFloorName(floorName);
+		if (StrUtil.isBlank(floorName)) {
+			convertObject.setSlaveBelong(buildingName);
+		} else {
+			convertObject.setSlaveBelong((StrUtil.isBlank(buildingName) ? AdmCommonConstant.EMPTY 
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, buildingName, floorName)));
+		}
+		return convertObject;
+	}
+	
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SH2SP_ARCHFORARCH, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SH2SP_ARCHFORARCH, groupCode, projectId, code);
+	}
+}

+ 104 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSp2BdRelationObject.java

@@ -0,0 +1,104 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ARCHFORARCH_SP2BD)
+public class ArchForArchSp2BdRelationObject extends AbstractReportRelationObject {
+
+	public ArchForArchSp2BdRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sp2Bd.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sp2Bd.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取楼层的信息
+		ObjectNode floorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), 
+				RelCodeEnum.Sp2Fl.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "空间", slave, "建筑");
+		String buildingName = slave.getLocalName();
+		String floorName = floorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : floorInfo.get("localName").asText();
+		convertObject.setMasterBuildingName(buildingName);
+		convertObject.setMasterFloorName(floorName);
+		if (StrUtil.isBlank(floorName)) {
+			convertObject.setMasterBelong(buildingName);
+		} else {
+			convertObject.setMasterBelong((StrUtil.isBlank(buildingName) ? AdmCommonConstant.EMPTY 
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, buildingName, floorName)));
+		}
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2BD_ARCHFORARCH, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2BD_ARCHFORARCH, groupCode, projectId, code);
+	}
+}

+ 107 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSp2FlRelationObject.java

@@ -0,0 +1,107 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ARCHFORARCH_SP2FL)
+public class ArchForArchSp2FlRelationObject extends AbstractReportRelationObject {
+
+	public ArchForArchSp2FlRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sp2Fl.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sp2Fl.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取建筑的信息
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(), 
+				RelCodeEnum.Sp2Bd.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "空间", slave, "楼层");
+		String buildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		String floorName = slave.getLocalName();
+		convertObject.setMasterBuildingName(buildingName);
+		convertObject.setMasterFloorName(floorName);
+		convertObject.setSlaveBuildingName(buildingName);
+		convertObject.setSlaveBelong(buildingName);
+		
+		if (StrUtil.isBlank(floorName)) {
+			convertObject.setMasterBelong(buildingName);
+		} else {
+			convertObject.setMasterBelong((StrUtil.isBlank(buildingName) ? AdmCommonConstant.EMPTY 
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, buildingName, floorName)));
+		}
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2FL_ARCHFORARCH, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2FL_ARCHFORARCH, groupCode, projectId, code);
+	}
+}

+ 110 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchForArchSp2SpRelationObject.java

@@ -0,0 +1,110 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.*;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.ARCHFORARCH_SP2SP)
+public class ArchForArchSp2SpRelationObject extends AbstractReportRelationObject {
+
+	public ArchForArchSp2SpRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sp2Sp.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId,
+				AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sp2Sp.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取建筑的信息
+		ObjectNode floorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(),
+				RelCodeEnum.Sp2Fl.name(), master.getId(), null);
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(),
+				RelCodeEnum.Sp2Bd.name(), master.getId(), null);
+		ObjectNode slaveFloorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(),
+				RelCodeEnum.Sp2Fl.name(), slave.getId(), null);
+		ObjectNode slaveBuildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.ArchForArch.name(),
+				RelCodeEnum.Sp2Bd.name(), slave.getId(), null);
+
+		AdmRelationObject convertObject = this.convertObject(master, "空间", slave, "空间");
+		String masterBuildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		String masterFloorName = floorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : floorInfo.get("localName").asText();
+		String slaveBuildingName = slaveBuildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : slaveBuildingInfo.get("localName").asText();
+		String slaveFloorName = slaveFloorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : slaveFloorInfo.get("localName").asText();
+		convertObject.setMasterBuildingName(masterBuildingName);
+		convertObject.setMasterFloorName(masterFloorName);
+		convertObject.setSlaveBuildingName(slaveBuildingName);
+		convertObject.setSlaveBelong(slaveFloorName);
+		
+		if (StrUtil.isBlank(masterFloorName)) {
+			convertObject.setMasterBelong(masterBuildingName);
+		} else {
+			convertObject.setMasterBelong((StrUtil.isBlank(masterBuildingName) ? AdmCommonConstant.EMPTY
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, masterBuildingName, masterFloorName)));
+		}
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_ARCHFORARCH, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_ARCHFORARCH, groupCode, projectId, code);
+	}
+}

+ 73 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ArchSubsetBd2FlRelationObject.java

@@ -0,0 +1,73 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月9日 下午5:28:21
+ */
+@Component(value = AdmRelationType.ARCHSUBSET_BD2FL)
+public class ArchSubsetBd2FlRelationObject extends AbstractRelationObject {
+
+	public ArchSubsetBd2FlRelationObject(IRelationReportService reportDownloadService) {
+		super(reportDownloadService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.ArchSubset.name());
+		objectNode.put("relCode", RelCodeEnum.Bd2Fl.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.ArchSubset.name());
+		requestData.setRelCode(RelCodeEnum.Bd2Fl.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+}

+ 101 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ConvectionNetworkMixMechRelationObject.java

@@ -0,0 +1,101 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.CONVECTIONNETWORK_MIXMECH)
+public class ConvectionNetworkMixMechRelationObject extends AbstractReportRelationObject {
+	
+	public ConvectionNetworkMixMechRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_2.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_2.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_2.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_2.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_2, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_2, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.AirConditioningZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于空调分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.AirConditioningZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于空调分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 101 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ConvectionNetworkNaturalRelationObject.java

@@ -0,0 +1,101 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.CONVECTIONNETWORK_NATURAL)
+public class ConvectionNetworkNaturalRelationObject extends AbstractReportRelationObject {
+	
+	public ConvectionNetworkNaturalRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.AirConditioningZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于空调分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.AirConditioningZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于空调分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 100 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/ConvectionNetworkOnewayMechRelationObject.java

@@ -0,0 +1,100 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.CONVECTIONNETWORK_ONEWAYMECH)
+public class ConvectionNetworkOnewayMechRelationObject extends AbstractReportRelationObject {
+	
+	public ConvectionNetworkOnewayMechRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_3.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_3.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_3.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_3.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_3, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_3, groupCode, projectId, code);
+	}
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.AirConditioningZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于空调分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.AirConditioningZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于空调分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 88 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/DeafultRelationObject.java

@@ -0,0 +1,88 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年11月1日 上午11:42:26
+ */
+@Component(value = AdmRelationType.DEFAULT_RELATION_OBJECT)
+public class DeafultRelationObject extends AbstractReportRelationObject {
+
+	public DeafultRelationObject(IRelationReportService reportDownloadService) {
+		super(reportDownloadService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId, AdmRelationTypeEnum typeEnum) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", typeEnum.getGraphCode());
+		objectNode.put("relCode", typeEnum.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent, AdmRelationTypeEnum typeEnum) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(typeEnum.getGraphCode());
+		requestData.setRelCode(typeEnum.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+	
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code, AdmRelationTypeEnum typeEnum) {
+		return this.beforeSaveRelationObject(relationObject, typeEnum, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code, AdmRelationTypeEnum typeEnum) {
+		return this.beforeSaveRelationObjects(relationObjects, typeEnum, groupCode, projectId, code);
+	}
+
+}

+ 99 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerEqBackupRelationObject.java

@@ -0,0 +1,99 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.EQUIPPOWER_EQBACKUP)
+public class EquipPowerEqBackupRelationObject extends AbstractReportRelationObject {
+	
+	public EquipPowerEqBackupRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_2.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_2.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_2.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_2.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "设备");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_2, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_2, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!AdmObjectInfoConstant.CHECK_CLASS_CODES.contains(masterClassCode)) {
+			return "主对象不属于低/高压开关柜,请参考规则";
+		}
+		return null;
+	}
+
+	
+}

+ 98 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerEqNormalRelationObject.java

@@ -0,0 +1,98 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.EQUIPPOWER_EQNORMAL)
+public class EquipPowerEqNormalRelationObject extends AbstractReportRelationObject {
+	
+	public EquipPowerEqNormalRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_1.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_1.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_1.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_1.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "设备");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_1, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_1, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!AdmObjectInfoConstant.CHECK_CLASS_CODES.contains(masterClassCode)) {
+			return "主对象不属于低/高压开关柜,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 97 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerSyBackupRelationObject.java

@@ -0,0 +1,97 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.EQUIPPOWER_SYBACKUP)
+public class EquipPowerSyBackupRelationObject extends AbstractReportRelationObject {
+	
+	public EquipPowerSyBackupRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_4.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_4.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_4.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_4.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "系统");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_4, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_4, groupCode, projectId, code);
+	}
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!AdmObjectInfoConstant.CHECK_CLASS_CODES.contains(masterClassCode)) {
+			return "主对象不属于低/高压开关柜,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 98 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/EquipPowerSyNormalRelationObject.java

@@ -0,0 +1,98 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.EQUIPPOWER_SYNORMAL)
+public class EquipPowerSyNormalRelationObject extends AbstractReportRelationObject {
+	
+	public EquipPowerSyNormalRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_3.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_3.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_3.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_3.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "系统");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_3, groupCode, projectId, code);
+	}
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_EQUIPPOWER_3, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!AdmObjectInfoConstant.CHECK_CLASS_CODES.contains(masterClassCode)) {
+			return "主对象不属于低/高压开关柜,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 88 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechCtrlEqCtrlRelationObject.java

@@ -0,0 +1,88 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHCTRL_EQCTRL)
+public class MechCtrlEqCtrlRelationObject extends AbstractReportRelationObject {
+
+	public MechCtrlEqCtrlRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_CONTROLRELATION_1.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_CONTROLRELATION_1.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_CONTROLRELATION_1.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_CONTROLRELATION_1.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "设备");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_CONTROLRELATION_1, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_CONTROLRELATION_1, groupCode, projectId, code);
+	}
+	
+}

+ 86 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechCtrlSyCtrlRelationObject.java

@@ -0,0 +1,86 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHCTRL_SYCTRL)
+public class MechCtrlSyCtrlRelationObject extends AbstractReportRelationObject {
+
+	public MechCtrlSyCtrlRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2SY_CONTROLRELATION_2.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2SY_CONTROLRELATION_2.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2SY_CONTROLRELATION_2.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2SY_CONTROLRELATION_2.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "系统");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2SY_CONTROLRELATION_2, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2SY_CONTROLRELATION_2, groupCode, projectId, code);
+	}
+}

+ 108 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchEq2BdRelationObject.java

@@ -0,0 +1,108 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHFORARCH_EQ2BD)
+public class MechForArchEq2BdRelationObject extends AbstractReportRelationObject {
+
+	public MechForArchEq2BdRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Eq2Bd.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2BD_FOR.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2BD_FOR.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取楼层信息
+		ObjectNode floorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, AdmRelationTypeEnum.EQ2BD_FOR.getGraphCode(), 
+				RelCodeEnum.Eq2Fl.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "设备", slave, "建筑");
+		String buildingName = slave.getLocalName();
+		String floorName = floorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : floorInfo.get("localName").asText();
+		convertObject.setMasterBuildingName(buildingName);
+		convertObject.setMasterFloorName(floorName);
+		
+		if (StrUtil.isBlank(floorName)) {
+			convertObject.setMasterBelong(buildingName);
+		} else {
+			convertObject.setMasterBelong((StrUtil.isBlank(buildingName) ? AdmCommonConstant.EMPTY 
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, buildingName, floorName)));
+		}
+		
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2BD_FOR, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2BD_FOR, groupCode, projectId, code);
+	}
+
+}

+ 109 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchEq2FlRelationObject.java

@@ -0,0 +1,109 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHFORARCH_EQ2FL)
+public class MechForArchEq2FlRelationObject extends AbstractReportRelationObject {
+
+	public MechForArchEq2FlRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Eq2Fl.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechForArch.name());
+		requestData.setRelCode(RelCodeEnum.Eq2Fl.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取建筑信息
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.MechForArch.name(), 
+				RelCodeEnum.Eq2Bd.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "设备", slave, "楼层");
+		String buildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		String floorName = slave.getLocalName();
+		convertObject.setMasterBuildingName(buildingName);
+		convertObject.setMasterFloorName(floorName);
+		convertObject.setSlaveBuildingName(buildingName);
+		convertObject.setSlaveBelong(buildingName);
+		if (StrUtil.isBlank(floorName)) {
+			convertObject.setMasterBelong(buildingName);
+		} else {
+			convertObject.setMasterBelong((StrUtil.isBlank(buildingName) ? AdmCommonConstant.EMPTY 
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, buildingName, floorName)));
+		}
+		
+		return convertObject;
+	}
+	
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2FL_FOR, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2FL_FOR, groupCode, projectId, code);
+	}
+
+}

+ 108 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchEq2ShRelationObject.java

@@ -0,0 +1,108 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHFORARCH_EQ2SH)
+public class MechForArchEq2ShRelationObject extends AbstractReportRelationObject {
+
+	public MechForArchEq2ShRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Eq2Sh.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechForArch.name());
+		requestData.setRelCode(RelCodeEnum.Eq2Sh.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取楼层信息
+		ObjectNode floorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.MechForArch.name(), 
+				RelCodeEnum.Eq2Fl.name(), master.getId(), null);
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.MechForArch.name(), 
+				RelCodeEnum.Eq2Bd.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "设备", slave, "竖井");
+		String buildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		String floorName = floorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : floorInfo.get("localName").asText();
+		convertObject.setMasterBuildingName(buildingName);
+		convertObject.setMasterFloorName(floorName);
+		if (StrUtil.isBlank(floorName)) {
+			convertObject.setMasterBelong(buildingName);
+		} else {
+			convertObject.setMasterBelong((StrUtil.isBlank(buildingName) ? AdmCommonConstant.EMPTY 
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, buildingName, floorName)));
+		}
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2SH_FOR, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2SH_FOR, groupCode, projectId, code);
+	}
+	
+}

+ 90 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2BdRelationObject.java

@@ -0,0 +1,90 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHFORARCH_SY2BD)
+public class MechForArchSy2BdRelationObject extends AbstractReportRelationObject {
+
+	public MechForArchSy2BdRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sy2Bd.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sy2Bd.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "系统", slave, "建筑");
+	}
+	
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SY2BD_FOR, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SY2BD_FOR, groupCode, projectId, code);
+	}
+}

+ 99 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2FlRelationObject.java

@@ -0,0 +1,99 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHFORARCH_SY2FL)
+public class MechForArchSy2FlRelationObject extends AbstractReportRelationObject {
+
+	public MechForArchSy2FlRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sy2Fl.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sy2Fl.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取楼层信息
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, AdmRelationTypeEnum.SY2FL_FOR.getGraphCode(), 
+				RelCodeEnum.Sy2Bd.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "系统", slave, "楼层");
+		String buildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		convertObject.setSlaveBuildingName(buildingName);
+		convertObject.setSlaveBelong(buildingName);
+		
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SY2FL_FOR, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SY2FL_FOR, groupCode, projectId, code);
+	}
+}

+ 90 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2ShRelationObject.java

@@ -0,0 +1,90 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHFORARCH_SY2SH)
+public class MechForArchSy2ShRelationObject extends AbstractReportRelationObject {
+
+	public MechForArchSy2ShRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sy2Sh.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sy2Sh.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "系统", slave, "竖井");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SY2SH_FOR, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SY2SH_FOR, groupCode, projectId, code);
+	}
+}

+ 107 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechForArchSy2SpRelationObject.java

@@ -0,0 +1,107 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHFORARCH_SY2SP)
+public class MechForArchSy2SpRelationObject extends AbstractReportRelationObject {
+
+	public MechForArchSy2SpRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechForArch.name());
+		objectNode.put("relCode", RelCodeEnum.Sy2Sp.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechForArch.name());
+		requestData.setRelCode(RelCodeEnum.Sy2Sp.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取楼层信息
+		ObjectNode floorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.MechForArch.name(), 
+				RelCodeEnum.Sy2Bd.name(), master.getId(), null);
+		ObjectNode buildingInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.MechForArch.name(), 
+				RelCodeEnum.Sy2Fl.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "系统", slave, "空间");
+		String buildingName = buildingInfo.get("localName") == null ? AdmCommonConstant.EMPTY : buildingInfo.get("localName").asText();
+		String floorName = floorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : floorInfo.get("localName").asText();
+		convertObject.setSlaveBuildingName(buildingName);
+		convertObject.setSlaveFloorName(floorName);
+		if (StrUtil.isBlank(floorName)) {
+			convertObject.setSlaveBelong(buildingName);
+		} else {
+			convertObject.setSlaveBelong((StrUtil.isBlank(buildingName) ? AdmCommonConstant.EMPTY 
+					: StrUtil.join(AdmCommonConstant.LINE_THROUGH, buildingName, floorName)));
+		}
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SY2SP_FOR, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SY2SP_FOR, groupCode, projectId, code);
+	}
+}

+ 100 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechInArchEq2BdRelationObject.java

@@ -0,0 +1,100 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHINARCH_EQ2BD)
+public class MechInArchEq2BdRelationObject extends AbstractReportRelationObject {
+
+	public MechInArchEq2BdRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechInArch.name());
+		objectNode.put("relCode", RelCodeEnum.Eq2Bd.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechInArch.name());
+		requestData.setRelCode(RelCodeEnum.Eq2Bd.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		// 获取楼层信息
+		ObjectNode floorInfo = this.relationReportService.getObjectByCodeAndId(groupCode, projectId, GraphCodeEnum.MechInArch.name(), 
+				RelCodeEnum.Eq2Fl.name(), master.getId(), null);
+		
+		AdmRelationObject convertObject = this.convertObject(master, "设备", slave, "建筑");
+		String buildingName = slave.getLocalName();
+		String floorName = floorInfo.get("localName") == null ? AdmCommonConstant.EMPTY : floorInfo.get("localName").asText();
+		convertObject.setMasterBuildingName(buildingName);
+		convertObject.setSlaveFloorName(floorName);
+		
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2BD, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2BD, groupCode, projectId, code);
+	}
+}

+ 95 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechInArchEq2FlRelationObject.java

@@ -0,0 +1,95 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHINARCH_EQ2FL)
+public class MechInArchEq2FlRelationObject extends AbstractReportRelationObject {
+
+	public MechInArchEq2FlRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechInArch.name());
+		objectNode.put("relCode", RelCodeEnum.Eq2Fl.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechInArch.name());
+		requestData.setRelCode(RelCodeEnum.Eq2Fl.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		AdmRelationObject convertObject = this.convertObject(master, "设备", slave, "楼层");
+		String floorName = master.getLocalName();
+		convertObject.setMasterFloorName(floorName);
+		convertObject.setSlaveFloorName(floorName);
+		
+		return convertObject;
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2FL, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2FL, groupCode, projectId, code);
+	}
+}

+ 90 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/MechInArchEq2SpRelationObject.java

@@ -0,0 +1,90 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.GraphCodeEnum;
+import com.persagy.proxy.adm.constant.RelCodeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.MECHINARCH_EQ2SP)
+public class MechInArchEq2SpRelationObject extends AbstractReportRelationObject {
+
+	public MechInArchEq2SpRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", GraphCodeEnum.MechInArch.name());
+		objectNode.put("relCode", RelCodeEnum.Eq2Sp.name());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(GraphCodeEnum.MechInArch.name());
+		requestData.setRelCode(RelCodeEnum.Eq2Sp.name());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "空间");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2SP_IN, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2SP_IN, groupCode, projectId, code);
+	}
+}

+ 102 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/RadiationNetworkConnectRelationObject.java

@@ -0,0 +1,102 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.RADIATIONNETWORK_CONNECT)
+public class RadiationNetworkConnectRelationObject extends AbstractReportRelationObject {
+	
+	public RadiationNetworkConnectRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		throw new UnsupportedOperationException("未实现的策略方法");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.LightingZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于照明分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.LightingZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于照明分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 102 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/RadiationNetworkTransparentRelationObject.java

@@ -0,0 +1,102 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.RADIATIONNETWORK_TRANSPARENT)
+public class RadiationNetworkTransparentRelationObject extends AbstractReportRelationObject {
+	
+	public RadiationNetworkTransparentRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_2.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_2.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_2.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_2.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "空间", slave, "空间");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_2, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_2, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.LightingZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于照明分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.LightingZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于照明分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 122 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/RelationObjectStrategy.java

@@ -0,0 +1,122 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.common.helper.SpringHelper;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月2日 下午10:46:03
+ */
+public interface RelationObjectStrategy {
+
+	String WHERE_IN = "$in";
+	
+	String OBJ_TYPE = "objType";
+	
+	ObjectMapper OBJECT_MAPPER = SpringHelper.getBean(ObjectMapper.class);
+	
+	static Map<String, String> OBJNAME_2_TYPE = new HashMap<String,String>(){
+		private static final long serialVersionUID = 1L;
+		{
+            put("对象ID", "id");
+            put("对象名称", "name");
+            put("对象本地编码", "localId");
+            put("对象本地名称", "localName");
+            put("设计图纸中编码", "cADID");
+        }
+    };
+    
+	/**
+	 * 统计关系总数
+	 * 
+	 * @param groupCode
+	 * @param projectId
+	 * @return
+	 */
+    long countRelationObjects(String groupCode, String projectId, AdmRelationTypeEnum typeEnum);
+    
+	/**
+	 * 查询出所有的关系信息
+	 * 
+	 * @param groupCode 集团编码
+	 * @param projectId 项目ID
+	 * @return 不会返回null
+	 */
+	List<AdmRelationObject> exportRelationObject(String groupCode, String projectId);
+	
+	/**
+	 * 查询出所有的关系对象数据
+	 * 
+	 * @param groupCode 集团编码
+	 * @param projectId 项目ID
+	 * @param mainContent	主对象的筛选关键字,筛选范围为id,name,local_id,local_name,cADID.为关系左侧对象
+	 * @param slaveContent	从对象的筛选关键字.objTo对应的对象,筛选范围为id,name,local_id,local_name.为关系右侧对象
+	 * @return 不会返回null
+	 */
+	List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent, AdmRelationTypeEnum typeEnum);
+	
+	/**
+	 * 分页查询关系对象数据
+	 * 
+	 * @param masterObjs 查询的数据集存储地方
+	 * @param requestData 请求参数
+	 * @param groupCode 集团编码
+	 * @param projectId 项目ID
+	 */
+	void queryPageRelations(List<ObjectDigital> masterObjs, RequestData requestData, String groupCode, String projectId);
+	
+	/**
+	 * 保存之前会校验数据的合法性
+	 * 
+	 * @param relationObject 需要校验的对象
+	 * @param groupCode
+	 * @param projectId
+	 * @param code 参考 OBJNAME_2_TYPE
+	 * @param typeEnum 
+	 * @return String - 校验失败的原因, ObjectNode -- BDTP接口的参数,不会返回null,请用instanceOf 判断返回值
+	 */
+	Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code, AdmRelationTypeEnum typeEnum);
+	/**
+	 * 检查关系对象数据的正确性,并完成额外字段的赋值功能
+	 *
+	 * @param relationTypeEnum AdmRelationTypeEnum枚举类
+	 * @param code
+	 * @return String - 校验失败的原因, ObjectNode -- BDTP接口的参数,不会返回null,请用instanceOf 判断返回值
+	 */
+	Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode,
+												 String projectId, String code, AdmRelationTypeEnum relationTypeEnum);
+
+	/**
+	 * 保存对象之间的关系
+	 * 
+	 * @param relationObject
+	 * @param groupCode
+	 * @param projectId
+	 * @return 
+	 */
+	boolean saveRelationObject(ObjectNode relationObject, String groupCode, String projectId);
+	
+	/**
+	 * 批量保存对象之间的关系
+	 * 
+	 * @param relationObjects
+	 * @param groupCode
+	 * @param projectId
+	 * @return 
+	 */
+	boolean saveRelationObjects(List<ObjectNode> relationObjects, String groupCode, String projectId);
+
+}

+ 99 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/SensorRelationshipSs2EqRelationObject.java

@@ -0,0 +1,99 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.SENSORRELATIONSHIP_SS2EQ)
+public class SensorRelationshipSs2EqRelationObject extends AbstractReportRelationObject {
+	
+	public SensorRelationshipSs2EqRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2EQ_SENSORRELATIONSHIP_SS2EQ.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2EQ_SENSORRELATIONSHIP_SS2EQ.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2EQ_SENSORRELATIONSHIP_SS2EQ.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2EQ_SENSORRELATIONSHIP_SS2EQ.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "设备");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2EQ_SENSORRELATIONSHIP_SS2EQ, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2EQ_SENSORRELATIONSHIP_SS2EQ, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!AdmObjectInfoConstant.CHECK_SENSOR_CODES.contains(masterClassCode)) {
+			return "主对象不是传感器,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 100 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/SensorRelationshipSs2SpRelationObject.java

@@ -0,0 +1,100 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 图类型编码 -- SensorRelationship
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.SENSORRELATIONSHIP_SS2SP)
+public class SensorRelationshipSs2SpRelationObject extends AbstractReportRelationObject {
+	
+	public SensorRelationshipSs2SpRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "空间");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!AdmObjectInfoConstant.CHECK_SENSOR_CODES.contains(masterClassCode)) {
+			return "主对象不是传感器,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 99 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/SensorRelationshipSs2SyRelationObject.java

@@ -0,0 +1,99 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmObjectInfoConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.SENSORRELATIONSHIP_SS2SY)
+public class SensorRelationshipSs2SyRelationObject extends AbstractReportRelationObject {
+	
+	public SensorRelationshipSs2SyRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.EQ2SY_SENSORRELATIONSHIP_SS2SY.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.EQ2SY_SENSORRELATIONSHIP_SS2SY.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.EQ2SY_SENSORRELATIONSHIP_SS2SY.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.EQ2SY_SENSORRELATIONSHIP_SS2SY.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "设备", slave, "系统");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.EQ2SY_SENSORRELATIONSHIP_SS2SY, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.EQ2SY_SENSORRELATIONSHIP_SS2SY, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!AdmObjectInfoConstant.CHECK_SENSOR_CODES.contains(masterClassCode)) {
+			return "主对象不是传感器,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 102 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/TrafficNetworkFFCloseRelationObject.java

@@ -0,0 +1,102 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.TRAFFICNETWORK_FFCLOSE)
+public class TrafficNetworkFFCloseRelationObject extends AbstractReportRelationObject {
+	
+	public TrafficNetworkFFCloseRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_3.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_3.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_3.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_3.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);	
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "空间", slave, "空间");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_3, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_3, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.GeneralZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于物业分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.GeneralZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于物业分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 102 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/TrafficNetworkFFOpenRelationObject.java

@@ -0,0 +1,102 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.TRAFFICNETWORK_FFOPEN)
+public class TrafficNetworkFFOpenRelationObject extends AbstractReportRelationObject {
+	
+	public TrafficNetworkFFOpenRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_2.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_2.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+	
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_2.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_2.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "空间", slave, "空间");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_2, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_2, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.GeneralZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于物业分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.GeneralZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于物业分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 102 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/strategy/relationdata/TrafficNetworkNormalRelationObject.java

@@ -0,0 +1,102 @@
+package com.persagy.proxy.adm.strategy.relationdata;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import com.persagy.dmp.common.helper.SpringHelper;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.common.model.response.CommonResult;
+import com.persagy.dmp.digital.client.DigitalRelationFacade;
+import com.persagy.dmp.digital.entity.ObjectDigital;
+import com.persagy.dmp.digital.entity.ObjectRelation;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationType;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.SpaceTypeEnum;
+import com.persagy.proxy.report.model.AdmRelationObject;
+import com.persagy.proxy.report.service.IRelationReportService;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy
+ * @author zhangqiankun
+ * @date 2021年9月3日 上午9:42:46
+ */
+@Component(value = AdmRelationType.TRAFFICNETWORK_NORMAL)
+public class TrafficNetworkNormalRelationObject extends AbstractReportRelationObject {
+	
+	public TrafficNetworkNormalRelationObject(IRelationReportService relationReportService) {
+		super(relationReportService);
+	}
+	
+	@Override
+	public long countRelationObjects(String groupCode, String projectId) {
+		QueryCriteria queryCriteria = new QueryCriteria();
+		ObjectNode objectNode = OBJECT_MAPPER.createObjectNode();
+		objectNode.put("graphCode", AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1.getGraphCode());
+		objectNode.put("relCode", AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1.getRelCode());
+		objectNode.put("valid", 1);
+		queryCriteria.setCriteria(objectNode);
+		queryCriteria.setOnlyCount(true);
+		
+		CommonResult<List<ObjectRelation>> result = DigitalRelationFacade.queryPrototype(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, queryCriteria);
+		return result == null ? 0 : (result.getCount() == null ? 0 : result.getCount());
+	}
+
+	@Override
+	public List<ObjectDigital> queryAllRelations(String groupCode, String projectId, String mainContent, Set<String> slaveContent) {
+		RequestData requestData = new RequestData();
+		requestData.setGraphCode(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1.getGraphCode());
+		requestData.setRelCode(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1.getRelCode());
+		if (StrUtil.isNotBlank(mainContent)) {
+			requestData.setMainContent(mainContent);
+		}
+		if (CollectionUtil.isNotEmpty(slaveContent)) {
+			requestData.setSlaveContent(slaveContent);
+		}
+		requestData.setPage(1L);
+		requestData.setSize(SpringHelper.getLong("persagy.common.sql.limit",500L));
+		
+		List<ObjectDigital> allDigitals = new ArrayList<ObjectDigital>();
+		this.queryPageRelations(allDigitals, requestData, groupCode, projectId);
+		return allDigitals;
+	}
+	
+	@Override
+	protected AdmRelationObject handleObjectDigital(ObjectDigital master, ObjectDigital slave, String groupCode, String projectId) {
+		return this.convertObject(master, "空间", slave, "空间");
+	}
+
+	@Override
+	public Object beforeSaveRelationObject(AdmRelationObject relationObject, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObject(relationObject, AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1, groupCode, projectId, code);
+	}
+
+	@Override
+	public Map<String,Object> beforeSaveRelationObjects(List<AdmRelationObject> relationObjects, String groupCode, String projectId, String code) {
+		return this.beforeSaveRelationObjects(relationObjects, AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1, groupCode, projectId, code);
+	}
+
+	@Override
+	protected String checkRelationObject(ObjectNode master, String masterClassCode, ObjectNode slave,
+			String slaveClassCode) {
+		if (!SpaceTypeEnum.GeneralZone.getCode().equals(masterClassCode)) {
+			return "主对象不属于物业分区类型,请参考规则";
+		}
+		if (!SpaceTypeEnum.GeneralZone.getCode().equals(slaveClassCode)) {
+			return "从对象不属于物业分区类型,请参考规则";
+		}
+		return null;
+	}
+	
+}

+ 38 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmContextUtil.java

@@ -0,0 +1,38 @@
+package com.persagy.proxy.adm.utils;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.persagy.dmp.common.context.AppContext;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+/**
+ * ADM上下文工具类
+ * @author Charlie Yu
+ * @date 2021-09-13
+ */
+public class AdmContextUtil {
+
+    /**
+     * 转换获取数据中台上下文参数
+     * @return
+     */
+    public static InstanceUrlParam toDmpContext() {
+        return InstanceUrlParam.builder().groupCode(AppContext.getContext().getGroupCode())
+                .projectId(AppContext.getContext().getProjectId())
+                .appId(AppContext.getContext().getAppId()).build();
+    }
+
+    /**
+     * 转换获取数据中台上下文参数
+     * @return
+     */
+    public static String generateIdStr(String prefix,Boolean addProjectFlag) {
+        if (StrUtil.isNotBlank(AppContext.getContext().getProjectId())
+                && addProjectFlag && AppContext.getContext().getProjectId().matches("^Pj[0-9]{10}$")){
+            String projectIdSuffix = StrUtil.subSuf(AppContext.getContext().getProjectId(),2);
+            return StrUtil.isNotBlank(prefix)?prefix+projectIdSuffix+ IdWorker.getIdStr():projectIdSuffix+ IdWorker.getIdStr();
+        }
+        return StrUtil.isNotBlank(prefix)?prefix+ IdWorker.getIdStr():IdWorker.getIdStr();
+    }
+
+}

+ 231 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmEntityTransferUtil.java

@@ -0,0 +1,231 @@
+package com.persagy.proxy.adm.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.utils.JsonNodeUtils;
+import com.persagy.dmp.common.exception.BusinessException;
+import com.persagy.dmp.common.helper.SpringHelper;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * ADM通用查询条件
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+public class AdmEntityTransferUtil {
+
+    /**
+     * 转换为数据中台对象
+     * @param objList
+     * @return
+     */
+    public static ArrayNode toDmpMultiEntity(List objList) {
+        ArrayNode arrayNode = JsonNodeUtils.toArrayNode(objList, "infos", null);
+        if(arrayNode == null) {
+            return arrayNode;
+        }
+        // outline特殊处理
+        for(int i = 0;i < arrayNode.size();i++) {
+            ObjectNode jsonNode = (ObjectNode) arrayNode.get(i);
+            JsonNode outLine = jsonNode.get("outline");
+            if(outLine != null && !outLine.isTextual()) {
+                jsonNode.remove("outline");
+                jsonNode.put("outline", outLine.toString());
+            }
+            JsonNode nullNode = jsonNode.get("nullList");
+            if(nullNode == null || !nullNode.isArray()) {
+                continue;
+            }
+            ArrayNode nullList = (ArrayNode) nullNode;
+            ArrayNode removeNode = jsonNode.putArray("$remove");
+            for(int k=0; k < nullList.size(); k++){
+                String node = nullList.get(k).textValue();
+                if(StrUtil.isBlank(node)) {
+                    continue;
+                }
+                if(node.startsWith("infos.")){
+                    node = node.replace("infos.","");
+                }
+                jsonNode.remove(node);
+                removeNode.add(node);
+            }
+            jsonNode.remove("nullList");
+        }
+        return arrayNode;
+    }
+
+    /**
+     * 转换为数据中台对象
+     * @param obj
+     * @return
+     */
+    public static JsonNode toDmpSingleEntity(Object obj) {
+        return JsonNodeUtils.toObjectNode(obj, "infos", null);
+    }
+
+    /**
+     * 转换为数据中心对象
+     * @param array 数据中台对象
+     * @param clazz 数据中心对象class
+     * @param <T>
+     * @return
+     */
+    public static <T> List<T> toAdmMultiEntity(List array, List<String> projection, Class<T> clazz) {
+        ArrayNode dataNode = JsonNodeUtils.toArrayNode(array, "infos", null);
+        return toAdmMultiEntity(dataNode, projection, clazz);
+    }
+    
+    public static <T> List<T> toAdmMultiEntityExtra(List array, List<String> projection, Class<T> clazz) {
+        ArrayNode dataNode = JsonNodeUtils.toArrayNode(array, null, null);
+        return toAdmMultiEntityExtra(dataNode, projection, clazz);
+    }
+
+    /**
+     * 转换为数据中心对象
+     * @param array
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> List<T> toAdmMultiEntity(ArrayNode array, List<String> projection, Class<T> clazz) {
+        if(ArrayUtil.isEmpty(array)) {
+            return null;
+        }
+        // 转换属性名
+        for(int i = 0, j = array.size();i < j;i++) {
+            JsonNode node = array.get(i);
+            if(node != null && node.isObject()) {
+                resetAdmProperty((ObjectNode) node, projection);
+            }
+        }
+        return JsonNodeUtils.toEntity(array, clazz, "infos");
+        /*try {
+			return JSONEntityUtil.toEntity(array, clazz, "infos");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+        return null;*/
+    }
+    
+    public static <T> List<T> toAdmMultiEntityExtra(ArrayNode array, List<String> projection, Class<T> clazz) {
+        if(ArrayUtil.isEmpty(array)) {
+            return null;
+        }
+        // 转换属性名
+        for(int i = 0, j = array.size();i < j;i++) {
+            JsonNode node = array.get(i);
+            if(node != null && node.isObject()) {
+                resetAdmProperty((ObjectNode) node, projection);
+            }
+        }
+        try {
+			return JSONEntityUtil.toEntity(array, clazz, "infos");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+        return null;
+    }
+
+    /**
+     * 转换为数据中心对象
+     * @param node
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> T toAdmSingleEntity(ObjectNode node, List<String> projection, Class<T> clazz) {
+        resetAdmProperty(node, projection);
+        return JsonNodeUtils.toEntity(node, clazz, "infos");
+    }
+
+    /**
+     * 处理dmp转adm对象的属性名
+     * @param node
+     */
+    private static void resetAdmProperty(ObjectNode node, List<String> projection) {
+        // 转换属性名 TODO 目前只有创建时间和修改时间需要转换,后续有其他时通过建立映射在此转换即可
+        copyProperty(node, "creationTime", "createTime");
+        copyProperty(node, "modifiedTime", "lastUpdate");
+        copyProperty(node, "objType", "objectType");
+        // outline特殊处理
+        JsonNode outLine = node.get("outline");
+        if(outLine != null && outLine.isTextual()) {
+            node.remove("outline");
+            ArrayNode arrayNode = toSingleEntityQuietly(outLine.textValue(), ArrayNode.class);
+            node.set("outline", arrayNode);
+        }
+        removeProperty(node, projection);
+    }
+
+    /**
+     * 转换为指定对象
+     * @param jsonStr
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> T toSingleEntityQuietly(String jsonStr, Class<T> clazz) {
+        try {
+            return SpringHelper.getBean(ObjectMapper.class).readValue(jsonStr, clazz);
+        } catch (IOException e) {
+            throw new BusinessException("outline格式解析失败");
+        }
+    }
+
+    /**
+     * 拷贝属性
+     * @param dmpData 数据中台对象
+     * @param srcProp 数据中台属性名
+     * @param desProp 对应的数据中心属性名
+     */
+    private static void copyProperty(ObjectNode dmpData, String srcProp, String desProp) {
+        if(dmpData == null) {
+            return;
+        }
+        JsonNode value = dmpData.get(srcProp);
+        if(value == null || value.isNull()) {
+            return;
+        }
+        dmpData.set(desProp, value);
+        dmpData.remove(srcProp);
+    }
+
+    /**
+     * 删除掉数据中心不需要的属性
+     * @param dmpData
+     */
+    private static void removeProperty(ObjectNode dmpData, List<String> projection){
+        if(CollUtil.isNotEmpty(projection)) {
+            // 转换为Set,提供遍历效率
+            Set<String> fieldSet = CollUtil.newHashSet(projection);
+            if(fieldSet.contains("localID")){//兼容adm前端数据
+                fieldSet.add("localId");
+            }
+            Iterator<String> fields =  dmpData.fieldNames();
+            while (fields.hasNext()) {
+                String field = fields.next();
+                // 返回结果中包含的不处理
+                if(fieldSet.contains(field)) {
+                    continue;
+                }
+                // 去掉不包含的属性
+                fields.remove();
+            }
+        } else {
+            // 返回全部时,去掉不需要属性
+            List<String> removeList = CollUtil.newArrayList("creator","valid", "createApp", "virtualCodes", "updateApp", "grouping", "modifier");
+            for(String removeField:removeList) {
+                dmpData.remove(removeField);
+            }
+        }
+    }
+}

+ 183 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmExcelUtil.java

@@ -0,0 +1,183 @@
+package com.persagy.proxy.adm.utils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.util.ResourceUtils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.request.AdmResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年10月21日 下午12:24:28
+ */
+@Slf4j
+public class AdmExcelUtil {
+
+	public static final String TEMP_PAHT = "/temp/";
+	
+	public static final String TEMP_UPLOAD_PAHT = "/temp/upload/";
+	
+	/**
+	 * 文件写入至本地
+	 * 
+	 * @param workbook
+	 * @param projectId
+	 * @param path
+	 * @param orgFileName
+	 * @return 
+	 */
+	public static String writeFile2Local(Workbook workbook, String projectId, String path, String orgFileName) {
+		FileOutputStream fileOutputStream = null;
+		String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+		// 重组文件名
+        String fileName = projectId + date + "." + orgFileName.substring(orgFileName.lastIndexOf(".") + 1);
+        try {
+    		// 调用中台存储完成之后,此文件存储至本地
+    		File templateFile = createTemplateFile(path, fileName);
+    		fileOutputStream = new FileOutputStream(templateFile);
+    		workbook.write(fileOutputStream);
+		} catch (Exception e) {
+			log.error("文件存储失败", e);
+		} finally {
+			if (fileOutputStream != null) {
+				try {
+					fileOutputStream.close();
+				} catch (IOException e) {}
+			}
+		}
+        return fileName;
+	}
+	
+	/**
+	 * 获取对应的文件,或者默认文件
+	 * 不同路径,防止镜像部署时获取不到
+	 * 
+	 * @param templateName 带后缀的文件名
+	 * @return
+	 * @throws FileNotFoundException 
+	 */
+	public static File getTemplateOrDefaultFile(String templateName) throws FileNotFoundException {
+		File file = ResourceUtils.getFile(AdmCommonConstant.SERVER_ROOT_PATH + TEMP_PAHT + templateName);
+		if (!file.exists()) {
+			file = ResourceUtils.getFile(AdmCommonConstant.SERVER_ROOT_PATH + TEMP_PAHT + "relation-template.xlsx");
+		}
+		return file;
+	}
+	
+	/**
+	 * 获取对应的模板文件,不同路径,防止镜像内获取不到
+	 * 
+	 * @param templateName 带后缀的文件名
+	 * @return
+	 * @throws FileNotFoundException 
+	 */
+	public static File getTemplateFile(String templateName) throws FileNotFoundException {
+		return ResourceUtils.getFile(AdmCommonConstant.SERVER_ROOT_PATH + TEMP_PAHT + templateName);
+	}
+	
+	/**
+	 * 创建本地文件,这里不再在classpath下创建
+	 * 
+	 * @param path 以 / 结尾
+	 * @param fileName 文件名称,带后缀
+	 * @throws IOException 
+	 */
+	public static File createTemplateFile(String path, String fileName) throws IOException {
+		File file = new File(path);
+		if (!file.exists()) {
+			file.mkdirs();
+		}
+		file = new File(path + fileName);
+		if (!file.exists()) {
+			file.createNewFile();
+		}
+		return file;
+	}
+	
+	/**
+	 * 获取导入结果
+	 * 
+	 * @param graphId
+	 * @param successCount
+	 * @param failCount
+	 * @return
+	 */
+	public static JSONObject getImportResult(String graphId, int successCount, int failCount) {
+		JSONObject result = new JSONObject();
+		result.put("relationType", graphId);
+		result.put("successCount", successCount);
+		result.put("failCount", failCount);
+        result.put("state", getState(successCount, failCount));
+		return result;
+	}
+	
+	/**
+	 * 获取导入结果
+	 * 
+	 * @param message
+	 * @param state
+	 * @param successCount
+	 * @param failCount
+	 * @return
+	 */
+	public static AdmResponse getImportFailResult(String message, String state, int successCount, int failCount) {
+		JSONObject content = new JSONObject();
+		content.put("state", state);
+		content.put("successCount", successCount);
+		content.put("failCount", failCount);
+		
+		AdmResponse failure = AdmResponse.failure(message);
+		failure.setContent(Lists.newArrayList(content));
+		return failure;
+	}
+	
+	/**
+	 * 获取导入结果
+	 * 
+	 * @param message
+	 * @param successCount
+	 * @param failCount
+	 * @return
+	 */
+	public static AdmResponse getImportSuccessResult(String message, int successCount, int failCount) {
+		JSONObject content = new JSONObject();
+		content.put("state", getState(successCount, failCount));
+		content.put("successCount", successCount);
+		content.put("failCount", failCount);
+		AdmResponse success = AdmResponse.success(Lists.newArrayList(content));
+		success.setMessage(message);
+		return success;
+	}
+	
+	/**
+	 * 获取文件导入状态
+	 * 
+	 * @param successCount
+	 * @param failCount
+	 * @return
+	 */
+	private static String getState(int successCount, int failCount) {
+		if (successCount > 0 && failCount > 0) {
+        	return "1";
+        } else if (successCount > 0 && failCount == 0) {
+        	return "0";
+        }
+        return "2";
+	}
+	
+}

+ 345 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/AdmQueryCriteriaHelper.java

@@ -0,0 +1,345 @@
+package com.persagy.proxy.adm.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.persagy.dmp.basic.model.QueryCriteria;
+import com.persagy.dmp.basic.model.QueryOperator;
+import com.persagy.dmp.common.constant.ValidEnum;
+import com.persagy.dmp.common.model.entity.BaseEntity;
+import com.persagy.proxy.adm.request.AdmQueryCriteria;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ADM通用查询条件
+ * @author Charlie Yu
+ * @date 2021-08-16
+ */
+public class AdmQueryCriteriaHelper {
+
+    /** 条件匹配字符串 */
+    public static final String[] COND_STR = {" = "," != "," > "," >= "," < "," <= "," in "," isnull "," contain "," startwith "," endwith "};
+    /** 条件匹配字符串 根据ADM实际调用查看,去掉空格*/
+    public static final String[] COND_STR_TRIM = {"=","!=",">",">=","<","<=","contain","isnull","in","startwith","endwith"};
+    /** 需要替换的字段对照 Map<AdmQueryCriteria.name, Map<AdmFieldName, DmpFieldName> */
+    public static Map<String, Map<String, String>> RENAME_MAP = new HashMap<>(16);
+    /** 与数据中台的操作参数对照 */
+    public static Map<String, String> OPERATOR_MAP = new HashMap<>();
+
+    static {
+        OPERATOR_MAP.put("!=", "$ne");
+        OPERATOR_MAP.put(">", "$gt");
+        OPERATOR_MAP.put(">=", "$gte");
+        OPERATOR_MAP.put("<", "$lt");
+        OPERATOR_MAP.put("<=", "$lte");
+        OPERATOR_MAP.put("in", "$in");
+        OPERATOR_MAP.put("contain", "$like");
+        OPERATOR_MAP.put("startwith", "$likeRight");
+        OPERATOR_MAP.put("endwith", "$likeLeft");
+    }
+
+    /**
+     * 将ADM的查询条件转换为DMP的
+     * 调用前注意:
+     * - 调用前将name赋值,才会将条件中adm的属性替换为dmp的属性
+     * - 统计查询时将isOnlyCount设置为true
+     * 调用后注意(需要调用者自行处理的):
+     * - 不处理级联,级联应在调用者里处理级联调用转换后查询赋值
+     * - 不处理projection,查询后自行根据projection筛选返回属性。(dmp只能指定扩展属性,而adm的是针对所有属性的)
+     * @param admCriteria
+     * @return
+     */
+    public static QueryCriteria toDmpCriteria(AdmQueryCriteria admCriteria) {
+        QueryCriteria dmpCriteria = new QueryCriteria();
+        // 拷贝分页
+        copyPageInfo(admCriteria, dmpCriteria);
+        // 处理filters
+        ObjectNode criteria = toCriteria(admCriteria.getName(), admCriteria.getFilters());
+        dmpCriteria.setCriteria(criteria);
+        if(StrUtil.isNotEmpty(admCriteria.getName())){
+            // 处理name
+            criteria.put("objType", admCriteria.getName());
+        }
+        // 补充valid = 1
+        if(!criteria.has(BaseEntity.PROP_VALID)) {
+            criteria.put(BaseEntity.PROP_VALID, ValidEnum.TRUE.getType());
+        }
+        // 补充关系条件
+        if(admCriteria.getRelationFrom() != null) {
+            criteria.set(QueryOperator.RELATION_FROM.getIndex(), admCriteria.getRelationFrom());
+        }
+        if(admCriteria.getRelationTo() != null) {
+            criteria.set(QueryOperator.RELATION_TO.getIndex(), admCriteria.getRelationTo());
+        }
+        // 处理排序
+        dmpCriteria.setOrders(toOrderItem(admCriteria.getOrders()));
+        // 处理统计
+        dmpCriteria.setOnlyCount(admCriteria.isOnlyCount());
+        return dmpCriteria;
+    }
+
+    /**
+     * 处理分页信息
+     * @param admCriteria
+     * @param dmpCriteria
+     */
+    public static void copyPageInfo(AdmQueryCriteria admCriteria, QueryCriteria dmpCriteria) {
+        // 页码
+        Integer pageNumber = admCriteria.getPageNumber();
+        if(pageNumber == null || pageNumber < 1) {
+            pageNumber = 1;
+        }
+        dmpCriteria.setPage(pageNumber.longValue());
+        // 条数
+        Integer pageSize = admCriteria.getPageSize();
+        if(pageSize == null || pageSize > admCriteria.getMaxRow()) {
+            pageSize = admCriteria.getMaxRow();
+        }
+        dmpCriteria.setSize(pageSize.longValue());
+    }
+
+    /**
+     * 排序字符串转换为对象
+     * @param orderStr
+     */
+    public static List<OrderItem> toOrderItem(String orderStr) {
+        if(StrUtil.isBlank(orderStr)) {
+            return null;
+        }
+        // 2021年10月20日16:00:01 兼容DMP中台的createTime,updateTime字段
+        orderStr = StrUtil.replace(orderStr,"createTime","creationTime");
+        orderStr = StrUtil.replace(orderStr,"updateTime","modifiedTime");
+        // 按,分隔
+        String[] orders = StrUtil.split(orderStr, ",");
+        List<OrderItem> orderList = new ArrayList<>();
+        for(String order:orders) {
+            // 按空格分隔
+            String[] items = StrUtil.split(order, " ");
+            // 去除空串
+            items = ArrayUtil.removeEmpty(items);
+            if(ArrayUtil.isEmpty(items)) {
+                continue;
+            }
+            OrderItem orderItem = new OrderItem();
+            // 第一位为排序字段
+            orderItem.setColumn(items[0].trim());
+            // 只有一位 或 第二位不是desc  表示为升序
+            orderItem.setAsc(items.length <= 1 || !"desc".equalsIgnoreCase(items[1]));
+            orderList.add(orderItem);
+        }
+        return orderList;
+    }
+
+    /**
+     * 将ADM过滤条件转换为DMP查询
+     * 由于数据中台不支持or条件,因此不能转换为中台的KV条件形式,只能转换为sql
+     * @param filters
+     * @return
+     */
+    public static ObjectNode toCriteria(String name, String filters) {
+        ObjectNode criteria = JsonNodeFactory.instance.objectNode();
+        // filters格式参考:http://doc.sagacloud.cn/doc/service/dev/lib/web/filters.html#%E8%BF%87%E6%BB%A4%E6%9D%A1%E4%BB%B6
+        if(StrUtil.isBlank(filters)) {
+            return criteria;
+        }
+        // 替换逻辑运算符: &&  ||  ;
+        filters = StrUtil.replace(filters, "&&", " and ");
+        filters = StrUtil.replace(filters, "||", " or ");
+        filters = StrUtil.replace(filters, ";", " and ");
+        // 处理[]
+        filters = StrUtil.replace(filters, "[", " ( ");
+        filters = StrUtil.replace(filters, "]", " ) ");
+        // 查找下一个 连接点[and or为连接点]
+        convertCondition(name, criteria, filters);
+        return criteria;
+    }
+
+    /**
+     * 转换为查询条件
+     * @param name
+     * @param criteria
+     * @param filters
+     */
+    private static void convertCondition(String name, ObjectNode criteria, String filters) {
+        // 按and分隔
+        List<String> andFilters = StrUtil.splitTrim(filters, " and ");
+        // 按分隔后的表达式依次处理
+        for(String andFilter:andFilters) {
+            // 按or分组
+            List<String> orFilters = StrUtil.splitTrim(andFilter, " or ");
+            if(CollUtil.isEmpty(orFilters)) {
+                continue;
+            }
+            // 长度为1,则不是or条件
+            if(orFilters.size() == 1) {
+                // 转换为Condition
+                convertExpress(name, criteria, orFilters.get(0));
+                continue;
+            }
+            // or条件
+            ObjectNode andOr = (ObjectNode) criteria.get(QueryOperator.AND_OR.getIndex());
+            if(andOr == null) {
+                // 没有此条件则创建
+                andOr = criteria.putObject(QueryOperator.AND_OR.getIndex());
+            }
+            // 转换为Condition
+            for(String orFilter:orFilters) {
+                convertExpress(name, andOr, orFilter);
+            }
+        }
+    }
+
+    /**
+     * 处理表达式
+     * @param criteria
+     * @param express
+     */
+    private static void convertExpress(String name, ObjectNode criteria, String express) {
+        String cond = StrUtil.isBlank(StrUtil.getContainsStrIgnoreCase(express, COND_STR)) ?
+                StrUtil.getContainsStrIgnoreCase(express, COND_STR_TRIM) : StrUtil.getContainsStrIgnoreCase(express, COND_STR);
+        if(StrUtil.isBlank(cond)) {
+            return;
+        }
+        int condIndex = StrUtil.indexOfIgnoreCase(express, cond, 0);
+        String condLeft = StrUtil.subPre(express, condIndex).trim();
+        String condRight = StrUtil.subSuf(express, condIndex+cond.length()).trim();
+        addCondition(name, criteria, condLeft, cond.trim().toLowerCase(), condRight);
+    }
+
+    /**
+     * 拼接条件
+     * @param criteria
+     * @param column
+     * @param operator
+     * @param value
+     */
+    private static void addCondition(String name, ObjectNode criteria, String column, String operator, String value) {
+        // 20211015 移除列名中的infos.
+        column = StrUtil.replaceIgnoreCase(column, "infos.", "");
+        // 替换列名
+        column = replaceColumns(name, column);
+        if("=".equals(operator)) {
+            criteria.set(column, getJsonNode(criteria, value));
+        } else if("in".equals(operator)) {
+            // 按,分隔
+            String[] splits = StrUtil.split(value, ",");
+            if(ArrayUtil.isEmpty(splits)) {
+                return;
+            }
+            ArrayNode node = criteria.putArray(column);
+            for(String split:splits) {
+                // 去掉所有的() 即为值
+                split = StrUtil.removeAll(split, '(',')');
+                node.add(getJsonNode(criteria, split.trim()));
+            }
+        } else if("isnull".equals(operator)) {
+            boolean ifNot = true;
+            if(column.indexOf("not") >= 0){
+                ifNot = false;
+                column = column.replace("not","").trim();
+            }
+            ObjectNode node = criteria.putObject(column);
+            node.put("$null", ifNot);
+        } else {
+            ObjectNode node = criteria.putObject(column);
+            node.set(OPERATOR_MAP.get(operator), getJsonNode(node, value));
+        }
+     }
+
+    /**
+     * 取Json值对象
+     * @param criteria
+     * @param value
+     * @return
+     */
+    private static JsonNode getJsonNode(ObjectNode criteria, String value) {
+        if(StrUtil.isBlank(value)) {
+            return criteria.nullNode();
+        }
+        // 字符串
+        if(StrUtil.startWith(value, "'") && StrUtil.endWith(value, "'")) {
+            return criteria.textNode(StrUtil.sub(value, 1, value.length()-1));
+        }
+        // 字符串
+        if(StrUtil.startWith(value, "\"") && StrUtil.endWith(value, "\"")) {
+            return criteria.textNode(StrUtil.sub(value, 1, value.length()-1));
+        }
+        // 数值
+        if (StrUtil.contains(value, ".")) {
+            try {
+                BigDecimal no = new BigDecimal(value);
+                return criteria.numberNode(no);
+            } catch (NumberFormatException e) {
+
+            }
+        }
+        // 整型
+        try {
+            Integer no = Integer.valueOf(value);
+            return criteria.numberNode(no);
+        } catch (NumberFormatException e) {
+
+        }
+        return criteria.nullNode();
+    }
+
+    /**
+     * 替换属性称名
+     * @param name
+     * @param column
+     * @return
+     */
+    private static String replaceColumns(String name, String column) {
+        Map<String, String> fieldMap = getRenameFields(name);
+        // 没有对照则使用原本的
+        if(MapUtil.isEmpty(fieldMap) || !fieldMap.containsKey(column)) {
+            return column;
+        }
+        return fieldMap.get(column);
+    }
+
+    /**
+     * 获取更名对照
+     * @param name
+     * @return
+     */
+    private static Map<String, String> getRenameFields(String name) {
+        // 获取通用对照
+        Map<String, String> commonMap = getRenameMap().get("COMMON");
+        // 获取此类型的对照
+        Map<String, String> nameMap = getRenameMap().get(name);
+        if(MapUtil.isEmpty(nameMap)) {
+            return commonMap;
+        }
+        Map<String, String> rsMap = new HashMap<>();
+        rsMap.putAll(commonMap);
+        rsMap.putAll(nameMap);
+        return rsMap;
+    }
+
+    /**
+     * 获取通用Map
+     * @return
+     */
+    private static Map<String, Map<String, String>> getRenameMap() {
+        if(MapUtil.isEmpty(RENAME_MAP)) {
+            // COMMON表示通用对照
+            Map<String, String> commonMap = new HashMap<>();
+            commonMap.put("createTime", "creationTime");
+            commonMap.put("lastUpdate", "modifiedTime");
+            RENAME_MAP.put("COMMON", commonMap);
+        }
+        return RENAME_MAP;
+    }
+}

+ 204 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/GeoToolsUtil.java

@@ -0,0 +1,204 @@
+package com.persagy.proxy.adm.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.extern.slf4j.Slf4j;
+import org.geotools.geometry.jts.JTSFactoryFinder;
+import org.locationtech.jts.geom.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * @ClassName GeoToolsUtil
+ * @Description: 点面包含关系分析
+ * @Author linhuili
+ * @Date 2021/9/3 20:31
+ * @Version V1.0
+ **/
+@Slf4j
+public class GeoToolsUtil {
+    /**
+     * 创建点
+     * @param pointLocal
+     */
+    private static Point createPoint(ObjectNode pointLocal){
+        double x =0.0D;
+        double y =0.0D;
+        double z =0.0D;
+        if(pointLocal.get("x") != null){
+            x = pointLocal.get("x").asDouble();
+        }
+        if(pointLocal.get("y") != null){
+            y = pointLocal.get("y").asDouble();
+        }
+        if(pointLocal.get("z") !=null){
+            z = pointLocal.get("z").asDouble();
+        }
+        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
+        Coordinate coord = new Coordinate(x, y,z);
+        Point point = geometryFactory.createPoint(coord);
+        return point;
+    }
+
+    /**
+     * 创建面
+     * @param outLines
+     */
+    private static Polygon createPolygon(List<ObjectNode> outLines){
+        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
+        List<Coordinate> objects = new ArrayList<>();
+        for (ObjectNode outLine : outLines) {
+            double x = 0.0D;
+            double y = 0.0D;
+            double z = 0.0D;
+            if(outLine.get("x") != null){
+                x =outLine.get("x").asDouble();
+            }
+            if(outLine.get("y") != null){
+                y = outLine.get("y").asDouble();
+            }
+            if(outLine.get("z") !=null){
+                z = outLine.get("z").asDouble();
+            }
+            Coordinate coordinate = new Coordinate(x, y, z);
+            objects.add(coordinate);
+        }
+        //注意数据的闭合
+        Coordinate[] coordinates = objects.toArray(new Coordinate[0]);
+        LinearRing ring = geometryFactory.createLinearRing(coordinates);
+        LinearRing holes[] = null;
+        Polygon polygon = geometryFactory.createPolygon(ring, holes);
+
+        return polygon;
+   }
+    /**
+     * 创建面
+     * @param outLines
+     */
+    private static Polygon createPolygon(ArrayNode outLines){
+        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
+        List<Coordinate> objects = new ArrayList<>();
+        for (JsonNode outLine : outLines) {
+            double x = outLine.has("X")?Double.parseDouble(outLine.get("X").asText()):0.0D;
+            double y = outLine.has("Y")?Double.parseDouble(outLine.get("Y").asText()):0.0D;
+            double z = 0L;
+            Coordinate coordinate = new Coordinate(x, y, z);
+            objects.add(coordinate);
+        }
+        //注意数据的闭合
+        Coordinate[] coordinates = objects.toArray(new Coordinate[0]);
+        LinearRing ring = geometryFactory.createLinearRing(coordinates);
+        return geometryFactory.createPolygon(ring, null);
+    }
+
+    /**
+     * 点面包含关系判断
+     * 用途:判断一个面是否包含一个点,即一个点是否在一个面内
+     * @param pointLocal 坐标点
+     * @param outLines 轮廓线
+     * @return
+     */
+   public static Boolean isPointInPoly(ObjectNode pointLocal, List<ObjectNode> outLines) {
+       //创建点
+       Point point = createPoint(pointLocal);
+       //创建面
+       Polygon polygon = createPolygon(outLines);
+       //判断点面包含关系
+       boolean flag = polygon.contains(point);
+       return flag;
+   }
+
+
+    /**
+     * 点面包含关系判断
+     * 用途:判断一个面是否包含一个点,即一个点是否在一个面内
+     * @param fromOutLines: 轮廓坐标
+     * @param toOutLines: 轮廓坐标
+     * @return
+     */
+    public static Boolean isPolyInPoly(List<ObjectNode> fromOutLines,
+                                       List<ObjectNode> toOutLines) {
+        if (CollUtil.isEmpty(fromOutLines) || CollUtil.isEmpty(toOutLines)){
+            return false;
+        }
+        //创建点
+        Polygon fromPolygon = createPolygon(fromOutLines);
+        //创建面
+        Polygon toPolygon = createPolygon(toOutLines);
+        //判断面-面包含关系
+        return fromPolygon.contains(toPolygon)
+                || fromPolygon.equalsTopo(toPolygon)
+                || fromPolygon.overlaps(toPolygon)
+                || toPolygon.contains(fromPolygon);
+    }
+
+    /**
+     * 点面包含关系判断
+     * 用途:判断一个面是否包含一个点,即一个点是否在一个面内
+     * @param pointLocal 坐标点
+     * @param outLines 轮廓线
+     * @return
+     */
+    public static Boolean isPointInPoly(ObjectNode pointLocal, ArrayNode outLines) {
+        if (null==pointLocal || CollUtil.isEmpty(outLines)){
+            return false;
+        }
+        //创建点
+        Point point = createPoint(pointLocal);
+        if (!outLines.get(0).isArray()){
+            return isPointInPoly(point,outLines);
+        }
+        for (JsonNode outLine : outLines) {
+            if (outLine.isArray() && outLine.get(0).isArray()){
+                ArrayNode subOutlines = (ArrayNode)outLine;
+                for (JsonNode subOutLine : subOutlines) {
+                    //创建面
+                    if (isPointInPoly(point,(ArrayNode) subOutLine)){
+                        return true;
+                    }
+                }
+                continue;
+            }
+            //创建面
+            if (isPointInPoly(point,(ArrayNode)outLine)){
+                return true;
+            }
+        }
+        //判断点面包含关系
+        return false;
+    }
+    /**
+     * 点面包含关系判断
+     * 用途:判断一个面是否包含一个点,即一个点是否在一个面内
+     * @param point 坐标点
+     * @param outLines 轮廓线
+     * @return
+     */
+    public static Boolean isPointInPoly(Point point, ArrayNode outLines) {
+        if (null==point || CollUtil.isEmpty(outLines)){
+            return false;
+        }
+        //创建面
+        try {
+            Polygon polygon = createPolygon(outLines);
+            // 判断点面包含关系
+            return polygon.contains(point);
+        }catch (IllegalArgumentException argumentE){
+            try {
+                // 将第一个加入最后一个结点尝试一下
+                outLines.add(outLines.get(0));
+                Polygon polygon = createPolygon(outLines);
+                // 判断点面包含关系
+                return polygon.contains(point);
+            }catch (Exception ignored){}
+        } catch (Exception e){
+            log.warn("解析失败"+outLines.toString(),e);
+        }
+        return false;
+    }
+
+}

File diff suppressed because it is too large
+ 208 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/JSONEntityUtil.java


+ 39 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/adm/utils/ObjectNameUtil.java

@@ -0,0 +1,39 @@
+package com.persagy.proxy.adm.utils;
+
+import cn.hutool.core.util.RandomUtil;
+
+/**
+ * 根据中心数据规则生成对象名字
+ * 参见 datacenterShaftNameUtil
+ * @author lvxy
+ * @date 2021/8/31
+ */
+public class ObjectNameUtil {
+
+    /**
+     * 竖井名字
+     *
+     * @param   name    名字
+     */
+    public static String objectName(String name){
+        return name + getCode(5);
+    } // Function shaftName()
+
+    /**
+     * 字母和数字组合的随机数
+     *
+     * @param   n   随机数的位数
+     */
+    private static String getCode(int n) {
+        String str = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ";//保存数字0-9 和 大小写字母
+        char[] ch = new char[n]; //声明一个字符数组对象ch 保存 验证码
+        for (int i=0 ; i< n; i++) {
+            //创建一个新的随机数生成器
+            int index = RandomUtil.getRandom().nextInt(str.length());//返回[0,string.length)范围的int值    作用:保存下标
+            ch[i] = str.charAt(index);//charAt() : 返回指定索引处的 char 值   ==》保存到字符数组对象ch里面
+        }
+        //将char数组类型转换为String类型保存到result
+        return  String.valueOf(ch);
+    }
+
+}

+ 64 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmCalcSpecialController.java

@@ -0,0 +1,64 @@
+package com.persagy.proxy.calculation.controller;
+
+import cn.hutool.core.util.StrUtil;
+import com.persagy.dmp.common.exception.BusinessException;
+import com.persagy.proxy.adm.constant.AdmCommonConstant;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.BusinessErrorRwdCode;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.adm.utils.AdmContextUtil;
+import com.persagy.proxy.calculation.service.AdmCalcSpecialService;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+/***
+ * Description: 机电管网系统关系计算
+ * @author : lijie
+ * @date :2021/9/14 23:15
+ * Update By lijie 2021/9/14 23:15
+ */
+@RestController
+@RequestMapping("/calc_special/")
+@RequiredArgsConstructor
+public class AdmCalcSpecialController {
+
+    private final AdmCalcSpecialService admCalcSpecialService;
+
+    /***
+     * Description: 管网系统设备分块  +  计算流向
+     * @param relationType : 关系类型
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/29 11:12
+     * Update By lijie 2021/9/29 11:12
+     */
+    @PostMapping("sys-block")
+    public AdmResponse sysBolck(@RequestParam("relationType") String relationType) throws Exception {
+        // 组装上下文条件
+        InstanceUrlParam context = AdmContextUtil.toDmpContext();
+        Map<String, AdmRelationTypeEnum> relationTypeMap = AdmRelationTypeEnum.getRelationTypeMap();
+        if (!relationTypeMap.containsKey(relationType)){
+            throw new BusinessException(BusinessErrorRwdCode.A7201.getCode(),BusinessErrorRwdCode.A7201.getDesc());
+        }
+        return admCalcSpecialService.sysBlock(context, relationTypeMap.get(relationType));
+    }
+    /***
+     * Description: 管网计算
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/29 11:58
+     * Update By lijie 2021/9/29 11:58
+     */
+    @GetMapping("calcNetworks")
+    public AdmResponse calcNetworks() throws Exception {
+        // 组装上下文条件
+        InstanceUrlParam context = AdmContextUtil.toDmpContext();
+        return admCalcSpecialService.calcNetworks(context);
+    }
+
+
+}

+ 71 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmManualRelCalController.java

@@ -0,0 +1,71 @@
+package com.persagy.proxy.calculation.controller;
+
+import com.persagy.proxy.calculation.model.AdmManualRelCalRequest;
+import com.persagy.proxy.calculation.model.AdmManualRelationCalcDel;
+import com.persagy.proxy.calculation.model.AdmRelationAddRequest;
+import com.persagy.proxy.adm.request.AdmCreateResponse;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.calculation.service.AdmManualRelCalService;
+import com.persagy.proxy.adm.utils.AdmContextUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/***
+ * Description:手动计算输入类
+ * @author : lijie
+ * @date :2021/8/31 11:37
+ * Update By lijie 2021/8/31 11:37
+ */
+@RestController
+@RequestMapping("/rel-manual-calc/")
+@RequiredArgsConstructor
+public class AdmManualRelCalController {
+
+    private final AdmManualRelCalService relationCalcService;
+    
+    /***
+     * Description: 添加关系
+     * @param request : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse  
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = "add")
+    public AdmCreateResponse addRelations(@RequestBody AdmRelationAddRequest request) throws Exception {
+        return relationCalcService.addRels(AdmContextUtil.toDmpContext(), request);
+    }
+    /***
+     * Description: 删除关系
+     * @param admManualRelationCalcDel : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = "del")
+    public AdmCreateResponse delRelations(@Validated @RequestBody AdmManualRelationCalcDel admManualRelationCalcDel) throws Exception {
+        return relationCalcService.delRels(AdmContextUtil.toDmpContext(), admManualRelationCalcDel);
+    }
+    /***
+     * Description: 查询关系数据
+     * @param admManualRelCalRequest : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = "query")
+    public AdmResponse query(@Validated @RequestBody AdmManualRelCalRequest admManualRelCalRequest) throws Exception {
+        return relationCalcService.query(AdmContextUtil.toDmpContext(), admManualRelCalRequest);
+    }
+
+
+
+
+}

+ 53 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmMepSystemCalcController.java

@@ -0,0 +1,53 @@
+package com.persagy.proxy.calculation.controller;
+
+import com.persagy.proxy.calculation.model.AdmMepSourceTypeEntity;
+import com.persagy.proxy.adm.request.AdmCreateRequest;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.calculation.service.AdmMepSystemCalcService;
+import com.persagy.proxy.adm.utils.AdmContextUtil;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import javax.ws.rs.QueryParam;
+
+/***
+ * Description: 机电管网系统关系计算
+ * @author : lijie
+ * @date :2021/9/14 23:15
+ * Update By lijie 2021/9/14 23:15
+ */
+@RestController
+@RequestMapping("/mep-system-calc/source/")
+@RequiredArgsConstructor
+public class AdmMepSystemCalcController {
+
+    private final AdmMepSystemCalcService admMepSystemCalcService;
+
+    /***
+     * Description: 添加源端设备类型
+     * @param request : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/14 23:20
+     * Update By lijie 2021/9/14 23:20
+     */
+    @PostMapping("add")
+    public AdmResponse add(@RequestBody AdmCreateRequest<AdmMepSourceTypeEntity> request) {
+        return admMepSystemCalcService.add(AdmContextUtil.toDmpContext(), request);
+    }
+    /***
+     * Description: 查询源端设备类型
+     * @param calcName : 关系名称
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/14 23:20
+     * Update By lijie 2021/9/14 23:20
+     */
+    @GetMapping("query")
+    public AdmResponse query(@QueryParam("calcName") String calcName) {
+        return admMepSystemCalcService.query(AdmContextUtil.toDmpContext(), calcName);
+    }
+
+
+}

+ 50 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmModelRelController.java

@@ -0,0 +1,50 @@
+package com.persagy.proxy.calculation.controller;
+
+import com.persagy.dmp.common.exception.BusinessException;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.adm.utils.AdmContextUtil;
+import com.persagy.proxy.dictionary.model.AdmModelRel;
+import com.persagy.proxy.dictionary.service.IAdmModelRelService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @ClassName AdmModelRelController
+ * @Description: 模型修改设备元空间的建筑楼层信息
+ * @Author linhuili
+ * @Date 2021/8/31 14:30
+ * @Version V1.0
+ **/
+@RestController
+@RequestMapping("/rel/update")
+@Slf4j
+public class AdmModelRelController {
+
+    @Autowired
+    private IAdmModelRelService service;
+
+    /**
+     * 模型修改设备元空间的建筑楼层信息
+     * @param admModelRel
+     * @return
+     * @throws Exception
+     */
+    @PostMapping("/equip-ispace")
+    public AdmResponse update(@RequestBody AdmModelRel admModelRel) throws Exception {
+        if(StringUtils.isEmpty(admModelRel.getModelId())){
+            throw new BusinessException("模型ID不能为空");
+        }
+        if(StringUtils.isEmpty(admModelRel.getFloorId())){
+            throw new BusinessException("楼层ID不能为空");
+        }
+        service.doUpdateModelInfo(AdmContextUtil.toDmpContext(), AdmModelRel.class,admModelRel);
+        return AdmResponse.success();
+    }
+
+}

+ 318 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/controller/AdmRelCalController.java

@@ -0,0 +1,318 @@
+package com.persagy.proxy.calculation.controller;
+
+import cn.hutool.core.collection.CollUtil;
+import com.persagy.dmp.common.exception.BusinessException;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.constant.BusinessErrorRwdCode;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.calculation.service.AdmRelCalService;
+import com.persagy.proxy.adm.utils.AdmContextUtil;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Map;
+
+/***
+ * Description:关系计算输入类
+ * @author : lijie
+ * @date :2021/8/31 11:37
+ * Update By lijie 2021/8/31 11:37
+ */
+@RestController
+@RequestMapping("/relation-calc/")
+@RequiredArgsConstructor
+public class AdmRelCalController {
+
+    private final AdmRelCalService admRelCalService;
+
+    /***
+     * Description: 添加关系(图类型关系为ArchSubset)
+     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型),以英文逗号隔开 HeatingZone,CleanZone,
+     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
+     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
+     * bd2sp: 建筑下的空间
+     * fl2sp: 楼层下的空间
+     * sh2bd: 建筑下的竖井,实际关系应该是bd2sh
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"bd2sp","fl2sp","sh2bd"})
+    public AdmResponse archSubsetCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
+                                              @RequestParam(value = "relationType",required = false) String relationTypeStr,
+                                              HttpServletRequest request) {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),CollUtil.newArrayList(getAdmRelationTypeEnum(request)),objectTypeStr);
+        return AdmResponse.success(new ArrayList<>());
+    }
+
+    /***
+     * Description: 添加关系(图类型关系为MechInArch)
+     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型),以英文逗号隔开 HeatingZone,CleanZone,
+     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
+     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
+     * eq2bd:设备所在建筑
+     * eq2fl:设备所在楼层
+     * eq2sh:设备所在竖井
+     * eq2sp_in:设备所在业务空间
+     * sy2bd: 系统所在建筑
+     * sy2fl: 系统所在楼层
+     * sy2sh: 系统所在竖井
+     * sy2sp: 系统所在业务空间
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"eq2bd","eq2fl","eq2sh","eq2sp_in","sy2bd","sy2fl","sy2sh","sy2sp"})
+    public AdmResponse mechInArchCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
+                                              @RequestParam(value = "relationType",required = false) String relationTypeStr,
+                                              HttpServletRequest request) {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(), CollUtil.newArrayList(getAdmRelationTypeEnum(request)),objectTypeStr);
+        return AdmResponse.success(new ArrayList<>());
+    }
+
+    /***
+     * Description: 添加关系(图类型关系为PropertyInArch)
+     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型),以英文逗号隔开 HeatingZone,CleanZone,
+     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
+     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
+     * pe2bd:资产所在建筑
+     * pe2fl:资产所在楼层
+     * pe2sh:资产所在竖井
+     * pe2sp:资产所在业务空间
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"pe2bd","pe2fl","pe2sh","pe2sp"})
+    public AdmResponse propertyInArchCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
+                                                  @RequestParam(value = "relationType",required = false) String relationTypeStr) {
+        // 资产暂时未引入,直接返回成功
+        // 组装上下文条件
+        InstanceUrlParam context = AdmContextUtil.toDmpContext();
+        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为MechForArch)
+     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型),以英文逗号隔开 HeatingZone,CleanZone,
+     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
+     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
+     * eq2sp_for:设备服务空间关系
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"eq2sp_for"})
+    public AdmResponse mechForArchCalcRelation(@RequestParam(value = "objectTypes",required = false) String objectTypeStr,
+                                               @RequestParam(value = "relationType",required = false) String relationTypeStr) {
+        // 资产暂时未引入,直接返回成功
+        // 组装上下文条件
+        InstanceUrlParam context = AdmContextUtil.toDmpContext();
+        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为ArchForArch)
+     * @param buildingId : 建筑id
+     * @param objectType : 对象分类
+     * @param type : 对象类型
+     * sp2sp:空间服务于空间
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"sp2sp"})
+    public AdmResponse archForArchCalcRelation( @RequestParam(value = "buildingId",required = false) String buildingId,
+                                                @RequestParam(value = "objectType",required = false) String objectType,
+                                                @RequestParam(value = "type",required = false) String type) {
+        admRelCalService.calcRelationForArchForArchSpToSp(AdmContextUtil.toDmpContext(),buildingId,objectType,type,
+                AdmRelationTypeEnum.SP2SP_ARCHFORARCH);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为SensorRelationship)
+     * eq2sp_SensorRelationship_ss2sp:传感器测量空间关系
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"eq2sp_SensorRelationship_ss2sp"})
+    public AdmResponse sensorRelationshipCalcRelation() {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
+                CollUtil.newArrayList(AdmRelationTypeEnum.EQ2SP_SENSORRELATIONSHIP_SS2SP),"AirConditioningZone");
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为ConvectionNetwork)
+     * sp2sp_ConvectionNetwork_1:Natural-空气自然对流
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"sp2sp_ConvectionNetwork_1"})
+    public AdmResponse convectionNetworkCalcRelation() {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
+                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1),null);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为RadiationNetwork)
+     * sp2sp_RadiationNetwork_1:光照辐射网络-Connect-光照连通
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"sp2sp_RadiationNetwork_1"})
+    public AdmResponse radiationNetworkCalcRelation() {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
+                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1),null);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为SpaceNeighborhood)
+     * sp2sp_SpaceNeighborhood_5:业务空间(同类)邻接关系-Connect-空间连通
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"sp2sp_SpaceNeighborhood_5"})
+    public AdmResponse spaceNeighborhoodCalcRelation() {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
+                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_SPACENEIGHBORHOOD_5),null);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(计算设备所在建筑,系统所在建筑,图类型关系为MechInArch)
+     * syeq2bd:建筑下的系统设备部件,计算设备所在建筑(eq2bd),系统所在建筑(sy2bd)
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"syeq2bd"})
+    public AdmResponse syeq2bdCalcRelation() {
+        Map<String, AdmRelationTypeEnum> relationTypeMap = AdmRelationTypeEnum.getRelationTypeMap();
+        if (!relationTypeMap.containsKey("eq2bd") || !relationTypeMap.containsKey("sy2bd")){
+            throw new BusinessException(BusinessErrorRwdCode.A7201.getCode(),BusinessErrorRwdCode.A7201.getDesc());
+        }
+        ArrayList<AdmRelationTypeEnum> admRelationTypeEnums =
+                CollUtil.newArrayList(relationTypeMap.get("eq2bd"), relationTypeMap.get("sy2bd"));
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),admRelationTypeEnums,null);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为TrafficNetwork)
+     * sp2sp_TrafficNetwork_1:建筑交通网络(同类)-Normal-普通交通
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"sp2sp_TrafficNetwork_1"})
+    public AdmResponse trafficNetworkCalcRelation() {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
+                CollUtil.newArrayList(AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_1),null);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 添加关系(图类型关系为ThroughRelationship)
+     * fl2fl:楼层贯通关系
+     * sh2sh:竖井贯通关系
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"fl2fl","sh2sh"})
+    public AdmResponse throughRelationshipCalcRelation(HttpServletRequest request) {
+        admRelCalService.calcRelation(AdmContextUtil.toDmpContext(),
+                CollUtil.newArrayList(getAdmRelationTypeEnum(request)),null);
+        return AdmResponse.success(new ArrayList<>());
+    }
+
+    /***
+     * Description: 更改计算标记
+     * @param relType : 关系类型
+     * @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型),以英文逗号隔开 HeatingZone,CleanZone,
+     *                      DomesticWaterSupplyZone,NetworkZone,TenantZone,AirConditioningZone,FunctionZone,
+     *                      FireZone,SecurityZone,GeneralZone,PowerSupplyZone,LightingZone
+     * sign: 更改计算标记
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    @PostMapping(value = {"sign"})
+    public AdmResponse changeSign( @RequestParam(value = "objectTypes",required = false) String objectTypeStr,
+                                   @RequestParam(value = "relationType",required = false) String relationTypeStr) {
+        // 资产暂时未引入,直接返回成功
+        // 组装上下文条件
+        InstanceUrlParam context = AdmContextUtil.toDmpContext();
+        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
+        return AdmResponse.success(new ArrayList<>());
+    }
+    /***
+     * Description: 其他计算接口,预留接口,用于处理其他的关系不存在接口会出现404问题
+     * @param relType : 关系类型
+     * @param objectTypeStr : 对象类型
+     * @param relationTypeStr : 关系类型
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/10/15 19:58
+     * Update By lijie 2021/10/15 19:58
+     */
+    @PostMapping(value = "{relType}")
+    public AdmResponse otherCal( @PathVariable("relType") String relType,
+                                 @RequestParam(value = "objectTypes",required = false) String objectTypeStr,
+                                 @RequestParam(value = "relationType",required = false) String relationTypeStr) {
+        // 资产暂时未引入,直接返回成功
+        // 组装上下文条件
+        InstanceUrlParam context = AdmContextUtil.toDmpContext();
+        // admRelCalService.calcRelation(context,relType,objectTypeStr,relationTypeStr);
+        return AdmResponse.success(new ArrayList<>());
+    }
+
+    /***
+     * Description: 获得关系枚举类型
+     * @param request : 请求体
+     * @return : com.persagy.proxy.adm.constant.AdmRelationTypeEnum
+     * @author : lijie
+     * @date :2021/9/11 22:33
+     * Update By lijie 2021/9/11 22:33
+     */
+    private AdmRelationTypeEnum getAdmRelationTypeEnum(HttpServletRequest request) {
+        String suffix = getSuffixRequestUrl(request);
+        Map<String, AdmRelationTypeEnum> relationTypeMap = AdmRelationTypeEnum.getRelationTypeMap();
+        if (!relationTypeMap.containsKey(suffix)){
+            throw new BusinessException(BusinessErrorRwdCode.A7201.getCode(),BusinessErrorRwdCode.A7201.getDesc());
+        }
+        return relationTypeMap.get(suffix);
+    }
+
+    /***
+     * Description: 获得最后一个/后请求地址
+     * @param request : 请求对象
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/11 22:09
+     * Update By lijie 2021/9/11 22:09
+     */
+    private String getSuffixRequestUrl(HttpServletRequest request) {
+        String requestURI = request.getRequestURI();
+        return requestURI.substring(requestURI.lastIndexOf("/")+1);
+    }
+
+}

+ 27 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmManualRelCalRequest.java

@@ -0,0 +1,27 @@
+package com.persagy.proxy.calculation.model;
+
+import lombok.Data;
+
+@Data
+public class AdmManualRelCalRequest {
+
+    /**主从对象类型,主1、从2*/
+    private String objectType;
+    /**关系类型*/
+    private String relType;
+    /**分类类型*/
+    private String category;
+    /**楼层id,未明确楼层传(isNull)*/
+    private String floorId;
+    /**建筑id,未明确建筑传(isNull)*/
+    private String buildingId;
+    /**模糊查询 关键词*/
+    private String vague;
+    /**模糊查询 关键词*/
+    private String vagueTo;
+    /** 第几页(从1开始) */
+    private Integer pageNumber;
+    /** 每页记录数(0 < 记录数 < 1000) */
+    private Integer pageSize;
+
+}

+ 26 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmManualRelationCalcDel.java

@@ -0,0 +1,26 @@
+package com.persagy.proxy.calculation.model;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class AdmManualRelationCalcDel {
+
+    /**主对象Id*/
+    @NotNull(message = "主对象 id 不可以为空")
+    private String fromId;
+
+    /**从对象 Id*/
+    @NotNull(message = "从对象 id 不可以为空")
+    private String toId;
+
+    /**关系类型*/
+    @NotNull(message = "关系类型不可以为空")
+    String relType;
+
+    /**图类型*/
+    //@NotNull(message = "图类型不可以为空")
+    String graphicType;
+
+}

+ 38 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmMepSourceTypeEntity.java

@@ -0,0 +1,38 @@
+package com.persagy.proxy.calculation.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/***
+ * Description: 源末端关系设置
+ * @author : lijie
+ * @date :2021/9/14 23:18
+ * Update By lijie 2021/9/14 23:18
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdmMepSourceTypeEntity {
+    /** 项目id */
+    private String projectId;
+
+    /** 计算卡片名称 */
+    private String calcName;
+
+    /** 源端设备类型 */
+    private String sourceType;
+
+    /** 前台使用源端设备类型 */
+    private String frontType;
+
+    /** 创建时间 */
+    private Date createTime;
+
+    /** 源端设备类型 */
+    private Integer sourceCount;
+}

+ 40 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/model/AdmRelationAddRequest.java

@@ -0,0 +1,40 @@
+package com.persagy.proxy.calculation.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonAlias;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AdmRelationAddRequest implements Serializable {
+    /**需要计算的类型*/
+    private String relType;
+
+    /**编码类型,CADID图纸编码(cadId),设备名称(name),设备ID(id),本地编码(localId),本地名称(localName)*/
+    private String type;
+
+    /**主对象内容*/
+    private String mainContent;
+
+    /**从对象内容*/
+    private Set<String> fromContent;
+
+    /**图类型编码*/
+    @JsonAlias({"graphicType","graphic_type"})
+    @JsonProperty("graphicType")
+    @JSONField(name = "graphicType",alternateNames = {"parentCode","graphic_type"})
+    private String graphicType;
+
+
+}

+ 33 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmCalcSpecialService.java

@@ -0,0 +1,33 @@
+package com.persagy.proxy.calculation.service;
+
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+/***
+ * Description: 关系计算-管网计算逻辑处理类
+ * @author : lijie
+ * @date :2021/9/29 11:07
+ * Update By lijie 2021/9/29 11:07
+ */
+public interface AdmCalcSpecialService {
+    /***
+     * Description: 管网系统设备分块  +  计算流向
+     * @param context : 基本请求参数
+     * @param admRelationTypeEnum : 关系类型枚举对象
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/29 11:12
+     * Update By lijie 2021/9/29 11:12
+     */
+    AdmResponse sysBlock(InstanceUrlParam context, AdmRelationTypeEnum admRelationTypeEnum);
+    /***
+     * Description: 管网计算
+     * @param context : 基本请求参数
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/29 11:58
+     * Update By lijie 2021/9/29 11:58
+     */
+    AdmResponse calcNetworks(InstanceUrlParam context);
+}

+ 47 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmManualRelCalService.java

@@ -0,0 +1,47 @@
+package com.persagy.proxy.calculation.service;
+
+import com.persagy.proxy.calculation.model.AdmManualRelCalRequest;
+import com.persagy.proxy.calculation.model.AdmManualRelationCalcDel;
+import com.persagy.proxy.calculation.model.AdmRelationAddRequest;
+import com.persagy.proxy.adm.request.AdmCreateResponse;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+/***
+ * Description: 手动关系计算逻辑处理接口
+ * @author : lijie
+ * @date :2021/8/31 12:14
+ * Update By lijie 2021/8/31 12:14
+ */
+public interface AdmManualRelCalService {
+    /***
+     * Description: 添加关系
+     *
+     * @param context: 存储集团编码及项目id的上下文
+     * @param request : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:14
+     * Update By lijie 2021/8/31 12:14
+     */
+    AdmCreateResponse addRels(InstanceUrlParam context, AdmRelationAddRequest request);
+    /***
+     * Description: 删除关系
+     * @param admManualRelationCalcDel : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    AdmCreateResponse delRels(InstanceUrlParam context, AdmManualRelationCalcDel admManualRelationCalcDel);
+    /***
+     * Description: 查询关系数据
+     * @param admManualRelCalRequest : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmCreateResponse
+     * @author : lijie
+     * @date :2021/8/31 12:10
+     * Update By lijie 2021/8/31 12:10
+     */
+    AdmResponse query(InstanceUrlParam context, AdmManualRelCalRequest admManualRelCalRequest);
+
+}

+ 35 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmMepSystemCalcService.java

@@ -0,0 +1,35 @@
+package com.persagy.proxy.calculation.service;
+
+import com.persagy.proxy.calculation.model.AdmMepSourceTypeEntity;
+import com.persagy.proxy.adm.request.AdmCreateRequest;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+/***
+ * Description: 源末端关系设置逻辑处理类
+ * @author : lijie
+ * @date :2021/9/14 23:21
+ * Update By lijie 2021/9/14 23:21
+ */
+public interface AdmMepSystemCalcService {
+    /***
+     * Description: 添加源末端关系
+     * @param context : 请求上下文
+     * @param request : 请求参数
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/14 23:23
+     * Update By lijie 2021/9/14 23:23
+     */
+    AdmResponse add(InstanceUrlParam context, AdmCreateRequest<AdmMepSourceTypeEntity> request);
+    /***
+     * Description: 查询源端设备类型
+     * @param context : 参数
+     * @param calcName : 关系名称
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/14 23:20
+     * Update By lijie 2021/9/14 23:20
+     */
+    AdmResponse query(InstanceUrlParam context, String calcName);
+}

+ 43 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/AdmRelCalService.java

@@ -0,0 +1,43 @@
+package com.persagy.proxy.calculation.service;
+
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+import java.util.List;
+
+/***
+ * Description: 关系计算逻辑处理接口
+ * @author : lijie
+ * @date :2021/8/31 12:14
+ * Update By lijie 2021/8/31 12:14
+ */
+public interface AdmRelCalService {
+
+    /***
+     * Description: 计算关系
+     * @param context : 请求参数
+     * @param admRelationTypeEnums : 关系类型集合
+     //* @param objectTypeStr : 参与计算的业务空间(为空表示所有业务空间类型)
+     //* @param relationTypeStr : 关系类型
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/11 20:35
+     * Update By lijie 2021/9/11 20:35
+     */
+    void calcRelation(InstanceUrlParam context, List<AdmRelationTypeEnum> admRelationTypeEnums, String relValue);
+    /***
+     * Description: 计算空间服务于空间的关系
+     * @param context : 通用参数
+     * @param buildingId : 建筑id
+     * @param objectType : 对象分类
+     * @param type : 对象类型
+     * @param sp2spArchforarch : 空间服务关系
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/30 14:49
+     * Update By lijie 2021/9/30 14:49
+     */
+    AdmResponse calcRelationForArchForArchSpToSp(InstanceUrlParam context, String buildingId, String objectType, String type,
+                                                 AdmRelationTypeEnum sp2spArchforarch);
+}

+ 31 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/IAdmObjectRelationCalService.java

@@ -0,0 +1,31 @@
+package com.persagy.proxy.calculation.service;
+
+import com.persagy.dmp.digital.entity.ObjectRelationProjectCal;
+import com.persagy.proxy.adm.service.IAdmBaseService;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 标记关系计算
+ * @author:linhuili
+ * @date:2021/10/15
+ */
+public interface IAdmObjectRelationCalService extends IAdmBaseService<ObjectRelationProjectCal> {
+
+    /**
+     *  根据关系类型查询标记计算关系
+     * @param context
+     * @param relationType
+     * @return
+     */
+    List<ObjectRelationProjectCal> queryCalRelByRelationType(InstanceUrlParam context, Set<String> relationType);
+
+    /**
+     * 更新标记计算关系
+     * @param context
+     * @param objectRelationProjectCals
+     */
+    void updateObjectCalRel(InstanceUrlParam context, List<ObjectRelationProjectCal> objectRelationProjectCals);
+}

+ 76 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/impl/AdmCalcSpecialServiceImpl.java

@@ -0,0 +1,76 @@
+package com.persagy.proxy.calculation.service.impl;
+
+import com.persagy.dmp.basic.dto.RequestData;
+import com.persagy.dmp.common.constant.CommonConstant;
+import com.persagy.dmp.digital.client.DigitalRelationCaclFacade;
+import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
+import com.persagy.proxy.adm.request.AdmResponse;
+import com.persagy.proxy.calculation.service.AdmCalcSpecialService;
+import com.persagy.proxy.common.entity.InstanceUrlParam;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/***
+ * Description: 官网关系计算逻辑类
+ * @author : lijie
+ * @date :2021/9/29 11:09
+ * Update By lijie 2021/9/29 11:09
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class AdmCalcSpecialServiceImpl implements AdmCalcSpecialService {
+    /***
+     * Description: 管网系统设备分块  +  计算流向
+     * @param context : 基本请求参数
+     * @param admRelationTypeEnum : 关系类型枚举对象
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * @date :2021/9/29 11:12
+     * Update By lijie 2021/9/29 11:12
+     */
+    @Override
+    public AdmResponse sysBlock(InstanceUrlParam context, AdmRelationTypeEnum admRelationTypeEnum) {
+        RequestData requestData = RequestData.builder()
+                .graphCode(admRelationTypeEnum.getGraphCode())
+                .relCode(admRelationTypeEnum.getRelCode())
+                .calBeforeRelFlag(true)
+                .build();
+        // 调用中台的计算逻辑
+        DigitalRelationCaclFacade.calculatingObjRelationPrototype(context.getGroupCode(),context.getProjectId(),
+                context.getAppId(), CommonConstant.DEFAULT_ID, requestData);
+        return AdmResponse.success();
+    }
+    /***
+     * Description: 管网计算
+     * @param context : 基本请求参数
+     * @return : com.persagy.proxy.adm.request.AdmResponse
+     * @author : lijie
+     * date :2021/9/29 11:58
+     * Update By lijie 2021/9/29 11:58
+     */
+    @Override
+    public AdmResponse calcNetworks(InstanceUrlParam context) {
+        // 1.根据项目id查询项目下的所有建筑
+        // 2.遍历建筑列表
+        // 2.1 根据建筑id查询建筑下所有楼层
+        // 2.2 获得所有楼层的modelId
+        // 2.3 根据楼层的modelId查询所有modelId当前对应的模型id(currentModelId)
+        // 2.4 风管立管连接
+        // 2.4.1 根据modelId查询所有管道类型大于0的管道
+        // 2.4.2 根据modelId对查询结果进行分组形成一个二维数组
+        // 2.4.3 循环二维数组
+        // 2.4.3.1 从二维数组中筛选出管道类型为2或3的管道:低楼层管道
+        // 2.4.3.2 从二维数组中筛选出管道类型为1或3的管道:高楼层管道
+        // 2.4.3.3 遍历低楼层管道获得{低楼层管道id:[高楼层管道id,高楼层管道id]}
+        // 2.4.3.3.1 获取低楼层管道的直线范围:管道直径>0:管道直径>>1:min(管道宽度,管道高度)>>1
+        // 2.4.3.3.2 获取低楼层管道的x,y坐标:location.points.get(0)
+        // 2.4.3.3.3 获取高楼层管道的x,y坐标:location.points.get(0)
+        // 2.4.3.3.4 mepSystemType(管道系统类型名称)相等且高楼层管道x,y不为空
+        // 2.4.3.3.5 低楼层x,y与高楼层的x,y的勾股和小于直线范围则符合
+
+
+        return AdmResponse.success();
+    }
+}

+ 0 - 0
adm-business/adm-middleware/src/main/java/com/persagy/proxy/calculation/service/impl/AdmManualRelCalServiceImpl.java


Some files were not shown because too many files changed in this diff