Przeglądaj źródła

Merge remote-tracking branch 'origin/likeadmin' into likeadmin

# Conflicts:
#	taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java
zhanghao 2 miesięcy temu
rodzic
commit
b60c3a0be7
45 zmienionych plików z 1529 dodań i 853 usunięć
  1. 10 0
      taphole-admin/pom.xml
  2. 19 12
      taphole-admin/src/main/resources/application-test.yml
  3. 5 0
      taphole-admin/src/main/resources/log4j2-spring.xml
  4. 0 13
      taphole-camera/src/main/java/com.sckj.camera/model/bo/CameraBO.java
  5. 0 24
      taphole-camera/src/main/java/com.sckj.camera/service/CameraServiceImpl.java
  6. 7 4
      taphole-camera/src/main/java/com.sckj.camera/util/LocalDateUtils.java
  7. 31 0
      taphole-common/src/main/java/com/sckj/common/manager/ScheduledTaskManager.java
  8. 14 1
      taphole-common/src/main/java/com/sckj/common/util/RedisUtils.java
  9. 4 0
      taphole-common/src/main/java/com/sckj/common/util/TimeUtils.java
  10. 4 0
      taphole-device/pom.xml
  11. 8 8
      taphole-device/src/main/java/com/sckj/device/controller/TCameraController.java
  12. 6 0
      taphole-device/src/main/java/com/sckj/device/entity/TCamera.java
  13. 0 71
      taphole-device/src/main/java/com/sckj/device/service/ITCameraService.java
  14. 111 38
      taphole-device/src/main/java/com/sckj/device/service/impl/TCameraServiceImpl.java
  15. 32 0
      taphole-device/src/main/java/com/sckj/device/validate/TCameraUpdateDTO.java
  16. 21 0
      taphole-device/src/main/java/com/sckj/device/vo/CameraDTO.java
  17. 5 1
      taphole-iron/pom.xml
  18. 1 13
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronDataController.java
  19. 46 7
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronParamController.java
  20. 49 63
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronVisualScreenController.java
  21. 0 9
      taphole-iron/src/main/java/com/sckj/iron/dto/CameraDTO.java
  22. 33 0
      taphole-iron/src/main/java/com/sckj/iron/dto/IronParamDTO.java
  23. 0 23
      taphole-iron/src/main/java/com/sckj/iron/dto/TrendData.java
  24. 44 0
      taphole-iron/src/main/java/com/sckj/iron/dto/WarnData.java
  25. 59 0
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java
  26. 10 16
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronParam.java
  27. 15 1
      taphole-iron/src/main/java/com/sckj/iron/entity/TL2Data.java
  28. 85 0
      taphole-iron/src/main/java/com/sckj/iron/entity/TL2Material.java
  29. 13 0
      taphole-iron/src/main/java/com/sckj/iron/mapper/TL2MaterialMapper.java
  30. 39 26
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronDataServiceImpl.java
  31. 59 21
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronParamServiceImpl.java
  32. 0 11
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TL2DataServiceImpl.java
  33. 38 0
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TL2MaterialServiceImpl.java
  34. 470 341
      taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java
  35. 0 56
      taphole-iron/src/main/java/com/sckj/iron/socketio/IronTrendListener.java
  36. 98 5
      taphole-iron/src/main/java/com/sckj/iron/socketio/PushData.java
  37. 0 15
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamUpdateValidate.java
  38. 16 10
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamDetailVo.java
  39. 16 10
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamListedVo.java
  40. 7 0
      taphole-opc/src/main/java/com/sckj/opc/dto/L2Data.java
  41. 57 0
      taphole-opc/src/main/java/com/sckj/opc/dto/L2Material.java
  42. 13 4
      taphole-opc/src/main/java/com/sckj/opc/opcua/L2DataServiceImpl.java
  43. 69 48
      taphole-opc/src/main/java/com/sckj/opc/opcua/OPCDAServiceImpl.java
  44. 11 1
      taphole-opc/src/main/java/com/sckj/opc/utils/CustomUtil.java
  45. 4 1
      taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogListedVo.java

+ 10 - 0
taphole-admin/pom.xml

@@ -73,6 +73,16 @@
             <groupId>com.sckj</groupId>
             <artifactId>taphole-opc</artifactId>
         </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-actuator</artifactId>-->
+<!--            <exclusions>-->
+<!--                <exclusion>-->
+<!--                    <artifactId>log4j-to-slf4j</artifactId>-->
+<!--                    <groupId>org.apache.logging.log4j</groupId>-->
+<!--                </exclusion>-->
+<!--            </exclusions>-->
+<!--        </dependency>-->
 
         <!--<dependency>-->
             <!--<groupId>org.springframework.boot</groupId>-->

+ 19 - 12
taphole-admin/src/main/resources/application-test.yml

@@ -1,41 +1,48 @@
 # 项目配置
 like:
-  upload-directory: /home/xiaofei/uploads/taphole/ # 上传目录
+  upload-directory: D:/opt/camera/
 
 # 服务配置
 server:
-  port: 8080
+  port: 28080
   servlet:
     context-path: /
+
 # 框架配置
 spring:
   # 数据源配置
   datasource:
-    url: jdbc:mysql://mysql:3306/taphole?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
+    url: jdbc:mysql://192.168.110.130:13306/taphole?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
     type: com.alibaba.druid.pool.DruidDataSource # 数据源类型
     driver-class-name: com.mysql.jdbc.Driver # MySql的驱动
     username: root # 数据库账号
     password: root # 数据库密码
   # Redis配置
   redis:
-    host: redis   # Redis服务地址
-    port: 6379        # Redis端口
-#    password: sckj@1234        # Redis密码
-#    database: 5       # 数据库索引
+    host: 192.168.110.130   # Redis服务地址
+    port: 16379        # Redis端口
+    password:         # Redis密码
+    database: 5       # 数据库索引
+#    lettuce:
+#      pool:
+#        max-wait: 30000 # 连接池最大阻塞等待时间(使用负数表示没有限制,默认-1)
+#        max-active: 100 # 连接池最大连接数(使用负数表示没有限制,默认8)
+#        max-idle: 20    # 连接池中的最大空闲连接(默认8)
+#        min-idle: 0     # 连接池中的最小空闲连接(默认0)
 
 # Mybatis-plus配置 【是否开启SQL日志输出】
 #mybatis-plus:
 #    configuration:
 #      log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 camera:
-  filepath: /home/xiaofei/uploads/taphole/
+  filepath: D:/opt/camera
   rtmp:
-    rtmphost: 172.28.1.10:1935
-    httphost: 150.158.22.179:18000
-    webrtchost: 192.168.110.130:8000
+    rtmphost: 127.0.0.1:1935
+    httphost: 127.0.0.1:80
+    webrtchost: 150.158.22.179:58000
 
 socketio:
-  #host: 0.0.0.0		#主机名,默认是 0.0.0.0 (这个设不设置无所谓,因为后面的 SocketConfig 类一般不用设置这个)
+  # host: 127.0.0.1		#主机名,默认是 0.0.0.0 (这个设不设置无所谓,因为后面的 SocketConfig 类一般不用设置这个)
   port: 33000			#监听端口
   maxFramePayloadLength: 1048576
   maxHttpContentLength: 1048576

+ 5 - 0
taphole-admin/src/main/resources/log4j2-spring.xml

@@ -67,6 +67,11 @@
             <AppenderRef ref="Console"/>
         </Logger>
 
+        <!-- 监控系统信息 -->
+        <Logger name="org.jinterop" level="error" additivity="false">
+            <AppenderRef ref="Console"/>
+        </Logger>
+
         <!-- 初始化日志 -->
         <root level="info">
             <appender-ref ref="Console"/>

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

@@ -1,13 +0,0 @@
-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;
-}

+ 0 - 24
taphole-camera/src/main/java/com.sckj.camera/service/CameraServiceImpl.java

@@ -1,12 +1,10 @@
 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;
@@ -25,10 +23,8 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestBody;
 
-import javax.annotation.PreDestroy;
 import javax.annotation.Resource;
 import java.io.File;
 import java.time.LocalDateTime;
@@ -434,25 +430,5 @@ public class CameraServiceImpl extends ServiceImpl<CameraMapper, Camera> {
 //        }
 //    }
 
-    @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);
-        }
-    }
-
 
 }

+ 7 - 4
taphole-camera/src/main/java/com.sckj.camera/util/LocalDateUtils.java

@@ -1,9 +1,6 @@
 package com.sckj.camera.util;
 
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.Period;
-import java.time.ZoneId;
+import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalUnit;
@@ -29,6 +26,12 @@ public class LocalDateUtils {
         return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
     }
 
+    public static String formatDate(Date date) {
+        Instant instant = date.toInstant();
+        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+        return localDateTime.format(DATE_TIME_FORMATTER);
+    }
+
     /**
      * Date 转 LocalDateTime
      *

+ 31 - 0
taphole-common/src/main/java/com/sckj/common/manager/ScheduledTaskManager.java

@@ -0,0 +1,31 @@
+package com.sckj.common.manager;
+
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.*;
+
+@Component
+public class ScheduledTaskManager {
+
+    private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
+    private final Map<String, ScheduledFuture<?>> tasks = new ConcurrentHashMap<>();
+
+    // 添加定时任务
+    public void addTask(String taskName, long initialDelay, long period, TimeUnit unit, Runnable task) {
+        ScheduledFuture<?> future = tasks.get(taskName);
+        if (future == null) {
+            future = executorService.scheduleAtFixedRate(task, initialDelay, period, unit);
+            tasks.put(taskName, future);
+        }
+    }
+
+    // 取消定时任务
+    public void cancelTask(String taskName) {
+        ScheduledFuture<?> future = tasks.get(taskName);
+        if (future != null) {
+            future.cancel(true);
+            tasks.remove(taskName);
+        }
+    }
+}

+ 14 - 1
taphole-common/src/main/java/com/sckj/common/util/RedisUtils.java

@@ -8,6 +8,7 @@ import org.springframework.data.redis.core.ScanOptions;
 import org.springframework.data.redis.serializer.RedisSerializer;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
 
 import javax.annotation.Resource;
 import java.util.*;
@@ -671,7 +672,7 @@ public class RedisUtils {
     public static void addFixedElement(String key, Object element, int maxSize) {
         // 将新的对象数组添加到列表头部
         redisTemplate.opsForList().leftPush(key, element);
-        // 修剪列表,只保留前 6 个元素
+        // 修剪列表,只保留前 maxSize 个元素
         redisTemplate.opsForList().trim(key, 0, maxSize - 1);
     }
 
@@ -685,4 +686,16 @@ public class RedisUtils {
         return redisTemplate.opsForList().range(key, 0, -1);
     }
 
+    /***
+     * 获取定数量最新的一条数据
+     * @param key
+     * @return
+     */
+    public static Object getFixedLatestElement(String key) {
+        // 获取列表中的所有元素
+        // 获取列表第一个元素(索引0)
+        List<Object> result = redisTemplate.opsForList().range(key, 0, 0);
+        return ObjectUtils.isEmpty(result) ? null : result.get(0);
+    }
+
 }

+ 4 - 0
taphole-common/src/main/java/com/sckj/common/util/TimeUtils.java

@@ -5,8 +5,12 @@ import java.lang.management.ManagementFactory;
 import java.text.DateFormat;
 import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.*;
 import java.util.regex.Pattern;
+import java.time.format.DateTimeFormatter;
 
 public class TimeUtils {
 

+ 4 - 0
taphole-device/pom.xml

@@ -31,6 +31,10 @@
             <artifactId>velocity-engine-core</artifactId>
             <version>2.3</version>
         </dependency>
+        <dependency>
+            <groupId>com.sckj</groupId>
+            <artifactId>taphole-camera</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 8 - 8
taphole-device/src/main/java/com/sckj/device/controller/TCameraController.java

@@ -1,17 +1,17 @@
 package com.sckj.device.controller;
 
 import com.sckj.common.aop.Log;
-import com.sckj.device.service.ITCameraService;
+import com.sckj.common.core.AjaxResult;
+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.device.service.impl.TCameraServiceImpl;
 import com.sckj.device.validate.TCameraCreateValidate;
-import com.sckj.device.validate.TCameraUpdateValidate;
 import com.sckj.device.validate.TCameraSearchValidate;
-import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.device.vo.TCameraListedVo;
+import com.sckj.device.validate.TCameraUpdateValidate;
 import com.sckj.device.vo.TCameraDetailVo;
-import com.sckj.common.core.AjaxResult;
-import com.sckj.common.core.PageResult;
-import com.sckj.common.validator.annotation.IDMust;
+import com.sckj.device.vo.TCameraListedVo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.validation.annotation.Validated;
@@ -26,7 +26,7 @@ import java.util.List;
 public class TCameraController {
 
     @Resource
-    ITCameraService iTCameraService;
+    TCameraServiceImpl iTCameraService;
 
     @GetMapping("/list")
     @ApiOperation(value="摄像头列表")

+ 6 - 0
taphole-device/src/main/java/com/sckj/device/entity/TCamera.java

@@ -70,4 +70,10 @@ public class TCamera implements Serializable {
     @ApiModelProperty(value = "品牌(1-海康 0-其他)")
     private String brand;
 
+    @ApiModelProperty(value = "RTSP端口")
+    private String portRtsp;
+
+    @ApiModelProperty(value = "显示顺序")
+    private Integer sort;
+
 }

+ 0 - 71
taphole-device/src/main/java/com/sckj/device/service/ITCameraService.java

@@ -1,71 +0,0 @@
-package com.sckj.device.service;
-
-import com.sckj.common.core.AjaxResult;
-import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.device.validate.TCameraCreateValidate;
-import com.sckj.device.validate.TCameraUpdateValidate;
-import com.sckj.device.validate.TCameraSearchValidate;
-import com.sckj.device.vo.TCameraListedVo;
-import com.sckj.device.vo.TCameraDetailVo;
-import com.sckj.common.core.PageResult;
-
-import java.util.List;
-
-/**
- * 摄像头服务接口类
- * @author zhanghao
- */
-public interface ITCameraService {
-
-    /**
-     * 摄像头列表
-     *
-     * @author zhanghao
-     * @param pageValidate 分页参数
-     * @param searchValidate 搜索参数
-     * @return PageResult<TCameraListedVo>
-     */
-    PageResult<TCameraListedVo> list(PageValidate pageValidate, TCameraSearchValidate searchValidate);
-
-    /**
-     * 摄像头详情
-     *
-     * @author zhanghao
-     * @param id 主键ID
-     * @return TCameraDetailVo
-     */
-    TCameraDetailVo detail(Integer id);
-
-    /**
-     * 摄像头新增
-     *
-     * @author zhanghao
-     * @param createValidate 参数
-     */
-    int add(TCameraCreateValidate createValidate);
-
-    /**
-     * 摄像头编辑
-     *
-     * @author zhanghao
-     * @param updateValidate 参数
-     */
-    int edit(TCameraUpdateValidate updateValidate);
-
-    /**
-     * 摄像头删除
-     *
-     * @author zhanghao
-     * @param id 主键ID
-     */
-    void del(Integer id);
-
-    /**
-     * 摄像头批量删除
-     *
-     * @author zhanghao
-     * @param ids 主键数组
-     */
-    AjaxResult<Object> del_ex(List<Long> ids);
-
-}

+ 111 - 38
taphole-device/src/main/java/com/sckj/device/service/impl/TCameraServiceImpl.java

@@ -1,27 +1,29 @@
 package com.sckj.device.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.github.yulichang.query.MPJQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sckj.camera.manager.CameraProperties;
 import com.sckj.common.TapholeAdminThreadLocal;
 import com.sckj.common.core.AjaxResult;
+import com.sckj.common.exception.OperateException;
 import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.device.service.ITCameraService;
 import com.sckj.device.validate.TCameraCreateValidate;
+import com.sckj.device.validate.TCameraUpdateDTO;
 import com.sckj.device.validate.TCameraUpdateValidate;
 import com.sckj.device.validate.TCameraSearchValidate;
+import com.sckj.device.vo.CameraDTO;
 import com.sckj.device.vo.TCameraListedVo;
 import com.sckj.device.vo.TCameraDetailVo;
-import com.sckj.common.config.GlobalConfig;
 import com.sckj.common.core.PageResult;
 import com.sckj.device.entity.TCamera;
 import com.sckj.device.mapper.TCameraMapper;
-import com.sckj.common.util.ListUtils;
-import com.sckj.common.util.TimeUtils;
-import com.sckj.common.util.UrlUtils;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
 import org.springframework.util.CollectionUtils;
 
@@ -29,43 +31,45 @@ import javax.annotation.Resource;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * 摄像头实现类
+ *
  * @author zhanghao
  */
 @Service
-public class TCameraServiceImpl implements ITCameraService {
-        
+public class TCameraServiceImpl extends ServiceImpl<TCameraMapper, TCamera> {
+
     @Resource
     TCameraMapper tCameraMapper;
 
     /**
      * 摄像头列表
      *
-     * @author zhanghao
-     * @param pageValidate 分页参数
+     * @param pageValidate   分页参数
      * @param searchValidate 搜索参数
      * @return PageResult<TCameraListedVo>
+     * @author zhanghao
      */
-    @Override
     public PageResult<TCameraListedVo> list(PageValidate pageValidate, TCameraSearchValidate searchValidate) {
-        Integer page  = pageValidate.getPageNo();
+        Integer page = pageValidate.getPageNo();
         Integer limit = pageValidate.getPageSize();
 
         QueryWrapper<TCamera> queryWrapper = new QueryWrapper<>();
         queryWrapper.orderByDesc("id");
 
         tCameraMapper.setSearch(queryWrapper, searchValidate, new String[]{
-            "=:no:str",
-            "like:name:str",
-            "=:model:str",
+                "=:no:str",
+                "like:name:str",
+                "=:model:str",
         });
 
         IPage<TCamera> iPage = tCameraMapper.selectPage(new Page<>(page, limit), queryWrapper.eq("type", "1"));
 
         List<TCameraListedVo> list = new LinkedList<>();
-        for(TCamera item : iPage.getRecords()) {
+        for (TCamera item : iPage.getRecords()) {
             TCameraListedVo vo = new TCameraListedVo();
             BeanUtils.copyProperties(item, vo);
             list.add(vo);
@@ -77,16 +81,15 @@ public class TCameraServiceImpl implements ITCameraService {
     /**
      * 摄像头详情
      *
-     * @author zhanghao
      * @param id 主键参数
      * @return TCamera
+     * @author zhanghao
      */
-    @Override
     public TCameraDetailVo detail(Integer id) {
         TCamera model = tCameraMapper.selectOne(
                 new QueryWrapper<TCamera>()
-                    .eq("id", id)
-                    .last("limit 1"));
+                        .eq("id", id)
+                        .last("limit 1"));
 
         Assert.notNull(model, "数据不存在");
 
@@ -98,13 +101,12 @@ public class TCameraServiceImpl implements ITCameraService {
     /**
      * 摄像头新增
      *
-     * @author zhanghao
      * @param createValidate 参数
+     * @author zhanghao
      */
-    @Override
     public int add(TCameraCreateValidate createValidate) {
         TCamera model = new TCamera();
-        if (!checkPortAndIp(createValidate.getPort(), createValidate.getIp())){
+        if (!checkPortAndIp(createValidate.getPort(), createValidate.getIp())) {
             return 0;
         }
         model.setCreateTime(new Date(System.currentTimeMillis()));
@@ -125,19 +127,18 @@ public class TCameraServiceImpl implements ITCameraService {
     /**
      * 摄像头编辑
      *
-     * @author zhanghao
      * @param updateValidate 参数
+     * @author zhanghao
      */
-    @Override
     public int edit(TCameraUpdateValidate updateValidate) {
         TCamera model = tCameraMapper.selectOne(
                 new QueryWrapper<TCamera>()
-                    .eq("id",  updateValidate.getId())
-                    .last("limit 1"));
+                        .eq("id", updateValidate.getId())
+                        .last("limit 1"));
 
         Assert.notNull(model, "数据不存在!");
 
-        if (!checkPortAndIp(updateValidate.getPort(), updateValidate.getIp())){
+        if (!checkPortAndIp(updateValidate.getPort(), updateValidate.getIp())) {
             return 0;
         }
 
@@ -154,14 +155,14 @@ public class TCameraServiceImpl implements ITCameraService {
         return tCameraMapper.updateById(model);
     }
 
-    public boolean checkPortAndIp(String port, String ip){
-        if (Integer.parseInt(port) > 65535 && Integer.parseInt(port) < 0){
+    public boolean checkPortAndIp(String port, String ip) {
+        if (Integer.parseInt(port) > 65535 && Integer.parseInt(port) < 0) {
             return false;
         }
         String IP_PATTERN = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
         Pattern pattern = Pattern.compile(IP_PATTERN);
         Matcher matcher = pattern.matcher(ip);
-        if (!matcher.matches()){
+        if (!matcher.matches()) {
             return false;
         }
         return true;
@@ -170,15 +171,14 @@ public class TCameraServiceImpl implements ITCameraService {
     /**
      * 摄像头删除
      *
-     * @author zhanghao
      * @param id 主键ID
+     * @author zhanghao
      */
-    @Override
     public void del(Integer id) {
         TCamera model = tCameraMapper.selectOne(
                 new QueryWrapper<TCamera>()
-                    .eq("id", id)
-                    .last("limit 1"));
+                        .eq("id", id)
+                        .last("limit 1"));
 
         Assert.notNull(model, "数据不存在!");
 
@@ -188,20 +188,93 @@ public class TCameraServiceImpl implements ITCameraService {
     /**
      * 摄像头批量删除
      *
-     * @author zhanghao
      * @param ids 主键数组
+     * @author zhanghao
      */
-    @Override
     public AjaxResult<Object> del_ex(List<Long> ids) {
         List<TCamera> models = tCameraMapper.selectList(
                 new QueryWrapper<TCamera>()
                         .in("id", ids));
 
-        if (CollectionUtils.isEmpty(models)){
+        if (CollectionUtils.isEmpty(models)) {
             return AjaxResult.failed("数据不存在");
         }
         tCameraMapper.delete(new QueryWrapper<TCamera>().in("id", ids));
         return AjaxResult.success();
     }
 
+    @Resource
+    private CameraProperties cameraProperties;
+
+
+    public Map<String, Object> getCameraInfo() {
+        List<TCamera> cameraList = lambdaQuery().eq(TCamera::getType, "1").in(TCamera::getStatus, "1", "2").orderByAsc(TCamera::getSort).list();
+        Map<String, Object> map = new HashMap<>();
+        List<CameraDTO> collect = cameraList.stream().flatMap((item) -> {
+            CameraDTO dto = new CameraDTO();
+            BeanUtils.copyProperties(item, dto);
+            String channelNumberStr = 1 + "02"; //新通道(2012年之后设备,02代表子码流)
+            String rtspUrl = "rtsp://" + item.getAccount() + ":" + item.getPassword() + "@" + item.getIp() + ":" + item.getPortRtsp() + "/" + channelNumberStr + "?transportmode=unicast"; //新码流
+            dto.setRtspUrl(rtspUrl);
+            return Stream.of(dto);
+        }).collect(Collectors.toList());
+        map.put("cameraList", collect);
+
+        List<CameraDTO> bannerList = new ArrayList<>();
+        for (CameraDTO cameraDTO : collect) {
+            if ("2".equals(cameraDTO.getStatus())) {
+                bannerList.add(cameraDTO);
+            }
+        }
+        map.put("bannerList", bannerList);
+        map.put("rtmpUrl", "http://" + cameraProperties.getRtmp().getWebrtchost());
+        return map;
+    }
+
+    public Map<String, Object> getCameraParamInfo() {
+        List<TCamera> cameraList = lambdaQuery().eq(TCamera::getType, "1").in(TCamera::getStatus, "1", "2").orderByAsc(TCamera::getSort).list();
+        Map<String, Object> map = new HashMap<>();
+        List<CameraDTO> collect = cameraList.stream().flatMap((item) -> {
+            CameraDTO dto = new CameraDTO();
+            BeanUtils.copyProperties(item, dto);
+            return Stream.of(dto);
+        }).collect(Collectors.toList());
+
+        List<CameraDTO> normalList = new ArrayList<>();
+        List<CameraDTO> bannerList = new ArrayList<>();
+
+        for (CameraDTO cameraDTO : collect) {
+            if ("1".equals(cameraDTO.getStatus())) {
+                normalList.add(cameraDTO);
+            }
+            if ("2".equals(cameraDTO.getStatus())) {
+                bannerList.add(cameraDTO);
+            }
+        }
+        map.put("normalList", normalList);
+        map.put("bannerList", bannerList);
+        return map;
+    }
+
+
+    @Transactional
+    public void updateBatchs(List<TCameraUpdateDTO> cameraList) {
+        for (TCameraUpdateDTO camera : cameraList) {
+            TCamera queryData = getById(camera.getId());
+            if (ObjectUtils.isEmpty(queryData)) {
+                throw new OperateException(String.format("传入的ID不存在:%s", camera.getId()));
+            }
+
+            LambdaUpdateWrapper<TCamera> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.eq(TCamera::getId, camera.getId());
+            if (ObjectUtils.isNotEmpty(camera.getStatus())) {
+                wrapper.set(TCamera::getStatus, camera.getStatus());
+            }
+            if (camera.getSort() != null) {
+                wrapper.set(TCamera::getSort, camera.getSort());
+            }
+            update(wrapper);
+        }
+    }
+
 }

+ 32 - 0
taphole-device/src/main/java/com/sckj/device/validate/TCameraUpdateDTO.java

@@ -0,0 +1,32 @@
+package com.sckj.device.validate;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * 摄像头参数
+ * @author zhanghao
+ */
+@Data
+@ApiModel("摄像头更新参数")
+public class TCameraUpdateDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @NotNull(message = "id参数必传")
+    @ApiModelProperty(value = "主键ID")
+    private Long id;
+
+    @NotNull(message = "status参数缺失")
+    @ApiModelProperty(value = "设备启用标志(1启用 0停用)")
+    private String status;
+
+    @NotNull(message = "显示顺序")
+    @ApiModelProperty(value = "显示顺序")
+    private Integer sort;
+
+}

+ 21 - 0
taphole-device/src/main/java/com/sckj/device/vo/CameraDTO.java

@@ -0,0 +1,21 @@
+package com.sckj.device.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("摄像头信息")
+public class CameraDTO {
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "设备启用标志(1启用 0停用)")
+    private String status;
+
+    @ApiModelProperty(value = "显示顺序")
+    private Integer sort;
+
+    @ApiModelProperty(value = "视频播放RTSP URL")
+    private String rtspUrl;
+}

+ 5 - 1
taphole-iron/pom.xml

@@ -32,7 +32,11 @@
         </dependency>
         <dependency>
             <groupId>com.sckj</groupId>
-            <artifactId>taphole-camera</artifactId>
+            <artifactId>taphole-warn</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sckj</groupId>
+            <artifactId>taphole-device</artifactId>
         </dependency>
     </dependencies>
 

+ 1 - 13
taphole-iron/src/main/java/com/sckj/iron/controller/TIronDataController.java

@@ -6,11 +6,8 @@ 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.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;
@@ -30,9 +27,6 @@ public class TIronDataController {
     @Resource
     TIronDataServiceImpl iTIronDataService;
 
-    @Resource
-    TL2DataServiceImpl tl2DataService;
-
     @GetMapping("/list")
     @ApiOperation(value = "出铁数据列表")
     public AjaxResult<PageResult<TIronDataListedVo>> list(@Validated PageValidate pageValidate,
@@ -48,13 +42,7 @@ public class TIronDataController {
         return AjaxResult.success(detail);
     }
 
-    @Log(title = "出铁数据新增")
-    @PostMapping("/add")
-    @ApiOperation(value = "出铁数据新增")
-    public AjaxResult<Object> add(@Validated @RequestBody TIronDataCreateValidate createValidate) {
-        iTIronDataService.add(createValidate);
-        return AjaxResult.success();
-    }
+
 
     @Log(title = "出铁数据删除")
     @PostMapping("/del")

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

@@ -2,6 +2,7 @@ package com.sckj.iron.controller;
 
 import com.sckj.common.aop.Log;
 import com.sckj.common.validate.commons.IdValidate;
+import com.sckj.iron.entity.TIronParam;
 import com.sckj.iron.service.impl.TIronParamServiceImpl;
 import com.sckj.iron.validate.TIronParamCreateValidate;
 import com.sckj.iron.validate.TIronParamUpdateValidate;
@@ -14,6 +15,7 @@ import com.sckj.common.core.PageResult;
 import com.sckj.common.validator.annotation.IDMust;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -29,15 +31,15 @@ public class TIronParamController {
     TIronParamServiceImpl iTIronParamService;
 
     @GetMapping("/list")
-    @ApiOperation(value="参数设定列表")
+    @ApiOperation(value = "参数设定列表")
     public AjaxResult<PageResult<TIronParamListedVo>> list(@Validated PageValidate pageValidate,
-                                                     @Validated TIronParamSearchValidate searchValidate) {
+                                                           @Validated TIronParamSearchValidate searchValidate) {
         PageResult<TIronParamListedVo> list = iTIronParamService.list(pageValidate, searchValidate);
         return AjaxResult.success(list);
     }
 
     @GetMapping("/detail")
-    @ApiOperation(value="参数设定详情")
+    @ApiOperation(value = "参数设定详情")
     public AjaxResult<TIronParamDetailVo> detail(@Validated @IDMust() @RequestParam("id") Integer id) {
         TIronParamDetailVo detail = iTIronParamService.detail(id);
         return AjaxResult.success(detail);
@@ -45,7 +47,7 @@ public class TIronParamController {
 
     @Log(title = "参数设定新增")
     @PostMapping("/add")
-    @ApiOperation(value="参数设定新增")
+    @ApiOperation(value = "参数设定新增")
     public AjaxResult<Object> add(@Validated @RequestBody TIronParamCreateValidate createValidate) {
         iTIronParamService.add(createValidate);
         return AjaxResult.success();
@@ -53,7 +55,7 @@ public class TIronParamController {
 
     @Log(title = "参数设定编辑")
     @PostMapping("/edit")
-    @ApiOperation(value="参数设定编辑")
+    @ApiOperation(value = "参数设定编辑")
     public AjaxResult<Object> edit(@Validated @RequestBody TIronParamUpdateValidate updateValidate) {
         iTIronParamService.edit(updateValidate);
         return AjaxResult.success();
@@ -61,7 +63,7 @@ public class TIronParamController {
 
     @Log(title = "参数设定删除")
     @PostMapping("/del")
-    @ApiOperation(value="参数设定删除")
+    @ApiOperation(value = "参数设定删除")
     public AjaxResult<Object> del(@Validated @RequestBody IdValidate idValidate) {
         iTIronParamService.del(idValidate.getId());
         return AjaxResult.success();
@@ -69,9 +71,46 @@ public class TIronParamController {
 
     @Log(title = "参数设定批量删除")
     @PostMapping("/del_ex")
-    @ApiOperation(value="参数设定批量删除")
+    @ApiOperation(value = "参数设定批量删除")
     public AjaxResult<Object> del_ex(@RequestBody List<Long> ids) {
         return iTIronParamService.del_ex(ids);
     }
 
+
+    @PostMapping("/getByParamType")
+    @ApiOperation(value = "根据参数类型获取参数列表")
+    public AjaxResult getByParamType(String paramType) {
+        List<TIronParam> list = iTIronParamService.lambdaQuery().eq(TIronParam::getParamType, paramType).list();
+        return AjaxResult.success(list);
+    }
+
+    @GetMapping("/getByParamName")
+    @ApiOperation(value = "根据参数名获取参数列表")
+    public AjaxResult getByParamName(String paramName) {
+        TIronParam ironParam = iTIronParamService.lambdaQuery().eq(TIronParam::getParamName, paramName).one();
+        return AjaxResult.success(ironParam);
+    }
+
+    @PostMapping("/updateByParamName")
+    @ApiOperation(value = "根据参数名更新参数列表")
+    public AjaxResult setByParamName(String paramName, String paramValue) {
+        List<TIronParam> list1 = iTIronParamService.lambdaQuery().eq(TIronParam::getParamName, paramName).list();
+        if (ObjectUtils.isEmpty(list1)) {
+            return AjaxResult.failed("不存在该数据,请确认参数名");
+        }
+        iTIronParamService.lambdaUpdate().eq(TIronParam::getParamName, paramName).set(TIronParam::getParamValue, paramValue);
+        return AjaxResult.success();
+    }
+
+    @Log(title = "更新参数列表")
+    @PostMapping("/updateIronParam")
+    @ApiOperation(value = "更新参数列表")
+    public AjaxResult<Object> updateIronParam(@RequestBody List<TIronParam> ironParamList) {
+        if (ObjectUtils.isEmpty(ironParamList)) {
+            return AjaxResult.failed("传入数据为空!");
+        }
+        iTIronParamService.updateBatchData(ironParamList);
+        return AjaxResult.success();
+    }
+
 }

+ 49 - 63
taphole-iron/src/main/java/com/sckj/iron/controller/TIronVisualScreenController.java

@@ -1,22 +1,20 @@
 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.Log;
 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.device.service.impl.TCameraServiceImpl;
+import com.sckj.device.validate.TCameraUpdateDTO;
+import com.sckj.iron.dto.IronParamDTO;
+import com.sckj.iron.entity.TIronData;
 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.TIronDataServiceImpl;
 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;
@@ -35,9 +33,10 @@ 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;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @Author feng
@@ -53,18 +52,14 @@ public class TIronVisualScreenController {
     IronLoginServiceImpl ironLoginService;
 
     @Resource
-    TL2DataServiceImpl tl2DataService;
+    TIronDataServiceImpl tl2DataService;
 
     @Resource
-    private CameraServiceImpl cameraService;
+    private TCameraServiceImpl cameraService;
 
     @Resource
     TIronParamServiceImpl iTIronParamService;
 
-    @Resource
-    private CameraProperties cameraProperties;
-
-
     @NotLogin
     @PostMapping("/login")
     @ApiOperation(value = "登录系统")
@@ -132,7 +127,7 @@ public class TIronVisualScreenController {
     @ApiOperation(value = "查询出铁数据")
     public AjaxResult queryIronData(@Validated PageValidate pageValidate, TIronDataSearchScreenValidate ironDataSearchScreenValidate) {
         //出铁操作
-        TL2Data tl2Data = new TL2Data();
+        TIronData tl2Data = new TIronData();
         BeanUtils.copyProperties(ironDataSearchScreenValidate, tl2Data);
         PageHelper.startPage(pageValidate.getPageNo(), pageValidate.getPageSize());
         return AjaxResult.success(tl2DataService.queryIronData(tl2Data));
@@ -143,7 +138,7 @@ public class TIronVisualScreenController {
     @ApiOperation(value = "导出出铁数据")
     public void exportIronData(TIronDataSearchScreenValidate ironDataSearchScreenValidate, HttpServletResponse response) throws IOException {
         //出铁操作
-        TL2Data tl2Data = new TL2Data();
+        TIronData tl2Data = new TIronData();
         BeanUtils.copyProperties(ironDataSearchScreenValidate, tl2Data);
         tl2DataService.exportIronData(tl2Data, response);
     }
@@ -153,15 +148,22 @@ public class TIronVisualScreenController {
      *
      * @return
      */
-    @ApiOperation("获取摄像头列表")
+    @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);
+    public AjaxResult getCameraInfo() {
+        return AjaxResult.success(cameraService.getCameraInfo());
+    }
+
+    /**
+     * 摄像头登录
+     *
+     * @return
+     */
+    @ApiOperation("获取摄像头参数信息")
+    @PostMapping("/getCameraParamInfo")
+    public AjaxResult getCameraParamInfo() {
+        TIronParam tIronParam = iTIronParamService.lambdaQuery().eq(TIronParam::getParamType, "camera_param").eq(TIronParam::getParamName, "camera_play_duration").one();
+        Map<String, Object> map = cameraService.getCameraParamInfo();
         map.put("cameraPlayDuration", tIronParam.getParamValue());
         return AjaxResult.success(map);
     }
@@ -171,54 +173,38 @@ public class TIronVisualScreenController {
      *
      * @return
      */
-    @ApiOperation("设置摄像头是否轮播、顺序")
+    @ApiOperation("更新摄像头轮播状态、顺序")
     @PostMapping("/updateCamera")
-    public AjaxResult updateCamera(@RequestBody List<CameraBO> cameraList) {
+    public AjaxResult updateCamera(@RequestBody List<TCameraUpdateDTO> cameraList) {
         if (ObjectUtils.isEmpty(cameraList)) {
-            return AjaxResult.failed("传入的摄像头列表数据为空");
+            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);
+    @PostMapping("/getIronParams")
+    @ApiOperation(value = "获取出铁参数设置(paramType=>出铁诊断模型参数:iron_judge,摄像头轮播时长参数:camera_param,大屏趋势图轮播项:iron_trend)")
+    public AjaxResult getIronParam(String paramType) {
+        List<TIronParam> list = iTIronParamService.lambdaQuery().eq(TIronParam::getStatus, "1")
+                .eq(TIronParam::getParamType, paramType).orderByAsc(TIronParam::getSort).list();
+        List<IronParamDTO> collect = list.stream().flatMap((item) -> {
+            IronParamDTO dto = new IronParamDTO();
+            BeanUtils.copyProperties(item, dto);
+            return Stream.of(dto);
+        }).collect(Collectors.toList());
+        return AjaxResult.success(collect);
     }
 
-    /**
-     * 摄像头登录
-     *
-     * @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("失败");
+
+    @Log(title = "更新出铁参数设置")
+    @PostMapping("/updateIronParams")
+    @ApiOperation(value = "更新出铁参数设置")
+    public AjaxResult<Object> updateIronParam(@RequestBody List<IronParamDTO> ironParamList) {
+        if (ObjectUtils.isEmpty(ironParamList)) {
+            return AjaxResult.failed("传入数据为空!");
         }
+        iTIronParamService.updateBatchs(ironParamList);
         return AjaxResult.success();
     }
 

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

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

+ 33 - 0
taphole-iron/src/main/java/com/sckj/iron/dto/IronParamDTO.java

@@ -0,0 +1,33 @@
+package com.sckj.iron.dto;
+
+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;
+
+@Data
+@ApiModel("参数设定实体")
+@TableName("t_iron_param")
+public class IronParamDTO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value="id", type= IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "参数名称")
+    private String paramName;
+
+    @ApiModelProperty(value = "参数值")
+    private String paramValue;
+
+    @ApiModelProperty(value = "参数说明")
+    private String paramDesc;
+
+
+}

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

@@ -1,23 +0,0 @@
-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;
-
-
-}

+ 44 - 0
taphole-iron/src/main/java/com/sckj/iron/dto/WarnData.java

@@ -0,0 +1,44 @@
+package com.sckj.iron.dto;
+
+import lombok.Builder;
+import lombok.Data;
+
+import static com.sckj.iron.socketio.DeviceEventListener.*;
+
+
+/***
+ * 实时数据
+ * 铁水温度、铁水流速、铁水成分、铁水流量
+ *
+ */
+@Data
+@Builder
+public class WarnData {
+
+    //open
+    //close
+    //
+    private String type;
+
+    private String desc;
+
+    public static WarnData of(String type, String desc) {
+        return WarnData.builder().type(type).desc(desc).build();
+    }
+
+    //开口预警
+    public static WarnData warnOpen(String desc) {
+        return WarnData.builder().type(TASKNAME_OPEN_WARN).desc(desc).build();
+    }
+
+    //出铁预警
+    public static WarnData warnTapping(String desc) {
+        return WarnData.builder().type(TASKNAME_TAPPING_WARN).desc(desc).build();
+    }
+
+    //堵口预警
+    public static WarnData warnClose(String desc) {
+        return WarnData.builder().type(TASKNAME_CLOSE_WARN).desc(desc).build();
+    }
+
+}

+ 59 - 0
taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java

@@ -1,5 +1,12 @@
 package com.sckj.iron.entity;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.HeadFontStyle;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadStyle;
+import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -10,6 +17,9 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.Date;
 
+@HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL,fillForegroundColor = -1)
+@HeadFontStyle(fontHeightInPoints = 16)
+@HeadRowHeight(40)
 @Data
 @ApiModel("出铁数据实体")
 @TableName("t_iron_data")
@@ -17,47 +27,96 @@ public class TIronData 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("铁口区域编号")
+    @ColumnWidth(25)
     private Long tapholeId;
 
     @ApiModelProperty(value = "出铁次数编号")
+    @ExcelProperty("出铁次数编号")
+    @ColumnWidth(25)
     private String ironNo;
 
     @ApiModelProperty(value = "出铁时间")
+    @ExcelProperty("出铁时间")
+    @ColumnWidth(25)
     private String ironCosttime;
 
     @ApiModelProperty(value = "实际出铁量")
+    @ExcelProperty("实际出铁量")
+    @ColumnWidth(25)
     private Double ironWeight;
 
     @ApiModelProperty(value = "实际渣量")
+    @ExcelProperty("实际渣量")
+    @ColumnWidth(25)
     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("开始时间")
+    @ColumnWidth(25)
     private String ironStarttime;
 
+    @ExcelProperty("结束时间")
+    @ColumnWidth(25)
     @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;
+
 }

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

@@ -31,24 +31,9 @@ public class TIronParam implements Serializable {
     private Date updateTime;
 
     @TableId(value="id", type= IdType.AUTO)
-    @ApiModelProperty(value = "")
+    @ApiModelProperty(value = "id")
     private Long id;
 
-//    @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 = "铁口区域编号")
     private Long tapholeId;
 
@@ -64,4 +49,13 @@ public class TIronParam implements Serializable {
     @ApiModelProperty(value = "参数值")
     private String paramValue;
 
+    @ApiModelProperty(value = "参数说明")
+    private String paramDesc;
+
+    @ApiModelProperty(value = "状态(1正常 0停用)")
+    private String status;
+
+    @ApiModelProperty(value = "排序")
+    private Integer sort;
+
 }

+ 15 - 1
taphole-iron/src/main/java/com/sckj/iron/entity/TL2Data.java

@@ -2,6 +2,11 @@ package com.sckj.iron.entity;
 
 import com.alibaba.excel.annotation.ExcelIgnore;
 import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.HeadFontStyle;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadStyle;
+import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -12,6 +17,9 @@ import lombok.Data;
 import java.io.Serializable;
 import java.util.Date;
 
+@HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL,fillForegroundColor = -1)
+@HeadFontStyle(fontHeightInPoints = 16)
+@HeadRowHeight(40)
 @Data
 @ApiModel("L2数据")
 @TableName("t_l2_data")
@@ -34,22 +42,27 @@ public class TL2Data implements Serializable {
 
     @ApiModelProperty(value = "铁口区域编号")
     @ExcelProperty("铁口区域编号")
+    @ColumnWidth(25)
     private Long tapholeId;
 
     @ApiModelProperty(value = "出铁次数编号")
     @ExcelProperty("出铁次数编号")
+    @ColumnWidth(25)
     private String ironNo;
 
     @ApiModelProperty(value = "出铁时间")
     @ExcelProperty("出铁时间")
+    @ColumnWidth(25)
     private String ironCosttime;
 
     @ApiModelProperty(value = "实际出铁量")
     @ExcelProperty("实际出铁量")
+    @ColumnWidth(25)
     private Double ironWeight;
 
     @ApiModelProperty(value = "实际渣量")
     @ExcelProperty("实际渣量")
+    @ColumnWidth(25)
     private String slagWeight;
 
     @ApiModelProperty(value = "铁水平均温度")
@@ -74,13 +87,14 @@ public class TL2Data implements Serializable {
 
     @ApiModelProperty(value = "开始时间")
     @ExcelProperty("开始时间")
+    @ColumnWidth(25)
     private String ironStarttime;
 
     @ExcelProperty("结束时间")
+    @ColumnWidth(25)
     @ApiModelProperty(value = "结束时间")
     private String ironEndtime;
 
-
     @ApiModelProperty(value = "碳")
     @ExcelIgnore
     private String elementC;

+ 85 - 0
taphole-iron/src/main/java/com/sckj/iron/entity/TL2Material.java

@@ -0,0 +1,85 @@
+package com.sckj.iron.entity;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.HeadFontStyle;
+import com.alibaba.excel.annotation.write.style.HeadRowHeight;
+import com.alibaba.excel.annotation.write.style.HeadStyle;
+import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
+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.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.Serializable;
+import java.util.Date;
+
+@HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL, fillForegroundColor = -1)
+@HeadFontStyle(fontHeightInPoints = 16)
+@HeadRowHeight(40)
+@Data
+@ApiModel("L2上料")
+@TableName("t_l2_material")
+public class TL2Material 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("铁口区域编号")
+    @ColumnWidth(25)
+    private Long tapholeId;
+
+    @ApiModelProperty(value = "L1发过来的charge号")
+    @ExcelProperty("L1发过来的charge号")
+    @ColumnWidth(25)
+    private String chargeNo;
+
+    @ApiModelProperty(value = "下料时间点")
+    @ExcelProperty("下料时间点")
+    @ColumnWidth(25)
+    private String downTime;
+
+    @ApiModelProperty(value = "干量")
+    @ExcelProperty("干量")
+    @ColumnWidth(25)
+    private String dryWeight;
+
+
+    public void toDataStream(DataOutputStream dos) throws Exception {
+        dos.writeLong(tapholeId);
+        dos.writeLong(boilerId);
+        dos.writeUTF(chargeNo);
+        dos.writeUTF(downTime);
+        dos.writeUTF(dryWeight);
+    }
+
+    public static TL2Material fromDataStream(DataInputStream dis) throws Exception {
+        TL2Material data = new TL2Material();
+        data.tapholeId = dis.readLong();
+        data.boilerId = dis.readLong();
+        data.chargeNo = dis.readUTF();
+        data.downTime = dis.readUTF();
+        data.dryWeight = dis.readUTF();
+        return data;
+    }
+
+
+}

+ 13 - 0
taphole-iron/src/main/java/com/sckj/iron/mapper/TL2MaterialMapper.java

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

+ 39 - 26
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronDataServiceImpl.java

@@ -4,23 +4,25 @@ 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.exception.OperateException;
+import com.sckj.common.util.ExcelUtils;
 import com.sckj.common.validate.commons.PageValidate;
 import com.sckj.iron.entity.TIronData;
 import com.sckj.iron.mapper.TIronDataMapper;
-import com.sckj.iron.validate.TIronDataCreateValidate;
 import com.sckj.iron.validate.TIronDataSearchValidate;
 import com.sckj.iron.vo.TIronDataDetailVo;
 import com.sckj.iron.vo.TIronDataListedVo;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
-import java.util.Date;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -94,26 +96,6 @@ public class TIronDataServiceImpl extends ServiceImpl<TIronDataMapper, TIronData
         return vo;
     }
 
-    /**
-     * 出铁数据新增
-     *
-     * @param createValidate 参数
-     * @author zhnaghao
-     */
-    public void add(TIronDataCreateValidate createValidate) {
-        TIronData model = new TIronData();
-        model.setCreateBy(String.valueOf(TapholeAdminThreadLocal.getAdminUsername()));
-        model.setCreateTime(new Date(System.currentTimeMillis()));
-        model.setTkbh(createValidate.getTkbh());
-        model.setCtcsbh(createValidate.getCtcsbh());
-        model.setCtsj(createValidate.getCtsj());
-        model.setCtl(createValidate.getCtl());
-        model.setZl(createValidate.getZl());
-        model.setWhcd(createValidate.getWhcd());
-        //model.setSbqy(createValidate.getSbqy());
-        model.setSj(createValidate.getSj());
-        tIronDataMapper.insert(model);
-    }
 
     /**
      * 出铁数据删除
@@ -135,19 +117,50 @@ public class TIronDataServiceImpl extends ServiceImpl<TIronDataMapper, TIronData
     /**
      * 出铁数据批量删除
      *
-     * @author zhanghao
      * @param ids 主键数组
+     * @author zhanghao
      */
-    public AjaxResult<Object> del_ex(List<Long> ids){
+    public AjaxResult<Object> del_ex(List<Long> ids) {
         List<TIronData> models = tIronDataMapper.selectList(
                 new QueryWrapper<TIronData>()
                         .in("id", ids));
 
-        if (CollectionUtils.isEmpty(models)){
+        if (CollectionUtils.isEmpty(models)) {
             return AjaxResult.failed("数据不存在");
         }
         tIronDataMapper.delete(new QueryWrapper<TIronData>().in("id", ids));
         return AjaxResult.success();
     }
 
+    /***
+     * 获取最新6条数据
+     * @return
+     */
+    public List<TIronData> queryIronData(TIronData ironData) {
+        QueryWrapper<TIronData> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda()
+                .eq(ObjectUtils.isNotEmpty(ironData.getSlagWeight()), TIronData::getSlagWeight, ironData.getSlagWeight())
+                .eq(ObjectUtils.isNotEmpty(ironData.getIronWeight()), TIronData::getIronWeight, ironData.getIronWeight())
+                .eq(ObjectUtils.isNotEmpty(ironData.getIronCosttime()), TIronData::getIronCosttime, ironData.getIronCosttime())
+                .eq(ObjectUtils.isNotEmpty(ironData.getIronNo()), TIronData::getIronNo, ironData.getIronNo())
+                .between(TIronData::getCreateTime, ironData.getIronStarttime(), ironData.getIronEndtime())
+                .eq(ObjectUtils.isNotEmpty(ironData.getTapholeId()), TIronData::getTapholeId, ironData.getTapholeId())
+        ;
+        return list(queryWrapper);
+    }
+
+    /***
+     * 导出数据
+     * @param ironData
+     * @param response
+     * @throws IOException
+     */
+    public void exportIronData(TIronData ironData, HttpServletResponse response) throws IOException {
+        if (ObjectUtils.isNotEmpty(ironData.getIronStarttime()) && ObjectUtils.isNotEmpty(ironData.getIronEndtime())) {
+            throw new OperateException("导出请选择开始时间和结束时间!");
+        }
+        List<TIronData> tl2DataList = queryIronData(ironData);
+        ExcelUtils.exportExcel(tl2DataList, TIronData.class, "出铁数据", "出铁数据", response);
+    }
+
 }

+ 59 - 21
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronParamServiceImpl.java

@@ -1,13 +1,16 @@
 package com.sckj.iron.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 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.exception.OperateException;
 import com.sckj.common.validate.commons.PageValidate;
+import com.sckj.iron.dto.IronParamDTO;
 import com.sckj.iron.entity.TIronParam;
 import com.sckj.iron.mapper.TIronParamMapper;
 import com.sckj.iron.validate.TIronParamCreateValidate;
@@ -15,8 +18,10 @@ import com.sckj.iron.validate.TIronParamSearchValidate;
 import com.sckj.iron.validate.TIronParamUpdateValidate;
 import com.sckj.iron.vo.TIronParamDetailVo;
 import com.sckj.iron.vo.TIronParamListedVo;
+import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.Assert;
 import org.springframework.util.CollectionUtils;
 
@@ -27,39 +32,40 @@ import java.util.List;
 
 /**
  * 参数设定实现类
+ *
  * @author zhnaghao
  */
 @Service
 public class TIronParamServiceImpl extends ServiceImpl<TIronParamMapper, TIronParam> {
-        
+
     @Resource
     TIronParamMapper tIronParamMapper;
 
     /**
      * 参数设定列表
      *
-     * @author zhnaghao
-     * @param pageValidate 分页参数
+     * @param pageValidate   分页参数
      * @param searchValidate 搜索参数
      * @return PageResult<TIronParamListedVo>
+     * @author zhnaghao
      */
     public PageResult<TIronParamListedVo> list(PageValidate pageValidate, TIronParamSearchValidate searchValidate) {
-        Integer page  = pageValidate.getPageNo();
+        Integer page = pageValidate.getPageNo();
         Integer limit = pageValidate.getPageSize();
 
         QueryWrapper<TIronParam> queryWrapper = new QueryWrapper<>();
         queryWrapper.orderByDesc("id");
 
         tIronParamMapper.setSearch(queryWrapper, searchValidate, new String[]{
-            "=:kkhs:str",
-            "=:ctsj:str",
-            "=:ctl:str",
+                "=:kkhs:str",
+                "=:ctsj:str",
+                "=:ctl:str",
         });
 
         IPage<TIronParam> iPage = tIronParamMapper.selectPage(new Page<>(page, limit), queryWrapper);
 
         List<TIronParamListedVo> list = new LinkedList<>();
-        for(TIronParam item : iPage.getRecords()) {
+        for (TIronParam item : iPage.getRecords()) {
             TIronParamListedVo vo = new TIronParamListedVo();
             BeanUtils.copyProperties(item, vo);
             list.add(vo);
@@ -71,15 +77,15 @@ public class TIronParamServiceImpl extends ServiceImpl<TIronParamMapper, TIronPa
     /**
      * 参数设定详情
      *
-     * @author zhnaghao
      * @param id 主键参数
      * @return TIronParam
+     * @author zhnaghao
      */
     public TIronParamDetailVo detail(Integer id) {
         TIronParam model = tIronParamMapper.selectOne(
                 new QueryWrapper<TIronParam>()
-                    .eq("id", id)
-                    .last("limit 1"));
+                        .eq("id", id)
+                        .last("limit 1"));
 
         Assert.notNull(model, "数据不存在");
 
@@ -91,8 +97,8 @@ public class TIronParamServiceImpl extends ServiceImpl<TIronParamMapper, TIronPa
     /**
      * 参数设定新增
      *
-     * @author zhnaghao
      * @param createValidate 参数
+     * @author zhnaghao
      */
     public void add(TIronParamCreateValidate createValidate) {
         TIronParam model = new TIronParam();
@@ -107,14 +113,14 @@ public class TIronParamServiceImpl extends ServiceImpl<TIronParamMapper, TIronPa
     /**
      * 参数设定编辑
      *
-     * @author zhnaghao
      * @param updateValidate 参数
+     * @author zhnaghao
      */
     public void edit(TIronParamUpdateValidate updateValidate) {
         TIronParam model = tIronParamMapper.selectOne(
                 new QueryWrapper<TIronParam>()
-                    .eq("id",  updateValidate.getId())
-                    .last("limit 1"));
+                        .eq("id", updateValidate.getId())
+                        .last("limit 1"));
 
         Assert.notNull(model, "数据不存在!");
 
@@ -129,14 +135,14 @@ public class TIronParamServiceImpl extends ServiceImpl<TIronParamMapper, TIronPa
     /**
      * 参数设定删除
      *
-     * @author zhnaghao
      * @param id 主键ID
+     * @author zhnaghao
      */
     public void del(Integer id) {
         TIronParam model = tIronParamMapper.selectOne(
                 new QueryWrapper<TIronParam>()
-                    .eq("id", id)
-                    .last("limit 1"));
+                        .eq("id", id)
+                        .last("limit 1"));
 
         Assert.notNull(model, "数据不存在!");
 
@@ -146,19 +152,51 @@ public class TIronParamServiceImpl extends ServiceImpl<TIronParamMapper, TIronPa
     /**
      * 参数设定批量删除
      *
-     * @author zhanghao
      * @param ids 主键数组
+     * @author zhanghao
      */
-    public AjaxResult<Object> del_ex(List<Long> ids){
+    public AjaxResult<Object> del_ex(List<Long> ids) {
         List<TIronParam> models = tIronParamMapper.selectList(
                 new QueryWrapper<TIronParam>()
                         .in("id", ids));
 
-        if (CollectionUtils.isEmpty(models)){
+        if (CollectionUtils.isEmpty(models)) {
             return AjaxResult.failed("数据不存在");
         }
         tIronParamMapper.delete(new QueryWrapper<TIronParam>().in("id", ids));
         return AjaxResult.success();
     }
 
+
+    @Transactional
+    public void updateBatchs(List<IronParamDTO> paramList) {
+        for (IronParamDTO ironParam : paramList) {
+            TIronParam queryData = getById(ironParam.getId());
+            if (ObjectUtils.isEmpty(queryData)) {
+                throw new OperateException(String.format("传入的ID不存在:%s", ironParam.getId()));
+            }
+            LambdaUpdateWrapper<TIronParam> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.eq(TIronParam::getId, ironParam.getId());
+            if (ObjectUtils.isNotEmpty(ironParam.getParamValue())) {
+                wrapper.set(TIronParam::getParamValue, ironParam.getParamValue());
+            }
+            update(wrapper);
+        }
+    }
+
+    public void updateBatchData(List<TIronParam> paramList) {
+        for (TIronParam ironParam : paramList) {
+            TIronParam queryData = getById(ironParam.getId());
+            if (ObjectUtils.isEmpty(queryData)) {
+                throw new OperateException(String.format("传入的ID不存在:%s", ironParam.getId()));
+            }
+            LambdaUpdateWrapper<TIronParam> wrapper = new LambdaUpdateWrapper<>();
+            wrapper.eq(TIronParam::getId, ironParam.getId());
+            if (ObjectUtils.isNotEmpty(ironParam.getParamValue())) {
+                wrapper.set(TIronParam::getParamValue, ironParam.getParamValue());
+            }
+            update(wrapper);
+        }
+    }
+
 }

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

@@ -213,17 +213,6 @@ public class TL2DataServiceImpl extends ServiceImpl<TL2DataMapper, TL2Data> {
      * 获取最新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()

+ 38 - 0
taphole-iron/src/main/java/com/sckj/iron/service/impl/TL2MaterialServiceImpl.java

@@ -0,0 +1,38 @@
+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.entity.TL2Material;
+import com.sckj.iron.mapper.TL2MaterialMapper;
+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 TL2MaterialServiceImpl extends ServiceImpl<TL2MaterialMapper, TL2Material> {
+
+
+    /***
+     * 获取最新2条数据
+     * @return
+     */
+    public List<TL2Material> getLatest2Data() {
+        LambdaQueryWrapper<TL2Material> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.isNotNull(TL2Material::getChargeNo).orderByDesc(TL2Material::getChargeNo).last("limit 2");
+        List<TL2Material> list = list(queryWrapper);
+        return list;
+    }
+
+
+}

+ 470 - 341
taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java

@@ -1,25 +1,29 @@
 package com.sckj.iron.socketio;
 
-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.camera.util.LocalDateUtils;
 import com.sckj.common.eventbus.EventListener;
+import com.sckj.common.manager.ScheduledTaskManager;
 import com.sckj.common.socketio.SocketUtil;
 import com.sckj.common.util.RedisUtils;
 import com.sckj.iron.dto.IronStepDTO;
 import com.sckj.iron.dto.RealtimeData;
-import com.sckj.iron.dto.TrendData;
+import com.sckj.iron.dto.WarnData;
 import com.sckj.iron.entity.TIronData;
+import com.sckj.iron.entity.TIronParam;
 import com.sckj.iron.entity.TL2Data;
+import com.sckj.iron.entity.TL2Material;
 import com.sckj.iron.service.impl.*;
 import com.sckj.iron.vo.IronStepVO;
 import com.sckj.opc.dto.L2Data;
+import com.sckj.opc.dto.L2Material;
 import com.sckj.opc.entity.OPCData;
 import com.sckj.opc.opcua.L2DataServiceImpl;
 import com.sckj.opc.service.OPCDataServiceImpl;
+import com.sckj.opc.utils.CustomUtil;
+import com.sckj.warn.service.ITExceptionLogService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.BeanUtils;
@@ -33,6 +37,11 @@ import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 /**
  * @Author feng
@@ -67,48 +76,18 @@ public class DeviceEventListener extends EventListener {
     @Resource
     TL2DataServiceImpl tl2DataService;
 
+    //参数
     @Resource
-    private L2DataServiceImpl l2DataServiceImpl;
+    TL2MaterialServiceImpl tl2MaterialService;
 
     @Resource
-    OPCDataServiceImpl opcDataService;
-
-    //实时数据
-    Map<String, Object> mRealtimeData = new HashMap<>();
-
-    //实时状态
-    Map<String, Object> mRealtimeStatus = new HashMap<>();
-
+    L2DataServiceImpl l2DataServiceImpl;
 
     @Resource
-    TrendData trendData;
-
-    //L1
-    private OPCData mOPCData;
-
-    //L2
-    private L2Data mL2Data;
-
-    // 1.创建表达式解析器
-    private SpelExpressionParser parser = new SpelExpressionParser();
-
-    // 2.创建变量上下文,设置变量
-    private StandardEvaluationContext mContext = new StandardEvaluationContext();
-
-    //出铁步骤
-    private List<IronStepVO> mSteps;
-
-    private static final String NODE = "node";
-
-    //定时器,用于铁口开口超时记录
-    private Timer timer = new Timer();
+    OPCDataServiceImpl opcDataService;
 
-    //是否出铁中
-    //1 出铁中    0 出铁结束
-    private boolean ironLoading1 = false;
-    private boolean ironLoading2 = false;
-    private boolean ironLoading3 = false;
-    private boolean ironLoading4 = false;
+    @Resource
+    ITExceptionLogService iTExceptionLogService;
 
     //1号出铁状态标记
     private static final String TAG_TAPHOLE1_STATUS = "AOD25606.PV";
@@ -130,16 +109,10 @@ public class DeviceEventListener extends EventListener {
     private static final String TAG_IRON_WEIGHT12 = "WI5402.PV";
 
     //预判和确认出铁
-    private static final String ypqrct = "lnct";
+    private static final String STEP_YPQRCT = "lnct";
 
     //铁量差计算
-    private static final String tlc = "tlc";
-
-    //最近任一铁口出铁结束时间
-    private Date lastIronEndTimeRecently;
-
-    @Resource(name = "taskExecutor")
-    ThreadPoolTaskExecutor taskExecutor;
+    private static final String STEP_TLC = "tlc";
 
     //铁水成分
     public static final String IRON_ELEMENT = "ironElement";
@@ -151,6 +124,8 @@ public class DeviceEventListener extends EventListener {
     public static final String IRON_WEIGHT = "ironWeight";
     //出铁状态
     private static final String IRON_STATUS = "ironStatus";
+    //总干量
+    private static final String IRON_TOTAL_DRY = "ironTotalDry";
 
     //鱼雷罐车
     private static final String CAR_STATUS = "ylgc";
@@ -159,14 +134,102 @@ public class DeviceEventListener extends EventListener {
     //摆动溜咀
     private static final String MOUTH_STATUS = "bdlz";
     //冲渣状态
-    private static final String FLUSH_STATUS = "flushStatus";
-    //预计出铁结束时间
-    private static final String PLAN_END_TIME = "planEndTime";
+    private static final String FLUSH_STATUS = "AOD25607.PV";
+
+    // 1.创建表达式解析器
+    private SpelExpressionParser parser = new SpelExpressionParser();
+
+    // 2.创建变量上下文,设置变量
+    private StandardEvaluationContext mContext = new StandardEvaluationContext();
+
+    //定时器
+    @Resource
+    private ScheduledTaskManager scheduledTaskManager;
+
+    //多任务
+    @Resource(name = "taskExecutor")
+    ThreadPoolTaskExecutor taskExecutor;
+
+    //开口预警
+    public static final String TASKNAME_OPEN_WARN = "open_warn";
+    //堵口预警,出铁xxx分钟开始
+    public static final String TASKNAME_CLOSE_WARN = "close_warn";
+    //出铁预警
+    public static final String TASKNAME_TAPPING_WARN = "tapping_warn";
+    //出铁诊断,出铁结束后xxx分钟开始
+    private static final String TASKNAME_TAPPING_TEST = "tapping_test";
+    //打泥量预计
+    private static final String TASKNAME_HIT_MUD = "hit_mud";
+    //出铁计时
+    private static final String TASKNAME_TAPPING_CONSTTIME = "tapping_consttime";
+
+    //铁口出铁状态
+    //1 出铁中    0 出铁结束
+    private AtomicBoolean ironLoading1 = new AtomicBoolean(false);
+    //
+    private AtomicBoolean ironLoading2 = new AtomicBoolean(false);
+    //
+    private AtomicBoolean ironLoading3 = new AtomicBoolean(false);
+    //
+    private AtomicBoolean ironLoading4 = new AtomicBoolean(false);
+
+    //出铁步骤
+    private List<IronStepVO> mSteps;
+
+    //出铁参数
+    private Map<String, TIronParam> mIronParamMap;
+
+    //节点标记
+    private static final String NODE = "node";
+
+    //实时数据
+    Map<String, Object> mRealtimeData = new ConcurrentHashMap<>();
+
+    //实时状态
+    Map<String, Object> mRealtimeStatus = new ConcurrentHashMap<>();
+
+
+    //最近任一铁口出铁结束时间
+    private Date mIronEndTimeRecently;
+
+    private BigDecimal speed1 = BigDecimal.ZERO;
+
+    private BigDecimal speed2 = BigDecimal.ZERO;
+
+    //标准流速
+    private BigDecimal STANDARD_SPEED;
 
+    //压差阈值
+    private BigDecimal PRESSURE_DIFF_VALUE;
+
+    //实时出铁总重量/总流量
+    private BigDecimal mTotalWeight = BigDecimal.ZERO;
+    //总干量
+    private BigDecimal mTotalDry = BigDecimal.ZERO;
+    //耗时(单位:s)
+    private AtomicInteger mSecondsElapsed = new AtomicInteger(0);
+
+    //redis保存最多数量数据
+    private static final int MAX_REDIS_COUNT = 50;
 
     @PostConstruct
     public void init() {
+        //程序启动后隔断时间启动订阅
+        scheduledTaskManager.addTask("opcsubscribe", 0, 15, TimeUnit.SECONDS, () -> {
+            log.info("opcdaService subscribe available");
+//            opcdaService.subscribeAvailable();
+            scheduledTaskManager.cancelTask("opcsubscribe");
+        });
+
         mSteps = ironStepService.getTreeSteps();
+        List<TIronParam> mIronParams = ironParamService.lambdaQuery().eq(TIronParam::getStatus, "1").eq(TIronParam::getParamType, "iron_judge").orderByAsc(TIronParam::getSort).list();
+        if (ObjectUtils.isNotEmpty(mIronParams)) {
+            mIronParamMap = mIronParams.stream()
+                    .collect(Collectors.toMap(TIronParam::getParamName, ironParam -> ironParam, (existing, replacement) -> existing));
+            STANDARD_SPEED = new BigDecimal(mIronParamMap.get("iron_speed").getParamValue());
+            PRESSURE_DIFF_VALUE = new BigDecimal(mIronParamMap.get("pressure_diff_value").getParamValue());
+        }
+
     }
 
     /***
@@ -175,20 +238,17 @@ public class DeviceEventListener extends EventListener {
      */
     @Subscribe
     public void onMessageEvent(OPCData opcData) {
-        if (SocketUtil.clientUserIds.isEmpty()) {
-            return;
-        }
-        this.mOPCData = opcData;
         //异步保存OPC数据
-        taskExecutor.submit(() -> opcDataService.save(mOPCData));
+        taskExecutor.submit(() -> {
+            opcDataService.save(opcData);
+        });
         //出铁操作
-        operate();
-
-        //趋势数据
-        trenddata();
+        taskExecutor.submit(() -> operate(opcData));
 
         //实时数据
-        realtime();
+        taskExecutor.submit(() -> {
+            setRealtimeDataAndStatus(opcData, null);
+        });
 
     }
 
@@ -197,111 +257,268 @@ public class DeviceEventListener extends EventListener {
      * @param l2Data
      */
     @Subscribe
-    public void onL2MessageEvent(L2Data l2Data) {
-        if (SocketUtil.clientUserIds.isEmpty()) {
-            return;
-        }
-        this.mL2Data = l2Data;
-        realtime();
-
+    public void onL2DataMessageEvent(L2Data l2Data) {
         TL2Data tl2Data = new TL2Data();
         //出铁操作
         BeanUtils.copyProperties(l2Data, tl2Data);
-
         //将L2实时数据保存到数据库
-        tl2DataService.saveOrUpdate(tl2Data);
-
+        taskExecutor.submit(() -> {
+            tl2DataService.saveOrUpdate(tl2Data);
+        });
         //将L2实时数据保存到Redis
-        RedisUtils.addFixedElement(IRON_ELEMENT, l2Data, 6);
-
-        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);
+        taskExecutor.submit(() -> {
+            RedisUtils.addFixedElement(IRON_ELEMENT, l2Data, MAX_REDIS_COUNT);
+            PushData.send2TrendIronElement(RedisUtils.getFixedElement(IRON_ELEMENT));
+        });
+
+        taskExecutor.submit(() -> {
+            setRealtimeDataAndStatus(null, l2Data);
+        });
+
+        taskExecutor.submit(() -> {
+
+            for (IronStepVO stepDTO : mSteps) {
+                if (NODE.equalsIgnoreCase(stepDTO.getNodeType())) {
+                    //处理子项
+                    for (IronStepVO child : stepDTO.getChilds()) {
+                        if (STEP_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);
+            PushData.send2Operation(mSteps, ironLoading1.get());
+        });
+
+    }
+
+
+    @Subscribe
+    public void onL2MaterialMessageEvent(L2Material l2Material) {
+        TL2Material tl2Material = new TL2Material();
+        //出铁操作
+        BeanUtils.copyProperties(l2Material, tl2Material);
+        //将L2上料实时数据保存到数据库
+        taskExecutor.submit(() -> {
+            tl2MaterialService.saveOrUpdate(tl2Material);
+        });
+
+        if (ironLoading1.get()) {
+            BigDecimal bigDecimalNew = new BigDecimal(l2Material.getDryWeight());
+            mTotalDry = mTotalDry.add(bigDecimalNew);
+        } else {
+            mTotalDry = BigDecimal.ZERO;
         }
-        setStepResult(mSteps);
+
+        RedisUtils.addFixedElement(IRON_TOTAL_DRY, mTotalDry, MAX_REDIS_COUNT);
+
     }
 
+    //1号铁口正在出铁的操作项目
+    private void taphole1Start(L2Data mL2Data) {
+        //通过“预判和确认出铁”标记开始出铁
+        boolean isReady = false;
+
+        for (IronStepVO stepDTO : mSteps) {
+            if (STEP_YPQRCT.equalsIgnoreCase(stepDTO.getIdentifier()) && 1 == stepDTO.getPassResult()) {
+                isReady = true;
+                break;
+            }
+        }
 
-    //趋势数据
-    private void trenddata() {
+        //炉前在接受到炉内出铁要求后,10分钟内打开铁口,未打开系统告警并记录
+//        if (isReady) {
+//            scheduledTaskManager.addTask(TASKNAME_OPEN_WARN, 0, OPEND_HOUR, TimeUnit.MINUTES, () -> {
+//                log.info("堵口预警:{}", TASKNAME_OPEN_WARN);
+//
+//                System.out.println("倒计时结束!10分钟已到。");
+//                // 出铁预警,打开系统告警并记录
+//                PushData.send2Warn("请立即打开铁口");
+//                log.info("准备出铁但是未及时出铁口,此处数据库记录");
+//                scheduledTaskManager.cancelTask(TASKNAME_OPEN_WARN); // 终止定时器
+//            });
+//        }
+
+
+        //由 0 -> 1 表明1号铁口开始出铁
+        //
+        //根据理论铁量、实时铁水流速,推测距离出铁结束的剩余时间
+//      Date ironTime = mOPCData.getServerTime();
+//      lastIronEndTimeRecently
+        //获取总干量
+        BigDecimal totalDry = new BigDecimal(ObjectUtils.defaultIfNull(mL2Data.getTotalDry(), "0"));
+        //计算出理论铁量
+        BigDecimal multiply = totalDry.multiply(new BigDecimal(1.0)).multiply(new BigDecimal(1.0));
         //
+//        float totalSpeed = speed1.add(speed2);
+//        if (totalSpeed > 0) {
+//            //理论时间
+//            BigDecimal divide = multiply.divide(new BigDecimal(totalSpeed), 2, BigDecimal.ROUND_HALF_UP);
+//            String plainString = divide.toPlainString();
+//            log.info("理论出铁时间:{}min", plainString);
+//        }
+
+        //堵口预警
+        scheduledTaskManager.addTask(TASKNAME_CLOSE_WARN, 0, 1, TimeUnit.MINUTES, () -> {
+            //堵口预警
+            log.info("堵口预警:{},speed1:{},speed2:{},STANDARD_SPEED:{}", speed1, speed2, TASKNAME_CLOSE_WARN);
+            if (speed1.compareTo(STANDARD_SPEED) > 0 || speed2.compareTo(STANDARD_SPEED) > 0) {
+                //流速过大可能是由于铁口深度不足或发生跑大流问题,则提示将当前铁口堵口
+                PushData.send2Warn(WarnData.warnClose("流速过快,请将当前铁口堵口"));
+            } else if ((speed1.compareTo(STANDARD_SPEED) < 0 || speed2.compareTo(STANDARD_SPEED) < 0) && (ironLoading2.get() || ironLoading3.get() || ironLoading4.get())) {
+                //若流速过小,但其它铁口正在出铁,则提示将当前铁口堵口
+                PushData.send2Warn(WarnData.warnClose("流速过小,请将当前铁口堵口"));
+            } else if ((speed1.compareTo(STANDARD_SPEED) < 0 || speed2.compareTo(STANDARD_SPEED) < 0) && (!ironLoading2.get() && !ironLoading3.get() && !ironLoading4.get())) {
+                //若流速过小且其他铁口均未出铁,则提示先将其它铁口打开,再进行堵口
+                PushData.send2Warn(WarnData.warnClose("请先打开其它铁口,再堵口"));
+            }
+        });
+
+        //开始计算打泥量,通过打泥量公式
+        //打泥量公式关联因素:铁口深度、钻杆直径、
+        //调用打泥量模型,计算预计使用多少打泥量进行堵口
+        scheduledTaskManager.addTask(TASKNAME_HIT_MUD, 0, 30, TimeUnit.SECONDS, () -> {
+            log.info("堵口预警:{},speed1:{},speed2:{},STANDARD_SPEED:{}", speed1, speed2, TASKNAME_HIT_MUD);
+            String dryString = totalDry.toPlainString();
+            //
+            //堵口预警
+            //计算理论铁量= 矿批 × 综合品位 × 1.06,其中矿批是指L2中的干量
+            scheduledTaskManager.cancelTask(TASKNAME_HIT_MUD);
+        });
+
+        //出铁计时
+        scheduledTaskManager.addTask(TASKNAME_TAPPING_CONSTTIME, 0, 1, TimeUnit.SECONDS, () -> {
+            int totalSeconds = mSecondsElapsed.get();
+            int hours = totalSeconds / 3600;
+            int minutes = (totalSeconds % 3600) / 60;
+            int seconds = totalSeconds % 60;
+            String elapsedTime = String.format("%02d:%02d:%02d", hours, minutes, seconds);
+            log.info("elapsedTime:{}", elapsedTime);
+            RedisUtils.addFixedElement(TASKNAME_TAPPING_CONSTTIME, elapsedTime, MAX_REDIS_COUNT);
+            PushData.send2CostTime(elapsedTime);
+            mSecondsElapsed.incrementAndGet();
+        });
 
     }
 
+    //1号铁口结束出铁的操作项目
+    private void taphole1End() {
+        //由 1-> 0 表明1号铁口结束出铁
+        mTotalWeight = BigDecimal.ZERO;
+        mTotalDry = BigDecimal.ZERO;
+        scheduledTaskManager.cancelTask(TASKNAME_OPEN_WARN);
+        scheduledTaskManager.cancelTask(TASKNAME_CLOSE_WARN);
+        scheduledTaskManager.cancelTask(TASKNAME_TAPPING_WARN);
+        scheduledTaskManager.cancelTask(TASKNAME_HIT_MUD);
+        scheduledTaskManager.cancelTask(TASKNAME_TAPPING_CONSTTIME);
+        mSecondsElapsed.set(0);
+
+        recordAfter();
+        recordBlock();
+
+        //开始出铁诊断
+        //获取开口耗时、出铁时间、实际出铁量、平均铁水流速、平均铁水温度等数据,进行阈值判定,诊断出铁是否正常
+        //xxx分钟延迟
+        scheduledTaskManager.addTask(TASKNAME_TAPPING_TEST, 0, 3, TimeUnit.SECONDS, () -> {
+            //堵口预警
+            log.info("定时任务:{},出铁诊断", TASKNAME_TAPPING_TEST);
+            L2Data fixedLatestElement = (L2Data) RedisUtils.getFixedLatestElement(IRON_ELEMENT);
+            //平均温度
+            String mudWeight = fixedLatestElement.getAvgTemp();
+            //出铁时间
+            String ironCosttime = fixedLatestElement.getIronCosttime();
+            //实际出铁量
+            String ironWeight = fixedLatestElement.getIronWeight();
+
+            TIronData ironData = new TIronData();
+            BeanUtils.copyProperties(ironData, fixedLatestElement);
+
+            ironDataService.save(ironData);
+
+            scheduledTaskManager.cancelTask(TASKNAME_TAPPING_TEST);
+        });
+
+    }
 
-    //实时数据显示
-    private void realtime() {
+    //出铁后,记录炉次、开口时间、鱼雷罐车车号、铁口深度、铁水流速
+    private void recordAfter() {
+        ironAfterService.add(null);
+    }
+
+    //堵口后,记录堵口时间、出铁量,打泥量、是否喷溅、是否跑泥
+    private void recordBlock() {
+        ironBlockService.add(null);
+    }
+
+    /***
+     * 设置实时数据值和状态
+     */
+    private synchronized void setRealtimeDataAndStatus(OPCData opcData, L2Data l2Data) {
         //铁水温度
         //铁水流速
         //铁水成分
         //铁水流量
         //WI5401.PV  1TH-1号车总重
         //WI5402.PV  1TH-2号车TPC总重
-        if (ObjectUtils.isNotEmpty(mOPCData)) {
-            if (mOPCData.getPointName().contains(TAG_IRON_TEMP)) {
+        if (ObjectUtils.isNotEmpty(opcData)) {
+            if (opcData.getPointName().contains(TAG_IRON_TEMP)) {
                 RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setValue(opcData.getData());
                 realtimeData.setUnit("℃");
                 realtimeData.setDesc("铁水温度");
-                realtimeData.setTime(mOPCData.getServerTime().toString());
+                realtimeData.setTime(LocalDateUtils.formatDate(opcData.getServerTime()));
                 mRealtimeData.put(IRON_TEMP, realtimeData);
                 //redis添加数据
-                RedisUtils.addFixedElement(IRON_TEMP, realtimeData, 6);
-            }
-
-            if (mOPCData.getPointName().contains(TAG_CAR11) || mOPCData.getPointName().contains(TAG_CAR12)) {
+                RedisUtils.addFixedElement(IRON_TEMP, realtimeData, MAX_REDIS_COUNT);
+                PushData.send2TrendIronTemp(RedisUtils.getFixedElement(IRON_TEMP));
+            } else if (opcData.getPointName().contains(TAG_CAR11) || opcData.getPointName().contains(TAG_CAR12)) {
 //            1TH-1号车受铁速度
                 RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setValue(opcData.getData());
                 realtimeData.setUnit("t/s");
 
                 RealtimeData ironSpeed = (RealtimeData) mRealtimeData.get(IRON_SPEED);
@@ -316,12 +533,14 @@ public class DeviceEventListener extends EventListener {
                     speeds = (RealtimeData[]) ironSpeed.getValue();
                 }
 
-                if (mOPCData.getPointName().contains(TAG_CAR11)) {
+                if (opcData.getPointName().contains(TAG_CAR11)) {
                     realtimeData.setDesc("1号车");
                     speeds[0] = realtimeData;
+                    speed1 = new BigDecimal(opcData.getData().toString());
                 } else {
                     realtimeData.setDesc("2号车");
                     speeds[1] = realtimeData;
+                    speed2 = new BigDecimal(opcData.getData().toString());
                 }
 
                 //只在两个都有数据的时候才添加
@@ -329,93 +548,82 @@ public class DeviceEventListener extends EventListener {
                         && 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);
+                    ironSpeed.setTime(LocalDateUtils.formatDate(opcData.getServerTime()));
+                    RedisUtils.addFixedElement(IRON_SPEED, ironSpeed, MAX_REDIS_COUNT);
+                    PushData.send2TrendIronSpeed(RedisUtils.getFixedElement(IRON_SPEED));
                 }
-            }
-
-            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);
-
-                    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);
-
-                    ironWeight.setTime(mOPCData.getServerTime().toString());
-                    RedisUtils.addFixedElement(IRON_WEIGHT, ironWeight, 6);
-                }
-            }
-
-
-            if (mOPCData.getPointName().contains(TAG_TAPHOLE1_STATUS)) {
+            } else if (opcData.getPointName().contains(TAG_TAPHOLE1_STATUS)) {
                 RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setValue(opcData.getData());
                 realtimeData.setDesc("出铁状态");
                 mRealtimeStatus.put(IRON_STATUS, realtimeData);
-            }
 
-//            if (mOPCData.getPointName().contains(CAR_STATUS)) {
-//                RealtimeData realtimeData = new RealtimeData();
-//                realtimeData.setValue(mOPCData.getData());
-//                realtimeData.setDesc("鱼雷罐车到位状态");
-//                mRealtimeDataMap.put(CAR_STATUS, realtimeData);
-//            }
+                ironLoading1.set("1".equals(opcData.getData().toString()));
 
+                if (ironLoading1.get()) {
+                    taphole1Start(l2Data);
+                } else {
+                    taphole1End();
+                }
 
-//            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);
-//            }
-
-            if (mOPCData.getPointName().contains(FLUSH_STATUS)) {
+            } else if (opcData.getPointName().contains(TAG_TAPHOLE2_STATUS)) {
+                ironLoading2.set("1".equals(opcData.getData().toString()));
+                if (ironLoading2.get()) {
+                    mIronEndTimeRecently = opcData.getServerTime();
+                }
+            } else if (opcData.getPointName().contains(TAG_TAPHOLE3_STATUS)) {
+                ironLoading3.set("1".equals(opcData.getData().toString()));
+                if (ironLoading3.get()) {
+                    mIronEndTimeRecently = opcData.getServerTime();
+                }
+            } else if (opcData.getPointName().contains(TAG_TAPHOLE4_STATUS)) {
+                ironLoading4.set("1".equals(opcData.getData().toString()));
+                if (!ironLoading4.get()) {
+                    mIronEndTimeRecently = opcData.getServerTime();
+                }
+            } else if (opcData.getPointName().contains(TAG_IRON_WEIGHT11) || opcData.getPointName().contains(TAG_IRON_WEIGHT12)) {
+                //铁水流量
+                RealtimeData ironWeight = new RealtimeData();
+                ironWeight.setDesc("铁水流量");
+                ironWeight.setUnit("t");
+                BigDecimal bigDecimalNew = new BigDecimal(opcData.getData().toString());
+                mTotalWeight = mTotalWeight.add(bigDecimalNew);
+                ironWeight.setValue(mTotalWeight);
+                mRealtimeData.put(IRON_WEIGHT, ironWeight);
+//                log.info(">>>>>>>>>>>>>{}:{},total:{}", opcData.getPointName(), opcData.getData(), totalWeight.toPlainString());
+
+                ironWeight.setTime(LocalDateUtils.formatDate(opcData.getServerTime()));
+                RedisUtils.addFixedElement(IRON_WEIGHT, ironWeight, MAX_REDIS_COUNT);
+                PushData.send2TrendIronWeight(RedisUtils.getFixedElement(IRON_WEIGHT));
+
+            } else if (opcData.getPointName().contains(FLUSH_STATUS)) {
                 RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(mOPCData.getData());
+                realtimeData.setValue(opcData.getData());
                 realtimeData.setDesc("冲渣状态");
                 mRealtimeStatus.put(FLUSH_STATUS, realtimeData);
             }
 
-            if (mOPCData.getPointName().contains(PLAN_END_TIME)) {
-                RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(mOPCData.getData());
-                realtimeData.setDesc("预计出铁结束时间");
-                mRealtimeData.put(PLAN_END_TIME, realtimeData);
-            }
-
 
-            float yc = Float.valueOf(ObjectUtils.defaultIfNull(mContext.lookupVariable("yc"), "0").toString());
-            if (yc > 190) {
-                log.info("预警出铁");
-                PushData.send2Warn(AjaxResult.success("预警出铁"));
+            BigDecimal yc = new BigDecimal(ObjectUtils.defaultIfNull(mContext.lookupVariable("yc"), "0").toString());
+            if (PRESSURE_DIFF_VALUE.compareTo(yc) < 0) {
+                //xxx分钟延迟
+                scheduledTaskManager.addTask(TASKNAME_TAPPING_WARN, 0, 3, TimeUnit.SECONDS, () -> {
+                    //堵口预警
+                    log.info("出铁预警:{}", TASKNAME_TAPPING_WARN);
+                    PushData.send2Warn(WarnData.warnTapping("压差超过阈值,请出铁"));
+                });
+            } else {
+                scheduledTaskManager.cancelTask(TASKNAME_TAPPING_WARN);
             }
 
+
         }
 
-        if (ObjectUtils.isNotEmpty(mL2Data)) {
+        if (ObjectUtils.isNotEmpty(l2Data)) {
             //铁水成分
             //预计出铁结束时间
-            String elementSi = mL2Data.getElementSi();
-            String elementS = mL2Data.getElementS();
+            String elementSi = l2Data.getElementSi();
+            String elementS = l2Data.getElementS();
 
             RealtimeData realtimeData = new RealtimeData();
             realtimeData.setValue(elementSi);
@@ -433,7 +641,7 @@ public class DeviceEventListener extends EventListener {
 
             RealtimeData realtimeData3 = new RealtimeData();
             realtimeData3.setValue(realtimeDataList);
-            realtimeData3.setDesc("铁水成分");
+            realtimeData3.setDesc("铁水成分(最近批次)");
 
             mRealtimeData.put(IRON_ELEMENT, realtimeData3);
         }
@@ -445,11 +653,7 @@ public class DeviceEventListener extends EventListener {
 
     }
 
-
-    private void operate() {
-        if (ObjectUtils.isEmpty(mOPCData)) {
-            return;
-        }
+    private synchronized void operate(OPCData mOPCData) {
         String pointName = mOPCData.getPointName();
         Object data = mOPCData.getData();
         for (IronStepVO stepDTO : mSteps) {
@@ -465,13 +669,7 @@ public class DeviceEventListener extends EventListener {
                         if (ObjectUtils.isEmpty(newPointName)) {
                             continue;
                         }
-
-                        if (newPointName.contains(".")) {
-                            newPointName = "channel." + newPointName;
-                        } else {
-                            newPointName = "channel.device." + newPointName;
-                        }
-
+                        newPointName = CustomUtil.createNewPointName(newPointName);
                         if (Objects.equals(newPointName, pointName)) {
                             //3.创建变量上下文,设置变量
                             childchild.setData(data);
@@ -481,11 +679,7 @@ public class DeviceEventListener extends EventListener {
                     if (ObjectUtils.isEmpty(newPointName)) {
                         continue;
                     }
-                    if (newPointName.contains(".")) {
-                        newPointName = "channel." + newPointName;
-                    } else {
-                        newPointName = "channel.device." + newPointName;
-                    }
+                    newPointName = CustomUtil.createNewPointName(newPointName);
                     if (Objects.equals(newPointName, pointName)) {
                         child.setData(data);
                     }
@@ -497,10 +691,7 @@ public class DeviceEventListener extends EventListener {
         setStepResult(mSteps);
 
 
-        ironReady();
-
-
-        PushData.send2Operation(mSteps, ironLoading1);
+        PushData.send2Operation(mSteps, ironLoading1.get());
 
     }
 
@@ -543,87 +734,6 @@ public class DeviceEventListener extends EventListener {
     }
 
 
-    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;
-            }
-        }
-
-        //炉前在接受到炉内出铁要求后,10分钟内打开铁口,未打开系统告警并记录
-        if (isReady) {
-            TimerTask task = new TimerTask() {
-                @Override
-                public void run() {
-                    System.out.println("倒计时结束!10分钟已到。");
-                    timer.cancel(); // 终止定时器
-                    // 打开系统告警并记录
-                    PushData.send2Warn("warn");
-                    log.info("准备出铁但是未及时出铁口,此处数据库记录");
-                }
-            };
-
-            // 倒计时10分钟(600秒)
-            long delay = 10 * 60 * 1000; // 10分钟转换为毫秒
-            // 在指定延迟后执行任务
-            timer.schedule(task, delay);
-        }
-
-        //根据PLC订阅的数据,AOD25606.PV=1为出铁中,AOD25606.PV=0出铁结束的信号,进行判断
-        //为1表示开始出铁,此时如果未超过10分钟,就取消定时器
-        //出铁结束
-        if (mOPCData.getPointName().contains(TAG_TAPHOLE1_STATUS)) {
-            //1:出铁中
-            //0:出铁结束
-            ironLoading1 = "1".equals(mOPCData.getData());
-
-            if ("1".equals(mOPCData.getData())) {
-                //由 0 -> 1
-                //表明1号铁口正在出铁
-                //根据理论铁量、实时铁水流速,推测距离出铁结束的剩余时间
-                //剩余时间=总时间-已经流去的时间
-//                mContext.lookupVariable("");
-                //计算理论铁量= 矿批 × 综合品位 × 1.06,其中矿批是指L2中的干量
-
-//                Date ironTime = mOPCData.getServerTime();
-//                lastIronEndTimeRecently
-
-
-            } else if ("0".equals(mOPCData.getData())) {
-                //由 1-> 0
-                try {
-                    timer.cancel(); // 终止定时器
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-                recordAfter();
-                recordBlock();
-
-                //出铁结束后,查询最近两次的数据
-                LambdaQueryWrapper<TIronData> queryWrapper = new QueryWrapper<TIronData>().lambda().orderByDesc(TIronData::getCtcsbh);
-                List<TIronData> oldIronDataList = ironDataService.list(queryWrapper);
-            }
-
-        }
-
-
-        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();
-        }
-
-    }
-
     /***
      * 判断是否通过
      * @param stepVO
@@ -640,7 +750,7 @@ public class DeviceEventListener extends EventListener {
             }
             stepVO.setStepName(flowName);
         } catch (Exception e) {
-            log.error("stepId:{},identifier:{},stepName:{}", stepVO.getStepId(), stepVO.getIdentifier(), flowName);
+            //log.info("stepId:{},identifier:{},stepName:{}", stepVO.getStepId(), stepVO.getIdentifier(), flowName);
         }
 
         //非流程必须项,直接放行
@@ -661,15 +771,6 @@ public class DeviceEventListener extends EventListener {
 
     }
 
-    //出铁后,记录炉次、开口时间、鱼雷罐车车号、铁口深度、铁水流速
-    private void recordAfter() {
-        ironAfterService.add(null);
-    }
-
-    //堵口后,记录堵口时间、出铁量,打泥量、是否喷溅、是否跑泥
-    private void recordBlock() {
-        ironBlockService.add(null);
-    }
 
     /***
      * 用户端点击触发
@@ -703,44 +804,72 @@ public class DeviceEventListener extends EventListener {
                 return;
             }
         }
+
+        setStepResult(mSteps);
+        PushData.send2Operation(mSteps, ironLoading1.get());
+
+        for (IronStepVO stepDTO : mSteps) {
+            for (IronStepVO child : stepDTO.getChilds()) {
+                if (Objects.equals(child.getIdentifier(), CAR_STATUS)) {
+                    RealtimeData realtimeData = new RealtimeData();
+                    realtimeData.setValue(child.getPassResult());
+                    realtimeData.setDesc("鱼雷罐车到位状态");
+                    mRealtimeStatus.put(CAR_STATUS, realtimeData);
+                }
+
+                if (Objects.equals(child.getIdentifier(), GUN_STATUS)) {
+                    RealtimeData realtimeData = new RealtimeData();
+                    realtimeData.setValue(child.getPassResult());
+                    realtimeData.setDesc("拔炮状态");
+                    mRealtimeStatus.put(GUN_STATUS, realtimeData);
+                }
+                if (Objects.equals(child.getIdentifier(), MOUTH_STATUS)) {
+                    RealtimeData realtimeData = new RealtimeData();
+                    realtimeData.setValue(child.getPassResult());
+                    realtimeData.setDesc("摆动溜嘴状态");
+                    mRealtimeStatus.put(MOUTH_STATUS, realtimeData);
+                }
+                PushData.send2RealtimeStatus(mRealtimeStatus);
+            }
+        }
+
     }
 
     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());
 
-
-            if (Objects.equals(message.getIdentifier(), CAR_STATUS)) {
-                RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(message.getData());
-                realtimeData.setDesc("鱼雷罐车到位状态");
-                mRealtimeStatus.put(CAR_STATUS, realtimeData);
-            }
-
-            if (Objects.equals(message.getIdentifier(), GUN_STATUS)) {
-                RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(message.getData());
-                realtimeData.setDesc("拔炮状态");
-                mRealtimeStatus.put(GUN_STATUS, realtimeData);
-            }
+            return true;
+        }
+        return false;
+    }
 
 
-            if (Objects.equals(message.getIdentifier(), MOUTH_STATUS)) {
-                RealtimeData realtimeData = new RealtimeData();
-                realtimeData.setValue(message.getData());
-                realtimeData.setDesc("摆动溜嘴状态");
-                mRealtimeStatus.put(MOUTH_STATUS, realtimeData);
+    /***
+     * 用户端点击触发,取消预警
+     * @param client
+     * @param message
+     */
+    @OnEvent(value = PushData.IRON_CANCEL_WARN)
+    public void cancelWarn(SocketIOClient client, WarnData message) {
+        if (ObjectUtils.isNotEmpty(message)) {
+            switch (message.getType()) {
+                case TASKNAME_OPEN_WARN:
+                    scheduledTaskManager.cancelTask(TASKNAME_OPEN_WARN);
+                    break;
+                case TASKNAME_TAPPING_WARN:
+                    scheduledTaskManager.cancelTask(TASKNAME_TAPPING_WARN);
+                    break;
+                case TASKNAME_CLOSE_WARN:
+                    scheduledTaskManager.cancelTask(TASKNAME_CLOSE_WARN);
+                    break;
+                default:
+                    break;
             }
-
-            PushData.send2RealtimeStatus(mRealtimeStatus);
-
-            return true;
         }
-        return false;
     }
 
 

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

@@ -1,56 +0,0 @@
-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("");
-    }
-
-
-
-
-
-
-
-}

+ 98 - 5
taphole-iron/src/main/java/com/sckj/iron/socketio/PushData.java

@@ -25,7 +25,22 @@ public class PushData {
     /**
      * 趋势数据
      **/
-    public static final String IRON_TREND = "IRON_TREND";
+    public static final String TrendIronWeight = "TrendIronWeight";
+
+    /**
+     * 趋势数据
+     **/
+    public static final String TrendIronTemp = "TrendIronTemp";
+
+    /**
+     * 趋势数据
+     **/
+    public static final String TrendIronSpeed = "TrendIronSpeed";
+
+    /**
+     * 趋势数据
+     **/
+    public static final String TrendIronElement = "TrendIronElement";
 
     /**
      * 实时数据
@@ -50,6 +65,18 @@ public class PushData {
     public static final String IRON_WARN = "IRON_WARN";
 
 
+    /***
+     * 开始出铁计时
+     */
+    public static final String IRON_COSTTIME = "IRON_COSTTIME";
+
+
+    /***
+     * 取消预警
+     */
+    public static final String IRON_CANCEL_WARN = "IRON_CANCEL_WARN";
+
+
     /**
      * 出铁操作
      *
@@ -63,13 +90,14 @@ public class PushData {
         //单独发消息
         socketClient.sendEvent(PushData.IRON_OPERATION, AjaxResult.success(message));
     }
+
     /**
      * 出铁操作
      *
      * @return
      * @Param
      **/
-    public static void send2Operation(Object message, String  userId) {
+    public static void send2Operation(Object message, String userId) {
         if (SocketUtil.connectMap.isEmpty()) {
             return;
         }
@@ -94,7 +122,7 @@ public class PushData {
      * @param message 发送的消息内容
      * @param isStopSendMsg  是否停止发送信息
      */
-    public static void send2Operation(Object message,boolean isStopSendMsg) {
+    public static void send2Operation(Object message, boolean isStopSendMsg) {
         if (SocketUtil.connectMap.isEmpty() || isStopSendMsg) {
             return;
         }
@@ -106,18 +134,66 @@ public class PushData {
 
 
     /**
+     * 趋势-铁水流量
+     *
+     * @return
+     * @Param
+     **/
+    public static void send2TrendIronWeight(Object message) {
+        if (SocketUtil.connectMap.isEmpty()) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.TrendIronWeight, AjaxResult.success(message));
+        }
+    }
+
+    /**
+     * 趋势-铁水温度
+     *
+     * @return
+     * @Param
+     **/
+    public static void send2TrendIronTemp(Object message) {
+        if (SocketUtil.connectMap.isEmpty()) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.TrendIronTemp, AjaxResult.success(message));
+        }
+    }
+
+    /**
+     * 趋势-
+     *
+     * @return
+     * @Param
+     **/
+    public static void send2TrendIronSpeed(Object message) {
+        if (SocketUtil.connectMap.isEmpty()) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.TrendIronSpeed, AjaxResult.success(message));
+        }
+    }
+
+    /**
      * 趋势
      *
      * @return
      * @Param
      **/
-    public static void send2Trend(Object message) {
+    public static void send2TrendIronElement(Object message) {
         if (SocketUtil.connectMap.isEmpty()) {
             return;
         }
         //
         for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
-            entry.getValue().sendEvent(PushData.IRON_TREND, AjaxResult.success(message));
+            entry.getValue().sendEvent(PushData.TrendIronElement, AjaxResult.success(message));
         }
     }
 
@@ -136,6 +212,7 @@ public class PushData {
             entry.getValue().sendEvent(PushData.IRON_REALTIME_DATA, AjaxResult.success(message));
         }
     }
+
     /**
      * 实时数据
      *
@@ -168,5 +245,21 @@ public class PushData {
         }
     }
 
+    /**
+     * 开始出铁计时
+     *
+     * @return
+     * @Param
+     **/
+    public static void send2CostTime(Object message) {
+        if (SocketUtil.connectMap.isEmpty()) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.IRON_COSTTIME, AjaxResult.success(message));
+        }
+    }
+
 
 }

+ 0 - 15
taphole-iron/src/main/java/com/sckj/iron/validate/TIronParamUpdateValidate.java

@@ -21,21 +21,6 @@ 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 = "参数类型")
     private String paramType;
 

+ 16 - 10
taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamDetailVo.java

@@ -22,20 +22,26 @@ public class TIronParamDetailVo implements Serializable {
     @ApiModelProperty(value = "")
     private Long id;
 
-    @ApiModelProperty(value = "开口耗时(s)")
-    private BigDecimal kkhs;
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
 
-    @ApiModelProperty(value = "出铁时间(s)")
-    private BigDecimal ctsj;
+    @ApiModelProperty(value = "锅炉编号")
+    private Long boilerId;
 
-    @ApiModelProperty(value = "出铁量(t)")
-    private BigDecimal ctl;
+    @ApiModelProperty(value = "参数类型")
+    private String paramType;
 
-    @ApiModelProperty(value = "出铁流速(t/s)")
-    private BigDecimal ctls;
+    @ApiModelProperty(value = "参数名称")
+    private String paramName;
 
-    @ApiModelProperty(value = "铁水温度变化(℃/s)")
-    private BigDecimal tswdbh;
+    @ApiModelProperty(value = "参数值")
+    private String paramValue;
+
+    @ApiModelProperty(value = "状态(1正常 0停用)")
+    private String status;
+
+    @ApiModelProperty(value = "排序")
+    private Integer sort;
 
 
 }

+ 16 - 10
taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamListedVo.java

@@ -22,20 +22,26 @@ public class TIronParamListedVo implements Serializable {
     @ApiModelProperty(value = "")
     private Long id;
 
-    @ApiModelProperty(value = "开口耗时(s)")
-    private BigDecimal kkhs;
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
 
-    @ApiModelProperty(value = "出铁时间(s)")
-    private BigDecimal ctsj;
+    @ApiModelProperty(value = "锅炉编号")
+    private Long boilerId;
 
-    @ApiModelProperty(value = "出铁量(t)")
-    private BigDecimal ctl;
+    @ApiModelProperty(value = "参数类型")
+    private String paramType;
 
-    @ApiModelProperty(value = "出铁流速(t/s)")
-    private BigDecimal ctls;
+    @ApiModelProperty(value = "参数名称")
+    private String paramName;
 
-    @ApiModelProperty(value = "铁水温度变化(℃/s)")
-    private BigDecimal tswdbh;
+    @ApiModelProperty(value = "参数值")
+    private String paramValue;
+
+    @ApiModelProperty(value = "状态(1正常 0停用)")
+    private String status;
+
+    @ApiModelProperty(value = "排序")
+    private Integer sort;
 
 
 }

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

@@ -86,6 +86,12 @@ public class L2Data implements Serializable {
         dos.writeUTF(totalDry);
         dos.writeUTF(ironStarttime);
         dos.writeUTF(ironEndtime);
+        dos.writeUTF(elementC);
+        dos.writeUTF(elementSi);
+        dos.writeUTF(elementMn);
+        dos.writeUTF(elementP);
+        dos.writeUTF(elementS);
+        dos.writeUTF(elementTi);
     }
 
     public static L2Data fromDataStream(DataInputStream dis) throws Exception {
@@ -101,6 +107,7 @@ public class L2Data implements Serializable {
         data.openDepth = dis.readUTF();
         data.totalDry = dis.readUTF();
         data.ironStarttime = dis.readUTF();
+        data.ironEndtime = dis.readUTF();
         data.elementC = dis.readUTF();
         data.elementSi = dis.readUTF();
         data.elementMn = dis.readUTF();

+ 57 - 0
taphole-opc/src/main/java/com/sckj/opc/dto/L2Material.java

@@ -0,0 +1,57 @@
+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;
+
+@Data
+public class L2Material implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @TableId(value="id", type= IdType.AUTO)
+    @ApiModelProperty(value = "id")
+    private Long id;
+
+    @ApiModelProperty(value = "锅炉编号")
+    private Long boilerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private Long tapholeId;
+
+    @ApiModelProperty(value = "L1发过来的charge号")
+    private String chargeNo;
+
+    @ApiModelProperty(value = "下料时间点")
+    private String downTime;
+
+    @ApiModelProperty(value = "干量")
+    private String dryWeight;
+
+
+    public void toDataStream(DataOutputStream dos) throws Exception {
+        dos.writeUTF(chargeNo);
+        dos.writeUTF(downTime);
+        dos.writeUTF(dryWeight);
+    }
+
+    public static L2Material fromDataStream(DataInputStream dis) throws Exception {
+        L2Material data = new L2Material();
+        data.chargeNo = dis.readUTF();
+        data.downTime = dis.readUTF();
+        data.dryWeight = dis.readUTF();
+        return data;
+    }
+
+
+
+}

+ 13 - 4
taphole-opc/src/main/java/com/sckj/opc/opcua/L2DataServiceImpl.java

@@ -2,6 +2,7 @@ package com.sckj.opc.opcua;
 
 import com.google.common.eventbus.AsyncEventBus;
 import com.sckj.opc.dto.L2Data;
+import com.sckj.opc.dto.L2Material;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -84,10 +85,18 @@ public class L2DataServiceImpl {
             while (true) {
                 try {
                     // 从输入流读取L2Data对象
-                    L2Data receivedData = L2Data.fromDataStream(dis);
-                    //出铁操作
-                    asyncEventBus.post(receivedData);
-                    System.out.println("Received L2Data from server: \n" + receivedData);
+                    // 新增:读取数据类型标识(需要服务端配合发送类型头)
+                    String dataType = dis.readUTF();
+                    if ("L2Data".equals(dataType)) {
+                        L2Data receivedData = L2Data.fromDataStream(dis);
+                        asyncEventBus.post(receivedData); //出铁操作
+//                        System.out.println("Received L2Data from server: \n" + receivedData);
+                    } else if ("L2Material".equals(dataType)) {
+                        L2Material receivedMaterial = L2Material.fromDataStream(dis);
+                        // 新增材料处理逻辑,例如:
+                         asyncEventBus.post(receivedMaterial);
+//                        System.out.println("Received L2Material from server: \n" + receivedMaterial);
+                    }
                 } catch (IOException e) {
                     System.err.println("Connection lost. Attempting to reconnect...");
                     socket.close();

+ 69 - 48
taphole-opc/src/main/java/com/sckj/opc/opcua/OPCDAServiceImpl.java

@@ -9,24 +9,27 @@ import com.sckj.opc.entity.OPCServer;
 import com.sckj.opc.service.OPCDataServiceImpl;
 import com.sckj.opc.service.OPCPointServiceImpl;
 import com.sckj.opc.service.OPCServerServiceImpl;
+import com.sckj.opc.utils.CustomUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.jinterop.dcom.common.JIException;
 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;
 
 import javax.annotation.PreDestroy;
 import javax.annotation.Resource;
-import java.net.UnknownHostException;
-import java.util.*;
-import java.util.concurrent.*;
-
-import static org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint;
+import java.text.DecimalFormat;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 
 @Service
 @Slf4j
@@ -48,16 +51,16 @@ public class OPCDAServiceImpl {
     ThreadPoolTaskExecutor taskExecutor;
 
     private ConcurrentHashMap<Long, Server> mOPCDaClientMap = new ConcurrentHashMap<>();
-    private ConcurrentHashMap<Long, Object> mOPCDaPointsMap = new ConcurrentHashMap<>();
+    private ConcurrentHashMap<String, OPCData> mOPCDaPointsMap = new ConcurrentHashMap<>();
 
 
     /**
      * 获得基础的连接信息
      */
     public Server createServer(OPCServer opcServer) {
-        if (mOPCDaClientMap.containsKey(opcServer.getId())) {
-            return mOPCDaClientMap.get(opcServer.getId());
-        }
+//        if (mOPCDaClientMap.containsKey(opcServer.getId())) {
+//            return mOPCDaClientMap.get(opcServer.getId());
+//        }
         final ConnectionInformation ci = new ConnectionInformation();
         ci.setHost(opcServer.getIp());          // OPCDA IP
         ci.setUser(opcServer.getUsername());              // 用户名,配置DCOM时配置的
@@ -66,21 +69,20 @@ public class OPCDAServiceImpl {
 
         log.info("Create Server : {}", opcServer);
 
-        log.info("availableProcessors:{}",Runtime.getRuntime().availableProcessors());
+        log.info("availableProcessors:{}", Runtime.getRuntime().availableProcessors());
         // 启动服务
         final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
         AutoReconnectController controller = new AutoReconnectController(server);
         // 连接到服务
         controller.connect();
-        mOPCDaClientMap.put(opcServer.getId(), server);
+//        mOPCDaClientMap.put(opcServer.getId(), server);
         return server;
     }
 
 
     public Object createSubscription(OPCServer opcServer, OPCPoint opcPoint) {
         StringBuilder sb = new StringBuilder();
-        if (ObjectUtils.isNotEmpty(opcPoint) && !mOPCDaPointsMap.containsKey(opcPoint.getId())) {
-            Map<String, Object> pointChangedMap = new LinkedHashMap<>();
+        if (ObjectUtils.isNotEmpty(opcPoint) && !mOPCDaPointsMap.containsKey(opcPoint.getPointName())) {
             Future<String> future = taskExecutor.submit(new Callable<String>() {
                 @Override
                 public String call() {
@@ -90,17 +92,15 @@ public class OPCDAServiceImpl {
 
                         String newPointName = opcPoint.getPointName();
 
-                        if(ObjectUtils.isEmpty(newPointName)){
+                        if (ObjectUtils.isEmpty(newPointName)) {
                             return null;
                         }
 
-                        if(newPointName.contains(".")){
-                            newPointName = "channel." + newPointName;
-                        }else{
-                            newPointName = "channel.device." + newPointName;
-                        }
+                        newPointName =  CustomUtil.createNewPointName(newPointName);
+
+                        log.info("{} start subscribe", newPointName);
 
-                        log.info("{} start subscribe",newPointName);
+                        mOPCDaPointsMap.put(opcPoint.getPointName(), OPCData.builder().build());
 
                         access.addItem(newPointName, (item, itemstate) -> {
                             int errorCode = itemstate.getErrorCode();
@@ -112,30 +112,47 @@ public class OPCDAServiceImpl {
                             } catch (JIException e) {
                                 e.printStackTrace();
                             }
-                            //DA中订阅是按照定时计算的,存在重复的数据项,进行过滤
-                            if (!Objects.equals(pointChangedMap.get(item.getId()), object)) {
-                                pointChangedMap.put(item.getId(), object);
-                                OPCData opcData = OPCData.builder()
-                                        .data(object)
-                                        .serverTime(calendar.getTime())
-                                        .sourceTime(calendar.getTime())
-                                        .statusCode((long) errorCode)
-                                        .pointName(pointName)
-                                        .build();
-                                //post给其他模块使用
-                                asyncEventBus.post(opcData);
-                                //opcDataService.save(opcData);
-                                log.info("DA,{},{}",item.getId(), itemstate.toString());
+                            synchronized (mOPCDaPointsMap) {
+                                //DA中订阅是按照定时计算的,存在重复的数据项,进行过滤
+                                OPCData previousData = mOPCDaPointsMap.get(opcPoint.getPointName());
+                                Object currentData = object;
+
+                                //直接比较原始对象,避免字符串转换误差
+                                boolean isNewData = previousData == null ||
+                                        !Objects.equals(previousData.getData(), currentData);
+
+                                // 添加数值精度处理(处理小数点后2位)
+                                if (!isNewData && currentData instanceof Number) {
+                                    DecimalFormat df = new DecimalFormat("#.##");
+                                    String prev = df.format(previousData.getData());
+                                    String curr = df.format(currentData);
+                                    isNewData = !prev.equals(curr);
+                                }
+
+                                if (isNewData) {
+                                    OPCData opcData = OPCData.builder()
+                                            .data(object)
+                                            .serverTime(calendar.getTime())
+                                            .sourceTime(calendar.getTime())
+                                            .statusCode((long) errorCode)
+                                            .pointName(pointName)
+                                            .build();
+                                    // 使用put原子操作更新数据
+                                    mOPCDaPointsMap.put(opcPoint.getPointName(), opcData);
+                                    //post给其他模块使用
+                                    asyncEventBus.post(opcData);
+                                    log.debug("DA,{},{}", item.getId(), itemstate);
+                                }
                             }
                         });
 
                         access.bind();
-                        mOPCDaPointsMap.put(opcPoint.getId(), opcPoint);
-                        while (mOPCDaPointsMap.containsKey(opcPoint.getId())) {
+
+                        while (mOPCDaPointsMap.containsKey(opcPoint.getPointName())) {
                             //阻塞,直到关闭订阅
                         }
                         access.unbind();
-                        log.info("{} stop subscribe",opcPoint.getPointName());
+                        log.info("{} stop subscribe", opcPoint.getPointName());
                     } catch (Exception e) {
                         e.printStackTrace();
                         return e.getMessage();
@@ -144,15 +161,17 @@ public class OPCDAServiceImpl {
                 }
             });
 
-            try {
-                String result = future.get(1,TimeUnit.SECONDS); //
-                log.error(">>> error:{}", result);
-                if (ObjectUtils.isNotEmpty(result)) {
-                    sb.append(opcPoint.getPointName() + "订阅异常:" + result);
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
+//            try {
+//                String result = future.get(10, TimeUnit.SECONDS); //
+//                log.error(">>> error:{}", result);
+//                if (ObjectUtils.isNotEmpty(result)) {
+//                    sb.append(opcPoint.getPointName() + "订阅异常:" + result);
+//                }
+//            } catch (Exception e) {
+//                e.printStackTrace();
+//                log.info("订阅异常:{}", opcPoint.getPointName());
+//            }
+
         }
         return sb;
     }
@@ -202,7 +221,9 @@ public class OPCDAServiceImpl {
             pointQueryWrapper.lambda().eq(OPCPoint::getOpcServerId, opcServer.getId()).eq(OPCPoint::getStatus, "1");
             List<OPCPoint> opcPointList = opcPointService.list(pointQueryWrapper);
             if (ObjectUtils.isNotEmpty(opcPointList)) {
+                log.info("start point list:");
                 for (OPCPoint opcPoint : opcPointList) {
+                    log.info(opcPoint.getPointName());
                     createSubscription(opcServer, opcPoint);
                 }
             }

+ 11 - 1
taphole-opc/src/main/java/com/sckj/opc/utils/CustomUtil.java

@@ -2,8 +2,8 @@ package com.sckj.opc.utils;
 
 import com.google.common.collect.Sets;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
-import org.springframework.util.StringUtils;
 
 import java.net.*;
 import java.util.*;
@@ -75,6 +75,16 @@ public class CustomUtil {
     }
 
 
+    public static String createNewPointName(String pointName) {
+        if (pointName.contains(".")) {
+            if (StringUtils.countMatches(pointName, ".") == 1) {
+                pointName = "channel." + pointName;
+            }
+        } else {
+            pointName = "channel.device." + pointName;
+        }
+        return pointName;
+    }
 
 
 }

+ 4 - 1
taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogListedVo.java

@@ -31,7 +31,10 @@ public class TExceptionLogListedVo implements Serializable {
     private String reportedStatus;
 
     @ApiModelProperty(value = "锅炉编号")
-    private Integer glId;
+    private Integer boilerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private Integer tapholeId;
 
 
 }