SyncSpaceImpl.java 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package com.persagy.bdtp.adm.service.impl;
  2. import cn.hutool.core.date.DatePattern;
  3. import cn.hutool.core.date.DateUtil;
  4. import cn.hutool.core.util.IdUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import com.fasterxml.jackson.databind.JsonNode;
  8. import com.fasterxml.jackson.databind.ObjectMapper;
  9. import com.fasterxml.jackson.databind.node.ArrayNode;
  10. import com.fasterxml.jackson.databind.node.ObjectNode;
  11. import com.fasterxml.jackson.databind.node.TextNode;
  12. import com.persagy.bdtp.adm.common.AdmConst;
  13. import com.persagy.bdtp.adm.dao.AdmJobSpaceMapper;
  14. import com.persagy.bdtp.adm.entity.Pagination;
  15. import com.persagy.bdtp.adm.entity.db.AdmJobSpace;
  16. import com.persagy.bdtp.adm.service.ISyncSpace;
  17. import com.persagy.bdtp.adm.service.ServiceUtil;
  18. import com.persagy.bdtp.adm.util.GeomUtil;
  19. import com.persagy.dmp.basic.model.QueryCriteria;
  20. import com.persagy.dmp.common.constant.ValidEnum;
  21. import com.persagy.dmp.digital.client.DigitalObjectClient;
  22. import org.locationtech.jts.geom.Polygon;
  23. import org.springframework.beans.factory.annotation.Autowired;
  24. import org.springframework.stereotype.Service;
  25. import org.springframework.transaction.annotation.Transactional;
  26. import java.io.IOException;
  27. import java.util.*;
  28. @Service
  29. public class SyncSpaceImpl implements ISyncSpace {
  30. @Autowired
  31. private ObjectMapper objectMapper;
  32. @Autowired
  33. private DigitalObjectClient objectClient;
  34. @Autowired
  35. private AdmJobSpaceMapper jobSpaceMapper;
  36. @Override
  37. @Transactional(rollbackFor = Exception.class)
  38. public Map<String, Object> sync(String groupCode, String projectId, String userId, String floorId, String zone) {
  39. if(StrUtil.isBlank(floorId))
  40. floorId = null;
  41. //查询bdtp的空间数据
  42. QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_SPACE);
  43. criteria.getCriteria().put("classCode", zone); //默认工作空间为物业分区
  44. //按楼层查询
  45. if (floorId != null) {
  46. ObjectNode rt = criteria.getCriteria().putObject("relationTo");
  47. rt.put("graphCode", "ArchSubset");
  48. rt.put("relCode", "Fl2Sp");
  49. rt.put("objFrom", floorId);
  50. }
  51. List<ObjectNode> spList = ServiceUtil.queryAllPage(() -> objectClient.query(groupCode, projectId, AdmConst.APP_ID, userId, criteria), criteria, new Pagination(500));
  52. List<AdmJobSpace> toCreate = new ArrayList<>();
  53. List<AdmJobSpace> toModify = new ArrayList<>();
  54. if(floorId == null){
  55. HashMap<String, List<ObjectNode>> floorMap = new HashMap<>();
  56. for(ObjectNode sp : spList) {
  57. JsonNode fId = sp.get("floorId");
  58. if(fId != null) {
  59. String flId = fId.asText();
  60. List<ObjectNode> flSps = floorMap.get(flId);
  61. if(flSps == null)
  62. floorMap.put(flId, flSps = new ArrayList<>());
  63. flSps.add(sp);
  64. }
  65. }
  66. for (Map.Entry<String, List<ObjectNode>> entry : floorMap.entrySet()) {
  67. syncByFloor(projectId, entry.getKey(), entry.getValue(), toCreate, toModify);
  68. }
  69. } else {
  70. syncByFloor(projectId, floorId, spList, toCreate, toModify);
  71. }
  72. String time = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
  73. for(AdmJobSpace job : toCreate) {
  74. job.setCreationTime(time);
  75. job.setCreator(AdmConst.CREATOR_SYNC);
  76. jobSpaceMapper.insert(job);
  77. }
  78. for(AdmJobSpace job : toModify) {
  79. job.setModifiedTime(time);
  80. job.setModifier(AdmConst.CREATOR_SYNC);
  81. jobSpaceMapper.updateById(job);
  82. }
  83. HashMap<String, Object> rtn = new HashMap<>();
  84. rtn.put("syncSpaces", toCreate.size() + toModify.size());
  85. return rtn;
  86. }
  87. private void syncByFloor(String projectId, String floorId, List<ObjectNode> spList, List<AdmJobSpace> toCreate, List<AdmJobSpace> toModify){
  88. //查询任务空间数据
  89. QueryWrapper<AdmJobSpace> wrapper = new QueryWrapper<>();
  90. wrapper.eq("project_id", projectId).eq("floor_id", floorId).eq("valid", ValidEnum.TRUE.getType());
  91. List<AdmJobSpace> jobSpaceList = jobSpaceMapper.selectList(wrapper);
  92. HashMap<String, AdmJobSpace> jobMap = new HashMap<>(jobSpaceList.size());
  93. jobSpaceList.forEach(job -> jobMap.put(job.getSpaceId(), job));
  94. //同步操作
  95. for(ObjectNode sp : spList){
  96. String spId = sp.get("id").asText();
  97. ArrayNode spOutline = null;
  98. Object o1 = sp.get("outline");
  99. if(o1 instanceof TextNode) {
  100. try {
  101. spOutline = objectMapper.readValue(((TextNode) o1).asText().toLowerCase(), ArrayNode.class); //暂时toLowerCase()处理
  102. } catch (IOException e) {
  103. }
  104. }
  105. if(!GeomUtil.checkPolygon(spOutline))
  106. continue;
  107. AdmJobSpace job = jobMap.remove(spId);
  108. if(job != null) { //id匹配
  109. boolean change = false;
  110. //轮廓变化的空间,重置任务状态
  111. if(!outlineMatch(job.getOutline(), spOutline)){
  112. job.setArchState(AdmConst.JOB_STATE_PROCESSING);
  113. job.setEquipState(AdmConst.JOB_STATE_PROCESSING);
  114. job.setOutline(spOutline);
  115. change = true;
  116. }
  117. //重置空间id
  118. if(!Objects.equals(spId, job.getSpaceId())) {
  119. job.setSpaceId(spId);
  120. change = true;
  121. }
  122. //轮廓和空间id都一致的,不需要做处理
  123. if(change)
  124. toModify.add(job);
  125. } else { //id未匹配
  126. job = matchByOutline(jobMap, spOutline);
  127. if(job != null) { //轮廓完全一致的任务空间,重新设置spaceId
  128. job.setSpaceId(spId);
  129. toModify.add(job);
  130. }
  131. }
  132. if (job == null) {
  133. job = new AdmJobSpace();
  134. job.setId(IdUtil.fastSimpleUUID());
  135. job.setSpaceId(spId);
  136. job.setOutline(spOutline);
  137. job.setArchState(AdmConst.JOB_STATE_PROCESSING);
  138. job.setEquipState(AdmConst.JOB_STATE_PROCESSING);
  139. job.setProjectId(projectId);
  140. job.setBuildingId(sp.get("buildingId").asText());
  141. job.setFloorId(floorId != null ? floorId : sp.get("floorId").asText());
  142. job.setValid(ValidEnum.TRUE.getType());
  143. toCreate.add(job);
  144. }
  145. }
  146. //未找到匹配关系的任务空间,删除
  147. for(AdmJobSpace job : jobMap.values()){
  148. job.setValid(ValidEnum.FALSE.getType());
  149. toModify.add(job);
  150. }
  151. }
  152. @Override
  153. public Map<String, Object> sync(String groupCode, String projectId, String userId, String zone) {
  154. return sync(groupCode, projectId, userId, null, zone);
  155. }
  156. private AdmJobSpace matchByOutline(HashMap<String, AdmJobSpace> jobMap, ArrayNode spOutline){
  157. if(jobMap.size() == 0)
  158. return null;
  159. if(!isValidOutline(spOutline))
  160. return null;
  161. Polygon[] ps = GeomUtil.getPolygon(spOutline);
  162. Map.Entry<String, AdmJobSpace> target = null;
  163. for(Map.Entry<String, AdmJobSpace> entry : jobMap.entrySet()){
  164. ArrayNode o2 = entry.getValue().getOutline();
  165. if(isValidOutline(o2) && polygonsMatch(ps, GeomUtil.getPolygon(o2))){
  166. target = entry;
  167. break;
  168. }
  169. }
  170. if(target != null){
  171. jobMap.remove(target.getKey());
  172. return target.getValue();
  173. }
  174. return null;
  175. }
  176. /**
  177. * 判断空间轮廓是否变化
  178. * TODO 区分覆盖等情况
  179. */
  180. private boolean outlineMatch(ArrayNode o1, ArrayNode o2){
  181. return polygonsMatch(GeomUtil.getPolygon(o1), GeomUtil.getPolygon(o2));
  182. }
  183. /**
  184. * 轮廓匹配判断
  185. * TODO 暂不考虑顺序
  186. */
  187. private boolean polygonsMatch(Polygon[] ps1, Polygon[] ps2){
  188. if (ps1.length == ps2.length) {
  189. for (int i = 0; i < ps2.length; i++) {
  190. if (!ps1[i].equalsExact(ps2[i]))
  191. return false;
  192. }
  193. return true;
  194. }
  195. return false;
  196. }
  197. private boolean isValidOutline(ArrayNode outline) {
  198. if(outline != null && outline.size() > 0 && outline.get(0).isArray()) {
  199. ArrayNode o1 = (ArrayNode) outline.get(0);
  200. if (o1.size() > 0 && o1.get(0).isArray()) {
  201. ArrayNode o2 = (ArrayNode) o1.get(0);
  202. return o2.size() >= 3;
  203. }
  204. }
  205. return false;
  206. }
  207. }