ModelServiceImpl.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. package com.fdkankan.fusion.service.impl;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.util.*;
  5. import java.util.concurrent.CompletableFuture;
  6. import java.util.concurrent.ExecutorService;
  7. import java.util.concurrent.ThreadPoolExecutor;
  8. import java.util.stream.Collectors;
  9. import cn.hutool.core.io.FileUtil;
  10. import cn.hutool.core.thread.ThreadUtil;
  11. import com.alibaba.fastjson.JSONArray;
  12. import com.alibaba.fastjson.JSONObject;
  13. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  14. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  15. import com.fdkankan.fusion.common.PageInfo;
  16. import com.fdkankan.fusion.common.util.*;
  17. import com.fdkankan.fusion.common.FilePath;
  18. import com.fdkankan.fusion.common.ResultCode;
  19. import com.fdkankan.fusion.config.CacheUtil;
  20. import com.fdkankan.fusion.entity.*;
  21. import com.fdkankan.fusion.exception.BusinessException;
  22. import com.fdkankan.fusion.mapper.IModelMapper;
  23. import com.fdkankan.fusion.request.ModelPram;
  24. import com.fdkankan.fusion.response.SceneVo;
  25. import com.fdkankan.fusion.service.*;
  26. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  27. import com.fdkankan.redis.util.RedisUtil;
  28. import lombok.SneakyThrows;
  29. import lombok.extern.slf4j.Slf4j;
  30. import org.apache.commons.io.FileUtils;
  31. import org.apache.commons.lang3.StringUtils;
  32. import org.springframework.beans.BeanUtils;
  33. import org.springframework.beans.factory.annotation.Autowired;
  34. import org.springframework.beans.factory.annotation.Value;
  35. import org.springframework.scheduling.annotation.Async;
  36. import org.springframework.stereotype.Service;
  37. import org.springframework.web.multipart.MultipartFile;
  38. /**
  39. * <p>
  40. * 服务实现类
  41. * </p>
  42. *
  43. * @author
  44. * @since 2022-08-03
  45. */
  46. @Service
  47. @Slf4j
  48. public class ModelServiceImpl extends ServiceImpl<IModelMapper, Model> implements IModelService {
  49. @Autowired
  50. LocalToOssUtil localToOssUtil;
  51. @Autowired
  52. UploadService uploadService;
  53. @Autowired
  54. ICaseNumService caseNumService;
  55. @Autowired
  56. ICaseService caseService;
  57. @Autowired
  58. IFusionNumService fusionNumService;
  59. @Autowired
  60. RedisUtil redisUtil;
  61. @Autowired
  62. ITmDepartmentService tmDepartmentService;
  63. @Autowired
  64. ITmUserService tmUserService;
  65. @Autowired
  66. ITmCameraService tmCameraService;
  67. @Autowired
  68. ThreadService threadService;
  69. @Autowired
  70. ISceneService sceneService;
  71. @Value("${spring.profiles.active}")
  72. private String environment;
  73. @Override
  74. public Model uploadObj(MultipartFile file,String username) throws Exception {
  75. if(file.isEmpty()){
  76. throw new BusinessException(ResultCode.UPLOAD_FILE_NO_EXIST);
  77. }
  78. if(file.getSize()>10 * 1024 * 1024 * 100){
  79. throw new BusinessException(ResultCode.UPLOAD_FILE_TO_LONG);
  80. }
  81. //获取文件名
  82. String fileName = file.getOriginalFilename();
  83. if(StringUtils.isEmpty(fileName)){
  84. throw new BusinessException(ResultCode.UPLOAD_FILE_NO_EXIST);
  85. }
  86. if(com.fdkankan.fusion.common.util.StringUtils.isChinese(fileName)){
  87. throw new BusinessException(ResultCode.UPLOAD_FILE_CHINA_NAME);
  88. }
  89. if(fileName.length() >50){
  90. throw new BusinessException(ResultCode.UPLOAD_FILE_NAME_TO_LONG);
  91. }
  92. if(!fileName.toLowerCase().endsWith(".zip")){
  93. throw new BusinessException(ResultCode.UPLOAD_FILE_TYPE_ERROR);
  94. }
  95. //获取文件后缀名
  96. String modelName = fileName.substring(0,fileName.lastIndexOf("."));
  97. TmUser tmUser = tmUserService.getLoginUser();
  98. Model model = new Model();
  99. model.setModelTitle(modelName);
  100. model.setModelSize(FileWriterUtil.setFileSize(file.getSize()));
  101. model.setUserName(username);
  102. model.setDeptId(tmUser.getDeptId());
  103. redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"0");
  104. this.save(model);
  105. String fileName2 = UUID.randomUUID().toString().replace("-","") +".zip";
  106. String objPath = String.format(FilePath.OBJ_LOCAL_PATH,environment , "modelId_"+model.getModelId()) ;
  107. log.info("uploadObj--ThreadStart-fileName:{},modeId:{}",fileName2,model.getModelId());
  108. File newObjFile = new File(objPath +"/" + fileName2);
  109. if(!newObjFile.getParentFile().exists()){
  110. newObjFile.getParentFile().mkdirs();
  111. }
  112. file.transferTo(newObjFile);
  113. threadService.uploadModelObj(fileName2,objPath,newObjFile,model);
  114. return model;
  115. }
  116. @Override
  117. public PageInfo pageList(ModelPram param, String userName) {
  118. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  119. List<String> deptIds = tmDepartmentService.getDeptIds();
  120. if(deptIds.size() <=0){
  121. return PageInfo.PageInfo(new Page<>(param.getPageNum(),param.getPageSize()));
  122. }
  123. if(param.getCaseId() !=null){
  124. String deptId = caseService.getDeptId(param.getCaseId());
  125. wrapper.eq(Model::getDeptId,deptId);
  126. }
  127. List<String> deptIds2 = tmDepartmentService.getSonByDeptIdAndDeptIds(deptIds, param.getDeptId(),param.getSearchType());
  128. wrapper.in(Model::getDeptId,deptIds2);
  129. wrapper.eq(Model::getType,3);
  130. wrapper.notIn(Model::getCreateStatus,-2);
  131. if(param.getStatus()!=null){ //参数2为成功,数据库中成功为1
  132. wrapper.eq(Model::getCreateStatus,param.getStatus() == 2 ? 1 :param.getStatus());
  133. }
  134. if(StringUtils.isNotBlank(param.getModelTitle())){
  135. wrapper.like(Model::getModelTitle,param.getModelTitle());
  136. }
  137. wrapper.orderByDesc(Model::getCreateTime);
  138. Page<Model> page = this.page(new Page<>(param.getPageNum(),param.getPageSize()),wrapper);
  139. Set<String> deptIdset = page.getRecords().stream().map(Model::getDeptId).collect(Collectors.toSet());
  140. HashMap<String, TmDepartment> mapByDept = tmDepartmentService.getMapByDeptIds(deptIdset);
  141. for (Model model : page.getRecords()) {
  142. if(model.getType() == 3 && StringUtils.isEmpty(model.getNum())) {
  143. model.setNum(model.getModelId().toString());
  144. }
  145. if(StringUtils.isNotBlank(model.getDeptId())){
  146. TmDepartment tmDepartment = mapByDept.get(model.getDeptId());
  147. if(tmDepartment != null){
  148. model.setDeptName(tmDepartment.getName());
  149. }
  150. }
  151. }
  152. return PageInfo.PageInfo(page);
  153. }
  154. private List<Model> getByDeptIds(List<String> asList) {
  155. if(asList.size() >0){
  156. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  157. wrapper.in(Model::getDeptId,asList);
  158. return list(wrapper);
  159. }
  160. return new ArrayList<>();
  161. }
  162. @Override
  163. public void delete(Integer modelId) {
  164. List<CaseNumEntity> caseNumEntityList = caseNumService.getByNum(modelId.toString());
  165. List<FusionNum> fusionNumList = fusionNumService.getByNum(modelId.toString());
  166. if(caseNumEntityList.size() >0 || fusionNumList.size() >0){
  167. StringBuilder title = new StringBuilder();
  168. List<Integer> caseIdIds = caseNumEntityList.parallelStream().map(CaseNumEntity::getCaseId).collect(Collectors.toList());
  169. if(caseIdIds.size() >0){
  170. List<CaseEntity> list = caseService.getByIds(caseIdIds);
  171. List<String> collect = list.parallelStream().map(CaseEntity::getCaseTitle).collect(Collectors.toList());
  172. for (String str : collect) {
  173. title.append(str).append(",");
  174. }
  175. if(title.length()>0){
  176. title.delete(title.length()-1,title.length());
  177. }
  178. }
  179. throw new BusinessException(ResultCode.CASE_USE.code, String.format(ResultCode.CASE_USE.msg,title));
  180. }
  181. Model model = this.getById(modelId);
  182. if(model == null ){
  183. throw new BusinessException(ResultCode.MODEL_NOT_EXIST);
  184. }
  185. this.removeById(modelId);
  186. fusionNumService.deleteByModelId(modelId);
  187. if(StringUtils.isNotBlank(model.getModelGlbUrl())){
  188. uploadService.deleteOssUrl(model.getModelGlbUrl());
  189. }
  190. }
  191. @Override
  192. public List<Model> getListByNum(List<String> numList) {
  193. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  194. wrapper.in(Model::getNum,numList);
  195. return this.list(wrapper);
  196. }
  197. @Override
  198. public List<Model> getListByModelIds(List<Integer> modelIds) {
  199. if(modelIds == null || modelIds.isEmpty()){
  200. return new ArrayList<>();
  201. }
  202. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  203. wrapper.in(Model::getModelId,modelIds);
  204. return this.list(wrapper);
  205. }
  206. @Override
  207. public List<Model> getListByModelIdStrs(List<String> numList) {
  208. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  209. wrapper.in(Model::getModelId,numList);
  210. wrapper.orderByDesc(Model::getCreateTime);
  211. return this.list(wrapper);
  212. }
  213. @Override
  214. public void deleteByNum(List<String> numList) {
  215. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  216. wrapper.in(Model::getNum,numList);
  217. this.remove(wrapper);
  218. }
  219. @Override
  220. public List<Model> getByUserName(String username) {
  221. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  222. wrapper.eq(Model::getUserName,username)
  223. .eq(Model::getType,3);
  224. return this.list(wrapper);
  225. }
  226. @Override
  227. public Model getIsNullNewByNum(String num,Integer type, Integer isObj) {
  228. LambdaQueryWrapper<Model> wrapper = new LambdaQueryWrapper<>();
  229. wrapper.eq(Model::getNum,num);
  230. wrapper.eq(Model::getType,type);
  231. Model model = this.getOne(wrapper);
  232. if(model == null){
  233. model = new Model();
  234. }
  235. if(model.getModelId() != null && StringUtils.isNotBlank(model.getModelGlbUrl()) && StringUtils.isNotBlank(model.getModelSize())){
  236. return model;
  237. }
  238. model.setModelDateType("obj");
  239. model.setType(type);
  240. model.setModelType("pointcloud"); //深时点云类型
  241. model.setCreateStatus(1);
  242. model.setIsObj(isObj);
  243. if(isObj == 1){ //看看,看见
  244. Scene scene = sceneService.getByNum(num);
  245. if(scene == null){
  246. throw new BusinessException(ResultCode.SCENE_NOT_EXIST);
  247. }
  248. String mesh3DtilesPath = String.format(FilePath.OBJ_OSS_PATH,num) + "/images/3dtiles/tileset.json";
  249. String sizePath = scene.getWebPath() + String.format(FilePath.OBJ_OSS_PATH,num) + "/images/3dtiles";
  250. if(localToOssUtil.existKey(scene.getWebPath() +mesh3DtilesPath)){
  251. model.setModelDateType("b3dm");
  252. model.setModelType("b3dm");
  253. model.setModelGlbUrl(JSONArray.toJSONString(Arrays.asList(scene.getMapping() +"/" +mesh3DtilesPath)));
  254. model.setModelSize(FileWriterUtil.setFileSize(localToOssUtil.getSizeCount( sizePath)));
  255. }else {
  256. String meshPath = String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh";
  257. if(localToOssUtil.existKey( scene.getWebPath() +meshPath +"/mesh.obj")){
  258. Long size = localToOssUtil.getSizeCount( scene.getWebPath() +meshPath);
  259. model.setModelSize(FileWriterUtil.setFileSize(size));
  260. model.setModelGlbUrl(JSONArray.toJSONString(Arrays.asList(scene.getMapping()+"/" + meshPath+"/mesh.obj")));
  261. }else {
  262. List<String> objPaths = new ArrayList<>();
  263. String meshPathjs = String.format(FilePath.OBJ_OSS_PATH, num)+"/data/";
  264. String jsonPath =scene.getWebPath() + meshPath + "/floors.json";
  265. if(!localToOssUtil.existKey(jsonPath)){
  266. jsonPath =scene.getWebPath() + meshPath +"mesh.json";
  267. }
  268. if(localToOssUtil.existKey(jsonPath)){
  269. String objectContent = localToOssUtil.getObjectContent(meshPath + "/floors.json");
  270. JSONObject jsonObject = JSONObject.parseObject(objectContent);
  271. JSONArray floors1 = jsonObject.getJSONArray("floors");
  272. for (Object object : floors1) {
  273. JSONObject jb = (JSONObject) object;
  274. String string = jb.getString("objPath");
  275. objPaths.add(scene.getMapping()+"/" +meshPathjs + string);
  276. }
  277. model.setModelGlbUrl(JSONArray.toJSONString(objPaths));
  278. Long size = localToOssUtil.getSize(scene.getWebPath() +meshPath);
  279. model.setModelSize(FileWriterUtil.setFileSize(size));
  280. }
  281. }
  282. model.setModelType("obj");
  283. }
  284. }
  285. model.setNum(num);
  286. this.saveOrUpdate(model);
  287. return model;
  288. }
  289. @Override
  290. public SceneVo getInfo(Integer modelId) {
  291. Model model = this.getById(modelId);
  292. if(model == null){
  293. throw new BusinessException(ResultCode.SCENE_NOT_EXIST);
  294. }
  295. SceneVo sceneVo = new SceneVo();
  296. BeanUtils.copyProperties(model,sceneVo);
  297. return sceneVo;
  298. }
  299. @Override
  300. public String uploadObjProgress(Integer modelId) {
  301. String redisKey = RedisKeyUtil.modelUpload+modelId;
  302. String cancel = RedisKeyUtil.modelCancelUpload+modelId;
  303. if(redisUtil.hasKey(cancel)){
  304. return redisUtil.get(cancel);
  305. }
  306. if(redisUtil.hasKey(redisKey)){
  307. return redisUtil.get(redisKey);
  308. }
  309. return "0";
  310. }
  311. @Override
  312. public void cancelUpload(Integer modelId) {
  313. String redisKey = RedisKeyUtil.modelCancelUpload+modelId;
  314. if(redisUtil.hasKey(redisKey)){
  315. return;
  316. }
  317. Model model = this.getById(modelId);
  318. if(model == null){
  319. return;
  320. }
  321. model.setCreateStatus(-2);
  322. this.updateById(model);
  323. redisUtil.set(redisKey,"-2");
  324. }
  325. @Override
  326. public HashMap<String, Model> getMapByNum(List<String> numList) {
  327. HashMap<String,Model> map = new HashMap<>();
  328. List<Model> modelList = this.getListByNum(numList);
  329. modelList.forEach(entity-> map.put(entity.getNum() + entity.getType(),entity));
  330. return map;
  331. }
  332. @Override
  333. public void copyModel(Integer modelId) {
  334. Model modelEntity = this.getById(modelId);
  335. if(modelEntity == null){
  336. throw new BusinessException(ResultCode.MODEL_NOT_EXIST);
  337. }
  338. Integer oldId = modelEntity.getModelId();
  339. modelEntity.setModelTitle(modelEntity.getModelTitle() +"(copy)");
  340. modelEntity.setModelId(null);
  341. this.save(modelEntity);
  342. // if(StringUtils.isNotBlank(modelEntity.getModelGlbUrl())){
  343. // String modelGlbUrl = modelEntity.getModelGlbUrl();
  344. // copyOssResource(modelGlbUrl,oldId,modelEntity.getModelId());
  345. // String newModelObjUrl = modelGlbUrl.replaceAll(oldId+"",modelEntity.getModelId()+"");
  346. // modelEntity.setModelGlbUrl(newModelObjUrl);
  347. // this.updateById(modelEntity);
  348. // }
  349. }
  350. private String getGlbUrl(Integer type, String num,Model model,String scenePath) {
  351. if(type == 0 || type == 1 || type == 4 || type == 6 || type == 7){ //看看,看见
  352. //ShellUtil.yunDownload(String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh" ,objPath);
  353. String objPathSource = scenePath + String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh";
  354. String objPath = String.format(FilePath.OBJ_LOCAL_PATH ,environment,num);
  355. ShellUtil.yunDownload(objPathSource ,objPath);
  356. List<String> localGlbPaths = new ArrayList<>();
  357. List<String> ossGlbPaths = new ArrayList<>();
  358. File localFile = new File(objPath);
  359. this.toGlB(localFile,localGlbPaths);
  360. Long modelSize = 0L;
  361. if(localGlbPaths.size() >0){
  362. for (String localGlbPath : localGlbPaths) {
  363. String ossGlbPath = localGlbPath.replace(FilePath.LOCAL_BASE_PATH,"fusion/");
  364. localToOssUtil.uploadOss(localGlbPath,ossGlbPath);
  365. if(ossGlbPath.contains("lod_")){
  366. if(ossGlbPath.contains("lod_0")){
  367. ossGlbPaths.add(CacheUtil.mapping +ossGlbPath);
  368. modelSize += localToOssUtil.getSize(ossGlbPath);
  369. }
  370. continue;
  371. }
  372. modelSize += localToOssUtil.getSize(ossGlbPath);
  373. ossGlbPaths.add( CacheUtil.mapping +ossGlbPath);
  374. }
  375. model.setModelSize(FileWriterUtil.setFileSize(modelSize));
  376. FileUtil.del(objPath);
  377. return JSONArray.toJSONString(ossGlbPaths);
  378. }
  379. FileUtil.del(objPath);
  380. }
  381. return null;
  382. }
  383. private void toGlB(File localFile, List<String> localGlbPath) {
  384. File[] files = localFile.listFiles();
  385. for (File file : files) {
  386. if(file.isDirectory()){
  387. toGlB(file,localGlbPath);
  388. }
  389. if(file.getName().contains(".obj")){
  390. String glbPath = OBJToGLBUtil.objToGlb(file.getPath(),file.getPath().replace(".obj",".glb") );
  391. localGlbPath.add(glbPath);
  392. }
  393. }
  394. }
  395. }