package com.fdkankan.manage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fdkankan.common.constant.ConstantFilePath; import com.fdkankan.common.constant.SceneConstant; import com.fdkankan.common.constant.UploadFilePath; import com.fdkankan.common.exception.BusinessException; import com.fdkankan.common.response.PageInfo; import com.fdkankan.common.util.CreateObjUtil; import com.fdkankan.common.util.FileUtils; import com.fdkankan.common.util.MatrixToImageWriterUtil; import com.fdkankan.common.util.RandomUtil; import com.fdkankan.manage.httpClient.service.LaserService; import com.fdkankan.manage.util.MangerUploadToOssUtil; import com.fdkankan.manage.common.CameraConstant; import com.fdkankan.manage.entity.*; import com.fdkankan.manage.mapper.ISceneProMapper; import com.fdkankan.manage.service.*; import com.fdkankan.manage.util.SceneStatusUtil; import com.fdkankan.manage.vo.request.SceneParam; import com.fdkankan.manage.vo.response.GroupByCount; import com.fdkankan.manage.vo.response.SceneVo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; import java.io.File; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; /** *

* pro场景表 服务实现类 *

* * @author * @since 2022-06-16 */ @Service @Slf4j public class SceneProServiceImpl extends ServiceImpl implements ISceneProService { @Autowired private ICameraService cameraService; @Autowired ICameraDetailService cameraDetailService; @Autowired ISceneService sceneService; @Autowired ISceneCopyLogService copyLogService; @Autowired IUserIncrementService userIncrementService; @Autowired ISceneProEditService sceneProEditService; @Autowired private MangerUploadToOssUtil mangeUploadToOssUtil; @Autowired IScenePlusService scenePlusService; @Autowired IScene3dNumService scene3dNumService; @Autowired ISceneCopyLogService sceneCopyLogService; @Autowired IScenePlusExtService scenePlusExtService; @Autowired LaserService laserService; @Value("${main.url}") private String mainUrl; @Value("${scene.pro.url}") private String sceneProUrl; @Value("${scene.pro.new.url}") private String sceneProNewUrl; @Override public ScenePro getByNum(String num) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ScenePro::getNum,num); wrapper.eq(ScenePro::getIsUpgrade,0); List list = this.list(wrapper); if(list == null || list.size() <=0){ return null; } return list.get(0); } @Override public HashMap getCountGroupByUserId(List userIdList) { HashMap map = new HashMap<>(); List result = this.getBaseMapper().getCountGroupByUserId(userIdList); result.forEach(entity ->map.put(entity.getId(),entity.getCount())); return map; } @Override public HashMap getCountGroupByCameraId(List cameraIds) { HashMap map = new HashMap<>(); List result = this.getBaseMapper().getCountGroupByCameraId(cameraIds); result.forEach(entity ->map.put(entity.getId(),entity.getCount())); return map; } @Override public void unbindCamera(Long cameraId) { LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>(); wrapper.set(ScenePro::getUserId,null) .eq(ScenePro::getCameraId,cameraId); wrapper.eq(ScenePro::getIsUpgrade,0); this.update(wrapper); } @Override public List getListByCameraId(Long cameraId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(ScenePro::getCameraId,cameraId); wrapper.eq(ScenePro::getIsUpgrade,0); return this.list(wrapper); } /** * @param payStatus -2 封存,为 1 解封 */ @Override public void lockOrUnLockBySpace(CameraDetail cameraDetail,Long cameraId,Integer payStatus) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper plusWr = new LambdaQueryWrapper<>(); Long count = 0L; if(payStatus == 1){ //解封,判断用户权益,用户会员权益无限容量 count = userIncrementService.getValidCountByCameraId(cameraId); wrapper.orderByAsc(ScenePro::getCreateTime); plusWr.orderByAsc(ScenePlus::getCreateTime); }else { wrapper.orderByDesc(ScenePro::getCreateTime); plusWr.orderByDesc(ScenePlus::getCreateTime); } wrapper.eq(ScenePro::getCameraId,cameraId) .eq(ScenePro::getPayStatus,payStatus) .eq(ScenePro::getSceneScheme,4) .eq(ScenePro::getIsUpgrade,0); plusWr.eq(ScenePlus::getCameraId,cameraId) .eq(ScenePlus::getPayStatus,payStatus); List list = this.list(wrapper); List plusList = scenePlusService.list(plusWr); Long beyondSpace = Math.abs(cameraDetail.getUsedSpace() - cameraDetail.getTotalSpace()); Long accumulateSpace = 0L; List lockedIds = new ArrayList<>(); if(payStatus == 1){ getScenePlusLockedIds(lockedIds,plusList,count,beyondSpace,accumulateSpace); getSceneLockedIds(lockedIds,list,count,beyondSpace,accumulateSpace); }else { getSceneLockedIds(lockedIds,list,count,beyondSpace,accumulateSpace); getScenePlusLockedIds(lockedIds,plusList,count,beyondSpace,accumulateSpace); } lockOrUnLockScenes(lockedIds,payStatus); } private void getSceneLockedIds(List lockedIds ,List list,Long count,Long beyondSpace,Long accumulateSpace){ if (list != null && list.size() > 0){ for (ScenePro scenePro : list){ accumulateSpace += scenePro.getSpace(); if (count ==0 && accumulateSpace.compareTo(beyondSpace) > 0){ break; } lockedIds.add(scenePro.getId()); } } } private void getScenePlusLockedIds(List lockedIds ,List list,Long count,Long beyondSpace,Long accumulateSpace){ if (list != null && list.size() > 0){ List plusIds = list.parallelStream().map(ScenePlus::getId).collect(Collectors.toList()); HashMap byPlusIds = scenePlusExtService.getByPlusIds(plusIds); for (ScenePlus scenePlus : list){ ScenePlusExt scenePlusExt = byPlusIds.get(scenePlus.getId()); accumulateSpace += scenePlusExt.getSpace(); if (count ==0 && accumulateSpace.compareTo(beyondSpace) > 0){ break; } lockedIds.add(scenePlus.getId()); } } } // payStatus 为 -2 封存,为 1 解封 private void lockOrUnLockScenes(List lockedIds,Integer payStatus) { if (lockedIds == null || lockedIds.size() == 0){ return; } LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.set(ScenePro::getPayStatus,payStatus) .eq(ScenePro::getIsUpgrade,0) .in(ScenePro::getId,lockedIds); this.update(updateWrapper); LambdaUpdateWrapper updatePlusWrapper = new LambdaUpdateWrapper<>(); updatePlusWrapper.set(ScenePlus::getPayStatus,payStatus) .in(ScenePlus::getId,lockedIds); scenePlusService.update(updatePlusWrapper); } @Override public PageInfo pageList(SceneParam param) { if(param.getType() == 2){ //深时 return laserService.pageList(param); } if(param.getType() == 3){ //双目lite return sceneService.pageList(param); } Page page = this.getBaseMapper().pageList(new Page<>(param.getPageNum(),param.getPageSize()),param); for (SceneVo record : page.getRecords()) { record.setStatusString(SceneStatusUtil.getStatusString(record)); } return PageInfo.PageInfo(page); } @Override public void move(SceneParam param) { Camera camera = cameraService.getBySnCode(param.getSnCode()); if(camera == null){ throw new BusinessException(-1,"sn码不存在。"); } CameraDetail cameraDetail = cameraDetailService.getByCameraId(camera.getId()); if(cameraDetail == null){ throw new BusinessException(-1,"sn码不存在。"); } ScenePro scenePro = this.getByNum(param.getNum()); ScenePlus scenePlus = scenePlusService.getByNum(param.getNum()); if((scenePro == null || scenePro.getCameraId() == null ) && (scenePlus== null || scenePlus.getCameraId() == null)){ throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005); } Long cameraId = scenePro == null ? scenePlus.getCameraId() : scenePro.getCameraId(); Long space = scenePro == null ? 0 :scenePro.getSpace(); if(scenePlus !=null){ ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId()); space = scenePlusExt.getSpace(); } Long newUseSpace = space + cameraDetail.getUsedSpace(); if(newUseSpace > cameraDetail.getTotalSpace()){ throw new BusinessException(-1,"相机容量不足,不能迁移"); } Camera oldCamera = cameraService.getById(cameraId); if(oldCamera == null){ throw new BusinessException(-1,"旧相机不存在"); } CameraDetail oldCameraDetail = cameraDetailService.getByCameraId(camera.getId()); if(oldCameraDetail == null){ throw new BusinessException(-1,"旧相机不存在。"); } if(!oldCameraDetail.getType().equals(cameraDetail.getType())){ throw new BusinessException(-1,"必须迁移至相同的类型的相机下面!"); } Long oldUseSpace = oldCameraDetail.getUsedSpace() - space < 0 ? 0 : oldCameraDetail.getUsedSpace() - space; oldCameraDetail.setUsedSpace(oldUseSpace); Long subSpace = oldCameraDetail.getTotalSpace() - oldUseSpace; if(subSpace >0){ //有剩余容量解封容量内场景 this.lockOrUnLockBySpace(oldCameraDetail,oldCameraDetail.getCameraId(),1); } cameraDetailService.updateById(oldCameraDetail); cameraDetail.setUsedSpace(newUseSpace); cameraDetailService.updateById(cameraDetail); if(scenePro!=null){ scenePro.setCameraId(camera.getId()); scenePro.setUserId(cameraDetail.getUserId()); this.updateById(scenePro); } if(scenePlus!=null){ scenePlus.setCameraId(camera.getId()); scenePlus.setUserId(cameraDetail.getUserId()); scenePlusService.updateById(scenePlus); } } @Override public void copy(String sceneNum) throws Exception { ScenePro scenePro = this.getByNum(sceneNum); ScenePlus scenePlus = scenePlusService.getByNum(sceneNum); if((scenePro == null || scenePro.getCameraId() == null ) && (scenePlus== null || scenePlus.getCameraId() == null)){ throw new BusinessException(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005); } Long cameraId = scenePro == null ? scenePlus.getCameraId() : scenePro.getCameraId(); CameraDetail detailEntity = cameraDetailService.getByCameraId(cameraId); if(detailEntity == null){ throw new BusinessException(CameraConstant.FAILURE_CODE_6029, CameraConstant.FAILURE_MSG_6029); } String newNum = scene3dNumService.generateSceneNum(detailEntity.getType()); if(scenePro !=null){ //v3场景复制 this.copyV3Scene(scenePro,newNum,detailEntity); } if(scenePlus != null){ //v4场景复制 scenePlusService.copyV4Scene(scenePlus,newNum,detailEntity); } } @Override public void deleteByNum(String num) { ScenePro scenePro = this.getByNum(num); if(scenePro!=null){ this.removeById(scenePro.getId()); } Scene scene = sceneService.getByNum(num); if(scene!=null){ sceneService.removeById(scene.getId()); } ScenePlus scenePlus = scenePlusService.getByNum(num); if(scenePlus!=null){ scenePlusService.removeById(scenePlus.getId()); } } @Override public void copyV3Scene(ScenePro oldScene,String newNum,CameraDetail cameraDetail) throws Exception { SceneProEdit oldEditScene = sceneProEditService.getByProId(oldScene.getId()); String oldNum = oldScene.getNum(); //复制数据库数据 oldScene.setId(null); oldScene.setStatus(0); oldScene.setNum(newNum); oldScene.setSceneName(oldScene.getSceneName().concat("(copy)")); oldScene.setWebSite(oldScene.getWebSite().replace(oldScene.getNum(), newNum)); oldScene.setThumb(oldScene.getThumb().replace(oldScene.getNum(), newNum)); oldScene.setVideos(oldScene.getVideos().replace(oldNum,newNum)); oldScene.setViewCount(0); String preDataSource = oldScene.getDataSource(); oldScene.setDataSource(this.setDataSource(preDataSource,oldScene.getSceneSource())); this.save(oldScene); sceneCopyLogService.saveByNum(oldNum,newNum,oldScene.getUserId()); //复制完成更新相机容量 cameraDetail.setUsedSpace(cameraDetail.getUsedSpace() + oldScene.getSpace()); cameraDetailService.updateById(cameraDetail); oldEditScene.setId(null); oldEditScene.setProId(oldScene.getId()); oldEditScene.setScreencapVoiceSrc(oldEditScene.getScreencapVoiceSrc() == null ? null : oldEditScene.getScreencapVoiceSrc().replace(oldNum, newNum)); oldEditScene.setScreencapVoiceSound(oldEditScene.getScreencapVoiceSound() == null ? null : oldEditScene.getScreencapVoiceSound().replace(oldNum, newNum)); oldEditScene.setScreencapVoiceSoundsync(oldEditScene.getScreencapVoiceSoundsync() == null ? null : oldEditScene.getScreencapVoiceSoundsync().replace(oldNum, newNum)); oldEditScene.setPlayData(oldEditScene.getPlayData() == null ? null : oldEditScene.getPlayData().replace(oldNum, newNum)); oldEditScene.setScreencapThumb(oldEditScene.getScreencapThumb() == null ? null : oldEditScene.getScreencapThumb().replace(oldNum, newNum)); oldEditScene.setFloorPlanPng(oldEditScene.getFloorPlanPng() == null ? null : oldEditScene.getFloorPlanPng().replace(oldNum, newNum)); sceneProEditService.save(oldEditScene); this.setQrCode(oldScene.getBuildType(), oldScene.getNum()); CompletableFuture.runAsync(() -> { try { log.info("开始复制场景-{}", new Date()); //oss复制计算结果资源 this.copyOssSource("v3",oldNum,newNum); this.copyLocalSource(oldNum,newNum); this.updateSceneJson("v3",oldScene.getVideos(),newNum,oldScene.getSceneName(),oldScene.getWebSite(),oldScene.getThumb(),oldScene.getId()); //上传资源到oss this.uploadNewSceneToOss(newNum); oldScene.setStatus(-2); this.updateById(oldScene); log.info("复制场景结束-{}", new Date()); } catch (Exception e) { log.error("复制场景异常", e); } }); } @Override public void updateSceneJson(String type,String videos,String newNum,String sceneName,String webSite,String thumb,Long id) throws Exception { //更新video HashMap map = new HashMap<>(); map.put("videos",videos); map.put("sceneName",sceneName); map.put("webSite",webSite); map.put("thumb",thumb); map.put("num",newNum); map.put("id",id); String uploadPath ; String localPath = ConstantFilePath.SCENE_PATH + "data/data" + newNum + File.separator + "scene.json"; if(type.equals("v3")){ uploadPath = localPath.replace(ConstantFilePath.SCENE_PATH, ""); }else { uploadPath =localPath.replace(ConstantFilePath.SCENE_V4_PATH, ""); } FileUtils.writeJsonFile(localPath, map); if(type.equals("v4")){ mangeUploadToOssUtil.upload(localPath,uploadPath); } } @Override public void uploadNewSceneToOss(String newNum) { Map map = new HashMap(); List urlList = new ArrayList<>(); FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "images/images" + newNum, urlList); FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "data/data" + newNum, urlList); FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "voice/voice" + newNum, urlList); FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "video/video" + newNum, urlList); for(String url : urlList){ map.put(url, url.replace(ConstantFilePath.SCENE_PATH, "")); } mangeUploadToOssUtil.uploadMulFiles(map); } @Override public String setDataSource(String preDataSource,Integer sceneSource) throws Exception { String datasourceFix; String newDataSource; // 判断场景是否拷贝过 ScenePro entity; do{ datasourceFix = RandomUtil.generateShortUuid(); entity = this.findByFileId(preDataSource.concat(datasourceFix)); }while(!ObjectUtils.isEmpty(entity)); newDataSource = datasourceFix.concat(datasourceFix); //oss复制源文件 String buildModelPath = ConstantFilePath.BUILD_MODEL_PATH; if(sceneSource.equals(4)){ buildModelPath = ConstantFilePath.BUILD_MODEL_LASER_PATH; } CreateObjUtil.ossUtilCp(ConstantFilePath.OSS_PREFIX +newDataSource.replace(buildModelPath, "")+"/", newDataSource); List urlList = new ArrayList<>(); FileUtils.readfilePath(newDataSource, urlList); Map fileMap = new HashMap<>(); for(String url : urlList){ fileMap.put(url, ConstantFilePath.OSS_PREFIX + url.replace(buildModelPath, "")); } mangeUploadToOssUtil.uploadMulFiles(fileMap); FileUtils.delAllFile(newDataSource); FileUtils.copyFolderAllFiles(preDataSource+"/",newDataSource+"/", true); return datasourceFix.concat(datasourceFix); } @Override public ScenePro findByFileId(String fileId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.like(ScenePro::getDataSource,fileId); List list = this.list(wrapper); if(list !=null && list.size() >0){ return list.get(0); } return null; } @Override public void setQrCode(String buildType,String num) throws Exception { String basePath = mainUrl; if("V2".equals(buildType)){ basePath += sceneProUrl; } if("V3".equals(buildType)){ basePath += sceneProNewUrl; } MatrixToImageWriterUtil.createQRCode(basePath + num, ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+num+".png", false,null); MatrixToImageWriterUtil.createQRCode(basePath + num + "&lang=en", ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+num+"_en.png", false,null); } @Override public void copyOssSource(String type ,String sceneNum, String newNum) throws Exception { List copyList = new ArrayList<>(); if(type.equals("v3")){ copyList.add("images/images" + sceneNum); copyList.add("data/data" + sceneNum); copyList.add("voice/voice" + sceneNum); copyList.add("video/video"+ sceneNum); }else if(type.equals("v4")){ String oldEditPath = String.format(UploadFilePath.EDIT_PATH, sceneNum); String oldViewPath = String.format(UploadFilePath.VIEW_PATH, sceneNum); copyList.add(oldEditPath); copyList.add(oldViewPath); } for (String sourcePath : copyList) { mangeUploadToOssUtil.copyFiles(sourcePath,sourcePath.replaceAll(sceneNum,newNum)); } } @Override public void copyLocalSource(String sceneNum, String newNum) throws Exception { FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"images/images" + sceneNum,ConstantFilePath.SCENE_PATH +"images/images" + newNum); FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"data/data" + sceneNum,ConstantFilePath.SCENE_PATH +"data/data" + newNum); reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/link-scene.json",sceneNum, newNum); reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/hot.json",sceneNum, newNum); FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"voice/voice" + sceneNum,ConstantFilePath.SCENE_PATH +"voice/voice" + newNum); FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"video/video" + sceneNum,ConstantFilePath.SCENE_PATH +"video/video" + newNum); } private void reloadFile(String filePath,String sceneNum, String newNum) throws Exception { // 修改link-scene.json String content = FileUtils.readFile(filePath); if (!ObjectUtils.isEmpty(content)) { content = content.replaceAll(sceneNum, newNum); FileUtils.writeFile(filePath,content); } } }