Quellcode durchsuchen

中国铁塔项目场景批量迁移接口

dsx vor 1 Jahr
Ursprung
Commit
d9339d0feb

+ 7 - 0
pom.xml

@@ -121,6 +121,13 @@
       <version>4.5.8</version>
     </dependency>
 
+    <!--        htt请求工具-->
+    <dependency>
+      <groupId>com.dtflys.forest</groupId>
+      <artifactId>forest-spring-boot-starter</artifactId>
+      <version>1.5.19</version>
+    </dependency>
+
 
   </dependencies>
 

+ 39 - 0
src/main/java/com/fdkankan/extend/callback/ErrorCallback.java

@@ -0,0 +1,39 @@
+package com.fdkankan.extend.callback;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.dtflys.forest.callback.OnError;
+import com.dtflys.forest.exceptions.ForestRuntimeException;
+import com.dtflys.forest.http.ForestRequest;
+import com.dtflys.forest.http.ForestResponse;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.web.response.ResultData;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/25
+ **/
+@Slf4j
+public class ErrorCallback implements OnError {
+
+    @Override
+    public void onError(ForestRuntimeException e, ForestRequest forestRequest,
+        ForestResponse forestResponse) {
+        JSONObject jsonObject = JSON.parseObject(forestResponse.getContent());
+        Integer status = jsonObject.getInteger("status");
+        if(status != null && status == 500){
+            log.error("接口报错,url:{},status:{},error:{}", forestRequest.getUrl(), status, jsonObject.getString("error"));
+            throw e;
+        }
+        ResultData result = JSON.parseObject(forestResponse.getContent(), ResultData.class);
+        if(result.getCode() != 0){
+            throw new BusinessException(result.getCode(), result.getMessage());
+        }
+        throw new BusinessException(-1, "未知异常");
+    }
+}

+ 25 - 0
src/main/java/com/fdkankan/extend/callback/SuccessCallback.java

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

+ 49 - 0
src/main/java/com/fdkankan/extend/callback/SuccessCondition.java

@@ -0,0 +1,49 @@
+package com.fdkankan.extend.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.web.response.ResultData;
+
+/**
+ * <p>
+ *  自定义成功/失败条件实现类
+ *  需要实现 SuccessWhen 接口
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/25
+ **/
+
+public class SuccessCondition 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;
+        }
+        ResultData result = JSON.parseObject(content, ResultData.class);
+        if(result.getCode() != 0){
+            reqStatus = false;
+            return reqStatus;
+        }
+        return true;
+    }
+}

+ 5 - 0
src/main/java/com/fdkankan/extend/controller/TowerController.java

@@ -163,6 +163,11 @@ public class TowerController {
 
     }
 
+    @PostMapping("/sceneBatchMove")
+    public ResultData sceneBatchMove(@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "origSnCode") String origSnCode, @RequestParam(value = "snCode") String snCode) throws IOException {
+        return towerService.sceneBatchMove(file, origSnCode, snCode);
+    }
+
 
 
 }

+ 52 - 0
src/main/java/com/fdkankan/extend/httpclient/HttpClient.java

@@ -0,0 +1,52 @@
+package com.fdkankan.extend.httpclient;
+
+import com.dtflys.forest.annotation.*;
+import com.dtflys.forest.callback.OnError;
+import com.dtflys.forest.callback.OnSuccess;
+import com.fdkankan.extend.callback.SuccessCondition;
+import com.fdkankan.web.response.ResultData;
+import com.yomahub.tlog.forest.TLogForestInterceptor;
+
+import java.util.Map;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/24
+ **/
+//@Success(condition = SuccessCondition.class)
+public interface HttpClient {
+
+    @Get(
+        url="{url}",
+        interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
+    )
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    ResultData<Map<String, Object>> get(@Var("url") String url, @Header Map<String, Object> headerMap, OnSuccess<ResultData> onSuccess, OnError onError);
+
+    @Post(
+            url="{url}",
+            interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
+    )
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    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}",
+            interceptor = TLogForestInterceptor.class
+    )   //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
+
+    ResultData post(@Var("url") String url, @Header Map<String, Object> headerMap, @JSONBody Object param);
+
+    @Post(
+            url="{url}"
+//            ,
+//            interceptor = TLogForestInterceptor.class    //加这个拦截器,打印的tlog日志会详细一些,包括头信息等等
+    )
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    ResultData post2(@Var("url") String url, @JSONBody Object param, OnSuccess<ResultData> onSuccess, OnError onError);
+
+}

+ 77 - 77
src/main/java/com/fdkankan/extend/listener/RabbitMqListener.java

@@ -1,77 +1,77 @@
-package com.fdkankan.extend.listener;
-
-import cn.hutool.core.exceptions.ExceptionUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.fdkankan.common.constant.CommonSuccessStatus;
-import com.fdkankan.extend.service.ITowerService;
-import com.fdkankan.redis.util.RedisUtil;
-import com.rabbitmq.client.Channel;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.amqp.core.Message;
-import org.springframework.amqp.rabbit.annotation.Queue;
-import org.springframework.amqp.rabbit.annotation.RabbitListener;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * <p>
- * TODO
- * </p>
- *
- * @author dengsixing
- * @since 2022/4/19
- **/
-@Slf4j
-@Component
-public class RabbitMqListener {
-
-    @Value("${queue.modeling.extend.tower.data-push}")
-    private String queueName;
-    @Autowired
-    private ITowerService towerService;
-    @Autowired
-    private RedisUtil redisUtil;
-
-    /**
-     * 铁塔项目数据推送监听器
-     * @param channel
-     * @param message
-     * @throws Exception
-     */
-    @RabbitListener(
-        queuesToDeclare = @Queue("${queue.modeling.extend.tower.data-push}")
-    )
-    public void towerSceneDataPush(Channel channel, Message message) throws Exception {
-        String key = "tower:scene:data:download";
-        String messageId = message.getMessageProperties().getMessageId();
-        String content = new String(message.getBody(), StandardCharsets.UTF_8);
-        JSONObject jsonObject = JSON.parseObject(content);
-        String num = jsonObject.getString("num");
-        String title = jsonObject.getString("title");
-        log.info("开始消费消息,id:{},queue:{},content:{}", messageId, queueName, content);
-        Map<String, Object> map = new HashMap<>();
-        map.put("title", title);
-        try {
-            String zipPath = towerService.packSceneDataHandler(num, title);
-            map.put("status", CommonSuccessStatus.SUCCESS.code());
-            map.put("zipPath", zipPath);
-            redisUtil.hset(key, num, JSON.toJSONString(map));
-        }catch (Exception e){
-            map.put("status", CommonSuccessStatus.FAIL.code());
-            map.put("error", ExceptionUtil.stacktraceToString(e, 3000));
-            redisUtil.hset(key, num, JSON.toJSONString(map));
-        }
-
-        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-        log.info("结束消费消息,id:{}", messageId);
-    }
-
-
-
-}
+//package com.fdkankan.extend.listener;
+//
+//import cn.hutool.core.exceptions.ExceptionUtil;
+//import com.alibaba.fastjson.JSON;
+//import com.alibaba.fastjson.JSONObject;
+//import com.fdkankan.common.constant.CommonSuccessStatus;
+//import com.fdkankan.extend.service.ITowerService;
+//import com.fdkankan.redis.util.RedisUtil;
+//import com.rabbitmq.client.Channel;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.amqp.core.Message;
+//import org.springframework.amqp.rabbit.annotation.Queue;
+//import org.springframework.amqp.rabbit.annotation.RabbitListener;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Component;
+//
+//import java.nio.charset.StandardCharsets;
+//import java.util.HashMap;
+//import java.util.Map;
+//
+///**
+// * <p>
+// * TODO
+// * </p>
+// *
+// * @author dengsixing
+// * @since 2022/4/19
+// **/
+//@Slf4j
+//@Component
+//public class RabbitMqListener {
+//
+//    @Value("${queue.modeling.extend.tower.data-push}")
+//    private String queueName;
+//    @Autowired
+//    private ITowerService towerService;
+//    @Autowired
+//    private RedisUtil redisUtil;
+//
+//    /**
+//     * 铁塔项目数据推送监听器
+//     * @param channel
+//     * @param message
+//     * @throws Exception
+//     */
+//    @RabbitListener(
+//        queuesToDeclare = @Queue("${queue.modeling.extend.tower.data-push}")
+//    )
+//    public void towerSceneDataPush(Channel channel, Message message) throws Exception {
+//        String key = "tower:scene:data:download";
+//        String messageId = message.getMessageProperties().getMessageId();
+//        String content = new String(message.getBody(), StandardCharsets.UTF_8);
+//        JSONObject jsonObject = JSON.parseObject(content);
+//        String num = jsonObject.getString("num");
+//        String title = jsonObject.getString("title");
+//        log.info("开始消费消息,id:{},queue:{},content:{}", messageId, queueName, content);
+//        Map<String, Object> map = new HashMap<>();
+//        map.put("title", title);
+//        try {
+//            String zipPath = towerService.packSceneDataHandler(num, title);
+//            map.put("status", CommonSuccessStatus.SUCCESS.code());
+//            map.put("zipPath", zipPath);
+//            redisUtil.hset(key, num, JSON.toJSONString(map));
+//        }catch (Exception e){
+//            map.put("status", CommonSuccessStatus.FAIL.code());
+//            map.put("error", ExceptionUtil.stacktraceToString(e, 3000));
+//            redisUtil.hset(key, num, JSON.toJSONString(map));
+//        }
+//
+//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+//        log.info("结束消费消息,id:{}", messageId);
+//    }
+//
+//
+//
+//}

+ 2 - 0
src/main/java/com/fdkankan/extend/service/IScenePlusService.java

@@ -18,5 +18,7 @@ public interface IScenePlusService extends IService<ScenePlus> {
 
     List<ScenePlus> getByCameraIds(Set<Long> cameraIds);
 
+    ScenePlus getByCameraIdAndNum(String num, Long cameraId);
+
 
 }

+ 7 - 0
src/main/java/com/fdkankan/extend/service/ISsoService.java

@@ -0,0 +1,7 @@
+package com.fdkankan.extend.service;
+
+public interface ISsoService {
+
+    public String login(String userName, String password);
+
+}

+ 5 - 2
src/main/java/com/fdkankan/extend/service/ITowerService.java

@@ -1,6 +1,7 @@
 package com.fdkankan.extend.service;
 
 import com.fdkankan.web.response.ResultData;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.crypto.BadPaddingException;
 import javax.crypto.IllegalBlockSizeException;
@@ -13,11 +14,13 @@ import java.util.List;
 
 public interface ITowerService {
 
-    public String packSceneDataHandler(String num, String title) throws Exception;
+    public String packSceneDataHandler(String num, String title, String logId) throws Exception;
 
     public void packSceneData(Long companyId, List<String> nums);
 
-    public void dataPush(String num, String title, String sceneId, String roomId, String zipPath) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException, Exception;
+    public void dataPush(String num, String title, String sceneId, String roomId, String zipPath, String logId) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException, Exception;
+
+    public ResultData sceneBatchMove(MultipartFile file, String origSnCode, String snCode) throws IOException;
 
 
 }

+ 5 - 0
src/main/java/com/fdkankan/extend/service/impl/ScenePlusServiceImpl.java

@@ -28,4 +28,9 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     public List<ScenePlus> getByCameraIds(Set<Long> cameraIds) {
         return this.list(new LambdaQueryWrapper<ScenePlus>().in(ScenePlus::getCameraId, cameraIds));
     }
+
+    @Override
+    public ScenePlus getByCameraIdAndNum(String num, Long cameraId) {
+       return this.getOne(new LambdaQueryWrapper<ScenePlus>().eq(ScenePlus::getCameraId, cameraId).eq(ScenePlus::getNum, num));
+    }
 }

+ 43 - 0
src/main/java/com/fdkankan/extend/service/impl/SsoServiceImpl.java

@@ -0,0 +1,43 @@
+package com.fdkankan.extend.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.Base64Converter;
+import com.fdkankan.common.util.PasswordUtils;
+import com.fdkankan.extend.callback.ErrorCallback;
+import com.fdkankan.extend.callback.SuccessCallback;
+import com.fdkankan.extend.httpclient.HttpClient;
+import com.fdkankan.extend.service.ISsoService;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+public class SsoServiceImpl implements ISsoService {
+
+    @Value("${host:https://www.4dkankan.com}")
+    private String host;
+    @Value("${api.login:/service/manage/login}")
+    private String loginUrl;
+    @Resource
+    private HttpClient httpClient;
+
+    @Override
+    public String login(String userName, String psw) {
+        String password = PasswordUtils.decycptPasswordWeb(Base64Converter.encode(psw));
+        Map<String, String> loginParams = new HashMap<>();
+        loginParams.put("userName", userName);
+        loginParams.put("password", password);
+        ResultData<Map<String, Object>> loginResult = httpClient.post(this.host.concat(loginUrl), new HashMap<>(), loginParams, new SuccessCallback(), new ErrorCallback());
+        String token = (String) loginResult.getData().get("token");
+        if (StrUtil.isEmpty(token)) {
+            throw new BusinessException(-1, "登录失败");
+        }
+        return token;
+    }
+}

+ 152 - 43
src/main/java/com/fdkankan/extend/service/impl/TowerServiceImpl.java

@@ -1,37 +1,48 @@
 package com.fdkankan.extend.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.exceptions.ExceptionUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.ZipUtil;
+import cn.hutool.http.HttpStatus;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fdkankan.common.constant.CommonSuccessStatus;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.ServerCode;
+import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.util.DateExtUtil;
 import com.fdkankan.extend.TowerSceneBean;
+import com.fdkankan.extend.callback.ErrorCallback;
+import com.fdkankan.extend.callback.SuccessCallback;
 import com.fdkankan.extend.entity.Camera;
 import com.fdkankan.extend.entity.CameraDetail;
 import com.fdkankan.extend.entity.ScenePlus;
-import com.fdkankan.extend.service.ICameraDetailService;
-import com.fdkankan.extend.service.ICameraService;
-import com.fdkankan.extend.service.IScenePlusService;
-import com.fdkankan.extend.service.ITowerService;
+import com.fdkankan.extend.httpclient.HttpClient;
+import com.fdkankan.extend.service.*;
 import com.fdkankan.extend.util.RsaCryptTools;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.model.utils.SceneUtil;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.web.response.ResultData;
 import lombok.extern.slf4j.Slf4j;
 import netscape.javascript.JSObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -59,6 +70,9 @@ public class TowerServiceImpl implements ITowerService {
     @Value("${tower.url}")
     private String url;
 
+    @Value("fyun.bucket")
+    private String bucket;
+
     @Autowired
     private FYunFileServiceInterface fYunFileService;
     @Autowired
@@ -72,8 +86,14 @@ public class TowerServiceImpl implements ITowerService {
     @Autowired
     private ICameraService cameraService;
 
+    @Autowired
+    private ISsoService ssoService;
+
+    @Resource
+    private HttpClient httpClient;
+
     @Override
-    public String packSceneDataHandler(String num, String title) throws Exception {
+    public String packSceneDataHandler(String num, String title, String logId) throws Exception {
 
         //校验场景名称是否正确
         String sceneStr = fYunFileService.getFileContent(ossScenePoolFilePath);
@@ -129,6 +149,28 @@ public class TowerServiceImpl implements ITowerService {
         //下载vision.txt
         fYunFileService.downloadFile(ossImagesPath.concat("vision.txt"), imagesPath.concat("vision.txt"));
 
+        //下载caches/images
+        List<String> panoramaImageList = SceneUtil.getPanoramaImageList(imagesPath.concat("vision.txt"));
+        log.info(JSON.toJSONString(panoramaImageList));
+        List<String> imageList = fYunFileService.listRemoteFiles(String.format(UploadFilePath.scene_result_data_path, num).concat("caches/images/"));
+        if(CollUtil.isNotEmpty(imageList)){
+            imageList.stream().forEach(key->{
+                if(panoramaImageList.contains(key.substring(key.lastIndexOf("/") + 1))){
+                    if(!FileUtil.exist(imagesPath.concat("8K"))){
+                        FileUtil.mkdir(imagesPath.concat("8K"));
+                    }
+                    fYunFileService.downloadFile(key, imagesPath.concat("8K"));
+                }
+            });
+//            //移除非必须文件
+//            List<String> fileNames = FileUtil.listFileNames(imagesPath.concat("8K/"));
+//            fileNames.stream().forEach(name->{
+//                if(!panoramaImageList.contains(name)){
+//                    FileUtil.del(imagesPath.concat("8K/") + name);
+//                }
+//            });
+        }
+
         this.convertVisable(imagesPath.concat("vision.txt"));
 
         //打包
@@ -137,7 +179,7 @@ public class TowerServiceImpl implements ITowerService {
         log.info("结束下载,开始推送:{}", num);
 
         try {
-            this.dataPush(num, title, towerSceneBean.getSceneId(), towerSceneBean.getRoomId(), zipPath);
+            this.dataPush(num, title, towerSceneBean.getSceneId(), towerSceneBean.getRoomId(), zipPath, logId);
         }finally {
             FileUtil.del(scenePath);
         }
@@ -145,6 +187,7 @@ public class TowerServiceImpl implements ITowerService {
         return zipPath;
     }
 
+
     private void convertVisable(String visionPath){
 
         String visionStr = FileUtil.readUtf8String(visionPath);
@@ -175,7 +218,6 @@ public class TowerServiceImpl implements ITowerService {
         int size = visibles.size();
         String[] visibleArr = new String[size];
         for(int j = 0; j < size; j++){
-            System.out.println(visibles.get(j));
             int index = (Integer)visibles.get(j);
             String uuid = uuidMap.get(index);
             visibleArr[j] = uuid;
@@ -204,12 +246,10 @@ public class TowerServiceImpl implements ITowerService {
         }else{
             String snCodeStr = fYunFileService.getFileContent(ossCameraPoolFilePath);
             List<String> snCodeList = Arrays.asList(snCodeStr.split(","));
-            List<Camera> cameraList = cameraService.listBySnCodes(snCodeList);
-            List<Long> cameraIdList = cameraList.stream().map(Camera::getId).collect(Collectors.toList());
             String sceneStr = fYunFileService.getFileContent(ossScenePoolFilePath);
             List<TowerSceneBean> towerSceneBeans = JSON.parseArray(sceneStr, TowerSceneBean.class);
             List<String> titleList = towerSceneBeans.stream().map(TowerSceneBean::getName).collect(Collectors.toList());
-            scenePlusList = scenePlusService.list(new LambdaQueryWrapper<ScenePlus>().in(ScenePlus::getCameraId, cameraIdList).in(ScenePlus::getTitle, titleList));
+            scenePlusList = scenePlusService.list(new LambdaQueryWrapper<ScenePlus>().in(ScenePlus::getTitle, titleList));
             List<String> dbTitleList = scenePlusList.stream().map(ScenePlus::getTitle).collect(Collectors.toList());
             List<String> notFindList = titleList.stream().filter(title -> {
                 if (dbTitleList.contains(title)) {
@@ -230,6 +270,8 @@ public class TowerServiceImpl implements ITowerService {
             return;
         }
 
+        String id = DateExtUtil.format(Calendar.getInstance().getTime(), "yyyyMMddHHmmss");
+
         //遍历场景列表开始下载
         scenePlusList.stream().forEach(plus -> {
             JSONObject jsonObject = new JSONObject();
@@ -237,7 +279,7 @@ public class TowerServiceImpl implements ITowerService {
                 jsonObject = new JSONObject();
                 jsonObject.put("title", plus.getTitle());
                 jsonObject.put("num", plus.getNum());
-                String zipPath = towerService.packSceneDataHandler(plus.getNum(), plus.getTitle());
+                String zipPath = towerService.packSceneDataHandler(plus.getNum(), plus.getTitle(), id);
                 jsonObject.put("status", CommonSuccessStatus.SUCCESS.code());
                 jsonObject.put("zipPath", zipPath);
                 redisUtil.hset(key, plus.getNum(), JSON.toJSONString(jsonObject));
@@ -251,7 +293,7 @@ public class TowerServiceImpl implements ITowerService {
     }
 
     @Override
-    public void dataPush(String num, String title, String sceneId, String roomId, String zipPath) throws Exception {
+    public void dataPush(String num, String title, String sceneId, String roomId, String zipPath, String logId) throws Exception {
 
         log.info("开始组装参数");
 
@@ -271,10 +313,15 @@ public class TowerServiceImpl implements ITowerService {
         log.info("compose:{}", compose);
         log.info("encrypt:{}", encrypt);
         log.info("开始推送");
-        String post = HttpUtil.post(url, params);
-        JSONObject jsonObject = JSON.parseObject(post);
+        try {
+            String post = HttpUtil.post(url, params);
+            JSONObject jsonObject = JSON.parseObject(post);
+            this.dataPushLog(num, title, jsonObject.getString("resultCode"), jsonObject.getString("resultMsg"), logId);
+        }catch (Exception e){
+            log.error("推送失败", e);
+            this.dataPushLog(num, title, String.valueOf(HttpStatus.HTTP_BAD_GATEWAY), "请求失败", logId);
+        }
 
-        this.dataPushLog(num, title, jsonObject.getString("resultCode"), jsonObject.getString("resultMsg"));
 
     }
 
@@ -295,40 +342,102 @@ public class TowerServiceImpl implements ITowerService {
 //        List<TowerSceneBean> towerSceneBeans = JSON.parseArray(sceneStr, TowerSceneBean.class);
 //        System.out.println(JSON.toJSONString(towerSceneBeans));
 
-        String visionStr = FileUtil.readUtf8String("C:\\Users\\dsx\\Desktop\\vision.txt");
-        JSONObject visionObj = JSON.parseObject(visionStr);
-        JSONArray array = visionObj.getJSONArray("sweepLocations");
-        Map<Integer, String> uuidMap = new HashMap<>();
-        for(int i = 0; i < array.size(); i++){
-            JSONObject o = (JSONObject)array.get(i);
-            uuidMap.put(i, o.getString("uuid"));
+//        String visionStr = FileUtil.readUtf8String("C:\\Users\\dsx\\Desktop\\vision.txt");
+//        JSONObject visionObj = JSON.parseObject(visionStr);
+//        JSONArray array = visionObj.getJSONArray("sweepLocations");
+//        Map<Integer, String> uuidMap = new HashMap<>();
+//        for(int i = 0; i < array.size(); i++){
+//            JSONObject o = (JSONObject)array.get(i);
+//            uuidMap.put(i, o.getString("uuid"));
+//        }
+//
+//        for(int i = 0; i < array.size(); i++){
+//            JSONObject o = (JSONObject)array.get(i);
+//            JSONArray visibles = o.getJSONArray("visibles");
+//            int size = visibles.size();
+//            String[] visibleArr = new String[size];
+//            for(int j = 0; j < size; j++){
+//                System.out.println(visibles.get(j));
+//                int index = (Integer)visibles.get(j);
+//                String uuid = uuidMap.get(index);
+//                visibleArr[j] = uuid;
+//            }
+//            o.put("visibles", visibleArr);
+//        }
+//
+//        FileUtil.writeUtf8String(JSON.toJSONString(visionObj), "C:\\Users\\dsx\\Desktop\\vision2.txt");
+
+        String test = "123123/sdfsdf.jpg";
+        System.out.println(test.substring(test.lastIndexOf("/")));
+
+
+    }
+
+    private void dataPushLog(String num, String title, String resultCode, String resultMsg, String logId){
+        Map<String, Object> log  = new HashMap<>();
+        log.put("num", num);
+        log.put("title", title);
+        log.put("resultCode", resultCode);
+        log.put("resultMsg", resultMsg);
+        String content = JSON.toJSONString(log).concat("\r\n");
+        FileUtil.appendUtf8String(content, parentPath.concat("download").concat("-").concat(logId).concat(".log"));
+    }
+
+    @Override
+    public ResultData sceneBatchMove(MultipartFile file, String origSnCode, String snCode) throws IOException {
+        if(file.isEmpty()){
+            throw new BusinessException(-1, "文件为空");
+        }
+        String origPath = "/home/backend/4dkankan_v4/modeling-extend/move/";
+        String move_url = "https://www.4dkankan.com/service/manage/scene/move";
+        String orgFileId = DateUtil.format(Calendar.getInstance().getTime(), DateExtUtil.dateStyle11);
+        String orgFilePath = origPath.concat(orgFileId).concat(".txt");
+        FileUtil.mkParentDirs(orgFilePath);
+        file.transferTo(new File(orgFilePath));
+
+        List<String> nums = FileUtil.readUtf8Lines(orgFilePath);
+        if(CollUtil.isEmpty(nums)){
+            throw new BusinessException(-1, "文件为空");
         }
 
-        for(int i = 0; i < array.size(); i++){
-            JSONObject o = (JSONObject)array.get(i);
-            JSONArray visibles = o.getJSONArray("visibles");
-            int size = visibles.size();
-            String[] visibleArr = new String[size];
-            for(int j = 0; j < size; j++){
-                System.out.println(visibles.get(j));
-                int index = (Integer)visibles.get(j);
-                String uuid = uuidMap.get(index);
-                visibleArr[j] = uuid;
-            }
-            o.put("visibles", visibleArr);
+        Camera camera = cameraService.findByChildName(origSnCode);
+        if(Objects.isNull(camera)){
+            throw new BusinessException(ErrorCode.CAMERA_BIND_NO_EXIST);
         }
 
-        FileUtil.writeUtf8String(JSON.toJSONString(visionObj), "C:\\Users\\dsx\\Desktop\\vision2.txt");
+        List<String> notExists = new ArrayList<>();
+        for (String num : nums) {
+            ScenePlus byCameraIdAndNum = scenePlusService.getByCameraIdAndNum(num, camera.getId());
+            if(Objects.isNull(byCameraIdAndNum)){
+                notExists.add(num);
+            }
+        }
+        if(CollUtil.isNotEmpty(notExists)){
+            throw new BusinessException(-1, "在原始相机下查询不到场景,请核查:".concat(JSON.toJSONString(notExists)));
+        }
 
-    }
+        //模拟登录
+        Map<String, Object> headers = new HashMap<>();
+        try {
+            String token = ssoService.login("zhongwentong", "4Dage168");
+            headers.put("token", token);
+        }catch (Exception e){
+            return ResultData.error(-1, "登录失败");
+        }
 
-    private void dataPushLog(String num, String title, String resultCode, String resultMsg){
-        String content = num.concat("-").concat(title).concat(" : ").concat(resultCode);
-        if(StrUtil.isNotEmpty(resultMsg)){
-            content = content.concat("-").concat(resultMsg);
+        List<Map<String, Object>> result = new ArrayList<>();
+        for (String num : nums) {
+            Map<String, Object> param = new HashMap<>();
+            param.put("num", num);
+            param.put("snCode", snCode);
+            ResultData<Map<String, Object>> resultData = httpClient.post(move_url, headers, param);
+
+            Map<String, Object> item = new HashMap<>();
+            item.put("num", num);
+            item.put("code", resultData.getCode());
+            item.put("message", resultData.getMessage());
+            result.add(item);
         }
-        content = content.concat("\r\n");
-        FileUtil.appendUtf8String(content, parentPath.concat("download.log"));
+        return ResultData.ok(result);
     }
-
 }