|
@@ -0,0 +1,244 @@
|
|
|
+package com.fdkankan.scene.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.io.FileUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.core.util.ZipUtil;
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.fdkankan.common.constant.ErrorCode;
|
|
|
+import com.fdkankan.common.constant.OperationType;
|
|
|
+import com.fdkankan.common.constant.ServerCode;
|
|
|
+import com.fdkankan.common.exception.BusinessException;
|
|
|
+import com.fdkankan.common.util.FileUtils;
|
|
|
+import com.fdkankan.common.util.OBJToGLBUtil;
|
|
|
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
|
|
|
+import com.fdkankan.model.constants.ConstantFilePath;
|
|
|
+import com.fdkankan.model.constants.UploadFilePath;
|
|
|
+import com.fdkankan.scene.bean.BoxModelBean;
|
|
|
+import com.fdkankan.scene.entity.SceneEditInfo;
|
|
|
+import com.fdkankan.scene.entity.ScenePlus;
|
|
|
+import com.fdkankan.scene.entity.ScenePlusExt;
|
|
|
+import com.fdkankan.scene.service.IBoxModelService;
|
|
|
+import com.fdkankan.scene.service.ISceneEditInfoService;
|
|
|
+import com.fdkankan.scene.service.IScenePlusExtService;
|
|
|
+import com.fdkankan.scene.service.IScenePlusService;
|
|
|
+import com.fdkankan.scene.vo.BaseJsonDataParamVO;
|
|
|
+import com.fdkankan.scene.vo.DeleteSidParamVO;
|
|
|
+import com.fdkankan.web.response.ResultData;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * TODO
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author dengsixing
|
|
|
+ * @since 2022/10/19
|
|
|
+ **/
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class BoxModelServiceImpl implements IBoxModelService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FYunFileServiceInterface fYunFileService;
|
|
|
+ @Autowired
|
|
|
+ private IScenePlusService scenePlusService;
|
|
|
+ @Autowired
|
|
|
+ private ISceneEditInfoService sceneEditInfoService;
|
|
|
+ @Autowired
|
|
|
+ private IScenePlusExtService scenePlusExtService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData uploadBoxModel(String num, String sid, MultipartFile file) throws Exception {
|
|
|
+
|
|
|
+ ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
|
|
|
+ if(Objects.isNull(scenePlus)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ }
|
|
|
+ ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
|
|
|
+ String bucket = scenePlusExt.getYunFileBucket();
|
|
|
+
|
|
|
+ if(!file.getOriginalFilename().endsWith(".zip")){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7015);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!FileUtils.checkFileSizeIsLimit(file.getSize(), 5, "M")){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7023, "5M");
|
|
|
+ }
|
|
|
+ String path = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "boxModel/" + sid + "/";
|
|
|
+ String zipPath = path + file.getOriginalFilename();
|
|
|
+ String srcPath = path + "data/";
|
|
|
+ String glbPath = path + sid + ".glb";
|
|
|
+
|
|
|
+ FileUtil.del(path);
|
|
|
+ FileUtil.mkParentDirs(zipPath);
|
|
|
+ file.transferTo(new File(zipPath));
|
|
|
+
|
|
|
+ //解压
|
|
|
+ ZipUtil.unzip(zipPath,srcPath);
|
|
|
+
|
|
|
+ //校验是否包含目录,如果包含目录提示错误
|
|
|
+ File srcFile = new File(srcPath);
|
|
|
+ Arrays.stream(srcFile.listFiles()).forEach(subFile->{
|
|
|
+ if(subFile.isDirectory()){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5065);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ //转glb
|
|
|
+ OBJToGLBUtil.objToGlb(srcPath, glbPath);
|
|
|
+
|
|
|
+ if(!FileUtil.exist(glbPath)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
|
|
|
+ }
|
|
|
+
|
|
|
+ //上传glb
|
|
|
+ fYunFileService.uploadFile(bucket, glbPath, String.format(UploadFilePath.USER_EDIT_PATH, num) + "boxModels/" + sid + ".glb");
|
|
|
+
|
|
|
+ return ResultData.ok(sid + ".glb");
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ ZipUtil.unzip("F:\\test\\新建文件夹\\police模型\\police模型.zip","F:\\test\\新建文件夹\\police模型\\maps");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData saveBoxModel(BaseJsonDataParamVO param) throws Exception {
|
|
|
+
|
|
|
+ JSONObject data = param.getData();
|
|
|
+ String sid = data.getString("sid");
|
|
|
+ if(StrUtil.isEmpty(sid)){
|
|
|
+ throw new BusinessException(ServerCode.PARAM_REQUIRED, sid);
|
|
|
+ }
|
|
|
+ ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
|
|
|
+ if(Objects.isNull(scenePlus))
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ //生成boxVideos数据
|
|
|
+ String boxPhotos = this.createBoxModels(param.getNum(), scenePlusExt.getYunFileBucket(), sid, data, sceneEditInfo, OperationType.ADDORUPDATE.code());
|
|
|
+
|
|
|
+ //更新数据库
|
|
|
+ this.updateBoxModels(sceneEditInfo, boxPhotos);
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData deleteBoxModel(DeleteSidParamVO param) throws Exception {
|
|
|
+
|
|
|
+ ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
|
|
|
+ if(Objects.isNull(scenePlus))
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ //根据sid移除json
|
|
|
+ String boxModels = this.createBoxModels(param.getNum(), scenePlusExt.getYunFileBucket(), param.getSid(), null, sceneEditInfo, OperationType.DELETE.code());
|
|
|
+
|
|
|
+ //写数据库
|
|
|
+ this.updateBoxModels(sceneEditInfo, boxModels);
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateBoxModels(SceneEditInfo sceneEditInfo, String boxModels){
|
|
|
+ sceneEditInfoService.update(new LambdaUpdateWrapper<SceneEditInfo>()
|
|
|
+ .set(SceneEditInfo::getBoxModels, boxModels)
|
|
|
+ .setSql("version = version + 1")
|
|
|
+ .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
|
|
|
+ }
|
|
|
+
|
|
|
+ private String createBoxModels(String num, String bucket, String sid, JSONObject data, SceneEditInfo sceneEditInfo, int type) throws Exception{
|
|
|
+
|
|
|
+ String boxModels = null;
|
|
|
+ if(sceneEditInfo != null){
|
|
|
+ boxModels = sceneEditInfo.getBoxModels();
|
|
|
+ }
|
|
|
+ JSONArray boxModelsJson = null;
|
|
|
+ if (StrUtil.isNotEmpty(boxModels)) {
|
|
|
+ boxModelsJson = JSONArray.parseArray(boxModels);
|
|
|
+ }else {
|
|
|
+ boxModelsJson = new JSONArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ String result = null;
|
|
|
+ //删除
|
|
|
+ if(type == OperationType.DELETE.code()){
|
|
|
+ Set<String> deleteFile = new HashSet<>();
|
|
|
+ if(boxModelsJson.size() == 0)
|
|
|
+ return null;
|
|
|
+ for(int i=0;i<boxModelsJson.size();++i){
|
|
|
+ JSONObject ele = boxModelsJson.getJSONObject(i);
|
|
|
+ if(ele.getString("sid").equals(sid)){
|
|
|
+ boxModelsJson.remove(i);
|
|
|
+ deleteFile.add(String.format(UploadFilePath.USER_EDIT_PATH, num) + sid + ".glb");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //删除资源文件
|
|
|
+ if(CollUtil.isNotEmpty(deleteFile))
|
|
|
+ deleteFile.stream().forEach(key -> {
|
|
|
+ try {
|
|
|
+ fYunFileService.deleteFile(bucket, key);
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.warn("oss删除文件失败,key:{}", key);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }else{
|
|
|
+ //更新
|
|
|
+ boolean exist = false;
|
|
|
+ for(int i=0;i<boxModelsJson.size();++i){
|
|
|
+ JSONObject ele = boxModelsJson.getJSONObject(i);
|
|
|
+ if(ele.getString("sid").equals(sid)){
|
|
|
+ data.put("createTime", ele.getLong("createTime"));
|
|
|
+ boxModelsJson.set(i, data);
|
|
|
+ exist = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //新增
|
|
|
+ if(!exist){
|
|
|
+ data.put("createTime", Calendar.getInstance().getTimeInMillis());
|
|
|
+ boxModelsJson.add(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if(boxModelsJson.size() != 0){
|
|
|
+
|
|
|
+ List<BoxModelBean> list = Lists.newArrayList();
|
|
|
+ for (Object o : boxModelsJson) {
|
|
|
+ JSONObject jsonObject = (JSONObject)o;
|
|
|
+ list.add(BoxModelBean.builder().createTime(jsonObject.getLong("createTime")).boxModel(jsonObject).build());
|
|
|
+ }
|
|
|
+ //按创建时间倒叙排序
|
|
|
+ list.sort(Comparator.comparingLong(BoxModelBean::getCreateTime).reversed());
|
|
|
+
|
|
|
+ // list转JSONArray
|
|
|
+ JSONArray array = new JSONArray();
|
|
|
+ list.stream().forEach(bean->{
|
|
|
+ array.add(bean.getBoxModel());
|
|
|
+ });
|
|
|
+
|
|
|
+ result = array.toJSONString();
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+}
|