package com.fdkankan.fusion.down; import cn.hutool.core.io.FileUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.deepoove.poi.XWPFTemplate; import com.fdkankan.fusion.common.FilePath; import com.fdkankan.fusion.common.ResultData; import com.fdkankan.fusion.common.util.DateUtils; import com.fdkankan.fusion.common.util.ShellUtil; import com.fdkankan.fusion.common.util.LocalToOssUtil; import com.fdkankan.fusion.entity.*; import com.fdkankan.fusion.httpClient.LaserService; import com.fdkankan.fusion.httpClient.response.FdkkResponse; import com.fdkankan.fusion.request.CaseParam; import com.fdkankan.fusion.response.DownVo; import com.fdkankan.fusion.response.DownloadProcessVo; import com.fdkankan.fusion.response.FusionNumVo; import com.fdkankan.fusion.response.SceneVo; import com.fdkankan.fusion.service.*; import com.fdkankan.fusion.service.impl.DownService; import com.fdkankan.redis.util.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import java.io.File; import java.io.FileOutputStream; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashSet; import java.util.List; @Service @Slf4j public class CaseDownService { @Value("${server.servlet.context-path}") String basePath; public static String jsonDataName = "data.json"; public static String caseInfo = "/case/getInfo?caseId="; public static String caseSettingsInfo = "/caseSettings/info?caseId="; public static String hostIcon = "/edit/hotIcon/list?caseId="; public static String caseView = "/caseView/allList?caseId="; public static String caseFiles = "/caseFiles/allList?caseId="; public static String caseFilesType = "/caseFilesType/allList?caseId="; public static String caseScene = "/case/sceneList?caseId="; public static String caseFusion = "/caseFusion/list?caseId="; public static String caseVideoFolder = "/caseVideoFolder/allList?caseId="; public static String caseVideo = "/caseVideo/allList?folderId="; public static String caseTag = "/caseTag/allList?caseId="; public static String caseTagPoint = "/caseTagPoint/allList?tagId="; public static String caseInquest = "/caseInquest/info?caseId="; public static String caseExtractDetail = "/caseExtractDetail/info?caseId="; public static String fusionGuide = "/fusionGuide/allList?caseId="; public static String fusionGuidePath = "/fusionGuidePath/allList?guideId="; public static String fusionMeter = "/fusionMeter/allList?fusionId="; public static String model = "/model/getInfo?modelId="; public static String caseImg = "/caseImg/getFfmpegImage?caseId="; public static String inquestInfoUrl = "/caseInquestInfo/info?caseId="; public static String casePathInfoUrl = "/casePath/info?caseId="; public static String laserData = "/laser/dataset/%s/getDataSet"; public static String laserDataQuery = "/laser/filter/%s/query?datasetId=%s"; @Autowired ICaseService caseService; @Autowired ICaseSettingsService caseSettingsService; @Autowired IFusionNumService fusionNumService; @Autowired ICaseViewService caseViewService; @Autowired ICaseVideoFolderService caseVideoFolderService; @Autowired ICaseVideoService caseVideoService; @Autowired ICaseFilesService caseFilesService; @Autowired ICaseFilesTypeService caseFilesTypeService; @Autowired IHotIconService hotIconService; @Autowired ICaseTagService caseTagService; @Autowired ICaseTagPointService caseTagPointService; @Autowired IFusionGuideService fusionGuideService; @Autowired IFusionGuidePathService fusionGuidePathService; @Autowired ICaseInquestService caseInquestService; @Autowired ICaseExtractDetailService caseExtractDetailService; @Autowired IFusionMeterService fusionMeterService; @Autowired IModelService modelService; @Autowired LaserService laserService; @Autowired ICaseOfflineService caseOfflineService; @Autowired ICaseImgService caseImgService; @Autowired ICaseInquestInfoService caseInquestInfoService; @Autowired ICasePathService casePathService; @Autowired RedisUtil redisUtil; @Value("${spring.profiles.active}") private String environment; public static String downProcessKey = "fusion:down:offline:process:caseId:%s"; public DownVo checkDown(Integer caseId) { DownVo downVo = new DownVo(); // CaseOffline byCaseId = caseOfflineService.getByCaseId(caseId); // if(byCaseId != null){ // downVo.setDownloadStatus(3); // downVo.setDownloadUrl(byCaseId.getOfflineUrl()); // } return downVo; } @Async public void downOffline(Integer caseId,String zipPath){ String timeKey = DateUtils.dateStr(); String caseOffPath = FilePath.OFFLINE_PACKAGE_PATH+timeKey + caseId; try { String redisKey = String.format(downProcessKey, caseId); if( redisUtil.hasKey(redisKey)){ String res = redisUtil.get(redisKey); DownloadProcessVo downloadProcessVo = JSONObject.parseObject(res, DownloadProcessVo.class); if(downloadProcessVo.getStatus() != 1003 && (downloadProcessVo.getPercent()== null || downloadProcessVo.getPercent() != 100)){ return; } } setRedisProcess(caseId,0); //复制前端资源 cpIndexHtml(caseId,caseOffPath); setRedisProcess(caseId,10); //创建data.json并下载资源 createDataJson(caseId,caseOffPath); setRedisProcess(caseId,50); //打包zip FileUtil.copyContent(new File(caseOffPath),new File(zipPath),true); caseOfflineService.saveByCase(caseId,zipPath); setRedisProcess(caseId,100,zipPath); }catch (Exception e){ log.info("down-offline-error:{}",caseId,e); setRedisProcess(caseId,0,null,1003); }finally { try { Thread.sleep(2000L); FileUtil.del(caseOffPath); setRedisProcess(caseId,0,null,1003); }catch (Exception e){ log.info("down-offline-del-error:{}",caseId,e); } } } public void setRedisProcess(Integer caseId,Integer num){ setRedisProcess(caseId,num,null,1000); } public void setRedisProcess(Integer caseId,Integer num,String url){ setRedisProcess(caseId,num,url,1000); } public void setRedisProcess(Integer caseId,Integer num,String url,Integer status){ String redisKey = String.format(downProcessKey, caseId); log.info("down-offline-process:{},{},{}",caseId,num,url); DownloadProcessVo processVo = new DownloadProcessVo(); processVo.setStatus(status); processVo.setPercent(num); processVo.setUrl( url); redisUtil.set(redisKey,JSONObject.toJSONString(processVo)); } public DownloadProcessVo process(Integer caseId) { DownloadProcessVo downVo = new DownloadProcessVo(); String redisKey = String.format(downProcessKey, caseId); if(redisUtil.hasKey(redisKey)){ return JSONObject.parseObject(redisUtil.get(redisKey),DownloadProcessVo.class); } return downVo; } public void createDataJson(Integer caseId,String caseOffPath){ log.info("down-offline-createDataJson:{}",caseOffPath); JSONObject jsonObject = new JSONObject(); CaseParam param = new CaseParam(); param.setCaseId(caseId); //设置案件信息 jsonObject.put(basePath+inquestInfoUrl+caseId, ResultData.ok(caseInquestInfoService.getByCaseId(caseId))); jsonObject.put(basePath+caseInfo+caseId, ResultData.ok(caseService.getInfo(caseId))); List caseSettings = caseSettingsService.getByCaseId(caseId); jsonObject.put(basePath+caseSettingsInfo+caseId, ResultData.ok(caseSettings)); for (CaseSettings caseSetting : caseSettings) { downResource(caseId,caseSetting.getBack(),caseOffPath); downResource(caseId,caseSetting.getCover(),caseOffPath); } List listByCaseId = fusionNumService.getListByCaseId(caseId,null); jsonObject.put(basePath+caseFusion+caseId, ResultData.ok(listByCaseId)); for (FusionNumVo fusion : listByCaseId) { jsonObject.put(basePath+fusionMeter+fusion.getFusionId(), ResultData.ok(fusionMeterService.getListByFusionId(fusion.getFusionId(),null))); } List sceneVos = caseService.sceneList(param); for (SceneVo sceneData : sceneVos) { //下载模型 if(StringUtils.isNotBlank(sceneData.getModelGlbUrl())){ downModel(caseId,sceneData.getModelGlbUrl(),caseOffPath); } if(sceneData.getType() != 3){ //下载场景离线包 downSwkk(caseId,sceneData.getNum(),sceneData.getType()); } if(sceneData.getType() == 2 || sceneData.getType() == 5){ FdkkResponse sceneInfo = laserService.getSceneInfo(sceneData.getNum()); HashSet dataSetIds = new HashSet<>(); if(sceneInfo != null){ JSONArray jsonArray = JSONArray.parseArray(JSONArray.toJSONString(sceneInfo.getData())); JSONArray newJsonArray = new JSONArray(); for (Object object : jsonArray) { JSONObject sceneInfoObj = (JSONObject) object; String newPath = String.format(FilePath.OFFLINE_LASER_OSS_PATH, sceneData.getNum(), sceneData.getNum()); String oldPath = sceneInfoObj.getString("webBin"); sceneInfoObj.put("oldWebBin",oldPath); sceneInfoObj.put("webBin",newPath + oldPath); newJsonArray.add(sceneInfoObj); dataSetIds.add( sceneInfoObj.getString("id")); } sceneInfo.setData(newJsonArray); jsonObject.put(String.format(laserData,sceneData.getNum()),sceneInfo); if(!dataSetIds.isEmpty()){ for (String dataSetId : dataSetIds) { FdkkResponse sceneInfo2 = laserService.getSceneInfoQuery(sceneData.getNum(),dataSetId); jsonObject.put(String.format(laserDataQuery,sceneData.getNum(),dataSetId),sceneInfo2); } } } } if(sceneData.getModelId() != null){ jsonObject.put(basePath+model+sceneData.getModelId(), ResultData.ok(modelService.getInfo(sceneData.getModelId()))); } } jsonObject.put(basePath+caseScene+caseId, ResultData.ok(sceneVos)); List caseViews = caseViewService.allList(caseId, null, null, null, null); jsonObject.put(basePath+caseView+caseId, ResultData.ok(caseViews)); for (CaseView view : caseViews) { downResource(caseId,view.getViewImg(),caseOffPath); downResource(caseId,view.getViewImgSmall(),caseOffPath); } List videoFolders = caseVideoFolderService.getAllList(caseId); jsonObject.put(basePath+caseVideoFolder+caseId, ResultData.ok(videoFolders)); for (CaseVideoFolder videoFolder : videoFolders) { downResource(caseId,videoFolder.getVideoFolderCover(),caseOffPath); downResource(caseId,videoFolder.getVideoMergeUrl(),caseOffPath); List allList = caseVideoService.getAllList(videoFolder.getVideoFolderId()); for (CaseVideo video : allList) { downResource(caseId,video.getVideoCover(),caseOffPath); downResource(caseId,video.getVideoPath(),caseOffPath); } jsonObject.put(basePath+caseVideo+videoFolder.getVideoFolderId(), ResultData.ok(allList)); } List caseFilesList = caseFilesService.allList(caseId, null); for (CaseFiles files : caseFilesList) { downResource(caseId,files.getFilesUrl(),caseOffPath); } jsonObject.put(basePath+caseFiles+caseId, ResultData.ok(caseFilesList)); jsonObject.put(basePath+caseFilesType+caseId, ResultData.ok(caseFilesTypeService.list())); List hotIconList = hotIconService.getListByCaseId(caseId); for (HotIcon hotIcon : hotIconList) { downResource(caseId,hotIcon.getIconUrl(),caseOffPath); } jsonObject.put(basePath+hostIcon+caseId, ResultData.ok(hotIconList)); List caseTagList = caseTagService.allList(caseId, null); jsonObject.put(basePath+caseTag+caseId, ResultData.ok(caseTagList)); for (CaseTag tag : caseTagList) { jsonObject.put(basePath+caseTagPoint+tag.getTagId(), ResultData.ok(caseTagPointService.allList(tag.getTagId()))); downResources(caseId,tag.getTagImgUrl(),caseOffPath); downResource(caseId,tag.getHotIconUrl(),caseOffPath); } jsonObject.put(basePath+casePathInfoUrl+caseId, ResultData.ok(casePathService.getByCaseId(caseId))); List fusionGuides = fusionGuideService.getAllList(caseId); jsonObject.put(basePath+fusionGuide+caseId, ResultData.ok(fusionGuides)); for (FusionGuide guide : fusionGuides) { downResource(caseId,guide.getCover(),caseOffPath); List listByGuideId = fusionGuidePathService.getListByGuideId(guide.getFusionGuideId()); for (FusionGuidePath guidePath : listByGuideId) { downResource(caseId,guidePath.getCover(),caseOffPath); } jsonObject.put(basePath+fusionGuidePath+guide.getFusionGuideId(), ResultData.ok(listByGuideId)); } CaseInquest caseInquest1 = caseInquestService.getByCaseId(caseId); if(caseInquest1 != null){ XWPFTemplate inquestTemp = caseInquestService.getWordByTemplate(caseInquest1); downWordByTemplate(caseId,inquestTemp,"caseInquest.doc",caseOffPath); } jsonObject.put(basePath+caseInquest+caseId, ResultData.ok(caseInquest1)); CaseExtractDetail caseExtractDetail1 = caseExtractDetailService.getByCaseId(caseId); if(caseExtractDetail1 != null){ XWPFTemplate detailTemp = caseExtractDetailService.getWordByTemplate(caseExtractDetail1); downWordByTemplate(caseId,detailTemp,"caseExtractDetail.doc",caseOffPath); } jsonObject.put(basePath+caseExtractDetail+caseId, ResultData.ok(caseExtractDetail1)); List caseImgList = caseImgService.getByCaseId(caseId, 1); for (CaseImg img : caseImgList) { downResource(img.getCaseId(),img.getImgUrl(),caseOffPath); } jsonObject.put(basePath+caseImg+caseId, ResultData.ok(caseImgList)); FileUtil.writeString(JSON.toJSONString(jsonObject), caseOffPath+"/www/package/"+jsonDataName,"UTF-8"); } //http://127.0.0.1:8080/offline.html?caseId=362&app=1&share=1#/show/summary static String batName = "start-browser.bat"; public void cpIndexHtml(Integer caseId,String caseOffPath){ log.info("down-offline-cpIndexHtml:{}",caseOffPath); FileUtil.copyContent(new File(FilePath.OFFLINE_TEMPLATE_PATH),new File(caseOffPath),true); String s = FileUtil.readString(caseOffPath + File.separator + batName, StandardCharsets.UTF_8); String s1 = s.replaceAll("@caseId", String.valueOf(caseId)); FileUtil.writeString(s1, caseOffPath + File.separator + batName,"UTF-8"); } @Autowired DownService downService; @Autowired LocalToOssUtil localToOssUtil; public void downSwkk(Integer caseId,String num,Integer type){ String swkkPath = FilePath.OFFLINE_PACKAGE_PATH+caseId + "/www/swkk/"+num; String swssPath = FilePath.OFFLINE_PACKAGE_PATH+caseId + "/www/swss/"+num; Integer isObj = 0; if(type == 4 || type == 6){ isObj =1; } try { FdkkResponse fdkkResponse = laserService.sceneLocInfo(num); }catch (Exception e){ log.info("下载场景离线包失败:{}",num,e); } } @Value("${upload.query-path}") private String queryPath; public void downZip(Integer type ,String uri,String kkzipPath,String kknumPath,String sszipPath,String ssNumPath){ try { if(type != 2 && type != 5){ //深时点云 if(uri.contains("?")){ uri = uri.split("[?]")[0]; } ShellUtil.yunDownload(uri.replace(queryPath, ""), kkzipPath); ShellUtil.unZip(kkzipPath,kknumPath); FileUtil.del(kkzipPath); }else { ShellUtil.yunDownloadSs(uri.replace(queryPath, ""), sszipPath); ShellUtil.unZip(sszipPath,ssNumPath); FileUtil.del(sszipPath); } }catch (Exception e){ log.info("下载场景离线包失败:{}",uri,e); } } public void downModel(Integer caseId, String modelGlbUrl,String offPath) { String path = offPath +FilePath.OFFLINE_OSS_PATH; JSONArray jsonArray = JSONArray.parseArray(modelGlbUrl); for (Object object : jsonArray) { String res = (String) object; log.info("下载模型:{}",res); res = res.replace(queryPath, ""); if(res.contains(".json") || res.contains(".shp")){ res = new File(res).getParentFile().getPath(); } localToOssUtil.downFormAli(res,path+queryPath+res); } } public void downResources(Integer caseId,String urls,String offPath) { JSONArray jsonArray = JSONArray.parseArray(urls); for (Object object : jsonArray) { String res = (String) object; downResource(caseId,res,offPath); } } public void downResource(Integer caseId,String url,String offPath) { if(StringUtils.isBlank(url) ){ return; } url = url.replace(queryPath, ""); if( !localToOssUtil.existKey(url)){ log.info("downResource文件不存在:{},{}",caseId,url); return; } String path = offPath + FilePath.OFFLINE_OSS_PATH; localToOssUtil.downFormAli(url,path+queryPath+url); } public void downWordByTemplate(Integer caseId,XWPFTemplate template,String name,String offPath){ // 指定输出文件的路径 String outputPath = offPath +FilePath.OFFLINE_RESOURCE_PACKAGE_PATH + name; try { FileOutputStream out = new FileOutputStream(outputPath); template.write(out); out.close(); log.info("文档已成功写入到: " + outputPath); } catch (Exception e) { log.info("写出文档失败:{},{}",caseId,name,e); } } }