package com.persagy.proxy.adm.handler; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; 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.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 com.persagy.proxy.adm.strategy.RelationObjectContext; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; /** * * @version 1.0.0 * @company persagy * @author zhangqiankun * @date 2021年10月15日 下午3:09:10 */ @Component @RequiredArgsConstructor public class RelationReportHandler { @Value("${middleware.group.code}") private String defaultCode; private final RelationObjectContext relationObjectContext; private final IRelationReportService relationReportService; /** * 查询出不在空间内的设备数据 * * @param groupCode * @param projectId */ public List findEquipByNotSpace(String groupCode, String projectId) { groupCode = StrUtil.isBlank(groupCode) ? defaultCode : groupCode; String equipment = AdmObjectType.EQUIPMENT.getIndex(); HashSet equipments = Sets.newHashSet(equipment); // 1.获取所有的设备对象数据 List classCodeAsc = Arrays.asList(OrderItem.asc("classCode")); List equipList = this.relationReportService.queryObjects(null, groupCode, projectId, null, null, equipments, classCodeAsc); if (CollectionUtil.isEmpty(equipList)) { return Lists.newArrayList(); } // 2.获取所有的设备类定义的className List classList = this.relationReportService.queryClassList(groupCode, projectId, null, equipments, null); /** key-classCode, value-className */ Map classDefine = new HashMap(); for (ObjectTypeDefine objectTypeDefine : classList) { classDefine.put(objectTypeDefine.getCode(), objectTypeDefine.getName()); } // 3.查询出所有的边类型为 Eq2Sp 的关系数据 List relationObjects = this.relationReportService.findRelationObjects(groupCode, projectId, null, RelCodeEnum.Eq2Sp.name(), null, null); Set excludeIds = new HashSet(); 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 queryProjectBindPoint(String groupCode, String projectId) { groupCode = StrUtil.isBlank(groupCode) ? defaultCode : groupCode; String equipment = AdmObjectType.EQUIPMENT.getIndex(); List classCodeAsc = Arrays.asList(OrderItem.asc("classCode")); // 1.获取项目名称 List 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 equipList = this.relationReportService.queryObjects(null, groupCode, projectId, null, null, Sets.newHashSet(equipment), classCodeAsc); if (CollectionUtil.isEmpty(equipList)) { return Lists.newArrayList(); } // 3.获取所有的设备、系统类定义信息 List classInfo = this.relationReportService.queryClassList(groupCode, projectId, null, Sets.newHashSet(equipment, AdmObjectType.SYSTEM.getIndex()), null); /** key-equipCode, value-equipName */ Map equipTemp = new HashMap(); /** key-systemCode, value-systemName */ Map systemTemp = new HashMap(); for (ObjectTypeDefine info : classInfo) { if (info.getCode().length() > 5) { equipTemp.put(info.getCode(), info.getName()); } else { systemTemp.put(info.getCode(), info.getName()); } } // 4.获取所有的信息点 Set equipCodes = equipTemp.keySet(); List 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 countClassCodeEquip(String groupCode, String projectId) { groupCode = StrUtil.isBlank(groupCode) ? defaultCode : groupCode; String equipment = AdmObjectType.EQUIPMENT.getIndex(); List classCodeAsc = Arrays.asList(OrderItem.asc("classCode")); // 1.获取项目名称 List 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 equipList = this.relationReportService.queryObjects(null, groupCode, projectId, null, null, Sets.newHashSet(equipment), classCodeAsc); if (CollectionUtil.isEmpty(equipList)) { return Lists.newArrayList(); } // 3.获取所有的设备、系统类定义信息 List classInfo = this.relationReportService.queryClassList(groupCode, projectId, null, Sets.newHashSet(equipment, AdmObjectType.SYSTEM.getIndex()), null); /** key-equipCode, value-equipName */ Map equipTemp = new HashMap(); /** key-systemCode, value-systemName */ Map systemTemp = new HashMap(); for (ObjectTypeDefine info : classInfo) { if (info.getCode().length() > 5) { equipTemp.put(info.getCode(), info.getName()); } else { systemTemp.put(info.getCode(), info.getName()); } } // 4.获取所有的信息点 Set equipCodes = equipTemp.keySet(); List 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 exportEquipmentExcel(List equipList, Map classDefine, Set excludeIds, String groupCode, String projectId) { /** key: 设备ID,value: 楼层名称 */ Map floorNameTemp = new HashMap(); this.findFloorName(floorNameTemp, groupCode, projectId); /** key: 设备ID,value: 建筑名称 */ Map buildNameTemp = new HashMap(); this.findBuildingName(buildNameTemp, groupCode, projectId); // 结果封装 List excelList = new ArrayList(); 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 exportEquipmentBindPointExcel(List equipList, Map equipTemp, Map systemTemp, List funidList, String groupCode, String projectId, String projectName) { /** key: 设备ID,value: 楼层名称 */ Map floorNameTemp = new HashMap(); this.findFloorName(floorNameTemp, groupCode, projectId); /** key: 设备ID,value: 建筑名称 */ Map buildNameTemp = new HashMap(); this.findBuildingName(buildNameTemp, groupCode, projectId); // 信息点分类信息统计 /** key: classCode, value: 信息点 */ Map> infoCodes = new HashMap>(); /** key: classCode, value: 静态信息点的数量 */ Map staticCount = new HashMap(); /** key: classCode, value: 动态信息点的数量 */ Map dynamicCount = new HashMap(); /** key: classCode_infoCode, value: 动静态 */ Map codeAttrbut = new HashMap(); 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 excelList = new ArrayList(); 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 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 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 exportClassEquipExcel(List equipList, Map equipTemp, Map systemTemp, List funidList, String groupCode, String projectId, String projectName) { /** key: classCode, value: 信息点 */ Map> infoCodes = new HashMap>(); /** key: classCode, value: 静态信息点的数量 */ Map staticCount = new HashMap(); /** key: classCode, value: 动态信息点的数量 */ Map dynamicCount = new HashMap(); /** key: classCode_infoCode, value: 动静态 */ Map codeAttrbut = new HashMap(); // 信息点数据汇总 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 equipId2BuildId = new HashMap(); /** key: 建筑ID,value: 建筑名称 */ Map buildNameTemp = new HashMap(); String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Bd.name(); List buildDigitals = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, null, null); if (CollectionUtil.isNotEmpty(buildDigitals)) { for (ObjectDigital master : buildDigitals) { List 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 equipBimIdByBuild = new HashMap(); /** key: classCode, value: 当BIMID不为空时,建筑ID为空时,值+1 */ Map equipBimIdByBuildNull = new HashMap(); /** key: classCode, value: 当BIMID为空时,建筑ID不为空时,值+1 */ Map equipBimIdNullByBuild = new HashMap(); /** key: classCode, value: 当BIMID为空时,建筑ID为空时,值+1 */ Map equipBimIdNullByBuildNull = new HashMap(); /** key: classCode, value: 已绑定的静态信息点数量 */ Map equipStaticInfoTemp = new HashMap(); /** key: classCode, value: 已绑定的动态信息点数量 */ Map equipDynamicInfoTemp = new HashMap(); /** key: classCode, value: 建筑ID */ Map classBuildId = new HashMap(); /** key: classCode_建筑ID, value: infos字段包含信息点的设备数量 */ Map classInfosByBuild = new HashMap(); /** key: classCode, value: infos字段包含信息点且建筑ID为空的设备数量 */ Map classInfosNotBuild = new HashMap(); /** key: classCode, value: 存在建筑的设备数量 */ Map classByBuild = new HashMap(); /** key: classCode, value: 不存在建筑的设备数量 */ Map classNotBuild = new HashMap(); // 总结出如上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 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 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 classCodes = classByBuild.keySet(); Set keySet = classNotBuild.keySet(); classCodes.addAll(keySet); // 结果封装 int count = 0; List excelList = new ArrayList(); 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 buildIdTemp key: 设备ID,value: 建筑ID * @param groupCode * @param projectId */ private void findBuildingName(Map buildNameTemp, String groupCode, String projectId) { // 获取建筑名称 String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Bd.name(); List buildDigitals = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, null, null); if (CollectionUtil.isNotEmpty(buildDigitals)) { for (ObjectDigital master : buildDigitals) { List 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 floorNameTemp, String groupCode, String projectId) { // 获取楼层名称 String graphAndRelKey = GraphCodeEnum.MechInArch.name() + AdmCommonConstant.UNDERLINE + RelCodeEnum.Eq2Fl.name(); List floorDigitals = this.relationObjectContext.queryAllRelations(groupCode, projectId, graphAndRelKey, null, null, null); if (CollectionUtil.isNotEmpty(floorDigitals)) { for (ObjectDigital master : floorDigitals) { List slaveDigitals = master.getRelObjs(); ObjectDigital slave = CollectionUtil.isEmpty(slaveDigitals) ? null : slaveDigitals.get(0); if (slave != null) { floorNameTemp.put(master.getId(), slave.getLocalName()); } } } } }