From 4c58f8f132adf830917b6b8f49f8c8de87aaf748 Mon Sep 17 00:00:00 2001
From: czt <czt18638530771@163.com>
Date: 星期四, 08 一月 2026 18:40:51 +0800
Subject: [PATCH] 数量检测提交2-检测协议实现

---
 fzzy-igdss-core/src/main/java/com/fzzy/igds/request/QuantityRequest.java                   |   43 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2005.java                       |   25 
 fzzy-igdss-io/pom.xml                                                                      |    3 
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/IoMessage.java                      |   26 
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityMessageConsumer.java |   51 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp1002.java                       |   20 
 fzzy-igdss-core/src/main/java/com/fzzy/igds/service/QuantityService.java                   |    9 
 fzzy-igdss-web/src/main/java/com/fzzy/security/manager/SecManager.java                     |   87 ++
 fzzy-igdss-core/src/main/java/com/fzzy/igds/service/FileService.java                       |   40 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityServerEngine.java    |  115 +++
 fzzy-igdss-core/src/main/java/com/fzzy/igds/utils/Base64Util.java                          |   58 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2003.java                       |   22 
 fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/impl/DefaultRemoteQuantityImpl.java   |   48 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantitySessionListener.java |   30 
 fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvokerImpl.java               |   43 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Req1001.java                        |   32 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2006.java                       |   20 
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/QueryProgressTask.java          |   65 ++
 fzzy-igdss-web/src/main/resources/templates/security/quantity.html                         |   35 
 fzzy-igdss-web/src/main/java/com/fzzy/security/SecurityController.java                     |   24 
 fzzy-igdss-web/src/main/java/com/fzzy/Application.java                                     |    3 
 fzzy-igdss-io/src/main/java/com/fzzy/igds/io/manager/QuantityRemoteManager.java            |   47 +
 fzzy-igdss-core/src/main/java/com/fzzy/igds/data/QuantityProgressData.java                 |   44 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/analysis/AnalysisService.java           |  299 +++++++++
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/BhznRemoteQuantityImpl.java     |  140 ++++
 fzzy-igdss-io/src/main/java/com/fzzy/igds/ServerRunner.java                                |   31 
 fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/RemoteQuantityService.java            |   70 ++
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/util/ServerUtils.java                   |   77 ++
 fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/ProtocolEnum.java                     |   41 +
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/CommandBuilder.java             |  210 ++++++
 fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2004.java                       |   26 
 fzzy-igdss-web/src/main/resources/static/security/quantity.js                              |   70 ++
 fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvoker.java                   |   25 
 33 files changed, 1,852 insertions(+), 27 deletions(-)

diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/ProtocolEnum.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/ProtocolEnum.java
new file mode 100644
index 0000000..a5390c2
--- /dev/null
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/constant/ProtocolEnum.java
@@ -0,0 +1,41 @@
+package com.fzzy.igds.constant;
+
+/**
+ * @Description 鎶撴媿鏂瑰紡
+ * @Author CZT
+ * @Date 2026/01/08 16:48
+ */
+public enum ProtocolEnum {
+
+    TCP_DEFAULT("TCP_DEFAULT", "绯荤粺榛樿鍗忚"),
+    TCP_MS_STORAGE("TCP_MS_STORAGE", "鐪夊北鏁伴噺妫�娴嬪崗璁�"),
+    TCP_XSX_V1("TCP_XSX_V1", "閼儨閼富鍗忚1.0"),
+    TCP_ZLDZ_GRAIN_V1("TCP_ZLDZ_GRAIN_V1", "姝f潵鐢靛瓙绮儏鍗忚1.0"),
+    TCP_FZZY_V3("TCP_FZZY_V3", "椋庢鑷磋繙V3.0鍗忚"),
+    TCP_FZZY_IOT_V3("TCP_FZZY_IOT_V3", "椋庢鑷磋繙鐗╄仈缃慥3.0鍗忚"),
+    TCP_SHUHAN_V1("TCP_SHUHAN_V1", "铚�姹夋暟閲忔娴媀1"),
+    TCP_FZZY_WEIGHT("TCP_FZZY_WEIGHT", "FZZY-鍦扮涓绘帶鍗忚"),
+    RK_WEATHER_V30("RK_WEATHER_V30", "寤哄ぇ浠佺姘旇薄绔欎簯V30"),
+    TCP_FZZY_QUANTITY_V35("TCP_FZZY_QUANTITY_V35", "椋庢鑷磋繙鏁伴噺妫�娴媀35"),
+    TCP_BHZH_GRAIN_FM_V1("TCP_BHZH_GRAIN_FM_V1", "閭︽捣鏅鸿兘鏃犵嚎涓绘満鐗圴1"),
+    TCP_BHZH_GRAIN_V2("TCP_BHZH_GRAIN_V2", "閭︽捣鏅鸿兘鏈夌嚎鐗圴2"),
+    TCP_BEIBO_GRAIN_V1("TCP_BEIBO_GRAIN_V1", "璐濆崥绮儏鍒嗘満鏈嶅姟绔崗璁�"),
+    FZZY_OPENAPI_HTTP("FZZY_OPENAPI_HTTP", "椋庢鑷磋繙API-HTTP鍗忚");
+
+    private String code;
+    private String msg;
+
+    ProtocolEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/data/QuantityProgressData.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/data/QuantityProgressData.java
new file mode 100644
index 0000000..7839bc8
--- /dev/null
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/data/QuantityProgressData.java
@@ -0,0 +1,44 @@
+package com.fzzy.igds.data;
+
+import com.bstek.dorado.annotation.PropertyDef;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 铏妫�娴嬭繘搴� 淇℃伅灏佽
+ *
+ * @author vince
+ */
+@Data
+public class QuantityProgressData implements Serializable {
+
+
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 1L;
+
+	@PropertyDef(label = "鎺у埗鏌淚D")
+	private String serId;
+
+	@PropertyDef(label = "缁勭粐缂栫爜")
+	private String companyId;
+
+	@PropertyDef(label = "浠撳簱ID")
+	private String depotId;
+
+	@PropertyDef(label = "搴撳尯ID")
+	private String deptId;
+
+	@PropertyDef(label = "褰撳墠鐘舵��")
+	private String state;
+
+	@PropertyDef(label = "杩涘害鐧惧垎姣�")
+	private int progress;
+
+	@PropertyDef(label = "璇存槑")
+	private String msg = "";
+
+
+}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvoker.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvoker.java
new file mode 100644
index 0000000..65535c4
--- /dev/null
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvoker.java
@@ -0,0 +1,25 @@
+package com.fzzy.igds.notify;
+
+import com.fzzy.igds.constant.OrderRespEnum;
+import com.fzzy.igds.data.QuantityProgressData;
+
+/**
+ * @Description
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+public interface NotifyWebInvoker {
+
+	String BEAN_ID = "notifyWebInvoker";
+	
+	/**
+	 * 鐩存帴閫氱煡椤甸潰
+	 * 
+	 * @param companyId
+	 * @param orderResp
+	 * @param notifyMsg
+	 */
+	void notifyWeb(String companyId, OrderRespEnum orderResp, String bizType,String notifyMsg);
+
+	void notifyQuantityProgress(QuantityProgressData progress);
+}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvokerImpl.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvokerImpl.java
new file mode 100644
index 0000000..1878fa6
--- /dev/null
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/notify/NotifyWebInvokerImpl.java
@@ -0,0 +1,43 @@
+package com.fzzy.igds.notify;
+
+import com.fzzy.igds.constant.OrderRespEnum;
+import com.fzzy.igds.data.QuantityProgressData;
+import com.fzzy.igds.websocket.WebSocketPacket;
+import com.fzzy.igds.websocket.WebSocketServer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Description
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Slf4j
+@Component
+public class NotifyWebInvokerImpl implements NotifyWebInvoker {
+
+    @Override
+    public void notifyWeb(String companyId, OrderRespEnum orderResp,
+                          String bizType, String notifyMsg) {
+        // 閫氱煡鍓嶇
+        WebSocketPacket packet = new WebSocketPacket();
+        packet.setBizType(bizType);
+        packet.setCompanyId(companyId);
+        packet.setOrderResp(orderResp.getCode());
+        packet.setData(notifyMsg);
+        WebSocketServer.sendByPocket(packet);
+    }
+
+    @Override
+    public void notifyQuantityProgress(QuantityProgressData progress) {
+        // 閫氱煡鍓嶇杩涘害淇℃伅
+        WebSocketPacket packet = new WebSocketPacket();
+        packet.setBizType("quantity");
+        packet.setCompanyId(progress.getCompanyId());
+        packet.setOrderResp(OrderRespEnum.ORDER_INPROGRESS.getCode());
+        packet.setData(progress);
+        packet.setDeptId(progress.getDeptId());
+        WebSocketServer.sendByPocket(packet);
+    }
+
+}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/request/QuantityRequest.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/request/QuantityRequest.java
new file mode 100644
index 0000000..887baf2
--- /dev/null
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/request/QuantityRequest.java
@@ -0,0 +1,43 @@
+package com.fzzy.igds.request;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 绮儏妫�娴嬭姹�
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class QuantityRequest extends ExeBaseRequest {
+
+	/**
+	 * 浜戝彴鍔熻兘 缂栫爜 PTZFunc
+	 */
+	public String func ;
+
+	/**
+	 * 浜戝彴鍔熻兘闄勫姞鍙傛暟锛屾瘮濡傞�熷害锛岄璁剧偣浣�
+	 */
+	public String par;
+
+
+	private Double length1 = 0.0 ;
+	private Double length2 = 0.0 ;
+	private Double length3 = 0.0 ;
+	private Double length4 = 0.0 ;
+
+	private Double width= 0.0;
+	private Double height= 0.0;
+	private Double lineHeight = 0.0;
+    private Double density = 0.0;
+	private Double length = 0.0;
+
+	private String ytIp;
+	private Integer ytPort;
+	private String  depotType;//浠撴埧绫诲瀷
+	private Double volumeAdd = 0.0;//v浣撶Н琛ュ伩 鍗曚綅 m鲁
+	private Double weightAdd = 0.0;//閲嶉噺琛ュ伩 鍗曚綅KG
+	private String sn;
+	//鐢ㄤ簬寮�濮嬮噰闆嗙殑鏃跺�欐彁鍓嶇敓鎴愭壒娆$紪鍙�
+	private String batchId;
+}
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/FileService.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/FileService.java
index 0367bbe..bf579a2 100644
--- a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/FileService.java
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/FileService.java
@@ -89,14 +89,28 @@
                 data.setBizTag(bizTag);
             }
 
-            data.setCreateTime(new Date());
-            data.setCreateBy(ContextUtil.getLoginUserName());
-
-            data.setUpdateTime(new Date());
-            data.setUpdateBy(ContextUtil.getLoginUserName());
-            fileMapper.insert(data);
+            saveFile(data);
         }
     }
+
+    /**
+     *
+     * @param data
+     */
+    public void saveFile(FileInfo data) {
+
+        data.setUpdateTime(new Date());
+        data.setUpdateBy(ContextUtil.getLoginUserName());
+
+        if(StringUtils.isBlank(data.getId())){
+            data.setId(ContextUtil.UUID());
+            data.setCreateTime(new Date());
+            data.setCreateBy(ContextUtil.getLoginUserName());
+        }
+
+        fileMapper.insert(data);
+    }
+
 
     /**
      * 鏍规嵁鏉′欢鏌ヨ鏁版嵁
@@ -139,6 +153,7 @@
         if("TEMP".equals(pathTag)) return getTempFilePath();
         if("CONF".equals(pathTag)) return getConfPath();
         if("TEMPLATE".equals(pathTag)) return getTemplateFilePath();
+        if("QUANTITY".equals(pathTag)) return getQuantityPath();
         if("WORD".equals(pathTag)) return getWordPath();
 
         return getCommonFilePath();
@@ -148,6 +163,19 @@
      * 鑾峰彇浜嬩欢鏂囦欢璺緞
      * @return
      */
+    public String getQuantityPath() {
+        String basePath = FrameworkConfig.getProfile() + "QUANTITY/" + DateFormatUtils.format(new Date(), "yyyyMM") + "/";
+        File file = new File(basePath);
+        if (!file.exists()) {
+            file.mkdirs();
+        }
+        return basePath;
+    }
+
+    /**
+     * 鑾峰彇浜嬩欢鏂囦欢璺緞
+     * @return
+     */
     public String getEventFilePath() {
         String basePath = FrameworkConfig.getProfile() + "EVENT/" + DateFormatUtils.format(new Date(), "yyyyMM") + "/";
         File file = new File(basePath);
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/QuantityService.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/QuantityService.java
index f80d2be..9f3a91c 100644
--- a/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/QuantityService.java
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/service/QuantityService.java
@@ -89,6 +89,15 @@
     }
 
     /**
+     * 淇濆瓨鏁版嵁
+     *
+     * @param data
+     */
+    public void saveData(Quantity data) {
+        quantityMapper.insert(data);
+    }
+
+    /**
      * 鏌ヨ閰嶇疆淇℃伅锛屾牴鎹簱鍖虹紪鐮佽幏鍙�
      *
      * @param companyId
diff --git a/fzzy-igdss-core/src/main/java/com/fzzy/igds/utils/Base64Util.java b/fzzy-igdss-core/src/main/java/com/fzzy/igds/utils/Base64Util.java
index 47f7052..28baaab 100644
--- a/fzzy-igdss-core/src/main/java/com/fzzy/igds/utils/Base64Util.java
+++ b/fzzy-igdss-core/src/main/java/com/fzzy/igds/utils/Base64Util.java
@@ -1,15 +1,18 @@
 package com.fzzy.igds.utils;
 
+import lombok.extern.slf4j.Slf4j;
 import sun.misc.BASE64Decoder;
 import sun.misc.BASE64Encoder;
 
 import java.io.*;
+import java.util.Base64;
 
 /**
  * @Description 鍥剧墖Base澶勭悊
  * @Author CZT
  * @Date 2026/1/7 11:07
  */
+@Slf4j
 public class Base64Util {
 
 	public static String BASE_IMG_START = "data:image/jpg;base64,";
@@ -85,4 +88,59 @@
 		}
 	}
 
+
+	/**
+	 * base64杞负鍥剧墖
+	 *
+	 * @param path   鏂囦欢璺緞锛氬埌鏂囦欢澶瑰嵆鍙紝浠g爜閲屼細鍦ㄦ枃浠跺す閲岀敓鎴愬搴旂殑jpg鏂囦欢
+	 * @param base64
+	 * @return
+	 */
+	public static String base64ToJpg(String path, String fileName, String base64) {
+		// 鍒ゆ柇鏂囦欢璺緞鏄惁瀛樺湪
+		File filePath = new File(path);
+		if (!filePath.exists()) {
+			filePath.mkdirs();
+		}
+		// 鍒涘缓鏂囦欢
+		String jpgFile = path + "\\" + fileName + ".jpg";
+		File file = new File(jpgFile);
+		boolean jpgFileExist = false;
+		try {
+			jpgFileExist = file.createNewFile();
+			log.info("jpg鏂囦欢鍒涘缓鎴愬姛");
+		} catch (IOException e) {
+			log.info("jpg鏂囦欢鍒涘缓澶辫触");
+			e.printStackTrace();
+		}
+		if (jpgFileExist) {
+			// 瑙e瘑
+			Base64.Decoder decoder = Base64.getDecoder();
+			// 鍘绘帀base64鍓嶇紑 data:image/jpeg;base64,
+			base64 = base64.substring(base64.indexOf(",", 1) + 1, base64.length());
+			byte[] b = decoder.decode(base64);
+			// 澶勭悊鏁版嵁
+			for (int i = 0; i < b.length; ++i) {
+				if (b[i] < 0) {
+					b[i] += 256;
+				}
+			}
+			// 淇濆瓨鍥剧墖
+			try {
+				FileOutputStream out = new FileOutputStream(jpgFile);
+				out.write(b);
+				out.flush();
+				out.close();
+				// 鍐欏叆鎴愬姛杩斿洖鏂囦欢璺緞
+				return jpgFile;
+			} catch (FileNotFoundException e) {
+				log.info("鏂囦欢鏈壘鍒�");
+				e.printStackTrace();
+			} catch (IOException e) {
+				log.info("鍐欏叆澶辫触");
+				e.printStackTrace();
+			}
+		}
+		return "鏂囦欢涓嶅瓨鍦�";
+	}
 }
\ No newline at end of file
diff --git a/fzzy-igdss-io/pom.xml b/fzzy-igdss-io/pom.xml
index f3b72e8..ce0de26 100644
--- a/fzzy-igdss-io/pom.xml
+++ b/fzzy-igdss-io/pom.xml
@@ -67,9 +67,6 @@
                 </includes>
                 <filtering>true</filtering>
             </resource>
-            <resource>
-                <directory>src/main/resources</directory>
-            </resource>
         </resources>
     </build>
 </project>
\ No newline at end of file
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/ServerRunner.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/ServerRunner.java
new file mode 100644
index 0000000..5803d50
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/ServerRunner.java
@@ -0,0 +1,31 @@
+package com.fzzy.igds;
+
+import com.fzzy.igds.quantity.server.BhznQuantityServerEngine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @Description 鍙互鏍规嵁閰嶇疆鏂囦欢鐏垫椿璋冩暣,閰嶇疆闅忕郴缁熻嚜鍔ㄥ惎鍔ㄦ湇鍔� -- 鎵ц椤哄簭10-19
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Component(ServerRunner.BEAN_ID)
+@Order(value = 10)
+public class ServerRunner implements CommandLineRunner {
+
+    public static final String BEAN_ID = "quantity.serverRunner";
+
+    @Resource
+    private BhznQuantityServerEngine serverEngine;
+
+    @Override
+    public void run(String... strings) throws Exception {
+
+        serverEngine.start(BhznQuantityServerEngine.PORT);
+
+    }
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/manager/QuantityRemoteManager.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/manager/QuantityRemoteManager.java
new file mode 100644
index 0000000..c8f0f45
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/manager/QuantityRemoteManager.java
@@ -0,0 +1,47 @@
+package com.fzzy.igds.io.manager;
+
+import com.fzzy.igds.io.service.RemoteQuantityService;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Description 鎺ュ彛Api鎵�鏈夊崗璁殑鍗忚绫伙紝鏍规嵁涓嶅悓鐨勫崗璁厤缃皟鐢ㄤ笉鍚岀殑鍗忚瀹炵幇
+ * @Author CZT
+ * @Date 2025/12/9 9:56
+ */
+@Component(QuantityRemoteManager.BEAN_ID)
+public class QuantityRemoteManager implements ApplicationContextAware {
+
+	public static final String BEAN_ID = "quantity.remoteManager";
+
+	public static Map<String, RemoteQuantityService> remoteQuantityMap = new HashMap<>();
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext)
+			throws BeansException {
+
+		Map<String, RemoteQuantityService> quantityMap = applicationContext
+				.getBeansOfType(RemoteQuantityService.class);
+		for (String key : quantityMap.keySet()) {
+			remoteQuantityMap.put(quantityMap.get(key).getProtocol(),
+					quantityMap.get(key));
+		}
+
+	}
+
+	/**
+	 * 鏍规嵁鍗忚鑾峰彇瀹炵幇
+	 *
+	 * @param protocol
+	 * @return
+	 */
+	public RemoteQuantityService getRemoteQuantityService(String protocol) {
+		return remoteQuantityMap.get(protocol);
+	}
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/RemoteQuantityService.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/RemoteQuantityService.java
new file mode 100644
index 0000000..185d878
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/RemoteQuantityService.java
@@ -0,0 +1,70 @@
+package com.fzzy.igds.io.service;
+
+import com.fzzy.igds.request.QuantityRequest;
+import com.fzzy.igds.response.BaseResponse;
+
+/**
+ * @Desc: 鏁伴噺妫�娴嬪姛鑳芥帴鍙e畾涔�
+ * @author: Andy
+ * @update-time: 2022/12/22
+ */
+public interface RemoteQuantityService {
+
+    /**
+     * 褰撳墠鍗忚鍚嶇О锛岀郴缁熸牴鎹崗璁悕绉拌嚜鍔ㄨ皟鐢ㄥ垎鏈哄尮閰嶇殑鍗忚瀹炵幇
+     *
+     * @return
+     */
+    String getProtocol();
+
+
+    /**
+     * 鏁伴噺妫�娴嬪紑濮嬫墽琛屾娴�
+     *
+     * @param request
+     * @return
+     */
+    BaseResponse checkStart(QuantityRequest request);
+
+
+    /**
+     * @Desc:杩滅▼涓嬪彂閰嶇疆淇℃伅
+     * @author: Andy
+     * @update-time: 2022/12/22
+     */
+    BaseResponse remoteConf(QuantityRequest request);
+
+    /**
+     * 鏆傚仠妫�娴嬪姛鑳�
+     *
+     * @param request
+     * @return
+     */
+    BaseResponse checkStop(QuantityRequest request);
+
+
+    /**
+     * 杩囩▼鎶撴媿鐓х墖
+     *
+     * @param request
+     * @return
+     */
+    BaseResponse snapImg(QuantityRequest request);
+
+    /**
+     * 鍏抽棴鎶ヨ
+     *
+     * @param request
+     * @return
+     */
+    BaseResponse closeWarn(QuantityRequest request);
+
+    /**
+     * 鎽勫儚澶翠簯鍙版帶鍒�
+     *
+     * @param Request
+     * @return
+     */
+    BaseResponse ptz(QuantityRequest Request);
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/impl/DefaultRemoteQuantityImpl.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/impl/DefaultRemoteQuantityImpl.java
new file mode 100644
index 0000000..d66d080
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/io/service/impl/DefaultRemoteQuantityImpl.java
@@ -0,0 +1,48 @@
+package com.fzzy.igds.io.service.impl;
+
+import com.fzzy.igds.constant.OrderRespEnum;
+import com.fzzy.igds.constant.ProtocolEnum;
+import com.fzzy.igds.io.service.RemoteQuantityService;
+import com.fzzy.igds.request.QuantityRequest;
+import com.fzzy.igds.response.BaseResponse;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class DefaultRemoteQuantityImpl implements RemoteQuantityService {
+
+    @Override
+    public String getProtocol() {
+        return ProtocolEnum.TCP_DEFAULT.getCode();
+    }
+
+    @Override
+    public BaseResponse checkStart(QuantityRequest request) {
+        return new BaseResponse(OrderRespEnum.NO_PROTOCOL);
+    }
+
+    @Override
+    public BaseResponse remoteConf(QuantityRequest request) {
+        return null;
+    }
+
+    @Override
+    public BaseResponse checkStop(QuantityRequest request) {
+        return new BaseResponse(OrderRespEnum.NO_PROTOCOL);
+    }
+
+    @Override
+    public BaseResponse snapImg(QuantityRequest request) {
+        return new BaseResponse(OrderRespEnum.NO_PROTOCOL);
+    }
+    
+    @Override
+    public BaseResponse closeWarn(QuantityRequest request) {
+        return new BaseResponse(OrderRespEnum.NO_PROTOCOL);
+    }
+
+    @Override
+    public BaseResponse ptz(QuantityRequest Request) {
+        return new BaseResponse(OrderRespEnum.NO_PROTOCOL);
+    }
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/analysis/AnalysisService.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/analysis/AnalysisService.java
new file mode 100644
index 0000000..347cd7b
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/analysis/AnalysisService.java
@@ -0,0 +1,299 @@
+package com.fzzy.igds.quantity.analysis;
+
+import com.alibaba.fastjson.JSON;
+import com.fzzy.igds.constant.Constant;
+import com.fzzy.igds.data.QuantityProgressData;
+import com.fzzy.igds.domain.Depot;
+import com.fzzy.igds.domain.FileInfo;
+import com.fzzy.igds.domain.Quantity;
+import com.fzzy.igds.domain.QuantityConf;
+import com.fzzy.igds.notify.NotifyWebInvoker;
+import com.fzzy.igds.quantity.command.BhznRemoteQuantityImpl;
+import com.fzzy.igds.quantity.command.CommandBuilder;
+import com.fzzy.igds.quantity.dto.IoMessage;
+import com.fzzy.igds.quantity.dto.Resp2003;
+import com.fzzy.igds.quantity.dto.Resp2004;
+import com.fzzy.igds.quantity.dto.Resp2006;
+import com.fzzy.igds.quantity.server.BhznQuantityServerEngine;
+import com.fzzy.igds.quantity.util.ServerUtils;
+import com.fzzy.igds.request.QuantityRequest;
+import com.fzzy.igds.service.DepotService;
+import com.fzzy.igds.service.FileService;
+import com.fzzy.igds.service.QuantityService;
+import com.fzzy.igds.utils.ContextUtil;
+import com.ruoyi.common.config.FrameworkConfig;
+import com.ruoyi.common.core.redis.RedisCache;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.Date;
+
+/**
+ * @Description 鍗忚瑙f瀽鍏ュ彛
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Slf4j
+@Component("fzzy.quantityAnalysisService")
+public class AnalysisService{
+
+    @Autowired
+    private DepotService depotService;
+    @Autowired
+    private QuantityService quantityService;
+    @Autowired
+    private NotifyWebInvoker notifyWebInvoker;
+    @Autowired
+    private FileService fileService;
+    @Autowired
+    private RedisCache redisUtil;
+    @Autowired
+    private BhznQuantityServerEngine bhznQuantityServerEngine;
+    @Autowired
+    private BhznRemoteQuantityImpl remoteQuantity;
+
+    /**
+     * @param sessionKey ip:port
+     */
+    public void analysis(String sessionKey, IoMessage message) throws Exception {
+
+        if (message == null) return;
+
+        String[] attr = sessionKey.split(":");
+        String ip = attr[0];
+        Integer port = Integer.valueOf(attr[1]);
+        String checkMsg = checkMsg(message);
+
+        if (null != checkMsg) {
+            log.warn("鏁伴噺妫�娴�---->>>骞冲彴锛氾紝鍒嗘満SN={}锛屾姤鏂囦俊鎭�-={}锛屽搷搴斿悧杩斿洖涓嶆纭紝鏃犳硶杩涜瑙f瀽," + checkMsg, message.getSn(), message.toString());
+            return;
+        }
+
+        QuantityConf conf = quantityService.getCacheQuantityConfBySn(message.getSn());
+
+        if (null == conf) {
+            //璇存槑褰撳墠璁惧鏈敞鍐屽钩鍙帮紝鐩存帴韪㈠嚭杩炴帴
+            log.info("鏁伴噺妫�娴�---->>>骞冲彴锛氱櫥闄嗚璇丼N-{}-骞冲彴鏈敞鍐岋紝鐩存帴韪㈠嚭杩炴帴", message.getSn());
+            bhznQuantityServerEngine.destroy(ip, port);
+            return;
+        }
+
+
+        switch (message.getFunctionId()) {
+            case "1001"://鏈嶅姟绔笅鍙戦厤缃�
+                //涓嶅鐞�
+                break;
+            case "1002"://缁堢璇锋眰鏃堕棿鍚屾
+                analysis1002(ip, port, conf, message);
+                break;
+            case "1003"://缁堢璁惧璇锋眰鐧婚檰
+                analysis1003(ip, port, conf, message);
+                break;
+            case "2001"://寮�濮嬫娴�
+                //
+                break;
+            case "2002"://鍋滄妫�娴�
+                //
+                break;
+            case "2003"://鏈嶅姟绔煡璇㈣繘搴�
+                analysis2003(ip, port, conf, message);
+                break;
+            case "2004"://缁堢鍙戣捣缁撴灉涓婃姤
+                analysis2004(ip, port, conf, message);
+                break;
+            case "2005"://鏈嶅姟绔彂璧锋暟鎹偣浣嶆彁鍙�
+                analysis2005(ip, port, conf, message);
+                break;
+            case "2006"://鏈嶅姟绔姹傛姄鎷嶏紝缁堢杩斿洖鍥惧儚淇℃伅
+                analysis2006(ip, port, conf, message);
+                break;
+            case "2007"://缁堢涓诲姩鍙戣捣蹇冭烦缁存寔
+                analysis2007(ip, port, conf, message);
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * 鐢ㄦ埛鐧婚檰鎴愬姛锛屾洿鏂版暟鎹拰缂撳瓨锛岃繘鍏ュ綋鍓嶆帴鍙h〃绀哄钩鍙板凡缁忚璇侀�氳繃锛岀洿鎺ユ洿鏂板苟杩斿洖姝e父淇℃伅
+     *
+     * @param ip
+     * @param port
+     * @param conf
+     * @param message
+     */
+    private void analysis1003(String ip, Integer port, QuantityConf conf, IoMessage message) {
+        conf.setIp(ip);
+        conf.setPort(port);
+        conf.setStatus(Constant.YN_Y);
+
+        quantityService.updateQuantityConfBySn(conf);
+
+        //杩斿洖姝e父
+        remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build1003Message(message));
+    }
+
+    /**
+     * 杩斿洖缁欑粓绔綋鍓嶆椂闂�
+     *
+     * @param quantityConf
+     * @param message
+     */
+    private void analysis1002(String ip, Integer port, QuantityConf quantityConf, IoMessage message) {
+        //鐩存帴杩斿洖
+        remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build1002Message(message));
+    }
+
+    /**
+     * 瑙f瀽缁堢杩斿洖鐨勯噰闆嗚繘搴�
+     *
+     * @param message
+     */
+    private void analysis2003(String ip, Integer port, QuantityConf conf, IoMessage message) {
+
+        String key = ServerUtils.buildRequestKey(conf.getCompanyId(), conf.getSn());
+
+        QuantityRequest quantityRequest = (QuantityRequest) redisUtil.getCacheObject(key);
+        if (quantityRequest == null) {
+            log.error("娌℃湁鎵惧埌鍙戦�佺殑鍛戒护锛屽彲鑳藉凡缁忚秴鏃讹紝鍙栨秷瑙f瀽锛�" + message.toString());
+            return;
+        }
+
+        QuantityProgressData progressData = new QuantityProgressData();
+        progressData.setCompanyId(conf.getCompanyId());
+        progressData.setDepotId(conf.getDepotId());
+        progressData.setDeptId(conf.getDeptId());
+        Resp2003 content = JSON.parseObject(message.getContent(), Resp2003.class);
+        if (content == null) {
+            log.error("娌℃湁鎵惧埌鍏宠仈閰嶇疆锛屽彇娑堣В鏋愶細" + message.toString());
+            return;
+        }
+        Depot depot = depotService.getCacheDepot(conf.getCompanyId(),
+                conf.getDepotId());
+        progressData.setProgress(content.getProgress());
+
+        log.info(depot.getName() + "鏁伴噺鐩戞祴鎵ц杩涘害锛�" + progressData.getProgress());
+        progressData.setMsg(depot.getName() + "鏁伴噺鐩戞祴鎵ц杩涘害锛�"
+                + progressData.getProgress());
+        notifyWebInvoker.notifyQuantityProgress(progressData);
+        //鏍规嵁杩涘害鎶撴媿
+        if (progressData.getProgress() >= 1 && progressData.getProgress() <= 25) {
+            remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build2006Message(message));
+        }
+        if (progressData.getProgress() > 25 && progressData.getProgress() <= 50) {
+            remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build2006Message(message));
+        }
+        if (progressData.getProgress() > 50 && progressData.getProgress() <= 75) {
+            remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build2006Message(message));
+        }
+        if (progressData.getProgress() > 75 && progressData.getProgress() <= 99) {
+            remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build2006Message(message));
+        }
+    }
+
+    /**
+     * 瑙f瀽缁堢杩斿洖鐨勭粨鏋滐紝骞惰繑鍥炴垚鍔�
+     *
+     * @param conf
+     * @param message
+     */
+    private void analysis2004(String ip, Integer port, QuantityConf conf, IoMessage message) {
+
+        Resp2004 content = JSON.parseObject(message.getContent(), Resp2004.class);
+        if (content == null) {
+            log.error("娌℃湁鏁版嵁锛屽彇娑堣В鏋愶細" + message.toString());
+            return;
+        }
+        String key = ServerUtils.buildRequestKey(conf.getCompanyId(), conf.getSn());
+
+        QuantityRequest request = (QuantityRequest) redisUtil.getCacheObject(key);
+
+        if (request == null) {
+            log.error("娌℃湁鑾峰彇鍒板彂閫佸懡浠わ紝鍙栨秷瑙f瀽锛�" + message.toString());
+            return;
+        }
+        Depot depot = depotService.getCacheDepot(conf.getCompanyId(), conf.getDepotId());
+        Quantity quantityData = new Quantity();
+        quantityData.setBatchId(request.getBatchId());
+        quantityData.setReceiveDate(new Date());
+        quantityData.setBulk(content.getVolume());
+        quantityData.setWeight(content.getWeight());
+        quantityData.setDepotId(depot.getId());
+        quantityData.setDeptId(depot.getDeptId());
+        quantityData.setCompanyId(depot.getCompanyId());
+        quantityData.setPoints("");
+        quantityService.saveData(quantityData);
+        //鐩存帴杩斿洖
+        remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build2004Message(message));
+    }
+
+    /**
+     * 瑙f瀽缁堢杩斿洖鐨勭偣浣嶆暟鎹�
+     *
+     * @param quantityConf
+     * @param message
+     */
+    private void analysis2005(String ip, Integer port, QuantityConf quantityConf, IoMessage message) {
+        // todo
+    }
+
+    /**
+     * 瑙f瀽鎶撴媿鐨勫浘鐗囦俊鎭�
+     *
+     * @param conf
+     * @param message
+     */
+    private void analysis2006(String ip, Integer port, QuantityConf conf, IoMessage message) {
+        Resp2006 content = JSON.parseObject(message.getContent(), Resp2006.class);
+        if (content == null) {
+            log.error("娌℃湁鏁版嵁锛屽彇娑堣В鏋愶細" + message.toString());
+            return;
+        }
+        String key = ServerUtils.buildRequestKey(conf.getCompanyId(), conf.getSn());
+        QuantityRequest res = (QuantityRequest) redisUtil.getCacheObject(key);
+        if (res == null) {
+            log.error("娌℃湁鑾峰彇鍒板彂閫佸懡浠わ紝鍙栨秷瑙f瀽锛�" + message.toString());
+            return;
+        }
+        String fileName = ContextUtil.generateId()+ ".jpg";
+        String savePath = fileService.getFileSavePath("QUANTITY");
+        String filePath = savePath+fileName;
+        fileService.baseImg2Disk(filePath, content.getData());
+        FileInfo data = new FileInfo();
+        data.setId(ContextUtil.UUID());
+        data.setCreateTime(new Date());
+        data.setFileName(fileName);
+        data.setFilePath(filePath.replace(FrameworkConfig.getProfile(), "/profile/"));
+        data.setBizId(res.getBatchId());
+        data.setBizTag("quantity");
+        data.setCompanyId(conf.getCompanyId());
+        fileService.saveFile(data);
+    }
+
+    /**
+     * 蹇冭烦鍙嶉
+     *
+     * @param quantityConf
+     * @param message
+     */
+    private void analysis2007(String ip, Integer port, QuantityConf quantityConf, IoMessage message) {
+        remoteQuantity.sendMsg(ip, port, CommandBuilder.getInstance().build2007Message(message));
+    }
+
+    public String checkMsg(IoMessage message) {
+        if (StringUtils.isEmpty(message.getResult())) return null;
+        if (ServerUtils.RESP_0.equals(message.getResult())) return null;
+        
+        if (ServerUtils.RESP_1.equals(message.getResult())) return "鍛戒护鏍煎紡閿欒";
+        if (ServerUtils.RESP_2.equals(message.getResult())) return "鍛戒护鏁版嵁妫�楠屽紓甯�";
+        if (ServerUtils.RESP_3.equals(message.getResult())) return "鍙戦�佽秴鏃堕敊璇�";
+        if (ServerUtils.RESP_4.equals(message.getResult())) return "缁堢璁惧涓嶅湪绾�";
+        if (ServerUtils.RESP_5.equals(message.getResult())) return "缁堢璁惧鎵ц涓�";
+        if (ServerUtils.RESP_6.equals(message.getResult())) return "缁堢璁惧鎶撴媿澶辫触";
+        if (ServerUtils.RESP_9.equals(message.getResult())) return "鍏跺畠閿欒";
+        return null;
+    }
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/BhznRemoteQuantityImpl.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/BhznRemoteQuantityImpl.java
new file mode 100644
index 0000000..96145ab
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/BhznRemoteQuantityImpl.java
@@ -0,0 +1,140 @@
+package com.fzzy.igds.quantity.command;
+
+import com.fzzy.igds.constant.OrderRespEnum;
+import com.fzzy.igds.constant.ProtocolEnum;
+import com.fzzy.igds.io.service.RemoteQuantityService;
+import com.fzzy.igds.notify.NotifyWebInvoker;
+import com.fzzy.igds.quantity.dto.IoMessage;
+import com.fzzy.igds.quantity.server.BhznQuantityServerEngine;
+import com.fzzy.igds.quantity.util.ServerUtils;
+import com.fzzy.igds.request.QuantityRequest;
+import com.fzzy.igds.response.BaseResponse;
+import com.ld.io.api.InvokeResult;
+import com.ruoyi.common.core.redis.RedisCache;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @Description
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Slf4j
+@Component(BhznRemoteQuantityImpl.BEAN_ID)
+public class BhznRemoteQuantityImpl implements RemoteQuantityService {
+
+    public static final String BEAN_ID = "fzzy.remoteQuantityService";
+    @Autowired
+    private BhznQuantityServerEngine bhznQuantityServerEngine;
+    @Autowired
+    private NotifyWebInvoker notifyWebInvoker;
+    @Autowired
+    private RedisCache redisUtil;
+
+    @Override
+    public String getProtocol() {
+        return ProtocolEnum.TCP_FZZY_QUANTITY_V35.getCode();
+    }
+
+    @Override
+    public BaseResponse checkStart(QuantityRequest request) {
+        try {
+
+            String key = ServerUtils.buildRequestKey(request.getCompanyId(), request.getSn());
+
+            IoMessage message = CommandBuilder.getInstance().build2001Message(request);
+            InvokeResult result = sendMsg(request.getIp(), request.getPort(), message);
+
+            // 濡傛灉鏈夋墽琛屽紓甯革紝鐩存帴閫氱煡鍒板墠绔�
+            if (InvokeResult.SUCCESS != result) {
+                log.info("骞冲彴------>>>>鏁伴噺妫�娴嬶細寮�濮嬫娴�-澶辫触{}", result.getMessage());
+                notifyWebInvoker.notifyWeb(request.getCompanyId(), OrderRespEnum.ORDER_ERROR, "SYS", request.getSerName() + "銆�寮�濮嬫娴嬶紝鍛戒护鎵ц澶辫触");
+                return new BaseResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                        "寮�濮嬫娴嬫墽琛屽け璐ワ細" + result.getMessage());
+            }
+
+            //鏈�闀夸繚瀛樹竴涓皬鏃�
+            redisUtil.setCacheObject(key, request, 60 * 60 , TimeUnit.SECONDS);
+
+            //鍚姩瀛愪换鍔″畾鏃舵煡璇㈣繘搴�
+            FutureTask<String> futureTask = new FutureTask<>(new QueryProgressTask(redisUtil, this, key));
+            ExecutorService executorService = Executors.newCachedThreadPool();
+            executorService.submit(futureTask);
+            executorService.shutdown();
+
+        } catch (Exception e) {
+            return new BaseResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                    "鎵ц澶辫触锛�" + e.getMessage());
+        }
+
+        return new BaseResponse(OrderRespEnum.ORDER_SUCCESS);
+    }
+
+
+    @Override
+    public BaseResponse remoteConf(QuantityRequest request) {
+
+        //妫�娴嬩箣鍓嶅厛涓嬪彂閰嶇疆
+        IoMessage message = CommandBuilder.getInstance().build1001Message(request);
+
+        InvokeResult result = sendMsg(request.getIp(), request.getPort(), message);
+
+        if (InvokeResult.SUCCESS != result) {
+            log.info("骞冲彴------>>>>鏁伴噺妫�娴嬶細涓嬪彂閰嶇疆澶辫触-澶辫触{}", result.getMessage());
+            notifyWebInvoker.notifyWeb(request.getCompanyId(), OrderRespEnum.ORDER_ERROR, "SYS", request.getSerName() + "銆�涓嬪彂妫�娴嬮厤缃紝鍛戒护鎵ц澶辫触");
+            return new BaseResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                    "涓嬪彂閰嶇疆鎵ц澶辫触锛�" + result.getMessage());
+        }
+
+        return new BaseResponse(OrderRespEnum.ORDER_SUCCESS);
+    }
+
+    @Override
+    public BaseResponse checkStop(QuantityRequest request) {
+        //妫�娴嬩箣鍓嶅厛涓嬪彂閰嶇疆
+        IoMessage message = CommandBuilder.getInstance().build2002Message(request);
+        InvokeResult result = sendMsg(request.getIp(), request.getPort(), message);
+        if (InvokeResult.SUCCESS != result) {
+            log.info("骞冲彴------>>>>鏁伴噺妫�娴嬶細鍋滄妫�娴�-澶辫触{}", result.getMessage());
+            notifyWebInvoker.notifyWeb(request.getCompanyId(), OrderRespEnum.ORDER_ERROR, "SYS", request.getSerName() + "銆�鍋滄妫�娴嬪け璐ワ紝鍛戒护鎵ц澶辫触");
+            return new BaseResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                    "鍋滄妫�娴嬫墽琛屽け璐ワ細" + result.getMessage());
+        }
+        String key = ServerUtils.buildRequestKey(request.getCompanyId(),request.getSn());
+        //鍒犻櫎缂撳瓨
+        redisUtil.deleteObject(key);
+
+        return new BaseResponse(OrderRespEnum.ORDER_SUCCESS);
+    }
+
+    @Override
+    public BaseResponse snapImg(QuantityRequest request) {
+        return new BaseResponse(OrderRespEnum.NO_PROTOCOL);
+    }
+
+    @Override
+    public BaseResponse closeWarn(QuantityRequest request) {
+        return new BaseResponse(OrderRespEnum.NO_FUNCTION);
+    }
+
+    @Override
+    public BaseResponse ptz(QuantityRequest Request) {
+        return new BaseResponse(OrderRespEnum.NO_FUNCTION);
+    }
+
+    public InvokeResult sendMsg(String ip, Integer port, IoMessage message) {
+
+        String msg = CommandBuilder.getInstance().build(message);
+
+        log.info("骞冲彴------>>>>鏁伴噺妫�娴嬶細鎶ユ枃淇℃伅-{}", msg);
+
+        InvokeResult result = bhznQuantityServerEngine.push(ip, port, msg.getBytes());
+        return result;
+    }
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/CommandBuilder.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/CommandBuilder.java
new file mode 100644
index 0000000..da0f3e6
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/CommandBuilder.java
@@ -0,0 +1,210 @@
+package com.fzzy.igds.quantity.command;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fzzy.igds.quantity.dto.IoMessage;
+import com.fzzy.igds.quantity.dto.Req1001;
+import com.fzzy.igds.quantity.dto.Resp1002;
+import com.fzzy.igds.quantity.util.ServerUtils;
+import com.fzzy.igds.request.QuantityRequest;
+
+/**
+ * @Description 鍛戒护鐢熸垚
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+public class CommandBuilder {
+
+    /**
+     * 涓嬪彂閰嶇疆
+     *
+     * @param request
+     * @return
+     */
+    public IoMessage build1001Message(QuantityRequest request) {
+        IoMessage message = new IoMessage();
+        // 璋冩暣淇℃伅
+        buildInfo(message, request);
+        Req1001 req1001 = new Req1001();
+        req1001.setHeight(request.getHeight().intValue());
+        req1001.setOrien(1);
+        req1001.setVoluWeight(request.getDensity().intValue());
+        req1001.setStorageType("01".equals(request.getDepotType()) ? 1 : 0);
+
+        req1001.setWeightAdd(request.getWeightAdd().intValue());
+        req1001.setVolumeAdd(request.getVolumeAdd().intValue());
+        if ("01".equals(request.getDepotType())) {
+            req1001.setStorageType(1);
+            req1001.setLength(new Double((request.getLength() * 100.00)).intValue());
+            req1001.setWidth(new Double((request.getWidth() * 100.00)).intValue());
+        } else {
+            req1001.setStorageType(0);
+            req1001.setRadius(new Double((request.getWidth() * 100.00)).intValue()); //绛掍粨鏃跺�欏搴﹀綋浣滃崐寰�
+        }
+        message.setContent(JSON.toJSONString(req1001));
+        message.setFunctionId(ServerUtils.FUNCTION_1001);
+        return message;
+    }
+
+    /**
+     * 鍥炲鏃堕棿
+     *
+     * @return
+     */
+    public IoMessage build1002Message(IoMessage message) {
+        message.setFunctionId(ServerUtils.FUNCTION_1002);
+        Resp1002 resp1002 = new Resp1002();
+        resp1002.setTime(System.currentTimeMillis());
+        message.setContent(JSON.toJSONString(resp1002));
+        return message;
+    }
+
+    /**
+     * 鍥炲鐧婚檰鎴愬姛
+     *
+     * @return
+     */
+    public IoMessage build1003Message(IoMessage message) {
+        message.setFunctionId(ServerUtils.FUNCTION_1003);
+        message.setContent(null);
+        return message;
+    }
+
+    /**
+     * 寮�濮嬫娴�
+     *
+     * @param request
+     * @return
+     */
+    public IoMessage build2001Message(QuantityRequest request) {
+        IoMessage message = new IoMessage();
+        // 璋冩暣淇℃伅
+        buildInfo(message, request);
+        message.setFunctionId(ServerUtils.FUNCTION_2001);
+        return message;
+    }
+
+    /**
+     * 鍋滄妫�娴�
+     *
+     * @param request
+     * @return
+     */
+    public IoMessage build2002Message(QuantityRequest request) {
+        IoMessage message = new IoMessage();
+        // 璋冩暣淇℃伅
+        buildInfo(message, request);
+        message.setFunctionId(ServerUtils.FUNCTION_2002);
+        return message;
+    }
+
+    /**
+     * 杩涘害鏌ヨ
+     *
+     * @param request
+     * @return
+     */
+    public IoMessage build2003Message(QuantityRequest request) {
+        IoMessage message = new IoMessage();
+        // 璋冩暣淇℃伅
+        buildInfo(message, request);
+        message.setFunctionId(ServerUtils.FUNCTION_2003);
+        return message;
+    }
+
+    /**
+     * 缁撴灉涓婃姤
+     *
+     * @param
+     * @return
+     */
+    public IoMessage build2004Message(IoMessage message) {
+        message.setFunctionId(ServerUtils.FUNCTION_2004);
+        message.setContent(null);
+        return message;
+    }
+
+    /**
+     * 鏌ヨ鐐逛綅鏁版嵁
+     *
+     * @param request
+     * @return
+     */
+    public IoMessage build2005Message(QuantityRequest request) {
+        IoMessage message = new IoMessage();
+        // 璋冩暣淇℃伅
+        buildInfo(message, request);
+        message.setFunctionId(ServerUtils.FUNCTION_2005);
+        return message;
+    }
+
+    /**
+     * 鎶撴媿
+     *
+     * @param message
+     * @return
+     */
+    public IoMessage build2006Message(IoMessage message) {
+        message.setFunctionId(ServerUtils.FUNCTION_2006);
+        message.setContent("");
+        return message;
+    }
+
+    /**
+     * 鎶撴媿
+     *
+     * @param request
+     * @return
+     */
+    public IoMessage build2006Message(QuantityRequest request) {
+        IoMessage message = new IoMessage();
+        // 璋冩暣淇℃伅
+        buildInfo(message, request);
+        message.setFunctionId(ServerUtils.FUNCTION_2006);
+        return message;
+    }
+
+    /**
+     * 蹇冭烦杩斿洖
+     *
+     * @param message
+     * @return
+     */
+    public IoMessage build2007Message(IoMessage message) {
+        //message.setFunctionId(ServerUtils.FUNCTION_2007);
+        return message;
+    }
+
+    public void buildInfo(IoMessage message, QuantityRequest request) {
+        message.setSn(request.getSn());
+        message.setOrderId(ServerUtils.createOrderId());
+        message.setSign(ServerUtils.SIGN_DEFAULT);
+        message.setResult(ServerUtils.RESP_0);
+        message.setVersion(ServerUtils.VERSION_1);
+    }
+
+    /**
+     * 鏍规嵁鐢熸垚鐨勫懡浠わ紝杩涜璋冩暣
+     *
+     * @param message
+     */
+    public String build(IoMessage message) {
+        StringBuffer hexSb = new StringBuffer();
+        hexSb.append(ServerUtils.MSG_BEGIN);
+        hexSb.append(JSONObject.toJSONString(message));
+        hexSb.append((ServerUtils.MSG_END));
+        return hexSb.toString();
+    }
+
+
+    private static CommandBuilder instance = new CommandBuilder();
+
+    private CommandBuilder() {
+    }
+
+    public static CommandBuilder getInstance() {
+        return instance;
+    }
+
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/QueryProgressTask.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/QueryProgressTask.java
new file mode 100644
index 0000000..89c7fd6
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/command/QueryProgressTask.java
@@ -0,0 +1,65 @@
+package com.fzzy.igds.quantity.command;
+
+import com.fzzy.igds.quantity.dto.IoMessage;
+import com.fzzy.igds.request.QuantityRequest;
+import com.ruoyi.common.core.redis.RedisCache;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.Callable;
+
+/**
+ * @Description 鏁伴噺妫�娴嬭繘搴︽煡璇紝榛樿鎵ц涓夋鏌ヨ鍜屼笁娆℃姄鎷�
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Slf4j
+public class QueryProgressTask implements Callable<String> {
+
+    private RedisCache redisUtil;
+
+    private String redisKey;
+
+    private BhznRemoteQuantityImpl remoteQuantityService;
+
+    public QueryProgressTask() {
+        super();
+    }
+
+    public QueryProgressTask(RedisCache redisUtil, BhznRemoteQuantityImpl remoteQuantityService, String redisKey) {
+        super();
+        this.redisUtil = redisUtil;
+        this.remoteQuantityService = remoteQuantityService;
+        this.redisKey = redisKey;
+    }
+
+    @Override
+    public String call() throws Exception {
+
+        int index = 1;
+        while (index <= 10) {
+            index++;
+            try {
+                Thread.sleep(1000 * 35);
+                QuantityRequest request = (QuantityRequest) redisUtil.getCacheObject(redisKey);
+                if (null == request) {
+                    index = 11;
+                    log.debug("瀛愬懡浠ゆ墽琛岃繘搴︽煡璇㈢粨鏉燂細妫�娴嬪畬鎴�" );
+                    return "SUCCESS";
+                }
+
+                IoMessage message = CommandBuilder.getInstance().build2003Message(request);
+                log.debug("骞冲彴---->>鏁伴噺妫�娴嬶細瀛愬懡浠ゆ墽琛岃繘搴︽煡璇細" + message.toString());
+                remoteQuantityService.sendMsg(request.getIp(), request.getPort(), message);
+
+                Thread.sleep(1000 * 3);
+
+            } catch (Exception e) {
+                log.error("骞冲彴---->>鏁伴噺妫�娴嬶細瀛愬懡浠ゆ墽琛屽嚭鐜板紓甯革細" + e.getMessage());
+                log.error(e.getMessage(), e);
+            }
+        }
+        
+        return "SUCCESS";
+    }
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/IoMessage.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/IoMessage.java
new file mode 100644
index 0000000..56dc025
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/IoMessage.java
@@ -0,0 +1,26 @@
+package com.fzzy.igds.quantity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Data
+public class IoMessage implements Serializable {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+    private String sn;//搴忓垪鍙�
+	private String version = "V1.0";
+    private String sign = "0000";
+    private String functionId;
+    private String result;
+    private String orderId;
+    private String content;//娑堟伅浣�
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Req1001.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Req1001.java
new file mode 100644
index 0000000..34d7090
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Req1001.java
@@ -0,0 +1,32 @@
+package com.fzzy.igds.quantity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Data
+public class Req1001 implements Serializable {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+    private int height;//瀹夎楂樺害
+    private int  orien;//瀹夎鏈濆悜 8涓爣鍑嗘柟鍚戯紝1-涓滐紝2-瑗匡紝3-鍗楋紝4-鍖楋紝5-涓滃崡锛�6-瑗垮崡锛�7-涓滃寳锛�8-瑗垮寳
+    private int voluWeight;//瀹归噸浠撳簱绮瀹归噸锛屽鏋滀笉濉啓锛屽悗鏈熸祴閲忥紝鍙繑鍥炰綋绉紝涓嶈繑鍥為噸閲忎俊鎭�
+    private int storageType;// 浠撴埧绫诲瀷  0-绛掍粨锛�1-骞虫埧浠擄紝
+    private int length;//浠撴埧闀�  鍗曚綅鍘樼背
+    private int width;// 浠撴埧瀹� 鍗曚綅鍘樼背
+    private int radius;// 绛掍粨鍗婂緞
+    private int coneHeight;//绛掍粨涓嬮敟楂樺害
+    private int probeX;//x杞村潗鏍囧亸绉婚噺
+    private int probeY;//y杞村潗鏍囧亸绉婚噺
+    private int volumeAdd;//v浣撶Н琛ュ伩 鍗曚綅 m鲁
+    private int weightAdd;//閲嶉噺琛ュ伩 鍗曚綅KG
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp1002.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp1002.java
new file mode 100644
index 0000000..1f33967
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp1002.java
@@ -0,0 +1,20 @@
+package com.fzzy.igds.quantity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Data
+public class Resp1002 implements Serializable {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+    private long time;//	鏃堕棿鎴筹紝褰撳墠姣鍊�
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2003.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2003.java
new file mode 100644
index 0000000..5c65df2
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2003.java
@@ -0,0 +1,22 @@
+package com.fzzy.igds.quantity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Data
+public class Resp2003 implements Serializable {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+    private int index;//	妫�娴嬬疮绉鏁�
+    private int progress;//	0-100锛岃〃绀�0%-100%
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2004.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2004.java
new file mode 100644
index 0000000..03d2a87
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2004.java
@@ -0,0 +1,26 @@
+package com.fzzy.igds.quantity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Data
+public class Resp2004 implements Serializable {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+    private int height;	//楂樺害 鍗曚綅鍘樼背
+    private double volume;	//浣撶Н
+    private double weight;	//閲嶉噺
+    private int index;	//妫�娴嬬疮绉鏁�
+
+
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2005.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2005.java
new file mode 100644
index 0000000..19919d8
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2005.java
@@ -0,0 +1,25 @@
+package com.fzzy.igds.quantity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Data
+public class Resp2005 implements Serializable {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+    private int index;//	妫�娴嬬疮绉鏁�
+    private int curPackage;//	褰撳墠鍖呮暟
+    private int sumPackeage;//	鎬诲寘鏁�
+    private int orien;//	瀹夎鏈濆悜
+    private int dataCount;//	鍧愭爣涓暟
+    private String data;//	鍧愭爣鏁版嵁
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2006.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2006.java
new file mode 100644
index 0000000..ff79069
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/dto/Resp2006.java
@@ -0,0 +1,20 @@
+package com.fzzy.igds.quantity.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Data
+public class Resp2006 implements Serializable {
+
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+    private String data;//	鍥剧墖鏁版嵁 base64鏍煎紡
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityMessageConsumer.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityMessageConsumer.java
new file mode 100644
index 0000000..607472c
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityMessageConsumer.java
@@ -0,0 +1,51 @@
+package com.fzzy.igds.quantity.server;
+
+import com.fzzy.igds.quantity.analysis.AnalysisService;
+import com.fzzy.igds.quantity.dto.IoMessage;
+import com.fzzy.igds.quantity.util.ServerUtils;
+import com.ld.io.api.IoMsgConsumer;
+import com.ld.io.api.IoSession;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Description 杩斿洖淇℃伅灏佽
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Service
+@Slf4j
+public class BhznQuantityMessageConsumer implements IoMsgConsumer {
+
+
+    @Autowired
+    private AnalysisService analysisService;
+
+    /**
+     * 澶勭悊娑堟伅
+     *
+     * @param ioSession
+     * @param bytes
+     */
+    @Override
+    public void consume(IoSession ioSession, byte[] bytes) {
+        if (null == bytes) {
+            log.error("Reply bytes is null");
+            return;
+        }
+        try {
+            String message = new String(bytes, ServerUtils.CHARSET);
+            message = message.substring(message.indexOf(ServerUtils.MSG_BEGIN) + ServerUtils.MSG_BEGIN.length());
+
+            log.info("鏁伴噺妫�娴�---->>骞冲彴锛氭姤鏂囦俊鎭細" + message);
+            IoMessage ioMessage = ServerUtils.buildMessage(message);
+
+            analysisService.analysis(ioSession.getBusinessKey(), ioMessage);
+
+        } catch (Exception e) {
+
+            log.error("鏁伴噺妫�娴�---->>骞冲彴锛氭姤鏂囧紓甯革細" + e.getMessage());
+        }
+    }
+}
\ No newline at end of file
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityServerEngine.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityServerEngine.java
new file mode 100644
index 0000000..911a332
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantityServerEngine.java
@@ -0,0 +1,115 @@
+package com.fzzy.igds.quantity.server;
+
+import com.fzzy.igds.quantity.util.ServerUtils;
+import com.ld.io.api.InvokeResult;
+import com.ld.io.api.IoServerOption;
+import com.ld.io.api.IoSession;
+import com.ld.io.api.IoSessionQuery;
+import com.ld.io.netty.NettyServer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import java.util.List;
+
+/**
+ * @Description 椋庢鑷磋繙鍗忚Server鍚姩绫�
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Slf4j
+@Service
+public class BhznQuantityServerEngine {
+
+    public static final Integer PORT = 9306;
+
+    @Autowired
+    private BhznQuantityMessageConsumer defaultMessageConsumer;
+    @Autowired
+    private BhznQuantitySessionListener defaultSessionListener;
+
+    private IoSessionQuery sessionQuery;
+
+    public void start(Integer port) {
+        IoServerOption ioServerOption = new IoServerOption();
+
+        if (null != port) {
+            ioServerOption.setPort(port);
+        } else {
+            ioServerOption.setPort(PORT);
+        }
+
+        ioServerOption.setDelimiter(ServerUtils.MSG_END.getBytes());
+
+        NettyServer ioServer = new NettyServer(ioServerOption, defaultMessageConsumer, defaultSessionListener);
+        ioServer.startup();
+
+        sessionQuery = ioServer.getSessionQuery();
+        log.info("* ");
+        log.info("* ========================");
+        log.info("* ");
+        log.info("* [QUANTITY-FZZY-SERVER锛欶ZZY_TCP_QUANTITY_V3.5,PORT={}]", PORT);
+        log.info("* ");
+        log.info("* ========================");
+        log.info("* ");
+
+        System.out.println("* ========================");
+        System.out.println("* ");
+        System.out.println("* [QUANTITY-FZZY-SERVER锛欶ZZY_TCP_QUANTITY_V3.5,PORT={}]" + port);
+        System.out.println("* ");
+        System.out.println("* ========================");
+    }
+
+    public IoSessionQuery getSessionQuery() {
+        return sessionQuery;
+    }
+
+    /**
+     * 鍙戦�佷俊鎭�
+     *
+     * @param ip
+     * @param port
+     * @param msg
+     * @return
+     */
+    public InvokeResult push(String ip, int port, byte[] msg) {
+        IoSessionQuery sessionFactory = getSessionQuery();
+        List<IoSession> sessions = sessionFactory.getAllSession();
+        IoSession session = null;
+        for (IoSession ioSession : sessions) {
+            if (ServerUtils.getServerKey(ip, port).equals(ioSession.getBusinessKey())) {
+                session = ioSession;
+                break;
+            }
+        }
+        if (null == session) {
+            return InvokeResult.CHANNEL_CLOSED;
+        }
+        return session.invoke(msg);
+    }
+
+    /**
+     * 涓诲姩閿�姣佸綋鍓嶈繛鎺�
+     *
+     * @param ip
+     * @param port
+     * @return
+     */
+    public InvokeResult destroy(String ip, int port) {
+        IoSessionQuery sessionFactory = getSessionQuery();
+        List<IoSession> sessions = sessionFactory.getAllSession();
+        IoSession session = null;
+        for (IoSession ioSession : sessions) {
+            if (ServerUtils.getServerKey(ip, port).equals(ioSession.getBusinessKey())) {
+                session = ioSession;
+                break;
+            }
+        }
+
+        if (null == session) {
+            return InvokeResult.SUCCESS;
+        }
+        // 鎵ц杩炴帴閿�姣�
+        session.destroy();
+        return InvokeResult.SUCCESS;
+    }
+}
\ No newline at end of file
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantitySessionListener.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantitySessionListener.java
new file mode 100644
index 0000000..f2a630f
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/server/BhznQuantitySessionListener.java
@@ -0,0 +1,30 @@
+package com.fzzy.igds.quantity.server;
+
+import com.fzzy.igds.quantity.util.ServerUtils;
+import com.ld.io.api.IoSession;
+import com.ld.io.api.IoSessionListener;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @Description
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Slf4j
+@Service
+public class BhznQuantitySessionListener implements IoSessionListener {
+
+    @Override
+    public void onCreate(IoSession session) {
+        log.info("++++鏂板缓杩炴帴++++-IP={}锛孭ORT={}", session.getAddress(), session.getPort());
+        // 娣诲姞鑷畾涔変笟鍔D
+        session.setBusinessKey(ServerUtils.getServerKey(session.getAddress(), session.getPort()));
+    }
+
+    @Override
+    public void onDestroy(IoSession session) {
+        log.info("----杩炴帴鏂紑-----IP={}锛孭ORT={}", session.getAddress(), session.getPort());
+
+    }
+}
diff --git a/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/util/ServerUtils.java b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/util/ServerUtils.java
new file mode 100644
index 0000000..1de716b
--- /dev/null
+++ b/fzzy-igdss-io/src/main/java/com/fzzy/igds/quantity/util/ServerUtils.java
@@ -0,0 +1,77 @@
+package com.fzzy.igds.quantity.util;
+
+import com.alibaba.fastjson.JSON;
+import com.fzzy.igds.constant.RedisConst;
+import com.fzzy.igds.quantity.dto.IoMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomUtils;
+
+/**
+ * @Description
+ * @Author CZT
+ * @Date 2026/01/08 16:36
+ */
+@Slf4j
+public class ServerUtils {
+
+
+    public static final String VERSION_1 = "v1.0";
+
+
+    public static final String SIGN_DEFAULT = "0000";
+
+    public static final String CHARSET = "UTF-8";
+    public static final String MSG_BEGIN = "<BHZN>";
+    public static final String MSG_END = "<END>";
+
+    //鍔熻兘鐮�
+    public static final String FUNCTION_1001 = "1001";// 鍩虹鍙傛暟閰嶇疆
+    public static final String FUNCTION_2001 = "2001";// 寮�濮嬫娴�
+    public static final String FUNCTION_2002 = "2002";// 鍋滄妫�娴�
+    public static final String FUNCTION_2003 = "2003";// 杩涘害鏌ヨ
+    public static final String FUNCTION_2004 = "2004";// 缁撴灉涓婃姤
+    public static final String FUNCTION_2005 = "2005";// 鍧愭爣鎻愬彇
+    public static final String FUNCTION_2006 = "2006";// 杩滅▼鎶撴媿
+    public static final String FUNCTION_2007 = "2007";// 蹇冭烦缁存寔
+    public static final String FUNCTION_1002 = "1002";// 鏃堕棿鍚屾
+    public static final String FUNCTION_1003 = "1003";// 璁惧鐧婚檰
+
+
+    //鍝嶅簲鐮�
+    public static String RESP_0 = "0";//	鎴愬姛
+    public static String RESP_1 = "1";//	鍛戒护鏍煎紡閿欒
+    public static String RESP_2 = "2";//	鍛戒护鏁版嵁妫�楠屽紓甯�
+    public static String RESP_3 = "3";//	鍙戦�佽秴鏃堕敊璇�
+    public static String RESP_4 = "4";//	缁堢璁惧涓嶅湪绾�
+    public static String RESP_5 = "5";//	缁堢璁惧鎵ц涓�
+    public static String RESP_6 = "6";//	缁堢璁惧鎶撴媿澶辫触
+    public static String RESP_9 = "9";//	鍏跺畠閿欒
+
+    /**
+     * 鐢熸垚TCP杩炴帴鐨凨EY
+     *
+     * @param ip
+     * @param port
+     * @return
+     */
+    public static String getServerKey(String ip, Integer port) {
+        return ip + ":" + port;
+    }
+
+    /**
+     * @param message
+     * @return
+     */
+    public static IoMessage buildMessage(String message) throws Exception {
+        IoMessage ioMessage = JSON.parseObject(message, IoMessage.class);
+        return ioMessage;
+    }
+
+    public static String buildRequestKey(String companyId, String sn) {
+        return RedisConst.buildKey(companyId, sn);
+    }
+
+    public static String createOrderId() {
+        return RandomUtils.nextInt(1000, 9999) + "";
+    }
+}
diff --git a/fzzy-igdss-web/src/main/java/com/fzzy/Application.java b/fzzy-igdss-web/src/main/java/com/fzzy/Application.java
index 1015140..6f6eb8f 100644
--- a/fzzy-igdss-web/src/main/java/com/fzzy/Application.java
+++ b/fzzy-igdss-web/src/main/java/com/fzzy/Application.java
@@ -11,9 +11,7 @@
 import org.springframework.boot.web.servlet.ServletRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.ImportResource;
 import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
-
 import java.util.LinkedHashSet;
 import java.util.Set;
 
@@ -25,7 +23,6 @@
 @EnableRedisHttpSession
 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
 @ComponentScan(basePackages = {"com.fzzy", "com.ruoyi", "com.ld"})
-
 @MapperScan("com.fzzy.*.mapper")
 @EntityScan(basePackages = {"com.fzzy.*.*.domain"})
 public class Application {
diff --git a/fzzy-igdss-web/src/main/java/com/fzzy/security/SecurityController.java b/fzzy-igdss-web/src/main/java/com/fzzy/security/SecurityController.java
index 0005205..e5699ab 100644
--- a/fzzy-igdss-web/src/main/java/com/fzzy/security/SecurityController.java
+++ b/fzzy-igdss-web/src/main/java/com/fzzy/security/SecurityController.java
@@ -9,6 +9,7 @@
 import com.fzzy.igds.data.PageResponse;
 import com.fzzy.igds.data.PatrolSuperData;
 import com.fzzy.igds.domain.*;
+import com.fzzy.igds.response.BaseResponse;
 import com.fzzy.igds.utils.ContextUtil;
 import com.fzzy.igds.utils.SystemUtil;
 import com.fzzy.common.manager.CommonManager;
@@ -277,7 +278,30 @@
         return secManager.getQuantityFiles(param);
     }
 
+    /**
+     * 鏁伴噺鐩戞祴-寮�濮嬫娴�
+     *
+     * @param param
+     * @return
+     */
+    @RequestMapping("/check-single")
+    @ResponseBody
+    public BaseResponse checkSingle(@RequestBody IgdsBaseParam param) {
 
+        return secManager.checkSingle(param);
+    }
+
+    /**
+     * 鏁伴噺鐩戞祴-鍋滄妫�娴�
+     *
+     * @param param
+     * @return
+     */
+    @RequestMapping("/check-stop")
+    @ResponseBody
+    public BaseResponse checkStop(@RequestBody IgdsBaseParam param) {
+        return secManager.checkStop(param);
+    }
 
     /*------------------宸℃洿杞ㄨ抗椤甸潰------------------*/
     /**
diff --git a/fzzy-igdss-web/src/main/java/com/fzzy/security/manager/SecManager.java b/fzzy-igdss-web/src/main/java/com/fzzy/security/manager/SecManager.java
index 3833576..895c2ec 100644
--- a/fzzy-igdss-web/src/main/java/com/fzzy/security/manager/SecManager.java
+++ b/fzzy-igdss-web/src/main/java/com/fzzy/security/manager/SecManager.java
@@ -4,15 +4,22 @@
 import com.fzzy.igds.camera.ApiCameraManager;
 import com.fzzy.igds.camera.data.ApiCameraData;
 import com.fzzy.igds.camera.data.ApiCameraResp;
+import com.fzzy.igds.constant.OrderRespEnum;
 import com.fzzy.igds.constant.RespCodeEnum;
 import com.fzzy.igds.data.*;
 import com.fzzy.igds.domain.*;
+import com.fzzy.igds.io.manager.QuantityRemoteManager;
+import com.fzzy.igds.io.service.RemoteQuantityService;
+import com.fzzy.igds.request.QuantityRequest;
+import com.fzzy.igds.response.BaseResponse;
 import com.fzzy.igds.service.*;
 import com.fzzy.igds.utils.ContextUtil;
 import com.fzzy.igds.utils.DateUtil;
 import com.ruoyi.common.utils.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.time.DateFormatUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
@@ -32,6 +39,8 @@
 
     @Resource
     private CommonManager commonManager;
+    @Resource
+    private QuantityRemoteManager remoteManager;
     @Resource
     private SecCameraService secCameraService;
     @Resource
@@ -316,4 +325,82 @@
 
         return new PageResponse<>(RespCodeEnum.CODE_0000.getCode(), "鎵ц鎴愬姛锛侊紒", fileList);
     }
+
+    /**
+     * 鍗曚粨妫�娴�
+     *
+     * @param param
+     * @return
+     */
+    public BaseResponse checkSingle(IgdsBaseParam param) {
+        if (null == param || StringUtils.isBlank(param.getDepotId())) {
+            return new BaseResponse(RespCodeEnum.CODE_1007.getCode(), RespCodeEnum.CODE_1007.getMsg());
+        }
+
+        if (StringUtils.isBlank(param.getCompanyId())) {
+            param.setCompanyId(ContextUtil.getCompanyId());
+        }
+
+        QuantityConf conf = quantityService.getCacheQuantityConf(param.getCompanyId(), param.getDepotId());
+        if (conf == null) {
+            return new BaseResponse(RespCodeEnum.CODE_1007.getCode(), RespCodeEnum.CODE_1007.getMsg());
+        }
+
+        RemoteQuantityService remoteQuantityService = remoteManager.getRemoteQuantityService(conf.getProtocol());
+
+        if (null == remoteQuantityService) {
+            return new BaseResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                    "绯荤粺娌℃湁" + conf.getProtocol() + "鐨勫崗璁疄鐜帮紝鎵ц琚嫆缁濓紒");
+        }
+
+        QuantityRequest request = new QuantityRequest();
+        BeanUtils.copyProperties(conf, request);
+        request.setDepotId(conf.getDepotId());
+        request.setYtIp(conf.getYtIp());
+        request.setCompanyId(conf.getCompanyId());
+        request.setDeptId(conf.getDeptId());
+        request.setSn(conf.getSn());
+        request.setLength(conf.getLength());
+
+        request.setBatchId(conf.getDepotId() + "_" + DateFormatUtils.format(new Date(), "yyyyMMddHHmm"));
+
+        return remoteQuantityService.checkStart(request);
+    }
+
+    /**
+     * 鍋滄妫�娴�
+     * @param param
+     * @return
+     */
+    public BaseResponse checkStop(IgdsBaseParam param) {
+        if (param == null || StringUtils.isEmpty(param.getDepotId())) {
+            return new BaseResponse(RespCodeEnum.CODE_1007.getCode(), RespCodeEnum.CODE_1007.getMsg());
+        }
+
+        if (StringUtils.isEmpty(param.getCompanyId())) {
+            param.setCompanyId(ContextUtil.getCompanyId());
+        }
+
+        QuantityConf conf = quantityService.getCacheQuantityConf(param.getCompanyId(), param.getDepotId());
+        if (conf == null) {
+            return new BaseResponse(RespCodeEnum.CODE_1007.getCode(), RespCodeEnum.CODE_1007.getMsg());
+        }
+
+        RemoteQuantityService remoteQuantityService = remoteManager.getRemoteQuantityService(conf.getProtocol());
+
+        if (null == remoteQuantityService) {
+            return new BaseResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                    "绯荤粺娌℃湁" + conf.getProtocol() + "鐨勫崗璁疄鐜帮紝鎵ц琚嫆缁濓紒");
+        }
+
+        QuantityRequest request = new QuantityRequest();
+        BeanUtils.copyProperties(conf, request);
+        request.setCompanyId(conf.getCompanyId());
+        request.setYtIp(conf.getYtIp());
+        request.setSn(conf.getSn());
+        request.setDeptId(conf.getDeptId());
+        request.setDepotId(conf.getDepotId());
+
+        return remoteQuantityService.checkStop(request);
+    }
 }
diff --git a/fzzy-igdss-web/src/main/resources/static/security/quantity.js b/fzzy-igdss-web/src/main/resources/static/security/quantity.js
index 0970d82..3c8be27 100644
--- a/fzzy-igdss-web/src/main/resources/static/security/quantity.js
+++ b/fzzy-igdss-web/src/main/resources/static/security/quantity.js
@@ -143,7 +143,6 @@
     }
 }
 
-
 /**
  * 璇锋眰鍥捐〃淇℃伅
  */
@@ -317,6 +316,68 @@
     $("#divPlugin2").html(html);
 }
 
+/**
+ * 鍚姩寮�濮嬫娴�
+ */
+function checkStart() {
+    if (!curCamera) {
+        shoTips("璇峰厛閫夋嫨璁惧锛�");
+        return;
+    }
+    layer.msg("寮�濮嬫墽琛屸�︹��");
+    var data = {
+        'depotId': curCamera.depotId
+    };
+    $.ajax({
+        type: "POST",
+        url: "/security/check-single",
+        dataType: "json",
+        contentType: "application/json;charset=UTF-8",
+        data: JSON.stringify(data),
+        success: function (result) {
+            if (result.code == "ORDER_SUCCESS") {
+                shoTips("鍛戒护鍙戠敓鎴愬姛锛岃绛夊緟缁堢杩斿洖缁撴灉鈥︹��");
+            } else {
+                shoTips("鍛戒护鍙戦�佸け璐ワ細" + result.msg);
+            }
+        },
+        error: function () {
+            shoTips("妫�娴嬪嚭鐜板紓甯革紝鎵ц澶辫触锛�");
+        }
+    });
+}
+
+/**
+ * 鍋滄妫�娴�
+ */
+function checkStop() {
+    if (!curCamera) {
+        shoTips("璇峰厛閫夋嫨浠撳簱锛�");
+        return;
+    }
+    layer.msg("寮�濮嬫墽琛屸�︹��");
+    var data = {
+        'depotId': curCamera.depotId
+    };
+    $.ajax({
+        type: "POST",
+        url: "/security/check-stop",
+        dataType: "json",
+        contentType: "application/json;charset=UTF-8",
+        data: JSON.stringify(data),
+        success: function (result) {
+            if (result.code == "ORDER_SUCCESS") {
+                shoTips("鍛戒护鍙戠敓鎴愬姛鈥︹��");
+            } else {
+                shoTips("鍛戒护鍙戦�佸け璐ワ細" + result.msg);
+            }
+        },
+        error: function () {
+            shoTips("妫�娴嬪嚭鐜板紓甯革紝鎵ц澶辫触锛�");
+        }
+    });
+}
+
 // 鍒濆鍖朎Charts娓╁害璧板娍鍥�
 function initEcharts(names, data) {
     // 鍒濆鍖朎Charts娓╁害璧板娍鍥�
@@ -389,4 +450,11 @@
     window.addEventListener('resize', function () {
         temperatureChart.resize();
     });
+}
+
+function shoTips(msg) {
+    layer.msg(msg,
+        {time: 3000, shift: 5, offset: "rb"},
+        function () {
+        });
 }
\ No newline at end of file
diff --git a/fzzy-igdss-web/src/main/resources/templates/security/quantity.html b/fzzy-igdss-web/src/main/resources/templates/security/quantity.html
index d079147..7cc3945 100644
--- a/fzzy-igdss-web/src/main/resources/templates/security/quantity.html
+++ b/fzzy-igdss-web/src/main/resources/templates/security/quantity.html
@@ -68,28 +68,34 @@
 
                     <!-- 绠�鍖栫殑瑙嗛鎺у埗宸ュ叿鏍�-->
                     <div style="margin-top: 15px; text-align: center; background-color: #f5f5f5; padding: 10px; border-radius: 4px;">
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
-                           涓婄Щ <i class="layui-icon layui-icon-up"></i>
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onmousedown="ptzControl(1);"
+                                onmouseup="moveStop();">
+                            涓婄Щ <i class="layui-icon layui-icon-up"></i>
                         </button>
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
-                           涓嬬Щ <i class="layui-icon layui-icon-down"></i>
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onmousedown="ptzControl(2);"
+                                onmouseup="moveStop();">
+                            涓嬬Щ <i class="layui-icon layui-icon-down"></i>
                         </button>
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
-                           宸︾Щ <i class="layui-icon layui-icon-left"></i>
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onmousedown="ptzControl(3);"
+                                onmouseup="moveStop();">
+                            宸︾Щ <i class="layui-icon layui-icon-left"></i>
                         </button>
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
-                           鍙崇Щ <i class="layui-icon layui-icon-right"></i>
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onmousedown="ptzControl(4);"
+                                onmouseup="moveStop();">
+                            鍙崇Щ <i class="layui-icon layui-icon-right"></i>
                         </button>
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
-                           鍔犲�� <i class="layui-icon layui-icon-addition"></i>
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onmousedown="ptzControl(10);"
+                                onmouseup="zoomStop();">
+                            鍙樼劍澶� <i class="layui-icon layui-icon-addition"></i>
                         </button>
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
-                           鍑忓�� <i class="layui-icon layui-icon-subtraction"></i>
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onmousedown="ptzControl(9);"
+                                onmouseup="zoomStop();">
+                            鍙樼劍灏� <i class="layui-icon layui-icon-subtraction"></i>
                         </button>
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onclick="checkStart()">
                             寮�濮嬫娴� <i class="layui-icon layui-icon-subtraction"></i>
                         </button>
-                        <button class="layui-btn layui-btn-default layui-btn-sm">
+                        <button class="layui-btn layui-btn-default layui-btn-sm" onclick="checkStop()">
                             鍋滄妫�娴� <i class="layui-icon layui-icon-subtraction"></i>
                         </button>
                     </div>
@@ -255,4 +261,5 @@
 <script th:src="@{/ajax/libs/layui/layui.js}"></script>
 <script th:src="@{/js/plugins/echarts/echarts.min-4.7.js}"></script>
 <script th:src="@{/security/quantity.js}"></script>
+<script th:src="@{/security/video-control.js}"></script>
 </html>
\ No newline at end of file

--
Gitblit v1.9.3