|
@@ -1,4 +1,11 @@
|
|
|
package com.fdkankan.scene.service.impl;
|
|
|
+import com.fdkankan.common.constant.CommonOperStatus;
|
|
|
+import com.fdkankan.common.constant.SceneAsynFuncType;
|
|
|
+import com.fdkankan.common.constant.SceneAsynModuleType;
|
|
|
+import com.fdkankan.common.constant.SceneAsynOperType;
|
|
|
+import com.fdkankan.scene.vo.SaveFiltersParamVO;
|
|
|
+import io.opencensus.metrics.LongGauge;
|
|
|
+import java.util.Date;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
@@ -44,6 +51,7 @@ import com.fdkankan.scene.bean.VertexBean;
|
|
|
import com.fdkankan.scene.bean.WallBean;
|
|
|
import com.fdkankan.scene.entity.CameraDetail;
|
|
|
import com.fdkankan.scene.entity.Company;
|
|
|
+import com.fdkankan.scene.entity.SceneAsynOperLog;
|
|
|
import com.fdkankan.scene.entity.SceneDataDownload;
|
|
|
import com.fdkankan.scene.entity.SceneEditControls;
|
|
|
import com.fdkankan.scene.entity.SceneEditInfo;
|
|
@@ -53,6 +61,7 @@ import com.fdkankan.scene.entity.ScenePlusExt;
|
|
|
import com.fdkankan.scene.mapper.ISceneEditInfoMapper;
|
|
|
import com.fdkankan.scene.service.ICameraDetailService;
|
|
|
import com.fdkankan.scene.service.ICompanyService;
|
|
|
+import com.fdkankan.scene.service.ISceneAsynOperLogService;
|
|
|
import com.fdkankan.scene.service.ISceneDataDownloadService;
|
|
|
import com.fdkankan.scene.service.ISceneEditControlsService;
|
|
|
import com.fdkankan.scene.service.ISceneEditInfoExtService;
|
|
@@ -103,6 +112,7 @@ import java.util.Map.Entry;
|
|
|
import java.util.Objects;
|
|
|
import java.util.Set;
|
|
|
import java.util.UUID;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.stream.Collectors;
|
|
|
import javax.annotation.Resource;
|
|
@@ -162,6 +172,8 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
private ICompanyService companyService;
|
|
|
@Autowired
|
|
|
private ISurveillanceService surveillanceService;
|
|
|
+ @Autowired
|
|
|
+ private ISceneAsynOperLogService sceneAsynOperLogService;
|
|
|
|
|
|
@Transactional
|
|
|
@Override
|
|
@@ -931,6 +943,27 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
if(scenePlus == null){
|
|
|
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
}
|
|
|
+
|
|
|
+ //查询是否存在等待中的异步操作记录,如果存在,直接反馈
|
|
|
+ List<SceneAsynOperLog> waittingLogList = sceneAsynOperLogService.list(
|
|
|
+ new LambdaQueryWrapper<SceneAsynOperLog>()
|
|
|
+ .eq(SceneAsynOperLog::getModule, SceneAsynModuleType.UPLOAD_DOWNLOAD.code())
|
|
|
+ .eq(SceneAsynOperLog::getFunction, SceneAsynFuncType.PANORAMIC_IMAGE.code())
|
|
|
+ .eq(SceneAsynOperLog::getState, CommonOperStatus.WAITING.code()));
|
|
|
+ if(CollUtil.isNotEmpty(waittingLogList)){
|
|
|
+ return ResultData.error(ErrorCode.FAILURE_CODE_5066);
|
|
|
+ }
|
|
|
+
|
|
|
+ //清除异步下载记录,防止再次下载的时候请求到旧的压缩包
|
|
|
+ sceneAsynOperLogService.remove(
|
|
|
+ new LambdaQueryWrapper<SceneAsynOperLog>()
|
|
|
+ .eq(SceneAsynOperLog::getNum, num)
|
|
|
+ .eq(SceneAsynOperLog::getModule, SceneAsynModuleType.UPLOAD_DOWNLOAD.code())
|
|
|
+ .eq(SceneAsynOperLog::getFunction, SceneAsynFuncType.PANORAMIC_IMAGE.code())
|
|
|
+ .eq(SceneAsynOperLog::getOperType, SceneAsynOperType.DOWNLOAD.code())
|
|
|
+ );
|
|
|
+
|
|
|
+
|
|
|
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
|
|
|
String bucket = scenePlusExt.getYunFileBucket();
|
|
|
|
|
@@ -956,7 +989,12 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
file.transferTo(targetFile);
|
|
|
|
|
|
//如果是压缩包上传,需要解压缩
|
|
|
+ int async = CommonStatus.NO.code();
|
|
|
if(file.getOriginalFilename().endsWith(".zip")){
|
|
|
+
|
|
|
+ //标记为异步处理
|
|
|
+ async = CommonStatus.YES.code();
|
|
|
+
|
|
|
//解压zip包
|
|
|
ZipUtil.unzip(zipTargetFilePath,targetImagesPath);
|
|
|
//删除压缩包
|
|
@@ -1068,6 +1106,85 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
|
|
|
}
|
|
|
fYunFileService.downloadFile(ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "") + "/data.fdage", target + File.separator + "capture/data.fdage");
|
|
|
+
|
|
|
+ if(async == CommonStatus.YES.code().intValue()){
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
+ CreateObjUtil.build3dModel(target , "1");
|
|
|
+
|
|
|
+ String uploadJsonPath= target + File.separator + "results" +File.separator+"upload.json";
|
|
|
+ Thread.sleep(2000);
|
|
|
+ boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime);
|
|
|
+ if(!exist){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
|
|
|
+ }
|
|
|
+ String uploadData = FileUtils.readFile(uploadJsonPath);
|
|
|
+ JSONObject uploadJson = null;
|
|
|
+ JSONArray array = null;
|
|
|
+ if(uploadData!=null) {
|
|
|
+ uploadJson = JSONObject.parseObject(uploadData);
|
|
|
+ array = uploadJson.getJSONArray("upload");
|
|
|
+ }
|
|
|
+ if(array == null){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
|
|
|
+ }
|
|
|
+ JSONObject fileJson = null;
|
|
|
+ String fileName = "";
|
|
|
+ for(int i = 0, len = array.size(); i < len; i++) {
|
|
|
+ fileJson = array.getJSONObject(i);
|
|
|
+ fileName = fileJson.getString("file");
|
|
|
+ //文件不存在抛出异常
|
|
|
+ if (!new File(target + File.separator + "results" + File.separator + fileName)
|
|
|
+ .exists()) {
|
|
|
+ throw new Exception(
|
|
|
+ target + File.separator + "results" + File.separator + fileName + "文件不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ //high文件夹
|
|
|
+ if (fileJson.getIntValue("clazz") == 3) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + "pan/high/" + fileName.replace("high/", ""));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //low文件夹
|
|
|
+ if (fileJson.getIntValue("clazz") == 4) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + "pan/low/" + fileName.replace("low/", ""));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //tiles文件夹,亚马逊没有裁剪图片api,不需要上传4k图
|
|
|
+ if (fileJson.getIntValue("clazz") == 5) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + fileName);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //tiles文件夹,亚马逊瓦片图
|
|
|
+ if (fileJson.getIntValue("clazz") == 7) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + fileName);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(map.size()>0) {
|
|
|
+ fYunFileService.uploadMulFiles(bucket, map);
|
|
|
+ }
|
|
|
+
|
|
|
+ //拷贝修改后的全景图到缓存目录
|
|
|
+ String cachedImagesPath = String.format(ConstantFilePath.SCENE_CACHE_IMAGES, num);
|
|
|
+ uploadFileList.stream().forEach(srcPath->{
|
|
|
+ cn.hutool.core.io.FileUtil.copy(srcPath, srcPath.replace(targetImagesPath, cachedImagesPath), true);
|
|
|
+ });
|
|
|
+
|
|
|
+ //更新数据库版本号
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+ this.upgradeVersionAndImgVersionById(sceneEditInfo.getId());
|
|
|
+ //更新scenejson缓存和oss文件版本号
|
|
|
+ upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
CreateObjUtil.build3dModel(target , "1");
|
|
|
|
|
|
String uploadJsonPath= target + File.separator + "results" +File.separator+"upload.json";
|
|
@@ -1152,6 +1269,91 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
return ResultData.ok();
|
|
|
}
|
|
|
|
|
|
+ public ResultData uploadPanoramaHandler(String num, String bucket, String target, String imgViewPath, List<String> uploadFileList, String targetImagesPath, List<String> notExistFileList) throws Exception {
|
|
|
+ CreateObjUtil.build3dModel(target , "1");
|
|
|
+
|
|
|
+ String uploadJsonPath= target + File.separator + "results" +File.separator+"upload.json";
|
|
|
+ Thread.sleep(2000);
|
|
|
+ boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime);
|
|
|
+ if(!exist){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
|
|
|
+ }
|
|
|
+ String uploadData = FileUtils.readFile(uploadJsonPath);
|
|
|
+ JSONObject uploadJson = null;
|
|
|
+ JSONArray array = null;
|
|
|
+ if(uploadData!=null) {
|
|
|
+ uploadJson = JSONObject.parseObject(uploadData);
|
|
|
+ array = uploadJson.getJSONArray("upload");
|
|
|
+ }
|
|
|
+ if(array == null){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
|
|
|
+ }
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ JSONObject fileJson = null;
|
|
|
+ String fileName = "";
|
|
|
+ for(int i = 0, len = array.size(); i < len; i++) {
|
|
|
+ fileJson = array.getJSONObject(i);
|
|
|
+ fileName = fileJson.getString("file");
|
|
|
+ //文件不存在抛出异常
|
|
|
+ if (!new File(target + File.separator + "results" + File.separator + fileName)
|
|
|
+ .exists()) {
|
|
|
+ throw new Exception(
|
|
|
+ target + File.separator + "results" + File.separator + fileName + "文件不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ //high文件夹
|
|
|
+ if (fileJson.getIntValue("clazz") == 3) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + "pan/high/" + fileName.replace("high/", ""));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //low文件夹
|
|
|
+ if (fileJson.getIntValue("clazz") == 4) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + "pan/low/" + fileName.replace("low/", ""));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //tiles文件夹,亚马逊没有裁剪图片api,不需要上传4k图
|
|
|
+ if (fileJson.getIntValue("clazz") == 5) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + fileName);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ //tiles文件夹,亚马逊瓦片图
|
|
|
+ if (fileJson.getIntValue("clazz") == 7) {
|
|
|
+ map.put(target + File.separator + "results" + File.separator + fileName,
|
|
|
+ imgViewPath + fileName);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(map.size()>0) {
|
|
|
+ fYunFileService.uploadMulFiles(bucket, map);
|
|
|
+ }
|
|
|
+
|
|
|
+ //拷贝修改后的全景图到缓存目录
|
|
|
+ String cachedImagesPath = String.format(ConstantFilePath.SCENE_CACHE_IMAGES, num);
|
|
|
+ uploadFileList.stream().forEach(srcPath->{
|
|
|
+ cn.hutool.core.io.FileUtil.copy(srcPath, srcPath.replace(targetImagesPath, cachedImagesPath), true);
|
|
|
+ });
|
|
|
+
|
|
|
+ //更新数据库版本号
|
|
|
+ ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+ this.upgradeVersionAndImgVersionById(sceneEditInfo.getId());
|
|
|
+ //更新scenejson缓存和oss文件版本号
|
|
|
+ this.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);
|
|
|
+
|
|
|
+ //如果部分成功,则需要返回成功数量和失败列表
|
|
|
+ if(CollUtil.isNotEmpty(notExistFileList)){
|
|
|
+ notExistFileList = notExistFileList.stream().map(filePath -> {
|
|
|
+ return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ return ResultData.ok(new UploadPanoramaVO(uploadFileList.size(), notExistFileList));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
|
|
|
@Override
|
|
@@ -1178,8 +1380,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
//判断全景图缓存是否存在,如果不存在,从计算目录中拷贝到缓存目录
|
|
|
this.cachePanorama(scenePlusExt.getDataSource(), num);
|
|
|
|
|
|
- String url = null;
|
|
|
- String downloadName = null;
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+
|
|
|
+ //标记是否是异步操作,默认是同步操作
|
|
|
//如果入参文件名不为空,则是单个文件下载,不需要打包
|
|
|
if(StrUtil.isNotEmpty(fileName)){
|
|
|
//如果是单张图片,直接提供oss url
|
|
@@ -1189,36 +1392,65 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
|
|
|
}
|
|
|
fYunFileService.uploadFile(bucket, localFilePath, ossFilePath);
|
|
|
- url = ossUrlPrefix + ossFilePath;
|
|
|
- downloadName = fileName;
|
|
|
+ String url = ossUrlPrefix + ossFilePath;
|
|
|
+ String downloadName = fileName;
|
|
|
+ map.put("asyn", CommonStatus.NO.code());
|
|
|
+ map.put("fileUrl", url + "?t=" + System.currentTimeMillis());
|
|
|
+ map.put("fileName", downloadName);
|
|
|
+ return ResultData.ok(map);
|
|
|
}else{
|
|
|
if(!cn.hutool.core.io.FileUtil.exist(localImagesPath)
|
|
|
|| cn.hutool.core.io.FileUtil.isDirEmpty(new File(localImagesPath))){
|
|
|
throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
|
|
|
}
|
|
|
|
|
|
- downloadName = num + "_images.zip";
|
|
|
- long start = Calendar.getInstance().getTimeInMillis();
|
|
|
- //打包
|
|
|
- String zipPath = cachePath + downloadName;
|
|
|
- ZipUtil.zip(localImagesPath, zipPath);
|
|
|
- long end1 = Calendar.getInstance().getTimeInMillis();
|
|
|
- log.info("打包耗时:" + (end1 - start));
|
|
|
- //上传压缩包
|
|
|
- fYunFileService.uploadFileByCommand(bucket, zipPath, String.format(cacheFormat, num) + downloadName);
|
|
|
- url = ossUrlPrefix + String.format(cacheFormat, num) + downloadName;
|
|
|
- long end2 = Calendar.getInstance().getTimeInMillis();
|
|
|
- log.info("上传耗时:" + (end2 - end1));
|
|
|
- //删除本地压缩包
|
|
|
- FileUtils.deleteFile(zipPath);
|
|
|
-// //删除本地目录
|
|
|
- FileUtils.deleteDirectory(localImagesPath);
|
|
|
- }
|
|
|
+ //清除旧的下载记录
|
|
|
+ sceneAsynOperLogService.remove(
|
|
|
+ new LambdaQueryWrapper<SceneAsynOperLog>()
|
|
|
+ .eq(SceneAsynOperLog::getNum, num)
|
|
|
+ .eq(SceneAsynOperLog::getOperType, SceneAsynOperType.DOWNLOAD.code())
|
|
|
+ .eq(SceneAsynOperLog::getModule, SceneAsynModuleType.UPLOAD_DOWNLOAD.code())
|
|
|
+ .eq(SceneAsynOperLog::getFunction, SceneAsynFuncType.PANORAMIC_IMAGE.code()));
|
|
|
+
|
|
|
+ //开始异步执行下载全景图压缩包操作
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+ SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
|
|
|
+ sceneAsynOperLog.setNum(num);
|
|
|
+ sceneAsynOperLog.setOperType(SceneAsynOperType.DOWNLOAD.code());
|
|
|
+ sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
|
|
|
+ sceneAsynOperLog.setFunction(SceneAsynFuncType.PANORAMIC_IMAGE.code());
|
|
|
+ sceneAsynOperLog.setVersion(sceneEditInfo.getImgVersion());
|
|
|
+ sceneAsynOperLogService.save(sceneAsynOperLog);
|
|
|
+ try {
|
|
|
+ String downloadName = num + "_images.zip";
|
|
|
+ long start = Calendar.getInstance().getTimeInMillis();
|
|
|
+ //打包
|
|
|
+ String zipPath = cachePath + downloadName;
|
|
|
+ ZipUtil.zip(localImagesPath, zipPath);
|
|
|
+ long end1 = Calendar.getInstance().getTimeInMillis();
|
|
|
+ log.info("打包耗时:" + (end1 - start));
|
|
|
+ //上传压缩包
|
|
|
+ fYunFileService.uploadFileByCommand(bucket, zipPath, String.format(cacheFormat, num) + downloadName);
|
|
|
+ String url = ossUrlPrefix + String.format(cacheFormat, num) + downloadName;
|
|
|
+ long end2 = Calendar.getInstance().getTimeInMillis();
|
|
|
+ log.info("上传耗时:" + (end2 - end1));
|
|
|
+ //删除本地压缩包
|
|
|
+ FileUtils.deleteFile(zipPath);
|
|
|
+ //删除本地目录
|
|
|
+ FileUtils.deleteDirectory(localImagesPath);
|
|
|
+ sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
|
|
|
+ sceneAsynOperLog.setUrl(url);
|
|
|
+ }catch (Exception e){
|
|
|
+ sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
|
|
|
+ log.error("下载全景图压缩包失败,num:" + num, e);
|
|
|
+ }
|
|
|
+ sceneAsynOperLogService.saveOrUpdate(sceneAsynOperLog);
|
|
|
+ });
|
|
|
|
|
|
- Map<String, Object> map = new HashMap<>();
|
|
|
- map.put("fileUrl", url + "?t=" + System.currentTimeMillis());
|
|
|
- map.put("fileName", downloadName);
|
|
|
- return ResultData.ok(map);
|
|
|
+ map.put("asyn", CommonStatus.YES.code());
|
|
|
+ return ResultData.ok(map);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void cachePanorama(String dataSource, String num){
|
|
@@ -2603,7 +2835,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public ResultData saveFilter(BaseDataParamVO param) throws Exception {
|
|
|
+ public ResultData saveFilter(SaveFiltersParamVO param) throws Exception {
|
|
|
|
|
|
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
|
|
|
if(Objects.isNull(scenePlus)){
|
|
@@ -2624,6 +2856,11 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
//写本地文件,作为备份
|
|
|
this.writeFilter(param.getNum());
|
|
|
|
|
|
+ //如果页面选择恢复默认,filters字段值为否
|
|
|
+ if(Objects.nonNull(param.getReset()) && param.getReset() == CommonStatus.YES.code().intValue()){
|
|
|
+ filters = CommonStatus.NO.code();
|
|
|
+ }
|
|
|
+
|
|
|
//更新数据库
|
|
|
SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
|
|
|
sceneEditInfoExt.setFilters(filters);
|