package com.fdkankan.scene.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ZipUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fdkankan.common.constant.ErrorCode; import com.fdkankan.common.constant.RecStatus; import com.fdkankan.common.exception.BusinessException; import com.fdkankan.common.util.FileUtils; import com.fdkankan.fyun.face.FYunFileServiceInterface; import com.fdkankan.model.constants.ConstantFilePath; import com.fdkankan.model.constants.UploadFilePath; import com.fdkankan.model.utils.CreateObjUtil; import com.fdkankan.scene.bean.EulerAngles; import com.fdkankan.scene.bean.ResponseScene; import com.fdkankan.scene.common.house.JsonToHouseUtil; import com.fdkankan.scene.entity.Scene3dfamily; import com.fdkankan.scene.entity.ScenePro; import com.fdkankan.scene.mapper.IScene3dfamilyMapper; import com.fdkankan.scene.service.IScene3dfamilyService; import com.fdkankan.scene.service.ISceneProService; import com.fdkankan.web.response.Result; import com.fdkankan.web.response.ResultData; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.File; import java.io.FileWriter; import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; /** * Created by Hb_zzZ on 2019/6/28. */ @Slf4j @Service public class Scene3dfamilyServiceImpl extends ServiceImpl implements IScene3dfamilyService { private static String DIR_NAME = "downloads/furnished/"; @Autowired private ISceneProService sceneProService; @Autowired private FYunFileServiceInterface fYunFileService; @Value("${fyun.host}") private String fyunHost; @Override public Result createZip(ScenePro sceneProEntity,long userId) throws Exception{ Scene3dfamily scene3dFamilyEntity = this.findSceneNumByNum(sceneProEntity.getNum(),0); String path = sceneProEntity.getDataSource() + "_3df" + File.separator + sceneProEntity.getNum(); try { if(scene3dFamilyEntity == null){ throw new BusinessException(ErrorCode.FAILURE_CODE_5032); } log.info("三维家 信息保存 路径 : " + path); //创建文件夹 FileUtils.createDir(path); //生成vision.json this.downloadVisionData(sceneProEntity); String dataBuf = "data" + File.separator + "data" + sceneProEntity.getNum() + File.separator; this.visionTxtToPano(ConstantFilePath.SCENE_PATH + dataBuf //本地路径 + "vision.json",path+ File.separator +"scene"+ File.separator+ dataBuf ); //拉取data fYunFileService.downloadFileByCommand(path + File.separator + "scene" + File.separator + "data" + File.separator + "data" + sceneProEntity.getNum(), "data" + File.separator + "data" + sceneProEntity.getNum() + File.separator); //转换house.json Integer bo = JsonToHouseUtil.ToHouseJson(path + File.separator + "scene" + File.separator + dataBuf); if(bo!=0){ switch (bo){ case -1: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "点位数据为空"); case -2: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "点位数据重复"); case -3: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "转换异常"); case -4: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "源文件不存在"); } } //写入 scene.json 改名为 getinfo.json ResultData result = sceneProService.getInfo(sceneProEntity.getNum()); ResponseScene responseScene = (ResponseScene) result.getData(); JSONObject dataJson = (JSONObject) JSONObject.toJSON(responseScene); FileUtils.writeFile(path + File.separator + "scene" + File.separator + "data" + File.separator + "data" + sceneProEntity.getNum() + File.separator + "getinfo.json", dataJson.toString()); //下载场景封面图 String ossImagePath = "images" + File.separator + "images" + sceneProEntity.getNum() + File.separator; String ImagePath = path + File.separator + "scene" + File.separator + "images" + File.separator + "images" + sceneProEntity.getNum(); FileUtils.downLoadFromUrl(sceneProEntity.getThumb(),"cover.jpg", ImagePath); //拉取images fYunFileService.downloadFile(ossImagePath + "floorLogoImg.png", ImagePath + "/floorLogoImg.png"); fYunFileService.downloadFile(ossImagePath + "floorplan.png", ImagePath + "/floorplan.png"); fYunFileService.downloadFile(ossImagePath + "logo-main.png", ImagePath + "/logo-main.png"); fYunFileService.downloadFile(ossImagePath + "logo-main-en.png", ImagePath + "/logo-main-en.png"); fYunFileService.downloadFile(ossImagePath + "smallPic.jpg", ImagePath + "/smallPic.jpg"); fYunFileService.downloadFile(ossImagePath + "thumbBigImg.jpg", ImagePath + "/thumbBigImg.jpg"); fYunFileService.downloadFile(ossImagePath + "thumbSmallImg.jpg", ImagePath + "/thumbSmallImg.jpg"); fYunFileService.downloadFileByCommand(ImagePath + "/pan", ossImagePath + "pan"); // 异步执行 CompletableFuture.runAsync(()->{ //压缩zip try { log.info("开始异步执行打包逻辑……"); //获取六面体图 fYunFileService.downloadFileByCommand(ImagePath + "/tiles", ossImagePath + "tiles"); //拉取video fYunFileService.downloadFileByCommand(path + File.separator + "scene" + File.separator + "video" + File.separator + "video" + sceneProEntity.getNum(), "video" + File.separator + "video" + sceneProEntity.getNum() + File.separator); //拉取voice fYunFileService.downloadFileByCommand(path + File.separator + "scene" + File.separator + "voice" + File.separator + "voice" + sceneProEntity.getNum(), "voice" + File.separator + "voice" + sceneProEntity.getNum() + File.separator); ZipUtil.zip(path, path + ".zip"); log.info("三维家 zip完成 : " + path); //上传oss // 上传到阿里云sso fYunFileService.uploadFileByCommand(path + ".zip", DIR_NAME + sceneProEntity.getNum() + ".zip"); log.info("upload success"); String url = fyunHost + DIR_NAME + sceneProEntity.getNum() + ".zip"; log.info("upload url: {}" + url); scene3dFamilyEntity.setZipLink(url); scene3dFamilyEntity.setStatus(1); scene3dFamilyEntity.setZipEndTime(new Date()); scene3dFamilyEntity.setUpdateTime(new Date()); this.updateById(scene3dFamilyEntity); } catch (Exception e) { e.printStackTrace(); scene3dFamilyEntity.setStatus(2); scene3dFamilyEntity.setZipEndTime(new Date()); scene3dFamilyEntity.setUpdateTime(new Date()); this.updateById(scene3dFamilyEntity); }finally { FileUtils.deleteDirectory(path); FileUtils.deleteFile(path + ".zip"); } }); }catch (Exception e){ scene3dFamilyEntity.setStatus(2); scene3dFamilyEntity.setZipEndTime(new Date()); scene3dFamilyEntity.setUpdateTime(new Date()); this.updateById(scene3dFamilyEntity); e.printStackTrace(); throw e; } return Result.success(); } @Override public Scene3dfamily findSceneNumByNum(String num,Integer status){ LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(Scene3dfamily::getSceneNum, num); if(status != null){ wrapper.eq(Scene3dfamily::getStatus, status); } List list = this.list(wrapper); if(CollUtil.isEmpty(list)){ return null; } return list.get(0); } @Override public JSONObject findSceneNumByNum2(ScenePro sceneProEntity){ JSONObject jsonObject = new JSONObject(); Scene3dfamily scene3dFamilyEntity = this.findSceneNumByNum(sceneProEntity.getNum(), null); if(scene3dFamilyEntity!=null){ jsonObject.put("url",scene3dFamilyEntity.getZipLink() == null ?"":scene3dFamilyEntity.getZipLink()); jsonObject.put("status",scene3dFamilyEntity.getStatus()); }else{ jsonObject.put("url",""); jsonObject.put("status",3); } //验证是否在打包 return jsonObject; } @Override public void updateSceneNumByNum (String sceneNum){ this.update(new LambdaUpdateWrapper().set(Scene3dfamily::getRecStatus, RecStatus.DISABLE.code()).eq(Scene3dfamily::getSceneNum, sceneNum)); } private void downloadVisionData(ScenePro sceneProEntity) throws Exception { StringBuffer dataBuf = new StringBuffer().append("data").append(File.separator) .append("data").append(sceneProEntity.getNum()).append(File.separator); StringBuffer imagesBuf = new StringBuffer().append("images").append(File.separator) .append("images").append(sceneProEntity.getNum()).append(File.separator); StringBuffer dataBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(dataBuf.toString()); StringBuffer imagesBuffer = new StringBuffer(ConstantFilePath.SCENE_PATH).append(imagesBuf.toString()); fYunFileService.downloadFile(imagesBuf.toString() + "vision.modeldata", dataBuffer.toString() + "vision.modeldata"); File file = new File(dataBuffer.toString() + "vision.modeldata"); if(!file.exists()) { throw new BusinessException(ErrorCode.FAILURE_CODE_5012); } CreateObjUtil.convertVisionmodeldataToTxt(dataBuffer.toString() + "vision.modeldata", dataBuffer.toString() + "vision.json"); fYunFileService.uploadFile(dataBuffer.toString() + "vision.json", dataBuf.toString() + "vision.json"); } private void downloadVisionData(String sceneNum) throws Exception { String dataBuf = String.format(UploadFilePath.IMG_VIEW_PATH,sceneNum); String dataBuffer = String.format(ConstantFilePath.SCENE_IMAGES_PATH_V4,sceneNum); fYunFileService.downloadFile(dataBuf.toString() + "vision.modeldata", dataBuffer.toString() + "vision.modeldata"); File file = new File(dataBuffer.toString() + "vision.modeldata"); if(!file.exists()) { throw new BusinessException(ErrorCode.FAILURE_CODE_5012); } CreateObjUtil.convertVisionmodeldataToTxt(dataBuffer.toString() + "vision.modeldata", dataBuffer.toString() + "vision.json"); fYunFileService.uploadFile(dataBuffer.toString() + "vision.json", dataBuf.toString() + "vision.json"); } /** * * @param src vision.json 路径 * @param tag pano.json 目录路径 */ private void visionTxtToPano(String src,String tag){ try { log.info("QuaternionToEulerUtil---------src:{},tag:{}",src,tag); String str = FileUtil.readUtf8String(src); JSONObject jsonObject = JSONObject.parseObject(str); JSONArray sweepLocations = jsonObject.getJSONArray("sweepLocations"); for (Object o : sweepLocations) { JSONObject obj = (JSONObject) o; JSONObject pose = obj.getJSONObject("pose"); JSONObject rotation = pose.getJSONObject("rotation"); JSONObject translation = pose.getJSONObject("translation"); Double w = rotation.getDouble("w"); Double x = rotation.getDouble("x"); Double y = rotation.getDouble("y"); Double z = rotation.getDouble("z"); Double x1 = translation.getDouble("x"); Double y1 = translation.getDouble("y"); Double z1 = translation.getDouble("z"); JSONObject newRotation = new JSONObject(); EulerAngles eulerAngles = new EulerAngles(w,x,y,z,x1,y1,z1); newRotation.put("x",eulerAngles.x); newRotation.put("y",eulerAngles.y); newRotation.put("z",eulerAngles.z); pose.put("target",newRotation); pose.remove("rotation"); } File file = new File(tag); if(!file.exists()){ file.mkdirs(); } FileWriter fw = new FileWriter(tag+ "pano.json"); fw.write(jsonObject.toJSONString()); fw.close(); }catch (Exception e){ log.error("QuaternionToEulerUtil---------error:",e); e.printStackTrace(); } } @Override public Result createZip(String sceneNum, String dataSource, String thumb, Long userId) throws Exception { Scene3dfamily scene3dFamilyEntity = this.findSceneNumByNum(sceneNum,0); String path = dataSource + "_3df" + File.separator + sceneNum; try { if(scene3dFamilyEntity == null){ throw new BusinessException(ErrorCode.FAILURE_CODE_5032); } log.info("三维家 信息保存 路径 : " + path); //创建文件夹 FileUtils.createDir(path); //生成vision.json this.downloadVisionData(sceneNum); String dataBuffer = String.format(ConstantFilePath.SCENE_IMAGES_PATH_V4,sceneNum); String dataBuf = "data" + File.separator + "data" + sceneNum + File.separator; this.visionTxtToPano(dataBuffer + "vision.json",path+ File.separator +"scene"+ File.separator+ dataBuf ); //拉取data fYunFileService.downloadFileByCommand(path + File.separator + "scene" + File.separator + "data" + File.separator + "data" + sceneNum, String.format(UploadFilePath.DATA_VIEW_PATH,sceneNum)); // 下载用户的户型图数据 if (fYunFileService.fileExist(String.format(UploadFilePath.USER_VIEW_PATH, sceneNum) + "floorplan.json")) { fYunFileService.downloadFile(String.format(UploadFilePath.USER_VIEW_PATH, sceneNum) + "floorplan.json", path + File.separator + "scene" + File.separator + "data" + File.separator + "data" + sceneNum+"/floorplan.json" ); } //转换house.json Integer bo = JsonToHouseUtil.ToHouseJsonV4(path + File.separator + "scene" + File.separator + dataBuf); if (bo != 0) { switch (bo) { case -1: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "点位数据为空"); case -2: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "点位数据重复"); case -3: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "转换异常"); case -4: throw new BusinessException(ErrorCode.FAILURE_CODE_5029.code(), "源文件不存在"); } } //下载 scene.json 改名为 getinfo.json fYunFileService.downloadFile(String.format(UploadFilePath.DATA_VIEW_PATH, sceneNum) + "scene.json", path + File.separator + "scene" + File.separator + "data" + File.separator + "data" + sceneNum + File.separator + "getinfo.json"); //下载场景封面图 String ossImagePath = String.format(UploadFilePath.IMG_VIEW_PATH, sceneNum); String ImagePath = path + File.separator + "scene" + File.separator + "images" + File.separator + "images" + sceneNum; FileUtils.downLoadFromUrl(thumb,"cover.jpg", ImagePath); //拉取images fYunFileService.downloadFile(ossImagePath + "floorLogoImg.png", ImagePath + "/floorLogoImg.png"); fYunFileService.downloadFile(ossImagePath + "floorplan.png", ImagePath + "/floorplan.png"); fYunFileService.downloadFile(ossImagePath + "logo-main.png", ImagePath + "/logo-main.png"); fYunFileService.downloadFile(ossImagePath + "logo-main-en.png", ImagePath + "/logo-main-en.png"); fYunFileService.downloadFile(ossImagePath + "smallPic.jpg", ImagePath + "/smallPic.jpg"); fYunFileService.downloadFile(ossImagePath + "thumbBigImg.jpg", ImagePath + "/thumbBigImg.jpg"); fYunFileService.downloadFile(ossImagePath + "thumbSmallImg.jpg", ImagePath + "/thumbSmallImg.jpg"); fYunFileService.downloadFileByCommand(ImagePath + "/pan", ossImagePath + "pan"); // 异步执行 CompletableFuture.runAsync(()->{ //压缩zip try { log.info("开始异步执行打包逻辑……"); //获取六面体图 fYunFileService.downloadFileByCommand(ImagePath + "/tiles", ossImagePath + "tiles"); //拉取video fYunFileService.downloadFileByCommand(path + File.separator + "scene" + File.separator + "video" + File.separator + "video" + sceneNum, String.format(UploadFilePath.VIDEOS_VIEW_PATH, sceneNum)); //拉取voice fYunFileService.downloadFileByCommand(path + File.separator + "scene" + File.separator + "voice" + File.separator + "voice" + sceneNum, String.format(UploadFilePath.VOICE_VIEW_PATH, sceneNum)); ZipUtil.zip(path, path + ".zip"); log.info("三维家 zip完成 : " + path); //上传oss // 上传到阿里云sso fYunFileService.uploadFileByCommand(path + ".zip", DIR_NAME + sceneNum + ".zip"); log.info("upload success"); String url = fyunHost + DIR_NAME + sceneNum + ".zip"; log.info("upload url: {}" + url); scene3dFamilyEntity.setZipLink(url); scene3dFamilyEntity.setStatus(1); scene3dFamilyEntity.setZipEndTime(new Date()); scene3dFamilyEntity.setUpdateTime(new Date()); this.updateById(scene3dFamilyEntity); } catch (Exception e) { e.printStackTrace(); scene3dFamilyEntity.setStatus(2); scene3dFamilyEntity.setZipEndTime(new Date()); scene3dFamilyEntity.setUpdateTime(new Date()); this.updateById(scene3dFamilyEntity); }finally { FileUtils.deleteDirectory(path); FileUtils.deleteFile(path + ".zip"); } }); }catch (Exception e){ scene3dFamilyEntity.setStatus(2); scene3dFamilyEntity.setZipEndTime(new Date()); scene3dFamilyEntity.setUpdateTime(new Date()); this.updateById(scene3dFamilyEntity); e.printStackTrace(); throw e; } return Result.success(); } }