package com.fdkankan.jp.xspace.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fdkankan.common.constant.CommonStatus; import com.fdkankan.common.util.CmdUtils; import com.fdkankan.fyun.face.FYunFileServiceInterface; import com.fdkankan.jp.xspace.common.constant.NasPathConstant; import com.fdkankan.jp.xspace.common.constant.OSSPathConstant; import com.fdkankan.jp.xspace.common.constant.UnityConstant; import com.fdkankan.jp.xspace.common.exception.PackException; import com.fdkankan.jp.xspace.entity.SceneXspace; import com.fdkankan.jp.xspace.entity.UnityConfig; import com.fdkankan.jp.xspace.service.IUnityConfigService; import com.fdkankan.jp.xspace.service.IUnityService; import com.fdkankan.jp.xspace.vo.SceneEditControlsVO; import com.fdkankan.jp.xspace.vo.SceneInfoVO; import com.fdkankan.redis.constant.RedisKey; import com.fdkankan.redis.util.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.io.File; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; @Slf4j @Service public class UnityServiceImpl implements IUnityService { @Resource private FYunFileServiceInterface fYunFileService; @Autowired private IUnityConfigService unityConfigService; @Resource private RedisUtil redisUtil; @Override public void packXspace(SceneXspace bean){ //准备资源 String workPath = this.pre(bean); //调用unity打包 this.callUnity(workPath); //文件处理/上传 this.dealFileAndUpload(bean, workPath); } private String pre(SceneXspace bean){ String num = bean.getNum(); String workPath = NasPathConstant.UNITY_WORK_PATH + bean.getNum() + "/" + bean.getSerial() + "/"; String localMeshPath = workPath + "mesh/"; FileUtil.mkdir(localMeshPath); String meshKey = String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, num) + "mesh/"; List fileList = fYunFileService.listRemoteFiles(meshKey); fileList.stream().forEach(v->{ fYunFileService.downloadFile(v, localMeshPath + v.replace(meshKey, "")); }); //如果有三维模型,需要下载三维模型原始文件 String sceneJsonKey = String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, bean.getNum()) + "scene.json"; String sceneJsonStr = fYunFileService.getFileContent(sceneJsonKey); JSONObject sceneJsonObj = JSON.parseObject(sceneJsonStr); String boxModelsStr = sceneJsonObj.getString("boxModels"); if(StrUtil.isNotEmpty(boxModelsStr)){ List jsonObjects = JSON.parseArray(boxModelsStr, JSONObject.class); if(CollUtil.isNotEmpty(jsonObjects)){ String userViewPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_USER, bean.getNum()); jsonObjects.stream().forEach(item->{ String sid = item.getString("sid"); String origObjPath = userViewPath + "boxModels/" + sid + "/"; List objFileList = fYunFileService.listRemoteFiles(origObjPath); if(CollUtil.isNotEmpty(objFileList)){ objFileList.stream().forEach(objKey->{ fYunFileService.downloadFile(objKey, workPath + objKey.replace(OSSPathConstant.SCENE_VIEW_DATA + bean.getNum() + "/", "")); }); } }); } } return workPath; } private void callUnity(String workPath){ UnityConfig unityConfig = unityConfigService.getOne(new LambdaQueryWrapper<>()); String cmdStr = UnityConstant.EXEC_UNITY_FORMAT.replaceAll("@workPath@",workPath).replace("@serial@", unityConfig.getSerial()).replace("@account@", unityConfig.getAccount()).replace("@pwd@", unityConfig.getPassword()); // String.format(UnityConstant.EXEC_UNITY_FORMAT, workPath, unityConfig.getSerial(), unityConfig.getAccount(), unityConfig.getPassword()); try { CmdUtils.callLine(cmdStr); }catch (Exception e){ log.error("unity执行报错,workPath:{}", workPath, e); throw new PackException("unity执行报错"); } String resultFilePath = workPath + "result.json"; boolean completed = this.checkComputeCompleted(resultFilePath, 3, 300); if(!completed){ throw new PackException("unity异常,没有生成result.json"); } String resultStr = FileUtil.readUtf8String(resultFilePath); JSONObject resultObj = JSON.parseObject(resultStr); boolean success = resultObj.getBooleanValue("success"); if(!success){ throw new PackException(resultObj.getString("message")); } } private boolean checkComputeCompleted(String uploadJsonPath, int maxCheckTimes, long waitTime){ int checkTimes = 1; boolean exist = false; do { if(new File(uploadJsonPath).exists()){ exist = true; break; } try { Thread.sleep(waitTime); } catch (InterruptedException e) { throw new RuntimeException(e); } ++checkTimes; }while (checkTimes <= maxCheckTimes); return exist; } private void dealFileAndUpload(SceneXspace bean, String workPath){ String xspaceSceneOssPath = String.format(OSSPathConstant.XSPACE_SCENE_FORMAT,bean.getNum(), bean.getSerial()); //复制user String sourceUserPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_USER, bean.getNum()); String targetUserPath = xspaceSceneOssPath + "user/"; fYunFileService.copyFileInBucket(sourceUserPath, targetUserPath); //复制data String sourceDataPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, bean.getNum()); String targetDataPath = xspaceSceneOssPath + "data/"; fYunFileService.copyFileInBucket(sourceDataPath, targetDataPath); //删除mesh fYunFileService.deleteFolder(targetDataPath + "mesh"); //复制images String sourceImagesPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_IMAGES, bean.getNum()); String targetImagesPath = xspaceSceneOssPath + "images/"; fYunFileService.copyFileInBucket(sourceImagesPath, targetImagesPath); //复制video String sourceVideoPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_VIDEO, bean.getNum()); String targetVideoPath = xspaceSceneOssPath + "video/"; fYunFileService.copyFileInBucket(sourceVideoPath, targetVideoPath); //复制vioce String sourceVoicePath = String.format(OSSPathConstant.SCENE_VIEW_DATA_VOICE, bean.getNum()); String targetVoicePath = xspaceSceneOssPath + "vioce/"; fYunFileService.copyFileInBucket(sourceVoicePath, targetVoicePath); //上传mesh List fileList = FileUtil.loopFiles(workPath); fileList.parallelStream().forEach(v->{ fYunFileService.uploadFile(v.getAbsolutePath(), v.getAbsolutePath().replace(workPath, targetDataPath)); }); //上传文件映射json // fYunFileService.uploadFile(workPath + "xxx.json", xspaceSceneOssPath + "xxx.json"); // //复制skybox图 // String sourceImagesPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_IMAGES, bean.getNum()) + "tiles/4k/"; // String targetImagesPath = xspaceSceneOssPath + "images/"; // fYunFileService.copyFileInBucket(sourceImagesPath, targetImagesPath); // // //复制user // String sourceUserPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_USER, bean.getNum()); // String targetUserPath = xspaceSceneOssPath + "user/"; // fYunFileService.copyFileInBucket(sourceUserPath, targetUserPath); // // //上传getInfo.json // String getInfoKey = xspaceSceneOssPath + "getInfo.json"; // SceneInfoVO getInfoJson = this.getSceneInfo4View(bean.getNum()); // fYunFileService.uploadFile(JSON.toJSONString(getInfoJson).toString().getBytes(StandardCharsets.UTF_8), getInfoKey); // // //上传floorplan.json // String floorplanPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, bean.getNum()) + "floorplan.json"; // if(getInfoJson.getFloorPlanUser() == 1){ // floorplanPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_USER, bean.getNum()) + "floorplan.json"; // } // String xspaceFloorplanPath = xspaceSceneOssPath + "floorplan.json"; // fYunFileService.copyFileInBucket(floorplanPath, xspaceFloorplanPath); // // //复制vision.modeldata // String sourceVisionPath = String.format(OSSPathConstant.SCENE_VIEW_DATA_IMAGES, bean.getNum()) + "vision.modeldata"; // String tagetVisionPath = xspaceSceneOssPath + "vision.modeldata"; // fYunFileService.copyFileInBucket(sourceVisionPath, tagetVisionPath); } private SceneInfoVO getSceneInfo4View(String num){ String key = String.format(RedisKey.SCENE_JSON, num); String sceneJson = redisUtil.get(key); SceneInfoVO sceneInfoVO = null; //先查询redis if(StrUtil.isEmpty(sceneJson)) { String objectName = String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, num) + "scene.json"; sceneJson = fYunFileService.getFileContent(objectName); } sceneInfoVO = JSON.parseObject(sceneJson, SceneInfoVO.class); sceneInfoVO.setScenePassword(null); if(Objects.isNull(sceneInfoVO.getFloorPlanAngle())){ sceneInfoVO.setFloorPlanAngle(0f); } if(Objects.isNull(sceneInfoVO.getFloorPlanCompass())){ sceneInfoVO.setFloorPlanCompass(0f); } SceneEditControlsVO controls = sceneInfoVO.getControls(); if(Objects.isNull(controls.getShowShare())){ controls.setShowShare(CommonStatus.YES.code().intValue()); } if(Objects.isNull(controls.getShowCapture())){ controls.setShowCapture(CommonStatus.YES.code().intValue()); } if(Objects.isNull(controls.getShowBillboardTitle())){ controls.setShowBillboardTitle(CommonStatus.YES.code().intValue()); } return sceneInfoVO; } }