|
@@ -1,50 +1,46 @@
|
|
|
-package com.fdkankan.scene.download.service.impl;
|
|
|
+package com.fdkankan.download.service.impl;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.collection.ConcurrentHashSet;
|
|
|
import cn.hutool.core.exceptions.ExceptionUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.json.JSON;
|
|
|
import cn.hutool.json.JSONObject;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
-import com.fdkankan.common.constant.ErrorCode;
|
|
|
+import com.fdkankan.common.constant.DownloadStatus;
|
|
|
+import com.fdkankan.common.constant.SceneDownloadProgressStatus;
|
|
|
import com.fdkankan.common.constant.ServerCode;
|
|
|
import com.fdkankan.common.constant.UploadFilePath;
|
|
|
import com.fdkankan.common.response.ResultData;
|
|
|
import com.fdkankan.common.util.FileUtils;
|
|
|
+import com.fdkankan.download.bean.CurrentDownloadNumUtil;
|
|
|
import com.fdkankan.fyun.constant.StorageType;
|
|
|
import com.fdkankan.fyun.oss.UploadToOssUtil;
|
|
|
+import com.fdkankan.platform.api.feign.PlatformUserClient;
|
|
|
import com.fdkankan.redis.constant.RedisKey;
|
|
|
import com.fdkankan.redis.util.RedisUtil;
|
|
|
-import com.fdkankan.scene.download.bean.DownLoadProgressBean;
|
|
|
-import com.fdkankan.scene.download.bean.DownLoadTaskBean;
|
|
|
-import com.fdkankan.scene.download.bean.ImageType;
|
|
|
-import com.fdkankan.scene.download.bean.ImageTypeDetail;
|
|
|
+import com.fdkankan.common.bean.DownLoadProgressBean;
|
|
|
+import com.fdkankan.common.bean.DownLoadTaskBean;
|
|
|
+import com.fdkankan.scene.api.dto.SceneInfoDTO;
|
|
|
+import com.fdkankan.scene.api.feign.SceneUserSceneClient;
|
|
|
+import com.fdkankan.download.bean.ImageType;
|
|
|
+import com.fdkankan.download.bean.ImageTypeDetail;
|
|
|
import com.google.common.collect.Lists;
|
|
|
import java.io.File;
|
|
|
import java.io.FileInputStream;
|
|
|
-import java.io.FileNotFoundException;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
import java.math.BigDecimal;
|
|
|
-import java.net.HttpURLConnection;
|
|
|
-import java.net.URL;
|
|
|
import java.net.URLEncoder;
|
|
|
import java.util.ArrayList;
|
|
|
-import java.util.Arrays;
|
|
|
import java.util.Calendar;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
import java.util.Set;
|
|
|
-import java.util.regex.Matcher;
|
|
|
-import java.util.regex.Pattern;
|
|
|
import java.util.stream.Collectors;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import lombok.var;
|
|
|
-import org.apache.commons.lang.StringEscapeUtils;
|
|
|
-import org.apache.tools.zip.ZipFile;
|
|
|
import org.apache.tools.zip.ZipOutputStream;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
@@ -64,12 +60,24 @@ import org.springframework.web.client.RestTemplate;
|
|
|
@Service
|
|
|
public class SceneDownloadHandlerServiceImpl {
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private PlatformUserClient platformUserClient;
|
|
|
+ @Autowired
|
|
|
+ private SceneUserSceneClient sceneUserSceneClient;
|
|
|
+
|
|
|
private static final String wwwroot = "wwwroot/";
|
|
|
+// private static final String[] prefixArr = new String[]{
|
|
|
+// "data/data%s/",
|
|
|
+// "voice/voice%s/",
|
|
|
+// "video/video%s/",
|
|
|
+// "images/images%s/"
|
|
|
+// };
|
|
|
+
|
|
|
private static final String[] prefixArr = new String[]{
|
|
|
- "data/data%s/",
|
|
|
- "voice/voice%s/",
|
|
|
- "video/video%s/",
|
|
|
- "images/images%s/"
|
|
|
+ UploadFilePath.DATA_VIEW_PATH,
|
|
|
+ UploadFilePath.VOICE_VIEW_PATH,
|
|
|
+ UploadFilePath.VIDEOS_VIEW_PATH,
|
|
|
+ UploadFilePath.IMG_VIEW_PATH
|
|
|
};
|
|
|
|
|
|
private static final List<ImageType> imageTypes = Lists.newArrayList();
|
|
@@ -99,27 +107,42 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
@Autowired
|
|
|
UploadToOssUtil uploadToOssUtil;
|
|
|
|
|
|
+ @Async("sceneDownLoadExecutror")
|
|
|
+ public void download(DownLoadTaskBean downLoadTaskBean){
|
|
|
+ //场景码
|
|
|
+ String num = null;
|
|
|
|
|
|
+ try {
|
|
|
+ num = downLoadTaskBean.getNum();
|
|
|
|
|
|
- @Async("sceneDownLoadExecutror")
|
|
|
- public void download(){
|
|
|
-
|
|
|
- StorageType storageType = StorageType.get(uploadType);
|
|
|
- switch (storageType){
|
|
|
- case OSS:
|
|
|
- this.download4Ali();
|
|
|
- break;
|
|
|
- case AWS:
|
|
|
- this.download4Aws();
|
|
|
- break;
|
|
|
- }
|
|
|
+ log.info("场景下载开始 - num[{}] - threadName[{}]", num, Thread.currentThread().getName());
|
|
|
+
|
|
|
+ long startTime = Calendar.getInstance().getTimeInMillis();
|
|
|
+
|
|
|
+ //执行场景下载逻辑
|
|
|
+ this.downloadHandler(downLoadTaskBean);
|
|
|
+
|
|
|
+ //耗时
|
|
|
+ long consumeTime = Calendar.getInstance().getTimeInMillis() - startTime;
|
|
|
|
|
|
+ log.info("场景下载结束 - num[{}] - threadName[{}] - consumeTime[{}]", num, Thread.currentThread().getName(), consumeTime);
|
|
|
+
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error(ExceptionUtil.stacktraceToString(e));
|
|
|
+ }finally {
|
|
|
+ if(StrUtil.isNotEmpty(num)){
|
|
|
+ //本地正在下载任务出队
|
|
|
+ CurrentDownloadNumUtil.removeSceneNum(num);
|
|
|
+ //删除正在下载任务
|
|
|
+ redisUtil.lRemove(RedisKey.SCENE_DOWNLOAD_ING, 1, num);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- public void download4Ali(){
|
|
|
+ public void downloadHandler(DownLoadTaskBean downLoadTaskBean) throws Exception{
|
|
|
|
|
|
- //场景码
|
|
|
- String num = null;
|
|
|
+ String num = downLoadTaskBean.getNum();
|
|
|
+ Long userId = downLoadTaskBean.getUserId();
|
|
|
|
|
|
//zip包路径
|
|
|
String zipPath = null;
|
|
@@ -131,12 +154,6 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
try {
|
|
|
Set<String> cacheKeys = new HashSet<>();
|
|
|
|
|
|
- //获取任务队列中队头场景码,如果是空,标识没有场景要下载,则退出程序
|
|
|
- num = this.getTaskSceneNum();
|
|
|
- if(StrUtil.isEmpty(num)){
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
Map<String, List<String>> allFiles = this.getAllFiles(num, v3localPath);
|
|
|
List<String> ossFilePaths = allFiles.get("ossFilePaths");
|
|
|
List<String> v3localFilePaths = allFiles.get("v3localFilePaths");
|
|
@@ -152,14 +169,20 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
|
|
|
JSONObject getInfoJson = this.zipGetInfoJson(out, num);
|
|
|
String resolution = "2k";
|
|
|
- if(getInfoJson.getInt("sceneSource") == 3 || getInfoJson.getInt("sceneSource") == 4){
|
|
|
+ if(getInfoJson.getInt("sceneSource") != null &&
|
|
|
+ (getInfoJson.getInt("sceneSource") == 3 || getInfoJson.getInt("sceneSource") == 4)){
|
|
|
resolution = "4k";
|
|
|
}
|
|
|
int imagesVersion = -1;
|
|
|
- if(getInfoJson.getInt("imagesVersion") != null){
|
|
|
- imagesVersion = getInfoJson.getInt("imagesVersion");
|
|
|
+ // TODO: 2022/3/29 V4版本目前没有imagesVersion字段,暂时用version字段替代
|
|
|
+// if(getInfoJson.getInt("imagesVersion") != null){
|
|
|
+// imagesVersion = getInfoJson.getInt("imagesVersion");
|
|
|
+// }
|
|
|
+ if(getInfoJson.getInt("version") != null){
|
|
|
+ imagesVersion = getInfoJson.getInt("version");
|
|
|
}
|
|
|
|
|
|
+
|
|
|
//固定文件写入
|
|
|
count = this.zipLocalFiles(out, v3localFilePaths, v3localPath, num, count, total);
|
|
|
|
|
@@ -176,18 +199,25 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
uploadToOssUtil.upload(zipPath, uploadPath);
|
|
|
|
|
|
//更新进度100
|
|
|
- this.updateProgress(new BigDecimal("100"), num, 1002, this.publicUrl + uploadPath);
|
|
|
+ String url = this.publicUrl + uploadPath;
|
|
|
+ this.updateProgress(null, num, SceneDownloadProgressStatus.DOWNLOAD_SUCCESS.code(), url);
|
|
|
+
|
|
|
+ //更新用户场景已下载次数
|
|
|
+ platformUserClient.updateDownloadNum(userId, 1);
|
|
|
+
|
|
|
+ //更新下载log状态为成功
|
|
|
+ sceneUserSceneClient.updateSceneDownloadLog(num, DownloadStatus.SUCCESS.code(), url, null);
|
|
|
|
|
|
}catch (Exception e){
|
|
|
- log.error(ExceptionUtil.stacktraceToString(e));
|
|
|
//更新进度为下载失败
|
|
|
- this.updateProgress( null, num, 1003, null);
|
|
|
+ this.updateProgress( null, num, SceneDownloadProgressStatus.DOWNLOAD_FAILED.code(), null);
|
|
|
+ //更新下载log状态为成功
|
|
|
+ sceneUserSceneClient.updateSceneDownloadLog(num, DownloadStatus.FAILD.code(), null, ExceptionUtil.stacktraceToString(e));
|
|
|
+ throw e;
|
|
|
}finally {
|
|
|
- if(StrUtil.isNotEmpty(num)){
|
|
|
- //删除正在下载任务
|
|
|
- redisUtil.lRemove(RedisKey.SCENE_DOWNLOAD_ING, 1, num);
|
|
|
+ if(StrUtil.isNotBlank(zipPath)){
|
|
|
//删除本地zip包
|
|
|
-// FileUtils.deleteFile(zipPath);
|
|
|
+ FileUtils.deleteFile(zipPath);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -197,7 +227,8 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
for (String filePath : ossFilePaths) {
|
|
|
if(filePath.contains(imageNumPath + "/panorama/panorama_edit/")){
|
|
|
//如果是编辑目录,只需要更新进度,不需要放进压缩包
|
|
|
- this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP), num, 1000, null);
|
|
|
+ this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),
|
|
|
+ num, SceneDownloadProgressStatus.DOWNLOADING.code(), null);
|
|
|
continue;
|
|
|
}else if((filePath.contains(imageNumPath + "/panorama/") && filePath.contains("tiles/" + resolution)) || filePath.contains(imageNumPath + "/tiles/" + resolution + "/")) {
|
|
|
this.processImage(filePath, out, resolution, imagesVersion, cacheKeys);
|
|
@@ -206,7 +237,8 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
}
|
|
|
|
|
|
//更新进度
|
|
|
- this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP), num, 1000, null);
|
|
|
+ this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),
|
|
|
+ num, SceneDownloadProgressStatus.DOWNLOAD_COMPRESSING.code(), null);
|
|
|
}
|
|
|
return count;
|
|
|
}
|
|
@@ -221,7 +253,7 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
//更新进度
|
|
|
this.updateProgress(
|
|
|
new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),
|
|
|
- num, 1000, null);
|
|
|
+ num, SceneDownloadProgressStatus.DOWNLOAD_COMPRESSING.code(), null);
|
|
|
}
|
|
|
//写入code.txt
|
|
|
this.zipBytes(out, "code.txt", num.getBytes());
|
|
@@ -233,7 +265,8 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
this.zipBytes(out, exeName, batContent.getBytes());
|
|
|
|
|
|
//更新进度为90%
|
|
|
- this.updateProgress(new BigDecimal("90"), num, 1001, null);
|
|
|
+ this.updateProgress(new BigDecimal("0.9").divide(new BigDecimal("0.8"), 6, BigDecimal.ROUND_HALF_UP), num,
|
|
|
+ SceneDownloadProgressStatus.DOWNLOAD_COMPRESSING.code(), null);
|
|
|
}
|
|
|
|
|
|
private Map<String, List<String>> getAllFiles(String num, String v3localPath) throws Exception{
|
|
@@ -268,38 +301,28 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
}
|
|
|
|
|
|
private JSONObject zipGetInfoJson(ZipOutputStream out, String num) throws Exception{
|
|
|
- String url = serverUrl + "api/scene/getInfo?num=" + num;
|
|
|
- String getInfoStr = restTemplate.getForObject(url, String.class);
|
|
|
- ResultData resultData = JSONUtil.toBean(getInfoStr, ResultData.class);
|
|
|
- if(resultData == null || ServerCode.SUCCESS.code() != resultData.getCode()){
|
|
|
- throw new Exception("getInfo请求失败,url:" + url);
|
|
|
+
|
|
|
+ ResultData<SceneInfoDTO> sceneViewInfo = sceneUserSceneClient.getSceneViewInfo(num);
|
|
|
+ if(!sceneViewInfo.getSuccess()){
|
|
|
+ throw new Exception(ServerCode.FEIGN_REQUEST_FAILD.message());
|
|
|
}
|
|
|
- JSONObject getInfoJson = JSONUtil.parseObj(resultData.getData());
|
|
|
+ SceneInfoDTO data = sceneViewInfo.getData();
|
|
|
+ JSONObject getInfoJson = null;
|
|
|
+ if(Objects.isNull(data)){
|
|
|
+ getInfoJson = new JSONObject();
|
|
|
+ }else {
|
|
|
+ getInfoJson = JSONUtil.parseObj(data);
|
|
|
+ }
|
|
|
+
|
|
|
getInfoJson.set("sceneScheme", 3);
|
|
|
getInfoJson.set("needKey", 0);
|
|
|
getInfoJson.set("sceneKey","");
|
|
|
- // 写入getInfo.json
|
|
|
+ //写入getInfo.json
|
|
|
String getInfoJsonPath = "wwwroot/data/data"+num + "/getInfo.json";
|
|
|
this.zipBytes(out, getInfoJsonPath, getInfoJson.toString().getBytes());
|
|
|
return getInfoJson;
|
|
|
}
|
|
|
|
|
|
- private String getTaskSceneNum() throws Exception{
|
|
|
- //redis待下载任务出队
|
|
|
- String downloadTask = redisUtil.lLeftPop("downloads:task:v4");
|
|
|
- if(StrUtil.isEmpty(downloadTask)){
|
|
|
- return null;
|
|
|
- }
|
|
|
- DownLoadTaskBean downLoadTaskBean = JSONUtil.toBean(downloadTask, DownLoadTaskBean.class);
|
|
|
- if(downLoadTaskBean == null || StrUtil.isEmpty(downLoadTaskBean.getNum()) || !"local".equals(downLoadTaskBean.getType())){
|
|
|
- throw new Exception("下载任务数据不正确,downloadTask:" + downloadTask);
|
|
|
- }
|
|
|
- String num = downLoadTaskBean.getNum();
|
|
|
- //正在下载任务入队
|
|
|
- redisUtil.lLeftPush(RedisKey.SCENE_DOWNLOAD_ING, num);
|
|
|
- return num;
|
|
|
- }
|
|
|
-
|
|
|
private void processImage(String key, ZipOutputStream out, String resolution, int imagesVersion, Set<String> imgKeys) throws Exception{
|
|
|
|
|
|
String fileName = key.substring(key.lastIndexOf("/")+1, key.indexOf("."));
|
|
@@ -391,22 +414,27 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
|
|
|
public void updateProgress(BigDecimal precent, String num, Integer status, String url){
|
|
|
|
|
|
- if(precent == null){
|
|
|
- precent = new BigDecimal(0);
|
|
|
- }
|
|
|
- if(status == null){
|
|
|
- precent = precent.multiply(new BigDecimal("0.8")).multiply(new BigDecimal("100"));
|
|
|
+ SceneDownloadProgressStatus progressStatus = SceneDownloadProgressStatus.get(status);
|
|
|
+ switch (progressStatus){
|
|
|
+ case DOWNLOAD_SUCCESS:
|
|
|
+ precent = new BigDecimal("100");
|
|
|
+ break;
|
|
|
+ case DOWNLOAD_FAILED:
|
|
|
+ precent = new BigDecimal("0");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ precent = precent.multiply(new BigDecimal("0.8")).multiply(new BigDecimal("100"));
|
|
|
}
|
|
|
|
|
|
DownLoadProgressBean progress = null;
|
|
|
- String key = String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS, num);
|
|
|
+ String key = String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4, num);
|
|
|
String progressStr = redisUtil.get(key);
|
|
|
if(StrUtil.isEmpty(progressStr)){
|
|
|
progress = DownLoadProgressBean.builder().percent(precent.intValue()).status(status).url(url).build();
|
|
|
}else{
|
|
|
progress = JSONUtil.toBean(progressStr, DownLoadProgressBean.class);
|
|
|
//如果下载失败,进度不变
|
|
|
- if(status == 1003 && progress.getPercent() != null){
|
|
|
+ if(status == SceneDownloadProgressStatus.DOWNLOAD_FAILED.code() && progress.getPercent() != null){
|
|
|
precent = new BigDecimal(progress.getPercent());
|
|
|
}
|
|
|
progress.setPercent(precent.intValue());
|
|
@@ -432,12 +460,4 @@ public class SceneDownloadHandlerServiceImpl {
|
|
|
}
|
|
|
|
|
|
|
|
|
- public void download4Aws(){
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
}
|