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 com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.fdkankan.common.constant.ConstantFilePath; import com.fdkankan.common.constant.ErrorCode; import com.fdkankan.common.constant.UploadFilePath; import com.fdkankan.common.exception.BusinessException; import com.fdkankan.model.utils.ConvertUtils; import com.fdkankan.redis.constant.RedisKey; import com.fdkankan.redis.util.RedisClient; import com.fdkankan.scene.bean.IconBean; import com.fdkankan.scene.bean.ResultData; import com.fdkankan.scene.bean.TagBean; import com.fdkankan.scene.entity.Scene; import com.fdkankan.scene.entity.SceneEditInfo; import com.fdkankan.scene.service.FYunFileService; import com.fdkankan.scene.service.ISceneProService; import com.fdkankan.scene.service.SceneEditInfoService; import com.fdkankan.scene.service.SceneService; import com.fdkankan.scene.vo.*; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; /** *

* pro场景表 服务实现类 *

* * @author dengsixing * @since 2021-12-23 */ @Slf4j @Service public class SceneProServiceImpl implements ISceneProService { // @Value("${fyun.host}") // private String ossUrlPrefix; // @Value("${fyun.type}") // private String fyunType; // @Value("${main.url}") // private String mainUrl; // @Value("${scene.url}") // private String sceneUrl; // @Value("${scene.pro.url}") // private String sceneProUrl; // @Value("${scene.pro.new.url}") // private String sceneProNewUrl; // @Value("${ecs.checkFile.maxTimes:5}") // private int maxCheckTimes; // @Value("${ecs.checkFile.waitTime:5000}") // private int waitTime; // @Autowired private FYunFileService fYunFileService; // @Autowired // private RedisLockUtil redisLockUtil; @Resource private RedisClient redisClient; // @Autowired // private ISceneDataDownloadService sceneDataDownloadService; // @Autowired // private ISceneProService sceneProService; @Autowired private SceneEditInfoService sceneEditInfoService; // @Autowired // private ISceneEditControlsService sceneEditControlsService; @Autowired private SceneService scenePlusService; // @Autowired // private IScenePlusExtService scenePlusExtService; // @Autowired // private ISceneUploadService sceneUploadService; // @Autowired // private ISceneAsynOperLogService sceneAsynOperLogService; @Transactional @Override public ResultData saveInitialPage(FileNameAndDataParamVO param) throws Exception{ Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup()); if(scenePlus == null){ throw new BusinessException(ErrorCode.FAILURE_CODE_5005); } SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); if(sceneEditInfo == null){ sceneEditInfo = new SceneEditInfo(); sceneEditInfo.setScenePlusId(scenePlus.getId()); sceneEditInfo.setEntry(param.getData()); sceneEditInfoService.save(sceneEditInfo); }else{ sceneEditInfoService.update( new LambdaUpdateWrapper() .set(SceneEditInfo::getEntry, param.getData()) .setSql("version = version + 1") .eq(SceneEditInfo::getId, sceneEditInfo.getId())); } return ResultData.ok(); } @Override public ResultData addOrUpdateTag(SaveTagsParamVO param) throws Exception { Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup()); if (scenePlus == null) throw new BusinessException(ErrorCode.FAILURE_CODE_5005); this.addOrUpdateHotData(param.getNum(), param.getSubgroup(), param.getHotDataList()); this.addOrUpdateIcons(param.getNum(), param.getSubgroup(), param.getIcons()); //保存数据库 SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); sceneEditInfoService.saveTagsToSceneEditInfo(param.getNum(), param.getSubgroup(), sceneEditInfo); sceneEditInfoService.updateById(sceneEditInfo); this.publicHotData(param.getNum(), param.getSubgroup()); return ResultData.ok(); } private void addOrUpdateHotData(String num, Integer subgroup, List hotDataList) throws Exception{ Map addOrUpdateMap = new HashMap<>(); int i = 0; for (HotParamVO hotParamVO : hotDataList) { JSONObject jsonObject = JSON.parseObject(hotParamVO.getHotData()); jsonObject.put("createTime", Calendar.getInstance().getTimeInMillis() + i++); addOrUpdateMap.put(hotParamVO.getSid(), jsonObject.toJSONString()); } // this.syncHotFromFileToRedis(num); //处理新增和修改数据 this.addOrUpdateHotDataHandler(num, subgroup, addOrUpdateMap); } private void addOrUpdateIcons(String num, Integer subgroup, Set icons) throws Exception{ if(CollUtil.isEmpty(icons)){ return; } // this.syncIconsFromFileToRedis(num); String key = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup)); redisClient.sSet(key, icons); } @Override public ResultData deleteTag(DeleteHotParamVO param) throws Exception { Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup()); if (scenePlus == null) throw new BusinessException(ErrorCode.FAILURE_CODE_5005); List deleteSidList = param.getSidList(); //处理删除状态数据 this.deleteHotData(param.getNum(), param.getSubgroup(), deleteSidList); //删除导览中的热点数据 this.deleteHotDataFromTourJson(param.getNum(), param.getSubgroup(), param.getSidList()); // //写入本地文件,作为备份 // this.writeHotJson(param.getNum()); //保存数据库 SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); sceneEditInfoService.saveTagsToSceneEditInfo(param.getNum(), param.getSubgroup(), sceneEditInfo); sceneEditInfoService.updateById(sceneEditInfo); this.publicHotData(param.getNum(), param.getSubgroup()); return ResultData.ok(); } private void deleteHotDataFromTourJson(String num, Integer subgroup, List sidList) throws IOException { String key = String.format(UploadFilePath.USER_VIEW_PATH, num) + "tour.json"; String tourJson = fYunFileService.getFileContent(key, subgroup); if(StrUtil.isEmpty(tourJson)){ return; } JSONArray jsonArray = JSON.parseArray(tourJson); if(CollUtil.isEmpty(jsonArray)){ return; } jsonArray.stream().forEach(tour->{ JSONObject obj = (JSONObject) tour; JSONArray itemArra = obj.getJSONArray("list"); itemArra.stream().forEach(item->{ JSONObject itemObj = (JSONObject) item; String tagId = itemObj.getString("tagId"); if(tagId != null && sidList.contains(tagId)){ itemObj.remove("tagId"); } }); }); fYunFileService.uploadFile(num, subgroup, jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8), key); } @Override public ResultData deleteIcons(DeleteHotIconParamVO param) throws Exception { Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup()); if (scenePlus == null) throw new BusinessException(ErrorCode.FAILURE_CODE_5005); List fileNameList = param.getFileNameList(); // this.syncIconsFromFileToRedis(param.getNum()); String key = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(param.getNum(), param.getSubgroup())); redisClient.setRemove(key, new HashSet<>(fileNameList)); //写入本地文件,作为备份 // this.writeHotJson(param.getNum()); return ResultData.ok(); } @Override public ResultData listTags(String num, Integer subgroup) throws Exception{ //保证热点数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis // this.syncHotFromFileToRedis(num); //保证icons数据安全性,当redis宕机导致icons数据丢失时,可以从文件中读取,恢复到redis // this.syncIconsFromFileToRedis(num); JSONObject result = new JSONObject(); //查询缓存是否包含热点数据 String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup)); Map allTagsMap = redisClient.hmget(key); List tags = Lists.newArrayList(); List tagBeanList = new ArrayList<>(); if(CollUtil.isNotEmpty(allTagsMap)){ allTagsMap.entrySet().stream().forEach(entry -> { JSONObject jsonObject = JSON.parseObject(entry.getValue()); tagBeanList.add( TagBean.builder() .createTime(jsonObject.getLong("createTime")) .tag(jsonObject).build()); }); //按创建时间倒叙排序 tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed()); //移除createTime字段 tags = tagBeanList.stream().map(tagBean -> { JSONObject tag = tagBean.getTag(); tag.remove("createTime"); return tag; }).collect(Collectors.toList()); } result.put("tags", tags); //查询缓存是否包含icons key = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup)); Set icons = redisClient.sGet(key); if(icons == null){ icons = Sets.newHashSet(); } List iconList = this.sortIcons(tags, icons); result.put("icons", iconList); return ResultData.ok(result); } private List sortIcons(List tags, Set icons){ //统计使用频次 List iconBeans = Lists.newArrayList(); for (String icon : icons) { int count = 0; for (JSONObject tag : tags) { String sid = tag.getString("icon"); if(StrUtil.isEmpty(sid) || !icon.equals(sid)){ continue; } ++count; } iconBeans.add(IconBean.builder().icon(icon).count(count).build()); } //排序 List iconList = iconBeans.stream().sorted(Comparator.comparing(IconBean::getCount).reversed()) .map(item -> { return item.getIcon(); }).collect(Collectors.toList()); return iconList; } private void publicHotData(String sceneNum, Integer subgroup) { String hotDataKey = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(sceneNum, subgroup)); Map hotMap = redisClient.hmget(hotDataKey); JSONArray tags = new JSONArray(); if(CollUtil.isNotEmpty(hotMap)){ List tagBeanList = hotMap.entrySet().stream().map(entry -> { JSONObject jsonObject = JSON.parseObject(entry.getValue()); return TagBean.builder() .createTime(jsonObject.getLong("createTime")) .tag(jsonObject).build(); }).collect(Collectors.toList()); //按创建时间倒叙排序 tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed()); //移除createTime字段 tagBeanList.stream().forEach(tagBean -> { tags.add(tagBean.getTag()); }); } String hotJsonPath = String.format(UploadFilePath.USER_VIEW_PATH, sceneNum) + "hot.json"; fYunFileService.uploadFile(sceneNum, subgroup, tags.toString().getBytes(StandardCharsets.UTF_8), hotJsonPath); } // // /** // *

// 保证热点数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis // *

// * @author dengsixing // * @date 2022/3/3 // **/ // private void syncHotFromFileToRedis(String num) throws Exception{ // // String key = String.format(RedisKey.SCENE_HOT_DATA, num); // boolean exist = redisUtil.hasKey(key); // if(exist){ // return; // } // String lockKey = String.format(RedisLockKey.LOCK_HOT_DATA_SYNC, num); // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString(); // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE); // if(!lock){ // throw new BusinessException(ErrorCode.SYSTEM_BUSY); // } // try{ // exist = redisUtil.hasKey(key); // if(exist){ // return; // } // String tagsFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "hot.json"; // String tagsData = FileUtils.readUtf8String(tagsFilePath); // if(StrUtil.isEmpty(tagsData)){ // return; // } // JSONObject jsonObject = JSON.parseObject(tagsData); // JSONArray tagsArr = jsonObject.getJSONArray("tags"); // if(CollUtil.isEmpty(tagsArr)){ // return; // } // Map map = new HashMap<>(); // for (Object o : tagsArr) { // JSONObject jo = (JSONObject)o; // map.put(jo.getString("sid"), jo.toJSONString()); // } // redisUtil.hmset(key, map); // }finally { // redisLockUtil.unlockLua(lockKey, lockVal); // } // } // // /** // *

// 保证icons数据安全性,当redis宕机导致icons数据丢失时,可以从文件中读取,恢复到redis // *

// * @author dengsixing // * @date 2022/3/3 // **/ // private void syncIconsFromFileToRedis(String num) throws Exception{ // // String key = String.format(RedisKey.SCENE_HOT_ICONS, num); // boolean exist = redisUtil.hasKey(key); // if(exist){ // return; // } // String lockKey = String.format(RedisLockKey.LOCK_HOT_ICONS_SYNC, num); // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString(); // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE); // if(!lock){ // throw new BusinessException(ErrorCode.SYSTEM_BUSY); // } // try{ // exist = redisUtil.hasKey(key); // if(exist){ // return; // } // String tagsFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "hot.json"; // String tagsData = FileUtils.readUtf8String(tagsFilePath); // if(StrUtil.isEmpty(tagsData)){ // return; // } // JSONObject jsonObject = JSON.parseObject(tagsData); // JSONArray iconArr = jsonObject.getJSONArray("icons"); // if(CollUtil.isEmpty(iconArr)){ // return; // } // redisUtil.sSet(key, iconArr.toJavaList(String.class).toArray()); // }finally { // redisLockUtil.unlockLua(lockKey, lockVal); // } // // } // // /** // *

// 热点数据保存 // // *

// * @author dengsixing // * @date 2022/3/3 // **/ // private void writeHotJson(String num) throws Exception{ // // String dataKey = String.format(RedisKey.SCENE_HOT_DATA, num); // Map tagMap = redisUtil.hmget(dataKey); // List tagList = Lists.newArrayList(); // tagMap.entrySet().stream().forEach(entry->{ // if(StrUtil.isNotEmpty(entry.getValue())){ // tagList.add(entry.getValue()); // } // }); // JSONObject jsonObject = new JSONObject(); // JSONArray tagJsonArr = new JSONArray(); // if(CollUtil.isNotEmpty(tagList)){ // tagList.stream().forEach(hot->{ // tagJsonArr.add(JSONObject.parseObject(hot)); // }); // } // jsonObject.put("tags", tagJsonArr); // // String iconsKey = String.format(RedisKey.SCENE_HOT_ICONS, num); // Set iconList = redisUtil.sGet(iconsKey); // jsonObject.put("icons", iconList); // // String hotJsonPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "hot.json"; // String lockKey = String.format(RedisLockKey.LOCK_HOT_JSON, num); // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString(); // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE); // if(!lock){ // return; // } // try{ // FileUtils.writeFile(hotJsonPath, jsonObject.toJSONString()); // }finally { // redisLockUtil.unlockLua(lockKey, lockVal); // } // } private void addOrUpdateHotDataHandler(String num, Integer subgroup, Map addOrUpdateMap){ if(CollUtil.isEmpty(addOrUpdateMap)) return; //数据验证,新增、修改状态,hotdata不能为空 for (String sid : addOrUpdateMap.keySet()) { String hotData = addOrUpdateMap.get(sid); if(StrUtil.isEmpty(hotData)){ throw new BusinessException(ErrorCode.FAILURE_CODE_7004); } } //批量写入缓存 String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup)); redisClient.hmset(key, addOrUpdateMap); } private void deleteHotData(String num, Integer subgroup, List deleteSidList) throws Exception { // this.syncHotFromFileToRedis(num); if(CollUtil.isEmpty(deleteSidList)){ return; } //从redis中加载热点数据 String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup)); //从redis中移除热点数据 redisClient.hdel(key, deleteSidList); } @Override public ResultData saveTagsVisible(SaveTagsVisibleParamVO param) throws Exception { Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup()); if (scenePlus == null ) { throw new BusinessException(ErrorCode.FAILURE_CODE_5005); } JSONArray visiblePanos = JSONArray.parseArray(param.getData()); //如果redis找不到,就从本地文件中reload // this.syncHotFromFileToRedis(param.getNum()); //从缓存中获取热点数据,如果为空,抛出异常 String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(param.getNum(), param.getSubgroup())); Map map = redisClient.hmget(key); if (CollUtil.isEmpty(map)) { throw new BusinessException(ErrorCode.FAILURE_CODE_7005); } List> allTags = map.entrySet().stream().filter(item -> { if (StrUtil.isBlank(item.getValue())) { return false; } return true; }).collect(Collectors.toList()); if (CollUtil.isEmpty(allTags)) { throw new BusinessException(ErrorCode.FAILURE_CODE_7005); } allTags.stream().forEach(entry->{ JSONObject hot = JSON.parseObject(entry.getValue()); visiblePanos.stream().forEach(item->{ if (hot.getString("sid").equals(((JSONObject) item).getString("sid"))) { hot.put("visiblePanos", ((JSONObject) item).getJSONArray("value")); hot.put("isHidden", ((JSONObject) item).getBoolean("isHidden")); entry.setValue(hot.toJSONString()); } }); }); //更新版本号 SceneEditInfo editInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); sceneEditInfoService.upgradeVersionById(editInfo.getId()); //放入缓存 Map finalMap = new HashMap<>(); allTags.stream().forEach(entry->{ finalMap.put(entry.getKey(), entry.getValue()); }); redisClient.hmset(key, finalMap); //写入本地文件,作为备份,以防redis数据丢失 // this.writeHotJson(param.getNum()); this.publicHotData(param.getNum(), param.getSubgroup()); return ResultData.ok(); } public static void main(String[] args) { String tmpDirPath = FileUtil.getTmpDirPath(); System.out.println(tmpDirPath); } @Override public ResultData saveRoam(BaseDataParamVO param) throws Exception { Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup()); if (scenePlus == null ) { throw new BusinessException(ErrorCode.FAILURE_CODE_5005); } JSONArray inputData = JSONObject.parseArray(param.getData()); // String prefix = fileName.substring(fileName.lastIndexOf(".")); //// String path = String.format(ConstantFilePath.SCENE_TMP_PATH_V4, num).concat(UUID.randomUUID().toString()).concat(prefix); // File tempFile = File.createTempFile(UUID.randomUUID().toString() ,prefix); //// File tempFile = FileUtil.createTempFile(prefix, true); // String path = tempFile.getAbsolutePath(); // // // String localDataPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, RedisKey.getNumStr(param.getNum(), param.getSubgroup())); // File directory = new File(localDataPath); // if (!directory.exists()) { // directory.mkdirs(); // } String viewImagesPath = String.format(UploadFilePath.IMG_VIEW_PATH, param.getNum()); //如果是云存储,将vision.modeldata下载到本地,如果是本地存储,场景计算完就已经将这个文件拷贝到编辑目录了存在这个文件了,不需要再下载 // fYunFileService.downloadFile(bucket, viewImagesPath + "vision.modeldata", localDataPath + "vision.modeldata"); // // //检查vision.modeldata本地是否存在,不存在抛出异常 // File file = new File(localDataPath + "vision.modeldata"); // if(!file.exists()) { // return ResultData.error(ErrorCode.FAILURE_CODE_5012); // } // //将vision.modeldata解压缩至vision.json // ConvertUtils.convertVisionModelDataToTxt(localDataPath + "vision.modeldata", localDataPath + "vision.json"); // String str = FileUtils.readFile(localDataPath + "vision.json"); String modeldataKey = viewImagesPath + "vision.modeldata"; String tempPath = FileUtil.getTmpDirPath() + UUID.randomUUID() + "/"; String localModeldataPath = fYunFileService.downloadFile(param.getNum(), param.getSubgroup(), modeldataKey, tempPath, "vision.modeldata"); String localVisionTxtPath = tempPath + "vision.txt"; ConvertUtils.convertVisionmodeldataToTxt(localModeldataPath, localVisionTxtPath); // String str = ConvertUtils.transferVisionUuidToIndex(localVisionTxtPath); String str = FileUtil.readUtf8String(localVisionTxtPath); // String str = fYunFileService.getFileContent(viewImagesPath + "vision.txt", param.getSubgroup()); JSONObject json = JSONObject.parseObject(str); JSONArray panos = json.getJSONArray("sweepLocations"); for (int i = 0; i < panos.size(); ++i) { JSONObject pano = panos.getJSONObject(i); for (int j = 0; j < inputData.size(); ++j) { JSONObject jo = inputData.getJSONObject(j); String currentPanoId = jo.getString("panoID"); JSONArray visibles = jo.getJSONArray("visibles"); JSONArray visibles3 = jo.getJSONArray("visibles3"); if (pano.getString("uuid").replaceAll("-", "").equals(currentPanoId)) { pano.put("visibles", visibles); pano.put("visibles3", visibles3); } } } // FileUtils.deleteFile(localDataPath + "vision.json"); // FileUtils.deleteFile(localDataPath + "vision.modeldata"); // FileUtils.writeFile(localDataPath + "vision.json", json.toString()); File tempFile = File.createTempFile(UUID.randomUUID().toString(), ".json"); File tempFile2 = File.createTempFile(UUID.randomUUID().toString(), ".txt"); FileUtil.writeUtf8String(json.toString(), tempFile.getAbsolutePath()); ConvertUtils.convertTxtToVisionModelData(tempFile.getAbsolutePath(), tempFile2.getAbsolutePath()); fYunFileService.uploadFile(param.getNum(), param.getSubgroup(), tempFile2.getAbsolutePath(), viewImagesPath + "vision.modeldata"); FileUtil.del(tempFile); FileUtil.del(tempFile2); //更新版本号 SceneEditInfo editInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); if(Objects.isNull(editInfo)){ editInfo = new SceneEditInfo(); editInfo.setScenePlusId(scenePlus.getId()); sceneEditInfoService.save(editInfo); }else{ sceneEditInfoService.upgradeVersionAndImgVersionById(editInfo.getId()); //更新scenejson缓存和oss文件版本号 sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), param.getSubgroup(), editInfo.getVersion() + 1, editInfo.getImgVersion() + 1); } return ResultData.ok(); } // // @Override // public void updateUserIdByCameraId(Long userId, Long cameraId) { // this.update(new LambdaUpdateWrapper() // .eq(ScenePro::getCameraId, cameraId) // .set(ScenePro::getUserId, userId)); // } // // @Override // public ResultData uploadModel(String num, MultipartFile file) throws Exception{ // if(StrUtil.isEmpty(num)){ // throw new BusinessException(ServerCode.PARAM_REQUIRED, "num"); // } // if(!file.getOriginalFilename().endsWith(".zip")){ // throw new BusinessException(ErrorCode.FAILURE_CODE_7015); // } // // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num); // if(scenePlus == null){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5005); // } // // //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作 // sceneAsynOperLogService.checkSceneAsynOper(num, null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.MODEL.code()); // // //清除全景图异步操作记录,防止再次下载的时候请求到旧的压缩包 // sceneAsynOperLogService.cleanLog(num, SceneAsynModuleType.UPLOAD_DOWNLOAD.code(), SceneAsynFuncType.MODEL.code()); // // ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId()); // String bucket = scenePlusExt.getYunFileBucket(); // // if(ModelKind.THREE_D_TILE.code().equals(scenePlusExt.getModelKind())){ // this.buildModel43dtiles(num, bucket, scenePlusExt.getDataSource(), file); // }else{ // this.buildModel4Dam(num, bucket, scenePlusExt.getDataSource(), scenePlusExt.getBuildType(), file); // } // // return ResultData.ok(); // } // // // /** // * 老算法(dam)上传模型逻辑 // * @param num // * @param bucket // * @param dataSource // * @param buildType // * @throws Exception // */ // private void buildModel4Dam(String num, String bucket, String dataSource, String buildType, MultipartFile file) throws Exception { // //文件上传的位置可以自定义 // String path = dataSource + "_obj2txt"; // String zipPath = path + "/zip/"; // String filePath = path + "/extras/"; // String resultPath = path + "/results/"; // // //压缩文件处理:解压缩,解压缩后复制等操作 // this.objAndImgFileHandler(resultPath, filePath, zipPath, file); // // //创建data.json // this.writeDataJson(path); // // CompletableFuture.runAsync(() -> { // SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog(); // sceneAsynOperLog.setNum(num); // sceneAsynOperLog.setOperType(SceneAsynOperType.UPLOAD.code()); // sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code()); // sceneAsynOperLog.setFunc(SceneAsynFuncType.MODEL.code()); // sceneAsynOperLogService.save(sceneAsynOperLog); // try { // //调用算法,不同的类型调用不同的算法 // if("V2".equals(buildType)){ // CreateObjUtil.objToTxt(path , "1"); // } // if("V3".equals(buildType)){ // CreateObjUtil.build3dModel(path , "1"); // } // // //算法计算完后,生成压缩文件,上传到oss // uploadFileofterBuildDamModel(path, filePath, num, bucket); // // //更新版本信息 // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num); // SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); // sceneEditInfoService.update( // new LambdaUpdateWrapper() // .setSql("version = version + 1") // .setSql("floor_edit_ver = floor_edit_ver + 1") // .setSql("floor_publish_ver = floor_publish_ver + 1") // .setSql("img_version = img_version + 1") // .set(SceneEditInfo::getIsUploadObj, CommonStatus.YES.code()) // .eq(SceneEditInfo::getId, sceneEditInfo.getId())); // // sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket); // // sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code()); // } catch (Exception e) { // log.error("上传dam模型,num:" + num, e); // sceneAsynOperLog.setState(CommonOperStatus.FAILD.code()); // } // sceneAsynOperLogService.updateById(sceneAsynOperLog); // }); // } // // /** // * 新算法(3dtiles)上传模型逻辑 // * @param num // * @param bucket // * @param dataSource // * @throws Exception // */ // private void buildModel43dtiles(String num, String bucket, String dataSource, MultipartFile file) throws Exception { // //文件上传的位置可以自定义 // String path = dataSource + "_obj2Tiles" + File.separator; // String meshPath = path + "mesh"; // String zipPath = path + "zip" + File.separator; // String zipFilePath = zipPath + file.getOriginalFilename(); // // // //压缩文件处理:解压缩,解压缩后复制等操作 // FileUtil.del(path); // FileUtil.mkdir(zipPath); // File zipFile = new File(zipFilePath); // file.transferTo(zipFile); // ZipUtil.unzip(zipFilePath, meshPath); // // String jsonName = ""; // if(fYunFileService.fileExist(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/floors.json")){ // jsonName = "floors.json"; // } // if(fYunFileService.fileExist(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/mesh.json")){ // jsonName = "mesh.json"; // } // // //检测文件 // String floorsJsonPath = meshPath + File.separator + jsonName; // if(!FileUtil.exist(floorsJsonPath)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5068.code(), "json file is not exist!"); // } // String floorsJsonStr = FileUtil.readUtf8String(floorsJsonPath); // JSONObject floorsJsonObj = JSON.parseObject(floorsJsonStr); // JSONArray floorArr = floorsJsonObj.getJSONArray("floors"); // if(CollUtil.isEmpty(floorArr)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5069.code(), "json content is error"); // } // Set floorNameSet = new HashSet<>(); // String finalJsonName = jsonName; // floorArr.stream().forEach(item->{ // JSONObject itemObj = (JSONObject) item; // //楼层目录是否存在 // String name = itemObj.getString("name"); // if(StrUtil.isEmpty(name) || !FileUtil.exist(meshPath + File.separator + name)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5070); // } // //检测obj文件是否存在 // if("floors.json".equals(finalJsonName)){ // String objPath = itemObj.getString("objPath"); // if(StrUtil.isEmpty(objPath) || !FileUtil.exist(path + objPath)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5070); // } // }else{ // JSONArray lods = itemObj.getJSONArray("lods"); // if(CollUtil.isEmpty(lods)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5069.code(), "json content is error"); // } // for (Object lod : lods) { // JSONObject lodObj = (JSONObject) lod; // String objPath = lodObj.getString("objPath"); // if(StrUtil.isEmpty(objPath) || !FileUtil.exist(path + objPath)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5070); // } // } // } // if(floorNameSet.contains(name)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5069); // } // floorNameSet.add(name); // }); // // //读取oss上的floors.jsoon用于校验用户上传的模型楼层数是否一一对应 // String ossFloorsJson = fYunFileService.getFileContent(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/" + jsonName); // JSONObject orginFloorsJsonObj = JSON.parseObject(ossFloorsJson); // JSONArray orginFloorArr = orginFloorsJsonObj.getJSONArray("floors"); // Set orginFloorNameSet = orginFloorArr.stream().map(item -> { // JSONObject itemObj = (JSONObject) item; // return itemObj.getString("name"); // }).collect(Collectors.toSet()); // if(floorNameSet.size() != orginFloorNameSet.size()){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5070); // } // orginFloorNameSet.stream().forEach(orginName->{ // if(!floorNameSet.contains(orginName)){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5070); // } // }); // // SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog(); // sceneAsynOperLog.setNum(num); // sceneAsynOperLog.setOperType(SceneAsynOperType.UPLOAD.code()); // sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code()); // sceneAsynOperLog.setFunc(SceneAsynFuncType.MODEL.code()); // sceneAsynOperLogService.save(sceneAsynOperLog); // CompletableFuture.runAsync(() -> { // try { // //调用算法 // String command = "bash /home/ubuntu/bin/Obj2Tiles.sh " + path; // log.info("上传3dtiles模型开始, num:{}, targetPath:{}", num, path); // CreateObjUtil.callshell(command); // log.info("上传3dtiles模型结束, num:{}, targetPath:{}", num, path); // // //检测计算结果 // String tilesPath = path + "3dtiles"; // String tilesetJsonPath = tilesPath + File.separator + "tileset.json"; // boolean success = ComputerUtil.checkComputeCompleted(tilesetJsonPath, maxCheckTimes, waitTime); // if(!success){ // throw new BusinessException(ErrorCode.FAILURE_CODE_7013); // } // // //删除logs // FileUtil.del(tilesPath + File.separator + "logs"); // // //算法计算完后,生成压缩文件,上传到oss // //上传3dtiles // fYunFileService.deleteFolder(bucket, String.format(UploadFilePath.IMG_VIEW_PATH, num) + "3dtiles"); // fYunFileService.uploadFileByCommand(bucket, tilesPath, String.format(UploadFilePath.IMG_VIEW_PATH, num) + "3dtiles"); // //上传mesh // fYunFileService.deleteFolder(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh"); // fYunFileService.uploadFileByCommand(bucket, meshPath, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh"); // // //更新版本信息 // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num); // SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); // sceneEditInfoService.update( // new LambdaUpdateWrapper() // .setSql("version = version + 1") // .setSql("floor_edit_ver = floor_edit_ver + 1") // .setSql("floor_publish_ver = floor_publish_ver + 1") // .setSql("img_version = img_version + 1") // .set(SceneEditInfo::getIsUploadObj, CommonStatus.YES.code()) // .eq(SceneEditInfo::getId, sceneEditInfo.getId())); // // sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket); // // sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code()); // } catch (Exception e) { // log.error("上传全景图报错,num:" + num, e); // sceneAsynOperLog.setState(CommonOperStatus.FAILD.code()); // } // sceneAsynOperLogService.updateById(sceneAsynOperLog); // }); // // } // // private void uploadFileofterBuildDamModel(String path, String filePath, String sceneNum, String bucket) throws Exception { // //因为共享目录有延迟,这里循环检测算法是否计算完毕3次,每次隔五秒 // String uploadJsonPath = path + File.separator + "results" +File.separator+"upload.json"; // boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime); // if(!exist){ // throw new BusinessException(ErrorCode.FAILURE_CODE_7013); // } // String uploadData = FileUtils.readFile(uploadJsonPath); // JSONObject uploadJson = null; // JSONArray array = null; // if(uploadData!=null) { // uploadJson = JSONObject.parseObject(uploadData); // array = uploadJson.getJSONArray("upload"); // } // // Map map = new HashMap(); // JSONObject fileJson = null; // String fileName = ""; // String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, sceneNum); // for(int i = 0, len = array.size(); i < len; i++) { // fileJson = array.getJSONObject(i); // fileName = fileJson.getString("file"); // //文件不存在抛出异常 // if (!new File(path + File.separator + "results" + File.separator + fileName).exists()) { // throw new Exception(path + File.separator + "results" + File.separator + fileName + "文件不存在"); // } // // //tex文件夹 // if (fileJson.getIntValue("clazz") == 15) { // map.put(path + File.separator + "results" + File.separator + fileName, // imgViewPath + ConstantFileName.modelUUID + "_50k_texture_jpg_high1/" + fileName.replace("tex/", "")); // continue; // } // } // // String damPath = path + File.separator + "results" +File.separator+ ConstantFileName.modelUUID+"_50k.dam"; // CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", damPath); // boolean existDam = ComputerUtil.checkComputeCompleted(damPath, 5, 2); // if(!existDam){ // throw new BusinessException(ErrorCode.FAILURE_CODE_7013); // } //// CreateObjUtil.convertDamToLzma(path + File.separator + "results"); //// CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", path + File.separator + "results" + File.separator+ConstantFileName.modelUUID+"_50k.dam"); //// map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam.lzma", imgViewPath +ConstantFileName.modelUUID+"_50k.dam.lzma"); // map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam", imgViewPath+ConstantFileName.modelUUID+"_50k.dam"); // // String ossMeshPath = String.format(UploadFilePath.DATA_VIEW_PATH, sceneNum) + "mesh"; // //删除oss中的mesh // fYunFileService.deleteFolder(bucket, ossMeshPath); // //上传obj相关文件 // List fileNames = FileUtil.listFileNames(filePath); // fileNames.stream().forEach(name->map.put(filePath + name, ossMeshPath + File.separator + name)); // // fYunFileService.uploadMulFiles(bucket, map); // } // // private void writeDataJson(String path) throws IOException { // JSONObject dataJson = new JSONObject(); // dataJson.put("obj2txt", true); // dataJson.put("split_type", "SPLIT_V6"); // dataJson.put("data_describe", "double spherical"); // dataJson.put("skybox_type", "SKYBOX_V5"); // FileUtils.writeFile(path + "/data.json", dataJson.toString()); // } // // private void objAndImgFileHandler(String resultPath, String filePath, String zipPath, MultipartFile file) // throws Exception { // FileUtils.delAllFile(resultPath); // File targetFile = new File(filePath); // if (!targetFile.exists()) { // targetFile.mkdirs(); // }else { // FileUtils.delAllFile(filePath); // } // // targetFile = new File(zipPath); // if (!targetFile.exists()) { // targetFile.mkdirs(); // }else { // FileUtils.delAllFile(zipPath); // } // // targetFile = new File(zipPath + file.getOriginalFilename()); // if(!targetFile.getParentFile().exists()){ // targetFile.getParentFile().mkdirs(); // } // // 保存压缩包到本地 // if(targetFile.exists()) // { // FileUtils.deleteFile(zipPath + file.getOriginalFilename()); // } // file.transferTo(targetFile); // // ZipUtil.unzip(zipPath + file.getOriginalFilename(), zipPath + "data/"); // // //源文件数据,判断是否有多个文件夹,有多个就提示错误,有一个就将文件夹里数据迁移到extras目录,无直接迁移到extras目录 // boolean flag = false; // //目录名称,如果不为空,则压缩文件第一层是目录 // String targetName = ""; // File dataFile = new File(zipPath + "data/"); // for(File data : dataFile.listFiles()){ // if(data.isDirectory() && flag){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5018); // } // if(data.isDirectory() && !flag){ // flag = true; // targetName = data.getName(); // } // } // // //是否包含obj文件 // boolean objFlag = false; // //是否包含mtl文件 // boolean mtlFlag = false; // File[] files = null; // String dataPath = null; // if(StrUtil.isEmpty(targetName)){ // files = dataFile.listFiles(); // dataPath = zipPath + "data/"; // }else{ // files = new File(zipPath + "data/" + targetName).listFiles(); // dataPath = zipPath + "data/" + targetName + File.separator; // } // // for(File data : files){ // if(data.isDirectory()){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5018); // } // // if(data.getName().endsWith(".jpg") || data.getName().endsWith(".png")){ // if(!FileUtils.checkFileSizeIsLimit(data.length(), 1.5, "M")){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5020); // } // } // if(data.getName().endsWith(".obj")){ // if(objFlag){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5019); // } // if(!data.getName().equals("mesh.obj")){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5060); // } // if(!FileUtils.checkFileSizeIsLimit(data.length(), 20, "M")){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5020); // } // // objFlag = true; // FileUtils.copyFile(dataPath + data.getName(), filePath + "mesh.obj", true); // continue; // } // // if(data.getName().endsWith(".mtl")){ // mtlFlag = true; // } // // FileUtils.copyFile(dataPath + data.getName(), filePath + data.getName(), true); // } // // //压缩文件中必须有且仅有一个obj和mtl文件,否则抛出异常 // if(!mtlFlag || !objFlag){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5059); // } // } // // public ResultData downloadModel(String num) throws Exception { // // if(StrUtil.isEmpty(num)){ // throw new BusinessException(ErrorCode.PARAM_REQUIRED); // } // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num); // if(scenePlus == null){ // throw new BusinessException(ErrorCode.FAILURE_CODE_5005); // } // // //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作 // sceneAsynOperLogService.checkSceneAsynOper(num,null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.MODEL.code()); // // //清除旧的下载记录 // sceneAsynOperLogService.cleanLog(num, SceneAsynModuleType.UPLOAD_DOWNLOAD.code(), SceneAsynFuncType.MODEL.code(), SceneAsynOperType.DOWNLOAD.code()); // // ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId()); // String bucket = scenePlusExt.getYunFileBucket(); // // SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId()); // // //开始异步执行下载全景图压缩包操作 // CompletableFuture.runAsync(() -> { // SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog(); // sceneAsynOperLog.setNum(num); // sceneAsynOperLog.setOperType(SceneAsynOperType.DOWNLOAD.code()); // sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code()); // sceneAsynOperLog.setFunc(SceneAsynFuncType.MODEL.code()); // sceneAsynOperLog.setVersion(sceneEditInfo.getImgVersion()); // sceneAsynOperLogService.save(sceneAsynOperLog); // try { // // String url = null; // if(ModelKind.THREE_D_TILE.code().equals(scenePlusExt.getModelKind())){ // url = downloadModel43dtiles(num, bucket, scenePlusExt, sceneEditInfo); // }else{ // url = downloadModel4Dam(num, bucket); // } // // sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code()); // sceneAsynOperLog.setUrl(url); // }catch (Exception e){ // sceneAsynOperLog.setState(CommonOperStatus.FAILD.code()); // log.error("下载模型压缩包失败,num:" + num, e); // } // sceneAsynOperLogService.saveOrUpdate(sceneAsynOperLog); // }); // // return ResultData.ok(); // } // // @Override // public ScenePro getByNum(String num) { // return this.getOne(new LambdaQueryWrapper().eq(ScenePro::getNum, num)); // } // // private String downloadModel43dtiles(String num, String bucket, ScenePlusExt scenePlusExt, SceneEditInfo sceneEditInfo){ // // //下载mesh到本地 // String meshOssPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/"; // String meshLocalPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "mesh"; // String zipName = num + "_mesh.zip"; // String zipFilePath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + zipName; // //下载 // fYunFileService.downloadFileByCommand(bucket, meshLocalPath, meshOssPath); // //打包 // ZipUtil.zip(meshLocalPath,zipFilePath); // //上传压缩包 // fYunFileService.uploadFile(bucket, zipFilePath, "downloads/extras/" + zipName); // //删除本地文件 // FileUtil.del(meshLocalPath); // FileUtil.del(zipFilePath); // String url = "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis(); // return url; // } // // public static void main(String[] args) throws Exception { // // ConvertUtils.convertVisionModelDataToTxt( "D:\\test\\vision.modeldata", "D:\\test\\vision.json"); // // } // // // private String downloadModel4Dam(String num, String bucket){ // String localImagePath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num); // if(!new File(localImagePath).exists()){ // new File(localImagePath).mkdirs(); // } // // String zipName = num + "_extras.zip"; // String zipPath = localImagePath + zipName; // // String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num); // //V3版本去oss下载2048模型 // String meshPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, num) + "mesh"; // FileUtils.deleteDirectory(meshPath); // fYunFileService.downloadFileByCommand(bucket, meshPath, dataViewPath + "mesh"); // log.info("meshPath="+meshPath); // if(!new File(meshPath).exists() || new File(meshPath).listFiles().length < 1){ // throw new BusinessException(ErrorCode.FAILURE_CODE_7006); // } // for(File file : new File(meshPath).listFiles()){ // if(file.isDirectory()){ // for (File item : file.listFiles()) { // if(item.getName().endsWith(".obj") && !"output.house.obj".equals(item.getName()) && // !"mesh.obj".equals(item.getName())){ // item.delete(); // } // if(item.getName().endsWith(".mtl") && !"output.house.mtl".equals(item.getName()) && // !"mesh.mtl".equals(item.getName())){ // item.delete(); // } // } // continue; // } // if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) && // !"mesh.obj".equals(file.getName())){ // file.delete(); // } // if(file.getName().endsWith(".mtl") && !"output.house.mtl".equals(file.getName()) && // !"mesh.mtl".equals(file.getName())){ // file.delete(); // } // } // //打包 // ZipUtil.zip(meshPath, zipPath); // //上传压缩包 // fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName); // String url = "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis(); // FileUtil.del(zipPath); // return url; // } // // @Override // public List listCleanOrigScene(int cleanOrigMonth) { // Date time = Calendar.getInstance().getTime(); // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -cleanOrigMonth)); // return this.baseMapper.selectCleanOrigScene(time); // } // // @Override // public List listCleanOss4DeletedScene(int month) { // Date time = Calendar.getInstance().getTime(); // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -month)); // return this.baseMapper.listCleanOss4DeletedScene(time); // } // // @Override // public List listCleanOss4TestCamera(Set cameraIds, int month) { // Date time = Calendar.getInstance().getTime(); // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -month)); // return this.baseMapper.listCleanOss4TestCamera(cameraIds, time); // } // // @Override // public List listColdStorageScene(int cleanOrigMonth) { // Date time = Calendar.getInstance().getTime(); // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -cleanOrigMonth)); // return this.baseMapper.selectColdStorageScene(time); // } }