package com.fdkankan.openApi.service.www.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fdkankan.common.constant.*;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.DateUtil;
import com.fdkankan.common.util.FileUtils;
import com.fdkankan.fyun.config.FYunFileConfig;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.model.constants.ConstantFilePath;
import com.fdkankan.model.constants.UploadFilePath;
import com.fdkankan.model.utils.ComputerUtil;
import com.fdkankan.model.utils.CreateObjUtil;
import com.fdkankan.openApi.bean.www.SceneJsonBean;
import com.fdkankan.openApi.common.PageInfo;
import com.fdkankan.openApi.entity.www.*;
import com.fdkankan.openApi.mapper.www.IScenePlusMapper;
import com.fdkankan.openApi.service.www.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.openApi.vo.www.CreateFicTitiousSceneParamVO;
import com.fdkankan.openApi.vo.www.SceneEditControlsVO;
import com.fdkankan.openApi.vo.www.SceneVO;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.web.response.ResultData;
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.util.*;
import java.util.stream.Collectors;
/**
*
* 场景主表 服务实现类
*
*
* @author
* @since 2023-02-15
*/
@DS("www")
@Service
public class ScenePlusServiceImpl extends ServiceImpl implements IScenePlusService {
@Value("${main.url}")
private String mainUrl;
@Value("${scene.pro.new.url}")
private String sceneUrl;
@Autowired
private FYunFileServiceInterface fYunFileService;
@Autowired
private ISceneEditInfoService sceneEditInfoService;
@Autowired
private IScenePlusExtService scenePlusExtService;
@Autowired
private ISceneEditInfoExtService sceneEditInfoExtService;
@Autowired
private ISceneEditControlsService sceneEditControlsService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private ICameraService cameraService;
@Autowired
private FYunFileConfig fYunFileConfig;
@Override
public ScenePlus getByNum(String num) {
return this.getOne(new LambdaQueryWrapper().eq(ScenePlus::getNum, num));
}
@Override
public ResultData createVirtualScene(CreateFicTitiousSceneParamVO param) throws Exception {
this.checkParams4createVirtualScene(param);
this.buildScene4CreateVirtualScene(param);
String website = this.updateScene4CreateVirtualScene(param);
return ResultData.ok(website);
}
private void checkParams4createVirtualScene(CreateFicTitiousSceneParamVO param){
SceneFrom sceneFrom = SceneFrom.get(param.getSceneFrom());
if(Objects.isNull(sceneFrom)){
throw new BusinessException(ErrorCode.PARAM_ERROR.code(), "sceneFrom错误");
}
Integer sceneSource = null;
switch (sceneFrom){
case SXZ:
sceneSource = SceneSource.YJHZ.code();
break;
}
if(Objects.isNull(sceneSource)){
throw new BusinessException(ErrorCode.PARAM_ERROR.code(), "sceneFrom错误");
}
param.setSceneSource(sceneSource);
}
private void buildScene4CreateVirtualScene(CreateFicTitiousSceneParamVO param) throws Exception {
String num = param.getNum();
String objName = param.getObjName();
String mtlName = param.getMtlName();
String localImagePath = String.format(ConstantFilePath.SCENE_IMAGES_PATH_V4, num);
String ossImagePath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
String ossObjPath = ossImagePath + objName;
if(!fYunFileService.fileExist(ossObjPath)){
throw new BusinessException(ErrorCode.FAILURE_CODE_4001, objName);
}
String ossMtlPath = ossImagePath + mtlName;
if(!fYunFileService.fileExist(ossMtlPath)){
throw new BusinessException(ErrorCode.FAILURE_CODE_4001, mtlName);
}
String ossTexturePath = ossImagePath + "dacf7dfa24ae47fab8fcebfe4dc41ab9_50k_texture_jpg_high1/";
// if(CollUtil.isEmpty(fYunFileService.listRemoteFiles(ossTexturePath))){
// throw new BusinessException(ErrorCode.FAILURE_CODE_4001, "贴图");
// }
String ossVisionTxtPath = ossImagePath + "vision.txt";
if(!fYunFileService.fileExist(ossVisionTxtPath)){
throw new BusinessException(ErrorCode.FAILURE_CODE_4001, "vision.txt");
}
FileUtil.del(localImagePath + "/result/");
FileUtil.del(localImagePath + "extras/");
fYunFileService.downloadFile(ossObjPath, localImagePath + "extras/" + "mesh.obj");
fYunFileService.downloadFile(ossMtlPath, localImagePath + "extras/" + mtlName);
fYunFileService.downloadFileByCommand(localImagePath + "extras/", ossTexturePath);
fYunFileService.downloadFile(ossVisionTxtPath, localImagePath + "vision.txt");
//创建data.json
JSONObject dataJson = new JSONObject();
dataJson.put("obj2txt", true);
dataJson.put("split_type", "SPLIT_V6");
dataJson.put("data_describe", "double spherical");
dataJson.put("skybox_type", "SKYBOX_V5");
FileUtil.writeUtf8String(dataJson.toJSONString(), localImagePath + "data.json");
//调用objToTxt算法
CreateObjUtil.build3dModel(localImagePath, "");
Thread.sleep(2000);
String uploadJsonPath = localImagePath + "results/upload.json";
boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, 3, 3000);
if(!exist){
throw new BusinessException(ErrorCode.FAILURE_CODE_5042);
}
String uploadData = FileUtils.readFile(uploadJsonPath);
JSONObject uploadJson = null;
JSONArray array = null;
if(uploadData!=null) {
uploadJson = JSONObject.parseObject(uploadData);
array = uploadJson.getJSONArray("upload");
}
if(array == null){
log.error("upload.json数据出错");
throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
}
Map 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");
String filePath = localImagePath + "results/" + fileName;
//文件不存在抛出异常
if(!FileUtil.exist(filePath)){
throw new BusinessException(ErrorCode.FAILURE_CODE_4002, filePath);
}
//tex文件夹
if (fileJson.getIntValue("clazz") == 15) {
map.put(filePath, ossImagePath + "dacf7dfa24ae47fab8fcebfe4dc41ab9_50k_texture_jpg_high1/" + fileName.replace("tex/", ""));
continue;
}
}
CreateObjUtil.convertTxtToDam(localImagePath + "results/" + "modeldata.txt", localImagePath + "results/" + "dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam");
// CreateObjUtil.convertDamToLzma(imagesBuffer.toString() + File.separator + "results" +File.separator+ "dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam");
// CreateObjUtil.convertTxtToDam(imagesBuffer.toString() + File.separator + "results" +File.separator+"modeldata.txt", imagesBuffer.toString() + File.separator + "results" + File.separator+ "dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam");
// map.put(imagesBuffer.toString() + File.separator + "results" +File.separator+"dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam.lzma", "images/images"+param.getNum()+"/"+"dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam.lzma");
map.put(localImagePath + "results/" + "dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam", ossImagePath + "dacf7dfa24ae47fab8fcebfe4dc41ab9_50k.dam");
FileUtils.deleteFile(localImagePath + "vision.modeldata");
CreateObjUtil.convertTxtToVisionmodeldata(localImagePath + "vision.txt", localImagePath + "vision.modeldata");
map.put(localImagePath + "vision.modeldata", ossImagePath + "vision.modeldata");
fYunFileService.uploadMulFiles(map);
}
private String updateScene4CreateVirtualScene(CreateFicTitiousSceneParamVO param){
ScenePlus scenePlus = this.getByNum(param.getNum());
ScenePlusExt scenePlusExt = null;
SceneEditInfo sceneEditInfo = null;
SceneEditInfoExt sceneEditInfoExt = null;
SceneEditControls sceneEditControls = null;
if(Objects.nonNull(scenePlus)){
scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfo.getId());
sceneEditControls = sceneEditControlsService.getByEditInfoId(sceneEditInfo.getId());
}else {
scenePlus = new ScenePlus();
scenePlusExt = new ScenePlusExt();
sceneEditInfo = new SceneEditInfo();
sceneEditInfoExt = new SceneEditInfoExt();
sceneEditControls = new SceneEditControls();
}
scenePlus.setNum(param.getNum());
scenePlus.setUserId(param.getUserId());
scenePlus.setTitle("四维看看");
scenePlus.setDescription("四维看看 让空间讲故事
");
scenePlus.setSceneStatus(SceneStatus.SUCCESS.code());
scenePlus.setPayStatus(PayStatus.PAY.code());
scenePlus.setSceneSource(param.getSceneSource());
this.saveOrUpdate(scenePlus);
scenePlus = this.getByNum(param.getNum());
scenePlusExt.setPlusId(scenePlus.getId());
scenePlusExt.setWebSite(mainUrl + "/" + sceneUrl + param.getNum());
scenePlusExt.setBuildType("V3");
scenePlusExt.setSceneResolution(param.getSceneResolution());
scenePlusExt.setSceneFrom(param.getSceneFrom());
scenePlusExt.setSceneKind(param.getSceneKind());
scenePlusExt.setModelKind(ModelKind.DAM.code());
scenePlusExtService.saveOrUpdate(scenePlusExt);
scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
sceneEditInfo.setScenePlusId(scenePlus.getId());
sceneEditInfo.setVersion(Objects.isNull(sceneEditInfo.getVersion()) ? 0 : sceneEditInfo.getVersion() + 1);
sceneEditInfo.setImgVersion(Objects.isNull(sceneEditInfo.getImgVersion()) ? 0 : sceneEditInfo.getImgVersion() + 1);
sceneEditInfo.setTitle(scenePlus.getTitle());
sceneEditInfo.setDescription(scenePlus.getDescription());
sceneEditInfoService.saveOrUpdate(sceneEditInfo);
sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
sceneEditInfoExt.setScenePlusId(scenePlus.getId());
sceneEditInfoExtService.saveOrUpdate(sceneEditInfoExt);
sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfo.getId());
sceneEditControls.setEditInfoId(sceneEditInfo.getId());
sceneEditControlsService.saveOrUpdate(sceneEditControls);
sceneEditControls = sceneEditControlsService.getByEditInfoId(sceneEditInfo.getId());
SceneJsonBean sceneJson = new SceneJsonBean();
BeanUtil.copyProperties(sceneEditInfoExt, sceneJson);
BeanUtil.copyProperties(sceneEditInfo, sceneJson);
SceneEditControlsVO sceneEditControlsVO = BeanUtil.copyProperties(sceneEditControls, SceneEditControlsVO.class);
sceneJson.setControls(sceneEditControlsVO);
sceneJson.setNum(param.getNum());
sceneJson.setCreateTime(scenePlus.getCreateTime());
sceneJson.setSceneResolution(scenePlusExt.getSceneResolution());
sceneJson.setVersion(sceneEditInfo.getVersion());
sceneJson.setImgVersion(sceneEditInfo.getImgVersion());
sceneJson.setSceneFrom(scenePlusExt.getSceneFrom());
sceneJson.setSceneKind(scenePlusExt.getSceneKind());
sceneJson.setModelKind(scenePlusExt.getModelKind());
sceneJson.setPayStatus(scenePlus.getPayStatus());
String sceneJsonStr = JSON.toJSONString(sceneJson);
//上传sceneJson文件
fYunFileService.uploadFile(sceneJsonStr.getBytes(), String.format(UploadFilePath.DATA_VIEW_PATH, param.getNum()) + "scene.json");
//scenejson写入缓存
redisUtil.set(String.format(RedisKey.SCENE_JSON, param.getNum()), sceneJsonStr);
return scenePlusExt.getWebSite();
}
@Override
public PageInfo getScenesByUserId(Integer userId,Integer pageNum,Integer pageSize) {
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ScenePlus::getUserId,userId);
Map cameraMap = cameraService.list().stream().collect(Collectors.toMap(Camera::getId, Camera::getSnCode));
Page scenePage = this.page(new Page<>(pageNum, pageSize), queryWrapper);
List sceneVos = scenePage.getRecords().stream().map(scenePlus -> {
SceneVO vo = new SceneVO();
vo.setSceneCode(scenePlus.getNum());
vo.setSceneName(scenePlus.getTitle());
vo.setCreateTime(DateUtil.date2String(scenePlus.getCreateTime(), null));
ScenePlusExt plusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
vo.setShootCount(plusExt.getShootCount());
vo.setSnCode(cameraMap.get(scenePlus.getCameraId()));
return vo;
}).collect(Collectors.toList());
return PageInfo.PageInfo(scenePage.getCurrent(),scenePage.getSize(),scenePage.getTotal(),sceneVos);
}
@Override
public Object getPointInfo(String sceneCode) {
// 获取vision.txt 文件内容返回
String content = fYunFileService.getFileContent(String.format(UploadFilePath.IMG_VIEW_PATH, sceneCode));
JSONObject jsonObject = JSONObject.parseObject(content);
return jsonObject.get("sweepLocations");
}
@Override
public List getSceneObjFilePaths(String sceneCode) {
List objFiles = fYunFileService.listRemoteFiles(String.format(UploadFilePath.DATA_VIEW_PATH, sceneCode).concat("mesh"))
.stream().map(file -> fYunFileConfig.getHost() + file).collect(Collectors.toList());
return objFiles;
}
@Override
public List getScenePanoramicImageFiles(String sceneCode) {
// 根据vision.txt 获取全景图文件
String content = fYunFileService.getFileContent(String.format(UploadFilePath.IMG_VIEW_PATH, sceneCode));
JSONObject jsonObject = JSONObject.parseObject(content);
return jsonObject.getJSONArray("sweepLocations").stream()
.map(json -> String.format(fYunFileConfig.getHost()
+ UploadFilePath.scene_result_data_path, sceneCode).concat("caches/images/")
+ ((JSONObject) json).getString("uuid").concat(".jpg")).collect(Collectors.toList());
}
}