package com.persagy.proxy.adm.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; 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.model.entity.BaseEntity; import com.persagy.dmp.define.entity.ObjectTypeDefine; import com.persagy.dmp.digital.entity.ObjectRelation; import com.persagy.proxy.adm.model.AdmDCSQueryRequest; import com.persagy.proxy.adm.model.AdmFloor; import com.persagy.proxy.adm.model.AdmSpace; import com.persagy.proxy.adm.request.AdmQueryCriteria; import com.persagy.proxy.adm.request.AdmResponse; import com.persagy.proxy.adm.service.IAdmRelationService; import com.persagy.proxy.adm.service.IAdmSpaceService; import com.persagy.proxy.adm.utils.AdmContextUtil; 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 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.*; import java.util.stream.Collectors; /** * ADM 空间 实现类 * @author lvxy * @date 2021/8/18 */ @Slf4j @Service public class AdmSpaceServiceImpl extends AbstractAdmBaseServiceImpl implements IAdmSpaceService { @Autowired private DmpRwdClient rwdClient; @Autowired private ObjectMapper objectMapper; @Autowired private IAdmRelationService relationService; @Override public List doInsertExt(InstanceUrlParam context, Class clazz, List voList) { Map spaceMapByFlId = CollUtil.fieldValueMap(voList, "floorId"); //查询空间中floorId 对应的floor DmpResult floors = queryFloorsByFloorIds(context, spaceMapByFlId.keySet()); if(CollUtil.isNotEmpty(floors.getData())){ ArrayList floorList = CollUtil.newArrayList(JSONUtil.toList(floors.getData().toString(),AdmFloor.class)); //space.height = floor.infos.height voList = processHeight(spaceMapByFlId, floorList); } //插入空间 List vosR = doInsert(context, clazz, voList); //添加绑定关系 processRelations(vosR); //处理关系标记 //TODO 处理关系标记 //processRelationType(); return vosR; } @Override public AdmResponse doQueryType(InstanceUrlParam context, AdmDCSQueryRequest request) { //查询定义类型 ObjectNode criteriaEq = JsonNodeFactory.instance.objectNode(); criteriaEq.put("parentCode", "space"); DmpResult resultDef = queryDefineType(context, criteriaEq); List defineList = null; if(resultDef.getResult().equals(DmpResult.SUCCESS)){ defineList = JSONUtil.toList(resultDef.getData().toString(), JSONObject.class); //获取实际空间对象的数量 //根据classCode floorId 查询查询实际存在的空间 assembleDefineTypes(context, defineList, request.getFloorId()); // 设置返回值 AdmResponse response = AdmResponse.success(defineList); Long total = resultDef.getCount() == null ? null : resultDef.getCount().longValue(); response.setTotal(total); return response; }else{ return null; } } @Override public AdmResponse doQuerySpaces(InstanceUrlParam context, AdmDCSQueryRequest request) { QueryCriteria dmpRequest = AdmQueryCriteriaHelper.toDmpCriteria(request); //查询的时候,floorId,buildingId 按照空间对象的自定义信息点处理 //TODO 这个ifelse判断是原来的代码实现,写此方法实现的时候不清楚实际业务,保留原来的判断,之后了解业务再根据业务调整 DmpResult dmpResult = new DmpResult<>(); List spaceArray = new ArrayList(); List zoneTypeList = StrUtil.isNotEmpty(request.getZoneType()) ? CollUtil.newArrayList(request.getZoneType()) : request.getZoneTypeList(); if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isNotEmpty(request.getFloorId()) && !request.getFloorId().equals("isnull")){ querySpaceByFl(dmpRequest,context, spaceArray, zoneTypeList, request.getFloorId(), "Fl2Sp"); }else if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isNotEmpty(request.getFloorId()) && request.getFloorId().equals("isnull")){ QueryCriteria queryFloor = ensureQueryCommParm(dmpRequest,context, Arrays.asList("floor"), AdmFloor.OBJ_TYPE); ObjectNode criteriaFl = queryFloor.getCriteria(); criteriaFl.put("buildingId", request.getBuildingId()); queryFloor.setCriteria(criteriaFl); DmpResult dmpResultFloors = queryObj(context, queryFloor); List floorList = JSONUtil.toList(JSONUtil.toJsonStr(dmpResultFloors.getData()), AdmFloor.class); Map floorMap = CollUtil.fieldValueMap(floorList, BaseEntity.PROP_ID); if(CollUtil.isNotEmpty(floorMap)){ QueryCriteria queryCriteria = ensureQueryCommParm(dmpRequest, context, zoneTypeList, AdmSpace.OBJ_TYPE); ObjectNode criteriaPe = queryCriteria.getCriteria(); JSONArray jsonArray = new JSONArray(); floorMap.keySet().forEach(floorId -> jsonArray.add(floorId)); criteriaPe.putPOJO("floorId", jsonArray); queryCriteria.setCriteria(criteriaPe); dmpResult = queryObj(context, queryCriteria); if(CollUtil.isNotEmpty(dmpResult.getData())){ spaceArray.addAll(dmpResult.getData()); } querySpaceByFl(dmpRequest, context, spaceArray, zoneTypeList, request.getBuildingId(), "Bd2Sp"); } }else if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isEmpty(request.getFloorId()) && !request.getBuildingId().equals("isnull")){ querySpaceByFl(dmpRequest,context, spaceArray, zoneTypeList, request.getBuildingId(), "Bd2Sp"); }else if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isEmpty(request.getFloorId()) && request.getBuildingId().equals("isnull")){ //未明确建筑 QueryCriteria queryCriteria = ensureQueryCommParm(dmpRequest, context, zoneTypeList, "space"); ObjectNode criteriaPe = queryCriteria.getCriteria(); JSONObject isnull = new JSONObject(); isnull.put("$null", true); criteriaPe.putPOJO("buildingId", isnull); queryCriteria.setCriteria(criteriaPe); dmpResult = queryObj(context, queryCriteria); if(CollUtil.isNotEmpty(dmpResult.getData())){ spaceArray.addAll(dmpResult.getData()); } }else if(StrUtil.isEmpty(request.getBuildingId()) && StrUtil.isEmpty(request.getFloorId())){ QueryCriteria queryCriteria = ensureQueryCommParm(dmpRequest, context, zoneTypeList, "space"); /* ObjectNode criteriaPe = queryCriteria.getCriteria(); JSONObject isnull = new JSONObject(); isnull.put("$null", true); criteriaPe.putPOJO("floorId", isnull); queryCriteria.setCriteria(criteriaPe);*/ dmpResult = queryObj(context, queryCriteria); if(CollUtil.isNotEmpty(dmpResult.getData())){ spaceArray.addAll(dmpResult.getData()); } } AdmResponse admResponse = new AdmResponse(); admResponse.setContent(spaceArray); admResponse.setTotal(spaceArray.size()*1l); admResponse.setPageSize(request.getPageSize()); admResponse.setPageNumber(request.getPageNumber()); admResponse.setResult(DmpResult.SUCCESS); admResponse.setMessage(""); return admResponse; } /** * 根据信息点查询空间 * @param context * @param spaceArray * @param zoneTypeList * @param objFrom flooIds / bulidingIds * @param relCode */ private void querySpaceByFl(QueryCriteria dmpRequest, InstanceUrlParam context, List spaceArray, List zoneTypeList, String objFrom, String relCode){ QueryCriteria queryCriteria = ensureQueryCommParm(dmpRequest,context, zoneTypeList, AdmSpace.OBJ_TYPE); addRelationTo(queryCriteria,objFrom,relCode); DmpResult dmpResult = queryObj(context, queryCriteria); if(CollUtil.isNotEmpty(dmpResult.getData())){ spaceArray.addAll(dmpResult.getData()); } } @Override public List querySpaceInShaft(InstanceUrlParam context, String shaftId, String spaceType) { AdmQueryCriteria request = new AdmQueryCriteria(); request.setName(AdmSpace.OBJ_TYPE); request.resetRelationCond(false, "ArchSubset", "Sh2Sp", spaceType, shaftId, true); AdmResponse rs = doQuery(context, request, AdmSpace.class); return (List) rs.getContent(); } @Override public List querySpaceInBuilding(InstanceUrlParam context, String buildingId, String spaceType) { AdmQueryCriteria request = new AdmQueryCriteria(); request.setName(AdmSpace.OBJ_TYPE); request.resetRelationCond(false, "ArchSubset", "Bd2Sp", spaceType, buildingId, true); AdmResponse rs = doQuery(context, request, AdmSpace.class); return (List) rs.getContent(); } @Override public Map> querySpaceMapInFloors(InstanceUrlParam context, List floorIds, String spaceType) { QueryCriteria queryRequest = new QueryCriteria(); ObjectNode criteriaRel = JsonNodeFactory.instance.objectNode(); criteriaRel.put("graphCode", "ArchSubset"); criteriaRel.put("relCode", "Fl2Sp"); criteriaRel.put("relValue", spaceType); ArrayNode objNode = criteriaRel.putArray("objFrom"); floorIds.forEach(floorId -> objNode.add(floorId)); queryRequest.setCriteria(criteriaRel); List relations = relationService.queryByCondition(context, queryRequest); if(CollUtil.isEmpty(relations)) { return null; } return relations.stream().collect(Collectors.groupingBy(ObjectRelation::getObjFrom, Collectors.mapping(ObjectRelation::getObjTo, Collectors.toList()))); } @Override public Map> queryTrafficSpaceMap(InstanceUrlParam context, Iterable spaceIds, String spaceType) { Map> result = new HashMap<>(); loadTrafficSpace(context, spaceIds, spaceType, true, result); loadTrafficSpace(context, spaceIds, spaceType, false, result); return result; } /** * 装载交通关系 * @param context * @param spaceIds * @param spaceType * @param isFrom * @param result */ private void loadTrafficSpace(InstanceUrlParam context, Iterable spaceIds, String spaceType, boolean isFrom, Map> result) { // 关系查询条件 QueryCriteria queryRequest = new QueryCriteria(); ObjectNode criteriaRel = JsonNodeFactory.instance.objectNode(); criteriaRel.put("graphCode", "TrafficNetwork"); criteriaRel.put("relValue", spaceType); ArrayNode objNode = criteriaRel.putArray(isFrom?"objFrom":"objTo"); spaceIds.forEach(spaceId -> objNode.add(spaceId)); queryRequest.setCriteria(criteriaRel); List relations = relationService.queryByCondition(context, queryRequest); if(CollUtil.isEmpty(relations)) { return; } // 存入Map for(ObjectRelation relation:relations) { String key = isFrom ? relation.getObjFrom() : relation.getObjTo(); String value = isFrom ? relation.getObjTo() : relation.getObjFrom(); Set valueList = result.get(key); if(CollUtil.isEmpty(valueList)) { valueList = new HashSet<>(); result.put(key, valueList); } valueList.add(value); } } /** * 空间的类型是根据项目自定义的 * 参见中心 * @Select("SELECT s.object_type as type,d.name FROM zone_space_base s * LEFT JOIN dict.dict_space_project d ON s.object_type = d.id WHERE s.project_id = #{projectId} AND d.project_id = #{projectId} * GROUP BY object_type, d.name") * @param context * @return */ @Override public List doQuerySpaceTypes(InstanceUrlParam context) { //根据项目id查询空间类型 Map codeNameMap = queryProjectDefineType(context); if(CollUtil.isNotEmpty(codeNameMap)){ //查询object JSONArray demObjs = queryAndDealObjs(context, codeNameMap.keySet()); if(CollUtil.isNotEmpty(demObjs)){ List spaceList = JSONArray.parseArray(JSONUtil.toJsonStr(demObjs), AdmSpace.class); Set classCodes = spaceList.stream().map(space -> space.getClassCode()).collect(Collectors.toSet()); if(CollUtil.isNotEmpty(classCodes)){ codeNameMap.keySet().removeIf(code -> !classCodes.contains(code)); } } } if(CollUtil.isNotEmpty(codeNameMap)){ List list = new ArrayList<>(codeNameMap.size()); codeNameMap.keySet().stream().forEach(code ->{ JSONObject jsonObject = new JSONObject(); jsonObject.put("name",codeNameMap.get(code)); jsonObject.put("code",code); list.add(jsonObject); }); return list; }else{ return null; } } private DmpResult queryObj(InstanceUrlParam context, QueryCriteria criteriaObject){ JSONObject paraPe = null; try { String paraStr = objectMapper.writeValueAsString(criteriaObject); paraPe = JSONObject.parseObject(paraStr); } catch (JsonProcessingException e) { throw new RuntimeException("转换查询条件出错:" + e.getMessage()); } return rwdClient.queryObject(context, paraPe); } private QueryCriteria ensureQueryCommParm(QueryCriteria dmpRequest, InstanceUrlParam context, Collection classCodes, String objType){ ObjectNode criteriaEq = JsonNodeFactory.instance.objectNode(); if(CollUtil.isNotEmpty(classCodes)){ ArrayNode array = criteriaEq.putObject("classCode").putArray("$in"); classCodes.forEach(code -> array.add(code)); } criteriaEq.put("objType", objType); dmpRequest.setCriteria(criteriaEq); return dmpRequest; } private JSONArray queryAndDealObjs(InstanceUrlParam context, Set codes){ QueryCriteria criteriaObject = ensureQueryCommParm(new QueryCriteria(), context, codes,AdmSpace.OBJ_TYPE); criteriaObject.setSize(50L); DmpResult dmpResult = queryObj(context, criteriaObject); if(CollUtil.isEmpty(dmpResult.getData())){ return null; } JSONArray demObjs = dmpResult.getData(); if(dmpResult.getCount() > criteriaObject.getSize()){ for(int page = 2; page < dmpResult.getCount()/criteriaObject.getSize()+1; page++){ criteriaObject.setPage(page*1L); demObjs.addAll(queryObj(context, criteriaObject).getData()); } } return demObjs; } private Map queryProjectDefineType(InstanceUrlParam context){ Map codeNameMap = null; ObjectNode criteriaEq = JsonNodeFactory.instance.objectNode(); criteriaEq.put("projectId", context.getProjectId()); criteriaEq.put("objType", AdmSpace.OBJ_TYPE); DmpResult resultDef = queryDefineType(context, criteriaEq); if(resultDef.getResult().equals(DmpResult.SUCCESS) && CollUtil.isNotEmpty(resultDef.getData())){ List defineList = JSONUtil.toList(resultDef.getData().toString(), ObjectTypeDefine.class); codeNameMap = defineList.stream().collect(Collectors.toMap(ObjectTypeDefine::getCode, ObjectTypeDefine::getName, (k1,k2)->k1)); } return codeNameMap; } /** * 查询空间flooId对应的infos中height存在的 flool * @param context * @param floolIds * @return */ private DmpResult queryFloorsByFloorIds(InstanceUrlParam context, Collection floolIds){ QueryCriteria queryCriteria = ensureQueryCommParm(new QueryCriteria(),context, CollUtil.newArrayList("floor"),"floor"); ObjectNode criteriaPe = queryCriteria.getCriteria(); if(CollUtil.isNotEmpty(floolIds)){ ArrayNode array = criteriaPe.putObject("id").putArray("$in"); floolIds.forEach(floorId -> array.add(floorId)); } JSONObject height = new JSONObject(); height.put("$gt", 0f); criteriaPe.putPOJO("height", height); queryCriteria.setCriteria(criteriaPe); queryCriteria.setWithoutCount(true); return queryObj(context, queryCriteria); } /** * space.height = floor.infos.height * @param spaceMapByFlId * @param floorList * @return */ private List processHeight(Map spaceMapByFlId, List floorList){ floorList.forEach(admFloor -> { if(CollUtil.isNotEmpty(admFloor.getInfos())){ Float height = (Float) admFloor.getInfos().get("height"); AdmSpace admSpace = spaceMapByFlId.get(admFloor.getId()); admSpace.setHeight(height); } }); return (List) spaceMapByFlId.values(); } /** * 添加绑定关系 */ private void processRelations(List vosR){ if(CollUtil.isNotEmpty(vosR)) { List relationDTOS = new ArrayList<>(vosR.size()); vosR.forEach(admSpace -> { if (StrUtil.isNotEmpty(admSpace.getBuildingId())) { relationDTOS.add(new RelationDTO(null, "ArchSubset", "Bd2Sp", null, admSpace.getBuildingId(), admSpace.getId())); } if (StrUtil.isNotEmpty(admSpace.getFloorId())) { relationDTOS.add(new RelationDTO(null, "ArchSubset", "Fl2Sp", null, admSpace.getFloorId(), admSpace.getId())); } }); if (CollUtil.isNotEmpty(relationDTOS)) { relationService.doSave(AdmContextUtil.toDmpContext(), relationDTOS); } } } /** * 转换为目标实体,并增加属性 */ private void assembleDefineTypes(InstanceUrlParam context, List defineList, String floorId){ boolean needCount = true; defineList.stream().forEach(defineType -> { //查询空间数量 int count = needCount ? countSpace(context, defineType.getString("code"), floorId) : 0; //处理单个对象 assembleDefineObj(defineType, count, context.getProjectId()); }); } /** * 单个转换为目标实体,并增加属性 */ private void assembleDefineObj(JSONObject defineType, int count, String projectId){ defineType.put("count", count); defineType.put("projectId", projectId); defineType.remove("aliasName"); defineType.remove("aliasCode"); defineType.remove("valid"); defineType.remove("objType"); defineType.remove("groupCode"); defineType.remove("parentCode"); defineType.remove("id"); } private void addRelationTo(QueryCriteria rwdQueryCriteria, String objFrom, String relCode){ ObjectNode relationTO = JsonNodeFactory.instance.objectNode(); relationTO.put("relCode", relCode); relationTO.put("graphCode", "ArchSubset"); relationTO.put("objFrom", objFrom); ObjectNode criteria = rwdQueryCriteria.getCriteria(); criteria.putPOJO("relationTo", relationTO); rwdQueryCriteria.setCriteria(criteria); } private void addRelationFrom(QueryCriteria rwdQueryCriteria, String objTo, String relCode){ ObjectNode relationFrom = JsonNodeFactory.instance.objectNode(); if(StrUtil.isNotEmpty(objTo)){ relationFrom.put("objTo", objTo); } ObjectNode criteria = rwdQueryCriteria.getCriteria(); criteria.putPOJO("relationFrom", relationFrom); rwdQueryCriteria.setCriteria(criteria); } /** * 查询存在空间的数量 * @param context * @param classCode * @param objFrom * @return */ private int countSpace(InstanceUrlParam context, String classCode, String objFrom){ QueryCriteria queryCriteria = ensureQueryCommParm(new QueryCriteria(), context, CollUtil.newArrayList(classCode),"space"); addRelationTo(queryCriteria, objFrom,"Fl2Sp"); queryCriteria.setOnlyCount(true); DmpResult dmpResult = queryObj(context, queryCriteria); return dmpResult.getCount(); } private DmpResult queryDefineType(InstanceUrlParam context, ObjectNode criteriaEq){ QueryCriteria criteriaObject = new QueryCriteria(); criteriaObject.setCriteria(criteriaEq); JSONObject paraPe = null; try { String paraStr = objectMapper.writeValueAsString(criteriaObject); paraPe = JSONObject.parseObject(paraStr); } catch (JsonProcessingException e) { throw new RuntimeException("查询公共定义的空间类型,转换查询条件出错:" + e.getMessage()); } return rwdClient.queryDefClass(context, paraPe); } }