map = new HashMap<>();
JSONArray jsonArray = JSON.parseArray(param.getData());
for (Object o : jsonArray) {
JSONObject mosaic = (JSONObject) o;
String panoId = mosaic.getString("panoId");
if(StrUtil.isEmpty(panoId)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
}
map.put(panoId, JSON.toJSONString(mosaic));
}
String key = String.format(RedisKey.SCENE_MOSAIC_DATA, param.getNum());
redisUtil.hmset(key, map);
//写入本地文件,作为备份
this.writeMosaic(param.getNum());
//更新数据库
this.updateMosaicFlag(param.getNum());
//更新版本号
this.upgradeVersionById(sceneEditInfo.getId());
return ResultData.ok();
}
private void updateMosaicFlag(String num){
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
boolean flag = redisUtil.hasKey(key);
if(flag){
sceneEditInfoExt.setMosaic(Integer.valueOf(CommonStatus.YES.code()));
}else{
sceneEditInfoExt.setMosaic(Integer.valueOf(CommonStatus.NO.code()));
}
sceneEditInfoExtService.updateById(sceneEditInfoExt);
}
/**
*
保证马赛克数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
**/
private void syncMosaicFromFileToRedis(String num) throws Exception{
String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
boolean exist = redisUtil.hasKey(key);
if(exist){
return;
}
// String uuid = cn.hutool.core.lang.UUID.randomUUID().toString();
String lockKey = String.format(RedisLockKey.LOCK_MOSAIC_DATA_SYNC, num);
boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_1_MINUTE);
if(!lock){
throw new BusinessException(ErrorCode.SYSTEM_BUSY);
}
try{
exist = redisUtil.hasKey(key);
if(exist){
return;
}
String filePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "mosaic.json";
String mosaicData = FileUtils.readUtf8String(filePath);
if(StrUtil.isEmpty(mosaicData)){
return;
}
JSONArray jsonArray = JSON.parseArray(mosaicData);
if(CollUtil.isEmpty(jsonArray)){
return;
}
Map map = new HashMap<>();
for (Object o : jsonArray) {
JSONObject jo = (JSONObject)o;
map.put(jo.getString("panoId"), jo.toJSONString());
}
redisUtil.hmset(key, map);
}finally {
redisLockUtil.unlockLua(lockKey);
}
}
/**
*
保证马赛克数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
**/
private void writeMosaic(String num) throws Exception{
String mosaicPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "mosaic.json";
String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
Map mosaicMap = redisUtil.hmget(key);
if(CollUtil.isEmpty(mosaicMap)){
FileUtils.deleteFile(mosaicPath);
return;
}
List mosaicList = Lists.newArrayList(mosaicMap.values());
JSONArray jsonArr = new JSONArray();
mosaicList.stream().forEach(mosaic->{
jsonArr.add(JSONObject.parseObject(mosaic));
});
String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
String lockKey = String.format(RedisLockKey.LOCK_MOSAIC_JSON, num);
boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
if(!lock){
return;
}
try{
FileUtils.writeFile(mosaicPath, jsonArr.toJSONString());
}finally {
redisLockUtil.unlockLua(lockKey, lockVal);
}
}
@Override
public ResultData uploadLinkPan(String num, String sid, String fileName, MultipartFile file) throws Exception {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
if(scenePlus == null){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
String bucket = scenePlusExt.getYunFileBucket();
String localDataPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, num);
String localImagesPath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num);
String path = scenePlusExt.getDataSource();
String target = localImagesPath + "panorama/" + sid;
FileUtils.deleteDirectory(target);
//文件写如本地磁盘
String filePath = target + File.separator + "extras/images" + File.separator + fileName;
File targetFile = new File(filePath);
if(!targetFile.getParentFile().exists()){
targetFile.getParentFile().mkdirs();
}
file.transferTo(targetFile);
//调用算法切全景图
FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
JSONObject visionJson = new JSONObject();
JSONArray visionArray = new JSONArray();
visionJson.put("uuid", sid);
visionJson.put("group", 1);
visionJson.put("subgroup", 0);
visionArray.add(visionJson);
JSONObject vision = new JSONObject();
vision.put("sweepLocations", visionArray);
cn.hutool.core.io.FileUtil.writeString(vision.toString(),
target + "/extras" + File.separator + "vision.txt",
StandardCharsets.UTF_8);
//data.json增加extras为执行重建算法
String type = "4k";
String data = FileUtils.readFile(target + File.separator + "data.json");
if(data != null){
JSONObject floorplanJson = new JSONObject();
floorplanJson.put("has_source_images", true);
floorplanJson.put("has_vision_txt", true);
JSONObject dataJson = JSONObject.parseObject(data);
dataJson.put("extras", floorplanJson);
dataJson.put("split_type", "SPLIT_V8");//替换全景图算法
String skyboxType = "SKYBOX_V6";//默认4k minion
if(SceneFrom.PRO.code().equals(scenePlusExt.getSceneFrom())){
skyboxType = "SKYBOX_V7";
type = "2k";
}
if(scenePlusExt.getSceneScheme() == 3){
if("4k".equals(scenePlusExt.getSceneResolution())){
skyboxType = "SKYBOX_V14";
}else{
skyboxType = "SKYBOX_V13";
}
}
dataJson.put("skybox_type", skyboxType);
cn.hutool.core.io.FileUtil.writeString(dataJson.toString(),
target + File.separator+"data.json", StandardCharsets.UTF_8);
}
//创建文件夹软连接并且复制data.json和project.json
String capturePath = target + File.separator + "capture";
String resultPath = target + File.separator + "results";
log.info("场景关联上传全景图:capturePath={}", capturePath);
log.info("场景关联上传全景图:resultPath={}", resultPath);
if(cn.hutool.core.io.FileUtil.exist(capturePath)){
cn.hutool.core.io.FileUtil.del(capturePath);
}
if(cn.hutool.core.io.FileUtil.exist(resultPath)){
cn.hutool.core.io.FileUtil.del(resultPath);
}
//下载data.fdage
if(FYunTypeEnum.AWS.code().equals(this.fyunType)){
//亚马逊保持旧方式,超链接capture
CreateObjUtil.createSoftConnection(path + File.separator + "capture", capturePath);
}
fYunFileService.downloadFile(ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "") + "/data.fdage", capturePath + "/data.fdage");
CreateObjUtil.build3dModel(target , "1");
//读取upload文件,获取需要上传的文件
JSONArray array = ComputerUtil.getUploadArray(resultPath + "/upload.json", this.maxCheckTimes, this.waitTime);
Map map = new HashMap<>();
JSONObject fileJson;
String uploadFile, uploadFilePath;
String imgEditPath = String.format(UploadFilePath.IMG_EDIT_PATH, num);
for(int i = 0, len = array.size(); i < len; i++){
fileJson = array.getJSONObject(i);
uploadFile = fileJson.getString("file");
uploadFilePath = resultPath +File.separator + uploadFile;
//文件不存在抛出异常
if(!cn.hutool.core.io.FileUtil.exist(uploadFilePath)){
throw new Exception(uploadFilePath + "文件不存在");
}
Integer clazz = fileJson.getIntValue("clazz");
if(Objects.isNull(clazz)){
continue;
}
if(clazz == 4 || clazz == 5 || clazz == 7){
map.put(uploadFilePath, imgEditPath + "panorama/" + sid + File.separator + uploadFile);
}
}
//上传全景图
map.put(filePath, imgEditPath + "panorama/" + sid + "/high/" + fileName);
fYunFileService.uploadMulFiles(bucket, map);
Map result = new HashMap<>();
result.put("type", type);
return ResultData.ok(result);
}
@Override
public ResultData saveLinkPan(SaveLinkPanParamVO param) throws Exception {
String num = param.getNum();
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
//添加场景关联数据
this.addOrUpdateLinPan(num, param.getLinkPans());
//添加场景关联图标
this.addOrUpdateLinkPanStyles(num, param.getStyles());
//场景关联数据备份到本地
this.writeLinkScene(num);
//更新场景关联标识、升级版本号
this.setLinkScenesAndUpgradeVersion(scenePlus.getId(), num);
return ResultData.ok();
}
@Override
public ResultData deleteStyles(DeleteLinkSceneStylesParamVO param) throws Exception {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
if (scenePlus == null)
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
List sidList = param.getSidList();
this.syncLinkPanStylesFromFileToRedis(param.getNum());
String key = String.format(RedisKey.SCENE_LINKPAN_STYLES, param.getNum());
List deleteList = redisUtil.hMultiGet(key, sidList);
redisUtil.hdel(key, sidList.toArray());
//写入本地文件,作为备份
this.writeLinkScene(param.getNum());
//删除oss文件
List deleteFileList = deleteList.stream().map(str -> {
JSONObject parse = JSON.parseObject(str);
return parse.getString("url");
}).collect(Collectors.toList());
sceneUploadService.delete(
DeleteFileParamVO.builder()
.num(param.getNum())
.fileNames(deleteFileList)
.bizType(FileBizType.LINK_STYLE.code()).build());
return ResultData.ok();
}
@Override
public ResultData deleteLinkPan(DeleteLinkPanParamVO param) throws Exception {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
if (scenePlus == null)
return ResultData.error(ErrorCode.FAILURE_CODE_5005);
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
String bucket = scenePlusExt.getYunFileBucket();
List deleteSidList = param.getSidList();
//处理删除状态数据
this.deletelinkPanData(param.getNum(), deleteSidList, bucket);
//写入本地文件,作为备份
this.writeLinkScene(param.getNum());
//更新场景关联标识、升级版本号
this.setLinkScenesAndUpgradeVersion(scenePlus.getId(), param.getNum());
return ResultData.ok();
}
private void deletelinkPanData(String num, List deleteSidList, String bucket) throws Exception {
if(CollUtil.isEmpty(deleteSidList)){
return;
}
this.syncLinPanFromFileToRedis(num);
//从redis中加载热点数据
String key = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
List deletDataList = redisUtil.hMultiGet(key, deleteSidList);
if(CollUtil.isEmpty(deletDataList))
return;
//从redis中移除热点数据
redisUtil.hdel(key, deleteSidList.toArray());
//删除oss文件
String imgEditPath = String.format(UploadFilePath.IMG_EDIT_PATH, num);
deleteSidList.stream().forEach(sid->{
fYunFileService.deleteFolder(bucket, imgEditPath + "panorama_edit/" + sid);
});
}
@Override
public ResultData listLinkPan(String num) throws Exception {
this.syncLinPanFromFileToRedis(num);
this.syncLinkPanStylesFromFileToRedis(num);
JSONObject result = new JSONObject();
//查询场景关联数据
String key = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
Map allTagsMap = redisUtil.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);
//封装styles数据
List styles = Lists.newArrayList();
key = String.format(RedisKey.SCENE_LINKPAN_STYLES, num);
Map styleMap = redisUtil.hmget(key);
if(CollUtil.isNotEmpty(styleMap)) {
for (String style : styleMap.values()) {
styles.add(JSON.parseObject(style));
}
}
//图标按写入时间排序
styles = this.sortStyles(styles);
result.put("styles", styles);
return ResultData.ok(result);
}
private List sortStyles(List styles){
if(CollUtil.isEmpty(styles)){
return null;
}
//统计使用频次
List styleBeans = Lists.newArrayList();
for (JSONObject style : styles) {
Long createTime = style.getLong("createTime");
createTime = Objects.isNull(createTime) ? Calendar.getInstance().getTimeInMillis() : createTime;
style.remove("createTime");
styleBeans.add(
StyleBean.builder().style(style)
.createTime(createTime).build());
}
//排序
List styleList = Lists.newArrayList();
if(CollUtil.isNotEmpty(styleBeans)){
styleList = styleBeans.stream().sorted(Comparator.comparing(StyleBean::getCreateTime).reversed())
.map(item -> {
return item.getStyle();
}).collect(Collectors.toList());
}
return styleList;
}
private void setLinkScenesAndUpgradeVersion(Long scenePlusId, String num){
SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlusId);
//查询缓存是否有场景关联数据
String key = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
Map allTagsMap = redisUtil.hmget(key);
boolean hashTags = false;
for (Entry tagMap : allTagsMap.entrySet()) {
if(StrUtil.isEmpty(tagMap.getValue())){
continue;
}
hashTags = true;
break;
}
//更新linkscenes字段
sceneEditInfoExtService.update(
new LambdaUpdateWrapper()
.set(SceneEditInfoExt::getLinks, hashTags ? CommonStatus.YES.code() : CommonStatus.NO.code())
.eq(SceneEditInfoExt::getEditInfoId, sceneEditInfo.getId()));
//更新场景版本
this.update(new LambdaUpdateWrapper()
.setSql("version=version+" + 1)
.setSql("link_version=link_version+" + 1)
.eq(SceneEditInfo::getId, sceneEditInfo.getId()));
}
/**
*
热点数据保存
*
* @author dengsixing
* @date 2022/3/3
**/
private void writeLinkScene(String num) throws Exception{
String dataKey = String.format(RedisKey.SCENE_LINKPAN_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(linkPan->{
tagJsonArr.add(JSONObject.parseObject(linkPan));
});
}
jsonObject.put("tags", tagJsonArr);
String stylesKey = String.format(RedisKey.SCENE_LINKPAN_STYLES, num);
Map styleMap = redisUtil.hmget(stylesKey);
List styleList = Lists.newArrayList();
if(CollUtil.isNotEmpty(styleMap)){
styleMap.values().stream().forEach(style->{
styleList.add(JSONObject.parseObject(style));
});
}
jsonObject.put("styles", styleList);
String linkScenePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "links.json";
String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
String lockKey = String.format(RedisLockKey.LOCK_LINK_SCENE_JSON, num);
boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
if(!lock){
return;
}
try{
cn.hutool.core.io.FileUtil.writeUtf8String(jsonObject.toJSONString(), linkScenePath);
}finally {
redisLockUtil.unlockLua(lockKey, lockVal);
}
}
private void addOrUpdateLinkPanStyles(String num, List styles) throws Exception{
this.syncLinkPanStylesFromFileToRedis(num);
if(CollUtil.isEmpty(styles)){
return;
}
long time = Calendar.getInstance().getTimeInMillis();
Map styleMap = new HashMap<>();
AtomicInteger index = new AtomicInteger();
styles.stream().forEach(style->{
String id = style.getString("sid");
style.put("createTime", time + index.getAndIncrement());
styleMap.put(id, style.toJSONString());
});
String key = String.format(RedisKey.SCENE_LINKPAN_STYLES, num);
redisUtil.hmset(key, styleMap);
}
/**
*
保证icons数据安全性,当redis宕机导致icons数据丢失时,可以从文件中读取,恢复到redis
*
* @author dengsixing
* @date 2022/3/3
**/
private void syncLinkPanStylesFromFileToRedis(String num) throws Exception{
String key = String.format(RedisKey.SCENE_LINKPAN_STYLES, num);
boolean exist = redisUtil.hasKey(key);
if(exist){
return;
}
String lockKey = String.format(RedisLockKey.LOCK_LINKPAN_STYLES_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 linkSceneFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num);
String linkSceneData = FileUtils.readUtf8String(linkSceneFilePath + "links.json");
if(StrUtil.isEmpty(linkSceneData)){
return;
}
JSONObject jsonObject = JSON.parseObject(linkSceneData);
JSONArray stylesArr = jsonObject.getJSONArray("styles");
if(CollUtil.isEmpty(stylesArr)){
return;
}
Map styleMap = new HashMap<>();
for (Object style : stylesArr) {
JSONObject styleObj = (JSONObject)style;
String id = styleObj.getString("sid");
styleMap.put(id, styleObj.toJSONString());
}
redisUtil.hmset(key, styleMap);
}finally {
redisLockUtil.unlockLua(lockKey, lockVal);
}
}
private void addOrUpdateLinPan(String num, List linkPanList) throws Exception{
Map addOrUpdateMap = new HashMap<>();
int i = 0;
for (JSONObject jsonObject : linkPanList) {
jsonObject.put("createTime", Calendar.getInstance().getTimeInMillis() + i++);
addOrUpdateMap.put(jsonObject.getString("sid"), jsonObject.toJSONString());
}
this.syncLinPanFromFileToRedis(num);
//处理新增和修改数据
this.addOrUpdateLinkPanHandler(num, addOrUpdateMap);
}
/**
*
保证热点数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
*
* @author dengsixing
* @date 2022/3/3
**/
private void syncLinPanFromFileToRedis(String num) throws Exception{
String key = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
boolean exist = redisUtil.hasKey(key);
if(exist){
return;
}
String lockKey = String.format(RedisLockKey.LOCK_LINKPAN_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 linkSceneFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num);
String linkSceneData = FileUtils.readUtf8String(linkSceneFilePath + "links.json");
if(StrUtil.isEmpty(linkSceneData)){
return;
}
JSONObject jsonObject = JSON.parseObject(linkSceneData);
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);
}
}
private void addOrUpdateLinkPanHandler(String num, Map addOrUpdateMap){
if(CollUtil.isEmpty(addOrUpdateMap))
return;
//数据验证,新增、修改状态,linkPan不能为空
for (String sid : addOrUpdateMap.keySet()) {
String linkPan = addOrUpdateMap.get(sid);
if(StrUtil.isEmpty(linkPan)){
throw new BusinessException(ErrorCode.FAILURE_CODE_7022);
}
}
//批量写入缓存
String key = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
redisUtil.hmset(key, addOrUpdateMap);
}
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()
.setSql("version = version + 1")
.set("box_videos", boxVideos)
.eq("id", sceneEditInfo.getId()));
}
}
private void updateBoxPhotos(SceneEditInfo sceneEditInfo, String boxPhotos){
this.update(new LambdaUpdateWrapper()
.set(SceneEditInfo::getBoxPhotos, boxPhotos)
.setSql("version = version + 1")
.eq(SceneEditInfo::getId, sceneEditInfo.getId()));
}
private String createBoxVideos(
String num, 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 deleteVidoeFile = new HashSet<>();
Set deletePicFile = new HashSet<>();
if(boxVideosJson.size() == 0)
return null;
for(int i=0;i(deleteVidoeFile)).build());
//删除资源文件
if(CollUtil.isNotEmpty(deleteVidoeFile))
sceneUploadService.delete(
DeleteFileParamVO.builder().num(num)
.bizType(FileBizType.BOX_POSTER.code())
.fileNames(new ArrayList<>(deletePicFile)).build());
}else{
boxVideo.put("createTime", Calendar.getInstance().getTimeInMillis());
//更新
boolean exist = false;
for(int i=0;i deleteFile = new HashSet<>();
if(boxPhotosJson.size() == 0)
return null;
for(int i=0;i(deleteFile)).build());
}else{
//更新
boolean exist = false;
for(int i=0;i 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;
}
private void transferToFlv(String num, String fileName, String bucket) throws Exception {
String userEditPath = String.format(UploadFilePath.USER_EDIT_PATH, num);
String localImagesPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num);
String localFilePath = localImagesPath + fileName;
File targetFile = new File(localImagesPath);
if (!targetFile.exists()){
targetFile.mkdirs();
}
targetFile = new File(localFilePath);
if (targetFile.exists()){
FileUtils.deleteFile(localFilePath);
}
//从用户编辑目录中下载视频到本地
String filePath = userEditPath + fileName;
fYunFileService.downloadFile(bucket, filePath, localImagesPath + fileName);
//视频格式转换
CreateObjUtil.mp4ToFlv(localFilePath, localFilePath.replace("mp4", "flv"));
//上传
String flvFileName = fileName.replace("mp4", "flv");
fYunFileService.uploadFile(bucket, localFilePath.replace("mp4", "flv"), userEditPath+flvFileName);
}
@Override
public ResultData deleteMosaics(DeleteMosaicParamVO param) throws Exception {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
//如果redis数据丢失,从本地文件中同步马赛克数据到redis
this.syncMosaicFromFileToRedis(param.getNum());
String key = String.format(RedisKey.SCENE_MOSAIC_DATA, param.getNum());
redisUtil.hdel(key, param.getPanoIdList().toArray());
//写入本地文件,作为备份
this.writeMosaic(param.getNum());
//更新数据库
this.updateMosaicFlag(param.getNum());
//更新版本号
this.upgradeVersionById(sceneEditInfo.getId());
return ResultData.ok();
}
@Override
public List getMosaicList(String num) throws Exception {
//如果redis数据丢失,从本地文件中同步马赛克数据到redis
this.syncMosaicFromFileToRedis(num);
String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
Map map = redisUtil.hmget(key);
if(CollUtil.isEmpty(map)){
ResultData.ok(new String[0]);
}
return map.values().stream()
.map(mosaic-> JSON.parseObject(mosaic))
.collect(Collectors.toList());
}
@Override
public ResultData addWaterMark(BaseFileParamVO param) throws Exception {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService
.getByScenePlusId(scenePlus.getId());
sceneEditInfoExt.setWaterMark(param.getFileName());
sceneEditInfoExtService.updateById(sceneEditInfoExt);
return ResultData.ok();
}
@Override
public ResultData deleteWaterMark(BaseFileParamVO param) throws Exception {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
sceneUploadService.delete(
DeleteFileParamVO.builder()
.num(param.getNum())
.fileNames(Lists.newArrayList(param.getFileName()))
.bizType(FileBizType.WATERMARK.code()).build());
SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
sceneEditInfoExt.setWaterMark("");
sceneEditInfoExtService.updateById(sceneEditInfoExt);
return ResultData.ok();
}
@Override
public ResultData saveFilter(BaseDataParamVO param) throws Exception {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
String key = String.format(RedisKey.SCENE_filter_DATA, param.getNum());
JSONArray filterArr = JSON.parseArray(param.getData());
int filters = CommonStatus.YES.code();
if(CollUtil.isEmpty(filterArr)){
filters = CommonStatus.NO.code();
redisUtil.del(key);
}else{
List filterList = filterArr.stream().map(item->JSON.toJSONString(item)).collect(Collectors.toList());
redisUtil.lRightPushAll(key, filterList);
}
//写本地文件,作为备份
this.writeFilter(param.getNum());
//更新数据库
SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
sceneEditInfoExt.setFilters(filters);
sceneEditInfoExtService.updateById(sceneEditInfoExt);
return ResultData.ok();
}
private void writeFilter(String num) throws Exception{
String filterPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "filter.json";
String key = String.format(RedisKey.SCENE_filter_DATA, num);
List filters = redisUtil.lGet(key, 0, -1);
if(CollUtil.isEmpty(filters)){
FileUtils.deleteFile(filterPath);
return;
}
String lockKey = String.format(RedisLockKey.LOCK_filter_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(filterPath, JSON.toJSONString(filters));
}finally {
redisLockUtil.unlockLua(lockKey, lockVal);
}
}
private void syncFiltersFromFileToRedis(String num) throws Exception{
String key = String.format(RedisKey.SCENE_filter_DATA, num);
boolean exist = redisUtil.hasKey(key);
if(exist){
return;
}
String lockKey = String.format(RedisLockKey.LOCK_FILTER_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 filePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num);
String filterData = FileUtils.readUtf8String(filePath + "filter.json");
if(StrUtil.isEmpty(filterData)){
return;
}
JSONArray jsonArray = JSON.parseArray(filterData);
if(CollUtil.isEmpty(jsonArray)){
return;
}
redisUtil.lRightPushAll(key, jsonArray.stream().collect(Collectors.toList()));
}finally {
redisLockUtil.unlockLua(lockKey, lockVal);
}
}
@Override
public ResultData listFilter(BaseSceneParamVO param) throws Exception {
//同步数据
this.syncFiltersFromFileToRedis(param.getNum());
//查询redis
String key = String.format(RedisKey.SCENE_filter_DATA, param.getNum());
List list = redisUtil.lGet(key, 0, -1);
List collect =
list.stream().map(str -> JSON.parseObject(str)).collect(Collectors.toList());
return ResultData.ok(collect);
}
}