dsx před 1 rokem
rodič
revize
02a76a7a4e

+ 2 - 0
src/main/java/com/fdkankan/external/Application.java

@@ -7,12 +7,14 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScans;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
 @SpringBootApplication
 @MapperScan("com.fdkankan.external.mapper")
 @ForestScan(basePackages = "com.fdkankan.external.httpclient")
 @EnableScheduling
+@ComponentScan(basePackages = {"com.fdkankan.*"})
 public class Application {
     public static void main(String[] args) {
         SpringApplication.run(Application.class, args);

+ 9 - 0
src/main/java/com/fdkankan/external/bean/LaserDownloadBean.java

@@ -0,0 +1,9 @@
+package com.fdkankan.external.bean;
+
+import lombok.Data;
+
+@Data
+public class LaserDownloadBean {
+    private Integer status;
+    private String url;
+}

+ 1 - 1
src/main/java/com/fdkankan/external/callback/ErrorCallback.java

@@ -31,7 +31,7 @@ public class ErrorCallback implements OnError {
             throw e;
         }
         ResultData result = JSON.parseObject(forestResponse.getContent(), ResultData.class);
-        if(result.getCode() != 0){
+        if(result.getCode() != 0 && result.getCode() != 200){
             throw new BusinessException(result.getCode(), result.getMessage());
         }
         throw new BusinessException(-1, "未知异常");

+ 1 - 1
src/main/java/com/fdkankan/external/callback/SuccessCondition.java

@@ -40,7 +40,7 @@ public class SuccessCondition implements SuccessWhen {
             return reqStatus;
         }
         ResultData result = JSON.parseObject(content, ResultData.class);
-        if(result.getCode() != 0){
+        if(result.getCode() != 0 && result.getCode() != 200){
             reqStatus = false;
             return reqStatus;
         }

+ 11 - 1
src/main/java/com/fdkankan/external/httpclient/HttpClient.java

@@ -3,7 +3,9 @@ package com.fdkankan.external.httpclient;
 import com.dtflys.forest.annotation.*;
 import com.dtflys.forest.callback.OnError;
 import com.dtflys.forest.callback.OnSuccess;
+import com.fdkankan.external.bean.LaserDownloadBean;
 import com.fdkankan.external.callback.SuccessCondition;
+import com.fdkankan.web.response.Result;
 import com.fdkankan.web.response.ResultData;
 import com.yomahub.tlog.forest.TLogForestInterceptor;
 
@@ -35,11 +37,19 @@ public interface HttpClient {
     ResultData<Map<String, Object>> post(@Var("url") String url, @Header Map<String, Object> headerMap, @JSONBody Object param, OnSuccess<ResultData> onSuccess, OnError onError);
 
     @Post(
-            url="{url}", timeout = 5 * 1000//
+            url="{url}", timeout = 5 * 60 * 1000//
 //            ,
 //            interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
     )
     @Retry(maxRetryCount = "3", maxRetryInterval = "100")
     ResultData post2(@Var("url") String url, @JSONBody Object param, OnSuccess<ResultData> onSuccess, OnError onError);
 
+    @Post(
+            url="{url}", timeout = 5 * 60 * 1000//
+//            ,
+//            interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
+    )
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    Result<LaserDownloadBean> downOfflineScene(@Var("url") String url, @JSONBody Object param, OnSuccess<ResultData> onSuccess, OnError onError);
+
 }

+ 2 - 0
src/main/java/com/fdkankan/external/service/impl/SceneEditInfoServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fdkankan.external.service.impl;
 
+import com.mybatisflex.annotation.UseDataSource;
 import com.mybatisflex.spring.service.impl.ServiceImpl;
 import com.fdkankan.external.entity.SceneEditInfo;
 import com.fdkankan.external.mapper.SceneEditInfoMapper;
@@ -12,6 +13,7 @@ import org.springframework.stereotype.Service;
  * @author dsx
  * @since 2023-12-12
  */
+@UseDataSource("www")
 @Service
 public class SceneEditInfoServiceImpl extends ServiceImpl<SceneEditInfoMapper, SceneEditInfo> implements ISceneEditInfoService {
 

+ 174 - 53
src/main/java/com/fdkankan/external/service/impl/SceneOfflinePackagePushServiceImpl.java

@@ -4,14 +4,22 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.date.TimeInterval;
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.thread.ExecutorBuilder;
+import cn.hutool.core.util.RuntimeUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.ZipUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.common.constant.CommonStatus;
 import com.fdkankan.common.constant.CommonSuccessStatus;
+import com.fdkankan.common.constant.FileSizeUnitType;
 import com.fdkankan.common.constant.SceneSource;
 import com.fdkankan.common.util.DateExtUtil;
+import com.fdkankan.common.util.FileSizeUtil;
 import com.fdkankan.external.bean.DownloadProcessBean;
+import com.fdkankan.external.bean.LaserDownloadBean;
 import com.fdkankan.external.callback.ErrorCallback;
 import com.fdkankan.external.callback.SuccessCallback;
 import com.fdkankan.external.entity.*;
@@ -20,6 +28,7 @@ import com.fdkankan.external.mapper.SceneOfflinePackagePushMapper;
 import com.fdkankan.external.service.*;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.web.response.Result;
 import com.fdkankan.web.response.ResultData;
 import com.mybatisflex.core.query.QueryWrapper;
 import com.mybatisflex.spring.service.impl.ServiceImpl;
@@ -30,10 +39,9 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.io.File;
+import java.nio.charset.Charset;
+import java.util.*;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.stream.Collectors;
 
@@ -50,9 +58,26 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
     @Value("${host.4dkk.scene}")
     private String fdkkSceneHost;
 
+    @Value("${host.laser}")
+    private String laserHost;
+
+    @Value("${oss.host.laser.old}")
+    private String ossHostLaserOld;
+    @Value("${oss.host.laser.new}")
+    private String ossHostLaserNew;
+    @Value("${oss.host.4dkk.old}")
+    private String ossHost4dkkOld;
+    @Value("${oss.host.4dkk.new}")
+    private String ossHost4dkkNew;
+
     @Value("${api.4dkk.scene.getInfo}")
     private String getInfoUrl;
 
+    @Value("${api.laser.downOfflineScene}")
+    private String downOfflineSceneUrl;
+    @Value("${file.offlineZip.dir}")
+    private String offlineZipDir;
+
     private final static ThreadPoolExecutor threadPoolExecutor = ExecutorBuilder.create().setCorePoolSize(1).setMaxPoolSize(3).build();
 
     @Autowired
@@ -130,7 +155,7 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
                     }
                     //如果没有推送过或者推送过但是版本号不一致,就需要推送
                     if(Objects.isNull(lastPush) || lastPush.getVersion() != scene.getOfflineVerForPush()){
-                        threadPoolExecutor.submit(()->{
+//                        threadPoolExecutor.submit(()->{
                             SceneOfflinePackagePush push = BeanUtil.copyProperties(commonPush, SceneOfflinePackagePush.class);
                             push.setZipType("laser");
                             push.setVersion(scene.getOfflineVerForPush());
@@ -139,7 +164,7 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
                             }catch (Exception e){
                                 log.error("场景推送失败,num:{}",scenePlus.getNum(), e);
                             }
-                        });
+//                        });
                     }
                     scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
                     isObj = scenePlusExt.getIsObj();
@@ -160,7 +185,7 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
 
                     //如果没有推送过或者推送过但是版本号不一致,就需要推送
                     if(Objects.isNull(lastPush) || lastPush.getVersion() != version){
-                        threadPoolExecutor.submit(()->{
+//                        threadPoolExecutor.submit(()->{
                             SceneOfflinePackagePush push = BeanUtil.copyProperties(commonPush, SceneOfflinePackagePush.class);
                             push.setZipType("kankan");
                             push.setVersion(version);
@@ -169,7 +194,7 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
                             }catch (Exception e){
                                 log.error("场景推送失败,num:{}",scenePlus.getNum(), e);
                             }
-                        });
+//                        });
                     }
                 }
             }catch (Exception e){
@@ -178,6 +203,88 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
         }
     }
 
+    private String genZipUrl4Kankan(String num){
+        String downloadUrl = null;
+        String downloadTaskKey = RedisKey.SCENE_DOWNLOADS_TASK_V4;
+        String progressKey = String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4, num);
+        TimeInterval timer = DateUtil.timer();
+        Map<String,String> playod = new HashMap<>(2);
+        playod.put("type","local");
+        playod.put("num",num);
+        redisUtil.lRightPush(downloadTaskKey, JSONObject.toJSONString(playod));
+        boolean exit = false;
+        String progress = null;
+        DownloadProcessBean downloadProcessBean = null;
+        do {
+            progress = redisUtil.get(progressKey);
+            if(StringUtils.isEmpty(progress)){
+                downloadProcessBean = new DownloadProcessBean();
+            }else{
+                downloadProcessBean = JSONObject.parseObject(progress, DownloadProcessBean.class);
+            }
+            Integer status = downloadProcessBean.getStatus();
+            if (Objects.nonNull(status) && status == 1002) {
+                downloadUrl = downloadProcessBean.getUrl();
+                exit = true;
+            }
+            if (Objects.nonNull(status) && status == 1003) {
+                log.error("下载失败,num:{}", num);
+                throw new RuntimeException("下载失败,num:" + num);
+            }
+            if (timer.intervalMinute() > 8 * 60) {
+                log.error("下载超时,num:{}", num);
+                throw new RuntimeException("下载超时,num:" + num);
+            }
+            try {
+                Thread.sleep(5000L);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        } while (!exit);
+
+        return downloadUrl.replace(ossHost4dkkOld, ossHost4dkkNew);
+    }
+
+    private String genZipUrl4Laser(String num){
+        String downloadUrl = null;
+        TimeInterval timer = DateUtil.timer();
+
+        boolean exit = false;
+
+        //请求激光系统开始下载
+        Map<String, Object> params = new HashMap<>();
+        params.put("sceneCode", num);
+        Result<LaserDownloadBean> resultData = httpClient.downOfflineScene(laserHost.concat(downOfflineSceneUrl), params, new SuccessCallback(), new ErrorCallback());
+        LaserDownloadBean laserRes = resultData.getData();
+        if(laserRes.getStatus() == 2){
+            return laserRes.getUrl().replace(ossHostLaserOld, ossHostLaserNew);
+        }
+        do {
+            resultData = httpClient.downOfflineScene(laserHost.concat(downOfflineSceneUrl), params, new SuccessCallback(), new ErrorCallback());
+            laserRes = resultData.getData();
+            Integer status = laserRes.getStatus();
+            if (Objects.nonNull(status) && status == 2) {
+                downloadUrl = laserRes.getUrl();
+                exit = true;
+            }
+            if (Objects.nonNull(status) && status == -1) {
+                log.error("下载失败,num:{}", num);
+                throw new RuntimeException("下载失败,num:" + num);
+            }
+            if (timer.intervalMinute() > 8 * 60) {
+                log.error("下载超时,num:{}", num);
+                throw new RuntimeException("下载超时,num:" + num);
+            }
+            try {
+                Thread.sleep(5000L);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        } while (!exit);
+
+        return downloadUrl.replace(ossHostLaserOld, ossHostLaserNew);
+    }
+
     @Override
     public SceneOfflinePackagePush getLastByCondition(SceneOfflinePackagePush condition) {
 
@@ -200,59 +307,58 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
     public void scenePushHandler(SceneOfflinePackagePush push){
         String num = push.getNum();
         String zipType = push.getZipType();
+        int version = push.getVersion();
         String downloadUrl = null;
 
-        String downloadTaskKey = RedisKey.SCENE_DOWNLOADS_TASK_V4;
-        String progressKey = String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4, num);
 
         try {
-            TimeInterval timer = DateUtil.timer();
-            Map<String,String> playod = new HashMap<>(2);
-            playod.put("type","local");
-            playod.put("sceneNum",num);
-            redisUtil.lRightPush(downloadTaskKey, JSONObject.toJSONString(playod));
-            boolean exit = false;
-            String progress = null;
-            DownloadProcessBean downloadProcessBean = null;
-            do {
-                progress = redisUtil.get(progressKey);
-                if(StringUtils.isEmpty(progress)){
-                    downloadProcessBean = new DownloadProcessBean();
+            if("laser".equals(zipType)){
+                downloadUrl = this.genZipUrl4Laser(num);
+            }else{
+                downloadUrl = this.genZipUrl4Kankan(num);
+            }
+
+            //开始推送到第三方服务
+            if(StrUtil.isEmpty(downloadUrl)){
+                throw new RuntimeException("场景下载失败,下载链接为空,场景码:" + num);
+            }
+
+            //下载到本地
+            String zipPath = offlineZipDir.concat(num).concat(".zip");
+            HttpUtil.downloadFile(downloadUrl, zipPath);
+
+            long size = FileUtil.size(new File(zipPath));
+            Integer mbSize = FileSizeUtil.convert(size, FileSizeUnitType.MB.code());
+            String dirPath = null;
+            if(mbSize > 500){
+                String unzipPath = offlineZipDir.concat(num).concat("-").concat(zipType).concat("-").concat(String.valueOf(version));
+                ZipUtil.unzip(zipPath, unzipPath, Charset.forName("GBK"));
+                if("laser".equals(zipType)){
+                    dirPath = unzipPath.concat("/www");
                 }else{
-                    downloadProcessBean = JSONObject.parseObject(progress, DownloadProcessBean.class);
-                }
-                Integer status = downloadProcessBean.getStatus();
-                if (Objects.nonNull(status) && status == 1002) {
-                    downloadUrl = downloadProcessBean.getUrl();
-                    exit = true;
-                }
-                if (Objects.nonNull(status) && status == 1003) {
-                    exit = true;
-                    log.error("下载失败,num:{}", num);
-                    throw new RuntimeException("下载失败,num:" + num);
+                    dirPath = unzipPath.concat("/wwwroot/scene_view_data");
                 }
-                if (timer.intervalMinute() > 8 * 60) {
-                    exit = true;
-                    log.error("下载超时,num:{}", num);
-                    throw new RuntimeException("下载超时,num:" + num);
-                }
-            } while (!exit);
+                String cmd = "cd " + dirPath + " && zip -r zip/" + num + ".zip " + num + " -s 100M";
+                RuntimeUtil.exec(cmd);
+                log.info("压缩命令:{}", cmd);
 
-            //开始推送到第三方服务
-            if(StrUtil.isNotEmpty(downloadUrl)){
-                ScenePlus scenePlus = scenePlusService.getByNum(num);
-                ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
-                Map<String, Object> params = new HashMap<>();
-                params.put("num", num);
-                params.put("title", scenePlus.getTitle());
-                params.put("zipType", zipType);
-                params.put("downloadUrl", downloadUrl);
-                params.put("version", push.getVersion());
-                params.put("calcTime", DateExtUtil.format(scenePlusExt.getAlgorithmTime(), DateExtUtil.dateStyle8));
-                httpClient.post2(push.getDestUrl(), params, new SuccessCallback(), new ErrorCallback());
             }
-            push.setPushStatus(CommonSuccessStatus.SUCCESS.code());
-            push.setZipPath(downloadUrl);
+
+//            ScenePlus scenePlus = scenePlusService.getByNum(num);
+//            ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
+//            Map<String, Object> params = new HashMap<>();
+//            params.put("num", num);
+//            params.put("title", scenePlus.getTitle());
+//            params.put("zipType", zipType);
+//            params.put("downloadUrl", downloadUrl);
+//            params.put("version", push.getVersion());
+//            params.put("calcTime", DateExtUtil.format(scenePlusExt.getAlgorithmTime(), DateExtUtil.dateStyle8));
+//            params.put("file", FileUtil.file(zipPath));
+//            String post = HttpUtil.post(push.getDestUrl(), params, 60 * 60 * 1000);
+//            log.info("场景推送成功,接收端返回结果:{}", post);
+////            httpClient.post2(push.getDestUrl(), params, new SuccessCallback(), new ErrorCallback());
+//            push.setPushStatus(CommonSuccessStatus.SUCCESS.code());
+//            push.setZipPath(downloadUrl);
         }catch (Exception e){
             log.error("场景推送失败,num:{}", num, e);
             push.setPushStatus(CommonSuccessStatus.FAIL.code());
@@ -260,4 +366,19 @@ public class SceneOfflinePackagePushServiceImpl extends ServiceImpl<SceneOffline
 
         this.saveOrUpdate(push);
     }
+
+    public static void main(String[] args) throws Exception {
+
+
+
+//        Map<String, Object> params = new HashMap<>();
+//        params.put("num", "KJ-t-WypZvHxCR4X");
+//        params.put("title", "123");
+//        params.put("zipType", "kankan");
+//        params.put("version", 1);
+//        params.put("calcTime", DateExtUtil.format(new Date(), DateExtUtil.dateStyle8));
+//        params.put("file", FileUtil.file("D:\\mnt\\external\\temp\\KJ-t-WypZvHxCR4X.zip"));
+//        final String post = HttpUtil.post("http://localhost:8080/scene/receive2", params, 60 * 60 * 1000);
+//        System.out.println(post);
+    }
 }

+ 2 - 0
src/main/java/com/fdkankan/external/service/impl/SceneServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fdkankan.external.service.impl;
 
+import com.mybatisflex.annotation.UseDataSource;
 import com.mybatisflex.core.query.QueryWrapper;
 import com.mybatisflex.spring.service.impl.ServiceImpl;
 import com.fdkankan.external.entity.Scene;
@@ -13,6 +14,7 @@ import org.springframework.stereotype.Service;
  * @author dsx
  * @since 2023-12-11
  */
+@UseDataSource("laser")
 @Service
 public class SceneServiceImpl extends ServiceImpl<SceneMapper, Scene> implements ISceneService {
 

+ 15 - 0
src/main/resources/application.yml

@@ -23,6 +23,7 @@ host:
   4dkk:
     manage: https://v4-uat.4dkankan.com
     scene: https://test.4dkankan.com
+  laser: https://uat-laser.4dkankan.com
 api:
   4dkk:
     manage:
@@ -32,6 +33,8 @@ api:
       downloadProcess: /service/manage/scene/downloadProcess?num=%s
     scene:
       getInfo: /service/scene/getInfo?num=%s
+  laser:
+    downOfflineScene: /laser/4dage/downOfflineScene
 
 forest:
   ## 日志总开关,打开/关闭Forest请求/响应日志(默认为 true)
@@ -64,6 +67,18 @@ mybatis-flex:
       url: jdbc:mysql://120.25.146.52:13306/fdkk_laser
       username: root
       password: JK123456%JIK
+oss:
+  host:
+    laser:
+      old: https://laser-oss.4dkankan.com
+      new: https://zgwwzzzx-laser-download.4dage.com
+    4dkk:
+      old: https://4dkk.4dage.com
+      new: https://zgwwzzzx-download.4dage.com
+
+file:
+  offlineZip:
+    dir: /mnt/external/temp/