From 4bcba729142ded6cd008f324e6a3bae364b6233b Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期六, 23 五月 2026 17:18:50 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_pro_河南鹤壁' into dev_pro_河南鹤壁

---
 src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskScheduler.java   |   50 +++++++++--
 src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskServiceImpl.java |   44 +++++++++-
 src/main/java/com/ruoyi/device/pojo/MaintenanceTask.java                    |    4 
 src/main/resources/mapper/quality/QualityInspectMapper.xml                  |  142 +++++++++++++----------------------
 4 files changed, 131 insertions(+), 109 deletions(-)

diff --git a/src/main/java/com/ruoyi/device/pojo/MaintenanceTask.java b/src/main/java/com/ruoyi/device/pojo/MaintenanceTask.java
index 350a09d..3fedf2c 100644
--- a/src/main/java/com/ruoyi/device/pojo/MaintenanceTask.java
+++ b/src/main/java/com/ruoyi/device/pojo/MaintenanceTask.java
@@ -62,8 +62,8 @@
     @Schema(description = "鏈�鍚庢墽琛屾椂闂�")
     private LocalDateTime lastExecutionTime;
 
-    @Schema(description = "鏄惁婵�娲�")
-    private boolean isActive;
+    @Schema(description = "鏄惁婵�娲�, 1=鍚敤, 0=鍋滅敤")
+    private Integer isActive;
 
     @Schema(description = "澶囨敞")
     @Excel(name = "澶囨敞")
diff --git a/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskScheduler.java b/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskScheduler.java
index ec7a8e3..3913b8b 100644
--- a/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskScheduler.java
+++ b/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskScheduler.java
@@ -25,13 +25,25 @@
     private final Scheduler scheduler;
 
     /**
-     * 娣诲姞鏂颁换鍔″埌璋冨害鍣�
+     * 娣诲姞鎴栨洿鏂颁换鍔″埌璋冨害鍣�
      */
     public void scheduleMaintenanceTask(MaintenanceTask task){
         try {
             JobDetail jobDetail = buildJobDetail(task);
             Trigger trigger = buildJobTrigger(task, jobDetail);
-            scheduler.scheduleJob(jobDetail, trigger);
+
+            // 妫�鏌ヨЕ鍙戝櫒鏄惁宸插瓨鍦�
+            TriggerKey triggerKey = trigger.getKey();
+            Trigger existingTrigger = scheduler.getTrigger(triggerKey);
+
+            if (existingTrigger != null) {
+                // 瑙﹀彂鍣ㄥ凡瀛樺湪锛屾洿鏂板畠
+                scheduler.rescheduleJob(triggerKey, trigger);
+            } else {
+                // 瑙﹀彂鍣ㄤ笉瀛樺湪锛屽厛纭繚 Job 瀛樺湪锛岀劧鍚庤皟搴﹁Е鍙戝櫒
+                scheduler.addJob(jobDetail, true);
+                scheduler.scheduleJob(trigger);
+            }
         }catch (SchedulerException e){
             log.error("SchedulerException scheduleMaintenanceTask ERROR",e);
             throw new RuntimeException(e);
@@ -45,26 +57,41 @@
        try{
            TriggerKey triggerKey = new TriggerKey("triggerMaintenanceTask_" + task.getId());
 
-           // 鑾峰彇鐜版湁瑙﹀彂鍣ㄥ苟杞崲涓� CronTrigger
+           // 鑾峰彇鐜版湁瑙﹀彂鍣�
            Trigger oldTrigger = scheduler.getTrigger(triggerKey);
+
+           // 鏋勫缓鏂扮殑 JobDetail 鍜� Trigger
+           JobDetail jobDetail = buildJobDetail(task);
+           Trigger newTrigger = buildJobTrigger(task, jobDetail);
+
+           if (oldTrigger == null) {
+               // 瑙﹀彂鍣ㄤ笉瀛樺湪锛岃鏄庝换鍔′箣鍓嶈鍒犻櫎杩�
+               // 鍏堢‘淇� Job 瀛樺湪锛岀劧鍚庤皟搴﹁Е鍙戝櫒
+               scheduler.addJob(jobDetail, true);
+               scheduler.scheduleJob(newTrigger);
+               return;
+           }
+
+           // 瑙﹀彂鍣ㄥ瓨鍦紝鐩存帴鏇存柊
            if (!(oldTrigger instanceof CronTrigger)) {
                throw new SchedulerException("Existing trigger is not a CronTrigger");
            }
 
-           // 3. 鏋勫缓CronTrigger锛岀‘淇濇寔涔呭寲閰嶇疆
-           CronTrigger newTrigger = TriggerBuilder.newTrigger()
-                   .withIdentity(triggerKey)                // 鍞竴鏍囪瘑锛岀敤浜庢寔涔呭寲瀛樺偍
-                   .withDescription(task.getTaskName() + "_TRIGGER") // 瑙﹀彂鍣ㄦ弿杩�
-                   .forJob(oldTrigger.getJobKey())                       // 鍏宠仈瀵瑰簲鐨凧ob
+           // 鏋勫缓鏂扮殑 CronTrigger
+           CronTrigger cronTrigger = TriggerBuilder.newTrigger()
+                   .withIdentity(triggerKey)
+                   .withDescription(task.getTaskName() + "_TRIGGER")
+                   .forJob(oldTrigger.getJobKey())
                    .withSchedule(CronScheduleBuilder
-                           .cronSchedule(convertToCronExpression(task)) // 閿欒繃鎵ц鏃剁殑绛栫暐锛堟牴鎹笟鍔¤皟鏁达級
+                           .cronSchedule(convertToCronExpression(task))
+                           .withMisfireHandlingInstructionDoNothing()
                    )
-                   // 4. 璁剧疆寮�濮嬫椂闂达紙鑻ヤ负null鍒欑珛鍗崇敓鏁堬級
                    .startAt(task.getNextExecutionTime() != null
                            ? Date.from(task.getNextExecutionTime().atZone(ZoneId.systemDefault()).toInstant())
                            : new Date())
                    .build();
-           scheduler.rescheduleJob(triggerKey, newTrigger);
+
+           scheduler.rescheduleJob(triggerKey, cronTrigger);
        }catch (SchedulerException e){
            log.error("SchedulerException rescheduleMaintenanceTask ERROR",e);
            throw new RuntimeException(e);
@@ -93,6 +120,7 @@
     public void unscheduleMaintenanceTask(Long taskId){
         try {
             JobKey jobKey = new JobKey("MaintenanceTask_" + taskId);
+            // 鍒犻櫎 Job 浼氳嚜鍔ㄥ垹闄ゅ叧鑱旂殑 Trigger
             scheduler.deleteJob(jobKey);
         }catch (SchedulerException e){
             log.error("SchedulerException unscheduleMaintenanceTask ERROR",e);
diff --git a/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskServiceImpl.java b/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskServiceImpl.java
index 3aaac94..c666f3f 100644
--- a/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskServiceImpl.java
+++ b/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskServiceImpl.java
@@ -67,7 +67,6 @@
 
     @Override
     public AjaxResult add(MaintenanceTask maintenanceTask) {
-        maintenanceTask.setActive(true);
         // 璁$畻棣栨鎵ц鏃堕棿
         TimingTask task = new TimingTask();
         task.setFrequencyType(maintenanceTask.getFrequencyType());
@@ -76,7 +75,10 @@
         maintenanceTask.setNextExecutionTime(firstExecutionTime);
         int insert = maintenanceTaskMapper.insert(maintenanceTask);
         if (insert > 0) {
-            maintenanceTaskScheduler.scheduleMaintenanceTask(maintenanceTask);
+            // 鍙湁褰� isActive 涓� 1 鏃舵墠娣诲姞鍒板畾鏃朵换鍔¤皟搴﹀櫒
+            if (maintenanceTask.getIsActive() != null && maintenanceTask.getIsActive() == 1) {
+                maintenanceTaskScheduler.scheduleMaintenanceTask(maintenanceTask);
+            }
         }
         return AjaxResult.success("娣诲姞鎴愬姛");
     }
@@ -87,22 +89,50 @@
         if (maintenanceTask1 == null) {
             return AjaxResult.warn("娌℃湁姝ゆ暟鎹�");
         }
+
+        // 淇濆瓨鏃х殑 isActive 鐘舵��
+        Integer oldIsActive = maintenanceTask1.getIsActive();
+        Integer newIsActive = maintenanceTask.getIsActive();
+
         BeanUtils.copyProperties(maintenanceTask, maintenanceTask1);
         int update = maintenanceTaskMapper.updateById(maintenanceTask1);
         if (update > 0) {
-            maintenanceTaskScheduler.rescheduleMaintenanceTask(maintenanceTask1);
+            // 澶勭悊 isActive 鐘舵�佸彉鍖�
+            if (newIsActive != null && newIsActive == 1) {
+                // 鏂扮姸鎬佷负鍚敤锛氭坊鍔犲埌瀹氭椂浠诲姟璋冨害鍣�
+                if (oldIsActive == null || oldIsActive != 1) {
+                    // 浠庢湭鍚敤鍙樹负鍚敤锛屾坊鍔犲埌璋冨害鍣�
+                    maintenanceTaskScheduler.scheduleMaintenanceTask(maintenanceTask1);
+                } else {
+                    // 宸茬粡鍚敤锛屾洿鏂拌皟搴﹀櫒涓殑浠诲姟
+                    maintenanceTaskScheduler.rescheduleMaintenanceTask(maintenanceTask1);
+                }
+            } else {
+                // 鏂扮姸鎬佷负鍋滅敤锛氫粠瀹氭椂浠诲姟璋冨害鍣ㄤ腑绉婚櫎
+                if (oldIsActive != null && oldIsActive == 1) {
+                    maintenanceTaskScheduler.unscheduleMaintenanceTask(maintenanceTask1.getId());
+                }
+            }
         }
         return AjaxResult.success("鏇存柊鎴愬姛");
     }
 
     @Override
     public AjaxResult delete(List<Long> ids) {
+        // 鍏堜粠瀹氭椂浠诲姟璋冨害鍣ㄤ腑绉婚櫎鎵�鏈夊緟鍒犻櫎鐨勪换鍔�
+        ids.forEach(id -> {
+            try {
+                maintenanceTaskScheduler.unscheduleMaintenanceTask(id);
+            } catch (Exception e) {
+                log.error("鍒犻櫎瀹氭椂浠诲姟璋冨害澶辫触, id: {}", id, e);
+            }
+        });
+
+        // 鍐嶄粠鏁版嵁搴撲腑鍒犻櫎璁板綍
         int delete = maintenanceTaskMapper.deleteBatchIds(ids);
         if (delete > 0) {
-            ids.forEach(id -> {
-                maintenanceTaskScheduler.unscheduleMaintenanceTask(id);
-            });
+            return AjaxResult.success("鍒犻櫎鎴愬姛");
         }
-        return AjaxResult.success("鍒犻櫎鎴愬姛");
+        return AjaxResult.error("鍒犻櫎澶辫触");
     }
 }
diff --git a/src/main/resources/mapper/quality/QualityInspectMapper.xml b/src/main/resources/mapper/quality/QualityInspectMapper.xml
index e4c3dd0..897138e 100644
--- a/src/main/resources/mapper/quality/QualityInspectMapper.xml
+++ b/src/main/resources/mapper/quality/QualityInspectMapper.xml
@@ -94,11 +94,7 @@
     </delete>
 
     <select id="getInspectStatistics" resultType="com.ruoyi.quality.dto.QualityInspectStatDto">
-        SELECT CASE pp.product_name
-                   WHEN '鍘熸潗鏂�' THEN 0
-                   WHEN '鍗婃垚鍝�' THEN 1
-                   WHEN '鎴愬搧' THEN 2
-                   END                     AS modelType,
+        SELECT qi.inspect_type AS modelType,
 
                IFNULL(SUM(qi.quantity), 0) AS totalCount,
 
@@ -107,22 +103,14 @@
                               ELSE 0
                    END), 0)                AS completedCount
 
-        FROM product p
-                 INNER JOIN product pp
-                            ON p.parent_id = pp.id
-                 LEFT JOIN product_model pm
-                           ON pm.product_id = p.id
-                 LEFT JOIN quality_inspect qi
-                           ON qi.product_model_id = pm.id
+        FROM quality_inspect qi
 
-        WHERE pp.product_name IN ('鍘熸潗鏂�', '鍗婃垚鍝�', '鎴愬搧')
-
-        GROUP BY pp.product_name
+        GROUP BY qi.inspect_type
 
     </select>
 
     <select id="getPassRateStatistics" resultType="com.ruoyi.quality.dto.QualityPassRateDto">
-        SELECT t.modelType,
+        SELECT qi.inspect_type AS modelType,
 
                COALESCE(SUM(qi.quantity), 0) AS totalCount,
 
@@ -185,27 +173,10 @@
                                    ), 0) * 100, 2)
                )                             AS passRate
 
-        FROM (SELECT 0 AS modelType
-              UNION ALL
-              SELECT 1
-              UNION ALL
-              SELECT 2) t
-                 LEFT JOIN product p
-                           ON 1 = 1
-                 LEFT JOIN product pp
-                           ON p.parent_id = pp.id
-                 LEFT JOIN product_model pm
-                           ON pm.product_id = p.id
-                 LEFT JOIN quality_inspect qi
-                           ON qi.product_model_id = pm.id
-                               AND (
-                                  (pp.product_name = '鍘熸潗鏂�' AND t.modelType = 0) OR
-                                  (pp.product_name = '鍗婃垚鍝�' AND t.modelType = 1) OR
-                                  (pp.product_name = '鎴愬搧' AND t.modelType = 2)
-                                  )
+        FROM quality_inspect qi
 
-        GROUP BY t.modelType
-        ORDER BY t.modelType;
+        GROUP BY qi.inspect_type
+        ORDER BY qi.inspect_type;
     </select>
 
 
@@ -297,18 +268,10 @@
                )                             AS passRate
 
         FROM base b
-                 LEFT JOIN product p ON 1 = 1
-                 LEFT JOIN product pp ON p.parent_id = pp.id
-                 LEFT JOIN product_model pm ON pm.product_id = p.id
                  LEFT JOIN quality_inspect qi
-                           ON qi.product_model_id = pm.id
+                           ON qi.inspect_type = b.modelType
                                AND YEAR(qi.check_time) = #{year}
                                AND MONTH(qi.check_time) = b.month_num
-                               AND (
-                                  (pp.product_name = '鍘熸潗鏂�' AND b.modelType = 0)
-                                      OR (pp.product_name = '鍗婃垚鍝�' AND b.modelType = 1)
-                                      OR (pp.product_name = '鎴愬搧' AND b.modelType = 2)
-                                  )
 
         GROUP BY b.month_num, b.modelType
         ORDER BY b.month_num, b.modelType;
@@ -316,45 +279,58 @@
     </select>
 
     <select id="getYearlyPassRateStatistics" resultType="com.ruoyi.quality.dto.QualityPassRateDto">
-        SELECT t.modelType,
+        SELECT qi.inspect_type AS modelType,
+
+               COALESCE(SUM(qi.quantity), 0) AS totalCount,
+
                COALESCE(SUM(
                                 CASE
-                                    WHEN pp.product_name = '鍘熸潗鏂�' AND t.modelType = 0 THEN qi.quantity
-                                    WHEN pp.product_name = '鍗婃垚鍝�' AND t.modelType = 1 THEN qi.quantity
-                                    WHEN pp.product_name = '鎴愬搧' AND t.modelType = 2 THEN qi.quantity
+                                    WHEN qi.inspect_state = 1 THEN qi.quantity
                                     ELSE 0
                                     END
-                        ), 0) AS totalCount,
+                        ), 0)                AS completedCount,
+
                COALESCE(SUM(
                                 CASE
-                                    WHEN pp.product_name = '鍘熸潗鏂�' AND t.modelType = 0 THEN qi.qualified_quantity
-                                    WHEN pp.product_name = '鍗婃垚鍝�' AND t.modelType = 1 THEN qi.qualified_quantity
-                                    WHEN pp.product_name = '鎴愬搧' AND t.modelType = 2 THEN qi.qualified_quantity
+                                    WHEN qi.inspect_state = 1 THEN qi.qualified_quantity
                                     ELSE 0
                                     END
-                        ), 0) AS qualifiedCount,
+                        ), 0)                AS qualifiedCount,
+
                COALESCE(SUM(
                                 CASE
-                                    WHEN pp.product_name = '鍘熸潗鏂�' AND t.modelType = 0 THEN qi.unqualified_quantity
-                                    WHEN pp.product_name = '鍗婃垚鍝�' AND t.modelType = 1 THEN qi.unqualified_quantity
-                                    WHEN pp.product_name = '鎴愬搧' AND t.modelType = 2 THEN qi.unqualified_quantity
+                                    WHEN qi.inspect_state = 1 THEN qi.unqualified_quantity
                                     ELSE 0
                                     END
-                        ), 0) AS unqualifiedCount
-        FROM (SELECT 0 AS modelType
-              UNION ALL
-              SELECT 1
-              UNION ALL
-              SELECT 2) t
-                 LEFT JOIN product p ON 1 = 1
-                 LEFT JOIN product pp ON p.parent_id = pp.id
-                 LEFT JOIN product_model pm ON pm.product_id = p.id
-                 LEFT JOIN quality_inspect qi
-                           ON qi.product_model_id = pm.id
-                               AND YEAR(qi.check_time) = #{year}
-                               AND qi.inspect_state = 1
-        GROUP BY t.modelType
-        ORDER BY t.modelType;
+                        ), 0)                AS unqualifiedCount,
+
+            /* 瀹屾垚鐜� */
+               IF(COALESCE(SUM(qi.quantity), 0) = 0, 0,
+                  ROUND(
+                          COALESCE(SUM(
+                                           CASE WHEN qi.inspect_state = 1 THEN qi.quantity ELSE 0 END
+                                   ), 0)
+                              / SUM(qi.quantity) * 100, 2)
+               )                             AS completionRate,
+
+            /* 鍚堟牸鐜� */
+               IF(COALESCE(SUM(
+                                   CASE WHEN qi.inspect_state = 1 THEN qi.quantity ELSE 0 END
+                           ), 0) = 0, 0,
+                  ROUND(
+                          COALESCE(SUM(
+                                           CASE WHEN qi.inspect_state = 1 THEN qi.qualified_quantity ELSE 0 END
+                                   ), 0)
+                              /
+                          COALESCE(SUM(
+                                           CASE WHEN qi.inspect_state = 1 THEN qi.quantity ELSE 0 END
+                                   ), 0) * 100, 2)
+               )                             AS passRate
+
+        FROM quality_inspect qi
+        WHERE YEAR(qi.check_time) = #{year}
+        GROUP BY qi.inspect_type
+        ORDER BY qi.inspect_type;
     </select>
 
 
@@ -383,7 +359,7 @@
             /* 鍘熸潗鏂� */
                COALESCE(SUM(
                                 CASE
-                                    WHEN pp.product_name = '鍘熸潗鏂�'
+                                    WHEN qi.inspect_type = 0
                                         THEN qi.quantity
                                     ELSE 0
                                     END
@@ -392,7 +368,7 @@
             /* 鍗婃垚鍝� */
                COALESCE(SUM(
                                 CASE
-                                    WHEN pp.product_name = '鍗婃垚鍝�'
+                                    WHEN qi.inspect_type = 1
                                         THEN qi.quantity
                                     ELSE 0
                                     END
@@ -401,19 +377,15 @@
             /* 鎴愬搧 */
                COALESCE(SUM(
                                 CASE
-                                    WHEN pp.product_name = '鎴愬搧'
+                                    WHEN qi.inspect_type = 2
                                         THEN qi.quantity
                                     ELSE 0
                                     END
                         ), 0) AS outgoingCount
 
         FROM months m
-                 LEFT JOIN product p ON 1 = 1
-                 LEFT JOIN product pp ON p.parent_id = pp.id
-                 LEFT JOIN product_model pm ON pm.product_id = p.id
                  LEFT JOIN quality_inspect qi
-                           ON qi.product_model_id = pm.id
-                               AND qi.inspect_state = 1
+                           ON qi.inspect_state = 1
                                AND YEAR(qi.check_time) = #{year}
                                AND MONTH(qi.check_time) = m.month_num
 
@@ -428,16 +400,8 @@
                                   FROM quality_inspect_param qip
                                            JOIN quality_inspect qi
                                                 ON qip.inspect_id = qi.id
-                                           JOIN product p
-                                                ON qi.product_id = p.id
-                                           JOIN product pp
-                                                ON p.parent_id = pp.id
                                   WHERE qi.inspect_state = 1
-                                    AND (
-                                      (#{modelType} = 1 AND pp.product_name = '鍘熸潗鏂�')
-                                          OR (#{modelType} = 2 AND pp.product_name = '鍗婃垚鍝�')
-                                          OR (#{modelType} = 3 AND pp.product_name = '鎴愬搧')
-                                      )
+                                    AND qi.inspect_type = #{modelType} - 1
                                   GROUP BY qip.parameter_item),
              ranked AS (SELECT name,
                                count,

--
Gitblit v1.9.3