1
0

7 Commity 35abbf7fc7 ... 6fdca84ec6

Autor SHA1 Správa Dátum
  zhifei 6fdca84ec6 对接读码器 1 rok pred
  zhifei 434deae870 添加设备日志及设备列表 1 rok pred
  zhifei c0e69e20a7 添加设备日志模块 1 rok pred
  zhifei 2b960f9e61 对接MES系统 1 rok pred
  zhifei bfb26edfc6 修改PLC连接包 1 rok pred
  zhifei 723b171ea0 tcp连接添加重试 1 rok pred
  zhifei 9b65b0fee6 ---添加喷码机构的对接 1 rok pred
60 zmenil súbory, kde vykonal 3168 pridanie a 301 odobranie
  1. 4 4
      pom.xml
  2. 1 1
      warewms-admin/src/main/resources/application-dev.yml
  3. 1 1
      warewms-admin/src/main/resources/application-prod.yml
  4. 12 10
      warewms-admin/src/main/resources/application.yml
  5. 77 1
      warewms-common/src/main/java/com/warewms/common/core/domain/base/page/PageDomain.java
  6. 27 37
      warewms-common/src/main/java/com/warewms/common/core/domain/base/page/TableDataInfo.java
  7. 2 2
      warewms-system/pom.xml
  8. 1 0
      warewms-system/src/main/java/com/warewms/hailiang/MES/MesService.java
  9. 3 1
      warewms-system/src/main/java/com/warewms/hailiang/MES/impl/MesServiceImpl.java
  10. 70 0
      warewms-system/src/main/java/com/warewms/hailiang/common/ChannelMap.java
  11. 75 0
      warewms-system/src/main/java/com/warewms/hailiang/common/DtuManage.java
  12. 51 0
      warewms-system/src/main/java/com/warewms/hailiang/common/MyDecoder.java
  13. 90 0
      warewms-system/src/main/java/com/warewms/hailiang/common/MyEncoder.java
  14. 55 0
      warewms-system/src/main/java/com/warewms/hailiang/common/NettyServer.java
  15. 28 0
      warewms-system/src/main/java/com/warewms/hailiang/common/NettyServerChannelInitializer.java
  16. 152 0
      warewms-system/src/main/java/com/warewms/hailiang/common/NettyServerHandler.java
  17. 63 0
      warewms-system/src/main/java/com/warewms/hailiang/config/LaunchRunner.java
  18. 5 5
      warewms-system/src/main/java/com/warewms/hailiang/config/PlcConfig.java
  19. 0 86
      warewms-system/src/main/java/com/warewms/hailiang/config/PlcConnectServiceRunner.java
  20. 29 0
      warewms-system/src/main/java/com/warewms/hailiang/config/SocketProperties.java
  21. 121 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader12Connect.java
  22. 121 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader13Connect.java
  23. 121 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader14Connect.java
  24. 120 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader3Connect.java
  25. 121 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader5Connect.java
  26. 121 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader6Connect.java
  27. 122 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader7Connect.java
  28. 121 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader8Connect.java
  29. 121 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader9Connect.java
  30. 109 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/InkjetPrintersConnect.java
  31. 23 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/TCPConnectBase.java
  32. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader12Handler.java
  33. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader13Handler.java
  34. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader14Handler.java
  35. 47 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader3Handler.java
  36. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader5Handler.java
  37. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader6Handler.java
  38. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader7Handler.java
  39. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader8Handler.java
  40. 45 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader9Handler.java
  41. 51 0
      warewms-system/src/main/java/com/warewms/hailiang/connect/handler/InkjetPrintersHandler.java
  42. 32 0
      warewms-system/src/main/java/com/warewms/hailiang/contoller/DeviceController.java
  43. 28 0
      warewms-system/src/main/java/com/warewms/hailiang/contoller/DeviceLogController.java
  44. 33 0
      warewms-system/src/main/java/com/warewms/hailiang/contoller/TestContoller.java
  45. 73 0
      warewms-system/src/main/java/com/warewms/hailiang/domian/Device.java
  46. 46 0
      warewms-system/src/main/java/com/warewms/hailiang/domian/DeviceLog.java
  47. 28 0
      warewms-system/src/main/java/com/warewms/hailiang/enums/CodeReaderEnum.java
  48. 53 0
      warewms-system/src/main/java/com/warewms/hailiang/enums/InkjetPrintersDirectivesEnum.java
  49. 22 2
      warewms-system/src/main/java/com/warewms/hailiang/enums/WeighPlcEnum.java
  50. 102 0
      warewms-system/src/main/java/com/warewms/hailiang/init/PlcConnectServiceRunner.java
  51. 62 0
      warewms-system/src/main/java/com/warewms/hailiang/init/TcpServiceRunner.java
  52. 19 0
      warewms-system/src/main/java/com/warewms/hailiang/mapper/DeviceLogMapper.java
  53. 20 0
      warewms-system/src/main/java/com/warewms/hailiang/service/DeviceLogService.java
  54. 16 0
      warewms-system/src/main/java/com/warewms/hailiang/service/DeviceService.java
  55. 56 0
      warewms-system/src/main/java/com/warewms/hailiang/service/impl/DeviceLogServiceImpl.java
  56. 47 0
      warewms-system/src/main/java/com/warewms/hailiang/service/impl/DeviceServiceImpl.java
  57. 0 147
      warewms-system/src/main/java/com/warewms/hailiang/util/HslTools.java
  58. 78 0
      warewms-system/src/main/java/com/warewms/hailiang/util/ParseMsgTools.java
  59. 4 4
      warewms-system/src/main/java/com/warewms/system/config/SecurityConfig.java
  60. 24 0
      warewms-system/src/main/resources/mapper/hailiang/DeviceLogMapper.xml

+ 4 - 4
pom.xml

@@ -43,7 +43,7 @@
         <knife4j.spring.version>3.0.3</knife4j.spring.version>
         <guava.version>23.0</guava.version>
         <guava.retry.version>2.0.0</guava.retry.version>
-        <HslCommunication.version>2.0.2</HslCommunication.version>
+        <iotCommunication.version>1.4.2</iotCommunication.version>
     </properties>
 
     <!-- 依赖声明 -->
@@ -205,9 +205,9 @@
             </dependency>
 
             <dependency>
-                <groupId>com.github.dathlin</groupId>
-                <artifactId>HslCommunication</artifactId>
-                <version>${HslCommunication.version}</version>
+                <groupId>com.github.xingshuangs</groupId>
+                <artifactId>iot-communication</artifactId>
+                <version>${iotCommunication.version}</version>
             </dependency>
 
         </dependencies>

+ 1 - 1
warewms-admin/src/main/resources/application-dev.yml

@@ -174,7 +174,7 @@ mybatis-plus:
     dbConfig:
       # 主键类型
       # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
-      idType: AUTO
+      idType: ASSIGN_ID
       logic-delete-field: deleted # 全局逻辑删除的实体字段名
       logic-delete-value: 1 # 逻辑已删除值(默认为 1)
       logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

+ 1 - 1
warewms-admin/src/main/resources/application-prod.yml

@@ -174,7 +174,7 @@ mybatis-plus:
     dbConfig:
       # 主键类型
       # AUTO 自增 NONE 空 INPUT 用户输入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
-      idType: AUTO
+      idType: ASSIGN_ID
       logic-delete-field: deleted # 全局逻辑删除的实体字段名
       logic-delete-value: 1 # 逻辑已删除值(默认为 1)
       logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

+ 12 - 10
warewms-admin/src/main/resources/application.yml

@@ -1,12 +1,10 @@
 # 指定环境的默认配置
 spring:
   profiles:
-    active: dev
+    active: test
 socket:
-  # 监听端口 8090
-  port: 8090
-  #ip地址
-  host: 127.0.0.1
+  InkjetPrinters:
+
 
 plc:
   plcList[0]:
@@ -15,17 +13,20 @@ plc:
     slot: 1
     rack: 0
     name: ChengZhongPlc
-    siemensPLCS: S1200
+    ePlcType: S1200
+    heartbeat: DB11.0.0
   plcList[1]:
-    ip: 172.20.52.22
+    ip: 172.20.27.2
     enable: false
-    name: XiMianPlc
-    siemensPLCS: S1500
+    name: DaoJiaoJiPlc
+    ePlcType: S200_SMART
+    heartbeat:
   plcList[2]:
     ip: 172.20.52.24
     enable: false
     name: ZaZhiPlc
-    siemensPLCS: S1500
+    ePlcType: S1500
+    heartbeat:
 
 MES:
   address: http://192.20.2.4:9090
@@ -35,3 +36,4 @@ MES:
   getBatchNoResultUrl: /api/SprayCode/SprayBatchNoResult
   #铣面
   MillingSurfaceUrl: /api/SprayCode/SprayMillingSurface
+

+ 77 - 1
warewms-common/src/main/java/com/warewms/common/core/domain/base/page/PageDomain.java

@@ -1,13 +1,23 @@
 package com.warewms.common.core.domain.base.page;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.warewms.common.exception.ServiceException;
+import com.warewms.common.utils.StringUtils;
+import com.warewms.common.utils.sql.SqlUtil;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import static com.warewms.common.core.domain.base.page.PageSort.ASC;
 import static com.warewms.common.core.domain.base.page.PageSort.DESC;
 
 /**
  * 分页数据
- * 
+ *
  * @author ruoyi
  */
 public class PageDomain
@@ -24,6 +34,19 @@ public class PageDomain
     /** 排序的方向desc或者asc */
     private String isAsc = "asc";
 
+    /**
+     * 当前记录起始索引 默认值
+     */
+    public static final int DEFAULT_PAGE_NUM = 1;
+
+    /**
+     * 每页显示记录数 默认值 默认查全部
+     */
+    public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
+
+    private static final String SEPARATOR = ",";
+
+
     public Integer getPageNum()
     {
         return pageNum;
@@ -63,5 +86,58 @@ public class PageDomain
         this.isAsc = CharSequenceUtil.equals(ASC.getDescription(), isAsc) ? ASC.getDescription() : DESC.getDescription(); ;
     }
 
+    public <T> Page<T> build() {
+        Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM);
+        Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE);
+        if (pageNum <= 0) {
+            pageNum = DEFAULT_PAGE_NUM;
+        }
+        Page<T> page = new Page<>(pageNum, pageSize);
+        List<OrderItem> orderItems = buildOrderItem();
+        if (CollUtil.isNotEmpty(orderItems)) {
+            page.addOrder(orderItems);
+        }
+        return page;
+    }
 
+    /**
+     * 构建排序
+     *
+     * 支持的用法如下:
+     * {isAsc:"asc",orderByColumn:"id"} order by id asc
+     * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
+     * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc
+     * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc
+     */
+    private List<OrderItem> buildOrderItem() {
+        if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) {
+            return null;
+        }
+        String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
+        orderBy = StringUtils.toUnderScoreCase(orderBy);
+
+        // 兼容前端排序类型
+        isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"});
+
+        String[] orderByArr = orderBy.split(SEPARATOR);
+        String[] isAscArr = isAsc.split(SEPARATOR);
+        if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) {
+            throw new ServiceException("排序参数有误");
+        }
+
+        List<OrderItem> list = new ArrayList<>();
+        // 每个字段各自排序
+        for (int i = 0; i < orderByArr.length; i++) {
+            String orderByStr = orderByArr[i];
+            String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i];
+            if ("asc".equals(isAscStr)) {
+                list.add(OrderItem.asc(orderByStr));
+            } else if ("desc".equals(isAscStr)) {
+                list.add(OrderItem.desc(orderByStr));
+            } else {
+                throw new ServiceException("排序参数有误");
+            }
+        }
+        return list;
+    }
 }

+ 27 - 37
warewms-common/src/main/java/com/warewms/common/core/domain/base/page/TableDataInfo.java

@@ -1,16 +1,21 @@
 package com.warewms.common.core.domain.base.page;
 
+import cn.hutool.http.HttpStatus;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.warewms.common.core.domain.base.BaseEntity;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.io.Serializable;
 import java.util.List;
 
 /**
  * 表格分页数据对象
- * 
+ *
  * @author ruoyi
  */
-public class TableDataInfo<T extends BaseEntity> implements Serializable
+@Data
+public class TableDataInfo<T> implements Serializable
 {
     private static final long serialVersionUID = 1L;
 
@@ -35,7 +40,7 @@ public class TableDataInfo<T extends BaseEntity> implements Serializable
 
     /**
      * 分页
-     * 
+     *
      * @param list 列表数据
      * @param total 总记录数
      */
@@ -45,43 +50,28 @@ public class TableDataInfo<T extends BaseEntity> implements Serializable
         this.total = total;
     }
 
-    public long getTotal()
-    {
-        return total;
-    }
-
-    public void setTotal(long total)
-    {
-        this.total = total;
+    public static <T> TableDataInfo<T> build(IPage<T> page) {
+        TableDataInfo<T> rspData = new TableDataInfo<>();
+        rspData.setCode(HttpStatus.HTTP_OK);
+        rspData.setMsg("查询成功");
+        rspData.setRows(page.getRecords());
+        rspData.setTotal(page.getTotal());
+        return rspData;
     }
 
-    public List<?> getRows()
-    {
-        return rows;
+    public static <T> TableDataInfo<T> build(List<T> list) {
+        TableDataInfo<T> rspData = new TableDataInfo<>();
+        rspData.setCode(HttpStatus.HTTP_OK);
+        rspData.setMsg("查询成功");
+        rspData.setRows(list);
+        rspData.setTotal(list.size());
+        return rspData;
     }
 
-    public void setRows(List<T> rows)
-    {
-        this.rows = rows;
-    }
-
-    public int getCode()
-    {
-        return code;
-    }
-
-    public void setCode(int code)
-    {
-        this.code = code;
-    }
-
-    public String getMsg()
-    {
-        return msg;
-    }
-
-    public void setMsg(String msg)
-    {
-        this.msg = msg;
+    public static <T> TableDataInfo<T> build() {
+        TableDataInfo<T> rspData = new TableDataInfo<>();
+        rspData.setCode(HttpStatus.HTTP_OK);
+        rspData.setMsg("查询成功");
+        return rspData;
     }
 }

+ 2 - 2
warewms-system/pom.xml

@@ -28,8 +28,8 @@
         </dependency>
 
         <dependency>
-            <groupId>com.github.dathlin</groupId>
-            <artifactId>HslCommunication</artifactId>
+            <groupId>com.github.xingshuangs</groupId>
+            <artifactId>iot-communication</artifactId>
         </dependency>
     </dependencies>
 

+ 1 - 0
warewms-system/src/main/java/com/warewms/hailiang/MES/MesService.java

@@ -1,6 +1,7 @@
 package com.warewms.hailiang.MES;
 
 import cn.hutool.json.JSONObject;
+import org.springframework.stereotype.Service;
 
 /**
  * Created with IntelliJ IDEA.

+ 3 - 1
warewms-system/src/main/java/com/warewms/hailiang/MES/impl/MesServiceImpl.java

@@ -8,6 +8,7 @@ import cn.hutool.json.JSONUtil;
 import com.warewms.hailiang.MES.MesService;
 import io.swagger.util.Json;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
 
 /**
  * Created with IntelliJ IDEA.
@@ -18,6 +19,7 @@ import org.springframework.beans.factory.annotation.Value;
  * To change this template use File | Settings | File Templates.
  * Description: MES对接实现类
  **/
+@Service
 public class MesServiceImpl implements MesService {
     @Value("${MES.address}")
     private String MESAddress;
@@ -25,7 +27,7 @@ public class MesServiceImpl implements MesService {
     @Value("${MES.getBatchNoUrl}")
     private String getBatchNoUrl;
 
-    @Value("${MES.getBatchNoResultURl}")
+    @Value("${MES.getBatchNoResultUrl}")
     private String getBatchNoResultURl;
 
 

+ 70 - 0
warewms-system/src/main/java/com/warewms/hailiang/common/ChannelMap.java

@@ -0,0 +1,70 @@
+package com.warewms.hailiang.common;
+
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelId;
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
+import org.springframework.util.CollectionUtils;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 功能描述: 管理通道Map类
+ *
+ * @Author keLe
+ * @Date 2022/8/26
+ */
+public class ChannelMap {
+
+    /**
+     * 管理一个全局map,保存连接进服务端的通道数量
+     */
+    private static final ConcurrentHashMap<ChannelId, Channel> CHANNEL_MAP = new ConcurrentHashMap<>(128);
+
+    public static ConcurrentHashMap<ChannelId, Channel> getChannelMap() {
+        return CHANNEL_MAP;
+    }
+
+    /**
+     *  获取指定name的channel
+     */
+    public static Channel getChannelByName(ChannelId channelId){
+        if(CollectionUtils.isEmpty(CHANNEL_MAP)){
+            return null;
+        }
+        return CHANNEL_MAP.get(channelId);
+    }
+
+    /**
+     *  将通道中的消息推送到每一个客户端
+     */
+    public static boolean pushNewsToAllClient(String obj){
+        if(CollectionUtils.isEmpty(CHANNEL_MAP)){
+            return false;
+        }
+        for(ChannelId channelId: CHANNEL_MAP.keySet()) {
+            Channel channel = CHANNEL_MAP.get(channelId);
+            channel.writeAndFlush(new TextWebSocketFrame(obj));
+        }
+        return true;
+    }
+
+    /**
+     *  将channel和对应的name添加到ConcurrentHashMap
+     */
+    public static void addChannel(ChannelId channelId,Channel channel){
+        CHANNEL_MAP.put(channelId,channel);
+    }
+
+    /**
+     *  移除掉name对应的channel
+     */
+    public static boolean removeChannelByName(ChannelId channelId){
+        if(CHANNEL_MAP.containsKey(channelId)){
+            CHANNEL_MAP.remove(channelId);
+            return true;
+        }
+        return false;
+    }
+
+}

+ 75 - 0
warewms-system/src/main/java/com/warewms/hailiang/common/DtuManage.java

@@ -0,0 +1,75 @@
+package com.warewms.hailiang.common;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelId;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 功能描述: 定时发送Dtu报文
+ *
+ * @Author keLe
+ * @Date 2022/8/29
+ */
+@Slf4j
+@Component
+public class DtuManage {
+
+
+    public void sendMsg(){
+        ConcurrentHashMap<ChannelId, Channel> channelMap = ChannelMap.getChannelMap();
+        if(CollectionUtils.isEmpty(channelMap)){
+            return;
+        }
+        ConcurrentHashMap.KeySetView<ChannelId, Channel> channelIds = channelMap.keySet();
+        byte[] msgBytes = {0x01, 0x03, 0x00, 0x02, 0x00, 0x01, 0x25, (byte) 0xCA};
+        for(ChannelId channelId : channelIds){
+            Channel channel = ChannelMap.getChannelByName(channelId);
+            // 判断是否活跃
+            if(channel==null || !channel.isActive()){
+                ChannelMap.getChannelMap().remove(channelId);
+                log.info("客户端:{},连接已经中断",channelId);
+                return ;
+            }
+            // 指令发送
+            ByteBuf buffer = Unpooled.buffer();
+            log.info("开始发送报文:{}",Arrays.toString(msgBytes));
+            buffer.writeBytes(msgBytes);
+            channel.writeAndFlush(buffer).addListener((ChannelFutureListener) future -> {
+                if (future.isSuccess()) {
+                    log.info("客户端:{},回写成功:{}",channelId,Arrays.toString(msgBytes));
+                } else {
+                    log.info("客户端:{},回写失败:{}",channelId,Arrays.toString(msgBytes));
+                }
+            });
+        }
+    }
+
+    /**
+     * 功能描述: 定时删除不活跃的连接
+     * @Author keLe
+     * @Date 2022/8/26
+     * @return void
+     */
+    public void deleteInactiveConnections(){
+        ConcurrentHashMap<ChannelId, Channel> channelMap = ChannelMap.getChannelMap();
+        if(!CollectionUtils.isEmpty(channelMap)){
+            for (Map.Entry<ChannelId, Channel> next : channelMap.entrySet()) {
+                ChannelId channelId = next.getKey();
+                Channel channel = next.getValue();
+                if (!channel.isActive()) {
+                    channelMap.remove(channelId);
+                    log.info("客户端:{},连接已经中断",channelId);
+                }
+            }
+        }
+    }
+}

+ 51 - 0
warewms-system/src/main/java/com/warewms/hailiang/common/MyDecoder.java

@@ -0,0 +1,51 @@
+package com.warewms.hailiang.common;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+
+import java.util.List;
+
+/**
+ * 功能描述: 自定义接收消息格式
+ */
+public class MyDecoder extends ByteToMessageDecoder {
+    @Override
+    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Object> out) throws Exception {
+        byte[] data = new byte[in.readableBytes()];
+        in.readBytes(data);
+        String msg = bytesToHexString(data);
+        out.add(msg);
+    }
+
+    public String bytesToHexString(byte[] bArray) {
+        StringBuffer sb = new StringBuffer(bArray.length);
+        String sTemp;
+        for (int i = 0; i < bArray.length; i++) {
+            sTemp = Integer.toHexString(0xFF & bArray[i]);
+            if (sTemp.length() < 2) {
+                sb.append(0);
+            }
+            sb.append(sTemp.toUpperCase());
+        }
+        return sb.toString();
+    }
+
+    public static String toHexString1(byte[] b) {
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < b.length; ++i) {
+            buffer.append(toHexString1(b[i]));
+        }
+        return buffer.toString();
+    }
+
+    public static String toHexString1(byte b) {
+        String s = Integer.toHexString(b & 0xFF);
+        if (s.length() == 1) {
+            return "0" + s;
+        } else {
+            return s;
+        }
+    }
+
+}

+ 90 - 0
warewms-system/src/main/java/com/warewms/hailiang/common/MyEncoder.java

@@ -0,0 +1,90 @@
+package com.warewms.hailiang.common;
+
+import cn.hutool.core.util.ByteUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.Scanner;
+import java.util.Stack;
+
+/**
+ * 功能描述: 自定义发送消息格式
+ *
+ */
+public class MyEncoder extends MessageToByteEncoder<String> {
+
+    @Override
+    protected void encode(ChannelHandlerContext channelHandlerContext, String s, ByteBuf byteBuf) throws Exception {
+        //将16进制字符串转为数组
+        byteBuf.writeBytes(hexString2Bytes(s));
+    }
+
+    /**
+     * 功能描述: 16进制字符串转字节数组
+     * @param src 16进制字符串
+     * @return byte[]
+     */
+    public static byte[] hexString2Bytes(String src) {
+        int l = src.length() / 2;
+        byte[] ret = new byte[l];
+        for (int i = 0; i < l; i++) {
+            ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
+        }
+        return ret;
+    }
+
+    /**
+     * 字符串转16进制字符串
+     * @param str
+     * @return
+     */
+    public static String StringTohexString(String str){
+        StringBuffer sb = new StringBuffer();
+        //将字符串转换为字符数组
+        char ch[] = str.toCharArray();
+        for(int i = 0; i < ch.    length; i++) {
+            String hexString = Integer.toHexString(ch[i]);
+            sb.append(hexString);
+        }
+        return sb.toString();
+    }
+    public static void main(String[] args) throws UnsupportedEncodingException {
+//        String str = "23";
+//        StringBuffer sb = new StringBuffer();
+//        //将字符串转换为字符数组
+//        char ch[] = str.toCharArray();
+//        for(int i = 0; i < ch.    length; i++) {
+//            String hexString = Integer.toHexString(ch[i]);
+//            sb.append(hexString);
+//        }
+//        String result = sb.toString();
+
+//        System.out.println(result);
+//        byte[] bytes = new byte[37];
+//        bytes[0] = 00;
+//        String s ="E800230100063132333332310200173131313131313131313131313131313131313131313131";
+
+//        String s ="E8 00 23 01 00 06 31 32 33 33 32 31 02 00 17 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31";
+//        String[] s2 = s.split(" ");
+//        int i  =Integer.parseInt(s2[0],16) ^ Integer.parseInt(s2[1],16) ;
+//        for (int i1 = 1; i1 < s2.length-1; i1++) {
+//            i = i ^ Integer.parseInt(s2[i1+1],16);
+//        }
+//        System.out.println(Integer.toHexString(i));
+
+//        System.out.println(Integer.parseInt("23",16));
+//        System.out.println(Arrays.toString(hexString2Bytes("8000")));
+
+//        System.out.println(Integer.parseInt("E8",16));
+//        for (int i = 1; i < bytes.length -1; i++) {
+//            y = y ^ bytes[i + 1];
+//            System.out.println(y);
+//        }
+//        System.out.println(Integer.toHexString(y));
+    }
+
+}

+ 55 - 0
warewms-system/src/main/java/com/warewms/hailiang/common/NettyServer.java

@@ -0,0 +1,55 @@
+package com.warewms.hailiang.common;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.net.InetSocketAddress;
+
+/**
+ * 功能描述: netty服务启动类
+ *
+ */
+@Slf4j
+@Component
+public class NettyServer {
+    public void start(InetSocketAddress address) {
+        //配置服务端的NIO线程组
+        EventLoopGroup bossGroup = new NioEventLoopGroup();
+        EventLoopGroup workerGroup = new NioEventLoopGroup();
+        try {
+            // 绑定线程池,编码解码
+            //服务端接受连接的队列长度,如果队列已满,客户端连接将被拒绝
+            ServerBootstrap bootstrap = new ServerBootstrap()
+                    .group(bossGroup, workerGroup)
+                    // 指定Channel
+                    .channel(NioServerSocketChannel.class)
+                    //使用指定的端口设置套接字地址
+                    .localAddress(address)
+                    //使用自定义处理类
+                    .childHandler(new NettyServerChannelInitializer())
+                    //服务端可连接队列数,对应TCP/IP协议listen函数中backlog参数
+                    .option(ChannelOption.SO_BACKLOG, 128)
+                    //保持长连接,2小时无数据激活心跳机制
+                    .childOption(ChannelOption.SO_KEEPALIVE, true)
+                    //将小的数据包包装成更大的帧进行传送,提高网络的负载
+                    .childOption(ChannelOption.TCP_NODELAY, true);
+            // 绑定端口,开始接收进来的连接
+            ChannelFuture future = bootstrap.bind(address).sync();
+            if (future.isSuccess()) {
+                log.info("netty服务器开始监听端口:{}",address.getPort());
+            }
+            //关闭channel和块,直到它被关闭
+            future.channel().closeFuture().sync();
+        } catch (Exception e) {
+            e.printStackTrace();
+            bossGroup.shutdownGracefully();
+            workerGroup.shutdownGracefully();
+        }
+    }
+}

+ 28 - 0
warewms-system/src/main/java/com/warewms/hailiang/common/NettyServerChannelInitializer.java

@@ -0,0 +1,28 @@
+package com.warewms.hailiang.common;
+
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.socket.SocketChannel;
+
+/**
+ * 功能描述: 服务端初始化,客户端与服务器端连接一旦创建,这个类中方法就会被回调,设置出站编码器和入站解码器
+ *
+ * @Author keLe
+ * @Date 2022/8/26
+ */
+public class NettyServerChannelInitializer extends ChannelInitializer<SocketChannel> {
+    @Override
+    protected void initChannel(SocketChannel socketChannel) throws Exception {
+        ChannelPipeline pipeline = socketChannel.pipeline();
+        //接收消息格式,使用自定义解析数据格式
+        pipeline.addLast("decoder",new MyDecoder());
+        //发送消息格式,使用自定义解析数据格式
+        pipeline.addLast("encoder",new MyEncoder());
+
+        //针对客户端,如果在1分钟时没有想服务端发送写心跳(ALL),则主动断开
+        //如果是读空闲或者写空闲,不处理,这里根据自己业务考虑使用
+        //pipeline.addLast(new IdleStateHandler(600,0,0, TimeUnit.SECONDS));
+        //自定义的空闲检测
+        pipeline.addLast(new NettyServerHandler());
+    }
+}

+ 152 - 0
warewms-system/src/main/java/com/warewms/hailiang/common/NettyServerHandler.java

@@ -0,0 +1,152 @@
+package com.warewms.hailiang.common;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelId;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import lombok.extern.slf4j.Slf4j;
+
+import java.net.InetSocketAddress;
+
+/**
+ * 功能描述: netty服务端处理类
+ *
+ */
+@Slf4j
+public class NettyServerHandler extends ChannelInboundHandlerAdapter {
+
+    /**
+     * 功能描述: 有客户端连接服务器会触发此函数
+     *
+     * @param ctx 通道
+     * @return void
+     */
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) {
+        InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
+        String clientIp = insocket.getAddress().getHostAddress();
+        int clientPort = insocket.getPort();
+        //获取连接通道唯一标识
+        ChannelId channelId = ctx.channel().id();
+        //如果map中不包含此连接,就保存连接
+        if (ChannelMap.getChannelMap().containsKey(channelId)) {
+            log.info("客户端:{},是连接状态,连接通道数量:{} ", channelId, ChannelMap.getChannelMap().size());
+        } else {
+            //保存连接
+            ChannelMap.addChannel(channelId, ctx.channel());
+            log.info("客户端:{},连接netty服务器[IP:{}-->PORT:{}]", channelId, clientIp, clientPort);
+            log.info("连接通道数量: {}", ChannelMap.getChannelMap().size());
+        }
+    }
+
+    /**
+     * 功能描述: 有客户端终止连接服务器会触发此函数
+     *
+     * @param ctx 通道处理程序上下文
+     * @return void
+     */
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) {
+        InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
+        String clientIp = inSocket.getAddress().getHostAddress();
+        ChannelId channelId = ctx.channel().id();
+        //包含此客户端才去删除
+        if (ChannelMap.getChannelMap().containsKey(channelId)) {
+            //删除连接
+            ChannelMap.getChannelMap().remove(channelId);
+            log.info("客户端:{},连接netty服务器[IP:{}-->PORT:{}]", channelId, clientIp, inSocket.getPort());
+            log.info("连接通道数量: " + ChannelMap.getChannelMap().size());
+        }
+    }
+
+    /**
+     * 功能描述: 有客户端发消息会触发此函数
+     *
+     * @param ctx 通道处理程序上下文
+     * @param msg 客户端发送的消息
+     * @return void
+     */
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        log.info("加载客户端报文,客户端id:{},客户端消息:{}", ctx.channel().id(), msg);
+        String data = String.valueOf(msg);
+        Integer water = Integer.parseInt(data.substring(6, 10), 16);
+        log.info("当前水位:{}cm", water);
+        //响应客户端
+        this.channelWrite(ctx.channel().id(), msg);
+    }
+
+    @Override
+    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
+        String bytes = "01 03 00 02 00 01 25 CA";
+        ctx.writeAndFlush(bytes);
+    }
+
+    /**
+     * 功能描述: 服务端给客户端发送消息
+     *
+     * @param channelId 连接通道唯一id
+     * @param msg       需要发送的消息内容
+     * @return void
+     */
+    public void channelWrite(ChannelId channelId, Object msg) throws Exception {
+        Channel channel = ChannelMap.getChannelMap().get(channelId);
+        if (channel == null) {
+            log.info("通道:{},不存在", channelId);
+            return;
+        }
+        if (msg == null || msg == "") {
+            log.info("服务端响应空的消息");
+            return;
+        }
+        //将客户端的信息直接返回写入ctx
+        channel.write(msg);
+        //刷新缓存区
+        channel.flush();
+    }
+
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+        String socketString = ctx.channel().remoteAddress().toString();
+        if (evt instanceof IdleStateEvent) {
+            IdleStateEvent event = (IdleStateEvent) evt;
+            if (event.state() == IdleState.READER_IDLE) {
+                log.info("Client:{},READER_IDLE 读超时", socketString);
+                ctx.disconnect();
+                Channel channel = ctx.channel();
+                ChannelId id = channel.id();
+                ChannelMap.removeChannelByName(id);
+            } else if (event.state() == IdleState.WRITER_IDLE) {
+                log.info("Client:{}, WRITER_IDLE 写超时", socketString);
+                ctx.disconnect();
+                Channel channel = ctx.channel();
+                ChannelId id = channel.id();
+                ChannelMap.removeChannelByName(id);
+            } else if (event.state() == IdleState.ALL_IDLE) {
+                log.info("Client:{},ALL_IDLE 总超时", socketString);
+                ctx.disconnect();
+                Channel channel = ctx.channel();
+                ChannelId id = channel.id();
+                ChannelMap.removeChannelByName(id);
+            }
+        }
+    }
+
+    /**
+     * 功能描述: 发生异常会触发此函数
+     *
+     * @param ctx   通道处理程序上下文
+     * @param cause 异常
+     * @return void
+     * @Author keLe
+     * @Date 2022/8/26
+     */
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        ctx.close();
+        log.info("{}:发生了错误,此连接被关闭。此时连通数量:{}", ctx.channel().id(), ChannelMap.getChannelMap().size());
+    }
+
+}

+ 63 - 0
warewms-system/src/main/java/com/warewms/hailiang/config/LaunchRunner.java

@@ -0,0 +1,63 @@
+/*
+package com.warewms.hailiang.config;
+
+
+import cn.hutool.cron.CronUtil;
+import com.warewms.hailiang.common.NettyServer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.net.InetSocketAddress;
+
+*/
+/**
+ * 功能描述: 任务队列
+ * @Author keLe
+ * @Date 2022/7/20
+ *//*
+
+@Component
+@Order(2)
+@Slf4j
+public class LaunchRunner implements CommandLineRunner {
+
+    @Resource
+    private NettyServer nettyServer;
+
+    @Resource
+    private SocketProperties socketProperties;
+
+
+    @Override
+    public void run(String... args) throws Exception {
+        TaskRunner();
+        InetSocketAddress address = new InetSocketAddress(socketProperties.getHost(),socketProperties.getPort());
+        log.info("netty服务器启动地址:"+socketProperties.getHost());
+        nettyServer.start(address);
+    }
+    */
+/**
+     * 执行正在运行的任务
+     *//*
+
+    private  void TaskRunner() {
+        */
+/**
+         * 任务队列启动
+         *//*
+
+        CronUtil.setMatchSecond(true);
+        CronUtil.start();
+        log.info("\n-----------------------任务服务启动------------------------\n\t" +
+                        "当前正在启动的{}个任务"+
+                        "\n-----------------------------------------------------------\n\t"
+                , CronUtil.getScheduler().size()
+
+        );
+
+    }
+}
+*/

+ 5 - 5
warewms-system/src/main/java/com/warewms/hailiang/config/PlcConfig.java

@@ -1,6 +1,6 @@
 package com.warewms.hailiang.config;
 
-import HslCommunication.Profinet.Siemens.SiemensPLCS;
+import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
 import lombok.Data;
 
 /**
@@ -23,10 +23,10 @@ public class PlcConfig {
 
     private byte rack;
 
+    private EPlcType ePlcType;
 
-    private SiemensPLCS siemensPLCS;
-
-    public void setSiemensPLCS(String  siemensPLCS) {
-        this.siemensPLCS = SiemensPLCS.valueOf(siemensPLCS);
+    public void setSiemensPLCS(String  ePlcType) {
+        this.ePlcType = EPlcType.valueOf(ePlcType);
     }
+
 }

+ 0 - 86
warewms-system/src/main/java/com/warewms/hailiang/config/PlcConnectServiceRunner.java

@@ -1,86 +0,0 @@
-package com.warewms.hailiang.config;
-
-
-import com.github.rholder.retry.*;
-import com.warewms.hailiang.util.HslTools;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.CommandLineRunner;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-
-/**
- * plc连接
- */
-@Component
-@Order(1)
-@Slf4j
-public class PlcConnectServiceRunner implements CommandLineRunner {
-
-    @Resource
-    private PlcProperties plcProperties;
-
-    private HashMap<String, HslTools> plcToolsMap = new HashMap<>();
-
-    @Override
-    public void run(String... args) throws Exception {
-        initConnect();
-        log.info("plc初始化完成!");
-    }
-
-    /**
-     * 初始化
-     */
-    private void initConnect() throws InterruptedException {
-        for (PlcConfig plcConfig : plcProperties.getPlcList()) {
-            if (plcConfig.getEnable()) {
-                log.info("初始化:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
-                HslTools hslTools = new HslTools(plcConfig);
-                Thread.sleep(5000);
-                if (hslTools.getSuccess()) {
-                    log.info("plc连接成功:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
-                    plcToolsMap.put(plcConfig.getName(), hslTools);
-                } else {
-                    new Thread(() -> {
-                        retry(plcConfig);
-                    }).start();
-                }
-            }
-        }
-
-    }
-
-    public void retry(PlcConfig plcConfig) {
-        new Thread(() -> {
-            Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
-                    .retryIfResult(Boolean.FALSE::equals)
-                    .retryIfExceptionOfType(Exception.class)
-                    .withStopStrategy(StopStrategies.stopAfterAttempt(5))
-                    .withWaitStrategy(WaitStrategies.fixedWait(3, TimeUnit.SECONDS))
-                    .build();
-            try {
-                retryer.call(() -> {
-                    log.info("重试:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
-                    HslTools hslTools = new HslTools(plcConfig);
-                    Thread.sleep(5000);
-                    if (hslTools.getSuccess()) {
-                        log.info("plc连接成功:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
-                        plcToolsMap.put(plcConfig.getName(), hslTools);
-                        return true;
-                    }
-                    return false;
-                });
-            } catch (RetryException | ExecutionException e) {
-                e.printStackTrace();
-            }
-        }).start();
-    }
-
-    public HslTools getPlcServer(String key){
-      return  plcToolsMap.get(key);
-    }
-}

+ 29 - 0
warewms-system/src/main/java/com/warewms/hailiang/config/SocketProperties.java

@@ -0,0 +1,29 @@
+package com.warewms.hailiang.config;
+
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.stereotype.Component;
+
+/**
+ * 功能描述: 配置类
+ *
+ * @Author keLe
+ * @Date 2022/8/26
+ */
+@Setter
+@Getter
+@ToString
+@Component
+@Configuration
+@PropertySource("classpath:application.yml")
+@ConfigurationProperties(prefix = "socket")
+public class SocketProperties {
+    private Integer port;
+    private String host;
+
+}

+ 121 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader12Connect.java

@@ -0,0 +1,121 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader12Handler;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader12Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.12";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader12";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader12Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 121 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader13Connect.java

@@ -0,0 +1,121 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader13Handler;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader13Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.13";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader13";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader13Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 121 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader14Connect.java

@@ -0,0 +1,121 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader14Handler;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader14Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.14";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader14";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader14Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 120 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader3Connect.java

@@ -0,0 +1,120 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader3Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.3";
+
+    private final String deviceName ="CodeReader3";
+
+    private final int PORT = 51236;
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable){
+            log.info("ip:{},deviceName:{}正在进行连接",IP_ADDR,deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader3Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                        log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                    }else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试",IP_ADDR,deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 121 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader5Connect.java

@@ -0,0 +1,121 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.connect.handler.CodeReader5Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader5Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.5";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader5";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader5Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 121 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader6Connect.java

@@ -0,0 +1,121 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.connect.handler.CodeReader6Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader6Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.6";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader6";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader6Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 122 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader7Connect.java

@@ -0,0 +1,122 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.connect.handler.CodeReader6Handler;
+import com.warewms.hailiang.connect.handler.CodeReader7Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader7Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.7";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader7";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader7Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 121 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader8Connect.java

@@ -0,0 +1,121 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.connect.handler.CodeReader8Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader8Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.8";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader8";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader8Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 121 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/CodeReader9Connect.java

@@ -0,0 +1,121 @@
+package com.warewms.hailiang.connect;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.CodeReader3Handler;
+import com.warewms.hailiang.connect.handler.CodeReader9Handler;
+import com.warewms.hailiang.domian.Device;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:倒角读码器连接
+ **/
+@Slf4j
+public class CodeReader9Connect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.9";
+
+    private final int PORT = 51236;
+
+    private final String deviceName ="CodeReader9";
+
+    private boolean enable = false;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        if (enable) {
+            log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName);
+            group = new NioEventLoopGroup();
+            try {
+                bootstrap = new Bootstrap();
+                bootstrap.group(group).channel(NioSocketChannel.class)
+                        .option(ChannelOption.TCP_NODELAY, true)
+                        .handler(new ChannelInitializer<SocketChannel>() {
+                            @Override
+                            protected void initChannel(SocketChannel socketChannel) throws Exception {
+                                socketChannel.pipeline().addLast(new CodeReader9Handler());
+                            }
+                        });
+                future = bootstrap.connect(IP_ADDR, PORT).sync();
+                future.addListener((channelFuture) -> {
+                    if (channelFuture.isSuccess()) {
+                        SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1"));
+                        log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName);
+                    } else {
+                        log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName);
+                        retry();
+                    }
+                });
+            } catch (Exception e) {
+                log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage());
+                retry();
+            }
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("ip:{},deviceName:{}连接重试",IP_ADDR,deviceName);
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            SpringUtil.getApplicationContext().publishEvent(new Device(deviceName,"1"));
+                            log.info("ip:{},deviceName:{}连接成功",IP_ADDR,deviceName);
+                        }else {
+                            log.info("ip:{},deviceName:{}连接失败等待重试!",IP_ADDR,deviceName);
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 109 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/InkjetPrintersConnect.java

@@ -0,0 +1,109 @@
+package com.warewms.hailiang.connect;
+
+import com.github.rholder.retry.*;
+import com.warewms.hailiang.connect.handler.InkjetPrintersHandler;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import lombok.CustomLog;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:45
+ * To change this template use File | Settings | File Templates.
+ * Description:喷码机tcp连接类
+ **/
+@Slf4j
+public class InkjetPrintersConnect implements TCPConnectBase {
+
+    private final String IP_ADDR = "172.20.27.4";
+
+    private final int PORT = 9999;
+
+    private ChannelFuture future;
+
+    private Bootstrap bootstrap;
+
+    private EventLoopGroup group;
+
+
+
+    @Override
+    public void init() throws InterruptedException {
+        log.info("喷码机正在进行连接");
+        group = new NioEventLoopGroup();
+        try {
+            bootstrap = new Bootstrap();
+            bootstrap.group(group).channel(NioSocketChannel.class)
+                    .option(ChannelOption.TCP_NODELAY, true)
+                    .handler(new ChannelInitializer<SocketChannel>() {
+                        @Override
+                        protected void initChannel(SocketChannel socketChannel) throws Exception {
+                            socketChannel.pipeline().addLast(new InkjetPrintersHandler());
+                        }
+                    });
+            future = bootstrap.connect(IP_ADDR, PORT).sync();
+            future.addListener((channelFuture) -> {
+                if (channelFuture.isSuccess()) {
+                    log.info("喷码机连接成功");
+                }else {
+                    log.info("连接失败等待重试!");
+                    retry();
+                }
+            });
+        } catch (Exception e) {
+            log.error("喷码设备连接异常,{},准备重试", e.getMessage());
+            retry();
+        }
+    }
+
+    @Override
+    public void retry() {
+        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                .retryIfResult(Boolean.FALSE::equals)
+                .retryIfExceptionOfType(Exception.class)
+                .withStopStrategy(StopStrategies.neverStop())
+                .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS))
+                .build();
+        try {
+            retryer.call(new Callable<Boolean>() {
+                AtomicBoolean isSuccess = new AtomicBoolean(false);
+                @Override
+                public Boolean call() throws Exception {
+                    log.info("喷码机连接重试");
+                    future = bootstrap.connect(IP_ADDR, PORT).sync();
+                    future.addListener((channelFuture) -> {
+                        isSuccess.set(channelFuture.isSuccess());
+                        if (channelFuture.isSuccess()) {
+                            log.info("喷码机连接成功");
+                        }else {
+                            log.info("连接失败等待重试!");
+                        }
+                    });
+                    Thread.sleep(3000);
+                    return isSuccess.get();
+                }
+            });
+        } catch (RetryException | ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void close() {
+        group.shutdownGracefully();
+    }
+
+}

+ 23 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/TCPConnectBase.java

@@ -0,0 +1,23 @@
+package com.warewms.hailiang.connect;
+
+import java.io.IOException;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:49
+ * To change this template use File | Settings | File Templates.
+ * Description:TCP连接基类
+ **/
+
+public interface TCPConnectBase {
+
+    void init() throws IOException, InterruptedException;
+
+    void retry() throws InterruptedException;
+
+    void close();
+
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader12Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader12Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader13Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader13Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader14Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader14Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 47 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader3Handler.java

@@ -0,0 +1,47 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.enums.CodeReaderEnum;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import com.warewms.hailiang.util.ParseMsgTools;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader3Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer(CodeReaderEnum.readCode.toString(), CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader5Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader5Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader6Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader6Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader7Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader7Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader8Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader8Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 45 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/CodeReader9Handler.java

@@ -0,0 +1,45 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class CodeReader9Handler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        ctx.writeAndFlush(Unpooled.copiedBuffer("T", CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("倒角读码器连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 51 - 0
warewms-system/src/main/java/com/warewms/hailiang/connect/handler/InkjetPrintersHandler.java

@@ -0,0 +1,51 @@
+package com.warewms.hailiang.connect.handler;
+
+import com.warewms.common.annotation.Log;
+import com.warewms.hailiang.connect.InkjetPrintersConnect;
+import com.warewms.hailiang.init.TcpServiceRunner;
+import com.warewms.hailiang.util.ParseMsgTools;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 17:07
+ * To change this template use File | Settings | File Templates.
+ * Description: 喷码机连接消息处理类
+ **/
+@Slf4j
+@Component
+public class InkjetPrintersHandler extends ChannelInboundHandlerAdapter  {
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+//        ParseMsgTools.StringTohexString("23071115000");
+        ctx.writeAndFlush(Unpooled.copiedBuffer(ParseMsgTools.StringTohexString("23071115000"), CharsetUtil.UTF_8));
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        ByteBuf byteBuf = (ByteBuf) msg;
+        log.info(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8)));
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("喷码机连接已断开!");
+        InkjetPrintersConnect inkjetPrintersConnect = (InkjetPrintersConnect) TcpServiceRunner.getTCPInstanceList().get("InkjetPrintersConnect");
+        inkjetPrintersConnect.retry();
+        super.channelInactive(ctx);
+    }
+}

+ 32 - 0
warewms-system/src/main/java/com/warewms/hailiang/contoller/DeviceController.java

@@ -0,0 +1,32 @@
+package com.warewms.hailiang.contoller;
+
+import com.warewms.common.core.domain.base.page.PageDomain;
+import com.warewms.common.core.domain.base.page.TableDataInfo;
+import com.warewms.hailiang.domian.Device;
+import com.warewms.hailiang.domian.DeviceLog;
+import com.warewms.hailiang.service.DeviceLogService;
+import com.warewms.hailiang.service.DeviceService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author AD
+ * @description 针对表【device_log(设备日志表)】的数据库操作Controller
+ * @createDate 2023-08-21 13:24:57
+ */
+@RestController
+@RequestMapping("/device")
+public class DeviceController {
+
+    @Autowired
+    DeviceService deviceService;
+
+    @GetMapping("/list")
+    public List<Device> getList(){
+       return deviceService.getList();
+    }
+}

+ 28 - 0
warewms-system/src/main/java/com/warewms/hailiang/contoller/DeviceLogController.java

@@ -0,0 +1,28 @@
+package com.warewms.hailiang.contoller;
+
+import com.warewms.common.core.domain.base.page.PageDomain;
+import com.warewms.common.core.domain.base.page.TableDataInfo;
+import com.warewms.hailiang.domian.DeviceLog;
+import com.warewms.hailiang.service.DeviceLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author AD
+ * @description 针对表【device_log(设备日志表)】的数据库操作Controller
+ * @createDate 2023-08-21 13:24:57
+ */
+@RestController
+@RequestMapping("/device/log")
+public class DeviceLogController {
+
+    @Autowired
+    DeviceLogService deviceLogService;
+
+    @GetMapping("/list")
+    public TableDataInfo<DeviceLog> getList(DeviceLog deviceLog, PageDomain pageDomain){
+       return deviceLogService.getList(deviceLog,pageDomain);
+    }
+}

+ 33 - 0
warewms-system/src/main/java/com/warewms/hailiang/contoller/TestContoller.java

@@ -0,0 +1,33 @@
+package com.warewms.hailiang.contoller;
+
+import com.warewms.hailiang.init.PlcConnectServiceRunner;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/7
+ * Time: 16:41
+ * To change this template use File | Settings | File Templates.
+ * Description:
+ **/
+@RestController
+@RequestMapping("/test")
+public class TestContoller {
+
+    @Autowired
+    PlcConnectServiceRunner plcConnectServiceRunner;
+
+    @GetMapping("/pclTest")
+    public Object testPlc(String plcName,String db,String type){
+        db = "V"+db;
+        if (type.equals("1")){
+            return plcConnectServiceRunner.getPlcServer(plcName).readBoolean(db);
+        }
+        return null;
+    }
+}

+ 73 - 0
warewms-system/src/main/java/com/warewms/hailiang/domian/Device.java

@@ -0,0 +1,73 @@
+package com.warewms.hailiang.domian;
+
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.warewms.common.core.domain.base.BaseEntity;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 设备表
+ * @TableName device
+ */
+@Data
+public class Device extends BaseEntity implements Serializable  {
+
+    /**
+     * 设备编号
+     */
+    private String deviceId;
+
+    /**
+     * 设备名称
+     */
+    private String deviceName;
+
+    /**
+     * 简称
+     */
+    private String abbreviation;
+    /**
+     * 产线
+     */
+    private String productionLine;
+    /**
+     * 设备IP
+     */
+    private String ip;
+
+    /**
+     * 端口
+     */
+    private int port;
+
+    /**
+     * 连接方式
+     */
+    private String connectionType;
+
+    /**
+     * 状态(1:连接正常:2.断开)
+     */
+    private String status;
+
+    private static final long serialVersionUID = 1L;
+
+    public Device(String deviceId, String deviceName, String abbreviation, String productionLine, String ip, int port, String connectionType, String status) {
+        this.deviceId = deviceId;
+        this.deviceName = deviceName;
+        this.abbreviation = abbreviation;
+        this.productionLine = productionLine;
+        this.ip = ip;
+        this.port = port;
+        this.connectionType = connectionType;
+    }
+
+    public Device(String deviceName, String status) {
+        this.deviceName = deviceName;
+        this.status = status;
+
+    }
+}

+ 46 - 0
warewms-system/src/main/java/com/warewms/hailiang/domian/DeviceLog.java

@@ -0,0 +1,46 @@
+package com.warewms.hailiang.domian;
+
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.warewms.common.core.domain.base.BaseEntity;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 设备日志表
+ * @TableName device_log
+ */
+@Data
+@TableName("device_log")
+public class DeviceLog extends BaseEntity implements Serializable  {
+    /**
+     * 日志编号
+     */
+    @TableId
+    private Long deviceLogId;
+
+    /**
+     * 设备编号
+     */
+    private String deviceId;
+
+    /**
+     * 设备名称
+     */
+    private String deviceName;
+
+    /**
+     * 日志内容
+     */
+    private String content;
+
+    /**
+     * 状态(1:信息:2报警)
+     */
+    private String status;
+
+    private static final long serialVersionUID = 1L;
+
+}

+ 28 - 0
warewms-system/src/main/java/com/warewms/hailiang/enums/CodeReaderEnum.java

@@ -0,0 +1,28 @@
+package com.warewms.hailiang.enums;
+
+public enum CodeReaderEnum {
+
+    /**
+     * 发起读码信号
+     */
+    readCode("T"),
+
+    /**
+     * 读码失败返回信号
+     */
+    ReadFailed("NG");
+
+    private String code;
+
+    CodeReaderEnum(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}

+ 53 - 0
warewms-system/src/main/java/com/warewms/hailiang/enums/InkjetPrintersDirectivesEnum.java

@@ -0,0 +1,53 @@
+package com.warewms.hailiang.enums;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 15:25
+ * To change this template use File | Settings | File Templates.
+ * Description:喷码机指令枚举
+ **/
+public enum InkjetPrintersDirectivesEnum {
+
+    /**
+     * 开机
+     */
+    BOOT("30 00 01 FF CE"),
+
+    /**
+     * 关机
+     */
+    SHUTDOWN("30 00 01 00 31"),
+
+    /**
+     * 消除故障
+     */
+    CODEE6("E6 00 00 E6"),
+
+    /**
+     * 运行发码程序
+     */
+    CODE41("41 00 01 01 41"),
+
+    /**
+     * 触发打印
+     */
+    CODE94("94 00 00 94");
+
+
+    private String code;
+
+    InkjetPrintersDirectivesEnum(String code) {
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}

+ 22 - 2
warewms-system/src/main/java/com/warewms/hailiang/enums/WeighPlcEnum.java

@@ -1,5 +1,7 @@
 package com.warewms.hailiang.enums;
 
+import lombok.Data;
+
 /**
  * Created with IntelliJ IDEA.
  *
@@ -8,17 +10,35 @@ package com.warewms.hailiang.enums;
  * Description:称重plc对接枚举
  **/
 public enum WeighPlcEnum {
+    /**
+     * 是否可以读取重量
+     */
+    IsRead(""),
+
+    /**
+     * 读取重量
+     */
+    ReadWeight(""),
 
     /**
-     * 心跳
+     * 读取重量反馈
      */
-    heartbeatDB("DB11.0.0");
+    returnWeight("");
 
     private String db;
 
+
     WeighPlcEnum(String db) {
         this.db = db;
     }
 
+    public String getDb() {
+        return db;
+    }
+
+    public void setDb(String db) {
+        this.db = db;
+    }
+
 }
 

+ 102 - 0
warewms-system/src/main/java/com/warewms/hailiang/init/PlcConnectServiceRunner.java

@@ -0,0 +1,102 @@
+package com.warewms.hailiang.init;
+
+
+import com.github.rholder.retry.*;
+import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
+import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
+import com.warewms.hailiang.config.PlcConfig;
+import com.warewms.hailiang.config.PlcProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * plc连接
+ */
+@Component
+@Order(1)
+@Slf4j
+public class PlcConnectServiceRunner implements CommandLineRunner {
+
+    @Resource
+    private PlcProperties plcProperties;
+
+    @Resource
+    ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    private HashMap<String, S7PLC> plcToolsMap = new HashMap<>();
+
+
+
+    @Override
+    public void run(String... args) throws Exception {
+        initConnect();
+        log.info("plc初始化完成!");
+    }
+
+    /**
+     * 初始化
+     */
+    private void initConnect() throws InterruptedException {
+        for (PlcConfig plcConfig : plcProperties.getPlcList()) {
+            if (plcConfig.getEnable()) {
+                log.info("初始化:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
+                try {
+                    S7PLC s7PLC = new S7PLC(plcConfig.getEPlcType(), plcConfig.getIp());
+                    s7PLC.connect();
+                    if (s7PLC.checkConnected()){
+                        plcToolsMap.put(plcConfig.getName(),s7PLC);
+                        log.info("plc:{},ip:{},连接成功",plcConfig.getName(),plcConfig.getIp());
+                    }
+                }catch (Exception e){
+                    log.info("plc:{},ip:{},连接失败",plcConfig.getName(),plcConfig.getIp());
+                    retry(plcConfig);
+                }
+            }
+        }
+
+    }
+
+    public void retry(PlcConfig plcConfig) {
+        threadPoolTaskExecutor.execute (() -> {
+            Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                    .retryIfResult(Boolean.FALSE::equals)
+                    .retryIfExceptionOfType(Exception.class)
+                    .withStopStrategy(StopStrategies.neverStop())
+                    .withWaitStrategy(WaitStrategies.fixedWait(7, TimeUnit.SECONDS))
+                    .build();
+            try {
+                retryer.call(() -> {
+                    log.info("重试:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
+                    try {
+                        S7PLC s7PLC = new S7PLC(plcConfig.getEPlcType(), plcConfig.getIp());
+                        s7PLC.connect();
+                        if (s7PLC.checkConnected()){
+                            plcToolsMap.put(plcConfig.getName(),s7PLC);
+                            log.info("plc:{},ip:{},重试连接成功",plcConfig.getName(),plcConfig.getIp());
+                            return true;
+                        }
+                    }catch (Exception e){
+                        log.info("plc:{},ip:{},重试连接失败,meg:{}",plcConfig.getName(),plcConfig.getIp(),e.getMessage());
+                        return false;
+                    }
+                    return false;
+                });
+            } catch (RetryException | ExecutionException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+    
+
+    public S7PLC getPlcServer(String key) {
+        return plcToolsMap.get(key);
+    }
+}

+ 62 - 0
warewms-system/src/main/java/com/warewms/hailiang/init/TcpServiceRunner.java

@@ -0,0 +1,62 @@
+package com.warewms.hailiang.init;
+
+import cn.hutool.core.util.ClassUtil;
+import com.warewms.hailiang.connect.TCPConnectBase;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Set;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/9
+ * Time: 14:44
+ * To change this template use File | Settings | File Templates.
+ * Description:tcp服务连接启动类
+ **/
+
+@Component
+@Order(2)
+@Slf4j
+public class TcpServiceRunner implements CommandLineRunner {
+
+    @Autowired
+    ThreadPoolTaskExecutor threadPoolTaskExecutor;
+
+    private static HashMap<String,TCPConnectBase> TCPInstanceList = new HashMap<>();
+
+    @Override
+    public void run(String... args) throws Exception {
+        Set<Class<?>> classes = ClassUtil.scanPackageBySuper("com.warewms.hailiang.connect", TCPConnectBase.class);
+        for (Class<?> aClass : classes) {
+            Object o = aClass.newInstance();
+            if (o instanceof TCPConnectBase) {
+                TCPConnectBase nodeModel = (TCPConnectBase) o;
+//                threadPoolTaskExecutor.execute(() -> {
+//                    try {
+//                        nodeModel.init();
+//                        System.out.println(aClass.getSimpleName());
+//                        TCPInstanceList.put(aClass.getSimpleName(),nodeModel);
+//                    } catch (IOException e) {
+//                        nodeModel.close();
+//                        throw new RuntimeException(e);
+//                    } catch (InterruptedException e) {
+//                        throw new RuntimeException(e);
+//                    }
+//                });
+            }
+        }
+    }
+
+    public static HashMap getTCPInstanceList(){
+        return TCPInstanceList;
+    }
+}

+ 19 - 0
warewms-system/src/main/java/com/warewms/hailiang/mapper/DeviceLogMapper.java

@@ -0,0 +1,19 @@
+package com.warewms.hailiang.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.warewms.hailiang.domian.DeviceLog;
+
+/**
+* @author AD
+* @description 针对表【device_log(设备日志表)】的数据库操作Mapper
+* @createDate 2023-08-21 13:24:57
+* @Entity  DeviceLog
+*/
+public interface DeviceLogMapper extends BaseMapper<DeviceLog> {
+
+}
+
+
+
+

+ 20 - 0
warewms-system/src/main/java/com/warewms/hailiang/service/DeviceLogService.java

@@ -0,0 +1,20 @@
+package com.warewms.hailiang.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.warewms.common.core.domain.base.page.PageDomain;
+import com.warewms.common.core.domain.base.page.TableDataInfo;
+import com.warewms.hailiang.domian.DeviceLog;
+import org.springframework.stereotype.Service;
+
+/**
+* @author AD
+* @description 针对表【device_log(设备日志表)】的数据库操作Service
+* @createDate 2023-08-21 13:24:57
+*/
+public interface DeviceLogService extends IService<DeviceLog> {
+
+    TableDataInfo<DeviceLog> getList(DeviceLog deviceLog, PageDomain pageDomain);
+
+    void crateLog(DeviceLog deviceLog);
+}

+ 16 - 0
warewms-system/src/main/java/com/warewms/hailiang/service/DeviceService.java

@@ -0,0 +1,16 @@
+package com.warewms.hailiang.service;
+
+import com.warewms.common.core.domain.base.page.PageDomain;
+import com.warewms.common.core.domain.base.page.TableDataInfo;
+import com.warewms.hailiang.domian.Device;
+import com.warewms.hailiang.domian.DeviceLog;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 设备管理service
+ */
+public interface DeviceService {
+    List<Device> getList();
+}

+ 56 - 0
warewms-system/src/main/java/com/warewms/hailiang/service/impl/DeviceLogServiceImpl.java

@@ -0,0 +1,56 @@
+package com.warewms.hailiang.service.impl;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.warewms.common.core.domain.base.page.PageDomain;
+import com.warewms.common.core.domain.base.page.TableDataInfo;
+import com.warewms.common.utils.StringUtils;
+import com.warewms.hailiang.domian.DeviceLog;
+import com.warewms.hailiang.mapper.DeviceLogMapper;
+import com.warewms.hailiang.service.DeviceLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @author AD
+ * @description 针对表【device_log(设备日志表)】的数据库操作Service实现
+ * @createDate 2023-08-21 13:24:57
+ */
+@Service
+public class DeviceLogServiceImpl extends ServiceImpl<DeviceLogMapper, DeviceLog>
+        implements DeviceLogService {
+
+    @Autowired
+    DeviceLogMapper deviceLogMapper;
+
+
+    @Override
+    public TableDataInfo<DeviceLog> getList(DeviceLog deviceLog, PageDomain pageDomain) {
+        Map<String, Object> params = deviceLog.getParams();
+        IPage<DeviceLog> deviceLogIPage = deviceLogMapper.selectPage(pageDomain.build(), new LambdaQueryWrapper<DeviceLog>()
+                .eq(StringUtils.isNotEmpty(deviceLog.getDeviceId()), DeviceLog::getDeviceId, deviceLog.getDeviceId())
+                .eq(StringUtils.isNotEmpty(deviceLog.getDeviceName()), DeviceLog::getDeviceName, deviceLog.getDeviceName())
+                .eq(StringUtils.isNotEmpty(deviceLog.getStatus()), DeviceLog::getStatus, deviceLog.getStatus())
+                .between(params.get("beginTime") != null && params.get("endTime") != null,
+                        DeviceLog::getCreateTime, params.get("beginTime"), params.get("endTime")));
+        return TableDataInfo.build(deviceLogIPage);
+    }
+
+    @Override
+    @Async
+    @EventListener
+    public void crateLog(DeviceLog deviceLog) {
+        deviceLogMapper.insert(deviceLog);
+    }
+}
+
+
+
+

+ 47 - 0
warewms-system/src/main/java/com/warewms/hailiang/service/impl/DeviceServiceImpl.java

@@ -0,0 +1,47 @@
+package com.warewms.hailiang.service.impl;
+
+import com.warewms.common.core.domain.base.page.TableDataInfo;
+import com.warewms.hailiang.domian.Device;
+import com.warewms.hailiang.service.DeviceService;
+import org.apache.ibatis.annotations.Update;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class DeviceServiceImpl implements DeviceService {
+
+    private List<Device> devices = new ArrayList<>();
+
+    {
+        devices.add(new Device("Z1_Daojia_PMJG-1-27.2", "DaoJiaoJiPlc", "倒角机", "Z1", "172.20.27.2", 102, "S7", "2"));
+        devices.add(new Device("Z1_DaoJiao_PMQ-1-27.4", "PanMaQi", "喷码器", "Z1", "172.20.27.4", 102, "TCP", "2"));
+        devices.add(new Device("Z1_DaoJia_DMQ-1-27.3", "CodeReader3", "倒角读码器", "Z1", "172.20.27.3", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_XiMian_DMQ-1-27.5", "CodeReader5", "铣面读码器", "Z1", "172.20.27.5", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_ZhaZhi_DMQ-1-27.6", "CodeReader6", "轧制读码器", "Z1", "172.20.27.6", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_DaSanPan_DMQ-1-27.7", "CodeReader7", "大散盘读码器1", "Z1", "172.20.27.7", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_DaSanPan_DMQ-2-27.8", "CodeReader8", "大散盘读码器2", "Z1", "172.20.27.8", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_DaSanPan_DMQ-3-27.9", "CodeReader9", "大散盘读码器3", "Z1", "172.20.27.9", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_DaSanPan_DMQ-4-27.12", "CodeReader12", "大散盘读码器4", "Z1", "172.20.27.12", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_TuiHuoSShangLiao_DMQ-1-27.13", "CodeReader13", "退货上料读码器", "Z1", "172.20.27.13", 51236, "TCP", "2"));
+        devices.add(new Device("Z1_TuiHuoXiaLiao_DMQ-1-27.14", "CodeReader14", "退货下料读码器", "Z1", "172.20.27.14", 51236, "TCP", "2"));
+    }
+
+    @Override
+    public List<Device> getList() {
+        return devices;
+    }
+
+    @Async
+    @EventListener
+    void updateStatus(Device d){
+        for (Device device : devices) {
+            if(device.getDeviceName().equals(d.getDeviceName())){
+                device.setStatus(d.getStatus());
+            }
+        }
+    }
+}

+ 0 - 147
warewms-system/src/main/java/com/warewms/hailiang/util/HslTools.java

@@ -1,147 +0,0 @@
-package com.warewms.hailiang.util;
-
-import HslCommunication.Core.Types.OperateResult;
-import HslCommunication.Core.Types.OperateResultExOne;
-import HslCommunication.Profinet.Siemens.SiemensPLCS;
-import HslCommunication.Profinet.Siemens.SiemensS7Net;
-import com.warewms.common.exception.ServiceException;
-import com.warewms.hailiang.config.PlcConfig;
-import lombok.extern.slf4j.Slf4j;
-
-import java.nio.charset.StandardCharsets;
-
-@Slf4j
-public class HslTools{
-
-    private SiemensS7Net siemensS7Net;
-    private Boolean IsSuccess;
-
-    public Boolean getSuccess() {
-        return IsSuccess;
-    }
-
-    public HslTools(PlcConfig plcConfig) {
-        log.info("正在创建连接:{},ip:{}",plcConfig.getSiemensPLCS(),plcConfig.getIp());
-        siemensS7Net = new SiemensS7Net(plcConfig.getSiemensPLCS(), plcConfig.getIp());
-        siemensS7Net.setSlot(plcConfig.getSlot());
-        siemensS7Net.setRack(plcConfig.getRack());
-        OperateResult operateResult = siemensS7Net.ConnectServer();
-        this.IsSuccess = operateResult.IsSuccess;
-        if (!this.IsSuccess){
-            log.info("连接结果:{}--{}--{}",operateResult.IsSuccess,operateResult.Message,operateResult.ErrorCode);
-        }
-    }
-
-
-    public OperateResult closeConn() {
-        OperateResult result = OperateResult.CreateSuccessResult();
-        try {
-            result = siemensS7Net.ConnectClose();
-        } catch (Exception e) {
-
-        }
-        siemensS7Net = null;
-        return result;
-    }
-
-    public boolean writeInt(String address, Integer value) {
-        OperateResult result = siemensS7Net.Write(address, value);
-        log.info(result.Message);
-        if (!result.IsSuccess) {
-            closeConn();
-            throw new ServiceException(String.format("写入数据失败,db:%s,数据:%d,错误信息:%s", address, value, result.Message));
-        }
-        return result.IsSuccess;
-    }
-
-    public boolean writeShort(String address, short value) {
-        OperateResult result = siemensS7Net.Write(address, value);
-        log.info(result.Message);
-        if (!result.IsSuccess) {
-            throw new ServiceException(String.format("写入数据失败,db:%s,错误信息:%s", address, result.Message));
-        } else {
-            log.info(String.format("写入数据完成,db:%s,数据:%d", address, value));
-        }
-        return result.IsSuccess;
-    }
-
-    public boolean writeBoolean(String address, Boolean value) {
-        OperateResult result = siemensS7Net.Write(address, value);
-        if (!result.IsSuccess) {
-            throw new ServiceException(String.format("写入数据失败,db:%s,错误信息:%s", address, address, result.Message));
-        } else {
-            log.info(String.format("写入数据完成,db:%s,数据:%b", address, value));
-        }
-        return result.IsSuccess;
-    }
-
-    public boolean writeString(String address, String value) {
-        OperateResult result = siemensS7Net.Write(address, value.getBytes(StandardCharsets.US_ASCII));
-        if (!result.IsSuccess) {
-            throw new ServiceException(String.format("写入数据失败,db:%s,错误信息:%s", address, result.Message));
-        } else {
-            log.info(String.format("写入数据完成,db:%s,数据:%s", address, value));
-        }
-        return result.IsSuccess;
-    }
-
-    public boolean writeStringStr(String address, String value) {
-        OperateResult result = siemensS7Net.Write(address, value);
-        if (!result.IsSuccess) {
-            throw new ServiceException(String.format("写入数据失败,db:%s,错误信息:%s", address, result.Message));
-        } else {
-            log.info(String.format("写入数据完成,db:%s,数据:%s", address, value));
-        }
-        return result.IsSuccess;
-    }
-
-    public String getString(String address) {
-        OperateResultExOne<String> result = siemensS7Net.ReadString(address);
-        if (!result.IsSuccess) {
-            log.error(String.format(String.format("String类型读取数据失败,db:%s,错误信息:%s", address, result.Message)));
-            return "";
-        } else {
-            return result.Content;
-        }
-    }
-
-    public boolean getBool(String address) {
-        OperateResultExOne<Boolean> result = siemensS7Net.ReadBool(address);
-        if (!result.IsSuccess) {
-            log.error(String.format(String.format("Bool类型读取数据失败,db:%s,错误信息:%s", address, result.Message)));
-            return false;
-        } else {
-            return result.Content;
-        }
-    }
-
-    public int getInt(String address) {
-        OperateResultExOne<Integer> result = siemensS7Net.ReadInt32(address);
-        if (!result.IsSuccess) {
-            log.error(String.format(String.format("int类型读取数据失败,db:%s,错误信息:%s", address, result.Message)));
-            return 0;
-        } else {
-            return result.Content;
-        }
-    }
-
-    public Float getFlot(String address) {
-        OperateResultExOne<Float> result = siemensS7Net.ReadFloat(address);
-        if (!result.IsSuccess) {
-            log.error(String.format(String.format("flot类型读取数据失败,db:%s,错误信息:%s", address, result.Message)));
-            return 0F;
-        } else {
-            return result.Content;
-        }
-    }
-
-    public Double getDabble(String address) {
-        OperateResultExOne<Double> result = siemensS7Net.ReadDouble(address);
-        if (!result.IsSuccess) {
-            log.error(String.format(String.format("dabble类型读取数据失败,db:%s,错误信息:%s", address, result.Message)));
-            return 0D;
-        } else {
-            return result.Content;
-        }
-    }
-}

+ 78 - 0
warewms-system/src/main/java/com/warewms/hailiang/util/ParseMsgTools.java

@@ -0,0 +1,78 @@
+package com.warewms.hailiang.util;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @author: liuzhifei
+ * Date: 2023/8/10
+ * Time: 10:34
+ * To change this template use File | Settings | File Templates.
+ * Description: 消息解析工具
+ **/
+public class ParseMsgTools {
+    /**
+     * 功能描述: 16进制字符串转字节数组
+     * @param src 16进制字符串
+     * @return byte[]
+     */
+    public static byte[] hexString2Bytes(String src) {
+        int l = src.length() / 2;
+        byte[] ret = new byte[l];
+        for (int i = 0; i < l; i++) {
+            ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
+        }
+        return ret;
+    }
+
+    /**
+     * 字符串转16进制字符串
+     * @param str
+     * @return
+     */
+    public static String StringTohexString(String str){
+        StringBuffer sb = new StringBuffer();
+        //将字符串转换为字符数组
+        char ch[] = str.toCharArray();
+        for(int i = 0; i < ch.    length; i++) {
+            String hexString = Integer.toHexString(ch[i]);
+            sb.append(hexString);
+        }
+        return sb.toString();
+    }
+    public static void main(String[] args) throws UnsupportedEncodingException {
+//        String str = "23";
+//        StringBuffer sb = new StringBuffer();
+//        //将字符串转换为字符数组
+//        char ch[] = str.toCharArray();
+//        for(int i = 0; i < ch.    length; i++) {
+//            String hexString = Integer.toHexString(ch[i]);
+//            sb.append(hexString);
+//        }
+//        String result = sb.toString();
+
+//        System.out.println(result);
+//        byte[] bytes = new byte[37];
+//        bytes[0] = 00;
+//        String s ="E800230100063132333332310200173131313131313131313131313131313131313131313131";
+
+//        String s ="E8 00 23 01 00 06 31 32 33 33 32 31 02 00 17 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31";
+//        String[] s2 = s.split(" ");
+//        int i  =Integer.parseInt(s2[0],16) ^ Integer.parseInt(s2[1],16) ;
+//        for (int i1 = 1; i1 < s2.length-1; i1++) {
+//            i = i ^ Integer.parseInt(s2[i1+1],16);
+//        }
+//        System.out.println(Integer.toHexString(i));
+
+//        System.out.println(Integer.parseInt("23",16));
+//        System.out.println(Arrays.toString(hexString2Bytes("8000")));
+
+//        System.out.println(Integer.parseInt("E8",16));
+//        for (int i = 1; i < bytes.length -1; i++) {
+//            y = y ^ bytes[i + 1];
+//            System.out.println(y);
+//        }
+//        System.out.println(Integer.toHexString(y));
+    }
+}

+ 4 - 4
warewms-system/src/main/java/com/warewms/system/config/SecurityConfig.java

@@ -22,7 +22,7 @@ import org.springframework.web.filter.CorsFilter;
 
 /**
  * spring security配置
- * 
+ *
  * @author ruoyi
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@@ -33,7 +33,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Autowired
     private UserDetailsService userDetailsService;
-    
+
     /**
      * 认证失败处理类
      */
@@ -51,7 +51,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Autowired
     private JwtAuthenticationTokenFilter authenticationTokenFilter;
-    
+
     /**
      * 跨域过滤器
      */
@@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register").permitAll()
+                .antMatchers("/login", "/register","/test/**").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

+ 24 - 0
warewms-system/src/main/resources/mapper/hailiang/DeviceLogMapper.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.warewms.hailiang.mapper.DeviceLogMapper">
+
+    <resultMap id="BaseResultMap" type="com.warewms.hailiang.domian.DeviceLog">
+            <id property="deviceLogId" column="device_log_id" jdbcType="BIGINT"/>
+            <result property="deviceId" column="device_id" jdbcType="VARCHAR"/>
+            <result property="deviceName" column="device_name" jdbcType="VARCHAR"/>
+            <result property="content" column="content" jdbcType="VARCHAR"/>
+            <result property="status" column="status" jdbcType="CHAR"/>
+            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+            <result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
+            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
+            <result property="remark" column="remark" jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        device_log_id,device_id,device_name,
+        content,status,create_time,
+        update_by,update_time,remark
+    </sql>
+</mapper>