Переглянути джерело

v4.12.0 上传模型 异步

dengsixing 1 рік тому
батько
коміт
4d2945d269

+ 30 - 2
src/main/java/com/fdkankan/scene/controller/SceneAsynOperLogController.java

@@ -1,6 +1,14 @@
 package com.fdkankan.scene.controller;
 
 
+import com.fdkankan.scene.annotation.CheckPermit;
+import com.fdkankan.scene.service.ISceneAsynOperLogService;
+import com.fdkankan.scene.vo.SceneAsynOperLogParamVO;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
@@ -10,12 +18,32 @@ import org.springframework.web.bind.annotation.RestController;
  *  前端控制器
  * </p>
  *
- * @author 
+ * @author
  * @since 2022-12-07
  */
 @RestController
-@RequestMapping("/scene/sceneAsynOperLog")
+@RequestMapping("/service/scene/edit")
 public class SceneAsynOperLogController {
 
+    @Autowired
+    private ISceneAsynOperLogService sceneAsynOperLogService;
+
+
+    /**
+     * <p>
+     查询异步操作
+     * </p>
+     * @author dengsixing
+     * @date 2022/10/19
+     * @param param
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @CheckPermit
+    @PostMapping("/getAsynOperLog")
+    public ResultData getAsynOperLog(@RequestBody @Validated SceneAsynOperLogParamVO param){
+        return sceneAsynOperLogService.getAsynOperLog(param);
+    }
+
+
 }
 

+ 0 - 15
src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -854,21 +854,6 @@ public class SceneEditController extends BaseController {
     }
 
     /**
-     * <p>
-     删除空间模型
-     * </p>
-     * @author dengsixing
-     * @date 2022/10/19
-     * @param param
-     * @return com.fdkankan.common.response.ResultData
-     **/
-    @CheckPermit
-    @PostMapping("/getAsynOperLog")
-    public ResultData getAsynOperLog(@RequestBody @Validated SceneAsynOperLogParamVO param){
-        return sceneAsynOperLogService.getAsynOperLog(param);
-    }
-
-    /**
      * 获取编辑器版本信息
      * @return
      */

+ 1 - 6
src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -1372,12 +1372,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             return ResultData.ok(map);
         }else{
             //清除旧的下载记录
-            sceneAsynOperLogService.remove(
-                new LambdaQueryWrapper<SceneAsynOperLog>()
-                    .eq(SceneAsynOperLog::getNum, num)
-                    .eq(SceneAsynOperLog::getOperType, SceneAsynOperType.DOWNLOAD.code())
-                    .eq(SceneAsynOperLog::getModule, SceneAsynModuleType.UPLOAD_DOWNLOAD.code())
-                    .eq(SceneAsynOperLog::getFunc, SceneAsynFuncType.PANORAMIC_IMAGE.code()));
+            sceneAsynOperLogService.cleanLog(num, SceneAsynModuleType.UPLOAD_DOWNLOAD.code(), SceneAsynFuncType.PANORAMIC_IMAGE.code(), SceneAsynOperType.DOWNLOAD.code());
 
             //开始异步执行下载全景图压缩包操作
             CompletableFuture.runAsync(() -> {

+ 158 - 102
src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.util.RuntimeUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSON;
@@ -14,63 +13,45 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 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.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFileName;
 import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.constants.UploadFilePath;
-import com.fdkankan.common.exception.BusinessException;
-import com.fdkankan.scene.bean.SceneBean;
-import com.fdkankan.web.response.ResultData;
 import com.fdkankan.model.utils.ComputerUtil;
 import com.fdkankan.model.utils.ConvertUtils;
 import com.fdkankan.model.utils.CreateObjUtil;
-import com.fdkankan.common.util.FileUtils;
-import com.fdkankan.common.util.OkHttpUtils;
-import com.fdkankan.fyun.constant.FYunTypeEnum;
-import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.constant.RedisLockKey;
 import com.fdkankan.redis.util.RedisLockUtil;
 import com.fdkankan.redis.util.RedisUtil;
 import com.fdkankan.scene.bean.IconBean;
+import com.fdkankan.scene.bean.SceneBean;
 import com.fdkankan.scene.bean.TagBean;
-import com.fdkankan.scene.entity.SceneEditInfo;
-import com.fdkankan.scene.entity.ScenePlus;
-import com.fdkankan.scene.entity.ScenePlusExt;
-import com.fdkankan.scene.entity.ScenePro;
+import com.fdkankan.scene.entity.*;
 import com.fdkankan.scene.mapper.ISceneProMapper;
-import com.fdkankan.scene.service.ISceneDataDownloadService;
-import com.fdkankan.scene.service.ISceneEditControlsService;
-import com.fdkankan.scene.service.ISceneEditInfoService;
-import com.fdkankan.scene.service.IScenePlusExtService;
-import com.fdkankan.scene.service.IScenePlusService;
-import com.fdkankan.scene.service.ISceneProService;
-import com.fdkankan.scene.service.ISceneUploadService;
-import com.fdkankan.scene.vo.BaseDataParamVO;
-import com.fdkankan.scene.vo.DeleteFileParamVO;
-import com.fdkankan.scene.vo.DeleteHotIconParamVO;
-import com.fdkankan.scene.vo.DeleteHotParamVO;
-import com.fdkankan.scene.vo.FileNameAndDataParamVO;
-import com.fdkankan.scene.vo.HotParamVO;
-import com.fdkankan.scene.vo.SaveTagsParamVO;
-import com.fdkankan.scene.vo.SaveTagsVisibleParamVO;
+import com.fdkankan.scene.service.*;
+import com.fdkankan.scene.vo.*;
+import com.fdkankan.web.response.ResultData;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
-import org.redisson.Redisson;
-import org.redisson.RedissonLock;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
 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.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
+
 /**
  * <p>
  * pro场景表 服务实现类
@@ -100,7 +81,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
     @Value("${ecs.checkFile.waitTime:5000}")
     private int waitTime;
 
-    @Autowired
+    @Resource
     private FYunFileServiceInterface fYunFileService;
     @Autowired
     private RedisLockUtil redisLockUtil;
@@ -120,6 +101,8 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
     private IScenePlusExtService scenePlusExtService;
     @Autowired
     private ISceneUploadService sceneUploadService;
+    @Autowired
+    private ISceneAsynOperLogService sceneAsynOperLogService;
 
     @Transactional
     @Override
@@ -695,6 +678,13 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         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();
 
@@ -704,28 +694,6 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             this.buildModel4Dam(num, bucket, scenePlusExt.getDataSource(), scenePlusExt.getBuildType(), file);
         }
 
-        //更新版本信息
-        SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
-        if(Objects.isNull(sceneEditInfo)){
-            sceneEditInfo = new SceneEditInfo();
-            sceneEditInfo.setScenePlusId(scenePlus.getId());
-            sceneEditInfo.setFloorPublishVer(1);
-            sceneEditInfo.setFloorEditVer(1);
-            sceneEditInfo.setIsUploadObj(CommonStatus.YES.code());
-            sceneEditInfoService.save(sceneEditInfo);
-        }else{
-            sceneEditInfoService.update(
-                new LambdaUpdateWrapper<SceneEditInfo>()
-                    .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);
-        }
-
         return ResultData.ok();
     }
 
@@ -751,16 +719,46 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         //创建data.json
         this.writeDataJson(path);
 
-        //调用算法,不同的类型调用不同的算法
-        if("V2".equals(buildType)){
-            CreateObjUtil.objToTxt(path , "1");
-        }
-        if("V3".equals(buildType)){
-            CreateObjUtil.build3dModel(path , "1");
-        }
+        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
-        this.uploadFileofterRebuildPanoram(path, filePath, num, bucket);
+                //算法计算完后,生成压缩文件,上传到oss
+                uploadFileofterBuildDamModel(path, filePath, num, bucket);
+
+                //更新版本信息
+                ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+                SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
+                sceneEditInfoService.update(
+                        new LambdaUpdateWrapper<SceneEditInfo>()
+                                .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);
+        });
     }
 
     /**
@@ -832,36 +830,64 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             }
         });
 
+        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);
+                }
 
-        //调用算法
-        String command = "bash /home/ubuntu/bin/Obj2Tiles.sh " + path;
-        log.info("上传3dtiles模型开始, num:{}, targetPath:{}", num, path);
-//        RuntimeUtil.exec(command);
-        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");
+                //删除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<SceneEditInfo>()
+                                .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 uploadFileofterRebuildPanoram(String path, String filePath, String sceneNum, String bucket) throws Exception {
+    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);
@@ -1033,16 +1059,46 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         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());
 
-        if(ModelKind.THREE_D_TILE.code().equals(scenePlusExt.getModelKind())){
-            return this.downloadModel43dtiles(num, bucket, scenePlusExt, sceneEditInfo);
-        }
+        //开始异步执行下载全景图压缩包操作
+        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);
+                }
 
-        return this.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
@@ -1050,7 +1106,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         return this.getOne(new LambdaQueryWrapper<ScenePro>().eq(ScenePro::getNum, num));
     }
 
-    private ResultData downloadModel43dtiles(String num, String bucket, ScenePlusExt scenePlusExt, SceneEditInfo sceneEditInfo){
+    private String downloadModel43dtiles(String num, String bucket, ScenePlusExt scenePlusExt, SceneEditInfo sceneEditInfo){
 
         //下载mesh到本地
         String meshOssPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/";
@@ -1067,7 +1123,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         FileUtil.del(meshLocalPath);
         FileUtil.del(zipFilePath);
         String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
-        return ResultData.ok(url);
+        return url;
     }
 
     public static void main(String[] args) throws Exception {
@@ -1077,7 +1133,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
     }
 
 
-    private ResultData downloadModel4Dam(String num, String bucket){
+    private String downloadModel4Dam(String num, String bucket){
         String localImagePath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num);
         if(!new File(localImagePath).exists()){
             new File(localImagePath).mkdirs();
@@ -1124,7 +1180,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
         String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
         FileUtil.del(zipPath);
-        return ResultData.ok(url);
+        return url;
     }
 
     @Override