BoxModelServiceImpl.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. package com.fdkankan.scene.service.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.io.FileUtil;
  4. import cn.hutool.core.util.CharsetUtil;
  5. import cn.hutool.core.util.StrUtil;
  6. import cn.hutool.core.util.ZipUtil;
  7. import com.alibaba.fastjson.JSONArray;
  8. import com.alibaba.fastjson.JSONObject;
  9. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  10. import com.fdkankan.common.constant.ErrorCode;
  11. import com.fdkankan.common.constant.OperationType;
  12. import com.fdkankan.common.constant.ServerCode;
  13. import com.fdkankan.common.exception.BusinessException;
  14. import com.fdkankan.common.util.FileUtils;
  15. import com.fdkankan.common.util.OBJToGLBUtil;
  16. import com.fdkankan.fyun.face.FYunFileServiceInterface;
  17. import com.fdkankan.model.constants.ConstantFilePath;
  18. import com.fdkankan.model.constants.UploadFilePath;
  19. import com.fdkankan.model.utils.ComputerUtil;
  20. import com.fdkankan.scene.bean.BoxModelBean;
  21. import com.fdkankan.scene.entity.SceneEditInfo;
  22. import com.fdkankan.scene.entity.ScenePlus;
  23. import com.fdkankan.scene.entity.ScenePlusExt;
  24. import com.fdkankan.scene.service.IBoxModelService;
  25. import com.fdkankan.scene.service.ISceneEditInfoService;
  26. import com.fdkankan.scene.service.IScenePlusExtService;
  27. import com.fdkankan.scene.service.IScenePlusService;
  28. import com.fdkankan.scene.vo.BaseJsonDataParamVO;
  29. import com.fdkankan.scene.vo.DeleteSidParamVO;
  30. import com.fdkankan.web.response.ResultData;
  31. import com.google.common.collect.Lists;
  32. import java.io.File;
  33. import java.io.IOException;
  34. import java.nio.charset.Charset;
  35. import java.util.Arrays;
  36. import java.util.Calendar;
  37. import java.util.Comparator;
  38. import java.util.HashSet;
  39. import java.util.List;
  40. import java.util.Objects;
  41. import java.util.Set;
  42. import lombok.extern.slf4j.Slf4j;
  43. import org.springframework.beans.factory.annotation.Autowired;
  44. import org.springframework.stereotype.Service;
  45. import org.springframework.web.multipart.MultipartFile;
  46. import javax.annotation.Resource;
  47. /**
  48. * <p>
  49. * TODO
  50. * </p>
  51. *
  52. * @author dengsixing
  53. * @since 2022/10/19
  54. **/
  55. @Slf4j
  56. @Service
  57. public class BoxModelServiceImpl implements IBoxModelService {
  58. @Resource
  59. private FYunFileServiceInterface fYunFileService;
  60. @Autowired
  61. private IScenePlusService scenePlusService;
  62. @Autowired
  63. private ISceneEditInfoService sceneEditInfoService;
  64. @Autowired
  65. private IScenePlusExtService scenePlusExtService;
  66. @Override
  67. public ResultData uploadBoxModel(String num, String sid, MultipartFile file) throws Exception {
  68. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
  69. if(Objects.isNull(scenePlus)){
  70. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  71. }
  72. ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
  73. String bucket = scenePlusExt.getYunFileBucket();
  74. if(!file.getOriginalFilename().endsWith(".zip") && !file.getOriginalFilename().endsWith(".glb")){
  75. throw new BusinessException(ErrorCode.FAILURE_CODE_7007.code(), ErrorCode.FAILURE_CODE_7007.formatMessage("zip或者glb"));
  76. }
  77. // if(!FileUtils.checkFileSizeIsLimit(file.getSize(), 5, "M")){
  78. // throw new BusinessException(ErrorCode.FAILURE_CODE_7023, "5M");
  79. // }
  80. String path = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "boxModel/" + sid + "/";
  81. try {
  82. String zipPath = path + file.getOriginalFilename();
  83. String srcPath = path + "data/";
  84. String glbPath = path + sid + ".glb";
  85. FileUtil.del(path);
  86. if(file.getOriginalFilename().endsWith(".zip")){
  87. FileUtil.mkParentDirs(zipPath);
  88. file.transferTo(new File(zipPath));
  89. //解压
  90. ZipUtil.unzip(zipPath,srcPath, CharsetUtil.CHARSET_GBK);
  91. //校验是否包含目录,如果包含目录提示错误
  92. File srcFile = new File(srcPath);
  93. Arrays.stream(srcFile.listFiles()).forEach(subFile->{
  94. if(subFile.isDirectory()){
  95. throw new BusinessException(ErrorCode.FAILURE_CODE_5065);
  96. }
  97. });
  98. //转glb
  99. OBJToGLBUtil.objToGlb(srcPath, glbPath);
  100. }else{
  101. FileUtil.mkParentDirs(glbPath);
  102. file.transferTo(new File(glbPath));
  103. }
  104. if(!ComputerUtil.checkComputeCompleted(glbPath, 10, 2000)){
  105. throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
  106. }
  107. //上传glb
  108. fYunFileService.uploadFile(bucket, glbPath, String.format(UploadFilePath.USER_EDIT_PATH, num) + "boxModels/" + sid + ".glb");
  109. //上传原始obj相关文件
  110. List<File> files = FileUtil.loopFiles(srcPath);
  111. files.stream().forEach(v->{
  112. String ossKey = String.format(UploadFilePath.USER_EDIT_PATH, num) + "boxModels/" + sid + "/" + v.getAbsolutePath().replace(srcPath, "");
  113. fYunFileService.uploadFile(v.getAbsolutePath(), ossKey);
  114. });
  115. return ResultData.ok(sid + ".glb");
  116. }catch (Exception e){
  117. log.error("上传三维模型失败", e);
  118. throw e;
  119. }finally {
  120. FileUtil.del(path);
  121. }
  122. }
  123. public static void main(String[] args) {
  124. ZipUtil.unzip("F:\\test\\新建文件夹\\police模型\\police模型.zip","F:\\test\\新建文件夹\\police模型\\maps");
  125. }
  126. @Override
  127. public ResultData saveBoxModel(BaseJsonDataParamVO param) throws Exception {
  128. JSONObject data = param.getData();
  129. String sid = data.getString("sid");
  130. if(StrUtil.isEmpty(sid)){
  131. throw new BusinessException(ServerCode.PARAM_REQUIRED, sid);
  132. }
  133. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
  134. if(Objects.isNull(scenePlus))
  135. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  136. ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
  137. SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  138. //生成boxVideos数据
  139. String boxPhotos = this.createBoxModels(param.getNum(), scenePlusExt.getYunFileBucket(), sid, data, sceneEditInfo, OperationType.ADDORUPDATE.code());
  140. //更新数据库
  141. this.updateBoxModels(sceneEditInfo, boxPhotos);
  142. return ResultData.ok();
  143. }
  144. @Override
  145. public ResultData deleteBoxModel(DeleteSidParamVO param) throws Exception {
  146. ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
  147. if(Objects.isNull(scenePlus))
  148. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  149. ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
  150. SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  151. //根据sid移除json
  152. String boxModels = this.createBoxModels(param.getNum(), scenePlusExt.getYunFileBucket(), param.getSid(), null, sceneEditInfo, OperationType.DELETE.code());
  153. //写数据库
  154. this.updateBoxModels(sceneEditInfo, boxModels);
  155. //删除oss文件
  156. String glbKey = String.format(UploadFilePath.USER_EDIT_PATH, param.getNum()) + "boxModels/" + param.getSid() + "glb";
  157. fYunFileService.deleteFile(glbKey);
  158. String modelPath = String.format(UploadFilePath.USER_EDIT_PATH, param.getNum()) + "boxModels/" + param.getSid();
  159. fYunFileService.deleteFolder(modelPath);
  160. return ResultData.ok();
  161. }
  162. private void updateBoxModels(SceneEditInfo sceneEditInfo, String boxModels){
  163. sceneEditInfoService.update(new LambdaUpdateWrapper<SceneEditInfo>()
  164. .set(SceneEditInfo::getBoxModels, boxModels)
  165. .setSql("version = version + 1")
  166. .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
  167. }
  168. private String createBoxModels(String num, String bucket, String sid, JSONObject data, SceneEditInfo sceneEditInfo, int type) throws Exception{
  169. String boxModels = null;
  170. if(sceneEditInfo != null){
  171. boxModels = sceneEditInfo.getBoxModels();
  172. }
  173. JSONArray boxModelsJson = null;
  174. if (StrUtil.isNotEmpty(boxModels)) {
  175. boxModelsJson = JSONArray.parseArray(boxModels);
  176. }else {
  177. boxModelsJson = new JSONArray();
  178. }
  179. String result = null;
  180. //删除
  181. if(type == OperationType.DELETE.code()){
  182. Set<String> deleteFile = new HashSet<>();
  183. if(boxModelsJson.size() == 0)
  184. return null;
  185. for(int i=0;i<boxModelsJson.size();++i){
  186. JSONObject ele = boxModelsJson.getJSONObject(i);
  187. if(ele.getString("sid").equals(sid)){
  188. boxModelsJson.remove(i);
  189. deleteFile.add(String.format(UploadFilePath.USER_EDIT_PATH, num) + sid + ".glb");
  190. }
  191. }
  192. //删除资源文件
  193. if(CollUtil.isNotEmpty(deleteFile))
  194. deleteFile.stream().forEach(key -> {
  195. try {
  196. fYunFileService.deleteFile(bucket, key);
  197. } catch (IOException e) {
  198. log.warn("oss删除文件失败,key:{}", key);
  199. }
  200. });
  201. }else{
  202. //更新
  203. boolean exist = false;
  204. for(int i=0;i<boxModelsJson.size();++i){
  205. JSONObject ele = boxModelsJson.getJSONObject(i);
  206. if(ele.getString("sid").equals(sid)){
  207. data.put("createTime", ele.getLong("createTime"));
  208. boxModelsJson.set(i, data);
  209. exist = true;
  210. }
  211. }
  212. //新增
  213. if(!exist){
  214. data.put("createTime", Calendar.getInstance().getTimeInMillis());
  215. boxModelsJson.add(data);
  216. }
  217. }
  218. if(boxModelsJson.size() != 0){
  219. List<BoxModelBean> list = Lists.newArrayList();
  220. for (Object o : boxModelsJson) {
  221. JSONObject jsonObject = (JSONObject)o;
  222. list.add(BoxModelBean.builder().createTime(jsonObject.getLong("createTime")).boxModel(jsonObject).build());
  223. }
  224. //按创建时间倒叙排序
  225. list.sort(Comparator.comparingLong(BoxModelBean::getCreateTime).reversed());
  226. // list转JSONArray
  227. JSONArray array = new JSONArray();
  228. list.stream().forEach(bean->{
  229. array.add(bean.getBoxModel());
  230. });
  231. result = array.toJSONString();
  232. }
  233. return result;
  234. }
  235. }