package com.fdkankan.fusion.service.impl; import java.io.File; import java.io.IOException; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.stream.Collectors; import cn.hutool.core.io.FileUtil; import cn.hutool.core.thread.ThreadUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fdkankan.fusion.common.PageInfo; import com.fdkankan.fusion.common.util.*; import com.fdkankan.fusion.common.FilePath; import com.fdkankan.fusion.common.ResultCode; import com.fdkankan.fusion.config.CacheUtil; import com.fdkankan.fusion.entity.*; import com.fdkankan.fusion.exception.BusinessException; import com.fdkankan.fusion.mapper.IModelMapper; import com.fdkankan.fusion.request.ModelPram; import com.fdkankan.fusion.response.SceneVo; import com.fdkankan.fusion.service.*; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fdkankan.redis.util.RedisUtil; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; /** *

* 服务实现类 *

* * @author * @since 2022-08-03 */ @Service @Slf4j public class ModelServiceImpl extends ServiceImpl implements IModelService { @Autowired LocalToOssUtil localToOssUtil; @Autowired UploadService uploadService; @Autowired ICaseNumService caseNumService; @Autowired ICaseService caseService; @Autowired IFusionNumService fusionNumService; @Autowired RedisUtil redisUtil; @Autowired ITmDepartmentService tmDepartmentService; @Autowired ITmUserService tmUserService; @Autowired ITmCameraService tmCameraService; @Autowired ThreadService threadService; @Autowired ISceneService sceneService; @Value("${spring.profiles.active}") private String environment; @Override public Model uploadObj(MultipartFile file,String username) throws Exception { if(file.isEmpty()){ throw new BusinessException(ResultCode.UPLOAD_FILE_NO_EXIST); } if(file.getSize()>10 * 1024 * 1024 * 100){ throw new BusinessException(ResultCode.UPLOAD_FILE_TO_LONG); } //获取文件名 String fileName = file.getOriginalFilename(); if(StringUtils.isEmpty(fileName)){ throw new BusinessException(ResultCode.UPLOAD_FILE_NO_EXIST); } if(com.fdkankan.fusion.common.util.StringUtils.isChinese(fileName)){ throw new BusinessException(ResultCode.UPLOAD_FILE_CHINA_NAME); } if(fileName.length() >50){ throw new BusinessException(ResultCode.UPLOAD_FILE_NAME_TO_LONG); } if(!fileName.toLowerCase().endsWith(".zip")){ throw new BusinessException(ResultCode.UPLOAD_FILE_TYPE_ERROR); } //获取文件后缀名 String modelName = fileName.substring(0,fileName.lastIndexOf(".")); TmUser tmUser = tmUserService.getLoginUser(); Model model = new Model(); model.setModelTitle(modelName); model.setModelSize(FileWriterUtil.setFileSize(file.getSize())); model.setUserName(username); model.setDeptId(tmUser.getDeptId()); redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"0"); this.save(model); String fileName2 = UUID.randomUUID().toString().replace("-","") +".zip"; String objPath = String.format(FilePath.OBJ_LOCAL_PATH,environment , "modelId_"+model.getModelId()) ; log.info("uploadObj--ThreadStart-fileName:{},modeId:{}",fileName2,model.getModelId()); File newObjFile = new File(objPath +"/" + fileName2); if(!newObjFile.getParentFile().exists()){ newObjFile.getParentFile().mkdirs(); } file.transferTo(newObjFile); threadService.uploadModelObj(fileName2,objPath,newObjFile,model); return model; } @Override public PageInfo pageList(ModelPram param, String userName) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); List deptIds = tmDepartmentService.getDeptIds(); if(deptIds.size() <=0){ return PageInfo.PageInfo(new Page<>(param.getPageNum(),param.getPageSize())); } if(param.getCaseId() !=null){ String deptId = caseService.getDeptId(param.getCaseId()); wrapper.eq(Model::getDeptId,deptId); } List deptIds2 = tmDepartmentService.getSonByDeptIdAndDeptIds(deptIds, param.getDeptId(),param.getSearchType()); wrapper.in(Model::getDeptId,deptIds2); wrapper.eq(Model::getType,3); wrapper.notIn(Model::getCreateStatus,-2); if(param.getStatus()!=null){ //参数2为成功,数据库中成功为1 wrapper.eq(Model::getCreateStatus,param.getStatus() == 2 ? 1 :param.getStatus()); } if(StringUtils.isNotBlank(param.getModelTitle())){ wrapper.like(Model::getModelTitle,param.getModelTitle()); } wrapper.orderByDesc(Model::getCreateTime); Page page = this.page(new Page<>(param.getPageNum(),param.getPageSize()),wrapper); Set deptIdset = page.getRecords().stream().map(Model::getDeptId).collect(Collectors.toSet()); HashMap mapByDept = tmDepartmentService.getMapByDeptIds(deptIdset); for (Model model : page.getRecords()) { if(model.getType() == 3 && StringUtils.isEmpty(model.getNum())) { model.setNum(model.getModelId().toString()); } if(StringUtils.isNotBlank(model.getDeptId())){ TmDepartment tmDepartment = mapByDept.get(model.getDeptId()); if(tmDepartment != null){ model.setDeptName(tmDepartment.getName()); } } } return PageInfo.PageInfo(page); } private List getByDeptIds(List asList) { if(asList.size() >0){ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(Model::getDeptId,asList); return list(wrapper); } return new ArrayList<>(); } @Override public void delete(Integer modelId) { List caseNumEntityList = caseNumService.getByNum(modelId.toString()); List fusionNumList = fusionNumService.getByNum(modelId.toString()); if(caseNumEntityList.size() >0 || fusionNumList.size() >0){ StringBuilder title = new StringBuilder(); List caseIdIds = caseNumEntityList.parallelStream().map(CaseNumEntity::getCaseId).collect(Collectors.toList()); if(caseIdIds.size() >0){ List list = caseService.getByIds(caseIdIds); List collect = list.parallelStream().map(CaseEntity::getCaseTitle).collect(Collectors.toList()); for (String str : collect) { title.append(str).append(","); } if(title.length()>0){ title.delete(title.length()-1,title.length()); } } throw new BusinessException(ResultCode.CASE_USE.code, String.format(ResultCode.CASE_USE.msg,title)); } Model model = this.getById(modelId); if(model == null ){ throw new BusinessException(ResultCode.MODEL_NOT_EXIST); } this.removeById(modelId); fusionNumService.deleteByModelId(modelId); if(StringUtils.isNotBlank(model.getModelGlbUrl())){ uploadService.deleteOssUrl(model.getModelGlbUrl()); } } @Override public List getListByNum(List numList) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(Model::getNum,numList); return this.list(wrapper); } @Override public List getListByModelIds(List modelIds) { if(modelIds == null || modelIds.isEmpty()){ return new ArrayList<>(); } LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(Model::getModelId,modelIds); return this.list(wrapper); } @Override public List getListByModelIdStrs(List numList) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(Model::getModelId,numList); wrapper.orderByDesc(Model::getCreateTime); return this.list(wrapper); } @Override public void deleteByNum(List numList) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(Model::getNum,numList); this.remove(wrapper); } @Override public List getByUserName(String username) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Model::getUserName,username) .eq(Model::getType,3); return this.list(wrapper); } @Override public Model getIsNullNewByNum(String num,Integer type, Integer isObj) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Model::getNum,num); wrapper.eq(Model::getType,type); Model model = this.getOne(wrapper); if(model == null){ model = new Model(); } if(model.getModelId() != null && StringUtils.isNotBlank(model.getModelGlbUrl()) && StringUtils.isNotBlank(model.getModelSize())){ return model; } model.setModelDateType("obj"); model.setType(type); model.setModelType("pointcloud"); //深时点云类型 model.setCreateStatus(1); model.setIsObj(isObj); if(isObj == 1){ //看看,看见 Scene scene = sceneService.getByNum(num); if(scene == null){ throw new BusinessException(ResultCode.SCENE_NOT_EXIST); } String mesh3DtilesPath = String.format(FilePath.OBJ_OSS_PATH,num) + "/images/3dtiles/tileset.json"; String sizePath = scene.getWebPath() + String.format(FilePath.OBJ_OSS_PATH,num) + "/images/3dtiles"; if(localToOssUtil.existKey(scene.getWebPath() +mesh3DtilesPath)){ model.setModelDateType("b3dm"); model.setModelType("b3dm"); model.setModelGlbUrl(JSONArray.toJSONString(Arrays.asList(scene.getMapping() +"/" +mesh3DtilesPath))); model.setModelSize(FileWriterUtil.setFileSize(localToOssUtil.getSizeCount( sizePath))); }else { String meshPath = String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh"; if(localToOssUtil.existKey( scene.getWebPath() +meshPath +"/mesh.obj")){ Long size = localToOssUtil.getSizeCount( scene.getWebPath() +meshPath); model.setModelSize(FileWriterUtil.setFileSize(size)); model.setModelGlbUrl(JSONArray.toJSONString(Arrays.asList(scene.getMapping()+"/" + meshPath+"/mesh.obj"))); }else { List objPaths = new ArrayList<>(); String meshPathjs = String.format(FilePath.OBJ_OSS_PATH, num)+"/data/"; String jsonPath =scene.getWebPath() + meshPath + "/floors.json"; if(!localToOssUtil.existKey(jsonPath)){ jsonPath =scene.getWebPath() + meshPath +"mesh.json"; } if(localToOssUtil.existKey(jsonPath)){ String objectContent = localToOssUtil.getObjectContent(meshPath + "/floors.json"); JSONObject jsonObject = JSONObject.parseObject(objectContent); JSONArray floors1 = jsonObject.getJSONArray("floors"); for (Object object : floors1) { JSONObject jb = (JSONObject) object; String string = jb.getString("objPath"); objPaths.add(scene.getMapping()+"/" +meshPathjs + string); } model.setModelGlbUrl(JSONArray.toJSONString(objPaths)); Long size = localToOssUtil.getSize(scene.getWebPath() +meshPath); model.setModelSize(FileWriterUtil.setFileSize(size)); } } model.setModelType("obj"); } } model.setNum(num); this.saveOrUpdate(model); return model; } @Override public SceneVo getInfo(Integer modelId) { Model model = this.getById(modelId); if(model == null){ throw new BusinessException(ResultCode.SCENE_NOT_EXIST); } SceneVo sceneVo = new SceneVo(); BeanUtils.copyProperties(model,sceneVo); return sceneVo; } @Override public String uploadObjProgress(Integer modelId) { String redisKey = RedisKeyUtil.modelUpload+modelId; String cancel = RedisKeyUtil.modelCancelUpload+modelId; if(redisUtil.hasKey(cancel)){ return redisUtil.get(cancel); } if(redisUtil.hasKey(redisKey)){ return redisUtil.get(redisKey); } return "0"; } @Override public void cancelUpload(Integer modelId) { String redisKey = RedisKeyUtil.modelCancelUpload+modelId; if(redisUtil.hasKey(redisKey)){ return; } Model model = this.getById(modelId); if(model == null){ return; } model.setCreateStatus(-2); this.updateById(model); redisUtil.set(redisKey,"-2"); } @Override public HashMap getMapByNum(List numList) { HashMap map = new HashMap<>(); List modelList = this.getListByNum(numList); modelList.forEach(entity-> map.put(entity.getNum() + entity.getType(),entity)); return map; } @Override public void copyModel(Integer modelId) { Model modelEntity = this.getById(modelId); if(modelEntity == null){ throw new BusinessException(ResultCode.MODEL_NOT_EXIST); } Integer oldId = modelEntity.getModelId(); modelEntity.setModelTitle(modelEntity.getModelTitle() +"(copy)"); modelEntity.setModelId(null); this.save(modelEntity); // if(StringUtils.isNotBlank(modelEntity.getModelGlbUrl())){ // String modelGlbUrl = modelEntity.getModelGlbUrl(); // copyOssResource(modelGlbUrl,oldId,modelEntity.getModelId()); // String newModelObjUrl = modelGlbUrl.replaceAll(oldId+"",modelEntity.getModelId()+""); // modelEntity.setModelGlbUrl(newModelObjUrl); // this.updateById(modelEntity); // } } private String getGlbUrl(Integer type, String num,Model model,String scenePath) { if(type == 0 || type == 1 || type == 4 || type == 6 || type == 7){ //看看,看见 //ShellUtil.yunDownload(String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh" ,objPath); String objPathSource = scenePath + String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh"; String objPath = String.format(FilePath.OBJ_LOCAL_PATH ,environment,num); ShellUtil.yunDownload(objPathSource ,objPath); List localGlbPaths = new ArrayList<>(); List ossGlbPaths = new ArrayList<>(); File localFile = new File(objPath); this.toGlB(localFile,localGlbPaths); Long modelSize = 0L; if(localGlbPaths.size() >0){ for (String localGlbPath : localGlbPaths) { String ossGlbPath = localGlbPath.replace(FilePath.LOCAL_BASE_PATH,"fusion/"); localToOssUtil.uploadOss(localGlbPath,ossGlbPath); if(ossGlbPath.contains("lod_")){ if(ossGlbPath.contains("lod_0")){ ossGlbPaths.add(CacheUtil.mapping +ossGlbPath); modelSize += localToOssUtil.getSize(ossGlbPath); } continue; } modelSize += localToOssUtil.getSize(ossGlbPath); ossGlbPaths.add( CacheUtil.mapping +ossGlbPath); } model.setModelSize(FileWriterUtil.setFileSize(modelSize)); FileUtil.del(objPath); return JSONArray.toJSONString(ossGlbPaths); } FileUtil.del(objPath); } return null; } private void toGlB(File localFile, List localGlbPath) { File[] files = localFile.listFiles(); for (File file : files) { if(file.isDirectory()){ toGlB(file,localGlbPath); } if(file.getName().contains(".obj")){ String glbPath = OBJToGLBUtil.objToGlb(file.getPath(),file.getPath().replace(".obj",".glb") ); localGlbPath.add(glbPath); } } } }