|
@@ -14,21 +14,27 @@ import com.fdkankan.common.constant.*;
|
|
|
import com.fdkankan.common.exception.BusinessException;
|
|
|
import com.fdkankan.common.response.ResultData;
|
|
|
import com.fdkankan.common.util.CreateObjUtil;
|
|
|
+import com.fdkankan.common.util.FileMd5Util;
|
|
|
import com.fdkankan.common.util.FileUtil;
|
|
|
import com.fdkankan.common.util.FileUtils;
|
|
|
import com.fdkankan.fyun.constant.StorageType;
|
|
|
import com.fdkankan.fyun.oss.UploadToOssUtil;
|
|
|
import com.fdkankan.redis.constant.RedisKey;
|
|
|
+import com.fdkankan.redis.constant.RedisLockKey;
|
|
|
+import com.fdkankan.redis.util.RedisLockUtil;
|
|
|
import com.fdkankan.redis.util.RedisUtil;
|
|
|
import com.fdkankan.scene.bean.SceneJsonBean;
|
|
|
+import com.fdkankan.scene.entity.SceneDataDownload;
|
|
|
import com.fdkankan.scene.entity.SceneEditControls;
|
|
|
import com.fdkankan.scene.entity.SceneEditInfo;
|
|
|
import com.fdkankan.scene.entity.ScenePro;
|
|
|
+import com.fdkankan.scene.entity.SceneProEdit;
|
|
|
import com.fdkankan.scene.entity.SceneProExt;
|
|
|
import com.fdkankan.scene.factory.FloorLogoHandlerFactory;
|
|
|
import com.fdkankan.scene.factory.MusicHandlerFactory;
|
|
|
import com.fdkankan.scene.factory.ScreenshotHandlerFactory;
|
|
|
import com.fdkankan.scene.mapper.ISceneEditInfoMapper;
|
|
|
+import com.fdkankan.scene.service.ISceneDataDownloadService;
|
|
|
import com.fdkankan.scene.service.ISceneEditControlsService;
|
|
|
import com.fdkankan.scene.service.ISceneEditInfoService;
|
|
|
import com.fdkankan.scene.service.ISceneProExtService;
|
|
@@ -41,6 +47,7 @@ import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Map.Entry;
|
|
|
+import java.util.UUID;
|
|
|
import java.util.stream.Collectors;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -64,6 +71,8 @@ import org.springframework.web.multipart.MultipartFile;
|
|
|
@Service
|
|
|
public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper, SceneEditInfo> implements ISceneEditInfoService {
|
|
|
|
|
|
+ @Value("${oss.prefix.ali}")
|
|
|
+ private String prefixAli;
|
|
|
@Value("${oss.prefix.url}")
|
|
|
private String ossUrlPrefix;
|
|
|
@Value("${upload.type}")
|
|
@@ -82,6 +91,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
RedisUtil redisUtil;
|
|
|
@Autowired
|
|
|
private ISceneProExtService sceneProExtService;
|
|
|
+ @Autowired
|
|
|
+ private RedisLockUtil redisLockUtil;
|
|
|
+ @Autowired
|
|
|
+ ISceneDataDownloadService sceneDataDownloadService;
|
|
|
|
|
|
|
|
|
@Override
|
|
@@ -756,6 +769,169 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
|
|
|
return ResultData.ok();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public ResultData sceneSync(String num, String type, String floorPlanJson, String ajkJson, String cameraJson,
|
|
|
+ MultipartFile[] files) throws Exception {
|
|
|
+
|
|
|
+ String lockKey = String.format(RedisLockKey.LOCK_SCENE_SYNC, num);
|
|
|
+ Boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_2_HOUR);
|
|
|
+ if(!lock){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5036);
|
|
|
+ }
|
|
|
+ try {
|
|
|
+
|
|
|
+ ScenePro scenePro = sceneProService.findBySceneNum(num);
|
|
|
+ if(scenePro == null){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ }
|
|
|
+ SceneProExt sceneProExt = sceneProExtService.findBySceneProId(scenePro.getId());
|
|
|
+
|
|
|
+ //更新scene.json文件
|
|
|
+ String strsceneInfos = FileUtils.readFile(ConstantFilePath.SCENE_PATH + "data" + File.separator + "data" + num + File.separator + "scene.json");
|
|
|
+ if(strsceneInfos == null)
|
|
|
+ new File(ConstantFilePath.SCENE_PATH + "data" + File.separator + "data" + num + File.separator + "scene.json").createNewFile();
|
|
|
+
|
|
|
+ String path = sceneProExt.getDataSource();// /mnt/data/0662c5389/831989883441512448/4898cab04f8c_202104141602356060/
|
|
|
+ if(path != null && !"".equals(path) && path.startsWith("http")){
|
|
|
+ path = ConstantFilePath.BUILD_MODEL_PATH + File.separator + path.split("/")[path.split("/").length - 2];
|
|
|
+ }
|
|
|
+ String target = path + "_ajk"; // /mnt/data/0662c5389/831989883441512448/4898cab04f8c_202104141602356060_ajk
|
|
|
+ File editPath = new File(target);
|
|
|
+ if(!editPath.exists()){
|
|
|
+ editPath.mkdirs();
|
|
|
+ }
|
|
|
+
|
|
|
+ //创建文件夹软连接并且复制data.json和project.json
|
|
|
+ if(new File(target + File.separator + "capture").exists()){
|
|
|
+ new File(target + File.separator + "capture").delete();
|
|
|
+ }
|
|
|
+ if(new File(target + File.separator + "caches").exists()){
|
|
|
+ //删除link
|
|
|
+ new File(target + File.separator + "caches" + File.separator + "images").delete();
|
|
|
+ //删除所有文件
|
|
|
+ FileUtils.delAllFile(target + File.separator + "caches");
|
|
|
+ }
|
|
|
+ if(new File(target + File.separator + "results").exists()){
|
|
|
+ FileUtils.delAllFile(target + File.separator + "results");
|
|
|
+ }
|
|
|
+ //创建文件夹,并link文件夹
|
|
|
+ new File(target + File.separator + "caches").mkdirs();
|
|
|
+ CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
|
|
|
+ if(new File(path + File.separator + "caches" + File.separator + "images").exists()){
|
|
|
+ CreateObjUtil.createSoftConnection(path + File.separator + "caches" + File.separator + "images", target + File.separator + "caches" + File.separator + "images");
|
|
|
+ }
|
|
|
+
|
|
|
+ FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
|
|
|
+ FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
|
|
|
+
|
|
|
+ //data.json增加extras为执行重建算法
|
|
|
+ String project = FileUtils.readFile(target + File.separator+"project.json");
|
|
|
+ if(project != null){
|
|
|
+ JSONObject projectJson = JSONObject.parseObject(project);
|
|
|
+ projectJson.put("parent", projectJson.get("uuid"));
|
|
|
+ projectJson.put("uuid", UUID.randomUUID().toString());
|
|
|
+ projectJson.put("time", System.currentTimeMillis());
|
|
|
+ FileUtils.writeFile(path + File.separator + "project.json", projectJson.toString());
|
|
|
+ }
|
|
|
+
|
|
|
+ String data = FileUtils.readFile(target + File.separator+"data.json");
|
|
|
+ if(data != null){
|
|
|
+ JSONObject floorplanJson = new JSONObject();
|
|
|
+ floorplanJson.put("has_floor_ajk_json", true);
|
|
|
+ floorplanJson.put("has_vision_txt", true);
|
|
|
+ floorplanJson.put("has_floorplan_json", true);
|
|
|
+
|
|
|
+ JSONObject dataJson = JSONObject.parseObject(data);
|
|
|
+ dataJson.put("extras", floorplanJson);
|
|
|
+ //V5表示不需要生成high,low文件
|
|
|
+ dataJson.put("skybox_type", "SKYBOX_V8");
|
|
|
+ dataJson.put("split_type", "SPLIT_V10");
|
|
|
+ FileUtils.writeFile(target + File.separator+"data.json", new String(dataJson.toString().getBytes(), "UTF-8"));
|
|
|
+ }
|
|
|
+
|
|
|
+ //文件上传的位置可以自定义
|
|
|
+ log.info("画墙重建模型开始");
|
|
|
+ File targetFile = new File(target + File.separator + "extras" + File.separator + "floor_ajk.json");
|
|
|
+ if(!targetFile.getParentFile().exists()){
|
|
|
+ targetFile.getParentFile().mkdirs();
|
|
|
+ }
|
|
|
+ if(targetFile.exists()){
|
|
|
+ FileUtils.deleteFile(target + File.separator + "extras" + File.separator + "floor_ajk.json");
|
|
|
+ }
|
|
|
+ // 保存
|
|
|
+ FileUtils.writeFile(target + File.separator + "extras" + File.separator + "floorplan.json", new String(floorPlanJson.getBytes(), "UTF-8"));
|
|
|
+
|
|
|
+ FileUtils.writeFile(target + File.separator + "extras" + File.separator + "floor_ajk.json", new String(ajkJson.getBytes(), "UTF-8"));
|
|
|
+ FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+num + File.separator + "floor_ajk.json", new String(ajkJson.getBytes(), "UTF-8"));
|
|
|
+
|
|
|
+ FileUtils.writeFile(target + File.separator + "extras" + File.separator + "vision.txt", new String(cameraJson.getBytes(), "UTF-8"));
|
|
|
+ FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+num + File.separator + "camera.json", new String(cameraJson.getBytes(), "UTF-8"));
|
|
|
+
|
|
|
+ for(int i = 0; i < files.length; i ++){
|
|
|
+
|
|
|
+ File cadImg = new File(target + File.separator + "extras" + File.separator + "Floorplans/" + files[i].getOriginalFilename());
|
|
|
+ if(!cadImg.getParentFile().exists()){
|
|
|
+ cadImg.getParentFile().mkdirs();
|
|
|
+ }
|
|
|
+ if(cadImg.exists())
|
|
|
+ {
|
|
|
+ cadImg.delete();
|
|
|
+ }
|
|
|
+
|
|
|
+ files[i].transferTo(cadImg);
|
|
|
+ }
|
|
|
+ //下载封面图
|
|
|
+ FileUtils.downLoadFromUrl(scenePro.getThumb() + "?t=" + System.currentTimeMillis(),
|
|
|
+ "Cover.png", target + File.separator + "extras" + File.separator + "CoverImage");
|
|
|
+ //转换成jpg
|
|
|
+ FileUtils.pngToJpg(target + File.separator + "extras" + File.separator + "CoverImage/Cover.png",
|
|
|
+ target + File.separator + "extras" + File.separator + "CoverImage/Cover.jpg");
|
|
|
+
|
|
|
+ //安居客算法运行
|
|
|
+ log.info("安居客算法:开始建模——"+num);
|
|
|
+ CreateObjUtil.build3dModel(target , "1");
|
|
|
+ if(!new File(target + File.separator + "results" + File.separator + "upload.json").exists()){
|
|
|
+ return ResultData.error(ErrorCode.FAILURE_CODE_5042);
|
|
|
+ }
|
|
|
+
|
|
|
+ String zipPath = target + File.separator + "results/" + num + ".zip";
|
|
|
+ new File(zipPath).delete();
|
|
|
+
|
|
|
+// FileUtils.zipFile(zipPath, target + File.separator + "results/ajk/");
|
|
|
+ String command = "bash /opt/ossutil/gzip.sh " + zipPath.replace(".zip", "") + " " + target + File.separator + "results/ajk/";
|
|
|
+ log.info("压缩文件:" + command);
|
|
|
+ CreateObjUtil.callshell(command);
|
|
|
+
|
|
|
+ if(!new File(zipPath).exists()){
|
|
|
+ return ResultData.error(ErrorCode.FAILURE_CODE_5043);
|
|
|
+ }
|
|
|
+ String fileMD5 = FileMd5Util.getFileMD5(new File(zipPath));
|
|
|
+
|
|
|
+ uploadToOssUtil.upload(zipPath, "data_download/" + num + ".zip");
|
|
|
+
|
|
|
+ SceneDataDownload sceneDataDownload = sceneDataDownloadService.findBySceneNum(num);
|
|
|
+ if(sceneDataDownload == null){
|
|
|
+ sceneDataDownload = new SceneDataDownload();
|
|
|
+ sceneDataDownload.setNum(num);
|
|
|
+ sceneDataDownload.setDownloadPath(prefixAli + "data_download/" + num + ".zip");
|
|
|
+ sceneDataDownload.setFileMd5(fileMD5);
|
|
|
+ sceneDataDownloadService.save(sceneDataDownload);
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ sceneDataDownload.setFileMd5(fileMD5);
|
|
|
+ sceneDataDownload.setUpdateTime(Calendar.getInstance().getTime());
|
|
|
+ sceneDataDownloadService.updateById(sceneDataDownload);
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("画墙重建模型失败...", e);
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5039);
|
|
|
+ }finally {
|
|
|
+ redisLockUtil.unlockLua(lockKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
private void updateBoxVideos(SceneEditInfo sceneEditInfo, Long sceneProId, String boxVideos){
|
|
|
if(StrUtil.isEmpty(boxVideos)){
|
|
|
return;
|