AdmSpaceServiceImpl.java 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832
  1. package com.persagy.proxy.object.service.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import cn.hutool.json.JSONUtil;
  6. import com.alibaba.fastjson.JSONArray;
  7. import com.alibaba.fastjson.JSONObject;
  8. import com.baomidou.mybatisplus.core.metadata.OrderItem;
  9. import com.fasterxml.jackson.core.JsonProcessingException;
  10. import com.fasterxml.jackson.databind.ObjectMapper;
  11. import com.fasterxml.jackson.databind.node.ArrayNode;
  12. import com.fasterxml.jackson.databind.node.JsonNodeFactory;
  13. import com.fasterxml.jackson.databind.node.ObjectNode;
  14. import com.google.common.collect.Sets;
  15. import com.persagy.dmp.basic.model.QueryCriteria;
  16. import com.persagy.dmp.common.context.AppContext;
  17. import com.persagy.dmp.common.helper.SpringHelper;
  18. import com.persagy.dmp.common.model.response.CommonResult;
  19. import com.persagy.dmp.define.entity.ObjectTypeDefine;
  20. import com.persagy.dmp.digital.client.DigitalObjectFacade;
  21. import com.persagy.dmp.digital.entity.ObjectRelation;
  22. import com.persagy.dmp.simple.client.DigitalObjectSimpleFacade;
  23. import com.persagy.proxy.adm.constant.AdmCommonConstant;
  24. import com.persagy.proxy.adm.constant.AdmRelationTypeEnum;
  25. import com.persagy.proxy.adm.constant.GraphCodeEnum;
  26. import com.persagy.proxy.adm.constant.RelCodeEnum;
  27. import com.persagy.proxy.adm.request.AdmDCSQueryRequest;
  28. import com.persagy.proxy.adm.request.AdmQueryCriteria;
  29. import com.persagy.proxy.adm.request.AdmResponse;
  30. import com.persagy.proxy.adm.service.IAdmRelationService;
  31. import com.persagy.proxy.adm.service.impl.AbstractAdmBaseServiceImpl;
  32. import com.persagy.proxy.adm.utils.AdmContextUtil;
  33. import com.persagy.proxy.adm.utils.AdmEntityTransferUtil;
  34. import com.persagy.proxy.adm.utils.AdmQueryCriteriaHelper;
  35. import com.persagy.proxy.calculation.service.AdmRelCalService;
  36. import com.persagy.proxy.common.client.DmpRwdClient;
  37. import com.persagy.proxy.common.entity.DmpResult;
  38. import com.persagy.proxy.common.entity.InstanceUrlParam;
  39. import com.persagy.proxy.common.entity.RelationDTO;
  40. import com.persagy.proxy.object.model.AdmEquipment;
  41. import com.persagy.proxy.object.model.AdmSpace;
  42. import com.persagy.proxy.object.model.AdmSystem;
  43. import com.persagy.proxy.object.service.IAdmEquipmentService;
  44. import com.persagy.proxy.object.service.IAdmSpaceService;
  45. import com.persagy.proxy.object.service.IAdmSystemService;
  46. import com.persagy.proxy.report.service.IRelationReportService;
  47. import lombok.extern.slf4j.Slf4j;
  48. import org.apache.commons.lang.StringUtils;
  49. import org.springframework.beans.factory.annotation.Autowired;
  50. import org.springframework.scheduling.annotation.Async;
  51. import org.springframework.stereotype.Service;
  52. import javax.servlet.http.HttpServletRequest;
  53. import java.util.*;
  54. import java.util.stream.Collectors;
  55. /**
  56. * ADM 空间 实现类
  57. * @author lvxy
  58. * @date 2021/8/18
  59. */
  60. @Slf4j
  61. @Service
  62. public class AdmSpaceServiceImpl extends AbstractAdmBaseServiceImpl<AdmSpace> implements IAdmSpaceService {
  63. @Autowired
  64. private DmpRwdClient rwdClient;
  65. @Autowired
  66. private ObjectMapper objectMapper;
  67. @Autowired
  68. private IAdmRelationService relationService;
  69. @Autowired
  70. private IAdmEquipmentService equipmentService;
  71. @Autowired
  72. private IAdmSystemService systemService;
  73. @Autowired
  74. private IRelationReportService relationReportService;
  75. @Autowired
  76. private AdmRelCalService admRelCalService;
  77. @Override
  78. public AdmResponse doQuery(InstanceUrlParam context, AdmQueryCriteria request, Class<AdmSpace> clazz) {
  79. AdmResponse response = super.doQuery(context, request, clazz);
  80. // 系统需要补充分类名称属性
  81. ensureSpecialValues(context, (List<AdmSpace>) response.getContent());
  82. return response;
  83. }
  84. @Override
  85. public List<AdmSpace> doInsertExt(InstanceUrlParam context, Class<AdmSpace> clazz, List<AdmSpace> voList) {
  86. Map<String, List<AdmSpace>> spaceMapByFlId = voList.stream().filter(admSpace -> StringUtils.isNotEmpty(admSpace.getFloorId())).collect(Collectors.groupingBy(AdmSpace::getFloorId));
  87. //查询空间中floorId 对应的floor
  88. if(CollUtil.isNotEmpty(spaceMapByFlId)){
  89. List<ObjectNode> floors = queryFloorsByFloorIds(context, spaceMapByFlId.keySet());
  90. if(CollUtil.isNotEmpty(floors)){
  91. //ArrayList<AdmFloor> floorList = CollUtil.newArrayList(JSONUtil.toList(floors.getData().toString(),AdmFloor.class));
  92. //space.height = floor.infos.height
  93. voList = processHeight(spaceMapByFlId, floors);
  94. }
  95. }
  96. //插入空间
  97. List<AdmSpace> vosR = doInsert(context, clazz, voList);
  98. //添加绑定关系
  99. processRelations(vosR);
  100. //处理关系标记
  101. SpringHelper.getBean(IAdmSpaceService.class).processRelationType(context,vosR);
  102. return vosR;
  103. }
  104. @Override
  105. public AdmResponse doQueryType(InstanceUrlParam context, AdmDCSQueryRequest request) {
  106. //查询定义类型
  107. ObjectNode criteriaEq = JsonNodeFactory.instance.objectNode();
  108. criteriaEq.put("parentCode", "space");
  109. DmpResult<JSONArray> resultDef = queryDefineType(context, criteriaEq);
  110. List<JSONObject> defineList = null;
  111. if(resultDef.getResult().equals(DmpResult.SUCCESS)){
  112. defineList = JSONUtil.toList(resultDef.getData().toString(), JSONObject.class);
  113. //获取实际空间对象的数量
  114. //根据classCode floorId 查询查询实际存在的空间
  115. assembleDefineTypes(context, defineList, request.getFloorId());
  116. // 设置返回值
  117. AdmResponse response = AdmResponse.success(defineList, request);
  118. Long total = resultDef.getCount() == null ? null : resultDef.getCount().longValue();
  119. response.setTotal(total);
  120. return response;
  121. }else{
  122. return null;
  123. }
  124. }
  125. @Override
  126. public AdmResponse doQuerySpaces(InstanceUrlParam context, AdmDCSQueryRequest request) {
  127. request.setName(AdmSpace.OBJ_TYPE);
  128. String classCodeFilter = "";
  129. if(StrUtil.isNotEmpty(request.getZoneType())){
  130. classCodeFilter = " classCode = '"+request.getZoneType()+"'";
  131. }else{
  132. classCodeFilter = " classCode in ['"+ String.join("', '",request.getZoneTypeList()) + "']";
  133. }
  134. String filters = request.getFilters();
  135. if(StrUtil.isBlank(filters)){
  136. request.setFilters(classCodeFilter);
  137. }else{
  138. request.setFilters(filters+"; "+classCodeFilter);
  139. }
  140. AdmResponse response = null;
  141. if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isNotEmpty(request.getFloorId()) && !request.getFloorId().equals("isnull")){
  142. //明确建筑,明确楼层
  143. request.setFilters(request.getFilters()+" ; buildingId = '"+request.getBuildingId()+"' ; floorId='"+request.getFloorId()+"' ;");
  144. /*response = doQuery(context,request,AdmSpace.class);
  145. return response;*/
  146. }else if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isNotEmpty(request.getFloorId()) && request.getFloorId().equals("isnull")){
  147. //查询此建筑下未关联楼层的空间
  148. request.setFilters(request.getFilters()+" ; buildingId = '"+request.getBuildingId()+"' ; floorId isnull");
  149. /*response = this.query(request);
  150. return response;*/
  151. }else if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isEmpty(request.getFloorId()) && !request.getBuildingId().equals("isnull")){
  152. //查询建筑下的空间
  153. /*ObjectNode relationTo = JsonNodeFactory.instance.objectNode();
  154. relationTo.put("relCode", "Bd2Sp");
  155. relationTo.put("graphCode", "ArchSubset");
  156. relationTo.put("objFrom", request.getBuildingId());
  157. request.setRelationTo(relationTo);
  158. response = query(request);
  159. return response;*/
  160. request.setFilters(request.getFilters()+" ; buildingId = '"+request.getBuildingId()+"' ; ");
  161. }else if(StrUtil.isNotEmpty(request.getBuildingId()) && StrUtil.isEmpty(request.getFloorId()) && request.getBuildingId().equals("isnull")){
  162. //未明确建筑下的空间
  163. //查询建筑下的空间
  164. /*ObjectNode relationTo = JsonNodeFactory.instance.objectNode();
  165. relationTo.put("relCode", "Bd2Sp");
  166. relationTo.put("graphCode", "ArchSubset");
  167. relationTo.put("$bindFlag", false);
  168. request.setRelationTo(relationTo);
  169. response = query(request);
  170. return response;*/
  171. request.setFilters(request.getFilters()+" ; buildingId isnull");
  172. }else if(StrUtil.isEmpty(request.getBuildingId()) && StrUtil.isEmpty(request.getFloorId())){
  173. }
  174. response = this.query(request);
  175. return response;
  176. }
  177. @Override
  178. public void ensureSpecialValues(InstanceUrlParam context, List<AdmSpace> vos) {
  179. if(CollUtil.isEmpty(vos)) {
  180. return;
  181. }
  182. // 1. 收集空间的设备对象,扩展设备对象赋值
  183. List<AdmEquipment> equipmentList = new ArrayList<>();
  184. for(AdmSpace vo:vos) {
  185. // 收集设备对象
  186. if(CollUtil.isEmpty(vo.getEquipment()) && CollUtil.isEmpty(vo.getEquipmentFor())) {
  187. continue;
  188. }
  189. if(CollUtil.isNotEmpty(vo.getEquipment())) {
  190. equipmentList.addAll(vo.getEquipment());
  191. }
  192. if(CollUtil.isNotEmpty(vo.getEquipmentFor())) {
  193. equipmentList.addAll(vo.getEquipmentFor());
  194. }
  195. }
  196. // 对象扩展属性赋值
  197. equipmentService.ensureSpecialValues(context, equipmentList);
  198. //2.收集空间的系统 扩展系统、及系统下设备对象赋值
  199. List<AdmSystem> admSystemList = new ArrayList<>();
  200. for(AdmSpace vo:vos) {
  201. // 收集设备对象
  202. if(CollUtil.isEmpty(vo.getGeneralSystem())) {
  203. continue;
  204. }
  205. admSystemList.addAll(vo.getGeneralSystem());
  206. }
  207. // 对象扩展属性赋值
  208. systemService.ensureSpecialValues(context, admSystemList);
  209. }
  210. @Override
  211. public List<AdmSpace> querySpaceInShaft(InstanceUrlParam context, String shaftId, String spaceType) {
  212. AdmQueryCriteria request = new AdmQueryCriteria();
  213. request.setName(AdmSpace.OBJ_TYPE);
  214. request.resetRelationCond(false, "ArchSubset", "Sh2Sp", spaceType, shaftId, true);
  215. AdmResponse rs = query(request);
  216. return (List<AdmSpace>) rs.getContent();
  217. }
  218. @Override
  219. public List<AdmSpace> querySpaceInBuilding(InstanceUrlParam context, String buildingId, String spaceType) {
  220. AdmQueryCriteria request = new AdmQueryCriteria();
  221. request.setName(AdmSpace.OBJ_TYPE);
  222. request.resetRelationCond(false, "ArchSubset", "Bd2Sp", spaceType, buildingId, true);
  223. AdmResponse rs = query(request);
  224. return (List<AdmSpace>) rs.getContent();
  225. }
  226. @Override
  227. public Map<String, List<String>> querySpaceMapInFloors(InstanceUrlParam context, List<String> floorIds, String spaceType) {
  228. QueryCriteria queryRequest = new QueryCriteria();
  229. ObjectNode criteriaRel = JsonNodeFactory.instance.objectNode();
  230. criteriaRel.put("graphCode", "ArchSubset");
  231. criteriaRel.put("relCode", "Fl2Sp");
  232. criteriaRel.put("relValue", spaceType);
  233. ArrayNode objNode = criteriaRel.putArray("objFrom");
  234. floorIds.forEach(floorId -> objNode.add(floorId));
  235. queryRequest.setCriteria(criteriaRel);
  236. List<ObjectRelation> relations = relationService.queryByCondition(context, queryRequest);
  237. if(CollUtil.isEmpty(relations)) {
  238. return null;
  239. }
  240. return relations.stream().collect(Collectors.groupingBy(ObjectRelation::getObjFrom,
  241. Collectors.mapping(ObjectRelation::getObjTo, Collectors.toList())));
  242. }
  243. @Override
  244. public Map<String, Set<String>> queryTrafficSpaceMap(InstanceUrlParam context, Iterable<String> spaceIds, String spaceType) {
  245. Map<String, Set<String>> result = new HashMap<>();
  246. loadTrafficSpace(context, spaceIds, spaceType, true, result);
  247. loadTrafficSpace(context, spaceIds, spaceType, false, result);
  248. return result;
  249. }
  250. /***
  251. * Description: 查询多建筑楼层下的空间id
  252. * @param request : 请求参数
  253. * @return : java.util.Set<java.lang.String>
  254. * @author : lijie
  255. * @date :2021/10/28 17:56
  256. * Update By lijie 2021/10/28 17:56
  257. */
  258. @Override
  259. public Set<String> queryMultiBuildingOrFloorSpaceIds(HttpServletRequest request) {
  260. String groupCode = AppContext.getContext().getGroupCode();
  261. String projectId = AppContext.getContext().getProjectId();
  262. // 1.查询楼层下的空间的关系统计数据
  263. CommonResult<List<ObjectRelation>> floorCountByObjIds = DigitalObjectSimpleFacade
  264. .queryRelationCountByObjIds(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID,
  265. getMultiBuildingOrFloorQueryWrapper(request,RelCodeEnum.Fl2Sp.name()));
  266. List<ObjectRelation> floorSpaceData = floorCountByObjIds.getData();
  267. // 2.查询建筑下的空间的关系统计数据
  268. CommonResult<List<ObjectRelation>> buildingCountByObjIds = DigitalObjectSimpleFacade
  269. .queryRelationCountByObjIds(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID,
  270. getMultiBuildingOrFloorQueryWrapper(request, RelCodeEnum.Bd2Sp.name()));
  271. List<ObjectRelation> buildingSpaceData = buildingCountByObjIds.getData();
  272. Set<String> spaceIds = CollUtil.newHashSet(CollUtil.isNotEmpty(floorSpaceData), floorSpaceData
  273. .stream().filter(objectRelation -> objectRelation.getCount()>1)
  274. .map(ObjectRelation::getObjTo).collect(Collectors.toSet()));
  275. spaceIds.addAll(CollUtil.newHashSet(CollUtil.isNotEmpty(buildingSpaceData),
  276. buildingSpaceData.stream().filter(objectRelation -> objectRelation.getCount()>1)
  277. .map(ObjectRelation::getObjTo).collect(Collectors.toSet())));
  278. return spaceIds;
  279. }
  280. /***
  281. * Description: 查询多建筑楼层下的空间列表
  282. * @param request : 请求参数
  283. * @return : java.util.Set<java.lang.String>
  284. * @author : lijie
  285. * @date :2021/10/28 17:56
  286. * Update By lijie 2021/10/28 17:56
  287. */
  288. @Override
  289. public AdmResponse queryMultiBuildingOrFloorSpaces(HttpServletRequest request) {
  290. // 1.查询多建筑楼层下的空间id列表
  291. Set<String> spaceIds = queryMultiBuildingOrFloorSpaceIds(request);
  292. AdmQueryCriteria spaceCriteria = new AdmQueryCriteria();
  293. String filters = " id in ['"+ String.join("', '", spaceIds) +"'] ";
  294. spaceCriteria.setFilters(filters);
  295. AdmQueryCriteria floorCriteria = new AdmQueryCriteria();
  296. floorCriteria.setName("floorList");
  297. AdmQueryCriteria buildingCriteria = new AdmQueryCriteria();
  298. buildingCriteria.setName("building");
  299. floorCriteria.setCascade(CollUtil.newArrayList(buildingCriteria));
  300. spaceCriteria.setCascade(CollUtil.newArrayList(floorCriteria));
  301. return super.doQuery(AdmContextUtil.toDmpContext(), spaceCriteria, AdmSpace.class);
  302. }
  303. /***
  304. * Description: 根据查询条件查询空间统计数据
  305. * @param request : 请求参数
  306. * @return : com.persagy.proxy.adm.request.AdmResponse
  307. * @author : lijie
  308. * @date :2021/10/28 21:07
  309. * Update By lijie 2021/10/28 21:07
  310. */
  311. @Override
  312. public AdmResponse query(AdmQueryCriteria request) {
  313. InstanceUrlParam context = AdmContextUtil.toDmpContext();
  314. AdmResponse response = super.doQuery(context, request, AdmSpace.class);
  315. // 系统需要补充分类名称属性
  316. ensureSpecialValues(context, (List<AdmSpace>) response.getContent());
  317. return response;
  318. }
  319. /**
  320. * 更新轮廓线
  321. * @param vos
  322. * @return
  323. */
  324. @Override
  325. public AdmResponse updateOutLine(List<AdmSpace> vos) {
  326. InstanceUrlParam context = AdmContextUtil.toDmpContext();
  327. vos = super.doUpdate(context, AdmSpace.class, vos);
  328. SpringHelper.getBean(IAdmSpaceService.class).processRelationType(context,vos);
  329. return AdmResponse.success(vos);
  330. }
  331. @Override
  332. public AdmResponse doUpdate(List<AdmSpace> vos) {
  333. if(CollUtil.isNotEmpty(vos)) {
  334. AdmRelationTypeEnum typeEnumBd = AdmRelationTypeEnum.BD2SP;
  335. AdmRelationTypeEnum typeEnumFl = AdmRelationTypeEnum.FL2SP;
  336. QueryCriteria criteria = new QueryCriteria();
  337. ObjectNode node = JsonNodeFactory.instance.objectNode();
  338. List<RelationDTO> relationDTOList = new ArrayList<>(vos.size());
  339. vos.forEach(admSpace -> {
  340. //处理建筑 楼层信息点
  341. int removeflBd = 0 ;//关系处理 0:不删除; 1:删除bd; 2:删除fl; 3:都删除;
  342. List<String> nullList = CollUtil.newArrayList(admSpace.getNullList());
  343. if(CollUtil.isNotEmpty(nullList)){
  344. if(nullList.contains("flowBuild")){
  345. removeflBd = 3;
  346. Map<String, Object> infos = new HashMap<>(16);
  347. infos.put("$remove", Arrays.asList("floorId","buildingId"));
  348. }
  349. }
  350. if(StrUtil.isNotEmpty(admSpace.getFlowBuild())){
  351. String flowBuild = admSpace.getFlowBuild();
  352. if(!flowBuild.contains("-")){
  353. if(flowBuild.startsWith("Bd")){
  354. admSpace.setBuildingId(flowBuild);
  355. if(StrUtil.isNotEmpty(admSpace.getFloorId())){
  356. Map<String, Object> infos = new HashMap<>(16);
  357. infos.put("$remove", Arrays.asList("floorId"));
  358. admSpace.setInfos(infos);
  359. removeflBd = 2;
  360. }
  361. }
  362. }else {
  363. String[] str = flowBuild.split("-");
  364. if(str[0].startsWith("Bd")){
  365. admSpace.setBuildingId(str[0]);
  366. admSpace.setFloorId(str[1]);
  367. }else{
  368. admSpace.setBuildingId(str[1]);
  369. admSpace.setFloorId(str[0]);
  370. }
  371. removeflBd = 3;
  372. }
  373. admSpace.setFlowBuild(null);
  374. }
  375. //删除关系 然后重建
  376. if(removeflBd == 3 || removeflBd == 2){
  377. node.put("relCode", typeEnumFl.getRelCode());
  378. node.put("objTo", admSpace.getId());
  379. node.put("graphCode", typeEnumFl.getGraphCode());
  380. criteria.setCriteria(node);
  381. relationService.doDelete(AdmContextUtil.toDmpContext(), criteria);
  382. }
  383. if(removeflBd == 3 || removeflBd == 1){
  384. node.put("relCode", typeEnumBd.getRelCode());
  385. node.put("objTo", admSpace.getId());
  386. node.put("graphCode", typeEnumBd.getGraphCode());
  387. criteria.setCriteria(node);
  388. relationService.doDelete(AdmContextUtil.toDmpContext(), criteria);
  389. }
  390. });
  391. vos.stream().forEach(space -> {
  392. if (StrUtil.isNotEmpty(space.getBuildingId())) {
  393. RelationDTO relationBd = new RelationDTO(null, typeEnumBd.getGraphCode(), typeEnumBd.getRelCode(), null, space.getBuildingId(), space.getId());
  394. relationDTOList.add(relationBd);
  395. }
  396. if (StrUtil.isNotEmpty(space.getFloorId())) {
  397. RelationDTO relationFl = new RelationDTO(null, typeEnumFl.getGraphCode(), typeEnumFl.getRelCode(), null, space.getFloorId(), space.getId());
  398. relationDTOList.add(relationFl);
  399. }
  400. });
  401. if (CollUtil.isNotEmpty(relationDTOList)) {
  402. relationService.doSave(AdmContextUtil.toDmpContext(), relationDTOList);
  403. }
  404. vos = super.doUpdate(AdmContextUtil.toDmpContext(), AdmSpace.class, vos);
  405. }
  406. return AdmResponse.success(vos);
  407. }
  408. /**
  409. * 触发关系计算
  410. * @param vos
  411. */
  412. @Async
  413. @Override
  414. public void processRelationType(InstanceUrlParam context,List<AdmSpace> vos) {
  415. admRelCalService.calcRelation(context,
  416. CollUtil.newArrayList(
  417. AdmRelationTypeEnum.SP2SP_SPACENEIGHBORHOOD_5,
  418. AdmRelationTypeEnum.SP2SP_TRAFFICNETWORK_3,
  419. AdmRelationTypeEnum.SP2SP_CONVECTIONNETWORK_1,
  420. AdmRelationTypeEnum.SP2SP_RADIATIONNETWORK_1),null);
  421. vos.forEach(admSpace -> {
  422. admRelCalService.calcRelation(context,
  423. CollUtil.newArrayList(AdmRelationTypeEnum.EQ2SP_IN),admSpace.getClassCode());
  424. });
  425. }
  426. /***
  427. * Description: 根据查询条件查询空间统计数据,定制接口,后续可优化口
  428. * @param request : 请求参数
  429. * @return : com.persagy.proxy.adm.request.AdmResponse
  430. * @author : lijie
  431. * @date :2021/10/28 21:07
  432. * Update By lijie 2021/10/28 21:07
  433. */
  434. private AdmResponse query(AdmDCSQueryRequest request) {
  435. String orders = request.getOrders();
  436. List<OrderItem> orderItem = AdmQueryCriteriaHelper.toOrderItem(orders);
  437. Set<String> classCodes = StrUtil.isBlank(request.getZoneType()) ? request.getZoneTypeList() : Sets.newHashSet(request.getZoneType());
  438. /*ObjectNode objectNode = objectMapper.createObjectNode();
  439. ObjectNode condition = objectMapper.createObjectNode();
  440. condition.put("$null", true);
  441. objectNode.putPOJO("floorId", condition);*/
  442. QueryCriteria queryCriteria = AdmQueryCriteriaHelper.toDmpCriteria(request);
  443. ObjectNode criteria = queryCriteria.getCriteria();
  444. List<ObjectNode> queryObjects = this.relationReportService.queryObjects(criteria, AppContext.getContext().getGroupCode(), AppContext.getContext().getProjectId(),
  445. null, classCodes, Sets.newHashSet("space"), orderItem);
  446. List<AdmSpace> admVOs = AdmEntityTransferUtil.toAdmMultiEntity(queryObjects, request.getProjection(), AdmSpace.class);
  447. // 级联查询
  448. processCascade(AdmContextUtil.toDmpContext(), admVOs, request.getName(), request.getCascade());
  449. // 设置返回值
  450. AdmResponse response = AdmResponse.success(admVOs);
  451. if(CollectionUtil.isEmpty(queryObjects)){
  452. response.setTotal(0L);
  453. response.setCount(0L);
  454. }else {
  455. response.setTotal((long) queryObjects.size());
  456. }
  457. response.setPageNumber(request.getPageNumber() == null ? 50 : request.getPageNumber());
  458. response.setPageSize(request.getPageSize() == null ? 1 : request.getPageSize());
  459. // 系统需要补充分类名称属性
  460. ensureSpecialValues(AdmContextUtil.toDmpContext(), admVOs);
  461. return response;
  462. }
  463. /***
  464. * Description: 子类重写,以便处理带buildingId
  465. * @param dmpRequest : 中台查询参数
  466. * @return : void
  467. * @author : lijie
  468. * @date :2021/10/28 20:25
  469. * Update By lijie 2021/10/28 20:25
  470. */
  471. @Override
  472. protected void processDmpCriteria(QueryCriteria dmpRequest) {
  473. ObjectNode criteria = dmpRequest.getCriteria();
  474. if (null==criteria){
  475. return;
  476. }
  477. ObjectMapper objectMapper = SpringHelper.getBean(ObjectMapper.class);
  478. if (criteria.has("floorId")){
  479. // 有楼层id过滤
  480. if(!criteria.get("floorId").toString().contains("$null")) {
  481. ObjectNode relationTo = objectMapper.createObjectNode();
  482. relationTo.put("graphCode", GraphCodeEnum.ArchSubset.name());
  483. relationTo.put("relCode", RelCodeEnum.Fl2Sp.name());
  484. relationTo.set("objFrom", criteria.get("floorId"));
  485. criteria.set("relationTo", relationTo);
  486. criteria.remove("floorId");
  487. if (criteria.has("buildingId"))
  488. criteria.remove("buildingId");
  489. return;
  490. }
  491. }
  492. if (criteria.has("buildingId")){
  493. // 有建筑id过滤
  494. ObjectNode relationTo = objectMapper.createObjectNode();
  495. relationTo.put("graphCode", GraphCodeEnum.ArchSubset.name());
  496. relationTo.put("relCode", RelCodeEnum.Bd2Sp.name());
  497. if(!criteria.get("buildingId").toString().contains("$null")) {
  498. relationTo.set("objFrom",criteria.get("buildingId"));
  499. }else{
  500. relationTo.put("$bindFlag", false);
  501. }
  502. criteria.set("relationTo",relationTo);
  503. criteria.remove("buildingId");
  504. }
  505. }
  506. /***
  507. * Description: 获得多建筑楼层下的空间的查询条件
  508. * @param request : 请求参数
  509. * @param relCode : 边类型
  510. * @return : com.fasterxml.jackson.databind.node.ObjectNode
  511. * @author : lijie
  512. * @date :2021/10/28 17:55
  513. * Update By lijie 2021/10/28 17:55
  514. */
  515. private ObjectNode getMultiBuildingOrFloorQueryWrapper(HttpServletRequest request,String relCode) {
  516. ObjectMapper objectMapper = SpringHelper.getBean(ObjectMapper.class);
  517. ObjectNode objectNode = objectMapper.createObjectNode();
  518. if (StrUtil.isNotBlank(AppContext.getContext().getProjectId())){
  519. objectNode.putPOJO("projectIds", Sets.newHashSet(AppContext.getContext().getProjectId()));
  520. }
  521. objectNode.putPOJO("graphCodes", Sets.newHashSet(GraphCodeEnum.ArchSubset.name()));
  522. objectNode.putPOJO("relCodes", Sets.newHashSet(relCode));
  523. objectNode.putPOJO("groups", Sets.newHashSet("objTo"));
  524. return objectNode;
  525. }
  526. /**
  527. * 装载交通关系
  528. * @param context
  529. * @param spaceIds
  530. * @param spaceType
  531. * @param isFrom
  532. * @param result
  533. */
  534. private void loadTrafficSpace(InstanceUrlParam context, Iterable<String> spaceIds, String spaceType, boolean isFrom, Map<String, Set<String>> result) {
  535. // 关系查询条件
  536. QueryCriteria queryRequest = new QueryCriteria();
  537. ObjectNode criteriaRel = JsonNodeFactory.instance.objectNode();
  538. criteriaRel.put("graphCode", "TrafficNetwork");
  539. criteriaRel.put("relValue", spaceType);
  540. ArrayNode objNode = criteriaRel.putArray(isFrom?"objFrom":"objTo");
  541. spaceIds.forEach(spaceId -> objNode.add(spaceId));
  542. queryRequest.setCriteria(criteriaRel);
  543. List<ObjectRelation> relations = relationService.queryByCondition(context, queryRequest);
  544. if(CollUtil.isEmpty(relations)) {
  545. return;
  546. }
  547. // 存入Map
  548. for(ObjectRelation relation:relations) {
  549. String key = isFrom ? relation.getObjFrom() : relation.getObjTo();
  550. String value = isFrom ? relation.getObjTo() : relation.getObjFrom();
  551. Set<String> valueList = result.get(key);
  552. if(CollUtil.isEmpty(valueList)) {
  553. valueList = new HashSet<>();
  554. result.put(key, valueList);
  555. }
  556. valueList.add(value);
  557. }
  558. }
  559. /**
  560. * 空间的类型是根据项目自定义的
  561. * 参见中心
  562. * @Select("SELECT s.object_type as type,d.name FROM zone_space_base s
  563. * LEFT JOIN dict.dict_space_project d ON s.object_type = d.id WHERE s.project_id = #{projectId} AND d.project_id = #{projectId}
  564. * GROUP BY object_type, d.name")
  565. * @param context
  566. * @return
  567. */
  568. @Override
  569. public List<JSONObject> doQuerySpaceTypes(InstanceUrlParam context) {
  570. //根据项目id查询空间类型
  571. Map<String, String> codeNameMap = queryProjectDefineType(context);
  572. if(CollUtil.isNotEmpty(codeNameMap)){
  573. //查询object
  574. JSONArray demObjs = queryAndDealObjs(context, codeNameMap.keySet());
  575. if(CollUtil.isNotEmpty(demObjs)){
  576. List<AdmSpace> spaceList = JSONArray.parseArray(JSONUtil.toJsonStr(demObjs), AdmSpace.class);
  577. Set<String> classCodes = spaceList.stream().map(space -> space.getClassCode()).collect(Collectors.toSet());
  578. if(CollUtil.isNotEmpty(classCodes)){
  579. codeNameMap.keySet().removeIf(code -> !classCodes.contains(code));
  580. }
  581. }
  582. }
  583. if(CollUtil.isNotEmpty(codeNameMap)){
  584. List<JSONObject> list = new ArrayList<>(codeNameMap.size());
  585. codeNameMap.keySet().stream().forEach(code ->{
  586. JSONObject jsonObject = new JSONObject();
  587. jsonObject.put("name",codeNameMap.get(code));
  588. jsonObject.put("code",code);
  589. list.add(jsonObject);
  590. });
  591. return list;
  592. }else{
  593. return null;
  594. }
  595. }
  596. private List<ObjectNode> queryObject(InstanceUrlParam context, QueryCriteria criteriaObject){
  597. JSONObject paraPe = null;
  598. String groupCode = AppContext.getContext().getGroupCode();
  599. String projectId = AppContext.getContext().getProjectId();
  600. List<ObjectNode> query = DigitalObjectFacade.query(groupCode, projectId, AdmCommonConstant.APP_ID, AdmCommonConstant.USER_ID, criteriaObject);
  601. return query;
  602. }
  603. private DmpResult<JSONArray> queryObj(InstanceUrlParam context, QueryCriteria criteriaObject){
  604. JSONObject paraPe = null;
  605. try {
  606. String paraStr = objectMapper.writeValueAsString(criteriaObject);
  607. paraPe = JSONObject.parseObject(paraStr);
  608. } catch (JsonProcessingException e) {
  609. throw new RuntimeException("转换查询条件出错:" + e.getMessage());
  610. }
  611. return rwdClient.queryObject(context, paraPe);
  612. }
  613. private QueryCriteria ensureQueryCommParm(QueryCriteria dmpRequest, InstanceUrlParam context, Collection<String> classCodes, String objType){
  614. ObjectNode criteriaEq = null;
  615. if(JSONUtil.isNull(dmpRequest.getCriteria())){
  616. criteriaEq = JsonNodeFactory.instance.objectNode();
  617. }else{
  618. criteriaEq = dmpRequest.getCriteria();
  619. }
  620. if(CollUtil.isNotEmpty(classCodes)){
  621. ArrayNode array = criteriaEq.putObject("classCode").putArray("$in");
  622. classCodes.forEach(code -> array.add(code));
  623. }
  624. criteriaEq.put("objType", objType);
  625. dmpRequest.setCriteria(criteriaEq);
  626. return dmpRequest;
  627. }
  628. private JSONArray queryAndDealObjs(InstanceUrlParam context, Set<String> codes){
  629. QueryCriteria criteriaObject = ensureQueryCommParm(new QueryCriteria(), context, codes,AdmSpace.OBJ_TYPE);
  630. criteriaObject.setSize(50L);
  631. DmpResult<JSONArray> dmpResult = queryObj(context, criteriaObject);
  632. if(CollUtil.isEmpty(dmpResult.getData())){
  633. return null;
  634. }
  635. JSONArray demObjs = dmpResult.getData();
  636. if(dmpResult.getCount() > criteriaObject.getSize()){
  637. for(int page = 2; page < dmpResult.getCount()/criteriaObject.getSize()+1; page++){
  638. criteriaObject.setPage(page*1L);
  639. demObjs.addAll(queryObj(context, criteriaObject).getData());
  640. }
  641. }
  642. return demObjs;
  643. }
  644. private Map<String, String> queryProjectDefineType(InstanceUrlParam context){
  645. Map<String, String> codeNameMap = null;
  646. ObjectNode criteriaEq = JsonNodeFactory.instance.objectNode();
  647. criteriaEq.put("projectId", context.getProjectId());
  648. criteriaEq.put("objType", AdmSpace.OBJ_TYPE);
  649. DmpResult<JSONArray> resultDef = queryDefineType(context, criteriaEq);
  650. if(resultDef.getResult().equals(DmpResult.SUCCESS) && CollUtil.isNotEmpty(resultDef.getData())){
  651. List<ObjectTypeDefine> defineList = JSONUtil.toList(resultDef.getData().toString(), ObjectTypeDefine.class);
  652. codeNameMap = defineList.stream().collect(Collectors.toMap(ObjectTypeDefine::getCode, ObjectTypeDefine::getName, (k1,k2)->k1));
  653. }
  654. return codeNameMap;
  655. }
  656. /**
  657. * 查询空间flooId对应的infos中height存在的 flool
  658. * @param context
  659. * @param floolIds
  660. * @return
  661. */
  662. private List<ObjectNode> queryFloorsByFloorIds(InstanceUrlParam context, Collection<String> floolIds){
  663. QueryCriteria queryCriteria = ensureQueryCommParm(new QueryCriteria(),context, CollUtil.newArrayList("floor"),"floor");
  664. ObjectNode criteriaPe = queryCriteria.getCriteria();
  665. if(CollUtil.isNotEmpty(floolIds)){
  666. ArrayNode array = criteriaPe.putObject("id").putArray("$in");
  667. floolIds.forEach(floorId -> array.add(floorId));
  668. }
  669. JSONObject height = new JSONObject();
  670. height.put("$gt", 0f);
  671. criteriaPe.putPOJO("height", height);
  672. queryCriteria.setCriteria(criteriaPe);
  673. queryCriteria.setWithoutCount(true);
  674. return queryObject(context, queryCriteria);
  675. }
  676. /**
  677. * space.height = floor.infos.height
  678. * @param spaceMapByFlId
  679. * @param floorList
  680. * @return
  681. */
  682. private List<AdmSpace> processHeight(Map<String, List<AdmSpace>> spaceMapByFlId, List<ObjectNode> floorList){
  683. List<AdmSpace> resultList = new ArrayList<>();
  684. floorList.forEach(node -> {
  685. try {
  686. if (!node.has("id")
  687. || !node.get("id").isTextual()){
  688. return;
  689. }
  690. List<AdmSpace> spaces = spaceMapByFlId.get(node.get("id").asText());
  691. if (CollUtil.isEmpty(spaces)){
  692. return;
  693. }
  694. if(node.has("height")){
  695. String height = node.get("height").asText();
  696. if (StrUtil.isNotBlank(height)) {
  697. for (AdmSpace admSpace : spaces) {
  698. admSpace.setHeight(Double.parseDouble(height));
  699. resultList.add(admSpace);
  700. }
  701. }
  702. }
  703. } catch (Exception e) {}
  704. });
  705. return resultList;
  706. }
  707. /**
  708. * 添加绑定关系
  709. */
  710. private void processRelations(List<AdmSpace> vosR){
  711. if(CollUtil.isNotEmpty(vosR)) {
  712. List<RelationDTO> relationDTOS = new ArrayList<>(vosR.size());
  713. vosR.forEach(admSpace -> {
  714. if (StrUtil.isNotEmpty(admSpace.getBuildingId())) {
  715. relationDTOS.add(new RelationDTO("GtArchSubset001", "ArchSubset", "Bd2Sp", admSpace.getClassCode(), admSpace.getBuildingId(), admSpace.getId()));
  716. }
  717. if (StrUtil.isNotEmpty(admSpace.getFloorId())) {
  718. relationDTOS.add(new RelationDTO("GtArchSubset001", "ArchSubset", "Fl2Sp", admSpace.getClassCode(), admSpace.getFloorId(), admSpace.getId()));
  719. }
  720. });
  721. if (CollUtil.isNotEmpty(relationDTOS)) {
  722. relationService.doSave(AdmContextUtil.toDmpContext(), relationDTOS);
  723. }
  724. }
  725. }
  726. /**
  727. * 转换为目标实体,并增加属性
  728. */
  729. private void assembleDefineTypes(InstanceUrlParam context, List<JSONObject> defineList, String floorId){
  730. boolean needCount = true;
  731. defineList.stream().forEach(defineType -> {
  732. //查询空间数量
  733. int count = needCount ? countSpace(context, defineType.getString("code"), floorId) : 0;
  734. //处理单个对象
  735. assembleDefineObj(defineType, count, context.getProjectId());
  736. });
  737. }
  738. /**
  739. * 单个转换为目标实体,并增加属性
  740. */
  741. private void assembleDefineObj(JSONObject defineType, int count, String projectId){
  742. defineType.put("count", count);
  743. defineType.put("projectId", projectId);
  744. defineType.remove("aliasName");
  745. defineType.remove("aliasCode");
  746. defineType.remove("valid");
  747. defineType.remove("objType");
  748. defineType.remove("groupCode");
  749. defineType.remove("parentCode");
  750. defineType.remove("id");
  751. }
  752. private void addRelationTo(QueryCriteria rwdQueryCriteria, String objFrom, String relCode){
  753. ObjectNode relationTO = JsonNodeFactory.instance.objectNode();
  754. relationTO.put("relCode", relCode);
  755. relationTO.put("graphCode", "ArchSubset");
  756. relationTO.put("objFrom", objFrom);
  757. ObjectNode criteria = rwdQueryCriteria.getCriteria();
  758. criteria.putPOJO("relationTo", relationTO);
  759. rwdQueryCriteria.setCriteria(criteria);
  760. }
  761. /**
  762. * 查询存在空间的数量
  763. * @param context
  764. * @param classCode
  765. * @param objFrom
  766. * @return
  767. */
  768. private int countSpace(InstanceUrlParam context, String classCode, String objFrom){
  769. QueryCriteria queryCriteriaSpace = new QueryCriteria();
  770. ObjectNode criteria = JsonNodeFactory.instance.objectNode();
  771. criteria.put("state", 1);
  772. queryCriteriaSpace.setCriteria(criteria);
  773. QueryCriteria queryCriteria = ensureQueryCommParm(queryCriteriaSpace, context, CollUtil.newArrayList(classCode),"space");
  774. addRelationTo(queryCriteria, objFrom,"Fl2Sp");
  775. queryCriteria.setOnlyCount(true);
  776. DmpResult<JSONArray> dmpResult = queryObj(context, queryCriteria);
  777. return dmpResult.getCount();
  778. }
  779. private DmpResult<JSONArray> queryDefineType(InstanceUrlParam context, ObjectNode criteriaEq){
  780. QueryCriteria criteriaObject = new QueryCriteria();
  781. criteriaObject.setCriteria(criteriaEq);
  782. JSONObject paraPe = null;
  783. try {
  784. String paraStr = objectMapper.writeValueAsString(criteriaObject);
  785. paraPe = JSONObject.parseObject(paraStr);
  786. } catch (JsonProcessingException e) {
  787. throw new RuntimeException("查询公共定义的空间类型,转换查询条件出错:" + e.getMessage());
  788. }
  789. return rwdClient.queryDefClass(context, paraPe);
  790. }
  791. }