|
|
@@ -17,6 +17,7 @@ import com.fdkankan.common.exception.BusinessException;
|
|
|
import com.fdkankan.common.response.Result;
|
|
|
import com.fdkankan.common.response.ResultData;
|
|
|
import com.fdkankan.common.util.ComputerUtil;
|
|
|
+import com.fdkankan.common.util.CreateHouseJsonUtil;
|
|
|
import com.fdkankan.common.util.CreateObjUtil;
|
|
|
import com.fdkankan.common.util.FileMd5Util;
|
|
|
import com.fdkankan.common.util.FileUtil;
|
|
|
@@ -29,10 +30,15 @@ import com.fdkankan.redis.constant.RedisLockKey;
|
|
|
import com.fdkankan.redis.util.RedisLockUtil;
|
|
|
import com.fdkankan.redis.util.RedisUtil;
|
|
|
import com.fdkankan.scene.bean.BoxPhotoBean;
|
|
|
+import com.fdkankan.scene.bean.IconBean;
|
|
|
+import com.fdkankan.scene.bean.PointBean;
|
|
|
import com.fdkankan.scene.bean.RequestSceneProV4;
|
|
|
import com.fdkankan.scene.bean.SceneJsonBean;
|
|
|
+import com.fdkankan.scene.bean.SegmentBean;
|
|
|
import com.fdkankan.scene.bean.StyleBean;
|
|
|
import com.fdkankan.scene.bean.TagBean;
|
|
|
+import com.fdkankan.scene.bean.VertexBean;
|
|
|
+import com.fdkankan.scene.bean.WallBean;
|
|
|
import com.fdkankan.scene.callback.FdkkMiniReqErrorCallback;
|
|
|
import com.fdkankan.scene.callback.FdkkMiniReqSuccessCallback;
|
|
|
import com.fdkankan.scene.entity.SceneDataDownload;
|
|
|
@@ -64,6 +70,7 @@ import java.io.File;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
+import java.util.Collection;
|
|
|
import java.util.Comparator;
|
|
|
import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
@@ -75,6 +82,7 @@ import java.util.Set;
|
|
|
import java.util.UUID;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.stream.Collectors;
|
|
|
+import javax.annotation.Resource;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
@@ -144,7 +152,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
IScenePlusService scenePlusService;
|
|
|
@Autowired
|
|
|
IScenePlusExtService scenePlusExtService;
|
|
|
- @Autowired
|
|
|
+ @Resource
|
|
|
private FdkankanMiniClient fdkankanMiniClient;
|
|
|
@Autowired
|
|
|
private ISceneUploadService sceneUploadService;
|
|
|
@@ -164,6 +172,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
sceneEditControlsDb = sceneEditControlsService.getBySceneEditId(sceneEditInfoDb.getId());
|
|
|
}
|
|
|
|
|
|
+ //用户上传的文件后缀名转小写
|
|
|
+ this.lowercaseExtName(param);
|
|
|
+
|
|
|
SceneEditInfo sceneEditInfo = BeanUtil.copyProperties(param, SceneEditInfo.class);
|
|
|
sceneEditInfo.setScenePlusId(scenePlus.getId());
|
|
|
if(Objects.isNull(sceneEditInfoDb)){
|
|
|
@@ -191,6 +202,21 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
+ private void lowercaseExtName(SceneEditInfoParamVO sceneEditInfo){
|
|
|
+ if(StrUtil.isNotEmpty(sceneEditInfo.getMusic())){
|
|
|
+ String extName = cn.hutool.core.io.FileUtil.extName(sceneEditInfo.getMusic());
|
|
|
+ if(StrUtil.isNotEmpty(extName)){
|
|
|
+ sceneEditInfo.setMusic(sceneEditInfo.getMusic().replace(extName, extName.toLowerCase()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(StrUtil.isNotEmpty(sceneEditInfo.getMusicFile())){
|
|
|
+ String extName = cn.hutool.core.io.FileUtil.extName(sceneEditInfo.getMusicFile());
|
|
|
+ if(StrUtil.isNotEmpty(extName)){
|
|
|
+ sceneEditInfo.setMusicFile(sceneEditInfo.getMusicFile().replace(extName, extName.toLowerCase()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public SceneEditInfo getBySceneProId(long sceneProId) {
|
|
|
return this.getOne(new LambdaQueryWrapper<SceneEditInfo>()
|
|
|
@@ -244,6 +270,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
sceneJson.setVideos(scenePlusExt.getVideos());
|
|
|
}
|
|
|
|
|
|
+ //发布马赛克列表
|
|
|
+ sceneJson.setMosaicList(this.getMosaicList(num));
|
|
|
+
|
|
|
//处理热点数据,生成hot.json
|
|
|
this.publicHotData(num, sceneEditInfo);
|
|
|
|
|
|
@@ -442,6 +471,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
sceneInfoVO.setSceneFrom(scenePlusExt.getSceneFrom());
|
|
|
sceneInfoVO.setSceneKind(scenePlusExt.getSceneKind());
|
|
|
sceneInfoVO.setVideos(scenePlusExt.getVideos());
|
|
|
+ sceneInfoVO.setMosaicList(this.getMosaicList(num));
|
|
|
|
|
|
// TODO: 2022/4/24 v3版本停机要切换---------------------------start
|
|
|
// this.setExtData(sceneInfoVO, scenePlus.getCameraId());
|
|
|
@@ -491,8 +521,8 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
if(sceneProV3.getRecStatus().equals("I")){
|
|
|
throw new BusinessException(ErrorCode.FAILURE_CODE_5009);
|
|
|
}
|
|
|
- if(SceneStatus.SUCCESS.code() != sceneProV3.getStatus()
|
|
|
- && SceneStatus.NO_DISPLAY.code() != sceneProV3.getStatus()){
|
|
|
+ if((SceneStatus.SUCCESS.code() != sceneProV3.getStatus() && SceneStatus.NO_DISPLAY.code() != sceneProV3.getStatus())
|
|
|
+ || (sceneProV3.getIsUpgrade() != null && sceneProV3.getIsUpgrade()== 2)){
|
|
|
throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
|
|
|
}
|
|
|
if(PayStatus.PAY.code() != sceneProV3.getPayStatus()){
|
|
|
@@ -601,6 +631,11 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
//写入数据库
|
|
|
Byte floorPlanUser = null;
|
|
|
if(StrUtil.isNotEmpty(floorJsonData)){
|
|
|
+ // TODO: 2022/7/26 生成hostType
|
|
|
+ JSONObject houseTypeJson = CreateHouseJsonUtil
|
|
|
+ .createHouseTypeJsonByUser(localDataPath + "floorplan_user.json");
|
|
|
+ uploadToOssUtil.upload(houseTypeJson.toJSONString().getBytes(), editUserPath + "houseType.json");
|
|
|
+
|
|
|
floorPlanUser = CommonStatus.YES.code();
|
|
|
}
|
|
|
SceneEditInfo sceneEditInfoDb = this.getByScenePlusId(scenePlus.getId());
|
|
|
@@ -638,7 +673,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public ResultData resetCad(String num){
|
|
|
+ public ResultData resetCad(String num) throws IOException {
|
|
|
|
|
|
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
|
|
|
if(Objects.isNull(scenePlus))
|
|
|
@@ -660,6 +695,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+ //根据floorplan_cad.json生成houseType.json
|
|
|
+ this.uploadHouseTypeJson(num);
|
|
|
+
|
|
|
ScenePro scenePro = sceneProService.findBySceneNum(num);
|
|
|
SceneEditInfo sceneEditInfoDb = this.getByScenePlusId(scenePlus.getId());
|
|
|
SceneEditInfoExt sceneEditInfoExt = null;
|
|
|
@@ -692,6 +730,112 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
|
|
|
}
|
|
|
|
|
|
+ private void uploadHouseTypeJson(String num) throws IOException {
|
|
|
+
|
|
|
+ JSONObject result = new JSONObject();
|
|
|
+ result.put("name", "houseType.json");
|
|
|
+ result.put("version", "2.1");
|
|
|
+
|
|
|
+ String floorplanCadPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan_cad.json";
|
|
|
+ String floorcadStr = uploadToOssUtil.getObjectContent(this.bucket, floorplanCadPath);
|
|
|
+
|
|
|
+ JSONObject floorcadObj = JSON.parseObject(floorcadStr);
|
|
|
+ JSONArray floors = floorcadObj.getJSONArray("floors");
|
|
|
+
|
|
|
+ JSONArray targetFloors = new JSONArray();
|
|
|
+ result.put("floors", targetFloors);
|
|
|
+ for(int i = 0; i < floors.size(); i++){
|
|
|
+ JSONObject floor = (JSONObject)floors.get(i);
|
|
|
+ JSONArray[] pointsAndWalls = this.createHouseTypeJsonHandler(floor);
|
|
|
+ JSONArray points = pointsAndWalls[0];
|
|
|
+ JSONArray walls = pointsAndWalls[1];
|
|
|
+ JSONObject targetFloor = new JSONObject();
|
|
|
+ targetFloor.put("points", points);
|
|
|
+ targetFloor.put("walls", walls);
|
|
|
+ targetFloors.add(targetFloor);
|
|
|
+ }
|
|
|
+
|
|
|
+ String hourseTypeJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, num) + "houseType.json";
|
|
|
+ uploadToOssUtil.upload(result.toJSONString().getBytes(), hourseTypeJsonPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ private JSONArray[] createHouseTypeJsonHandler(JSONObject floor){
|
|
|
+
|
|
|
+ JSONArray[] result = new JSONArray[2];
|
|
|
+
|
|
|
+ //处理点
|
|
|
+ Map<Integer, VertexBean> vertexMap = new HashMap<>();
|
|
|
+ Map<String, PointBean> pointMap = new HashMap<>();
|
|
|
+ Map<Integer, String> vpMap = new HashMap<>();
|
|
|
+ JSONArray vertexArr = floor.getJSONArray("vertex-xy");
|
|
|
+ for(int i = 0; i < vertexArr.size(); i++){
|
|
|
+ Object o = vertexArr.get(i);
|
|
|
+
|
|
|
+ VertexBean vertexBean = JSON.parseObject(JSON.toJSONString(o), VertexBean.class);
|
|
|
+ Integer vertexId = vertexBean.getId();
|
|
|
+ vertexMap.put(vertexId, vertexBean);
|
|
|
+
|
|
|
+ String pointId = "Point" + i;
|
|
|
+ pointMap.put(pointId, PointBean.builder().vectorId(pointId).x(vertexBean.getX()).y(vertexBean.getY()).build());
|
|
|
+
|
|
|
+ vpMap.put(vertexId, pointId);
|
|
|
+ }
|
|
|
+
|
|
|
+ //处理墙
|
|
|
+ Map<Integer, SegmentBean> segmentMap = new HashMap<>();
|
|
|
+ Map<String, WallBean> wallMap = new HashMap<>();
|
|
|
+ Map<Integer, String> swMap = new HashMap<>();
|
|
|
+ JSONArray segmentArr = floor.getJSONArray("segment");
|
|
|
+ Map<String, String> startMap = new HashMap<>();
|
|
|
+ Map<String, String> endMap = new HashMap<>();
|
|
|
+ for(int i = 0; i < segmentArr.size(); i++){
|
|
|
+ Object o = segmentArr.get(i);
|
|
|
+
|
|
|
+ SegmentBean segmentBean = JSON.parseObject(JSON.toJSONString(o), SegmentBean.class);
|
|
|
+ String startPointId = vpMap.get(segmentBean.getA());
|
|
|
+ String endPointId = vpMap.get(segmentBean.getB());
|
|
|
+ segmentBean.setStartPointId(startPointId);
|
|
|
+ segmentBean.setEndPointId(endPointId);
|
|
|
+
|
|
|
+ Integer segmentId = segmentBean.getId();
|
|
|
+ segmentMap.put(segmentId, segmentBean);
|
|
|
+
|
|
|
+ String wallId = "Wall" + i;
|
|
|
+ WallBean wallBean = WallBean.builder()
|
|
|
+ .vectorId(wallId)
|
|
|
+ .start(segmentBean.getStartPointId())
|
|
|
+ .end(segmentBean.getEndPointId())
|
|
|
+ .children(new String[]{})
|
|
|
+ .width(0.2d)
|
|
|
+ .build();
|
|
|
+ wallMap.put(wallId, wallBean);
|
|
|
+
|
|
|
+ startMap.put(wallBean.getStart(), wallBean.getVectorId());
|
|
|
+ endMap.put(wallBean.getEnd(), wallBean.getVectorId());
|
|
|
+
|
|
|
+ swMap.put(segmentId, wallId);
|
|
|
+ }
|
|
|
+
|
|
|
+ Collection<PointBean> pointBeans = pointMap.values();
|
|
|
+ for (PointBean pointBean : pointBeans) {
|
|
|
+ Map<String, String> parent = new HashMap<>();
|
|
|
+ String startParent = startMap.get(pointBean.getVectorId());
|
|
|
+ String endParent = endMap.get(pointBean.getVectorId());
|
|
|
+ parent.put(startParent, "start");
|
|
|
+ parent.put(endParent, "end");
|
|
|
+ pointBean.setParent(parent);
|
|
|
+ }
|
|
|
+ JSONArray pointArr = JSON.parseArray(JSON.toJSONString(pointBeans));
|
|
|
+ result[0] = pointArr;
|
|
|
+
|
|
|
+ Collection<WallBean> wallBeans = wallMap.values();
|
|
|
+ JSONArray wallArr = JSON.parseArray(JSON.toJSONString(wallBeans));
|
|
|
+ result[1] = wallArr;
|
|
|
+
|
|
|
+ return result;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public ResultData renameCad(RenameCadParamVO param) throws IOException {
|
|
|
|
|
|
@@ -753,7 +897,15 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public void upgradeSceneJsonVersion(String num, int version) throws IOException {
|
|
|
+ public void upgradeVersionAndImgVersionById(Long id) {
|
|
|
+ this.update(new LambdaUpdateWrapper<SceneEditInfo>()
|
|
|
+ .setSql("version=version + " + 1)
|
|
|
+ .setSql("img_version=img_version + " + 1)
|
|
|
+ .eq(SceneEditInfo::getId, id));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void upgradeSceneJsonVersion(String num, int version, Integer imgVersion) throws IOException {
|
|
|
|
|
|
//更新redis缓存版本号
|
|
|
String key = String.format(RedisKey.SCENE_JSON, num);
|
|
|
@@ -761,6 +913,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
if(StrUtil.isNotEmpty(sceneJson)){
|
|
|
SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
|
|
|
sceneJsonBean.setVersion(version);
|
|
|
+ if(Objects.nonNull(imgVersion)){
|
|
|
+ sceneJsonBean.setImgVersion(imgVersion + 1);
|
|
|
+ }
|
|
|
redisUtil.set(key, JSON.toJSONString(sceneJsonBean));
|
|
|
}
|
|
|
|
|
|
@@ -770,6 +925,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
if(StrUtil.isNotEmpty(sceneJson)){
|
|
|
SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
|
|
|
sceneJsonBean.setVersion(version);
|
|
|
+ if(Objects.nonNull(imgVersion)){
|
|
|
+ sceneJsonBean.setImgVersion(imgVersion + 1);
|
|
|
+ }
|
|
|
uploadToOssUtil.upload(JSON.toJSONString(sceneJsonBean).getBytes(StandardCharsets.UTF_8), sceneJsonPath);
|
|
|
}
|
|
|
|
|
|
@@ -1007,9 +1165,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
|
|
|
//更新数据库版本号
|
|
|
SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
- this.upgradeVersionById(sceneEditInfo.getId());
|
|
|
+ this.upgradeVersionAndImgVersionById(sceneEditInfo.getId());
|
|
|
//更新scenejson缓存和oss文件版本号
|
|
|
- this.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1);
|
|
|
+ this.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1);
|
|
|
|
|
|
//如果部分成功,则需要返回成功数量和失败列表
|
|
|
if(CollUtil.isNotEmpty(notExistFileList)){
|
|
|
@@ -1081,13 +1239,18 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
}
|
|
|
|
|
|
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));
|
|
|
//上传压缩包
|
|
|
// uploadToOssUtil.upload(zipPath, String.format(cacheFormat, num) + downloadName);
|
|
|
uploadToOssUtil.uploadBySh(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);
|
|
|
// //删除本地目录
|
|
|
@@ -1300,7 +1463,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
//更新scene.json版本号
|
|
|
// this.upgradeVersionToSceneJson(num);
|
|
|
//更新scenejson缓存和oss文件版本号
|
|
|
- this.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1);
|
|
|
+ this.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, null);
|
|
|
|
|
|
return ResultData.ok();
|
|
|
}
|
|
|
@@ -1504,172 +1667,117 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
@Override
|
|
|
public ResultData addMosaics(BaseDataParamVO param) throws Exception {
|
|
|
|
|
|
- JSONArray mosaicArr = JSONArray.parseArray(param.getData());
|
|
|
- if (CollUtil.isEmpty(mosaicArr) || mosaicArr.size() > 1) {
|
|
|
- throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
|
|
|
- }
|
|
|
- JSONObject mosicObj= mosaicArr.getJSONObject(0);
|
|
|
+ //如果redis数据丢失,从本地文件中同步马赛克数据到redis
|
|
|
+ this.syncMosaicFromFileToRedis(param.getNum());
|
|
|
|
|
|
- ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
|
|
|
- if(Objects.isNull(scenePlus)){
|
|
|
- throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ JSONArray jsonArray = JSON.parseArray(param.getData());
|
|
|
+ for (Object o : jsonArray) {
|
|
|
+ JSONObject mosaic = (JSONObject) o;
|
|
|
+ String panoId = mosaic.getString("panoId");
|
|
|
+ if(StrUtil.isEmpty(panoId)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
|
|
|
+ }
|
|
|
+ map.put(panoId, JSON.toJSONString(mosaic));
|
|
|
}
|
|
|
- ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
|
|
|
- SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
- SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfo.getId());
|
|
|
-
|
|
|
- String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, param.getNum());
|
|
|
- String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, param.getNum());
|
|
|
+ String key = String.format(RedisKey.SCENE_MOSAIC_DATA, param.getNum());
|
|
|
+ redisUtil.hmset(key, map);
|
|
|
|
|
|
- String path = scenePlusExt.getDataSource();
|
|
|
- if(StrUtil.isNotEmpty(path) && path.startsWith("http")){
|
|
|
- path = ConstantFilePath.BUILD_MODEL_PATH + File.separator + path.split("/")[path.split("/").length - 2];
|
|
|
- }
|
|
|
- String target = path + "_roi";
|
|
|
+ //写入本地文件,作为备份
|
|
|
+ this.writeMosaic(param.getNum());
|
|
|
|
|
|
- cn.hutool.core.io.FileUtil.del(target);
|
|
|
+ //更新数据库
|
|
|
+ this.updateMosaicFlag(param.getNum());
|
|
|
|
|
|
- //文件上传的位置可以自定义
|
|
|
- String filePath = target + File.separator + "extras" + File.separator + "images/";
|
|
|
- File imageFile = new File(filePath);
|
|
|
- if(!imageFile.getParentFile().exists()){
|
|
|
- imageFile.getParentFile().mkdirs();
|
|
|
- }
|
|
|
- FileUtils.copyFolderAllFiles(path + "/caches/images/", filePath, true);
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
|
|
|
- String mosaicData = sceneEditInfoExt.getMosaics();
|
|
|
- JSONArray jsonArray = new JSONArray();
|
|
|
- if(StrUtil.isNotEmpty(mosaicData)){
|
|
|
- jsonArray = JSONArray.parseArray(mosaicData);
|
|
|
- }
|
|
|
- jsonArray.add(mosicObj);
|
|
|
+ private void updateMosaicFlag(String num){
|
|
|
+ ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
|
|
|
+ SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
|
|
|
|
|
|
- // 准备算法数据
|
|
|
- List<JSONObject> mosaicsList = new ArrayList<>();
|
|
|
- for(int i = 0, len = jsonArray.size(); i < len; i++){
|
|
|
- JSONObject jsonObject = jsonArray.getJSONObject(i);
|
|
|
- boolean contains = false;
|
|
|
- for (JSONObject item : mosaicsList) {
|
|
|
- if(StringUtils.equals(item.getString("panoId"),jsonObject.getString("panoId"))){
|
|
|
- contains = true;
|
|
|
- item.getJSONArray("rect").addAll(jsonObject.getJSONArray("rect"));
|
|
|
- }
|
|
|
- }
|
|
|
- if(!contains){
|
|
|
- mosaicsList.add(jsonObject);
|
|
|
- }
|
|
|
+ String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
|
|
|
+ boolean flag = redisUtil.hasKey(key);
|
|
|
+ if(flag){
|
|
|
+ sceneEditInfoExt.setMosaic(Integer.valueOf(CommonStatus.YES.code()));
|
|
|
+ }else{
|
|
|
+ sceneEditInfoExt.setMosaic(Integer.valueOf(CommonStatus.NO.code()));
|
|
|
}
|
|
|
- JSONObject roiImageJSon = new JSONObject();
|
|
|
- roiImageJSon.put("batch",mosaicsList);
|
|
|
-
|
|
|
- FileUtils.writeFile(target + File.separator + "extras" + File.separator + "image-ROI.json", JSON.toJSONString(roiImageJSon,SerializerFeature.DisableCircularReferenceDetect));
|
|
|
+ sceneEditInfoExtService.updateById(sceneEditInfoExt);
|
|
|
+ }
|
|
|
|
|
|
- FileUtils.copyFile(path + File.separator + "results/vision.txt", target + File.separator+"extras/vision.txt", true);
|
|
|
- FileUtils.copyFile(path + File.separator + "results/vision2.txt", target + File.separator+"extras/vision2.txt", true);
|
|
|
- FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
|
|
|
- String data = FileUtils.readFile(target + File.separator+"data.json");
|
|
|
- if(data != null){
|
|
|
- JSONObject floorplanJson = new JSONObject();
|
|
|
- floorplanJson.put("has_source_images", true);
|
|
|
- floorplanJson.put("has_vision_txt", true);
|
|
|
+ /**
|
|
|
+ * <p>
|
|
|
+ 保证马赛克数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
|
|
|
+ **/
|
|
|
+ private void syncMosaicFromFileToRedis(String num) throws Exception{
|
|
|
|
|
|
- JSONObject dataJson = JSONObject.parseObject(data);
|
|
|
- dataJson.put("extras", floorplanJson);
|
|
|
- //V5表示不需要生成high,low文件
|
|
|
- dataJson.put("skybox_type", "SKYBOX_V6");
|
|
|
- if(scenePlusExt.getSceneScheme() == 11){
|
|
|
- dataJson.put("skybox_type", "SKYBOX_V7");
|
|
|
- }
|
|
|
- dataJson.put("split_type", "SPLIT_V18");
|
|
|
- //sceneScheme为3切成瓦片图
|
|
|
- if(scenePlusExt.getSceneScheme() == 3){
|
|
|
- dataJson.put("skybox_type", "SKYBOX_V4");
|
|
|
- }
|
|
|
- FileUtils.writeFile(target + File.separator+"data.json", new String(dataJson.toString().getBytes(), "UTF-8"));
|
|
|
+ String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
|
|
|
+ boolean exist = redisUtil.hasKey(key);
|
|
|
+ if(exist){
|
|
|
+ return;
|
|
|
}
|
|
|
-
|
|
|
- FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
|
|
|
-
|
|
|
- //进行计算
|
|
|
- log.info("马赛克建模开始, num:{}, path:{}" + param.getNum(), target);
|
|
|
- CreateObjUtil.build3dModel2(target , "1");
|
|
|
- log.info("马赛克建模结束, num:{}, path:{}" + param.getNum(), target);
|
|
|
-
|
|
|
- //读取upload文件,检验需要上传的文件是否存在
|
|
|
- String uploadJsonPath = target + File.separator + "results" + File.separator + "upload.json";
|
|
|
- boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime);
|
|
|
- if(!exist){
|
|
|
- throw new BusinessException(ErrorCode.FAILURE_CODE_5042);
|
|
|
+ String lockKey = String.format(RedisLockKey.LOCK_MOSAIC_DATA_SYNC, num);
|
|
|
+ boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_1_MINUTE);
|
|
|
+ if(!lock){
|
|
|
+ throw new BusinessException(ErrorCode.SYSTEM_BUSY);
|
|
|
}
|
|
|
- String uploadData = FileUtils.readFile(target + File.separator + "results" + File.separator + "upload.json");
|
|
|
- JSONObject uploadJson = JSONObject.parseObject(uploadData);
|
|
|
- JSONArray array = uploadJson.getJSONArray("upload");
|
|
|
- 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/", ""));
|
|
|
+ try{
|
|
|
+ exist = redisUtil.hasKey(key);
|
|
|
+ if(exist){
|
|
|
+ return;
|
|
|
}
|
|
|
- //low文件夹
|
|
|
- if(fileJson.getIntValue("clazz") == 4){
|
|
|
- map.put(target + File.separator + "results" +File.separator+ fileName,
|
|
|
- imgViewPath + "pan/low/"+ fileName.replace("low/", ""));
|
|
|
+ String filePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num);
|
|
|
+ String mosaicData = FileUtils.readFile(filePath + "mosaic.json");
|
|
|
+ if(StrUtil.isEmpty(mosaicData)){
|
|
|
+ return;
|
|
|
}
|
|
|
-
|
|
|
- //tiles文件夹,亚马逊没有裁剪图片api,不需要上传4k图
|
|
|
- if(fileJson.getIntValue("clazz") == 5){
|
|
|
- map.put(target + File.separator + "results" + File.separator+ fileName,
|
|
|
- imgViewPath + fileName);
|
|
|
+ JSONArray jsonArray = JSON.parseArray(mosaicData);
|
|
|
+ if(CollUtil.isEmpty(jsonArray)){
|
|
|
+ return;
|
|
|
}
|
|
|
-
|
|
|
- //tiles文件夹,亚马逊瓦片图
|
|
|
- if(fileJson.getIntValue("clazz") == 7 ){
|
|
|
- map.put(target + File.separator + "results" + File.separator+ fileName,
|
|
|
- imgViewPath + fileName);
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ for (Object o : jsonArray) {
|
|
|
+ JSONObject jo = (JSONObject)o;
|
|
|
+ map.put(jo.getString("panoId"), jo.toJSONString());
|
|
|
}
|
|
|
+ redisUtil.hmset(key, map);
|
|
|
+ }finally {
|
|
|
+ redisLockUtil.unlockLua(lockKey);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- for(String imagesName : imageFile.list()){
|
|
|
- //覆盖原始图片资源
|
|
|
- FileUtils.copyFile(target + File.separator + "extras/images/" + imagesName,
|
|
|
- path + File.separator + "caches/images/" + imagesName, true);
|
|
|
- FileUtils.deleteFile(target + File.separator + "extras/images/" + imagesName);
|
|
|
- }
|
|
|
-
|
|
|
- uploadToOssUtil.uploadMulFiles(map);
|
|
|
-
|
|
|
- this.upgradeVersionById(sceneEditInfo.getId());
|
|
|
+ /**
|
|
|
+ * <p>
|
|
|
+ 保证马赛克数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
|
|
|
+ **/
|
|
|
+ private void writeMosaic(String num) throws Exception{
|
|
|
|
|
|
- sceneEditInfoExt.setMosaics(JSON.toJSONString(jsonArray,SerializerFeature.DisableCircularReferenceDetect));
|
|
|
- sceneEditInfoExtService.updateById(sceneEditInfoExt);
|
|
|
+ String mosaicPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "mosaic.json";
|
|
|
|
|
|
- // 更新 scene.json
|
|
|
- String sceneJsonPath = dataViewPath + "scene.json";
|
|
|
- String sceneJson = uploadToOssUtil.getObjectContent(this.bucket, sceneJsonPath);
|
|
|
- JSONObject scenejson = new JSONObject();
|
|
|
- if(StrUtil.isNotEmpty(sceneJson)) {
|
|
|
- scenejson = JSONObject.parseObject(sceneJson);
|
|
|
+ String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
|
|
|
+ Map<String, String> mosaicMap = redisUtil.hmget(key);
|
|
|
+ if(CollUtil.isEmpty(mosaicMap)){
|
|
|
+ FileUtils.deleteFile(mosaicPath);
|
|
|
+ return;
|
|
|
}
|
|
|
- scenejson.put("mosaics",JSON.toJSONString(jsonArray, SerializerFeature.DisableCircularReferenceDetect));
|
|
|
- Integer version = scenejson.getIntValue("version");
|
|
|
- version = Objects.isNull(version) ? 1 : version + 1;
|
|
|
- scenejson.put("version", version);
|
|
|
- uploadToOssUtil.upload(scenejson.toJSONString().getBytes(), sceneJsonPath);
|
|
|
+ List<String> mosaicList = Lists.newArrayList(mosaicMap.values());
|
|
|
+ JSONArray jsonArr = new JSONArray();
|
|
|
+ mosaicList.stream().forEach(mosaic->{
|
|
|
+ jsonArr.add(JSONObject.parseObject(mosaic));
|
|
|
+ });
|
|
|
|
|
|
- Map<String,Object> result = new HashMap<>(1);
|
|
|
- result.put("mosaics",jsonArray);
|
|
|
|
|
|
- return ResultData.ok(result);
|
|
|
+ String lockKey = String.format(RedisLockKey.LOCK_MOSAIC_JSON, num);
|
|
|
+ boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_1_MINUTE);
|
|
|
+ if(!lock){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try{
|
|
|
+ FileUtils.writeFile(mosaicPath, jsonArr.toJSONString());
|
|
|
+ }finally {
|
|
|
+ redisLockUtil.unlockLua(lockKey);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -2000,7 +2108,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
.eq(SceneEditInfoExt::getEditInfoId, sceneEditInfo.getId()));
|
|
|
|
|
|
//更新场景版本
|
|
|
- this.upgradeVersionById(sceneEditInfo.getId());
|
|
|
+ this.update(new LambdaUpdateWrapper<SceneEditInfo>()
|
|
|
+ .setSql("version=version+" + 1)
|
|
|
+ .setSql("link_version=link_version+" + 1)
|
|
|
+ .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -2402,4 +2513,70 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
uploadToOssUtil.upload(localFilePath.replace("mp4", "flv"), userEditPath+flvFileName);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public ResultData deleteMosaics(DeleteMosaicParamVO param) throws Exception {
|
|
|
+
|
|
|
+ //如果redis数据丢失,从本地文件中同步马赛克数据到redis
|
|
|
+ this.syncMosaicFromFileToRedis(param.getNum());
|
|
|
+
|
|
|
+ String key = String.format(RedisKey.SCENE_MOSAIC_DATA, param.getNum());
|
|
|
+ redisUtil.hdel(key, param.getPanoIdList().toArray());
|
|
|
+
|
|
|
+ //写入本地文件,作为备份
|
|
|
+ this.writeMosaic(param.getNum());
|
|
|
+
|
|
|
+ //更新数据库
|
|
|
+ this.updateMosaicFlag(param.getNum());
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<JSONObject> getMosaicList(String num) throws Exception {
|
|
|
+
|
|
|
+ //如果redis数据丢失,从本地文件中同步马赛克数据到redis
|
|
|
+ this.syncMosaicFromFileToRedis(num);
|
|
|
+
|
|
|
+ String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
|
|
|
+ Map<String, String> map = redisUtil.hmget(key);
|
|
|
+ if(CollUtil.isEmpty(map)){
|
|
|
+ ResultData.ok(new String[0]);
|
|
|
+ }
|
|
|
+ return map.values().stream()
|
|
|
+ .map(mosaic-> JSON.parseObject(mosaic))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData addWaterMark(BaseFileParamVO param) throws Exception {
|
|
|
+ ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
|
|
|
+ if(Objects.isNull(scenePlus)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ }
|
|
|
+ SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService
|
|
|
+ .getByScenePlusId(scenePlus.getId());
|
|
|
+ sceneEditInfoExt.setWaterMark(param.getFileName());
|
|
|
+ sceneEditInfoExtService.updateById(sceneEditInfoExt);
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData deleteWaterMark(BaseFileParamVO param) throws Exception {
|
|
|
+ ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
|
|
|
+ if(Objects.isNull(scenePlus)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ }
|
|
|
+ sceneUploadService.delete(
|
|
|
+ DeleteFileParamVO.builder()
|
|
|
+ .num(param.getNum())
|
|
|
+ .fileNames(Lists.newArrayList(param.getFileName()))
|
|
|
+ .bizType(FileBizType.WATERMARK.code()).build());
|
|
|
+
|
|
|
+ SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
|
|
|
+ sceneEditInfoExt.setWaterMark("");
|
|
|
+ sceneEditInfoExtService.updateById(sceneEditInfoExt);
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
}
|