SceneFileBuildServiceImpl.java 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715
  1. package com.fdkankan.contro.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.collection.CollUtil;
  4. import cn.hutool.core.date.DateUtil;
  5. import cn.hutool.core.io.FileUtil;
  6. import cn.hutool.core.thread.ThreadUtil;
  7. import cn.hutool.core.util.StrUtil;
  8. import cn.hutool.extra.qrcode.QrCodeUtil;
  9. import cn.hutool.extra.qrcode.QrConfig;
  10. import cn.hutool.http.HttpUtil;
  11. import com.alibaba.fastjson.JSON;
  12. import com.alibaba.fastjson.JSONObject;
  13. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  14. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  15. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  16. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  17. import com.fdkankan.common.constant.*;
  18. import com.fdkankan.common.exception.BusinessException;
  19. import com.fdkankan.common.util.DateExtUtil;
  20. import com.fdkankan.common.util.FileUtils;
  21. import com.fdkankan.common.util.SnowflakeIdGenerator;
  22. import com.fdkankan.contro.constant.RedisConstants;
  23. import com.fdkankan.contro.entity.*;
  24. import com.fdkankan.contro.mapper.ISceneFileBuildMapper;
  25. import com.fdkankan.contro.service.*;
  26. import com.fdkankan.contro.vo.ResponseSceneFile;
  27. import com.fdkankan.contro.vo.ScenePlusVO;
  28. import com.fdkankan.fyun.config.FYunFileConfig;
  29. import com.fdkankan.fyun.face.FYunFileServiceInterface;
  30. import com.fdkankan.image.MatrixToImageWriterUtil;
  31. import com.fdkankan.model.constants.ConstantFilePath;
  32. import com.fdkankan.model.constants.UploadFilePath;
  33. import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
  34. import com.fdkankan.rabbitmq.util.RabbitMqProducer;
  35. import com.fdkankan.redis.constant.RedisKey;
  36. import com.fdkankan.redis.util.RedisLockUtil;
  37. import com.fdkankan.redis.util.RedisUtil;
  38. import com.fdkankan.web.response.Result;
  39. import com.fdkankan.web.response.ResultData;
  40. import com.fdkankan.web.util.RSAEncrypt;
  41. import lombok.extern.slf4j.Slf4j;
  42. import org.apache.commons.codec.binary.Base64;
  43. import org.apache.commons.lang3.StringUtils;
  44. import org.joda.time.DateTime;
  45. import org.springframework.beans.factory.annotation.Autowired;
  46. import org.springframework.beans.factory.annotation.Value;
  47. import org.springframework.cloud.context.config.annotation.RefreshScope;
  48. import org.springframework.http.*;
  49. import org.springframework.stereotype.Service;
  50. import org.springframework.util.LinkedMultiValueMap;
  51. import org.springframework.util.MultiValueMap;
  52. import org.springframework.util.ObjectUtils;
  53. import org.springframework.web.client.RestTemplate;
  54. import java.io.File;
  55. import java.io.IOException;
  56. import java.nio.charset.StandardCharsets;
  57. import java.util.*;
  58. import java.util.concurrent.CompletableFuture;
  59. import java.util.concurrent.ExecutorService;
  60. import java.util.stream.Collectors;
  61. /**
  62. * <p>
  63. * 场景文件建模表 服务实现类
  64. * </p>
  65. *
  66. * @author dengsixing
  67. * @since 2021-12-23
  68. */
  69. @RefreshScope
  70. @Slf4j
  71. @Service
  72. public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper, SceneFileBuild> implements ISceneFileBuildService {
  73. private static final String SPLICE = "#";
  74. @Value("${main.url}")
  75. private String mainUrl;
  76. @Value("${scene.pro.new.url}")
  77. private String sceneProNewUrl;
  78. @Value("${queue.modeling.modeling-pre}")
  79. private String queueModelingPre;
  80. @Value("${queue.modeling.v3.modeling-pre}")
  81. private String queueV3ModelingPre;
  82. @Value("${v3.controlUrl:#{null}}")
  83. private String v3controlUrl;
  84. @Value("${model.modelKind:3dtiles}")
  85. private String modelKind;
  86. @Value("#{'${model.3dtiles.sceneSource:}'.split(',')}")
  87. private List<Integer> sdTilesSceneSourceList;
  88. @Value("${build.notSupport.beforeTime:202203}")
  89. private String jgNotSupportBuildTime;
  90. @Autowired
  91. private RedisUtil redisUtil;
  92. @Autowired
  93. private IScenePlusExtService scenePlusExtService;
  94. @Autowired
  95. private IScene3dNumService scene3dNumService;
  96. @Autowired
  97. private IScenePlusService scenePlusService;
  98. @Autowired
  99. private RabbitMqProducer rabbitMqProducer;
  100. @Autowired
  101. private ISceneProEditService sceneProEditService;
  102. @Autowired
  103. private ISceneEditInfoService sceneEditInfoService;
  104. @Autowired
  105. private ISceneEditControlsService sceneEditControlsService;
  106. @Autowired
  107. private ISceneEditInfoExtService sceneEditInfoExtService;
  108. @Autowired
  109. private ISceneCooperationService sceneCooperationService;
  110. @Autowired
  111. private ISceneResourceCameraService sceneResourceCameraService;
  112. @Autowired
  113. private ISceneResourceCooperationService sceneResourceCooperationService;
  114. @Autowired
  115. private ICameraService cameraService;
  116. @Autowired
  117. private ICameraDetailService cameraDetailService;
  118. @Autowired
  119. private IUserService userService;
  120. @Autowired
  121. private ICompanyService companyService;
  122. @Autowired
  123. private FYunFileServiceInterface fYunFileService;
  124. @Autowired
  125. private FYunFileConfig fYunFileConfig;
  126. @Autowired
  127. private ISceneProService sceneProService;
  128. @Autowired
  129. private IFdkkLaserService fdkkLaserService;
  130. @Autowired
  131. private RedisLockUtil redisLockUtil;
  132. private RestTemplate restTemplate = new RestTemplate();
  133. @Autowired
  134. private ISceneCopyDistinctEnvService sceneCopyDistinctEnvService;
  135. @Override
  136. public SceneFileBuild findByFileId(String fileId) {
  137. List<SceneFileBuild> list = this.list(new LambdaQueryWrapper<SceneFileBuild>().eq(SceneFileBuild::getFileId, fileId)
  138. .orderByDesc(SceneFileBuild::getId));
  139. if(CollUtil.isEmpty(list)){
  140. return null;
  141. }
  142. return list.get(0);
  143. }
  144. @Override
  145. public ResponseSceneFile preUpload(String params) throws Exception {
  146. log.info("preUpload-params: "+params);
  147. if (StrUtil.isEmpty(params)){
  148. throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  149. }
  150. params = params.replaceAll("%2B", "+");
  151. Base64 base64 = new Base64();
  152. String cipher = params;
  153. // 私钥解密过程
  154. byte[] res = RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile()),
  155. base64.decode(cipher));
  156. String restr = new String(res, "UTF-8");
  157. log.debug("preUpload-params解密结果:" + restr);
  158. String[] strArr = restr.split(SPLICE);
  159. if (strArr.length != 5) {
  160. throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  161. }
  162. String mac = strArr[0];
  163. String totalPicNum = strArr[1];
  164. String chunks = strArr[2];
  165. String folderName = strArr[3];
  166. if (StrUtil.isEmpty(mac)){
  167. throw new BusinessException(ErrorCode.FAILURE_CODE_5044);
  168. }
  169. if (totalPicNum == null){
  170. throw new BusinessException(ErrorCode.FAILURE_CODE_5045);
  171. }
  172. if (chunks == null){
  173. throw new BusinessException(ErrorCode.FAILURE_CODE_5046);
  174. }
  175. if (folderName == null){
  176. throw new BusinessException(ErrorCode.FAILURE_CODE_5047);
  177. }
  178. log.info("mac:{} 准备上传文件,folderName:{}", mac, folderName);
  179. ResponseSceneFile responseSceneFile = new ResponseSceneFile();
  180. // 检测是否有生成
  181. String fileId = redisUtil.get(String.format(RedisConstants.FOLDER_FILEID_BUILD, folderName));
  182. if (!ObjectUtils.isEmpty(fileId)) {
  183. responseSceneFile.setFileId(fileId);
  184. return responseSceneFile;
  185. }
  186. SceneFileBuild sceneFileBuild = this.findByUnicode(folderName);
  187. if (sceneFileBuild != null) {
  188. fileId = sceneFileBuild.getFileId();
  189. responseSceneFile.setFileId(fileId);
  190. redisUtil.set(String.format(RedisConstants.FOLDER_FILEID_BUILD, folderName), fileId, 2 * 24 * 60 * 60);
  191. return responseSceneFile;
  192. }
  193. // 加锁
  194. boolean lock = redisLockUtil.lock(String.format(RedisConstants.FOLDER_LOCK_BUILD, folderName), 120);
  195. if (!lock) {
  196. throw new BusinessException(ErrorCode.FAILURE_CODE_5052);
  197. }
  198. // 查找场景表
  199. LambdaQueryWrapper<ScenePro> proWrapper = new LambdaQueryWrapper<>();
  200. proWrapper.like(ScenePro::getDataSource, "/" + folderName).eq(ScenePro::getRecStatus, 'A');
  201. ScenePro pro = sceneProService.getOne(proWrapper);
  202. String dataSource = null;
  203. if (!ObjectUtils.isEmpty(pro)) {
  204. dataSource = pro.getDataSource();
  205. } else {
  206. dataSource = scenePlusService.getDataSourceLikeUnicode("/" + folderName);
  207. }
  208. if (!ObjectUtils.isEmpty(dataSource)) {
  209. log.info("从数据库中查到与 fileId:{} 匹配的路径为:{}", fileId, dataSource);
  210. int n = dataSource.split("/").length;
  211. if (n > 1) {
  212. fileId = dataSource.split("/")[n - 2];
  213. }
  214. }
  215. if (ObjectUtils.isEmpty(fileId)) {
  216. fileId = new SnowflakeIdGenerator(0, 0).nextId() + "";
  217. log.info("新生成build数据,{}", fileId);
  218. }
  219. sceneFileBuild = new SceneFileBuild();
  220. sceneFileBuild.setChildName(mac);
  221. sceneFileBuild.setFileId(fileId);
  222. sceneFileBuild.setRecStatus("A");
  223. sceneFileBuild.setUnicode(folderName);
  224. sceneFileBuild.setTotalPicNum(Integer.valueOf(totalPicNum));
  225. sceneFileBuild.setChunks(Integer.valueOf(chunks));
  226. sceneFileBuild.setCreateTime(new Date());
  227. this.save(sceneFileBuild);
  228. redisUtil.set(String.format(RedisConstants.FOLDER_FILEID_BUILD, folderName), fileId, 2 * 24 * 60 * 60);
  229. redisUtil.set(String.format(RedisConstants.FILEID_FOLDER_BUILD, fileId), folderName, 2 * 24 * 60 * 60);
  230. responseSceneFile.setFileId(fileId);
  231. return responseSceneFile;
  232. }
  233. public SceneFileBuild findByUnicode(String unicode) {
  234. List<SceneFileBuild> list = this.list(new QueryWrapper<SceneFileBuild>()
  235. .eq("unicode", unicode)
  236. .orderByDesc("id"));
  237. if(CollUtil.isEmpty(list))
  238. return null;
  239. return list.get(0);
  240. }
  241. public ScenePlusVO buildScene(String fileId, String prefix,JSONObject jsonObject,String buildType,long cameraType) throws Exception{
  242. //调用createScene方法生成scene数据和加入算法队列
  243. String sceneNum = "";
  244. String cameraName = jsonObject.getJSONObject("cam").getString("uuid");
  245. String unicode = jsonObject.getString("creator") + "_" + jsonObject.getString("uuidtime");
  246. Camera camera = cameraService.getByChildName(cameraName);
  247. if (camera == null) {
  248. throw new BusinessException(CameraConstant.FAILURE_6003);
  249. }
  250. CameraDetail cameraDetail = cameraDetailService.getByCameraId(camera.getId());
  251. if (cameraDetail == null) {
  252. log.error("该相机详情不存在:" + cameraName);
  253. throw new BusinessException(CameraConstant.FAILURE_6003);
  254. }
  255. //查看场景中的文件目录是否有改文件id,有则重新计算改场景,无则新建场景
  256. ScenePlus scenePlus = scenePlusService.getByFileId("/" + fileId + "/");
  257. int rebuild = 1;
  258. if (ObjectUtils.isEmpty(scenePlus)) {
  259. sceneNum = scene3dNumService.generateSceneNum(cameraDetail.getType());
  260. rebuild = 0;
  261. } else {
  262. sceneNum = scenePlus.getNum();
  263. if (scenePlus.getSceneStatus().equals(SceneStatus.wait.code())) {
  264. log.info(scenePlus.getNum() + ":场景处于计算中,不能再计算");
  265. return null;
  266. }
  267. }
  268. if (sceneNum == null) {
  269. log.error("大场景序号为空:" + sceneNum);
  270. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  271. }
  272. String dataSource = cameraName.replace("4DKKPRO_", "").replace("-fdage", "").toLowerCase() + File.separator +
  273. fileId + File.separator + unicode;
  274. if (cameraType == 14) {
  275. dataSource = ConstantFilePath.BUILD_MODEL_LASER_PATH +dataSource;
  276. } else {
  277. dataSource = ConstantFilePath.BUILD_MODEL_PATH + dataSource;
  278. }
  279. String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, sceneNum);
  280. String icon = null;
  281. if (!ObjectUtils.isEmpty(jsonObject.getString("icon"))) {
  282. fYunFileService.copyFileInBucket(ConstantFilePath.OSS_PREFIX + prefix + jsonObject.getString("icon"),imgViewPath + jsonObject.getString("icon"));
  283. icon = fYunFileConfig.getHost() + imgViewPath + jsonObject.getString("icon");
  284. log.info("上传icon成功....");
  285. }
  286. return buildScenePost(dataSource, jsonObject, buildType, cameraType, sceneNum, cameraDetail, rebuild,icon);
  287. }
  288. private ScenePlusVO buildScenePost(String dataSource, JSONObject jsonObject, String buildType, long cameraType,
  289. String sceneNum, CameraDetail cameraDetail, int rebuild,String icon) throws Exception {
  290. String localDataPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, sceneNum);
  291. String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, sceneNum);
  292. String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, sceneNum);
  293. String userName = null;
  294. if (!ObjectUtils.isEmpty(cameraDetail.getUserId())) {
  295. SSOUser user = userService.getSSOUserByUserId(cameraDetail.getUserId());
  296. userName = ObjectUtils.isEmpty(user) ? null : user.getUserName();
  297. }
  298. JSONObject firmwareVersion = new JSONObject();
  299. if (!ObjectUtils.isEmpty(jsonObject.getString("camSoftwareVersion"))) {
  300. firmwareVersion.put("camSoftwareVersion", jsonObject.getString("camSoftwareVersion"));
  301. }
  302. if (!ObjectUtils.isEmpty(jsonObject.getString("version"))) {
  303. firmwareVersion.put("version", jsonObject.getString("version"));
  304. }
  305. String sceneUrl = mainUrl + "/" + sceneProNewUrl;
  306. //重算的场景,先移除该场景对应的容量
  307. if (rebuild == 1) {
  308. scenePlusService.resetSpace(sceneNum);
  309. //删除oss的houst_floor.json(国际版可能会卡住)
  310. fYunFileService.deleteFile(dataViewPath + "houst_floor.json");
  311. } else {
  312. //上传log-main.png
  313. fYunFileService.uploadFile(ConstantFilePath.LOGO_PATH + "logo-main.png", imgViewPath + "logo-main.png");
  314. fYunFileService.uploadFile(ConstantFilePath.LOGO_PATH + "logo-main-en.png", imgViewPath + "logo-main-en.png");
  315. }
  316. String algorithm = jsonObject.getString("location") != null && "1".equals(jsonObject.getString("location")) ? "sfm" : "slam";
  317. ScenePlusVO scenePlusVO = this.createScenePlus(sceneNum, cameraDetail.getCameraId(), jsonObject.getString("creator"),
  318. jsonObject.getString("pwd"),cameraType, dataSource, icon, cameraDetail.getUserId(), userName,algorithm,
  319. jsonObject.getJSONArray("points").size(), jsonObject.getString("name"), jsonObject.getString("info"),
  320. jsonObject.getInteger("scenetype"), jsonObject.getString("gps"), rebuild,
  321. jsonObject.getInteger("resolution"), firmwareVersion.toString(), sceneUrl, buildType, cameraDetail.getCooperationUser());
  322. if (Objects.nonNull(scenePlusVO)) {
  323. JSONObject statusJson = new JSONObject();
  324. //临时将-2改成1,app还没完全更新
  325. statusJson.put("status", scenePlusVO.getSceneStatus() == -2 ? 1 : scenePlusVO.getSceneStatus());
  326. statusJson.put("webSite", scenePlusVO.getWebSite());
  327. statusJson.put("sceneNum", scenePlusVO.getNum());
  328. statusJson.put("thumb", scenePlusVO.getThumb());
  329. statusJson.put("payStatus", 0);
  330. statusJson.put("recStatus", 'A');
  331. FileUtils.writeFile(localDataPath + "status.json", statusJson.toString());
  332. fYunFileService.uploadFile(localDataPath + "status.json", dataViewPath + "status.json");
  333. }
  334. BuildSceneCallMessage mqMessage = getBuildSceneMqMessage(sceneNum, cameraType, algorithm, jsonObject.getInteger("resolution"), buildType,
  335. scenePlusVO.getDataSource());
  336. if (cameraDetail.getCompanyId() != null) {
  337. Company company = companyService.getById(cameraDetail.getCompanyId());
  338. if (company != null && !ObjectUtils.isEmpty(company.getCalculateFlexibility()) && !company.getCalculateFlexibility()) {
  339. mqMessage.setFlexibility(-1);
  340. }
  341. }
  342. mqMessage.getExt().put("deleteExtras", true);
  343. rabbitMqProducer.sendByWorkQueue(queueModelingPre, mqMessage);
  344. return scenePlusVO;
  345. }
  346. public ScenePlusVO buildV3Scene(ScenePro scenePro,String fileId, String prefix,JSONObject jsonObject,String buildType,long cameraType) throws Exception{
  347. //调用createScene方法生成scene数据和加入算法队列
  348. String cameraName = jsonObject.getJSONObject("cam").getString("uuid");
  349. String unicode = jsonObject.getString("creator") + "_" + jsonObject.getString("uuidtime");
  350. Camera camera = cameraService.getByChildName(cameraName);
  351. if (camera == null) {
  352. throw new BusinessException(CameraConstant.FAILURE_6003);
  353. }
  354. CameraDetail cameraDetail = cameraDetailService.getByCameraId(camera.getId());
  355. if (cameraDetail == null) {
  356. log.error("该相机详情不存在:" + cameraName);
  357. throw new BusinessException(CameraConstant.FAILURE_6003);
  358. }
  359. String sceneNum = scenePro.getNum();
  360. if (scenePro.getStatus().equals(SceneStatus.wait.code())) {
  361. log.info(scenePro.getNum() + ":场景处于计算中,不能再计算");
  362. return null;
  363. }
  364. String localDataPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, sceneNum);
  365. String imgViewPath = String.format(ConstantFilePath.IMAGE_PATH_FORMAT, sceneNum);
  366. String dataViewPath = String.format(ConstantFilePath.DATA_PATH_FORMAT, sceneNum);
  367. String userName = null;
  368. if (!ObjectUtils.isEmpty(cameraDetail.getUserId())) {
  369. SSOUser user = userService.getSSOUserByUserId(cameraDetail.getUserId());
  370. userName = ObjectUtils.isEmpty(user) ? null : user.getUserName();
  371. }
  372. String icon = null;
  373. if (!ObjectUtils.isEmpty(jsonObject.getString("icon"))) {
  374. fYunFileService.copyFileInBucket(ConstantFilePath.OSS_PREFIX + prefix + jsonObject.getString("icon"),imgViewPath + jsonObject.getString("icon"));
  375. icon = fYunFileConfig.getHost() + imgViewPath + jsonObject.getString("icon");
  376. log.info("上传icon成功....");
  377. }
  378. JSONObject firmwareVersion = new JSONObject();
  379. if (!ObjectUtils.isEmpty(jsonObject.getString("camSoftwareVersion"))) {
  380. firmwareVersion.put("camSoftwareVersion", jsonObject.getString("camSoftwareVersion"));
  381. }
  382. if (!ObjectUtils.isEmpty(jsonObject.getString("version"))) {
  383. firmwareVersion.put("version", jsonObject.getString("version"));
  384. }
  385. //删除oss的houst_floor.json(国际版可能会卡住)
  386. fYunFileService.deleteFile(dataViewPath + "houst_floor.json");
  387. String algorithm = jsonObject.getString("location") != null && "1".equals(jsonObject.getString("location")) ? "sfm" : "slam";
  388. ScenePlusVO scenePlusVO = this.createScenePro(sceneNum, camera.getId(), camera.getChildName(), jsonObject.getString("creator"),
  389. jsonObject.getString("pwd"), unicode,cameraType, fileId, icon, cameraDetail.getUserId(), userName,algorithm,
  390. jsonObject.getJSONArray("points").size(), jsonObject.getString("name"), jsonObject.getString("info"),
  391. jsonObject.getInteger("scenetype"), jsonObject.getString("gps"),
  392. jsonObject.getInteger("resolution"), firmwareVersion.toString(), buildType);
  393. if (Objects.nonNull(scenePlusVO)) {
  394. JSONObject statusJson = new JSONObject();
  395. //临时将-2改成1,app还没完全更新
  396. statusJson.put("status", scenePlusVO.getSceneStatus() == -2 ? 1 : scenePlusVO.getSceneStatus());
  397. statusJson.put("webSite", scenePlusVO.getWebSite());
  398. statusJson.put("sceneNum", scenePlusVO.getNum());
  399. statusJson.put("thumb", scenePlusVO.getThumb());
  400. statusJson.put("payStatus", 0);
  401. statusJson.put("recStatus", 'A');
  402. FileUtils.writeFile(localDataPath + "status.json", statusJson.toString());
  403. fYunFileService.uploadFile(localDataPath + "status.json", dataViewPath + "status.json");
  404. }
  405. BuildSceneCallMessage mqMessage = getBuildSceneMqMessage(sceneNum, cameraType, algorithm, jsonObject.getInteger("resolution"), buildType,
  406. scenePlusVO.getDataSource());
  407. if (cameraDetail.getCompanyId() != null) {
  408. Company company = companyService.getById(cameraDetail.getCompanyId());
  409. if (company != null) {
  410. log.info("复制企业logo");
  411. SceneProEdit sceneEditInfo = sceneProEditService.getByProId(scenePlusVO.getId());
  412. if (StrUtil.isNotEmpty(company.getTopLogo())) {
  413. fYunFileService.copyFileInBucket(company.getTopLogo(),imgViewPath + "logo-main.png");
  414. }
  415. if (StrUtil.isNotEmpty(company.getFloorLogo())) {
  416. fYunFileService.copyFileInBucket(company.getFloorLogo(),imgViewPath + "floorLogoImg.png");
  417. sceneEditInfo.setFloorLogo("user");
  418. }
  419. if (StrUtil.isNotEmpty(company.getQrLogo())) {
  420. createQrCode(sceneNum,scenePlusVO.getWebSite(),company.getQrLogo());
  421. }
  422. sceneProEditService.updateById(sceneEditInfo);
  423. if (!ObjectUtils.isEmpty(company.getCalculateFlexibility()) && !company.getCalculateFlexibility()) {
  424. mqMessage.setFlexibility(-1);
  425. }
  426. }
  427. }
  428. rabbitMqProducer.sendByWorkQueue(queueV3ModelingPre, mqMessage);
  429. return scenePlusVO;
  430. }
  431. private void createQrCode(String num, String url, String qrLogo) {
  432. String localLogoPath = null;
  433. if (!org.apache.commons.lang3.ObjectUtils.isEmpty(qrLogo)) {
  434. try {
  435. localLogoPath = ConstantFilePath.AGENT_PATH + qrLogo.substring(qrLogo.lastIndexOf("//") + 1);
  436. HttpUtil.downloadFile(qrLogo, localLogoPath);
  437. } catch (Exception e) {
  438. log.error("公司logo下载失败:{}", qrLogo);
  439. localLogoPath = null;
  440. }
  441. }
  442. //生成二维码
  443. String outPathZh = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+ num +".png";
  444. String outPathEn = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+ num +"_en.png";
  445. QrConfig qrConfig = QrConfig.create();
  446. qrConfig.setWidth(512);
  447. qrConfig.setHeight(512);
  448. if(!org.apache.commons.lang3.ObjectUtils.isEmpty(localLogoPath)){
  449. qrConfig.setImg(localLogoPath);
  450. }
  451. QrCodeUtil.generate(url, qrConfig, FileUtil.file(outPathZh));
  452. QrCodeUtil.generate(url + "&lang=en", qrConfig, FileUtil.file(outPathEn));
  453. //上传二维码
  454. fYunFileService.uploadFile(outPathZh, String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + num + ".png");
  455. fYunFileService.uploadFile(outPathEn, String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + num + "_en.png");
  456. if(!org.apache.commons.lang3.ObjectUtils.isEmpty(localLogoPath)){
  457. FileUtils.deleteFile(localLogoPath);
  458. }
  459. }
  460. @Override
  461. public ResultData uploadSuccessBuild(String params) throws Exception {
  462. log.info("uploadSuccessBuild-params: " + params);
  463. String preParams = params;
  464. if (StringUtils.isEmpty(params)) {
  465. throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  466. }
  467. params = params.replaceAll("%2B", "+");
  468. params = params.replaceAll(" ", "+");
  469. Base64 base64 = new Base64();
  470. String cipher = params;
  471. // 私钥解密过程
  472. byte[] res = RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile()), base64.decode(cipher));
  473. String restr = new String(res, "UTF-8");
  474. log.info("uploadSuccessBuild-params解密结果:" + restr);
  475. String[] strArr = restr.split(SPLICE);
  476. if (strArr.length != 3) {
  477. throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  478. }
  479. String mac = strArr[0];
  480. String fileId = strArr[1];
  481. String folderName = redisUtil.get(String.format(RedisConstants.FILEID_FOLDER_BUILD, fileId));
  482. if(StringUtils.isEmpty(folderName)){
  483. SceneFileBuild fileBuild = findByFileId(fileId);
  484. if(ObjectUtils.isEmpty(fileBuild)){
  485. throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
  486. }
  487. folderName = fileBuild.getUnicode();
  488. redisUtil.set(String.format(RedisConstants.FILEID_FOLDER_BUILD, fileId), folderName,2 * 24 * 60 * 60);
  489. }
  490. StringBuilder prefixBuffer = new StringBuilder(mac).append(File.separator).append(fileId).append(File.separator).append(folderName).append(File.separator);
  491. String buildType = "V2";
  492. Long cameraType = 10L;
  493. if(!fYunFileService.fileExist(ConstantFilePath.OSS_PREFIX + prefixBuffer + "data.fdage")){
  494. log.error("data.fdage文件不存在");
  495. throw new BusinessException(CameraConstant.FAILURE_6009);
  496. }
  497. JSONObject fdageJson = JSONObject.parseObject(fYunFileService.getFileContent(ConstantFilePath.OSS_PREFIX + prefixBuffer + "data.fdage"));
  498. if(ObjectUtils.isEmpty(fdageJson)){
  499. log.info("data.fdage文件为空!");
  500. throw new BusinessException(CameraConstant.FAILURE_6009);
  501. }
  502. //根据videoVersion判断是V2还是V3版本的算法和页面
  503. if (fdageJson.containsKey("videoVersion") && StrUtil.isNotEmpty(fdageJson.getString("videoVersion"))) {
  504. if (fdageJson.getIntValue("videoVersion") >= 4) {
  505. buildType = "V3";
  506. cameraType = 11L;
  507. }
  508. }
  509. // 判断是否是V3的场景
  510. ScenePro scenePro = sceneProService.getOne(
  511. new LambdaQueryWrapper<ScenePro>().like(ScenePro::getDataSource, fileId));
  512. boolean callV3 = callV3(scenePro, preParams, fdageJson, "api/scene/file/uploadSuccessBuild");
  513. if(callV3) return ResultData.ok();
  514. if (ObjectUtils.isEmpty(scenePro) || (!ObjectUtils.isEmpty(scenePro.getIsUpgrade()) && scenePro.getIsUpgrade() == 1)) {
  515. buildScene(fileId, prefixBuffer.toString(),fdageJson,buildType,cameraType);
  516. }else{
  517. buildV3Scene(scenePro,fileId, prefixBuffer.toString(),fdageJson,buildType,cameraType);
  518. }
  519. return ResultData.ok();
  520. }
  521. private boolean callV3(ScenePro scenePro, String preParams, JSONObject fdageJson,String api) throws Exception {
  522. String cameraName = fdageJson.getJSONObject("cam").getString("uuid");
  523. Camera camera = cameraService.getByChildName(cameraName);
  524. if (camera == null) {
  525. throw new BusinessException(CameraConstant.FAILURE_6003);
  526. }
  527. CameraDetail cameraDetail = cameraDetailService.getByCameraId(camera.getId());
  528. if (cameraDetail == null) {
  529. log.error("该相机详情不存在:" + cameraName);
  530. throw new BusinessException(CameraConstant.FAILURE_6003);
  531. }
  532. // 判断是否是正顺|火调|普通v3的场景,如果是正顺|火调|普通v3的场景,则发送到原来的系统进行计算
  533. if (!ObjectUtils.isEmpty(cameraDetail.getCompanyId())) {
  534. Company company = companyService.getById(cameraDetail.getCompanyId());
  535. if(ObjectUtils.isEmpty(company)){
  536. log.error("企业配置有误:" + cameraName);
  537. throw new BusinessException(CameraConstant.FAILURE_6003);
  538. }
  539. if (!ObjectUtils.isEmpty(company.getSceneVersion()) && company.getSceneVersion().equals("V3")) {
  540. callV3Service(preParams, api);
  541. return Boolean.TRUE;
  542. }
  543. }
  544. // TODO: 2023/1/12 3dtiles临时上激光场景
  545. // else if (Objects.nonNull(scenePro) &&
  546. // scenePro.getSceneSource() != SceneSource.JG.code() &&
  547. // scenePro.getIsUpgrade() == CommonStatus.NO.code().intValue()){
  548. // callV3Service(preParams,api);
  549. // return Boolean.TRUE;
  550. // }
  551. return Boolean.FALSE;
  552. }
  553. public void callV3Service(String params,String api) throws Exception {
  554. log.info("params:{}", params);
  555. if(ObjectUtils.isEmpty(v3controlUrl)){
  556. log.error("未配置V3服务器!");
  557. throw new Exception("未配置V3服务器!");
  558. }
  559. HttpHeaders headers = new HttpHeaders();
  560. headers.setContentType(MediaType.MULTIPART_FORM_DATA);
  561. MultiValueMap<String,String> paramMap = new LinkedMultiValueMap();
  562. paramMap.add("params",params);
  563. HttpEntity<Object> formEntity = new HttpEntity<>(paramMap,headers);
  564. ResponseEntity<Result> responseEntity = restTemplate.postForEntity(v3controlUrl+api, formEntity, Result.class);
  565. if (responseEntity.getStatusCode().value() != HttpStatus.OK.value() || responseEntity.getBody().getCode() != ServerCode.SUCCESS.code()) {
  566. log.error("正顺场景请求V3服务器失败, params:{}, result:{}",params, JSON.toJSONString(responseEntity));
  567. throw new BusinessException(ErrorCode.SYSTEM_BUSY);
  568. }
  569. log.info("正顺场景请求V3服务器成功!");
  570. }
  571. @Override
  572. public ResultData turntableUploadSuccess(String params) throws Exception {
  573. log.info("turntableUploadSuccess-params: " + params);
  574. String preParams = params;
  575. if (StringUtils.isEmpty(params)) {
  576. throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  577. }
  578. params = params.replaceAll("%2B", "+");
  579. params = params.replaceAll(" ", "+");
  580. Base64 base64 = new Base64();
  581. String cipher = params;
  582. // 私钥解密过程
  583. byte[] res = RSAEncrypt.decrypt(RSAEncrypt.loadPrivateKeyByStr(RSAEncrypt.loadPrivateKeyByFile()),
  584. base64.decode(cipher));
  585. String restr = new String(res, "UTF-8");
  586. log.info("turntableUploadSuccess-params解密结果:" + restr);
  587. String[] strArr = restr.split(SPLICE);
  588. if (strArr.length != 3) {
  589. throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  590. }
  591. String mac = strArr[0];
  592. String fileId = strArr[1];
  593. String folderName = redisUtil.get(String.format(RedisConstants.FILEID_FOLDER_BUILD, fileId));
  594. if(StringUtils.isEmpty(folderName)){
  595. SceneFileBuild fileBuild = findByFileId(fileId);
  596. if(ObjectUtils.isEmpty(fileBuild)){
  597. throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
  598. }
  599. folderName = fileBuild.getUnicode();
  600. redisUtil.set(String.format(RedisConstants.FILEID_FOLDER_BUILD, fileId), folderName);
  601. }
  602. //云目录
  603. StringBuilder prefixBuffer = new StringBuilder(mac).append(File.separator).append(fileId).append(File.separator).append(folderName).append(File.separator);
  604. if(!fYunFileService.fileExist(ConstantFilePath.OSS_PREFIX + prefixBuffer + "data.fdage")){
  605. log.error("data.fdage文件不存在");
  606. throw new BusinessException(CameraConstant.FAILURE_6009);
  607. }
  608. JSONObject fdageJson = JSONObject.parseObject(fYunFileService.getFileContent(ConstantFilePath.OSS_PREFIX + prefixBuffer + "data.fdage"));
  609. if(ObjectUtils.isEmpty(fdageJson)){
  610. log.info("data.fdage文件为空");
  611. throw new BusinessException(CameraConstant.FAILURE_6009);
  612. }
  613. String buildType = "V3";
  614. //13表示转台
  615. Long cameraType = 13L;
  616. //激光转台 八目相机占用 10 和 11
  617. if(fdageJson.getJSONObject("cam").getIntValue("type") == 10){
  618. //激光转台
  619. cameraType = 14L;
  620. }
  621. // 判断是否是V3的场景
  622. ScenePro scenePro = sceneProService.getOne(
  623. new LambdaQueryWrapper<ScenePro>().like(ScenePro::getDataSource, fileId));
  624. boolean callV3 = callV3(scenePro, preParams, fdageJson, "api/scene/file/turntableUploadSuccess");
  625. if (callV3) return ResultData.ok();
  626. //激光场景校验是否能够计算
  627. this.checkJgCanBuild(scenePro);
  628. ScenePlusVO scenePlusVO = null;
  629. if (ObjectUtils.isEmpty(scenePro) || (!ObjectUtils.isEmpty(scenePro.getIsUpgrade()) && scenePro.getIsUpgrade() == 1)) {
  630. scenePlusVO = buildScene(fileId, prefixBuffer.toString(), fdageJson, buildType, cameraType);
  631. } else {
  632. scenePlusVO = buildV3Scene(scenePro,fileId, prefixBuffer.toString(), fdageJson, buildType, cameraType);
  633. }
  634. if(ObjectUtils.isEmpty(scenePlusVO)){
  635. return ResultData.ok();
  636. }
  637. // 通知激光场景系统开始构建场景
  638. if(cameraType.longValue() == 14){
  639. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(scenePlusVO.getNum());
  640. Long sceneUserId = scenePlus.getUserId();
  641. String userName = null;
  642. if(!ObjectUtils.isEmpty(sceneUserId)){
  643. userName = userService.getSSOUserByUserId(sceneUserId).getUserName();
  644. }
  645. //判断 是否为激光相机
  646. Camera camera = cameraService.getByChildName(mac);
  647. if(!ObjectUtils.isEmpty(scenePlus)){
  648. fdkkLaserService.saveScene(scenePlus,fdageJson.getString("pwd"),camera,userName,false);
  649. }else{
  650. fdkkLaserService.saveScene(scenePro,fdageJson.getString("pwd"),camera,userName,false);
  651. }
  652. }
  653. return ResultData.ok();
  654. }
  655. public ScenePlusVO createScenePlus(String projectNum, Long cameraId, String phoneId, String sceneKey,
  656. Long cameraType, String dataSource, String pic, Long userId, String userName,
  657. String algorithm, Integer sceneShootCount, String sceneName,
  658. String sceneDec, Integer sceneType, String gps,Integer type,
  659. Integer resolution, String firmwareVersion, String url, String buildType,
  660. Long cooperationUser)throws Exception{
  661. ScenePlusVO scenePlusVO = new ScenePlusVO();
  662. ScenePlus scenePlus = new ScenePlus();
  663. ScenePlusExt scenePlusExt = new ScenePlusExt();
  664. scenePlusExt.setWebSite(url+projectNum);
  665. scenePlus.setCameraId(cameraId);
  666. scenePlus.setPhoneId(phoneId);
  667. scenePlus.setNum(projectNum);
  668. scenePlus.setSceneSource(1);
  669. scenePlusExt.setDataSource(dataSource);
  670. if(resolution == null || resolution.intValue() == 0){
  671. scenePlusExt.setSceneScheme(cameraType.intValue());
  672. }else {
  673. scenePlusExt.setSceneScheme(4);
  674. }
  675. //转台相机用4k图
  676. if(cameraType.longValue() == 13 ){
  677. scenePlus.setSceneSource(3);
  678. scenePlusExt.setSceneScheme(10);
  679. }
  680. //激光相机
  681. if(cameraType.longValue() == 14 ){
  682. scenePlus.setSceneSource(4);
  683. scenePlusExt.setSceneScheme(10);
  684. }
  685. if(ModelKind.THREE_D_TILE.code().equals(modelKind)
  686. && CollUtil.isNotEmpty(sdTilesSceneSourceList)
  687. && sdTilesSceneSourceList.contains(scenePlus.getSceneSource())){
  688. scenePlusExt.setModelKind(modelKind);
  689. }
  690. if (pic != null && pic.length() > 5) {
  691. scenePlusExt.setThumb(pic);
  692. } else {
  693. scenePlusExt.setThumb(ConstantUrl.DEFAULT_SCENE_PIC);
  694. }
  695. scenePlusExt.setThumb(scenePlusExt.getThumb().concat("?t=") + System.currentTimeMillis());
  696. if (!ObjectUtils.isEmpty(userName)) {
  697. scenePlus.setUserId(userId);
  698. }
  699. if (sceneShootCount == null) {
  700. scenePlusExt.setShootCount(0);
  701. } else {
  702. scenePlusExt.setShootCount(sceneShootCount);
  703. }
  704. if (sceneName != null) {
  705. scenePlus.setTitle(sceneName);
  706. }
  707. if (sceneDec != null) {
  708. scenePlus.setDescription("<p>" + new String(sceneDec.getBytes("UTF-8")) + "</p>");
  709. }
  710. if (sceneType != null) {
  711. scenePlus.setSceneType(sceneType);
  712. }
  713. if (gps != null && !gps.trim().equals("")) {
  714. scenePlusExt.setGps(gps);
  715. }
  716. scenePlusExt.setAlgorithm(algorithm);
  717. if(!org.springframework.util.StringUtils.isEmpty(firmwareVersion)){
  718. scenePlusExt.setFirmwareVersion(firmwareVersion);
  719. }
  720. scenePlusExt.setBuildType(buildType);
  721. log.info("场景记录添加到数据库:"+projectNum);
  722. //type=0为新生成场景,其余为重新计算场景
  723. SceneEditInfo sceneEditInfo = new SceneEditInfo();
  724. SceneEditInfoExt sceneEditInfoExt = new SceneEditInfoExt();
  725. SceneEditControls sceneEditControls = new SceneEditControls();
  726. if(type == 0){
  727. scenePlus.setSceneStatus(SceneStatus.wait.code());
  728. scenePlusService.save(scenePlus);
  729. scenePlusExt.setPlusId(scenePlus.getId());
  730. scenePlusExtService.save(scenePlusExt);
  731. sceneEditInfo.setTitle(scenePlus.getTitle());
  732. sceneEditInfo.setDescription(scenePlus.getDescription());
  733. sceneEditInfo.setScenePlusId(scenePlus.getId());
  734. if(StrUtil.isNotBlank(sceneKey)) {
  735. sceneEditInfo.setScenePassword(sceneKey);
  736. sceneEditControls.setShowLock((int) CommonStatus.YES.code());
  737. }
  738. sceneEditInfoService.save(sceneEditInfo);
  739. sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
  740. sceneEditInfoExt.setScenePlusId(scenePlus.getId());
  741. sceneEditInfoExtService.save(sceneEditInfoExt);
  742. sceneEditControls.setEditInfoId(sceneEditInfo.getId());
  743. sceneEditControlsService.save(sceneEditControls);
  744. //新增场景时,同时新增场景协作信息
  745. if(cooperationUser != null){
  746. SceneCooperation sceneCooperationEntity = new SceneCooperation();
  747. sceneCooperationEntity.setNum(projectNum);
  748. sceneCooperationEntity.setUserId(cooperationUser);
  749. sceneCooperationService.save(sceneCooperationEntity);
  750. List<SceneResourceCamera> resourceCameraList = sceneResourceCameraService.findListByCameraId(cameraId);
  751. SceneResourceCooperation sceneResourceCooperation = null;
  752. if(resourceCameraList != null && resourceCameraList.size() > 0){
  753. for (SceneResourceCamera sceneResourceCamera : resourceCameraList) {
  754. sceneResourceCooperation = new SceneResourceCooperation();
  755. sceneResourceCooperation.setSceneResourceId(sceneResourceCamera.getSceneResourceId());
  756. sceneResourceCooperation.setSceneCooperationId(sceneCooperationEntity.getId());
  757. sceneResourceCooperationService.save(sceneResourceCooperation);
  758. }
  759. }
  760. }
  761. }else {
  762. ScenePlus oldScene = scenePlusService.getScenePlusByNum(projectNum);
  763. scenePlus.setId(oldScene.getId());
  764. scenePlus.setSceneStatus(0);
  765. scenePlus.setRecStatus(RecStatus.VALID.code());
  766. scenePlus.setPayStatus(0);
  767. scenePlus.setCreateTime(Calendar.getInstance().getTime());
  768. ScenePlusExt oldSceneExt = scenePlusExtService.getScenePlusExtByPlusId(oldScene.getId());
  769. scenePlusExt.setSpace(oldSceneExt.getSpace());
  770. scenePlusExt.setEcs(oldSceneExt.getEcs());
  771. scenePlusExt.setViewCount(oldSceneExt.getViewCount());
  772. if(sceneName!=null) {
  773. scenePlus.setTitle(sceneName);
  774. }
  775. if(sceneType!=null) {
  776. scenePlus.setSceneType(sceneType);
  777. }
  778. scenePlusService.updateById(scenePlus);
  779. scenePlusExtService.updateById(scenePlusExt);
  780. SceneEditInfo oldSceneEditInfo = sceneEditInfoService.getByScenePlusId(oldScene.getId());
  781. SceneEditInfoExt oldSceneEditeIinfoExt = sceneEditInfoExtService.getByEditInfoId(oldSceneEditInfo.getId());
  782. sceneEditInfo.setTitle(scenePlus.getTitle());
  783. sceneEditInfo.setDescription(scenePlus.getDescription());
  784. sceneEditInfo.setId(oldSceneEditInfo.getId());
  785. sceneEditInfo.setScenePlusId(scenePlus.getId());
  786. sceneEditInfo.setFloorLogoSize(100);
  787. sceneEditInfo.setRecStatus(RecStatus.VALID.code());
  788. sceneEditInfo.setFloorPublishVer(oldSceneEditInfo.getFloorEditVer() + 1);
  789. sceneEditInfo.setFloorEditVer(oldSceneEditInfo.getFloorEditVer() + 1);
  790. sceneEditInfo.setVersion(oldSceneEditInfo.getVersion() + 1);
  791. sceneEditInfoService.updateById(sceneEditInfo);
  792. if(Objects.nonNull(oldSceneEditeIinfoExt)){
  793. sceneEditInfoExt.setId(oldSceneEditeIinfoExt.getId());
  794. }
  795. sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
  796. sceneEditInfoExt.setScenePlusId(scenePlus.getId());
  797. sceneEditInfoExtService.saveOrUpdate(sceneEditInfoExt);
  798. }
  799. BeanUtil.copyProperties(scenePlusExt, scenePlusVO);
  800. BeanUtil.copyProperties(scenePlus, scenePlusVO);
  801. return scenePlusVO;
  802. }
  803. public ScenePlusVO createScenePro(String projectNum, Long cameraId, String cameraName, String phoneId, String sceneKey,
  804. String unicode, Long cameraType, String fileId, String pic, Long userId, String userName,
  805. String algorithm, Integer sceneShootCount, String sceneName,String sceneDec,
  806. Integer sceneType, String gps,Integer resolution, String firmwareVersion, String buildType
  807. )throws Exception{
  808. ScenePro scene = sceneProService.getByNum(projectNum);
  809. SceneProEdit sceneEdit = sceneProEditService.getByProId(scene.getId());
  810. scene.setCameraId(cameraId);
  811. scene.setPhoneId(phoneId);
  812. scene.setNum(projectNum);
  813. scene.setSpace(0L);
  814. if (pic != null && pic.length() > 5) {
  815. scene.setThumb(pic);
  816. } else {
  817. scene.setThumb(ConstantUrl.DEFAULT_SCENE_PIC);
  818. }
  819. scene.setThumb(scene.getThumb().concat("?t=") + System.currentTimeMillis());
  820. if (!ObjectUtils.isEmpty(userName)) {
  821. scene.setUserId(userId);
  822. }
  823. if (sceneShootCount == null) {
  824. scene.setShootCount(0);
  825. } else {
  826. scene.setShootCount(sceneShootCount);
  827. }
  828. if (sceneName != null) {
  829. scene.setSceneName(sceneName);
  830. }
  831. if (sceneDec != null) {
  832. scene.setSceneDec("<p>" + new String(sceneDec.getBytes("UTF-8")) + "</p>");
  833. }
  834. if (sceneType != null) {
  835. scene.setSceneType(sceneType);
  836. }
  837. if (gps != null && !gps.trim().equals("")) {
  838. scene.setGps(gps);
  839. }
  840. scene.setAlgorithm(algorithm);
  841. if(!org.springframework.util.StringUtils.isEmpty(firmwareVersion)){
  842. scene.setFirmwareVersion(firmwareVersion);
  843. }
  844. scene.setBuildType(buildType);
  845. log.info("场景记录添加到数据库:"+projectNum);
  846. scene.setStatus(0);
  847. scene.setPayStatus(0);
  848. scene.setRecStatus("A");
  849. scene.setCreateTime(new Date());
  850. if (sceneName != null) {
  851. scene.setSceneName(sceneName);
  852. }
  853. if (sceneType != null) {
  854. scene.setSceneType(sceneType);
  855. }
  856. sceneProService.updateById(scene);
  857. sceneEdit.setNeedKey(0);
  858. if (cameraType.longValue() != 14 && !ObjectUtils.isEmpty(sceneKey)) {
  859. sceneEdit.setNeedKey(1);
  860. sceneEdit.setSceneKey(sceneKey);
  861. }
  862. sceneEdit.setProId(scene.getId());
  863. sceneEdit.setMapVisi(1);
  864. sceneEdit.setTourVisi(1);
  865. sceneEdit.setVrVisi(1);
  866. sceneEdit.setCadImgVisi(1);
  867. sceneEdit.setPanoVisi(1);
  868. sceneEdit.setOverlay(null);
  869. sceneEdit.setM2dVisi(1);
  870. sceneEdit.setPlayData(null);
  871. sceneEdit.setFloorLogo("0");
  872. sceneEdit.setM3dVisi(1);
  873. sceneEdit.setJumpScene(false);
  874. sceneEdit.setMeasureVisi(0);
  875. sceneEdit.setFloorLogoSize(100);
  876. sceneEdit.setUpdateTime(new Date());
  877. sceneEdit.setRecStatus("A");
  878. sceneEdit.setFloorPublishVer(sceneEdit.getFloorEditVer() + 1);
  879. sceneEdit.setFloorEditVer(sceneEdit.getFloorEditVer() + 1);
  880. sceneEdit.setVersion(sceneEdit.getVersion() + 1);
  881. sceneEdit.setImagesVersion(sceneEdit.getImagesVersion() + 1);
  882. sceneProEditService.updateById(sceneEdit);
  883. JSONObject scenejson = JSONObject.parseObject(JSONObject.toJSONString(scene));
  884. scenejson.put("thumbImg", 0);
  885. scenejson.put("version", sceneEdit.getVersion());
  886. scenejson.put("floorLogo", 0);
  887. if(!ObjectUtils.isEmpty(sceneKey)){
  888. scenejson.put("sceneKey", sceneKey);
  889. scenejson.put("public", 1);
  890. }else{
  891. scenejson.put("sceneKey", "");
  892. scenejson.put("public", 0);
  893. }
  894. if(cameraType.longValue() < 4 || cameraType.longValue() == 5 || cameraType.longValue() == 6){
  895. scenejson.put("visions", 1);
  896. }else {
  897. scenejson.put("visions", 2);
  898. }
  899. scenejson.put("createTime", new DateTime(new Date()).toString("yyyy-MM-dd HH:mm"));
  900. scenejson.put("floorPublishVer", sceneEdit.getFloorPublishVer());
  901. scenejson.put("floorEditVer", sceneEdit.getFloorEditVer());
  902. scenejson.put("rulerVisi", sceneEdit.getRulerVisi());
  903. scenejson.put("entry", null);
  904. if(!org.springframework.util.StringUtils.isEmpty(sceneEdit.getHotsIds())){
  905. scenejson.put("hots", 1);
  906. }
  907. File file = new File(ConstantFilePath.SCENE_PATH+"data/data"+projectNum);
  908. if(!file.exists()||!file.isDirectory())
  909. {
  910. file.mkdirs();
  911. }
  912. FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data/data"+projectNum+File.separator+"scene.json", scenejson.toString());
  913. //生成二维码
  914. MatrixToImageWriterUtil.createQRCode(scene.getWebSite(), ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+projectNum+".png",false, null);
  915. MatrixToImageWriterUtil.createQRCode(scene.getWebSite() + "&lang=en", ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+projectNum+"_en.png",false, null);
  916. log.info("二维码生成完成");
  917. ScenePlusVO scenePlusVO = new ScenePlusVO();
  918. scenePlusVO.setSceneStatus(scene.getStatus());
  919. scenePlusVO.setThumb(scene.getThumb());
  920. scenePlusVO.setPayStatus(scene.getPayStatus());
  921. scenePlusVO.setId(scene.getId());
  922. scenePlusVO.setNum(scene.getNum());
  923. scenePlusVO.setWebSite(scene.getWebSite());
  924. scenePlusVO.setDataSource(scene.getDataSource());
  925. return scenePlusVO;
  926. }
  927. public BuildSceneCallMessage getBuildSceneMqMessage(String projectNum,
  928. Long cameraType, String algorithm, Integer resolution,
  929. String buildType, String dataSource) {
  930. BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
  931. mqMsg.setSceneNum(projectNum);
  932. mqMsg.setCameraType(String.valueOf(cameraType));
  933. mqMsg.setAlgorithm(algorithm);
  934. mqMsg.setResolution(String.valueOf(resolution));
  935. mqMsg.setBuildType(buildType);
  936. mqMsg.setPath(dataSource);
  937. mqMsg.setCreateTime(DateUtil.format(Calendar.getInstance().getTime(), DateExtUtil.dateStyle));
  938. mqMsg.setExt(new HashMap<>());
  939. return mqMsg;
  940. }
  941. @Override
  942. public ResultData rebuildScene(String num,Boolean force,Boolean deleteExtras) throws IOException {
  943. ScenePro scenePro = sceneProService.getByNum(num);
  944. // TODO: 2023/1/12 3dtiles临时上激光场景
  945. // if(Objects.nonNull(scenePro) && (Objects.isNull(scenePro.getIsUpgrade())
  946. // || scenePro.getIsUpgrade() != CommonStatus.YES.code().intValue())){
  947. // if(scenePro.getSceneSource() == SceneSource.JG.code().intValue()){
  948. // return rebuildV3Scene(scenePro,num,force);
  949. // }else{
  950. // return rebuildV3SceneToMini(scenePro);
  951. // }
  952. // }
  953. //激光场景校验是否能够计算
  954. this.checkJgCanBuild(scenePro);
  955. //如果是v3场景,不允许重算,需要升级v4后再调此接口进行重算
  956. if(Objects.nonNull(scenePro) && (Objects.isNull(scenePro.getIsUpgrade())
  957. || scenePro.getIsUpgrade() != CommonStatus.YES.code().intValue())){
  958. return rebuildV3Scene(scenePro,num,force);
  959. }
  960. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
  961. if(Objects.isNull(scenePlus)){
  962. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  963. }
  964. if (scenePlus.getSceneStatus() == 0 && (ObjectUtils.isEmpty(force) || !force)) {
  965. throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
  966. }
  967. ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
  968. String path = scenePlusExt.getDataSource();
  969. Integer sceneSource = scenePlus.getSceneSource();
  970. String buildType = scenePlusExt.getBuildType();
  971. Integer sceneScheme = scenePlusExt.getSceneScheme();
  972. String dataFdageOssPath = ConstantFilePath.OSS_PREFIX+ path.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
  973. .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "") + "/data.fdage";
  974. JSONObject fdageData = JSONObject.parseObject(fYunFileService.getFileContent(dataFdageOssPath));
  975. if(ObjectUtils.isEmpty(fdageData)){
  976. log.error("data.fdage文件不存在");
  977. return ResultData.error(CameraConstant.FAILURE_6009.code(), CameraConstant.FAILURE_6009.message());
  978. }
  979. //重算的场景,先移除该场景对应的容量
  980. scenePlusService.resetSpace(num);
  981. String statusJsonOssPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "status.json";
  982. JSONObject statusJson = JSONObject.parseObject(fYunFileService.getFileContent(String.format(UploadFilePath.DATA_VIEW_PATH, num) + "status.json"));
  983. if(ObjectUtils.isEmpty(statusJson)){
  984. statusJson = new JSONObject();
  985. }
  986. //临时将-2改成1,app还没完全更新
  987. statusJson.put("status", SceneStatus.wait.code());
  988. fYunFileService.uploadFile(statusJson.toJSONString().getBytes(StandardCharsets.UTF_8),statusJsonOssPath);
  989. Long cameraType = (long)sceneScheme == 3 ? 12 : (long)sceneScheme;
  990. //判断是否转台相机
  991. if(sceneSource == 3){
  992. cameraType = 13L;
  993. }
  994. if(sceneSource == 4){
  995. cameraType = 14L;
  996. }
  997. BuildSceneCallMessage message = null;
  998. if(sceneSource == 4){
  999. String userName = null;
  1000. Long sceneUserId = scenePlus.getUserId();
  1001. if (!ObjectUtils.isEmpty(sceneUserId)) {
  1002. SSOUser user = userService.getSSOUserByUserId(sceneUserId);
  1003. userName = user.getUserName();
  1004. }
  1005. Camera cameraEntity = cameraService.getById(scenePlus.getCameraId());
  1006. fdkkLaserService.saveScene(scenePlus,null,cameraEntity,userName,true);
  1007. message = this.getBuildSceneMqMessage(
  1008. num, cameraType,
  1009. fdageData.getString("location") != null && "1".equals(fdageData.getString("location")) ? "sfm" : "slam",
  1010. fdageData.getInteger("resolution"), buildType, path);
  1011. }else{
  1012. message = this.getBuildSceneMqMessage(
  1013. num, cameraType, fdageData.getString("location") != null && "1".equals(fdageData.getString("location")) ? "sfm" : "slam",
  1014. fdageData.getInteger("resolution"), buildType,
  1015. path);
  1016. }
  1017. if(deleteExtras){
  1018. message.getExt().put("deleteExtras",deleteExtras);
  1019. }
  1020. if (force) {
  1021. message.setRebuild("1");
  1022. }
  1023. rabbitMqProducer.sendByWorkQueue(queueModelingPre, message);
  1024. scenePlusService.update(new LambdaUpdateWrapper<ScenePlus>()
  1025. .set(ScenePlus::getSceneStatus, SceneStatus.wait.code())
  1026. .eq(ScenePlus::getNum, num));
  1027. if(ModelKind.THREE_D_TILE.code().equals(modelKind)
  1028. && CollUtil.isNotEmpty(sdTilesSceneSourceList)
  1029. && sdTilesSceneSourceList.contains(scenePlus.getSceneSource())){
  1030. scenePlusExt.setModelKind(modelKind);
  1031. }
  1032. scenePlusExtService.updateById(scenePlusExt);
  1033. return ResultData.ok();
  1034. }
  1035. /**
  1036. * 由于算法不支持2022年三月份前的激光场景计算,这里需要校验是否是能计算,不能就退出重算
  1037. * @return
  1038. */
  1039. private void checkJgCanBuild(ScenePro scenePro){
  1040. if(Objects.isNull(scenePro) || StrUtil.isEmpty(scenePro.getDataSource()) || !SceneSource.JG.code().equals(scenePro.getSceneSource())){
  1041. return;
  1042. }
  1043. cn.hutool.core.date.DateTime limitTime = DateExtUtil.parse(jgNotSupportBuildTime, DateExtUtil.dateStyle10);
  1044. String dataSource = scenePro.getDataSource();
  1045. String sceneDateTimeStr = dataSource.substring(dataSource.lastIndexOf("_") + 1).substring(0, 6);
  1046. //如果截取的时间串是空的,无法判断时间,就退出,正常走计算逻辑
  1047. if(StrUtil.isEmpty(sceneDateTimeStr)){
  1048. return;
  1049. }
  1050. cn.hutool.core.date.DateTime sceneDateTime = null;
  1051. try{
  1052. sceneDateTime = DateExtUtil.parse(sceneDateTimeStr, DateExtUtil.dateStyle10);
  1053. if(Objects.isNull(sceneDateTime)){
  1054. return;
  1055. }
  1056. }catch (Exception e){
  1057. //如果截取的时间串转换日期错误,无法判断时间,退出函数
  1058. return;
  1059. }
  1060. if(sceneDateTime.before(limitTime)){
  1061. throw new BusinessException(ErrorCode.FAILURE_CODE_5067);
  1062. }
  1063. }
  1064. public ResultData rebuildV3Scene(ScenePro scenePro,String num,Boolean force) throws IOException {
  1065. if (scenePro.getStatus() == 0 && (ObjectUtils.isEmpty(force) || !force)) {
  1066. throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
  1067. }
  1068. String path = scenePro.getDataSource();
  1069. Integer sceneSource = scenePro.getSceneSource();
  1070. String buildType = scenePro.getBuildType();
  1071. Integer sceneScheme = scenePro.getSceneScheme();
  1072. String dataFdageOssPath = ConstantFilePath.OSS_PREFIX+ path.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
  1073. .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "") + "/data.fdage";
  1074. JSONObject fdageData = JSONObject.parseObject(fYunFileService.getFileContent(dataFdageOssPath));
  1075. if(ObjectUtils.isEmpty(fdageData)){
  1076. log.error("data.fdage文件不存在");
  1077. return ResultData.error(CameraConstant.FAILURE_6009.code(), CameraConstant.FAILURE_6009.message());
  1078. }
  1079. String statusJsonOssPath = String.format(ConstantFilePath.DATA_PATH_FORMAT, num) + "status.json";
  1080. JSONObject statusJson = JSONObject.parseObject(fYunFileService.getFileContent(statusJsonOssPath));
  1081. if (ObjectUtils.isEmpty(statusJson)) {
  1082. statusJson = new JSONObject();
  1083. }
  1084. //临时将-2改成1,app还没完全更新
  1085. statusJson.put("status", SceneStatus.wait.code());
  1086. fYunFileService.uploadFile(statusJson.toJSONString().getBytes(StandardCharsets.UTF_8),statusJsonOssPath);
  1087. Long cameraType = (long)sceneScheme == 3 ? 12 : (long)sceneScheme;
  1088. //判断是否转台相机
  1089. if(sceneSource == 3){
  1090. cameraType = 13L;
  1091. }
  1092. if(sceneSource == 4){
  1093. cameraType = 14L;
  1094. }
  1095. if (sceneSource == 4) {
  1096. String userName = null;
  1097. Long sceneUserId = scenePro.getUserId();
  1098. if (!ObjectUtils.isEmpty(sceneUserId)) {
  1099. SSOUser user = userService.getSSOUserByUserId(sceneUserId);
  1100. userName = user.getUserName();
  1101. }
  1102. Camera cameraEntity = cameraService.getById(scenePro.getCameraId());
  1103. fdkkLaserService.saveScene(scenePro, null, cameraEntity, userName, true);
  1104. }
  1105. BuildSceneCallMessage buildSceneMqMessage = this.getBuildSceneMqMessage(
  1106. num, cameraType, fdageData.getString("location") != null && "1".equals(fdageData.getString("location")) ? "sfm" : "slam",
  1107. fdageData.getInteger("resolution"), buildType, path);
  1108. rabbitMqProducer.sendByWorkQueue(queueV3ModelingPre, buildSceneMqMessage);
  1109. //重算的场景,先移除该场景对应的容量
  1110. sceneProService.update(new LambdaUpdateWrapper<ScenePro>()
  1111. .set(ScenePro::getStatus, SceneStatus.wait.code())
  1112. .set(ScenePro::getSpace,0)
  1113. .eq(ScenePro::getNum, num));
  1114. return ResultData.ok();
  1115. }
  1116. @Override
  1117. public ResultData copyDataAndBuild(String sourceBucet,String dataSource, String sceneVer) throws Exception {
  1118. if(!SceneVersionType.V3.code().equals(sceneVer)
  1119. && !SceneVersionType.V4.code().equals(sceneVer)){
  1120. throw new BusinessException(ErrorCode.PARAM_FORMAT_ERROR.code(),"版本有误,请填写 V3 或者 V4");
  1121. }
  1122. String fYunPath = ConstantFilePath.OSS_PREFIX + dataSource.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
  1123. .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
  1124. // if(!ObjectUtils.isEmpty(sourceBucet)){
  1125. // fYunFileService.copyFileBetweenBucket(sourceBucet,fYunPath,fYunFileConfig.getBucket(),fYunPath);
  1126. // }
  1127. // 下载data.fdage
  1128. JSONObject fdageData = JSONObject.parseObject(fYunFileService.getFileContent(fYunPath + "/data.fdage"));
  1129. if(ObjectUtils.isEmpty(fdageData)){
  1130. throw new BusinessException(ErrorCode.SYSTEM_ERROR.code(),"4dage 文件不存在");
  1131. }
  1132. String cameraName = fdageData.getJSONObject("cam").getString("uuid");
  1133. Camera cameraEntity = cameraService.getByChildName(cameraName);
  1134. if(cameraEntity == null){
  1135. throw new BusinessException(ErrorCode.FAILURE_CODE_6003);
  1136. }
  1137. CameraDetail detailEntity = cameraDetailService.getByCameraId(cameraEntity.getId());
  1138. if(detailEntity == null){
  1139. throw new BusinessException(ErrorCode.FAILURE_CODE_6003);
  1140. }
  1141. // 拷贝资源至新的资源路径
  1142. String[] newDataPath = dataSource.split("/");
  1143. newDataPath[4] = newDataPath[4] + "_" + System.currentTimeMillis();
  1144. String time = DateExtUtil.format(Calendar.getInstance().getTime(), DateExtUtil.dateStyle11);
  1145. newDataPath[5] = newDataPath[5].split("_")[0] + "_" + time;
  1146. String newDataSource = Arrays.stream(newDataPath).collect(Collectors.joining("/"));
  1147. String newFYunPath = ConstantFilePath.OSS_PREFIX + newDataSource.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
  1148. .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
  1149. List<ScenePro> pros = sceneProService.list(new LambdaQueryWrapper<ScenePro>().eq(ScenePro::getDataSource, newDataSource));
  1150. if (CollUtil.isNotEmpty(pros)) {
  1151. return ResultData.error(ErrorCode.PARAM_ERROR.code(),newDataSource + "已存在,请勿重复添加!");
  1152. }
  1153. List<ScenePlusExt> plusExts = scenePlusExtService.list(new LambdaQueryWrapper<ScenePlusExt>().eq(ScenePlusExt::getDataSource, newDataSource));
  1154. if (CollUtil.isNotEmpty(plusExts)) {
  1155. return ResultData.error(ErrorCode.PARAM_ERROR.code(),newDataSource + "已存在,请勿重复添加!");
  1156. }
  1157. List<String> newFyunFileList = fYunFileService.listRemoteFiles(newFYunPath);
  1158. if(CollUtil.isNotEmpty(newFyunFileList)){
  1159. return ResultData.error(ErrorCode.PARAM_ERROR.code(),newFYunPath + "已存在,请勿重复添加!");
  1160. }
  1161. String sceneNum = scene3dNumService.generateSceneNum(detailEntity.getType());
  1162. //写入日志表
  1163. SceneCopyDistinctEnv sceneCopyDistinctEnv = new SceneCopyDistinctEnv();
  1164. sceneCopyDistinctEnv.setNum(sceneNum);
  1165. sceneCopyDistinctEnv.setSrcDataSource(dataSource);
  1166. sceneCopyDistinctEnv.setTargetDataSource(newDataSource);
  1167. sceneCopyDistinctEnvService.save(sceneCopyDistinctEnv);
  1168. ExecutorService executor = ThreadUtil.newSingleExecutor();
  1169. try {
  1170. CompletableFuture.runAsync(() -> {
  1171. try {
  1172. fYunFileService.copyFileBetweenBucket(sourceBucet, fYunPath, fYunFileConfig.getBucket(), newFYunPath);
  1173. fdageData.put("uuidtime",time);
  1174. fYunFileService.uploadFile(fdageData.toJSONString().getBytes(),newFYunPath+"/data.fdage");
  1175. Long cameraType = 11L;
  1176. //判断是否转台相机
  1177. if (detailEntity.getType() == 9) {
  1178. cameraType = 13L;
  1179. }
  1180. if (detailEntity.getType() == 10) {
  1181. cameraType = 14L;
  1182. }
  1183. String icon = null;
  1184. String imgViewPath = null;
  1185. switch (sceneVer) {
  1186. case "V3":
  1187. imgViewPath = String.format(ConstantFilePath.IMAGE_PATH_FORMAT, sceneNum);
  1188. if(fdageData.containsKey("icon") && StringUtils.isNotEmpty(fdageData.getString("icon"))){
  1189. String ossPath = ConstantFilePath.OSS_PREFIX + newDataSource.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
  1190. .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
  1191. fYunFileService.copyFileInBucket(ossPath + File.separator + fdageData.getString("icon"),imgViewPath + fdageData.getString("icon"));
  1192. icon = fYunFileConfig.getHost() + imgViewPath + fdageData.getString("icon");
  1193. }
  1194. buildV3Scene2(newDataSource,fdageData,cameraType,sceneNum,cameraEntity,detailEntity,icon);
  1195. break;
  1196. case "V4":
  1197. imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, sceneNum);
  1198. if(fdageData.containsKey("icon") && StringUtils.isNotEmpty(fdageData.getString("icon"))){
  1199. String ossPath = ConstantFilePath.OSS_PREFIX + newDataSource.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
  1200. .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
  1201. fYunFileService.copyFileInBucket(ossPath + File.separator + fdageData.getString("icon"),imgViewPath + fdageData.getString("icon"));
  1202. icon = fYunFileConfig.getHost() + imgViewPath + fdageData.getString("icon");
  1203. }
  1204. buildScenePost(newDataSource, fdageData, "V3", cameraType, sceneNum, detailEntity, 0, icon);
  1205. if (cameraType == 14) {
  1206. // 通知激光系统
  1207. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(sceneNum);
  1208. String userName = null;
  1209. if (!ObjectUtils.isEmpty(detailEntity.getUserId())) {
  1210. userName = userService.getSSOUserByUserId(detailEntity.getUserId()).getUserName();
  1211. }
  1212. fdkkLaserService.saveScene(scenePlus, fdageData.getString("pwd"), cameraEntity, userName, false);
  1213. }
  1214. break;
  1215. }
  1216. }catch (Exception e){
  1217. log.error("复制场景异常", e);
  1218. }
  1219. }, executor).whenComplete((reslut, e) -> {
  1220. log.info("复制场景souceDataSource:{},newDataSource:{}结束-{}",dataSource,newDataSource, new Date());
  1221. });
  1222. }catch (Exception e){
  1223. log.error("线程错误:{}",e);
  1224. }finally {
  1225. executor.shutdown();
  1226. }
  1227. Map<String,Object> result = new HashMap<>();
  1228. result.put("code",sceneNum);
  1229. result.put("newDataSource",newDataSource);
  1230. return ResultData.ok(result);
  1231. }
  1232. private void buildV3Scene2(String dataSource,JSONObject jsonObject,long cameraType,String sceneNum,Camera cameraEntity,CameraDetail detailEntity,String icon) throws Exception {
  1233. String cameraName = jsonObject.getJSONObject("cam").getString("uuid");
  1234. log.info("查询相机:" + cameraName);
  1235. String userName = null;
  1236. if(detailEntity.getUserId() != null){
  1237. SSOUser user = userService.getSSOUserByUserId(detailEntity.getUserId());
  1238. userName = user.getUserName();
  1239. }
  1240. JSONObject firmwareVersion = new JSONObject();
  1241. if(jsonObject.containsKey("camSoftwareVersion") && StringUtils.isNotEmpty(jsonObject.getString("camSoftwareVersion"))){
  1242. firmwareVersion.put("camSoftwareVersion", jsonObject.getString("camSoftwareVersion"));
  1243. }
  1244. if(jsonObject.containsKey("version") && StringUtils.isNotEmpty(jsonObject.getString("version"))){
  1245. firmwareVersion.put("version", jsonObject.getString("version"));
  1246. }
  1247. String buildType = "V3";
  1248. String sceneUrl = mainUrl + "/" + sceneProNewUrl;
  1249. boolean isObj = jsonObject.containsKey("exportMeshObj") && jsonObject.getIntValue("exportMeshObj") == 1;
  1250. ScenePro scenePro = createScenePro(sceneNum, detailEntity.getCameraId(), jsonObject.getString("creator"),
  1251. jsonObject.getString("pwd"),
  1252. cameraType, dataSource, "", icon, detailEntity.getUserId(), userName,
  1253. jsonObject.getString("location") != null && "1".equals(jsonObject.getString("location")) ? "sfm" : "slam",
  1254. jsonObject.getJSONArray("points").size(), jsonObject.getString("name"), jsonObject.getString("info"),
  1255. jsonObject.getInteger("scenetype"), jsonObject.getString("gps"), 0,
  1256. jsonObject.getInteger("resolution"), firmwareVersion.toString(), sceneUrl, buildType,
  1257. detailEntity.getCooperationUser(), isObj);
  1258. // 通知激光场景系统开始构建场景
  1259. if(cameraType == 14){
  1260. scenePro.setStatus(0);
  1261. fdkkLaserService.saveScene(scenePro, jsonObject.getString("pwd"), cameraEntity, userName, false);
  1262. }
  1263. BuildSceneCallMessage buildSceneMqMessage = this.getBuildSceneMqMessage(
  1264. sceneNum, cameraType, jsonObject.getString("location") != null && "1".equals(jsonObject.getString("location")) ? "sfm" : "slam",
  1265. jsonObject.getInteger("resolution"), buildType, dataSource);
  1266. rabbitMqProducer.sendByWorkQueue(queueV3ModelingPre, buildSceneMqMessage);
  1267. }
  1268. public ScenePro createScenePro(String projectNum, Long cameraId, String phoneId, String sceneKey,
  1269. Long cameraType, String dataSource, String imgsName,
  1270. String pic, Long userId, String userName, String algorithm,
  1271. Integer sceneShootCount, String sceneName, String sceneDec, Integer sceneType,
  1272. String gps, Integer type, Integer resolution, String firmwareVersion, String url,
  1273. String buildType, Long cooperationUser,Boolean isObj) throws Exception {
  1274. ScenePro scene;
  1275. SceneProEdit sceneEdit;
  1276. if (type == 0) {
  1277. scene = new ScenePro();
  1278. sceneEdit = new SceneProEdit();
  1279. } else {
  1280. scene = sceneProService.getByNum(projectNum);
  1281. sceneEdit = sceneProEditService.getByProId(scene.getId());
  1282. }
  1283. //先返回链接地址
  1284. scene.setWebSite(url + projectNum);
  1285. scene.setCameraId(cameraId);
  1286. scene.setPhoneId(phoneId);
  1287. scene.setNum(projectNum);
  1288. scene.setSceneSource(1);
  1289. scene.setDataSource(dataSource);
  1290. if (cameraType.longValue() == 5 || cameraType.longValue() == 6) {
  1291. //场景来源双目相机
  1292. scene.setSceneSource(2);
  1293. }
  1294. if (resolution == null || resolution.intValue() == 0) {
  1295. scene.setSceneScheme(cameraType.intValue());
  1296. } else {
  1297. scene.setSceneScheme(4);
  1298. }
  1299. //场景来源双目相机,sceneScheme为4,加载high,low图
  1300. if (cameraType.longValue() == 5 || cameraType.longValue() == 6) {
  1301. scene.setSceneScheme(4);
  1302. }
  1303. //转台相机用4k图
  1304. if (cameraType.longValue() == 13) {
  1305. scene.setSceneSource(3);
  1306. scene.setSceneScheme(10);
  1307. }
  1308. //激光相机
  1309. if (cameraType.longValue() == 14) {
  1310. scene.setSceneSource(4);
  1311. scene.setSceneScheme(10);
  1312. }
  1313. if (pic != null && pic.length() > 5) {
  1314. scene.setThumb(pic);
  1315. } else {
  1316. scene.setThumb(ConstantUrl.DEFAULT_SCENE_PIC);
  1317. }
  1318. scene.setThumb(scene.getThumb().concat("?t=") + System.currentTimeMillis());
  1319. if (!ObjectUtils.isEmpty(userName)) {
  1320. scene.setUserId(userId);
  1321. }
  1322. if (sceneShootCount == null) {
  1323. scene.setShootCount(0);
  1324. } else {
  1325. scene.setShootCount(sceneShootCount);
  1326. }
  1327. if (sceneName != null) {
  1328. scene.setSceneName(sceneName);
  1329. }
  1330. if (sceneDec != null) {
  1331. scene.setSceneDec("<p>" + new String(sceneDec.getBytes("UTF-8")) + "</p>");
  1332. }
  1333. if (sceneType != null) {
  1334. scene.setSceneType(sceneType);
  1335. }
  1336. if (gps != null && !gps.trim().equals("")) {
  1337. scene.setGps(gps);
  1338. }
  1339. scene.setAlgorithm(algorithm);
  1340. scene.setFilesName(imgsName);
  1341. if (!org.springframework.util.StringUtils.isEmpty(firmwareVersion)) {
  1342. scene.setFirmwareVersion(firmwareVersion);
  1343. }
  1344. scene.setBuildType(buildType);
  1345. log.info("场景记录添加到数据库:" + projectNum);
  1346. //type=0为新生成场景,其余为重新计算场景
  1347. if (type == 0) {
  1348. scene.setIsObj(ObjectUtils.isEmpty(isObj) || !isObj ? 0 : 1);
  1349. sceneProService.save(scene);
  1350. sceneEdit = new SceneProEdit();
  1351. sceneEdit.setNeedKey(0);
  1352. if (sceneKey == null) {
  1353. sceneKey = "";
  1354. }
  1355. sceneEdit.setSceneKey(sceneKey);
  1356. if (!sceneKey.equals("")) {
  1357. sceneEdit.setNeedKey(1);
  1358. } else {
  1359. sceneEdit.setNeedKey(0);
  1360. }
  1361. sceneEdit.setProId(scene.getId());
  1362. sceneEdit.setMapVisi(1);
  1363. sceneEdit.setTourVisi(1);
  1364. sceneEdit.setVrVisi(1);
  1365. sceneEdit.setRulerVisi(0);
  1366. sceneEdit.setCadImgVisi(1);
  1367. sceneEdit.setPanoVisi(1);
  1368. sceneEdit.setM2dVisi(1);
  1369. sceneEdit.setM3dVisi(1);
  1370. sceneEdit.setMeasureVisi(0);
  1371. sceneEdit.setFloorLogoSize(100);
  1372. sceneEdit.setCreateTime(new Date());
  1373. sceneProEditService.save(sceneEdit);
  1374. //新增场景时,同时新增场景协作信息
  1375. if (cooperationUser != null) {
  1376. SceneCooperation sceneCooperationEntity = new SceneCooperation();
  1377. sceneCooperationEntity.setNum(projectNum);
  1378. sceneCooperationEntity.setUserId(cooperationUser);
  1379. sceneCooperationService.save(sceneCooperationEntity);
  1380. List<SceneResourceCamera> resourceCameraList = sceneResourceCameraService.findListByCameraId(cameraId);
  1381. SceneResourceCooperation sceneResourceCooperationEntity = null;
  1382. if (resourceCameraList != null && resourceCameraList.size() > 0) {
  1383. for (SceneResourceCamera sceneResourceCameraEntity : resourceCameraList) {
  1384. sceneResourceCooperationEntity = new SceneResourceCooperation();
  1385. sceneResourceCooperationEntity.setSceneResourceId(sceneResourceCameraEntity.getSceneResourceId());
  1386. sceneResourceCooperationEntity.setSceneCooperationId(sceneCooperationEntity.getId());
  1387. sceneResourceCooperationService.save(sceneResourceCooperationEntity);
  1388. }
  1389. }
  1390. }
  1391. } else {
  1392. scene.setStatus(0);
  1393. scene.setPayStatus(0);
  1394. scene.setRecStatus("A");
  1395. scene.setCreateTime(new Date());
  1396. if (sceneName != null) {
  1397. scene.setSceneName(sceneName);
  1398. }
  1399. if (sceneType != null) {
  1400. scene.setSceneType(sceneType);
  1401. }
  1402. sceneProService.updateById(scene);
  1403. sceneEdit.setNeedKey(0);
  1404. if (cameraType.longValue() != 14 && !ObjectUtils.isEmpty(sceneKey)) {
  1405. sceneEdit.setNeedKey(1);
  1406. sceneEdit.setSceneKey(sceneKey);
  1407. }
  1408. sceneEdit.setProId(scene.getId());
  1409. sceneEdit.setMapVisi(1);
  1410. sceneEdit.setTourVisi(1);
  1411. sceneEdit.setVrVisi(1);
  1412. sceneEdit.setCadImgVisi(1);
  1413. sceneEdit.setPanoVisi(1);
  1414. sceneEdit.setOverlay(null);
  1415. sceneEdit.setM2dVisi(1);
  1416. sceneEdit.setPlayData(null);
  1417. sceneEdit.setFloorLogo("0");
  1418. sceneEdit.setM3dVisi(1);
  1419. sceneEdit.setJumpScene(false);
  1420. sceneEdit.setMeasureVisi(0);
  1421. sceneEdit.setFloorLogoSize(100);
  1422. sceneEdit.setUpdateTime(new Date());
  1423. sceneEdit.setRecStatus("A");
  1424. sceneEdit.setFloorPublishVer(sceneEdit.getFloorEditVer() + 1);
  1425. sceneEdit.setFloorEditVer(sceneEdit.getFloorEditVer() + 1);
  1426. sceneEdit.setVersion(sceneEdit.getVersion() + 1);
  1427. sceneEdit.setImagesVersion(sceneEdit.getImagesVersion() + 1);
  1428. sceneProEditService.updateById(sceneEdit);
  1429. }
  1430. JSONObject scenejson = JSONObject.parseObject(JSONObject.toJSONString(scene));
  1431. scenejson.put("thumbImg", 0);
  1432. scenejson.put("version", sceneEdit.getVersion());
  1433. scenejson.put("floorLogo", 0);
  1434. if (!ObjectUtils.isEmpty(sceneKey)) {
  1435. scenejson.put("sceneKey", sceneKey);
  1436. scenejson.put("public", 1);
  1437. } else {
  1438. scenejson.put("sceneKey", "");
  1439. scenejson.put("public", 0);
  1440. }
  1441. if (cameraType.longValue() < 4 || cameraType.longValue() == 5 || cameraType.longValue() == 6) {
  1442. scenejson.put("visions", 1);
  1443. } else {
  1444. scenejson.put("visions", 2);
  1445. }
  1446. scenejson.put("createTime", new DateTime(new Date()).toString("yyyy-MM-dd HH:mm"));
  1447. scenejson.put("floorPublishVer", sceneEdit.getFloorPublishVer());
  1448. scenejson.put("floorEditVer", sceneEdit.getFloorEditVer());
  1449. scenejson.put("rulerVisi", sceneEdit.getRulerVisi());
  1450. scenejson.put("entry", null);
  1451. if (!org.springframework.util.StringUtils.isEmpty(sceneEdit.getHotsIds())) {
  1452. scenejson.put("hots", 1);
  1453. }
  1454. File file = new File(ConstantFilePath.SCENE_PATH + "data/data" + projectNum);
  1455. if (!file.exists() || !file.isDirectory()) {
  1456. file.mkdirs();
  1457. }
  1458. FileUtils.writeFile(ConstantFilePath.SCENE_PATH + "data/data" + projectNum + File.separator + "scene.json", scenejson.toString());
  1459. return scene;
  1460. }
  1461. private ResultData rebuildV3SceneToMini(ScenePro scenePro){
  1462. log.info("v3场景重算,请求v3服务器,url:{}",v3controlUrl+"api/scene/rebuildScene?num=" + scenePro.getNum());
  1463. ResponseEntity<Result> responseEntity = restTemplate.getForEntity(v3controlUrl+"api/scene/rebuildScene?num=" + scenePro.getNum(), Result.class);
  1464. if (responseEntity.getStatusCode().value() != HttpStatus.OK.value() || responseEntity.getBody().getCode() != ServerCode.SUCCESS.code()) {
  1465. log.error("请求V3服务器重算场景失败, num:{}, result:{}",scenePro.getNum(), JSON.toJSONString(responseEntity));
  1466. throw new BusinessException(ErrorCode.SYSTEM_BUSY);
  1467. }
  1468. log.info("v3场景重算,请求v3服务器,url:{}, result",v3controlUrl+"api/scene/rebuildScene?num=" + scenePro.getNum(), JSON.toJSONString(responseEntity));
  1469. return ResultData.ok();
  1470. }
  1471. }