From ab389a5a6b329b15a655340ba7b87bce7fd7871d Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期三, 24 十二月 2025 17:16:19 +0800
Subject: [PATCH] 添加新增设备自动生成编码

---
 mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/DeviceConfigServiceImpl.java |   53 ++++++++++++++++-
 mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/DeviceConfigController.java    |    6 +
 mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java            |   62 ++++++++++++++++++++
 mes-web/src/views/device/DeviceEditDialog.vue                                                    |   45 ++++++++++++---
 mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java    |    2 
 mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceConfigMapper.java            |    6 ++
 6 files changed, 157 insertions(+), 17 deletions(-)

diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/DeviceConfigController.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/DeviceConfigController.java
index c1f5da1..ecf6b1e 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/DeviceConfigController.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/controller/DeviceConfigController.java
@@ -50,9 +50,11 @@
                 // 鍒涘缓鎴愬姛鍚庯紝閲嶆柊鑾峰彇璁惧瀵硅薄
                 DeviceConfig created = deviceConfigService.getDeviceByCode(deviceConfig.getDeviceCode());
                 return Result.success(created);
-            } else {
-                return Result.error("璁惧閰嶇疆宸插瓨鍦�");
             }
+            return Result.error("璁惧閰嶇疆宸插瓨鍦�");
+        } catch (IllegalArgumentException e) {
+            log.warn("鍒涘缓璁惧閰嶇疆鍙傛暟鏍¢獙澶辫触: {}", e.getMessage());
+            return Result.error(e.getMessage());
         } catch (Exception e) {
             log.error("鍒涘缓璁惧閰嶇疆澶辫触", e);
             return Result.error("鍒涘缓璁惧閰嶇疆澶辫触");
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceConfigMapper.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceConfigMapper.java
index dddf712..accea99 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceConfigMapper.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/mapper/DeviceConfigMapper.java
@@ -13,6 +13,12 @@
 public interface DeviceConfigMapper extends BaseMapper<DeviceConfig> {
 
     /**
+     * 鑾峰彇璁惧缂栫爜鏈�澶у簭鍙凤紙DEV_xxxxxx 涓殑鏁板瓧閮ㄥ垎锛�
+     */
+    @Select("SELECT IFNULL(MAX(CAST(SUBSTRING(device_code, 5) AS UNSIGNED)), 0) FROM device_config WHERE device_code LIKE 'DEV_%'")
+    Long selectMaxDeviceCodeNumber();
+
+    /**
      * 鏍规嵁椤圭洰ID鍜岃澶囩被鍨嬫煡璇㈣澶囬厤缃垪琛�
      * @param projectId 椤圭洰ID
      * @param deviceType 璁惧绫诲瀷
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/DeviceConfigServiceImpl.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/DeviceConfigServiceImpl.java
index 6f5b2b3..c48c702 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/DeviceConfigServiceImpl.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/DeviceConfigServiceImpl.java
@@ -11,6 +11,7 @@
 import com.mes.device.vo.DeviceConfigVO;
 import com.mes.device.vo.StatisticsVO;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
@@ -32,10 +33,27 @@
     @Override
     public boolean createDevice(DeviceConfig deviceConfig) {
         try {
+            // 鑻ユ湭浼犲垯鐢熸垚璁惧缂栫爜
+            String code = StringUtils.trimToEmpty(deviceConfig.getDeviceCode());
+            if (StringUtils.isBlank(code)) {
+                code = generateDeviceCode();
+                deviceConfig.setDeviceCode(code);
+            } else {
+                deviceConfig.setDeviceCode(code);
+            }
+
             // 妫�鏌ヨ澶囩紪鍙锋槸鍚﹀凡瀛樺湪
-            if (isDeviceCodeExists(deviceConfig.getDeviceCode(), null)) {
-                log.warn("璁惧缂栧彿宸插瓨鍦�: {}", deviceConfig.getDeviceCode());
-                return false;
+            if (isDeviceCodeExists(code, null)) {
+                log.warn("璁惧缂栧彿宸插瓨鍦�: {}", code);
+                throw new IllegalArgumentException("璁惧缂栫爜宸插瓨鍦�");
+            }
+
+            // 鍏煎鏃у瓧娈碉細缁熶竴灏� device_id 濉负 deviceCode锛岄伩鍏嶉潪绌�/鍞竴绾︽潫闂
+            deviceConfig.setDeviceId(code);
+
+            // 椤圭洰ID鏈紶鍒欎娇鐢ㄩ粯璁ら」鐩紙鍗曢」鐩満鏅彲鐢級锛岄伩鍏嶉潪绌虹害鏉�
+            if (deviceConfig.getProjectId() == null) {
+                deviceConfig.setProjectId(1L);
             }
             
             // 鍒濆鍖栬澶囩姸鎬佷负绂荤嚎
@@ -50,7 +68,7 @@
             return result;
         } catch (Exception e) {
             log.error("鍒涘缓璁惧閰嶇疆澶辫触", e);
-            return false;
+            throw e;
         }
     }
 
@@ -61,6 +79,16 @@
             if (isDeviceCodeExists(deviceConfig.getDeviceCode(), deviceConfig.getId())) {
                 log.warn("璁惧缂栧彿宸插瓨鍦�: {}", deviceConfig.getDeviceCode());
                 return false;
+            }
+
+            // 鍚屾 device_id 涓� deviceCode锛屼繚鎸佷竴鑷�
+            if (StringUtils.isNotBlank(deviceConfig.getDeviceCode())) {
+                deviceConfig.setDeviceId(deviceConfig.getDeviceCode().trim());
+            }
+
+            // 鑻ラ」鐩甀D缂哄け锛屼娇鐢ㄩ粯璁ら」鐩�
+            if (deviceConfig.getProjectId() == null) {
+                deviceConfig.setProjectId(1L);
             }
             
             boolean result = updateById(deviceConfig);
@@ -341,8 +369,13 @@
 
     @Override
     public boolean isDeviceCodeExists(String deviceCode, Long excludeId) {
+        if (StringUtils.isBlank(deviceCode)) {
+            return false;
+        }
+        String trimmed = deviceCode.trim();
+
         LambdaQueryWrapper<DeviceConfig> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(DeviceConfig::getDeviceCode, deviceCode);
+        wrapper.eq(DeviceConfig::getDeviceCode, trimmed);
         wrapper.eq(DeviceConfig::getIsDeleted, 0);
         
         if (excludeId != null) {
@@ -352,6 +385,16 @@
         return count(wrapper) > 0;
     }
 
+    /**
+     * 绠�鍗曠殑璁惧缂栫爜鐢熸垚鍣細DEV_鍓嶇紑 
+     */
+    private String generateDeviceCode() {
+        Long maxNo = getBaseMapper().selectMaxDeviceCodeNumber();
+        long next = (maxNo == null ? 0 : maxNo) + 1;
+        // 宸︿晶琛ラ浂鍒�6浣嶏紝渚嬪 DEV_000123
+        return String.format("DEV_%06d", next);
+    }
+
     @Override
     public boolean updateDeviceStatus(Long id, String status) {
         try {
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
index f07e714..d46acfb 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/device/service/impl/GlassInfoServiceImpl.java
@@ -641,7 +641,7 @@
             // 涓庡鍏ヨ鍒欎繚鎸佷竴鑷达細glassId 鍓嶅姞宸ョ▼鍙峰墠缂�锛屾暟閲�>1鏃惰拷鍔犲簭鍙�
             String baseGlassId = engineeringId.trim() + glassId;
             for (int idx = 0; idx < qty; idx++) {
-                String finalGlassId = qty > 1 ? baseGlassId + "_" + (idx + 1) : baseGlassId;
+                String finalGlassId = qty > 1 ? baseGlassId + (idx + 1) : baseGlassId;
 
                 GlassInfo glassInfo = new GlassInfo();
                 glassInfo.setGlassId(finalGlassId);
diff --git a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
index 352dfde..db6fc48 100644
--- a/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
+++ b/mes-processes/mes-plcSend/src/main/java/com/mes/task/service/TaskExecutionEngine.java
@@ -32,6 +32,8 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 
+import javax.annotation.PreDestroy;
+
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -3154,5 +3156,65 @@
             return summary;
         }
     }
+
+    /**
+     * 搴旂敤鍏抽棴鏃舵竻鐞嗚祫婧�
+     */
+    @PreDestroy
+    public void destroy() {
+        log.info("寮�濮嬫竻鐞員askExecutionEngine璧勬簮...");
+        
+        // 鍋滄鎵�鏈夊畾鏃朵换鍔�
+        for (Map.Entry<String, List<ScheduledFuture<?>>> entry : taskScheduledTasks.entrySet()) {
+            String taskId = entry.getKey();
+            List<ScheduledFuture<?>> futures = entry.getValue();
+            if (futures != null) {
+                for (ScheduledFuture<?> future : futures) {
+                    if (future != null && !future.isDone()) {
+                        future.cancel(true);
+                    }
+                }
+            }
+            log.debug("宸插仠姝换鍔� {} 鐨勬墍鏈夊畾鏃跺櫒", taskId);
+        }
+        taskScheduledTasks.clear();
+        
+        // 鍏抽棴瀹氭椂鍣ㄧ嚎绋嬫睜
+        shutdownExecutor(scheduledExecutor, "瀹氭椂鍣ㄧ嚎绋嬫睜");
+        
+        // 鍏抽棴骞惰鎵ц绾跨▼姹�
+        shutdownExecutor(executorService, "骞惰鎵ц绾跨▼姹�");
+        
+        // 娓呯┖杩愯涓婁笅鏂�
+        runningTaskContexts.clear();
+        
+        log.info("TaskExecutionEngine璧勬簮娓呯悊瀹屾垚");
+    }
+    
+    /**
+     * 鍏抽棴绾跨▼姹�
+     */
+    private void shutdownExecutor(ExecutorService executor, String name) {
+        if (executor == null || executor.isShutdown()) {
+            return;
+        }
+        
+        executor.shutdown();
+        try {
+            if (!executor.awaitTermination(10, TimeUnit.SECONDS)) {
+                log.warn("{} 鍦�10绉掑唴鏈兘姝e父鍏抽棴锛屽己鍒跺叧闂�", name);
+                executor.shutdownNow();
+                if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
+                    log.error("{} 寮哄埗鍏抽棴澶辫触", name);
+                }
+            } else {
+                log.info("{} 宸叉甯稿叧闂�", name);
+            }
+        } catch (InterruptedException e) {
+            log.warn("{} 鍏抽棴杩囩▼涓涓柇", name, e);
+            executor.shutdownNow();
+            Thread.currentThread().interrupt();
+        }
+    }
 }
 
diff --git a/mes-web/src/views/device/DeviceEditDialog.vue b/mes-web/src/views/device/DeviceEditDialog.vue
index ad6668c..63123c5 100644
--- a/mes-web/src/views/device/DeviceEditDialog.vue
+++ b/mes-web/src/views/device/DeviceEditDialog.vue
@@ -31,12 +31,16 @@
             </el-form-item>
 
             <el-form-item label="璁惧缂栫爜" prop="deviceCode">
-              <el-input
-                v-model="deviceForm.deviceCode"
-                placeholder="璇疯緭鍏ヨ澶囩紪鐮�"
-                maxlength="50"
-                :disabled="isEdit"
-              />
+              <template v-if="isEdit">
+                <el-input
+                  v-model="deviceForm.deviceCode"
+                  maxlength="50"
+                  disabled
+                />
+              </template>
+              <template v-else>
+                <el-tag type="info">淇濆瓨鍚庤嚜鍔ㄧ敓鎴�</el-tag>
+              </template>
             </el-form-item>
 
             <el-form-item label="璁惧绫诲瀷" prop="deviceType">
@@ -373,7 +377,8 @@
   description: '',
   isPrimary: false,
   enabled: true,
-  extraParams: null
+  extraParams: null,
+  projectId: 1
 })
 
 const deviceForm = reactive(getDefaultForm())
@@ -382,14 +387,35 @@
 const isEdit = computed(() => !!props.deviceData)
 
 // 琛ㄥ崟楠岃瘉瑙勫垯
+const validateDeviceCode = async (rule, value, callback) => {
+  if (!value) {
+    // 鍏佽鐣欑┖锛屽悗鍙拌嚜鍔ㄧ敓鎴�
+    return callback()
+  }
+  try {
+    const res = await deviceConfigApi.checkCode(
+      value.trim(),
+      isEdit.value ? props.deviceData?.id : null
+    )
+    if (res?.data === true) {
+      callback(new Error('璁惧缂栫爜宸插瓨鍦紝璇锋洿鎹�'))
+    } else {
+      callback()
+    }
+  } catch (err) {
+    console.error('妫�鏌ヨ澶囩紪鐮佸け璐�', err)
+    callback(new Error('璁惧缂栫爜鏍¢獙澶辫触锛岃绋嶅悗閲嶈瘯'))
+  }
+}
+
 const deviceRules = {
   deviceName: [
     { required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' },
     { min: 1, max: 50, message: '璁惧鍚嶇О闀垮害鍦� 1 鍒� 50 涓瓧绗�', trigger: 'blur' }
   ],
   deviceCode: [
-    { required: true, message: '璇疯緭鍏ヨ澶囩紪鐮�', trigger: 'blur' },
-    { pattern: /^[A-Z0-9_]+$/, message: '璁惧缂栫爜鍙兘鍖呭惈澶у啓瀛楁瘝銆佹暟瀛楀拰涓嬪垝绾�', trigger: 'blur' }
+    { pattern: /^[A-Z0-9_]+$/, message: '璁惧缂栫爜鍙兘鍖呭惈澶у啓瀛楁瘝銆佹暟瀛楀拰涓嬪垝绾�', trigger: 'blur' },
+    { validator: validateDeviceCode, trigger: 'blur' }
   ],
   deviceType: [
     { required: true, message: '璇烽�夋嫨璁惧绫诲瀷', trigger: 'change' }
@@ -771,6 +797,7 @@
       isPrimary: deviceForm.isPrimary,
       enabled: deviceForm.enabled,
       description: deviceForm.description,
+      projectId: deviceForm.projectId,
       configJson: configJsonValue,  // 淇濆瓨閰嶇疆鍙傛暟JSON
       extraParams: JSON.stringify(extraObj)
     }

--
Gitblit v1.8.0