dsx 1 рік тому
батько
коміт
e0f4d96f16
27 змінених файлів з 1013 додано та 349 видалено
  1. 9 16
      pom.xml
  2. 0 2
      src/main/java/com/fdkankan/extend/ExtendApplication.java
  3. 27 0
      src/main/java/com/fdkankan/extend/aop/LimitType.java
  4. 35 0
      src/main/java/com/fdkankan/extend/aop/RedisLimit.java
  5. 109 0
      src/main/java/com/fdkankan/extend/aop/RedisLimitAspect.java
  6. 3 1
      src/main/java/com/fdkankan/extend/TowerSceneBean.java
  7. 23 109
      src/main/java/com/fdkankan/extend/controller/TowerController.java
  8. 177 0
      src/main/java/com/fdkankan/extend/entity/ScenePlusExt.java
  9. 91 64
      src/main/java/com/fdkankan/extend/listener/RabbitMqListener.java
  10. 18 0
      src/main/java/com/fdkankan/extend/mapper/IScenePlusExtMapper.java
  11. 2 0
      src/main/java/com/fdkankan/extend/service/ICameraService.java
  12. 22 0
      src/main/java/com/fdkankan/extend/service/IScenePlusExtService.java
  13. 5 0
      src/main/java/com/fdkankan/extend/service/IScenePlusService.java
  14. 6 1
      src/main/java/com/fdkankan/extend/service/ITowerService.java
  15. 5 0
      src/main/java/com/fdkankan/extend/service/impl/CameraServiceImpl.java
  16. 33 0
      src/main/java/com/fdkankan/extend/service/impl/ScenePlusExtServiceImpl.java
  17. 70 2
      src/main/java/com/fdkankan/extend/service/impl/ScenePlusServiceImpl.java
  18. 137 67
      src/main/java/com/fdkankan/extend/service/impl/TowerServiceImpl.java
  19. 0 3
      src/main/java/com/fdkankan/extend/util/RsaCryptTools.java
  20. 22 0
      src/main/java/com/fdkankan/extend/vo/SceneVo.java
  21. 96 0
      src/main/resources/application-prod.yml
  22. 96 0
      src/main/resources/application-test.yml
  23. 0 40
      src/main/resources/bootstrap-prod.yml
  24. 0 40
      src/main/resources/bootstrap-test.yml
  25. 0 3
      src/main/resources/bootstrap.yml
  26. 2 1
      src/main/resources/logback-spring.xml
  27. 25 0
      src/main/resources/redisScript/limit.lua

+ 9 - 16
pom.xml

@@ -60,24 +60,17 @@
           <groupId>com.aliyun</groupId>
           <artifactId>aliyun-java-sdk-core</artifactId>
         </exclusion>
+        <exclusion>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </exclusion>
+        <exclusion>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </exclusion>
       </exclusions>
     </dependency>
 
-    <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
-    <dependency>
-      <groupId>com.alibaba.cloud</groupId>
-      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
-      <version>2.2.7.RELEASE</version>
-    </dependency>
-
-
-    <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-config -->
-    <dependency>
-      <groupId>com.alibaba.cloud</groupId>
-      <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-      <version>2.2.7.RELEASE</version>
-    </dependency>
-
     <dependency>
       <groupId>com.fdkankan</groupId>
       <artifactId>4dkankan-utils-rabbitmq</artifactId>
@@ -132,7 +125,7 @@
   </dependencies>
 
   <build>
-    <finalName>${artifactId}</finalName>
+    <finalName>scene-data-push</finalName>
     <plugins>
       <plugin>
         <groupId>org.springframework.boot</groupId>

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

@@ -3,12 +3,10 @@ package com.fdkankan.extend;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 import org.springframework.context.annotation.ComponentScan;
 
 
 @SpringBootApplication
-@EnableDiscoveryClient
 @ComponentScan(basePackages = {"com.fdkankan.*"})
 @MapperScan("com.fdkankan.**.mapper")
 public class ExtendApplication {

+ 27 - 0
src/main/java/com/fdkankan/extend/aop/LimitType.java

@@ -0,0 +1,27 @@
+package com.fdkankan.extend.aop;
+
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public enum LimitType {
+
+    /**
+     * 应用维度
+     */
+    APP_KEY("appKey"),
+    /**
+     * 自定义维度
+     */
+    CUSTOMER("customer"),
+
+    /**
+     * ip维度
+     */
+    IP("ip"),
+    ;
+
+    private String code;
+
+
+
+}

+ 35 - 0
src/main/java/com/fdkankan/extend/aop/RedisLimit.java

@@ -0,0 +1,35 @@
+package com.fdkankan.extend.aop;
+
+import java.lang.annotation.*;
+import java.util.concurrent.TimeUnit;
+
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface RedisLimit {
+
+    // 资源名称
+    String name() default "";
+
+    // 资源key
+    String key() default "";
+
+    /**
+     * 滑动窗口时间单位,默认 秒
+     */
+    TimeUnit timeUnit() default TimeUnit.SECONDS;
+
+    // 时间
+    int period();
+
+    // 最多访问次数
+    int limitCount();
+
+    // 类型
+    LimitType limitType() default LimitType.APP_KEY;
+
+    // 提示信息
+    String msg() default "亲,限流了,稍后再试!";
+
+}

+ 109 - 0
src/main/java/com/fdkankan/extend/aop/RedisLimitAspect.java

@@ -0,0 +1,109 @@
+package com.fdkankan.extend.aop;
+
+import cn.hutool.core.util.StrUtil;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.web.util.WebUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.core.script.RedisScript;
+import org.springframework.scripting.support.ResourceScriptSource;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.time.Instant;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Aspect
+@Configuration
+public class RedisLimitAspect {
+
+    private final static String REDIS_LIMIT_KEY_PREFIX = "openapi:limit:key:resource:%s:%s";
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+    @Resource
+    private RedisScript<Long> limitRedisScript;
+
+    @Before("@annotation(com.fdkankan.extend.aop.RedisLimit)")
+    public void before(JoinPoint joinPoint){
+        MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
+        Method method = methodSignature.getMethod();
+        RedisLimit redisLimit = method.getAnnotation(RedisLimit.class);
+        LimitType limitType = redisLimit.limitType();//限流方式
+        String resource = redisLimit.name();//资源名
+
+        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        HttpServletRequest request = requestAttributes.getRequest();
+        int period = redisLimit.period();
+        int limitCount = redisLimit.limitCount();
+        TimeUnit timeUnit = redisLimit.timeUnit();
+        String key = null;
+        switch (limitType){
+            case APP_KEY:
+                key = request.getHeader("Authorization");
+                if (StrUtil.isEmpty(key)) {
+                    throw new BusinessException(ErrorCode.AUTH_FAIL);
+                }
+                break;
+            case IP:
+                key = WebUtil.getIpAddress(request);
+                break;
+            case CUSTOMER:
+                key = redisLimit.key();
+                break;
+            default:
+                key = StringUtils.upperCase(method.getName());
+        }
+        boolean limited = this.shouldLimited(key, resource, limitCount, period, timeUnit);
+        if(limited){
+            throw new BusinessException(ErrorCode.SYSTEM_BUSY.code(), redisLimit.msg());
+        }
+    }
+
+    private boolean shouldLimited(String key, String resource, long max, long timeout, TimeUnit timeUnit) {
+        key = String.format(REDIS_LIMIT_KEY_PREFIX, key, resource);
+        // 统一使用单位毫秒
+        long ttl = timeUnit.toMillis(timeout);
+        // 当前时间毫秒数
+        long now = Instant.now().toEpochMilli();
+        long expired = now - ttl;
+        /**
+         * 注意这里必须转为 String,否则会报错 java.lang.Long cannot be cast to java.lang.String
+         * stringRedisTemplate.execute(RedisScript<T> script, List<K> keys, Object... args)
+         */
+        Long executeTimes = (Long)redisTemplate.execute(limitRedisScript, Collections.singletonList(key), String.valueOf(now), String.valueOf(ttl), String.valueOf(expired), String.valueOf(max));
+        if (executeTimes != null) {
+            if (executeTimes == 0) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    @Bean("limitRedisScript")
+    public RedisScript<Long> limitRedisScript() {
+        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
+        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("redisScript/limit.lua")));
+        redisScript.setResultType(Long.class);
+        return redisScript;
+    }
+
+}

+ 3 - 1
src/main/java/com/fdkankan/extend/TowerSceneBean.java

@@ -1,4 +1,4 @@
-package com.fdkankan.extend;
+package com.fdkankan.extend.bean;
 
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -16,4 +16,6 @@ public class TowerSceneBean {
     private String name;//场景名称
 
     private String roomId;//机房id
+
+    private String num;
 }

+ 23 - 109
src/main/java/com/fdkankan/extend/controller/TowerController.java

@@ -1,14 +1,12 @@
 package com.fdkankan.extend.controller;
 
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpUtil;
-import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.extend.aop.LimitType;
+import com.fdkankan.extend.aop.RedisLimit;
+import com.fdkankan.extend.service.IScenePlusService;
 import com.fdkankan.extend.service.ITowerService;
-import com.fdkankan.extend.util.FileUtil;
 import com.fdkankan.web.response.ResultData;
-import okhttp3.MultipartBody;
-import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
@@ -22,7 +20,6 @@ import org.apache.http.util.EntityUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
-import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
 
 import javax.servlet.http.HttpServletRequest;
 import java.io.File;
@@ -34,12 +31,27 @@ import java.util.List;
 import java.util.Map;
 
 @RestController
-@RequestMapping("/china/tower")
+@RequestMapping("/scene")
 public class TowerController {
 
     @Autowired
     private ITowerService towerService;
 
+    @Autowired
+    private IScenePlusService scenePlusService;
+
+    /**
+     * 根据场景码列表获取场景信息
+     * @param nums
+     * @return
+     */
+    @PostMapping("/listByNums")
+    @RedisLimit(name = "scene/listByNums", limitType = LimitType.CUSTOMER,  key = "scene/" +
+            "listByNums", limitCount = 5, period = 1)
+    public ResultData listSceneByNums(@RequestBody List<String> nums) {
+        return ResultData.ok(scenePlusService.listSceneByNums(nums));
+    }
+
     @PostMapping("/packSceneData")
     public ResultData packSceneData(Long companyId, String nums){
         List<String> numList = null;
@@ -65,108 +77,10 @@ public class TowerController {
         return ResultData.ok(originalFilename);
     }
 
-    /**
-     * 使用httpclint 发送文件,如果不传输文件,直接设置fileParams=null,
-     * 如果不设置请求头参数,直接设置headerParams=null,就可以进行普通参数的POST请求了
-     *
-     * @param url          请求路径
-     * @param fileParams   文件参数
-     * @param otherParams  其他字符串参数
-     * @param headerParams 请求头参数
-     * @return
-     */
-    public static String uploadFile(String url, Map<String, MultipartFile> fileParams, Map<String, String> otherParams, Map<String, String> headerParams) {
-        CloseableHttpClient httpClient = HttpClients.createDefault();
-        String result = "";
-        try {
-            HttpPost httpPost = new HttpPost(url);
-            //设置请求头
-            if (headerParams != null && headerParams.size() > 0) {
-                for (Map.Entry<String, String> e : headerParams.entrySet()) {
-                    String value = e.getValue();
-                    String key = e.getKey();
-                    if (StringUtils.isNotBlank(value)) {
-                        httpPost.setHeader(key, value);
-                    }
-                }
-            }
-            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
-            builder.setCharset(Charset.forName("utf-8"));
-            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//加上此行代码解决返回中文乱码问题
-            //    文件传输http请求头(multipart/form-data)
-            if (fileParams != null && fileParams.size() > 0) {
-                for (Map.Entry<String, MultipartFile> e : fileParams.entrySet()) {
-                    String fileParamName = e.getKey();
-                    MultipartFile file = e.getValue();
-                    if (file != null) {
-                        String fileName = file.getOriginalFilename();
-                        builder.addBinaryBody(fileParamName, file.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
-                    }
-                }
-            }
-            //    字节传输http请求头(application/json)
-            ContentType contentType = ContentType.create("application/json", Charset.forName("UTF-8"));
-            if (otherParams != null && otherParams.size() > 0) {
-                for (Map.Entry<String, String> e : otherParams.entrySet()) {
-                    String value = e.getValue();
-                    if (StringUtils.isNotBlank(value)) {
-                        builder.addTextBody(e.getKey(), value, contentType);// 类似浏览器表单提交,对应input的name和value
-                    }
-                }
-            }
-            HttpEntity entity = builder.build();
-            httpPost.setEntity(entity);
-            HttpResponse response = httpClient.execute(httpPost);// 执行提交
-            HttpEntity responseEntity = response.getEntity();
-            if (responseEntity != null) {
-                // 将响应内容转换为字符串
-                result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            try {
-                httpClient.close();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-        return result;
-    }
-
-    public static void main(String[] args) throws Exception{
-        String urlStr = "http://localhost:8361/extend/china/tower/testUpload";
-//        String picPath1 = "D://apache-maven-3.8.1-bin.zip";
-//        String arg1 = "入参1";
-//        Map<String, String> headerParams = new HashMap<>();
-//        headerParams.put("token", "testToken");
-//
-//        Map<String, MultipartFile> fileParams = new HashMap<>();
-//        //本地文件转为MultipartFile
-////        String picPath = "/var/111.png";
-//        MultipartFile file1 = FileUtil.pathToMultipartFile(picPath1);
-//        //url转为MultipartFile
-//        fileParams.put("file", file1);
-//
-//        Map<String, String> otherParams = new HashMap<>();
-//        otherParams.put("arg1", arg1);
-//
-//        String res = uploadFile(URL, fileParams, otherParams, headerParams);
-        Map<String, Object> map = new HashMap<>();
-//        map.put("file", FileUtil.createFileItem("D://apache-maven-3.8.1-bin.zip"));
-        map.put("file", new File("D://apache-maven-3.8.1-bin.zip"));
-        map.put("arg1", "第一个参数");
-        String post = HttpUtil.post(urlStr, map);
-//        String body = HttpRequest.post(urlStr).form(map).contentType("multipart/form-data").execute().body();
-
-    }
-
-    @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);
-    }
+//    @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);
+//    }
 
 
 

+ 177 - 0
src/main/java/com/fdkankan/extend/entity/ScenePlusExt.java

@@ -0,0 +1,177 @@
+package com.fdkankan.extend.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2023-02-15
+ */
+@Getter
+@Setter
+@TableName("t_scene_plus_ext")
+public class ScenePlusExt implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * t_scene_plus主键
+     */
+    @TableField("plus_id")
+    private Long plusId;
+
+    /**
+     * 场景数据目录
+     */
+    @TableField("data_source")
+    private String dataSource;
+
+    /**
+     * 场景链接
+     */
+    @TableField("web_site")
+    private String webSite;
+
+    /**
+     * 缩略图链接
+     */
+    @TableField("thumb")
+    private String thumb;
+
+    /**
+     * 方案:1-双目,2-转台,3-六目,4-八目,10-获取4k图,11-获取2k,12-获取1k
+     */
+    @TableField("scene_scheme")
+    private Integer sceneScheme;
+
+    /**
+     * 使用用量
+     */
+    @TableField("space")
+    private Long space;
+
+    /**
+     * 云服务器类型
+     */
+    @TableField("ecs")
+    private String ecs;
+
+    /**
+     * 点位数量
+     */
+    @TableField("shoot_count")
+    private Integer shootCount;
+
+    /**
+     * 浏览次数
+     */
+    @TableField("view_count")
+    private Integer viewCount;
+
+    /**
+     * gps定位
+     */
+    @TableField("gps")
+    private String gps;
+
+    /**
+     * 算法类型(slam、sfm)
+     */
+    @TableField("algorithm")
+    private String algorithm;
+
+    /**
+     * 固件版本
+     */
+    @TableField("firmware_version")
+    private String firmwareVersion;
+
+    /**
+     * 算法类型(V2,V3)
+     */
+    @TableField("build_type")
+    private String buildType;
+
+    /**
+     * 分辨率(2k,4k)
+     */
+    @TableField("scene_resolution")
+    private String sceneResolution;
+
+    /**
+     * 场景来源,lite:双目lite相机,pro:八目相机,minion:双面转台相机,laser:激光相机,virtual:虚拟场景,sketch:图片建模场景
+     */
+    @TableField("scene_from")
+    private String sceneFrom;
+
+    /**
+     * 切图方式(tiles:瓦片图,face:切片图,pan:全景图 ,local:本地切片,cube:立体图)
+     */
+    @TableField("scene_kind")
+    private String sceneKind;
+
+    /**
+     * 算法生成模型类型(dam,3dtiles)
+     */
+    @TableField("model_kind")
+    private String modelKind;
+
+    /**
+     * 点位视频
+     */
+    @TableField("videos")
+    private String videos;
+
+    /**
+     * oss桶名
+     */
+    @TableField("yun_file_bucket")
+    private String yunFileBucket;
+
+    /**
+     * 算法计算完成时间
+     */
+    @TableField("algorithm_time")
+    private Date algorithmTime;
+
+    /**
+     * 计算耗时
+     */
+    @TableField("compute_time")
+    private Long computeTime;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+    @TableField("is_obj")
+    private Integer isObj;
+
+
+}

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

@@ -1,43 +1,64 @@
-//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;
-//
+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.bean.TowerSceneBean;
+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.ExchangeTypes;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.core.MessageProperties;
+import org.springframework.amqp.rabbit.annotation.Exchange;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.QueueBinding;
+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 {
+
+    @Autowired
+    private ITowerService towerService;
+    @Autowired
+    private RedisUtil redisUtil;
+
+    /** 场景推送队列*/
+    public static final String TIE_TA_SCENE_PUSH_QUEUE = "tie_ta_scene_push_queue";
+
+    /** 场景推送交换机*/
+    public static final String TIE_TA_SCENE_PUSH_EXCHANGE = "tie_ta_scene_push_exchange";
+
+    /** 场景推送交换机路由*/
+    public static final String TIE_TA_SCENE_PUSH_ROUTING = "tie_ta_scene_push_routing";
+
+    /** 场景推送回调队列*/
+    public static final String TIE_TA_SCENE_PUSH_CALLBACK_QUEUE = "tie_ta_scene_push_callback_queue";
+
+    /** 场景推送回调交换机*/
+    public static final String TIE_TA_SCENE_PUSH_CALLBACK_EXCHANGE = "tie_ta_scene_push_callback_exchange";
+
+    /** 场景推送回调交换机路由*/
+    public static final String TIE_TA_SCENE_PUSH_CALLBACK_ROUTING = "tie_ta_scene_push_callback_routing";
+
 //    /**
 //     * 铁塔项目数据推送监听器
 //     * @param channel
@@ -45,33 +66,39 @@
 //     * @throws Exception
 //     */
 //    @RabbitListener(
-//        queuesToDeclare = @Queue("${queue.modeling.extend.tower.data-push}")
+////            queuesToDeclare = @Queue(TIE_TA_SCENE_PUSH_QUEUE),
+//            bindings = @QueueBinding(
+//                    value = @Queue(value = TIE_TA_SCENE_PUSH_CALLBACK_QUEUE, ignoreDeclarationExceptions = "true"),
+//                    exchange = @Exchange(value = TIE_TA_SCENE_PUSH_CALLBACK_EXCHANGE, type = ExchangeTypes.TOPIC, ignoreDeclarationExceptions = "true"),
+//                    key = TIE_TA_SCENE_PUSH_CALLBACK_ROUTING),
+//            concurrency = "1"
 //    )
 //    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);
+//        final MessageProperties messageProperties = message.getMessageProperties();
+//        log.info("开始消费场景推送队列,content:{}", content);
 //        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));
-//        }
-//
+//        log.info(jsonObject.toJSONString());
+////        System.out.println(jsonObject.toJSONString());
+////        towerService.pushScene(towerSceneBean);
 //        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-//        log.info("结束消费消息,id:{}", messageId);
+//        log.info("结束消费场景推送队列,content:{}", content);
 //    }
-//
-//
-//
-//}
+
+    @RabbitListener(
+            queuesToDeclare = @Queue(TIE_TA_SCENE_PUSH_QUEUE),
+            concurrency = "1"
+    )
+    public void callback(Channel channel, Message message) throws Exception {
+        String content = new String(message.getBody(), StandardCharsets.UTF_8);
+        log.info("开始消费场景推送队列,content:{}", content);
+        Thread.sleep(5000L);
+        TowerSceneBean towerSceneBean = JSON.parseObject(content, TowerSceneBean.class);
+        towerService.pushScene(towerSceneBean);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+        log.info("结束消费场景推送队列,content:{}", content);
+    }
+
+
+
+}

+ 18 - 0
src/main/java/com/fdkankan/extend/mapper/IScenePlusExtMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.extend.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.extend.entity.ScenePlusExt;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-02-15
+ */
+@Mapper
+public interface IScenePlusExtMapper extends BaseMapper<ScenePlusExt> {
+
+}

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

@@ -19,5 +19,7 @@ public interface ICameraService extends IService<Camera> {
 
     List<Camera> listBySnCodes(List<String> snCodes);
 
+    List<Camera> getByCameraIdList(List<Long> cameraIdList);
+
 
 }

+ 22 - 0
src/main/java/com/fdkankan/extend/service/IScenePlusExtService.java

@@ -0,0 +1,22 @@
+package com.fdkankan.extend.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.extend.entity.ScenePlusExt;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-02-15
+ */
+public interface IScenePlusExtService extends IService<ScenePlusExt> {
+
+    ScenePlusExt getByPlusId(long plusId);
+
+    List<ScenePlusExt> getByPlusIdList(List<Long> plusIdList);
+
+}

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

@@ -2,6 +2,7 @@ package com.fdkankan.extend.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.extend.entity.ScenePlus;
+import com.fdkankan.extend.vo.SceneVo;
 
 import java.util.List;
 import java.util.Set;
@@ -20,5 +21,9 @@ public interface IScenePlusService extends IService<ScenePlus> {
 
     ScenePlus getByCameraIdAndNum(String num, Long cameraId);
 
+    List<SceneVo> listSceneByNums(List<String> nums);
+
+    ScenePlus getByNum(String num);
+
 
 }

+ 6 - 1
src/main/java/com/fdkankan/extend/service/ITowerService.java

@@ -1,5 +1,7 @@
 package com.fdkankan.extend.service;
 
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.extend.bean.TowerSceneBean;
 import com.fdkankan.web.response.ResultData;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -11,6 +13,7 @@ import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.InvalidKeySpecException;
 import java.util.List;
+import java.util.Map;
 
 public interface ITowerService {
 
@@ -18,9 +21,11 @@ public interface ITowerService {
 
     public void packSceneData(Long companyId, List<String> nums);
 
-    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 JSONObject dataPush(String num, String sceneId, String roomId, String zipPath) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidKeySpecException, Exception;
 
     public ResultData sceneBatchMove(MultipartFile file, String origSnCode, String snCode) throws IOException;
 
+    public void pushScene(TowerSceneBean towerSceneBean) throws Exception;
+
 
 }

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

@@ -33,4 +33,9 @@ public class CameraServiceImpl extends ServiceImpl<ICameraMapper, Camera> implem
         }
         return this.list(new LambdaQueryWrapper<Camera>().in(Camera::getSnCode, snCodes));
     }
+
+    @Override
+    public List<Camera> getByCameraIdList(List<Long> cameraIdList) {
+        return this.list(new LambdaQueryWrapper<Camera>().in(Camera::getId, cameraIdList));
+    }
 }

+ 33 - 0
src/main/java/com/fdkankan/extend/service/impl/ScenePlusExtServiceImpl.java

@@ -0,0 +1,33 @@
+package com.fdkankan.extend.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.extend.entity.ScenePlusExt;
+import com.fdkankan.extend.mapper.IScenePlusExtMapper;
+import com.fdkankan.extend.service.IScenePlusExtService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-02-15
+ */
+@Service
+public class ScenePlusExtServiceImpl extends ServiceImpl<IScenePlusExtMapper, ScenePlusExt> implements IScenePlusExtService {
+
+
+    @Override
+    public ScenePlusExt getByPlusId(long plusId) {
+        return this.getOne(new LambdaQueryWrapper<ScenePlusExt>().eq(ScenePlusExt::getPlusId, plusId));
+    }
+
+    @Override
+    public List<ScenePlusExt> getByPlusIdList(List<Long> plusIdList) {
+        return this.list(new LambdaQueryWrapper<ScenePlusExt>().select(ScenePlusExt::getPlusId, ScenePlusExt::getWebSite).in(ScenePlusExt::getPlusId, plusIdList));
+    }
+}

+ 70 - 2
src/main/java/com/fdkankan/extend/service/impl/ScenePlusServiceImpl.java

@@ -1,15 +1,24 @@
 package com.fdkankan.extend.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.extend.entity.Camera;
 import com.fdkankan.extend.entity.ScenePlus;
+import com.fdkankan.extend.entity.ScenePlusExt;
 import com.fdkankan.extend.mapper.IScenePlusMapper;
+import com.fdkankan.extend.service.ICameraService;
+import com.fdkankan.extend.service.IScenePlusExtService;
 import com.fdkankan.extend.service.IScenePlusService;
+import com.fdkankan.extend.vo.SceneVo;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.List;
-import java.util.Set;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -23,6 +32,11 @@ import java.util.Set;
 @Service
 public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlus> implements IScenePlusService {
 
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Autowired
+    private ICameraService cameraService;
+
 
     @Override
     public List<ScenePlus> getByCameraIds(Set<Long> cameraIds) {
@@ -33,4 +47,58 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     public ScenePlus getByCameraIdAndNum(String num, Long cameraId) {
        return this.getOne(new LambdaQueryWrapper<ScenePlus>().eq(ScenePlus::getCameraId, cameraId).eq(ScenePlus::getNum, num));
     }
+
+    @Override
+    public List<SceneVo> listSceneByNums(List<String> nums) {
+        if(CollUtil.isEmpty(nums)){
+            return null;
+        }
+        if(nums.size() > 50){
+            nums = nums.subList(0, 50);
+        }
+
+        List<ScenePlus> scenePlusList = this.list(
+                new LambdaQueryWrapper<ScenePlus>()
+                        .in(ScenePlus::getNum, nums)
+                        .select(ScenePlus::getId, ScenePlus::getNum, ScenePlus::getTitle, ScenePlus::getCameraId, ScenePlus::getCreateTime, ScenePlus::getSceneStatus));
+        if(CollUtil.isEmpty(scenePlusList)){
+            return null;
+        }
+
+        List<Long> scenePlusIdList = new ArrayList<>();
+        List<Long> cameraIdList = new ArrayList<>();
+        scenePlusList.stream().forEach(plus -> {
+            scenePlusIdList.add(plus.getId());
+            if(Objects.nonNull(plus)){
+                cameraIdList.add(plus.getCameraId());
+            }
+        });
+
+        List<ScenePlusExt> plusExtList = scenePlusExtService.getByPlusIdList(scenePlusIdList);
+        Map<Long, ScenePlusExt> plusExtMap = plusExtList.stream().collect(Collectors.toMap(ScenePlusExt::getPlusId, Function.identity()));
+
+        Map<Long, String> cameraMap = null;
+        if(CollUtil.isNotEmpty(cameraIdList)){
+            List<Camera> cameraList = cameraService.getByCameraIdList(cameraIdList);
+            cameraMap = cameraList.stream().collect(Collectors.toMap(Camera::getId, Camera::getSnCode));
+        }
+
+        Map<Long, String> finalCameraMap = cameraMap;
+        List<SceneVo> collect = scenePlusList.stream().map(scenePlus -> {
+            SceneVo towerSceneVo = BeanUtil.copyProperties(scenePlus, SceneVo.class);
+            towerSceneVo.setWebSite(plusExtMap.get(scenePlus.getId()).getWebSite());
+            towerSceneVo.setCreateTime(plusExtMap.get(scenePlus.getId()).getAlgorithmTime());
+            if (CollUtil.isNotEmpty(finalCameraMap)) {
+                towerSceneVo.setSnCode(finalCameraMap.get(scenePlus.getCameraId()));
+            }
+            return towerSceneVo;
+        }).collect(Collectors.toList());
+
+        return collect;
+    }
+
+    @Override
+    public ScenePlus getByNum(String num) {
+        return this.getOne(new LambdaQueryWrapper<ScenePlus>().eq(ScenePlus::getNum, num));
+    }
 }

+ 137 - 67
src/main/java/com/fdkankan/extend/service/impl/TowerServiceImpl.java

@@ -6,20 +6,22 @@ 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.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.AES;
 import cn.hutool.http.HttpStatus;
 import cn.hutool.http.HttpUtil;
+import cn.hutool.jwt.signers.AlgorithmUtil;
 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.constant.SceneStatus;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.AesUtil;
 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.bean.TowerSceneBean;
 import com.fdkankan.extend.entity.Camera;
 import com.fdkankan.extend.entity.CameraDetail;
 import com.fdkankan.extend.entity.ScenePlus;
@@ -29,24 +31,25 @@ 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.rabbitmq.util.RabbitMqProducer;
 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.amqp.rabbit.core.RabbitTemplate;
 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 javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 import java.io.File;
 import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
-@RefreshScope
 @Slf4j
 @Service
 public class TowerServiceImpl implements ITowerService {
@@ -61,6 +64,14 @@ public class TowerServiceImpl implements ITowerService {
 
     private static String pushLogPath = parentPath.concat("log.txt");
 
+    public static final String TIE_TA_SCENE_PUSH_CALLBACK_QUEUE = "tie_ta_scene_push_callback_queue";
+
+    /** 场景推送回调交换机*/
+    public static final String TIE_TA_SCENE_PUSH_CALLBACK_EXCHANGE = "tie_ta_scene_push_callback_exchange";
+
+    /** 场景推送回调交换机路由*/
+    public static final String TIE_TA_SCENE_PUSH_CALLBACK_ROUTING = "tie_ta_scene_push_callback_routing";
+
     @Value("${tower.manufact}")
     private String manufact;
 
@@ -70,9 +81,6 @@ public class TowerServiceImpl implements ITowerService {
     @Value("${tower.url}")
     private String url;
 
-    @Value("fyun.bucket")
-    private String bucket;
-
     @Autowired
     private FYunFileServiceInterface fYunFileService;
     @Autowired
@@ -92,6 +100,12 @@ public class TowerServiceImpl implements ITowerService {
     @Resource
     private HttpClient httpClient;
 
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+
+    @Autowired
+    private RabbitTemplate rabbitTemplate;
+
     @Override
     public String packSceneDataHandler(String num, String title, String logId) throws Exception {
 
@@ -179,7 +193,7 @@ public class TowerServiceImpl implements ITowerService {
         log.info("结束下载,开始推送:{}", num);
 
         try {
-            this.dataPush(num, title, towerSceneBean.getSceneId(), towerSceneBean.getRoomId(), zipPath, logId);
+            this.dataPush(num, towerSceneBean.getSceneId(), towerSceneBean.getRoomId(), zipPath);
         }finally {
             FileUtil.del(scenePath);
         }
@@ -293,7 +307,9 @@ public class TowerServiceImpl implements ITowerService {
     }
 
     @Override
-    public void dataPush(String num, String title, String sceneId, String roomId, String zipPath, String logId) throws Exception {
+    public JSONObject dataPush(String num, String sceneId, String roomId, String zipPath) throws Exception {
+
+        JSONObject jsonObject = null;
 
         log.info("开始组装参数");
 
@@ -314,63 +330,19 @@ public class TowerServiceImpl implements ITowerService {
         log.info("encrypt:{}", encrypt);
         log.info("开始推送");
         try {
-            String post = HttpUtil.post(url, params);
-            JSONObject jsonObject = JSON.parseObject(post);
-            this.dataPushLog(num, title, jsonObject.getString("resultCode"), jsonObject.getString("resultMsg"), logId);
+            String post = HttpUtil.post(url, params, 60*60*1000);
+            jsonObject = JSON.parseObject(post);
+            if(!jsonObject.containsKey("resultCode")){
+                throw new RuntimeException("铁塔接口出参错误");
+            }
+            return jsonObject;
         }catch (Exception e){
-            log.error("推送失败", e);
-            this.dataPushLog(num, title, String.valueOf(HttpStatus.HTTP_BAD_GATEWAY), "请求失败", logId);
+            log.error("调用铁塔接口出错,场景:{}", num, e);
+            jsonObject = new JSONObject();
+            jsonObject.put("resultCode", -2);
+            jsonObject.put("resultMsg", "调用铁塔接口出错");
+            return jsonObject;
         }
-
-
-    }
-
-    public static void main(String[] args) {
-//        Map<String, Object> params = new HashMap<>();
-//        params.put("stationCode", "410192010000001484");
-//        params.put("roomEntityID", "000102050000000003085104");
-//        params.put("file", FileUtil.file("D:\\test\\410192010000001484_000102050000000003085104.zip"));
-//        params.put("manufact", "3");
-//        params.put("upUserAcct", "111");
-//        params.put("encrypt", "oNFZonGRrum3hldhU9AcMwP0JsXoxZocaTSTgj1h1Ag9pJzro9us0udinPr058y9KcwSPtkO58TKVE4csnasTZT00jghJQqsk0ATiNzX8QZh+F1iH33j6I3NHZu3vzjAV4lVHSo23WcEMo4s9G5dxymagYl8FKd7ua0/CYNysrs=");
-//        String post = HttpUtil.post("http://120.52.136.13:2808/fileManager/uploadRsaFileZipView", params);
-//        JSONObject jsonObject = JSON.parseObject(post);
-//        System.out.println(jsonObject.toJSONString());
-
-//        String sceneStr = fYunFileService.getFileContent(ossScenePoolFilePath);
-//        String sceneStr = FileUtil.readUtf8String("D:\\四维时代\\中国铁塔\\郑州-天津.js");
-//        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"));
-//        }
-//
-//        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){
@@ -383,6 +355,10 @@ public class TowerServiceImpl implements ITowerService {
         FileUtil.appendUtf8String(content, parentPath.concat("download").concat("-").concat(logId).concat(".log"));
     }
 
+    public static void main(String[] args) {
+//        System.out.println(AlgorithmUtil.getId("AES"));
+    }
+
     @Override
     public ResultData sceneBatchMove(MultipartFile file, String origSnCode, String snCode) throws IOException {
         if(file.isEmpty()){
@@ -440,4 +416,98 @@ public class TowerServiceImpl implements ITowerService {
         }
         return ResultData.ok(result);
     }
+
+    @Override
+    public void pushScene(TowerSceneBean towerSceneBean) throws Exception {
+
+        JSONObject pushResult = null;
+        String num = towerSceneBean.getNum();
+        Map<String, Object> noticeContent = new HashMap<>();
+        noticeContent.put("num", num);
+        String scenePath = parentPath.concat(num).concat("/");
+
+        try {
+
+            //场景本地数据父目录
+            String sceneSourcePath = scenePath.concat(towerSceneBean.getSceneId()).concat("_").concat(towerSceneBean.getRoomId());
+            String zipPath = sceneSourcePath.concat(".zip");
+
+            log.info("开始下载:{}", num);
+
+            ScenePlus scenePlus = scenePlusService.getByNum(num);
+            if(Objects.isNull(scenePlus)){
+                throw new RuntimeException("查询不到此场景");
+            }
+            if(scenePlus.getSceneStatus() != SceneStatus.SUCCESS.code() && scenePlus.getSceneStatus() != SceneStatus.NO_DISPLAY.code()){
+                throw new RuntimeException("场景计算中");
+            }
+
+            //data数据下载
+            String dataPath = sceneSourcePath + "/data/";
+            String ossDataPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
+            //下载floorplan.json
+            fYunFileService.downloadFile(ossDataPath.concat("floorplan.json"), dataPath.concat("floorplan.json"));
+
+//           //下载scene.json
+            String sceneJsonPath = dataPath.concat("scene.json");
+            String sceneJson = fYunFileService.getFileContent(ossDataPath.concat("scene.json"));
+            JSONObject sceneJsonObj = JSON.parseObject(sceneJson);
+            sceneJsonObj.put("sceneKind", "pano");
+            FileUtil.writeUtf8String(sceneJsonObj.toJSONString(), sceneJsonPath);
+
+            //下载mesh
+            FileUtil.mkdir(dataPath.concat("mesh/"));
+            List<String> meshList = fYunFileService.listRemoteFiles(ossDataPath.concat("mesh"));
+            meshList.parallelStream().forEach(key -> fYunFileService.downloadFile(key, dataPath.concat("mesh/")));
+
+            //images数据下载
+            String imagesPath = sceneSourcePath + "/images/";
+            String ossImagesPath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
+            //下载high图
+            List<String> highList = fYunFileService.listRemoteFiles(ossImagesPath.concat("pan/high/"));
+            FileUtil.mkdir(imagesPath.concat("4k/"));
+            highList.parallelStream().forEach(key -> fYunFileService.downloadFile(key, imagesPath.concat("4k/")));
+            //下载low图
+            FileUtil.mkdir(imagesPath.concat("512/"));
+            List<String> lowList = fYunFileService.listRemoteFiles(ossImagesPath.concat("pan/low/"));
+            lowList.parallelStream().forEach(key -> fYunFileService.downloadFile(key, imagesPath.concat("512/")));
+            //下载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"));
+                    }
+                });
+            }
+
+            this.convertVisable(imagesPath.concat("vision.txt"));
+
+            //打包
+            ZipUtil.zip(sceneSourcePath, zipPath, true);
+
+            log.info("打包成功,开始推送:{}", num);
+
+            pushResult = this.dataPush(num, towerSceneBean.getSceneId(), towerSceneBean.getRoomId(), zipPath);
+
+        }catch (Exception e){
+            log.error("场景推送出错,未知异常", e);
+            pushResult = new JSONObject();
+            pushResult.put("resultCode", -3);
+            pushResult.put("resultMsg", e.getMessage());
+        } finally {
+            noticeContent.put("result", pushResult);
+            rabbitMqProducer.sendByWorkQueue(TIE_TA_SCENE_PUSH_CALLBACK_QUEUE, noticeContent);
+//            rabbitTemplate.convertAndSend(TIE_TA_SCENE_PUSH_CALLBACK_EXCHANGE , TIE_TA_SCENE_PUSH_CALLBACK_ROUTING , noticeContent);
+            FileUtil.del(scenePath);
+        }
+    }
 }

+ 0 - 3
src/main/java/com/fdkankan/extend/util/RsaCryptTools.java

@@ -1,7 +1,5 @@
 package com.fdkankan.extend.util;
 
-import org.bouncycastle.crypto.InvalidCipherTextException;
-
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
@@ -55,7 +53,6 @@ public class RsaCryptTools {
      * @param privateInfoStr
      * @return
      * @throws IOException
-     * @throws InvalidCipherTextException
      */
     public static String encryptData(String data, String privateInfoStr) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
 

+ 22 - 0
src/main/java/com/fdkankan/extend/vo/SceneVo.java

@@ -0,0 +1,22 @@
+package com.fdkankan.extend.vo;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class SceneVo {
+
+    private String num;
+
+    private String webSite;
+
+    private String title;
+
+    private String snCode;
+
+    private Date createTime;
+
+    private Integer sceneStatus;
+
+}

Різницю між файлами не показано, бо вона завелика
+ 96 - 0
src/main/resources/application-prod.yml


Різницю між файлами не показано, бо вона завелика
+ 96 - 0
src/main/resources/application-test.yml


+ 0 - 40
src/main/resources/bootstrap-prod.yml

@@ -1,40 +0,0 @@
-spring:
-  application:
-    name: 4dkankan-center-modeling-extend
-  cloud:
-    nacos:
-      server-addr: 172.20.1.63:8848
-      namespace: 4dkankan-v4-prod
-      config:
-        file-extension: yaml
-        namespace: ${spring.cloud.nacos.namespace}
-        shared-configs:
-          - data-id: common-db-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-redis-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-rabbitmq-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-fyun-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-      discovery:
-        namespace: ${spring.cloud.nacos.namespace}
-#        namespace: public
-
-
-
-
-
-

+ 0 - 40
src/main/resources/bootstrap-test.yml

@@ -1,40 +0,0 @@
-spring:
-  application:
-    name: 4dkankan-center-modeling-extend
-  cloud:
-    nacos:
-      server-addr: 120.24.144.164:8848
-      namespace: 4dkankan-v4-test
-      config:
-        file-extension: yaml
-        namespace: ${spring.cloud.nacos.namespace}
-        shared-configs:
-          - data-id: common-db-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-redis-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-rabbitmq-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-          - data-id: common-fyun-config.yaml
-            group: DEFAULT_GROUP
-            refresh: true
-
-      discovery:
-        namespace: ${spring.cloud.nacos.namespace}
-#        namespace: public
-
-
-
-
-
-

+ 0 - 3
src/main/resources/bootstrap.yml

@@ -1,3 +0,0 @@
-spring:
-  profiles:
-    active: test

+ 2 - 1
src/main/resources/logback-spring.xml

@@ -5,9 +5,10 @@
 <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
 <configuration scan="true" scanPeriod="10 seconds">
 	<springProperty scope="context" name="LOG_PATH" source="logging.path"/>
+	<springProperty scope="context" name="APPLICATION_NAME" source="spring.application.name"/>
 	<contextName>logback</contextName>
 	<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
-	<property name="log.path" value="${LOG_PATH}/modeling-extend/logs" />
+	<property name="log.path" value="${LOG_PATH}/${APPLICATION_NAME}/logs" />
 
 	<!-- 彩色日志 -->
 	<!-- 彩色日志依赖的渲染类 -->

+ 25 - 0
src/main/resources/redisScript/limit.lua

@@ -0,0 +1,25 @@
+--local key = KEYS[1]
+local now = tonumber(ARGV[1]) -- 当前时时间戳
+local ttl = tonumber(ARGV[2]) -- key的过期时间
+local expired = tonumber(ARGV[3]) -- 元素过期分数上限(用于移除过期时间窗口元素)
+local limitCount = tonumber(ARGV[4]) --限制访问次数
+
+-- 清除过期的数据
+-- 移除指定分数区间内的所有元素,expired 即已经过期的 score
+-- 根据当前时间毫秒数 - 超时毫秒数,得到过期时间 expired
+redis.call('zremrangebyscore', KEYS[1], 0, expired)
+
+-- 获取 zset 中的当前元素个数
+local current = tonumber(redis.call('zcard', KEYS[1]))
+local next = current + 1
+
+if next > limitCount then
+  -- 达到限流大小 返回 0
+  return 0;
+else
+  -- 往 zset 中添加一个[value,score]均为当前时间戳的元素,[value,score]
+  redis.call("zadd", KEYS[1], now, now)
+  -- 每次访问均重新设置 zset 的过期时间,单位毫秒
+  redis.call("pexpire", KEYS[1], ttl)
+  return next
+end