Browse Source

调用算法相关数据接口优化

yangyue 1 month ago
parent
commit
aabf2d1702
23 changed files with 1233 additions and 168 deletions
  1. 33 14
      algorithm-service/pom.xml
  2. 9 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/config/MyBatisPlusConfig.java
  3. 109 109
      algorithm-service/src/main/java/cn/com/taiji/algorithm/config/MysqlGenerator.java
  4. 40 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/controller/VideoTreeController.java
  5. 4 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/mapper/VideoCatalogMapper.java
  6. 9 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/mapper/VideoInfoMapper.java
  7. 29 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/model/AlgorithmInfo.java
  8. 40 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/model/AlgorithmInfoDTO.java
  9. 85 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/model/TableDataInfo.java
  10. 25 10
      algorithm-service/src/main/java/cn/com/taiji/algorithm/model/VideoCatalog.java
  11. 10 4
      algorithm-service/src/main/java/cn/com/taiji/algorithm/model/VideoInfo.java
  12. 39 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/model/VideoInfoDTO.java
  13. 5 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/service/IVideoCatalogService.java
  14. 6 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/service/IVideoInfoService.java
  15. 3 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/service/IVideoTreeService.java
  16. 15 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/service/impl/VideoCatalogServiceImpl.java
  17. 12 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/service/impl/VideoInfoServiceImpl.java
  18. 71 15
      algorithm-service/src/main/java/cn/com/taiji/algorithm/service/impl/VideoTreeServiceImpl.java
  19. 99 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/task/AlgorithmTask.java
  20. 74 15
      algorithm-service/src/main/java/cn/com/taiji/algorithm/task/Videotask.java
  21. 459 0
      algorithm-service/src/main/java/cn/com/taiji/algorithm/utils/StringUtils.java
  22. 15 1
      algorithm-service/src/main/resources/application.yml
  23. 42 0
      algorithm-service/src/main/resources/mapper/VideoInfoMapper.xml

+ 33 - 14
algorithm-service/pom.xml

@@ -10,6 +10,9 @@
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>algorithm-service</artifactId>
+    <version>1.0</version>
+    <name>algorithm-service</name>
+    <description>DataService project for Spring Boot</description>
 
     <properties>
         <maven.compiler.source>8</maven.compiler.source>
@@ -20,11 +23,13 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
+            <version>2.1.3.RELEASE</version>
         </dependency>
 
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-devtools</artifactId>
+            <version>2.1.3.RELEASE</version>
             <scope>runtime</scope>
             <optional>true</optional>
         </dependency>
@@ -36,6 +41,12 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.10</version>
+        </dependency>
+
+        <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
             <version>1.2.75</version>
@@ -48,17 +59,18 @@
         </dependency>
 
         <!-- 海康SDK -->
-        <dependency>
-            <groupId>com.hikvision.ga</groupId>
-            <artifactId>artemis-http-client</artifactId>
-            <version>1.1.3</version>
-        </dependency>
+        <!--        <dependency>-->
+        <!--            <groupId>com.hikvision.ga</groupId>-->
+        <!--            <artifactId>artemis-http-client</artifactId>-->
+        <!--            <version>1.1.3</version>-->
+        <!--        </dependency>-->
 
 
         <!-- Mysql驱动包 -->
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.15</version>
         </dependency>
         <dependency>
             <groupId>com.alibaba</groupId>
@@ -89,18 +101,25 @@
             <version>3.4.3</version>
         </dependency>
 
-        <!-- mybatis plus 代码生成器依赖 -->
+        <!-- pagehelper 分页插件 -->
         <dependency>
-            <groupId>com.baomidou</groupId>
-            <artifactId>mybatis-plus-generator</artifactId>
-            <version>3.4.1</version>
-        </dependency>
-        <!-- 代码生成器模板 -->
-        <dependency>
-            <groupId>org.freemarker</groupId>
-            <artifactId>freemarker</artifactId>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper</artifactId>
+            <version>5.2.1</version>
         </dependency>
 
+        <!-- mybatis plus 代码生成器依赖 -->
+        <!--        <dependency>-->
+        <!--            <groupId>com.baomidou</groupId>-->
+        <!--            <artifactId>mybatis-plus-generator</artifactId>-->
+        <!--            <version>3.4.1</version>-->
+        <!--        </dependency>-->
+        <!--        &lt;!&ndash; 代码生成器模板 &ndash;&gt;-->
+        <!--        <dependency>-->
+        <!--            <groupId>org.freemarker</groupId>-->
+        <!--            <artifactId>freemarker</artifactId>-->
+        <!--        </dependency>-->
+
     </dependencies>
 
     <build>

+ 9 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/config/MyBatisPlusConfig.java

@@ -3,6 +3,7 @@ package cn.com.taiji.algorithm.config;
 import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import com.github.pagehelper.PageInterceptor;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -22,4 +23,12 @@ public class MyBatisPlusConfig {
         interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
         return interceptor;
     }
+
+    /**
+     * pagehelper的分页插件
+     */
+    @Bean
+    public PageInterceptor pageInterceptor() {
+        return new PageInterceptor();
+    }
 }

+ 109 - 109
algorithm-service/src/main/java/cn/com/taiji/algorithm/config/MysqlGenerator.java

@@ -1,109 +1,109 @@
-package cn.com.taiji.algorithm.config;
-
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
-import com.baomidou.mybatisplus.generator.AutoGenerator;
-import com.baomidou.mybatisplus.generator.InjectionConfig;
-import com.baomidou.mybatisplus.generator.config.*;
-import com.baomidou.mybatisplus.generator.config.po.TableFill;
-import com.baomidou.mybatisplus.generator.config.po.TableInfo;
-import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
-import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @Description 
- * 
- * @Author  yangyue
- * @Date 2021/11/7 
- */
-public class MysqlGenerator {
-    /**
-     * RUN THIS
-     */
-    public static void main(String[] args) {
-        // 代码生成器
-        AutoGenerator mpg = new AutoGenerator();
-
-        // TODO 全局配置   用来设置生成文件的命名
-        GlobalConfig gc = new GlobalConfig();
-        gc.setOutputDir("E:/software/IDEA/IdeaProjects/data-service/algorithm-service/src/main/java");
-        // 设置用户名
-        gc.setAuthor("yangyue");
-        gc.setOpen(true);
-        // service 命名方式
-        gc.setServiceName("I"+"%sService");
-        // service impl 命名方式
-        gc.setServiceImplName("%sServiceImpl");
-        // 自定义文件命名,注意 %s 会自动填充表实体属性!
-        gc.setMapperName("%sMapper");
-        gc.setXmlName("%sMapper");
-        gc.setFileOverride(true);
-        gc.setActiveRecord(true);
-        // XML 二级缓存
-        gc.setEnableCache(false);
-        // XML ResultMap
-        gc.setBaseResultMap(true);
-        // XML columList
-        gc.setBaseColumnList(false);
-        mpg.setGlobalConfig(gc);
-
-        // TODO 数据源配置
-        DataSourceConfig dsc = new DataSourceConfig();
-        dsc.setUrl("jdbc:mysql://8.130.72.63:18080/ax_seat_show?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true");
-        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
-        dsc.setUsername("root");
-        dsc.setPassword("Taiji@2023#data");
-        mpg.setDataSource(dsc);
-
-        //  包配置   文件生成后对应的包
-        PackageConfig pc = new PackageConfig();
-
-        pc.setParent("cn.com.taiji.algorithm");
-        pc.setEntity("model");
-        pc.setMapper("mapper");
-        pc.setService("service");
-        pc.setServiceImpl("service.impl");
-        mpg.setPackageInfo(pc);
-
-        //  自定义需要填充的字段
-        List<TableFill> tableFillList = new ArrayList<>();
-
-
-        // 自定义配置
-        InjectionConfig cfg = new InjectionConfig() {
-            @Override
-            public void initMap() {
-                // to do nothing
-            }
-        };
-        List<FileOutConfig> focList = new ArrayList<>();
-        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
-            @Override
-            public String outputFile(TableInfo tableInfo) {
-                // 自定义输入文件名称和生成的mapper.xml文件所在的包
-                return "E:/software/IDEA/IdeaProjects/data-service/algorithm-service/src/main/resources/mapper/"
-                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
-            }
-        });
-        cfg.setFileOutConfigList(focList);
-        mpg.setCfg(cfg);
-        mpg.setTemplate(new TemplateConfig().setXml(null));
-
-        // 策略配置   StrategyConfig数据表
-        StrategyConfig strategy = new StrategyConfig();
-        strategy.setNaming(NamingStrategy.underline_to_camel);
-        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
-        strategy.setEntityLombokModel(true);
-        strategy.setRestControllerStyle(true);
-
-        // 需要生成哪些表的文件  在这里用,分开,这里生成的是style和room两个表
-        strategy.setInclude(new String("algorithm_info").split(","));
-
-        mpg.setStrategy(strategy);
-        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
-        mpg.execute();
-
-    }
-}
+package cn.com.taiji.algorithm.config;//package cn.com.taiji.algorithm.config;
+//
+//import com.baomidou.mybatisplus.core.toolkit.StringPool;
+//import com.baomidou.mybatisplus.generator.AutoGenerator;
+//import com.baomidou.mybatisplus.generator.InjectionConfig;
+//import com.baomidou.mybatisplus.generator.config.*;
+//import com.baomidou.mybatisplus.generator.config.po.TableFill;
+//import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+//import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+//import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+///**
+// * @Description
+// *
+// * @Author  yangyue
+// * @Date 2021/11/7
+// */
+//public class MysqlGenerator {
+//    /**
+//     * RUN THIS
+//     */
+//    public static void main(String[] args) {
+//        // 代码生成器
+//        AutoGenerator mpg = new AutoGenerator();
+//
+//        // TODO 全局配置   用来设置生成文件的命名
+//        GlobalConfig gc = new GlobalConfig();
+//        gc.setOutputDir("E:/software/IDEA/IdeaProjects/data-service/algorithm-service/src/main/java");
+//        // 设置用户名
+//        gc.setAuthor("yangyue");
+//        gc.setOpen(true);
+//        // service 命名方式
+//        gc.setServiceName("I"+"%sService");
+//        // service impl 命名方式
+//        gc.setServiceImplName("%sServiceImpl");
+//        // 自定义文件命名,注意 %s 会自动填充表实体属性!
+//        gc.setMapperName("%sMapper");
+//        gc.setXmlName("%sMapper");
+//        gc.setFileOverride(true);
+//        gc.setActiveRecord(true);
+//        // XML 二级缓存
+//        gc.setEnableCache(false);
+//        // XML ResultMap
+//        gc.setBaseResultMap(true);
+//        // XML columList
+//        gc.setBaseColumnList(false);
+//        mpg.setGlobalConfig(gc);
+//
+//        // TODO 数据源配置
+//        DataSourceConfig dsc = new DataSourceConfig();
+//        dsc.setUrl("jdbc:mysql://8.130.72.63:18080/ax_seat_show?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true");
+//        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
+//        dsc.setUsername("root");
+//        dsc.setPassword("Taiji@2023#data");
+//        mpg.setDataSource(dsc);
+//
+//        //  包配置   文件生成后对应的包
+//        PackageConfig pc = new PackageConfig();
+//
+//        pc.setParent("cn.com.taiji.algorithm");
+//        pc.setEntity("model");
+//        pc.setMapper("mapper");
+//        pc.setService("service");
+//        pc.setServiceImpl("service.impl");
+//        mpg.setPackageInfo(pc);
+//
+//        //  自定义需要填充的字段
+//        List<TableFill> tableFillList = new ArrayList<>();
+//
+//
+//        // 自定义配置
+//        InjectionConfig cfg = new InjectionConfig() {
+//            @Override
+//            public void initMap() {
+//                // to do nothing
+//            }
+//        };
+//        List<FileOutConfig> focList = new ArrayList<>();
+//        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
+//            @Override
+//            public String outputFile(TableInfo tableInfo) {
+//                // 自定义输入文件名称和生成的mapper.xml文件所在的包
+//                return "E:/software/IDEA/IdeaProjects/data-service/algorithm-service/src/main/resources/mapper/"
+//                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+//            }
+//        });
+//        cfg.setFileOutConfigList(focList);
+//        mpg.setCfg(cfg);
+//        mpg.setTemplate(new TemplateConfig().setXml(null));
+//
+//        // 策略配置   StrategyConfig数据表
+//        StrategyConfig strategy = new StrategyConfig();
+//        strategy.setNaming(NamingStrategy.underline_to_camel);
+//        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+//        strategy.setEntityLombokModel(true);
+//        strategy.setRestControllerStyle(true);
+//
+//        // 需要生成哪些表的文件  在这里用,分开,这里生成的是style和room两个表
+//        strategy.setInclude(new String("video_catalog,video_info").split(","));
+//
+//        mpg.setStrategy(strategy);
+//        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
+//        mpg.execute();
+//
+//    }
+//}

+ 40 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/controller/VideoTreeController.java

@@ -1,12 +1,21 @@
 package cn.com.taiji.algorithm.controller;
 
 
+import cn.com.taiji.algorithm.model.TableDataInfo;
+import cn.com.taiji.algorithm.model.VideoCatalog;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
+import cn.com.taiji.algorithm.service.IVideoCatalogService;
+import cn.com.taiji.algorithm.service.IVideoInfoService;
 import cn.com.taiji.algorithm.service.IVideoTreeService;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 /**
  * <p>
  * 大屏预警记录表 前端控制器
@@ -22,8 +31,39 @@ public class VideoTreeController {
     @Autowired
     private IVideoTreeService treeService;
 
+    @Autowired
+    private IVideoInfoService videoInfoService;
+
+    @Autowired
+    private IVideoCatalogService videoCatalogService;
+
     @GetMapping("pull")
     public void pull() {
         treeService.httpsPost();
     }
+
+    @GetMapping("page")
+    public TableDataInfo page(Integer pageNum, Integer pageSize, String areaCode, String platformId, String taskName, Integer taskStatus,
+                              String sourceType, String algorithmType, String deviceId) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<VideoInfoDTO> infoDTOS = videoInfoService.queryVideoInfoPage(areaCode, platformId, taskName, taskStatus, sourceType, algorithmType, deviceId);
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(200);
+        rspData.setMsg("查询成功");
+        rspData.setRows(infoDTOS);
+        rspData.setTotal(new PageInfo(infoDTOS).getTotal());
+        return rspData;
+    }
+
+    @GetMapping("catalog")
+    public TableDataInfo catalog(Integer pageNum, Integer pageSize, String areaCode, String platformId) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<VideoCatalog> catalogs = videoCatalogService.queryCatalogPage(areaCode, platformId);
+        TableDataInfo rspData = new TableDataInfo();
+        rspData.setCode(200);
+        rspData.setMsg("查询成功");
+        rspData.setRows(catalogs);
+        rspData.setTotal(new PageInfo(catalogs).getTotal());
+        return rspData;
+    }
 }

+ 4 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/mapper/VideoCatalogMapper.java

@@ -1,7 +1,11 @@
 package cn.com.taiji.algorithm.mapper;
 
 import cn.com.taiji.algorithm.model.VideoCatalog;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>

+ 9 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/mapper/VideoInfoMapper.java

@@ -1,7 +1,11 @@
 package cn.com.taiji.algorithm.mapper;
 
 import cn.com.taiji.algorithm.model.VideoInfo;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -13,4 +17,9 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface VideoInfoMapper extends BaseMapper<VideoInfo> {
 
+    List<VideoInfoDTO> selectVideoInfoPage(@Param("areaCode") String areaCode, @Param("platformId") String platformId,
+                                           @Param("taskName") String taskName, @Param("taskStatus") Integer taskStatus,
+                                           @Param("sourceType") String sourceType, @Param("algorithmType") String algorithmType,
+                                           @Param("deviceId") String deviceId);
+
 }

+ 29 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/model/AlgorithmInfo.java

@@ -1,6 +1,8 @@
 package cn.com.taiji.algorithm.model;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 
@@ -15,20 +17,29 @@ import java.io.Serializable;
 @TableName ("algorithm_info")
 public class AlgorithmInfo implements Serializable {
 
+	/** ID */
+	@TableId("id")
+	@JSONField(serialize = false)
+	private Integer id;
+
 	/** 算法任务ID */
 	@TableField("task_id")
+	@JSONField(serialize = false)
 	private String taskId;
 
 	/** 任务类型:实时(realtime),历史(history),离线文件(file),RTSP流(rtsp)等。 */
 	@TableField("stream_type")
+	@JSONField(serialize = false)
 	private String streamType;
 
 	/** 数据源类型:视频(video)、图片(picture)。 */
 	@TableField("source_type")
+	@JSONField(serialize = false)
 	private String sourceType;
 
 	/** 算法类型,为镜像能力值的子集,随任务下发给算法容器。默认为镜像能力集。 */
 	@TableField("algorithm_type")
+	@JSONField(serialize = false)
 	private String algorithmType;
 
 	/** 算法任务名称。 */
@@ -37,6 +48,7 @@ public class AlgorithmInfo implements Serializable {
 
 	/** 算法任务所分析的摄像头点位ID,格式为点位ID##任务ID。 */
 	@TableField("camera_id")
+	@JSONField(serialize = false)
 	private String cameraId;
 
 	/** 任务启动状态。1:启动,0:停止。 */
@@ -45,54 +57,71 @@ public class AlgorithmInfo implements Serializable {
 
 	/** 该任务消耗的图片分析能力单位,默认QPS为1。 */
 	@TableField("picture_QPS")
+	@JSONField(serialize = false)
 	private String pictureQps;
 
 	/** 该任务消耗的视频分析能力单位,默认为1。 */
 	@TableField("capacity_ratio")
+	@JSONField(serialize = false)
 	private String capacityRatio;
 
 	/** 历史流或离线文件任务分析的开始时间,精确到秒,长度10位。 */
 	@TableField("start_time")
+	@JSONField(serialize = false)
 	private Long startTime;
 
 	/** 历史流任务分析的结束时间,精确到秒,长度10位。 */
 	@TableField("end_time")
+	@JSONField(serialize = false)
 	private Long endTime;
 
 	/** 历史流或离线文件任务的分析倍速,默认位1。 */
 	@TableField("scale")
+	@JSONField(serialize = false)
 	private Integer scale;
 
 	/** 视频文件对应的HTTP地址(分析时将通过该地址下载文件),或RTSP流地址。 */
 	@TableField("file_URL")
+	@JSONField(serialize = false)
 	private String fileUrl;
 
 	/** 下发该任务的算法仓ID。 */
 	@TableField("dispatch_repoId")
+	@JSONField(serialize = false)
 	private String dispatchRepoId;
 
 	/** 该任务执行的分时段调度策略ID。 */
 	@TableField("schedule_strategyId")
+	@JSONField(serialize = false)
 	private String scheduleStrategyId;
 
 	/** 任务可调度执行的算法仓ID列表,关联跨中心调度策略。 */
 	@TableField("schedule_repoIds")
+	@JSONField(serialize = false)
 	private String scheduleRepoIds;
 
 	/** 任务创建时间,为1970年1月1日0:0:0至今的毫秒。 */
 	@TableField("create_time")
+	@JSONField(serialize = false)
 	private Long createTime;
 
 	/** 任务信息最后更新时间,为1970年1月1日0:0:0至今的毫秒。 */
 	@TableField("update_time")
+	@JSONField(serialize = false)
 	private Long updateTime;
 
 	/** 随任务下发的自定义信息,例如线圈参数。 */
 	@TableField("user_data")
+	@JSONField(serialize = false)
 	private String userData;
 
 	/** 任务的容器ID,相同ID的任务会调度给相同的算法容器。一般为空 */
 	@TableField("task_group_containerId")
+	@JSONField(serialize = false)
 	private String taskGroupContainerId;
 
+	/** 监控国标编码 */
+	@TableField("device_id")
+	private String deviceId;
+
 }

+ 40 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/model/AlgorithmInfoDTO.java

@@ -0,0 +1,40 @@
+package cn.com.taiji.algorithm.model;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 算法信息
+ * @Author  yangyue
+ * @Date 2024/04/07 
+ */
+@Data
+public class AlgorithmInfoDTO implements Serializable {
+
+	/** 算法任务名称。 */
+	private String taskName;
+
+	/** 任务启动状态。1:启动,0:停止。 */
+	private Integer taskStatus;
+
+	/** 数据源类型:视频(video)、图片(picture)。 */
+	private String sourceType;
+
+	/** 算法类型,为镜像能力值的子集,随任务下发给算法容器。默认为镜像能力集。 */
+	private String algorithmType;
+
+	/** 算法任务所分析的摄像头点位ID,格式为点位ID##任务ID。 */
+	private String cameraId;
+
+	/** 视频文件对应的HTTP地址(分析时将通过该地址下载文件),或RTSP流地址。 */
+	private String fileUrl;
+
+	/** 监控国标编码 */
+	private String deviceId;
+
+}

+ 85 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/model/TableDataInfo.java

@@ -0,0 +1,85 @@
+package cn.com.taiji.algorithm.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 表格分页数据对象
+ *
+ * @author ruoyi
+ */
+public class TableDataInfo implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 总记录数 */
+    private long total;
+
+    /** 列表数据 */
+    private List<?> rows;
+
+    /** 消息状态码 */
+    private int code;
+
+    /** 消息内容 */
+    private String msg;
+
+    /**
+     * 表格数据对象
+     */
+    public TableDataInfo()
+    {
+    }
+
+    /**
+     * 分页
+     *
+     * @param list 列表数据
+     * @param total 总记录数
+     */
+    public TableDataInfo(List<?> list, int total)
+    {
+        this.rows = list;
+        this.total = total;
+    }
+
+    public long getTotal()
+    {
+        return total;
+    }
+
+    public void setTotal(long total)
+    {
+        this.total = total;
+    }
+
+    public List<?> getRows()
+    {
+        return rows;
+    }
+
+    public void setRows(List<?> rows)
+    {
+        this.rows = rows;
+    }
+
+    public int getCode()
+    {
+        return code;
+    }
+
+    public void setCode(int code)
+    {
+        this.code = code;
+    }
+
+    public String getMsg()
+    {
+        return msg;
+    }
+
+    public void setMsg(String msg)
+    {
+        this.msg = msg;
+    }
+}

+ 25 - 10
algorithm-service/src/main/java/cn/com/taiji/algorithm/model/VideoCatalog.java

@@ -1,5 +1,6 @@
 package cn.com.taiji.algorithm.model;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
@@ -19,6 +20,11 @@ import java.io.Serializable;
 @TableName ("video_catalog")
 public class VideoCatalog implements Serializable {
 
+	/** ID */
+	@TableId("id")
+	@JSONField(serialize = false)
+	private Integer id;
+
 	/** 行政区划编码 */
 	@TableField("area_code")
 	private String areaCode;
@@ -33,37 +39,46 @@ public class VideoCatalog implements Serializable {
 
 	/** 平台 ID */
 	@TableField("PlatformID")
-	private String platformId;
+	private Integer platformId;
 
 	/** 监控在线数 */
 	@TableField("OnlineCount")
-	private String onlineCount;
+	@JSONField(serialize = false)
+	private Integer onlineCount;
 
 	/** 监控总数 */
 	@TableField("Count")
-	private String count;
+	@JSONField(serialize = false)
+	private Integer count;
 
 	@TableField("level")
-	private String level;
+	@JSONField(serialize = false)
+	private Integer level;
 
 	@TableField("SecrecyCount")
-	private String secrecyCount;
+	@JSONField(serialize = false)
+	private Integer secrecyCount;
 
 	@TableField("gongansource")
-	private String gongansource;
+	@JSONField(serialize = false)
+	private Integer gongansource;
 
 	/** 监控故障数 */
 	@TableField("FaultCount")
-	private String faultCount;
+	@JSONField(serialize = false)
+	private Integer faultCount;
 
 	/** 监控可用数(在线无故障) */
 	@TableField("HealthCount")
-	private String healthCount;
+	@JSONField(serialize = false)
+	private Integer healthCount;
 
 	@TableField("Piccount")
-	private String piccount;
+	@JSONField(serialize = false)
+	private Integer piccount;
 
 	@TableField("RecommendCount")
-	private String recommendCount;
+	@JSONField(serialize = false)
+	private Integer recommendCount;
 
 }

+ 10 - 4
algorithm-service/src/main/java/cn/com/taiji/algorithm/model/VideoInfo.java

@@ -1,5 +1,6 @@
 package cn.com.taiji.algorithm.model;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
@@ -19,13 +20,18 @@ import java.io.Serializable;
 @TableName ("video_info")
 public class VideoInfo implements Serializable {
 
+	/** ID */
+	@TableId("id")
+	@JSONField(serialize = false)
+	private Integer id;
+
 	/** 监控接入服务器主消息号(调流时使用) */
 	@TableField("groupId")
-	private Integer groupId;
+	private String groupId;
 
 	/** 监控通道号(调流时使用) */
 	@TableField("monitorId")
-	private Integer monitorId;
+	private String monitorId;
 
 	/** 监控名称 */
 	@TableField("monitorName")
@@ -65,11 +71,11 @@ public class VideoInfo implements Serializable {
 
 	/** 监控国标编码 */
 	@TableField("DeviceId")
-	private Integer deviceId;
+	private String deviceId;
 
 	/** 平台 ID */
 	@TableField("PlatformId")
-	private Integer platformId;
+	private String platformId;
 
 	/** 需要监控平台开启巡检,巡检之后才知道具体格式
 空:未巡检到或无法识别

+ 39 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/model/VideoInfoDTO.java

@@ -0,0 +1,39 @@
+package cn.com.taiji.algorithm.model;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Description 
+ * @Author  yangyue
+ * @Date 2024/04/01 
+ */
+@Data
+public class VideoInfoDTO implements Serializable {
+
+	/** 监控名称 */
+	private String monitorName;
+
+	/** 区域编码 */
+	private String areaCode;
+
+	/** 纬度 */
+	private String latitude;
+
+	/** 经度 */
+	private String longitude;
+
+	/** 监控国标编码 */
+	private String deviceId;
+
+	/** 平台 ID */
+	private String platformId;
+
+	private List<AlgorithmInfoDTO>  algorithmInfos;
+
+}

+ 5 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/service/IVideoCatalogService.java

@@ -1,8 +1,11 @@
 package cn.com.taiji.algorithm.service;
 
 import cn.com.taiji.algorithm.model.VideoCatalog;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * <p>
  *  服务类
@@ -13,4 +16,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IVideoCatalogService extends IService<VideoCatalog> {
 
+    List<VideoCatalog> queryCatalogPage(String areaCode, String platformId);
+
 }

+ 6 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/service/IVideoInfoService.java

@@ -1,8 +1,11 @@
 package cn.com.taiji.algorithm.service;
 
 import cn.com.taiji.algorithm.model.VideoInfo;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * <p>
  *  服务类
@@ -13,4 +16,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IVideoInfoService extends IService<VideoInfo> {
 
+    List<VideoInfoDTO> queryVideoInfoPage(String areaCode, String platformId, String taskName, Integer taskStatus,
+                                          String sourceType, String algorithmType, String deviceId);
+
 }

+ 3 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/service/IVideoTreeService.java

@@ -1,6 +1,9 @@
 package cn.com.taiji.algorithm.service;
 
 
+import cn.com.taiji.algorithm.model.AlgorithmInfo;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
+
 import java.time.LocalDate;
 import java.util.List;
 

+ 15 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/service/impl/VideoCatalogServiceImpl.java

@@ -2,10 +2,16 @@ package cn.com.taiji.algorithm.service.impl;
 
 import cn.com.taiji.algorithm.model.VideoCatalog;
 import cn.com.taiji.algorithm.mapper.VideoCatalogMapper;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
 import cn.com.taiji.algorithm.service.IVideoCatalogService;
+import cn.com.taiji.algorithm.utils.StringUtils;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * <p>
  *  服务实现类
@@ -17,4 +23,13 @@ import org.springframework.stereotype.Service;
 @Service
 public class VideoCatalogServiceImpl extends ServiceImpl<VideoCatalogMapper, VideoCatalog> implements IVideoCatalogService {
 
+    @Autowired
+    private VideoCatalogMapper catalogMapper;
+
+    @Override
+    public List<VideoCatalog> queryCatalogPage(String areaCode, String platformId) {
+        return catalogMapper.selectList(new LambdaQueryWrapper<VideoCatalog>()
+                .eq(StringUtils.isNotEmpty(areaCode),VideoCatalog::getAreaCode,areaCode)
+                .eq(StringUtils.isNotEmpty(platformId),VideoCatalog::getPlatformId,platformId));
+    }
 }

+ 12 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/service/impl/VideoInfoServiceImpl.java

@@ -2,10 +2,14 @@ package cn.com.taiji.algorithm.service.impl;
 
 import cn.com.taiji.algorithm.model.VideoInfo;
 import cn.com.taiji.algorithm.mapper.VideoInfoMapper;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
 import cn.com.taiji.algorithm.service.IVideoInfoService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * <p>
  *  服务实现类
@@ -17,4 +21,12 @@ import org.springframework.stereotype.Service;
 @Service
 public class VideoInfoServiceImpl extends ServiceImpl<VideoInfoMapper, VideoInfo> implements IVideoInfoService {
 
+    @Autowired
+    private VideoInfoMapper videoInfoMapper;
+
+    @Override
+    public List<VideoInfoDTO> queryVideoInfoPage(String areaCode, String platformId, String taskName, Integer taskStatus,
+                                                 String sourceType, String algorithmType, String deviceId) {
+        return videoInfoMapper.selectVideoInfoPage(areaCode, platformId, taskName, taskStatus, sourceType, algorithmType, deviceId);
+    }
 }

+ 71 - 15
algorithm-service/src/main/java/cn/com/taiji/algorithm/service/impl/VideoTreeServiceImpl.java

@@ -2,10 +2,14 @@ package cn.com.taiji.algorithm.service.impl;
 
 
 import cn.com.taiji.algorithm.model.VideoCatalog;
+import cn.com.taiji.algorithm.model.VideoInfo;
+import cn.com.taiji.algorithm.model.VideoInfoDTO;
 import cn.com.taiji.algorithm.service.IVideoCatalogService;
+import cn.com.taiji.algorithm.service.IVideoInfoService;
 import cn.com.taiji.algorithm.service.IVideoTreeService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -35,6 +39,9 @@ public class VideoTreeServiceImpl implements IVideoTreeService {
     @Autowired
     private IVideoCatalogService catalogService;
 
+    @Autowired
+    private IVideoInfoService videoInfoService;
+
     @Value("${taiji.clientId}")
     private String clientId;
 
@@ -69,10 +76,10 @@ public class VideoTreeServiceImpl implements IVideoTreeService {
 
         String parentCode = "0";
         String platformid = "0";
-        String deviceUrl = url + "/api/CommonApi/GetOrganizationList?client_id="+clientId+"&parentCode="+parentCode+"&platformid="+platformid;
+        String catalogUrl = url + "/api/CommonApi/GetOrganizationList?client_id="+clientId+"&parentCode="+parentCode+"&platformid="+platformid;
 
         // log.info(deviceUrl);
-        ResponseEntity<JSONObject> exchange = restTemplate.exchange(deviceUrl, HttpMethod.GET, reqEntity,JSONObject.class);
+        ResponseEntity<JSONObject> exchange = restTemplate.exchange(catalogUrl, HttpMethod.GET, reqEntity,JSONObject.class);
         log.info(exchange.getBody().toString());
         JSONObject resData = exchange.getBody();
         JSONArray jsonArray = resData.getJSONArray("List");
@@ -83,36 +90,85 @@ public class VideoTreeServiceImpl implements IVideoTreeService {
             //     // catalogService.saveOrUpdate(o,new LambdaQueryWrapper<VideoCatalog>()
             //     //         .eq(VideoCatalog::getPlatformId, o.getPlatformId()));
             // });
-            getChildNodes(restTemplate,reqEntity,catalogs,url + "/api/CommonApi/GetOrganizationList?client_id="+clientId);
-            catalogService.saveBatch(orgChildNodes);
+            catalogArrayList.clear();
+            getChildNodes(restTemplate, reqEntity, catalogs, url + "/api/CommonApi/GetOrganizationList?client_id=" + clientId);
+
+
+            catalogArrayList.forEach(videoCatalog -> {
+                catalogService.saveOrUpdate(videoCatalog,new LambdaQueryWrapper<VideoCatalog>()
+                        .eq(VideoCatalog::getAreaCode,videoCatalog.getAreaCode())
+                        .eq(VideoCatalog::getPlatformId,videoCatalog.getPlatformId()));
+            });
+            log.info("长度:{}", catalogArrayList.size());
         }
-    }
 
+        List<VideoCatalog> list = catalogService.list();
+        if (null != list && list.size() > 0) {
+            String deviceUrl = url + "/api/CommonApi/GetMonitorByOrganization?pageSize=100&client_id="+clientId;
+            list.forEach(videoCatalog -> {
+                int page = 1;
+                String videoInfoUrl = deviceUrl + "&organizationcode="+videoCatalog.getAreaCode()+"&platformid="+videoCatalog.getPlatformId()+"&page="+page;
+                ResponseEntity<JSONObject> devicList = restTemplate.exchange(videoInfoUrl, HttpMethod.GET, reqEntity,JSONObject.class);
+                int count = devicList.getBody().getIntValue("Count");
+                log.info("数量:{}", count);
+                if (count > 0) {
+
+                    JSONArray videoInfoArray = devicList.getBody().getJSONArray("List");
+                    List<VideoInfo> videoInfos = JSONArray.parseArray(videoInfoArray.toJSONString(), VideoInfo.class);
+                    int i = (count - 1) / 100 + 1;
+                    for (int j = 2 ; j <= i ; j++) {
+                        getdevices(restTemplate, reqEntity, videoInfos, deviceUrl + "&organizationcode="+videoCatalog.getAreaCode()+"&platformid="+videoCatalog.getPlatformId()+"&page="+j);
+                    }
+                    if (null != videoInfos && videoInfos.size() > 0) {
+//                        videoInfoService.saveBatch(videoInfos);
+                        videoInfos.forEach(videoInfo -> {
+                            videoInfoService.saveOrUpdate(videoInfo,new LambdaQueryWrapper<VideoInfo>()
+                                    .eq(VideoInfo::getAreaCode,videoInfo.getAreaCode())
+                                    .eq(VideoInfo::getDeviceId,videoInfo.getDeviceId()));
+                        });
+                    }
+                }
+            });
+        }
+    }
 
 
-    public static List<VideoCatalog> orgChildNodes = new ArrayList<VideoCatalog>();
+    public static List<VideoCatalog> catalogArrayList = new ArrayList<VideoCatalog>();
 
     //根据父节点递归所有子节点
     public void getChildNodes(RestTemplate restTemplate, HttpEntity reqEntity, List<VideoCatalog> list, String url) {
         for (VideoCatalog catalog : list) {
 
-            orgChildNodes.add(catalog);
+            catalogArrayList.add(catalog);
             String catalogUrl = url + "&parentCode="+catalog.getAreaCode()+"&platformid="+catalog.getPlatformId();
             ResponseEntity<JSONObject> exchange = restTemplate.exchange(catalogUrl, HttpMethod.GET, reqEntity,JSONObject.class);
             log.info(exchange.getBody().toString());
             JSONObject resData = exchange.getBody();
             JSONArray jsonArray = resData.getJSONArray("List");
             List<VideoCatalog> catalogs = JSONArray.parseArray(jsonArray.toJSONString(), VideoCatalog.class);
-            for (VideoCatalog log : catalogs) {
-                //遍历出父id等于参数的id,add进子节点集合
-                if (catalog.getParentCode().equals(log.getParentCode())) {
-                    //递归遍历下一级
-                    getChildNodes(restTemplate,reqEntity,list,url);
-                    // orgChildNodes.add(log);
-                }
+            if (catalogs.size() > 0) {
+//                for (VideoCatalog log : catalogs) {
+//                    //遍历出父id等于参数的id,add进子节点集合
+//                    if (catalog.getAreaCode().equals(log.getParentCode())) {
+//                        //递归遍历下一级
+//                        getChildNodes(restTemplate,reqEntity,catalogs,url);
+//                        // orgChildNodes.add(log);
+//                    }
+//                }
+                //递归遍历下一级
+                getChildNodes(restTemplate,reqEntity,catalogs,url);
             }
         }
-        // return orgChildNodes;
+//         return catalogArrayList;
+    }
+
+    public void getdevices(RestTemplate restTemplate, HttpEntity reqEntity, List<VideoInfo> list, String url) {
+        ResponseEntity<JSONObject> devicList = restTemplate.exchange(url, HttpMethod.GET, reqEntity,JSONObject.class);
+        JSONArray videoInfoArray = devicList.getBody().getJSONArray("List");
+        List<VideoInfo> videoInfos = JSONArray.parseArray(videoInfoArray.toJSONString(), VideoInfo.class);
+        if (null != videoInfos && videoInfos.size() > 0) {
+            list.addAll(videoInfos);
+        }
     }
 
 }

+ 99 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/task/AlgorithmTask.java

@@ -0,0 +1,99 @@
+package cn.com.taiji.algorithm.task;
+
+
+import cn.com.taiji.algorithm.model.AlgorithmInfo;
+import cn.com.taiji.algorithm.model.VideoCatalog;
+import cn.com.taiji.algorithm.model.VideoInfo;
+import cn.com.taiji.algorithm.service.IAlgorithmInfoService;
+import cn.com.taiji.algorithm.service.IVideoCatalogService;
+import cn.com.taiji.algorithm.service.IVideoInfoService;
+import cn.com.taiji.algorithm.utils.StringUtils;
+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.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description
+ *
+ * @Author  yangyue
+ * @Date 2021/11/18
+ */
+
+@Component
+@Slf4j
+public class AlgorithmTask {
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private IAlgorithmInfoService algorithmInfoService;
+
+    @Scheduled(cron = "0 0 0/1 * * ?")
+    public void httpsPost() {
+        String url = "http://10.110.74.237:9499/algorepo/tasks?query=param";
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
+        HttpEntity reqEntity = new HttpEntity(headers);
+
+        ResponseEntity<JSONObject> exchange = restTemplate.exchange(url, HttpMethod.GET, reqEntity,JSONObject.class);
+//        log.info(exchange.getBody().toString());
+        JSONObject resData = exchange.getBody();
+        /**
+         * {
+         *     "msg": "OK",
+         *     "totalSize": 168,
+         *     "data": [
+         *         {
+         *             "imageId": "c5c5f94b577b4594ab1ab4d336e7843b",
+         *             "imageName": "tqvc/tianying",
+         *             "imageTag": "2.4.19-2.3.6.ga",
+         *             "vendorName": "alibaba_test",
+         *             "taskGroups": [
+         *                 {
+         *                     "groupId": "test",
+         *                     "taskInfos": [
+         */
+        Integer totalSize = resData.getInteger("totalSize");
+        if (totalSize != null && totalSize > 0) {
+            JSONArray data = resData.getJSONArray("data");
+            data.stream().forEach(item -> {
+                JSONArray groups = JSONObject.parseObject(JSONObject.toJSONString(item)).getJSONArray("taskGroups");
+                if (groups != null && groups.size() > 0) {
+                    groups.stream().forEach(task -> {
+                        JSONArray infos = JSONObject.parseObject(JSONObject.toJSONString(task)).getJSONArray("taskInfos");
+                        List<AlgorithmInfo> list = JSONArray.parseArray(infos.toJSONString(), AlgorithmInfo.class);
+                        if (null != list && list.size() > 0) {
+                            list.stream().forEach(algorithm -> {
+                                JSONArray array = JSONObject.parseArray(algorithm.getAlgorithmType());
+                                String[] strs = new String[array.size()];
+                                String[] strings = array.toArray(strs);
+                                algorithm.setAlgorithmType(StringUtils.join(strings,","));
+                                algorithm.setDeviceId(algorithm.getCameraId().substring(0,algorithm.getCameraId().indexOf("##")));
+                                algorithmInfoService.saveOrUpdate(algorithm,new LambdaQueryWrapper<AlgorithmInfo>()
+                                        .eq(AlgorithmInfo::getTaskId,algorithm.getTaskId()));
+                            });
+                        }
+                    });
+                }
+            });
+        }
+    }
+
+}

+ 74 - 15
algorithm-service/src/main/java/cn/com/taiji/algorithm/task/Videotask.java

@@ -2,9 +2,12 @@ package cn.com.taiji.algorithm.task;
 
 
 import cn.com.taiji.algorithm.model.VideoCatalog;
+import cn.com.taiji.algorithm.model.VideoInfo;
 import cn.com.taiji.algorithm.service.IVideoCatalogService;
+import cn.com.taiji.algorithm.service.IVideoInfoService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -36,6 +39,9 @@ public class Videotask {
     @Autowired
     private IVideoCatalogService catalogService;
 
+    @Autowired
+    private IVideoInfoService videoInfoService;
+
     @Value("${taiji.clientId}")
     private String clientId;
 
@@ -70,10 +76,10 @@ public class Videotask {
 
         String parentCode = "0";
         String platformid = "0";
-        String deviceUrl = url + "/api/CommonApi/GetOrganizationList?client_id="+clientId+"&parentCode="+parentCode+"&platformid="+platformid;
+        String catalogUrl = url + "/api/CommonApi/GetOrganizationList?client_id="+clientId+"&parentCode="+parentCode+"&platformid="+platformid;
 
         // log.info(deviceUrl);
-        ResponseEntity<JSONObject> exchange = restTemplate.exchange(deviceUrl, HttpMethod.GET, reqEntity,JSONObject.class);
+        ResponseEntity<JSONObject> exchange = restTemplate.exchange(catalogUrl, HttpMethod.GET, reqEntity,JSONObject.class);
         log.info(exchange.getBody().toString());
         JSONObject resData = exchange.getBody();
         JSONArray jsonArray = resData.getJSONArray("List");
@@ -84,33 +90,86 @@ public class Videotask {
             //     // catalogService.saveOrUpdate(o,new LambdaQueryWrapper<VideoCatalog>()
             //     //         .eq(VideoCatalog::getPlatformId, o.getPlatformId()));
             // });
-            getChildNodes(restTemplate,reqEntity,catalogs,url + "/api/CommonApi/GetOrganizationList?client_id="+clientId);
-            catalogService.saveBatch(orgChildNodes);
+            catalogArrayList.clear();
+            getChildNodes(restTemplate, reqEntity, catalogs, url + "/api/CommonApi/GetOrganizationList?client_id=" + clientId);
+
+
+            catalogArrayList.forEach(videoCatalog -> {
+                catalogService.saveOrUpdate(videoCatalog,new LambdaQueryWrapper<VideoCatalog>()
+                        .eq(VideoCatalog::getAreaCode,videoCatalog.getAreaCode())
+                        .eq(VideoCatalog::getPlatformId,videoCatalog.getPlatformId()));
+            });
+            log.info("长度:{}", catalogArrayList.size());
+        }
+
+        List<VideoCatalog> list = catalogService.list();
+        if (null != list && list.size() > 0) {
+            String deviceUrl = url + "/api/CommonApi/GetMonitorByOrganization?pageSize=100&client_id="+clientId;
+            list.forEach(videoCatalog -> {
+                int page = 1;
+                String videoInfoUrl = deviceUrl + "&organizationcode="+videoCatalog.getAreaCode()+"&platformid="+videoCatalog.getPlatformId()+"&page="+page;
+                ResponseEntity<JSONObject> devicList = restTemplate.exchange(videoInfoUrl, HttpMethod.GET, reqEntity,JSONObject.class);
+                int count = devicList.getBody().getIntValue("Count");
+                log.info("数量:{}", count);
+                if (count > 0) {
+
+                    JSONArray videoInfoArray = devicList.getBody().getJSONArray("List");
+                    List<VideoInfo> videoInfos = JSONArray.parseArray(videoInfoArray.toJSONString(), VideoInfo.class);
+                    int i = (count - 1) / 100 + 1;
+                    for (int j = 2 ; j <= i ; j++) {
+                        getdevices(restTemplate, reqEntity, videoInfos, deviceUrl + "&organizationcode="+videoCatalog.getAreaCode()+"&platformid="+videoCatalog.getPlatformId()+"&page="+j);
+                    }
+                    if (null != videoInfos && videoInfos.size() > 0) {
+//                        videoInfoService.saveBatch(videoInfos);
+                        videoInfos.forEach(videoInfo -> {
+                            videoInfoService.saveOrUpdate(videoInfo,new LambdaQueryWrapper<VideoInfo>()
+                                    .eq(VideoInfo::getAreaCode,videoInfo.getAreaCode())
+                                    .eq(VideoInfo::getDeviceId,videoInfo.getDeviceId()));
+                        });
+                    }
+                }
+            });
         }
     }
 
-    public static List<VideoCatalog> orgChildNodes = new ArrayList<VideoCatalog>();
+
+
+    public static List<VideoCatalog> catalogArrayList = new ArrayList<VideoCatalog>();
 
     //根据父节点递归所有子节点
-    public static List<VideoCatalog> getChildNodes(RestTemplate restTemplate, HttpEntity reqEntity, List<VideoCatalog> list, String url) {
+    public void getChildNodes(RestTemplate restTemplate, HttpEntity reqEntity, List<VideoCatalog> list, String url) {
         for (VideoCatalog catalog : list) {
-            orgChildNodes.add(catalog);
+
+            catalogArrayList.add(catalog);
             String catalogUrl = url + "&parentCode="+catalog.getAreaCode()+"&platformid="+catalog.getPlatformId();
             ResponseEntity<JSONObject> exchange = restTemplate.exchange(catalogUrl, HttpMethod.GET, reqEntity,JSONObject.class);
             log.info(exchange.getBody().toString());
             JSONObject resData = exchange.getBody();
             JSONArray jsonArray = resData.getJSONArray("List");
             List<VideoCatalog> catalogs = JSONArray.parseArray(jsonArray.toJSONString(), VideoCatalog.class);
-            for (VideoCatalog log : catalogs) {
-                //遍历出父id等于参数的id,add进子节点集合
-                if (catalog.getParentCode().equals(log.getParentCode())) {
-                    //递归遍历下一级
-                    getChildNodes(restTemplate,reqEntity,list,url);
-                    orgChildNodes.add(log);
-                }
+            if (catalogs.size() > 0) {
+//                for (VideoCatalog log : catalogs) {
+//                    //遍历出父id等于参数的id,add进子节点集合
+//                    if (catalog.getAreaCode().equals(log.getParentCode())) {
+//                        //递归遍历下一级
+//                        getChildNodes(restTemplate,reqEntity,catalogs,url);
+//                        // orgChildNodes.add(log);
+//                    }
+//                }
+                //递归遍历下一级
+                getChildNodes(restTemplate,reqEntity,catalogs,url);
             }
         }
-        return orgChildNodes;
+//         return catalogArrayList;
+    }
+
+    public void getdevices(RestTemplate restTemplate, HttpEntity reqEntity, List<VideoInfo> list, String url) {
+        ResponseEntity<JSONObject> devicList = restTemplate.exchange(url, HttpMethod.GET, reqEntity,JSONObject.class);
+        JSONArray videoInfoArray = devicList.getBody().getJSONArray("List");
+        List<VideoInfo> videoInfos = JSONArray.parseArray(videoInfoArray.toJSONString(), VideoInfo.class);
+        if (null != videoInfos && videoInfos.size() > 0) {
+            list.addAll(videoInfos);
+        }
     }
 
 }

+ 459 - 0
algorithm-service/src/main/java/cn/com/taiji/algorithm/utils/StringUtils.java

@@ -0,0 +1,459 @@
+package cn.com.taiji.algorithm.utils;
+
+
+import cn.hutool.core.text.StrFormatter;
+
+import java.util.*;
+
+/**
+ * 字符串工具类
+ *
+ * @author seat
+ */
+public class StringUtils extends org.apache.commons.lang3.StringUtils
+{
+    /** 空字符串 */
+    private static final String NULLSTR = "";
+
+    /** 下划线 */
+    private static final char SEPARATOR = '_';
+    private static final String XIA = "_";
+
+    /**
+     * 获取参数不为空值
+     *
+     * @param value defaultValue 要判断的value
+     * @return value 返回值
+     */
+    public static <T> T nvl(T value, T defaultValue)
+    {
+        return value != null ? value : defaultValue;
+    }
+
+    /**
+     * * 判断一个Collection是否为空, 包含List,Set,Queue
+     *
+     * @param coll 要判断的Collection
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Collection<?> coll)
+    {
+        return isNull(coll) || coll.isEmpty();
+    }
+
+    /**
+     * * 判断一个Collection是否非空,包含List,Set,Queue
+     *
+     * @param coll 要判断的Collection
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Collection<?> coll)
+    {
+        return !isEmpty(coll);
+    }
+
+    /**
+     * * 判断一个对象数组是否为空
+     *
+     * @param objects 要判断的对象数组
+     ** @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Object[] objects)
+    {
+        return isNull(objects) || (objects.length == 0);
+    }
+
+    /**
+     * * 判断一个对象数组是否非空
+     *
+     * @param objects 要判断的对象数组
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Object[] objects)
+    {
+        return !isEmpty(objects);
+    }
+
+    /**
+     * * 判断一个Map是否为空
+     *
+     * @param map 要判断的Map
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Map<?, ?> map)
+    {
+        return isNull(map) || map.isEmpty();
+    }
+
+    /**
+     * * 判断一个Map是否为空
+     *
+     * @param map 要判断的Map
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Map<?, ?> map)
+    {
+        return !isEmpty(map);
+    }
+
+    /**
+     * * 判断一个字符串是否为空串
+     *
+     * @param str String
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(String str)
+    {
+        return isNull(str) || NULLSTR.equals(str.trim());
+    }
+
+    /**
+     * * 判断一个字符串是否为非空串
+     *
+     * @param str String
+     * @return true:非空串 false:空串
+     */
+    public static boolean isNotEmpty(String str)
+    {
+        return !isEmpty(str);
+    }
+
+    /**
+     * * 判断一个对象是否为空
+     *
+     * @param object Object
+     * @return true:为空 false:非空
+     */
+    public static boolean isNull(Object object)
+    {
+        return object == null;
+    }
+
+    /**
+     * * 判断一个对象是否非空
+     *
+     * @param object Object
+     * @return true:非空 false:空
+     */
+    public static boolean isNotNull(Object object)
+    {
+        return !isNull(object);
+    }
+
+    /**
+     * * 判断一个对象是否是数组类型(Java基本型别的数组)
+     *
+     * @param object 对象
+     * @return true:是数组 false:不是数组
+     */
+    public static boolean isArray(Object object)
+    {
+        return isNotNull(object) && object.getClass().isArray();
+    }
+
+    /**
+     * 去空格
+     */
+    public static String trim(String str)
+    {
+        return (str == null ? "" : str.trim());
+    }
+
+    /**
+     * 截取字符串
+     *
+     * @param str 字符串
+     * @param start 开始
+     * @return 结果
+     */
+    public static String substring(final String str, int start)
+    {
+        if (str == null)
+        {
+            return NULLSTR;
+        }
+
+        if (start < 0)
+        {
+            start = str.length() + start;
+        }
+
+        if (start < 0)
+        {
+            start = 0;
+        }
+        if (start > str.length())
+        {
+            return NULLSTR;
+        }
+
+        return str.substring(start);
+    }
+
+    /**
+     * 截取字符串
+     *
+     * @param str 字符串
+     * @param start 开始
+     * @param end 结束
+     * @return 结果
+     */
+    public static String substring(final String str, int start, int end)
+    {
+        if (str == null)
+        {
+            return NULLSTR;
+        }
+
+        if (end < 0)
+        {
+            end = str.length() + end;
+        }
+        if (start < 0)
+        {
+            start = str.length() + start;
+        }
+
+        if (end > str.length())
+        {
+            end = str.length();
+        }
+
+        if (start > end)
+        {
+            return NULLSTR;
+        }
+
+        if (start < 0)
+        {
+            start = 0;
+        }
+        if (end < 0)
+        {
+            end = 0;
+        }
+
+        return str.substring(start, end);
+    }
+
+    /**
+     * 格式化文本, {} 表示占位符<br>
+     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
+     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
+     * 例:<br>
+     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
+     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
+     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
+     *
+     * @param template 文本模板,被替换的部分用 {} 表示
+     * @param params 参数值
+     * @return 格式化后的文本
+     */
+    public static String format(String template, Object... params)
+    {
+        if (isEmpty(params) || isEmpty(template))
+        {
+            return template;
+        }
+        return StrFormatter.format(template, params);
+    }
+
+    /**
+     * 字符串转set
+     *
+     * @param str 字符串
+     * @param sep 分隔符
+     * @return set集合
+     */
+    public static final Set<String> str2Set(String str, String sep)
+    {
+        return new HashSet<String>(str2List(str, sep, true, false));
+    }
+
+    /**
+     * 字符串转list
+     *
+     * @param str 字符串
+     * @param sep 分隔符
+     * @param filterBlank 过滤纯空白
+     * @param trim 去掉首尾空白
+     * @return list集合
+     */
+    public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
+    {
+        List<String> list = new ArrayList<String>();
+        if (StringUtils.isEmpty(str))
+        {
+            return list;
+        }
+
+        // 过滤空白字符串
+        if (filterBlank && StringUtils.isBlank(str))
+        {
+            return list;
+        }
+        String[] split = str.split(sep);
+        for (String string : split)
+        {
+            if (filterBlank && StringUtils.isBlank(string))
+            {
+                continue;
+            }
+            if (trim)
+            {
+                string = string.trim();
+            }
+            list.add(string);
+        }
+
+        return list;
+    }
+
+    /**
+     * 驼峰转下划线命名
+     */
+    public static String toUnderScoreCase(String str)
+    {
+        if (str == null)
+        {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        // 前置字符是否大写
+        boolean preCharIsUpperCase = true;
+        // 当前字符是否大写
+        boolean curreCharIsUpperCase = true;
+        // 下一字符是否大写
+        boolean nexteCharIsUpperCase = true;
+        for (int i = 0; i < str.length(); i++)
+        {
+            char c = str.charAt(i);
+            if (i > 0)
+            {
+                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
+            }
+            else
+            {
+                preCharIsUpperCase = false;
+            }
+
+            curreCharIsUpperCase = Character.isUpperCase(c);
+
+            if (i < (str.length() - 1))
+            {
+                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
+            }
+
+            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
+            {
+                sb.append(SEPARATOR);
+            }
+            else if (i != 0 && !preCharIsUpperCase)
+            {
+                if (curreCharIsUpperCase){
+                    sb.append(SEPARATOR);
+                }
+            }
+            sb.append(Character.toLowerCase(c));
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * 是否包含字符串
+     *
+     * @param str 验证字符串
+     * @param strs 字符串组
+     * @return 包含返回true
+     */
+    public static boolean inStringIgnoreCase(String str, String... strs)
+    {
+        if (str != null && strs != null)
+        {
+            for (String s : strs)
+            {
+                if (str.equalsIgnoreCase(trim(s)))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
+     *
+     * @param name 转换前的下划线大写方式命名的字符串
+     * @return 转换后的驼峰式命名的字符串
+     */
+    public static String convertToCamelCase(String name)
+    {
+        StringBuilder result = new StringBuilder();
+        // 快速检查
+        if (name == null || name.isEmpty())
+        {
+            // 没必要转换
+            return "";
+        }
+        else if (!name.contains(XIA))
+        {
+            // 不含下划线,仅将首字母大写
+            return name.substring(0, 1).toUpperCase() + name.substring(1);
+        }
+        // 用下划线将原始字符串分割
+        String[] camels = name.split("_");
+        for (String camel : camels)
+        {
+            // 跳过原始字符串中开头、结尾的下换线或双重下划线
+            if (camel.isEmpty())
+            {
+                continue;
+            }
+            // 首字母大写
+            result.append(camel.substring(0, 1).toUpperCase());
+            result.append(camel.substring(1).toLowerCase());
+        }
+        return result.toString();
+    }
+
+    /**
+     * 驼峰式命名法 例如:user_name->userName
+     */
+    public static String toCamelCase(String s)
+    {
+        if (s == null)
+        {
+            return null;
+        }
+        s = s.toLowerCase();
+        StringBuilder sb = new StringBuilder(s.length());
+        boolean upperCase = false;
+        for (int i = 0; i < s.length(); i++)
+        {
+            char c = s.charAt(i);
+
+            if (c == SEPARATOR)
+            {
+                upperCase = true;
+            }
+            else if (upperCase)
+            {
+                sb.append(Character.toUpperCase(c));
+                upperCase = false;
+            }
+            else
+            {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T cast(Object obj)
+    {
+        return (T) obj;
+    }
+}

+ 15 - 1
algorithm-service/src/main/resources/application.yml

@@ -54,9 +54,23 @@ mybatis-plus:
       logic-delete-value: 1
       # 逻辑未删除值(默认为 0)
       logic-not-delete-value: 0
-      id-type: assign_id
+      id-type: auto
       update-strategy: not_empty
     banner: false   # 不打印banner
+# PageHelper分页插件
+pagehelper:
+  helperDialect: mysql
+  reasonable: true
+  supportMethodsArguments: true
+  offsetAsPageNum: true
+  rowBoundsWithCount: true
+  params: count=countSql
+logging:
+  # 本地开发环境通过level控制
+  level:
+    root: info
+    cn.com.taiji: debug
+    org.springframework.web: debug
 taiji:
 #  17
 #  clientId: 8c4eae47a0e64854b78952e8da18caf2

+ 42 - 0
algorithm-service/src/main/resources/mapper/VideoInfoMapper.xml

@@ -22,4 +22,46 @@
         <result column="HLSUrl" property="hlsurl" />
     </resultMap>
 
+    <resultMap id="VideoInfoDTOMap" type="cn.com.taiji.algorithm.model.VideoInfoDTO">
+        <result column="monitorName" property="monitorName" />
+        <result column="AreaCode" property="areaCode" />
+        <result column="Latitude" property="latitude" />
+        <result column="Longitude" property="longitude" />
+        <result column="DeviceId" property="deviceId" />
+        <result column="PlatformId" property="platformId" />
+        <collection property="algorithmInfos" ofType="AlgorithmInfoDTO">
+            <result column="task_name" property="taskName" />
+            <result column="task_status" property="taskStatus" />
+            <result column="source_type" property="sourceType" />
+            <result column="algorithm_type" property="algorithmType" />
+            <result column="camera_id" property="cameraId" />
+            <result column="file_URL" property="fileUrl" />
+            <result column="device_id" property="deviceId" />
+        </collection>
+    </resultMap>
+
+    <select id="selectVideoInfoPage_COUNT" resultType="Long">
+        select count(1)
+        from video_info
+        <where>
+            <if test="areaCode != null and areaCode != ''">and AreaCode = #{areaCode}</if>
+            <if test="platformId != null and platformId != ''">and PlatformId = #{platformId}</if>
+        </where>
+    </select>
+
+    <select id="selectVideoInfoPage" resultMap="VideoInfoDTOMap">
+        select v.monitorName,v.AreaCode,v.Latitude,v.Longitude,v.DeviceId,v.PlatformId,
+               a.task_name,a.task_status,a.source_type,a.algorithm_type,a.camera_id,a.file_URL,a.device_id
+        from video_info v left join algorithm_info a on v.DeviceId = a.device_id
+        <where>
+            <if test="areaCode != null and areaCode != ''">and v.AreaCode = #{areaCode}</if>
+            <if test="platformId != null and platformId != ''">and v.PlatformId = #{platformId}</if>
+            <if test="taskName != null and taskName != ''">and a.task_name = #{taskName}</if>
+            <if test="taskStatus != null">and a.task_status = #{taskStatus}</if>
+            <if test="sourceType != null and sourceType != ''">and a.source_type = #{sourceType}</if>
+            <if test="algorithmType != null and algorithmType != ''">and FIND_IN_SET(#{algorithmType},a.algorithm_type)</if>
+            <if test="deviceId != null and deviceId != ''">and a.device_id = #{deviceId}</if>
+        </where>
+    </select>
+
 </mapper>