|
@@ -2,20 +2,26 @@ package com.fdkankan.scene.service.impl;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.img.ImgUtil;
|
|
|
import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.io.IoUtil;
|
|
|
+import cn.hutool.core.util.CharsetUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.core.util.ZipUtil;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.fdkankan.common.constant.*;
|
|
|
import com.fdkankan.common.exception.BusinessException;
|
|
|
+import com.fdkankan.common.util.FileUtils;
|
|
|
import com.fdkankan.redis.constant.RedisKey;
|
|
|
import com.fdkankan.redis.util.RedisClient;
|
|
|
+import com.fdkankan.scene.bean.BoxPhotoBean;
|
|
|
import com.fdkankan.scene.bean.ResultData;
|
|
|
import com.fdkankan.scene.bean.SceneJsonBean;
|
|
|
import com.fdkankan.scene.bean.TagBean;
|
|
@@ -29,12 +35,15 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
+import java.io.File;
|
|
|
import java.io.IOException;
|
|
|
import java.io.InputStream;
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
import java.util.*;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -65,6 +74,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<SceneEditInfoMapper, S
|
|
|
private SceneFileMappingService sceneFileMappingService;
|
|
|
@Resource
|
|
|
CustomHttpClient customHttpClient;
|
|
|
+ @Autowired
|
|
|
+ private SceneAsynOperLogService sceneAsynOperLogService;
|
|
|
+ @Autowired
|
|
|
+ private ICommonService commonService;
|
|
|
|
|
|
/**
|
|
|
* 保存场景基础设置
|
|
@@ -491,6 +504,288 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<SceneEditInfoMapper, S
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
+ public ResultData uploadPanorama(String num, Integer subgroup, String upTime, MultipartFile file) throws Exception {
|
|
|
+
|
|
|
+ if(!file.getOriginalFilename().endsWith(".zip") && !file.getOriginalFilename().endsWith(".jpg")){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7007, "jpg或者zip");
|
|
|
+ }
|
|
|
+
|
|
|
+ Scene scenePlus = sceneService.getByNum(num, subgroup, upTime);
|
|
|
+ if(scenePlus == null){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作
|
|
|
+ sceneAsynOperLogService.checkSceneAsynOper(scenePlus.getId(), null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.PANORAMIC_IMAGE.code());
|
|
|
+
|
|
|
+ //清除全景图异步操作记录,防止再次下载的时候请求到旧的压缩包
|
|
|
+ sceneAsynOperLogService.cleanLog(scenePlus.getId(), SceneAsynModuleType.UPLOAD_DOWNLOAD.code(), SceneAsynFuncType.PANORAMIC_IMAGE.code());
|
|
|
+
|
|
|
+ //原始计算根目录
|
|
|
+ String numStr = RedisKey.getNumStr(num, subgroup, upTime, scenePlus.getCacheKeyHasTime());
|
|
|
+ String path = String.format(ConstantFilePath.SCENE_USER_PATH_V4, numStr);
|
|
|
+ //全景图计算根目录
|
|
|
+ String target = path + "_images";
|
|
|
+ //解压缩文件存放目录
|
|
|
+ String targetImagesPath = target + "/extras/images/";
|
|
|
+ //压缩文件保存目录
|
|
|
+ String zipTargetFilePath = targetImagesPath + file.getOriginalFilename();
|
|
|
+
|
|
|
+ //先删除本地文件
|
|
|
+ FileUtil.del(targetImagesPath);
|
|
|
+ File targetFile = new File(zipTargetFilePath);
|
|
|
+ if(!targetFile.getParentFile().exists()){
|
|
|
+ targetFile.getParentFile().mkdirs();
|
|
|
+ }
|
|
|
+ file.transferTo(targetFile);
|
|
|
+
|
|
|
+ //如果是压缩包上传,需要解压缩
|
|
|
+ int async = CommonStatus.NO.code();
|
|
|
+ if(file.getOriginalFilename().endsWith(".zip")){
|
|
|
+
|
|
|
+ //标记为异步处理
|
|
|
+ async = CommonStatus.YES.code();
|
|
|
+
|
|
|
+ //解压zip包
|
|
|
+ ZipUtil.unzip(zipTargetFilePath,targetImagesPath, CharsetUtil.CHARSET_GBK);
|
|
|
+ //删除压缩包
|
|
|
+ FileUtil.del(zipTargetFilePath);
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断文件夹目录结构,图片必须放在压缩包根目录下,不支持空文件夹或其他格式文件上传
|
|
|
+ File[] files = new File(targetImagesPath).listFiles();
|
|
|
+ Arrays.stream(files).forEach(item->{
|
|
|
+ if(item.isDirectory()){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_7018);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ //获取解压后的文件列表
|
|
|
+ List<String> uploadFileList = FileUtils.getFileList(targetImagesPath);
|
|
|
+ if(CollUtil.isEmpty(uploadFileList)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5062);
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断是否有可用的jpg文件
|
|
|
+ boolean existJpg = false;
|
|
|
+ if(CollUtil.isNotEmpty(uploadFileList)){
|
|
|
+ existJpg = uploadFileList.stream().anyMatch(str -> {
|
|
|
+ if(str.endsWith(".jpg")){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if(!existJpg){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5062);
|
|
|
+ }
|
|
|
+
|
|
|
+ //比对图片列表,不存在的要返回名称集合
|
|
|
+ List<SceneFileMapping> sceneFileMappings = sceneFileMappingService.getByScene(num, subgroup, upTime);
|
|
|
+ List<SceneFileMapping> panList = sceneFileMappings.stream().filter(v -> v.getKey().contains("images/pan/high/")).collect(Collectors.toList());
|
|
|
+ Map<String, SceneFileMapping> panMap = panList.stream().collect(Collectors.toMap(v -> FileUtil.getName(v.getKey()), v -> v));
|
|
|
+ List<String> panoramaImageList = panList.stream().map(v -> FileUtil.getName(v.getKey())).collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<String> notExistFileList = uploadFileList.stream().filter(filePath -> {
|
|
|
+ filePath = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
|
|
|
+ if(CollUtil.isEmpty(panoramaImageList) || panoramaImageList.contains(filePath)){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if(CollUtil.isNotEmpty(notExistFileList)){
|
|
|
+ //删除错误文件
|
|
|
+ notExistFileList.parallelStream().forEach(filePath->{
|
|
|
+ FileUtil.del(filePath);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断成功的图片,如果成功图片为0,就直接返回,不需要执行算法
|
|
|
+ uploadFileList = FileUtils.getFileList(targetImagesPath);
|
|
|
+ if(CollUtil.isEmpty(uploadFileList)){
|
|
|
+ if(CollUtil.isNotEmpty(notExistFileList)){
|
|
|
+ notExistFileList = notExistFileList.stream().map(filePath -> {
|
|
|
+ return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ return ResultData.ok(new UploadPanoramaVO(0,0, notExistFileList));
|
|
|
+ }
|
|
|
+
|
|
|
+ //上传
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+
|
|
|
+ String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
|
|
|
+
|
|
|
+ //如果部分成功,则需要返回成功数量和失败列表
|
|
|
+ if(CollUtil.isNotEmpty(notExistFileList)){
|
|
|
+ notExistFileList = notExistFileList.stream().map(filePath -> {
|
|
|
+ return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ UploadPanoramaVO uploadPanoramaVO = new UploadPanoramaVO();
|
|
|
+ uploadPanoramaVO.setAsyn(async);
|
|
|
+ if(async == CommonStatus.YES.code().intValue()){
|
|
|
+ List<String> finalUploadFileList = uploadFileList;
|
|
|
+ List<String> finalNotExistFileList = notExistFileList;
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
+ SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
|
|
|
+ sceneAsynOperLog.setNum(num);
|
|
|
+ sceneAsynOperLog.setOperType(SceneAsynOperType.UPLOAD.code());
|
|
|
+ sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
|
|
|
+ sceneAsynOperLog.setFunc(SceneAsynFuncType.PANORAMIC_IMAGE.code());
|
|
|
+ if(CollUtil.isNotEmpty(finalNotExistFileList)){
|
|
|
+ Map<String, Object> extData = new HashMap<>();
|
|
|
+ extData.put("successCnt", finalUploadFileList.size());
|
|
|
+ extData.put("failList", finalNotExistFileList);
|
|
|
+ sceneAsynOperLog.setExtData(JSON.toJSONString(extData));
|
|
|
+ }
|
|
|
+ sceneAsynOperLogService.save(sceneAsynOperLog);
|
|
|
+ try {
|
|
|
+ this.uploadPanoramaHandler(num,subgroup,upTime,target,imgViewPath, finalUploadFileList,targetImagesPath);
|
|
|
+ sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("上传全景图报错,num:" + num, e);
|
|
|
+ sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
|
|
|
+ }
|
|
|
+ sceneAsynOperLogService.updateById(sceneAsynOperLog);
|
|
|
+ });
|
|
|
+ }else{
|
|
|
+ this.uploadPanoramaHandler(num,subgroup,upTime,target,imgViewPath,uploadFileList,targetImagesPath);
|
|
|
+ if(CollUtil.isNotEmpty(notExistFileList)){
|
|
|
+ uploadPanoramaVO.setSuccessCnt(uploadFileList.size());
|
|
|
+ uploadPanoramaVO.setFailList(notExistFileList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ FileUtil.del(target);
|
|
|
+ return ResultData.ok(uploadPanoramaVO);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void uploadPanoramaHandler(String num, Integer subgroup, String upTime, String target, String imgViewPath, List<String> uploadFileList, String targetImagesPath) throws Exception {
|
|
|
+
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ String resultPath = target + File.separator + "results/";
|
|
|
+ FileUtil.mkdir(resultPath);
|
|
|
+
|
|
|
+ //4K
|
|
|
+ String highPath = resultPath + "pan/high/";
|
|
|
+ //512
|
|
|
+ String lowPath = resultPath + "pan/low/";
|
|
|
+ List<String> origImgs = FileUtil.listFileNames(targetImagesPath);
|
|
|
+ for (String origImg : origImgs) {
|
|
|
+ FileUtil.copy(targetImagesPath + origImg, highPath + origImg, true);
|
|
|
+ map.put(highPath + origImg, imgViewPath + "pan/high/" + origImg);
|
|
|
+ ImgUtil.scale(new File(highPath + origImg), new File(lowPath + origImg), 0.125f);
|
|
|
+ map.put(lowPath + origImg, imgViewPath + "pan/low/" + origImg);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(map.size()>0) {
|
|
|
+ fYunFileService.uploadMulFiles(num, subgroup, upTime, map);
|
|
|
+ }
|
|
|
+
|
|
|
+ //更新数据库版本号
|
|
|
+ Scene scenePlus = sceneService.getByNum(num, subgroup, upTime);
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+ this.upgradeVersionAndImgVersionById(sceneEditInfo.getId());
|
|
|
+ //更新scenejson缓存和oss文件版本号
|
|
|
+ this.upgradeSceneJsonVersion(num, subgroup, upTime, scenePlus.getCacheKeyHasTime(), sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData downloadPanorama(FileParamVO param) throws Exception {
|
|
|
+
|
|
|
+ String num = param.getNum();
|
|
|
+ Integer subgroup = param.getSubgroup();
|
|
|
+ String upTimeKey = param.getUpTimeKey();
|
|
|
+ String fileName = param.getFileName();
|
|
|
+
|
|
|
+ Scene scenePlus = sceneService.getByNum(num, subgroup, upTimeKey);
|
|
|
+ if(Objects.isNull(scenePlus)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作
|
|
|
+ sceneAsynOperLogService.checkSceneAsynOper(scenePlus.getId(),null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.PANORAMIC_IMAGE.code());
|
|
|
+
|
|
|
+ String numStr = RedisKey.getNumStr(num, subgroup, upTimeKey, scenePlus.getCacheKeyHasTime());
|
|
|
+ String cachePath = String.format(ConstantFilePath.SCENE_CACHE, numStr);
|
|
|
+ String localImagesPath = String.format(ConstantFilePath.SCENE_CACHE_IMAGES, numStr);
|
|
|
+
|
|
|
+ String cacheFormat = "downloads/scene/%s/caches/";
|
|
|
+ String cacheImageFormat = "downloads/scene/%s/caches/images/";
|
|
|
+
|
|
|
+ List<SceneFileMapping> sceneFileMappings = sceneFileMappingService.getByScene(num, subgroup, upTimeKey);
|
|
|
+ List<SceneFileMapping> panList = sceneFileMappings.stream().filter(v -> v.getKey().contains("images/pan/high/")).collect(Collectors.toList());
|
|
|
+ Map<String, SceneFileMapping> panMap = panList.stream().collect(Collectors.toMap(v -> FileUtil.getName(v.getKey()), v -> v));
|
|
|
+
|
|
|
+// List<String> panoramaImageList = panList.stream().map(v -> FileUtil.getName(v.getKey())).collect(Collectors.toList());
|
|
|
+
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+
|
|
|
+ //标记是否是异步操作,默认是同步操作
|
|
|
+ //如果入参文件名不为空,则是单个文件下载,不需要打包
|
|
|
+ if(StrUtil.isNotEmpty(fileName)){
|
|
|
+ if(!panMap.keySet().contains(fileName)){
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
|
|
|
+ }
|
|
|
+ String url = panMap.get(fileName).getKey();
|
|
|
+ String downloadName = fileName;
|
|
|
+ map.put("asyn", CommonStatus.NO.code());
|
|
|
+ map.put("fileUrl", url);
|
|
|
+ map.put("fileName", downloadName);
|
|
|
+ return ResultData.ok(map);
|
|
|
+ }else{
|
|
|
+ //清除旧的下载记录
|
|
|
+ sceneAsynOperLogService.cleanLog(scenePlus.getId(), SceneAsynModuleType.UPLOAD_DOWNLOAD.code(), SceneAsynFuncType.PANORAMIC_IMAGE.code(), SceneAsynOperType.DOWNLOAD.code());
|
|
|
+
|
|
|
+ //开始异步执行下载全景图压缩包操作
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+ SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
|
|
|
+ sceneAsynOperLog.setNum(num);
|
|
|
+ sceneAsynOperLog.setSceneId(scenePlus.getId());
|
|
|
+ sceneAsynOperLog.setOperType(SceneAsynOperType.DOWNLOAD.code());
|
|
|
+ sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
|
|
|
+ sceneAsynOperLog.setFunc(SceneAsynFuncType.PANORAMIC_IMAGE.code());
|
|
|
+ sceneAsynOperLog.setVersion(sceneEditInfo.getImgVersion());
|
|
|
+ sceneAsynOperLogService.save(sceneAsynOperLog);
|
|
|
+ try {
|
|
|
+
|
|
|
+ //下载到本地目录
|
|
|
+ FileUtil.del(localImagesPath);
|
|
|
+ for (SceneFileMapping sceneFileMapping : panList) {
|
|
|
+ customHttpClient.downloadFile(sceneFileMapping.getUrl(), localImagesPath, fileName);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ String downloadName = num + "_images.zip";
|
|
|
+ //打包
|
|
|
+ String zipPath = cachePath + downloadName;
|
|
|
+ ZipUtil.zip(localImagesPath, zipPath);
|
|
|
+ //上传压缩包
|
|
|
+ fYunFileService.uploadFile(num, subgroup,upTimeKey,zipPath, String.format(cacheFormat, num) + downloadName);
|
|
|
+ String url = String.format(cacheFormat, num) + downloadName;
|
|
|
+ //删除本地压缩包
|
|
|
+ FileUtil.del(zipPath);
|
|
|
+ //删除本地目录
|
|
|
+ FileUtil.del(localImagesPath);
|
|
|
+ sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
|
|
|
+ sceneAsynOperLog.setUrl(url);
|
|
|
+ }catch (Exception e){
|
|
|
+ sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
|
|
|
+ log.error("下载全景图压缩包失败,num:" + num, e);
|
|
|
+ }
|
|
|
+ sceneAsynOperLogService.saveOrUpdate(sceneAsynOperLog);
|
|
|
+ });
|
|
|
+
|
|
|
+ map.put("asyn", CommonStatus.YES.code());
|
|
|
+ return ResultData.ok(map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
public void saveTagsToSceneEditInfo(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime, SceneEditInfo sceneEditInfo){
|
|
|
//查询缓存是否包含热点数据
|
|
|
String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup, upTime, cacheKeyHasTime));
|
|
@@ -709,4 +1004,261 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<SceneEditInfoMapper, S
|
|
|
list.stream().map(str -> JSON.parseObject(str)).collect(Collectors.toList());
|
|
|
return ResultData.ok(collect);
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData saveVideoBox(FileNameAndDataParamVO param) throws Exception {
|
|
|
+
|
|
|
+ JSONObject boxVideo = JSONObject.parseObject(param.getData());
|
|
|
+ String sid = boxVideo.getString("sid");
|
|
|
+ if(StrUtil.isEmpty(sid)){
|
|
|
+ throw new BusinessException(ErrorCode.PARAM_REQUIRED);
|
|
|
+ }
|
|
|
+ Scene scenePlus = sceneService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
|
|
|
+ if(Objects.isNull(scenePlus))
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ //转换视频格式
|
|
|
+ commonService.transferToFlv(param.getNum(), param.getSubgroup(), param.getUpTimeKey(), scenePlus.getCacheKeyHasTime(), param.getFileName());
|
|
|
+
|
|
|
+ //生成boxVideos数据
|
|
|
+ String boxVideos = this.createBoxVideos(sid, boxVideo, sceneEditInfo, OperationType.ADDORUPDATE.code());
|
|
|
+
|
|
|
+ //更新数据库
|
|
|
+ this.updateBoxVideos(sceneEditInfo, scenePlus.getId(), boxVideos);
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData deleteVideoBox(DeleteSidParamVO param) throws Exception {
|
|
|
+
|
|
|
+ Scene scenePlus = sceneService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
|
|
|
+ if(Objects.isNull(scenePlus))
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ //根据sid移除json
|
|
|
+ String boxVideos = this.createBoxVideos(param.getSid(), null, sceneEditInfo, OperationType.DELETE.code());
|
|
|
+
|
|
|
+ //写数据库
|
|
|
+ this.updateBoxVideos(sceneEditInfo,scenePlus.getId(),boxVideos);
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String createBoxVideos(String sid, JSONObject boxVideo,
|
|
|
+ SceneEditInfo sceneEditInfo, int type) throws Exception{
|
|
|
+
|
|
|
+ String boxVideos = null;
|
|
|
+ if(sceneEditInfo != null){
|
|
|
+ boxVideos = sceneEditInfo.getBoxVideos();
|
|
|
+ }
|
|
|
+ JSONArray boxVideosJson = null;
|
|
|
+ if (StrUtil.isNotEmpty(boxVideos)) {
|
|
|
+ boxVideosJson = JSONArray.parseArray(boxVideos);
|
|
|
+ }else {
|
|
|
+ boxVideosJson = new JSONArray();
|
|
|
+ }
|
|
|
+ if(boxVideosJson.size() > 0){
|
|
|
+ int i = 1;
|
|
|
+ long timeInMillis = Calendar.getInstance().getTimeInMillis();
|
|
|
+ for (Object o : boxVideosJson) {
|
|
|
+ JSONObject item = (JSONObject)o;
|
|
|
+ if(Objects.nonNull(item.getLong("createTime"))){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ item.put("createTime", timeInMillis - (i++));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String result = null;
|
|
|
+ //删除
|
|
|
+ if(type == OperationType.DELETE.code()){
|
|
|
+ Set<String> deleteVidoeFile = new HashSet<>();
|
|
|
+ Set<String> deletePicFile = new HashSet<>();
|
|
|
+ if(boxVideosJson.size() == 0)
|
|
|
+ return null;
|
|
|
+ for(int i=0;i<boxVideosJson.size();++i){
|
|
|
+ JSONObject ele = boxVideosJson.getJSONObject(i);
|
|
|
+ if(ele.getString("sid").equals(sid)){
|
|
|
+
|
|
|
+ String poster = ele.getString("poster");
|
|
|
+ if(StrUtil.isNotEmpty(poster))
|
|
|
+ deletePicFile.add(poster);
|
|
|
+ String url = ele.getString("url");
|
|
|
+ if(StrUtil.isNotEmpty(url)){
|
|
|
+ deleteVidoeFile.add(url);
|
|
|
+ deleteVidoeFile.add(url.replace(".mp4",".flv"));
|
|
|
+ }
|
|
|
+
|
|
|
+ boxVideosJson.remove(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ boxVideo.put("createTime", Calendar.getInstance().getTimeInMillis());
|
|
|
+
|
|
|
+ //更新
|
|
|
+ boolean exist = false;
|
|
|
+ for(int i=0;i<boxVideosJson.size();++i){
|
|
|
+ JSONObject ele = boxVideosJson.getJSONObject(i);
|
|
|
+ if(ele.getString("sid").equals(sid)){
|
|
|
+ boxVideosJson.set(i, boxVideo);
|
|
|
+ exist = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //新增
|
|
|
+ if(!exist){
|
|
|
+ boxVideosJson.add(boxVideo);
|
|
|
+ }
|
|
|
+
|
|
|
+ boxVideosJson.clear();
|
|
|
+ boxVideosJson.add(boxVideo);
|
|
|
+
|
|
|
+ }
|
|
|
+ if(boxVideosJson.size() != 0){
|
|
|
+ result = boxVideosJson.toJSONString();
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateBoxVideos(SceneEditInfo sceneEditInfo, Long scenePlusId, String boxVideos){
|
|
|
+ if(Objects.isNull(sceneEditInfo)){
|
|
|
+ sceneEditInfo = new SceneEditInfo();
|
|
|
+ sceneEditInfo.setScenePlusId(scenePlusId);
|
|
|
+ sceneEditInfo.setBoxVideos(boxVideos);
|
|
|
+ this.save(sceneEditInfo);
|
|
|
+ }else{
|
|
|
+ this.update(new UpdateWrapper<SceneEditInfo>()
|
|
|
+ .setSql("version = version + 1")
|
|
|
+ .set("box_videos", boxVideos)
|
|
|
+ .eq("id", sceneEditInfo.getId()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData saveBoxPhoto(BaseDataParamVO param) throws Exception {
|
|
|
+
|
|
|
+ JSONObject boxPhoto = JSONObject.parseObject(param.getData());
|
|
|
+ String sid = boxPhoto.getString("sid");
|
|
|
+ if(StrUtil.isEmpty(sid)){
|
|
|
+ throw new BusinessException(ErrorCode.PARAM_REQUIRED, sid);
|
|
|
+ }
|
|
|
+ Scene scenePlus = sceneService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
|
|
|
+ if(Objects.isNull(scenePlus))
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ //生成boxVideos数据
|
|
|
+ String boxPhotos = this.createBoxPhotos(sid, boxPhoto, sceneEditInfo, OperationType.ADDORUPDATE.code());
|
|
|
+
|
|
|
+ //更新数据库
|
|
|
+ this.updateBoxPhotos(sceneEditInfo, boxPhotos);
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData deleteBoxPhoto(DeleteSidParamVO param) throws Exception {
|
|
|
+
|
|
|
+ Scene scenePlus = sceneService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
|
|
|
+ if(Objects.isNull(scenePlus))
|
|
|
+ throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
|
|
|
+
|
|
|
+ SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
|
|
|
+
|
|
|
+ //根据sid移除json
|
|
|
+ String boxPhotos = this.createBoxPhotos(param.getSid(), null, sceneEditInfo, OperationType.DELETE.code());
|
|
|
+
|
|
|
+ //写数据库
|
|
|
+ this.updateBoxPhotos(sceneEditInfo, boxPhotos);
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void updateBoxPhotos(SceneEditInfo sceneEditInfo, String boxPhotos){
|
|
|
+ this.update(new LambdaUpdateWrapper<SceneEditInfo>()
|
|
|
+ .set(SceneEditInfo::getBoxPhotos, boxPhotos)
|
|
|
+ .setSql("version = version + 1")
|
|
|
+ .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
|
|
|
+ }
|
|
|
+
|
|
|
+ private String createBoxPhotos(String sid, JSONObject boxPhoto, SceneEditInfo sceneEditInfo, int type) throws Exception{
|
|
|
+
|
|
|
+ String boxPhotos = null;
|
|
|
+ if(sceneEditInfo != null){
|
|
|
+ boxPhotos = sceneEditInfo.getBoxPhotos();
|
|
|
+ }
|
|
|
+ JSONArray boxPhotosJson = null;
|
|
|
+ if (StrUtil.isNotEmpty(boxPhotos)) {
|
|
|
+ boxPhotosJson = JSONArray.parseArray(boxPhotos);
|
|
|
+ }else {
|
|
|
+ boxPhotosJson = new JSONArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ String result = null;
|
|
|
+ //删除
|
|
|
+ if(type == OperationType.DELETE.code()){
|
|
|
+ Set<String> deleteFile = new HashSet<>();
|
|
|
+ if(boxPhotosJson.size() == 0)
|
|
|
+ return null;
|
|
|
+ for(int i=0;i<boxPhotosJson.size();++i){
|
|
|
+ JSONObject ele = boxPhotosJson.getJSONObject(i);
|
|
|
+ if(ele.getString("sid").equals(sid)){
|
|
|
+
|
|
|
+ String poster = ele.getString("poster");
|
|
|
+ if(StrUtil.isNotEmpty(poster))
|
|
|
+ deleteFile.add(poster);
|
|
|
+ String url = ele.getString("url");
|
|
|
+ if(StrUtil.isNotEmpty(url))
|
|
|
+ deleteFile.add(url);
|
|
|
+
|
|
|
+ boxPhotosJson.remove(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ //更新
|
|
|
+ boolean exist = false;
|
|
|
+ for(int i=0;i<boxPhotosJson.size();++i){
|
|
|
+ JSONObject ele = boxPhotosJson.getJSONObject(i);
|
|
|
+ if(ele.getString("sid").equals(sid)){
|
|
|
+ boxPhoto.put("createTime", ele.getLong("createTime"));
|
|
|
+ boxPhotosJson.set(i, boxPhoto);
|
|
|
+ exist = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //新增
|
|
|
+ if(!exist){
|
|
|
+ boxPhoto.put("createTime", Calendar.getInstance().getTimeInMillis());
|
|
|
+ boxPhotosJson.add(boxPhoto);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if(boxPhotosJson.size() != 0){
|
|
|
+
|
|
|
+ List<BoxPhotoBean> list = Lists.newArrayList();
|
|
|
+ for (Object o : boxPhotosJson) {
|
|
|
+ JSONObject jsonObject = (JSONObject)o;
|
|
|
+ list.add(BoxPhotoBean.builder().createTime(jsonObject.getLong("createTime")).boxPhoto(jsonObject).build());
|
|
|
+ }
|
|
|
+ //按创建时间倒叙排序
|
|
|
+ list.sort(Comparator.comparingLong(BoxPhotoBean::getCreateTime).reversed());
|
|
|
+
|
|
|
+ // list转JSONArray
|
|
|
+ JSONArray array = new JSONArray();
|
|
|
+ list.stream().forEach(bean->{
|
|
|
+ array.add(bean.getBoxPhoto());
|
|
|
+ });
|
|
|
+
|
|
|
+ result = array.toJSONString();
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|