From c477506a6d672f71c6353608f3cf3424d8026790 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 13 四月 2026 18:18:40 +0800
Subject: [PATCH] refactor(approve): 优化审批流程ID生成逻辑

---
 src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskJob.java |  198 ++++++++++++++++++++++++++----------------------
 1 files changed, 107 insertions(+), 91 deletions(-)

diff --git a/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskJob.java b/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskJob.java
index fca829a..69ba222 100644
--- a/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskJob.java
+++ b/src/main/java/com/ruoyi/device/service/impl/MaintenanceTaskJob.java
@@ -1,8 +1,14 @@
 package com.ruoyi.device.service.impl;
 
+import com.ruoyi.device.mapper.DeviceLedgerMapper;
+import com.ruoyi.device.pojo.DeviceLedger;
 import com.ruoyi.device.pojo.DeviceMaintenance;
 import com.ruoyi.device.pojo.MaintenanceTask;
-import org.quartz.*;
+import org.quartz.DisallowConcurrentExecution;
+import org.quartz.Job;
+import org.quartz.JobDataMap;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -13,14 +19,16 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.YearMonth;
+import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 @Component
-@DisallowConcurrentExecution // 绂佹骞跺彂鎵ц鍚屼竴涓狫ob
+@DisallowConcurrentExecution
 public class MaintenanceTaskJob implements Job, Serializable {
-    private static final long serialVersionUID = 1L; // 蹇呴』瀹氫箟搴忓垪鍖朓D
+    private static final long serialVersionUID = 1L;
 
     @Autowired
     private DeviceMaintenanceServiceImpl deviceMaintenanceService;
@@ -28,15 +36,15 @@
     @Autowired
     private JdbcTemplate jdbcTemplate;
 
+    @Autowired
+    private DeviceLedgerMapper deviceLedgerMapper;
+
     @Override
     public void execute(JobExecutionContext context) throws JobExecutionException {
         JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
-        // 淇绫诲瀷杞崲閿欒锛屾纭幏鍙杢askId
         Long taskId = jobDataMap.getLong("maintenanceTaskId");
 
         try {
-            // 3. 灏濊瘯鏌ヨ浣犵殑涓氬姟鏁版嵁
-            // 閫氳繃JDBC妯℃澘鏌ヨ瀹氭椂浠诲姟淇℃伅锛屼娇鐢ㄥ弬鏁板寲鏌ヨ闃叉SQL娉ㄥ叆
             String yourSql = "SELECT * FROM maintenance_task where id = ?";
             List<MaintenanceTask> tasks = jdbcTemplate.query(
                     yourSql,
@@ -45,58 +53,49 @@
             );
             MaintenanceTask timingTask = tasks.isEmpty() ? null : tasks.get(0);
             if (timingTask == null) {
-                throw new JobExecutionException("MaintenanceTaskJob鎵句笉鍒板畾鏃朵换鍔�: " + taskId);
+                throw new JobExecutionException("MaintenanceTaskJob鎵句笉鍒板畾鏃朵换鍔� " + taskId);
             }
 
-            // 2. 鍒涘缓骞朵繚瀛樺贰妫�浠诲姟璁板綍 - 杩欏氨鏄偍鎻愪緵鐨勪唬鐮佸簲璇ユ斁鐨勪綅缃�
-            DeviceMaintenance deviceMaintenance = createInspectionTask(timingTask);
-            deviceMaintenanceService.save(deviceMaintenance);
+            List<Long> deviceIds = resolveDeviceIds(timingTask);
+            List<DeviceMaintenance> maintenanceList = new ArrayList<>();
+            for (Long deviceId : deviceIds) {
+                int quantity = resolveQuantity(deviceId);
+                for (int i = 0; i < quantity; i++) {
+                    maintenanceList.add(createInspectionTask(timingTask, deviceId));
+                }
+            }
+            deviceMaintenanceService.saveBatch(maintenanceList);
 
-            // 3. 鏇存柊瀹氭椂浠诲姟鐨勬墽琛屾椂闂�
             if (!tasks.isEmpty()) {
                 MaintenanceTask task = tasks.get(0);
-
-                // 鏇存柊鏈�鍚庢墽琛屾椂闂翠负褰撳墠鏃堕棿
                 LocalDateTime lastExecutionTime = LocalDateTime.now();
-
-                // 璁$畻涓嬫鎵ц鏃堕棿
                 LocalDateTime nextExecutionTime = calculateNextExecutionTime(
                         task.getFrequencyType(),
                         task.getFrequencyDetail(),
                         lastExecutionTime
                 );
 
-                // 鎵ц鏇存柊鎿嶄綔
-                String updateSql = "UPDATE maintenance_task " +
-                        "SET last_execution_time = ?, next_execution_time = ? " +
-                        "WHERE id = ?";
-
-                jdbcTemplate.update(
-                        updateSql,
-                        lastExecutionTime,
-                        nextExecutionTime,
-                        taskId
-                );
+                String updateSql = "UPDATE maintenance_task SET last_execution_time = ?, next_execution_time = ? WHERE id = ?";
+                jdbcTemplate.update(updateSql, lastExecutionTime, nextExecutionTime, taskId);
             }
         } catch (Exception e) {
             throw new JobExecutionException(e);
         }
     }
 
-    // 杩欏氨鏄偍鎻愪緵鐨勪唬鐮佸皝瑁呮垚鐨勬柟娉�
-    private DeviceMaintenance createInspectionTask(MaintenanceTask timingTask) {
+    private DeviceMaintenance createInspectionTask(MaintenanceTask timingTask, Long deviceLedgerId) {
         DeviceMaintenance inspectionTask = new DeviceMaintenance();
-
-        // 澶嶅埗鍩烘湰灞炴��
-        inspectionTask.setDeviceName(timingTask.getTaskName());
+        DeviceLedger deviceLedger = deviceLedgerMapper.selectById(deviceLedgerId);
+        inspectionTask.setDeviceName(deviceLedger != null ? deviceLedger.getDeviceName() : timingTask.getTaskName());
         inspectionTask.setMaintenanceTaskId(timingTask.getId());
-        inspectionTask.setDeviceLedgerId(timingTask.getTaskId());
+        inspectionTask.setDeviceLedgerId(deviceLedgerId);
+        inspectionTask.setAreaId(timingTask.getAreaId() != null ? timingTask.getAreaId() : (deviceLedger != null ? deviceLedger.getAreaId() : null));
         inspectionTask.setMaintenancePlanTime(LocalDateTime.now());
         inspectionTask.setFrequencyType(timingTask.getFrequencyType());
         inspectionTask.setFrequencyDetail(timingTask.getFrequencyDetail());
         inspectionTask.setTenantId(timingTask.getTenantId());
         inspectionTask.setStatus(0);
-        inspectionTask.setDeviceModel(timingTask.getDeviceModel());
+        inspectionTask.setDeviceModel(deviceLedger != null ? deviceLedger.getDeviceModel() : timingTask.getDeviceModel());
         inspectionTask.setCreateUser(Integer.parseInt(timingTask.getRegistrantId().toString()));
         inspectionTask.setUpdateTime(LocalDateTime.now());
         inspectionTask.setCreateTime(LocalDateTime.now());
@@ -104,13 +103,33 @@
         return inspectionTask;
     }
 
+    private List<Long> resolveDeviceIds(MaintenanceTask timingTask) {
+        if (timingTask.getDeviceLedgerIdsStr() != null && !timingTask.getDeviceLedgerIdsStr().trim().isEmpty()) {
+            return Arrays.stream(timingTask.getDeviceLedgerIdsStr().split(","))
+                    .map(String::trim)
+                    .filter(item -> !item.isEmpty())
+                    .map(Long::valueOf)
+                    .distinct()
+                    .collect(java.util.stream.Collectors.toList());
+        }
+        List<Long> ids = new ArrayList<>();
+        if (timingTask.getTaskId() != null) {
+            ids.add(timingTask.getTaskId());
+        }
+        return ids;
+    }
 
-    /**
-     * 璁$畻涓嬫鎵ц鏃堕棿
-     */
-    private LocalDateTime calculateNextExecutionTime(String frequencyType,
-                                                     String frequencyDetail,
-                                                     LocalDateTime currentTime) {
+    private int resolveQuantity(Long deviceLedgerId) {
+        try {
+            String sql = "SELECT number FROM device_ledger WHERE id = ?";
+            Number quantity = jdbcTemplate.queryForObject(sql, Number.class, deviceLedgerId);
+            return quantity == null || quantity.intValue() < 1 ? 1 : quantity.intValue();
+        } catch (Exception ignored) {
+            return 1;
+        }
+    }
+
+    private LocalDateTime calculateNextExecutionTime(String frequencyType, String frequencyDetail, LocalDateTime currentTime) {
         try {
             switch (frequencyType) {
                 case "DAILY":
@@ -121,6 +140,8 @@
                     return calculateMonthlyNextTime(frequencyDetail, currentTime);
                 case "QUARTERLY":
                     return calculateQuarterlyNextTime(frequencyDetail, currentTime);
+                case "YEARLY":
+                    return calculateYearlyNextTime(frequencyDetail, currentTime);
                 default:
                     throw new IllegalArgumentException("涓嶆敮鎸佺殑棰戠巼绫诲瀷: " + frequencyType);
             }
@@ -129,84 +150,52 @@
         }
     }
 
-    /**
-     * 璁$畻姣忔棩浠诲姟鐨勪笅娆℃墽琛屾椂闂�
-     */
     private LocalDateTime calculateDailyNextTime(String timeStr, LocalDateTime current) {
-        LocalTime executionTime = LocalTime.parse(timeStr); // 瑙f瀽鏍煎紡 "HH:mm"
+        LocalTime executionTime = LocalTime.parse(timeStr);
         LocalDateTime nextTime = LocalDateTime.of(current.toLocalDate(), executionTime);
-
-        // 濡傛灉浠婂ぉ鐨勬椂闂村凡杩囷紝鍒欏畨鎺掓槑澶�
         return current.isBefore(nextTime) ? nextTime : nextTime.plusDays(1);
     }
 
-    /**
-     * 璁$畻姣忓懆浠诲姟鐨勪笅娆℃墽琛屾椂闂�
-     */
     private LocalDateTime calculateWeeklyNextTime(String detail, LocalDateTime current) {
         String[] parts = detail.split(",");
-        String dayOfWeekStr = parts[0];  // 濡� "MON" 鎴� "MON|WED|FRI"
-        LocalTime time = LocalTime.parse(parts[1]); // 鏃堕棿閮ㄥ垎
-
-        // 瑙f瀽鏄熸湡鍑�(鏀寔澶氫釜鏄熸湡)
+        String dayOfWeekStr = parts[0];
+        LocalTime time = LocalTime.parse(parts[1]);
         Set<DayOfWeek> targetDays = parseDayOfWeeks(dayOfWeekStr);
 
-        // 浠庡綋鍓嶆椂闂村紑濮嬫壘涓嬩竴涓鍚堟潯浠剁殑鏄熸湡鍑�
         LocalDateTime nextTime = current;
         while (true) {
             nextTime = nextTime.plusDays(1);
             if (targetDays.contains(nextTime.getDayOfWeek())) {
                 return LocalDateTime.of(nextTime.toLocalDate(), time);
             }
-
-            // 闃叉鏃犻檺寰幆(鐞嗚涓婁笉浼氬彂鐢�)
             if (nextTime.isAfter(current.plusYears(1))) {
                 throw new RuntimeException("鏃犳硶鎵惧埌涓嬫鎵ц鏃堕棿");
             }
         }
     }
 
-    /**
-     * 璁$畻姣忔湀浠诲姟鐨勪笅娆℃墽琛屾椂闂�
-     */
     private LocalDateTime calculateMonthlyNextTime(String detail, LocalDateTime current) {
         String[] parts = detail.split(",");
         int dayOfMonth = Integer.parseInt(parts[0]);
         LocalTime time = LocalTime.parse(parts[1]);
-
-        // 浠庝笅涓湀寮�濮嬭绠�
-        LocalDateTime nextTime = current.plusMonths(1)
+        return current.plusMonths(1)
                 .withDayOfMonth(Math.min(dayOfMonth, current.plusMonths(1).toLocalDate().lengthOfMonth()))
                 .with(time);
-
-        return nextTime;
     }
 
-    /**
-     * 璁$畻姣忓搴︿换鍔$殑涓嬫鎵ц鏃堕棿
-     */
     private LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) {
         String[] parts = detail.split(",");
-        int quarterMonth = Integer.parseInt(parts[0]); // 1=绗�1涓湀锛�2=绗�2涓湀锛�3=绗�3涓湀
+        int quarterMonth = Integer.parseInt(parts[0]);
         int dayOfMonth = Integer.parseInt(parts[1]);
         LocalTime time = LocalTime.parse(parts[2]);
 
-        // 璁$畻褰撳墠瀛e害
-        int currentQuarter = (current.getMonthValue() - 1) / 3 + 1;
         int currentMonthInQuarter = (current.getMonthValue() - 1) % 3 + 1;
-
         YearMonth targetYearMonth;
         if (currentMonthInQuarter < quarterMonth) {
-            // 鏈搴﹀唴杩樻湁鎵ц鏈轰細
-            targetYearMonth = YearMonth.from(current)
-                    .plusMonths(quarterMonth - currentMonthInQuarter);
+            targetYearMonth = YearMonth.from(current).plusMonths(quarterMonth - currentMonthInQuarter);
         } else {
-            // 闇�瑕佸埌涓嬩釜瀛e害
-            targetYearMonth = YearMonth.from(current)
-                    .plusMonths(3 - currentMonthInQuarter + quarterMonth);
+            targetYearMonth = YearMonth.from(current).plusMonths(3 - currentMonthInQuarter + quarterMonth);
         }
-
-        // 澶勭悊鏈堟湯鏃ユ湡
         int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth());
 
         return LocalDateTime.of(
@@ -218,26 +207,53 @@
         );
     }
 
-    /**
-     * 瑙f瀽鏄熸湡鍑犲瓧绗︿覆
-     */
+    private LocalDateTime calculateYearlyNextTime(String detail, LocalDateTime current) {
+        String[] parts = detail.split(",");
+        int month = Integer.parseInt(parts[0]);
+        int dayOfMonth = Integer.parseInt(parts[1]);
+        LocalTime time = LocalTime.parse(parts[2]);
+
+        YearMonth targetYearMonth = YearMonth.of(current.getYear(), month);
+        int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth());
+        LocalDateTime target = LocalDateTime.of(current.getYear(), month, adjustedDay, time.getHour(), time.getMinute());
+        if (!target.isAfter(current)) {
+            targetYearMonth = YearMonth.of(current.getYear() + 1, month);
+            adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth());
+            target = LocalDateTime.of(current.getYear() + 1, month, adjustedDay, time.getHour(), time.getMinute());
+        }
+        return target;
+    }
+
     private Set<DayOfWeek> parseDayOfWeeks(String dayOfWeekStr) {
         Set<DayOfWeek> days = new HashSet<>();
         String[] dayStrs = dayOfWeekStr.split("\\|");
-
         for (String dayStr : dayStrs) {
             switch (dayStr) {
-                case "MON": days.add(DayOfWeek.MONDAY); break;
-                case "TUE": days.add(DayOfWeek.TUESDAY); break;
-                case "WED": days.add(DayOfWeek.WEDNESDAY); break;
-                case "THU": days.add(DayOfWeek.THURSDAY); break;
-                case "FRI": days.add(DayOfWeek.FRIDAY); break;
-                case "SAT": days.add(DayOfWeek.SATURDAY); break;
-                case "SUN": days.add(DayOfWeek.SUNDAY); break;
-                default: throw new IllegalArgumentException("鏃犳晥鐨勬槦鏈熷嚑: " + dayStr);
+                case "MON":
+                    days.add(DayOfWeek.MONDAY);
+                    break;
+                case "TUE":
+                    days.add(DayOfWeek.TUESDAY);
+                    break;
+                case "WED":
+                    days.add(DayOfWeek.WEDNESDAY);
+                    break;
+                case "THU":
+                    days.add(DayOfWeek.THURSDAY);
+                    break;
+                case "FRI":
+                    days.add(DayOfWeek.FRIDAY);
+                    break;
+                case "SAT":
+                    days.add(DayOfWeek.SATURDAY);
+                    break;
+                case "SUN":
+                    days.add(DayOfWeek.SUNDAY);
+                    break;
+                default:
+                    throw new IllegalArgumentException("鏃犳晥鐨勬槦鏈熷嚑: " + dayStr);
             }
         }
-
         return days;
     }
 }

--
Gitblit v1.9.3