SyncAppImpl.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. package com.persagy.bdtp.adm.service.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DatePattern;
  4. import cn.hutool.core.date.DateUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  7. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  8. import com.fasterxml.jackson.databind.JsonNode;
  9. import com.fasterxml.jackson.databind.ObjectMapper;
  10. import com.fasterxml.jackson.databind.node.ArrayNode;
  11. import com.fasterxml.jackson.databind.node.ObjectNode;
  12. import com.persagy.bdtp.adm.client.DicClient;
  13. import com.persagy.bdtp.adm.client.RwdClient;
  14. import com.persagy.bdtp.adm.common.AdmConst;
  15. import com.persagy.bdtp.adm.dao.*;
  16. import com.persagy.bdtp.adm.datatx.ObjectMapper4Tx;
  17. import com.persagy.bdtp.adm.entity.*;
  18. import com.persagy.bdtp.adm.entity.db.*;
  19. import com.persagy.bdtp.adm.service.*;
  20. import com.persagy.bdtp.adm.util.DataExtrasUtil;
  21. import com.persagy.dmp.basic.model.QueryCriteria;
  22. import com.persagy.dmp.common.constant.ValidEnum;
  23. import com.persagy.dmp.define.entity.RelationDefine;
  24. import com.persagy.dmp.digital.client.DigitalObjectClient;
  25. import com.persagy.dmp.digital.client.DigitalRelationClient;
  26. import com.persagy.dmp.digital.entity.ObjectRelation;
  27. import org.springframework.beans.factory.annotation.Autowired;
  28. import org.springframework.stereotype.Service;
  29. import org.springframework.transaction.annotation.Transactional;
  30. import java.sql.Timestamp;
  31. import java.util.*;
  32. @Service
  33. public class SyncAppImpl implements ISyncApp {
  34. @Autowired
  35. private RwdClient rwdClient;
  36. @Autowired
  37. private DicClient dicClient;
  38. @Autowired
  39. private DigitalObjectClient objectClient;
  40. @Autowired
  41. private DigitalRelationClient relationClient;
  42. @Autowired
  43. private AdmClientFlagMapper clientFlagMapper;
  44. @Autowired
  45. private IConfigService configService;
  46. @Autowired
  47. private AdmPipeMapper pipeMapper;
  48. @Autowired
  49. private AdmJobSpaceMapper jobSpaceMapper;
  50. @Autowired
  51. private AdmProblemArchMapper problemArchMapper;
  52. @Autowired
  53. private AdmProblemEquipMapper problemEquipMapper;
  54. @Autowired
  55. private AdmFileMapper fileMapper;
  56. @Autowired
  57. private AdmQrCodeMapper qrCodeMapper;
  58. @Autowired
  59. private AdmServeAreaMapper serveAreaMapper;
  60. @Autowired
  61. private ISyncModel syncModel;
  62. @Autowired
  63. private ObjectMapper objectMapper;
  64. @Autowired
  65. private IAdmLogService logService;
  66. @Autowired
  67. private AdmUploadJobMapper uploadJobMapper;
  68. private final ObjectMapper4Tx mapper4Tx;
  69. @Autowired
  70. public SyncAppImpl(ObjectMapper4Tx mapper4Tx) {
  71. this.mapper4Tx = mapper4Tx;
  72. }
  73. @Override
  74. public String getClientId(String userId) {
  75. AdmClientFlag flagEntity = new AdmClientFlag();
  76. flagEntity.setUserId(userId);
  77. clientFlagMapper.insert(flagEntity);
  78. return String.valueOf(flagEntity.getId());
  79. }
  80. @Override
  81. public Dict downloadDict(String groupCode, String projectId, String userId) {
  82. return queryDict(groupCode, projectId, userId, true, true);
  83. }
  84. @Override
  85. public Dict queryDict(String groupCode, String projectId, String userId, boolean includeRel, boolean includeInfos){
  86. //从知识库服务获取专业分类
  87. QueryCriteria majorCriteria = ServiceUtil.getQueryCriteria(objectMapper);
  88. majorCriteria.getCriteria().put("type", "major");
  89. List<Map<String, Object>> majorList = ServiceUtil.call (() -> dicClient.dataQuery(groupCode, projectId, AdmConst.APP_ID, userId, majorCriteria));
  90. //查询系统和设备定义
  91. QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_SYSTEM, AdmConst.OBJ_TYPE_EQUIPMENT);
  92. List<TypeDef> typeList = ServiceUtil.queryAllPage(() -> rwdClient.queryObjectType(groupCode, projectId, AdmConst.APP_ID, userId, criteria), criteria, new Pagination(500));
  93. LinkedList<TypeDef> sysList = new LinkedList<>();
  94. LinkedList<TypeDef> equipList = new LinkedList<>();
  95. for(TypeDef def : typeList){
  96. if(def.getObjType().equals(AdmConst.OBJ_TYPE_SYSTEM))
  97. sysList.add(def);
  98. else if(def.getObjType().equals(AdmConst.OBJ_TYPE_EQUIPMENT))
  99. equipList.add(def);
  100. }
  101. Dict data = new Dict();
  102. data.setMajor(majorList);
  103. data.setSystem(sysList);
  104. data.setEquipment(equipList);
  105. //查询关系定义
  106. if(includeRel) {
  107. List<RelationDefine> relList = ServiceUtil.call(() -> rwdClient.queryRelDef(groupCode, projectId, AdmConst.APP_ID, userId, new QueryCriteria()));
  108. data.setRelation(relList);
  109. }
  110. //查询信息点定义
  111. if(includeInfos) {
  112. QueryCriteria qc = new QueryCriteria();
  113. qc.setCriteria(objectMapper.createObjectNode());
  114. List<InfoDef> funcList = ServiceUtil.call(() -> rwdClient.queryFunc(groupCode, projectId, AdmConst.APP_ID, userId, qc));
  115. data.setInfos(funcList);
  116. }
  117. return data;
  118. }
  119. @Override
  120. public Map<String, Object> downloadConfig(String groupCode, String projectId, String userId) {
  121. //配置数据查询
  122. List<AdmM2dEquip> m2dTypes = configService.queryM2dEquip(projectId);
  123. List<AdmInfosConfig> infosConfig = configService.queryInfosConfig(projectId);
  124. List<AdmRelsConfig> relConfig = configService.queryRelsConfig(projectId);
  125. List<AdmPipeConfig> pipeConfig = configService.queryPipeConfig(projectId);
  126. List<AdmConfig> config = configService.queryCommonConfig(projectId);
  127. List<AdmComponent> component = configService.queryComponent(projectId);
  128. List<AdmContainerConfig> containerConfig = configService.queryContainerConfig(projectId);
  129. HashMap<String, Object> data = new HashMap<>();
  130. data.put("m2dTypes", m2dTypes);
  131. data.put("infosConfig", infosConfig);
  132. data.put("relConfig", relConfig);
  133. data.put("pipeConfig", pipeConfig);
  134. data.put("config", config);
  135. data.put("component", component);
  136. data.put("containerConfig", containerConfig);
  137. return data;
  138. }
  139. @Override
  140. public Map<String, Object> downloadFrameData(String groupCode, String projectId, String userId) {
  141. //TODO 项目修改为从运维平台查询
  142. QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_PROJECT);
  143. List<ObjectNode> prjList = ServiceUtil.call(() -> objectClient.query(groupCode, null, AdmConst.APP_ID, userId, criteria));
  144. packInfos(prjList);
  145. QueryCriteria criteria2 = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_BUILDING, AdmConst.OBJ_TYPE_FLOOR);
  146. List<ObjectNode> bdAndFl = ServiceUtil.call(() -> objectClient.query(groupCode, projectId, AdmConst.APP_ID, userId, criteria2));
  147. packInfos(bdAndFl);
  148. HashMap<String, Object> data = new HashMap<>();
  149. data.put("projects", prjList);
  150. data.put("buildingsAndFloors", bdAndFl);
  151. return data;
  152. }
  153. private void packInfos(List<ObjectNode> dataList){
  154. if(dataList != null) {
  155. for(ObjectNode node : dataList) {
  156. handle4Download(node);
  157. DataExtrasUtil.packObjExtras(node);
  158. }
  159. }
  160. }
  161. /** 下载前处理数据结构 */
  162. private void handle4Download(ObjectNode node){
  163. JsonNode ol = node.get("outline");
  164. if(ol != null){
  165. try {
  166. node.set("outline", objectMapper.readValue(ol.asText(), ArrayNode.class));
  167. }catch (Exception e) {
  168. }
  169. }
  170. JsonNode bl = node.get("bimLocation");
  171. if(bl != null) {
  172. try {
  173. String[] arr = bl.asText().split(",");
  174. ObjectNode ln = objectMapper.createObjectNode();
  175. ln.put("x", Double.parseDouble(arr[0]));
  176. ln.put("y", Double.parseDouble(arr[1]));
  177. ln.put("z", Double.parseDouble(arr[2]));
  178. node.set("location", ln);
  179. node.remove("bimLocation");
  180. }catch (Exception e) {
  181. }
  182. }
  183. }
  184. @Override
  185. public BuildingData downloadBuildingData(String projectId, String buildingId, String uploadFlag, String lastDownloadTime) {
  186. throw new RuntimeException("not supported");
  187. }
  188. @Override
  189. public BuildingData downloadBuildingData(String groupCode, String projectId, String userId, String clientId, String buildingId, Long bdtpDownloadTs, Long admDownloadTs) {
  190. String operator = getOperator(clientId, userId);
  191. // //从bdtp下载对象(空间、竖井)
  192. // QueryCriteria archCriteria = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_SPACE, AdmConst.OBJ_TYPE_SHAFT);
  193. // buildDownloadQueryCriteria(archCriteria, operator, bdtpDownloadTs);
  194. // ObjectNode rt = archCriteria.getCriteria().putObject("relationTo");
  195. // rt.put("graphCode", "ArchSubset");
  196. // rt.put("objFrom", buildingId);
  197. // List<ObjectNode> archList = ServiceUtil.queryAllPage(() -> objectClient.query(groupCode, projectId, AdmConst.APP_ID, userId, archCriteria), archCriteria, new Pagination(500));
  198. // //系统、设备
  199. // QueryCriteria eqCriteria = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_SYSTEM, AdmConst.OBJ_TYPE_EQUIPMENT);
  200. // buildDownloadQueryCriteria(eqCriteria, operator, bdtpDownloadTs);
  201. // ObjectNode rf = eqCriteria.getCriteria().putObject("relationFrom");
  202. // rf.put("graphCode", "MechInArch");
  203. // rf.put("objTo", buildingId);
  204. // List<ObjectNode> eqList = ServiceUtil.queryAllPage(() -> objectClient.query(groupCode, projectId, AdmConst.APP_ID, userId, eqCriteria), eqCriteria, new Pagination(500));
  205. //
  206. // List<ObjectNode> objs = new ArrayList<>();
  207. // if(archList != null)
  208. // objs.addAll(archList);
  209. // if(eqList != null)
  210. // objs.addAll(eqList);
  211. //从bdtp下载对象(空间、竖井、系统、设备)
  212. QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper, AdmConst.OBJ_TYPE_SPACE, AdmConst.OBJ_TYPE_SHAFT, AdmConst.OBJ_TYPE_SYSTEM, AdmConst.OBJ_TYPE_EQUIPMENT);
  213. buildDownloadQueryCriteria(criteria, operator, bdtpDownloadTs, buildingId);
  214. List<ObjectNode> objs = ServiceUtil.queryAllPage(() -> objectClient.query(groupCode, projectId, AdmConst.APP_ID, userId, criteria), criteria, new Pagination(500));
  215. if(objs == null)
  216. objs = new ArrayList<>(0);
  217. packInfos(objs);
  218. test4Ts(objs);
  219. //关系数据按项目下载,不在建筑数据中处理
  220. //管道数据,实验方案
  221. List<AdmPipe> pipes = pipeMapper.selectList(buildDownloadQueryWrapper(new QueryWrapper<AdmPipe>(), projectId, buildingId, operator, admDownloadTs));
  222. //任务相关数据查询
  223. List<AdmJobSpace> jobSpace = jobSpaceMapper.selectList(buildDownloadQueryWrapper(new QueryWrapper<AdmJobSpace>(), projectId, buildingId, operator, admDownloadTs));
  224. List<AdmProblemArch> problemArch = problemArchMapper.selectList(buildDownloadQueryWrapper(new QueryWrapper<AdmProblemArch>(), projectId, buildingId, operator, admDownloadTs));
  225. List<AdmProblemEquip> problemEquip = problemEquipMapper.selectList(buildDownloadQueryWrapper(new QueryWrapper<AdmProblemEquip>(), projectId, buildingId, operator, admDownloadTs));
  226. List<AdmFile> file = fileMapper.selectList(buildDownloadQueryWrapper(new QueryWrapper<AdmFile>(), projectId, buildingId, operator, admDownloadTs));
  227. List<AdmQrCode> qrCode = qrCodeMapper.selectList(buildDownloadQueryWrapper(new QueryWrapper<AdmQrCode>(), projectId, buildingId, operator, admDownloadTs));
  228. List<AdmServeArea> serveArea = serveAreaMapper.selectList(buildDownloadQueryWrapper(new QueryWrapper<AdmServeArea>(), projectId, buildingId, operator, admDownloadTs));
  229. BuildingData data = new BuildingData();
  230. data.setBuildingId(buildingId);
  231. data.setObjects(objs);
  232. data.setPipes(pipes);
  233. data.setJobSpace(jobSpace);
  234. data.setProblemArch(problemArch);
  235. data.setProblemEquip(problemEquip);
  236. data.setFile(file);
  237. data.setQrCode(qrCode);
  238. data.setServeArea(serveArea);
  239. data.buildDownloadTs();
  240. return data;
  241. }
  242. private String getOperator(String clientId, String userId){
  243. return userId + ':' + clientId;
  244. }
  245. private <T> QueryWrapper<T> buildDownloadQueryWrapper(QueryWrapper<T> wrapper, String projectId, String buildingId, String operator, Long lastDownloadTime){
  246. wrapper.eq("project_id", projectId).eq("building_id", buildingId);
  247. if (lastDownloadTime != null && lastDownloadTime > 0) { //非初始化下载
  248. wrapper.gt("ts", lastDownloadTime);
  249. wrapper.and(
  250. w -> w.isNotNull("modifier").ne("modifier", operator)
  251. .or()
  252. .isNull("modifier").ne("creator", operator)
  253. );
  254. }
  255. return wrapper;
  256. }
  257. private void buildDownloadQueryCriteria(QueryCriteria criteria, String operator, Long lastDownloadTime, String buildingId){
  258. if (lastDownloadTime != null && lastDownloadTime > 0) {
  259. criteria.getCriteria().putObject("ts").put("$gt", lastDownloadTime);
  260. criteria.getCriteria().putObject("modifier").put("$ne", operator); //TODO 暂时只能处理modifier
  261. }
  262. if(StrUtil.isNotBlank(buildingId))
  263. criteria.getCriteria().put("buildingId", buildingId);
  264. }
  265. //TODO debug 接口未返回ts时,添加一个
  266. private void test4Ts(List<?> dataList){
  267. for(Object data : dataList) {
  268. if(data instanceof ObjectNode) {
  269. if (((ObjectNode) data).get("ts") == null)
  270. ((ObjectNode) data).put("ts", System.currentTimeMillis());
  271. } else if(data instanceof ObjectRelation){
  272. if(((ObjectRelation) data).getTs() == null)
  273. ((ObjectRelation) data).setTs(new Date());
  274. }
  275. }
  276. }
  277. @Override
  278. public ProjectData downloadProjectData(String groupCode, String projectId, String userId, String clientId, Long bdtpDownloadTs, Long admDownloadTs) {
  279. String operator = getOperator(clientId, userId);
  280. QueryCriteria criteria = ServiceUtil.getQueryCriteria(objectMapper);
  281. buildDownloadQueryCriteria(criteria, operator, bdtpDownloadTs, null);
  282. //List<ObjectRelation> rels = ServiceUtil.queryAllPage(() -> relationClient.query(groupCode, projectId, AdmConst.APP_ID, userId, criteria), criteria, new Pagination(500));
  283. //TODO debug 关系数据量过大,测试下载1000条
  284. criteria.setPage(1L);
  285. criteria.setSize(1000L);
  286. List<ObjectNode> rels = ServiceUtil.call(() -> rwdClient.queryRelation(groupCode, projectId, AdmConst.APP_ID, userId, criteria));
  287. test4Ts(rels);
  288. ProjectData data = new ProjectData();
  289. data.setRelations(rels);
  290. data.buildDownloadTs();
  291. return data;
  292. }
  293. @Override
  294. public UploadRtn uploadData(UploadData uploadData, String groupCode, String projectId, String userId, String clientId) {
  295. if(!uploadData.notEmpty())
  296. return new UploadRtn(AdmConst.UPLOAD_FINISHED);
  297. String operator = getOperator(clientId, userId);
  298. //检查上传任务状态
  299. String status = checkUploadStatus(uploadData.getUploadJobId(), operator, projectId);
  300. if(status != null)
  301. return new UploadRtn(status);
  302. String timestamp = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
  303. List<AdmUploadLog> logs = new ArrayList<>();
  304. //TODO 分布式事务管理
  305. try {
  306. //上传bdtp数据
  307. if (CollUtil.isNotEmpty(uploadData.getObjects())) {
  308. D2mMessage d2mMessage = new D2mMessage("object");
  309. List<ObjectNode>[] objData = prepareBdtpData(uploadData.getObjects(), operator, timestamp, uploadData.getUploadJobId(), d2mMessage, logs);
  310. uploadObjs(groupCode, projectId, userId, objData);
  311. sendD2mMessage(d2mMessage);
  312. }
  313. if (CollUtil.isNotEmpty(uploadData.getRelations())) {
  314. List<ObjectNode>[] relData = prepareBdtpData(uploadData.getRelations(), operator, timestamp, uploadData.getUploadJobId(), null, logs);
  315. uploadRels(groupCode, projectId, userId, relData);
  316. }
  317. //上传adm数据
  318. uploadAdmData(uploadData, operator, timestamp, logs);
  319. } catch (Exception e) {
  320. markStatus(uploadData.getUploadJobId(), AdmConst.UPLOAD_ERROR);
  321. if(e instanceof RuntimeException)
  322. throw (RuntimeException)e;
  323. throw new RuntimeException(e);
  324. }
  325. //标注上传任务状态
  326. markStatus(uploadData.getUploadJobId(), AdmConst.UPLOAD_FINISHED);
  327. //记录日志
  328. logService.saveUploadLog(logs);
  329. return new UploadRtn(AdmConst.UPLOAD_FINISHED);
  330. }
  331. private String checkUploadStatus(String uploadJobId, String operator, String projectId){
  332. AdmUploadJob job = uploadJobMapper.selectOne(new QueryWrapper<AdmUploadJob>().eq("id", uploadJobId));
  333. if(job != null) {
  334. if(!AdmConst.UPLOAD_ERROR.equals(job.getStatus()))
  335. return job.getStatus();
  336. } else {
  337. job = new AdmUploadJob();
  338. job.setId(uploadJobId);
  339. job.setProjectId(projectId);
  340. job.setOperator(operator);
  341. job.setStatus(AdmConst.UPLOAD_PROCESSING);
  342. job.setStartTime(new Timestamp(new Date().getTime()));
  343. uploadJobMapper.insert(job);
  344. }
  345. return null;
  346. }
  347. private void markStatus(String uploadJobId, String status) {
  348. AdmUploadJob job = new AdmUploadJob();
  349. job.setId(uploadJobId);
  350. job.setStatus(status);
  351. job.setFinishTime(new Timestamp(new Date().getTime()));
  352. uploadJobMapper.updateById(job);
  353. }
  354. private void uploadObjs(String groupCode, String projectId, String userId, List<ObjectNode>[] data) {
  355. if(data[0].size() > 0)
  356. ServiceUtil.call(() -> objectClient.create(groupCode, projectId, AdmConst.APP_ID, userId, data[0]));
  357. if (data[1].size() > 0)
  358. ServiceUtil.call(() -> objectClient.update(groupCode, projectId, AdmConst.APP_ID, userId, data[1]));
  359. }
  360. private void uploadRels(String groupCode, String projectId, String userId, List<ObjectNode>[] data) {
  361. if(data[0].size() > 0)
  362. ServiceUtil.call(() -> relationClient.create(groupCode, projectId, AdmConst.APP_ID, userId, data[0]));
  363. if (data[1].size() > 0)
  364. ServiceUtil.call(() -> relationClient.update(groupCode, projectId, AdmConst.APP_ID, userId, data[1]));
  365. }
  366. private List<ObjectNode>[] prepareBdtpData(List<ObjectNode> list, String operator, String time, String jobId, D2mMessage d2mMessage, List<AdmUploadLog> logs){
  367. List<ObjectNode> updateList = new ArrayList<>();
  368. Iterator<ObjectNode> iter = list.iterator();
  369. while (iter.hasNext()) {
  370. ObjectNode entity = iter.next();
  371. handle4Upload(entity);
  372. DataExtrasUtil.unpackObjExtras(entity);
  373. entity.remove("ts"); //调用bdtp接口前,删除ts字段
  374. AdmUploadLog log;
  375. if (entity.get("state").asInt() == 1) {
  376. updateList.add(entity);
  377. iter.remove();
  378. boolean remove = entity.get("valid").asInt() == ValidEnum.FALSE.getType();
  379. //设备数据上传时向模型服务发同步消息
  380. if(d2mMessage != null && AdmConst.OBJ_TYPE_EQUIPMENT.equals(entity.get("objType"))) {
  381. if(remove)
  382. d2mMessage.appendRemoveItem(entity);
  383. else
  384. d2mMessage.appendModifyItem(entity);
  385. }
  386. log = new AdmUploadLog(jobId, operator, remove ? AdmUploadLog.REMOVE : AdmUploadLog.MODIFY);
  387. log.setData(entity, objectMapper);
  388. entity.put("updateApp", AdmConst.CREATOR_APP);
  389. entity.put("modifier", operator);
  390. entity.put("modifiedTime", time);
  391. //修改对象信息点,轮廓不上传
  392. if(entity.get("outline") != null)
  393. entity.remove("outline");
  394. //TODO 可能需要进行删除信息点操作
  395. } else {
  396. if(d2mMessage != null)
  397. d2mMessage.appendAddItem(entity);
  398. log = new AdmUploadLog(jobId, operator, AdmUploadLog.ADD);
  399. log.setData(entity, objectMapper);
  400. entity.put("createApp", AdmConst.CREATOR_APP);
  401. entity.put("creator", operator);
  402. entity.put("creationTime", time);
  403. //TODO 临时处理,方便之后的增量查询
  404. entity.put("modifier", operator);
  405. entity.put("modifiedTime", time);
  406. }
  407. logs.add(log);
  408. }
  409. return new List[] {list, updateList};
  410. }
  411. @Transactional(rollbackFor = Exception.class)
  412. public void uploadAdmData(UploadData uploadData, String operator, String time, List<AdmUploadLog> logs) {
  413. if (CollUtil.isNotEmpty(uploadData.getPipes())) {
  414. uploadAdmEntities(uploadData.getPipes(), operator, time, uploadData.getUploadJobId(), pipeMapper, new D2mMessage("pipe"), logs, true);
  415. }
  416. if (CollUtil.isNotEmpty(uploadData.getJobSpace())) {
  417. uploadAdmEntities(uploadData.getJobSpace(), operator, time, uploadData.getUploadJobId(), jobSpaceMapper, null, logs, false);
  418. }
  419. if (CollUtil.isNotEmpty(uploadData.getProblemArch())) {
  420. uploadAdmEntities(uploadData.getProblemArch(), operator, time, uploadData.getUploadJobId(), problemArchMapper, null, logs, false);
  421. }
  422. if (CollUtil.isNotEmpty(uploadData.getProblemEquip())) {
  423. uploadAdmEntities(uploadData.getProblemEquip(), operator, time, uploadData.getUploadJobId(), problemEquipMapper, null, logs, false);
  424. }
  425. if (CollUtil.isNotEmpty(uploadData.getFile())) {
  426. uploadAdmEntities(uploadData.getFile(), operator, time, uploadData.getUploadJobId(), fileMapper, null, logs, false);
  427. }
  428. if (CollUtil.isNotEmpty(uploadData.getQrCode())) {
  429. uploadAdmEntities(uploadData.getQrCode(), operator, time, uploadData.getUploadJobId(), qrCodeMapper, null, logs, false);
  430. }
  431. if (CollUtil.isNotEmpty(uploadData.getServeArea())) {
  432. uploadAdmEntities(uploadData.getServeArea(), operator, time, uploadData.getUploadJobId(), serveAreaMapper, null, logs, false);
  433. }
  434. }
  435. private <T extends BaseAdmDataEntity> void uploadAdmEntities(List<T> list, String operator, String time, String jobId, BaseMapper<T> mapper, D2mMessage d2mMessage, List<AdmUploadLog> logs, boolean merge) {
  436. List<T> updateList = new ArrayList<>();
  437. Iterator<T> iter = list.iterator();
  438. while (iter.hasNext()) {
  439. T entity = iter.next();
  440. AdmUploadLog log;
  441. if (entity.getState() == 1) {
  442. updateList.add(entity);
  443. iter.remove();
  444. boolean remove = entity.getValid().intValue() == ValidEnum.FALSE.getType();
  445. if(d2mMessage != null) {
  446. if(remove)
  447. d2mMessage.appendRemoveItem(entity);
  448. else
  449. d2mMessage.appendModifyItem(entity);
  450. }
  451. log = new AdmUploadLog(jobId, operator, remove ? AdmUploadLog.REMOVE : AdmUploadLog.MODIFY);
  452. //任务空间不上传轮廓数据
  453. if(entity instanceof AdmJobSpace)
  454. ((AdmJobSpace) entity).setOutline(null);
  455. } else {
  456. if(d2mMessage != null)
  457. d2mMessage.appendAddItem(entity);
  458. log = new AdmUploadLog(jobId, operator, AdmUploadLog.ADD);
  459. }
  460. log.setData(entity, objectMapper);
  461. logs.add(log);
  462. entity.setTs(null); //保存数据前,删除ts字段
  463. }
  464. //insert
  465. if(list.size() > 0) {
  466. for(T entity : list) {
  467. entity.setCreator(operator);
  468. entity.setCreationTime(time);
  469. mapper.insert(entity);
  470. }
  471. }
  472. //update
  473. if (updateList.size() > 0) {
  474. Map<String, T> dbObjsMap = null;
  475. if(merge) {
  476. ArrayList<String> updateIds = new ArrayList<>(updateList.size());
  477. updateList.forEach(entity -> updateIds.add(entity.getId()));
  478. List<T> dbList = mapper.selectBatchIds(updateIds);
  479. dbObjsMap = new HashMap<>(dbList.size());
  480. for(T dbObj : dbList) {
  481. dbObjsMap.put(dbObj.getId(), dbObj);
  482. }
  483. }
  484. for(T entity : updateList) {
  485. if(merge)
  486. entity = mergeEntity(entity, dbObjsMap.get(entity.getId()));
  487. entity.setModifier(operator);
  488. entity.setModifiedTime(time);
  489. mapper.updateById(entity);
  490. }
  491. }
  492. sendD2mMessage(d2mMessage);
  493. }
  494. private <T extends BaseAdmDataEntity> T mergeEntity(T obj, T dbObj) {
  495. if (dbObj != null) {
  496. if(dbObj instanceof AdmPipe)
  497. ((AdmPipe)obj).setInfos(mergeInfos(((AdmPipe) obj).getInfos(), ((AdmPipe) dbObj).getInfos()));
  498. }
  499. return obj;
  500. }
  501. private ObjectNode mergeInfos(ObjectNode infos, ObjectNode dbInfos){
  502. if (dbInfos != null) {
  503. if(infos != null)
  504. dbInfos.setAll(infos);
  505. return dbInfos;
  506. } else
  507. return infos;
  508. }
  509. private void sendD2mMessage(D2mMessage d2mMessage){
  510. if (d2mMessage != null && d2mMessage.isNotEmpty()) {
  511. if(d2mMessage.getAddItems() != null){
  512. for(Object o : d2mMessage.getAddItems()) {
  513. markM2dState(o);
  514. }
  515. }
  516. if(d2mMessage.getModifyItems() != null){
  517. for(Object o : d2mMessage.getModifyItems()) {
  518. markM2dState(o);
  519. }
  520. }
  521. if(d2mMessage.getRemoveItems() != null) {
  522. for(Object o : d2mMessage.getRemoveItems()) {
  523. markM2dState(o);
  524. }
  525. }
  526. syncModel.sendMessageToModel(d2mMessage);
  527. }
  528. }
  529. /** 上传前处理数据结构 */
  530. private void handle4Upload(ObjectNode node){
  531. JsonNode l = node.get("location");
  532. if(l != null) {
  533. try {
  534. node.put("bimLocation", StrUtil.join(",", l.get("x").asDouble(), l.get("y").asDouble(), l.get("z").asDouble()));
  535. node.remove("location");
  536. }catch (Exception e) {
  537. }
  538. }
  539. }
  540. private void markM2dState(Object item){
  541. //TODO 标记数据同步状态
  542. }
  543. }