Bläddra i källkod

添加相关文档和组件

wangxiaofei 7 månader sedan
förälder
incheckning
e348aafb8a
42 ändrade filer med 1428 tillägg och 344 borttagningar
  1. BIN
      doc/Windows_master_2024-10-11.zip
  2. BIN
      doc/ffmpeg-2024-10-07-git-496b8d7a13-full_build.7z
  3. BIN
      doc/ffmpeg-5.1.tar.gz
  4. BIN
      doc/ffmpeg-7.1.tar.xz
  5. BIN
      doc/yasm-1.3.0.tar.gz
  6. BIN
      doc/炉前出铁系统技术要求6-14.docx
  7. BIN
      doc/炉前智能出铁需求.pptx
  8. 17 0
      pom.xml
  9. 1 1
      taphole-admin/src/main/java/com/sckj/admin/TapholeAdminApplication.java
  10. 3 3
      taphole-admin/src/main/java/com/sckj/admin/config/SwaggerConfig.java
  11. 35 1
      taphole-admin/src/main/java/com/sckj/admin/config/WebMvcConfig.java
  12. 33 3
      taphole-admin/src/main/resources/application-dev.yml
  13. 5 0
      taphole-admin/src/main/resources/application-prod.yml
  14. 6 0
      taphole-admin/src/main/resources/application-test.yml
  15. 1 28
      taphole-admin/src/main/resources/application.yml
  16. 79 79
      taphole-camera/src/main/java/com.sckj.camera/controller/CameraFileController.java
  17. 66 84
      taphole-camera/src/main/java/com.sckj.camera/controller/DeviceController.java
  18. 78 78
      taphole-camera/src/main/java/com.sckj.camera/controller/FlowController.java
  19. 0 7
      taphole-camera/src/main/java/com.sckj.camera/model/entity/Camera.java
  20. 2 1
      taphole-camera/src/main/java/com.sckj.camera/model/mapper/CameraFileMapper.java
  21. 2 1
      taphole-camera/src/main/java/com.sckj.camera/model/mapper/CameraFlowMapper.java
  22. 2 1
      taphole-camera/src/main/java/com.sckj.camera/model/mapper/CameraMapper.java
  23. 18 56
      taphole-camera/src/main/java/com.sckj.camera/service/DeviceServiceImpl.java
  24. 1 0
      taphole-camera/src/main/resources/loadFFmpeg.properties
  25. 17 0
      taphole-common/pom.xml
  26. 30 0
      taphole-common/src/main/java/com/sckj/common/socketio/MessageController.java
  27. 27 0
      taphole-common/src/main/java/com/sckj/common/socketio/ServerRunner.java
  28. 59 0
      taphole-common/src/main/java/com/sckj/common/socketio/SocketConfig.java
  29. 18 0
      taphole-common/src/main/java/com/sckj/common/socketio/SocketEventContants.java
  30. 58 0
      taphole-common/src/main/java/com/sckj/common/socketio/SocketHandler.java
  31. 92 0
      taphole-common/src/main/java/com/sckj/common/socketio/SocketUtil.java
  32. 93 0
      taphole-common/src/main/java/com/sckj/common/socketio/SocketioProperties.java
  33. 61 0
      taphole-common/src/main/java/com/sckj/common/socketio/socktjs.html
  34. 20 0
      taphole-common/src/main/java/com/sckj/common/validate/commons/IdValidate.java
  35. 21 0
      taphole-common/src/main/java/com/sckj/common/validate/commons/IdsValidate.java
  36. 25 0
      taphole-common/src/main/java/com/sckj/common/validate/commons/PageValidate.java
  37. 128 0
      taphole-common/src/main/java/com/sckj/common/websocket/MapWebSocketHandler.java
  38. 58 0
      taphole-common/src/main/java/com/sckj/common/websocket/SemaphoreUtils.java
  39. 124 0
      taphole-common/src/main/java/com/sckj/common/websocket/WebSocketConfig.java
  40. 106 0
      taphole-common/src/main/java/com/sckj/common/websocket/WebSocketServer.java
  41. 141 0
      taphole-common/src/main/java/com/sckj/common/websocket/WebSocketUsers.java
  42. 1 1
      taphole-front/src/main/java/com/sckj/front/config/SwaggerConfig.java

BIN
doc/Windows_master_2024-10-11.zip


BIN
doc/ffmpeg-2024-10-07-git-496b8d7a13-full_build.7z


BIN
doc/ffmpeg-5.1.tar.gz


BIN
doc/ffmpeg-7.1.tar.xz


BIN
doc/yasm-1.3.0.tar.gz


BIN
doc/炉前出铁系统技术要求6-14.docx


BIN
doc/炉前智能出铁需求.pptx


+ 17 - 0
pom.xml

@@ -57,6 +57,8 @@
         <aliyun-java.version>4.5.16</aliyun-java.version>
 
         <weixin.version>4.4.0</weixin.version>
+        <knife4j>3.0.3</knife4j>
+        <socketio>2.0.3</socketio>
     </properties>
 
     <!-- 依赖声明 -->
@@ -253,6 +255,21 @@
                 <version>${weixin.version}</version>
             </dependency>
 
+            <!--knife4j-->
+            <dependency>
+                <groupId>com.github.xiaoymin</groupId>
+                <artifactId>knife4j-spring-boot-starter</artifactId>
+                <version>${knife4j}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.corundumstudio.socketio</groupId>
+                <artifactId>netty-socketio</artifactId>
+                <version>${socketio}</version>
+            </dependency>
+
+
+
             <!-- 全局工具 -->
             <dependency>
                 <groupId>com.sckj</groupId>

+ 1 - 1
taphole-admin/src/main/java/com/sckj/admin/TapholeAdminApplication.java

@@ -13,7 +13,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
  */
 @Configuration
 @ComponentScan(basePackages = {"com.sckj"})
-@MapperScan(basePackages = {"com.sckj.*.mapper"})
+@MapperScan(basePackages = {"com.sckj.**.mapper"})
 @EnableTransactionManagement
 @SpringBootApplication(exclude = {RedisRepositoriesAutoConfiguration.class})
 public class TapholeAdminApplication {

+ 3 - 3
taphole-admin/src/main/java/com/sckj/admin/config/SwaggerConfig.java

@@ -28,18 +28,18 @@ public class SwaggerConfig {
                 .apiInfo(apiInfo())
                 .enable(enabled)
                 .select()
-                .apis(RequestHandlerSelectors.basePackage("com.mdd.admin.controller"))
+                .apis(RequestHandlerSelectors.basePackage("com.sckj"))
                 .build()
                 .pathMapping(pathMapping);
     }
 
     private ApiInfo apiInfo(){
-        String author = "FZR";
+        String author = "sckj";
         String url = "https://gitee.com/likeadmin/likeadmin_java";
         String email = "tinyants@163.com";
 
         return new ApiInfoBuilder()
-                .title("LikeAdmin【后台】接口文档")
+                .title("宝钢智能出铁系统【后台】接口文档")
                 .description("likeadmin是一套使用流行的技术栈的快速开发管理后台")
                 .version(GlobalConfig.version)
                 .contact(new Contact(author, url, email))

+ 35 - 1
taphole-admin/src/main/java/com/sckj/admin/config/WebMvcConfig.java

@@ -4,13 +4,19 @@ import com.sckj.admin.TapholeAdminInterceptor;
 import com.sckj.common.config.GlobalConfig;
 import com.sckj.common.util.YmlUtils;
 import org.jetbrains.annotations.NotNull;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.CacheControl;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 import javax.annotation.Resource;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Web配置
@@ -39,7 +45,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         registry.addInterceptor(likeAdminInterceptor)
-                .addPathPatterns("/**");
+                .addPathPatterns("/**").excludePathPatterns("/doc.html","/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs");
     }
 
     /**
@@ -50,6 +56,34 @@ public class WebMvcConfig implements WebMvcConfigurer {
         String directory = YmlUtils.get("like.upload-directory");
         registry.addResourceHandler("/"+ GlobalConfig.publicPrefix +"/**")
                 .addResourceLocations("file:" + directory);
+
+        /** swagger配置 */
+        registry.addResourceHandler("/doc.html")
+                .addResourceLocations("classpath:/META-INF/resources/doc.html")
+                .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());
+    }
+
+    /**
+     * 跨域配置
+     */
+    @Bean
+    public CorsFilter corsFilter()
+    {
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+        // 设置访问源地址
+        config.addAllowedOriginPattern("*");
+        // 设置访问源请求头
+        config.addAllowedHeader("*");
+        // 设置访问源请求方法
+        config.addAllowedMethod("*");
+        // 有效期 1800秒
+        config.setMaxAge(1800L);
+        // 添加映射路径,拦截一切请求
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        source.registerCorsConfiguration("/**", config);
+        // 返回新的CorsFilter
+        return new CorsFilter(source);
     }
 
 }

+ 33 - 3
taphole-admin/src/main/resources/application-dev.yml

@@ -2,23 +2,53 @@
 like:
   upload-directory: /www/uploads/likeadmin-java/ # 上传目录
 
+# 服务配置
+server:
+  port: 28080
+  servlet:
+    context-path: /
+
 # 框架配置
 spring:
   # 数据源配置
   datasource:
-    url: jdbc:mysql://localhost:13306/taphole?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
+    url: jdbc:mysql://112.124.32.131:3306/taphole?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
     type: com.zaxxer.hikari.HikariDataSource # 数据源类型
     driver-class-name: com.mysql.jdbc.Driver # MySql的驱动
     username: root # 数据库账号
-    password: root@123 # 数据库密码
+    password: lghr4ELx6GuN2Xp9 # 数据库密码
   # Redis配置
   redis:
     host: 101.37.148.192   # Redis服务地址
     port: 6379        # Redis端口
     password: sckj@1234        # Redis密码
     database: 5       # 数据库索引
+#    lettuce:
+#      pool:
+#        max-wait: 30000 # 连接池最大阻塞等待时间(使用负数表示没有限制,默认-1)
+#        max-active: 100 # 连接池最大连接数(使用负数表示没有限制,默认8)
+#        max-idle: 20    # 连接池中的最大空闲连接(默认8)
+#        min-idle: 0     # 连接池中的最小空闲连接(默认0)
 
 # Mybatis-plus配置 【是否开启SQL日志输出】
 #mybatis-plus:
 #    configuration:
-#      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+#      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+app:
+  filepath: D:/opt/camera
+
+rtmp:
+  rtmphost: 127.0.0.1:1935
+  httphost: 127.0.0.1:7080
+
+socketio:
+  host: 127.0.0.1		#主机名,默认是 0.0.0.0 (这个设不设置无所谓,因为后面的 SocketConfig 类一般不用设置这个)
+  port: 33000			#监听端口
+  maxFramePayloadLength: 1048576
+  maxHttpContentLength: 1048576
+  bossCount: 1
+  workCount: 100
+  allowCustomRequests: true
+  upgradeTimeout: 1000000		#协议升级超时时间(毫秒),默认10000。HTTP握手升级为ws协议超时时间
+  pingTimeout: 6000000		    #Ping消息超时时间(毫秒),默认60000,这个时间间隔内没有接收到心跳消息就会发送超时事件
+  pingInterval: 25000			#Ping消息间隔(毫秒),默认25000。客户端向服务器发送一条心跳消息间隔

+ 5 - 0
taphole-admin/src/main/resources/application-prod.yml

@@ -2,6 +2,11 @@
 like:
   upload-directory: /www/uploads/likeadmin-java/ # 上传目录
 
+# 服务配置
+server:
+  port: 8082
+  servlet:
+    context-path: /
 # 框架配置
 spring:
   # 数据源配置

+ 6 - 0
taphole-admin/src/main/resources/application-test.yml

@@ -2,6 +2,12 @@
 like:
   upload-directory: /www/uploads/likeadmin-java/ # 上传目录
 
+# 服务配置
+server:
+  port: 8082
+  servlet:
+    context-path: /
+
 # 框架配置
 spring:
   # 数据源配置

+ 1 - 28
taphole-admin/src/main/resources/application.yml

@@ -14,13 +14,7 @@ like:
     # 是否开启swagger
     enabled: true
     # 请求前缀
-    pathMapping: /dev-api
-
-# 服务配置
-server:
-  port: 8082
-  servlet:
-    context-path: /
+    pathMapping: /
 
 # 框架配置
 spring:
@@ -31,22 +25,6 @@ spring:
     throw-exception-if-no-handler-found: true
     pathmatch:
       matching-strategy: ant_path_matcher
-  # 数据源配置
-  datasource:
-    url: jdbc:mysql://localhost:13306/taphole?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
-    type: com.zaxxer.hikari.HikariDataSource # 数据源类型
-    driver-class-name: com.mysql.jdbc.Driver # MySql的驱动
-    username: root # 数据库账号
-    password: root@123 # 数据库密码
-    hikari:
-      connection-timeout: 30000     # 等待连接分配连接的最大时长(毫秒),超出时长还没可用连接则发送SQLException,默认30秒
-      minimum-idle: 5               # 最小连接数
-      maximum-pool-size: 20         # 最大连接数
-      auto-commit: true             # 自动提交
-      idle-timeout: 600000          # 连接超时的最大时长(毫秒),超时则被释放(retired),默认10分钟
-      pool-name: DateSourceHikariCP # 连接池名称
-      max-lifetime: 1800000         # 连接的生命时长(毫秒),超时而且没被使用则被释放,默认30分钟(1800000ms)
-      connection-init-sql: SELECT 1 # 连接时发起SQL测试脚本
   # 限制配置
   servlet:
     multipart:
@@ -55,11 +33,6 @@ spring:
       enabled: true
   # Redis配置
   redis:
-    host: 101.37.148.192   # Redis服务地址
-    port: 6379        # Redis端口
-    password: sckj@1234        # Redis密码
-    database: 5       # 数据库索引
-    timeout: 5000     # 连接超时
     lettuce:
       pool:
         max-wait: 30000 # 连接池最大阻塞等待时间(使用负数表示没有限制,默认-1)

+ 79 - 79
taphole-camera/src/main/java/com.sckj.camera/controller/CameraFileController.java

@@ -1,91 +1,91 @@
-package com.sckj.camera.controller;//package com.sckj.camera.controller;
-//
-//import com.sckj.camera.model.entity.CameraFile;
-//import com.sckj.camera.service.CameraFileService;
-//import io.swagger.annotations.Api;
-//import io.swagger.annotations.ApiImplicitParam;
-//import io.swagger.annotations.ApiImplicitParams;
-//import io.swagger.annotations.ApiOperation;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.web.bind.annotation.*;
-//
-//import javax.servlet.http.HttpServletResponse;
-//
-///**
-// * Description:
-// * Author:zhangzeyu
-// */
-//@Api(tags = "文件上传下载")
-//@RestController
-//@RequestMapping(value = "/camerafile", produces = { "application/json;charset=utf-8" })
-//public class CameraFileController {
-//
-//    @Autowired
-//    private CameraFileService cameraFileService;
-//
-//    /**
-//     * 下载文件
-//     *
-//     * @param id
-//     * @param response
-//     */
-//    @ApiOperation(value = "下载文件")
-//    @ApiImplicitParam(name = "id", value = "内容ID", required = true, paramType = "path", dataType = "int")
-//    @GetMapping("/{id}")
-//    public void getFile(@PathVariable Integer id, HttpServletResponse response) {
-//        cameraFileService.downloadFile(id, response);
-//    }
-//
-//    /**
-//     * 下载文件
-//     *
-//     * @param fileName
-//     * @param filePath
-//     * @param response
-//     */
-//    @ApiOperation(value = "下载指定路径文件")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "fileName", value = "下载文件显示名", required = true, paramType = "query", dataType = "string"),
-//            @ApiImplicitParam(name = "filePath", value = "文件路径,由接口提供", required = true, paramType = "query", dataType = "string")
-//    })
-//    @GetMapping("/getFile")
-//    public void getFileByPath(String fileName, String filePath, HttpServletResponse response) {
+package com.sckj.camera.controller;
+
+import com.sckj.camera.model.entity.CameraFile;
+import com.sckj.camera.service.CameraFileServiceImpl;
+import com.sckj.common.core.AjaxResult;
+import com.sckj.common.core.PageResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Description:
+ * Author:sckj
+ */
+@Api(tags = "文件上传下载")
+@RestController
+@RequestMapping(value = "/camerafile", produces = { "application/json;charset=utf-8" })
+public class CameraFileController {
+
+    @Autowired
+    private CameraFileServiceImpl cameraFileService;
+
+    /**
+     * 下载文件
+     *
+     * @param id
+     * @param response
+     */
+    @ApiOperation(value = "下载文件")
+    @ApiImplicitParam(name = "id", value = "内容ID", required = true, paramType = "path", dataType = "int")
+    @GetMapping("/{id}")
+    public void getFile(@PathVariable Integer id, HttpServletResponse response) {
+        cameraFileService.downloadFile(id, response);
+    }
+
+    /**
+     * 下载文件
+     *
+     * @param fileName
+     * @param filePath
+     * @param response
+     */
+    @ApiOperation(value = "下载指定路径文件")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "fileName", value = "下载文件显示名", required = true, paramType = "query", dataType = "string"),
+            @ApiImplicitParam(name = "filePath", value = "文件路径,由接口提供", required = true, paramType = "query", dataType = "string")
+    })
+    @GetMapping("/getFile")
+    public void getFileByPath(String fileName, String filePath, HttpServletResponse response) {
 //        Assert.isBlank(filePath, "文件路径不可为空");
 //        HAssert.isBlank(fileName, "文件名称不可为空");
-//        cameraFileService.downloadFromPath(filePath, fileName, response);
-//    }
-//
-//    /**
-//     * 删除文件
-//     *
-//     * @param id 文件id
-//     */
-//    @ApiOperation("删除文件")
-//    @ApiImplicitParam(name = "id", value = "文件ID", paramType = "path", dataType = "int")
-//    @DeleteMapping("/{id}")
-//    public ResultEntity<String> delete(@PathVariable Integer id) {
-//        cameraFileService.deleteFile(id);
-//        return ResultUtils.ok();
-//    }
-//
-//    /**
-//     * 根据ip和类型查找文件
-//     *
-//     * @param ipc 网络摄像机ip地址
-//     * @param type 文件类型 0-所有 1-video 2-picture 3-record
-//     */
+        cameraFileService.downloadFromPath(filePath, fileName, response);
+    }
+
+    /**
+     * 删除文件
+     *
+     * @param id 文件id
+     */
+    @ApiOperation("删除文件")
+    @ApiImplicitParam(name = "id", value = "文件ID", paramType = "path", dataType = "int")
+    @DeleteMapping("/{id}")
+    public AjaxResult delete(@PathVariable Integer id) {
+        cameraFileService.deleteFile(id);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 根据ip和类型查找文件
+     *
+     * @param ipc 网络摄像机ip地址
+     * @param type 文件类型 0-所有 1-video 2-picture 3-record
+     */
 //    @ApiOperation("查找文件")
 //    @ApiImplicitParams({
 //            @ApiImplicitParam(name = "ipc", value = "网络摄像机ip地址", paramType = "path", dataType = "string"),
 //            @ApiImplicitParam(name = "type", value = "文件类型", paramType = "path", dataType = "int"),
-//            @ApiImplicitParam(name = "pageNum", value = "页码", paramType = "query", dataType = "string"),
-//            @ApiImplicitParam(name = "pageSize", value = "数量", paramType = "query", dataType = "string")
 //    })
 //    @GetMapping("/findFilePage")
-//    public ResultEntity<PageResult<CameraFile>> findFilePage(String ipc,
+//    public AjaxResult<PageResult<CameraFile>> findFilePage(String ipc,
 //                                                             Integer type,
 //                                                             @RequestParam(defaultValue = "1") Integer pageNum,
 //                                                             @RequestParam(defaultValue = "10") Integer pageSize) {
-//        return ResultUtils.ok(cameraFileService.findFilePage(ipc,type,pageNum,pageSize));
+//        return AjaxResult.success(cameraFileService.findFilePage(ipc,type,pageNum,pageSize));
 //    }
-//}
+}

+ 66 - 84
taphole-camera/src/main/java/com.sckj.camera/controller/DeviceController.java

@@ -1,84 +1,66 @@
-//package com.sckj.camera.controller;
-//
-//import com.sckj.camera.model.entity.Camera;
-//
-//
-//import com.sckj.camera.service.DeviceServiceImpl;
-//import com.sckj.common.core.AjaxResult;
-//import io.swagger.annotations.Api;
-//import io.swagger.annotations.ApiImplicitParam;
-//import io.swagger.annotations.ApiImplicitParams;
-//import io.swagger.annotations.ApiOperation;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.web.bind.annotation.*;
-//
-//import java.util.List;
-//
-//@Api(tags = "相机设备")
-//@RestController
-//@RequestMapping(value = "/camera")
-//public class DeviceController    {
-//
-//    @Autowired
-//    private DeviceServiceImpl deviceService;
-//
-//    @ApiOperation("相机设备分页信息(by试验台ID)")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "testerId", value = "试验台id", paramType = "query", dataType = "String"),
-//    })
-//    @GetMapping("/findPage")
-//    public AjaxResult findPage(@RequestParam(required = false) String testerId) {
-//        return AjaxResult.success(deviceService.findPage(testerId));
-//    }
-//
-//    @ApiOperation("NVR分页信息")
-//    @GetMapping("/findNvrPage")
-//    public AjaxResult findNvrPage() {
-//        return AjaxResult.success(deviceService.findNvrPage());
-//    }
-//
-//    @ApiOperation("NVR列表")
-//    @GetMapping("/findNvr")
-//    public AjaxResult findPage() {
-//        return AjaxResult.success(deviceService.findNvrList());
-//    }
-//
-//    @ApiOperation("查询相机设备")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "cameraId", value = "相机设备Id", paramType = "query", dataType = "Integer"),
-//    })
-//    @GetMapping("/findCamera")
-//    public AjaxResult findCamera(Integer cameraId) {
-//        return AjaxResult.success(deviceService.getById(cameraId));
-//    }
-//
-//    @ApiOperation("更新相机设备信息")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "camera", value = "相机设备信息", paramType = "body", dataType = "Camera"),
-//    })
-//    @PostMapping("/updateCamera")
-//    public AjaxResult updateCamera(@RequestBody Camera camera) {
-//        deviceService.updateCamera(camera);
-//        return AjaxResult.success();
-//    }
-//
-//    @ApiOperation("删除相机设备信息")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "cameraId", value = "相机设备Id", paramType = "query", dataType = "Integer"),
-//    })
-//    @GetMapping("/deleteCamera")
-//    public AjaxResult deleteCamera(Integer cameraId) {
-//        deviceService.removeById(cameraId);
-//        return AjaxResult.success();
-//    }
-//
-//    @ApiOperation("相机设备树")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "testerList", value = "有权限试验室id号", paramType = "body", dataType = "List<String>"),
-//    })
-//    @PostMapping("/getCameraTree")
-//    public AjaxResult getCameraTree(@RequestBody List<String> testerList) {
-//        return AjaxResult.success(deviceService.getCameraTree(testerList));
-//    }
-//
-//}
+package com.sckj.camera.controller;
+
+import com.github.pagehelper.PageHelper;
+import com.sckj.camera.model.entity.Camera;
+import com.sckj.camera.service.DeviceServiceImpl;
+import com.sckj.common.core.AjaxResult;
+import com.sckj.common.validate.commons.PageValidate;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+@Api(tags = "相机设备")
+@RestController
+@RequestMapping(value = "/camera")
+public class DeviceController  {
+
+    @Autowired
+    private DeviceServiceImpl deviceService;
+
+    @ApiOperation("相机设备分页信息(by试验台ID)")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "testerId", value = "试验台id", paramType = "query", dataType = "String"),
+    })
+    @GetMapping("/list")
+    public AjaxResult list(@Validated PageValidate pageValidate,
+                               @Validated Camera searchValidate) {
+        PageHelper.startPage(pageValidate.getPageNo(),pageValidate.getPageSize());
+        return AjaxResult.success(deviceService.list());
+    }
+
+
+    @ApiOperation("查询相机设备")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "cameraId", value = "相机设备Id", paramType = "query", dataType = "Integer"),
+    })
+    @GetMapping("/findCamera")
+    public AjaxResult findCamera(Integer cameraId) {
+        return AjaxResult.success(deviceService.getById(cameraId));
+    }
+
+    @ApiOperation("更新相机设备信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "camera", value = "相机设备信息", paramType = "body", dataType = "Camera"),
+    })
+    @PostMapping("/updateCamera")
+    public AjaxResult updateCamera(@RequestBody Camera camera) {
+        deviceService.updateCamera(camera);
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("删除相机设备信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "cameraId", value = "相机设备Id", paramType = "query", dataType = "Integer"),
+    })
+    @GetMapping("/deleteCamera")
+    public AjaxResult deleteCamera(Integer cameraId) {
+        deviceService.removeById(cameraId);
+        return AjaxResult.success();
+    }
+
+
+}

+ 78 - 78
taphole-camera/src/main/java/com.sckj.camera/controller/FlowController.java

@@ -1,78 +1,78 @@
-//package com.sckj.camera.controller;
-//
-//import com.sckj.camera.service.FlowServiceImpl;
-//import com.sckj.common.core.AjaxResult;
-//import io.swagger.annotations.Api;
-//import io.swagger.annotations.ApiImplicitParam;
-//import io.swagger.annotations.ApiImplicitParams;
-//import io.swagger.annotations.ApiOperation;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.web.bind.annotation.GetMapping;
-//import org.springframework.web.bind.annotation.RequestMapping;
-//import org.springframework.web.bind.annotation.RestController;
-//
-//@Api(tags = "视频流")
-//@RestController
-//@RequestMapping(value = "/flow")
-//public class FlowController    {
-//
-//    @Autowired
-//    private FlowServiceImpl flowService;
-//
-//    /**
-//     * 停止并删除推流
-//     * @param tasker 推流名
-//     */
-//    @ApiOperation("关闭进程")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
-//    })
-//    @GetMapping("/stopByTasker")
-//    public AjaxResult stopByTasker(String tasker){
-//        flowService.stopByTasker(tasker);
-//        return  AjaxResult.success();
-//    }
-//
-//    /**
-//     * 开始录制
-//     * @param tasker 推流名
-//     */
-//    @ApiOperation("开始录制")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
-//    })
-//    @GetMapping("/startRecord")
-//    public AjaxResult startRecord(String tasker){
-//        flowService.startRecord(tasker);
-//        return  AjaxResult.success();
-//    }
-//
-//    /**
-//     * 停止录制
-//     * @param tasker 推流名
-//     */
-//    @ApiOperation("停止录制")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
-//    })
-//    @GetMapping("/stopRecord")
-//    public AjaxResult stopRecord(String tasker){
-//        flowService.stopRecord(tasker);
-//        return  AjaxResult.success();
-//    }
-//
-//    /**
-//     * 流状态更新
-//     * @param tasker 推流名
-//     */
-//    @ApiOperation("流状态更新")
-//    @ApiImplicitParams({
-//            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
-//    })
-//    @GetMapping("/notification")
-//    public AjaxResult notification(String tasker){
-//        flowService.notification(tasker);
-//        return  AjaxResult.success();
-//    }
-//
-//}
+package com.sckj.camera.controller;
+
+import com.sckj.camera.service.FlowServiceImpl;
+import com.sckj.common.core.AjaxResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "视频流")
+@RestController
+@RequestMapping(value = "/flow")
+public class FlowController    {
+
+    @Autowired
+    private FlowServiceImpl flowService;
+
+    /**
+     * 停止并删除推流
+     * @param tasker 推流名
+     */
+    @ApiOperation("关闭进程")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
+    })
+    @GetMapping("/stopByTasker")
+    public AjaxResult stopByTasker(String tasker){
+        flowService.stopByTasker(tasker);
+        return  AjaxResult.success();
+    }
+
+    /**
+     * 开始录制
+     * @param tasker 推流名
+     */
+    @ApiOperation("开始录制")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
+    })
+    @GetMapping("/startRecord")
+    public AjaxResult startRecord(String tasker){
+        flowService.startRecord(tasker);
+        return  AjaxResult.success();
+    }
+
+    /**
+     * 停止录制
+     * @param tasker 推流名
+     */
+    @ApiOperation("停止录制")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
+    })
+    @GetMapping("/stopRecord")
+    public AjaxResult stopRecord(String tasker){
+        flowService.stopRecord(tasker);
+        return  AjaxResult.success();
+    }
+
+    /**
+     * 流状态更新
+     * @param tasker 推流名
+     */
+    @ApiOperation("流状态更新")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "tasker", value = "推流名", paramType = "query", dataType = "String")
+    })
+    @GetMapping("/notification")
+    public AjaxResult notification(String tasker){
+        flowService.notification(tasker);
+        return  AjaxResult.success();
+    }
+
+}

+ 0 - 7
taphole-camera/src/main/java/com.sckj.camera/model/entity/Camera.java

@@ -41,16 +41,9 @@ public class Camera {
     //设备名称
     private String name;
 
-    //设备是否支持云台控制
-    @TableField(value = "ptz_control")
-    private Byte ptzControl;
-
     //设备启用标志
     private Byte enable;
 
-    //这个是我用来标识这个摄像头是属于哪个房间的
-    @TableField(value = "tester_id")
-    private String testerId;
 
     private Date createTime;
 

+ 2 - 1
taphole-camera/src/main/java/com.sckj.camera/model/mapper/CameraFileMapper.java

@@ -2,7 +2,8 @@ package com.sckj.camera.model.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.sckj.camera.model.entity.CameraFile;
+import com.sckj.common.core.basics.IBaseMapper;
 
-public interface CameraFileMapper extends BaseMapper<CameraFile> {
+public interface CameraFileMapper extends IBaseMapper<CameraFile> {
 
 }

+ 2 - 1
taphole-camera/src/main/java/com.sckj.camera/model/mapper/CameraFlowMapper.java

@@ -3,6 +3,7 @@ package com.sckj.camera.model.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.sckj.camera.model.entity.CameraFlow;
+import com.sckj.common.core.basics.IBaseMapper;
 
-public interface CameraFlowMapper  extends BaseMapper<CameraFlow> {
+public interface CameraFlowMapper  extends IBaseMapper<CameraFlow> {
 }

+ 2 - 1
taphole-camera/src/main/java/com.sckj.camera/model/mapper/CameraMapper.java

@@ -3,6 +3,7 @@ package com.sckj.camera.model.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.sckj.camera.model.entity.Camera;
+import com.sckj.common.core.basics.IBaseMapper;
 
-public interface CameraMapper   extends BaseMapper<Camera> {
+public interface CameraMapper   extends IBaseMapper<Camera> {
 }

+ 18 - 56
taphole-camera/src/main/java/com.sckj.camera/service/DeviceServiceImpl.java

@@ -1,50 +1,38 @@
 package com.sckj.camera.service;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sckj.camera.model.entity.Camera;
 import com.sckj.camera.model.mapper.CameraMapper;
-import com.sckj.camera.model.view.CameraTreeVO;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 @Service
 @Transactional
 public class DeviceServiceImpl extends ServiceImpl<CameraMapper, Camera> {
 
-    public Camera findPage(String testerId) {
-//        HTCriteria<Camera> criteria = HTCriteria.getInstance(Camera.class);
-//        criteria.andEqualTo(Camera::getType,0);
+//    public Camera findPage(String type) {
+//        Map<String,Object> map = new HashMap<>();
+//
+//        if (StringUtils.isNotBlank((type))) {
+//            map.put("type",type);
+//        }else{
+//            map.put("type",0);
+//        }
+//        List<Camera> cameras = baseMapper.selectByMap(map);
+//        if(ObjectUtils.isNotEmpty(cameras)){
+//            return cameras.get(0);
+//        }
+//        return null;
+//    }
 
-        Map<String,Object> map = new HashMap<>();
-        map.put("type",0);
-        if (StringUtils.isNotBlank((testerId))) {
-            map.put("type",testerId);
-        }
-        List<Camera> cameras = baseMapper.selectByMap(map);
-        if(ObjectUtils.isNotEmpty(cameras)){
-            return cameras.get(0);
-        }
-        return null;
-    }
 
-    public List<Camera> findNvrPage() {
-//        HTCriteria<Camera> criteria = HTCriteria.getInstance(Camera.class);
-//        criteria.andEqualTo(Camera::getType,1);
-//        return findPage(criteria,pageNum,pageSize);
-        LambdaQueryWrapper<Camera> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(Camera::getType,"1");
-        return baseMapper.selectList(queryWrapper);
-    }
-
-    public List<Camera> findNvrList() {
-        return  null;
-    }
 
     public void updateCamera(Camera camera) {
         if (camera.getCameraId() != null) {
@@ -57,31 +45,5 @@ public class DeviceServiceImpl extends ServiceImpl<CameraMapper, Camera> {
         }
     }
 
-    public List<CameraTreeVO> getCameraTree(List<String> testerList) {
-
-        List<CameraTreeVO> treeList = new ArrayList<>();
-        List<Camera> cameraList=null;
-
-        if (testerList.size() > 0) {
-            LambdaQueryWrapper<Camera> queryWrapper = new LambdaQueryWrapper<>();
-            queryWrapper.in(Camera::getTesterId,testerList).or().eq(Camera::getType,"1");
-            cameraList =  baseMapper.selectList(queryWrapper);
-        } else {
-            cameraList = list();
-        }
-
-        Map<Integer, List<Camera>> cameraMap = cameraList.stream().collect(Collectors.groupingBy(Camera::getNvrId));
-        //nvr或无nvr管理的摄像机
-        List<Camera> nvrList = cameraMap.get(0);
-        //生成树
-        for (Camera nvr : nvrList) {
-            CameraTreeVO cameraTreeVO = new CameraTreeVO();
-            cameraTreeVO.setNvr(nvr);
-            cameraTreeVO.setCameraList(cameraMap.get(nvr.getCameraId()));
-            treeList.add(cameraTreeVO);
-        }
-
-        return treeList;
-    }
 
 }

+ 1 - 0
taphole-camera/src/main/resources/loadFFmpeg.properties

@@ -1,4 +1,5 @@
 #ffmpeg执行路径,一般为ffmpeg的安装目录,该路径只能是目录,不能为具体文件路径,否则会报错
+#path=/usr/bin/
 path=D:\\project\\xiha\\ffmpeg-2024-10-07-git-496b8d7a13-full_build\\bin\\
 #path=E:/ffmpeg/bin/
 #存放任务的默认Map的初始化大小

+ 17 - 0
taphole-common/pom.xml

@@ -209,6 +209,23 @@
             <groupId>com.github.binarywang</groupId>
             <artifactId>weixin-java-pay</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-spring-boot-starter</artifactId>
+        </dependency>
+
+        <!-- SpringBoot Websocket -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.corundumstudio.socketio</groupId>
+            <artifactId>netty-socketio</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 30 - 0
taphole-common/src/main/java/com/sckj/common/socketio/MessageController.java

@@ -0,0 +1,30 @@
+package com.sckj.common.socketio;
+
+import com.sckj.common.core.AjaxResult;
+import io.swagger.annotations.Api;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 消息Controller
+ *
+ * @author sckj
+ */
+@RestController
+@Api(tags="消息")
+@RequestMapping("/message")
+public class MessageController   {
+
+    /**
+     *  给指定客户端发送消息
+     *
+     * @Param [userId, message]
+     * @return
+     **/
+    @GetMapping("/sendToOne")
+    public AjaxResult sendToOne(String userId , String message){
+        SocketUtil.sendToOne(userId,message);
+        return AjaxResult.success("单独发送消息成功。");
+    }
+}

+ 27 - 0
taphole-common/src/main/java/com/sckj/common/socketio/ServerRunner.java

@@ -0,0 +1,27 @@
+package com.sckj.common.socketio;
+
+import com.corundumstudio.socketio.SocketIOServer;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+@AllArgsConstructor
+public class ServerRunner implements CommandLineRunner {
+
+    private final SocketIOServer socketIOServer;
+
+    /**
+     *  项目启动时,自动启动 socket 服务,服务端开始工作
+     *
+     * @Param [args]
+     * @return
+     **/
+    @Override
+    public void run(String... args)  {
+        socketIOServer.start();
+        log.info("socket.io server started !");
+    }
+}

+ 59 - 0
taphole-common/src/main/java/com/sckj/common/socketio/SocketConfig.java

@@ -0,0 +1,59 @@
+package com.sckj.common.socketio;
+
+import com.corundumstudio.socketio.SocketIOServer;
+import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @Author sckj
+ * @Date 2024-10-15 下午 04:40
+ * @Description TODO
+ */
+@Component
+public class SocketConfig {
+
+    @Resource
+    SocketioProperties socketioProperties;
+
+    @Bean
+    public SocketIOServer socketIOServer() {
+        com.corundumstudio.socketio.Configuration configuration = new com.corundumstudio.socketio.Configuration();
+        configuration.setPort(socketioProperties.getPort());
+        com.corundumstudio.socketio.SocketConfig socketConfig=new com.corundumstudio.socketio.SocketConfig();
+        socketConfig.setReuseAddress(true);
+        configuration.setSocketConfig(socketConfig);
+        configuration.setOrigin(null);
+        configuration.setBossThreads(socketioProperties.getBossCount());
+        configuration.setWorkerThreads(socketioProperties.getWorkCount());
+        configuration.setAllowCustomRequests(socketioProperties.getAllowCustomRequests());
+        configuration.setUpgradeTimeout(socketioProperties.getUpgradeTimeout());
+        configuration.setPingTimeout(socketioProperties.getPingTimeout());
+        configuration.setPingInterval(socketioProperties.getPingInterval());
+        //设置 sessionId 随机
+        configuration.setRandomSession(true);
+
+//         configuration.setKeyStorePassword("pi0yo93pqgrs");
+//         configuration.setKeyStore(this.getClass().getResourceAsStream("www.ibms.club.jks"));
+//         configuration.setAuthorizationListener(data -> {
+//             String token = data.getSingleUrlParam("token");
+//             return StrUtil.isNotBlank(token);
+//         });
+
+        //初始化 Socket 服务端配置
+        return new SocketIOServer(configuration);
+    }
+
+    /**
+     *  Spring加载 SocketIOServer
+     *
+     * @Param [server]
+     * @return
+     **/
+    @Bean
+    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketIOServer ) {
+        return new SpringAnnotationScanner(socketIOServer );
+    }
+}

+ 18 - 0
taphole-common/src/main/java/com/sckj/common/socketio/SocketEventContants.java

@@ -0,0 +1,18 @@
+package com.sckj.common.socketio;
+
+/**
+ * @Author sckj
+ * @Date 2024-10-15 下午 04:39
+ * @Description TODO
+ */
+public class SocketEventContants {
+    /**
+     * 用户频道
+     **/
+    public static final String CHANNEL_USER = "channel_user";
+
+    /**
+     * 系统频道
+     **/
+    public static final String CHANNEL_SYSTEM = "channel_system";
+}

+ 58 - 0
taphole-common/src/main/java/com/sckj/common/socketio/SocketHandler.java

@@ -0,0 +1,58 @@
+package com.sckj.common.socketio;
+
+import com.corundumstudio.socketio.SocketIOServer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+/**
+ * @Author: sckj
+ * @Description: 客户端自动连接和断开、服务端关闭
+ */
+@Component
+@Slf4j
+public class SocketHandler {
+
+    @Autowired
+    private SocketIOServer socketIoServer;
+
+    /**
+     *  容器销毁前,自动调用此方法,关闭 socketIo 服务端
+     *
+     * @Param []
+     * @return
+     **/
+    @PreDestroy
+    private void destroy(){
+        try {
+            log.debug("关闭 socket 服务端");
+            socketIoServer.stop();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    @PostConstruct
+    public void init() {
+        log.debug("SocketEventListener initialized");
+
+        //添加监听,客户端自动连接到 socket 服务端
+        socketIoServer.addConnectListener(client -> {
+            String userId = client.getHandshakeData().getSingleUrlParam("userId");
+            SocketUtil.connectMap.put(userId, client);
+            log.debug("客户端userId: "+ userId+ "已连接,客户端ID为:" + client.getSessionId());
+        });
+
+        //添加监听,客户端跟 socket 服务端自动断开
+        socketIoServer.addDisconnectListener(client -> {
+            String userId = client.getHandshakeData().getSingleUrlParam("userId");
+            SocketUtil.connectMap.remove(userId, client);
+            log.debug("客户端userId:" + userId + "断开连接,客户端ID为:" + client.getSessionId());
+        });
+    }
+
+
+}

+ 92 - 0
taphole-common/src/main/java/com/sckj/common/socketio/SocketUtil.java

@@ -0,0 +1,92 @@
+package com.sckj.common.socketio;
+
+import com.corundumstudio.socketio.SocketIOClient;
+import com.corundumstudio.socketio.annotation.OnEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @Author sckj
+ * @Date 2024-10-15 下午 04:41
+ * @Description TODO
+ */
+@Component
+@Slf4j
+public class SocketUtil {
+
+    //暂且把用户&客户端信息存在缓存
+    public static ConcurrentMap<String, SocketIOClient> connectMap = new ConcurrentHashMap<>();
+
+    /**
+     *  单发消息(以 userId 为标识符,给用户发送消息)
+     *
+     * @Param [userId, message]
+     * @return
+     **/
+    public static void sendToOne(String userId, Object message) {
+        //拿出某个客户端信息
+        SocketIOClient socketClient = getSocketClient(userId);
+        if (Objects.nonNull(socketClient) ){
+            //单独给他发消息
+            socketClient.sendEvent(SocketEventContants.CHANNEL_USER,message);
+        }else{
+            log.info(userId + "已下线,暂不发送消息。");
+        }
+    }
+
+    /**
+     *  群发消息
+     *
+     * @Param
+     * @return
+     **/
+    public static void sendToAll(Object message) {
+        if (connectMap.isEmpty()){
+            return;
+        }
+        //给在这个频道的每个客户端发消息
+        for (Map.Entry<String, SocketIOClient> entry : connectMap.entrySet()) {
+            entry.getValue().sendEvent(SocketEventContants.CHANNEL_SYSTEM, message);
+        }
+    }
+
+    /**
+     * 根据 userId 识别出 socket 客户端
+     * @param userId
+     * @return
+     */
+    public static SocketIOClient getSocketClient(String userId){
+        SocketIOClient client = null;
+        if (StringUtils.hasLength(userId) &&  !connectMap.isEmpty()){
+            for (String key : connectMap.keySet()) {
+                if (userId.equals(key)){
+                    client = connectMap.get(key);
+                }
+            }
+        }
+        return client;
+    }
+
+    /**
+     *  1)使用事件注解,服务端监听获取客户端消息;
+     *  2)拿到客户端发过来的消息之后,可以再根据业务逻辑发送给想要得到这个消息的人;
+     *  3)channel_system 之所以会向全体客户端发消息,是因为我跟前端约定好了,你们也可以自定定义;
+     *
+     * @Param message
+     * @return
+     **/
+    @OnEvent(value = SocketEventContants.CHANNEL_SYSTEM)
+    public void channelSystemListener(String message) {
+        if (!StringUtils.hasLength(message)){
+            return;
+        }
+
+        sendToAll(message);
+    }
+}

+ 93 - 0
taphole-common/src/main/java/com/sckj/common/socketio/SocketioProperties.java

@@ -0,0 +1,93 @@
+package com.sckj.common.socketio;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author sckj
+ * @Date 2024-10-15 下午 04:42
+ * @Description socketio属性
+ */
+@Component
+@ConfigurationProperties(prefix = "socketio")
+public class SocketioProperties {
+    private String host;
+
+    private Integer port;
+
+    private int bossCount;
+
+    private int workCount;
+
+    private boolean allowCustomRequests;
+
+    private int upgradeTimeout;
+
+    private int pingTimeout;
+
+    private int pingInterval;
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public Integer getPort() {
+        return port;
+    }
+
+    public void setPort(Integer port) {
+        this.port = port;
+    }
+
+    public int getBossCount() {
+        return bossCount;
+    }
+
+    public void setBossCount(int bossCount) {
+        this.bossCount = bossCount;
+    }
+
+    public int getWorkCount() {
+        return workCount;
+    }
+
+    public void setWorkCount(int workCount) {
+        this.workCount = workCount;
+    }
+
+    public boolean getAllowCustomRequests() {
+        return allowCustomRequests;
+    }
+
+    public void setAllowCustomRequests(boolean allowCustomRequests) {
+        this.allowCustomRequests = allowCustomRequests;
+    }
+
+    public int getUpgradeTimeout() {
+        return upgradeTimeout;
+    }
+
+    public void setUpgradeTimeout(int upgradeTimeout) {
+        this.upgradeTimeout = upgradeTimeout;
+    }
+
+    public int getPingTimeout() {
+        return pingTimeout;
+    }
+
+    public void setPingTimeout(int pingTimeout) {
+        this.pingTimeout = pingTimeout;
+    }
+
+    public int getPingInterval() {
+        return pingInterval;
+    }
+
+    public void setPingInterval(int pingInterval) {
+        this.pingInterval = pingInterval;
+    }
+}

+ 61 - 0
taphole-common/src/main/java/com/sckj/common/socketio/socktjs.html

@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <title>TestConnect</title>
+    <base>
+    <script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
+    <script src="https://cdn.bootcss.com/socket.io/2.0.3/socket.io.js"></script>
+    <style>
+        body {
+            padding: 20px;
+        }
+        #console {
+            height: 450px;
+            overflow: auto;
+        }
+        .msg-color {
+            color: green;
+        }
+    </style>
+</head>
+ 
+<body>
+<div id="console" class="well"></div>
+ 
+</body>
+<script type="text/javascript">
+    var socket;
+    connect();
+ 
+    function connect() {
+        var userId = 'zhanleai';
+        var opts = {
+            query: 'userId=' + userId
+        };
+        socket = io.connect('http://127.0.0.1:33000', opts);
+        socket.on('connect', function () {
+            console.log("连接成功");
+            output('当前用户是:' + userId );
+            output('<span class="msg-color">连接成功了。</span>');
+        });
+        socket.on('disconnect', function () {
+            output('<span class="msg-color">下线了。 </span>');
+        });
+ 
+        socket.on('channel_user', function (data) {
+            let msg= JSON.stringify(data)
+            output('收到 channel_user 频道消息了:' + msg );
+            console.log(data);
+ 
+        });
+ 
+    }
+ 
+    function output(message) {
+        var element = $("<div>" + message + "</div>");
+        $('#console').prepend(element);
+    }
+ 
+</script>
+</html>

+ 20 - 0
taphole-common/src/main/java/com/sckj/common/validate/commons/IdValidate.java

@@ -0,0 +1,20 @@
+package com.sckj.common.validate.commons;
+
+import com.sckj.common.validator.annotation.IDMust;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel("ID参数")
+public class IdValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @IDMust(message = "id参数必传且需大于0")
+    @ApiModelProperty(value = "ID", required = true)
+    private Integer id;
+
+}

+ 21 - 0
taphole-common/src/main/java/com/sckj/common/validate/commons/IdsValidate.java

@@ -0,0 +1,21 @@
+package com.sckj.common.validate.commons;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@ApiModel("IDS参数")
+public class IdsValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @NotNull(message = "ids参数缺失")
+    @ApiModelProperty(value = "ID数组", required = true)
+    private List<Integer> ids;
+
+}

+ 25 - 0
taphole-common/src/main/java/com/sckj/common/validate/commons/PageValidate.java

@@ -0,0 +1,25 @@
+package com.sckj.common.validate.commons;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import javax.validation.constraints.DecimalMax;
+import javax.validation.constraints.DecimalMin;
+import java.io.Serializable;
+
+@Data
+@ApiModel("分页参数")
+public class PageValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    // 当前分页
+    @DecimalMin(value = "1", message = "pageNo参数必须大于0的数字")
+    public Integer pageNo = 1;
+
+    // 每页条数
+    @DecimalMin(value = "1", message = "pageSize参数必须是大于0的数字")
+    @DecimalMax(value = "60", message = "pageSize参数必须是小于60的数字")
+    private Integer pageSize = 20;
+
+}

+ 128 - 0
taphole-common/src/main/java/com/sckj/common/websocket/MapWebSocketHandler.java

@@ -0,0 +1,128 @@
+package com.sckj.common.websocket;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+/**
+ * @Author feng
+ * @Date 2024-06-05 上午 11:48
+ * @Description TODO
+ */
+@Component
+public class MapWebSocketHandler extends TextWebSocketHandler {
+    private static final CopyOnWriteArraySet<MapWebSocketHandler> webSocketSet = new CopyOnWriteArraySet<>();
+    private WebSocketSession session;
+   // private String sid;
+
+    private static Logger log = LoggerFactory.getLogger(MapWebSocketHandler.class);
+
+    @Override
+    public void afterConnectionEstablished(WebSocketSession webSocketSession) {
+        this.session = webSocketSession;
+        String path = webSocketSession.getUri().getPath();
+        String uid = path.substring(path.lastIndexOf("/") + 1);
+        //sid = session.getAttributes().getOrDefault("sid", "").toString();
+        webSocketSet.add(this);
+        sessionMap.put(uid, webSocketSession);
+        log.info("WebSocket连接已建立, sid: {}", uid);
+    }
+
+    @Override
+    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+        super.handleTextMessage(session, message);
+        //log.info("接收到{}的信息: {}", sid, message);
+        // 群发消息或其他处理逻辑
+        for (MapWebSocketHandler item : webSocketSet) {
+            try {
+                //if (item.sid.equals(sid)) {
+                    // item.sendMessage(message.getPayload());
+                //
+            } catch (Exception e) {
+                log.error("发送消息时发生错误", e);
+            }
+        }
+    }
+
+    @Override
+    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
+        if (session.isOpen()) {
+            session.close();
+        }
+        webSocketSet.remove(this);
+        log.error("WebSocket连接发生错误", throwable);
+    }
+
+
+    @Override
+    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
+        webSocketSet.remove(this);
+        //
+        URI uri = session.getUri();
+        //
+
+        //log.info("WebSocket连接已关闭, sid: {}, 原因: {}", sid, status.getReason());
+    }
+
+    private static Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();
+
+    public static void sendMessageToUser(String userId, String message) {
+        WebSocketSession session = sessionMap.get(userId);
+        if (session != null && session.isOpen()) {
+            try {
+                session.sendMessage(new TextMessage(message));
+            } catch (IOException e) {
+                // 处理发送失败的情况
+                e.printStackTrace();
+            }
+        } else {
+            // 处理会话不存在或已关闭的情况
+            log.error("处理会话不存在或已关闭的情况, uid: {}", userId);
+        }
+    }
+
+
+//    private void sendMessage(String message) throws IOException {
+//        session.getBasicRemote().sendText(message);
+//    }
+
+    // 可以增加根据sid筛选的消息推送方法
+//    public static void sendInfo(SocketMsg socketMsg, String targetSid) throws IOException {
+// ...
+//    }
+
+//    private static final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
+//​
+//    @Override
+//    public void afterConnectionEstablished(WebSocketSession session) {
+//        sessions.add(session);
+//    }
+//​
+//    @Override
+//    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
+//        // 处理消息
+//        for (WebSocketSession webSocketSession : sessions) {
+//            try {
+//                webSocketSession.sendMessage(message);
+//            } catch (IOException e) {
+//                e.printStackTrace();
+//            }
+//        }
+//    }
+//​
+//    @Override
+//    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
+//        sessions.remove(session);
+//    }
+
+}

+ 58 - 0
taphole-common/src/main/java/com/sckj/common/websocket/SemaphoreUtils.java

@@ -0,0 +1,58 @@
+package com.sckj.common.websocket;
+
+import java.util.concurrent.Semaphore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 信号量相关处理
+ * 
+ * @author taphole
+ */
+public class SemaphoreUtils
+{
+    /**
+     * SemaphoreUtils 日志控制器
+     */
+    private static final Logger LOGGER = LoggerFactory.getLogger(SemaphoreUtils.class);
+
+    /**
+     * 获取信号量
+     * 
+     * @param semaphore
+     * @return
+     */
+    public static boolean tryAcquire(Semaphore semaphore)
+    {
+        boolean flag = false;
+
+        try
+        {
+            flag = semaphore.tryAcquire();
+        }
+        catch (Exception e)
+        {
+            LOGGER.error("获取信号量异常", e);
+        }
+
+        return flag;
+    }
+
+    /**
+     * 释放信号量
+     * 
+     * @param semaphore
+     */
+    public static void release(Semaphore semaphore)
+    {
+
+        try
+        {
+            semaphore.release();
+        }
+        catch (Exception e)
+        {
+            LOGGER.error("释放信号量异常", e);
+        }
+    }
+}

+ 124 - 0
taphole-common/src/main/java/com/sckj/common/websocket/WebSocketConfig.java

@@ -0,0 +1,124 @@
+package com.sckj.common.websocket;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.web.socket.handler.AbstractWebSocketHandler;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * websocket 配置
+ * 
+ * @author taphole
+ */
+@Slf4j
+@Configuration
+@EnableWebSocket
+public class WebSocketConfig  implements WebSocketConfigurer
+{
+//    @Bean
+//    public ServerEndpointExporter serverEndpointExporter()
+//    {
+//        return new ServerEndpointExporter();
+//    }
+
+    @Resource
+    MapWebSocketHandler mapWebSocketHandler;
+
+//    @Bean
+//    public MapWebSocketHandler mapWebSocketHandler() {
+//        return new MapWebSocketHandler();
+//    }
+
+
+    @Override
+    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+        registry.addHandler(mapWebSocketHandler, "/websocket/{sid}").setAllowedOrigins("*").withSockJS();
+    }
+
+//    @Bean
+//    public WebSocketHandler myHandler() {
+//        return new MyWsHandler();
+//    }
+
+//    @Data
+//    @AllArgsConstructor
+//    public class SessionBean{
+//        private WebSocketSession webSocketSession;
+//        private int clientId;
+//    }
+
+//    /**
+//     * WebSocket 自定义处理程序
+//     */
+//    @Component
+//    public class MyWsHandler extends TextWebSocketHandler {
+//        // WebSocketSession 对象可以封装一下吧用户的信息封装进去
+//        private Map<String, SessionBean> sessionMap = new ConcurrentHashMap<>();
+//        // 线程安全的int值
+//        private   AtomicInteger clientIdMaker = new AtomicInteger(0);
+//
+//        // 连接建立
+//        @Override
+//        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
+//            super.afterConnectionEstablished(session);
+//            // 放在父方法调用之后
+//            SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());
+//            sessionMap.put(session.getId(),sessionBean);
+//            log.info(sessionMap.get(session.getId()) + " connected");
+//        }
+//
+//        // 收到消息
+//        @Override
+//        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+//            super.handleTextMessage(session, message);
+//            log.info(sessionMap.get(session.getId()).getClientId() + " : " + message.getPayload());
+//        }
+//
+//        // 传输异常
+//        @Override
+//        public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
+//            super.handleTransportError(session, exception);
+//            // 如果异常就关闭 session
+//            if (session.isOpen()) {
+//                session.close();
+//            }
+//            sessionMap.remove(session.getId());
+//        }
+//
+//        // 连接关闭
+//        @Override
+//        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
+//            super.afterConnectionClosed(session, status);
+//            log.info(sessionMap.get(session.getId()) + " closed");
+//            sessionMap.remove(session.getId());
+//        }
+//
+//        @Scheduled(fixedRate = 2000) // 每隔2s执行一次
+//        public   void sendMessage() throws IOException {
+//            System.out.println("每隔2s执行一次");
+//            for(String key: sessionMap.keySet()){ // 给所有客户端发送消息
+//                sessionMap.get(key).getWebSocketSession().sendMessage(new TextMessage("beat"));
+//            }
+//        }
+//    }
+
+}

+ 106 - 0
taphole-common/src/main/java/com/sckj/common/websocket/WebSocketServer.java

@@ -0,0 +1,106 @@
+package com.sckj.common.websocket;//package com.sckj.framework.websocket;
+//
+//import java.util.concurrent.Semaphore;
+//import javax.websocket.OnClose;
+//import javax.websocket.OnError;
+//import javax.websocket.OnMessage;
+//import javax.websocket.OnOpen;
+//import javax.websocket.Session;
+//import javax.websocket.server.ServerEndpoint;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.stereotype.Component;
+//
+///**
+// * websocket 消息处理
+// *
+// * @author taphole
+// */
+//@Component
+//@ServerEndpoint("/websocket/message")
+//public class WebSocketServer
+//{
+//    /**
+//     * WebSocketServer 日志控制器
+//     */
+//    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketServer.class);
+//
+//    /**
+//     * 默认最多允许同时在线人数100
+//     */
+//    public static int socketMaxOnlineCount = 100;
+//
+//    private static Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);
+//
+//    /**
+//     * 连接建立成功调用的方法
+//     */
+//    @OnOpen
+//    public void onOpen(Session session) throws Exception
+//    {
+//        boolean semaphoreFlag = false;
+//        // 尝试获取信号量
+//        semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
+//        if (!semaphoreFlag)
+//        {
+//            // 未获取到信号量
+//            LOGGER.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
+//            WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制数:" + socketMaxOnlineCount);
+//            session.close();
+//        }
+//        else
+//        {
+//            // 添加用户
+//            WebSocketUsers.put(session.getId(), session);
+//            LOGGER.info("\n 建立连接 - {}", session);
+//            LOGGER.info("\n 当前人数 - {}", WebSocketUsers.getUsers().size());
+//            WebSocketUsers.sendMessageToUserByText(session, "连接成功");
+//        }
+//    }
+//
+//    /**
+//     * 连接关闭时处理
+//     */
+//    @OnClose
+//    public void onClose(Session session)
+//    {
+//        LOGGER.info("\n 关闭连接 - {}", session);
+//        // 移除用户
+//        boolean removeFlag = WebSocketUsers.remove(session.getId());
+//        if (!removeFlag)
+//        {
+//            // 获取到信号量则需释放
+//            SemaphoreUtils.release(socketSemaphore);
+//        }
+//    }
+//
+//    /**
+//     * 抛出异常时处理
+//     */
+//    @OnError
+//    public void onError(Session session, Throwable exception) throws Exception
+//    {
+//        if (session.isOpen())
+//        {
+//            // 关闭连接
+//            session.close();
+//        }
+//        String sessionId = session.getId();
+//        LOGGER.info("\n 连接异常 - {}", sessionId);
+//        LOGGER.info("\n 异常信息 - {}", exception);
+//        // 移出用户
+//        WebSocketUsers.remove(sessionId);
+//        // 获取到信号量则需释放
+//        SemaphoreUtils.release(socketSemaphore);
+//    }
+//
+//    /**
+//     * 服务器接收到客户端消息时调用的方法
+//     */
+//    @OnMessage
+//    public void onMessage(String message, Session session)
+//    {
+//        String msg = message.replace("你", "我").replace("吗", "");
+//        WebSocketUsers.sendMessageToUserByText(session, msg);
+//    }
+//}

+ 141 - 0
taphole-common/src/main/java/com/sckj/common/websocket/WebSocketUsers.java

@@ -0,0 +1,141 @@
+package com.sckj.common.websocket;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.websocket.Session;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * websocket 客户端用户集
+ * 
+ * @author taphole
+ */
+public class WebSocketUsers
+{
+    /**
+     * WebSocketUsers 日志控制器
+     */
+    private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);
+
+    /**
+     * 用户集
+     */
+    private static Map<String, Session> USERS = new ConcurrentHashMap<>();
+
+    /**
+     * 存储用户
+     *
+     * @param key 唯一键
+     * @param session 用户信息
+     */
+    public static void put(String key, Session session)
+    {
+        USERS.put(key, session);
+    }
+
+    /**
+     * 移除用户
+     *
+     * @param session 用户信息
+     *
+     * @return 移除结果
+     */
+    public static boolean remove(Session session)
+    {
+        String key = null;
+        boolean flag = USERS.containsValue(session);
+        if (flag)
+        {
+            Set<Map.Entry<String, Session>> entries = USERS.entrySet();
+            for (Map.Entry<String, Session> entry : entries)
+            {
+                Session value = entry.getValue();
+                if (value.equals(session))
+                {
+                    key = entry.getKey();
+                    break;
+                }
+            }
+        }
+        else
+        {
+            return true;
+        }
+        return remove(key);
+    }
+
+    /**
+     * 移出用户
+     *
+     * @param key 键
+     */
+    public static boolean remove(String key)
+    {
+        LOGGER.info("\n 正在移出用户 - {}", key);
+        Session remove = USERS.remove(key);
+        if (remove != null)
+        {
+            boolean containsValue = USERS.containsValue(remove);
+            LOGGER.info("\n 移出结果 - {}", containsValue ? "失败" : "成功");
+            return containsValue;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    /**
+     * 获取在线用户列表
+     *
+     * @return 返回用户集合
+     */
+    public static Map<String, Session> getUsers()
+    {
+        return USERS;
+    }
+
+    /**
+     * 群发消息文本消息
+     *
+     * @param message 消息内容
+     */
+    public static void sendMessageToUsersByText(String message)
+    {
+        Collection<Session> values = USERS.values();
+        for (Session value : values)
+        {
+            sendMessageToUserByText(value, message);
+        }
+    }
+
+    /**
+     * 发送文本消息
+     *
+     * @param session 自己的用户名
+     * @param message 消息内容
+     */
+    public static void sendMessageToUserByText(Session session, String message)
+    {
+        if (session != null)
+        {
+            try
+            {
+                session.getBasicRemote().sendText(message);
+            }
+            catch (IOException e)
+            {
+                LOGGER.error("\n[发送消息异常]", e);
+            }
+        }
+        else
+        {
+            LOGGER.info("\n[你已离线]");
+        }
+    }
+}

+ 1 - 1
taphole-front/src/main/java/com/sckj/front/config/SwaggerConfig.java

@@ -28,7 +28,7 @@ public class SwaggerConfig {
                 .apiInfo(apiInfo())
                 .enable(enabled)
                 .select()
-                .apis(RequestHandlerSelectors.basePackage("com.mdd.front"))
+                .apis(RequestHandlerSelectors.basePackage("com.sckj"))
                 .build()
                 .pathMapping(pathMapping);
     }