package com.fdkankan.jp.xspace.service.impl; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; 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); List fileList = fYunFileService.listRemoteFiles(String.format(OSSPathConstant.SCENE_VIEW_DATA_DATA, num) + "mesh/"); fileList.stream().forEach(v->{ fYunFileService.downloadFile(v, localMeshPath); }); return workPath; } private void callUnity(String workPath){ UnityConfig unityConfig = unityConfigService.getOne(new LambdaQueryWrapper<>()); String cmdStr = UnityConstant.EXEC_UNITY_FORMAT.replace("@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()); //上传mesh List fileList = FileUtil.loopFiles(workPath); fileList.parallelStream().forEach(v->{ fYunFileService.uploadFile(v.getAbsolutePath(), v.getAbsolutePath().replace(workPath, xspaceSceneOssPath)); }); //上传文件映射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 = xspaceFloorplanPath + "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, 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; } }