瀏覽代碼

打印机集成

qzy 9 月之前
父節點
當前提交
828a1c834a
共有 37 個文件被更改,包括 1928 次插入120 次删除
  1. 二進制
      .mvn/wrapper/maven-wrapper.jar
  2. 0 18
      .mvn/wrapper/maven-wrapper.properties
  3. 29 6
      config.xml
  4. 0 0
      log/ice_ipcsdk.log
  5. 1 3
      src/main/java/com/gzlh/background/BackgroundClientHandler.java
  6. 1 3
      src/main/java/com/gzlh/background/BackgroundClientNetty.java
  7. 4 0
      src/main/java/com/gzlh/bus/CenterActionCommand.java
  8. 14 1
      src/main/java/com/gzlh/bus/EventThread.java
  9. 72 0
      src/main/java/com/gzlh/bus/SubmitHarborPoleThread.java
  10. 2 0
      src/main/java/com/gzlh/bus/SysConfig.java
  11. 1 0
      src/main/java/com/gzlh/config/ModuleEnum.java
  12. 7 2
      src/main/java/com/gzlh/config/SystemObject.java
  13. 4 4
      src/main/java/com/gzlh/config/dto/ApplicationConfigDTO.java
  14. 15 0
      src/main/java/com/gzlh/config/dto/SerialSetting.java
  15. 0 1
      src/main/java/com/gzlh/device/electron/brand/ElectronBrandType.java
  16. 3 0
      src/main/java/com/gzlh/device/electron/client/ElectronNettyConfig.java
  17. 3 0
      src/main/java/com/gzlh/device/plc/action/PLCAction.java
  18. 3 1
      src/main/java/com/gzlh/device/plc/client/PlcNettyConfig.java
  19. 93 63
      src/main/java/com/gzlh/device/plc/handler/PLCHadnler.java
  20. 9 0
      src/main/java/com/gzlh/device/print/action/PrintCommonAction.java
  21. 24 0
      src/main/java/com/gzlh/device/print/brand/PrintBrandType.java
  22. 43 0
      src/main/java/com/gzlh/device/print/client/PrintClientHandler.java
  23. 109 0
      src/main/java/com/gzlh/device/print/client/PrintNettyConfig.java
  24. 91 0
      src/main/java/com/gzlh/device/print/controller/PrintController.java
  25. 14 0
      src/main/java/com/gzlh/device/print/event/PrintEvent.java
  26. 21 0
      src/main/java/com/gzlh/device/print/factory/PrintFactory.java
  27. 15 0
      src/main/java/com/gzlh/device/print/handler/IPrintHandler.java
  28. 67 0
      src/main/java/com/gzlh/device/print/handler/impl/PrintYingMeiHandler.java
  29. 14 0
      src/main/java/com/gzlh/device/print/server/PrintServer.java
  30. 76 0
      src/main/java/com/gzlh/device/print/test/BeiHaiPrintBO.java
  31. 110 0
      src/main/java/com/gzlh/device/print/test/JMPrintThread.java
  32. 11 3
      src/main/java/com/gzlh/device/weighbridge/client/WeighbridgeNettyConfig.java
  33. 1 1
      src/main/java/com/gzlh/entity/ReqBO.java
  34. 8 8
      src/main/java/com/gzlh/startup/StartupRunner.java
  35. 9 3
      src/main/java/com/gzlh/utils/DeviceCache.java
  36. 1053 0
      src/main/java/com/gzlh/utils/EpsonCommands.java
  37. 1 3
      src/main/java/com/gzlh/utils/WordHandlerUtils.java

二進制
.mvn/wrapper/maven-wrapper.jar


+ 0 - 18
.mvn/wrapper/maven-wrapper.properties

@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar

+ 29 - 6
config.xml

@@ -2,8 +2,8 @@
 
 <config>
     <managerSetting>
-        <enable>false</enable>
-        <host>192.168.3.127</host>
+        <enable>true</enable>
+        <host>192.168.3.15</host>
         <beatPort>8050</beatPort>
         <serverUrl>http://127.0.0.1:9191</serverUrl>
     </managerSetting>
@@ -13,7 +13,7 @@
         <ip>10.5.136.55</ip>
         <channelCode>DE2</channelCode>
         <channelName>货运进道2</channelName>
-        <!--0 货运通道 1 行政通道-->
+        <!--0 货运通道 1 行政通道 2 港内称重-->
         <channelType>0</channelType>
         <!--车牌保存路径-->
         <fileRootPath>D:\\file</fileRootPath>
@@ -21,7 +21,7 @@
     <!--设备相关设置-->
     <sysConfig>
         <caputreSetting>
-            <enable>true</enable>
+            <enable>false</enable>
             <brand>6000</brand>
             <host>192.168.55.100</host>
             <port>8000</port>
@@ -29,7 +29,7 @@
             <pwd>ap123456</pwd>
         </caputreSetting>
         <serialSetting>
-            <host>10.5.136.55</host>
+            <host>192.168.127.254</host>
             <weighbridge>
                 <enable>false</enable>
                 <port>4003</port>
@@ -46,8 +46,14 @@
                 <port>4002</port>
                 <brand>2000</brand>
             </electron>
-            <plc>
+            <print>
                 <enable>false</enable>
+                <ip>192.168.3.250</ip>
+                <port>9100</port>
+                <brand>1000</brand>
+            </print>
+            <plc>
+                <enable>true</enable>
                 <port>4001</port>
                 <!--输出-->
                 <out>
@@ -67,6 +73,12 @@
                     <fRedPoint>3</fRedPoint>
                     <!--后红外-->
                     <bRedPoint>4</bRedPoint>
+                    <!--打印榜单-->
+                    <printWeight>5</printWeight>
+                    <!--试榜单-->
+                    <testPrint>6</testPrint>
+                    <!--取消榜单,不发送数据第三方-->
+                    <cancelPrint>7</cancelPrint>
                 </status>
             </plc>
         </serialSetting>
@@ -205,5 +217,16 @@
                 <action>CENTER.SUBMIT</action>
             </actionList>
         </event>
+        <event>
+            <!--按了打印榜单按钮-->
+            <name>PLC.START</name>
+            <actionList>
+                <action>PRINT.REQ_PRINT</action>
+                <action>CENTER.TIMER_SLEEP(500)</action>
+                <action>PLC.RAILING_RISE_ON</action>
+                <action>CENTER.TIMER_SLEEP(500)</action>
+                <action>PLC.RAILING_RISE_OFF</action>
+            </actionList>
+        </event>
     </eventList>
 </config>

+ 0 - 0
log/ice_ipcsdk.log


+ 1 - 3
src/main/java/com/gzlh/background/client/BackgroundClientHandler.java → src/main/java/com/gzlh/background/BackgroundClientHandler.java

@@ -1,9 +1,8 @@
-package com.gzlh.background.client;
+package com.gzlh.background;
 
 import cn.hutool.cache.CacheUtil;
 import cn.hutool.cache.impl.TimedCache;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.gzlh.bus.EventBus;
 import com.gzlh.bus.SysConfig;
@@ -15,7 +14,6 @@ import com.gzlh.config.hksdk.HkUtils;
 import com.gzlh.config.hksdk.bo.HKCacheManager;
 import com.gzlh.device.capture.brand.CaptureBrandType;
 import com.gzlh.device.led.utils.LedOptions;
-import com.gzlh.device.plc.event.PLCEvent;
 import com.gzlh.entity.CommandBO;
 import com.gzlh.utils.DeviceCache;
 import io.netty.channel.ChannelHandler;

+ 1 - 3
src/main/java/com/gzlh/background/client/BackgroundClientNetty.java → src/main/java/com/gzlh/background/BackgroundClientNetty.java

@@ -1,4 +1,4 @@
-package com.gzlh.background.client;
+package com.gzlh.background;
 
 import com.gzlh.bus.SysConfig;
 import com.gzlh.config.dto.ManagerSetting;
@@ -12,11 +12,9 @@ import io.netty.handler.codec.string.StringEncoder;
 import io.netty.handler.timeout.IdleStateHandler;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import javax.annotation.Resource;
 import java.util.concurrent.TimeUnit;
 
 @Configuration

+ 4 - 0
src/main/java/com/gzlh/bus/CenterActionCommand.java

@@ -7,5 +7,9 @@ public interface CenterActionCommand {
 
     //    提交数据
     String SUBMIT = "SUBMIT";
+    /**
+     * 港内称重提交
+     */
+    String SUBMIT_HARBORPOLE = "SUBMIT_HARBORPOLE";
 
 }

+ 14 - 1
src/main/java/com/gzlh/bus/EventThread.java

@@ -17,6 +17,7 @@ import com.gzlh.device.electron.factory.ElectronFactory;
 
 import com.gzlh.device.led.factory.LedFactory;
 import com.gzlh.device.plc.handler.PLCHadnler;
+import com.gzlh.device.print.factory.PrintFactory;
 import com.gzlh.device.weighbridge.factory.WeighbridgeFactory;
 import com.gzlh.device.weighbridge.handler.impl.CommonWeighbridgeHandler;
 
@@ -43,6 +44,7 @@ public class EventThread implements Runnable {
         LedFactory ledFactory = SystemObject.ledFactory;
         WeighbridgeFactory weighbridgeFactory = SystemObject.weighbridgeFactory;
         ElectronFactory electronFactory = SystemObject.electronFactory;
+        PrintFactory printFactory = SystemObject.printFactory;
         PLCHadnler plcHadnler = SpringUtil.getBean(PLCHadnler.class);
         CaptureFactory captureFactory = SystemObject.captureFactory;
         CaputreSetting caputreSetting = SysConfig.caputreSetting;
@@ -79,7 +81,11 @@ public class EventThread implements Runnable {
                         } else if (StrUtil.equals(module, ModuleEnum.ELECTRON_MODULE.getModuleEn())) {
                             //动作属于电子车牌
                             electronFactory.handler(serialSetting.getElectron().getBrand()).handlerAction(command);
-                        } else if (StrUtil.equals(module, ModuleEnum.CENTER_MODULE.getModuleEn())) {
+                        }  else if (StrUtil.equals(module, ModuleEnum.PRINT_MODULE.getModuleEn())) {
+                            //动作属于打印机
+                            printFactory.handler(serialSetting.getPrint().getBrand()).handlerAction(command);
+                        }
+                        else if (StrUtil.equals(module, ModuleEnum.CENTER_MODULE.getModuleEn())) {
                             //动作属于中心总线
                             handlerAction(command);
                         }
@@ -100,9 +106,16 @@ public class EventThread implements Runnable {
             handlerSleep(action);
         } else if (StrUtil.contains(action, CenterActionCommand.SUBMIT)) {
             handlerSubmit();
+        }else if (StrUtil.contains(action, CenterActionCommand.SUBMIT_HARBORPOLE)) {
+            //港内称重
+            handlerHarborpoleSubmit();
         }
     }
 
+    private void handlerHarborpoleSubmit() {
+        ThreadUtil.execute(new SubmitHarborPoleThread());
+    }
+
     /**
      * 调度中心休眠
      *

+ 72 - 0
src/main/java/com/gzlh/bus/SubmitHarborPoleThread.java

@@ -0,0 +1,72 @@
+package com.gzlh.bus;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import cn.hutool.http.HttpResponse;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.gzlh.config.ModuleEnum;
+import com.gzlh.config.SystemObject;
+import com.gzlh.device.led.utils.LedOptions;
+import com.gzlh.device.plc.event.PLCEvent;
+import com.gzlh.entity.CommandBO;
+import com.gzlh.entity.ReqBO;
+import com.gzlh.utils.DeviceCache;
+import com.gzlh.utils.WordHandlerUtils;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class SubmitHarborPoleThread implements Runnable{
+    @Override
+    public void run() {
+        String api = SysConfig.managerSetting.getServerUrl() + "/open/submitHarborPole";
+        ReqBO reqBO=EventDataManager.getCacheData();
+        String bodyParams = JSONUtil.toJsonStr(reqBO);
+        if (StrUtil.isEmpty(bodyParams)
+                || ChannelCacheManager.checkExit(reqBO.getCarNo())
+        ||!ChannelCacheManager.stateEnable(SysConfig.channelSetting.getChannelCode())) {
+            return;
+        }
+        ChannelCacheManager.addCache(reqBO.getCarNo());
+        log.info("Req:{}", bodyParams);
+        EventBus eventBus = SpringUtil.getBean(EventBus.class);
+        try (HttpResponse response = HttpUtil.createPost(api).body(WordHandlerUtils.AESEncrypt(bodyParams)).execute()) {
+            log.info("提交港内地磅数据-返回结果:{}", response.body());
+            if (response.getStatus() == 200) {
+                String body = response.body();
+                JSONObject jsonObject = JSONUtil.parseObj(body);
+    //            返回数据解密
+                String data = WordHandlerUtils.AESDecrypt(jsonObject.get("data").toString());
+                log.info("data:{}", data);
+                CommandBO commandBO = JSONUtil.toBean(data, CommandBO.class);
+                LedOptions options = new LedOptions().setLine("04").setShowType("00");
+                if (jsonObject.getInt("code") == 200) {
+                    log.info("抬杆放行============");
+                    eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.RAILING_RISE);
+                    options.setColor("02");
+                    if (ModuleEnum.LED_MODULE.getModuleEn().equalsIgnoreCase(commandBO.getCommand().getModule())) {
+                        SystemObject.ledFactory.handler(SysConfig.serialSetting.getLed().getBrand())
+                                .sendMsg(commandBO.getCommand().getExtra(), options);
+                    }
+                } else {
+                    options.setColor("01");
+                    if (ModuleEnum.LED_MODULE.getModuleEn().equalsIgnoreCase(commandBO.getCommand().getModule())) {
+                        SystemObject.ledFactory.handler(SysConfig.serialSetting.getLed().getBrand())
+                                .sendMsg(commandBO.getCommand().getExtra(), options);
+                    } else {
+                        eventBus.startEvent(commandBO.getCommand().getModule() + "." + commandBO.getCommand().getCommand());
+                    }
+                    if (SysConfig.channelSetting.getChannelType() == 1) {
+                        eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.CHECK_ADMIN_FAILED);
+                    }
+                }
+            } else {
+                eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.SUBMIT_TIMEOUT);
+            }
+        }
+
+//        重置记录的设备触发时间
+        DeviceCache.resetTimeMap();
+    }
+}

+ 2 - 0
src/main/java/com/gzlh/bus/SysConfig.java

@@ -4,6 +4,7 @@ import cn.hutool.core.io.FileUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.XML;
 import com.gzlh.config.dto.*;
+import com.gzlh.utils.DeviceCache;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 
@@ -38,5 +39,6 @@ public class SysConfig {
         caputreSetting=configDTO.getConfig().getSysConfig().getCaputreSetting();
         channelSetting=configDTO.getConfig().getChannelSetting();
         managerSetting=configDTO.getConfig().getManagerSetting();
+        DeviceCache.deviceStatusInit();
     }
 }

+ 1 - 0
src/main/java/com/gzlh/config/ModuleEnum.java

@@ -13,6 +13,7 @@ public enum ModuleEnum {
     GATE_MODULE("道闸","GATE"),
     CAPTURE_MODULE("抓拍单元","CAPTURE"),
     PLC_MODULE("PLC","PLC"),
+    PRINT_MODULE("打印机","PRINT"),
     CENTER_MODULE("action调度中心","CENTER"),
     ELECTRON_MODULE("电子车牌","ELECTRON"),
     ;

+ 7 - 2
src/main/java/com/gzlh/config/SystemObject.java

@@ -3,6 +3,7 @@ package com.gzlh.config;
 import com.gzlh.device.capture.factory.CaptureFactory;
 import com.gzlh.device.electron.factory.ElectronFactory;
 import com.gzlh.device.led.factory.LedFactory;
+import com.gzlh.device.print.factory.PrintFactory;
 import com.gzlh.device.weighbridge.factory.WeighbridgeFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -11,7 +12,6 @@ import org.springframework.stereotype.Component;
 public class SystemObject {
 
 
-
     public static FilePropertiesConfig filePropertiesConfig;
 
 
@@ -22,6 +22,7 @@ public class SystemObject {
     public static CaptureFactory captureFactory;
 
     public static ElectronFactory electronFactory;
+    public static PrintFactory printFactory;
 
     @Autowired
     void setElectronFactory(ElectronFactory electronFactory) {
@@ -29,7 +30,6 @@ public class SystemObject {
     }
 
 
-
     @Autowired
     void setFilePropertiesConfig(FilePropertiesConfig filePropertiesConfig) {
         SystemObject.filePropertiesConfig = filePropertiesConfig;
@@ -49,4 +49,9 @@ public class SystemObject {
     void setCaptureFactory(CaptureFactory captureFactory) {
         SystemObject.captureFactory = captureFactory;
     }
+
+    @Autowired
+    void setPrintFactory(PrintFactory printFactory) {
+        SystemObject.printFactory = printFactory;
+    }
 }

+ 4 - 4
src/main/java/com/gzlh/config/dto/ApplicationConfigDTO.java

@@ -17,14 +17,14 @@ public class ApplicationConfigDTO implements Serializable {
     @NoArgsConstructor
     @Data
     public static class ConfigDTO {
+        @JsonProperty("managerSetting")
+        private ManagerSetting managerSetting;
+        @JsonProperty("channelSetting")
+        private ChannelSetting channelSetting;
         @JsonProperty("configList")
         private ConfigListDTO sysConfig;
         @JsonProperty("eventList")
         private EventListDTO eventList;
-        @JsonProperty("channelSetting")
-        private ChannelSetting channelSetting;
-        @JsonProperty("managerSetting")
-        private ManagerSetting managerSetting;
         @NoArgsConstructor
         @Data
         public static class EventListDTO {

+ 15 - 0
src/main/java/com/gzlh/config/dto/SerialSetting.java

@@ -21,6 +21,18 @@ public class SerialSetting implements Serializable {
     @JsonProperty("electron")
     private ElectronSetting electron;
 
+    @JsonProperty("print")
+    private PrintSetting print;
+
+
+
+    @Data
+    public static class PrintSetting{
+        private boolean enable;
+        private String ip;
+        private int port;
+        private Integer brand;
+    }
     @Data
     public static class ElectronSetting{
         private Boolean enable;
@@ -81,6 +93,9 @@ public class SerialSetting implements Serializable {
              * 后红外
              */
             private String bRedPoint;
+            private String printWeight;
+            private String testPrint;
+            private String cancelPrint;
         }
     }
 

+ 0 - 1
src/main/java/com/gzlh/device/electron/brand/ElectronBrandType.java

@@ -1,6 +1,5 @@
 package com.gzlh.device.electron.brand;
 
-import com.gzlh.device.capture.brand.CaptureBrandType;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 

+ 3 - 0
src/main/java/com/gzlh/device/electron/client/ElectronNettyConfig.java

@@ -1,8 +1,10 @@
 package com.gzlh.device.electron.client;
 
 import com.gzlh.bus.SysConfig;
+import com.gzlh.config.ModuleEnum;
 import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.config.netty.NettyDecoder;
+import com.gzlh.utils.DeviceCache;
 import com.gzlh.utils.XorUtils;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.buffer.ByteBuf;
@@ -73,6 +75,7 @@ public class ElectronNettyConfig {
             if (future1.isSuccess()) {
                 channel = future1.channel();
                 log.info("电子车牌 串口服务器连接成功,{},{}", host, port);
+                DeviceCache.changeDeviceStatus(ModuleEnum.ELECTRON_MODULE.getModuleZh(), 1);
             } else {
                 log.error("-------------电子车牌 连接服务器失败,{},{}-----------,进行重连", host, port);
                 future1.channel().eventLoop().schedule(this::connect, 5, TimeUnit.SECONDS);

+ 3 - 0
src/main/java/com/gzlh/device/plc/action/PLCAction.java

@@ -28,4 +28,7 @@ public interface PLCAction {
     String RAILING_FALL_ON="RAILING_FALL_ON";
     String RAILING_FALL_OFF="RAILING_FALL_OFF";
 
+    String REQ_PRINT="REQ_PRINT";
+    String CANCEL_PRINT="CANCEL_PRINT";
+    String TEST_PRINT="TEST_PRINT";
 }

+ 3 - 1
src/main/java/com/gzlh/device/plc/client/PlcNettyConfig.java

@@ -2,9 +2,11 @@ package com.gzlh.device.plc.client;
 
 import cn.hutool.core.thread.ThreadUtil;
 import com.gzlh.bus.SysConfig;
+import com.gzlh.config.ModuleEnum;
 import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.config.netty.NettyDecoder;
 
+import com.gzlh.utils.DeviceCache;
 import com.gzlh.utils.XorUtils;
 import io.netty.bootstrap.Bootstrap;
 import io.netty.buffer.ByteBuf;
@@ -76,7 +78,7 @@ public class PlcNettyConfig {
             if (future1.isSuccess()) {
                 channel = future1.channel();
                 log.info("plc 串口服务器连接成功,{},{}", host, port);
-
+                DeviceCache.changeDeviceStatus(ModuleEnum.PLC_MODULE.getModuleZh(), 1);
             } else {
                 log.error("-------------plc 连接服务器失败,{},{}-----------,进行重连", host, port);
                 future1.channel().eventLoop().schedule(this::connect, 5, TimeUnit.SECONDS);

+ 93 - 63
src/main/java/com/gzlh/device/plc/handler/PLCHadnler.java

@@ -9,6 +9,7 @@ import com.gzlh.bus.EventDataManager;
 import com.gzlh.bus.EventThread;
 import com.gzlh.bus.SysConfig;
 import com.gzlh.config.ModuleEnum;
+import com.gzlh.config.SystemObject;
 import com.gzlh.config.cache.CarCache;
 import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.config.task.TaskService;
@@ -19,6 +20,9 @@ import com.gzlh.device.plc.action.PLCAction;
 import com.gzlh.device.plc.client.PlcNettyConfig;
 import com.gzlh.device.plc.event.PLCEvent;
 import com.gzlh.device.plc.service.PLCService;
+import com.gzlh.device.print.action.PrintCommonAction;
+import com.gzlh.device.print.event.PrintEvent;
+import com.gzlh.device.print.factory.PrintFactory;
 import com.gzlh.device.weighbridge.event.WeighbridgeEvent;
 import com.gzlh.device.weighbridge.handler.impl.CommonWeighbridgeHandler;
 import com.gzlh.entity.ReqBO;
@@ -46,8 +50,9 @@ public class PLCHadnler {
 
 
     public void handlerAction(String action) {
-       // log.info("plc handler action:{}", action);
+        // log.info("plc handler action:{}", action);
         SerialSetting serialSetting = SysConfig.serialSetting;
+        PrintFactory printFactory = SystemObject.printFactory;
         if (StrUtil.equals(action, PLCAction.RED_LIGHT_ON)) {
             //亮红灯
             String redPoint = serialSetting.getPlc().getOut().getSignalRedPoint();
@@ -92,6 +97,12 @@ public class PLCHadnler {
             String packData = ModbusUtils.buildRequestPacket(command);
             plcNettyConfig.send(packData);
             taskService.addTask(new CheckDownTask(RandomUtil.randomNumbers(10), 200, 1));
+        } else if (StrUtil.equals(action, PLCAction.REQ_PRINT)) {
+            printFactory.handler(serialSetting.getPrint().getBrand()).reqPrint();
+        } else if (StrUtil.equals(action, PLCAction.TEST_PRINT)) {
+            printFactory.handler(serialSetting.getPrint().getBrand()).testPrint();
+        } else if (StrUtil.equals(action, PLCAction.CANCEL_PRINT)) {
+            printFactory.handler(serialSetting.getPrint().getBrand()).cancelPrint();
         }
     }
 
@@ -107,7 +118,7 @@ public class PLCHadnler {
         //  log.info("oldPlcInfo status:{}", oldPlcInfo);
 //        将plc的设备信息补到8存入缓存
         String newPlcInfo = String.format("%8s", result).replace(" ", "0");
-         log.info("plc status:{}", newPlcInfo);
+      //  log.info("plc status:{}", newPlcInfo);
         String newReverse = new StringBuffer(newPlcInfo).reverse().toString();
 //          log.info("new plc reverse status:{}", newReverse);
         if (StrUtil.isEmpty(oldPlcInfo)) {
@@ -117,22 +128,23 @@ public class PLCHadnler {
         if (SysConfig.channelSetting.getChannelType() == 0) {
             //货车通道
             doHandler(oldPlcInfo, newReverse);
-        }else {
+        } else {
             //行政通道
-            doManager(oldPlcInfo,newReverse);
+            doManager(oldPlcInfo, newReverse);
         }
     }
 
     /**
      * 行政通道
+     *
      * @param oldPlcInfo
      * @param newReverse
      */
     private void doManager(String oldPlcInfo, String newReverse) {
-        if (StrUtil.equals(oldPlcInfo,newReverse)){
+        if (StrUtil.equals(oldPlcInfo, newReverse)) {
             return;
         }
-        log.info("newReverse:{},{}", newReverse,CommonWeighbridgeHandler.hsCar);
+        log.info("newReverse:{},{}", newReverse, CommonWeighbridgeHandler.hsCar);
         DeviceCache.setPlcStatus(newReverse);
         SerialSetting.PlcDTO.StatusDTO status = SysConfig.serialSetting.getPlc().getStatus();
         int len = newReverse.length();
@@ -143,12 +155,12 @@ public class PLCHadnler {
             String oldPointStatus = oldPlcInfo.charAt(i) + "";
             String judgePoint = i + "";
             String radarPoint = status.getRadarPoint();
-            String radarPointStatus=newReverse.charAt(Integer.parseInt(radarPoint))+"";
+            String radarPointStatus = newReverse.charAt(Integer.parseInt(radarPoint)) + "";
             String upPoint = status.getUpPoint();
-            String upPointStatus=newReverse.charAt(Integer.parseInt(upPoint))+"";
+            String upPointStatus = newReverse.charAt(Integer.parseInt(upPoint)) + "";
             String downPoint = status.getDownPoint();//默认是1
-            String downPointStatus=newReverse.charAt(Integer.parseInt(downPoint))+"";
-            if (!StrUtil.equals(newPointStatus,oldPointStatus)){
+            String downPointStatus = newReverse.charAt(Integer.parseInt(downPoint)) + "";
+            if (!StrUtil.equals(newPointStatus, oldPointStatus)) {
                 //看看哪个位变化了
                 //上到位。。。
                 if (upPoint.equals(judgePoint)) {
@@ -166,7 +178,7 @@ public class PLCHadnler {
                 }
                 if (radarPoint.equals(judgePoint)) {
                     //雷达从1--->0 初始化
-                    if (radarPointStatus.equals("0")&&!CommonWeighbridgeHandler.hsCar) {
+                    if (radarPointStatus.equals("0") && !CommonWeighbridgeHandler.hsCar) {
                         eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.IDLE);
                     }
                 }
@@ -191,6 +203,9 @@ public class PLCHadnler {
                 String fRedPoint = status.getFRedPoint();
                 String bRedPoint = status.getBRedPoint();
                 String upPoint = status.getUpPoint();
+                String printWeight = status.getPrintWeight();
+                String testPrint = status.getTestPrint();
+                String cancelPrint = status.getCancelPrint();
 
                 String downPoint = status.getDownPoint();//默认是1
                 //状态变化
@@ -198,65 +213,80 @@ public class PLCHadnler {
                     //上到位。抬杆结束。。
                     if (upPoint.equals(judgePoint)) {
                         //上到位触发-->发送继电器断开---->防止不落杆
-                        String upPointStatus=newReverse.charAt(Integer.parseInt(upPoint))+"";
+                        String upPointStatus = newReverse.charAt(Integer.parseInt(upPoint)) + "";
                         if (upPointStatus.equals("1")) {
                             eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.UP_POINT_READ);
                         }
-                    }
+                    } else
 //                    log.info("newReverse:{}", newReverse);
-                    //看下是哪个状态发生变化
-                    if (radarPoint.equals(judgePoint)) {
-                        //雷达变化0--->1不管  1--->0,判断是否是退出
-                        if (newPointStatus.equals("1")) {
-                            //变化时间
-                            DeviceCache.putTime(judgePoint, new Date());
-                            break;
-                        }
-                        //退车
-                        if (((newReverse.charAt(Integer.parseInt(fRedPoint)) + "").equals("0"))
-                                && !CommonWeighbridgeHandler.hsCar) {
-                            log.info("----通道初始化-----");
-                            eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.IDLE);
-                        }
-                    } else if (fRedPoint.equals(judgePoint)) {
-                        //前红外发生变化 1--->0时,判断是否开始读地磅数;0--->1时不管
-                        if (newPointStatus.equals("0")) {
-                            String radarPointStatus = newReverse.charAt(Integer.parseInt(radarPoint)) + "";
-                            //开始称重逻辑:存在车牌,并且雷达状态是0
-                            if (CommonWeighbridgeHandler.hsCar
-                                    && radarPointStatus.equals("0")) {
-                                log.info("read----------");
-                                eventBus.startEvent(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn() + "." + WeighbridgeEvent.READ);
+                        //看下是哪个状态发生变化
+                        if (radarPoint.equals(judgePoint)) {
+                            //雷达变化0--->1不管  1--->0,判断是否是退出
+                            if (newPointStatus.equals("1")) {
+                                //变化时间
+                                DeviceCache.putTime(judgePoint, new Date());
+                                break;
                             }
-                        }
-                    } else if (bRedPoint.equals(judgePoint)) {
-                        //后红外发生变化 0--->1:看下是否是下到位=0时车头碰到红外
-                        String downStatus = newReverse.charAt(Integer.parseInt(downPoint)) + "";
+                            //退车
+                            if (((newReverse.charAt(Integer.parseInt(fRedPoint)) + "").equals("0"))
+                                    && !CommonWeighbridgeHandler.hsCar) {
+                                log.info("----通道初始化-----");
+                                eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.IDLE);
+                            }
+                        } else if (fRedPoint.equals(judgePoint)) {
+                            //前红外发生变化 1--->0时,判断是否开始读地磅数;0--->1时不管
+                            if (newPointStatus.equals("0")) {
+                                String radarPointStatus = newReverse.charAt(Integer.parseInt(radarPoint)) + "";
+                                //开始称重逻辑:存在车牌,并且雷达状态是0
+                                if (CommonWeighbridgeHandler.hsCar
+                                        && radarPointStatus.equals("0")) {
+                                    log.info("read----------");
+                                    eventBus.startEvent(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn() + "." + WeighbridgeEvent.READ);
+                                }
+                            }
+                        } else if (bRedPoint.equals(judgePoint)) {
+                            //后红外发生变化 0--->1:看下是否是下到位=0时车头碰到红外
+                            String downStatus = newReverse.charAt(Integer.parseInt(downPoint)) + "";
 //                        log.info("new point:{},{}", newPointStatus, downStatus);
-                        if (newPointStatus.equals("1") && (downStatus.equals("1")) && CommonWeighbridgeHandler.hsCar) {
-                            DeviceCache.setInterrupt(true);
-                            LedOptions ledOptions = new LedOptions();
-                            ledOptions.setLine("04").setColor("01");
-                            String msg = "请后退";
-                            ledFactory.handler(ledDTO.getBrand()).sendMsg(msg, ledOptions);
-                            //变化时间
-                            DeviceCache.putTime(judgePoint, new Date());
-                            break;
-                        }
-                        ReqBO reqBO = EventDataManager.getCacheData();
-                        //后退进行称重 1--->0
-                        if (newPointStatus.equals("0")
-                                && (downStatus.equals("1")) && reqBO != null && StrUtil.isNotEmpty(reqBO.getCarNo())) {
-                            DeviceCache.setInterrupt(false);
-                            eventBus.startEvent(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn() + "." + WeighbridgeEvent.READ);
-                        }
-                    } else if (downPoint.equals(judgePoint)) {
-                        //下到位触发
-                        String downStatus = newReverse.charAt(Integer.parseInt(downPoint)) + "";
-                        if (downStatus.equals("1")) {//洛干
-                            eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.IDLE);
+                            if (newPointStatus.equals("1") && (downStatus.equals("1")) && CommonWeighbridgeHandler.hsCar) {
+                                DeviceCache.setInterrupt(true);
+                                LedOptions ledOptions = new LedOptions();
+                                ledOptions.setLine("04").setColor("01");
+                                String msg = "请后退";
+                                ledFactory.handler(ledDTO.getBrand()).sendMsg(msg, ledOptions);
+                                //变化时间
+                                DeviceCache.putTime(judgePoint, new Date());
+                                break;
+                            }
+                            ReqBO reqBO = EventDataManager.getCacheData();
+                            //后退进行称重 1--->0
+                            if (newPointStatus.equals("0")
+                                    && (downStatus.equals("1")) && reqBO != null && StrUtil.isNotEmpty(reqBO.getCarNo())) {
+                                DeviceCache.setInterrupt(false);
+                                eventBus.startEvent(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleEn() + "." + WeighbridgeEvent.READ);
+                            }
+                        } else if (downPoint.equals(judgePoint)) {
+                            //下到位触发
+                            String downStatus = newReverse.charAt(Integer.parseInt(downPoint)) + "";
+                            if (downStatus.equals("1")) {//洛干
+                                eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PLCEvent.IDLE);
+                            }
+                        } else if (printWeight.equals(judgePoint)) {
+                            //开始打印
+                            if (newPointStatus.equals("1")) {
+                                eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PrintEvent.START_PRINT);
+                            }
+                        } else if (testPrint.equals(judgePoint)) {
+                            //试打印
+                            if (newPointStatus.equals("1")) {
+                                eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PrintEvent.TEST_PRINT);
+                            }
+                        } else if (cancelPrint.equals(judgePoint)) {
+                            //取消榜单
+                            if (newPointStatus.equals("1")) {
+                                eventBus.startEvent(ModuleEnum.PLC_MODULE.getModuleEn() + "." + PrintEvent.CANCEL_PRINT);
+                            }
                         }
-                    }
                     //变化时间
                     DeviceCache.putTime(judgePoint, new Date());
                 }

+ 9 - 0
src/main/java/com/gzlh/device/print/action/PrintCommonAction.java

@@ -0,0 +1,9 @@
+package com.gzlh.device.print.action;
+
+/**
+ * print共同
+ */
+public interface PrintCommonAction {
+
+
+}

+ 24 - 0
src/main/java/com/gzlh/device/print/brand/PrintBrandType.java

@@ -0,0 +1,24 @@
+package com.gzlh.device.print.brand;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum PrintBrandType {
+
+    YING_MEI(1000, "映美打印机");
+
+
+    private int code;
+    private String brand;
+
+    public static String getBrandByCode(int code) {
+        for (PrintBrandType brandType : PrintBrandType.values()) {
+            if (brandType.getCode() == code) {
+                return brandType.getBrand();
+            }
+        }
+        return null;
+    }
+}

+ 43 - 0
src/main/java/com/gzlh/device/print/client/PrintClientHandler.java

@@ -0,0 +1,43 @@
+package com.gzlh.device.print.client;
+
+import cn.hutool.extra.spring.SpringUtil;
+import com.gzlh.bus.SysConfig;
+import com.gzlh.config.ModuleEnum;
+import com.gzlh.config.dto.SerialSetting;
+import com.gzlh.device.weighbridge.factory.WeighbridgeFactory;
+import com.gzlh.utils.DeviceCache;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@ChannelHandler.Sharable
+public class PrintClientHandler extends SimpleChannelInboundHandler<String> {
+
+    private PrintNettyConfig nettyConfig;
+
+    public PrintClientHandler(PrintNettyConfig nettyConfig) {
+        this.nettyConfig = nettyConfig;
+    }
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
+        log.info("print client:{}",msg);
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        log.error("地磅 连接断开,进行重连");
+        DeviceCache.changeDeviceStatus(ModuleEnum.PRINT_MODULE.getModuleZh(), 0);
+        nettyConfig.connect();
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        log.error("weight error:{}", cause.getMessage());
+    }
+
+
+}
+

+ 109 - 0
src/main/java/com/gzlh/device/print/client/PrintNettyConfig.java

@@ -0,0 +1,109 @@
+package com.gzlh.device.print.client;
+
+import com.gzlh.bus.SysConfig;
+import com.gzlh.config.ModuleEnum;
+import com.gzlh.config.dto.SerialSetting;
+import com.gzlh.utils.DeviceCache;
+import com.gzlh.utils.XorUtils;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.*;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.nio.charset.StandardCharsets;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+@Slf4j
+public class PrintNettyConfig {
+
+
+    @Autowired
+    private PrintClientHandler printClientHandler;
+
+    private Channel channel;
+
+    @Bean("print")
+    public Bootstrap bootstrap() {
+        SerialSetting serialSetting = SysConfig.serialSetting;
+        SerialSetting.PrintSetting printSetting = serialSetting.getPrint();
+        int port = printSetting.getPort();
+        String host=printSetting.getIp();
+        if (printSetting.isEnable()) {
+            log.info("初始化 打印机 ======================:{},{}", host, port);
+        }
+        EventLoopGroup group = new NioEventLoopGroup();
+        return new Bootstrap()
+                .group(group)
+                .channel(NioSocketChannel.class)
+                .remoteAddress(host, port)
+                .option(ChannelOption.SO_KEEPALIVE, true)
+                .handler(new ChannelInitializer<SocketChannel>() {
+                    @Override
+                    protected void initChannel(SocketChannel ch) {
+                        try {
+                            ChannelPipeline pipeline = ch.pipeline();
+                            pipeline.addLast("decoder", new StringDecoder(StandardCharsets.UTF_8));
+                           // pipeline.addLast("encoder", new StringEncoder(StandardCharsets.UTF_8));
+
+                            pipeline.addLast("handler", printClientHandler);
+                        } catch (Exception e) {
+                            log.info("error connect:{}", e.getMessage());
+                        }
+                    }
+                });
+    }
+
+    @Bean
+    public PrintClientHandler printClientHandler() {
+        return new PrintClientHandler(this);
+    }
+
+    public void connect() {
+        SerialSetting serialSetting = SysConfig.serialSetting;
+        SerialSetting.PrintSetting printSetting = serialSetting.getPrint();
+        int port = printSetting.getPort();
+        String host=printSetting.getIp();
+        ChannelFuture future = bootstrap().connect();
+        future.addListener((ChannelFutureListener) future1 -> {
+            if (future1.isSuccess()) {
+                channel = future1.channel();
+                log.info("打印机 连接服务器成功,{},{}", host, port);
+                DeviceCache.changeDeviceStatus(ModuleEnum.PRINT_MODULE.getModuleZh(), 1);
+            } else {
+                log.error("-------------打印机 连接服务器失败-----------,进行重连");
+                future1.channel().eventLoop().schedule(this::connect, 5, TimeUnit.SECONDS);
+            }
+        });
+        try {
+            future.channel().closeFuture().sync();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void send(byte[] command) {
+        if (channel != null && channel.isActive()) {
+            channel.writeAndFlush(Unpooled.wrappedBuffer(command));
+        } else {
+            log.error("未建立连接,无法发送消息");
+        }
+
+    }
+
+    public void close() {
+        if (channel != null) {
+            channel.close();
+        }
+    }
+}
+

+ 91 - 0
src/main/java/com/gzlh/device/print/controller/PrintController.java

@@ -0,0 +1,91 @@
+package com.gzlh.device.print.controller;
+
+import cn.hutool.cache.CacheUtil;
+import cn.hutool.cache.impl.TimedCache;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.XmlUtil;
+import cn.hutool.log.StaticLog;
+import com.gzlh.bus.EventDataManager;
+import com.gzlh.bus.SysConfig;
+import com.gzlh.config.SystemObject;
+import com.gzlh.device.led.utils.LedOptions;
+import com.gzlh.device.print.client.PrintNettyConfig;
+import com.gzlh.device.print.test.BeiHaiPrintBO;
+import com.gzlh.entity.ReqBO;
+import com.gzlh.utils.EpsonCommands;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.MediaType;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+@RestController
+@RequestMapping("/print")
+@Slf4j
+public class PrintController {
+    @Resource
+    private PrintNettyConfig printNettyConfig;
+
+    @RequestMapping("test")
+    public String test() {
+        BeiHaiPrintBO printBO = new BeiHaiPrintBO();
+        printBO.setIp("192.168.3.250")
+                .setTitle("北部湾港北海码头铁山港作业区有限公司货物过磅单")
+                .setGoodsName("大豆")
+                .setCarNo("桂A046T")
+                .setBoatNo("2419")
+                .setVoyage("157816")
+                .setOwner("中粮油脂有限公司")
+                .setAddress("南岸作业区1磅")
+                .setRemarks("请箱扫码支付")
+                .setNum("50")
+                .setBoatName("中弘666")
+                .setGrossWeight(16.8)
+                .setTare(15.8)
+                .setNetWeight(0.5)
+                .setGrossWeightTime("2024-12-20 15:00:01")
+                .setTareTime("2024-12-20 15:03:01")
+        ;
+        Charset charset = Charset.forName("GBK");
+        // 发送打印命令
+        String title = printBO.getTitle() + "\n";
+        printNettyConfig.send(EpsonCommands.mergerByteArray(
+                EpsonCommands.printLineHeight((byte) 50),
+                EpsonCommands.fontSizeSetBig(7),
+                EpsonCommands.emphasizedSetting(true),
+                EpsonCommands.alignCenter(), title.getBytes(charset)));
+        String text = "船名: " + printBO.getBoatName() + "\n" +
+                "船次: " + printBO.getBoatNo() + " \n" +
+                "仓单号: " + printBO.getVoyage() + " \n" +
+                "货名: " + printBO.getGoodsName() + " \n" +
+                "货主单位: " + printBO.getOwner() + "\n" +
+                "车号: " + printBO.getCarNo() + "\n" +
+                "毛重时间: " + printBO.getGrossWeightTime() + "\n" +
+                "毛重: " + printBO.getGrossWeight() + "吨\n" +
+                "皮重时间: " + printBO.getTareTime() + "\n" +
+                "皮重: " + printBO.getTare() + "吨\n" +
+                "净重: " + printBO.getNetWeight() + "吨\n" +
+                "件数/重量/体积: " + printBO.getNum() + "/" + printBO.getNetWeight() + "/" + printBO.getVolume() + "\n" +
+                "地点: " + printBO.getAddress() + "\n" +
+                "备注: " + printBO.getRemarks();
+        byte[] str = text.getBytes(charset);
+        byte[] data = EpsonCommands.mergerByteArray(EpsonCommands.fontSizeSetBig(3),
+                EpsonCommands.emphasizedSetting(false), EpsonCommands.alignLeft(),
+                str, EpsonCommands.printLineFeed((byte) 1), EpsonCommands.feedPaperCut());
+        printNettyConfig.send(data);
+        return "ok";
+    }
+}

+ 14 - 0
src/main/java/com/gzlh/device/print/event/PrintEvent.java

@@ -0,0 +1,14 @@
+package com.gzlh.device.print.event;
+
+/**
+ * led内置事件
+ */
+public interface PrintEvent {
+    /**
+     * 超时事件
+     */
+    String START_PRINT = "START";
+    String TEST_PRINT = "TEST_START";
+    String CANCEL_PRINT = "CANCEL_START";
+    String READ = "READ";
+}

+ 21 - 0
src/main/java/com/gzlh/device/print/factory/PrintFactory.java

@@ -0,0 +1,21 @@
+package com.gzlh.device.print.factory;
+
+
+
+import com.gzlh.device.print.handler.IPrintHandler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class PrintFactory {
+    @Autowired
+    private List<IPrintHandler>handlers;
+
+    public IPrintHandler handler(int code){
+       return handlers.stream().filter(h->h.brandType().getCode()==code)
+                .findAny().orElseThrow(()->new IllegalArgumentException("不支持的打印机"));
+    }
+
+}

+ 15 - 0
src/main/java/com/gzlh/device/print/handler/IPrintHandler.java

@@ -0,0 +1,15 @@
+package com.gzlh.device.print.handler;
+
+import com.gzlh.device.print.brand.PrintBrandType;
+
+public interface IPrintHandler {
+
+    PrintBrandType brandType();
+
+    void sendMsg( String content);
+
+    void handlerAction(String action);
+    void reqPrint();
+    void testPrint();
+    void cancelPrint();
+}

+ 67 - 0
src/main/java/com/gzlh/device/print/handler/impl/PrintYingMeiHandler.java

@@ -0,0 +1,67 @@
+package com.gzlh.device.print.handler.impl;
+
+import cn.hutool.cache.CacheUtil;
+import cn.hutool.cache.impl.TimedCache;
+import cn.hutool.core.util.StrUtil;
+import com.gzlh.device.print.action.PrintCommonAction;
+import com.gzlh.device.print.brand.PrintBrandType;
+import com.gzlh.device.print.handler.IPrintHandler;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Service;
+
+/**
+ * 上海仰邦科技股份有限公司BX-5(M)K/6K(YY)-V4.2 led发送处理器
+ */
+@Service
+@Slf4j
+public class PrintYingMeiHandler implements IPrintHandler {
+    private final static TimedCache<String, Boolean> cache = CacheUtil.newTimedCache(20000);
+    private final static String KEY_PREFIX = "YING_MEI_PRINT";
+
+
+    @Override
+    public PrintBrandType brandType() {
+        return PrintBrandType.YING_MEI;
+    }
+
+    @Override
+    public void sendMsg(String content) {
+        log.info(PrintBrandType.YING_MEI.getBrand() + "发送消息:{}", content);
+    }
+
+    @Override
+    public void handlerAction(String action) {
+        log.info("action:{}", action);
+    }
+
+    @Override
+    public void reqPrint() {
+        if (canPrint()) {
+            log.info("reqPrint");
+        }
+    }
+
+    @Override
+    public void testPrint() {
+        if (canPrint()) {
+            log.info("testPrint");
+        }
+    }
+
+    @Override
+    public void cancelPrint() {
+        if (canPrint()) {
+            log.info("cancelPrint");
+        }
+    }
+
+    private boolean canPrint() {
+        Boolean check = cache.get(KEY_PREFIX);
+        boolean flag = check == null;
+        if (flag) {
+            cache.put(KEY_PREFIX, true);
+        }
+        return flag;
+    }
+}

+ 14 - 0
src/main/java/com/gzlh/device/print/server/PrintServer.java

@@ -0,0 +1,14 @@
+package com.gzlh.device.print.server;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+public class PrintServer {
+
+    public void reqServerToPrint() {
+        // 实现打印功能
+        System.out.println("打印内容:");
+    }
+}

+ 76 - 0
src/main/java/com/gzlh/device/print/test/BeiHaiPrintBO.java

@@ -0,0 +1,76 @@
+package com.gzlh.device.print.test;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class BeiHaiPrintBO {
+    /**
+     * 标题
+     */
+    private String title="";
+    private String ip;
+    /**
+     * 船名
+     */
+    private String boatName="";
+    /**
+     * 航次
+     */
+    private String boatNo="";
+    /**
+     * 仓单号
+     */
+    private String voyage="";
+    /**
+     * 货物
+     */
+    private String goodsName="";
+    /**
+     * 货主
+     */
+    private String owner="";
+    /**
+     * 车牌号
+     */
+    private String carNo="";
+
+    /**
+     * 毛重
+     */
+    private Double grossWeight;
+    /**
+     * 毛重时间
+     */
+    private String grossWeightTime="";
+
+    /**
+     * 皮重
+     */
+    private Double tare;
+    /**
+     * 皮重时间
+     */
+    private String tareTime="";
+    /**
+     * 净重
+     */
+    private Double netWeight;
+    /**
+     * 件数
+     */
+    private String num="0";
+    /**
+     * 体积
+     */
+    private String volume="0";
+    /**
+     * 地点
+     */
+    private String address="";
+    /**
+     * 备注
+     */
+    private String remarks="";
+}

+ 110 - 0
src/main/java/com/gzlh/device/print/test/JMPrintThread.java

@@ -0,0 +1,110 @@
+package com.gzlh.device.print.test;
+
+import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.json.JSONUtil;
+import com.gzlh.utils.EpsonCommands;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.charset.Charset;
+
+/**
+ * 映美打印机
+ */
+@Slf4j
+public class JMPrintThread implements Runnable{
+
+    private BeiHaiPrintBO printBO;
+
+    public JMPrintThread(BeiHaiPrintBO printBO) {
+        this.printBO = printBO;
+    }
+
+    @Override
+    public void run() {
+
+        Socket socket= null;
+        try {
+            String ip= printBO.getIp();
+            socket = new Socket(ip,9100);
+            boolean result= socket.isConnected();
+            if (!result){
+                log.error("打印机:{},连接异常",ip);
+                return;
+            }
+            // 获取输出流
+            OutputStream outputStream = socket.getOutputStream();
+            Charset charset=  Charset.forName("GBK");
+            // 发送打印命令
+            String title=printBO.getTitle()+"\n";
+            outputStream.write(EpsonCommands.initPrinter());
+            outputStream.write(EpsonCommands.mergerByteArray(
+                    EpsonCommands.printLineHeight((byte) 50),
+                    EpsonCommands.fontSizeSetBig(7),
+                    EpsonCommands.emphasizedSetting(true),
+                    EpsonCommands.alignCenter(),title.getBytes(charset)
+            ));
+
+            String text = "船名: "+printBO.getBoatName()+"\n" +
+                    "船次: "+printBO.getBoatNo()+" \n" +
+                    "仓单号: "+printBO.getVoyage()+" \n" +
+                    "货名: "+printBO.getGoodsName()+" \n" +
+                    "货主单位: "+printBO.getOwner()+"\n" +
+                    "车号: "+printBO.getCarNo()+"\n" +
+                    "毛重时间: "+printBO.getGrossWeightTime()+"\n" +
+                    "毛重: "+printBO.getGrossWeight()+"吨\n"+
+                    "皮重时间: "+printBO.getTareTime()+"\n"+
+                    "皮重: "+printBO.getTare()+"吨\n"+
+                    "净重: "+printBO.getNetWeight()+"吨\n"+
+                    "件数/重量/体积: "+printBO.getNum()+"/"+printBO.getNetWeight()+"/"+printBO.getVolume()+"\n"+
+                    "地点: "+printBO.getAddress()+"\n"+
+                    "备注: "+printBO.getRemarks();
+            byte[] str = text.getBytes(charset);
+            byte[]data=EpsonCommands.mergerByteArray(EpsonCommands.fontSizeSetBig(3),
+                    EpsonCommands.emphasizedSetting(false),EpsonCommands.alignLeft(),
+                    str,EpsonCommands.printLineFeed((byte) 1),EpsonCommands.feedPaperCut());
+
+            outputStream.write(data);
+            // 关闭连接
+            outputStream.close();
+
+            log.info("print done======:{}", JSONUtil.toJsonStr(printBO));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        finally {
+            if (socket != null){
+                try {
+                    socket.close();
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+    }
+
+    public static void main(String[] args) {
+        BeiHaiPrintBO printBO1=new BeiHaiPrintBO();
+        printBO1.setIp("192.168.3.250")
+                .setTitle("北部湾港北海码头铁山港作业区有限公司货物过磅单")
+                .setGoodsName("大豆")
+                .setCarNo("桂A046T")
+                .setBoatNo("2419")
+                .setVoyage("157816")
+                .setOwner("中粮油脂有限公司")
+                .setAddress("南岸作业区1磅")
+                .setRemarks("请箱扫码支付")
+                .setNum("50")
+                .setBoatName("中弘666")
+                .setGrossWeight(16.8)
+                .setTare(15.8)
+                .setNetWeight(0.5)
+                .setGrossWeightTime("2024-12-20 15:00:01")
+                .setTareTime("2024-12-20 15:03:01")
+        ;
+        ThreadUtil.execute(new JMPrintThread(printBO1));
+    }
+}

+ 11 - 3
src/main/java/com/gzlh/device/weighbridge/client/WeighbridgeNettyConfig.java

@@ -1,9 +1,14 @@
 package com.gzlh.device.weighbridge.client;
 
 import com.gzlh.bus.SysConfig;
+import com.gzlh.config.ModuleEnum;
 import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.config.netty.NettyDecoder;
+import com.gzlh.utils.DeviceCache;
+import com.gzlh.utils.XorUtils;
 import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
 import io.netty.channel.*;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
@@ -24,7 +29,7 @@ public class WeighbridgeNettyConfig {
 
 
     @Autowired
-    private WeighbridgeClientHandler nettyClientHandler;
+    private WeighbridgeClientHandler weighbridgeClientHandler;
 
     private Channel channel;
 
@@ -51,7 +56,7 @@ public class WeighbridgeNettyConfig {
                             pipeline.addLast("decoder", new StringDecoder(StandardCharsets.UTF_8));
                             pipeline.addLast("encoder", new StringEncoder(StandardCharsets.UTF_8));
 
-                            pipeline.addLast("handler", nettyClientHandler);
+                            pipeline.addLast("handler", weighbridgeClientHandler);
                         } catch (Exception e) {
                             log.info("error connect:{}", e.getMessage());
                         }
@@ -74,6 +79,7 @@ public class WeighbridgeNettyConfig {
             if (future1.isSuccess()) {
                 channel = future1.channel();
                 log.info("地磅 连接服务器成功,{},{}", host, port);
+                DeviceCache.changeDeviceStatus(ModuleEnum.WEIGHBRIDGE_MODULE.getModuleZh(), 1);
             } else {
                 log.error("-------------地磅 连接服务器失败-----------,进行重连");
                 future1.channel().eventLoop().schedule(this::connect, 5, TimeUnit.SECONDS);
@@ -88,7 +94,9 @@ public class WeighbridgeNettyConfig {
 
     public void send(String message) {
         if (channel != null && channel.isActive()) {
-            channel.writeAndFlush(message);
+            ByteBuf bufff = Unpooled.buffer();
+            bufff.writeBytes(XorUtils.hexString2Bytes(message));
+            channel.writeAndFlush(bufff);
         } else {
             log.error("未建立连接,无法发送消息");
         }

+ 1 - 1
src/main/java/com/gzlh/entity/ReqBO.java

@@ -27,7 +27,7 @@ public class ReqBO implements Serializable {
     /**
      * 车牌
      */
-    private String carNo="";;
+    private String carNo="";
     /**
      * 车牌图片base64
      */

+ 8 - 8
src/main/java/com/gzlh/startup/StartupRunner.java

@@ -2,15 +2,12 @@ package com.gzlh.startup;
 
 import cn.hutool.core.thread.ThreadUtil;
 import cn.hutool.core.util.RandomUtil;
-import cn.hutool.extra.spring.SpringUtil;
-import com.gzlh.background.client.BackgroundClientNetty;
+import com.gzlh.background.BackgroundClientNetty;
 import com.gzlh.bus.SysConfig;
 import com.gzlh.bus.task.CheckInitTask;
 import com.gzlh.config.dto.CaputreSetting;
 import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.config.ModuleEnum;
-import com.gzlh.config.SystemObject;
-import com.gzlh.bus.EventBus;
 import com.gzlh.config.hksdk.HCNetSDK;
 import com.gzlh.config.hksdk.HkUtils;
 import com.gzlh.config.hksdk.bo.HKCacheManager;
@@ -19,14 +16,11 @@ import com.gzlh.device.capture.brand.CaptureBrandType;
 import com.gzlh.device.electron.client.ElectronNettyConfig;
 import com.gzlh.device.led.client.LedNettyConfig;
 import com.gzlh.device.plc.client.PlcNettyConfig;
-import com.gzlh.device.plc.event.PLCEvent;
 import com.gzlh.device.plc.job.SearchJob;
+import com.gzlh.device.print.client.PrintNettyConfig;
 import com.gzlh.device.weighbridge.client.WeighbridgeNettyConfig;
 
-import com.gzlh.hx.api.IceSdk;
-import com.gzlh.hx.callback.PlateCallback;
 import com.gzlh.hx.handler.InitHxSDK;
-import com.sun.jna.Pointer;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Component;
@@ -45,6 +39,8 @@ public class StartupRunner implements CommandLineRunner {
     @Resource
     private PlcNettyConfig plcNettyConfig;
     @Resource
+    private PrintNettyConfig printNettyConfig;
+    @Resource
     private ElectronNettyConfig electronNettyConfig;
     @Resource
     private TaskService taskService;
@@ -72,12 +68,16 @@ public class StartupRunner implements CommandLineRunner {
             ThreadUtil.execute(() -> plcNettyConfig.connect());
             ThreadUtil.execute(new SearchJob());
         }
+        if (SysConfig.serialSetting.getPrint().isEnable()) {
+            ThreadUtil.execute(() -> printNettyConfig.connect());
+        }
         if (serialSetting.getElectron().getEnable()) {
             ThreadUtil.execute(() -> electronNettyConfig.connect());
         }
         if (SysConfig.managerSetting.isEnable()) {
             ThreadUtil.execute(() -> backgroundClientNetty.connect());
         }
+
         CaputreSetting caputreSetting = SysConfig.caputreSetting;
         if (caputreSetting.isEnable()) {
             if (caputreSetting.getBrand() == CaptureBrandType.HK_BRAND.getCode()) {

+ 9 - 3
src/main/java/com/gzlh/utils/DeviceCache.java

@@ -10,6 +10,7 @@ import com.gzlh.config.dto.SerialSetting;
 import com.gzlh.device.capture.brand.CaptureBrandType;
 import com.gzlh.device.electron.brand.ElectronBrandType;
 import com.gzlh.device.led.brand.LedBrandType;
+import com.gzlh.device.print.brand.PrintBrandType;
 import com.gzlh.device.weighbridge.brand.WeighbridgeBrandType;
 import com.gzlh.entity.DeviceStatus;
 import org.springframework.util.StringUtils;
@@ -50,9 +51,6 @@ public class DeviceCache {
     }
 
     public static String getDeviceStatusJson() {
-        if (StringUtils.isEmpty(deviceStatus.getChannelCode())) {
-            deviceStatusInit();
-        }
         return JSONUtil.toJsonStr(deviceStatus);
     }
 
@@ -97,6 +95,14 @@ public class DeviceCache {
                     ModuleEnum.ELECTRON_MODULE.getModuleZh());
             deviceStatus.getDeviceList().add(electron);
         }
+        if (serialSetting.getPrint().isEnable()) {
+            SerialSetting.PrintSetting printSetting = serialSetting.getPrint();
+            DeviceStatus.Device electron = new DeviceStatus.Device(printSetting.getIp(),
+                    printSetting.getPort(),
+                    PrintBrandType.getBrandByCode(printSetting.getBrand()),
+                    ModuleEnum.PRINT_MODULE.getModuleZh());
+            deviceStatus.getDeviceList().add(electron);
+        }
     }
 
     public static DeviceStatus getDeviceStatus() {

+ 1053 - 0
src/main/java/com/gzlh/utils/EpsonCommands.java

@@ -0,0 +1,1053 @@
+package com.gzlh.utils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+public class EpsonCommands {
+
+    public static final int HEIGHT_PARTING_DEFAULT = 255;
+    private static String hexStr = "0123456789ABCDEF";
+    private static String[] binaryArray = {"0000", "0001", "0010", "0011",
+            "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
+            "1100", "1101", "1110", "1111"};
+
+    public static final byte ESC = 0x1B; // 指令换码
+    public static final byte FS = 0x1C; // 文本分隔符
+    public static final byte GS = 0x1D; // 组分隔符
+    public static final byte DLE = 16; // 数据连接换码
+    public static final byte EOT = 4; // 传输结束
+    public static final byte ENQ = 5; // 询问字符
+    public static final byte SP = 32; // 空格
+    public static final byte LF = 0x0A; // 打印并换行(水平定位)
+    public static final byte HT = 9; // 水平制表(横向列表)
+    public static final byte CR = 13; // 归位键
+    public static final byte FF = 12;// 走纸控制(打印并回到标准模式(在页模式下) )
+    public static final byte CAN = 24; // 作废(页模式下取消打印数据 )
+
+    /**
+     * CodePage table
+     */
+    public static final byte CODE_PAGE_PC437 = 0;
+    public static final byte CODE_PAGE_KATAKANA = 1;
+    public static final byte CODE_PAGE_PC850 = 2;
+    public static final byte CODE_PAGE_PC860 = 3;
+    public static final byte CODE_PAGE_PC863 = 4;
+    public static final byte CODE_PAGE_PC865 = 5;
+    public static final byte CODE_PAGE_WPC1252 = 16;
+    public static final byte CODE_PAGE_PC866 = 17;
+    public static final byte CODE_PAGE_PC852 = 18;
+    public static final byte CODE_PAGE_PC858 = 19;
+    public static final byte CODE_PAGE_THAI_42 = 20;
+    public static final byte CODE_PAGE_THAI_11 = 21;
+    public static final byte CODE_PAGE_THAI_13 = 22;
+    public static final byte CODE_PAGE_THAI_14 = 23;
+    public static final byte CODE_PAGE_THAI_16 = 24;
+    public static final byte CODE_PAGE_THAI_17 = 25;
+    public static final byte CODE_PAGE_THAI_18 = 26;
+
+    @Retention(SOURCE)
+    @Target({ANNOTATION_TYPE})
+    public @interface ByteDef {
+        /**
+         * Defines the allowed constants for this element
+         */
+        byte[] value() default {};
+
+        /**
+         * Defines whether the constants can be used as a flag, or just as an enum (the default)
+         */
+        boolean flag() default false;
+    }
+
+    @ByteDef(flag = true, value = {
+            CODE_PAGE_PC437,
+            CODE_PAGE_KATAKANA,
+            CODE_PAGE_PC850,
+            CODE_PAGE_PC860,
+            CODE_PAGE_PC863,
+            CODE_PAGE_PC865,
+            CODE_PAGE_WPC1252,
+            CODE_PAGE_PC866,
+            CODE_PAGE_PC852,
+            CODE_PAGE_PC858,
+            CODE_PAGE_THAI_42,
+            CODE_PAGE_THAI_11,
+            CODE_PAGE_THAI_13,
+            CODE_PAGE_THAI_14,
+            CODE_PAGE_THAI_16,
+            CODE_PAGE_THAI_17,
+            CODE_PAGE_THAI_18
+    })
+    public @interface CodePage {
+    }
+
+    /**
+     * BarCode table
+     */
+    public static class BarCode {
+        public static final byte UPC_A = 0;
+        public static final byte UPC_E = 1;
+        public static final byte EAN13 = 2;
+        public static final byte EAN8 = 3;
+        public static final byte CODE39 = 4;
+        public static final byte ITF = 5;
+        public static final byte NW7 = 6;
+        //public static final byte CODE93      = 72;
+        public static final byte CODE128 = 73;
+    }
+
+    /**
+     * <p>
+     * Initialize printer
+     * <p>
+     * Clears the data in the print buffer and resets the printer modes to the modes that were
+     * in effect when the power was turned on.
+     * <p>
+     * Format
+     * ASCII    :  ESC   @
+     * HEX      :  0x1B  0x40
+     * Decimal  :  27    64
+     */
+    public static final byte[] RESET = {ESC, 0x40};
+
+    /**
+     * Select justification
+     * <p>
+     * Aligns all the data in one line to the position specified by n as follows.<p>
+     * <p>
+     * Format <p>
+     * ASCII    :  ESC   a      n
+     * HEX      :  0x1B  0x61   n
+     * Decimal  :  27    97     n
+     * <p>
+     * Range 0 <= n <= 2  or 48 <= n <= 50 <p>
+     * Default n = 0 <p>
+     * Left justification : 0 or 48 <p>
+     * Centering  : 1 or 49 <p>
+     * Right justification : 2 or 50 <p>
+     */
+    public static final byte[] ALIGN_LEFT = {ESC, 0x61, 0x00};
+    public static final byte[] ALIGN_CENTER = {ESC, 0x61, 0x01};
+    public static final byte[] ALIGN_RIGHT = {ESC, 0x61, 0x02};
+
+    /**
+     * Print and line feed
+     * <p>
+     * Prints the data in the print buffer and feeds one line based on the current line spacing.
+     * <p>
+     * Format
+     * ASCII    :  LF
+     * HEX      :  0x0A
+     * Decimal  :  10
+     */
+    public static final byte[] LINE_FEED = {LF};
+
+    /**
+     * Print and feed n lines.
+     * <p>
+     * Prints the data in the print buffer and feeds n lines .
+     * <p>
+     * Format <p>
+     * ASCII    :  ESC   d      n
+     * HEX      :  0x1B  0x64   n
+     * Decimal  :  27    100    n
+     * <p>
+     * Range 0 <= n <= 255 <p>
+     * Default n = 1 <p>
+     */
+    public static final byte[] LINE_FEED_N = {ESC, 0x64, 0x01};
+
+    /**
+     * Print and reverse feed n lines.
+     * <p>
+     * Prints the data in the print buffer and feeds n lines in the reverse direction.
+     * <p>
+     * Format <p>
+     * ASCII    :  ESC   e      n
+     * HEX      :  0x1B  0x65   n
+     * Decimal  :  27    101    n
+     * <p>
+     * Range 0 <= n <= 255 <p>
+     * Default n = 0 <p>
+     * <p>
+     * Note: <p>
+     * With the some printer,the range of n is  0 <= n <= 2.
+     */
+    public static final byte[] LINE_FEED_REVERSE = {ESC, 0x65, 0x01};
+
+    /**
+     * Turn emphasized mode on/off
+     * <p>
+     * Turns emphasized mode on or off.<p>
+     * When the LBS of n is 0, emphasized mode is turned off.<p>
+     * When the LBS of n is 1, emphasized mode is turned on.<p>
+     * <p>
+     * Format <p>
+     * ASCII    :  ESC   E      n
+     * HEX      :  0x1B  0x45   n
+     * Decimal  :  27    69     n
+     * <p>
+     * Range 0 <= n <= 255 <p>
+     * Default n = 0 <p>
+     */
+    public static final byte[] EMPHASIZED_OFF = {ESC, 0x45, 0x00};
+    public static final byte[] EMPHASIZED_ON = {ESC, 0x45, 0xF};
+
+    /**
+     * Select character font
+     * <p>
+     * Select character fonts.<p>
+     * <p>
+     * Format <p>
+     * ASCII    :  ESC   M      n
+     * HEX      :  0x1B  0x4D   n
+     * Decimal  :  27    77     n
+     * <p>
+     * Range 0 <= n <= 2  or 48 <= n <= 50 <p>
+     * Default n = 0 <p>
+     * font A : 0 or 48 <p>
+     * font B : 1 or 49 <p>
+     * font C : 2 or 50 <p>
+     * Notes: <p>
+     * 1. Some printers do not have font C , See the ESC/POS Application Programming Guide
+     * (ESC/POS APG ).<p>
+     * 2. With the TM-U220, the range of n is n = 0,1,48 and 49. The default value is 1.<p>
+     */
+    public static final byte[] FONT_A = {ESC, 0x4D, 0x00};
+    public static final byte[] FONT_B = {ESC, 0x4D, 0x01};
+    public static final byte[] FONT_C = {ESC, 0x4D, 0x02};
+
+    /**
+     * Select CN font
+     * <p>
+     * Select CN fonts.<p>
+     * <p>
+     * <p>
+     * Format <p>
+     * ASCII    :  FS    !      n
+     * HEX      :  0x1C  0x21   n
+     * Decimal  :  28    33     n
+     * <p>
+     * Range 0 <= n <= 1 <p>
+     * Default n = 0 <p>
+     * font A : 0 <p>
+     * font B : 1 <p>
+     */
+    public static final byte[] FONT_CN_A = {FS, 0x21, 0x00};
+    public static final byte[] FONT_CN_B = {FS, 0x21, 0x01};
+
+    /**
+     * Select print modes
+     * <p>
+     * Selects the character font and styles (emphasize ,double-height,double-width,and
+     * underline) together.<p>
+     * <p>
+     * Format <p>
+     * ASCII    :  ESC   !      n
+     * HEX      :  0x1B  0x21   n
+     * Decimal  :  27    33     n
+     * <p>
+     * Range 0 <= n <= 255 <p>
+     * Default n = 0 <p>
+     * <p>
+     */
+    public static final byte[] FONT_DOUBLE_HEIGHT_OFF = {ESC, 0x21, 0x00};
+    public static final byte[] FONT_DOUBLE_HEIGHT_ON = {ESC, 0x21, 0xF};
+    public static final byte[] FONT_DOUBLE_HEIGHT_WIDTH_ON = {ESC, 0x21, 0x38};
+
+
+    public static final byte[] HORIZONTAL_TAB = {ESC, 0x2C, 0x14, 0x1C, 0x00};
+
+    public static final byte[] HT_NEXT = {HT};
+
+    public static final byte[] LINE_HEIGHT_NORMAL = {ESC, 0x32};
+
+    public static final byte[] LINE_HEIGHT_N = {ESC, 0x33, 0x08};
+
+    /**
+     * Generate pulse
+     * <p>
+     * Outputs the pulse specified by t1 and t2 to connector pin m to open the chash drawer,
+     * as follows.<p>
+     * <p>
+     * Format <p>
+     * ASCII    :  ESC   p      m     t1      t2
+     * HEX      :  0x1B  0x70   m     t1      t2
+     * Decimal  :  27    112    m     t1      t2
+     * <p>
+     * Range : <br>
+     * m = 0,1,48,49 <br>
+     * 0 <= t1 <= 255 <br>
+     * 0 <= t2 <= 255 <br>
+     * <p>
+     * t1 specifies the pulse ON time as [t1 x 2ms]
+     * t1 specifies the pulse OFF time as [t2 x 2ms]
+     * <p>
+     * Note : <br>
+     * some printer , if t2 < 50 ,t2 should be 50.<br>
+     * some printer , if t1 < 50 ,t1 should be 50. If t2 < 50 , t2 should be 50<br>
+     */
+    public static final byte[] GENERATE_PULSE = {ESC, 0x70, 0x00, 0x3C, 0x78};
+
+    /**
+     * Select printing color
+     * <p>
+     * Select the printing color specified by n .<br>
+     * When the n is 0,48 , color 1 is selected.<br>
+     * When the n is 1,49 , color 2 is selected.<br>
+     * <p>
+     * Format <br>
+     * ASCII    :  ESC   r      n  <br>
+     * HEX      :  0x1B  0x72   n  <br>
+     * Decimal  :  27    114    n  <br>
+     * <p>
+     * Range <br>
+     * n = 0,1,48,49 <br>
+     * <p>
+     * Default  <br>
+     * n = 0 <br>
+     * <p>
+     * Note: <br>
+     * Some printer , it is recommended to obtain the ESC/POS Application programming
+     * Guide (ESC/POS APG), which describes the recommended operation for 2 color printing
+     * control;
+     */
+    public static final byte[] COLOR_SET_1 = {ESC, 0x72, 0x00};
+    public static final byte[] COLOR_SET_2 = {ESC, 0x72, 0x01};
+
+    /**
+     * Select character code table
+     * <p>
+     * Selects a page n from the character code table .
+     * <p>
+     * Format <br>
+     * ASCII    :  ESC   t      n
+     * HEX      :  0x1B  0x74   n
+     * Decimal  :  27    116    n
+     * <p>
+     * Range : <br>
+     * Except for Thai model : 0 <= n <= 5 ,16 <= n <= 19 ,0 = 254,255 <br>
+     * For Thai model : 0 <= n <= 5 ,16 <= n <= 26 ,0 = 254,255 <p>
+     * Default :<br>
+     * Except for Thai model : n = 0 <br>
+     * For Thai model : n = 20 <br>
+     * <p>
+     *
+     * @see CodePage
+     * @see #CODE_PAGE_PC437
+     * @see #CODE_PAGE_KATAKANA
+     * @see #CODE_PAGE_PC850
+     * @see #CODE_PAGE_PC860
+     * @see #CODE_PAGE_PC863
+     * @see #CODE_PAGE_PC865
+     * @see #CODE_PAGE_WPC1252
+     * @see #CODE_PAGE_PC866
+     * @see #CODE_PAGE_PC852
+     * @see #CODE_PAGE_PC858
+     */
+    public static final byte[] SELECT_CODE_TAB = {ESC, 0x74, CODE_PAGE_WPC1252};
+
+    /**
+     * Turn white/black reverse printing mode on/off
+     * <p>
+     * Turns white/black reverse printing mode on or off.<p>
+     * When the LBS of n is 0, white/black reverse mode is turned off.<p>
+     * When the LBS of n is 1, white/black reverse mode is turned on.<p>
+     * <p>
+     * Format <p>
+     * ASCII    :  GS    B      n
+     * HEX      :  0x1D  0x45   n
+     * Decimal  :  29    66     n
+     * <p>
+     * Range 0 <= n <= 255 <p>
+     * Default n = 0 <p>
+     */
+    public static final byte[] PRINTING_MODE_OFF = {GS, 0x42, 0x00};
+    public static final byte[] PRINTING_MODE_ON = {GS, 0x42, (byte) 0x80};
+
+    /**
+     * Select bar code height
+     * <p>
+     * Selects the height of the bar code as n dots.<p>
+     * <p>
+     * Format <br>
+     * ASCII    :  GS    h      n <br>
+     * HEX      :  0x1D  0x68   n <br>
+     * Decimal  :  29    104    n <br>
+     * <p>
+     * Range <br>
+     * 0 <= n <= 255
+     * <p>
+     * Default <br>
+     * n = 0 <p>
+     */
+    public static final byte[] BARCODE_HEIGHT = {GS, 0x68, (byte) 0xA2};
+
+    /**
+     * 初始化打印机
+     *
+     * @return bytes for this command
+     * @see #RESET
+     */
+    public static byte[] initPrinter() {
+        return RESET;
+    }
+
+    /**
+     * 左对齐
+     * ESC a n
+     *
+     * @return bytes for this command
+     */
+    public static byte[] alignLeft() {
+        return ALIGN_LEFT;
+    }
+
+    /**
+     * 居中对齐
+     * ESC a n
+     *
+     * @return bytes for this command
+     */
+    public static byte[] alignCenter() {
+        return ALIGN_CENTER;
+    }
+
+    /**
+     * 右对齐
+     * ESC a n
+     *
+     * @return bytes for this command
+     */
+    public static byte[] alignRight() {
+        return ALIGN_RIGHT;
+    }
+
+    /**
+     * 打印并换行
+     *
+     * @return bytes for this command
+     * @see #LINE_FEED
+     */
+    public static byte[] printLineFeed() {
+        return LINE_FEED;
+    }
+
+    /**
+     * 打印并走纸n行
+     * Prints the data in the print buffer and feeds n lines
+     * ESC d n
+     *
+     * @param n lines
+     * @return bytes for this command
+     */
+    public static byte[] printLineFeed(byte n) {
+        LINE_FEED_N[2] = n;
+        return LINE_FEED_N;
+    }
+
+    /**
+     * 打印并反向走纸n行(不一定有效)
+     * Prints the data in the print buffer and feeds n lines in the reserve direction
+     * ESC e n
+     *
+     * @param n lines
+     * @return bytes for this command
+     * @see #LINE_FEED_REVERSE
+     */
+    public static byte[] printAndReverseFeedLines(byte n) {
+        LINE_FEED_REVERSE[2] = n;
+        return LINE_FEED_REVERSE;
+    }
+
+    /**
+     * 加粗设置
+     *
+     * @param isEmphasized on / off ,true is on
+     * @return bytes for this command
+     * @see #EMPHASIZED_OFF
+     * @see #EMPHASIZED_ON
+     */
+    public static byte[] emphasizedSetting(boolean isEmphasized) {
+        return isEmphasized ? EMPHASIZED_ON : EMPHASIZED_OFF;
+    }
+
+    /**
+     * Select Font A
+     *
+     * @return bytes for this command
+     * @see #FONT_A
+     */
+    public static byte[] selectFontA() {
+        return FONT_A;
+    }
+
+    /**
+     * Select Font B
+     *
+     * @return bytes for this command
+     * @see #FONT_B
+     */
+    public static byte[] selectFontB() {
+        return FONT_B;
+    }
+
+    /**
+     * Select Font C ( some printers don't have font C )
+     *
+     * @return bytes for this command
+     * @see #FONT_C
+     */
+    public static byte[] selectFontC() {
+        return FONT_C;
+    }
+
+    /**
+     * Select CN Font A
+     * FS ! n
+     *
+     * @return bytes for this command
+     * @see #FONT_CN_A
+     */
+    public static byte[] selectCNFontA() {
+        return FONT_CN_A;
+    }
+
+    /**
+     * Select CN Font B
+     * FS ! n
+     *
+     * @return bytes for this command
+     * @see #FONT_CN_B
+     */
+    public static byte[] selectCNFontB() {
+        return FONT_CN_B;
+    }
+
+    /**
+     * 关闭双倍字高 chart
+     * ESC ! n
+     *
+     * @return bytes for this command
+     * @see #FONT_DOUBLE_HEIGHT_OFF
+     */
+    public static byte[] doubleHeightWidthOff() {
+        return FONT_DOUBLE_HEIGHT_OFF;
+    }
+
+    /**
+     * 双倍字高(仅英文字体有效)
+     * ESC ! n
+     *
+     * @return bytes for this command
+     * @see #FONT_DOUBLE_HEIGHT_ON
+     */
+    public static byte[] doubleHeightOn() {
+        return FONT_DOUBLE_HEIGHT_ON;
+    }
+
+    /**
+     * 双倍字体高宽(仅英文字体有效)
+     * ESC ! n
+     *
+     * @return bytes for this command
+     * @see #FONT_DOUBLE_HEIGHT_ON
+     */
+    public static byte[] doubleHeightWidthOn() {
+        return FONT_DOUBLE_HEIGHT_WIDTH_ON;
+    }
+
+    public static byte[] printHorizontalTab() {
+        return HORIZONTAL_TAB;
+    }
+
+    public static byte[] printHTNext() {
+        return HT_NEXT;
+    }
+
+    public static byte[] printLineNormalHeight() {
+        return LINE_HEIGHT_NORMAL;
+    }
+
+    public static byte[] printLineHeight(byte height) {
+        LINE_HEIGHT_N[2] = height;
+        return LINE_HEIGHT_N;
+    }
+
+    /**
+     * 弹开纸箱
+     * Drawer kick-out connector pin 2
+     * ESC p m t1 t2
+     *
+     * @return bytes for this command
+     */
+    public static byte[] drawerKick() {
+        return GENERATE_PULSE;
+    }
+
+    /**
+     * 选择打印颜色1(不一定有效)
+     * ESC r n
+     *
+     * @return bytes for this command
+     */
+    public static byte[] selectColor1() {
+        return COLOR_SET_1;
+    }
+
+    /**
+     * 选择打印颜色2(不一定有效)
+     * ESC r n
+     *
+     * @return bytes for this command
+     */
+    public static byte[] selectColor2() {
+        return COLOR_SET_2;
+    }
+
+    /**
+     * Select character code table
+     * ESC t n
+     *
+     * @param cp CODE_PAGE_WPC1252
+     * @return bytes for this command
+     * @see CodePage
+     */
+    public static byte[] selectCodeTab(@CodePage byte cp) {
+        SELECT_CODE_TAB[2] = cp;
+        return SELECT_CODE_TAB;
+    }
+
+
+
+    /**
+     * select bar code height
+     * Select the height of the bar code as n dots
+     * default dots = 162
+     * <p>
+     * GS h n
+     *
+     * @param dots ( height of the bar code )
+     * @return bytes for this command
+     */
+    public static byte[] barcode_height(byte dots) {
+        BARCODE_HEIGHT[2] = dots;
+        return BARCODE_HEIGHT;
+    }
+
+    /**
+     * select font hri
+     * Selects a font for the Human Readable Interpretation (HRI) characters when printing a barcode, using n as follows:
+     *
+     * @param n Font
+     *          0, 48 Font A
+     *          1, 49 Font B
+     * @return bytes for this command
+     */
+    public static byte[] select_font_hri(byte n) {
+        byte[] result = new byte[3];
+        result[0] = GS;
+        result[1] = 102;
+        result[2] = n;
+        return result;
+    }
+
+    /**
+     * select position_hri
+     * Selects the print position of Human Readable Interpretation (HRI) characters when printing a barcode, using n as follows:
+     *
+     * @param n Print position
+     *          0, 48 Not printed
+     *          1, 49 Above the barcode
+     *          2, 50 Below the barcode
+     *          3, 51 Both above and below the barcode
+     * @return bytes for this command
+     */
+    public static byte[] select_position_hri(byte n) {
+        byte[] result = new byte[3];
+        result[0] = GS;
+        result[1] = 72;
+        result[2] = n;
+        return result;
+    }
+
+    /**
+     * Set horizontal tab positions
+     *
+     * @param col ( coulumn )
+     * @return bytes for this command
+     */
+    public static byte[] set_HT_position(byte col) {
+        byte[] result = new byte[4];
+        result[0] = ESC;
+        result[1] = 68;
+        result[2] = col;
+        result[3] = 0;
+        return result;
+    }
+
+    /**
+     * 字体变大为标准的n倍
+     *
+     * @param num 倍数
+     * @return bytes for this command
+     */
+    public static byte[] fontSizeSetBig(int num) {
+        byte realSize = 0;
+        switch (num) {
+            case 0:            // 宽度|高度
+                realSize = 0;  // 0000|0000
+                break;
+            case 1:
+                realSize = 13; // 0001|0001
+                break;
+            case 2:
+                realSize = 34; // 0010|0010
+                break;
+            case 3:
+                realSize = 51; // 0011|0011
+                break;
+            case 4:
+                realSize = 68; // 0100|0100
+                break;
+            case 5:
+                realSize = 85; // 0101|0101
+                break;
+            case 6:
+                realSize = 102; // 0110|0110
+                break;
+            case 7:
+                realSize = 119; // 0111|0111
+                break;
+        }
+        byte[] result = new byte[3];
+        result[0] = GS;
+        result[1] = 33;
+        result[2] = realSize;
+        return result;
+    }
+
+    /**
+     * 字体变大为标准的n倍
+     *
+     * @param num 倍数
+     * @return bytes for this command
+     */
+    public static byte[] fontHeightSizeSetBig(int num) {
+        byte realSize = 0;
+        switch (num) {
+            case 0:            // 宽度|高度
+                realSize = 0;  // 0000|0000
+                break;
+            case 1:
+                realSize = 1; // 0000|0001
+                break;
+            case 2:
+                realSize = 2; // 0000|0010
+                break;
+            case 3:
+                realSize = 3; // 0000|0011
+                break;
+            case 4:
+                realSize = 4; // 0000|0100
+                break;
+            case 5:
+                realSize = 5; // 0000|0101
+                break;
+            case 6:
+                realSize = 6; // 0000|0110
+                break;
+            case 7:
+                realSize = 7; // 0000|0111
+                break;
+        }
+        byte[] result = new byte[3];
+        result[0] = GS;
+        result[1] = 33;
+        result[2] = realSize;
+        return result;
+    }
+
+    // ------------------------条形码---------------------------
+    // 设置条码的位置--与设置文本对齐方式相同
+    // 设置条码的宽度GS w n
+    public static byte[] setBarCodeWith(int width) {
+        byte[] result = new byte[3];
+        result[0] = GS;// 0x1D
+        result[1] = 0x77;// 'W'
+        result[2] = (byte) width;
+        return result;
+    }
+
+    // 设置条码的高度GS h n
+    public static byte[] setBarCodeHeight(int height) {
+        byte[] result = new byte[3];
+        result[0] = GS;
+        result[1] = 0x68;
+        result[2] = (byte) height /*0xA2*/;
+        return result;
+    }
+
+    // 条码注释打印在条码位置GS H n
+    // 打印条码时, 为HRI字符选择打印位置(HRI 是对条码内容注释的字符)
+    // 0, 48 不打印;1, 49 在条码上方;2, 50 在条码下方;3, 51 在条码上方及下方
+    public static byte[] setHRILocation(int loc) {
+        byte[] result = new byte[3];
+        result[0] = GS;
+        result[1] = 0x48;
+        result[2] = (byte) loc;
+        return result;
+    }
+
+    /**
+     * 选定条形码系统(m值)并打印条码
+     * <p>
+     * 【GS k m d1...dk NUL】 该命令在这种格式下以 NUL 结束 0 UPC-A 11 ≤ k ≤ 12 48 ≤ d ≤ 57 1
+     * UPC-E 11 ≤ k ≤ 12 48 ≤ d ≤ 57 2 JAN13 (EAN13) 12 ≤ k ≤ 13 48 ≤ d ≤ 57 3 JAN 8
+     * (EAN8) 7 ≤ k ≤ 8 48 ≤ d ≤ 57 4 CODE39 1 ≤ k 48 ≤ d ≤ 57, 65 ≤ d ≤ 90, 32, 36,
+     * 37, 43, 45, 46, 47 5 ITF 1 ≤ k (偶数) 48 ≤ d ≤ 57 6 CODABAR 1 ≤ k 48 ≤ d ≤ 57,
+     * 65 ≤ d ≤ 68, 36, 43, 45, 46, 47, 58
+     * <p>
+     * 【GS k m n d1...dn】 n用来指示条码数据的个数, 打印机将其后边 n 字节数据作为条码数据处理
+     * 65 UPC-A 11 ≤ n ≤ 12
+     * 48 ≤ d ≤ 57
+     * 66 UPC-E 11 ≤ n ≤ 12 48 ≤ d ≤ 57
+     * 67 JAN13 (EAN13) 12 ≤ n ≤ 13 48 ≤ d ≤ 57
+     * 68 JAN 8 (EAN8) 7 ≤ n ≤ 8 48 ≤ d ≤ 57
+     * 69 CODE39 1 ≤ n ≤ 255 48 ≤ d ≤ 57, 65 ≤ d ≤ 90, 32, 36, 37, 43, 45, 46, 47
+     * 70 ITF 1 ≤ n ≤ 255(偶数) 48 ≤ d ≤ 57
+     * 71 CODABAR 1 ≤ n ≤ 255 48 ≤ d ≤ 57, 65 ≤ d ≤ 68, 36, 43, 45, 46, 47, 58
+     * 72 CODE93 1 ≤ n ≤ 255 0 ≤ d ≤ 127
+     * [实例] 打印 GS k 72 7 67 111 100 101 13 57 51
+     * 73 CODE128 2 ≤ n ≤ 255 0 ≤ d ≤ 127
+     * [实例] 打印"No. 123456"的实例数据,首先用CODE B打印"No."
+     * 然后用CODE C 打印下列数字。GS k 73 10 123 66 78 111 46 123 67 12 34 56
+     */
+    public static byte[] printBarCode(int m, byte[] dk) {
+        byte[] result = new byte[3 + dk.length + 1];
+        result[0] = GS;
+        result[1] = 0x6B;
+        result[2] = (byte) m;// 选定条形码系统
+        for (int i = 0; i < dk.length; i++) {
+            result[3 + i] = dk[i];
+        }
+        result[result.length - 1] = 0;
+        return result;
+    }
+
+    public static byte[] printBarCode(int m, int n, byte[] dn) {
+        byte[] result = new byte[4 + n];
+        result[0] = GS;
+        result[1] = 0x6B;
+        result[2] = (byte) m;// 选定条形码系统
+        result[3] = (byte) n;// 条码数据的个数
+        for (int i = 0; i < n; i++) {
+            result[4 + i] = dn[i];
+        }
+        return result;
+    }
+
+    public static byte[] printBarCodeGP(int m, int n, String dn) {
+        n = 8;
+        byte[] result = new byte[6 + n];
+        result[0] = GS;
+        result[1] = 0x6B;
+        result[2] = (byte) m;// 选定条形码系统
+        result[3] = (byte) (n + 2);// 条码数据的个数
+        result[4] = (byte) 123;
+        result[5] = (byte) 67;
+        for (int i = 0; i < n; i++) {
+            result[6 + i] = (byte) (10 + i);
+        }
+        return result;
+    }
+
+    /**
+     * print bar code
+     *
+     * @param barcode_typ   ( Barcode.CODE39, Barcode.EAN8 ,...)
+     * @param barcode2print value
+     * @return bytes for this command
+     */
+    public static byte[] print_bar_code(byte barcode_typ, String barcode2print) {
+        byte[] barcodeBytes = barcode2print.getBytes();
+        byte[] result = new byte[3 + barcodeBytes.length + 1];
+        result[0] = GS;
+        result[1] = 107;
+        result[2] = barcode_typ;
+        int idx = 3;
+        for (byte b : barcodeBytes) {
+            result[idx] = b;
+            idx++;
+        }
+        result[idx] = 0;
+        return result;
+    }
+
+    /**
+     * print bar code
+     *
+     * @param barcode_typ(Barcode.CODE39,Barcode.EAN8,...)
+     * @param barcode2print
+     * @return bytes for this command
+     */
+    public static byte[] print_bar_code128(byte barcode_typ, String barcode2print) {
+        byte[] barcodebytes = barcode2print.getBytes();
+        byte[] result = new byte[4 + barcodebytes.length];
+        result[0] = GS;
+        result[1] = 107;
+        result[2] = barcode_typ;
+        result[3] = (byte) barcodebytes.length;
+        int idx = 4;
+
+        for (int i = 0; i < barcodebytes.length; i++) {
+            result[idx] = barcodebytes[i];
+            idx++;
+        }
+
+        return result;
+    }
+
+    /**
+     * 进纸切割
+     * Feeds paper to ( cutting position + n x vertical motion unit )
+     * and executes a full cut ( cuts the paper completely )
+     *
+     * @return bytes for this command
+     */
+
+    public static byte[] feedPaperCut() {
+        byte[] result = new byte[4];
+        result[0] = GS;
+        result[1] = 86;
+        result[2] = 65;
+        result[3] = 0;
+        return result;
+    }
+
+    /**
+     * 进纸切割(留部分)
+     * Feeds paper to ( cutting position + n x vertical motion unit )
+     * and executes a partial cut ( one point left uncut )
+     *
+     * @return bytes for this command
+     */
+    public static byte[] feedPaperCutPartial() {
+        byte[] result = new byte[4];
+        result[0] = GS;
+        result[1] = 86;
+        result[2] = 66;
+        result[3] = 0;
+        return result;
+    }
+
+
+
+
+    /**
+     * 合并byte数组
+     *
+     * @param byteArray byte数组
+     * @return 一个byte数组
+     */
+    public static byte[] mergerByteArray(byte[]... byteArray) {
+        int length = 0;
+        for (byte[] item : byteArray) {
+            length += item.length;
+        }
+        byte[] result = new byte[length];
+        int index = 0;
+        for (byte[] item : byteArray) {
+            for (byte b : item) {
+                result[index] = b;
+                index++;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 2进制转成16进制
+     *
+     * @param binaryStr 2进制串
+     * @return 16进制串
+     */
+    public static String binaryStrToHexString(String binaryStr) {
+        String hex = "";
+        String f4 = binaryStr.substring(0, 4);
+        String b4 = binaryStr.substring(4, 8);
+        for (int i = 0; i < binaryArray.length; i++) {
+            if (f4.equals(binaryArray[i]))
+                hex += hexStr.substring(i, i + 1);
+        }
+        for (int i = 0; i < binaryArray.length; i++) {
+            if (b4.equals(binaryArray[i]))
+                hex += hexStr.substring(i, i + 1);
+        }
+        return hex;
+    }
+
+    /**
+     * 16进制指令list转换为byte[]指令
+     *
+     * @param list 指令集
+     * @return byte[]指令
+     */
+    public static byte[] hexListToByte(List<String> list) {
+        ArrayList<byte[]> commandList = new ArrayList<>();
+        for (String hexStr : list) {
+            commandList.add(hexStringToBytes(hexStr));
+        }
+        int len = 0;
+        for (byte[] srcArray : commandList) {
+            len += srcArray.length;
+        }
+        byte[] destArray = new byte[len];
+        int destLen = 0;
+        for (byte[] srcArray : commandList) {
+            System.arraycopy(srcArray, 0, destArray, destLen, srcArray.length);
+            destLen += srcArray.length;
+        }
+        return destArray;
+    }
+
+    /**
+     * 16进制串转byte数组
+     *
+     * @param hexString 16进制串
+     * @return byte数组
+     */
+    public static byte[] hexStringToBytes(String hexString) {
+        if (hexString == null || hexString.equals("")) {
+            return null;
+        }
+        hexString = hexString.toUpperCase();
+        int length = hexString.length() / 2;
+        char[] hexChars = hexString.toCharArray();
+        byte[] d = new byte[length];
+        for (int i = 0; i < length; i++) {
+            int pos = i * 2;
+            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
+        }
+        return d;
+    }
+
+    /**
+     * 16进制char 转 byte
+     *
+     * @param c char
+     * @return byte
+     */
+    private static byte charToByte(char c) {
+        return (byte) hexStr.indexOf(c);
+    }
+
+    public static void main(String[] args) {
+
+    }
+}

+ 1 - 3
src/main/java/com/gzlh/utils/WordHandlerUtils.java

@@ -108,7 +108,7 @@ public class WordHandlerUtils {
 
         SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
 
-        Cipher cipher = null; // 选择AES算法、工作模式为ECB、填充方式为PKCS5Padding
+        Cipher cipher = null;
         byte[] encryptedBytes =null;
         try {
             cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
@@ -118,8 +118,6 @@ public class WordHandlerUtils {
                 | IllegalBlockSizeException | InvalidKeyException e) {
             e.printStackTrace();
         }
-
-//        System.out.println("Encrypted Text: " + DatatypeConverter.printHexBinary(encryptedBytes));
         return DatatypeConverter.printHexBinary(encryptedBytes);
     }