CaseDownService.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. package com.fdkankan.fusion.down;
  2. import cn.hutool.core.io.FileUtil;
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONArray;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.deepoove.poi.XWPFTemplate;
  7. import com.fdkankan.fusion.common.FilePath;
  8. import com.fdkankan.fusion.common.ResultCode;
  9. import com.fdkankan.fusion.common.ResultData;
  10. import com.fdkankan.fusion.common.util.DateUtils;
  11. import com.fdkankan.fusion.common.util.ShellUtil;
  12. import com.fdkankan.fusion.common.util.UploadToOssUtil;
  13. import com.fdkankan.fusion.config.CacheUtil;
  14. import com.fdkankan.fusion.entity.*;
  15. import com.fdkankan.fusion.exception.BusinessException;
  16. import com.fdkankan.fusion.httpClient.LaserService;
  17. import com.fdkankan.fusion.httpClient.response.FdkkResponse;
  18. import com.fdkankan.fusion.request.CaseParam;
  19. import com.fdkankan.fusion.response.*;
  20. import com.fdkankan.fusion.service.*;
  21. import com.fdkankan.fusion.service.impl.DownService;
  22. import com.fdkankan.redis.util.RedisUtil;
  23. import lombok.extern.slf4j.Slf4j;
  24. import org.apache.commons.lang3.StringUtils;
  25. import org.springframework.beans.factory.annotation.Autowired;
  26. import org.springframework.beans.factory.annotation.Value;
  27. import org.springframework.scheduling.annotation.Async;
  28. import org.springframework.stereotype.Service;
  29. import java.io.File;
  30. import java.io.FileOutputStream;
  31. import java.net.URLDecoder;
  32. import java.net.URLEncoder;
  33. import java.nio.charset.StandardCharsets;
  34. import java.util.HashMap;
  35. import java.util.HashSet;
  36. import java.util.List;
  37. @Service
  38. @Slf4j
  39. public class CaseDownService {
  40. @Value("${server.servlet.context-path}")
  41. String basePath;
  42. public static String jsonDataName = "data.json";
  43. public static String caseInfoUrl = "/case/getInfo?caseId=";
  44. public static String caseFilesTypeTreeUrl = "/caseFilesType/getByTree?caseId=";
  45. public static String sceneListUrl = "/case/sceneList?caseId=";
  46. public static String caseImgListUrl = "/caseImg/getFfmpegImage?caseId=";
  47. public static String caseFileOtherUrl = "/caseFiles/allList?caseId=%s&filesTypeId=6";
  48. public static String caseVideoFolderUrl = "/caseVideoFolder/allList?caseId=";
  49. public static String caseFilesInfoUrl = "/fusion/caseFiles/info?filesId=";
  50. public static String fusionAndSceneTypeSceneUrl = "/case/getFusionAndScene?caseId=%s&type=scene";
  51. public static String fusionAndSceneTypeFusionUrl = "/case/getFusionAndScene?caseId=%s&type=fusion";
  52. public static String systemSettingListUrl = "/systemSetting/list";
  53. public static String laserData = "/laser/dataset/%s/getDataSet";
  54. public static String laserDataSetAndControlPoint = "/laser/4dage/%s/getDataSetAndControlPoint";
  55. public static String laserDataQuery = "/laser/filter/%s/query?datasetId=%s";
  56. @Autowired
  57. ICaseService caseService;
  58. @Autowired
  59. ICaseFilesTypeService caseFilesTypeService;
  60. @Autowired
  61. LaserService laserService;
  62. @Autowired
  63. FusionDownService fusionDownService;
  64. @Autowired
  65. IMapConfigService mapConfigService;
  66. @Autowired
  67. ICaseImgService caseImgService;
  68. @Autowired
  69. ICaseFilesService caseFilesService;
  70. @Autowired
  71. ICaseVideoFolderService caseVideoFolderService;
  72. @Autowired
  73. ISystemSettingService systemSettingService;
  74. @Autowired
  75. RedisUtil redisUtil;
  76. @Value("${spring.profiles.active}")
  77. private String environment;
  78. public static String downProcessKey = "fusion:down:offline:process:caseId:%s";
  79. public DownVo checkDown(Integer caseId) {
  80. DownVo downVo = new DownVo();
  81. // CaseOffline byCaseId = caseOfflineService.getByCaseId(caseId);
  82. // if(byCaseId != null){
  83. // downVo.setDownloadStatus(3);
  84. // downVo.setDownloadUrl(byCaseId.getOfflineUrl());
  85. // }
  86. return downVo;
  87. }
  88. @Async
  89. public void downOffline(Integer caseId,String fromRoute){
  90. String caseOffPath = null;
  91. String zipName = null;
  92. try {
  93. String redisKey = String.format(downProcessKey, caseId);
  94. if( redisUtil.hasKey(redisKey)){
  95. String res = redisUtil.get(redisKey);
  96. DownloadProcessVo downloadProcessVo = JSONObject.parseObject(res, DownloadProcessVo.class);
  97. if(downloadProcessVo.getStatus() != 1003 && (downloadProcessVo.getPercent()== null || downloadProcessVo.getPercent() != 100)){
  98. return;
  99. }
  100. }
  101. String timeKey = DateUtils.dateStr();
  102. caseOffPath =FilePath.OFFLINE_PACKAGE_PATH_CASE+timeKey+caseId ;
  103. setRedisProcess(caseId,0);
  104. //复制前端资源
  105. cpIndexHtml(caseId,caseOffPath,fromRoute);
  106. setRedisProcess(caseId,10);
  107. //创建data.json并下载资源
  108. createDataJson(caseId,caseOffPath+"/www");
  109. setRedisProcess(caseId,50);
  110. //打包zip
  111. zipName = caseOffPath+".zip";
  112. ShellUtil.zip(zipName,caseOffPath);
  113. setRedisProcess(caseId,70);
  114. //上传oss
  115. String ossUrl = zipName.replace("/mnt/fusion", "fusion/"+CacheUtil.environment);
  116. ShellUtil.yunUpload(zipName,ossUrl);
  117. ossUrl = queryPath + ossUrl;
  118. setRedisProcess(caseId,100,ossUrl);
  119. }catch (Exception e){
  120. setRedisProcess(caseId,0,null,1003);
  121. log.info("down-offline-error:{}",caseId,e);
  122. }finally {
  123. delFile(caseOffPath);
  124. delFile(zipName);
  125. }
  126. }
  127. private void delFile(String path){
  128. if(StringUtils.isNotBlank(path)){
  129. try {
  130. Thread.sleep(2000L);
  131. FileUtil.del(path);
  132. }catch (Exception e){
  133. log.info("删除文件失败:{}",path);
  134. }
  135. }
  136. }
  137. public void setRedisProcess(Integer caseId,Integer num){
  138. setRedisProcess(caseId,num,null,1000);
  139. }
  140. public void setRedisProcess(Integer caseId,Integer num,String url){
  141. setRedisProcess(caseId,num,url,1000);
  142. }
  143. public void setRedisProcess(Integer caseId,Integer num,String url,Integer status){
  144. String redisKey = String.format(downProcessKey, caseId);
  145. log.info("down-offline-process:{},{},{}",caseId,num,url);
  146. DownloadProcessVo processVo = new DownloadProcessVo();
  147. processVo.setStatus(status);
  148. processVo.setPercent(num);
  149. processVo.setUrl( url);
  150. redisUtil.set(redisKey,JSONObject.toJSONString(processVo));
  151. }
  152. public DownloadProcessVo process(Integer caseId) {
  153. DownloadProcessVo downVo = new DownloadProcessVo();
  154. String redisKey = String.format(downProcessKey, caseId);
  155. if(redisUtil.hasKey(redisKey)){
  156. return JSONObject.parseObject(redisUtil.get(redisKey),DownloadProcessVo.class);
  157. }
  158. return downVo;
  159. }
  160. public void createDataJson(Integer caseId,String casePath){
  161. log.info("down-offline-createDataJson:{}",caseId);
  162. JSONObject jsonObject = new JSONObject();
  163. //设置案件信息
  164. jsonObject.put(basePath+caseInfoUrl+caseId, ResultData.ok(caseService.getInfo(caseId,false)));
  165. List<CaseFilesTypeTreeVo> byTree = caseFilesTypeService.getByTree(caseId);
  166. for (CaseFilesTypeTreeVo caseFilesTypeTreeVo : byTree) {
  167. downTreeResource(caseFilesTypeTreeVo,casePath,jsonObject);
  168. }
  169. jsonObject.put(basePath+caseFilesTypeTreeUrl+caseId, ResultData.ok(byTree));
  170. List<CaseImg> caseImgList = caseImgService.getByCaseId(caseId, 1);
  171. for (CaseImg caseImg : caseImgList) {
  172. downResource(caseImg.getImgUrl(),casePath);
  173. }
  174. jsonObject.put(basePath+caseImgListUrl+caseId, ResultData.ok(caseImgList));
  175. List<CaseFiles> files = caseFilesService.allList(caseId, 6);
  176. for (CaseFiles file : files) {
  177. //downResource(file.getFilesUrl(),casePath);
  178. downCaseFiles(file,casePath);
  179. }
  180. jsonObject.put(basePath+String.format(caseFileOtherUrl,caseId), ResultData.ok(files));
  181. List<CaseVideoFolder> allList = caseVideoFolderService.getAllList(caseId);
  182. for (CaseVideoFolder caseVideoFolder : allList) {
  183. downResource(caseVideoFolder.getVideoFolderCover(),casePath);
  184. downResource(caseVideoFolder.getVideoMergeUrl(),casePath);
  185. }
  186. jsonObject.put(basePath+caseVideoFolderUrl+caseId, ResultData.ok(allList));
  187. jsonObject.put(basePath+systemSettingListUrl, ResultData.ok(systemSettingService.list()));
  188. CaseParam param = new CaseParam();
  189. param.setCaseId(caseId);
  190. jsonObject.put(basePath+sceneListUrl+caseId, ResultData.ok(caseService.sceneList(param)));
  191. List<FusionAndSceneVo> sceneList = caseService.getFusionAndScene(caseId, "scene");
  192. jsonObject.put(basePath+String.format(fusionAndSceneTypeSceneUrl,caseId), ResultData.ok(sceneList));
  193. List<FusionAndSceneVo> fusionList = caseService.getFusionAndScene(caseId, "fusion");
  194. jsonObject.put(basePath+String.format(fusionAndSceneTypeFusionUrl,caseId), ResultData.ok(fusionList));
  195. for (FusionAndSceneVo fusionAndSceneVo : sceneList) {
  196. //下载场景
  197. downSwkk(casePath,fusionAndSceneVo.getNum(),fusionAndSceneVo.getSceneType());
  198. if(fusionAndSceneVo.getSceneType() == 2 || fusionAndSceneVo.getSceneType() == 5){
  199. FdkkResponse sceneInfo = laserService.getSceneInfo(fusionAndSceneVo.getNum());
  200. HashSet<String> dataSetIds = new HashSet<>();
  201. if(sceneInfo != null){
  202. JSONArray jsonArray = JSONArray.parseArray(JSONArray.toJSONString(sceneInfo.getData()));
  203. JSONArray newJsonArray = new JSONArray();
  204. for (Object object : jsonArray) {
  205. JSONObject sceneInfoObj = (JSONObject) object;
  206. String newPath = String.format(FilePath.OFFLINE_LASER_OSS_PATH, fusionAndSceneVo.getNum(), fusionAndSceneVo.getNum());
  207. String oldPath = sceneInfoObj.getString("webBin");
  208. sceneInfoObj.put("oldWebBin",oldPath);
  209. sceneInfoObj.put("webBin",newPath + oldPath);
  210. newJsonArray.add(sceneInfoObj);
  211. dataSetIds.add( sceneInfoObj.getString("id"));
  212. }
  213. sceneInfo.setData(newJsonArray);
  214. jsonObject.put(String.format(laserData,fusionAndSceneVo.getNum()),sceneInfo);
  215. if(!dataSetIds.isEmpty()){
  216. for (String dataSetId : dataSetIds) {
  217. FdkkResponse sceneInfo2 = laserService.getSceneInfoQuery(fusionAndSceneVo.getNum(),dataSetId);
  218. jsonObject.put(String.format(laserDataQuery,fusionAndSceneVo.getNum(),dataSetId),sceneInfo2);
  219. }
  220. }
  221. }
  222. FdkkResponse dataSetAndControlPoint = laserService.getDataSetAndControlPoint(fusionAndSceneVo.getNum());
  223. if(dataSetAndControlPoint !=null){
  224. jsonObject.put(String.format(laserDataSetAndControlPoint,fusionAndSceneVo.getNum()),dataSetAndControlPoint);
  225. }
  226. }
  227. }
  228. for (FusionAndSceneVo fusionAndSceneVo : fusionList) {
  229. downFusion(casePath,fusionAndSceneVo.getFusionId());
  230. }
  231. String jsonString = JSON.toJSONString(jsonObject);
  232. FileUtil.writeString(jsonString, casePath+"/package/"+jsonDataName,"UTF-8");
  233. }
  234. private void downTreeResource(CaseFilesTypeTreeVo caseFilesTypeTreeVo,String casePath,JSONObject jsonObject) {
  235. if(caseFilesTypeTreeVo.getCaseFilesList() != null && !caseFilesTypeTreeVo.getCaseFilesList().isEmpty()){
  236. for (CaseFiles caseFiles : caseFilesTypeTreeVo.getCaseFilesList()) {
  237. downCaseFiles(caseFiles,casePath);
  238. CaseFiles info = caseFilesService.info(caseFiles.getFilesId());
  239. jsonObject.put(basePath+caseFilesInfoUrl+caseFiles.getFilesId(), ResultData.ok(info));
  240. }
  241. }
  242. if(caseFilesTypeTreeVo.getChildrenList() != null && !caseFilesTypeTreeVo.getChildrenList().isEmpty()){
  243. List<CaseFilesTypeTreeVo> childrenList = caseFilesTypeTreeVo.getChildrenList();
  244. for (CaseFilesTypeTreeVo filesTypeTreeVo : childrenList) {
  245. downTreeResource(filesTypeTreeVo,casePath,jsonObject);
  246. }
  247. }
  248. }
  249. //http://127.0.0.1:8080/offline.html?caseId=362&app=1&share=1#/show/summary
  250. static String batName = "start-browser.bat";
  251. public void cpIndexHtml(Integer caseId,String casePath,String fromRoute){
  252. log.info("down-offline-cpIndexHtml:{}",caseId);
  253. FileUtil.copyContent(new File(FilePath.OFFLINE_TEMPLATE_PATH_CASE),new File(casePath),true);
  254. String s = FileUtil.readString(casePath + File.separator + batName, StandardCharsets.UTF_8);
  255. String s1 = s.replaceAll("@caseId", String.valueOf(caseId));
  256. if(StringUtils.isBlank(fromRoute)){
  257. fromRoute = "fire";
  258. }
  259. s1 = s1.replaceAll("@fromRoute", fromRoute);
  260. FileUtil.writeString(s1, casePath + File.separator + batName,"UTF-8");
  261. }
  262. @Autowired
  263. DownService downService;
  264. @Autowired
  265. UploadToOssUtil uploadToOssUtil;
  266. private void downFusion(String casePath,Integer fusionId) {
  267. String path = casePath +"/fusion_offline/"+fusionId;
  268. try {
  269. log.info("下载多元融合:{},{}",casePath,fusionId);
  270. fusionDownService.downOffline(fusionId,path,null);
  271. }catch (Exception e){
  272. log.info("下载多元融合失败:{}",fusionId,e);
  273. throw new BusinessException(ResultCode.SCENE_DOWN_ERROR);
  274. }
  275. }
  276. public void downSwkk(String path,String num,Integer type){
  277. String swkkPath = path + "/swkk/"+num;
  278. String swkkZipPath = swkkPath +".zip";
  279. String swssPath = path + "/swss/"+num;
  280. String swssZipPath = swssPath +".zip";
  281. Integer isObj = 0;
  282. if(type == 4 || type == 6){
  283. isObj =1;
  284. }
  285. try {
  286. DownVo downVo = downService.checkDownLoad(num, isObj,"offline");
  287. log.info("down:{}",downVo);
  288. if(downVo.getDownloadStatus() == 3 && StringUtils.isNotBlank(downVo.getDownloadUrl())){
  289. downZip(type,downVo.getDownloadUrl(),swkkZipPath,swkkPath,swssZipPath,swssPath);
  290. }else {
  291. DownVo down = downService.down(num, isObj,"offline");
  292. if(down.getDownloadStatus() == 1){
  293. DownloadProcessVo downloadProcessVo = downService.downloadProcess(num, isObj);
  294. while (downloadProcessVo.getStatus() == 1000 || downloadProcessVo.getStatus() == 1001 ){
  295. downloadProcessVo = downService.downloadProcess(num, isObj);
  296. Thread.sleep(2000L);
  297. }
  298. if(downloadProcessVo.getStatus() == 1003 && StringUtils.isBlank(downVo.getDownloadUrl())){
  299. throw new BusinessException(ResultCode.SCENE_DOWN_ERROR);
  300. }
  301. downZip(type,downloadProcessVo.getUrl(),swkkZipPath,swkkPath,swssZipPath,swssPath);
  302. }
  303. }
  304. }catch (Exception e){
  305. log.info("下载场景离线包失败:{}",num,e);
  306. throw new BusinessException(ResultCode.SCENE_DOWN_ERROR);
  307. }
  308. }
  309. @Value("${upload.query-path}")
  310. private String queryPath;
  311. @Value("${upload.query-path-ss}")
  312. private String ssQueryPath;
  313. public void downZip(Integer type ,String uri,String kkzipPath,String kknumPath,String sszipPath,String ssNumPath){
  314. try {
  315. if(type != 2 && type != 5){ //深时点云
  316. if(uri.contains("?")){
  317. uri = uri.split("[?]")[0];
  318. }
  319. ShellUtil.yunDownload(uri.replace(queryPath, ""), kkzipPath);
  320. ShellUtil.unZip(kkzipPath,kknumPath);
  321. FileUtil.del(kkzipPath);
  322. }else {
  323. ShellUtil.yunDownloadSs(uri.replace(ssQueryPath, ""), sszipPath);
  324. ShellUtil.unZip(sszipPath,ssNumPath);
  325. FileUtil.del(sszipPath);
  326. }
  327. }catch (Exception e){
  328. log.info("下载场景离线包失败:{}",uri,e);
  329. }
  330. }
  331. public void downModel(Integer caseId, String modelGlbUrl) {
  332. String path = String.format(FilePath.OFFLINE_OSS_PATH,caseId);
  333. JSONArray jsonArray = JSONArray.parseArray(modelGlbUrl);
  334. for (Object object : jsonArray) {
  335. String res = (String) object;
  336. log.info("下载模型:{}",res);
  337. res = res.replace(queryPath, "");
  338. if(res.contains(".json") ){
  339. res = new File(res).getParentFile().getPath();
  340. }
  341. if(!res.contains(".")){
  342. res += "/";
  343. }
  344. ShellUtil.yunDownload(res, path + "/" + res);
  345. }
  346. }
  347. public void downResources(String urls,String path) {
  348. JSONArray jsonArray = JSONArray.parseArray(urls);
  349. for (Object object : jsonArray) {
  350. String res = (String) object;
  351. downResource(res,path);
  352. }
  353. }
  354. public void downResource(String url,String path) {
  355. if(StringUtils.isBlank(url) ){
  356. return;
  357. }
  358. url = url.replace(queryPath, "");
  359. String desPath = path + "/" + url;
  360. log.info("downResource:{}",url);
  361. if(!desPath.contains(".")){
  362. ShellUtil.yunDownload(url, new File(desPath).getParentFile().getPath());
  363. return;
  364. }
  365. ShellUtil.yunDownload(url,desPath);
  366. }
  367. public void downCaseFiles(CaseFiles caseFiles,String path){
  368. if(StringUtils.isBlank(caseFiles.getFilesUrl()) ){
  369. return;
  370. }
  371. String url = caseFiles.getFilesUrl().replace(queryPath, "");
  372. String desPath = path + "/" + url;
  373. log.info("downResource:{}",url);
  374. if(!desPath.contains(".")){
  375. ShellUtil.yunDownload(url, new File(desPath).getParentFile().getPath());
  376. return;
  377. }
  378. String filePath = String.format(FilePath.File_OSS_PATH, environment, caseFiles.getFilesId() + "/");
  379. if(url.contains(filePath)){
  380. ShellUtil.yunDownload(filePath, path +"/" + filePath);
  381. return;
  382. }
  383. ShellUtil.yunDownload(url,desPath);
  384. }
  385. }