Selaa lähdekoodia

add laser offline

xiewj 1 vuosi sitten
vanhempi
commit
1a38f48703

+ 5 - 1
pom.xml

@@ -98,7 +98,11 @@
                 </exclusion>
             </exclusions>
         </dependency>
-
+        <dependency>
+            <groupId>net.lingala.zip4j</groupId>
+            <artifactId>zip4j</artifactId>
+            <version>2.11.5</version>
+        </dependency>
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>

+ 47 - 0
src/main/java/com/fdkankan/download/bean/LaserResultData.java

@@ -0,0 +1,47 @@
+package com.fdkankan.download.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LaserResultData<T> implements Serializable {
+    /**
+     * 状态码
+     */
+    private int code;
+    /**
+     * 响应信息
+     */
+    private String msg;
+    /**
+     * 后端返回结果
+     */
+    private T data;
+
+    public static LaserResultData ok(Object data) {
+        return ok("成功", data);
+    }
+
+    public static LaserResultData ok(String msg, Object data) {
+        return base(0, msg, data);
+    }
+
+    private static LaserResultData base(int code, String msg, Object data ) {
+        LaserResultData rd = new LaserResultData();
+        rd.setCode(code);
+        rd.setMsg(msg);
+        rd.setData(data);
+        return rd;
+    }
+
+    public static LaserResultData error(int code, String msg) {
+        return error(code, msg, null); }
+    public static LaserResultData error(int code, String msg, Object data) {
+        return base(code, msg, data);
+    }
+}

+ 25 - 0
src/main/java/com/fdkankan/download/callback/SuccessLaserCallback.java

@@ -0,0 +1,25 @@
+package com.fdkankan.download.callback;
+
+import com.dtflys.forest.callback.OnSuccess;
+import com.dtflys.forest.http.ForestRequest;
+import com.dtflys.forest.http.ForestResponse;
+import com.fdkankan.download.bean.LaserResultData;
+import com.fdkankan.download.bean.ResultData;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/25
+ **/
+@Slf4j
+public class SuccessLaserCallback implements OnSuccess<LaserResultData> {
+
+    @Override
+    public void onSuccess(LaserResultData laserResultData, ForestRequest forestRequest, ForestResponse forestResponse) {
+        log.info("请求成功,url:{},result:{}", forestRequest.getUrl(), forestResponse.getContent());
+    }
+}

+ 50 - 0
src/main/java/com/fdkankan/download/callback/SuccessLaserCondition.java

@@ -0,0 +1,50 @@
+package com.fdkankan.download.callback;
+
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.dtflys.forest.callback.SuccessWhen;
+import com.dtflys.forest.http.ForestRequest;
+import com.dtflys.forest.http.ForestResponse;
+import com.fdkankan.download.bean.LaserResultData;
+import com.fdkankan.download.bean.ResultData;
+
+/**
+ * <p>
+ *  自定义成功/失败条件实现类
+ *  需要实现 SuccessWhen 接口
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/25
+ **/
+
+public class SuccessLaserCondition implements SuccessWhen {
+
+    /**
+     * 请求成功条件
+     * @param req Forest请求对象
+     * @param res Forest响应对象
+     * @return 是否成功,true: 请求成功,false: 请求失败
+     */
+    @Override
+    public boolean successWhen(ForestRequest req, ForestResponse res) {
+        boolean reqStatus = res.noException() &&   // 请求过程没有异常
+            res.statusOk() &&     // 并且状态码在 100 ~ 399 范围内
+            res.statusIsNot(203);
+        if(!reqStatus){
+            return reqStatus;
+        }
+
+        String content = res.getContent();
+        if(StrUtil.isEmpty(content)){
+            reqStatus = false;
+            return reqStatus;
+        }
+        LaserResultData result = JSON.parseObject(content, LaserResultData.class);
+        if(result.getCode() != 200){
+            reqStatus = false;
+            return reqStatus;
+        }
+        return true;
+    }
+}

+ 9 - 1
src/main/java/com/fdkankan/download/controller/BatchDownloadController.java

@@ -5,6 +5,7 @@ import cn.hutool.system.SystemUtil;
 import cn.hutool.system.oshi.OshiUtil;
 import com.fdkankan.download.bean.ResultData;
 import com.fdkankan.download.service.IBatchDonloadService;
+import com.fdkankan.download.service.ILaserService;
 import com.fdkankan.download.service.ISnService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,6 +32,8 @@ public class BatchDownloadController {
     private IBatchDonloadService batchDonloadService;
     @Autowired
     private ISnService snService;
+    @Autowired
+    ILaserService laserService;
 
     @PostMapping("download")
     public ResultData bacthDownload(@RequestParam(value = "file") MultipartFile file) throws Exception {
@@ -57,7 +60,12 @@ public class BatchDownloadController {
 //        return ResultData.ok(snService.list());
     }
 
-
+    @GetMapping("testlaser")
+    public ResultData testlaser(String num) throws Exception {
+        laserService.downloadHandler(num);
+        return ResultData.ok(1);
+//        return ResultData.ok(snService.list());
+    }
 
 
 }

+ 23 - 0
src/main/java/com/fdkankan/download/entity/DTO/OfflineDTO.java

@@ -0,0 +1,23 @@
+package com.fdkankan.download.entity.DTO;
+
+import lombok.Data;
+
+/**
+ * @author Xiewj
+ * @date 2024年1月4日11:48:46
+ */
+@Data
+public class OfflineDTO {
+
+    /***
+     * @descriptieon 1 json   ,2下载,3复制 ,4全景图
+     * @author xiewj
+     */
+    private int type;
+    private String key;
+    private String path;
+    private Object data;
+    private String sceneCode;
+
+
+}

+ 21 - 1
src/main/java/com/fdkankan/download/httpclient/HttpClient.java

@@ -1,12 +1,19 @@
 package com.fdkankan.download.httpclient;
 
+import com.alibaba.fastjson.JSONObject;
 import com.dtflys.forest.annotation.*;
 import com.dtflys.forest.callback.OnError;
 import com.dtflys.forest.callback.OnSuccess;
+import com.fdkankan.download.bean.LaserResultData;
 import com.fdkankan.download.bean.ResultData;
+import com.fdkankan.download.callback.ErrorCallback;
+import com.fdkankan.download.callback.SuccessCallback;
 import com.fdkankan.download.callback.SuccessCondition;
+import com.fdkankan.download.callback.SuccessLaserCondition;
+import com.fdkankan.download.entity.DTO.OfflineDTO;
 import com.yomahub.tlog.forest.TLogForestInterceptor;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -17,7 +24,6 @@ import java.util.Map;
  * @author dengsixing
  * @since 2022/4/24
  **/
-@Success(condition = SuccessCondition.class)
 public interface HttpClient {
 
     @Get(
@@ -25,6 +31,7 @@ public interface HttpClient {
         interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
     )
     @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    @Success(condition = SuccessCondition.class)
     ResultData<Map<String, Object>> get(@Var("url") String url, @Header Map<String, Object> headerMap, OnSuccess<ResultData> onSuccess, OnError onError);
 
     @Post(
@@ -32,6 +39,7 @@ public interface HttpClient {
             interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
     )
     @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    @Success(condition = SuccessCondition.class)
     ResultData<Map<String, Object>> post(@Var("url") String url, @Header Map<String, Object> headerMap, @JSONBody Object param, OnSuccess<ResultData> onSuccess, OnError onError);
 
     @Post(
@@ -40,6 +48,18 @@ public interface HttpClient {
 //            interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
     )
     @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    @Success(condition = SuccessCondition.class)
     ResultData post2(@Var("url") String url, @JSONBody Object param, OnSuccess<ResultData> onSuccess, OnError onError);
 
+
+
+    @Get(
+            url="{url}",
+            interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
+    )
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    @Success(condition = SuccessLaserCondition.class)
+    LaserResultData<List<OfflineDTO>>  get(@Var("url") String url, OnSuccess<LaserResultData> onSuccess, OnError onError);
+
+
 }

+ 19 - 0
src/main/java/com/fdkankan/download/service/ILaserService.java

@@ -0,0 +1,19 @@
+package com.fdkankan.download.service;
+
+import com.fdkankan.download.entity.Camera;
+import com.mybatisflex.core.service.IService;
+
+import java.util.List;
+
+/**
+ * 相机主表 服务层。
+ *
+ * @author dsx
+ * @since 2023-12-08
+ */
+public interface ILaserService   {
+
+    void downloadHandler(String num) throws Exception;
+
+
+}

+ 3 - 1
src/main/java/com/fdkankan/download/service/impl/BatchDonloadServiceImpl.java

@@ -18,10 +18,12 @@ import com.fdkankan.download.util.Base64Converter;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.Resource;
 import java.io.File;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
@@ -51,7 +53,7 @@ public class BatchDonloadServiceImpl implements IBatchDonloadService {
 
     @Value("${api.downloadProcess}")
     private String downloadProcessUrl;
-    @Autowired
+    @Resource
     private HttpClient httpClient;
     @Autowired
     private ISsoService ssoService;

+ 3 - 1
src/main/java/com/fdkankan/download/service/impl/GenSceneRunnerImpl.java

@@ -50,6 +50,8 @@ public class GenSceneRunnerImpl implements CommandLineRunner {
 
     private final static ThreadPoolExecutor threadPoolExecutor = ExecutorBuilder.create().setCorePoolSize(5).setMaxPoolSize(5).build();
 
+    @Autowired
+    ILaserService laserService;
 
     @Override
     public void run(String... args) throws Exception {
@@ -88,7 +90,7 @@ public class GenSceneRunnerImpl implements CommandLineRunner {
                             threadPoolExecutor.submit(() -> {
                                 try {
                                     // TODO: 2024/1/3 文杰实现
-
+                                    laserService.downloadHandler(scenePlus.getNum());
                                     downloadLogService.saveLog(scenePlus.getNum(), "laser", CommonSuccessStatus.SUCCESS.code(), null);
                                 } catch (Exception e) {
                                     downloadLogService.saveLog(scenePlus.getNum(), "laser", CommonSuccessStatus.FAIL.code(), ExceptionUtil.stacktraceToString(e, 3000));

+ 214 - 0
src/main/java/com/fdkankan/download/service/impl/LaserService.java

@@ -0,0 +1,214 @@
+package com.fdkankan.download.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.file.FileReader;
+import cn.hutool.core.io.file.FileWriter;
+import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.system.oshi.OshiUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.util.CmdUtils;
+import com.fdkankan.download.bean.LaserResultData;
+import com.fdkankan.download.bean.ResultData;
+import com.fdkankan.download.callback.ErrorCallback;
+import com.fdkankan.download.callback.SuccessCallback;
+import com.fdkankan.download.callback.SuccessLaserCallback;
+import com.fdkankan.download.entity.DTO.OfflineDTO;
+import com.fdkankan.download.httpclient.HttpClient;
+import com.fdkankan.download.service.IDownloadService;
+import com.fdkankan.download.service.ILaserService;
+import com.fdkankan.download.service.IScenePlusService;
+import com.fdkankan.download.util.ImgUtil;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import jodd.util.SystemUtil;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import net.lingala.zip4j.ZipFile;
+import net.lingala.zip4j.model.ZipParameters;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import oshi.software.os.OperatingSystem;
+import oshi.software.os.windows.WindowsOperatingSystem;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Xiewj
+ * @date 2024/1/4
+ */
+@Service
+@Slf4j
+public class LaserService  implements ILaserService {
+
+    @Value("${laserhost}")
+    private String host;
+    @Resource
+    private HttpClient httpClient;
+    @Value("${api.offlineData}")
+    private String offlineData;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Value("${laser.bucket}")
+    private String bucket;
+    @Value("${path.source-local-laser}")
+    private String sourceLocal;
+    @Value("${path.laserschool}")
+    private String laserschool;
+    @Autowired
+    IDownloadService downloadService;
+    @Value("${download.config.resource-url}")
+    private String resourceUrl;
+    @Value("${download.config.laser-resource-url}")
+    private String laserResourceUrl;
+    @Value("${path.zip-local}")
+    private String zipLocalFormat;
+    @Override
+    public void downloadHandler(String num) throws Exception {
+        String url = host.concat(String.format(offlineData, num));
+        try {
+            LaserResultData<List<OfflineDTO> > resultData = httpClient.get(url, new SuccessLaserCallback(), new ErrorCallback());
+            if (resultData.getCode()==200){
+                OperatingSystem os = OshiUtil.getOs();
+
+                List<OfflineDTO> data = resultData.getData();
+                for (OfflineDTO datum : data) {
+                    //1 json   ,2下载,3深度图 ,4全景图
+                    switch (datum.getType()) {
+                        case 1:
+                            FileUtil.writeUtf8String(JSON.toJSONStringWithDateFormat(datum.getData(),"yyyy-MM-dd HH:mm:ss").replaceAll("\\n", " ").replaceAll("\\t", " "), sourceLocal+ File.separator+datum.getPath());
+                            break;
+                        case 2:
+                            if (os instanceof WindowsOperatingSystem){
+                                String path = datum.getKey();
+                                if (datum.getKey().startsWith("/")) {
+                                    path = path.substring(1);
+                                }
+                                List<String> strings = fYunFileService.listRemoteFiles(bucket,path);
+                                for (String key : strings) {
+                                    if (StrUtil.isEmpty(FileUtil.extName(key))){
+                                        continue;
+                                    }
+                                    String srcPath=key;
+                                    if(!key.startsWith("/")){
+                                        srcPath = "/"+key;
+                                    }
+                                    this.downloadFile(laserResourceUrl+key,sourceLocal+
+                                            File.separator+datum.getSceneCode()+
+                                            File.separator+"www"+
+                                            File.separator+datum.getSceneCode()+srcPath);
+                                }
+                            }else{
+                                String srcPath=datum.getKey();
+                                if("/".equals(datum.getKey().substring(0,1))){
+                                    srcPath = srcPath.substring(1);
+                                }
+                                fYunFileService.downloadFileByCommand(bucket,srcPath,sourceLocal+datum.getPath());
+                            }
+                            break;
+                        case 3:
+                            if (os instanceof WindowsOperatingSystem){
+                                String path = datum.getKey();
+                                if (datum.getKey().startsWith("/")) {
+                                    path = path.substring(1);
+                                }
+                                List<String> strings = fYunFileService.listRemoteFiles(bucket,path);
+                                for (String key : strings) {
+                                    if (StrUtil.isEmpty(FileUtil.extName(key))||FileUtil.extName(key).equalsIgnoreCase("ply")){
+                                        continue;
+                                    }
+                                    this.downloadFile(laserResourceUrl+key,sourceLocal+
+                                            File.separator+datum.getSceneCode()+
+                                            File.separator+"www"+
+                                            File.separator+datum.getSceneCode()+
+                                            File.separator+"wwwroot"+
+                                            File.separator+datum.getSceneCode()+
+                                            File.separator+"data"+
+                                            File.separator+datum.getSceneCode()+
+                                            File.separator+"depthmap"+
+                                            File.separator+FileUtil.getName(key));
+                                }
+                            }else{
+                                String srcPath=datum.getKey();
+                                if("/".equals(datum.getKey().substring(0,1))){
+                                    srcPath = srcPath.substring(1);
+                                }
+                                fYunFileService.downloadFileByCommand(bucket,srcPath,sourceLocal+datum.getPath());
+                                File[] deptLs = FileUtil.ls(sourceLocal+datum.getPath());
+                                for (File dept : deptLs) {
+                                    if (FileUtil.extName(dept).equalsIgnoreCase("ply")){
+                                        FileUtil.del(dept);
+                                    }
+                                }
+                            }
+                            break;
+                        case 4:
+                            downloadService.cutImg(num,sourceLocal+datum.getPath(),"4k","tiles");
+                            break;
+                        default:
+                            break;
+                    }
+                }
+                String path=sourceLocal+File.separator+num;
+
+                //处理html的编码
+                String htmlPath=laserschool+"www/offline.html";
+                if (FileUtil.exist(htmlPath)){
+                    String copyPath=path+File.separator+"www"+File.separator;
+                    FileUtil.copy(htmlPath, copyPath, true);
+                    FileReader fileReader = new FileReader(copyPath+"offline.html");
+                    String html = fileReader.readString();
+                    FileWriter fileWriter=new FileWriter(copyPath+"offline.html");
+                    fileWriter.write(html.replaceAll("@lang@","zh"),false);
+                }
+                String browserBatPath=laserschool+"start-browser.bat";
+                if (FileUtil.exist(browserBatPath)){
+                    String copyPath=path+File.separator;
+                    FileUtil.copy(browserBatPath, copyPath, true);
+                    FileReader fileReader = new FileReader(copyPath+"start-browser.bat");
+                    String bat = fileReader.readString();
+                    FileWriter fileWriter=new FileWriter(copyPath+"start-browser.bat");
+                    fileWriter.write(bat.replaceAll("@sceneCode@",num),false);
+                }
+                String target=num + "_laser.zip";
+                File file=offlineZip(num, path, target);
+                String zipPath = String.format(this.zipLocalFormat, num + "_laser");
+                FileUtil.move(file,new File(zipPath),true);
+                log.info("生成完成");
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }finally {
+//            String path=sourceLocal+File.separator+num;
+//            FileUtil.del(path);
+        }
+
+    }
+    @SneakyThrows
+    public File offlineZip(String sceneCode, String path, String target) {
+        String bashOfflinePath = laserschool + "bashOffline.zip";
+        File file = new File(path + File.separator + "bashOffline.zip");
+        FileUtil.copy(new File(bashOfflinePath), file, true);
+        ZipParameters zipParameters = new ZipParameters();
+        zipParameters.setOverrideExistingFilesInZip(false);
+        ZipFile zipFile = new ZipFile(file);
+        zipFile.setCharset(Charset.forName("GBK"));
+        zipFile.removeFile("www/offline.html");
+        zipFile.addFolder(new File(path + File.separator + "www"), zipParameters);
+        zipFile.addFile(new File(path + File.separator + "start-browser.bat"));
+        return FileUtil.rename(zipFile.getFile(),target, true);
+    }
+    public void downloadFile(String url, String path){
+        File file = new File(path);
+        if(!file.getParentFile().exists()){
+            file.getParentFile().mkdirs();
+        }
+        HttpUtil.downloadFile(url,  FileUtil.file(path));
+    }
+}

+ 4 - 2
src/main/resources/application-test.yml

@@ -92,8 +92,8 @@ path:
   zip-local: /home/backend/downloads/scenes/%s.zip
   zip-root: wwwroot/
   zip-oss: downloads/scenes/%s.zip
-  laserschool: I:\offline\school\
-  source-local-laser: I:\offline\downloads\scenesLaser
+  laserschool: /mnt/fdkk_laser/uploadPath/offlineGenerate/
+  source-local-laser: /mnt/fdkk_laser/uploadPath/offline
 download:
   dir: D:\test2\
   task: ${download.dir}task.txt
@@ -102,6 +102,8 @@ download:
     public-url: https://4dkk.4dage.com/
     resource-url: https://4dkankan.oss-cn-shenzhen-internal.aliyuncs.com/
     # resource-url: https://4dkankan.oss-cn-shenzhen.aliyuncs.com/
+    #laser-resource-url: https://laser-data.oss-cn-shenzhen.aliyuncs.com/
+    laser-resource-url: https://laser-data.oss-cn-shenzhen-internal.aliyuncs.com/
     exe-name: start-browser.bat
     exe-content: | # | 表示不转义特殊字符
       taskkill /f /t /im http.exe