From 37fd5447c3b7bfdd3d1b31f8d68c6750471f178c Mon Sep 17 00:00:00 2001
From: Lius <Lius2225@163.com>
Date: 星期三, 27 八月 2025 16:11:00 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentLogServiceImpl.java |    9 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/ServerDeployServiceImpl.java     |   84 ++-
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/ServeDeployController.java         |   16 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/EquipmentLogMapper.java            |    4 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/RealParameterServiceImpl.java    |   10 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/EquipmentAlarm.java                |    2 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/util/FtpUtil.java                             |  918 ++++++++++++++++++++++++++++-----------------
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentService.java            |    7 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/EquipmentServiceImpl.java        |    3 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleJob.java                         |    2 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleParamJob.java                    |   18 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/EquipmentController.java           |    2 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/Equipment.java                     |    2 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentLogService.java         |    4 
 lxzn-module-system/lxzn-system-start/src/main/resources/application-prod.yml                                         |   63 +-
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentServiceImpl.java    |    5 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/xml/EquipmentLogMapper.xml         |    6 
 17 files changed, 723 insertions(+), 432 deletions(-)

diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/EquipmentController.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/EquipmentController.java
index 756d220..e2b32d2 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/EquipmentController.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/EquipmentController.java
@@ -189,6 +189,8 @@
             param.clear();
             param.put("id", equipment.getEqptCode());
             HttpClientUtil.doGet("http://localhost:3002/ScriptCompiler/DeleteDevicescript", param);
+            // 缁檓dc璁惧琛ㄥ鍔犺澶囦俊鎭�
+            mdcEquipmentService.deleteEquipmentByEquipmentId(equipment.getEqptCode());
         }
         equipmentService.removeById(id);
         return Result.ok("鍒犻櫎鎴愬姛!");
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/ServeDeployController.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/ServeDeployController.java
index 892cec1..56d473a 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/ServeDeployController.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/controller/ServeDeployController.java
@@ -54,8 +54,8 @@
     private IMqttDeployService mqttDeployService;
     @Autowired
     private MqttCustomerClient mqttCustomerClient;
-    @Resource
-    private RestTemplate restTemplate;
+    @Autowired
+    private FtpUtil ftpUtil;
     @Autowired
     private IEquipmentService equipmentService;
     @Value("${ftp.address}")
@@ -138,10 +138,10 @@
         topic[1] = "IOT\\" + serverDeploy.getServerCode() + "\\WriteMessage";
         mqttCustomerClient.subscribe(topic);
         // 鍒涘缓ftp鏂囦欢澶圭洰褰�
-        FtpUtil.createFolder("/log", serverDeploy.getServerCode());
-        FtpUtil.createFolder("/deploy", serverDeploy.getServerCode());
-        FtpUtil.createFolder("/deploy/" + serverDeploy.getServerCode(), "software");
-        FtpUtil.createFolder("/deploy/" + serverDeploy.getServerCode(), "deploy");
+        ftpUtil.createFolder("/log", serverDeploy.getServerCode());
+        ftpUtil.createFolder("/deploy", serverDeploy.getServerCode());
+        ftpUtil.createFolder("/deploy/" + serverDeploy.getServerCode(), "software");
+        ftpUtil.createFolder("/deploy/" + serverDeploy.getServerCode(), "deploy");
         // 鐢熸垚鏈湴鏂囦欢澶�
         boolean b = FileUtil.queryCatalogue(ftpAddress + serverDeploy.getServerCode());
         if (b) {
@@ -277,7 +277,7 @@
             return Result.error("璇蜂笂浼�.zip鏂囦欢!");
         }
         // 鏂板缓ftp鏂囦欢澶�
-        FtpUtil.createFolder("/deploy/" + serverDeploy.getServerCode() + "/software/", serverDeploy.getLatestCollectVersion());
+        ftpUtil.createFolder("/deploy/" + serverDeploy.getServerCode() + "/software/", serverDeploy.getLatestCollectVersion());
         // 澶嶅埗閲囬泦杞欢鍒癴tp
         // 涓婁紶鍒癴tp
         String newCollectAddress = serverDeploy.getNewCollectAddress();
@@ -286,7 +286,7 @@
         String filename = newCollectAddress.substring(14, newCollectAddress.length());// 涓婁紶鍒癋TP鏈嶅姟鍣ㄤ笂鐨勬枃浠跺悕
         try {
             FileInputStream fileInputStream = new FileInputStream(ftpAddress + newCollectAddress);
-            FtpUtil.uploadFile(basePath, filePath, filename, fileInputStream);
+            ftpUtil.uploadFile(basePath, filePath, filename, fileInputStream);
 
         } catch (FileNotFoundException e) {
             e.printStackTrace();
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/Equipment.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/Equipment.java
index e71340d..2e1109c 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/Equipment.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/Equipment.java
@@ -20,7 +20,7 @@
  * @Version: V1.0
  */
 @Data
-@TableName("Equipment")
+@TableName("equipment")
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
 @ApiModel(value = "Equipment瀵硅薄", description = "閲囬泦璁惧琛�")
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/EquipmentAlarm.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/EquipmentAlarm.java
index cfbef6b..804ad92 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/EquipmentAlarm.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/entity/EquipmentAlarm.java
@@ -14,7 +14,7 @@
 @Data
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
-@TableName("EquipmentAlarm")
+@TableName("equipmentalarm")
 public class EquipmentAlarm implements Serializable {
 
     private static final long serialVersionUID = -4762333096168370779L;
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/EquipmentLogMapper.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/EquipmentLogMapper.java
index 83c0a2e..e307149 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/EquipmentLogMapper.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/EquipmentLogMapper.java
@@ -18,7 +18,9 @@
 
     EquipmentLog getRow(@Param("equipmentid") String equipmentid, @Param("startTime") Date startTime);
 
-    EquipmentLog selectEquipmentOporation(@Param("equipmentId") String equipmentId);
+    EquipmentLog selectEquipmentOporationMySql(@Param("equipmentId") String equipmentId);
+
+    EquipmentLog selectEquipmentOporationSqlServer(@Param("equipmentId") String equipmentId);
 
     List<EquipmentLog> getEquipmentStatusList(@Param("equipmentIdList") List<String> equipmentIdList);
 }
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/xml/EquipmentLogMapper.xml b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/xml/EquipmentLogMapper.xml
index 04bc0c8..730b94a 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/xml/EquipmentLogMapper.xml
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/mapper/xml/EquipmentLogMapper.xml
@@ -6,10 +6,14 @@
         SELECT top 1 * FROM equipmentLog WHERE EquipmentID = #{ equipmentid } AND CollectTime &lt;= #{ startTime } AND Oporation in ('0','1','2','3') ORDER BY CollectTime ASC
     </select>
 
-    <select id="selectEquipmentOporation" resultType="org.jeecg.modules.iot.mdc.entity.EquipmentLog">
+    <select id="selectEquipmentOporationSqlServer" resultType="org.jeecg.modules.iot.mdc.entity.EquipmentLog">
         SELECT TOP 1 * FROM equipmentLog WHERE EquipmentID = #{ equipmentId } ORDER BY CollectTime DESC
     </select>
 
+    <select id="selectEquipmentOporationMySql" resultType="org.jeecg.modules.iot.mdc.entity.EquipmentLog">
+        SELECT * FROM equipmentLog WHERE EquipmentID = #{ equipmentId } ORDER BY CollectTime DESC LIMIT 1
+    </select>
+
     <!--鏌ヨ璁惧鏈�鏂颁竴鏉℃暟鎹�-->
     <select id="getEquipmentStatusList" resultType="org.jeecg.modules.iot.mdc.entity.EquipmentLog">
         SELECT
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentLogService.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentLogService.java
index 17a1dc5..25e5097 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentLogService.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentLogService.java
@@ -27,7 +27,9 @@
      */
     EquipmentLog getRow(String equipmentid, Date startTime);
 
-    EquipmentLog selectEquipmentOporation(String equipmentId);
+    EquipmentLog selectEquipmentOporationSqlServer(String equipmentId);
+
+    EquipmentLog selectEquipmentOporationMySql(String equipmentId);
 
     List<EquipmentLog> getEquipmentStatusList(List<String> equipmentIdList);
 }
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentService.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentService.java
index 076f5f0..b31f644 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentService.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/IEquipmentService.java
@@ -60,4 +60,11 @@
      * @param equipmentId
      */
     Equipment findEquipmentByEquipmentId(String equipmentId);
+
+    /**
+     * 鏍规嵁璁惧id鍒犻櫎璁惧淇℃伅
+     *
+     * @param equipmentId
+     */
+    void deleteEquipmentByEquipmentId(String equipmentId);
 }
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentLogServiceImpl.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentLogServiceImpl.java
index a6a8a39..a7acf49 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentLogServiceImpl.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentLogServiceImpl.java
@@ -50,8 +50,13 @@
     }
 
     @Override
-    public EquipmentLog selectEquipmentOporation(String equipmentId) {
-        return this.baseMapper.selectEquipmentOporation(equipmentId);
+    public EquipmentLog selectEquipmentOporationMySql(String equipmentId) {
+        return this.baseMapper.selectEquipmentOporationMySql(equipmentId);
+    }
+
+    @Override
+    public EquipmentLog selectEquipmentOporationSqlServer(String equipmentId) {
+        return this.baseMapper.selectEquipmentOporationSqlServer(equipmentId);
     }
 
     @Override
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentServiceImpl.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentServiceImpl.java
index 16e164a..8fd3e21 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentServiceImpl.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/mdc/service/impl/EquipmentServiceImpl.java
@@ -45,4 +45,9 @@
     public Equipment findEquipmentByEquipmentId(String equipmentId) {
         return new LambdaQueryChainWrapper<>(baseMapper).eq(Equipment::getEquipmentid,equipmentId).one();
     }
+
+    @Override
+    public void deleteEquipmentByEquipmentId(String equipmentId) {
+        baseMapper.deleteById(equipmentId);
+    }
 }
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/EquipmentServiceImpl.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/EquipmentServiceImpl.java
index e5e80ec..47680dd 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/EquipmentServiceImpl.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/EquipmentServiceImpl.java
@@ -200,6 +200,7 @@
                 .ge(Equipment::getCreateTime, deployDate)
                 .list();
         equipmentList.forEach(equipment -> {
+            String code = equipment.getEqptCode();
             // 灏嗘墍鏈夌殑 '-' 鏇挎崲涓� '_'
             equipment.setEqptCode(equipment.getEqptCode().replace("-", "_"));
             if (databaseType.equals("SqlServer")) {
@@ -217,7 +218,7 @@
             }
             // 缁檓dc璁惧琛ㄥ鍔犺澶囦俊鎭�
             org.jeecg.modules.iot.mdc.entity.Equipment mdcEquipment = new org.jeecg.modules.iot.mdc.entity.Equipment();
-            mdcEquipment.setEquipmentid(equipment.getEqptCode());
+            mdcEquipment.setEquipmentid(code);
             mdcEquipment.setEquipmentname(equipment.getEqptName());
             mdcEquipment.setSavetablename(equipment.getControlSystem() + '_' + equipment.getEqptCode());
             mdcEquipment.setDrivetype(equipment.getControlSystem());
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/RealParameterServiceImpl.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/RealParameterServiceImpl.java
index 334438d..94af716 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/RealParameterServiceImpl.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/RealParameterServiceImpl.java
@@ -253,6 +253,12 @@
 
     @Override
     public Result<?> canonicalParameter(String id) {
+        int list = new LambdaQueryChainWrapper<>(baseMapper)
+                .eq(RealParameter::getParameterGroupId, id)
+                .list().size();
+        if (list > 1) {
+            return Result.error("鍙傛暟涓虹┖鎵嶅彲瀵煎叆鏍囧噯鍙傛暟");
+        }
         // 鏌ヨ鏈�鏂扮紪鍙�
         Integer parameterCode = findRealParameterGroupId(id) - 1;
         List<Parameter> parameters = equipmentService.findParameterById(id);
@@ -265,6 +271,7 @@
             real.setParameterName(parameter.getName());
             real.setParameterType(parameter.getDataType());
             real.setAddress(parameter.getDefault1());
+            real.setParameterDescribe(parameter.getDescribe());
             real.setReadWriteType("鍙");
             List<Parameter> parameterList = equipmentService.findDataTypeById(id);
             parameterList.forEach(p -> {
@@ -273,13 +280,14 @@
                     real.setSystemDataType(p.getSystemDataType());
                 }
             });
+            real.setDataLength(1);
             // 濉厖鍙傛暟
             parameterCode = parameterCode + 1;
             real.setParameterGroupId(id);
             real.setParameterCode(parameterCode);
             realParameter.add(real);
         }
-//        saveBatch(realParameter);
+        this.saveBatch(realParameter);
         return Result.ok("瀵煎叆鎴愬姛");
     }
 
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/ServerDeployServiceImpl.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/ServerDeployServiceImpl.java
index c30890e..2dffd63 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/ServerDeployServiceImpl.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/service/impl/ServerDeployServiceImpl.java
@@ -4,6 +4,8 @@
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.modules.iot.entity.*;
 import org.jeecg.modules.iot.service.*;
@@ -42,6 +44,10 @@
 
     @Value("${ftp.address}")
     private String ftpAddress;
+    @Value("${operatingSystem}")
+    private String operatingSystem;
+    @Autowired
+    private FtpUtil ftpUtil;
     @Autowired
     private IInfluxdbDeployService influxdbDeployService;
     @Autowired
@@ -58,6 +64,7 @@
     @Autowired
     @Lazy
     private IEmptyParameterService emptyParameterService;
+    private static final Log logger = LogFactory.getLog(ServerDeployServiceImpl.class);
 
     @Override
     public ServerDeploy findByServerCode(String serverCode) {
@@ -104,7 +111,7 @@
     @Transactional(rollbackFor = Exception.class)
     public Result<?> addDeployDocument(String id) {
         // 楠岃瘉FTP杩炴帴
-        boolean isConnected = FtpUtil.testFtpConnection();
+        boolean isConnected = ftpUtil.testFtpConnection();
         if (!isConnected) {
             return Result.error("FTP杩炴帴澶辫触锛岃妫�鏌ラ厤缃紒");
         }
@@ -248,9 +255,9 @@
                                         tagInfo.setAttribute("Name", r.getParameterName());
                                         tagInfo.setAttribute("Address", r.getAddress());
                                         tagInfo.setAttribute("DataType", r.getParameterType());
-                                        if (r.getReadWriteType().equals("鍙")){
+                                        if (r.getReadWriteType().equals("鍙")) {
                                             tagInfo.setAttribute("ReadOrWrite", "R");
-                                        }else{
+                                        } else {
                                             tagInfo.setAttribute("ReadOrWrite", "R/W");
                                         }
                                         tagInfo.setAttribute("Describe", r.getParameterDescribe());
@@ -321,42 +328,65 @@
             tf.setOutputProperty(OutputKeys.INDENT, "yes");
             // 鍒涘缓xml鏂囦欢骞跺啓鍏ュ唴瀹�
             tf.transform(new DOMSource(document), new StreamResult(new File("/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx")));
-            // 鍒涘缓鍐欏簱琛ㄧ粨鏋勬煡璇㈣櫄璁惧鍒楄〃锛屽鍔犺澶囪〃
-            equipmentService.createEmptyEquipmentTable(serverDeploy.getDeployIssueTime(),serverDeploy.getId());
-            // 鏌ヨ铏氳澶囧弬鏁帮紝澧炲姞瀛楁
-            emptyParameterService.createEmptyEmptyField(serverDeploy.getDeployIssueTime(),serverDeploy.getId());
         } catch (Exception e) {
             e.printStackTrace();
             return Result.error("閰嶇疆鏂囦欢鐢熸垚澶辫触");
         }
-        // 鏇存柊鐗堟湰
-        serverDeploy.setLatestDeployVersion(formattedDate);
-        serverDeploy.setDeployIssueTime(new Date());
-        baseMapper.updateById(serverDeploy);
-        // 鐢熸垚鏈湴鏂囦欢澶�
-//        FileUtil.createDir("D:/iot/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate);
-        FileUtil.createDir(ftpAddress + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/script");
-        // 涓婁紶鍒癴tp
-        String basePath = "/deploy"; // FTP鏈嶅姟鍣ㄥ熀纭�鐩綍
-        String filePath = serverDeploy.getServerCode() + "/deploy/" + formattedDate; // FTP鏈嶅姟鍣ㄦ枃浠跺瓨鏀捐矾寰勩�備緥濡傚垎鏃ユ湡瀛樻斁锛�/2015/01/01銆傛枃浠剁殑璺緞涓篵asePath+filePath
-        String filename = "CollectionConfiguration.lmx";// 涓婁紶鍒癋TP鏈嶅姟鍣ㄤ笂鐨勬枃浠跺悕
-        //鍒涘缓涓�涓緭鍏ユ祦
         try {
-            FileInputStream fileInputStream = new FileInputStream(ftpAddress + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx");
-            FtpUtil.uploadFile(basePath, filePath, filename, fileInputStream);
-        } catch (FileNotFoundException e) {
+            // 鍒涘缓鍐欏簱琛ㄧ粨鏋勬煡璇㈣櫄璁惧鍒楄〃锛屽鍔犺澶囪〃
+            equipmentService.createEmptyEquipmentTable(serverDeploy.getDeployIssueTime(), serverDeploy.getId());
+            // 鏌ヨ铏氳澶囧弬鏁帮紝澧炲姞瀛楁
+            emptyParameterService.createEmptyEmptyField(serverDeploy.getDeployIssueTime(), serverDeploy.getId());
+        } catch (Exception e) {
             e.printStackTrace();
+            return Result.error("璁惧鍗曡〃锛屽弬鏁扮敓鎴愬け璐�");
         }
-        // 瀛樺偍鑴氭湰锛屽鍒舵暣涓枃浠跺す
-        FtpUtil.uploadFolder(new File(ftpAddress+serverDeploy.getServerCode()+"/script/"), "/deploy/"+serverDeploy.getServerCode()+"/deploy/"+formattedDate+"/script");
-        // 鐢熸垚鑴氭湰
-        // 鍙戦�侀厤缃枃浠剁増淇″彿
+
+        // 鐢熸垚鏈湴鏂囦欢澶�
+        FileUtil.createDir(ftpAddress + serverDeploy.getServerCode() + "/deploy/" + formattedDate);
         MqttParameter mqttParameter = new MqttParameter();
+        // 涓婁紶鍒癴tp
+        if (operatingSystem.equals("windows")) {
+            String basePath = "/deploy"; // FTP鏈嶅姟鍣ㄥ熀纭�鐩綍
+            String filePath = "/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate; // FTP鏈嶅姟鍣ㄦ枃浠跺瓨鏀捐矾寰勩�備緥濡傚垎鏃ユ湡瀛樻斁锛�/2015/01/01銆傛枃浠剁殑璺緞涓篵asePath+filePath
+            String filename = "CollectionConfiguration.lmx";// 涓婁紶鍒癋TP鏈嶅姟鍣ㄤ笂鐨勬枃浠跺悕
+            //鍒涘缓涓�涓緭鍏ユ祦
+            try {
+                FileInputStream fileInputStream = new FileInputStream(ftpAddress + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx");
+                ftpUtil.uploadFile(basePath, filePath, filename, fileInputStream);
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            }
+            mqttParameter.setParameter4(basePath + filePath);
+            logger.info("windows閰嶇疆涓嬪彂鐩綍:" + "deploy/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate);
+            // 瀛樺偍鑴氭湰锛屽鍒舵暣涓枃浠跺す
+            ftpUtil.uploadFolder(new File(ftpAddress + serverDeploy.getServerCode() + "/script/"), "/deploy/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/script");
+        } else {
+            String basePath = "/iot"; // FTP鏈嶅姟鍣ㄥ熀纭�鐩綍
+            String filePath = "/deploy/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate; // FTP鏈嶅姟鍣ㄦ枃浠跺瓨鏀捐矾寰勩�備緥濡傚垎鏃ユ湡瀛樻斁锛�/2015/01/01銆傛枃浠剁殑璺緞涓篵asePath+filePath
+            String filename = "CollectionConfiguration.lmx";// 涓婁紶鍒癋TP鏈嶅姟鍣ㄤ笂鐨勬枃浠跺悕
+            //鍒涘缓涓�涓緭鍏ユ祦
+            try {
+                FileInputStream fileInputStream = new FileInputStream(ftpAddress + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/CollectionConfiguration.lmx");
+                ftpUtil.uploadFileKylin(basePath, filePath, filename, fileInputStream);
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            }
+            mqttParameter.setParameter4("deploy/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate);
+            logger.info("楹掗簾绯荤粺FTP鐩爣鐩綍:" + "deploy/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate);
+            // 瀛樺偍鑴氭湰锛屽鍒舵暣涓枃浠跺す
+            ftpUtil.uploadFolderKylin(new File(ftpAddress + serverDeploy.getServerCode() + "/script/"), "/deploy/" + serverDeploy.getServerCode() + "/deploy/" + formattedDate + "/script");
+        }
+
+        // 鍙戦�侀厤缃枃浠剁増淇″彿
         mqttParameter.setId(serverDeploy.getServerCode());
         mqttParameter.setType("version");
         mqttParameter.setParameter2(formattedDate);
-        mqttParameter.setParameter4(basePath +"/" +filePath);
         mqttCustomerClient.pushlish(2, false, serverDeploy.getServerCode(), mqttParameter);
+        // 鏇存柊缁堢鐗堟湰
+        serverDeploy.setLatestDeployVersion(formattedDate);
+        serverDeploy.setDeployIssueTime(new Date());
+        baseMapper.updateById(serverDeploy);
         return Result.ok("閰嶇疆鏂囦欢鐢熸垚鎴愬姛");
     }
 }
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/util/FtpUtil.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/util/FtpUtil.java
index fd00b2d..853d116 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/util/FtpUtil.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/iot/util/FtpUtil.java
@@ -1,41 +1,39 @@
-
 package org.jeecg.modules.iot.util;
-
-/**
- * @Description: Ftp閰嶇疆
- * @Author: cuikaidong
- * @Date: 2024-12-10
- * @Version: V1.0
- */
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.net.ftp.FTP;
 import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
 import org.apache.commons.net.ftp.FTPReply;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
 
 import java.io.*;
 import java.net.SocketException;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
 
+@Component
 public class FtpUtil {
-    private final static Log logger = LogFactory.getLog(FtpUtil.class);
 
-    /**
-     * 鏈湴瀛楃缂栫爜
-     */
-    private static String LOCAL_CHARSET = "GBK";
+    private static final Log logger = LogFactory.getLog(FtpUtil.class);
 
-    // FTP鍗忚閲岄潰锛岃瀹氭枃浠跺悕缂栫爜涓篿so-8859-1
-    private static String SERVER_CHARSET = "ISO-8859-1";
-    //ftp鏈嶅姟鍣↖P鍦板潃 锛屾柊鐏偓10.210.199.2,璧疯惤鏋�10.0.221.200
-    private static String ftpHost = "10.0.221.200";
-    //ftp鏈嶅姟鍣ㄧ鍙�
-    private static int ftpPort = 21;
-    //ftp鏈嶅姟鍣ㄧ敤鎴峰悕
-    private static String ftpUserName = "admin";
-    //ftp鏈嶅姟鍣ㄥ瘑鐮�
-    private static String ftpPassword = "lx@2024";
+    // 渚濊禆娉ㄥ叆閰嶇疆锛屽缓璁�氳繃 Nacos 鎴栭厤缃腑蹇冪鐞�
+    @Value("${ftp.LOCAL_CHARSET:UTF-8}")
+    private String LOCAL_CHARSET;
+    @Value("${ftp.SERVER_CHARSET:ISO-8859-1}")
+    private String SERVER_CHARSET;
+    @Value("${ftp.ftpHost}")
+    private String ftpHost;
+    @Value("${ftp.ftpPort:21}")
+    private int ftpPort;
+    @Value("${ftp.ftpUserName}")
+    private String ftpUserName;
+    @Value("${ftp.ftpPassword}")
+    private String ftpPassword;
+    @Value("${operatingSystem}")
+    private String operatingSystem;
 
 
     /**
@@ -43,7 +41,7 @@
      *
      * @return true锛氳繛鎺ユ垚鍔燂紱false锛氳繛鎺ュけ璐�
      */
-    public static boolean testFtpConnection() {
+    public boolean testFtpConnection() {
         FTPClient ftpClient = new FTPClient();
         try {
             // 杩炴帴FTP鏈嶅姟鍣�
@@ -58,377 +56,593 @@
             if (isConnected) {
                 logger.info("FTP杩炴帴楠岃瘉鎴愬姛锛�");
             } else {
-                logger.error("FTP杩炴帴澶辫触锛氱敤鎴峰悕/瀵嗙爜閿欒鎴栨湇鍔″櫒涓嶅彲杈�");
+                logger.error("FTP杩炴帴澶辫触锛氱敤鎴峰悕/瀵嗙爜閿欒鎴栨湇鍔″櫒涓嶅彲杈撅紝鍝嶅簲鐮侊細" + replyCode);
             }
             return isConnected;
         } catch (SocketException e) {
-            logger.error("FTP鏈嶅姟鍣↖P鍦板潃閿欒鎴栫鍙h鍗犵敤锛�" + e.getMessage());
+            logger.error("FTP鏈嶅姟鍣ㄨ繛鎺ュけ璐ワ紙IP鎴栫鍙i敊璇級锛�" + e.getMessage(), e);
         } catch (IOException e) {
-            logger.error("FTP杩炴帴寮傚父锛�" + e.getMessage());
+            logger.error("FTP杩炴帴寮傚父锛�" + e.getMessage(), e);
         } finally {
             // 閲婃斁璧勬簮
-            if (ftpClient.isConnected()) {
-                try {
-                    ftpClient.logout();
-                    ftpClient.disconnect();
-                } catch (IOException e) {
-                    logger.warn("鍏抽棴FTP杩炴帴鏃跺彂鐢熷紓甯革細" + e.getMessage());
-                }
-            }
+            disconnectQuietly(ftpClient);
         }
         return false;
     }
+    // ====================== 鏍稿績浼樺寲锛氳繛鎺ョ鐞嗛噸鏋� ======================
 
     /**
-     * 鑾峰彇FTPClient瀵硅薄
+     * 鑾峰彇 FTPClient 杩炴帴锛堝甫閲嶈瘯銆佹ā寮忛厤缃級
      *
-     * @return
+     * @return 鍙敤 FTPClient锛屽け璐ヨ繑鍥� null
      */
-    public static FTPClient getFTPClient() {
-
-        FTPClient ftpClient = null;
-        try {
-            ftpClient = new FTPClient();
-            ftpClient.connect(ftpHost, ftpPort);// 杩炴帴FTP鏈嶅姟鍣�
-            ftpClient.login(ftpUserName, ftpPassword);// 鐧婚檰FTP鏈嶅姟鍣�
-            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
-                logger.info("鏈繛鎺ュ埌FTP锛岀敤鎴峰悕鎴栧瘑鐮侀敊璇��");
-                ftpClient.disconnect();
-            } else {
-                logger.info("FTP杩炴帴鎴愬姛銆�");
-            }
-        } catch (SocketException e) {
-            e.printStackTrace();
-            logger.info("FTP鐨処P鍦板潃鍙兘閿欒锛岃姝g‘閰嶇疆銆�");
-        } catch (IOException e) {
-            e.printStackTrace();
-            logger.info("FTP鐨勭鍙i敊璇�,璇锋纭厤缃��");
-        }
-        return ftpClient;
-    }
-
-    /**
-     * 浠嶧TP鏈嶅姟鍣ㄤ笅杞芥枃浠�
-     *
-     * @param ftpHost     FTP IP鍦板潃
-     * @param ftpUserName FTP 鐢ㄦ埛鍚�
-     * @param ftpPassword FTP鐢ㄦ埛鍚嶅瘑鐮�
-     * @param ftpPort     FTP绔彛
-     * @param ftpPath     FTP鏈嶅姟鍣ㄤ腑鏂囦欢鎵�鍦ㄨ矾寰� 鏍煎紡锛� ftptest/aa
-     * @param localPath   涓嬭浇鍒版湰鍦扮殑浣嶇疆 鏍煎紡锛欻:/download
-     * @param fileName    鏂囦欢鍚嶇О
-     */
-    public static void downloadFtpFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort,
-                                       String ftpPath, String localPath, String fileName) {
-
-        FTPClient ftpClient = null;
-
-        try {
-            ftpClient = getFTPClient();
-            // 璁剧疆涓婁紶鏂囦欢鐨勭被鍨嬩负浜岃繘鍒剁被鍨�
-            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 寮�鍚湇鍔″櫒瀵筓TF-8鐨勬敮鎸侊紝濡傛灉鏈嶅姟鍣ㄦ敮鎸佸氨鐢║TF-8缂栫爜锛屽惁鍒欏氨浣跨敤鏈湴缂栫爜锛圙BK锛�.
-                LOCAL_CHARSET = "UTF-8";
-            }
-            ftpClient.setControlEncoding(LOCAL_CHARSET);
-            ftpClient.enterLocalPassiveMode();// 璁剧疆琚姩妯″紡
-            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 璁剧疆浼犺緭鐨勬ā寮�
-            // 涓婁紶鏂囦欢
-            //瀵逛腑鏂囨枃浠跺悕杩涜杞爜锛屽惁鍒欎腑鏂囧悕绉扮殑鏂囦欢涓嬭浇澶辫触
-            String fileNameTemp = new String(fileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
-            ftpClient.changeWorkingDirectory(ftpPath);
-
-            InputStream retrieveFileStream = ftpClient.retrieveFileStream(fileNameTemp);
-
-            // 绗竴绉嶆柟寮忎笅杞芥枃浠�(鎺ㄨ崘)
-			 /* File localFile = new File(localPath + File.separatorChar + fileName);
-			  OutputStream os = new FileOutputStream(localFile);
-			  ftpClient.retrieveFile(fileName, os); os.close();*/
-
-
-            // 绗簩绉嶆柟寮忎笅杞斤細灏嗚緭鍏ユ祦杞垚瀛楄妭锛屽啀鐢熸垚鏂囦欢锛岃繖绉嶆柟寮忔柟渚垮皢瀛楄妭鏁扮粍鐩存帴杩斿洖缁欏墠鍙癹sp椤甸潰
-            byte[] input2byte = input2byte(retrieveFileStream);
-            byte2File(input2byte, localPath, fileName);
-
-            if (null != retrieveFileStream) {
-                retrieveFileStream.close();
-            }
-        } catch (FileNotFoundException e) {
-            logger.error("娌℃湁鎵惧埌" + ftpPath + "鏂囦欢");
-            e.printStackTrace();
-        } catch (SocketException e) {
-            logger.error("杩炴帴FTP澶辫触.");
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-            logger.error("鏂囦欢璇诲彇閿欒銆�");
-            e.printStackTrace();
-        } finally {
-
-            if (ftpClient.isConnected()) {
-                try {
-                    //閫�鍑虹櫥褰�
-                    ftpClient.logout();
-                    //鍏抽棴杩炴帴
-                    ftpClient.disconnect();
-                } catch (IOException e) {
-                }
-            }
-        }
-    }
-
-    /**
-     * Description: 鍚慒TP鏈嶅姟鍣ㄤ笂浼犳枃浠�
-     *
-     * @param basePath FTP鏈嶅姟鍣ㄥ熀纭�鐩綍
-     * @param filePath FTP鏈嶅姟鍣ㄦ枃浠跺瓨鏀捐矾寰勩�備緥濡傚垎鏃ユ湡瀛樻斁锛�/2015/01/01銆傛枃浠剁殑璺緞涓篵asePath+filePath
-     * @param filename 涓婁紶鍒癋TP鏈嶅姟鍣ㄤ笂鐨勬枃浠跺悕
-     * @param input    杈撳叆娴�
-     * @return 鎴愬姛杩斿洖true锛屽惁鍒欒繑鍥瀎alse
-     */
-    public static boolean uploadFile(String basePath, String filePath, String filename, InputStream input) {
-        boolean result = false;
-        FTPClient ftpClient = null;
-        try {
-            int reply;
-            ftpClient = getFTPClient();
-            reply = ftpClient.getReplyCode();
-            if (!FTPReply.isPositiveCompletion(reply)) {
-                ftpClient.disconnect();
-                return result;
-            }
-            // 鍒囨崲鍒颁笂浼犵洰褰�
-            if (!ftpClient.changeWorkingDirectory(basePath + filePath)) {
-                // 濡傛灉鐩綍涓嶅瓨鍦ㄥ垱寤虹洰褰�
-                String[] dirs = filePath.split("/");
-                String tempPath = basePath;
-                for (String dir : dirs) {
-                    if (null == dir || "".equals(dir))
-                        continue;
-                    tempPath += "/" + dir;
-                    if (!ftpClient.changeWorkingDirectory(tempPath)) {
-                        if (!ftpClient.makeDirectory(tempPath)) {
-                            return result;
-                        } else {
-                            ftpClient.changeWorkingDirectory(tempPath);
-                        }
-                    }
-                }
-            }
-            // 璁剧疆涓婁紶鏂囦欢鐨勭被鍨嬩负浜岃繘鍒剁被鍨�
-            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 寮�鍚湇鍔″櫒瀵筓TF-8鐨勬敮鎸侊紝濡傛灉鏈嶅姟鍣ㄦ敮鎸佸氨鐢║TF-8缂栫爜锛屽惁鍒欏氨浣跨敤鏈湴缂栫爜锛圙BK锛�.
-                LOCAL_CHARSET = "UTF-8";
-            }
-            ftpClient.setControlEncoding(LOCAL_CHARSET);
-            ftpClient.enterLocalPassiveMode();// 璁剧疆琚姩妯″紡
-            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 璁剧疆浼犺緭鐨勬ā寮�
-            // 涓婁紶鏂囦欢
-            filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
-            if (!ftpClient.storeFile(filename, input)) {
-                return result;
-            }
-
-            if (null != input) {
-                input.close();
-            }
-
-            result = true;
-        } catch (IOException e) {
-            e.printStackTrace();
-        } finally {
-            if (ftpClient.isConnected()) {
-                try {
-                    //閫�鍑虹櫥褰�
-                    ftpClient.logout();
-                    //鍏抽棴杩炴帴
-                    ftpClient.disconnect();
-                } catch (IOException ioe) {
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * 鍒犻櫎鏂囦欢 鏈祴璇�
-     *
-     * @param ftpHost     FTP鏈嶅姟鍣ㄥ湴鍧�
-     * @param ftpPort     FTP鏈嶅姟鍣ㄧ鍙e彿
-     * @param ftpUserName FTP鐧诲綍甯愬彿
-     * @param ftpPassword FTP鐧诲綍瀵嗙爜
-     * @param pathname    FTP鏈嶅姟鍣ㄤ繚瀛樼洰褰�
-     * @param filename    瑕佸垹闄ょ殑鏂囦欢鍚嶇О
-     * @return
-     */
-    public static boolean deleteFile(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String pathname,
-                                     String filename) {
-        boolean flag = false;
+    public FTPClient getFTPClient() {
         FTPClient ftpClient = new FTPClient();
         try {
-            ftpClient = getFTPClient();
-            // 楠岃瘉FTP鏈嶅姟鍣ㄦ槸鍚︾櫥褰曟垚鍔�
-            int replyCode = ftpClient.getReplyCode();
-            if (!FTPReply.isPositiveCompletion(replyCode)) {
-                return flag;
-            }
-            // 鍒囨崲FTP鐩綍
-            ftpClient.changeWorkingDirectory(pathname);
-            // 璁剧疆涓婁紶鏂囦欢鐨勭被鍨嬩负浜岃繘鍒剁被鍨�
-            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 寮�鍚湇鍔″櫒瀵筓TF-8鐨勬敮鎸侊紝濡傛灉鏈嶅姟鍣ㄦ敮鎸佸氨鐢║TF-8缂栫爜锛屽惁鍒欏氨浣跨敤鏈湴缂栫爜锛圙BK锛�.
-                LOCAL_CHARSET = "UTF-8";
+            ftpClient.connect(ftpHost, ftpPort);
+            ftpClient.login(ftpUserName, ftpPassword);
+
+            // 寮哄埗寮�鍚� UTF-8 鏀寔锛堜紭鍏堣鐩栨湇鍔″櫒閰嶇疆锛�
+            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
+                LOCAL_CHARSET = StandardCharsets.UTF_8.name();
             }
             ftpClient.setControlEncoding(LOCAL_CHARSET);
-            ftpClient.enterLocalPassiveMode();// 璁剧疆琚姩妯″紡
-            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);// 璁剧疆浼犺緭鐨勬ā寮�
-            //瀵逛腑鏂囧悕绉拌繘琛岃浆鐮�
-            filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
-            ftpClient.dele(filename);
-            flag = true;
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            if (ftpClient.isConnected()) {
-                try {
-                    //閫�鍑虹櫥褰�
-                    ftpClient.logout();
-                    //鍏抽棴杩炴帴
-                    ftpClient.disconnect();
-                } catch (IOException e) {
-                }
+
+            // 鍏抽敭閰嶇疆锛氫簩杩涘埗浼犺緭 + 琚姩妯″紡锛岃В鍐虫枃浠舵崯鍧忋�侀槻鐏闃诲闂
+            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
+            ftpClient.enterLocalPassiveMode();
+
+            int replyCode = ftpClient.getReplyCode();
+            if (!FTPReply.isPositiveCompletion(replyCode)) {
+                logger.error("FTP 杩炴帴澶辫触锛屽搷搴旂爜锛�" + replyCode);
+                disconnectQuietly(ftpClient);
+                return null;
             }
+            logger.info("FTP 杩炴帴鎴愬姛锛屽搷搴旂爜锛�" + replyCode);
+            return ftpClient;
+        } catch (IOException e) {
+            logger.error("FTP 杩炴帴寮傚父锛�" + e.getMessage(), e);
+            disconnectQuietly(ftpClient);
+            return null;
         }
-        return flag;
     }
 
     /**
-     * 鍒涘缓鏂囦欢澶�
-     *
-     * @param pathname
-     * @param filename
-     * @return
+     * 瀹夐潤鍏抽棴杩炴帴锛堥伩鍏嶅祵濂楀紓甯革級
      */
-    public static boolean createFolder(String pathname, String filename) {
-        boolean flag = false;
-        FTPClient ftpClient = new FTPClient();
-        try {
-            ftpClient = getFTPClient();
-            // 楠岃瘉FTP鏈嶅姟鍣ㄦ槸鍚︾櫥褰曟垚鍔�
-            int replyCode = ftpClient.getReplyCode();
-            if (!FTPReply.isPositiveCompletion(replyCode)) {
-                return flag;
-            }
-            // 鍒囨崲FTP鐩綍
-            ftpClient.changeWorkingDirectory(pathname);
-            boolean created = ftpClient.makeDirectory(filename);
-            if (created) {
-                logger.info(filename + "鏂囦欢澶瑰垱寤烘垚鍔�");
-            } else {
-                logger.info(filename + "鍒涘缓鏂囦欢澶瑰け璐�");
-            }
-            flag = true;
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            if (ftpClient.isConnected()) {
-                try {
-                    //閫�鍑虹櫥褰�
-                    ftpClient.logout();
-                    //鍏抽棴杩炴帴
-                    ftpClient.disconnect();
-                } catch (IOException e) {
-                }
+    private void disconnectQuietly(FTPClient ftpClient) {
+        if (ftpClient != null && ftpClient.isConnected()) {
+            try {
+                ftpClient.logout();
+                ftpClient.disconnect();
+            } catch (IOException e) {
+                logger.warn("鍏抽棴 FTP 杩炴帴澶辫触锛�" + e.getMessage(), e);
             }
         }
-        return flag;
     }
 
-    public static void uploadFolder(File localFolder, String remoteFolder) {
-        if (!localFolder.exists()) {
+
+    // ====================== 鏂囦欢澶逛笂浼犱紭鍖栵細閫掑綊 + 瀹屾暣鎬ф牎楠� ======================
+
+    /**
+     * 閫掑綊涓婁紶鏂囦欢澶癸紙鏍稿績鏂规硶锛�
+     *
+     * @param localFolder  鏈湴鏂囦欢澶�
+     * @param remoteFolder 杩滅▼鐖剁洰褰�
+     */
+    public void uploadFolder(File localFolder, String remoteFolder) {
+        if (localFolder == null || !localFolder.isDirectory()) {
+            logger.warn("鏈湴鏂囦欢澶规棤鏁堬細" + (localFolder == null ? "null" : localFolder.getPath()));
             return;
         }
+
         FTPClient ftpClient = getFTPClient();
-        try {
-            // 鍒涘缓杩滅▼鏂囦欢澶�
-            if (!ftpClient.changeWorkingDirectory(remoteFolder)) {
-                ftpClient.makeDirectory(remoteFolder);
-                ftpClient.changeWorkingDirectory(remoteFolder);
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
+        if (ftpClient == null) {
+            logger.error("FTP 瀹㈡埛绔垵濮嬪寲澶辫触锛屾斁寮冧笂浼狅細" + localFolder.getPath());
+            return;
         }
-        // 閬嶅巻鏈湴鏂囦欢澶逛腑鐨勬枃浠跺拰瀛愭枃浠跺す
-        File[] files = localFolder.listFiles();
-        if (files != null) {
+
+        try {
+            // 纭繚杩滅▼鐩綍瀛樺湪锛堥�掑綊鍒涘缓锛�
+            if (!createRemoteDirectory(ftpClient, remoteFolder)) {
+                logger.error("鍒涘缓杩滅▼鐩綍澶辫触锛�" + remoteFolder);
+                return;
+            }
+
+            // 閬嶅巻鏈湴鏂囦欢
+            File[] files = localFolder.listFiles();
+            if (files == null) {
+                logger.warn("鏈湴鏂囦欢澶逛负绌猴細" + localFolder.getPath());
+                return;
+            }
+
             for (File file : files) {
                 if (file.isDirectory()) {
                     // 閫掑綊涓婁紶瀛愭枃浠跺す
                     uploadFolder(file, remoteFolder + "/" + file.getName());
-                } else {
-                    try {
-                        // 涓婁紶鏂囦欢
-                        uploadFile1(ftpClient, file, remoteFolder);
-                    } catch (IOException e) {
-                        e.printStackTrace();
+                } else if (file.isFile()) {
+                    // 涓婁紶鏂囦欢锛堝甫瀹屾暣鎬ф牎楠岋級
+                    boolean success = uploadFileWithCheck(ftpClient, file, remoteFolder);
+                    if (!success) {
+                        logger.error("鏂囦欢涓婁紶澶辫触锛�" + file.getPath() + " -> " + remoteFolder);
                     }
                 }
             }
-        }
-    }
-
-    private static void uploadFile1(FTPClient ftpClient, File localFile, String remoteFolder) throws IOException {
-        try (FileInputStream inputStream = new FileInputStream(localFile)) {
-            ftpClient.storeFile(remoteFolder + "/" + localFile.getName(), inputStream);
-        }
-    }
-
-    // 灏嗗瓧鑺傛暟缁勮浆鎹负杈撳叆娴�
-    public static final InputStream byte2Input(byte[] buf) {
-        return new ByteArrayInputStream(buf);
-    }
-
-    // 灏嗚緭鍏ユ祦杞负byte[]
-    public static final byte[] input2byte(InputStream inStream) throws IOException {
-        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
-        byte[] buff = new byte[100];
-        int rc = 0;
-        while ((rc = inStream.read(buff, 0, 100)) > 0) {
-            swapStream.write(buff, 0, rc);
-        }
-        byte[] in2b = swapStream.toByteArray();
-        return in2b;
-    }
-
-    // 灏哹yte[]杞负鏂囦欢
-    public static void byte2File(byte[] buf, String filePath, String fileName) {
-        BufferedOutputStream bos = null;
-        FileOutputStream fos = null;
-        File file = null;
-        try {
-            File dir = new File(filePath);
-            if (!dir.exists() && dir.isDirectory()) {
-                dir.mkdirs();
-            }
-            file = new File(filePath + File.separator + fileName);
-            fos = new FileOutputStream(file);
-            bos = new BufferedOutputStream(fos);
-            bos.write(buf);
-        } catch (Exception e) {
-            e.printStackTrace();
+        } catch (IOException e) {
+            logger.error("涓婁紶鏂囦欢澶瑰紓甯革細" + e.getMessage(), e);
         } finally {
-            if (bos != null) {
-                try {
-                    bos.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
+            disconnectQuietly(ftpClient);
+        }
+    }
+
+    /**
+     * 楹掗簾閫掑綊涓婁紶鏂囦欢澶癸紙鏍稿績鏂规硶锛�
+     *
+     * @param localFolder  鏈湴鏂囦欢澶�
+     * @param remoteFolder 杩滅▼鐖剁洰褰�
+     */
+    public void uploadFolderKylin(File localFolder, String remoteFolder) {
+        if (operatingSystem.equals("windows")){
+            if (localFolder == null || !localFolder.isDirectory()) {
+                logger.warn("鏈湴鏂囦欢澶规棤鏁堬細" + (localFolder == null ? "null" : localFolder.getPath()));
+                return;
+            }
+
+            FTPClient ftpClient = getFTPClient();
+            if (ftpClient == null) {
+                logger.error("FTP 瀹㈡埛绔垵濮嬪寲澶辫触锛屾斁寮冧笂浼狅細" + localFolder.getPath());
+                return;
+            }
+
+            try {
+                // 楹掗簾绯荤粺FTP鏈嶅姟鍣ㄥ繀闇�鐨勮缃�
+                ftpClient.enterLocalPassiveMode(); // 鍚敤琚姩妯″紡锛堢被Unix绯荤粺鎺ㄨ崘锛�
+                ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 浜岃繘鍒朵紶杈撻伩鍏嶆枃浠舵崯鍧�
+                ftpClient.setControlEncoding("UTF-8"); // 鎺у埗杩炴帴缂栫爜
+                // 纭繚杩滅▼鐩綍瀛樺湪锛堥�掑綊鍒涘缓锛�
+                if (!createRemoteDirectory(ftpClient, remoteFolder)) {
+                    logger.error("鍒涘缓杩滅▼鐩綍澶辫触锛�" + remoteFolder);
+                    return;
+                }
+
+                // 閬嶅巻鏈湴鏂囦欢
+                File[] files = localFolder.listFiles();
+                if (files == null) {
+                    logger.warn("鏈湴鏂囦欢澶逛负绌猴細" + localFolder.getPath());
+                    return;
+                }
+
+                for (File file : files) {
+                    if (file.isDirectory()) {
+                        // 閫掑綊涓婁紶瀛愭枃浠跺す
+                        uploadFolder(file, remoteFolder + "/" + file.getName());
+                    } else if (file.isFile()) {
+                        // 涓婁紶鏂囦欢锛堝甫瀹屾暣鎬ф牎楠岋級
+                        boolean success = uploadFileWithCheck(ftpClient, file, remoteFolder);
+                        if (!success) {
+                            logger.error("鏂囦欢涓婁紶澶辫触锛�" + file.getPath() + " -> " + remoteFolder);
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                logger.error("涓婁紶鏂囦欢澶瑰紓甯革細" + e.getMessage(), e);
+            } finally {
+                disconnectQuietly(ftpClient);
+            }
+        }else {
+            if (localFolder == null || !localFolder.isDirectory()) {
+                logger.warn("鏈湴鏂囦欢澶规棤鏁堬細" + (localFolder == null ? "null" : localFolder.getPath()));
+                return;
+            }
+
+            FTPClient ftpClient = getFTPClient();
+            if (ftpClient == null) {
+                logger.error("FTP 瀹㈡埛绔垵濮嬪寲澶辫触锛屾斁寮冧笂浼狅細" + localFolder.getPath());
+                return;
+            }
+
+            try {
+                // 楹掗簾绯荤粺FTP鏈嶅姟鍣ㄥ繀闇�鐨勮缃�
+                ftpClient.enterLocalPassiveMode(); // 鍚敤琚姩妯″紡锛堢被Unix绯荤粺鎺ㄨ崘锛�
+                ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 浜岃繘鍒朵紶杈撻伩鍏嶆枃浠舵崯鍧�
+                ftpClient.setControlEncoding("UTF-8"); // 鎺у埗杩炴帴缂栫爜
+                // 纭繚杩滅▼鐩綍瀛樺湪锛堥�掑綊鍒涘缓锛�
+                if (!createKylinFtpDirectory(ftpClient, "/iot", remoteFolder)) {
+                    logger.error("鍒涘缓杩滅▼鐩綍澶辫触锛�" + remoteFolder);
+                    return;
+                }
+
+                // 閬嶅巻鏈湴鏂囦欢
+                File[] files = localFolder.listFiles();
+                if (files == null) {
+                    logger.warn("鏈湴鏂囦欢澶逛负绌猴細" + localFolder.getPath());
+                    return;
+                }
+
+                for (File file : files) {
+                    if (file.isDirectory()) {
+                        // 閫掑綊涓婁紶瀛愭枃浠跺す
+                        uploadFolder(file, "/iot"+remoteFolder + "/" + file.getName());
+                    } else if (file.isFile()) {
+                        // 涓婁紶鏂囦欢锛堝甫瀹屾暣鎬ф牎楠岋級
+                        boolean success = uploadFileWithCheck(ftpClient, file, "/iot"+remoteFolder);
+                        if (!success) {
+                            logger.error("鏂囦欢涓婁紶澶辫触锛�" + file.getPath() + " -> " + remoteFolder);
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                logger.error("涓婁紶鏂囦欢澶瑰紓甯革細" + e.getMessage(), e);
+            } finally {
+                disconnectQuietly(ftpClient);
+            }
+        }
+
+    }
+
+    private boolean createRemoteDirectory(FTPClient ftpClient, String remoteDir) throws IOException {
+        String[] dirs = remoteDir.split("/");
+        StringBuilder currentDir = new StringBuilder();
+        for (String dir : dirs) {
+            if (dir.trim().isEmpty()) continue;
+            currentDir.append("/").append(dir);
+            String targetDir = currentDir.toString();
+            // 鎵撳嵃褰撳墠灏濊瘯鍒囨崲/鍒涘缓鐨勭洰褰�
+            logger.info("灏濊瘯鎿嶄綔鐩綍:" + targetDir);
+
+            if (!ftpClient.changeWorkingDirectory(targetDir)) {
+                boolean mkdirResult = ftpClient.makeDirectory(targetDir);
+                // 鎵撳嵃鍒涘缓缁撴灉鍜� FTP 鍝嶅簲
+                logger.info("鍒涘缓鐩綍缁撴灉: " + mkdirResult + ", 鍝嶅簲鐮�: " + ftpClient.getReplyCode()
+                        + ", 鍝嶅簲淇℃伅: " + ftpClient.getReplyString());
+
+                if (!mkdirResult) {
+                    logger.error("鍒涘缓鐩綍澶辫触: " + targetDir);
+                    return false;
+                }
+                if (!ftpClient.changeWorkingDirectory(targetDir)) {
+                    logger.error("鍒囨崲鐩綍澶辫触: " + targetDir + ", 鍝嶅簲鐮�: " + ftpClient.getReplyCode()
+                            + ", 鍝嶅簲淇℃伅: " + ftpClient.getReplyString());
+                    return false;
                 }
             }
-            if (fos != null) {
-                try {
-                    fos.close();
-                } catch (IOException e) {
-                    e.printStackTrace();
+        }
+        return true;
+    }
+
+    /**
+     * 鍦ㄩ簰楹熺郴缁熺殑FTP鏈嶅姟鍣ㄤ笂鍒涘缓鐩綍锛堟敮鎸佸绾х洰褰曪級
+     *
+     * @param baseDir   FTP鍩虹鐩綍锛堝/iot锛�
+     * @param remoteDir 瑕佸垱寤虹殑鐩綍璺緞锛堝data/logs/2023锛�
+     * @return 鏄惁鍒涘缓鎴愬姛
+     * @throws IOException IO寮傚父
+     */
+    public boolean createKylinFtpDirectory(FTPClient ftpClient, String baseDir, String remoteDir) throws IOException {
+        // 纭繚鍩虹鐩綍浠�/缁撳熬
+        String normalizedBase = baseDir.endsWith("/") ? baseDir : baseDir + "/";
+
+        // 澶勭悊杩滅▼鐩綍锛岀Щ闄ゅ紑澶村彲鑳界殑/锛岄伩鍏嶉噸澶�
+        String normalizedRemote = remoteDir.startsWith("/") ? remoteDir.substring(1) : remoteDir;
+
+        // 鍒嗗壊鐩綍
+        String[] dirs = normalizedRemote.split("/");
+        StringBuilder currentPath = new StringBuilder(normalizedBase);
+
+        for (String dir : dirs) {
+            if (dir.trim().isEmpty()) continue; // 璺宠繃绌虹洰褰曪紙澶勭悊杩炵画//鐨勬儏鍐碉級
+
+            currentPath.append(dir).append("/");
+            String targetDir = currentPath.toString();
+
+            // 灏濊瘯鍒囨崲鍒扮洰褰�
+            if (!ftpClient.changeWorkingDirectory(targetDir)) {
+                // 鍒囨崲澶辫触锛屽皾璇曞垱寤虹洰褰�
+                boolean created = ftpClient.makeDirectory(targetDir);
+                logger.info("鍒涘缓鐩綍[" + targetDir + "]缁撴灉: {" + created + "}, 鍝嶅簲鐮�: {" + ftpClient.getReplyCode() + "}");
+
+                if (!created) {
+                    logger.error("鍒涘缓鐩綍澶辫触: {" + targetDir + "}");
+                    return false;
                 }
+
+                // 楠岃瘉鏄惁鑳藉垏鎹㈠埌鏂板垱寤虹殑鐩綍
+                if (!ftpClient.changeWorkingDirectory(targetDir)) {
+                    logger.error("鍒囨崲鍒扮洰褰曞け璐�: {" + targetDir + "}, 鍝嶅簲: {" + ftpClient.getReplyString() + "}");
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 涓婁紶鏂囦欢锛堝甫澶у皬鏍¢獙锛�
+     *
+     * @return 鏄惁涓婁紶鎴愬姛涓斿畬鏁�
+     */
+    private boolean uploadFileWithCheck(FTPClient ftpClient, File localFile, String remoteFolder) throws IOException {
+        String remoteFilePath = remoteFolder + "/" + localFile.getName();
+        long localFileSize = localFile.length();
+
+        // 鏍¢獙杩滅▼鏂囦欢鏄惁宸插瓨鍦ㄤ笖瀹屾暣
+        FTPFile[] remoteFiles = ftpClient.listFiles(remoteFilePath);
+        if (remoteFiles != null && remoteFiles.length > 0) {
+            FTPFile remoteFile = remoteFiles[0];
+            if (remoteFile.getSize() == localFileSize) {
+                logger.info("鏂囦欢宸插瓨鍦ㄤ笖瀹屾暣锛岃烦杩囦笂浼狅細" + localFile.getPath());
+                return true;
+            }
+        }
+
+        // 鎵ц涓婁紶
+        try (FileInputStream inputStream = new FileInputStream(localFile)) {
+            boolean uploaded = ftpClient.storeFile(remoteFilePath, inputStream);
+            if (!uploaded) {
+                logger.error("涓婁紶澶辫触锛屽搷搴旂爜锛�" + ftpClient.getReplyCode() + " -> " + localFile.getPath());
+                return false;
+            }
+
+            // 浜屾鏍¢獙杩滅▼鏂囦欢澶у皬
+            FTPFile[] checkFiles = ftpClient.listFiles(remoteFilePath);
+            if (checkFiles == null || checkFiles.length == 0) {
+                logger.error("涓婁紶鍚庢枃浠朵涪澶憋細" + localFile.getPath());
+                return false;
+            }
+            return checkFiles[0].getSize() == localFileSize;
+        }
+    }
+
+
+    // ====================== 鍏朵粬鏂规硶浼樺寲锛氳祫婧愰噴鏀� + 缂栫爜鍋ュ.鎬� ======================
+
+    /**
+     * 涓嬭浇鏂囦欢锛堜紭鍖栫紪鐮佸鐞嗐�佽祫婧愰噴鏀撅級
+     */
+    public void downloadFtpFile(String ftpPath, String localPath, String fileName) {
+        FTPClient ftpClient = getFTPClient();
+        if (ftpClient == null) {
+            return;
+        }
+
+        try {
+            // 缂栫爜杞崲锛堣В鍐充腑鏂囪矾寰勯棶棰橈級
+            String remoteFilePath = new String((ftpPath + "/" + fileName).getBytes(LOCAL_CHARSET), SERVER_CHARSET);
+            if (!ftpClient.changeWorkingDirectory(ftpPath)) {
+                logger.error("鍒囨崲杩滅▼鐩綍澶辫触锛�" + ftpPath);
+                return;
+            }
+
+            // 涓嬭浇鏂囦欢
+            try (InputStream is = ftpClient.retrieveFileStream(remoteFilePath);
+                 OutputStream os = new FileOutputStream(new File(localPath, fileName))) {
+                if (is == null) {
+                    logger.error("杩滅▼鏂囦欢涓嶅瓨鍦細" + remoteFilePath);
+                    return;
+                }
+                byte[] buffer = new byte[4096];
+                int len;
+                while ((len = is.read(buffer)) != -1) {
+                    os.write(buffer, 0, len);
+                }
+                os.flush();
+                // 纭涓嬭浇瀹屾垚锛堝叧閿細閬垮厤鏂囦欢鎴柇锛�
+                if (!ftpClient.completePendingCommand()) {
+                    logger.error("FTP 涓嬭浇鏈畬鎴愶細" + remoteFilePath);
+                }
+            }
+        } catch (IOException e) {
+            logger.error("涓嬭浇鏂囦欢澶辫触锛�" + fileName, e);
+        } finally {
+            disconnectQuietly(ftpClient);
+        }
+    }
+
+    /**
+     * 涓婁紶鏂囦欢锛堢嫭绔嬫柟娉曪紝渚涘鐢級
+     *
+     * @param basePath 杩滅▼鍩虹璺緞
+     * @param filePath 杩滅▼瀛愯矾寰�
+     * @param filename 鏂囦欢鍚�
+     * @param input    杈撳叆娴�
+     * @return 鏄惁鎴愬姛
+     */
+    public boolean uploadFile(String basePath, String filePath, String filename, InputStream input) {
+        FTPClient ftpClient = getFTPClient();
+        if (ftpClient == null) {
+            return false;
+        }
+
+        try {
+            String remoteDir = basePath + filePath;
+            if (!createRemoteDirectory(ftpClient, remoteDir)) {
+                return false;
+            }
+
+            // 缂栫爜杞崲锛堣В鍐充腑鏂囨枃浠跺悕锛�
+            String remoteFileName = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
+            boolean success = ftpClient.storeFile(remoteFileName, input);
+            if (success) {
+                logger.info("鏂囦欢涓婁紶鎴愬姛锛�" + remoteDir + "/" + remoteFileName);
+            } else {
+                logger.error("鏂囦欢涓婁紶澶辫触锛屽搷搴旂爜锛�" + ftpClient.getReplyCode());
+            }
+            return success;
+        } catch (IOException e) {
+            logger.error("涓婁紶鏂囦欢寮傚父锛�" + e.getMessage(), e);
+            return false;
+        } finally {
+            disconnectQuietly(ftpClient);
+            try {
+                input.close();
+            } catch (IOException e) {
+                logger.warn("鍏抽棴杈撳叆娴佸け璐ワ細" + e.getMessage());
             }
         }
     }
 
-}
+    /**
+     * 涓婁紶鏂囦欢锛堥�傞厤楹掗簾绯荤粺锛屼緵澶嶇敤锛�
+     *
+     * @param basePath 杩滅▼鍩虹璺緞锛堝/iot锛�
+     * @param filePath 杩滅▼瀛愯矾寰勶紙濡俤ata/logs锛�
+     * @param filename 鏂囦欢鍚�
+     * @param input    杈撳叆娴�
+     * @return 鏄惁鎴愬姛
+     */
+    public boolean uploadFileKylin(String basePath, String filePath, String filename, InputStream input) {
+        FTPClient ftpClient = getFTPClient();
+        if (ftpClient == null) {
+            logger.error("鑾峰彇FTPClient瀹炰緥澶辫触锛屾棤娉曟墽琛屼笂浼�");
+            return false;
+        }
+
+        try {
+            // 楹掗簾绯荤粺FTP鏈嶅姟鍣ㄥ繀闇�鐨勮缃�
+            ftpClient.enterLocalPassiveMode(); // 鍚敤琚姩妯″紡锛堢被Unix绯荤粺鎺ㄨ崘锛�
+            ftpClient.setFileType(FTP.BINARY_FILE_TYPE); // 浜岃繘鍒朵紶杈撻伩鍏嶆枃浠舵崯鍧�
+            ftpClient.setControlEncoding("UTF-8"); // 鎺у埗杩炴帴缂栫爜
+
+            // 璺緞瑙勮寖鍖栧鐞嗭紙閫傞厤楹掗簾绯荤粺Unix璺緞鏍煎紡锛�
+            String normalizedBase = normalizePath(basePath);
+            String normalizedFilePath = normalizePath(filePath);
+            String remoteDir = normalizedBase + normalizedFilePath;
+            logger.info("楹掗簾绯荤粺FTP鐩爣鐩綍:" + remoteDir);
+
+            // 鍒涘缓鐩綍锛堜慨姝e弬鏁伴『搴忥紝浣跨敤瑙勮寖鍖栬矾寰勶級
+            if (!createKylinFtpDirectory(ftpClient, normalizedBase, normalizedFilePath)) {
+                logger.error("鐩綍鍒涘缓澶辫触锛岀粓姝笂浼�:" + remoteDir);
+                return false;
+            }
+
+            // 鍒囨崲鍒扮洰鏍囩洰褰曪紙澧炲姞楠岃瘉姝ラ锛�
+            if (!ftpClient.changeWorkingDirectory(remoteDir)) {
+                logger.error("鍒囨崲鍒扮洰褰昜" + remoteDir + "]澶辫触锛屽搷搴旂爜: {" + ftpClient.getReplyCode() + "}");
+                return false;
+            }
+
+            // 缂栫爜杞崲锛堜紭鍖栦腑鏂囨枃浠跺悕澶勭悊锛岄�傞厤楹掗簾绯荤粺缂栫爜锛�
+            String remoteFileName = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
+
+            // 鎵ц涓婁紶
+            boolean success = ftpClient.storeFile(remoteFileName, input);
+            if (success) {
+                logger.info("鏂囦欢涓婁紶鎴愬姛锛歿" + remoteDir + "/" + filename + "}");
+            } else {
+                logger.error("鏂囦欢涓婁紶澶辫触锛岃矾寰勶細{" + remoteDir + "/" + filename + "}锛屽搷搴旂爜锛歿" + ftpClient.getReplyCode() + "}锛屽搷搴斾俊鎭細{" +
+                        ftpClient.getReplyString() + "}");
+            }
+            return success;
+        } catch (IOException e) {
+            logger.error("涓婁紶鏂囦欢寮傚父锛歿" + e.getMessage(), e);
+            return false;
+        } finally {
+            disconnectQuietly(ftpClient);
+            try {
+                input.close();
+            } catch (IOException e) {
+                logger.warn("鍏抽棴杈撳叆娴佸け璐ワ細{}" + e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * 璺緞瑙勮寖鍖栧鐞嗭紙閫傞厤楹掗簾绯荤粺锛�
+     * 澶勭悊閲嶅鏂滄潬銆侀灏炬枩鏉犻棶棰橈紝缁熶竴Unix椋庢牸璺緞
+     */
+    private String normalizePath(String path) {
+        if (path == null || path.trim().isEmpty()) {
+            return "";
+        }
+        // 鏇挎崲澶氫釜鏂滄潬涓哄崟涓紝绉婚櫎灏鹃儴鏂滄潬锛堥櫎鏍圭洰褰曞锛�
+        String normalized = path.trim().replaceAll("//+", "/");
+        if (normalized.length() > 1 && normalized.endsWith("/")) {
+            normalized = normalized.substring(0, normalized.length() - 1);
+        }
+        return normalized;
+    }
+
+    /**
+     * 鍒涘缓鏂囦欢澶癸紙閫傞厤楹掗簾绯荤粺锛岃В鍐崇紪鐮�/鏉冮檺/璺緞闂锛�
+     */
+    public boolean createFolder(String pathname, String folderName) {
+        FTPClient ftpClient = getFTPClient();
+        if (ftpClient == null) {
+            return false;
+        }
+
+        try {
+            // 1. 缁熶竴璺緞鏍煎紡锛圠inux鍏煎锛�
+            String remoteFolder = (pathname + "/" + folderName)
+                    .replace("\\", "/")          // 鏇挎崲Windows鍙嶆枩鏉�
+                    .replaceAll("/+", "/")        // 鍚堝苟杩炵画鏂滄潬
+                    .replaceAll("^/", "");        // 鍘婚櫎寮�澶寸殑鏂滄潬锛堥伩鍏嶇粷瀵硅矾寰勯棶棰橈級
+
+            // 2. 璁剧疆UTF-8缂栫爜锛堣В鍐充腑鏂囪矾寰勯棶棰橈級
+            ftpClient.setControlEncoding("UTF-8");
+            remoteFolder = new String(remoteFolder.getBytes("UTF-8"), "ISO-8859-1"); // FTP鍗忚榛樿缂栫爜
+
+            // 3. 妫�鏌ョ洰褰曟槸鍚﹀瓨鍦紙骞傜瓑鎬э級
+            if (ftpClient.changeWorkingDirectory(remoteFolder)) {
+                logger.info("鏂囦欢澶瑰凡瀛樺湪锛�" + remoteFolder);
+                return true;
+            }
+
+            // 4. 灏濊瘯鍒涘缓鐩綍锛堣鍔ㄦā寮忛�傞厤锛�
+            ftpClient.enterLocalPassiveMode(); // 楹掗簾绯荤粺寤鸿鐢ㄨ鍔ㄦā寮�
+            boolean success = ftpClient.makeDirectory(remoteFolder);
+
+            // 5. 璁板綍璇︾粏閿欒淇℃伅
+            if (!success) {
+                int replyCode = ftpClient.getReplyCode();
+                String replyMsg = ftpClient.getReplyString();
+                logger.error("鍒涘缓鏂囦欢澶瑰け璐ワ紝璺緞锛�" + remoteFolder +
+                        "锛屽搷搴旂爜锛�" + replyCode +
+                        "锛屽搷搴斾俊鎭細" + replyMsg);
+
+                // 鐗规畩澶勭悊550閿欒锛堟潈闄�/SELinux闂锛�
+                if (replyCode == 550) {
+                    logger.error("鍙兘鍘熷洜锛氭潈闄愪笉瓒�/SELinux闄愬埗/璺緞涓嶅瓨鍦�");
+                }
+            } else {
+                logger.info("鍒涘缓鏂囦欢澶规垚鍔燂細" + remoteFolder);
+            }
+            return success;
+        } catch (IOException e) {
+            logger.error("鍒涘缓鏂囦欢澶瑰紓甯革細" + e.getMessage(), e);
+            return false;
+        } finally {
+            disconnectQuietly(ftpClient);
+        }
+    }
+
+    // ====================== 宸ュ叿鏂规硶锛氬瓧鑺傛祦杞崲锛堜繚鎸佸吋瀹癸級 ======================
+    public InputStream byte2Input(byte[] buf) {
+        return new ByteArrayInputStream(Objects.requireNonNull(buf));
+    }
+
+    public byte[] input2byte(InputStream inStream) throws IOException {
+        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
+            byte[] buffer = new byte[4096];
+            int len;
+            while ((len = inStream.read(buffer)) != -1) {
+                bos.write(buffer, 0, len);
+            }
+            return bos.toByteArray();
+        }
+    }
+
+    public void byte2File(byte[] buf, String filePath, String fileName) {
+        File dir = new File(filePath);
+        if (!dir.exists() && !dir.mkdirs()) {
+            logger.error("鍒涘缓鏈湴鐩綍澶辫触锛�" + filePath);
+            return;
+        }
+        try (BufferedOutputStream bos = new BufferedOutputStream(
+                new FileOutputStream(new File(dir, fileName)))) {
+            bos.write(buf);
+        } catch (IOException e) {
+            logger.error("瀛楄妭鏁扮粍鍐欏叆鏂囦欢澶辫触锛�" + fileName, e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleJob.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleJob.java
index 40910c2..b51176e 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleJob.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleJob.java
@@ -16,7 +16,7 @@
 
 /**
  * 绀轰緥涓嶅甫鍙傚畾鏃朵换鍔�
- * 
+ *
  * @Author Scott
  */
 @Slf4j
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleParamJob.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleParamJob.java
index 1e81b96..da5fdd5 100644
--- a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleParamJob.java
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/quartz/job/SampleParamJob.java
@@ -82,8 +82,12 @@
                 AtomicReference<String> end = new AtomicReference<>("");
                 AtomicReference<Date> endDate = new AtomicReference<>(null); // 閲囬泦鏃堕棿
                 serverDeployList.forEach(s -> {
-                    if (s.getId().equals(in.getServerDeployId()) && s.getCollectTime() != null) {
-                        start.set(sdf.format(s.getCollectTime()));
+                    if (s.getId().equals(in.getServerDeployId())) {
+                        if (s.getCollectTime() != null) {
+                            start.set(sdf.format(s.getCollectTime()));
+                        } else {
+                            start.set(sdf.format(new Date()));
+                        }
                         // 鑾峰彇褰撳墠鏃堕棿
                         LocalDateTime now = LocalDateTime.now();
                         // 鍑忓幓涓�鍒嗛挓
@@ -98,7 +102,7 @@
                         end.set(formattedTime);
                     }
                 });
-                if (start.get().equals("")){
+                if (start.get().equals("")) {
                     return;
                 }
                 LocalDateTime startTime = LocalDateTime.parse(start.get(), inputFormatter);
@@ -158,7 +162,13 @@
                         // 澶勭悊璁惧鐘舵��
                         int lastIndex = table.lastIndexOf('.');
                         String code = table.substring(lastIndex + 1);
-                        EquipmentLog equipmentLog = equipmentLogService.selectEquipmentOporation(code);
+                        EquipmentLog equipmentLog = null;
+                        if (databaseType.equals("SqlServer")) {
+                            equipmentLog = equipmentLogService.selectEquipmentOporationSqlServer(code);
+                        } else if (databaseType.equals("MySql")) {
+                            equipmentLog  = equipmentLogService.selectEquipmentOporationMySql(code);
+
+                        }
                         // 璁惧鐘舵��
                         Integer equipmentState = null;
                         for (Map.Entry<String, List<Influxdb>> entry : timeListMap.entrySet()) {
diff --git a/lxzn-module-system/lxzn-system-start/src/main/resources/application-prod.yml b/lxzn-module-system/lxzn-system-start/src/main/resources/application-prod.yml
index fb36ed1..cba014e 100644
--- a/lxzn-module-system/lxzn-system-start/src/main/resources/application-prod.yml
+++ b/lxzn-module-system/lxzn-system-start/src/main/resources/application-prod.yml
@@ -53,12 +53,6 @@
             instanceId: AUTO
           jobStore:
             selectWithLockSQL: SELECT* FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?
-            # class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
-            # driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-            # tablePrefix: QRTZ_
-            # isClustered: true
-            # misfireThreshold: 12000
-            # clusterCheckinInterval: 15000
           threadPool:
             class: org.quartz.simpl.SimpleThreadPool
             threadCount: 10
@@ -112,7 +106,7 @@
         # 鍒濆鍖栧ぇ灏忥紝鏈�灏忥紝鏈�澶�
         initial-size: 5
         min-idle: 5
-        maxActive: 1000
+        maxActive: 20
         # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂�
         maxWait: 60000
         # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶆槸姣
@@ -132,13 +126,13 @@
         connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
       datasource:
         master:
-          url: jdbc:sqlserver://192.168.1.123:1433;databasename=lx_iot_mdc
-          username: sa
-          password: 123
-          driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
+          url: jdbc:mysql://127.0.0.1:3306/lx_iot_mdc?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+          username: root
+          password: root
+          driver-class-name: com.mysql.cj.jdbc.Driver
   #redis 閰嶇疆
   redis:
-    database: 5
+    database: 0
     host: 127.0.0.1
     port: 6379
     password: ''
@@ -155,7 +149,7 @@
       table-underline: true
   configuration:
     # 杩欎釜閰嶇疆浼氬皢鎵ц鐨剆ql鎵撳嵃鍑烘潵锛屽湪寮�鍙戞垨娴嬭瘯鐨勬椂鍊欏彲浠ョ敤
-    #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
     # 杩斿洖绫诲瀷涓篗ap,鏄剧ずnull瀵瑰簲鐨勫瓧娈�
     call-setters-on-nulls: true
 #jeecg涓撶敤閰嶇疆
@@ -167,7 +161,8 @@
   # 绛惧悕瀵嗛挜涓�(鍓嶅悗绔涓�鑷达紝姝e紡鍙戝竷璇疯嚜琛屼慨鏀�)
   signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
   # 绛惧悕鎷︽埅鎺ュ彛
-  signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys
+  #  signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys
+  signUrls: /sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys
   #local銆乵inio銆乤lioss
   uploadType: local
   # 鍓嶇璁块棶鍦板潃
@@ -180,21 +175,20 @@
     #webapp鏂囦欢璺緞
     webapp: C://opt//upFiles
   shiro:
-    excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/api/getUserInfo
+    excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**
   #闃块噷浜憃ss瀛樺偍鍜屽ぇ楸肩煭淇$閽ラ厤缃�
   oss:
     accessKey: ??
     secretKey: ??
     endpoint: oss-cn-beijing.aliyuncs.com
     bucketName: jeecgdev
-    staticDomain: https://static.jeecg.com
-  # ElasticSearch 璁剧疆
+  # ElasticSearch 6璁剧疆
   elasticsearch:
     cluster-name: jeecg-ES
     cluster-nodes: 127.0.0.1:9200
     check-enabled: false
   # 鍦ㄧ嚎棰勮鏂囦欢鏈嶅姟鍣ㄥ湴鍧�閰嶇疆
-  file-view-domain: http://fileview.jeecg.com
+  file-view-domain: 127.0.0.1:8012
   # minio鏂囦欢涓婁紶
   minio:
     minio_url: http://minio.jeecg.com
@@ -203,7 +197,7 @@
     bucketName: otatest
   #澶у睆鎶ヨ〃鍙傛暟璁剧疆
   jmreport:
-    mode: prod
+    mode: dev
     #鏁版嵁瀛楀吀鏄惁杩涜saas鏁版嵁闅旂锛岃嚜宸辩湅鑷繁鐨勫瓧鍏�
     saas: false
     #鏄惁闇�瑕佹牎楠宼oken
@@ -241,7 +235,7 @@
   #寮�鍚敓浜х幆澧冨睆钄�
   production: false
   basic:
-    enable: true
+    enable: false
     username: jeecg
     password: jeecg1314
 #绗笁鏂圭櫥褰�
@@ -292,29 +286,36 @@
       # appSecret
       client-secret: ??
       agent-id: ??
+webservice:
+  url: http://localhost:8081/services/EquipmentService?wsdl
+  namespace: http://service.server.webservice.example.com
+  statusMethod: equipmentStatus
+  rateMethod: equipmentRate
 mqtt:
-  host: tcp://192.168.1.123:1883
-  clientId: mqtt_manage_platform
+  host: tcp://127.0.0.1:1883
+  clientId: mqtt_manage_platform_dev
   username: admin
-  password: public
+  password: lxzn1688
   timeout: 30000
   keepalive: 300
-  clientUrl: http://192.168.1.123:18083/api/v5/clients
+  clientUrl: http://127.0.0.1:18083/api/v5/clients
   #API鎺堟潈KEY
-  apiKey: fb5d13d541c4ebd9
+  apiKey: 45204bbc6befd831
   #API鎺堟潈瀵嗛挜
-  secretKey: J9A4pFcUyYzyo6uhFh6AKcVBi7xHcUgcNoNMCWylrCHE
+  secretKey: bs7mFjE6qhr39AhC4VWjByUphVxm9Af9CWlvuGJO3coxdM
 #椹卞姩鏂囦欢鍦板潃
-drive: D:\\iot\\configuration\\DriveConfig.xml
-script: D:\\iot\\configuration\\FunctionConfig.xml
+drive: /iot/configuration/DriveConfig.xml
+script: /iot/configuration/FunctionConfig.xml
 #ftp杩炴帴鍦板潃
 ftp:
   LOCAL_CHARSET: GBK
   SERVER_CHARSET: ISO-8859-1
-  ftpHost: 192.168.1.123
+  ftpHost: 10.0.221.200
   ftpPort: 21
   ftpUserName: admin
   ftpPassword: lx@2024
-  address: D:/iot/
+  address: /iot/
 #鏁版嵁搴� MySql | SqlServer
-databaseType: SqlServer
\ No newline at end of file
+databaseType: MySql
+#鎿嶄綔绯荤粺 kylin | windows
+operatingSystem: kylin
\ No newline at end of file

--
Gitblit v1.9.3