SyncAppImpl.java 26 KB

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