From 1a89a2eca92540f2a6e9ed5c140b00610f2f4bfc Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 13 四月 2026 14:11:50 +0800
Subject: [PATCH] yys 1.设备巡检,保养加入年维度

---
 src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java |  258 ++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 233 insertions(+), 25 deletions(-)

diff --git a/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java b/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java
index efcd90f..5d13ffa 100644
--- a/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java
+++ b/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskJob.java
@@ -1,23 +1,56 @@
 package com.ruoyi.inspectiontask.service.impl;
 
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.device.mapper.DeviceLedgerMapper;
+import com.ruoyi.device.pojo.DeviceLedger;
 import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper;
+import com.ruoyi.inspectiontask.mapper.TimingTaskMapper;
 import com.ruoyi.inspectiontask.pojo.InspectionTask;
 import com.ruoyi.inspectiontask.pojo.TimingTask;
 import com.ruoyi.inspectiontask.service.TimingTaskService;
-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;
 import org.springframework.stereotype.Component;
 
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.time.DayOfWeek;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.YearMonth;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 @Component
-@DisallowConcurrentExecution // 绂佹骞跺彂鎵ц鍚屼竴涓狫ob
-public class TimingTaskJob implements Job {
+@DisallowConcurrentExecution
+public class TimingTaskJob implements Job, Serializable {
+    private static final long serialVersionUID = 1L;
 
     @Autowired
-    private
-    TimingTaskService timingTaskService;
+    private TimingTaskMapper timingTaskMapper;
+
+    @Autowired
+    private TimingTaskService timingTaskService;
 
     @Autowired
     private InspectionTaskMapper inspectionTaskMapper;
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    private DeviceLedgerMapper deviceLedgerMapper;
 
     @Override
     public void execute(JobExecutionContext context) throws JobExecutionException {
@@ -25,41 +58,216 @@
         Long taskId = jobDataMap.getLong("taskId");
 
         try {
-            // 1. 鑾峰彇瀹氭椂浠诲姟璇︽儏
-            TimingTask timingTask = timingTaskService.getById(taskId);
-            if (timingTask == null || !timingTask.isActive()) {
-                return;
+            String sql = "SELECT * FROM timing_task WHERE id = ?";
+            List<TimingTask> tasks = jdbcTemplate.query(
+                    sql,
+                    new BeanPropertyRowMapper<>(TimingTask.class),
+                    taskId
+            );
+            TimingTask timingTask = tasks.isEmpty() ? null : tasks.get(0);
+            if (timingTask == null) {
+                throw new JobExecutionException("閹靛彞绗夐崚鏉跨暰閺冩湹鎹㈤崝? " + taskId);
             }
 
-            // 2. 鍒涘缓骞朵繚瀛樺贰妫�浠诲姟璁板綍 - 杩欏氨鏄偍鎻愪緵鐨勪唬鐮佸簲璇ユ斁鐨勪綅缃�
-            InspectionTask inspectionTask = createInspectionTask(timingTask);
-            inspectionTaskMapper.insert(inspectionTask);
+            List<Long> deviceIds = resolveTaskIds(timingTask);
+            if (deviceIds.isEmpty()) {
+                throw new JobExecutionException("鐎规碍妞傛禒璇插閺堫亪鍘ょ純顔款啎婢�? " + taskId);
+            }
 
-            // 3. 鏇存柊瀹氭椂浠诲姟鐨勬墽琛屾椂闂�
-            timingTaskService.updateTaskExecutionTime(taskId);
+            for (Long deviceId : deviceIds) {
+                DeviceLedger deviceLedger = deviceLedgerMapper.selectById(deviceId);
+                if (deviceLedger == null) {
+                    continue;
+                }
+                int count = getDeviceCount(deviceLedger.getNumber());
+                for (int i = 0; i < count; i++) {
+                    inspectionTaskMapper.insert(createInspectionTask(timingTask, deviceLedger));
+                }
+            }
 
-            // 4. 璁板綍鎵ц鏃ュ織
-//            timingTaskService.recordExecutionLog(taskId, true, "浠诲姟鎵ц鎴愬姛锛岀敓鎴愬贰妫�浠诲姟ID: " + inspectionTask.getId());
-
+            if (!tasks.isEmpty()) {
+                LocalDateTime lastExecutionTime = LocalDateTime.now();
+                LocalDateTime nextExecutionTime = calculateNextExecutionTime(
+                        timingTask.getFrequencyType(),
+                        timingTask.getFrequencyDetail(),
+                        lastExecutionTime
+                );
+                String updateSql = "UPDATE timing_task SET last_execution_time = ?, next_execution_time = ? WHERE id = ?";
+                jdbcTemplate.update(updateSql, lastExecutionTime, nextExecutionTime, taskId);
+            }
         } catch (Exception e) {
-//            timingTaskService.recordExecutionLog(taskId, false, "浠诲姟鎵ц澶辫触: " + e.getMessage());
             throw new JobExecutionException(e);
         }
     }
 
-    // 杩欏氨鏄偍鎻愪緵鐨勪唬鐮佸皝瑁呮垚鐨勬柟娉�
-    private InspectionTask createInspectionTask(TimingTask timingTask) {
-        InspectionTask inspectionTask = new InspectionTask();
+    private List<Long> resolveTaskIds(TimingTask timingTask) {
+        if (StringUtils.isNotBlank(timingTask.getTaskIdsStr())) {
+            return Arrays.stream(timingTask.getTaskIdsStr().split(","))
+                    .filter(StringUtils::isNotBlank)
+                    .map(String::trim)
+                    .map(Long::valueOf)
+                    .distinct()
+                    .collect(Collectors.toList());
+        }
+        if (timingTask.getTaskId() != null) {
+            return new ArrayList<>(Arrays.asList(timingTask.getTaskId().longValue()));
+        }
+        return new ArrayList<>();
+    }
 
-        // 澶嶅埗鍩烘湰灞炴��
-        inspectionTask.setTaskName(timingTask.getTaskName());
+    private int getDeviceCount(BigDecimal number) {
+        if (number == null) {
+            return 1;
+        }
+        int count = number.intValue();
+        return count > 0 ? count : 1;
+    }
+
+    private InspectionTask createInspectionTask(TimingTask timingTask, DeviceLedger deviceLedger) {
+        InspectionTask inspectionTask = new InspectionTask();
+        inspectionTask.setTaskName(deviceLedger.getDeviceName());
+        inspectionTask.setTaskId(deviceLedger.getId().intValue());
+        inspectionTask.setAreaId(deviceLedger.getAreaId());
         inspectionTask.setInspectorId(timingTask.getInspectorIds());
         inspectionTask.setInspectionLocation(timingTask.getInspectionLocation());
-        inspectionTask.setRemarks("鑷姩鐢熸垚鑷畾鏃朵换鍔D: " + timingTask.getId());
+        inspectionTask.setRemarks("閼奉亜濮╅悽鐔稿灇閼奉亜鐣鹃弮鏈垫崲閸旑搹D: " + timingTask.getId());
         inspectionTask.setRegistrantId(timingTask.getRegistrantId());
+        inspectionTask.setRegistrant(timingTask.getRegistrant());
         inspectionTask.setFrequencyType(timingTask.getFrequencyType());
         inspectionTask.setFrequencyDetail(timingTask.getFrequencyDetail());
-
+        inspectionTask.setTenantId(timingTask.getTenantId());
         return inspectionTask;
     }
+
+    private LocalDateTime calculateNextExecutionTime(String frequencyType,
+                                                     String frequencyDetail,
+                                                     LocalDateTime currentTime) {
+        try {
+            switch (frequencyType) {
+                case "DAILY":
+                    return calculateDailyNextTime(frequencyDetail, currentTime);
+                case "WEEKLY":
+                    return calculateWeeklyNextTime(frequencyDetail, currentTime);
+                case "MONTHLY":
+                    return calculateMonthlyNextTime(frequencyDetail, currentTime);
+                case "QUARTERLY":
+                    return calculateQuarterlyNextTime(frequencyDetail, currentTime);
+                case "YEARLY":
+                    return calculateYearlyNextTime(frequencyDetail, currentTime);
+                default:
+                    throw new IllegalArgumentException("娑撳秵鏁幐浣烘畱妫版垹宸肩猾璇茬��: " + frequencyType);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("鐠侊紕鐣绘稉瀣偧閹笛嗩攽閺冨爼妫挎径杈Е: " + e.getMessage(), e);
+        }
+    }
+
+    private LocalDateTime calculateDailyNextTime(String timeStr, LocalDateTime current) {
+        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];
+        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]);
+        return current.plusMonths(1)
+                .withDayOfMonth(Math.min(dayOfMonth, current.plusMonths(1).toLocalDate().lengthOfMonth()))
+                .with(time);
+    }
+
+    private LocalDateTime calculateQuarterlyNextTime(String detail, LocalDateTime current) {
+        String[] parts = detail.split(",");
+        int quarterMonth = Integer.parseInt(parts[0]);
+        int dayOfMonth = Integer.parseInt(parts[1]);
+        LocalTime time = LocalTime.parse(parts[2]);
+
+        int currentMonthInQuarter = (current.getMonthValue() - 1) % 3 + 1;
+        YearMonth targetYearMonth;
+        if (currentMonthInQuarter < quarterMonth) {
+            targetYearMonth = YearMonth.from(current).plusMonths(quarterMonth - currentMonthInQuarter);
+        } else {
+            targetYearMonth = YearMonth.from(current).plusMonths(3 - currentMonthInQuarter + quarterMonth);
+        }
+
+        int adjustedDay = Math.min(dayOfMonth, targetYearMonth.lengthOfMonth());
+        return LocalDateTime.of(
+                targetYearMonth.getYear(),
+                targetYearMonth.getMonthValue(),
+                adjustedDay,
+                time.getHour(),
+                time.getMinute()
+        );
+    }
+
+    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);
+            }
+        }
+
+        return days;
+    }
 }

--
Gitblit v1.9.3