2
0

4 コミット a1430b34d0 ... 186b70bbab

作者 SHA1 メッセージ 日付
  wangxiaofei 186b70bbab 实时大屏功能完善3 1 ヶ月 前
  wangxiaofei 5eaacf4705 实时大屏功能完善2 1 ヶ月 前
  wangxiaofei 6fa67ee45d 实时大屏功能完善 1 ヶ月 前
  wangxiaofei d53e0d97f6 代码优化 1 ヶ月 前
65 ファイル変更2426 行追加1253 行削除
  1. 1 1
      doc/import_all_images.sh
  2. 40 0
      docker/config/nginx/nginx.conf
  3. 4 4
      docker/docker-compose.yml
  4. 12 0
      docker/docker部署流程.md
  5. 10 2
      pom.xml
  6. 13 0
      taphole-camera/src/main/java/com.sckj.camera/model/bo/CameraBO.java
  7. 3 0
      taphole-camera/src/main/java/com.sckj.camera/model/entity/Camera.java
  8. 38 16
      taphole-camera/src/main/java/com.sckj.camera/service/CameraServiceImpl.java
  9. 5 0
      taphole-common/pom.xml
  10. 2 7
      taphole-common/src/main/java/com/sckj/common/eventbus/EventBusConfig.java
  11. 23 13
      taphole-common/src/main/java/com/sckj/common/socketio/SocketHandler.java
  12. 51 0
      taphole-common/src/main/java/com/sckj/common/socketio/SocketServer.java
  13. 32 0
      taphole-common/src/main/java/com/sckj/common/util/ExcelUtils.java
  14. 111 88
      taphole-common/src/main/java/com/sckj/common/util/RedisUtils.java
  15. 4 0
      taphole-iron/pom.xml
  16. 0 64
      taphole-iron/src/main/java/com/sckj/iron/controller/IronVisualScreenController.java
  17. 2 3
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronAfterController.java
  18. 2 3
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronBlockController.java
  19. 20 8
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronDataController.java
  20. 2 2
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronParamController.java
  21. 42 11
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronStepController.java
  22. 226 0
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronVisualScreenController.java
  23. 9 0
      taphole-iron/src/main/java/com/sckj/iron/dto/CameraDTO.java
  24. 2 0
      taphole-iron/src/main/java/com/sckj/iron/dto/IronStepDTO.java
  25. 25 0
      taphole-iron/src/main/java/com/sckj/iron/dto/RealtimeData.java
  26. 23 0
      taphole-iron/src/main/java/com/sckj/iron/dto/TrendData.java
  27. 1 7
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java
  28. 25 10
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronParam.java
  29. 5 5
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronStep.java
  30. 109 0
      taphole-iron/src/main/java/com/sckj/iron/entity/TL2Data.java
  31. 1 0
      taphole-iron/src/main/java/com/sckj/iron/mapper/TIronParamMapper.java
  32. 14 0
      taphole-iron/src/main/java/com/sckj/iron/mapper/TL2DataMapper.java
  33. 0 63
      taphole-iron/src/main/java/com/sckj/iron/service/ITIronAfterService.java
  34. 0 63
      taphole-iron/src/main/java/com/sckj/iron/service/ITIronBlockService.java
  35. 0 63
      taphole-iron/src/main/java/com/sckj/iron/service/ITIronDataService.java
  36. 0 71
      taphole-iron/src/main/java/com/sckj/iron/service/ITIronParamService.java
  37. 2 8
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronAfterServiceImpl.java
  38. 2 8
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronBlockServiceImpl.java
  39. 3 9
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronDataServiceImpl.java
  40. 8 19
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronParamServiceImpl.java
  41. 73 18
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronStepServiceImpl.java
  42. 77 0
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TL2DataServiceImpl.java
  43. 580 560
      taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java
  44. 77 0
      taphole-iron/src/main/java/com/sckj/iron/socketio/IronRealtimeListener.java
  45. 56 0
      taphole-iron/src/main/java/com/sckj/iron/socketio/IronTrendListener.java
  46. 57 14
      taphole-iron/src/main/java/com/sckj/iron/socketio/PushData.java
  47. 39 0
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchScreenValidate.java
  48. 28 16
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchValidate.java
  49. 23 15
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamCreateValidate.java
  50. 15 6
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamSearchValidate.java
  51. 23 14
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamUpdateValidate.java
  52. 31 0
      taphole-iron/src/main/java/com/sckj/iron/vo/IronRealTimeVO.java
  53. 39 5
      taphole-iron/src/main/java/com/sckj/iron/vo/IronStepVO.java
  54. 49 0
      taphole-iron/src/main/java/com/sckj/iron/vo/IronTrendVO.java
  55. 44 0
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronDataVo.java
  56. 136 0
      taphole-opc/src/main/java/com/sckj/opc/dto/L2Data.java
  57. 12 9
      taphole-opc/src/main/java/com/sckj/opc/entity/OPCPoint.java
  58. 9 4
      taphole-opc/src/main/java/com/sckj/opc/entity/OPCServer.java
  59. 139 0
      taphole-opc/src/main/java/com/sckj/opc/opcua/L2DataServiceImpl.java
  60. 20 4
      taphole-opc/src/main/java/com/sckj/opc/opcua/OPCDAServiceImpl.java
  61. 5 28
      taphole-opc/src/main/java/com/sckj/opc/opcua/OPCUAServiceImpl.java
  62. 1 0
      taphole-opc/src/main/java/com/sckj/opc/service/OPCDataServiceImpl.java
  63. 6 3
      taphole-warn/src/main/java/com/sckj/warn/entity/TExceptionLog.java
  64. 5 4
      taphole-warn/src/main/java/com/sckj/warn/service/impl/TExceptionLogServiceImpl.java
  65. 10 5
      taphole-warn/src/main/java/com/sckj/warn/validate/TExceptionLogCreateValidate.java

+ 1 - 1
doc/import_all_images.sh

@@ -1,2 +1,2 @@
 #!/bin/bash
-ls /root/dockerimages/*.tar | xargs -I {} docker load -i {}
+ls /home/document/dockerimages/*.tar | xargs -I {} docker load -i {}

+ 40 - 0
docker/config/nginx/nginx.conf

@@ -0,0 +1,40 @@
+#user  nobody;
+worker_processes  1;
+
+events {
+    worker_connections  1024;
+}
+
+http {
+    include       mime.types;
+    default_type  application/octet-stream;
+
+    sendfile        on;
+    keepalive_timeout  65;
+
+    #gzip  on;
+
+    server {
+        listen       80;
+        server_name  localhost;
+
+        location /api/ {
+            proxy_set_header Host $http_host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header REMOTE-HOST $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_pass http://172.28.1.100:8080/api/;
+        }
+
+        location / {
+            root /etc/nginx/html/dist;
+            try_files $uri $uri/ /index.html;
+            index index.html index.htm;
+        }
+
+        error_page   500 502 503 504  /50x.html;
+        location = /50x.html {
+            root   html;
+        }
+    }
+}

+ 4 - 4
docker/docker-compose.yml

@@ -51,7 +51,7 @@ services:
     networks:
       - taphole
     ports:
-      - "56379:6379"
+      - "16379:6379"
     command: redis-server --appendonly yes
 
 
@@ -101,9 +101,9 @@ services:
       dockerfile: Dockerfile
     volumes:
       # - ./target/taphole-admin-1.0.0.jar:/app/my-springboot-app.jar
-      - ./target/loadFFmpeg.properties:/app/loadFFmpeg.properties
-      - /home/xiaofei/taphole/hcsdk/linux:/home/xiaofei/taphole/hcsdk/linux
-      - /home/xiaofei/uploads/taphole/:/home/xiaofei/uploads/taphole/  #映射资源目录
+      #- ./target/loadFFmpeg.properties:/app/loadFFmpeg.properties
+      - /home/document/taphole/hcsdk/linux:/home/document/taphole/hcsdk/linux
+      - /home/document/uploads/taphole/:/home/document/uploads/taphole/  #映射资源目录
       # - /usr/local/ffmpeg/bin:/usr/local/ffmpeg/bin
     ports:
       - "28080:8080"

+ 12 - 0
docker/docker部署流程.md

@@ -108,4 +108,16 @@
     2.mysql的配置文件mysql.cnf,初始化数据库语句
     3.target文件夹,存放jar包和loadFFmpeg.propertis
 
+六、arm架构
+    docker pull --platform linux/arm64/v8 mpromonet/webrtc-streamer:v0.8.8
+    
+    docker pull --platform linux/arm64/v8 nginx:1.27.3
+    
+    docker pull --platform linux/arm64/v8 mysql:latest
+    
+    docker pull --platform linux/arm64/v8 library/redis:7
+    
+    docker pull --platform linux/arm64/v8 library/redis:7.2
+    
+    docker pull --platform linux/arm64/v8 library/redis:7.2.6
     

+ 10 - 2
pom.xml

@@ -49,7 +49,7 @@
         <oshi-core.version>6.1.2</oshi-core.version>
         <sa-token.version>1.32.0</sa-token.version>
         <sa-token-redis.version>1.32.0</sa-token-redis.version>
-        <easyexcel.version>3.1.3</easyexcel.version>
+        <easyexcel.version>3.3.4</easyexcel.version>
         <quartz-scheduler.version>2.3.2</quartz-scheduler.version>
 
         <qiniu.version>7.9.5</qiniu.version>
@@ -64,6 +64,7 @@
         <druid.version>1.2.23</druid.version>
 
         <milo.version>0.6.13</milo.version>
+        <fastexcel.version>1.1.0</fastexcel.version>
 
     </properties>
 
@@ -219,7 +220,7 @@
                 <version>${aliyun-java.version}</version>
             </dependency>
 
-            <!-- EasyExcel -->
+            <!-- EasyExcel-->
             <dependency>
                 <groupId>com.alibaba</groupId>
                 <artifactId>easyexcel</artifactId>
@@ -378,12 +379,19 @@
                 <artifactId>taphole-iron</artifactId>
                 <version>${taphole.version}</version>
             </dependency>
+
             <dependency>
                 <groupId>com.sckj</groupId>
                 <artifactId>taphole-opc</artifactId>
                 <version>${taphole.version}</version>
             </dependency>
 
+<!--            <dependency>-->
+<!--                <groupId>cn.idev.excel</groupId>-->
+<!--                <artifactId>fastexcel</artifactId>-->
+<!--                <version>${fastexcel.version}</version>-->
+<!--            </dependency>-->
+
         </dependencies>
     </dependencyManagement>
 

+ 13 - 0
taphole-camera/src/main/java/com.sckj.camera/model/bo/CameraBO.java

@@ -0,0 +1,13 @@
+package com.sckj.camera.model.bo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class CameraBO implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private Long id;
+    private String status;
+    private Integer sort;
+}

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

@@ -70,4 +70,7 @@ public class Camera extends BaseEntity {
     //品牌 (1-海康,目前只有海康)
     private String brand;
 
+    //显示顺序
+    private Integer sort;
+
 }

+ 38 - 16
taphole-camera/src/main/java/com.sckj.camera/service/CameraServiceImpl.java

@@ -1,10 +1,12 @@
 package com.sckj.camera.service;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sckj.camera.hik.HCNetTools;
 import com.sckj.camera.manager.CameraProperties;
 import com.sckj.camera.manager.HikCameraManager;
+import com.sckj.camera.model.bo.CameraBO;
 import com.sckj.camera.model.dto.CameraDTO;
 import com.sckj.camera.model.dto.ResultDTO;
 import com.sckj.camera.model.entity.Camera;
@@ -39,7 +41,6 @@ import java.util.List;
 import static com.sckj.common.util.ConfigUtils.set;
 
 @Service
-@Transactional
 public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
 
     private final Logger logger = LoggerFactory.getLogger(CameraServiceImpl.class);
@@ -68,7 +69,7 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
         updateById(camera);
     }
 
-    public AjaxResult enabledCameraMsg(){
+    public AjaxResult enabledCameraMsg() {
         String[] status = new String[]{"1", "2"};
         List<Camera> cameraList = baseMapper.selectList(
                 new QueryWrapper<Camera>().in("status", status).orderByDesc("id"));
@@ -80,12 +81,12 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
         return AjaxResult.success();
     }
 
-    public AjaxResult statusChange(Long id){
+    public AjaxResult statusChange(Long id) {
         Camera camera = baseMapper.selectOne(
                 new QueryWrapper<Camera>()
                         .eq("id", id)
                         .last("limit 1"));
-        if (camera == null){
+        if (camera == null) {
             return AjaxResult.failed("该相机不存在");
         }
         camera.setStatus(camera.getStatus().equals("1") ? "2" : "1");
@@ -120,7 +121,7 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
         logger.info("自动开启视频推送");
         QueryWrapper<Camera> queryWrapper = new QueryWrapper<>();
         //排除禁用的设备
-        queryWrapper.lambda().ne(Camera::getStatus, "0").eq(Camera::getType,"1");
+        queryWrapper.lambda().ne(Camera::getStatus, "0").eq(Camera::getType, "1");
 
         List<Camera> cameraList = list(queryWrapper);
         if (ObjectUtils.isEmpty(cameraList)) {
@@ -160,7 +161,7 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
      * @param rtspName
      * @return
      */
-    private ResultDTO pushStream(CameraDTO cameraDTO, String appName, String rtspName)   {
+    private ResultDTO pushStream(CameraDTO cameraDTO, String appName, String rtspName) {
         ResultDTO resultDTO = new ResultDTO();
         String rtmpUrl = "rtmp://" + cameraProperties.getRtmp().getRtmphost() + "/live/" + appName; //rtmp链
         String flvUrl = "http://" + cameraProperties.getRtmp().getHttphost() + "/live/" + appName + ".live.flv"; //live-flv链
@@ -219,7 +220,7 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
         String channelNumberStr = cameraDTO.getChannelNumber() + "02"; //新通道(2012年之后设备,02代表子码流)
         String rtspName = "rtsp://" + cameraDTO.getAccount() + ":" + cameraDTO.getPassword() + "@" + cameraDTO.getIp() + ":554/" + channelNumberStr + "?transportmode=unicast"; //新码流
         resultDTO.setRtspUrl(rtspName);
-        resultDTO.setWebrtcUrl("http://"+cameraProperties.getRtmp().getWebrtchost());
+        resultDTO.setWebrtcUrl("http://" + cameraProperties.getRtmp().getWebrtchost());
         return resultDTO;
     }
 
@@ -259,7 +260,7 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
             rtspName += cameraDTO.getVcr().getAccount() + ":" + cameraDTO.getVcr().getPassword() + "@" + cameraDTO.getVcr().getIp() + ":554/Streaming/tracks/" + channelNumberStr + "?starttime=" + startTime;
         }
         resultDTO.setRtspUrl(rtspName);
-        resultDTO.setWebrtcUrl("http://"+cameraProperties.getRtmp().getWebrtchost());
+        resultDTO.setWebrtcUrl("http://" + cameraProperties.getRtmp().getWebrtchost());
         return resultDTO;
     }
 
@@ -396,6 +397,7 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
         }
         return ffmpegService.stopTranscoding(taskName);
     }
+
     /**
      * 停止推流
      *
@@ -406,9 +408,9 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
             return false;
         }
         QueryWrapper<CameraFlow> queryWrapper = new QueryWrapper<>();
-        queryWrapper.lambda().likeLeft(CameraFlow::getTaskName,ip.replace(".",""));
+        queryWrapper.lambda().likeLeft(CameraFlow::getTaskName, ip.replace(".", ""));
         List<CameraFlow> list = flowService.list(queryWrapper);
-        if(ObjectUtils.isEmpty(list)){
+        if (ObjectUtils.isEmpty(list)) {
             return false;
         }
         return ffmpegService.stopTranscoding(list.get(0).getTaskName());
@@ -423,12 +425,32 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
     }
 
 
-    @PreDestroy
-    public void closeRealStream() {
-        logger.info("关闭推送流");
-        for (CameraFlow cameraFlow : flowService.list()) {
-            String taskName = cameraFlow.getTaskName();
-            ffmpegService.stopTranscoding(taskName);
+//    @PreDestroy
+//    public void closeRealStream() {
+//        logger.info("关闭推送流");
+//        for (CameraFlow cameraFlow : flowService.list()) {
+//            String taskName = cameraFlow.getTaskName();
+//            ffmpegService.stopTranscoding(taskName);
+//        }
+//    }
+
+    @Transactional
+    public void updateBatchs(List<CameraBO> cameraList) {
+        for (CameraBO camera : cameraList) {
+            Camera queryData = getById(camera.getId());
+            if (ObjectUtils.isEmpty(queryData)) {
+                throw new OperateException(String.format("传入的ID不存在:%s", camera.getId()));
+            }
+
+            LambdaUpdateWrapper<Camera> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.eq(Camera::getId, camera.getId());
+            if (ObjectUtils.isNotEmpty(camera.getStatus())) {
+                wrapper.set(Camera::getStatus, camera.getStatus());
+            }
+            if (camera.getSort() != null) {
+                wrapper.set(Camera::getSort, camera.getSort());
+            }
+            update(wrapper);
         }
     }
 

+ 5 - 0
taphole-common/pom.xml

@@ -302,6 +302,11 @@
         </dependency>
         <!--   utgard   end   -->
 
+<!--        <dependency>-->
+<!--            <groupId>cn.idev.excel</groupId>-->
+<!--            <artifactId>fastexcel</artifactId>-->
+<!--        </dependency>-->
+
     </dependencies>
 
 </project>

+ 2 - 7
taphole-common/src/main/java/com/sckj/common/eventbus/EventBusConfig.java

@@ -18,15 +18,10 @@ import java.util.concurrent.Executor;
 @Configuration
 @Slf4j
 public class EventBusConfig {
-    @Bean
-    public EventBus eventBus() {
-        return new EventBus();
-    }
-
-    @Bean("myAsyncEventBus")
+    @Bean("asyncEventBus")
     @Lazy(value = true)
     public AsyncEventBus createAsyncEventBus(Executor taskExecutor) {
-        log.info("myAsyncEventBus=============");
+        log.info("asyncEventBus=============");
         return new AsyncEventBus(taskExecutor);
     }
 }

+ 23 - 13
taphole-common/src/main/java/com/sckj/common/socketio/SocketHandler.java

@@ -1,5 +1,7 @@
 package com.sckj.common.socketio;
 
+import cn.dev33.satoken.stp.StpLogic;
+import cn.dev33.satoken.stp.StpUtil;
 import com.corundumstudio.socketio.SocketIOServer;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
@@ -23,19 +25,19 @@ public class SocketHandler {
     private static final String USERID = "userId";
 
     /**
-     *  容器销毁前,自动调用此方法,关闭 socketIo 服务端
+     * 容器销毁前,自动调用此方法,关闭 socketIo 服务端
      *
-     * @Param []
      * @return
+     * @Param []
      **/
     @PreDestroy
-    private void destroy(){
+    private void destroy() {
         try {
             log.debug("关闭 socket 服务端");
-            if(null != socketIoServer){
+            if (null != socketIoServer) {
                 socketIoServer.stop();
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             e.printStackTrace();
         }
     }
@@ -46,22 +48,30 @@ public class SocketHandler {
 
         //添加监听,客户端自动连接到 socket 服务端
         socketIoServer.addConnectListener(client -> {
-            String userId = client.getHandshakeData().getSingleUrlParam(USERID);
-            log.info("客户端userId: {},已连接,客户端ID为:{}",userId,client.getSessionId());
+//            String userId = client.getHandshakeData().getSingleUrlParam(USERID);
+            String token = client.getHandshakeData().getSingleUrlParam("token");
+//            log.info("客户端userId: {},已连接,客户端ID为:{}",userId,client.getSessionId());
 
-            if(ObjectUtils.isNotEmpty(userId)){
+            String userId = ObjectUtils.defaultIfNull(StpUtil.getLoginIdByToken(token), "").toString();
+            System.out.println("loginIdByToken:" + userId);
+
+            if (ObjectUtils.isNotEmpty(userId)) {
                 SocketUtil.connectMap.put(userId, client);
-                SocketUtil.clientUserIds.put(client,userId);
+                SocketUtil.clientUserIds.put(client, userId);
+            } else {
+                System.out.println("该用户未登录!");
             }
+
         });
 
         //添加监听,客户端跟 socket 服务端自动断开
         socketIoServer.addDisconnectListener(client -> {
-            String userId = client.getHandshakeData().getSingleUrlParam(USERID);
-            log.info("客户端userId: {},断开连接,客户端ID为:{}",userId,client.getSessionId());
-            if(ObjectUtils.isNotEmpty(userId)){
+            String token = client.getHandshakeData().getSingleUrlParam("token");
+            String userId = ObjectUtils.defaultIfNull(StpUtil.getLoginIdByToken(token), "").toString();
+            log.info("客户端userId: {},断开连接,客户端ID为:{}", userId, client.getSessionId());
+            if (ObjectUtils.isNotEmpty(userId)) {
                 SocketUtil.connectMap.remove(userId, client);
-                SocketUtil.clientUserIds.remove(client,userId);
+                SocketUtil.clientUserIds.remove(client, userId);
             }
         });
 

+ 51 - 0
taphole-common/src/main/java/com/sckj/common/socketio/SocketServer.java

@@ -0,0 +1,51 @@
+package com.sckj.common.socketio;
+
+import cn.dev33.satoken.stp.StpUtil;
+
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+import java.util.List;
+import java.util.Map;
+
+@ServerEndpoint("/socketio")
+public class SocketServer {
+
+    @OnOpen
+    public void onOpen(Session session) {
+        // 获取Token
+        // 获取HandshakeRequest对象
+        Map<String,String> pathParams = session.getPathParameters();
+        Map<String, List<String>> queryParamMap = session.getRequestParameterMap();
+
+        // 从查询参数中获取Token
+        String token = null;
+        if (queryParamMap.containsKey("token")) {
+            token = queryParamMap.get("token").get(0);
+        }
+        try {
+            // 验证Token
+            StpUtil.checkLogin();
+            // 获取当前用户的角色和权限
+            String username = StpUtil.getLoginIdAsString();
+            // 这里可以根据用户名从数据库或其他存储中获取用户的角色和权限
+            // 根据角色和权限决定是否允许连接
+            if (hasPermission(username)) {
+                // 允许连接
+            } else {
+                session.close();
+            }
+        } catch (Exception e) {
+            try {
+                session.close();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    private boolean hasPermission(String username) {
+        // 根据用户名检查权限,例如从数据库中查询
+        return true; // 示例中假设用户有权限
+    }
+}

+ 32 - 0
taphole-common/src/main/java/com/sckj/common/util/ExcelUtils.java

@@ -0,0 +1,32 @@
+package com.sckj.common.util;
+
+import com.alibaba.excel.EasyExcel;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.List;
+
+public class ExcelUtils {
+    /***
+     * 导出Excel
+     * @param data
+     * @param clazz
+     * @param sheetName
+     * @param fileName
+     * @param response
+     * @throws IOException
+     */
+    public static void exportExcel(List<?> data, Class<?> clazz, String sheetName, String fileName, HttpServletResponse response) throws IOException {
+        String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
+        response.setContentType("application/vnd.ms-excel");
+        response.setCharacterEncoding("utf8");
+        response.setHeader("Content-disposition", "attachment;filename=" + encodedFileName);
+        ServletOutputStream outputStream = response.getOutputStream();
+        EasyExcel.write(outputStream, clazz)
+                .sheet(sheetName)
+                .doWrite(data);
+        outputStream.close();
+    }
+}

+ 111 - 88
taphole-common/src/main/java/com/sckj/common/util/RedisUtils.java

@@ -25,8 +25,8 @@ public class RedisUtils {
     /**
      * 注入Redis
      *
-     * @author fzr
      * @param redisTemplate Redis对象
+     * @author fzr
      */
     @Resource
     public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
@@ -36,8 +36,8 @@ public class RedisUtils {
     /**
      * 对象句柄
      *
-     * @author fzr
      * @return RedisTemplate
+     * @author fzr
      */
     public static RedisTemplate<String, Object> handler() {
         return redisTemplate;
@@ -46,9 +46,9 @@ public class RedisUtils {
     /**
      * 指定缓存失效时间
      *
-     * @author fzr
-     * @param key 键
+     * @param key    键
      * @param second 时间(秒)
+     * @author fzr
      */
     public static void expire(String key, Long second) {
         key = redisPrefix + key;
@@ -58,9 +58,9 @@ public class RedisUtils {
     /**
      * 指定缓存失效时间
      *
-     * @author fzr
-     * @param key 键
+     * @param key         键
      * @param millisecond 时间(毫秒)
+     * @author fzr
      */
     public static void pExpire(String key, Long millisecond) {
         key = redisPrefix + key;
@@ -70,8 +70,8 @@ public class RedisUtils {
     /**
      * 指定缓存永久有效
      *
-     * @author fzr
      * @param key 键
+     * @author fzr
      */
     public static void persist(String key) {
         key = redisPrefix + key;
@@ -81,9 +81,9 @@ public class RedisUtils {
     /**
      * 根据key获取过期时间
      *
-     * @author fzr
      * @param key 键不能为null
      * @return 返回0代表为永久有效(秒)
+     * @author fzr
      */
     public static Long ttl(String key) {
         key = redisPrefix + key;
@@ -93,9 +93,9 @@ public class RedisUtils {
     /**
      * 根据key获取过期时间
      *
-     * @author fzr
      * @param key 键不能为null
      * @return 返回0代表为永久有效(毫秒)
+     * @author fzr
      */
     public static Long pTtl(String key) {
         key = redisPrefix + key;
@@ -105,9 +105,9 @@ public class RedisUtils {
     /**
      * 判断key是否存在
      *
-     * @author fzr
      * @param key 键
      * @return true=存在,false=不存在
+     * @author fzr
      */
     public static Boolean exists(String key) {
         key = redisPrefix + key;
@@ -117,8 +117,8 @@ public class RedisUtils {
     /**
      * 删除1个或多个键
      *
-     * @author fzr
      * @param key 键(一个或多个)
+     * @author fzr
      */
     @SuppressWarnings("unchecked")
     public static void del(String... key) {
@@ -126,7 +126,7 @@ public class RedisUtils {
             key[0] = redisPrefix + key[0];
             redisTemplate.delete(key[0]);
         } else {
-            for (int i=0; key.length > i; i++) {
+            for (int i = 0; key.length > i; i++) {
                 key[i] = redisPrefix + key[i];
             }
             redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
@@ -136,9 +136,9 @@ public class RedisUtils {
     /**
      * 给key赋值一个新的key名
      *
-     * @author fzr
      * @param oldKey 旧的key
      * @param newKey 新的key
+     * @author fzr
      */
     public static void rename(String oldKey, String newKey) {
         oldKey = redisPrefix + oldKey;
@@ -149,10 +149,10 @@ public class RedisUtils {
     /**
      * 将当前数据库的key移动到给定的数据库db当中
      *
-     * @author fzr
      * @param key 键
-     * @param db 库
+     * @param db  
      * @return Boolean
+     * @author fzr
      */
     public static Boolean move(String key, int db) {
         key = redisPrefix + key;
@@ -162,10 +162,10 @@ public class RedisUtils {
     /**
      * 获取匹配的key值
      *
-     * @author fzr
-     * @author fzr
      * @param pattern 通配符(*, ?, [])
      * @return Set
+     * @author fzr
+     * @author fzr
      */
     public static Set<String> keys(String pattern) {
         return redisTemplate.keys(pattern);
@@ -174,9 +174,9 @@ public class RedisUtils {
     /**
      * 随机返回一个key
      *
+     * @return String
      * @author fzr
      * @author fzr
-     * @return String
      */
     public static String randomKey() {
         return redisTemplate.randomKey();
@@ -187,9 +187,9 @@ public class RedisUtils {
     /**
      * 按匹配获取或有KEY
      *
-     * @author fzr
      * @param pattern 规则
      * @return Set<String>
+     * @author fzr
      */
     public static Set<String> matchSet(String pattern) {
         Set<String> keys = new LinkedHashSet<>();
@@ -215,9 +215,9 @@ public class RedisUtils {
     /**
      * 获取key的值
      *
-     * @author fzr
      * @param key 键
      * @return Object
+     * @author fzr
      */
     public static Object get(String key) {
         key = redisPrefix + key;
@@ -227,10 +227,10 @@ public class RedisUtils {
     /**
      * 获取旧值并设置新值
      *
-     * @author fzr
-     * @param key 键
+     * @param key    键
      * @param newVal 新值
      * @return Object
+     * @author fzr
      */
     public static Object getSet(String key, Object newVal) {
         key = redisPrefix + key;
@@ -240,9 +240,9 @@ public class RedisUtils {
     /**
      * 设置键值对
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param value 值
+     * @author fzr
      */
     public static void set(String key, Object value) {
         key = redisPrefix + key;
@@ -252,10 +252,10 @@ public class RedisUtils {
     /**
      * 设置键值对并设置时间
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param value 值
-     * @param time time要大于0 如果time小于等于0 将设置无限期
+     * @param time  time要大于0 如果time小于等于0 将设置无限期
+     * @author fzr
      */
     public static void set(String key, Object value, long time) {
         key = redisPrefix + key;
@@ -269,10 +269,10 @@ public class RedisUtils {
     /**
      * 递增
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param delta 要增加几(大于0)
      * @return Long
+     * @author fzr
      */
     public static Long incr(String key, long delta) {
         if (delta < 0) {
@@ -285,10 +285,10 @@ public class RedisUtils {
     /**
      * 递减
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param delta 要减少几(小于0)
      * @return Long
+     * @author fzr
      */
     public static Long decr(String key, long delta) {
         if (delta < 0) {
@@ -303,10 +303,10 @@ public class RedisUtils {
     /**
      * 获取key中field域的值
      *
-     * @author fzr
-     * @param key 键 不能为null
+     * @param key   键 不能为null
      * @param field 项 不能为null
      * @return 值
+     * @author fzr
      */
     public static Object hGet(String key, String field) {
         key = redisPrefix + key;
@@ -316,10 +316,10 @@ public class RedisUtils {
     /**
      * 判断key中有没有field域名
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param field 字段
      * @return Boolean
+     * @author fzr
      */
     public static Boolean hExists(String key, Object field) {
         key = redisPrefix + key;
@@ -329,9 +329,9 @@ public class RedisUtils {
     /**
      * 获取hashKey对应的所有键值
      *
-     * @author fzr
      * @param key 键
      * @return 对应的多个键值
+     * @author fzr
      */
     public Map<Object, Object> hmGet(String key) {
         key = redisPrefix + key;
@@ -341,9 +341,9 @@ public class RedisUtils {
     /**
      * 设置field1->N个域,对应的值是value1->N
      *
-     * @author fzr
      * @param key 键
      * @param map 对应多个键值
+     * @author fzr
      */
     public static void hmSet(String key, Map<String, Object> map) {
         key = redisPrefix + key;
@@ -353,10 +353,10 @@ public class RedisUtils {
     /**
      * HashSet 并设置时间
      *
-     * @author fzr
-     * @param key 键
-     * @param map 对应多个键值
+     * @param key  键
+     * @param map  对应多个键值
      * @param time 时间(秒)
+     * @author fzr
      */
     public static void hmSet(String key, Map<String, Object> map, long time) {
         key = redisPrefix + key;
@@ -369,10 +369,10 @@ public class RedisUtils {
     /**
      * 向一张hash表中放入数据,如果不存在将创建
      *
-     * @author fzr
-     * @param key 键
-     * @param item 项
+     * @param key   键
+     * @param item  项
      * @param value 值
+     * @author fzr
      */
     public static void hSet(String key, String item, Object value) {
         key = redisPrefix + key;
@@ -382,12 +382,12 @@ public class RedisUtils {
     /**
      * 向一张hash表中放入数据,如果不存在将创建
      *
-     * @author fzr
-     * @param key 键
-     * @param item 项
+     * @param key   键
+     * @param item  项
      * @param value 值
-     * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
+     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
      * @return true 成功 false失败
+     * @author fzr
      */
     public static boolean hSet(String key, String item, Object value, long time) {
         key = redisPrefix + key;
@@ -401,9 +401,9 @@ public class RedisUtils {
     /**
      * 删除hash表中的值
      *
-     * @author fzr
-     * @param key 键 不能为null
+     * @param key  键 不能为null
      * @param item 项 可以使多个 不能为null
+     * @author fzr
      */
     public static void hDel(String key, Object... item) {
         key = redisPrefix + key;
@@ -413,10 +413,10 @@ public class RedisUtils {
     /**
      * 判断hash表中是否有该项的值
      *
-     * @author fzr
-     * @param key 键 不能为null
+     * @param key  键 不能为null
      * @param item 项 不能为null
      * @return true 存在 false不存在
+     * @author fzr
      */
     public static boolean hHasKey(String key, String item) {
         key = redisPrefix + key;
@@ -426,11 +426,11 @@ public class RedisUtils {
     /**
      * hash递增 如果不存在,就会创建一个并把新增后的值返回
      *
-     * @author fzr
-     * @param key 键
+     * @param key  键
      * @param item 项
-     * @param by 要增加几(大于0)
+     * @param by   要增加几(大于0)
      * @return double
+     * @author fzr
      */
     public static double hIncr(String key, String item, long by) {
         key = redisPrefix + key;
@@ -440,11 +440,11 @@ public class RedisUtils {
     /**
      * hash递减
      *
-     * @author fzr
-     * @param key 键
+     * @param key  键
      * @param item 项
-     * @param by 要减少记(小于0)
+     * @param by   要减少记(小于0)
      * @return double
+     * @author fzr
      */
     public static double hDecr(String key, String item, long by) {
         key = redisPrefix + key;
@@ -456,9 +456,9 @@ public class RedisUtils {
     /**
      * 根据key获取Set中的所有值
      *
-     * @author fzr
      * @param key 键
      * @return Set
+     * @author fzr
      */
     public static Set<Object> sGet(String key) {
         key = redisPrefix + key;
@@ -468,10 +468,10 @@ public class RedisUtils {
     /**
      * 根据value从一个set中查询,是否存在
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param value 值
      * @return true 存在 false不存在
+     * @author fzr
      */
     public Boolean sHasKey(String key, Object value) {
         key = redisPrefix + key;
@@ -481,10 +481,10 @@ public class RedisUtils {
     /**
      * 将数据放入set缓存
      *
-     * @author fzr
-     * @param key 键
+     * @param key    键
      * @param values 值 可以是多个
      * @return 成功个数
+     * @author fzr
      */
     public static Long sSet(String key, Object... values) {
         key = redisPrefix + key;
@@ -494,11 +494,11 @@ public class RedisUtils {
     /**
      * 将set数据放入缓存
      *
-     * @author fzr
-     * @param key 键
-     * @param time 时间(秒)
+     * @param key    键
+     * @param time   时间(秒)
      * @param values 值 可以是多个
      * @return 成功个数
+     * @author fzr
      */
     public Long sSetAndTime(String key, long time, Object... values) {
         key = redisPrefix + key;
@@ -508,9 +508,9 @@ public class RedisUtils {
     /**
      * 获取set缓存的长度
      *
-     * @author fzr
      * @param key 键
      * @return Long
+     * @author fzr
      */
     public Long sGetSetSize(String key) {
         key = redisPrefix + key;
@@ -520,10 +520,10 @@ public class RedisUtils {
     /**
      * 移除值为value的
      *
-     * @author fzr
-     * @param key 键
+     * @param key    键
      * @param values 值 可以是多个
      * @return 移除的个数
+     * @author fzr
      */
     public Long setRemove(String key, Object... values) {
         key = redisPrefix + key;
@@ -535,11 +535,11 @@ public class RedisUtils {
     /**
      * 获取list缓存的内容
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param start 开始
-     * @param end 结束 0 到 -1代表所有值
+     * @param end   结束 0 到 -1代表所有值
      * @return List
+     * @author fzr
      */
     public List<Object> lGet(String key, long start, long end) {
         key = redisPrefix + key;
@@ -549,9 +549,9 @@ public class RedisUtils {
     /**
      * 获取list缓存的长度
      *
-     * @author fzr
      * @param key 键
      * @return Long
+     * @author fzr
      */
     public Long lGetListSize(String key) {
         key = redisPrefix + key;
@@ -561,10 +561,10 @@ public class RedisUtils {
     /**
      * 通过索引获取list中的值
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param index 索引 index>=0时,0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
      * @return Object
+     * @author fzr
      */
     public Object lGetIndex(String key, long index) {
         key = redisPrefix + key;
@@ -574,10 +574,10 @@ public class RedisUtils {
     /**
      * 将list放入缓存
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param value 值
      * @return boolean
+     * @author fzr
      */
     public boolean lSet(String key, Object value) {
         key = redisPrefix + key;
@@ -588,11 +588,11 @@ public class RedisUtils {
     /**
      * 将list放入缓存
      *
-     * @author fzr
-     * @param key 键
-     * @param value 值
+     * @param key    键
+     * @param value  值
      * @param second 时间(秒)
      * @return boolean
+     * @author fzr
      */
     public boolean lSet(String key, Object value, long second) {
         key = redisPrefix + key;
@@ -605,10 +605,10 @@ public class RedisUtils {
     /**
      * 将list放入缓存
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param value 值
      * @return boolean
+     * @author fzr
      */
     public boolean lSet(String key, List<Object> value) {
         key = redisPrefix + key;
@@ -619,11 +619,11 @@ public class RedisUtils {
     /**
      * 将list放入缓存
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param value 值
-     * @param time 时间(秒)
+     * @param time  时间(秒)
      * @return boolean
+     * @author fzr
      */
     public boolean lSet(String key, List<Object> value, Long time) {
         key = redisPrefix + key;
@@ -636,11 +636,11 @@ public class RedisUtils {
     /**
      * 根据索引修改list中的某条数据
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param index 索引
      * @param value 值
      * @return boolean
+     * @author fzr
      */
     public boolean lUpdateIndex(String key, Long index, Object value) {
         key = redisPrefix + key;
@@ -651,15 +651,38 @@ public class RedisUtils {
     /**
      * 移除N个值为value
      *
-     * @author fzr
-     * @param key 键
+     * @param key   键
      * @param count 移除多少个
      * @param value 值
      * @return 移除的个数
+     * @author fzr
      */
     public Long lRemove(String key, Long count, Object value) {
         key = redisPrefix + key;
         return redisTemplate.opsForList().remove(key, count, value);
     }
 
+    /***
+     * 添加指定数量的数据
+     * @param key
+     * @param element
+     * @param maxSize
+     */
+    public static void addFixedElement(String key, Object element, int maxSize) {
+        // 将新的对象数组添加到列表头部
+        redisTemplate.opsForList().leftPush(key, element);
+        // 修剪列表,只保留前 6 个元素
+        redisTemplate.opsForList().trim(key, 0, maxSize - 1);
+    }
+
+    /***
+     * 获取定数量的数据
+     * @param key
+     * @return
+     */
+    public static List<Object> getFixedElement(String key) {
+        // 获取列表中的所有元素
+        return redisTemplate.opsForList().range(key, 0, -1);
+    }
+
 }

+ 4 - 0
taphole-iron/pom.xml

@@ -30,6 +30,10 @@
             <groupId>com.sckj</groupId>
             <artifactId>taphole-opc</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.sckj</groupId>
+            <artifactId>taphole-camera</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 0 - 64
taphole-iron/src/main/java/com/sckj/iron/controller/IronVisualScreenController.java

@@ -1,64 +0,0 @@
-package com.sckj.iron.controller;
-
-import com.sckj.common.aop.NotLogin;
-import com.sckj.common.aop.NotPower;
-import com.sckj.common.core.AjaxResult;
-import com.sckj.iron.service.impl.IronLoginServiceImpl;
-import com.sckj.iron.validate.IronLoginValidate;
-import com.sckj.iron.vo.IronLoginVo;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * @Author feng
- * @Date 2024-11-18 上午 09:44
- * @Description 可视化大屏登录
- */
-@RestController
-@RequestMapping("api/visual/screen")
-@Api(tags = "可视化大屏")
-public class IronVisualScreenController {
-
-    @Resource
-    IronLoginServiceImpl ironLoginService;
-
-
-
-    @NotLogin
-    @PostMapping("/login")
-    @ApiOperation(value="登录系统")
-    public AjaxResult<IronLoginVo> login(@Validated() @RequestBody IronLoginValidate loginsValidate) {
-        IronLoginVo vo = ironLoginService.login(loginsValidate);
-        return AjaxResult.success(vo);
-    }
-
-    @NotPower
-    @PostMapping("/logout")
-    @ApiOperation(value="退出登录")
-    public AjaxResult<Object> logout(HttpServletRequest request) {
-        ironLoginService.logout(request.getHeader("token"));
-        return AjaxResult.success();
-    }
-
-
-
-    @NotLogin
-    @PostMapping("/getDeviceInfo")
-    @ApiOperation(value="获取设备信息")
-    public AjaxResult<Object> getDeviceInfo(String loginsValidate) {
-        String vo = ironLoginService.getDeviceInfo(loginsValidate);
-        return AjaxResult.success(vo);
-    }
-
-
-
-
-}

+ 2 - 3
taphole-iron/src/main/java/com/sckj/iron/controller/TIronAfterController.java

@@ -1,10 +1,9 @@
 package com.sckj.iron.controller;
 
 import com.sckj.common.aop.Log;
-import com.sckj.iron.service.ITIronAfterService;
 import com.sckj.common.validate.commons.IdValidate;
+import com.sckj.iron.service.impl.TIronAfterServiceImpl;
 import com.sckj.iron.validate.TIronAfterCreateValidate;
-import com.sckj.iron.validate.TIronAfterUpdateValidate;
 import com.sckj.iron.validate.TIronAfterSearchValidate;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.iron.vo.TIronAfterListedVo;
@@ -26,7 +25,7 @@ import java.util.List;
 public class TIronAfterController {
 
     @Resource
-    ITIronAfterService iTIronAfterService;
+    TIronAfterServiceImpl iTIronAfterService;
 
     @GetMapping("/list")
     @ApiOperation(value="出铁后列表")

+ 2 - 3
taphole-iron/src/main/java/com/sckj/iron/controller/TIronBlockController.java

@@ -1,10 +1,9 @@
 package com.sckj.iron.controller;
 
 import com.sckj.common.aop.Log;
-import com.sckj.iron.service.ITIronBlockService;
 import com.sckj.common.validate.commons.IdValidate;
+import com.sckj.iron.service.impl.TIronBlockServiceImpl;
 import com.sckj.iron.validate.TIronBlockCreateValidate;
-import com.sckj.iron.validate.TIronBlockUpdateValidate;
 import com.sckj.iron.validate.TIronBlockSearchValidate;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.iron.vo.TIronBlockListedVo;
@@ -26,7 +25,7 @@ import java.util.List;
 public class TIronBlockController {
 
     @Resource
-    ITIronBlockService iTIronBlockService;
+    TIronBlockServiceImpl iTIronBlockService;
 
     @GetMapping("/list")
     @ApiOperation(value="堵口后列表")

+ 20 - 8
taphole-iron/src/main/java/com/sckj/iron/controller/TIronDataController.java

@@ -6,8 +6,11 @@ import com.sckj.common.core.PageResult;
 import com.sckj.common.validate.commons.IdValidate;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.common.validator.annotation.IDMust;
-import com.sckj.iron.service.ITIronDataService;
+import com.sckj.iron.entity.TL2Data;
+import com.sckj.iron.service.impl.TIronDataServiceImpl;
+import com.sckj.iron.service.impl.TL2DataServiceImpl;
 import com.sckj.iron.validate.TIronDataCreateValidate;
+import com.sckj.iron.validate.TIronDataSearchScreenValidate;
 import com.sckj.iron.validate.TIronDataSearchValidate;
 import com.sckj.iron.vo.TIronDataDetailVo;
 import com.sckj.iron.vo.TIronDataListedVo;
@@ -25,18 +28,21 @@ import java.util.List;
 public class TIronDataController {
 
     @Resource
-    ITIronDataService iTIronDataService;
+    TIronDataServiceImpl iTIronDataService;
+
+    @Resource
+    TL2DataServiceImpl tl2DataService;
 
     @GetMapping("/list")
-    @ApiOperation(value="出铁数据列表")
+    @ApiOperation(value = "出铁数据列表")
     public AjaxResult<PageResult<TIronDataListedVo>> list(@Validated PageValidate pageValidate,
-                                                     @Validated TIronDataSearchValidate searchValidate) {
+                                                          @Validated TIronDataSearchValidate searchValidate) {
         PageResult<TIronDataListedVo> list = iTIronDataService.list(pageValidate, searchValidate);
         return AjaxResult.success(list);
     }
 
     @GetMapping("/detail")
-    @ApiOperation(value="出铁数据详情")
+    @ApiOperation(value = "出铁数据详情")
     public AjaxResult<TIronDataDetailVo> detail(@Validated @IDMust() @RequestParam("id") Integer id) {
         TIronDataDetailVo detail = iTIronDataService.detail(id);
         return AjaxResult.success(detail);
@@ -44,7 +50,7 @@ public class TIronDataController {
 
     @Log(title = "出铁数据新增")
     @PostMapping("/add")
-    @ApiOperation(value="出铁数据新增")
+    @ApiOperation(value = "出铁数据新增")
     public AjaxResult<Object> add(@Validated @RequestBody TIronDataCreateValidate createValidate) {
         iTIronDataService.add(createValidate);
         return AjaxResult.success();
@@ -52,7 +58,7 @@ public class TIronDataController {
 
     @Log(title = "出铁数据删除")
     @PostMapping("/del")
-    @ApiOperation(value="出铁数据删除")
+    @ApiOperation(value = "出铁数据删除")
     public AjaxResult<Object> del(@Validated @RequestBody IdValidate idValidate) {
         iTIronDataService.del(idValidate.getId());
         return AjaxResult.success();
@@ -60,9 +66,15 @@ public class TIronDataController {
 
     @Log(title = "出铁数据批量删除")
     @PostMapping("/del_ex")
-    @ApiOperation(value="出铁数据批量删除")
+    @ApiOperation(value = "出铁数据批量删除")
     public AjaxResult<Object> del_ex(@RequestBody List<Long> ids) {
         return iTIronDataService.del_ex(ids);
     }
 
+
+
+
+
+
+
 }

+ 2 - 2
taphole-iron/src/main/java/com/sckj/iron/controller/TIronParamController.java

@@ -1,8 +1,8 @@
 package com.sckj.iron.controller;
 
 import com.sckj.common.aop.Log;
-import com.sckj.iron.service.ITIronParamService;
 import com.sckj.common.validate.commons.IdValidate;
+import com.sckj.iron.service.impl.TIronParamServiceImpl;
 import com.sckj.iron.validate.TIronParamCreateValidate;
 import com.sckj.iron.validate.TIronParamUpdateValidate;
 import com.sckj.iron.validate.TIronParamSearchValidate;
@@ -26,7 +26,7 @@ import java.util.List;
 public class TIronParamController {
 
     @Resource
-    ITIronParamService iTIronParamService;
+    TIronParamServiceImpl iTIronParamService;
 
     @GetMapping("/list")
     @ApiOperation(value="参数设定列表")

+ 42 - 11
taphole-iron/src/main/java/com/sckj/iron/controller/TIronStepController.java

@@ -1,14 +1,15 @@
 package com.sckj.iron.controller;
 
 
+import com.sckj.common.aop.Log;
 import com.sckj.common.aop.NotLogin;
 import com.sckj.common.core.AjaxResult;
+import com.sckj.iron.entity.TIronStep;
 import com.sckj.iron.service.impl.TIronStepServiceImpl;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
@@ -21,21 +22,51 @@ public class TIronStepController {
     @Resource
     TIronStepServiceImpl iTIronStepService;
 
-    @GetMapping("/getSteps")
-    @ApiOperation(value="获取步骤")
+    @GetMapping("/getTreeSteps")
+    @ApiOperation(value = "获取步骤")
     @NotLogin
-    public AjaxResult getSteps() {
-        return AjaxResult.success(iTIronStepService.getSteps());
+    public AjaxResult getTreeSteps() {
+        return AjaxResult.success(iTIronStepService.getTreeSteps());
     }
 
+//    @GetMapping("/getLinkedMapSteps")
+//    @ApiOperation(value = "获取步骤")
+//    @NotLogin
+//    public AjaxResult getLinkedMapSteps() {
+//        return AjaxResult.success(iTIronStepService.getLinkedMapSteps());
+//    }
 
-    @GetMapping("/refreshSteps")
-    @ApiOperation(value="刷新步骤")
+
+    @GetMapping("/refreshTreeSteps")
+    @ApiOperation(value = "刷新步骤")
     @NotLogin
-    public AjaxResult refreshSteps() {
-        iTIronStepService.refreshSteps();
+    public AjaxResult refreshTreeSteps() {
+        iTIronStepService.refreshTreeSteps();
         return AjaxResult.success(LocalDateTime.now());
     }
 
+    @Log(title = "新增或者更新")
+    @PostMapping("/saveOrUpdate")
+    @ApiOperation(value = "新增或者更新")
+    public AjaxResult saveOrUpdate(@Validated @RequestBody TIronStep tIronStep) {
+        iTIronStepService.saveOrUpdate(tIronStep);
+        return AjaxResult.success();
+    }
+
+    @Log(title = "删除")
+    @PostMapping("/del")
+    @ApiOperation(value = "删除")
+    public AjaxResult del(@Validated @RequestBody TIronStep tIronStep) {
+        iTIronStepService.removeById(tIronStep);
+        return AjaxResult.success();
+    }
+
+    @GetMapping("/detail")
+    @ApiOperation(value="详情")
+    public AjaxResult detail(TIronStep tIronStep) {
+        TIronStep detail = iTIronStepService.getById(tIronStep.getStepId());
+        return AjaxResult.success(detail);
+    }
+
 
 }

+ 226 - 0
taphole-iron/src/main/java/com/sckj/iron/controller/TIronVisualScreenController.java

@@ -0,0 +1,226 @@
+package com.sckj.iron.controller;
+
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.github.pagehelper.PageHelper;
+import com.sckj.camera.manager.CameraProperties;
+import com.sckj.camera.model.bo.CameraBO;
+import com.sckj.camera.model.entity.Camera;
+import com.sckj.camera.service.CameraServiceImpl;
+import com.sckj.common.aop.NotLogin;
+import com.sckj.common.aop.NotPower;
+import com.sckj.common.core.AjaxResult;
+import com.sckj.common.util.RedisUtils;
+import com.sckj.common.validate.commons.PageValidate;
+import com.sckj.iron.dto.CameraDTO;
+import com.sckj.iron.entity.TIronParam;
+import com.sckj.iron.entity.TL2Data;
+import com.sckj.iron.service.impl.IronLoginServiceImpl;
+import com.sckj.iron.service.impl.TIronParamServiceImpl;
+import com.sckj.iron.service.impl.TL2DataServiceImpl;
+import com.sckj.iron.socketio.DeviceEventListener;
+import com.sckj.iron.validate.IronLoginValidate;
+import com.sckj.iron.validate.TIronDataSearchScreenValidate;
+import com.sckj.iron.vo.IronLoginVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Author feng
+ * @Date 2024-11-18 上午 09:44
+ * @Description 可视化大屏登录
+ */
+@RestController
+@RequestMapping("api/visualscreen")
+@Api(tags = "可视化大屏")
+public class TIronVisualScreenController {
+
+    @Resource
+    IronLoginServiceImpl ironLoginService;
+
+    @Resource
+    TL2DataServiceImpl tl2DataService;
+
+    @Resource
+    private CameraServiceImpl cameraService;
+
+    @Resource
+    TIronParamServiceImpl iTIronParamService;
+
+    @Resource
+    private CameraProperties cameraProperties;
+
+
+    @NotLogin
+    @PostMapping("/login")
+    @ApiOperation(value = "登录系统")
+    public AjaxResult<IronLoginVo> login(@Validated() @RequestBody IronLoginValidate loginsValidate) {
+        IronLoginVo vo = ironLoginService.login(loginsValidate);
+        return AjaxResult.success(vo);
+    }
+
+    @NotPower
+    @PostMapping("/logout")
+    @ApiOperation(value = "退出登录")
+    public AjaxResult<Object> logout(HttpServletRequest request) {
+        ironLoginService.logout(request.getHeader("token"));
+        return AjaxResult.success();
+    }
+
+
+    /***
+     * 从L2获取铁水成分数据
+     * @return
+     */
+    @NotLogin
+    @PostMapping("/getIronElement")
+    @ApiOperation(value = "获取铁水成分数据")
+    public AjaxResult getIronElement() {
+        List vo = RedisUtils.getFixedElement(DeviceEventListener.IRON_ELEMENT);
+        return AjaxResult.success(vo);
+    }
+
+    /***
+     * 获取铁水流速数据
+     * @return
+     */
+    @PostMapping("/getIronSpeed")
+    @ApiOperation(value = "获取铁水流速数据")
+    public AjaxResult getIronSpeed() {
+        List vo = RedisUtils.getFixedElement(DeviceEventListener.IRON_SPEED);
+        return AjaxResult.success(vo);
+    }
+
+    /***
+     * 获取铁流量数据
+     * @return
+     */
+    @PostMapping("/getIronWeight")
+    @ApiOperation(value = "获取铁流量数据")
+    public AjaxResult getIronWeight() {
+        List vo = RedisUtils.getFixedElement(DeviceEventListener.IRON_WEIGHT);
+        return AjaxResult.success(vo);
+    }
+
+    /***
+     * 获取铁水温度数据
+     * @return
+     */
+    @PostMapping("/getIronTemp")
+    @ApiOperation(value = "获取铁水温度数据")
+    public AjaxResult getIronTemp() {
+        List vo = RedisUtils.getFixedElement(DeviceEventListener.IRON_TEMP);
+        return AjaxResult.success(vo);
+    }
+
+
+    @PostMapping("/getIronData")
+    @ApiOperation(value = "查询出铁数据")
+    public AjaxResult queryIronData(@Validated PageValidate pageValidate, TIronDataSearchScreenValidate ironDataSearchScreenValidate) {
+        //出铁操作
+        TL2Data tl2Data = new TL2Data();
+        BeanUtils.copyProperties(ironDataSearchScreenValidate, tl2Data);
+        PageHelper.startPage(pageValidate.getPageNo(), pageValidate.getPageSize());
+        return AjaxResult.success(tl2DataService.queryIronData(tl2Data));
+    }
+
+
+    @PostMapping("/exportIronData")
+    @ApiOperation(value = "导出出铁数据")
+    public void exportIronData(TIronDataSearchScreenValidate ironDataSearchScreenValidate, HttpServletResponse response) throws IOException {
+        //出铁操作
+        TL2Data tl2Data = new TL2Data();
+        BeanUtils.copyProperties(ironDataSearchScreenValidate, tl2Data);
+        tl2DataService.exportIronData(tl2Data, response);
+    }
+
+    /**
+     * 摄像头登录
+     *
+     * @return
+     */
+    @ApiOperation("获取摄像头列表")
+    @PostMapping("/getCameraInfo")
+    public AjaxResult list() {
+        List<Camera> normalCameras = cameraService.lambdaQuery().eq(Camera::getStatus, "1").orderByAsc(Camera::getSort).list();
+        List<Camera> bannerCameras = cameraService.lambdaQuery().eq(Camera::getStatus, "2").orderByAsc(Camera::getSort).list();
+        TIronParam tIronParam = iTIronParamService.lambdaQuery().eq(TIronParam::getParamType, "cameraParam").eq(TIronParam::getParamName, "cameraPlayDuration").one();
+        Map<String, Object> map = new HashMap<>();
+        map.put("normalList", normalCameras);
+        map.put("bannerList", bannerCameras);
+        map.put("cameraPlayDuration", tIronParam.getParamValue());
+        return AjaxResult.success(map);
+    }
+
+    /**
+     * 摄像头登录
+     *
+     * @return
+     */
+    @ApiOperation("设置摄像头是否轮播、顺序")
+    @PostMapping("/updateCamera")
+    public AjaxResult updateCamera(@RequestBody List<CameraBO> cameraList) {
+        if (ObjectUtils.isEmpty(cameraList)) {
+            return AjaxResult.failed("传入的摄像头列表数据为空");
+        }
+        cameraService.updateBatchs(cameraList);
+        return AjaxResult.success();
+    }
+
+
+    /**
+     * 摄像头播放
+     *
+     * @param cameraId 相机信息ID
+     * @return ResultDTO
+     */
+    @ApiOperation("摄像头播放")
+    @PostMapping("/playCamera")
+    public AjaxResult playCamera(Long cameraId) {
+        Camera camera = cameraService.getById(cameraId);
+        if (ObjectUtils.isEmpty(camera)) {
+            return AjaxResult.failed("该摄像头不存在");
+        }
+        String channelNumberStr = 1 + "02"; //新通道(2012年之后设备,02代表子码流)
+        String rtspName = "rtsp://" + camera.getAccount() + ":" + camera.getPassword() + "@" + camera.getIp() + ":554/" + channelNumberStr + "?transportmode=unicast"; //新码流
+        String webrtcUrl = "http://" + cameraProperties.getRtmp().getWebrtchost();
+        CameraDTO cameraDTO = new CameraDTO();
+        cameraDTO.setRtmpUrl(webrtcUrl);
+        cameraDTO.setRtspUrl(rtspName);
+        return AjaxResult.success(cameraDTO);
+    }
+
+    /**
+     * 摄像头登录
+     *
+     * @return
+     */
+    @ApiOperation("设置摄像头轮播参数")
+    @PostMapping("/updateCameraParam")
+    public AjaxResult cameraParamUpdate(Integer cameraPlayDuration) {
+        try {
+            iTIronParamService.lambdaUpdate().eq(TIronParam::getParamType, "cameraParam").eq(TIronParam::getParamName, "cameraPlayDuration")
+                    .set(TIronParam::getParamValue, cameraPlayDuration).update();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed("失败");
+        }
+        return AjaxResult.success();
+    }
+
+
+}

+ 9 - 0
taphole-iron/src/main/java/com/sckj/iron/dto/CameraDTO.java

@@ -0,0 +1,9 @@
+package com.sckj.iron.dto;
+
+import lombok.Data;
+
+@Data
+public class CameraDTO {
+    private String rtspUrl;
+    private String rtmpUrl;
+}

+ 2 - 0
taphole-iron/src/main/java/com/sckj/iron/dto/IronStepDTO.java

@@ -26,4 +26,6 @@ public class IronStepDTO extends TIronStep {
 
     private List<IronStepDTO> childs;
 
+    private List<String> extraList;
+
 }

+ 25 - 0
taphole-iron/src/main/java/com/sckj/iron/dto/RealtimeData.java

@@ -0,0 +1,25 @@
+package com.sckj.iron.dto;
+
+import lombok.Data;
+import org.springframework.stereotype.Component;
+
+/***
+ * 实时数据
+ * 铁水温度、铁水流速、铁水成分、铁水流量
+ *
+ */
+@Data
+@Component
+public class RealtimeData {
+
+//    private String key;
+
+    private Object value;
+
+    private String unit;
+
+    private String desc;
+
+    private String time;
+
+}

+ 23 - 0
taphole-iron/src/main/java/com/sckj/iron/dto/TrendData.java

@@ -0,0 +1,23 @@
+package com.sckj.iron.dto;
+
+import com.sckj.opc.entity.OPCData;
+import lombok.Data;
+import org.springframework.stereotype.Component;
+
+/***
+ * 趋势数据
+ */
+@Data
+@Component
+public class TrendData {
+    //铁水温度
+    private Object ironTemp;
+
+    //铁水流速1
+    private Object ironSpeed1;
+
+    //铁水流速2
+    private Object ironSpeed2;
+
+
+}

+ 1 - 7
taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java

@@ -30,7 +30,7 @@ public class TIronData implements Serializable {
     private Date updateTime;
 
     @TableId(value="id", type= IdType.AUTO)
-    @ApiModelProperty(value = "")
+    @ApiModelProperty(value = "id")
     private Long id;
 
     @ApiModelProperty(value = "铁口编号")
@@ -51,13 +51,7 @@ public class TIronData implements Serializable {
     @ApiModelProperty(value = "危害程度")
     private String whcd;
 
-    @ApiModelProperty(value = "设备区域")
-    private String sbqy;
-
     @ApiModelProperty(value = "时间")
     private String sj;
 
-    @ApiModelProperty(value = "次数")
-    private String cs;
-
 }

+ 25 - 10
taphole-iron/src/main/java/com/sckj/iron/entity/TIronParam.java

@@ -34,19 +34,34 @@ public class TIronParam implements Serializable {
     @ApiModelProperty(value = "")
     private Long id;
 
-    @ApiModelProperty(value = "开口耗时(s)")
-    private BigDecimal kkhs;
+//    @ApiModelProperty(value = "开口耗时(s)")
+//    private BigDecimal openHours;
+//
+//    @ApiModelProperty(value = "出铁时间(s)")
+//    private BigDecimal ironTime;
+//
+//    @ApiModelProperty(value = "出铁量(t)")
+//    private BigDecimal ironWeight;
+//
+//    @ApiModelProperty(value = "出铁流速(t/s)")
+//    private BigDecimal ironSpeed;
+//
+//    @ApiModelProperty(value = "铁水温度变化(℃/s)")
+//    private BigDecimal ironwaterTemp;
 
-    @ApiModelProperty(value = "出铁时间(s)")
-    private BigDecimal ctsj;
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
 
-    @ApiModelProperty(value = "出铁量(t)")
-    private BigDecimal ctl;
+    @ApiModelProperty(value = "锅炉编号")
+    private Long boilerId;
 
-    @ApiModelProperty(value = "出铁流速(t/s)")
-    private BigDecimal ctls;
+    @ApiModelProperty(value = "参数类型")
+    private String paramType;
 
-    @ApiModelProperty(value = "铁水温度变化(℃/s)")
-    private BigDecimal tswdbh;
+    @ApiModelProperty(value = "参数名称")
+    private String paramName;
+
+    @ApiModelProperty(value = "参数值")
+    private String paramValue;
 
 }

+ 5 - 5
taphole-iron/src/main/java/com/sckj/iron/entity/TIronStep.java

@@ -28,7 +28,7 @@ public class TIronStep implements Serializable {
     @ApiModelProperty(value = "更新时间")
     private String updateTime;
 
-    @TableId(value="step_id", type= IdType.AUTO)
+    @TableId(value="step_id", type= IdType.INPUT)
     @ApiModelProperty(value = "stepId")
     private String stepId;
 
@@ -39,10 +39,7 @@ public class TIronStep implements Serializable {
     private String stepName;
 
     @ApiModelProperty(value = "通过条件")
-    private String stepTj;
-
-    @ApiModelProperty(value = "下一步")
-    private String nextStep;
+    private String stepCondition;
 
     @ApiModelProperty(value = "节点类型(start、end、node、child)")
     private String nodeType;
@@ -62,4 +59,7 @@ public class TIronStep implements Serializable {
     @ApiModelProperty(value = "订阅点名称(通道.设备.标识)")
     private String pointName;
 
+    @ApiModelProperty(value = "步骤名称表达式")
+    private String stepNameExpression;
+
 }

+ 109 - 0
taphole-iron/src/main/java/com/sckj/iron/entity/TL2Data.java

@@ -0,0 +1,109 @@
+package com.sckj.iron.entity;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ApiModel("L2数据")
+@TableName("t_l2_data")
+public class TL2Data implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "创建时间")
+    @ExcelIgnore
+    private Date createTime;
+
+    @TableId(value="id", type= IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    @ExcelIgnore
+    private Long id;
+
+    @ApiModelProperty(value = "锅炉编号")
+    @ExcelIgnore
+    private Long boilerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    @ExcelProperty("铁口区域编号")
+    private Long tapholeId;
+
+    @ApiModelProperty(value = "出铁次数编号")
+    @ExcelProperty("出铁次数编号")
+    private String ironNo;
+
+    @ApiModelProperty(value = "出铁时间")
+    @ExcelProperty("出铁时间")
+    private String ironCosttime;
+
+    @ApiModelProperty(value = "实际出铁量")
+    @ExcelProperty("实际出铁量")
+    private Double ironWeight;
+
+    @ApiModelProperty(value = "实际渣量")
+    @ExcelProperty("实际渣量")
+    private String slagWeight;
+
+    @ApiModelProperty(value = "铁水平均温度")
+    @ExcelIgnore
+    private String avgTemp;
+
+    @ApiModelProperty(value = "泥炮量")
+    @ExcelIgnore
+    private String mudWeight;
+
+    @ApiModelProperty(value = "钻杆直径")
+    @ExcelIgnore
+    private String pollMm;
+
+    @ApiModelProperty(value = "开口深度")
+    @ExcelIgnore
+    private String openDepth;
+
+    @ApiModelProperty(value = "上料总干量")
+    @ExcelIgnore
+    private Double totalDry;
+
+    @ApiModelProperty(value = "开始时间")
+    @ExcelProperty("开始时间")
+    private String ironStarttime;
+
+    @ExcelProperty("结束时间")
+    @ApiModelProperty(value = "结束时间")
+    private String ironEndtime;
+
+
+    @ApiModelProperty(value = "碳")
+    @ExcelIgnore
+    private String elementC;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "硅")
+    private String elementSi;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "锰")
+    private String elementMn;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "磷")
+    private String elementP;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "硫")
+    private String elementS;
+
+    @ExcelIgnore
+    @ApiModelProperty(value = "钛")
+    private String elementTi;
+
+
+}

+ 1 - 0
taphole-iron/src/main/java/com/sckj/iron/mapper/TIronParamMapper.java

@@ -10,4 +10,5 @@ import org.apache.ibatis.annotations.Mapper;
  */
 @Mapper
 public interface TIronParamMapper extends IBaseMapper<TIronParam> {
+
 }

+ 14 - 0
taphole-iron/src/main/java/com/sckj/iron/mapper/TL2DataMapper.java

@@ -0,0 +1,14 @@
+package com.sckj.iron.mapper;
+
+import com.sckj.common.core.basics.IBaseMapper;
+import com.sckj.iron.entity.TIronAfter;
+import com.sckj.iron.entity.TL2Data;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 出铁后Mapper
+ * @author zhanghao
+ */
+@Mapper
+public interface TL2DataMapper extends IBaseMapper<TL2Data> {
+}

+ 0 - 63
taphole-iron/src/main/java/com/sckj/iron/service/ITIronAfterService.java

@@ -1,63 +0,0 @@
-package com.sckj.iron.service;
-
-import com.sckj.common.core.AjaxResult;
-import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.iron.validate.TIronAfterCreateValidate;
-import com.sckj.iron.validate.TIronAfterUpdateValidate;
-import com.sckj.iron.validate.TIronAfterSearchValidate;
-import com.sckj.iron.vo.TIronAfterListedVo;
-import com.sckj.iron.vo.TIronAfterDetailVo;
-import com.sckj.common.core.PageResult;
-
-import java.util.List;
-
-/**
- * 出铁后服务接口类
- * @author zhanghao
- */
-public interface ITIronAfterService {
-
-    /**
-     * 出铁后列表
-     *
-     * @author zhanghao
-     * @param pageValidate 分页参数
-     * @param searchValidate 搜索参数
-     * @return PageResult<TIronAfterListedVo>
-     */
-    PageResult<TIronAfterListedVo> list(PageValidate pageValidate, TIronAfterSearchValidate searchValidate);
-
-    /**
-     * 出铁后详情
-     *
-     * @author zhanghao
-     * @param id 主键ID
-     * @return TIronAfterDetailVo
-     */
-    TIronAfterDetailVo detail(Integer id);
-
-    /**
-     * 出铁后新增
-     *
-     * @author zhanghao
-     * @param createValidate 参数
-     */
-    void add(TIronAfterCreateValidate createValidate);
-
-    /**
-     * 出铁后删除
-     *
-     * @author zhanghao
-     * @param id 主键ID
-     */
-    void del(Integer id);
-
-    /**
-     * 出铁后批量删除
-     *
-     * @author zhanghao
-     * @param ids 主键数组
-     */
-    AjaxResult<Object> del_ex(List<Long> ids);
-
-}

+ 0 - 63
taphole-iron/src/main/java/com/sckj/iron/service/ITIronBlockService.java

@@ -1,63 +0,0 @@
-package com.sckj.iron.service;
-
-import com.sckj.common.core.AjaxResult;
-import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.iron.validate.TIronBlockCreateValidate;
-import com.sckj.iron.validate.TIronBlockUpdateValidate;
-import com.sckj.iron.validate.TIronBlockSearchValidate;
-import com.sckj.iron.vo.TIronBlockListedVo;
-import com.sckj.iron.vo.TIronBlockDetailVo;
-import com.sckj.common.core.PageResult;
-
-import java.util.List;
-
-/**
- * 堵口后服务接口类
- * @author zhanghao
- */
-public interface ITIronBlockService {
-
-    /**
-     * 堵口后列表
-     *
-     * @author zhanghao
-     * @param pageValidate 分页参数
-     * @param searchValidate 搜索参数
-     * @return PageResult<TIronBlockListedVo>
-     */
-    PageResult<TIronBlockListedVo> list(PageValidate pageValidate, TIronBlockSearchValidate searchValidate);
-
-    /**
-     * 堵口后详情
-     *
-     * @author zhanghao
-     * @param id 主键ID
-     * @return TIronBlockDetailVo
-     */
-    TIronBlockDetailVo detail(Integer id);
-
-    /**
-     * 堵口后新增
-     *
-     * @author zhanghao
-     * @param createValidate 参数
-     */
-    void add(TIronBlockCreateValidate createValidate);
-
-    /**
-     * 堵口后删除
-     *
-     * @author zhanghao
-     * @param id 主键ID
-     */
-    void del(Integer id);
-
-    /**
-     * 堵口后批量删除
-     *
-     * @author zhanghao
-     * @param ids 主键ID
-     */
-    AjaxResult<Object> del_ex(List<Long> ids);
-
-}

+ 0 - 63
taphole-iron/src/main/java/com/sckj/iron/service/ITIronDataService.java

@@ -1,63 +0,0 @@
-package com.sckj.iron.service;
-
-import com.sckj.common.core.AjaxResult;
-import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.iron.validate.TIronDataCreateValidate;
-import com.sckj.iron.validate.TIronDataUpdateValidate;
-import com.sckj.iron.validate.TIronDataSearchValidate;
-import com.sckj.iron.vo.TIronDataListedVo;
-import com.sckj.iron.vo.TIronDataDetailVo;
-import com.sckj.common.core.PageResult;
-
-import java.util.List;
-
-/**
- * 出铁数据服务接口类
- * @author zhnaghao
- */
-public interface ITIronDataService {
-
-    /**
-     * 出铁数据列表
-     *
-     * @author zhnaghao
-     * @param pageValidate 分页参数
-     * @param searchValidate 搜索参数
-     * @return PageResult<TIronDataListedVo>
-     */
-    PageResult<TIronDataListedVo> list(PageValidate pageValidate, TIronDataSearchValidate searchValidate);
-
-    /**
-     * 出铁数据详情
-     *
-     * @author zhnaghao
-     * @param id 主键ID
-     * @return TIronDataDetailVo
-     */
-    TIronDataDetailVo detail(Integer id);
-
-    /**
-     * 出铁数据新增
-     *
-     * @author zhnaghao
-     * @param createValidate 参数
-     */
-    void add(TIronDataCreateValidate createValidate);
-
-    /**
-     * 出铁数据删除
-     *
-     * @author zhnaghao
-     * @param id 主键ID
-     */
-    void del(Integer id);
-
-    /**
-     * 出铁数据批量删除
-     *
-     * @author zhanghao
-     * @param ids 主键数组
-     */
-    AjaxResult<Object> del_ex(List<Long> ids);
-
-}

+ 0 - 71
taphole-iron/src/main/java/com/sckj/iron/service/ITIronParamService.java

@@ -1,71 +0,0 @@
-package com.sckj.iron.service;
-
-import com.sckj.common.core.AjaxResult;
-import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.iron.validate.TIronParamCreateValidate;
-import com.sckj.iron.validate.TIronParamUpdateValidate;
-import com.sckj.iron.validate.TIronParamSearchValidate;
-import com.sckj.iron.vo.TIronParamListedVo;
-import com.sckj.iron.vo.TIronParamDetailVo;
-import com.sckj.common.core.PageResult;
-
-import java.util.List;
-
-/**
- * 参数设定服务接口类
- * @author zhnaghao
- */
-public interface ITIronParamService {
-
-    /**
-     * 参数设定列表
-     *
-     * @author zhnaghao
-     * @param pageValidate 分页参数
-     * @param searchValidate 搜索参数
-     * @return PageResult<TIronParamListedVo>
-     */
-    PageResult<TIronParamListedVo> list(PageValidate pageValidate, TIronParamSearchValidate searchValidate);
-
-    /**
-     * 参数设定详情
-     *
-     * @author zhnaghao
-     * @param id 主键ID
-     * @return TIronParamDetailVo
-     */
-    TIronParamDetailVo detail(Integer id);
-
-    /**
-     * 参数设定新增
-     *
-     * @author zhnaghao
-     * @param createValidate 参数
-     */
-    void add(TIronParamCreateValidate createValidate);
-
-    /**
-     * 参数设定编辑
-     *
-     * @author zhnaghao
-     * @param updateValidate 参数
-     */
-    void edit(TIronParamUpdateValidate updateValidate);
-
-    /**
-     * 参数设定删除
-     *
-     * @author zhnaghao
-     * @param id 主键ID
-     */
-    void del(Integer id);
-
-    /**
-     * 参数设定批量删除
-     *
-     * @author zhanghao
-     * @param ids 主键数组
-     */
-    AjaxResult<Object> del_ex(List<Long> ids);
-
-}

+ 2 - 8
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronAfterServiceImpl.java

@@ -3,17 +3,15 @@ package com.sckj.iron.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sckj.common.TapholeAdminThreadLocal;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.common.core.PageResult;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.iron.entity.TIronAfter;
-import com.sckj.iron.entity.TIronData;
 import com.sckj.iron.mapper.TIronAfterMapper;
-import com.sckj.iron.service.ITIronAfterService;
 import com.sckj.iron.validate.TIronAfterCreateValidate;
 import com.sckj.iron.validate.TIronAfterSearchValidate;
-import com.sckj.iron.validate.TIronAfterUpdateValidate;
 import com.sckj.iron.vo.TIronAfterDetailVo;
 import com.sckj.iron.vo.TIronAfterListedVo;
 import org.springframework.beans.BeanUtils;
@@ -31,7 +29,7 @@ import java.util.List;
  * @author zhanghao
  */
 @Service
-public class TIronAfterServiceImpl implements ITIronAfterService {
+public class TIronAfterServiceImpl  extends ServiceImpl<TIronAfterMapper, TIronAfter> {
         
     @Resource
     TIronAfterMapper tIronAfterMapper;
@@ -44,7 +42,6 @@ public class TIronAfterServiceImpl implements ITIronAfterService {
      * @param searchValidate 搜索参数
      * @return PageResult<TIronAfterListedVo>
      */
-    @Override
     public PageResult<TIronAfterListedVo> list(PageValidate pageValidate, TIronAfterSearchValidate searchValidate) {
         Integer page  = pageValidate.getPageNo();
         Integer limit = pageValidate.getPageSize();
@@ -78,7 +75,6 @@ public class TIronAfterServiceImpl implements ITIronAfterService {
      * @param id 主键参数
      * @return TIronAfter
      */
-    @Override
     public TIronAfterDetailVo detail(Integer id) {
         TIronAfter model = tIronAfterMapper.selectOne(
                 new QueryWrapper<TIronAfter>()
@@ -98,7 +94,6 @@ public class TIronAfterServiceImpl implements ITIronAfterService {
      * @author zhanghao
      * @param createValidate 参数
      */
-    @Override
     public void add(TIronAfterCreateValidate createValidate) {
         TIronAfter model = new TIronAfter();
         model.setCreateBy(String.valueOf(TapholeAdminThreadLocal.getAdminUsername()));
@@ -118,7 +113,6 @@ public class TIronAfterServiceImpl implements ITIronAfterService {
      * @author zhanghao
      * @param id 主键ID
      */
-    @Override
     public void del(Integer id) {
         TIronAfter model = tIronAfterMapper.selectOne(
                 new QueryWrapper<TIronAfter>()

+ 2 - 8
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronBlockServiceImpl.java

@@ -3,17 +3,15 @@ package com.sckj.iron.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sckj.common.TapholeAdminThreadLocal;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.common.core.PageResult;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.iron.entity.TIronBlock;
-import com.sckj.iron.entity.TIronData;
 import com.sckj.iron.mapper.TIronBlockMapper;
-import com.sckj.iron.service.ITIronBlockService;
 import com.sckj.iron.validate.TIronBlockCreateValidate;
 import com.sckj.iron.validate.TIronBlockSearchValidate;
-import com.sckj.iron.validate.TIronBlockUpdateValidate;
 import com.sckj.iron.vo.TIronBlockDetailVo;
 import com.sckj.iron.vo.TIronBlockListedVo;
 import org.springframework.beans.BeanUtils;
@@ -31,7 +29,7 @@ import java.util.List;
  * @author zhanghao
  */
 @Service
-public class TIronBlockServiceImpl implements ITIronBlockService {
+public class TIronBlockServiceImpl  extends ServiceImpl<TIronBlockMapper, TIronBlock> {
         
     @Resource
     TIronBlockMapper tIronBlockMapper;
@@ -44,7 +42,6 @@ public class TIronBlockServiceImpl implements ITIronBlockService {
      * @param searchValidate 搜索参数
      * @return PageResult<TIronBlockListedVo>
      */
-    @Override
     public PageResult<TIronBlockListedVo> list(PageValidate pageValidate, TIronBlockSearchValidate searchValidate) {
         Integer page  = pageValidate.getPageNo();
         Integer limit = pageValidate.getPageSize();
@@ -78,7 +75,6 @@ public class TIronBlockServiceImpl implements ITIronBlockService {
      * @param id 主键参数
      * @return TIronBlock
      */
-    @Override
     public TIronBlockDetailVo detail(Integer id) {
         TIronBlock model = tIronBlockMapper.selectOne(
                 new QueryWrapper<TIronBlock>()
@@ -98,7 +94,6 @@ public class TIronBlockServiceImpl implements ITIronBlockService {
      * @author zhanghao
      * @param createValidate 参数
      */
-    @Override
     public void add(TIronBlockCreateValidate createValidate) {
         TIronBlock model = new TIronBlock();
         model.setCreateBy(String.valueOf(TapholeAdminThreadLocal.getAdminUsername()));
@@ -118,7 +113,6 @@ public class TIronBlockServiceImpl implements ITIronBlockService {
      * @author zhanghao
      * @param id 主键ID
      */
-    @Override
     public void del(Integer id) {
         TIronBlock model = tIronBlockMapper.selectOne(
                 new QueryWrapper<TIronBlock>()

+ 3 - 9
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronDataServiceImpl.java

@@ -3,16 +3,15 @@ package com.sckj.iron.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sckj.common.TapholeAdminThreadLocal;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.common.core.PageResult;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.iron.entity.TIronData;
 import com.sckj.iron.mapper.TIronDataMapper;
-import com.sckj.iron.service.ITIronDataService;
 import com.sckj.iron.validate.TIronDataCreateValidate;
 import com.sckj.iron.validate.TIronDataSearchValidate;
-import com.sckj.iron.validate.TIronDataUpdateValidate;
 import com.sckj.iron.vo.TIronDataDetailVo;
 import com.sckj.iron.vo.TIronDataListedVo;
 import org.springframework.beans.BeanUtils;
@@ -31,7 +30,7 @@ import java.util.List;
  * @author zhnaghao
  */
 @Service
-public class TIronDataServiceImpl implements ITIronDataService {
+public class TIronDataServiceImpl extends ServiceImpl<TIronDataMapper, TIronData> {
 
     @Resource
     TIronDataMapper tIronDataMapper;
@@ -44,7 +43,6 @@ public class TIronDataServiceImpl implements ITIronDataService {
      * @return PageResult<TIronDataListedVo>
      * @author zhnaghao
      */
-    @Override
     public PageResult<TIronDataListedVo> list(PageValidate pageValidate, TIronDataSearchValidate searchValidate) {
         Integer page = pageValidate.getPageNo();
         Integer limit = pageValidate.getPageSize();
@@ -83,7 +81,6 @@ public class TIronDataServiceImpl implements ITIronDataService {
      * @return TIronData
      * @author zhnaghao
      */
-    @Override
     public TIronDataDetailVo detail(Integer id) {
         TIronData model = tIronDataMapper.selectOne(
                 new QueryWrapper<TIronData>()
@@ -103,7 +100,6 @@ public class TIronDataServiceImpl implements ITIronDataService {
      * @param createValidate 参数
      * @author zhnaghao
      */
-    @Override
     public void add(TIronDataCreateValidate createValidate) {
         TIronData model = new TIronData();
         model.setCreateBy(String.valueOf(TapholeAdminThreadLocal.getAdminUsername()));
@@ -114,9 +110,8 @@ public class TIronDataServiceImpl implements ITIronDataService {
         model.setCtl(createValidate.getCtl());
         model.setZl(createValidate.getZl());
         model.setWhcd(createValidate.getWhcd());
-        model.setSbqy(createValidate.getSbqy());
+        //model.setSbqy(createValidate.getSbqy());
         model.setSj(createValidate.getSj());
-        model.setCs(createValidate.getCs());
         tIronDataMapper.insert(model);
     }
 
@@ -126,7 +121,6 @@ public class TIronDataServiceImpl implements ITIronDataService {
      * @param id 主键ID
      * @author zhnaghao
      */
-    @Override
     public void del(Integer id) {
         TIronData model = tIronDataMapper.selectOne(
                 new QueryWrapper<TIronData>()

+ 8 - 19
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronParamServiceImpl.java

@@ -3,15 +3,13 @@ package com.sckj.iron.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.sckj.common.TapholeAdminThreadLocal;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.common.core.PageResult;
-import com.sckj.common.util.TimeUtils;
 import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.iron.entity.TIronData;
 import com.sckj.iron.entity.TIronParam;
 import com.sckj.iron.mapper.TIronParamMapper;
-import com.sckj.iron.service.ITIronParamService;
 import com.sckj.iron.validate.TIronParamCreateValidate;
 import com.sckj.iron.validate.TIronParamSearchValidate;
 import com.sckj.iron.validate.TIronParamUpdateValidate;
@@ -32,7 +30,7 @@ import java.util.List;
  * @author zhnaghao
  */
 @Service
-public class TIronParamServiceImpl implements ITIronParamService {
+public class TIronParamServiceImpl extends ServiceImpl<TIronParamMapper, TIronParam> {
         
     @Resource
     TIronParamMapper tIronParamMapper;
@@ -45,7 +43,6 @@ public class TIronParamServiceImpl implements ITIronParamService {
      * @param searchValidate 搜索参数
      * @return PageResult<TIronParamListedVo>
      */
-    @Override
     public PageResult<TIronParamListedVo> list(PageValidate pageValidate, TIronParamSearchValidate searchValidate) {
         Integer page  = pageValidate.getPageNo();
         Integer limit = pageValidate.getPageSize();
@@ -78,7 +75,6 @@ public class TIronParamServiceImpl implements ITIronParamService {
      * @param id 主键参数
      * @return TIronParam
      */
-    @Override
     public TIronParamDetailVo detail(Integer id) {
         TIronParam model = tIronParamMapper.selectOne(
                 new QueryWrapper<TIronParam>()
@@ -98,16 +94,13 @@ public class TIronParamServiceImpl implements ITIronParamService {
      * @author zhnaghao
      * @param createValidate 参数
      */
-    @Override
     public void add(TIronParamCreateValidate createValidate) {
         TIronParam model = new TIronParam();
         model.setCreateTime(new Date(System.currentTimeMillis()));
         model.setCreateBy(String.valueOf(TapholeAdminThreadLocal.getAdminUsername()));
-        model.setKkhs(createValidate.getKkhs());
-        model.setCtsj(createValidate.getCtsj());
-        model.setCtl(createValidate.getCtl());
-        model.setCtls(createValidate.getCtls());
-        model.setTswdbh(createValidate.getTswdbh());
+        model.setParamType(createValidate.getParamType());
+        model.setParamName(createValidate.getParamName());
+        model.setParamValue(createValidate.getParamValue());
         tIronParamMapper.insert(model);
     }
 
@@ -117,7 +110,6 @@ public class TIronParamServiceImpl implements ITIronParamService {
      * @author zhnaghao
      * @param updateValidate 参数
      */
-    @Override
     public void edit(TIronParamUpdateValidate updateValidate) {
         TIronParam model = tIronParamMapper.selectOne(
                 new QueryWrapper<TIronParam>()
@@ -128,11 +120,9 @@ public class TIronParamServiceImpl implements ITIronParamService {
 
         model.setUpdateBy(String.valueOf(TapholeAdminThreadLocal.getAdminUsername()));
         model.setUpdateTime(new Date(System.currentTimeMillis()));
-        model.setKkhs(updateValidate.getKkhs());
-        model.setCtsj(updateValidate.getCtsj());
-        model.setCtl(updateValidate.getCtl());
-        model.setCtls(updateValidate.getCtls());
-        model.setTswdbh(updateValidate.getTswdbh());
+        model.setParamType(updateValidate.getParamType());
+        model.setParamName(updateValidate.getParamName());
+        model.setParamValue(updateValidate.getParamValue());
         tIronParamMapper.updateById(model);
     }
 
@@ -142,7 +132,6 @@ public class TIronParamServiceImpl implements ITIronParamService {
      * @author zhnaghao
      * @param id 主键ID
      */
-    @Override
     public void del(Integer id) {
         TIronParam model = tIronParamMapper.selectOne(
                 new QueryWrapper<TIronParam>()

+ 73 - 18
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronStepServiceImpl.java

@@ -3,19 +3,17 @@ package com.sckj.iron.service.impl;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.eventbus.AsyncEventBus;
-import com.sckj.iron.dto.IronStepDTO;
 import com.sckj.iron.entity.TIronStep;
 import com.sckj.iron.mapper.TIronStepMapper;
 import com.sckj.iron.vo.IronStepVO;
-import com.sckj.opc.entity.OPCData;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 出铁步骤配置实现类
@@ -35,33 +33,90 @@ public class TIronStepServiceImpl extends ServiceImpl<TIronStepMapper, TIronStep
      * 获取步骤及其子步骤
      * @return
      */
-    public List<IronStepVO> getSteps() {
+    public List<IronStepVO> getTreeSteps() {
         QueryWrapper<TIronStep> queryWrapper = new QueryWrapper<>();
         queryWrapper.lambda().eq(TIronStep::getStatus, "1").orderByAsc(TIronStep::getSort);
         List<TIronStep> stepList = list(queryWrapper);
+        //按照 StepId 长度排序
+        stepList = stepList.stream()
+                .sorted((d1, d2) -> d1.getStepId().length() - d2.getStepId().length())
+                .collect(Collectors.toList());
+
+        Map<String, IronStepVO> stepMap = new HashMap<>();
         List<IronStepVO> stepDTOList = new ArrayList<>();
-        IronStepVO stepDTO = null;
+        // 将所有部门存入 Map 中
         for (TIronStep step : stepList) {
-            if (step.getStepId().length() == 3) {
-                stepDTO = new IronStepVO();
-                stepDTO.setChilds(new ArrayList<>());
-                BeanUtils.copyProperties(step, stepDTO);
-                stepDTOList.add(stepDTO);
+            IronStepVO stepVO = new IronStepVO();
+            BeanUtils.copyProperties(step, stepVO);
+            stepMap.put(step.getStepId(), stepVO);
+        }
+
+        for (TIronStep step : stepList) {
+            String stepId = step.getStepId();
+            IronStepVO currentDto = stepMap.get(stepId);
+            if (stepId.length() == 3) {
+                stepDTOList.add(currentDto);
             } else {
-                if (ObjectUtils.isNotEmpty(stepDTO) && StringUtils.startsWith(step.getStepId(), stepDTO.getStepId())) {
-                    IronStepVO stepChildDTO = new IronStepVO();
-                    BeanUtils.copyProperties(step, stepChildDTO);
-                    stepDTO.getChilds().add(stepChildDTO);
+                String parentId = stepId.substring(0, stepId.length() - 3);
+                IronStepVO parent = stepMap.get(parentId);
+                if (parent != null) {
+                    parent.addChilds(currentDto);
                 }
             }
         }
         return stepDTOList;
     }
 
+//    public Map<String,IronStepVO> getLinkedMapSteps(){
+//        QueryWrapper<TIronStep> queryWrapper = new QueryWrapper<>();
+//        queryWrapper.lambda().eq(TIronStep::getStatus, "1").orderByAsc(TIronStep::getSort);
+//        List<TIronStep> stepList = list(queryWrapper);
+//
+//        //将 stepList 转换为 LinkedHashMap
+//        Map<String, IronStepVO> stepMap = stepList.stream()
+//                .map(step->{
+//                    IronStepVO vo = new IronStepVO();
+//                    BeanUtils.copyProperties(step, vo);
+//                    return vo;
+//                })
+//                .collect(Collectors.toMap(
+//                        IronStepVO::getStepId,
+//                        step -> step,
+//                        (existing, replacement) -> existing,
+//                        LinkedHashMap::new
+//                ));
+//
+//        Map<String,IronStepVO> treeMap = new LinkedHashMap<>();
+//
+//        String key = "";
+//        for(Map.Entry<String,IronStepVO> entry: stepMap.entrySet()){
+//            IronStepVO step = entry.getValue();
+//            if (step.getStepId().length() == 3) {
+//                key = entry.getKey();
+//                step.setChilds(new LinkedHashMap<>());
+//                treeMap.put(key,step);
+////                stepDTO = new IronStepVO();
+////                stepDTO.setChilds(new ArrayList<>());
+////                BeanUtils.copyProperties(step, stepDTO);
+////                stepDTOList.add(stepDTO);
+//            } else {
+//                treeMap.get(key).getChilds().put(entry.getKey(),entry.getValue());
+////                if (ObjectUtils.isNotEmpty(stepDTO) && StringUtils.startsWith(step.getStepId(), stepDTO.getStepId())) {
+////                    IronStepVO stepChildDTO = new IronStepVO();
+////                    BeanUtils.copyProperties(step, stepChildDTO);
+////                    stepDTO.getChilds().add(stepChildDTO);
+////                }
+//            }
+//        }
+//
+//
+//        return stepMap;
+//
+//    }
+
 
-    public void refreshSteps() {
-        List<IronStepVO> steps = this.getSteps();
-        asyncEventBus.post(steps);
+    public void refreshTreeSteps() {
+        asyncEventBus.post(Boolean.TRUE);
     }
 
 

+ 77 - 0
taphole-iron/src/main/java/com/sckj/iron/service/impl/TL2DataServiceImpl.java

@@ -0,0 +1,77 @@
+package com.sckj.iron.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckj.common.util.ExcelUtils;
+import com.sckj.iron.entity.TL2Data;
+import com.sckj.iron.mapper.TL2DataMapper;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * L2数据
+ *
+ * @author zhnaghao
+ */
+@Service
+public class TL2DataServiceImpl extends ServiceImpl<TL2DataMapper, TL2Data> {
+
+
+    /***
+     * 获取最新2条数据
+     * @return
+     */
+    public List<TL2Data> getLatest2Data() {
+        LambdaQueryWrapper<TL2Data> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.isNotNull(TL2Data::getIronEndtime).orderByDesc(TL2Data::getIronNo).last("limit 2");
+        List<TL2Data> list = list(queryWrapper);
+        return list;
+    }
+
+    /***
+     * 获取最新6条数据
+     * @return
+     */
+    public List<TL2Data> getLatest6Data() {
+        LambdaQueryWrapper<TL2Data> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.isNotNull(TL2Data::getIronEndtime).orderByDesc(TL2Data::getIronNo).last("limit 6");
+        List<TL2Data> list = list(queryWrapper);
+        return list;
+    }
+
+    /***
+     * 获取最新6条数据
+     * @return
+     */
+    public List<TL2Data> queryIronData(TL2Data tl2Data) {
+        QueryWrapper<TL2Data> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda()
+                .eq(ObjectUtils.isNotEmpty(tl2Data.getSlagWeight()), TL2Data::getSlagWeight, tl2Data.getSlagWeight())
+                .eq(ObjectUtils.isNotEmpty(tl2Data.getIronWeight()), TL2Data::getIronWeight, tl2Data.getIronWeight())
+                .eq(ObjectUtils.isNotEmpty(tl2Data.getIronCosttime()), TL2Data::getIronCosttime, tl2Data.getIronCosttime())
+                .eq(ObjectUtils.isNotEmpty(tl2Data.getIronNo()), TL2Data::getIronNo, tl2Data.getIronNo())
+                .eq(ObjectUtils.isNotEmpty(tl2Data.getIronStarttime()), TL2Data::getIronStarttime, tl2Data.getIronStarttime())
+                .eq(ObjectUtils.isNotEmpty(tl2Data.getIronEndtime()), TL2Data::getIronEndtime, tl2Data.getIronEndtime())
+                .eq(ObjectUtils.isNotEmpty(tl2Data.getTapholeId()), TL2Data::getTapholeId, tl2Data.getTapholeId())
+        ;
+        return list(queryWrapper);
+    }
+
+    /***
+     * 导出数据
+     * @param tl2Data
+     * @param response
+     * @throws IOException
+     */
+    public void exportIronData(TL2Data tl2Data, HttpServletResponse response)  throws IOException {
+        List<TL2Data> tl2DataList = queryIronData(tl2Data);
+        ExcelUtils.exportExcel(tl2DataList,TL2Data.class,"出铁数据","出铁数据",response);
+    }
+
+
+}

+ 580 - 560
taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java

@@ -1,29 +1,38 @@
 package com.sckj.iron.socketio;
 
-import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.corundumstudio.socketio.SocketIOClient;
 import com.corundumstudio.socketio.annotation.OnEvent;
 import com.google.common.eventbus.Subscribe;
+import com.sckj.common.core.AjaxResult;
 import com.sckj.common.eventbus.EventListener;
 import com.sckj.common.socketio.SocketUtil;
+import com.sckj.common.util.RedisUtils;
 import com.sckj.iron.dto.IronStepDTO;
-import com.sckj.iron.service.impl.TIronStepServiceImpl;
-import com.sckj.iron.vo.IronOperataion;
+import com.sckj.iron.dto.RealtimeData;
+import com.sckj.iron.dto.TrendData;
+import com.sckj.iron.entity.TIronData;
+import com.sckj.iron.entity.TL2Data;
+import com.sckj.iron.service.impl.*;
 import com.sckj.iron.vo.IronStepVO;
+import com.sckj.opc.dto.L2Data;
 import com.sckj.opc.entity.OPCData;
+import com.sckj.opc.opcua.L2DataServiceImpl;
+import com.sckj.opc.service.OPCDataServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.BeanUtils;
 import org.springframework.expression.spel.standard.SpelExpressionParser;
 import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Stream;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.util.*;
 
 /**
  * @Author feng
@@ -34,706 +43,717 @@ import java.util.stream.Stream;
 @Slf4j
 public class DeviceEventListener extends EventListener {
 
-    private static final String TAG1 = "TAG1";
-    private static final String TAG2 = "TAG2";
-    private static final String TAG3 = "TAG3";
-    private static final String TAG4 = "TAG4";
-    private static final String TAG5 = "TAG5";
-    private static final String TAG6 = "TAG6";
-    private static final String TAG7 = "TAG7";
-    private static final String TAG8 = "TAG8";
-    private static final String TAG9 = "TAG9";
-    private static final String TAG10 = "TAG10";
-    private static final String TAG11 = "TAG11";
-    private static final String TAG12 = "TAG12";
-    private static final String TAG13 = "TAG13";
-    private static final String TAG14 = "TAG14";
-    private static final String TAG15 = "TAG15";
-
+    //步骤数据
     @Resource
     TIronStepServiceImpl ironStepService;
 
-    @Deprecated
-    private Map<String, IronOperataion> operateMap = new ConcurrentHashMap<>();
+    //出铁数据
+    @Resource
+    TIronDataServiceImpl ironDataService;
 
-    private Map<SocketIOClient, IronOperataion> operateMap2 = new ConcurrentHashMap<>();
+    //出铁后
+    @Resource
+    TIronAfterServiceImpl ironAfterService;
+
+    //堵口后
+    @Resource
+    TIronBlockServiceImpl ironBlockService;
+
+    //参数
+    @Resource
+    TIronParamServiceImpl ironParamService;
+
+    //参数
+    @Resource
+    TL2DataServiceImpl tl2DataService;
 
-    private Map<SocketIOClient, List<IronStepDTO>> operateMap3 = new ConcurrentHashMap<>();
+    @Resource
+    private L2DataServiceImpl l2DataServiceImpl;
+
+    @Resource
+    OPCDataServiceImpl opcDataService;
+
+    //实时数据
+    Map<String, Object> mRealtimeData = new HashMap<>();
+
+    //实时状态
+    Map<String, Object> mRealtimeStatus = new HashMap<>();
+
+
+    @Resource
+    TrendData trendData;
+
+    //L1
+    private OPCData mOPCData;
+
+    //L2
+    private L2Data mL2Data;
 
     // 1.创建表达式解析器
     private SpelExpressionParser parser = new SpelExpressionParser();
 
     // 2.创建变量上下文,设置变量
-    private StandardEvaluationContext ctx = new StandardEvaluationContext();
+    private StandardEvaluationContext mContext = new StandardEvaluationContext();
 
+    //出铁步骤
     private List<IronStepVO> mSteps;
 
+    private static final String NODE = "node";
+
+    //定时器,用于铁口开口超时记录
+    private Timer timer = new Timer();
+
+    //是否出铁中
+    //1 出铁中    0 出铁结束
+    private boolean ironLoading1 = false;
+    private boolean ironLoading2 = false;
+    private boolean ironLoading3 = false;
+    private boolean ironLoading4 = false;
+
+    //1号出铁状态标记
+    private static final String TAG_TAPHOLE1_STATUS = "AOD25606.PV";
+    //2号出铁状态标记
+    private static final String TAG_TAPHOLE2_STATUS = "AOD25622.PV";
+    //3号出铁状态标记
+    private static final String TAG_TAPHOLE3_STATUS = "AOD25706.PV";
+    //4号出铁状态标记
+    private static final String TAG_TAPHOLE4_STATUS = "AOD25722.PV";
+    //铁水温度
+    private static final String TAG_IRON_TEMP = "CL510104.CPV";
+    //1TH-1号车受铁速度
+    private static final String TAG_CAR11 = "WZ540101.PV";
+    //1TH-2号车受铁速度
+    private static final String TAG_CAR12 = "WZ540201.PV";
+    //1TH-1号车总重
+    private static final String TAG_IRON_WEIGHT11 = "WI5401.PV";
+    //1TH-2号车TPC总重
+    private static final String TAG_IRON_WEIGHT12 = "WI5402.PV";
+
+    //预判和确认出铁
+    private static final String ypqrct = "lnct";
+
+    //铁量差计算
+    private static final String tlc = "tlc";
+
+    //最近任一铁口出铁结束时间
+    private Date lastIronEndTimeRecently;
+
+    @Resource(name = "taskExecutor")
+    ThreadPoolTaskExecutor taskExecutor;
+
+    //铁水成分
+    public static final String IRON_ELEMENT = "ironElement";
+    //铁水温度
+    public static final String IRON_TEMP = "ironTemp";
+    //铁水流速
+    public static final String IRON_SPEED = "ironSpeed";
+    //重量
+    public static final String IRON_WEIGHT = "ironWeight";
+    //出铁状态
+    private static final String IRON_STATUS = "ironStatus";
+
+    //鱼雷罐车
+    private static final String CAR_STATUS = "ylgc";
+    //拔炮
+    private static final String GUN_STATUS = "npkkj";
+    //摆动溜咀
+    private static final String MOUTH_STATUS = "bdlz";
+    //冲渣状态
+    private static final String FLUSH_STATUS = "flushStatus";
+    //预计出铁结束时间
+    private static final String PLAN_END_TIME = "planEndTime";
+
+
     @PostConstruct
     public void init() {
-        mSteps = ironStepService.getSteps();
+        mSteps = ironStepService.getTreeSteps();
     }
 
+    /***
+     * L1数据项
+     * @param opcData
+     */
     @Subscribe
     public void onMessageEvent(OPCData opcData) {
-        if (SocketUtil.connectMap.isEmpty()) {
+        if (SocketUtil.clientUserIds.isEmpty()) {
             return;
         }
+        this.mOPCData = opcData;
+        //异步保存OPC数据
+        taskExecutor.submit(() -> opcDataService.save(mOPCData));
+        //出铁操作
+        operate();
 
-        operate3(opcData);
+        //趋势数据
+        trenddata();
+
+        //实时数据
+        realtime();
 
-//        for (Map.Entry<SocketIOClient, String> entry : SocketUtil.clientUserIds.entrySet()) {
-//            //根据在线用户初始化炼铁操作数据
-//            if (!operateMap2.containsKey(entry.getKey())) {
-//                operateMap2.put(entry.getKey(), new IronOperataion());
-//            }
-//        }
-//
-//        for (Map.Entry<SocketIOClient, String> entry : SocketUtil.clientUserIds.entrySet()) {
-//            //根据在线用户初始化炼铁操作数据
-//            if (!operateMap3.containsKey(entry.getKey())) {
-//                operateMap3.put(entry.getKey(), ironStepService.getSteps());
-//            }
-//        }
-//
-//
-//        for (Map.Entry<SocketIOClient, List<IronStepDTO>> entry : operateMap3.entrySet()) {
-//            //根据公共数据和私有数据进行填充
-//            List<IronStepDTO> ironOperate = entry.getValue();
-////            if (!operateMap3.containsKey(entry.getKey())) {
-////                operateMap3.put()
-////            }
-//
-//            operate3(ironOperate, opcData, entry.getKey());
-//        }
-
-
-//        for (Map.Entry<SocketIOClient, IronOperataion> entry : operateMap2.entrySet()) {
-//            //根据公共数据和私有数据进行填充
-//            IronOperataion ironOperate = entry.getValue();
-//            operate2(ironOperate, opcData, entry.getKey());
-//        }
-//        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
-//            //根据在线用户初始化炼铁操作数据
-//            if (!operateMap.containsKey(entry.getKey())) {
-//                operateMap.put(entry.getKey(), new IronOperataion());
-//            }
-//        }
-//        for (Map.Entry<String, IronOperataion> entry : operateMap.entrySet()) {
-//            //根据公共数据和私有数据进行填充
-//            IronOperataion ironOperate = entry.getValue();
-//            operate(ironOperate, opcData, entry.getKey());
-//        }
     }
 
-    @Deprecated
-    private void operate(IronOperataion ironOperate, OPCData opcData, String userId) {
-        String identifier = opcData.getPointName();
-        try {
-            identifier = identifier.split("\\.")[2];
-        } catch (Exception e) {
-            e.printStackTrace();
+    /***
+     * L2数据项
+     * @param l2Data
+     */
+    @Subscribe
+    public void onL2MessageEvent(L2Data l2Data) {
+        if (SocketUtil.clientUserIds.isEmpty()) {
             return;
         }
-        Object data = opcData.getData();
-
-        //出铁
-        if (TAG1.equals(identifier)
-                || TAG2.equals(identifier)
-                || TAG3.equals(identifier)
-                || TAG4.equals(identifier)
-                || TAG5.equals(identifier)
-                || TAG6.equals(identifier)
-                || TAG7.equals(identifier)
-                || TAG8.equals(identifier)
-                || TAG9.equals(identifier)
-                || TAG10.equals(identifier)
-        ) {
-            //ylgcdw 鱼雷罐车到位
-            if (identifier.equals(TAG1)) {
-                if ("0".equals(data)) {
-                    ironOperate.setYlgcdw("0");
-                } else {
-                    ironOperate.setYlgcdw("1");
-                }
-            }
-
-            //tbxtzc 铁摆系统正常
-            if (identifier.equals(TAG2)) {
-                if ("0".equals(data)) {
-                    ironOperate.setTbxtzc("0");
-                } else {
-                    ironOperate.setTbxtzc("1");
-                }
-            }
-
-            //npkkjzbwb 泥炮、开口机准备完毕
-            if (identifier.equals(TAG3)) {
-                if ("0".equals(data)) {
-                    ironOperate.setNpkkjzbwb("0");
-                } else {
-                    ironOperate.setNpkkjzbwb("1");
-                }
-            }
+        this.mL2Data = l2Data;
+        realtime();
 
+        TL2Data tl2Data = new TL2Data();
+        //出铁操作
+        BeanUtils.copyProperties(l2Data, tl2Data);
 
-            //炉前准备
-            if ("1".equals(ironOperate.getYlgcdw())
-                    && "1".equals(ironOperate.getTbxtzc())
-                    && "1".equals(ironOperate.getNpkkjzbwb())
-                    && "1".equals(ironOperate.getRydw())
-            ) {
-                ironOperate.setLqzb("1");
-            } else {
-                log.info("lqzb failed => ylgcdw:{},tbxtzc:{},npkkjzbwb:{},rydw:{}", ironOperate.getYlgcdw(), ironOperate.getTbxtzc(), ironOperate.getNpkkjzbwb(), ironOperate.getRydw());
-
-                ironOperate.setRydw("0");
-                ironOperate.setLqzb("0");
+        //将L2实时数据保存到数据库
+        tl2DataService.saveOrUpdate(tl2Data);
 
-                ironOperate.setSzbykq("0");
-                ironOperate.setCtmskq("0");
-                ironOperate.setZggbdj("0");
-                ironOperate.setWwtj("0");
+        //将L2实时数据保存到Redis
+        RedisUtils.addFixedElement(IRON_ELEMENT, l2Data, 6);
 
-                ironOperate.setLqsqct("0");
+        for (IronStepVO stepDTO : mSteps) {
+            if (NODE.equalsIgnoreCase(stepDTO.getNodeType())) {
+                //处理子项
+                for (IronStepVO child : stepDTO.getChilds()) {
+                    if (tlc.equals(child.getIdentifier())) {
+                        List<TL2Data> latest2Data = tl2DataService.getLatest2Data();
+                        if (latest2Data.size() >= 2) {
+                            HashMap[] hashMaps = new HashMap[6];
+                            child.setExtraInfo(hashMaps);
+                            //理论出铁量 = 矿批 × 综合品位 × 1.06
+                            //铁量差 = 理论出铁量 - 实际出铁量
+                            TL2Data tl2Data1Last = latest2Data.get(0);
+                            double llLast = tl2Data1Last.getTotalDry() * 1.0 * 1.06;
+                            double ironWeightLast = tl2Data1Last.getIronWeight();
+                            double tlcLast = llLast - ironWeightLast;
+
+                            TL2Data tl2Data1LastLast = latest2Data.get(1);
+                            double llLastLast = tl2Data1LastLast.getTotalDry() * 1.0 * 1.06;
+                            double ironWeightLastLast = tl2Data1Last.getIronWeight();
+                            double tlcLastLast = llLastLast - ironWeightLastLast;
+
+                            //铁量差在合理范围内
+                            // 上一次铁量差:-30       上上次铁量差:20 t
+                            // 理论出铁量:1500 t      理论出铁量:1400 t
+                            // 实际出铁量:1530 t      实际出铁量: 1380 t
+                            final String sctlc = "sctlc";
+                            final String ssctlc = "ssctlc";
+                            final String scll = "scll";
+                            final String sscll = "sscll";
+                            final String scsj = "scsj";
+                            final String sscsj = "sscsj";
+
+                            //child.setPassResult(1);
+                            for (IronStepVO childChild : child.getChilds()) {
+                                if (sctlc.equals(childChild.getIdentifier())) {
+                                    childChild.setData(tlcLast);
+                                } else if (ssctlc.equals(childChild.getIdentifier())) {
+                                    childChild.setData(tlcLastLast);
+                                } else if (scll.equals(childChild.getIdentifier())) {
+                                    childChild.setData(llLast);
+                                } else if (sscll.equals(childChild.getIdentifier())) {
+                                    childChild.setData(llLastLast);
+                                } else if (scsj.equals(childChild.getIdentifier())) {
+                                    childChild.setData(ironWeightLast);
+                                } else if (sscsj.equals(childChild.getIdentifier())) {
+                                    childChild.setData(ironWeightLastLast);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        setStepResult(mSteps);
+    }
 
-                ironOperate.setGlyxqk("0");
-                ironOperate.setTlcjs("0");
-                ironOperate.setCtfs("0");
-                ironOperate.setLncttj("0");
 
-                ironOperate.setYpqrct("0");
+    //趋势数据
+    private void trenddata() {
+        //
 
-                ironOperate.setLqctcz("0");
+    }
 
-                PushData.send2Operation(ironOperate, userId);
-                return;
-            }
 
-//            if (identifier.contains(TAG4)) {
-//                ironOperate.setRydw(data);
-//            }
-
-            //水闸泵已开启,水闸槽水量正常
-            if (identifier.equals(TAG4)) {
-                if ("0".equals(data)) {
-                    ironOperate.setSzbykq("0");
+    //实时数据显示
+    private void realtime() {
+        //铁水温度
+        //铁水流速
+        //铁水成分
+        //铁水流量
+        //WI5401.PV  1TH-1号车总重
+        //WI5402.PV  1TH-2号车TPC总重
+        if (ObjectUtils.isNotEmpty(mOPCData)) {
+            if (mOPCData.getPointName().contains(TAG_IRON_TEMP)) {
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setUnit("℃");
+                realtimeData.setDesc("铁水温度");
+                realtimeData.setTime(mOPCData.getServerTime().toString());
+                mRealtimeData.put(IRON_TEMP, realtimeData);
+                //redis添加数据
+                RedisUtils.addFixedElement(IRON_TEMP, realtimeData, 6);
+            }
+
+            if (mOPCData.getPointName().contains(TAG_CAR11) || mOPCData.getPointName().contains(TAG_CAR12)) {
+//            1TH-1号车受铁速度
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setUnit("t/s");
+
+                RealtimeData ironSpeed = (RealtimeData) mRealtimeData.get(IRON_SPEED);
+                RealtimeData[] speeds = null;
+                if (ObjectUtils.isEmpty(ironSpeed)) {
+                    ironSpeed = new RealtimeData();
+                    ironSpeed.setDesc("铁水流速");
+                    speeds = new RealtimeData[2];
+                    ironSpeed.setValue(speeds);
+                    mRealtimeData.put(IRON_SPEED, ironSpeed);
                 } else {
-                    ironOperate.setSzbykq("1");
+                    speeds = (RealtimeData[]) ironSpeed.getValue();
                 }
-            }
 
-            //除尘开启出铁模式
-            if (identifier.equals(TAG5)) {
-                if ("0".equals(data)) {
-                    ironOperate.setCtmskq("0");
+                if (mOPCData.getPointName().contains(TAG_CAR11)) {
+                    realtimeData.setDesc("1号车");
+                    speeds[0] = realtimeData;
                 } else {
-                    ironOperate.setCtmskq("1");
+                    realtimeData.setDesc("2号车");
+                    speeds[1] = realtimeData;
                 }
-            }
 
-            //主沟盖板吊装机处于待机位
-            if (identifier.equals(TAG6)) {
-                if ("0".equals(data)) {
-                    ironOperate.setZggbdj("0");
-                } else {
-                    ironOperate.setZggbdj("1");
+                //只在两个都有数据的时候才添加
+                if (ObjectUtils.isNotEmpty(speeds)
+                        && ObjectUtils.isNotEmpty(speeds[0]) && ObjectUtils.isNotEmpty(speeds[0].getValue())
+                        && ObjectUtils.isNotEmpty(speeds[1]) && ObjectUtils.isNotEmpty(speeds[1].getValue())
+                ) {
+                    ironSpeed.setTime(mOPCData.getServerTime().toString());
+                    RedisUtils.addFixedElement(IRON_SPEED, ironSpeed, 6);
                 }
             }
 
-            //外围条件
-            if ("1".equals(ironOperate.getSzbykq())
-                    && "1".equals(ironOperate.getCtmskq())
-                    && "1".equals(ironOperate.getZggbdj())
-            ) {
-                ironOperate.setWwtj("1");
-            } else {
-                log.info("wwtj failed => szbykq:{},ctmskq:{},zggbdj:{}", ironOperate.getSzbykq(), ironOperate.getCtmskq(), ironOperate.getZggbdj());
-
-                ironOperate.setWwtj("0");
-
-                ironOperate.setLqsqct("0");
-
-                ironOperate.setGlyxqk("0");
-                ironOperate.setTlcjs("0");
-                ironOperate.setCtfs("0");
-                ironOperate.setLncttj("0");
+            if (mOPCData.getPointName().contains(TAG_IRON_WEIGHT11) || mOPCData.getPointName().contains(TAG_IRON_WEIGHT12)) {
+//              铁水流量
+                RealtimeData ironWeight = (RealtimeData) mRealtimeData.get(IRON_WEIGHT);
+                if (ObjectUtils.isEmpty(ironWeight)) {
+                    ironWeight = new RealtimeData();
+                    ironWeight.setDesc("铁水流量");
+                    ironWeight.setUnit("t");
+                    ironWeight.setValue(new BigDecimal(String.valueOf(mOPCData.getData())));
+                    mRealtimeData.put(IRON_WEIGHT, ironWeight);
 
-                ironOperate.setYpqrct("0");
-
-                ironOperate.setLqctcz("0");
+                    ironWeight.setTime(mOPCData.getServerTime().toString());
+                    RedisUtils.addFixedElement(IRON_WEIGHT, ironWeight, 6);
+                } else {
+                    BigDecimal bigDecimalOld = ((BigDecimal) ironWeight.getValue());
+                    BigDecimal bigDecimalNew = new BigDecimal(mOPCData.getData().toString());
+                    BigDecimal add = bigDecimalOld.add(bigDecimalNew);
+                    ironWeight.setValue(add);
 
-                PushData.send2Operation(ironOperate, userId);
+                    ironWeight.setTime(mOPCData.getServerTime().toString());
+                    RedisUtils.addFixedElement(IRON_WEIGHT, ironWeight, 6);
+                }
+            }
 
-                return;
 
+            if (mOPCData.getPointName().contains(TAG_TAPHOLE1_STATUS)) {
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setDesc("出铁状态");
+                mRealtimeStatus.put(IRON_STATUS, realtimeData);
             }
 
-            if ("0".equals(ironOperate.getLqsqct())) {
-                ironOperate.setGlyxqk("0");
-                ironOperate.setTlcjs("0");
-                ironOperate.setCtfs("0");
-                ironOperate.setLncttj("0");
+//            if (mOPCData.getPointName().contains(CAR_STATUS)) {
+//                RealtimeData realtimeData = new RealtimeData();
+//                realtimeData.setValue(mOPCData.getData());
+//                realtimeData.setDesc("鱼雷罐车到位状态");
+//                mRealtimeDataMap.put(CAR_STATUS, realtimeData);
+//            }
 
-                ironOperate.setYpqrct("0");
 
-                ironOperate.setLqctcz("0");
+//            if (mOPCData.getPointName().contains(TAG_IRON_STATUS1)) {
+//                RealtimeData realtimeData = new RealtimeData();
+//                realtimeData.setValue(mOPCData.getData());
+//                realtimeData.setDesc("拔炮状态");
+//                mRealtimeDataMap.put(GUN_STATUS, realtimeData);
+//            }
+//
+//
+//            if (mOPCData.getPointName().contains(TAG_IRON_STATUS1)) {
+//                RealtimeData realtimeData = new RealtimeData();
+//                realtimeData.setValue(mOPCData.getData());
+//                realtimeData.setDesc("摆动溜咀");
+//                mRealtimeDataMap.put(MOUTH_STATUS, realtimeData);
+//            }
 
-                PushData.send2Operation(ironOperate, userId);
-                return;
+            if (mOPCData.getPointName().contains(FLUSH_STATUS)) {
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setDesc("冲渣状态");
+                mRealtimeStatus.put(FLUSH_STATUS, realtimeData);
             }
 
-
-            //高炉运行情况
-            if (identifier.equals(TAG7)) {
-                if ("0".equals(data)) {
-                    ironOperate.setGlyxqk("0");
-                } else {
-                    ironOperate.setGlyxqk("1");
-                }
+            if (mOPCData.getPointName().contains(PLAN_END_TIME)) {
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setDesc("预计出铁结束时间");
+                mRealtimeData.put(PLAN_END_TIME, realtimeData);
             }
 
-            //理论铁量、铁铁差计算
-            if (identifier.equals(TAG8)) {
-                if ("0".equals(data)) {
-                    ironOperate.setTlcjs("0");
-                } else {
-                    ironOperate.setTlcjs("1");
-                }
-            }
 
-            //出铁口模式
-            if (identifier.equals(TAG9)) {
-                if ("0".equals(data)) {
-                    ironOperate.setCtfs("0");
-                } else {
-                    ironOperate.setCtfs("1");
-                }
+            float yc = Float.valueOf(ObjectUtils.defaultIfNull(mContext.lookupVariable("yc"), "0").toString());
+            if (yc > 190) {
+                log.info("预警出铁");
+                PushData.send2Warn(AjaxResult.success("预警出铁"));
             }
 
-            //炉内出铁条件
-            if ("1".equals(ironOperate.getLqsqct())
-                    && "1".equals(ironOperate.getGlyxqk())
-                    && "1".equals(ironOperate.getTlcjs())
-                    && "1".equals(ironOperate.getCtfs())
-            ) {
-                ironOperate.setLncttj("1");
-            } else {
-                ironOperate.setLncttj("0");
+        }
 
-                log.info("lncttj failed => glyxqk:{},tlcjs:{},ctkms:{}", ironOperate.getGlyxqk(), ironOperate.getTlcjs(), ironOperate.getCtfs());
+        if (ObjectUtils.isNotEmpty(mL2Data)) {
+            //铁水成分
+            //预计出铁结束时间
+            String elementSi = mL2Data.getElementSi();
+            String elementS = mL2Data.getElementS();
 
-                ironOperate.setYpqrct("0");
+            RealtimeData realtimeData = new RealtimeData();
+            realtimeData.setValue(elementSi);
+            realtimeData.setUnit("%");
+            realtimeData.setDesc("硅");
 
-                ironOperate.setLqctcz("0");
+            RealtimeData realtimeData2 = new RealtimeData();
+            realtimeData2.setValue(elementS);
+            realtimeData2.setUnit("%");
+            realtimeData2.setDesc("硫");
 
-                PushData.send2Operation(ironOperate, userId);
-                return;
-            }
+            List<RealtimeData> realtimeDataList = new ArrayList<>();
+            realtimeDataList.add(realtimeData);
+            realtimeDataList.add(realtimeData2);
 
-            if ("1".equals(ironOperate.getYpqrct())) {
-                ironOperate.setLqctcz("1");
-            } else {
-                ironOperate.setLqctcz("0");
-            }
+            RealtimeData realtimeData3 = new RealtimeData();
+            realtimeData3.setValue(realtimeDataList);
+            realtimeData3.setDesc("铁水成分");
 
-            PushData.send2Operation(ironOperate, userId);
+            mRealtimeData.put(IRON_ELEMENT, realtimeData3);
         }
 
-        //glyxqk 高炉运行情况
-        //tlcjs 理论铁量、铁铁差计算
-        //ctkms 出铁口模式
-
-        //趋势
-        if (Stream.of("TAG5", "TAG6", "TAG7", "TAG8").anyMatch(identifier::contains)) {
-            // PushData.sendToTrend(JSON.toJSONString(opcData));
-            //铁水成分
-            //铁水流速
-            //铁水流量
-            //铁水温度
-        }
+        //推送实时数据
+        PushData.send2RealtimeData(mRealtimeData);
+        //推送实时状态
+        PushData.send2RealtimeStatus(mRealtimeStatus);
 
-        //实时数据
-        if (Stream.of("TAG9", "TAG10").anyMatch(identifier::contains)) {
-//            PushData.sendToRealtime(JSON.toJSONString(opcData));
-            //除铁中
-            //
-            //
-            //
-            //
-        }
     }
 
-    private void operate2(IronOperataion ironOperate, OPCData opcData, SocketIOClient socketIOClient) {
-        String identifier = opcData.getPointName();
-        try {
-            identifier = identifier.split("\\.")[2];
-        } catch (Exception e) {
-            e.printStackTrace();
+
+    private void operate() {
+        if (ObjectUtils.isEmpty(mOPCData)) {
             return;
         }
-        Object data = opcData.getData();
-
-        //出铁
-        if (TAG1.equals(identifier)
-                || TAG2.equals(identifier)
-                || TAG3.equals(identifier)
-                || TAG4.equals(identifier)
-                || TAG5.equals(identifier)
-                || TAG6.equals(identifier)
-                || TAG7.equals(identifier)
-                || TAG8.equals(identifier)
-                || TAG9.equals(identifier)
-                || TAG10.equals(identifier)
-        ) {
-            //ylgcdw 鱼雷罐车到位
-            if (identifier.equals(TAG1)) {
-                if ("0".equals(data)) {
-                    ironOperate.setYlgcdw("0");
-                } else {
-                    ironOperate.setYlgcdw("1");
-                }
-            }
+        String pointName = mOPCData.getPointName();
+        Object data = mOPCData.getData();
+        for (IronStepVO stepDTO : mSteps) {
+            //log.info("nodetype:{},pointname:{},opc pointname:{}",stepDTO.getNodeType(),stepDTO.getPointName(),pointName);
+            if (NODE.equalsIgnoreCase(stepDTO.getNodeType())) {
+                //处理子项
+                for (IronStepVO child : stepDTO.getChilds()) {
+                    for (IronStepVO childchild : child.getChilds()) {
 
-            //tbxtzc 铁摆系统正常
-            if (identifier.equals(TAG2)) {
-                if ("0".equals(data)) {
-                    ironOperate.setTbxtzc("0");
-                } else {
-                    ironOperate.setTbxtzc("1");
-                }
-            }
+                        //plc的point和step的point一致
+                        String newPointName = childchild.getPointName();
 
-            //npkkjzbwb 泥炮、开口机准备完毕
-            if (identifier.equals(TAG3)) {
-                if ("0".equals(data)) {
-                    ironOperate.setNpkkjzbwb("0");
-                } else {
-                    ironOperate.setNpkkjzbwb("1");
-                }
-            }
+                        if (ObjectUtils.isEmpty(newPointName)) {
+                            continue;
+                        }
 
+                        if (newPointName.contains(".")) {
+                            newPointName = "channel." + newPointName;
+                        } else {
+                            newPointName = "channel.device." + newPointName;
+                        }
 
-            //炉前准备
-            if ("1".equals(ironOperate.getYlgcdw())
-                    && "1".equals(ironOperate.getTbxtzc())
-                    && "1".equals(ironOperate.getNpkkjzbwb())
-                    && "1".equals(ironOperate.getRydw())
-            ) {
-                ironOperate.setLqzb("1");
-            } else {
-                log.info("lqzb failed => ylgcdw:{},tbxtzc:{},npkkjzbwb:{},rydw:{}", ironOperate.getYlgcdw(), ironOperate.getTbxtzc(), ironOperate.getNpkkjzbwb(), ironOperate.getRydw());
+                        if (Objects.equals(newPointName, pointName)) {
+                            //3.创建变量上下文,设置变量
+                            childchild.setData(data);
+                        }
+                    }
+                    String newPointName = child.getPointName();
+                    if (ObjectUtils.isEmpty(newPointName)) {
+                        continue;
+                    }
+                    if (newPointName.contains(".")) {
+                        newPointName = "channel." + newPointName;
+                    } else {
+                        newPointName = "channel.device." + newPointName;
+                    }
+                    if (Objects.equals(newPointName, pointName)) {
+                        child.setData(data);
+                    }
 
-                ironOperate.setRydw("0");
-                ironOperate.setLqzb("0");
+                }
+            }
+        }
 
-                ironOperate.setSzbykq("0");
-                ironOperate.setCtmskq("0");
-                ironOperate.setZggbdj("0");
-                ironOperate.setWwtj("0");
+        setStepResult(mSteps);
 
-                ironOperate.setLqsqct("0");
 
-                ironOperate.setGlyxqk("0");
-                ironOperate.setTlcjs("0");
-                ironOperate.setCtfs("0");
-                ironOperate.setLncttj("0");
+        ironReady();
 
-                ironOperate.setYpqrct("0");
 
-                ironOperate.setLqctcz("0");
+        PushData.send2Operation(mSteps, ironLoading1);
 
+    }
 
-                PushData.send2Operation(ironOperate, socketIOClient);
-                return;
-            }
+    //计算每步结果
+    private void setStepResult(List<IronStepVO> mSteps) {
+        boolean foundFalsePass = false;
+        //发现第一个pass是false,后续都为false,包括父项和子项
+        for (IronStepVO stepDTO : mSteps) {
+            for (IronStepVO child : stepDTO.getChilds()) {
+                for (IronStepVO childChild : child.getChilds()) {
+                    //子项的子项 验证是否通过
+                    validateStepPass(childChild);
 
-//            if (identifier.contains(TAG4)) {
-//                ironOperate.setRydw(data);
-//            }
+                    if (!foundFalsePass && 0 == childChild.getPassResult()) {
+                        foundFalsePass = true;
+                    }
 
-            //水闸泵已开启,水闸槽水量正常
-            if (identifier.equals(TAG4)) {
-                if ("0".equals(data)) {
-                    ironOperate.setSzbykq("0");
-                } else {
-                    ironOperate.setSzbykq("1");
+                    if (foundFalsePass) {
+                        childChild.setPassResult(0);
+                    }
                 }
-            }
 
-            //除尘开启出铁模式
-            if (identifier.equals(TAG5)) {
-                if ("0".equals(data)) {
-                    ironOperate.setCtmskq("0");
-                } else {
-                    ironOperate.setCtmskq("1");
+                //子项验证是否通过
+                validateStepPass(child);
+                if (!foundFalsePass && 0 == child.getPassResult()) {
+                    foundFalsePass = true;
                 }
-            }
-
-            //主沟盖板吊装机处于待机位
-            if (identifier.equals(TAG6)) {
-                if ("0".equals(data)) {
-                    ironOperate.setZggbdj("0");
-                } else {
-                    ironOperate.setZggbdj("1");
+                //子项
+                if (foundFalsePass) {
+                    child.setPassResult(0);
                 }
             }
+            //父项
+            validateStepPass(stepDTO);
+            //父项
+            if (foundFalsePass) {
+                stepDTO.setPassResult(0);
+            }
+        }
+    }
 
-            //外围条件
-            if ("1".equals(ironOperate.getSzbykq())
-                    && "1".equals(ironOperate.getCtmskq())
-                    && "1".equals(ironOperate.getZggbdj())
-            ) {
-                ironOperate.setWwtj("1");
-            } else {
-                log.info("wwtj failed => szbykq:{},ctmskq:{},zggbdj:{}", ironOperate.getSzbykq(), ironOperate.getCtmskq(), ironOperate.getZggbdj());
-
-                ironOperate.setWwtj("0");
-
-                ironOperate.setLqsqct("0");
-
-                ironOperate.setGlyxqk("0");
-                ironOperate.setTlcjs("0");
-                ironOperate.setCtfs("0");
-                ironOperate.setLncttj("0");
-
-                ironOperate.setYpqrct("0");
-
-                ironOperate.setLqctcz("0");
-
-                PushData.send2Operation(ironOperate, socketIOClient);
 
-                return;
+    private void ironReady() {
+        if (ObjectUtils.isEmpty(mOPCData)) {
+            return;
+        }
+        //通过“预判和确认出铁”标记开始出铁
+        boolean isReady = false;
 
+        for (IronStepVO stepDTO : mSteps) {
+            if (ypqrct.equalsIgnoreCase(stepDTO.getIdentifier()) && 1 == stepDTO.getPassResult()) {
+                isReady = true;
+                break;
             }
+        }
 
-            if ("0".equals(ironOperate.getLqsqct())) {
-                ironOperate.setGlyxqk("0");
-                ironOperate.setTlcjs("0");
-                ironOperate.setCtfs("0");
-                ironOperate.setLncttj("0");
+        //炉前在接受到炉内出铁要求后,10分钟内打开铁口,未打开系统告警并记录
+        if (isReady) {
+            TimerTask task = new TimerTask() {
+                @Override
+                public void run() {
+                    System.out.println("倒计时结束!10分钟已到。");
+                    timer.cancel(); // 终止定时器
+                    // 打开系统告警并记录
+                    PushData.send2Warn("warn");
+                    log.info("准备出铁但是未及时出铁口,此处数据库记录");
+                }
+            };
 
-                ironOperate.setYpqrct("0");
+            // 倒计时10分钟(600秒)
+            long delay = 10 * 60 * 1000; // 10分钟转换为毫秒
+            // 在指定延迟后执行任务
+            timer.schedule(task, delay);
+        }
 
-                ironOperate.setLqctcz("0");
+        //根据PLC订阅的数据,AOD25606.PV=1为出铁中,AOD25606.PV=0出铁结束的信号,进行判断
+        //为1表示开始出铁,此时如果未超过10分钟,就取消定时器
+        //出铁结束
+        if (mOPCData.getPointName().contains(TAG_TAPHOLE1_STATUS)) {
+            //1:出铁中
+            //0:出铁结束
+            ironLoading1 = "1".equals(mOPCData.getData());
 
-                PushData.send2Operation(ironOperate, socketIOClient);
-                return;
-            }
+            if ("1".equals(mOPCData.getData())) {
+                //由 0 -> 1
+                //表明1号铁口正在出铁
+                //根据理论铁量、实时铁水流速,推测距离出铁结束的剩余时间
+                //剩余时间=总时间-已经流去的时间
+//                mContext.lookupVariable("");
+                //计算理论铁量= 矿批 × 综合品位 × 1.06,其中矿批是指L2中的干量
 
+//                Date ironTime = mOPCData.getServerTime();
+//                lastIronEndTimeRecently
 
-            //高炉运行情况
-            if (identifier.equals(TAG7)) {
-                if ("0".equals(data)) {
-                    ironOperate.setGlyxqk("0");
-                } else {
-                    ironOperate.setGlyxqk("1");
-                }
-            }
 
-            //理论铁量、铁铁差计算
-            if (identifier.equals(TAG8)) {
-                if ("0".equals(data)) {
-                    ironOperate.setTlcjs("0");
-                } else {
-                    ironOperate.setTlcjs("1");
+            } else if ("0".equals(mOPCData.getData())) {
+                //由 1-> 0
+                try {
+                    timer.cancel(); // 终止定时器
+                } catch (Exception e) {
+                    e.printStackTrace();
                 }
-            }
+                recordAfter();
+                recordBlock();
 
-            //出铁口模式
-            if (identifier.equals(TAG9)) {
-                if ("0".equals(data)) {
-                    ironOperate.setCtfs("0");
-                } else {
-                    ironOperate.setCtfs("1");
-                }
+                //出铁结束后,查询最近两次的数据
+                LambdaQueryWrapper<TIronData> queryWrapper = new QueryWrapper<TIronData>().lambda().orderByDesc(TIronData::getCtcsbh);
+                List<TIronData> oldIronDataList = ironDataService.list(queryWrapper);
             }
 
-            //炉内出铁条件
-            if ("1".equals(ironOperate.getLqsqct())
-                    && "1".equals(ironOperate.getGlyxqk())
-                    && "1".equals(ironOperate.getTlcjs())
-                    && "1".equals(ironOperate.getCtfs())
-            ) {
-                ironOperate.setLqsqct(ironOperate.getLqsqct());
-                ironOperate.setLncttj("1");
-            } else {
-                ironOperate.setLncttj("0");
-
-                log.info("lncttj failed => glyxqk:{},tlcjs:{},ctkms:{}", ironOperate.getGlyxqk(), ironOperate.getTlcjs(), ironOperate.getCtfs());
+        }
 
-                ironOperate.setYpqrct("0");
 
-                ironOperate.setLqctcz("0");
+        if (mOPCData.getPointName().contains(TAG_TAPHOLE1_STATUS)
+                || mOPCData.getPointName().contains(TAG_TAPHOLE2_STATUS)
+                || mOPCData.getPointName().contains(TAG_TAPHOLE3_STATUS)
+                || mOPCData.getPointName().contains(TAG_TAPHOLE4_STATUS)
+        ) {
+            lastIronEndTimeRecently = mOPCData.getServerTime();
+        }
 
-                PushData.send2Operation(ironOperate, socketIOClient);
-                return;
-            }
+    }
 
-            if ("1".equals(ironOperate.getYpqrct())) {
-                ironOperate.setLqctcz("1");
+    /***
+     * 判断是否通过
+     * @param stepVO
+     */
+    private void validateStepPass(IronStepVO stepVO) {
+        //根据唯一名称设置环境变量
+        mContext.setVariable(stepVO.getIdentifier(), stepVO.getData());
+        String flowName = "";
+        try {
+            if ("calc".equalsIgnoreCase(stepVO.getNodeType())) {
+                flowName = parser.parseExpression(stepVO.getStepNameExpression()).getValue(mContext, String.class);
             } else {
-                ironOperate.setLqctcz("0");
+                flowName = parser.parseExpression("'" + stepVO.getStepName() + "'").getValue(mContext, String.class);
             }
-
-            PushData.send2Operation(ironOperate, socketIOClient);
+            stepVO.setStepName(flowName);
+        } catch (Exception e) {
+            log.error("stepId:{},identifier:{},stepName:{}", stepVO.getStepId(), stepVO.getIdentifier(), flowName);
         }
 
-        //glyxqk 高炉运行情况
-        //tlcjs 理论铁量、铁铁差计算
-        //ctkms 出铁口模式
-
-        //趋势
-        if (Stream.of("TAG5", "TAG6", "TAG7", "TAG8").anyMatch(identifier::contains)) {
-            // PushData.sendToTrend(JSON.toJSONString(opcData));
-            //铁水成分
-            //铁水流速
-            //铁水流量
-            //铁水温度
+        //非流程必须项,直接放行
+        if ("0".equals(stepVO.getRequired())) {
+            stepVO.setPassResult(1);
+            return;
         }
 
-        //实时数据
-        if (Stream.of("TAG9", "TAG10").anyMatch(identifier::contains)) {
-//            PushData.sendToRealtime(JSON.toJSONString(opcData));
-            //除铁中
-            //
-            //
-            //
-            //
+        if (ObjectUtils.isNotEmpty(stepVO.getStepCondition())) {
+            boolean result = false;
+            try {
+                result = parser.parseExpression(stepVO.getStepCondition()).getValue(mContext, Boolean.class);
+            } catch (Exception e) {
+                result = false;
+            }
+            stepVO.setPassResult(result ? 1 : 0);
         }
-    }
-
-    private void operate3(OPCData opcData) {
-        String pointName = opcData.getPointName();
-        Object data = opcData.getData();
-
-        for (IronStepVO stepDTO : mSteps) {
-            //log.info("nodetype:{},pointname:{},opc pointname:{}",stepDTO.getNodeType(),stepDTO.getPointName(),pointName);
-            if ("node".equalsIgnoreCase(stepDTO.getNodeType())) {
-                //处理子项
-                for (IronStepVO child : stepDTO.getChilds()) {
-                    if (Objects.equals(child.getPointName(), pointName)) {
-                        //3.创建变量上下文,设置变量
-                        ctx.setVariable(child.getIdentifier(), data);
-                        child.setData(data);
-
-                        boolean result = false;
-
-                        if (ObjectUtils.isNotEmpty(child.getStepTj())) {
-                            try {
-                                result = parser.parseExpression(child.getStepTj()).getValue(ctx, Boolean.class);
-                            } catch (Exception e) {
-
-                            }
-                        }
 
-                        child.setPass(result);
+    }
 
-                        //log.info("pointName:{},data:{},tj:{},result:{}", pointName, data, child.getStepTj(), result);
-                    }
-                }
-                try {
-                    boolean result = false;
-                    if (ObjectUtils.isNotEmpty(stepDTO.getStepTj())) {
-                        try {
-                            result = parser.parseExpression(stepDTO.getStepTj()).getValue(ctx, Boolean.class);
-                        } catch (Exception e) {
+    //出铁后,记录炉次、开口时间、鱼雷罐车车号、铁口深度、铁水流速
+    private void recordAfter() {
+        ironAfterService.add(null);
+    }
 
-                        }
-                    }
-                    stepDTO.setPass(result);
-                } catch (Exception e) {
-                    stepDTO.setPass(false);
-                }
+    //堵口后,记录堵口时间、出铁量,打泥量、是否喷溅、是否跑泥
+    private void recordBlock() {
+        ironBlockService.add(null);
+    }
 
-            }
+    /***
+     * 用户端点击触发
+     * @param client
+     * @param message
+     */
+    @OnEvent(value = PushData.IRON_CONFIRM)
+    public void confirmIron(SocketIOClient client, IronStepDTO message) {
+        String userId;
+        if (ObjectUtils.isEmpty(client) || ObjectUtils.isEmpty(userId = SocketUtil.clientUserIds.get(client))) {
+            log.info("该客户已下线");
+            PushData.send2Operation("该客户已下线", false);
+            return;
         }
 
-        log.info("==========================================");
-        //log.info("steps before:{}", JSON.toJSONString(mSteps));
-        log.info("==========================================");
+        if (ObjectUtils.isEmpty(message)) {
+            log.info("请求数据为空");
+            PushData.send2Operation("请求数据为空", false);
+            return;
+        }
 
-        boolean foundFalsePass = false;
 
-        //发现第一个pass是false,后续的手动操作都为false,包括父项和子项
+        log.info("--->userId : {}", userId);
         for (IronStepVO stepDTO : mSteps) {
             for (IronStepVO child : stepDTO.getChilds()) {
-                if (!foundFalsePass && !child.isPass()) {
-                    foundFalsePass = true;
-                }
-                if (foundFalsePass) {
-                    child.setPass(false);
+                if (validateManualData(message, userId, child)) {
+                    return;
                 }
             }
-            if (foundFalsePass) {
-                stepDTO.setPass(false);
+            if (validateManualData(message, userId, stepDTO)) {
+                return;
             }
         }
+    }
 
-        log.info("==========================================");
-        log.info("steps after:{}", JSON.toJSONString(mSteps));
-        log.info("==========================================");
+    private boolean validateManualData(IronStepDTO message, String userId, IronStepVO stepDTO) {
+        if (Objects.equals(stepDTO.getStepId(), message.getStepId()) && Objects.equals(stepDTO.getIdentifier(), message.getIdentifier()) && Objects.equals("2", stepDTO.getConfirmMode())) {
+            stepDTO.setData(message.getData());
+            setStepResult(mSteps);
+            PushData.send2Operation(mSteps, ironLoading1);
+            //这里手动记录时间
+            log.info("userId:{},stepId:{},identifier:{},data:{},pass:{}", userId, message.getStepId(), message.getIdentifier(), message.getData(), message.isPass());
 
 
-        PushData.send2Operation(mSteps);
-    }
+            if (Objects.equals(message.getIdentifier(), CAR_STATUS)) {
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(message.getData());
+                realtimeData.setDesc("鱼雷罐车到位状态");
+                mRealtimeStatus.put(CAR_STATUS, realtimeData);
+            }
 
-    @OnEvent(value = PushData.IRON_CONFIRM)
-    public void confirmIron(SocketIOClient client, IronStepDTO message) {
-        if (ObjectUtils.isEmpty(message) || ObjectUtils.isEmpty(client)) {
-            return;
-        }
-        log.info("---> {}", SocketUtil.clientUserIds.get(client));
-        for (IronStepVO stepDTO : mSteps) {
-            for (IronStepVO child : stepDTO.getChilds()) {
-                if (child.getStepId().equals(message.getStepId())) {
-                    ctx.setVariable(child.getIdentifier(), message.getData());
-                    child.setPass(message.isPass());
-                    PushData.send2Operation(mSteps);
-                    return;
-                }
+            if (Objects.equals(message.getIdentifier(), GUN_STATUS)) {
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(message.getData());
+                realtimeData.setDesc("拔炮状态");
+                mRealtimeStatus.put(GUN_STATUS, realtimeData);
+            }
+
+
+            if (Objects.equals(message.getIdentifier(), MOUTH_STATUS)) {
+                RealtimeData realtimeData = new RealtimeData();
+                realtimeData.setValue(message.getData());
+                realtimeData.setDesc("摆动溜嘴状态");
+                mRealtimeStatus.put(MOUTH_STATUS, realtimeData);
             }
+
+            PushData.send2RealtimeStatus(mRealtimeStatus);
+
+            return true;
         }
+        return false;
     }
 
 
     /***
      * 数据库更改后调用接口刷新步骤
-     * @param steps
      */
     @Subscribe
-    public void onIronStep(List<IronStepVO> steps) {
-        if (ObjectUtils.isNotEmpty(steps)) {
-            this.mSteps = steps;
+    public void onIronStep(Boolean refresh) {
+        if (ObjectUtils.isNotEmpty(refresh) && refresh) {
+            mSteps = ironStepService.getTreeSteps();
+            log.info("流程步骤数据刷新:{}", LocalDateTime.now());
         }
     }
 
 
-//    @OnEvent(value = PushData.IRON_CONFIRM)
-//    public void confirmIron(SocketIOClient client, IronOperataion message) {
-//        if (ObjectUtils.isEmpty(message) || ObjectUtils.isEmpty(client)) {
-//            return;
-//        }
-//        log.info("---> {}", SocketUtil.clientUserIds.get(client));
-//        log.info("人员到位(rydw):{},{}", message.getUserId(), message.getRydw());
-//        log.info("炉前申请出铁(rydw):{},{}", message.getUserId(), message.getLqsqct());
-//        log.info("预判和确认出铁(rydw):{},{}", message.getUserId(), message.getYpqrct());
-//        IronOperataion ironOperataion = operateMap2.get(client);
-//        if (ObjectUtils.isNotEmpty(ironOperataion)) {
-//            if (ObjectUtils.isNotEmpty(message.getRydw())) {
-//                ironOperataion.setRydw(message.getRydw());
-//            }
-//            if (ObjectUtils.isNotEmpty(message.getLqsqct())) {
-//                ironOperataion.setLqsqct(message.getLqsqct());
-//            }
-//            if (ObjectUtils.isNotEmpty(message.getYpqrct())) {
-//                ironOperataion.setYpqrct(message.getYpqrct());
-//            }
-//            PushData.send2Operation(ironOperataion, client);
-//        } else {
-//            log.info("失效的会话");
-//        }
-//
-//    }
-
-
 }

+ 77 - 0
taphole-iron/src/main/java/com/sckj/iron/socketio/IronRealtimeListener.java

@@ -0,0 +1,77 @@
+package com.sckj.iron.socketio;
+
+import com.google.common.eventbus.Subscribe;
+import com.sckj.common.eventbus.EventListener;
+import com.sckj.common.socketio.SocketUtil;
+import com.sckj.iron.service.impl.TIronStepServiceImpl;
+import com.sckj.opc.entity.OPCData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @Author feng
+ * @Date 2024-11-19 上午 11:05
+ * @Description 实时数据推送
+ */
+@Component
+@Slf4j
+public class IronRealtimeListener extends EventListener {
+
+    @Resource
+    TIronStepServiceImpl ironStepService;
+
+
+
+    @Subscribe
+    public void onMessageEvent(OPCData opcData) {
+        if (SocketUtil.clientUserIds.isEmpty()) {
+            return;
+        }
+        realtime(opcData);
+    }
+
+    private Map<String,Object> mRealtimeMap = new ConcurrentHashMap<>();
+
+     {
+         //流速
+         mRealtimeMap.put("speed",0);
+         //流量
+         mRealtimeMap.put("flow",0);
+         //温度
+         mRealtimeMap.put("temp",0);
+         //成分
+         mRealtimeMap.put("element",0);
+
+         //开口或堵口  AOD25606.PV=0
+         //出铁时及拔炮 AOD25606.PV=1
+         //鱼雷罐车到位
+         //溜咀摆动
+         //冲渣启动           渣流量(L1)>0 下渣;渣流量(L1)= 0 下渣
+
+    }
+
+    /***
+     * 铁水成分
+     * 铁水流速
+     * 铁水流量
+     * 铁水温度
+     * @param opcData
+     */
+    private void realtime(OPCData opcData) {
+        String pointName = opcData.getPointName();
+        Object data = opcData.getData();
+
+        PushData.send2RealtimeData("");
+    }
+
+
+
+
+
+
+
+}

+ 56 - 0
taphole-iron/src/main/java/com/sckj/iron/socketio/IronTrendListener.java

@@ -0,0 +1,56 @@
+package com.sckj.iron.socketio;
+
+import com.google.common.eventbus.Subscribe;
+import com.sckj.common.eventbus.EventListener;
+import com.sckj.common.socketio.SocketUtil;
+import com.sckj.iron.service.impl.TIronStepServiceImpl;
+import com.sckj.opc.entity.OPCData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @Author feng
+ * @Date 2024-11-19 上午 11:05
+ * @Description 趋势数据推送
+ */
+@Component
+@Slf4j
+public class IronTrendListener extends EventListener {
+
+    @Resource
+    TIronStepServiceImpl ironStepService;
+
+
+
+    @Subscribe
+    public void onMessageEvent(OPCData opcData) {
+        if (SocketUtil.clientUserIds.isEmpty()) {
+            return;
+        }
+        trend(opcData);
+    }
+
+
+    /***
+     * 铁水成分
+     * 铁水流速
+     * 铁水流量
+     * 铁水温度
+     * @param opcData
+     */
+    private void trend(OPCData opcData) {
+        String pointName = opcData.getPointName();
+        Object data = opcData.getData();
+
+        PushData.send2Trend("");
+    }
+
+
+
+
+
+
+
+}

+ 57 - 14
taphole-iron/src/main/java/com/sckj/iron/socketio/PushData.java

@@ -1,6 +1,7 @@
 package com.sckj.iron.socketio;
 
 import com.corundumstudio.socketio.SocketIOClient;
+import com.sckj.common.core.AjaxResult;
 import com.sckj.common.socketio.SocketUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
@@ -29,13 +30,25 @@ public class PushData {
     /**
      * 实时数据
      **/
-    public static final String IRON_REALTIME = "IRON_REALTIME";
+    public static final String IRON_REALTIME_DATA = "IRON_REALTIME_DATA";
+    /**
+     * 实时数据
+     **/
+    public static final String IRON_REALTIME_STATUS = "IRON_REALTIME_STATUS";
 
     /***
-     * 人员到位、炉前确认出铁、预判和确认出铁
+     * 一、炉前准备:铁摆系统正常、泥炮开口机准备完毕、人员到位
+     * 二、炉前申请出铁
+     * 三、炉内出铁条件:高炉运行情况
+     * 四、预判和确认出铁
      */
     public static final String IRON_CONFIRM = "IRON_CONFIRM";
 
+    /***
+     * 发出预警
+     */
+    public static final String IRON_WARN = "IRON_WARN";
+
 
     /**
      * 出铁操作
@@ -48,7 +61,7 @@ public class PushData {
             return;
         }
         //单独发消息
-        socketClient.sendEvent(PushData.IRON_OPERATION, message);
+        socketClient.sendEvent(PushData.IRON_OPERATION, AjaxResult.success(message));
     }
     /**
      * 出铁操作
@@ -62,66 +75,96 @@ public class PushData {
         }
         if (ObjectUtils.isEmpty(userId)) {
             for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
-                entry.getValue().sendEvent(PushData.IRON_OPERATION, message);
+                entry.getValue().sendEvent(PushData.IRON_OPERATION, AjaxResult.success(message));
             }
         } else {
             //某个客户端信息
             SocketIOClient socketClient = SocketUtil.getSocketClient(userId);
             if (Objects.nonNull(socketClient)) {
                 //单独给他发消息
-                socketClient.sendEvent(PushData.IRON_OPERATION, message);
+                socketClient.sendEvent(PushData.IRON_OPERATION, AjaxResult.success(message));
             } else {
                 log.info(userId + "已下线,暂不发送消息。");
             }
         }
     }
 
+    /***
+     * 出铁操作
+     * @param message 发送的消息内容
+     * @param isStopSendMsg  是否停止发送信息
+     */
+    public static void send2Operation(Object message,boolean isStopSendMsg) {
+        if (SocketUtil.connectMap.isEmpty() || isStopSendMsg) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.IRON_OPERATION, AjaxResult.success(message));
+        }
+    }
+
+
     /**
      * 趋势
      *
      * @return
      * @Param
      **/
-    public static void send2Operation(Object message) {
+    public static void send2Trend(Object message) {
         if (SocketUtil.connectMap.isEmpty()) {
             return;
         }
         //
         for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
-            entry.getValue().sendEvent(PushData.IRON_OPERATION, message);
+            entry.getValue().sendEvent(PushData.IRON_TREND, AjaxResult.success(message));
         }
     }
 
-
     /**
-     * 趋势
+     * 实时数据
      *
      * @return
      * @Param
      **/
-    public static void send2Trend(Object message) {
+    public static void send2RealtimeData(Object message) {
         if (SocketUtil.connectMap.isEmpty()) {
             return;
         }
         //
         for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
-            entry.getValue().sendEvent(PushData.IRON_TREND, message);
+            entry.getValue().sendEvent(PushData.IRON_REALTIME_DATA, AjaxResult.success(message));
         }
     }
-
     /**
      * 实时数据
      *
      * @return
      * @Param
      **/
-    public static void send2Realtime(Object message) {
+    public static void send2RealtimeStatus(Object message) {
+        if (SocketUtil.connectMap.isEmpty()) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.IRON_REALTIME_STATUS, AjaxResult.success(message));
+        }
+    }
+
+    /**
+     * 发出预警
+     *
+     * @return
+     * @Param
+     **/
+    public static void send2Warn(Object message) {
         if (SocketUtil.connectMap.isEmpty()) {
             return;
         }
         //
         for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
-            entry.getValue().sendEvent(PushData.IRON_REALTIME, message);
+            entry.getValue().sendEvent(PushData.IRON_WARN, AjaxResult.success(message));
         }
     }
 

+ 39 - 0
taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchScreenValidate.java

@@ -0,0 +1,39 @@
+package com.sckj.iron.validate;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel("出铁数据搜素参数")
+public class TIronDataSearchScreenValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "锅炉编号")
+    private Long boilerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
+
+    @ApiModelProperty(value = "出铁次数编号")
+    private String ironNo;
+
+    @ApiModelProperty(value = "出铁时间")
+    private String ironCosttime;
+
+    @ApiModelProperty(value = "实际出铁量")
+    private double ironWeight;
+
+    @ApiModelProperty(value = "实际渣量")
+    private String slagWeight;
+
+    @ApiModelProperty(value = "开始时间")
+    private String ironStarttime;
+
+    @ApiModelProperty(value = "结束时间")
+    private String ironEndtime;
+
+}

+ 28 - 16
taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchValidate.java

@@ -13,31 +13,43 @@ public class TIronDataSearchValidate implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "铁口编号")
-    private Integer tkbh;
+    @ApiModelProperty(value = "锅炉编号")
+    private Long boilerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
 
     @ApiModelProperty(value = "出铁次数编号")
-    private Integer ctcsbh;
+    private String ironNo;
 
     @ApiModelProperty(value = "出铁时间")
-    private String ctsj;
+    private String ironCosttime;
+
+    @ApiModelProperty(value = "实际出铁量")
+    private double ironWeight;
+
+    @ApiModelProperty(value = "实际渣量")
+    private String slagWeight;
+
+    @ApiModelProperty(value = "铁水平均温度")
+    private String avgTemp;
 
-    @ApiModelProperty(value = "出铁量")
-    private String ctl;
+    @ApiModelProperty(value = "泥炮量")
+    private String mudWeight;
 
-    @ApiModelProperty(value = "渣量")
-    private String zl;
+    @ApiModelProperty(value = "钻杆直径")
+    private String pollMm;
 
-    @ApiModelProperty(value = "危害程度")
-    private String whcd;
+    @ApiModelProperty(value = "开口深度")
+    private String openDepth;
 
-    @ApiModelProperty(value = "设备区域")
-    private String sbqy;
+    @ApiModelProperty(value = "上料总干量")
+    private double totalDry;
 
-    @ApiModelProperty(value = "时间")
-    private String sj;
+    @ApiModelProperty(value = "开始时间")
+    private String ironStarttime;
 
-    @ApiModelProperty(value = "次数")
-    private String cs;
+    @ApiModelProperty(value = "结束时间")
+    private String ironEndtime;
 
 }

+ 23 - 15
taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamCreateValidate.java

@@ -19,19 +19,27 @@ public class TIronParamCreateValidate implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "开口耗时(s)")
-    private BigDecimal kkhs;
-
-    @ApiModelProperty(value = "出铁时间(s)")
-    private BigDecimal ctsj;
-
-    @ApiModelProperty(value = "出铁量(t)")
-    private BigDecimal ctl;
-
-    @ApiModelProperty(value = "出铁流速(t/s)")
-    private BigDecimal ctls;
-
-    @ApiModelProperty(value = "铁水温度变化(℃/s)")
-    private BigDecimal tswdbh;
-
+//    @ApiModelProperty(value = "开口耗时(s)")
+//    private BigDecimal kkhs;
+//
+//    @ApiModelProperty(value = "出铁时间(s)")
+//    private BigDecimal ctsj;
+//
+//    @ApiModelProperty(value = "出铁量(t)")
+//    private BigDecimal ctl;
+//
+//    @ApiModelProperty(value = "出铁流速(t/s)")
+//    private BigDecimal ctls;
+//
+//    @ApiModelProperty(value = "铁水温度变化(℃/s)")
+//    private BigDecimal tswdbh;
+
+    @ApiModelProperty(value = "参数类型")
+    private String paramType;
+
+    @ApiModelProperty(value = "参数名称")
+    private String paramName;
+
+    @ApiModelProperty(value = "参数值")
+    private String paramValue;
 }

+ 15 - 6
taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamSearchValidate.java

@@ -18,13 +18,22 @@ public class TIronParamSearchValidate implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "开口耗时(s)")
-    private BigDecimal kkhs;
+//    @ApiModelProperty(value = "开口耗时(s)")
+//    private BigDecimal kkhs;
+//
+//    @ApiModelProperty(value = "出铁时间(s)")
+//    private BigDecimal ctsj;
+//
+//    @ApiModelProperty(value = "出铁量(t)")
+//    private BigDecimal ctl;
 
-    @ApiModelProperty(value = "出铁时间(s)")
-    private BigDecimal ctsj;
+    @ApiModelProperty(value = "参数类型")
+    private String paramType;
 
-    @ApiModelProperty(value = "出铁量(t)")
-    private BigDecimal ctl;
+    @ApiModelProperty(value = "参数名称")
+    private String paramName;
+
+    @ApiModelProperty(value = "参数值")
+    private String paramValue;
 
 }

+ 23 - 14
taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamUpdateValidate.java

@@ -21,19 +21,28 @@ public class TIronParamUpdateValidate implements Serializable {
     @ApiModelProperty(value = "主键id")
     private Long id;
 
-    @ApiModelProperty(value = "开口耗时(s)")
-    private BigDecimal kkhs;
-
-    @ApiModelProperty(value = "出铁时间(s)")
-    private BigDecimal ctsj;
-
-    @ApiModelProperty(value = "出铁量(t)")
-    private BigDecimal ctl;
-
-    @ApiModelProperty(value = "出铁流速(t/s)")
-    private BigDecimal ctls;
-
-    @ApiModelProperty(value = "铁水温度变化(℃/s)")
-    private BigDecimal tswdbh;
+//    @ApiModelProperty(value = "开口耗时(s)")
+//    private BigDecimal kkhs;
+//
+//    @ApiModelProperty(value = "出铁时间(s)")
+//    private BigDecimal ctsj;
+//
+//    @ApiModelProperty(value = "出铁量(t)")
+//    private BigDecimal ctl;
+//
+//    @ApiModelProperty(value = "出铁流速(t/s)")
+//    private BigDecimal ctls;
+//
+//    @ApiModelProperty(value = "铁水温度变化(℃/s)")
+//    private BigDecimal tswdbh;
+
+    @ApiModelProperty(value = "参数类型")
+    private String paramType;
+
+    @ApiModelProperty(value = "参数名称")
+    private String paramName;
+
+    @ApiModelProperty(value = "参数值")
+    private String paramValue;
 
 }

+ 31 - 0
taphole-iron/src/main/java/com/sckj/iron/vo/IronRealTimeVO.java

@@ -0,0 +1,31 @@
+package com.sckj.iron.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @Author feng
+ * @Date 2024-11-21 上午 11:32
+ * @Description 实时状态数据
+ */
+@Data
+public class IronRealTimeVO {
+
+    @ApiModelProperty(value = "出铁状态")
+    private String AOD25606;
+
+    @ApiModelProperty(value = "鱼雷罐车到位信号")
+    private String ylgcOK;
+
+    @ApiModelProperty(value = "摆动溜咀")
+    private String bdlz;
+
+    @ApiModelProperty(value = "出渣中状态")
+    private String czzt;
+
+
+
+
+
+
+}

+ 39 - 5
taphole-iron/src/main/java/com/sckj/iron/vo/IronStepVO.java

@@ -3,7 +3,9 @@ package com.sckj.iron.vo;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @Author feng
@@ -13,13 +15,16 @@ import java.util.List;
 @Data
 public class IronStepVO {
 
+    @ApiModelProperty(value = "出铁次数编号")
+    private String ironNum;
+
     @ApiModelProperty(value = "stepId")
     private String stepId;
 
-    @ApiModelProperty(value = "步骤名称")
+    @ApiModelProperty(value = "步骤名称(包含公式)")
     private String stepName;
 
-    @ApiModelProperty(value = "唯一名称")
+    @ApiModelProperty(value = "步骤的唯一标识")
     private String identifier;
 
     @ApiModelProperty(value = "节点类型(start、end、node、child)")
@@ -29,10 +34,11 @@ public class IronStepVO {
     private String pointName;
 
     @ApiModelProperty(value = "通过条件")
-    private String stepTj;
+    private String stepCondition;
 
-    @ApiModelProperty(value = "是否通过(1是 0否)")
-    private boolean pass;
+    //
+    @ApiModelProperty(value = "通过结果(1通过、0未通过)")
+    private int passResult;
 
     @ApiModelProperty(value = "确认方式(1自动 2手动)")
     private String confirmMode;
@@ -40,6 +46,34 @@ public class IronStepVO {
     @ApiModelProperty(value = "数据")
     private Object data;
 
+    @ApiModelProperty(value = "流程是否必须项(0否 1是)")
+    private String required;
+
+    @ApiModelProperty(value = "步骤名称表达式")
+    private String stepNameExpression;
+
+    public IronStepVO() {
+        this.childs = new ArrayList<>();
+    }
+
+    public void addChilds(IronStepVO child) {
+        this.childs.add(child);
+    }
+
     private List<IronStepVO> childs;
 
+    private Map<String,Object>[] extraInfo;
+
+    public void setPass(){
+        this.passResult = 1;
+    }
+
+    public void setNotPass(){
+        this.passResult = 0;
+    }
+
+    public boolean ispass(){
+        return 1 == passResult;
+    }
+
 }

+ 49 - 0
taphole-iron/src/main/java/com/sckj/iron/vo/IronTrendVO.java

@@ -0,0 +1,49 @@
+package com.sckj.iron.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @Author feng
+ * @Date 2024-11-21 上午 11:32
+ * @Description 铁水温度趋势
+ */
+@Data
+public class IronTrendVO {
+
+    @ApiModelProperty(value = "出铁次数编号")
+    private String ironNum;
+
+    @ApiModelProperty(value = "stepId")
+    private String stepId;
+
+    @ApiModelProperty(value = "步骤名称")
+    private String stepName;
+
+    @ApiModelProperty(value = "步骤的唯一标识")
+    private String identifier;
+
+    @ApiModelProperty(value = "节点类型(start、end、node、child)")
+    private String nodeType;
+
+    @ApiModelProperty(value = "订阅点名称(通道.设备.标识)")
+    private String pointName;
+
+    @ApiModelProperty(value = "通过条件")
+    private String stepCondition;
+
+    //
+    @ApiModelProperty(value = "通过结果(1通过、0未通过)")
+    private int passResult;
+
+    @ApiModelProperty(value = "确认方式(1自动 2手动)")
+    private String confirmMode;
+
+    @ApiModelProperty(value = "数据")
+    private Object data;
+
+
+
+}

+ 44 - 0
taphole-iron/src/main/java/com/sckj/iron/vo/TIronDataVo.java

@@ -0,0 +1,44 @@
+package com.sckj.iron.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ApiModel("出铁数据实体")
+public class TIronDataVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value="id", type= IdType.AUTO)
+    @ApiModelProperty(value = "")
+    private Long id;
+
+    @ApiModelProperty(value = "铁口编号")
+    private Integer tkbh;
+
+    @ApiModelProperty(value = "出铁次数编号")
+    private Integer ctcsbh;
+
+    @ApiModelProperty(value = "出铁时间")
+    private String ctsj;
+
+    @ApiModelProperty(value = "出铁量")
+    private String ctl;
+
+    @ApiModelProperty(value = "渣量")
+    private String zl;
+
+    @ApiModelProperty(value = "危害程度")
+    private String whcd;
+
+    @ApiModelProperty(value = "时间")
+    private String sj;
+
+}

+ 136 - 0
taphole-opc/src/main/java/com/sckj/opc/dto/L2Data.java

@@ -0,0 +1,136 @@
+package com.sckj.opc.dto;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Author feng
+ * @Date 2024-12-18 上午 09:47
+ * @Description TODO
+ */
+@Data
+public class L2Data implements Serializable {
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private String tapholeId;
+
+    @ApiModelProperty(value = "出铁次数编号")
+    private String ironNo;
+
+    @ApiModelProperty(value = "出铁时间")
+    private String ironCosttime;
+
+    @ApiModelProperty(value = "实际出铁量")
+    private String ironWeight;
+
+    @ApiModelProperty(value = "实际渣量")
+    private String slagWeight;
+
+    @ApiModelProperty(value = "铁水平均温度")
+    private String avgTemp;
+
+    @ApiModelProperty(value = "泥炮量")
+    private String mudWeight;
+
+    @ApiModelProperty(value = "钻杆直径")
+    private String pollMm;
+
+    @ApiModelProperty(value = "开口深度")
+    private String openDepth;
+
+    @ApiModelProperty(value = "上料总干量")
+    private String totalDry;
+
+    @ApiModelProperty(value = "开始时间")
+    private String ironStarttime;
+
+    @ApiModelProperty(value = "结束时间")
+    private String ironEndtime;
+
+    //铁水成分 碳
+    private String elementC;
+
+    //铁水成分 硅
+    private String elementSi;
+
+    //铁水成分 锰
+    private String elementMn;
+
+    //铁水成分 磷
+    private String elementP;
+
+    //铁水成分 硫
+    private String elementS;
+
+    //铁水成分 钛
+    private String elementTi;
+
+
+    public void toDataStream(DataOutputStream dos) throws Exception {
+        dos.writeUTF(tapholeId);
+        dos.writeUTF(ironNo);
+        dos.writeUTF(ironCosttime);
+        dos.writeUTF(ironWeight);
+        dos.writeUTF(slagWeight);
+        dos.writeUTF(avgTemp);
+        dos.writeUTF(mudWeight);
+        dos.writeUTF(pollMm);
+        dos.writeUTF(openDepth);
+        dos.writeUTF(totalDry);
+        dos.writeUTF(ironStarttime);
+        dos.writeUTF(ironEndtime);
+    }
+
+    public static L2Data fromDataStream(DataInputStream dis) throws Exception {
+        L2Data data = new L2Data();
+        data.tapholeId = dis.readUTF();
+        data.ironNo = dis.readUTF();
+        data.ironCosttime = dis.readUTF();
+        data.ironWeight = dis.readUTF();
+        data.slagWeight = dis.readUTF();
+        data.avgTemp = dis.readUTF();
+        data.mudWeight = dis.readUTF();
+        data.pollMm = dis.readUTF();
+        data.openDepth = dis.readUTF();
+        data.totalDry = dis.readUTF();
+        data.ironStarttime = dis.readUTF();
+        data.elementC = dis.readUTF();
+        data.elementSi = dis.readUTF();
+        data.elementMn = dis.readUTF();
+        data.elementP = dis.readUTF();
+        data.elementS = dis.readUTF();
+        data.elementTi = dis.readUTF();
+        return data;
+    }
+
+    @Override
+    public String toString() {
+        return "L2Data{" +
+                "tapholeId='" + tapholeId + '\'' +
+                ", ironNo='" + ironNo + '\'' +
+                ", ironCosttime='" + ironCosttime + '\'' +
+                ", ironWeight='" + ironWeight + '\'' +
+                ", slagWeight='" + slagWeight + '\'' +
+                ", avgTemp='" + avgTemp + '\'' +
+                ", mudWeight='" + mudWeight + '\'' +
+                ", pollMm='" + pollMm + '\'' +
+                ", openDepth='" + openDepth + '\'' +
+                ", totalDry='" + totalDry + '\'' +
+                ", ironStarttime='" + ironStarttime + '\'' +
+                ", ironEndtime='" + ironEndtime + '\'' +
+                ", elementC='" + elementC + '\'' +
+                ", elementSi='" + elementSi + '\'' +
+                ", elementMn='" + elementMn + '\'' +
+                ", elementP='" + elementP + '\'' +
+                ", elementS='" + elementS + '\'' +
+                ", elementTi='" + elementTi + '\'' +
+                '}';
+    }
+}

+ 12 - 9
taphole-opc/src/main/java/com/sckj/opc/entity/OPCPoint.java

@@ -25,20 +25,11 @@ public class OPCPoint {
     @ApiModelProperty(value = "所属opcserver")
     private Long opcServerId;
 
-//    @ApiModelProperty(value = "订阅点名称")
-//    private String identifier;
-//
-//    @ApiModelProperty(value = "订阅点说明")
-//    private String identifierDesc;
-
 
     @ApiModelProperty(value = "所属锅炉")
     private String boilerId;
 
 
-    @ApiModelProperty(value = "流程步骤")
-    private String stepId;
-
     @ApiModelProperty(value = "命名空间,默认为2")
     private Integer namespaceIndex;
 
@@ -52,4 +43,16 @@ public class OPCPoint {
     @ApiModelProperty(value = "订阅点说明")
     private String pointDesc;
 
+    @ApiModelProperty(value = "OPC协议,有:UA、DA")
+    private String opcProtocol;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "请求频率(秒)")
+    private int period;
+
 }

+ 9 - 4
taphole-opc/src/main/java/com/sckj/opc/entity/OPCServer.java

@@ -45,14 +45,19 @@ public class OPCServer {
     @ApiModelProperty(value = "IP地址")
     private String ip;
 
-
-
-
     @ApiModelProperty(value = "状态")
     private String status;
 
-
     @ApiModelProperty(value = "KEPServer的注册表ID")
     private String clsid;
 
+    @ApiModelProperty(value = "所属锅炉")
+    private String boilerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
 }

+ 139 - 0
taphole-opc/src/main/java/com/sckj/opc/opcua/L2DataServiceImpl.java

@@ -0,0 +1,139 @@
+package com.sckj.opc.opcua;
+
+import com.google.common.eventbus.AsyncEventBus;
+import com.sckj.opc.dto.L2Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * @Author feng
+ * @Date 2024-12-19 上午 11:42
+ * @Description TODO
+ */
+@Service
+@Slf4j
+public class L2DataServiceImpl {
+
+    @Autowired
+    private AsyncEventBus asyncEventBus;
+
+    @Resource(name = "taskExecutor")
+    ThreadPoolTaskExecutor taskExecutor;
+
+    @PostConstruct
+    private void init() {
+        taskExecutor.submit(this::initTCP);
+    }
+
+    /***
+     * L2数据源
+     */
+
+    private void initTCP() {
+        System.out.println("TCP start");
+
+        final String serverIP = "127.0.0.1"; // 服务端IP地址
+        final int serverPort = 8888; // 服务端端口号
+        final int maxRetries = 10; // 最大重试次数
+        final long retryInterval = 5000; // 重试间隔时间(毫秒)
+
+        Socket socket = null;
+        DataOutputStream dos;
+        DataInputStream dis;
+        int attempt = 0;
+
+        // 连接重试机制
+        while (attempt < maxRetries) {
+            try {
+                socket = new Socket(serverIP, serverPort);
+                System.out.println("Connected to server at " + serverIP + ":" + serverPort);
+                break;
+            } catch (UnknownHostException e) {
+                System.err.println("Unknown host: " + serverIP);
+                break;
+            } catch (IOException e) {
+                attempt++;
+                System.err.println("Attempt " + attempt + ": Connection failed. Retrying in " + retryInterval / 1000 + " seconds...");
+                try {
+                    Thread.sleep(retryInterval);
+                } catch (InterruptedException ie) {
+                    Thread.currentThread().interrupt();
+                    System.err.println("Thread interrupted while sleeping.");
+                    break;
+                }
+            }
+        }
+
+        if (socket == null) {
+            System.err.println("Failed to connect to server after " + maxRetries + " attempts.");
+            return;
+        }
+        try {
+            dos = new DataOutputStream(socket.getOutputStream());
+            dis = new DataInputStream(socket.getInputStream());
+            while (true) {
+                try {
+                    // 从输入流读取L2Data对象
+                    L2Data receivedData = L2Data.fromDataStream(dis);
+                    //出铁操作
+                    asyncEventBus.post(receivedData);
+                    System.out.println("Received L2Data from server: \n" + receivedData);
+                } catch (IOException e) {
+                    System.err.println("Connection lost. Attempting to reconnect...");
+                    socket.close();
+                    socket = null;
+                    attempt = 0;
+
+                    // 重新连接重试机制
+                    while (attempt < maxRetries) {
+                        try {
+                            socket = new Socket(serverIP, serverPort);
+                            System.out.println("Reconnected to server at " + serverIP + ":" + serverPort);
+                            dos = new DataOutputStream(socket.getOutputStream());
+                            dis = new DataInputStream(socket.getInputStream());
+                            break;
+                        } catch (UnknownHostException ex) {
+                            System.err.println("Unknown host: " + serverIP);
+                            break;
+                        } catch (IOException ex) {
+                            attempt++;
+                            System.err.println("Attempt " + attempt + ": Reconnection failed. Retrying in " + retryInterval / 1000 + " seconds...");
+                            try {
+                                Thread.sleep(retryInterval);
+                            } catch (InterruptedException ie) {
+                                Thread.currentThread().interrupt();
+                                System.err.println("Thread interrupted while sleeping.");
+                                break;
+                            }
+                        }
+                    }
+
+                    if (socket == null) {
+                        System.err.println("Failed to reconnect to server after " + maxRetries + " attempts.");
+                        return;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (socket != null && !socket.isClosed()) {
+                try {
+                    socket.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+}

+ 20 - 4
taphole-opc/src/main/java/com/sckj/opc/opcua/OPCDAServiceImpl.java

@@ -16,6 +16,7 @@ import org.openscada.opc.lib.common.ConnectionInformation;
 import org.openscada.opc.lib.common.NotConnectedException;
 import org.openscada.opc.lib.da.*;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 
@@ -63,6 +64,8 @@ public class OPCDAServiceImpl {
         ci.setPassword(opcServer.getPassword());           // 密码
         ci.setClsid(opcServer.getClsid()); //KEPServer的注册表ID
 
+        log.info("Create Server : {}", opcServer);
+
         log.info("availableProcessors:{}",Runtime.getRuntime().availableProcessors());
         // 启动服务
         final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
@@ -75,7 +78,6 @@ public class OPCDAServiceImpl {
 
 
     public Object createSubscription(OPCServer opcServer, OPCPoint opcPoint) {
-        final int PERIOD = 100 * 10;
         StringBuilder sb = new StringBuilder();
         if (ObjectUtils.isNotEmpty(opcPoint) && !mOPCDaPointsMap.containsKey(opcPoint.getId())) {
             Map<String, Object> pointChangedMap = new LinkedHashMap<>();
@@ -84,9 +86,23 @@ public class OPCDAServiceImpl {
                 public String call() {
                     try {
                         Server server = createServer(opcServer);
-                        AccessBase access = new SyncAccess(server, PERIOD);
-                        log.info("{} start subscribe",opcPoint.getPointName());
-                        access.addItem(opcPoint.getPointName(), (item, itemstate) -> {
+                        AccessBase access = new SyncAccess(server, opcPoint.getPeriod() * 1000);
+
+                        String newPointName = opcPoint.getPointName();
+
+                        if(ObjectUtils.isEmpty(newPointName)){
+                            return null;
+                        }
+
+                        if(newPointName.contains(".")){
+                            newPointName = "channel." + newPointName;
+                        }else{
+                            newPointName = "channel.device." + newPointName;
+                        }
+
+                        log.info("{} start subscribe",newPointName);
+
+                        access.addItem(newPointName, (item, itemstate) -> {
                             int errorCode = itemstate.getErrorCode();
                             String pointName = item.getId();
                             Calendar calendar = itemstate.getTimestamp();

+ 5 - 28
taphole-opc/src/main/java/com/sckj/opc/opcua/OPCUAServiceImpl.java

@@ -158,29 +158,6 @@ public class OPCUAServiceImpl {
                 }
         );
         //创建连接
-        //Thread.sleep(5*1000); // 线程休眠一下再返回对象,给创建过程一个时间。
-        opcUaClient.addFaultListener(new ServiceFaultListener() {
-            @Override
-            public void onServiceFault(ServiceFault serviceFault) {
-                log.info("Added ServiceFaultListener >> : {}", serviceFault.toString());
-//                if (serviceFault.getResponseHeader().getServiceResult().isBad()) {
-//                    opcUaClient.disconnect();
-//                }
-            }
-        });
-
-        opcUaClient.addSessionActivityListener(new SessionActivityListener() {
-            @Override
-            public void onSessionActive(UaSession session) {
-                log.info("onSessionActive: {}", JSON.toJSONString(session));
-            }
-
-            @Override
-            public void onSessionInactive(UaSession session) {
-                log.info("onSessionInactive: {}", JSON.toJSONString(session));
-            }
-        });
-
         opcUaClient.connect().get();
 
         mOPCUaClientMap.put(opcServer.getId(), opcUaClient);
@@ -216,11 +193,11 @@ public class OPCUAServiceImpl {
         for (OPCPoint opcPoint : opcPointList) {
             //创建监控的参数
             MonitoringParameters parameters = new MonitoringParameters(
-                    subscription.nextClientHandle(),
-                    1000.0,     // sampling interval
-                    null,       // filter, null means use default
-                    uint(10),   // queue size
-                    true        // discard oldest
+                    subscription.nextClientHandle(),// 客户端句柄
+                    1000.0,     // 采样间隔 sampling interval
+                    null,       // 过滤器filter, null means use default
+                    uint(10),   // 队列大小
+                    true        // 丢弃旧值
             );
             //创建订阅
             NodeId nodeId = new NodeId(opcPoint.getNamespaceIndex(), opcPoint.getPointName());

+ 1 - 0
taphole-opc/src/main/java/com/sckj/opc/service/OPCDataServiceImpl.java

@@ -14,4 +14,5 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class OPCDataServiceImpl extends ServiceImpl<OPCDataMapper, OPCData> {
+
 }

+ 6 - 3
taphole-warn/src/main/java/com/sckj/warn/entity/TExceptionLog.java

@@ -36,8 +36,8 @@ public class TExceptionLog implements Serializable {
     @ApiModelProperty(value = "异常类型(开口耗时、出铁时间、出铁量、流速、铁水温度变化)")
     private Integer exceptionType;
 
-    @ApiModelProperty(value = "异常区域(铁口区域,目前只有1号铁口区域)")
-    private String exceptionArea;
+//    @ApiModelProperty(value = "异常区域(铁口区域,目前只有1号铁口区域)")
+//    private String exceptionArea;
 
     @ApiModelProperty(value = "危害程度(轻微、中等、重度)")
     private String exceptionLevel;
@@ -46,6 +46,9 @@ public class TExceptionLog implements Serializable {
     private String reportedStatus;
 
     @ApiModelProperty(value = "锅炉编号")
-    private Integer glId;
+    private Integer boilerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private Integer tapholeId;
 
 }

+ 5 - 4
taphole-warn/src/main/java/com/sckj/warn/service/impl/TExceptionLogServiceImpl.java

@@ -119,10 +119,11 @@ public class TExceptionLogServiceImpl implements ITExceptionLogService {
         model.setCreateTime(new Date(System.currentTimeMillis()));//gg
         model.setUpdateTime(new Date(System.currentTimeMillis()));//gg
         model.setExceptionType(createValidate.getExceptionType());
-        model.setExceptionArea(createValidate.getExceptionArea());
+       // model.setExceptionArea(createValidate.getExceptionArea());
         model.setExceptionLevel(createValidate.getExceptionLevel());
         model.setReportedStatus(createValidate.getReportedStatus());
-        model.setGlId(createValidate.getGlId());
+        model.setBoilerId(createValidate.getBoilerId());
+        model.setTapholeId(createValidate.getTapholeId());
         tExceptionLogMapper.insert(model);
     }
 
@@ -193,9 +194,9 @@ public class TExceptionLogServiceImpl implements ITExceptionLogService {
         for (int i = 0; i < tExceptionLogList.size(); i++) {
             Row row = sheet.createRow(i + 1);
             TExceptionLog tExceptionLog = tExceptionLogList.get(i);
-            row.createCell(0).setCellValue(tExceptionLog.getGlId());
+            row.createCell(0).setCellValue(tExceptionLog.getBoilerId());
             row.createCell(1).setCellValue(tExceptionLog.getExceptionType());
-            row.createCell(2).setCellValue(tExceptionLog.getExceptionArea());
+            row.createCell(2).setCellValue(tExceptionLog.getTapholeId());
             row.createCell(3).setCellValue(tExceptionLog.getExceptionLevel());
             row.createCell(4).setCellValue(tExceptionLog.getReportedStatus().equals("0") ? "未上报" : "已上报");
             row.createCell(5).setCellValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(tExceptionLog.getCreateTime()));

+ 10 - 5
taphole-warn/src/main/java/com/sckj/warn/validate/TExceptionLogCreateValidate.java

@@ -21,9 +21,9 @@ public class TExceptionLogCreateValidate implements Serializable {
     @ApiModelProperty(value = "异常类型(开口耗时、出铁时间、出铁量、流速、铁水温度变化)")
     private Integer exceptionType;
 
-    @NotNull(message = "exceptionArea参数缺失")
-    @ApiModelProperty(value = "异常区域(铁口区域,目前只有1号铁口区域)")
-    private String exceptionArea;
+//    @NotNull(message = "exceptionArea参数缺失")
+//    @ApiModelProperty(value = "异常区域(铁口区域,目前只有1号铁口区域)")
+//    private String exceptionArea;
 
     @NotNull(message = "exceptionLevel参数缺失")
     @ApiModelProperty(value = "危害程度(轻微、中等、重度)")
@@ -33,8 +33,13 @@ public class TExceptionLogCreateValidate implements Serializable {
     @ApiModelProperty(value = "上报状态,将异常事件上报至视频以及 AI 融合系统(1是 0否)")
     private String reportedStatus;
 
-    @NotNull(message = "glId参数缺失")
+    @NotNull(message = "boilerId参数缺失")
     @ApiModelProperty(value = "锅炉编号")
-    private Integer glId;
+    private Integer boilerId;
+
+
+    @NotNull(message = "boilerId参数缺失")
+    @ApiModelProperty(value = "铁口区域编号")
+    private Integer tapholeId;
 
 }