Эх сурвалжийг харах

Merge branch 'master' of http://60.171.161.56:20000/tjf/deviceManage

wangmengwei 1 өдөр өмнө
parent
commit
e1e5ba8e50
47 өөрчлөгдсөн 2087 нэмэгдсэн , 790 устгасан
  1. BIN
      AudioFile/123.pcm
  2. 0 0
      AudioFile/DecodeSaveData.pcm
  3. BIN
      AudioFile/DeviceSaveData.g711
  4. 0 0
      AudioFile/此文件夹中放入发送给设备的音频文件.txt
  5. 0 94
      README.md
  6. 0 12
      bin/clean.bat
  7. 0 12
      bin/package.bat
  8. 0 14
      bin/run.bat
  9. BIN
      doc/若依环境使用手册.docx
  10. 0 7
      pom.xml
  11. 0 11
      ruoyi-admin/pom.xml
  12. 91 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/manage/AlgorithmSetController.java
  13. 3 3
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/manage/TaskManageController.java
  14. 0 147
      ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java
  15. 124 124
      ruoyi-admin/src/main/resources/application-druid.yml
  16. 2 2
      ruoyi-admin/src/main/resources/application.yml
  17. 131 0
      ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/AlgorithmSet.java
  18. 26 0
      ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ChannelNumber.java
  19. 1 1
      ruoyi-framework/pom.xml
  20. 369 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/AdvancedSystemMonitor.java
  21. 10 9
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java
  22. 11 1
      ruoyi-system/pom.xml
  23. 1 1
      ruoyi-system/src/main/java/com/ruoyi/hk/AlarmDataParse.java
  24. 1 1
      ruoyi-system/src/main/java/com/ruoyi/hk/CommonMethod/osSelect.java
  25. 1 1
      ruoyi-system/src/main/java/com/ruoyi/hk/FMSGCallBack_V31.java
  26. 25 24
      ruoyi-system/src/main/java/com/ruoyi/hk/HCNetSDK.java
  27. 227 60
      ruoyi-system/src/main/java/com/ruoyi/hk/HkUtils.java
  28. 50 0
      ruoyi-system/src/main/java/com/ruoyi/manage/domain/AlgorithmChannel.java
  29. 12 0
      ruoyi-system/src/main/java/com/ruoyi/manage/domain/ClockSet.java
  30. 100 33
      ruoyi-system/src/main/java/com/ruoyi/manage/domain/TaskManage.java
  31. 71 0
      ruoyi-system/src/main/java/com/ruoyi/manage/mapper/AlgorithmChannelMapper.java
  32. 64 0
      ruoyi-system/src/main/java/com/ruoyi/manage/mapper/AlgorithmSetMapper.java
  33. 1 0
      ruoyi-system/src/main/java/com/ruoyi/manage/mapper/TaskManageMapper.java
  34. 61 0
      ruoyi-system/src/main/java/com/ruoyi/manage/service/IAlgorithmChannelService.java
  35. 62 0
      ruoyi-system/src/main/java/com/ruoyi/manage/service/IAlgorithmSetService.java
  36. 3 2
      ruoyi-system/src/main/java/com/ruoyi/manage/service/ITaskManageService.java
  37. 93 0
      ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/AlgorithmChannelServiceImpl.java
  38. 97 0
      ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/AlgorithmSetServiceImpl.java
  39. 44 5
      ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/ChannelNumberServiceImpl.java
  40. 71 24
      ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/TaskManageServiceImpl.java
  41. 75 0
      ruoyi-system/src/main/resources/mapper/manage/AlgorithmChannelMapper.xml
  42. 134 0
      ruoyi-system/src/main/resources/mapper/manage/AlgorithmSetMapper.xml
  43. 40 11
      ruoyi-system/src/main/resources/mapper/manage/ChannelNumberMapper.xml
  44. 42 24
      ruoyi-system/src/main/resources/mapper/manage/ClockSetMapper.xml
  45. 44 14
      ruoyi-system/src/main/resources/mapper/manage/TaskManageMapper.xml
  46. 0 67
      ry.bat
  47. 0 86
      ry.sh

BIN
AudioFile/123.pcm


+ 0 - 0
AudioFile/DecodeSaveData.pcm


BIN
AudioFile/DeviceSaveData.g711


+ 0 - 0
AudioFile/此文件夹中放入发送给设备的音频文件.txt


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 94
README.md


+ 0 - 12
bin/clean.bat

@@ -1,12 +0,0 @@
-@echo off
-echo.
-echo [信息] 清理工程target生成路径。
-echo.
-
-%~d0
-cd %~dp0
-
-cd ..
-call mvn clean
-
-pause

+ 0 - 12
bin/package.bat

@@ -1,12 +0,0 @@
-@echo off
-echo.
-echo [信息] 打包Web工程,生成war/jar包文件。
-echo.
-
-%~d0
-cd %~dp0
-
-cd ..
-call mvn clean package -Dmaven.test.skip=true
-
-pause

+ 0 - 14
bin/run.bat

@@ -1,14 +0,0 @@
-@echo off
-echo.
-echo [信息] 使用Jar命令运行Web工程。
-echo.
-
-cd %~dp0
-cd ../ruoyi-admin/target
-
-set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
-
-java -jar %JAVA_OPTS% ruoyi-admin.jar
-
-cd bin
-pause

BIN
doc/若依环境使用手册.docx


+ 0 - 7
pom.xml

@@ -121,13 +121,6 @@
                 <version>${pagehelper.boot.version}</version>
             </dependency>
 
-            <!-- 获取系统信息 -->
-            <dependency>
-                <groupId>com.github.oshi</groupId>
-                <artifactId>oshi-core</artifactId>
-                <version>${oshi.version}</version>
-            </dependency>
-
             <!-- io常用工具类 -->
             <dependency>
                 <groupId>commons-io</groupId>

+ 0 - 11
ruoyi-admin/pom.xml

@@ -16,17 +16,6 @@
     </description>
 
     <dependencies>
-        <!--海康威视-->
-        <dependency>
-            <groupId>net.java.jna</groupId>
-            <artifactId>jna</artifactId>
-            <version>1.0.0</version>
-        </dependency>
-        <dependency>
-            <groupId>net.java.examples</groupId>
-            <artifactId>examples</artifactId>
-            <version>1.0.0</version>
-        </dependency>
         <!--转图片用-->
         <dependency>
             <groupId>commons-fileupload</groupId>

+ 91 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/manage/AlgorithmSetController.java

@@ -0,0 +1,91 @@
+package com.ruoyi.web.controller.manage;
+
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.domain.entity.AlgorithmSet;
+import com.ruoyi.manage.service.IAlgorithmSetService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * 算法Controller
+ *
+ * @author boman
+ * @date 2025-08-12
+ */
+@RestController
+@RequestMapping("/manage/algorithmSet")
+public class AlgorithmSetController extends BaseController {
+    @Autowired
+    private IAlgorithmSetService algorithmSetService;
+
+    /**
+     * 查询算法列表
+     */
+    @PreAuthorize("@ss.hasPermi('manage:algorithmSet:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(AlgorithmSet algorithmSet) {
+        startPage();
+        List<AlgorithmSet> list = algorithmSetService.selectAlgorithmSetList(algorithmSet);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出算法列表
+     */
+    @PreAuthorize("@ss.hasPermi('manage:algorithmSet:export')")
+    @Log(title = "算法", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, AlgorithmSet algorithmSet) {
+        List<AlgorithmSet> list = algorithmSetService.selectAlgorithmSetList(algorithmSet);
+        ExcelUtil<AlgorithmSet> util = new ExcelUtil<AlgorithmSet>(AlgorithmSet.class);
+        util.exportExcel(response, list, "算法数据");
+    }
+
+    /**
+     * 获取算法详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('manage:algorithmSet:query')")
+    @GetMapping(value = "/{algorithmId}")
+    public AjaxResult getInfo(@PathVariable("algorithmId") Long algorithmId) {
+        return success(algorithmSetService.selectAlgorithmSetByAlgorithmId(algorithmId));
+    }
+
+    /**
+     * 新增算法
+     */
+    @PreAuthorize("@ss.hasPermi('manage:algorithmSet:add')")
+    @Log(title = "算法", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody AlgorithmSet algorithmSet) {
+        return toAjax(algorithmSetService.insertAlgorithmSet(algorithmSet));
+    }
+
+    /**
+     * 修改算法
+     */
+    @PreAuthorize("@ss.hasPermi('manage:algorithmSet:edit')")
+    @Log(title = "算法", businessType = BusinessType.UPDATE)
+    @PostMapping("/put")
+    public AjaxResult edit(@RequestBody AlgorithmSet algorithmSet) {
+        return toAjax(algorithmSetService.updateAlgorithmSet(algorithmSet));
+    }
+
+    /**
+     * 删除算法
+     */
+    @PreAuthorize("@ss.hasPermi('manage:algorithmSet:remove')")
+    @Log(title = "算法", businessType = BusinessType.DELETE)
+    @GetMapping("/delete/{algorithmIds}")
+    public AjaxResult remove(@PathVariable Long[] algorithmIds) {
+        return toAjax(algorithmSetService.deleteAlgorithmSetByAlgorithmIds(algorithmIds));
+    }
+}

+ 3 - 3
ruoyi-admin/src/main/java/com/ruoyi/web/controller/manage/TaskManageController.java

@@ -19,7 +19,7 @@ import java.util.List;
  * 任务管理Controller
  *
  * @author boman
- * @date 2025-05-07
+ * @date 2025-08-12
  */
 @RestController
 @RequestMapping("/manage/taskManage")
@@ -66,7 +66,7 @@ public class TaskManageController extends BaseController {
     @Log(title = "任务管理", businessType = BusinessType.INSERT)
     @PostMapping
     public AjaxResult add(@RequestBody TaskManage taskManage) {
-        return toAjax(taskManageService.insertTaskManage(taskManage));
+        return taskManageService.insertTaskManage(taskManage);
     }
 
     /**
@@ -76,7 +76,7 @@ public class TaskManageController extends BaseController {
     @Log(title = "任务管理", businessType = BusinessType.UPDATE)
     @PostMapping("/put")
     public AjaxResult edit(@RequestBody TaskManage taskManage) {
-        return toAjax(taskManageService.updateTaskManage(taskManage));
+        return taskManageService.updateTaskManage(taskManage);
     }
 
     /**

+ 0 - 147
ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java

@@ -1,147 +0,0 @@
-/*
-package com.ruoyi.web.core.config;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import com.ruoyi.common.config.RuoYiConfig;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.models.auth.In;
-import springfox.documentation.builders.ApiInfoBuilder;
-import springfox.documentation.builders.PathSelectors;
-import springfox.documentation.builders.RequestHandlerSelectors;
-import springfox.documentation.service.ApiInfo;
-import springfox.documentation.service.ApiKey;
-import springfox.documentation.service.AuthorizationScope;
-import springfox.documentation.service.Contact;
-import springfox.documentation.service.SecurityReference;
-import springfox.documentation.service.SecurityScheme;
-import springfox.documentation.spi.DocumentationType;
-import springfox.documentation.spi.service.contexts.SecurityContext;
-import springfox.documentation.spring.web.plugins.Docket;
-
-*/
-/**
- * Swagger2的接口配置
- * 
- * @author ruoyi
- *//*
-
-@Configuration
-public class SwaggerConfig
-{
-    */
-/** 系统基础配置 *//*
-
-    @Autowired
-    private RuoYiConfig ruoyiConfig;
-
-    */
-/** 是否开启swagger *//*
-
-    @Value("${swagger.enabled}")
-    private boolean enabled;
-
-    */
-/** 设置请求的统一前缀 *//*
-
-    @Value("${swagger.pathMapping}")
-    private String pathMapping;
-
-    */
-/**
-     * 创建API
-     *//*
-
-    @Bean
-    public Docket createRestApi()
-    {
-        return new Docket(DocumentationType.OAS_30)
-                // 是否启用Swagger
-                .enable(enabled)
-                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
-                .apiInfo(apiInfo())
-                // 设置哪些接口暴露给Swagger展示
-                .select()
-                // 扫描所有有注解的api,用这种方式更灵活
-                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
-                // 扫描指定包中的swagger注解
-                // .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
-                // 扫描所有 .apis(RequestHandlerSelectors.any())
-                .paths(PathSelectors.any())
-                .build()
-                */
-/* 设置安全模式,swagger可以设置访问token *//*
-
-                .securitySchemes(securitySchemes())
-                .securityContexts(securityContexts())
-                .pathMapping(pathMapping);
-    }
-
-    */
-/**
-     * 安全模式,这里指定token通过Authorization头请求头传递
-     *//*
-
-    private List<SecurityScheme> securitySchemes()
-    {
-        List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
-        apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
-        return apiKeyList;
-    }
-
-    */
-/**
-     * 安全上下文
-     *//*
-
-    private List<SecurityContext> securityContexts()
-    {
-        List<SecurityContext> securityContexts = new ArrayList<>();
-        securityContexts.add(
-                SecurityContext.builder()
-                        .securityReferences(defaultAuth())
-                        .operationSelector(o -> o.requestMappingPattern().matches("/.*"))
-                        .build());
-        return securityContexts;
-    }
-
-    */
-/**
-     * 默认的安全上引用
-     *//*
-
-    private List<SecurityReference> defaultAuth()
-    {
-        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
-        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
-        authorizationScopes[0] = authorizationScope;
-        List<SecurityReference> securityReferences = new ArrayList<>();
-        securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
-        return securityReferences;
-    }
-
-    */
-/**
-     * 添加摘要信息
-     *//*
-
-    private ApiInfo apiInfo()
-    {
-        // 用ApiInfoBuilder进行定制
-        return new ApiInfoBuilder()
-                // 设置标题
-                .title("标题:若依管理系统_接口文档")
-                // 描述
-                .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
-                // 作者信息
-                .contact(new Contact(ruoyiConfig.getName(), null, null))
-                // 版本
-                .version("版本号:" + ruoyiConfig.getVersion())
-                .build();
-    }
-}
-*/

+ 124 - 124
ruoyi-admin/src/main/resources/application-druid.yml

@@ -1,133 +1,133 @@
 # 项目相关配置
 ruoyi:
-    # 名称
-    name: 设备管理
-    # 版本
-    version: 3.8.9
-    # 版权年份
-    copyrightYear: 2025
-    # 实例演示开关
-    demoEnabled: true
-    # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
-    profile: D:/ruoyi/uploadPath/pw
-    # 获取ip地址开关
-    addressEnabled: false
-    # 验证码类型 math 数组计算 char 字符验证
-    captchaType: math
+  # 名称
+  name: 设备管理
+  # 版本
+  version: 3.8.9
+  # 版权年份
+  copyrightYear: 2025
+  # 实例演示开关
+  demoEnabled: true
+  # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
+  profile: D:/ruoyi/uploadPath/pw
+  # 获取ip地址开关
+  addressEnabled: false
+  # 验证码类型 math 数组计算 char 字符验证
+  captchaType: math
 # 开发环境配置
 server:
-    # 服务器的HTTP端口,默认为8080
-    port: 8057
-    servlet:
-        # 应用的访问路径
-        context-path: /
-    tomcat:
-        # tomcat的URI编码
-        uri-encoding: UTF-8
-        # tomcat最大线程数,默认为200
-        max-threads: 800
-        # Tomcat启动初始化的线程数,默认值25
-        min-spare-threads: 30
+  # 服务器的HTTP端口,默认为8080
+  port: 8057
+  servlet:
+    # 应用的访问路径
+    context-path: /
+  tomcat:
+    # tomcat的URI编码
+    uri-encoding: UTF-8
+    # tomcat最大线程数,默认为200
+    max-threads: 800
+    # Tomcat启动初始化的线程数,默认值25
+    min-spare-threads: 30
 # 数据源配置
 spring:
-    # redis 配置
-    redis:
-        # 地址
-#        host: 60.171.161.56
-        host: 127.0.0.1
-        # 端口,默认为6379
-#        port: 20001
-        port: 6379
-        # 数据库索引
-        database: 9
-        # 密码
-#        password: Boman123
+  # redis 配置
+  redis:
+    # 地址
+    #        host: 60.171.161.56
+    host: 127.0.0.1
+    # 端口,默认为6379
+    #        port: 20001
+    port: 6379
+    # 数据库索引
+    database: 9
+    # 密码
+    #        password: Boman123
+    password: 123456
+    # 连接超时时间
+    timeout: 10s
+    lettuce:
+      pool:
+        # 连接池中的最小空闲连接
+        min-idle: 0
+        # 连接池中的最大空闲连接
+        max-idle: 8
+        # 连接池的最大数据库连接数
+        max-active: 8
+        # #连接池最大阻塞等待时间(使用负值表示没有限制)
+        max-wait: -1ms
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    driverClassName: com.mysql.cj.jdbc.Driver
+    druid:
+      # 主库数据源
+      master:
+        url: jdbc:mysql://127.0.0.1:3306/device_manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
+        username: root
         password: 123456
-        # 连接超时时间
-        timeout: 10s
-        lettuce:
-            pool:
-                # 连接池中的最小空闲连接
-                min-idle: 0
-                # 连接池中的最大空闲连接
-                max-idle: 8
-                # 连接池的最大数据库连接数
-                max-active: 8
-                # #连接池最大阻塞等待时间(使用负值表示没有限制)
-                max-wait: -1ms
-    datasource:
-        type: com.alibaba.druid.pool.DruidDataSource
-        driverClassName: com.mysql.cj.jdbc.Driver
-        druid:
-            # 主库数据源
-            master:
-                url: jdbc:mysql://127.0.0.1:3306/device_manage?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
-                username: root
-                password: 123456
-            # 从库数据源
-            slave:
-                # 从数据源开关/默认关闭
-                enabled: false
-                url:
-                username:
-                password:
-            # 初始连接数
-            initialSize: 5
-            # 最小连接池数量
-            minIdle: 10
-            # 最大连接池数量
-            maxActive: 20
-            # 配置获取连接等待超时的时间
-            maxWait: 60000
-            # 配置连接超时时间
-            connectTimeout: 30000
-            # 配置网络超时时间
-            socketTimeout: 60000
-            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-            timeBetweenEvictionRunsMillis: 60000
-            # 配置一个连接在池中最小生存的时间,单位是毫秒
-            minEvictableIdleTimeMillis: 300000
-            # 配置一个连接在池中最大生存的时间,单位是毫秒
-            maxEvictableIdleTimeMillis: 900000
-            # 配置检测连接是否有效
-            validationQuery: SELECT 1 FROM DUAL
-            testWhileIdle: true
-            testOnBorrow: false
-            testOnReturn: false
-            webStatFilter:
-                enabled: true
-            statViewServlet:
-                enabled: false
-                # 设置白名单,不填则允许所有访问
-                allow:
-                url-pattern: /druid/*
-                # 控制台管理用户名和密码
-                login-username: admin
-                login-password: Boman123
-            filter:
-                stat:
-                    enabled: true
-                    # 慢SQL记录
-                    log-slow-sql: true
-                    slow-sql-millis: 1000
-                    merge-sql: true
-                wall:
-                    config:
-                        multi-statement-allow: true
+      # 从库数据源
+      slave:
+        # 从数据源开关/默认关闭
+        enabled: false
+        url:
+        username:
+        password:
+      # 初始连接数
+      initialSize: 5
+      # 最小连接池数量
+      minIdle: 10
+      # 最大连接池数量
+      maxActive: 20
+      # 配置获取连接等待超时的时间
+      maxWait: 60000
+      # 配置连接超时时间
+      connectTimeout: 30000
+      # 配置网络超时时间
+      socketTimeout: 60000
+      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
+      timeBetweenEvictionRunsMillis: 60000
+      # 配置一个连接在池中最小生存的时间,单位是毫秒
+      minEvictableIdleTimeMillis: 300000
+      # 配置一个连接在池中最大生存的时间,单位是毫秒
+      maxEvictableIdleTimeMillis: 900000
+      # 配置检测连接是否有效
+      validationQuery: SELECT 1 FROM DUAL
+      testWhileIdle: true
+      testOnBorrow: false
+      testOnReturn: false
+      webStatFilter:
+        enabled: true
+      statViewServlet:
+        enabled: false
+        # 设置白名单,不填则允许所有访问
+        allow:
+        url-pattern: /druid/*
+        # 控制台管理用户名和密码
+        login-username: admin
+        login-password: Boman123
+      filter:
+        stat:
+          enabled: true
+          # 慢SQL记录
+          log-slow-sql: true
+          slow-sql-millis: 1000
+          merge-sql: true
+        wall:
+          config:
+            multi-statement-allow: true
 # MQTT配置
 mqtt:
-    #  server-uri: tcp://13.229.167.76:1883
-    server-uri: tcp://60.171.161.56:20009
-    #  server-uri: tcp://127.0.0.1:1883
-    #  server-uri: tcp://192.168.101.147:1883
-    #  server-uri: tcp://127.0.0.1:1883
-    client-id: JavaClientBoManDev
-    username:
-    password:
-    default-topic: toServer_leaveStat,toServer_playStat,toServer_picPos,toServer_workStat
-    default-qos: 1
-    timeout: 30
-    keep-alive: 60
-    clean-session: true
-    auto-reconnect: true
-    command-timeout: 10
+  server-uri: tcp://13.229.167.76:1883
+#  server-uri: tcp://60.171.161.56:20009
+  #      server-uri: tcp://127.0.0.1:1883
+  #  server-uri: tcp://192.168.101.147:1883
+  #  server-uri: tcp://127.0.0.1:1883
+  client-id: JavaClientBoManDev
+  username:
+  password:
+  default-topic: toServer_leaveStat,toServer_playStat,toServer_picPos,toServer_workStat
+  default-qos: 1
+  timeout: 30
+  keep-alive: 60
+  clean-session: true
+  auto-reconnect: true
+  command-timeout: 10

+ 2 - 2
ruoyi-admin/src/main/resources/application.yml

@@ -19,8 +19,8 @@ spring:
     # 国际化资源文件路径
     basename: i18n/messages
   profiles:
-#          active: druid
-          active: prod
+          active: druid
+#          active: prod
   # 文件上传
   servlet:
     multipart:

+ 131 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/AlgorithmSet.java

@@ -0,0 +1,131 @@
+package com.ruoyi.common.core.domain.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 算法对象 algorithm_set
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+public class AlgorithmSet extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 算法ID */
+    private Long algorithmId;
+
+    /** 算法编号 */
+    @Excel(name = "算法编号")
+    private String algorithmNum;
+
+    /** 算法名称 */
+    @Excel(name = "算法名称")
+    private String algorithmName;
+
+    /** 算法描述 */
+    @Excel(name = "算法描述")
+    private String algorithmDescription;
+
+    /** 算法阈值严格 */
+    @Excel(name = "算法阈值严格")
+    private String algorithmThresholdStrict;
+
+    /** 算法阈值 */
+    @Excel(name = "算法阈值")
+    private String algorithmThreshold;
+
+    /** 删除标志(0代表存在 1代表删除) */
+    private String delFlag;
+
+    public void setAlgorithmId(Long algorithmId) 
+    {
+        this.algorithmId = algorithmId;
+    }
+
+    public Long getAlgorithmId()
+    {
+        return algorithmId;
+    }
+
+    public void setAlgorithmNum(String algorithmNum)
+    {
+        this.algorithmNum = algorithmNum;
+    }
+
+    public String getAlgorithmNum()
+    {
+        return algorithmNum;
+    }
+
+    public void setAlgorithmName(String algorithmName)
+    {
+        this.algorithmName = algorithmName;
+    }
+
+    public String getAlgorithmName()
+    {
+        return algorithmName;
+    }
+
+    public void setAlgorithmDescription(String algorithmDescription)
+    {
+        this.algorithmDescription = algorithmDescription;
+    }
+
+    public String getAlgorithmDescription()
+    {
+        return algorithmDescription;
+    }
+
+    public void setAlgorithmThresholdStrict(String algorithmThresholdStrict)
+    {
+        this.algorithmThresholdStrict = algorithmThresholdStrict;
+    }
+
+    public String getAlgorithmThresholdStrict()
+    {
+        return algorithmThresholdStrict;
+    }
+
+    public void setAlgorithmThreshold(String algorithmThreshold)
+    {
+        this.algorithmThreshold = algorithmThreshold;
+    }
+
+    public String getAlgorithmThreshold()
+    {
+        return algorithmThreshold;
+    }
+
+    public void setDelFlag(String delFlag)
+    {
+        this.delFlag = delFlag;
+    }
+
+    public String getDelFlag()
+    {
+        return delFlag;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("algorithmId", getAlgorithmId())
+            .append("algorithmNum", getAlgorithmNum())
+            .append("algorithmName", getAlgorithmName())
+            .append("algorithmDescription", getAlgorithmDescription())
+            .append("algorithmThresholdStrict", getAlgorithmThresholdStrict())
+            .append("algorithmThreshold", getAlgorithmThreshold())
+            .append("delFlag", getDelFlag())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .append("remark", getRemark())
+            .toString();
+    }
+}

+ 26 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/ChannelNumber.java

@@ -97,6 +97,31 @@ public class ChannelNumber extends BaseEntity {
     /** 子菜单 */
     private List<ChannelNumber> children = new ArrayList<ChannelNumber>();
 
+    /**
+     * 算法集合
+     */
+    private List<AlgorithmSet> algorithmSetList = new ArrayList<>();
+
+    /**
+     * 算法集合id
+     */
+    private Long[] algorithmSetIds;
+
+    public Long[] getAlgorithmSetIds() {
+        return algorithmSetIds;
+    }
+
+    public void setAlgorithmSetIds(Long[] algorithmSetIds) {
+        this.algorithmSetIds = algorithmSetIds;
+    }
+
+    public List<AlgorithmSet> getAlgorithmSetList() {
+        return algorithmSetList;
+    }
+
+    public void setAlgorithmSetList(List<AlgorithmSet> algorithmSetList) {
+        this.algorithmSetList = algorithmSetList;
+    }
 
     public List<ChannelNumber> getChildren() {
         return children;
@@ -254,6 +279,7 @@ public class ChannelNumber extends BaseEntity {
                 ", isChannel='" + isChannel + '\'' +
                 ", parameterSet=" + parameterSet +
                 ", children=" + children +
+                ", algorithmSetList=" + algorithmSetList +
                 '}';
     }
 }

+ 1 - 1
ruoyi-framework/pom.xml

@@ -51,8 +51,8 @@
         <dependency>
             <groupId>com.github.oshi</groupId>
             <artifactId>oshi-core</artifactId>
+            <version>6.6.5</version>
         </dependency>
-
         <!-- 系统模块-->
         <dependency>
             <groupId>com.ruoyi</groupId>

+ 369 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/AdvancedSystemMonitor.java

@@ -0,0 +1,369 @@
+package com.ruoyi.framework.web.domain;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class AdvancedSystemMonitor {
+
+    /**
+     * CPU插槽 0 温度: 48.5°C
+     * CPU插槽 1 温度: 47.2°C
+     * CPU核心 Socket0-Core0 频率: 3.20 GHz
+     * CPU核心 Socket0-Core1 频率: 3.18 GHz
+     * CPU核心 Socket1-Core24 频率: 2.95 GHz
+     * CPU核心 Socket1-Core25 频率: 2.97 GHz
+     * <p>
+     * GPU #0 信息:
+     * 索引: 0
+     * 名称: NVIDIA GeForce RTX 3090
+     * 温度: 62°C
+     * 使用率: 24%
+     * 显存使用: 3456 MB
+     * 总显存: 24564 MB
+     * 功耗: 350.0 W
+     * 功耗限制: 400.0 W
+     * 图形时钟: 1860 MHz
+     * 显存时钟: 1219 MHz
+     * <p>
+     * GPU #1 信息:
+     * 索引: 1
+     * 名称: NVIDIA Tesla V100
+     * 温度: 58°C
+     * 使用率: 45%
+     * 显存使用: 16384 MB
+     * 总显存: 32768 MB
+     * 功耗: 250.0 W
+     * 功耗限制: 300.0 W
+     * 图形时钟: 1380 MHz
+     * 显存时钟: 877 MHz
+     * <p>
+     * 网络速率 (eth0):
+     * 下行: 1.23 Gbps
+     * 上行: 345.67 Mbps
+     */
+    public static String advancedSystem() {
+        try {
+            // 1. 获取所有CPU插槽的温度
+            Map<Integer, Double> cpuTemps = getCpuTemperatures();
+            cpuTemps.forEach((socket, temp) ->
+                    System.out.printf("CPU插槽 %d 温度: %.1f°C\n", socket, temp)
+            );
+
+            // 2. 获取所有CPU核心的实时频率
+            Map<String, Double> cpuFrequencies = getCpuFrequencies();
+            cpuFrequencies.forEach((core, freq) ->
+                    System.out.printf("CPU核心 %s 频率: %.2f GHz\n", core, freq)
+            );
+
+            // 3. 获取所有GPU信息
+            List<Map<String, String>> gpuInfoList = getMultiGpuInfo();
+            for (int i = 0; i < gpuInfoList.size(); i++) {
+                System.out.println("\nGPU #" + i + " 信息:");
+                gpuInfoList.get(i).forEach((key, value) ->
+                        System.out.println("  " + key + ": " + value)
+                );
+            }
+
+            // 4. 获取网络速率
+            String interfaceName = "eth0"; // 替换为你的网卡名称
+            NetworkStats stats1 = getNetworkStats(interfaceName);
+            TimeUnit.SECONDS.sleep(1);
+            NetworkStats stats2 = getNetworkStats(interfaceName);
+
+            long rxRate = (stats2.rxBytes - stats1.rxBytes) * 8; // 比特/秒
+            long txRate = (stats2.txBytes - stats1.txBytes) * 8; // 比特/秒
+
+            System.out.printf("\n网络速率 (%s):\n  下行: %s\n  上行: %s\n",
+                    interfaceName,
+                    formatRate(rxRate),
+                    formatRate(txRate)
+            );
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    // 获取多CPU插槽的温度
+    private static Map<Integer, Double> getCpuTemperatures() throws Exception {
+        Map<Integer, Double> temps = new HashMap<>();
+
+        // 方法1: 通过hwmon获取物理CPU温度
+        File hwmonDir = new File("/sys/class/hwmon/");
+        for (File hwmon : hwmonDir.listFiles()) {
+            try {
+                // 检测是否为CPU温度传感器
+                File nameFile = new File(hwmon, "name");
+                if (!nameFile.exists()) continue;
+
+                try (BufferedReader nameReader = new BufferedReader(new FileReader(nameFile))) {
+                    String name = nameReader.readLine();
+                    if (name == null || !(name.contains("coretemp") || name.contains("k10temp"))) continue;
+
+                    // 查找所有物理CPU的温度
+                    for (int i = 1; i <= 16; i++) {
+                        File tempFile = new File(hwmon, "temp" + i + "_input");
+                        File labelFile = new File(hwmon, "temp" + i + "_label");
+
+                        if (tempFile.exists()) {
+                            // 读取温度标签确定是物理CPU
+                            String label = "Unknown";
+                            if (labelFile.exists()) {
+                                try (BufferedReader labelReader = new BufferedReader(new FileReader(labelFile))) {
+                                    label = labelReader.readLine();
+                                }
+                            }
+
+                            // 只获取物理CPU温度(Package或Tdie)
+                            if (label.contains("Package") || label.contains("Tdie")) {
+                                try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
+                                    double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
+                                    // 提取CPU插槽ID
+                                    int socketId = 0;
+                                    Pattern p = Pattern.compile("(\\d+)");
+                                    Matcher m = p.matcher(label);
+                                    if (m.find()) socketId = Integer.parseInt(m.group());
+
+                                    temps.put(socketId, temp);
+                                }
+                            }
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                // 继续下一个hwmon
+            }
+        }
+
+        // 方法2: 回退到thermal_zone方法
+        if (temps.isEmpty()) {
+            File thermalDir = new File("/sys/class/thermal/");
+            for (File zone : thermalDir.listFiles()) {
+                if (zone.getName().startsWith("thermal_zone")) {
+                    try {
+                        // 检查类型
+                        File typeFile = new File(zone, "type");
+                        if (!typeFile.exists()) continue;
+
+                        try (BufferedReader typeReader = new BufferedReader(new FileReader(typeFile))) {
+                            String type = typeReader.readLine();
+                            if (type == null || !type.contains("x86_pkg_temp")) continue;
+
+                            // 读取温度
+                            File tempFile = new File(zone, "temp");
+                            if (tempFile.exists()) {
+                                try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
+                                    double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
+                                    // 尝试从目录名获取zone ID
+                                    String zoneId = zone.getName().replace("thermal_zone", "");
+                                    temps.put(Integer.parseInt(zoneId), temp);
+                                }
+                            }
+                        }
+                    } catch (Exception e) {
+                        // 忽略错误
+                    }
+                }
+            }
+        }
+
+        if (temps.isEmpty()) throw new Exception("无法检测到CPU温度传感器");
+        return temps;
+    }
+
+    // 获取所有CPU核心频率
+    private static Map<String, Double> getCpuFrequencies() throws Exception {
+        Map<String, Double> frequencies = new HashMap<>();
+        int socketCount = 0;
+        int coreCount = 0;
+
+        // 检测CPU核心
+        File cpuDir = new File("/sys/devices/system/cpu/");
+        for (File file : cpuDir.listFiles()) {
+            if (file.getName().matches("cpu\\d+")) {
+                String coreId = file.getName().replace("cpu", "");
+
+                // 读取实时频率
+                String freqPath = "/sys/devices/system/cpu/cpu" + coreId + "/cpufreq/scaling_cur_freq";
+                File freqFile = new File(freqPath);
+
+                if (freqFile.exists()) {
+                    try (BufferedReader br = new BufferedReader(new FileReader(freqFile))) {
+                        String line = br.readLine();
+                        if (line != null) {
+                            double freq = Double.parseDouble(line.trim()) / 1_000_000.0;
+                            frequencies.put("Socket0-Core" + coreId, freq);
+                        }
+                    }
+                }
+                coreCount++;
+            }
+        }
+
+        // 如果通过sysfs获取失败,尝试从/proc/cpuinfo获取
+        if (frequencies.isEmpty()) {
+            try (BufferedReader br = new BufferedReader(new FileReader("/proc/cpuinfo"))) {
+                String line;
+                int processor = -1;
+                while ((line = br.readLine()) != null) {
+                    if (line.startsWith("processor")) {
+                        String[] parts = line.split(":");
+                        processor = Integer.parseInt(parts[1].trim());
+                    } else if (line.startsWith("cpu MHz")) {
+                        String[] parts = line.split(":");
+                        double freq = Double.parseDouble(parts[1].trim()) / 1000.0;
+                        frequencies.put("Core" + processor, freq);
+                    }
+                }
+            }
+        }
+
+        return frequencies;
+    }
+
+    // 获取多GPU信息
+    private static List<Map<String, String>> getMultiGpuInfo() {
+        List<Map<String, String>> gpuList = new ArrayList<>();
+
+        // 使用nvidia-smi获取多GPU信息
+        try {
+            Process process = Runtime.getRuntime().exec(
+                    "nvidia-smi --query-gpu=index,name,temperature.gpu,utilization.gpu,memory.used,memory.total,power.draw,power.limit,clocks.current.graphics,clocks.current.memory --format=csv,noheader,nounits"
+            );
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            String line;
+            int gpuIndex = 0;
+
+            while ((line = reader.readLine()) != null) {
+                String[] parts = line.split(", ");
+                if (parts.length >= 10) {
+                    Map<String, String> gpuInfo = new HashMap<>();
+                    gpuInfo.put("索引", parts[0].trim());
+                    gpuInfo.put("名称", parts[1].trim());
+                    gpuInfo.put("温度", parts[2].trim() + "°C");
+                    gpuInfo.put("使用率", parts[3].trim() + "%");
+                    gpuInfo.put("显存使用", parts[4].trim() + " MB");
+                    gpuInfo.put("总显存", parts[5].trim() + " MB");
+                    gpuInfo.put("功耗", parts[6].trim() + " W");
+                    gpuInfo.put("功耗限制", parts[7].trim() + " W");
+                    gpuInfo.put("图形时钟", parts[8].trim() + " MHz");
+                    gpuInfo.put("显存时钟", parts[9].trim() + " MHz");
+
+                    gpuList.add(gpuInfo);
+                    gpuIndex++;
+                }
+            }
+
+            // 检查是否有GPU被检测到
+            if (gpuIndex > 0) return gpuList;
+        } catch (Exception e) {
+            System.err.println("nvidia-smi执行错误: " + e.getMessage());
+        }
+
+        // 备用方法:尝试从sysfs读取AMD/集成GPU信息
+        try {
+            File hwmonDir = new File("/sys/class/hwmon/");
+            for (File hwmon : hwmonDir.listFiles()) {
+                try {
+                    // 检测是否为GPU
+                    File nameFile = new File(hwmon, "name");
+                    if (!nameFile.exists()) continue;
+
+                    try (BufferedReader nameReader = new BufferedReader(new FileReader(nameFile))) {
+                        String name = nameReader.readLine();
+                        if (name == null || !(name.contains("amdgpu") || name.contains("radeon"))) continue;
+
+                        Map<String, String> gpuInfo = new HashMap<>();
+                        gpuInfo.put("类型", name);
+
+                        // 读取温度
+                        for (int i = 1; i <= 5; i++) {
+                            File tempFile = new File(hwmon, "temp" + i + "_input");
+                            if (tempFile.exists()) {
+                                try (BufferedReader tempReader = new BufferedReader(new FileReader(tempFile))) {
+                                    double temp = Double.parseDouble(tempReader.readLine().trim()) / 1000.0;
+                                    gpuInfo.put("温度", String.format("%.1f°C", temp));
+                                    break;
+                                }
+                            }
+                        }
+
+                        // 读取功耗(如果可用)
+                        File powerFile = new File(hwmon, "power1_average");
+                        if (powerFile.exists()) {
+                            try (BufferedReader powerReader = new BufferedReader(new FileReader(powerFile))) {
+                                double power = Double.parseDouble(powerReader.readLine().trim()) / 1_000_000.0;
+                                gpuInfo.put("功耗", String.format("%.1f W", power));
+                            }
+                        }
+
+                        gpuList.add(gpuInfo);
+                    }
+                } catch (Exception e) {
+                    // 继续下一个hwmon
+                }
+            }
+        } catch (Exception e) {
+            System.err.println("sysfs读取错误: " + e.getMessage());
+        }
+
+        // 如果没有检测到GPU,添加一个错误信息
+        if (gpuList.isEmpty()) {
+            Map<String, String> errorInfo = new HashMap<>();
+            errorInfo.put("错误", "未检测到GPU或需要安装驱动");
+            gpuList.add(errorInfo);
+        }
+
+        return gpuList;
+    }
+
+    // 网络统计数据结构
+    private static class NetworkStats {
+        long rxBytes;
+        long txBytes;
+    }
+
+    // 获取网络统计信息
+    private static NetworkStats getNetworkStats(String interfaceName) throws Exception {
+        NetworkStats stats = new NetworkStats();
+        File file = new File("/proc/net/dev");
+
+        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
+            String line;
+            while ((line = br.readLine()) != null) {
+                line = line.trim();
+                if (line.startsWith(interfaceName + ":")) {
+                    String[] parts = line.split("\\s+");
+                    stats.rxBytes = Long.parseLong(parts[1]);
+                    stats.txBytes = Long.parseLong(parts[9]);
+                    break;
+                }
+            }
+        }
+        return stats;
+    }
+
+    // 格式化网络速率
+    private static String formatRate(long rateBitsPerSec) {
+        if (rateBitsPerSec < 1000) {
+            return rateBitsPerSec + " bps";
+        } else if (rateBitsPerSec < 1_000_000) {
+            return String.format("%.2f Kbps", rateBitsPerSec / 1000.0);
+        } else if (rateBitsPerSec < 1_000_000_000) {
+            return String.format("%.2f Mbps", rateBitsPerSec / 1_000_000.0);
+        } else {
+            return String.format("%.2f Gbps", rateBitsPerSec / 1_000_000_000.0);
+        }
+    }
+}

+ 10 - 9
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java

@@ -1,16 +1,8 @@
 package com.ruoyi.framework.web.domain;
 
-import java.net.UnknownHostException;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
 import com.ruoyi.common.utils.Arith;
 import com.ruoyi.common.utils.ip.IpUtils;
-import com.ruoyi.framework.web.domain.server.Cpu;
-import com.ruoyi.framework.web.domain.server.Jvm;
-import com.ruoyi.framework.web.domain.server.Mem;
-import com.ruoyi.framework.web.domain.server.Sys;
-import com.ruoyi.framework.web.domain.server.SysFile;
+import com.ruoyi.framework.web.domain.server.*;
 import oshi.SystemInfo;
 import oshi.hardware.CentralProcessor;
 import oshi.hardware.CentralProcessor.TickType;
@@ -21,6 +13,13 @@ import oshi.software.os.OSFileStore;
 import oshi.software.os.OperatingSystem;
 import oshi.util.Util;
 
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import static com.ruoyi.framework.web.domain.AdvancedSystemMonitor.advancedSystem;
+
 /**
  * 服务器相关信息
  * 
@@ -119,6 +118,8 @@ public class Server
         setJvmInfo();
 
         setSysFiles(si.getOperatingSystem());
+
+        advancedSystem();
     }
 
     /**

+ 11 - 1
ruoyi-system/pom.xml

@@ -16,7 +16,17 @@
     </description>
 
     <dependencies>
-
+        <!--海康威视-->
+        <dependency>
+            <groupId>net.java.jna</groupId>
+            <artifactId>jna</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>net.java.examples</groupId>
+            <artifactId>examples</artifactId>
+            <version>1.0.0</version>
+        </dependency>
         <!-- 通用工具-->
         <dependency>
             <groupId>com.ruoyi</groupId>

+ 1 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hk/AlarmDataParse.java → ruoyi-system/src/main/java/com/ruoyi/hk/AlarmDataParse.java

@@ -1,4 +1,4 @@
-package com.ruoyi.web.controller.hk;
+package com.ruoyi.hk;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONObject;

+ 1 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hk/CommonMethod/osSelect.java → ruoyi-system/src/main/java/com/ruoyi/hk/CommonMethod/osSelect.java

@@ -1,4 +1,4 @@
-package com.ruoyi.web.controller.hk.CommonMethod;
+package com.ruoyi.hk.CommonMethod;
 
 /**
  * @author

+ 1 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hk/FMSGCallBack_V31.java → ruoyi-system/src/main/java/com/ruoyi/hk/FMSGCallBack_V31.java

@@ -1,5 +1,5 @@
 
-package com.ruoyi.web.controller.hk;
+package com.ruoyi.hk;
 
 import com.sun.jna.Pointer;
 

+ 25 - 24
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hk/HCNetSDK.java → ruoyi-system/src/main/java/com/ruoyi/hk/HCNetSDK.java

@@ -1,4 +1,4 @@
-package com.ruoyi.web.controller.hk;
+package com.ruoyi.hk;
 
 import com.sun.jna.*;
 import com.sun.jna.examples.win32.W32API;
@@ -338,8 +338,8 @@ public interface HCNetSDK extends Library {
     public static final int NET_DVR_SUPPORT_BLTSHRINKY = 0x10;//显卡BLT支持Y轴缩小;如果不支持,系统会用软件方法转换;
     public static final int NET_DVR_SUPPORT_BLTSTRETCHX = 0x20;//显卡BLT支持X轴放大;如果不支持,系统会用软件方法转换;
     public static final int NET_DVR_SUPPORT_BLTSTRETCHY = 0x40;//显卡BLT支持Y轴放大;如果不支持,系统会用软件方法转换;
-    public static final int NET_DVR_SUPPORT_SSE = 0x80;//CPU支持SSE指令,Intel Pentium3以上支持SSE指令;
-    public static final int NET_DVR_SUPPORT_MMX = 0x100;//CPU支持MMX指令集,Intel Pentium3以上支持SSE指令;
+    public static final int NET_DVR_SUPPORT_SSE = 0x80;//CPU支持SSE指令, Pentium3以上支持SSE指令;
+    public static final int NET_DVR_SUPPORT_MMX = 0x100;//CPU支持MMX指令集, Pentium3以上支持SSE指令;
     /**********************
      * 云台控制命令 begin
      *************************/
@@ -4399,8 +4399,11 @@ DVR实现巡航数据结构
 
     //语音对讲参数
     public static class NET_DVR_COMPRESSION_AUDIO extends Structure {
-        public byte byAudioEncType;   //音频编码类型 0-G722; 1-G711
-        public byte[] byres = new byte[7];//这里保留音频的压缩参数
+        public byte byAudioEncType;   //0- G722,1- G711_U,2- G711_A,5- MP2L2,6- G726,7- AAC,8- PCM,9-G722,10-G723,11-G729,12-AAC_LC,13-AAC_LD,14-Opus,15-MP3,16-ADPCM
+        public byte  byAudioSamplingRate;//音频采样率 0-默认,1-16kHZ,2-32kHZ,3-48kHZ, 4- 44.1kHZ,5-8kHZ
+        public byte  byAudioBitRate;// 音频码率 参考 BITRATE_ENCODE_INDEX
+        public byte[]  byres=new byte[4];//这里保留音频的压缩参数
+        public byte  bySupport;//bySupport Bit0表示 Mp2l2前4个字节的含义表示后面内容音频数据长度
     }
 
     public static class NET_DVR_AUDIODEC_INFO extends Structure {
@@ -4593,14 +4596,14 @@ DVR实现巡航数据结构
         public short wDuration;            //行为事件触发时间阈值: 1-120秒,建议5秒,判断是有效报警的时间  在ATM系统中触发文件阈值为 1-1000秒
         public byte bySensitivity;        //灵敏度参数,范围[1-100]
         public byte byRate;               //占比:区域内所有未报警目标尺寸目标占区域面积的比重,归一化为-;
-    /*
-    检测目标,可支持多选,具体定义为:
-    0~所有目标(表示不锁定检测目标,所有目标都将进行检测)
-    0x01 ~ 人,
-    0x02 ~ 车,
-    0x04 ~ 其他,
-    该字段支持多选,按位取值,例如3表示1+2.
-    */
+        /*
+        检测目标,可支持多选,具体定义为:
+        0~所有目标(表示不锁定检测目标,所有目标都将进行检测)
+        0x01 ~ 人,
+        0x02 ~ 车,
+        0x04 ~ 其他,
+        该字段支持多选,按位取值,例如3表示1+2.
+        */
         public byte byDetectionTarget;
         public byte byPriority;//优先级,0~低,1~中,2~高
         public byte byAlarmConfidence;    //报警置信度, 0-低,1-较低,2-较高,3-高
@@ -5032,7 +5035,7 @@ DVR实现巡航数据结构
         public byte byBright;                        //车牌亮度
         public byte byLicenseLen;                    //车牌字符个数
         public byte byEntireBelieve;                //整个车牌的置信度,-100
-        public byte byRegion;                       // 区域索引值 0-保留,1-欧洲(EU),2-俄语区域(ER),3-欧洲&(EU&CIS) ,4-中东(ME),0xff-所有
+        public byte byRegion;                       // 区域索引值 0-保留,1-欧洲(EU),3-欧洲&(EU&CIS) ,4-中东(ME),0xff-所有
         public byte byCountry;                      // 国家索引值,参照枚举COUNTRY_INDEX(不支持"COUNTRY_ALL = 0xff, //ALL  全部")
         public byte byArea;                         //区域(省份),各国家内部区域枚举,阿联酋参照 EMI_AREA
         public byte byPlateSize;                    //车牌尺寸,0~未知,1~long, 2~short(中东车牌使用)
@@ -7081,7 +7084,7 @@ DVR实现巡航数据结构
 
     //人体特征识别结果结构体
     public static class NET_VCA_HUMAN_FEATURE extends Structure {
-        public byte byRes3;    
+        public byte byRes3;
         public byte bySex;         //性别, 0-表示“未知”(算法不支持),1 – 男 , 2 – 女, 0xff-算法支持,但是没有识别出来
         public byte byEyeGlass;    //是否戴眼镜 0-表示“未知”(算法不支持),1 – 不戴, 2 – 戴,0xff-算法支持,但是没有识别出来
         //抓拍图片人脸年龄的使用方式,如byAge为15,byAgeDeviation为1,表示,实际人脸图片年龄的为14-16之间
@@ -8429,7 +8432,7 @@ DVR实现巡航数据结构
      34-皖,0xff-全部
      */
         public byte byProvince;//省份索引值
-        public byte byRegion;// 区域索引值 0-保留,1-欧洲,2-俄语区域, 3-欧洲&(EU&CIS),4-中东(Middle East)
+        public byte byRegion;// 区域索引值 0-保留,1-欧洲, 3-欧洲&(EU&CIS),4-中东(Middle East)
         public byte byCountry;//国家索引,参照枚举COUNTRY_INDEX(不支持“COUNTRY_ALL = 0xff,//ALL 全部”)
         public short wPlatePixelWidthMin;//车牌像素识别宽度最小值(单位是像素)当前推荐范围[130,500]
         public short wPlatePixelWidthMax;//车牌像素识别宽度最大值(单位是像素)当前推荐范围[130,500]
@@ -9058,10 +9061,6 @@ DVR实现巡航数据结构
     5-HIK 3.8-16mm F1.5(HV3816P-8MPIR)
     6-HIK 11-40mm F1.7 (HV1140P-8MPIR)
     7-HIK 2.7-12mm F1.2(TV2712P-MPIR)
-    8- MZ5721D-12MPIR
-    9- MZ1555D-12MPIR
-    10- MZ5721D-12MPIR(RS485)
-    11- MZ1555D-12MPIR(RS485)
     */
         public byte byIrisMode;
         public byte byMirror;  /* 镜像:0 off,1- leftright,2- updown,3-center 4-Auto*/
@@ -9544,14 +9543,14 @@ DVR实现巡航数据结构
     }
 
     public static interface FVoiceDataCallBack_V30 extends Callback {
-        public void invoke(int lVoiceComHandle, Pointer pRecvDataBuffer, int dwBufSize, byte byAudioFlag, Pointer pUser);
+        public void invoke(int lVoiceComHandle, Pointer pRecvDataBuffer, int dwBufSize, byte byAudioFlag, int pUser);
     }
 
     public static interface FVoiceDataCallBack_MR extends Callback {
         public void invoke(int lVoiceComHandle, Pointer pRecvDataBuffer, int dwBufSize, byte byAudioFlag, int dwUser);
     }
 
-    public static interface FVoiceDataCallBack_MR_V30 extends Callback {
+    public static interface FVoiceDataCallback_MR_V30 extends Callback {
         public void invoke(int lVoiceComHandle, Pointer pRecvDataBuffer, int dwBufSize, byte byAudioFlag, Pointer pUser);
     }
 
@@ -9877,9 +9876,11 @@ DVR实现巡航数据结构
     boolean NET_DVR_StopVoiceCom(int lVoiceComHandle);
 
     //语音转发
+
+    boolean NET_DVR_GetCurrentAudioCompress(int lUserID, NET_DVR_COMPRESSION_AUDIO lpCompressAudio);
     int NET_DVR_StartVoiceCom_MR(int lUserID, FVoiceDataCallBack_MR fVoiceDataCallBack, int dwUser);
 
-    int NET_DVR_StartVoiceCom_MR_V30(int lUserID, int dwVoiceChan, FVoiceDataCallBack_MR_V30 fVoiceDataCallBack, Pointer pUser);
+    int NET_DVR_StartVoiceCom_MR_V30(int lUserID, int dwVoiceChan, FVoiceDataCallback_MR_V30 fVoiceDataCallBack, Pointer pUser);
 
     boolean NET_DVR_VoiceComSendData(int lVoiceComHandle, byte[] pSendBuf, int dwBufSize);
 
@@ -9931,7 +9932,7 @@ DVR实现巡航数据结构
     void NET_DVR_ReleaseG722Decoder(Pointer pDecHandle);
 
     //G711: Win64、Linux32、Linux64
-    Pointer NET_DVR_InitG711Encoder(Pointer enc_info); //NET_DVR_AUDIOENC_INFO
+    Pointer NET_DVR_InitG711Encoder(NET_DVR_AUDIOENC_INFO enc_info);//NET_DVR_AUDIOENC_INFO//NET_DVR_AUDIOENC_INFO
 
     boolean NET_DVR_EncodeG711Frame(Pointer handle, NET_DVR_AUDIOENC_PROCESS_PARAM p_enc_proc_param);
 

+ 227 - 60
ruoyi-admin/src/main/java/com/ruoyi/web/controller/hk/BjsbController.java → ruoyi-system/src/main/java/com/ruoyi/hk/HkUtils.java

@@ -1,25 +1,42 @@
-package com.ruoyi.web.controller.hk;
+package com.ruoyi.hk;
 
 import com.ruoyi.common.core.domain.AjaxResult;
-import com.ruoyi.web.controller.hk.CommonMethod.osSelect;
+import com.ruoyi.hk.CommonMethod.osSelect;
 import com.sun.jna.Native;
 import com.sun.jna.Pointer;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 
 /**
  * @Author: tjf
- * @Date: 2025/6/6 星期五 16:03
+ * @Date: 2025/8/12 星期二 9:23
  * @Describe:
  */
-@RestController
-@RequestMapping("/hk")
-public class BjsbController {
+public class HkUtils {
+    static int lUserID = -1;
     static HCNetSDK hCNetSDK = null;
-    static int lUserID = -1;//用户句柄
+    static int lVoiceComHandle = -1; //语音对讲句柄
+    static int Count = 0;
+    static int PCM_SEND = 1920;
     static int lAlarmHandle = -1;
     static FMSGCallBack_V31 fMSFCallBack_V31 = null; //报警布防回调函数
+    static cbVoicePcmDataCallBack_MR_V30 cbVoicePcmDataCallBack_mr_v30 = null;
+
+    /**
+     * 海康摄像头音频转发
+     */
+    static class cbVoicePcmDataCallBack_MR_V30 implements HCNetSDK.FVoiceDataCallback_MR_V30 {
+        public void invoke(int lVoiceComHandle, Pointer pRecvDataBuffer, int dwBufSize, byte byAudioFlag, Pointer pUser) {
+            if (Count == 250) {//降低打印频率
+                System.out.println("-----=cbVoiceDataCallBack_MR_V30 enter---------");
+                Count = 0;
+            }
+            Count++;
+        }
+    }
+
     /**
      * 根据不同操作系统选择不同的库文件和库路径
      *
@@ -34,9 +51,10 @@ public class BjsbController {
                     if (osSelect.isWindows())
                         //win系统加载库路径
                         strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
+
                     else if (osSelect.isLinux())
                         //Linux系统加载库路径
-                        strDllPath = System.getProperty("user.dir") + "/libOne/libhcnetsdk.so";
+                        strDllPath = System.getProperty("user.dir") + "/lib/libhcnetsdk.so";
                     hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
                 } catch (Exception ex) {
                     System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
@@ -47,11 +65,207 @@ public class BjsbController {
         return true;
     }
 
+    /**
+     * 登录设备,支持 V40 和 V30 版本,功能一致。
+     *
+     * @param ip   设备IP地址
+     * @param port SDK端口,默认为设备的8000端口
+     * @param user 设备用户名
+     * @param psw  设备密码
+     * @return 登录成功返回用户ID,失败返回-1
+     */
+    public static int loginDevice(String ip, short port, String user, String psw) {
+        // 创建设备登录信息和设备信息对象
+        HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
+        HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
+
+        // 设置设备IP地址
+        byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
+        byte[] ipBytes = ip.getBytes();
+        System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length));
+        loginInfo.sDeviceAddress = deviceAddress;
+
+        // 设置用户名和密码
+        byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
+        byte[] password = psw.getBytes();
+        System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length));
+        System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length));
+        loginInfo.sUserName = userName;
+
+        // 设置端口和登录模式
+        loginInfo.wPort = port;
+        loginInfo.bUseAsynLogin = false; // 同步登录
+        loginInfo.byLoginMode = 0; // 使用SDK私有协议
+
+        // 执行登录操作
+        int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
+        if (userID == -1) {
+            System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError());
+        } else {
+            System.out.println(ip + " 设备登录成功!");
+            // 处理通道号逻辑
+            int startDChan = deviceInfo.struDeviceV30.byStartDChan;
+            System.out.println("预览起始通道号: " + startDChan);
+        }
+        return userID; // 返回登录结果
+    }
+
+    /**
+     * 获取音频编码参数
+     *
+     * @param userID 设备注册句柄
+     */
+    public static void getCurrentAudioCompress(int userID) {
+        HCNetSDK.NET_DVR_COMPRESSION_AUDIO net_dvr_compression_audio = new HCNetSDK.NET_DVR_COMPRESSION_AUDIO();
+        boolean b_AudioCompress = hCNetSDK.NET_DVR_GetCurrentAudioCompress(userID, net_dvr_compression_audio);
+        if (b_AudioCompress == false) {
+            System.out.println("获取音频编码格式参数失败,错误码为" + hCNetSDK.NET_DVR_GetLastError());
+            return;
+        }
+        net_dvr_compression_audio.read();
+        System.out.println("音频编码类型:" + net_dvr_compression_audio.byAudioEncType);
+        System.out.println("音频采样率:" + net_dvr_compression_audio.byAudioSamplingRate);
+        return;
+    }
+
+    /**
+     * 设备注销
+     */
+    public static boolean logout() {
+
+        if (hCNetSDK.NET_DVR_Logout(lUserID)) {
+            System.out.println("注销成功");
+        }
+
+        return true;
+    }
+
+    /**
+     * 给对应摄像头发送音频
+     *
+     * @return
+     */
+    public static AjaxResult sendAudio() throws InterruptedException, IOException {
+        if (hCNetSDK == null) {
+            if (!createSDKInstance()) {
+                System.out.println("Load SDK fail");
+                return AjaxResult.error("Load SDK fail");
+            }
+        }
+        //linux系统建议调用以下接口加载组件库
+        if (osSelect.isLinux()) {
+            HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
+            HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
+            //这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
+            String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
+            String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
+            System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
+            ptrByteArray1.write();
+            hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer());
+            System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
+            ptrByteArray2.write();
+            hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, ptrByteArray2.getPointer());
+            String strPathCom = System.getProperty("user.dir") + "/lib/";
+            HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
+            System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
+            struComPath.write();
+            hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer());
+        }
+        boolean initSuc = hCNetSDK.NET_DVR_Init();
+        if (initSuc != true) {
+            System.out.println("初始化失败");
+        }
+        hCNetSDK.NET_DVR_SetLogToFile(3, "./sdkLog", false);
+        //设备登录 需要设备信息
+        lUserID = HkUtils.loginDevice("10.90.90.68", (short) 8000, "admin", "zxy123456");
+        //获取设备音频编码参数,确定转发音频参数
+        HkUtils.getCurrentAudioCompress(lUserID);
+        System.out.println("\n[Module]开启PCM语音转发示例代码");
+        HkUtils.startTransPCMData(lUserID);
+        HkUtils.logout();
+        //释放SDK
+        hCNetSDK.NET_DVR_Cleanup();
+        return AjaxResult.success();
+    }
+    /**
+     * :: 生成临时WAV文件
+     * powershell -Command "Add-Type -AssemblyName System.Speech; $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer; $speak.SetOutputToWaveFile('%USERPROFILE%\Desktop\temp.wav'); $speak.Speak('测试'); $speak.Dispose()"
+     *
+     * :: 转换为PCM
+     * ffmpeg -i "%USERPROFILE%\Desktop\temp.wav" -f s16le -acodec pcm_s16le -ar 16000 -ac 1 "%USERPROFILE%\Desktop\123.pcm"
+     *
+     * :: 清理临时文件
+     * del "%USERPROFILE%\Desktop\temp.wav"
+     */
+    /**
+     * pcm音频转发
+     *
+     * @param luserID
+     */
+    public static void startTransPCMData(int luserID) {
+        //设置语音PCM回调函数
+        if (cbVoicePcmDataCallBack_mr_v30 == null) {
+            cbVoicePcmDataCallBack_mr_v30 = new cbVoicePcmDataCallBack_MR_V30();
+        }
+        lVoiceComHandle = hCNetSDK.NET_DVR_StartVoiceCom_MR_V30(lUserID, 1, cbVoicePcmDataCallBack_mr_v30, null);
+        if (lVoiceComHandle < 0) {
+            System.out.println("NET_DVR_StartVoiceCom_MR_V30 error," + hCNetSDK.NET_DVR_GetLastError());
+            hCNetSDK.NET_DVR_Logout(lUserID);
+            hCNetSDK.NET_DVR_Cleanup();
+            return;
+        }
+        System.out.println("NET_DVR_StartVoiceCom_MR_V30 suss\n");
+        //读取发送到设备的PCM音频文件,视频采样率和位数需要和设备编码参数保持一致
+        File m_hStreamFile = new File(System.getProperty("user.dir") + "\\AudioFile\\123.pcm");
+        try {
+            // 获取文件的输入流
+            FileInputStream inputStream = new FileInputStream(m_hStreamFile);
+            int PCMdataLength = 0;
+            try {
+                //返回文件的总字节数
+                PCMdataLength = inputStream.available();
+            } catch (IOException e1) {
+                e1.printStackTrace();
+            }
+            if (PCMdataLength < 0) {
+                System.out.println("MP3 file dataSize < 0");
+                return;
+            }
+            HCNetSDK.BYTE_ARRAY ptrVoicePcmByte = new HCNetSDK.BYTE_ARRAY(PCMdataLength);
+            try {
+                inputStream.read(ptrVoicePcmByte.byValue);
+            } catch (IOException e2) {
+                e2.printStackTrace();
+            }
+            ptrVoicePcmByte.write();
+            for (int i = 0; i < PCMdataLength / PCM_SEND; i++) {
+                HCNetSDK.BYTE_ARRAY ptrPcmSend = new HCNetSDK.BYTE_ARRAY(PCM_SEND);
+                System.arraycopy(ptrVoicePcmByte.byValue, i * PCM_SEND, ptrPcmSend.byValue, 0, PCM_SEND);
+                ptrPcmSend.write();
+                if (hCNetSDK.NET_DVR_VoiceComSendData(lVoiceComHandle, ptrPcmSend.byValue, PCM_SEND) == false) {
+                    System.out.println("NET_DVR_VoiceComSendData failed, error code:" + hCNetSDK.NET_DVR_GetLastError());
+                } else {
+                    System.out.println("NET_DVR_VoiceComSendData:" + PCM_SEND + ":succeed ,data is " + i * PCM_SEND);
+                }
+                //需要实时速率发送数据
+                try {
+                    Thread.sleep(40);
+                } catch (InterruptedException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            return;
+        }
+        return;
+    }
+
     /**
      * 获取表计数据
      */
-    @PostMapping("/getBj")
-    public AjaxResult getBj() {
+    public static AjaxResult getBj() {
         if (hCNetSDK == null) {
             if (!createSDKInstance()) {
                 System.out.println("Load SDK fail");
@@ -128,52 +342,6 @@ public class BjsbController {
         }
     }
 
-
-    /**
-     * 登录设备,支持 V40 和 V30 版本,功能一致。
-     *
-     * @param ip   设备IP地址
-     * @param port SDK端口,默认为设备的8000端口
-     * @param user 设备用户名
-     * @param psw  设备密码
-     * @return 登录成功返回用户ID,失败返回-1
-     */
-    public static int loginDevice(String ip, short port, String user, String psw) {
-        // 创建设备登录信息和设备信息对象
-        HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
-        HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
-
-        // 设置设备IP地址
-        byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
-        byte[] ipBytes = ip.getBytes();
-        System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length));
-        loginInfo.sDeviceAddress = deviceAddress;
-
-        // 设置用户名和密码
-        byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
-        byte[] password = psw.getBytes();
-        System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length));
-        System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length));
-        loginInfo.sUserName = userName;
-
-        // 设置端口和登录模式
-        loginInfo.wPort = port;
-        loginInfo.bUseAsynLogin = false; // 同步登录
-        loginInfo.byLoginMode = 0; // 使用SDK私有协议
-
-        // 执行登录操作
-        int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
-        if (userID == -1) {
-            System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError());
-        } else {
-            System.out.println(ip + " 设备登录成功!");
-            // 处理通道号逻辑
-            int startDChan = deviceInfo.struDeviceV30.byStartDChan;
-            System.out.println("预览起始通道号: " + startDChan);
-        }
-        return userID; // 返回登录结果
-    }
-
     /**
      * 报警主机注销用户,释放资源
      */
@@ -198,5 +366,4 @@ public class BjsbController {
         }
         return AjaxResult.error("报警主机注销用户失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
     }
-
 }

+ 50 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/domain/AlgorithmChannel.java

@@ -0,0 +1,50 @@
+package com.ruoyi.manage.domain;
+
+import com.ruoyi.common.core.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 算法和通道关联对象 algorithm_channel
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+public class AlgorithmChannel extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 算法ID */
+    private Long algorithmId;
+
+    /** 通道ID */
+    private Long channelId;
+
+    public void setAlgorithmId(Long algorithmId) 
+    {
+        this.algorithmId = algorithmId;
+    }
+
+    public Long getAlgorithmId() 
+    {
+        return algorithmId;
+    }
+
+    public void setChannelId(Long channelId) 
+    {
+        this.channelId = channelId;
+    }
+
+    public Long getChannelId() 
+    {
+        return channelId;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("algorithmId", getAlgorithmId())
+            .append("channelId", getChannelId())
+            .toString();
+    }
+}

+ 12 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/domain/ClockSet.java

@@ -18,6 +18,11 @@ public class ClockSet extends BaseEntity
     /** 打卡时间设置id */
     private Long clockSetId;
 
+    /**
+     * 名称
+     */
+    private String clockName;
+
     /** 上午上班时间 */
     //@JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "上午上班时间", width = 30, dateFormat = "yyyy-MM-dd")
@@ -37,7 +42,13 @@ public class ClockSet extends BaseEntity
     //@JsonFormat(pattern = "yyyy-MM-dd")
     @Excel(name = "下午下班时间", width = 30, dateFormat = "yyyy-MM-dd")
     private String clockEndPm;
+    public String getClockName() {
+        return clockName;
+    }
 
+    public void setClockName(String clockName) {
+        this.clockName = clockName;
+    }
     public void setClockSetId(Long clockSetId) 
     {
         this.clockSetId = clockSetId;
@@ -83,6 +94,7 @@ public class ClockSet extends BaseEntity
     @Override
     public String toString() {
         return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+                .append("clockName", getClockName())
             .append("clockSetId", getClockSetId())
             .append("clockBeginAm", getClockBeginAm())
             .append("clockEndAm", getClockEndAm())

+ 100 - 33
ruoyi-system/src/main/java/com/ruoyi/manage/domain/TaskManage.java

@@ -1,15 +1,18 @@
 package com.ruoyi.manage.domain;
 
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.annotation.Excel;
 import com.ruoyi.common.core.domain.BaseEntity;
+import com.ruoyi.common.core.domain.entity.AlgorithmSet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * 任务管理对象 task_manage
  * 
  * @author boman
- * @date 2025-05-07
+ * @date 2025-08-12
  */
 public class TaskManage extends BaseEntity
 {
@@ -18,6 +21,14 @@ public class TaskManage extends BaseEntity
     /** 任务ID */
     private Long taskId;
 
+    /** 工作计划id(打卡时间表) */
+    @Excel(name = "工作计划id(打卡时间表)")
+    private Long clockSetId;
+
+    /** 工作计划名称 */
+    @Excel(name = "工作计划名称")
+    private String clockName;
+
     /** 任务编号 */
     @Excel(name = "任务编号")
     private String taskNum;
@@ -26,6 +37,10 @@ public class TaskManage extends BaseEntity
     @Excel(name = "任务描述")
     private String taskDetails;
 
+    /** IO口信号输出1:是,2:否 */
+    @Excel(name = "IO口信号输出1:是,2:否")
+    private String ioOutput;
+
     /** 通道ID */
     @Excel(name = "通道ID")
     private Long channelId;
@@ -38,14 +53,46 @@ public class TaskManage extends BaseEntity
     @Excel(name = "上报地址")
     private String reportAddress;
 
-    /** 选择的算法编号 逗号分割 */
-    @Excel(name = "选择的算法编号 逗号分割")
-    private String algorithmSet;
-
     /** 删除标志(0代表存在 1代表删除) */
     private String delFlag;
+    /**
+     * 是否开启严格模式(0代表开启 1代表关闭)
+     */
+    private String isStrict;
+
+    /**
+     * 算法集合
+     */
+    private List<AlgorithmSet> algorithmSetList = new ArrayList<>();
+    /**
+     * 算法集合id
+     */
+    private Long[] algorithmSetIds;
 
-    public void setTaskId(Long taskId) 
+    public String getIsStrict() {
+        return isStrict;
+    }
+
+    public void setIsStrict(String isStrict) {
+        this.isStrict = isStrict;
+    }
+
+    public Long[] getAlgorithmSetIds() {
+        return algorithmSetIds;
+    }
+
+    public void setAlgorithmSetIds(Long[] algorithmSetIds) {
+        this.algorithmSetIds = algorithmSetIds;
+    }
+    public List<AlgorithmSet> getAlgorithmSetList() {
+        return algorithmSetList;
+    }
+
+    public void setAlgorithmSetList(List<AlgorithmSet> algorithmSetList) {
+        this.algorithmSetList = algorithmSetList;
+    }
+
+    public void setTaskId(Long taskId)
     {
         this.taskId = taskId;
     }
@@ -55,6 +102,26 @@ public class TaskManage extends BaseEntity
         return taskId;
     }
 
+    public void setClockSetId(Long clockSetId) 
+    {
+        this.clockSetId = clockSetId;
+    }
+
+    public Long getClockSetId() 
+    {
+        return clockSetId;
+    }
+
+    public void setClockName(String clockName) 
+    {
+        this.clockName = clockName;
+    }
+
+    public String getClockName() 
+    {
+        return clockName;
+    }
+
     public void setTaskNum(String taskNum) 
     {
         this.taskNum = taskNum;
@@ -75,6 +142,16 @@ public class TaskManage extends BaseEntity
         return taskDetails;
     }
 
+    public void setIoOutput(String ioOutput) 
+    {
+        this.ioOutput = ioOutput;
+    }
+
+    public String getIoOutput() 
+    {
+        return ioOutput;
+    }
+
     public void setChannelId(Long channelId) 
     {
         this.channelId = channelId;
@@ -105,16 +182,6 @@ public class TaskManage extends BaseEntity
         return reportAddress;
     }
 
-    public void setAlgorithmSet(String algorithmSet) 
-    {
-        this.algorithmSet = algorithmSet;
-    }
-
-    public String getAlgorithmSet() 
-    {
-        return algorithmSet;
-    }
-
     public void setDelFlag(String delFlag) 
     {
         this.delFlag = delFlag;
@@ -127,20 +194,20 @@ public class TaskManage extends BaseEntity
 
     @Override
     public String toString() {
-        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
-            .append("taskId", getTaskId())
-            .append("taskNum", getTaskNum())
-            .append("taskDetails", getTaskDetails())
-            .append("channelId", getChannelId())
-            .append("videoAddress", getVideoAddress())
-            .append("reportAddress", getReportAddress())
-            .append("algorithmSet", getAlgorithmSet())
-            .append("delFlag", getDelFlag())
-            .append("createBy", getCreateBy())
-            .append("createTime", getCreateTime())
-            .append("updateBy", getUpdateBy())
-            .append("updateTime", getUpdateTime())
-            .append("remark", getRemark())
-            .toString();
+        return "TaskManage{" +
+                "taskId=" + taskId +
+                ", clockSetId=" + clockSetId +
+                ", clockName='" + clockName + '\'' +
+                ", taskNum='" + taskNum + '\'' +
+                ", taskDetails='" + taskDetails + '\'' +
+                ", ioOutput='" + ioOutput + '\'' +
+                ", channelId=" + channelId +
+                ", videoAddress='" + videoAddress + '\'' +
+                ", reportAddress='" + reportAddress + '\'' +
+                ", delFlag='" + delFlag + '\'' +
+                ", isStrict='" + isStrict + '\'' +
+                ", algorithmSetList=" + algorithmSetList +
+                ", algorithmSetIds=" + Arrays.toString(algorithmSetIds) +
+                '}';
     }
 }

+ 71 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/mapper/AlgorithmChannelMapper.java

@@ -0,0 +1,71 @@
+package com.ruoyi.manage.mapper;
+
+import com.ruoyi.manage.domain.AlgorithmChannel;
+
+import java.util.List;
+
+/**
+ * 算法和通道关联Mapper接口
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+public interface AlgorithmChannelMapper 
+{
+    /**
+     * 查询算法和通道关联
+     * 
+     * @param algorithmId 算法和通道关联主键
+     * @return 算法和通道关联
+     */
+    public AlgorithmChannel selectAlgorithmChannelByAlgorithmId(Long algorithmId);
+
+    /**
+     * 查询算法和通道关联列表
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 算法和通道关联集合
+     */
+    public List<AlgorithmChannel> selectAlgorithmChannelList(AlgorithmChannel algorithmChannel);
+
+    /**
+     * 新增算法和通道关联
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 结果
+     */
+    public int insertAlgorithmChannel(AlgorithmChannel algorithmChannel);
+
+    /**
+     * 修改算法和通道关联
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 结果
+     */
+    public int updateAlgorithmChannel(AlgorithmChannel algorithmChannel);
+
+    /**
+     * 删除算法和通道关联
+     * 
+     * @param algorithmId 算法和通道关联主键
+     * @return 结果
+     */
+    public int deleteAlgorithmChannelByAlgorithmId(Long algorithmId);
+
+    /**
+     * 批量删除算法和通道关联
+     * 
+     * @param algorithmIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteAlgorithmChannelByAlgorithmIds(Long[] algorithmIds);
+    public int deleteAlgorithmChannelByChannelId(Long channelId);
+    public int deleteAlgorithmChannelByChannelIds(Long[] channelIds);
+
+    /**
+     * 批量新增
+     * @param algorithmChannelList
+     * @return
+     */
+     int batchAlgorithmChannel(List<AlgorithmChannel> algorithmChannelList);
+}

+ 64 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/mapper/AlgorithmSetMapper.java

@@ -0,0 +1,64 @@
+package com.ruoyi.manage.mapper;
+
+import com.ruoyi.common.core.domain.entity.AlgorithmSet;
+
+import java.util.List;
+
+/**
+ * 算法Mapper接口
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+public interface AlgorithmSetMapper 
+{
+    /**
+     * 查询算法
+     * 
+     * @param algorithmId 算法主键
+     * @return 算法
+     */
+    public AlgorithmSet selectAlgorithmSetByAlgorithmId(Long algorithmId);
+
+    /**
+     * 查询算法列表
+     * 
+     * @param algorithmSet 算法
+     * @return 算法集合
+     */
+    public List<AlgorithmSet> selectAlgorithmSetList(AlgorithmSet algorithmSet);
+
+    /**
+     * 新增算法
+     * 
+     * @param algorithmSet 算法
+     * @return 结果
+     */
+    public int insertAlgorithmSet(AlgorithmSet algorithmSet);
+
+    /**
+     * 修改算法
+     * 
+     * @param algorithmSet 算法
+     * @return 结果
+     */
+    public int updateAlgorithmSet(AlgorithmSet algorithmSet);
+
+    /**
+     * 删除算法
+     * 
+     * @param algorithmId 算法主键
+     * @return 结果
+     */
+    public int deleteAlgorithmSetByAlgorithmId(Long algorithmId);
+
+    /**
+     * 批量删除算法
+     * 
+     * @param algorithmIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteAlgorithmSetByAlgorithmIds(Long[] algorithmIds);
+
+    List<AlgorithmSet> selectAlgorithmSetByChannelId(Long channelId);
+}

+ 1 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/mapper/TaskManageMapper.java

@@ -19,6 +19,7 @@ public interface TaskManageMapper
      * @return 任务管理
      */
     public TaskManage selectTaskManageByTaskId(Long taskId);
+    public TaskManage selectTaskManageByChannelId(Long channelId);
 
     /**
      * 查询任务管理列表

+ 61 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/service/IAlgorithmChannelService.java

@@ -0,0 +1,61 @@
+package com.ruoyi.manage.service;
+
+import java.util.List;
+import com.ruoyi.manage.domain.AlgorithmChannel;
+
+/**
+ * 算法和通道关联Service接口
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+public interface IAlgorithmChannelService 
+{
+    /**
+     * 查询算法和通道关联
+     * 
+     * @param algorithmId 算法和通道关联主键
+     * @return 算法和通道关联
+     */
+    public AlgorithmChannel selectAlgorithmChannelByAlgorithmId(Long algorithmId);
+
+    /**
+     * 查询算法和通道关联列表
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 算法和通道关联集合
+     */
+    public List<AlgorithmChannel> selectAlgorithmChannelList(AlgorithmChannel algorithmChannel);
+
+    /**
+     * 新增算法和通道关联
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 结果
+     */
+    public int insertAlgorithmChannel(AlgorithmChannel algorithmChannel);
+
+    /**
+     * 修改算法和通道关联
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 结果
+     */
+    public int updateAlgorithmChannel(AlgorithmChannel algorithmChannel);
+
+    /**
+     * 批量删除算法和通道关联
+     * 
+     * @param algorithmIds 需要删除的算法和通道关联主键集合
+     * @return 结果
+     */
+    public int deleteAlgorithmChannelByAlgorithmIds(Long[] algorithmIds);
+
+    /**
+     * 删除算法和通道关联信息
+     * 
+     * @param algorithmId 算法和通道关联主键
+     * @return 结果
+     */
+    public int deleteAlgorithmChannelByAlgorithmId(Long algorithmId);
+}

+ 62 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/service/IAlgorithmSetService.java

@@ -0,0 +1,62 @@
+package com.ruoyi.manage.service;
+
+import com.ruoyi.common.core.domain.entity.AlgorithmSet;
+
+import java.util.List;
+
+/**
+ * 算法Service接口
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+public interface IAlgorithmSetService 
+{
+    /**
+     * 查询算法
+     * 
+     * @param algorithmId 算法主键
+     * @return 算法
+     */
+    public AlgorithmSet selectAlgorithmSetByAlgorithmId(Long algorithmId);
+
+    /**
+     * 查询算法列表
+     * 
+     * @param algorithmSet 算法
+     * @return 算法集合
+     */
+    public List<AlgorithmSet> selectAlgorithmSetList(AlgorithmSet algorithmSet);
+
+    /**
+     * 新增算法
+     * 
+     * @param algorithmSet 算法
+     * @return 结果
+     */
+    public int insertAlgorithmSet(AlgorithmSet algorithmSet);
+
+    /**
+     * 修改算法
+     * 
+     * @param algorithmSet 算法
+     * @return 结果
+     */
+    public int updateAlgorithmSet(AlgorithmSet algorithmSet);
+
+    /**
+     * 批量删除算法
+     * 
+     * @param algorithmIds 需要删除的算法主键集合
+     * @return 结果
+     */
+    public int deleteAlgorithmSetByAlgorithmIds(Long[] algorithmIds);
+
+    /**
+     * 删除算法信息
+     * 
+     * @param algorithmId 算法主键
+     * @return 结果
+     */
+    public int deleteAlgorithmSetByAlgorithmId(Long algorithmId);
+}

+ 3 - 2
ruoyi-system/src/main/java/com/ruoyi/manage/service/ITaskManageService.java

@@ -1,5 +1,6 @@
 package com.ruoyi.manage.service;
 
+import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.manage.domain.TaskManage;
 
 import java.util.List;
@@ -34,7 +35,7 @@ public interface ITaskManageService
      * @param taskManage 任务管理
      * @return 结果
      */
-    public int insertTaskManage(TaskManage taskManage);
+    public AjaxResult insertTaskManage(TaskManage taskManage);
 
     /**
      * 修改任务管理
@@ -42,7 +43,7 @@ public interface ITaskManageService
      * @param taskManage 任务管理
      * @return 结果
      */
-    public int updateTaskManage(TaskManage taskManage);
+    public AjaxResult updateTaskManage(TaskManage taskManage);
 
     /**
      * 批量删除任务管理

+ 93 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/AlgorithmChannelServiceImpl.java

@@ -0,0 +1,93 @@
+package com.ruoyi.manage.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.manage.mapper.AlgorithmChannelMapper;
+import com.ruoyi.manage.domain.AlgorithmChannel;
+import com.ruoyi.manage.service.IAlgorithmChannelService;
+
+/**
+ * 算法和通道关联Service业务层处理
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+@Service
+public class AlgorithmChannelServiceImpl implements IAlgorithmChannelService 
+{
+    @Autowired
+    private AlgorithmChannelMapper algorithmChannelMapper;
+
+    /**
+     * 查询算法和通道关联
+     * 
+     * @param algorithmId 算法和通道关联主键
+     * @return 算法和通道关联
+     */
+    @Override
+    public AlgorithmChannel selectAlgorithmChannelByAlgorithmId(Long algorithmId)
+    {
+        return algorithmChannelMapper.selectAlgorithmChannelByAlgorithmId(algorithmId);
+    }
+
+    /**
+     * 查询算法和通道关联列表
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 算法和通道关联
+     */
+    @Override
+    public List<AlgorithmChannel> selectAlgorithmChannelList(AlgorithmChannel algorithmChannel)
+    {
+        return algorithmChannelMapper.selectAlgorithmChannelList(algorithmChannel);
+    }
+
+    /**
+     * 新增算法和通道关联
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 结果
+     */
+    @Override
+    public int insertAlgorithmChannel(AlgorithmChannel algorithmChannel)
+    {
+        return algorithmChannelMapper.insertAlgorithmChannel(algorithmChannel);
+    }
+
+    /**
+     * 修改算法和通道关联
+     * 
+     * @param algorithmChannel 算法和通道关联
+     * @return 结果
+     */
+    @Override
+    public int updateAlgorithmChannel(AlgorithmChannel algorithmChannel)
+    {
+        return algorithmChannelMapper.updateAlgorithmChannel(algorithmChannel);
+    }
+
+    /**
+     * 批量删除算法和通道关联
+     * 
+     * @param algorithmIds 需要删除的算法和通道关联主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlgorithmChannelByAlgorithmIds(Long[] algorithmIds)
+    {
+        return algorithmChannelMapper.deleteAlgorithmChannelByAlgorithmIds(algorithmIds);
+    }
+
+    /**
+     * 删除算法和通道关联信息
+     * 
+     * @param algorithmId 算法和通道关联主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlgorithmChannelByAlgorithmId(Long algorithmId)
+    {
+        return algorithmChannelMapper.deleteAlgorithmChannelByAlgorithmId(algorithmId);
+    }
+}

+ 97 - 0
ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/AlgorithmSetServiceImpl.java

@@ -0,0 +1,97 @@
+package com.ruoyi.manage.service.impl;
+
+import com.ruoyi.common.core.domain.entity.AlgorithmSet;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.manage.mapper.AlgorithmSetMapper;
+import com.ruoyi.manage.service.IAlgorithmSetService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 算法Service业务层处理
+ * 
+ * @author boman
+ * @date 2025-08-12
+ */
+@Service
+public class AlgorithmSetServiceImpl implements IAlgorithmSetService 
+{
+    @Autowired
+    private AlgorithmSetMapper algorithmSetMapper;
+
+    /**
+     * 查询算法
+     * 
+     * @param algorithmId 算法主键
+     * @return 算法
+     */
+    @Override
+    public AlgorithmSet selectAlgorithmSetByAlgorithmId(Long algorithmId)
+    {
+        return algorithmSetMapper.selectAlgorithmSetByAlgorithmId(algorithmId);
+    }
+
+    /**
+     * 查询算法列表
+     * 
+     * @param algorithmSet 算法
+     * @return 算法
+     */
+    @Override
+    public List<AlgorithmSet> selectAlgorithmSetList(AlgorithmSet algorithmSet)
+    {
+        return algorithmSetMapper.selectAlgorithmSetList(algorithmSet);
+    }
+
+    /**
+     * 新增算法
+     * 
+     * @param algorithmSet 算法
+     * @return 结果
+     */
+    @Override
+    public int insertAlgorithmSet(AlgorithmSet algorithmSet)
+    {
+        algorithmSet.setCreateTime(DateUtils.getNowDate());
+        return algorithmSetMapper.insertAlgorithmSet(algorithmSet);
+    }
+
+    /**
+     * 修改算法
+     * 
+     * @param algorithmSet 算法
+     * @return 结果
+     */
+    @Override
+    public int updateAlgorithmSet(AlgorithmSet algorithmSet)
+    {
+        algorithmSet.setUpdateTime(DateUtils.getNowDate());
+        return algorithmSetMapper.updateAlgorithmSet(algorithmSet);
+    }
+
+    /**
+     * 批量删除算法
+     * 
+     * @param algorithmIds 需要删除的算法主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlgorithmSetByAlgorithmIds(Long[] algorithmIds)
+    {
+        return algorithmSetMapper.deleteAlgorithmSetByAlgorithmIds(algorithmIds);
+    }
+
+    /**
+     * 删除算法信息
+     * 
+     * @param algorithmId 算法主键
+     * @return 结果
+     */
+    @Override
+    public int deleteAlgorithmSetByAlgorithmId(Long algorithmId)
+    {
+        return algorithmSetMapper.deleteAlgorithmSetByAlgorithmId(algorithmId);
+    }
+}

+ 44 - 5
ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/ChannelNumberServiceImpl.java

@@ -1,20 +1,22 @@
 package com.ruoyi.manage.service.impl;
 
 import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.AlgorithmSet;
 import com.ruoyi.common.core.domain.entity.ChannelNumber;
 import com.ruoyi.common.core.domain.entity.ParameterSet;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.manage.domain.AlgorithmChannel;
 import com.ruoyi.manage.domain.ChannelNumberVo;
 import com.ruoyi.manage.domain.EquipmentManage;
-import com.ruoyi.manage.mapper.ChannelNumberMapper;
-import com.ruoyi.manage.mapper.EquipmentManageMapper;
-import com.ruoyi.manage.mapper.ParameterSetMapper;
+import com.ruoyi.manage.mapper.*;
 import com.ruoyi.manage.service.IChannelNumberService;
 import com.ruoyi.mqtt.service.MqttService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
@@ -35,14 +37,16 @@ import static com.ruoyi.common.constant.Constants.*;
 public class ChannelNumberServiceImpl implements IChannelNumberService {
     @Autowired
     private ChannelNumberMapper channelNumberMapper;
-
     @Autowired
     private ParameterSetMapper parameterSetMapper;
     @Autowired
     private EquipmentManageMapper equipmentManageMapper;
-
     @Autowired
     private MqttService mqttService;
+    @Autowired
+    private AlgorithmChannelMapper algorithmChannelMapper;
+    @Autowired
+    private AlgorithmSetMapper algorithmSetMapper;
 
     /**
      * 查询通道管理
@@ -87,6 +91,13 @@ public class ChannelNumberServiceImpl implements IChannelNumberService {
                 channelNumberOne.setIsChannel(Y);
                 channelNumberOne.setParameterSet(parameterSet);
             }
+            for (ChannelNumber number : channelNumbers) {
+                //查询通道的算法集合
+                List<AlgorithmSet> algorithmSets = algorithmSetMapper.selectAlgorithmSetByChannelId(number.getChannelId());
+                if (algorithmSets != null && !algorithmSets.isEmpty()) {
+                    number.setAlgorithmSetList(algorithmSets);
+                }
+            }
         }
         return channelNumbers;
     }
@@ -115,9 +126,30 @@ public class ChannelNumberServiceImpl implements IChannelNumberService {
                 return AjaxResult.error("发布消息失败:" + DETECTION_RTSP);
             }
         }
+        //新增算法和通道信息
+        insertAlgorithmChannel(channelNumber);
         return AjaxResult.success();
     }
 
+    /**
+     * 新增算法和通道信息
+     */
+    public void insertAlgorithmChannel(ChannelNumber channelNumber) {
+        Long channelId = channelNumber.getChannelId();
+        Long[] algorithmSetIds = channelNumber.getAlgorithmSetIds();
+        if (StringUtils.isNotEmpty(algorithmSetIds)) {
+            //新增算法和通道信息
+            List<AlgorithmChannel> list = new ArrayList<AlgorithmChannel>(algorithmSetIds.length);
+            for (Long algorithmSetId : algorithmSetIds) {
+                AlgorithmChannel algorithmChannel = new AlgorithmChannel();
+                algorithmChannel.setChannelId(channelId);
+                algorithmChannel.setAlgorithmId(algorithmSetId);
+                algorithmChannel.setCreateTime(DateUtils.getNowDate());
+                list.add(algorithmChannel);
+            }
+            algorithmChannelMapper.batchAlgorithmChannel(list);
+        }
+    }
 
     /**
      * 修改通道管理
@@ -137,6 +169,7 @@ public class ChannelNumberServiceImpl implements IChannelNumberService {
      * @return 结果
      */
     @Override
+    @Transactional
     public AjaxResult updateChannelNumber(ChannelNumber channelNumber) {
         Long channelId = channelNumber.getChannelId();
         ChannelNumber channelNumberOld = channelNumberMapper.selectChannelNumberByChannelNum(channelNumber);
@@ -152,6 +185,10 @@ public class ChannelNumberServiceImpl implements IChannelNumberService {
                 return AjaxResult.error("发布消息失败:" + DETECTION_RTSP);
             }
         }
+        //删除算法和通道信息
+        algorithmChannelMapper.deleteAlgorithmChannelByChannelId(channelNumber.getChannelId());
+        //新增算法和通道信息
+        insertAlgorithmChannel(channelNumber);
         channelNumber.setUpdateTime(DateUtils.getNowDate());
         channelNumberMapper.updateChannelNumber(channelNumber);
         return AjaxResult.success();
@@ -174,6 +211,8 @@ public class ChannelNumberServiceImpl implements IChannelNumberService {
                 return AjaxResult.error("发布消息失败:" + DETECTION_RTSP);
             }
         }
+        //删除算法和通道信息
+        algorithmChannelMapper.deleteAlgorithmChannelByChannelIds(channelIds);
         return row > 0 ? AjaxResult.success() : AjaxResult.error();
     }
 

+ 71 - 24
ruoyi-system/src/main/java/com/ruoyi/manage/service/impl/TaskManageServiceImpl.java

@@ -1,97 +1,144 @@
 package com.ruoyi.manage.service.impl;
 
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.AlgorithmSet;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.manage.domain.AlgorithmChannel;
 import com.ruoyi.manage.domain.TaskManage;
+import com.ruoyi.manage.mapper.AlgorithmChannelMapper;
+import com.ruoyi.manage.mapper.AlgorithmSetMapper;
 import com.ruoyi.manage.mapper.TaskManageMapper;
 import com.ruoyi.manage.service.ITaskManageService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
  * 任务管理Service业务层处理
- * 
+ *
  * @author boman
  * @date 2025-05-07
  */
 @Service
-public class TaskManageServiceImpl implements ITaskManageService 
-{
+public class TaskManageServiceImpl implements ITaskManageService {
     @Autowired
     private TaskManageMapper taskManageMapper;
+    @Autowired
+    private AlgorithmChannelMapper algorithmChannelMapper;
+    @Autowired
+    private AlgorithmSetMapper algorithmSetMapper;
 
     /**
      * 查询任务管理
-     * 
+     *
      * @param taskId 任务管理主键
      * @return 任务管理
      */
     @Override
-    public TaskManage selectTaskManageByTaskId(Long taskId)
-    {
+    public TaskManage selectTaskManageByTaskId(Long taskId) {
         return taskManageMapper.selectTaskManageByTaskId(taskId);
     }
 
     /**
      * 查询任务管理列表
-     * 
+     *
      * @param taskManage 任务管理
      * @return 任务管理
      */
     @Override
-    public List<TaskManage> selectTaskManageList(TaskManage taskManage)
-    {
-        return taskManageMapper.selectTaskManageList(taskManage);
+    public List<TaskManage> selectTaskManageList(TaskManage taskManage) {
+        List<TaskManage> taskManages = taskManageMapper.selectTaskManageList(taskManage);
+        if (taskManages != null && !taskManages.isEmpty()) {
+            for (TaskManage manage : taskManages) {
+                Long channelId = manage.getChannelId();
+                List<AlgorithmSet> algorithmSets = algorithmSetMapper.selectAlgorithmSetByChannelId(channelId);
+                if (algorithmSets != null && !algorithmSets.isEmpty()) {
+                    manage.setAlgorithmSetList(algorithmSets);
+                }
+            }
+        }
+        return taskManages;
     }
 
     /**
      * 新增任务管理
-     * 
+     *
      * @param taskManage 任务管理
      * @return 结果
      */
     @Override
-    public int insertTaskManage(TaskManage taskManage)
-    {
+    public AjaxResult insertTaskManage(TaskManage taskManage) {
+        Long channelId = taskManage.getChannelId();
+        TaskManage taskManageOld = taskManageMapper.selectTaskManageByChannelId(channelId);
+        if (taskManageOld != null) {
+            return AjaxResult.error("当前通道编号任务已存在");
+        }
+        //判断该通道号是否已经有任务
         taskManage.setCreateTime(DateUtils.getNowDate());
-        return taskManageMapper.insertTaskManage(taskManage);
+        taskManageMapper.insertTaskManage(taskManage);
+        insertAlgorithmChannel(channelId, taskManage.getAlgorithmSetIds());
+        return AjaxResult.success();
+    }
+
+    /**
+     * 新增算法和通道信息
+     */
+    public void insertAlgorithmChannel(Long channelId, Long[] algorithmSetIds) {
+        if (StringUtils.isNotEmpty(algorithmSetIds)) {
+            //新增算法和通道信息
+            List<AlgorithmChannel> list = new ArrayList<AlgorithmChannel>(algorithmSetIds.length);
+            for (Long algorithmSetId : algorithmSetIds) {
+                AlgorithmChannel algorithmChannel = new AlgorithmChannel();
+                algorithmChannel.setChannelId(channelId);
+                algorithmChannel.setAlgorithmId(algorithmSetId);
+                algorithmChannel.setCreateTime(DateUtils.getNowDate());
+                list.add(algorithmChannel);
+            }
+            algorithmChannelMapper.batchAlgorithmChannel(list);
+        }
     }
 
     /**
      * 修改任务管理
-     * 
+     *
      * @param taskManage 任务管理
      * @return 结果
      */
     @Override
-    public int updateTaskManage(TaskManage taskManage)
-    {
+    @Transactional
+    public AjaxResult updateTaskManage(TaskManage taskManage) {
+        //删除算法和通道信息
+        algorithmChannelMapper.deleteAlgorithmChannelByChannelId(taskManage.getChannelId());
+        //新增算法和通道信息
+        insertAlgorithmChannel(taskManage.getChannelId(), taskManage.getAlgorithmSetIds());
         taskManage.setUpdateTime(DateUtils.getNowDate());
-        return taskManageMapper.updateTaskManage(taskManage);
+        taskManageMapper.updateTaskManage(taskManage);
+        return AjaxResult.success();
     }
 
     /**
      * 批量删除任务管理
-     * 
+     *
      * @param taskIds 需要删除的任务管理主键
      * @return 结果
      */
     @Override
-    public int deleteTaskManageByTaskIds(Long[] taskIds)
-    {
+    public int deleteTaskManageByTaskIds(Long[] taskIds) {
         return taskManageMapper.deleteTaskManageByTaskIds(taskIds);
     }
 
     /**
      * 删除任务管理信息
-     * 
+     *
      * @param taskId 任务管理主键
      * @return 结果
      */
     @Override
-    public int deleteTaskManageByTaskId(Long taskId)
-    {
+    public int deleteTaskManageByTaskId(Long taskId) {
         return taskManageMapper.deleteTaskManageByTaskId(taskId);
     }
 }

+ 75 - 0
ruoyi-system/src/main/resources/mapper/manage/AlgorithmChannelMapper.xml

@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.manage.mapper.AlgorithmChannelMapper">
+
+    <resultMap type="AlgorithmChannel" id="AlgorithmChannelResult">
+        <result property="algorithmId" column="algorithm_id"/>
+        <result property="channelId" column="channel_id"/>
+    </resultMap>
+
+    <sql id="selectAlgorithmChannelVo">
+        select algorithm_id, channel_id
+        from algorithm_channel
+    </sql>
+
+    <select id="selectAlgorithmChannelList" parameterType="AlgorithmChannel" resultMap="AlgorithmChannelResult">
+        <include refid="selectAlgorithmChannelVo"/>
+        <where>
+        </where>
+    </select>
+
+    <select id="selectAlgorithmChannelByAlgorithmId" parameterType="Long" resultMap="AlgorithmChannelResult">
+        <include refid="selectAlgorithmChannelVo"/>
+        where algorithm_id = #{algorithmId}
+    </select>
+
+    <insert id="insertAlgorithmChannel" parameterType="AlgorithmChannel">
+        insert into algorithm_channel
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="algorithmId != null">algorithm_id,</if>
+            <if test="channelId != null">channel_id,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="algorithmId != null">#{algorithmId},</if>
+            <if test="channelId != null">#{channelId},</if>
+        </trim>
+    </insert>
+    <insert id="batchAlgorithmChannel">
+        insert IGNORE into algorithm_channel(algorithm_id,channel_id) values
+        <foreach item="item" index="index" collection="list" separator=",">
+            (#{item.algorithmId},#{item.channelId})
+        </foreach>
+    </insert>
+
+    <update id="updateAlgorithmChannel" parameterType="AlgorithmChannel">
+        update algorithm_channel
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="channelId != null">channel_id = #{channelId},</if>
+        </trim>
+        where algorithm_id = #{algorithmId}
+    </update>
+
+    <delete id="deleteAlgorithmChannelByAlgorithmId" parameterType="Long">
+        delete
+        from algorithm_channel
+        where algorithm_id = #{algorithmId}
+    </delete>
+
+    <delete id="deleteAlgorithmChannelByAlgorithmIds" parameterType="String">
+        delete from algorithm_channel where algorithm_id in
+        <foreach item="algorithmId" collection="array" open="(" separator="," close=")">
+            #{algorithmId}
+        </foreach>
+    </delete>
+    <delete id="deleteAlgorithmChannelByChannelId" parameterType="Long">
+        delete from algorithm_channel where channel_id = #{channelId}
+    </delete>
+    <delete id="deleteAlgorithmChannelByChannelIds" parameterType="Long">
+        delete from algorithm_channel where channel_id in
+        <foreach collection="array" item="channelId" open="(" separator="," close=")">
+            #{channelId}
+        </foreach>
+    </delete>
+</mapper>

+ 134 - 0
ruoyi-system/src/main/resources/mapper/manage/AlgorithmSetMapper.xml

@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.manage.mapper.AlgorithmSetMapper">
+
+    <resultMap type="AlgorithmSet" id="AlgorithmSetResult">
+        <result property="algorithmId" column="algorithm_id"/>
+        <result property="algorithmNum" column="algorithm_num"/>
+        <result property="algorithmName" column="algorithm_name"/>
+        <result property="algorithmDescription" column="algorithm_description"/>
+        <result property="algorithmThresholdStrict" column="algorithm_threshold_strict"/>
+        <result property="algorithmThreshold" column="algorithm_threshold"/>
+        <result property="delFlag" column="del_flag"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="remark" column="remark"/>
+    </resultMap>
+
+    <sql id="selectAlgorithmSetVo">
+        select algorithm_id,
+               algorithm_num,
+               algorithm_name,
+               algorithm_description,
+               algorithm_threshold_strict,
+               algorithm_threshold,
+               del_flag,
+               create_by,
+               create_time,
+               update_by,
+               update_time,
+               remark
+        from algorithm_set
+    </sql>
+
+    <select id="selectAlgorithmSetList" parameterType="AlgorithmSet" resultMap="AlgorithmSetResult">
+        <include refid="selectAlgorithmSetVo"/>
+        <where>
+            <if test="algorithmNum != null  and algorithmNum != ''">and algorithm_num = #{algorithmNum}</if>
+            <if test="algorithmName != null  and algorithmName != ''">and algorithm_name like concat('%',
+                #{algorithmName}, '%')
+            </if>
+            <if test="algorithmDescription != null  and algorithmDescription != ''">and algorithm_description =
+                #{algorithmDescription}
+            </if>
+            <if test="algorithmThresholdStrict != null  and algorithmThresholdStrict != ''">and
+                algorithm_threshold_strict = #{algorithmThresholdStrict}
+            </if>
+            <if test="algorithmThreshold != null  and algorithmThreshold != ''">and algorithm_threshold =
+                #{algorithmThreshold}
+            </if>
+        </where>
+    </select>
+
+    <select id="selectAlgorithmSetByAlgorithmId" parameterType="Long" resultMap="AlgorithmSetResult">
+        <include refid="selectAlgorithmSetVo"/>
+        where algorithm_id = #{algorithmId}
+    </select>
+    <select id="selectAlgorithmSetByChannelId" parameterType="Long" resultMap="AlgorithmSetResult">
+        SELECT
+            algorithm_id,
+            algorithm_num,
+            algorithm_name
+        FROM
+            algorithm_set
+        where
+            algorithm_id in
+            (select algorithm_id FROM algorithm_channel where channel_id = #{channelId})
+
+    </select>
+
+    <insert id="insertAlgorithmSet" parameterType="AlgorithmSet" useGeneratedKeys="true" keyProperty="algorithmId">
+        insert into algorithm_set
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="algorithmNum != null">algorithm_num,</if>
+            <if test="algorithmName != null">algorithm_name,</if>
+            <if test="algorithmDescription != null">algorithm_description,</if>
+            <if test="algorithmThresholdStrict != null">algorithm_threshold_strict,</if>
+            <if test="algorithmThreshold != null">algorithm_threshold,</if>
+            <if test="delFlag != null">del_flag,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="remark != null">remark,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="algorithmNum != null">#{algorithmNum},</if>
+            <if test="algorithmName != null">#{algorithmName},</if>
+            <if test="algorithmDescription != null">#{algorithmDescription},</if>
+            <if test="algorithmThresholdStrict != null">#{algorithmThresholdStrict},</if>
+            <if test="algorithmThreshold != null">#{algorithmThreshold},</if>
+            <if test="delFlag != null">#{delFlag},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <update id="updateAlgorithmSet" parameterType="AlgorithmSet">
+        update algorithm_set
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="algorithmNum != null">algorithm_num = #{algorithmNum},</if>
+            <if test="algorithmName != null">algorithm_name = #{algorithmName},</if>
+            <if test="algorithmDescription != null">algorithm_description = #{algorithmDescription},</if>
+            <if test="algorithmThresholdStrict != null">algorithm_threshold_strict = #{algorithmThresholdStrict},</if>
+            <if test="algorithmThreshold != null">algorithm_threshold = #{algorithmThreshold},</if>
+            <if test="delFlag != null">del_flag = #{delFlag},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where algorithm_id = #{algorithmId}
+    </update>
+
+    <delete id="deleteAlgorithmSetByAlgorithmId" parameterType="Long">
+        delete
+        from algorithm_set
+        where algorithm_id = #{algorithmId}
+    </delete>
+
+    <delete id="deleteAlgorithmSetByAlgorithmIds" parameterType="String">
+        delete from algorithm_set where algorithm_id in
+        <foreach item="algorithmId" collection="array" open="(" separator="," close=")">
+            #{algorithmId}
+        </foreach>
+    </delete>
+</mapper>

+ 40 - 11
ruoyi-system/src/main/resources/mapper/manage/ChannelNumberMapper.xml

@@ -23,28 +23,57 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateBy"    column="update_by"    />
         <result property="updateTime"    column="update_time"    />
         <result property="remark"    column="remark"    />
+        <collection  property="algorithmSetList"   javaType="java.util.List"  resultMap="AlgorithmSetResult" />
+    </resultMap>
+    <resultMap type="AlgorithmSet" id="AlgorithmSetResult">
+        <result property="algorithmId" column="algorithm_id"/>
+        <result property="algorithmNum" column="algorithm_num"/>
+        <result property="algorithmName" column="algorithm_name"/>
     </resultMap>
-
     <sql id="selectChannelNumberVo">
         select channel_id, channel_num,equipment_id, equipment_num, equipment_name, video_address,photo_address,port, account,password,protocol_type, channel_details, del_flag, create_by, create_time, update_by, update_time, remark from channel_number
     </sql>
 
     <select id="selectChannelNumberList" parameterType="ChannelNumber" resultMap="ChannelNumberResult">
-        <include refid="selectChannelNumberVo"/>
+        select c.channel_id, c.channel_num,c.equipment_id, c.equipment_num, c.equipment_name, c.video_address,c.photo_address,c.port, c.account,c.password,c.protocol_type,
+        c.channel_details, c.del_flag, c.create_by, c.create_time, c.update_by, c.update_time, c.remark
+        from channel_number c
         <where>
-            <if test="equipmentNum != null  and equipmentNum != ''"> and equipment_num  like concat('%', #{equipmentNum}, '%')</if>
-            <if test="equipmentName != null  and equipmentName != ''"> and equipment_name like concat('%', #{equipmentName}, '%')</if>
-            <if test="channelNum != null  and channelNum != ''"> and channel_num = #{channelNum}</if>
-            <if test="videoAddress != null  and videoAddress != ''"> and video_address = #{videoAddress}</if>
-            <if test="protocolType != null  and protocolType != ''"> and protocol_type = #{protocolType}</if>
-            <if test="channelDetails != null  and channelDetails != ''"> and channel_details = #{channelDetails}</if>
+            <if test="equipmentNum != null  and equipmentNum != ''"> and c.equipment_num  like concat('%', #{equipmentNum}, '%')</if>
+            <if test="equipmentName != null  and equipmentName != ''"> and c.equipment_name like concat('%', #{equipmentName}, '%')</if>
+            <if test="channelNum != null  and channelNum != ''"> and c.channel_num = #{channelNum}</if>
+            <if test="videoAddress != null  and videoAddress != ''"> and c.video_address = #{videoAddress}</if>
+            <if test="protocolType != null  and protocolType != ''"> and c.protocol_type = #{protocolType}</if>
+            <if test="channelDetails != null  and channelDetails != ''"> and c.channel_details = #{channelDetails}</if>
         </where>
-        order by create_time DESC
+        order by c.create_time DESC
     </select>
     
     <select id="selectChannelNumberByChannelId" parameterType="ChannelNumber" resultMap="ChannelNumberResult">
-        <include refid="selectChannelNumberVo"/>
-        where channel_id = #{channelId}
+        select c.channel_id,
+               c.channel_num,
+               c.equipment_id,
+               c.equipment_num,
+               c.equipment_name,
+               c.video_address,
+               c.photo_address,
+               c.port,
+               c.account,
+               c.password,
+               c.protocol_type,
+               c.channel_details,
+               c.del_flag,
+               c.create_by,
+               c.create_time,
+               c.update_by,
+               c.update_time,
+               c.remark,
+               als.algorithm_name,
+               als.algorithm_id
+        from channel_number c
+                 left join algorithm_channel a on a.channel_id = c.channel_id
+                 left join algorithm_set als on als.algorithm_id = a.algorithm_id
+        where c.channel_id = #{channelId}
     </select>
     <select id="selectChannelNumberByChannelNum" parameterType="string" resultMap="ChannelNumberResult">
         <include refid="selectChannelNumberVo"/>

+ 42 - 24
ruoyi-system/src/main/resources/mapper/manage/ClockSetMapper.xml

@@ -1,36 +1,49 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper
-PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.manage.mapper.ClockSetMapper">
-    
+
     <resultMap type="ClockSet" id="ClockSetResult">
-        <result property="clockSetId"    column="clock_set_id"    />
-        <result property="clockBeginAm"    column="clock_begin_am"    />
-        <result property="clockEndAm"    column="clock_end_am"    />
-        <result property="clockBeginPm"    column="clock_begin_pm"    />
-        <result property="clockEndPm"    column="clock_end_pm"    />
-        <result property="createBy"    column="create_by"    />
-        <result property="createTime"    column="create_time"    />
-        <result property="updateBy"    column="update_by"    />
-        <result property="updateTime"    column="update_time"    />
-        <result property="remark"    column="remark"    />
+        <result property="clockSetId" column="clock_set_id"/>
+        <result property="clockName" column="clock_name"/>
+        <result property="clockBeginAm" column="clock_begin_am"/>
+        <result property="clockEndAm" column="clock_end_am"/>
+        <result property="clockBeginPm" column="clock_begin_pm"/>
+        <result property="clockEndPm" column="clock_end_pm"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="remark" column="remark"/>
     </resultMap>
 
     <sql id="selectClockSetVo">
-        select clock_set_id, clock_begin_am, clock_end_am, clock_begin_pm, clock_end_pm, create_by, create_time, update_by, update_time, remark from clock_set
+        select clock_set_id,
+               clock_name,
+               clock_begin_am,
+               clock_end_am,
+               clock_begin_pm,
+               clock_end_pm,
+               create_by,
+               create_time,
+               update_by,
+               update_time,
+               remark
+        from clock_set
     </sql>
 
     <select id="selectClockSetList" parameterType="ClockSet" resultMap="ClockSetResult">
         <include refid="selectClockSetVo"/>
-        <where>  
-            <if test="clockBeginAm != null "> and clock_begin_am = #{clockBeginAm}</if>
-            <if test="clockEndAm != null "> and clock_end_am = #{clockEndAm}</if>
-            <if test="clockBeginPm != null "> and clock_begin_pm = #{clockBeginPm}</if>
-            <if test="clockEndPm != null "> and clock_end_pm = #{clockEndPm}</if>
+        <where>
+            <if test="clockName != null ">and clock_name = #{clockName}</if>
+            <if test="clockBeginAm != null ">and clock_begin_am = #{clockBeginAm}</if>
+            <if test="clockEndAm != null ">and clock_end_am = #{clockEndAm}</if>
+            <if test="clockBeginPm != null ">and clock_begin_pm = #{clockBeginPm}</if>
+            <if test="clockEndPm != null ">and clock_end_pm = #{clockEndPm}</if>
         </where>
     </select>
-    
+
     <select id="selectClockSetByClockSetId" parameterType="Long" resultMap="ClockSetResult">
         <include refid="selectClockSetVo"/>
         where clock_set_id = #{clockSetId}
@@ -39,6 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <insert id="insertClockSet" parameterType="ClockSet" useGeneratedKeys="true" keyProperty="clockSetId">
         insert into clock_set
         <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="clockName != null">clock_name,</if>
             <if test="clockBeginAm != null">clock_begin_am,</if>
             <if test="clockEndAm != null">clock_end_am,</if>
             <if test="clockBeginPm != null">clock_begin_pm,</if>
@@ -48,8 +62,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateBy != null">update_by,</if>
             <if test="updateTime != null">update_time,</if>
             <if test="remark != null">remark,</if>
-         </trim>
+        </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="clockName != null">#{clockName},</if>
             <if test="clockBeginAm != null">#{clockBeginAm},</if>
             <if test="clockEndAm != null">#{clockEndAm},</if>
             <if test="clockBeginPm != null">#{clockBeginPm},</if>
@@ -59,12 +74,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="updateBy != null">#{updateBy},</if>
             <if test="updateTime != null">#{updateTime},</if>
             <if test="remark != null">#{remark},</if>
-         </trim>
+        </trim>
     </insert>
 
     <update id="updateClockSet" parameterType="ClockSet">
         update clock_set
         <trim prefix="SET" suffixOverrides=",">
+            <if test="clockName != null">clock_name = #{clockName},</if>
             <if test="clockBeginAm != null">clock_begin_am = #{clockBeginAm},</if>
             <if test="clockEndAm != null">clock_end_am = #{clockEndAm},</if>
             <if test="clockBeginPm != null">clock_begin_pm = #{clockBeginPm},</if>
@@ -79,11 +95,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     </update>
 
     <delete id="deleteClockSetByClockSetId" parameterType="Long">
-        delete from clock_set where clock_set_id = #{clockSetId}
+        delete
+        from clock_set
+        where clock_set_id = #{clockSetId}
     </delete>
 
     <delete id="deleteClockSetByClockSetIds" parameterType="String">
-        delete from clock_set where clock_set_id in 
+        delete from clock_set where clock_set_id in
         <foreach item="clockSetId" collection="array" open="(" separator="," close=")">
             #{clockSetId}
         </foreach>

+ 44 - 14
ruoyi-system/src/main/resources/mapper/manage/TaskManageMapper.xml

@@ -6,50 +6,74 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     
     <resultMap type="TaskManage" id="TaskManageResult">
         <result property="taskId"    column="task_id"    />
+        <result property="clockSetId"    column="clock_set_id"    />
+        <result property="clockName"    column="clock_name"    />
         <result property="taskNum"    column="task_num"    />
         <result property="taskDetails"    column="task_details"    />
+        <result property="ioOutput"    column="io_output"    />
         <result property="channelId"    column="channel_id"    />
         <result property="videoAddress"    column="video_address"    />
         <result property="reportAddress"    column="report_address"    />
-        <result property="algorithmSet"    column="algorithm_set"    />
+        <result property="isStrict"    column="is_strict"    />
         <result property="delFlag"    column="del_flag"    />
         <result property="createBy"    column="create_by"    />
         <result property="createTime"    column="create_time"    />
         <result property="updateBy"    column="update_by"    />
         <result property="updateTime"    column="update_time"    />
         <result property="remark"    column="remark"    />
+        <collection  property="algorithmSetList"   javaType="java.util.List"  resultMap="AlgorithmSetResult" />
+    </resultMap>
+    <resultMap type="AlgorithmSet" id="AlgorithmSetResult">
+        <result property="algorithmId" column="algorithm_id"/>
+        <result property="algorithmNum" column="algorithm_num"/>
+        <result property="algorithmName" column="algorithm_name"/>
+        <result property="algorithmThresholdStrict" column="algorithm_threshold_strict"/>
     </resultMap>
-
     <sql id="selectTaskManageVo">
-        select task_id, task_num, task_details, channel_id, video_address, report_address, algorithm_set, del_flag, create_by, create_time, update_by, update_time, remark from task_manage
+        select task_id, clock_set_id, clock_name, task_num, task_details, io_output, channel_id, is_strict,video_address, report_address, del_flag, create_by, create_time, update_by, update_time, remark from task_manage
     </sql>
 
     <select id="selectTaskManageList" parameterType="TaskManage" resultMap="TaskManageResult">
-        <include refid="selectTaskManageVo"/>
+        select t.task_id, t.clock_set_id, t.clock_name, t.task_num, t.task_details, t.io_output, t.channel_id, t.video_address, t.report_address, t.del_flag,t.is_strict,
+        t.create_by, t.create_time, t.update_by, t.update_time, t.remark
+        from task_manage t
         <where>  
-            <if test="taskNum != null  and taskNum != ''"> and task_num = #{taskNum}</if>
-            <if test="taskDetails != null  and taskDetails != ''"> and task_details = #{taskDetails}</if>
-            <if test="channelId != null "> and channel_id = #{channelId}</if>
-            <if test="videoAddress != null  and videoAddress != ''"> and video_address = #{videoAddress}</if>
-            <if test="reportAddress != null  and reportAddress != ''"> and report_address = #{reportAddress}</if>
-            <if test="algorithmSet != null  and algorithmSet != ''"> and algorithm_set = #{algorithmSet}</if>
+            <if test="clockSetId != null "> and t.clock_set_id = #{clockSetId}</if>
+            <if test="clockName != null  and clockName != ''"> and t.clock_name like concat('%', #{clockName}, '%')</if>
+            <if test="taskNum != null  and taskNum != ''"> and t.task_num like concat('%', #{taskNum}, '%')</if>
+            <if test="taskDetails != null  and taskDetails != ''"> and t.task_details = #{taskDetails}</if>
+            <if test="ioOutput != null  and ioOutput != ''"> and t.io_output = #{ioOutput}</if>
+            <if test="channelId != null "> and t.channel_id = #{channelId}</if>
+            <if test="videoAddress != null  and videoAddress != ''"> and t.video_address = #{videoAddress}</if>
+            <if test="reportAddress != null  and reportAddress != ''"> and t.report_address = #{reportAddress}</if>
         </where>
     </select>
     
     <select id="selectTaskManageByTaskId" parameterType="Long" resultMap="TaskManageResult">
+        select t.task_id, t.clock_set_id, t.clock_name, t.task_num, t.task_details, t.io_output, t.channel_id, t.video_address, t.report_address, t.del_flag,t.is_strict,
+               t.create_by, t.create_time, t.update_by, t.update_time, t.remark,als.algorithm_name,als.algorithm_id,als.algorithm_threshold_strict
+        from task_manage t
+                 left join algorithm_channel a on a.channel_id = t.channel_id
+                 left join algorithm_set als on als.algorithm_id = a.algorithm_id
+        where t.task_id = #{taskId}
+    </select>
+    <select id="selectTaskManageByChannelId" parameterType="Long" resultMap="TaskManageResult">
         <include refid="selectTaskManageVo"/>
-        where task_id = #{taskId}
+        where channel_id = #{channelId}
     </select>
 
     <insert id="insertTaskManage" parameterType="TaskManage" useGeneratedKeys="true" keyProperty="taskId">
         insert into task_manage
         <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="clockSetId != null">clock_set_id,</if>
+            <if test="clockName != null">clock_name,</if>
             <if test="taskNum != null">task_num,</if>
             <if test="taskDetails != null">task_details,</if>
+            <if test="ioOutput != null">io_output,</if>
             <if test="channelId != null">channel_id,</if>
             <if test="videoAddress != null">video_address,</if>
             <if test="reportAddress != null">report_address,</if>
-            <if test="algorithmSet != null">algorithm_set,</if>
+            <if test="isStrict != null">is_strict,</if>
             <if test="delFlag != null">del_flag,</if>
             <if test="createBy != null">create_by,</if>
             <if test="createTime != null">create_time,</if>
@@ -58,12 +82,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="remark != null">remark,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="clockSetId != null">#{clockSetId},</if>
+            <if test="clockName != null">#{clockName},</if>
             <if test="taskNum != null">#{taskNum},</if>
             <if test="taskDetails != null">#{taskDetails},</if>
+            <if test="ioOutput != null">#{ioOutput},</if>
             <if test="channelId != null">#{channelId},</if>
             <if test="videoAddress != null">#{videoAddress},</if>
             <if test="reportAddress != null">#{reportAddress},</if>
-            <if test="algorithmSet != null">#{algorithmSet},</if>
+            <if test="isStrict != null">#{isStrict},</if>
             <if test="delFlag != null">#{delFlag},</if>
             <if test="createBy != null">#{createBy},</if>
             <if test="createTime != null">#{createTime},</if>
@@ -76,12 +103,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <update id="updateTaskManage" parameterType="TaskManage">
         update task_manage
         <trim prefix="SET" suffixOverrides=",">
+            <if test="clockSetId != null">clock_set_id = #{clockSetId},</if>
+            <if test="clockName != null">clock_name = #{clockName},</if>
             <if test="taskNum != null">task_num = #{taskNum},</if>
             <if test="taskDetails != null">task_details = #{taskDetails},</if>
+            <if test="ioOutput != null">io_output = #{ioOutput},</if>
             <if test="channelId != null">channel_id = #{channelId},</if>
             <if test="videoAddress != null">video_address = #{videoAddress},</if>
             <if test="reportAddress != null">report_address = #{reportAddress},</if>
-            <if test="algorithmSet != null">algorithm_set = #{algorithmSet},</if>
+            <if test="isStrict != null">is_strict = #{isStrict},</if>
             <if test="delFlag != null">del_flag = #{delFlag},</if>
             <if test="createBy != null">create_by = #{createBy},</if>
             <if test="createTime != null">create_time = #{createTime},</if>

+ 0 - 67
ry.bat

@@ -1,67 +0,0 @@
-@echo off
-
-rem jar平级目录
-set AppName=ruoyi-admin.jar
-
-rem JVM参数
-set JVM_OPTS="-Dname=%AppName%  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
-
-
-ECHO.
-	ECHO.  [1] 启动%AppName%
-	ECHO.  [2] 关闭%AppName%
-	ECHO.  [3] 重启%AppName%
-	ECHO.  [4] 启动状态 %AppName%
-	ECHO.  [5] 退 出
-ECHO.
-
-ECHO.请输入选择项目的序号:
-set /p ID=
-	IF "%id%"=="1" GOTO start
-	IF "%id%"=="2" GOTO stop
-	IF "%id%"=="3" GOTO restart
-	IF "%id%"=="4" GOTO status
-	IF "%id%"=="5" EXIT
-PAUSE
-:start
-    for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
-		set pid=%%a
-		set image_name=%%b
-	)
-	if  defined pid (
-		echo %%is running
-		PAUSE
-	)
-
-start javaw %JVM_OPTS% -jar %AppName%
-
-echo  starting……
-echo  Start %AppName% success...
-goto:eof
-
-rem 函数stop通过jps命令查找pid并结束进程
-:stop
-	for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
-		set pid=%%a
-		set image_name=%%b
-	)
-	if not defined pid (echo process %AppName% does not exists) else (
-		echo prepare to kill %image_name%
-		echo start kill %pid% ...
-		rem 根据进程ID,kill进程
-		taskkill /f /pid %pid%
-	)
-goto:eof
-:restart
-	call :stop
-    call :start
-goto:eof
-:status
-	for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
-		set pid=%%a
-		set image_name=%%b
-	)
-	if not defined pid (echo process %AppName% is dead ) else (
-		echo %image_name% is running
-	)
-goto:eof

+ 0 - 86
ry.sh

@@ -1,86 +0,0 @@
-#!/bin/sh
-# ./ry.sh start 启动 stop 停止 restart 重启 status 状态
-AppName=ruoyi-admin.jar
-
-# JVM参数
-JVM_OPTS="-Dname=$AppName  -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps  -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
-APP_HOME=`pwd`
-LOG_PATH=$APP_HOME/logs/$AppName.log
-
-if [ "$1" = "" ];
-then
-    echo -e "\033[0;31m 未输入操作名 \033[0m  \033[0;34m {start|stop|restart|status} \033[0m"
-    exit 1
-fi
-
-if [ "$AppName" = "" ];
-then
-    echo -e "\033[0;31m 未输入应用名 \033[0m"
-    exit 1
-fi
-
-function start()
-{
-    PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
-
-	if [ x"$PID" != x"" ]; then
-	    echo "$AppName is running..."
-	else
-		nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 &
-		echo "Start $AppName success..."
-	fi
-}
-
-function stop()
-{
-    echo "Stop $AppName"
-
-	PID=""
-	query(){
-		PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
-	}
-
-	query
-	if [ x"$PID" != x"" ]; then
-		kill -TERM $PID
-		echo "$AppName (pid:$PID) exiting..."
-		while [ x"$PID" != x"" ]
-		do
-			sleep 1
-			query
-		done
-		echo "$AppName exited."
-	else
-		echo "$AppName already stopped."
-	fi
-}
-
-function restart()
-{
-    stop
-    sleep 2
-    start
-}
-
-function status()
-{
-    PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l`
-    if [ $PID != 0 ];then
-        echo "$AppName is running..."
-    else
-        echo "$AppName is not running..."
-    fi
-}
-
-case $1 in
-    start)
-    start;;
-    stop)
-    stop;;
-    restart)
-    restart;;
-    status)
-    status;;
-    *)
-
-esac

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно