From dd3c0399c9f3c2e70bfd0072cddadcd8d34f18bb Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期日, 24 五月 2026 18:11:21 +0800
Subject: [PATCH] 测试类
---
src/test/java/com/ruoyi/device/service/impl/MaintenanceTaskJobTest.java | 448 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 448 insertions(+), 0 deletions(-)
diff --git a/src/test/java/com/ruoyi/device/service/impl/MaintenanceTaskJobTest.java b/src/test/java/com/ruoyi/device/service/impl/MaintenanceTaskJobTest.java
new file mode 100644
index 0000000..0c41f05
--- /dev/null
+++ b/src/test/java/com/ruoyi/device/service/impl/MaintenanceTaskJobTest.java
@@ -0,0 +1,448 @@
+package com.ruoyi.device.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ruoyi.device.mapper.MaintenanceTaskMapper;
+import com.ruoyi.device.pojo.DeviceMaintenance;
+import com.ruoyi.device.pojo.MaintenanceTask;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.YearMonth;
+import java.time.LocalDate;
+import java.time.DayOfWeek;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 璁惧淇濆吇浠诲姟娴嬭瘯绫�
+ *
+ * 鏌ヨ鏁版嵁搴撲腑鐨勪繚鍏讳换鍔★紝鏍规嵁鐧昏鏃ユ湡銆侀娆°�佸紑濮嬫棩鏈熶笌鏃堕棿鏉ョ敓鎴愪繚鍏昏褰�
+ * 浠庣櫥璁版棩鏈熷埌浠婂ぉ锛屾寜棰戞鐢熸垚鎵�鏈夌鍚堢殑璁板綍
+ */
+@SpringBootTest
+public class MaintenanceTaskJobTest {
+
+ @Autowired
+ private MaintenanceTaskMapper maintenanceTaskMapper;
+
+ @Autowired
+ private DeviceMaintenanceServiceImpl deviceMaintenanceService;
+
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ /**
+ * 娴嬭瘯锛氭寜鏃ユ湡鍒嗘暎鐢熸垚淇濆吇璁板綍
+ * 浠庣櫥璁版棩鏈熷埌浠婂ぉ锛屾寜鏃ユ湡椤哄簭锛屾瘡澶╃殑鎵�鏈夎澶囦繚鍏昏褰曚竴璧风敓鎴�
+ */
+ @Test
+ void testGenerateOneByOne() {
+ // 鏌ヨ鎵�鏈夊惎鐢ㄧ殑淇濆吇浠诲姟
+ List<MaintenanceTask> tasks = maintenanceTaskMapper.selectList(
+ new LambdaQueryWrapper<MaintenanceTask>()
+ .eq(MaintenanceTask::getIsActive, 1)
+ .eq(MaintenanceTask::getDeleted, 0)
+ );
+
+ if (tasks.isEmpty()) {
+ System.out.println("=== 娌℃湁鎵惧埌淇濆吇浠诲姟 ===");
+ return;
+ }
+
+ // 鎵惧嚭鏈�鏃╁拰鏈�鏅氱殑鐧昏鏃ユ湡
+ LocalDate earliestDate = tasks.stream()
+ .map(MaintenanceTask::getRegistrationDate)
+ .filter(Objects::nonNull)
+ .min(LocalDate::compareTo)
+ .orElse(LocalDate.now());
+ LocalDate latestDate = LocalDate.now();
+
+ System.out.println("=== 鐧昏鏃ユ湡鑼冨洿: " + earliestDate + " 鑷� " + latestDate + " ===");
+ System.out.println("=== 鍏辨壘鍒� " + tasks.size() + " 涓繚鍏讳换鍔� ===\n");
+
+ // 鎸夋棩鏈熼『搴忕敓鎴愶紝姣忓ぉ鐢熸垚涓�娆�
+ LocalDate currentDate = earliestDate;
+ int totalRecords = 0;
+
+ while (!currentDate.isAfter(latestDate)) {
+ final LocalDate date = currentDate;
+ final List<DeviceMaintenance> recordsToSave = new ArrayList<>();
+
+ // 鎵惧嚭褰撳ぉ闇�瑕佷繚鍏荤殑鎵�鏈変换鍔�
+ for (MaintenanceTask task : tasks) {
+ LocalDate startDate = task.getRegistrationDate() != null ? task.getRegistrationDate() : LocalDate.now();
+ if (date.isBefore(startDate)) {
+ continue; // 璺宠繃鐧昏鏃ユ湡涔嬪墠鐨勬棩鏈�
+ }
+
+ // 妫�鏌ヨ浠诲姟鐨勯娆℃槸鍚﹀尮閰嶅綋澶�
+ if (isExecutionDate(task.getFrequencyType(), task.getFrequencyDetail(), startDate, date)) {
+ LocalTime time = getExecutionTime(task.getFrequencyDetail());
+ LocalDateTime executionDateTime = LocalDateTime.of(date, time);
+
+ DeviceMaintenance record = createMaintenanceRecord(task, executionDateTime);
+ recordsToSave.add(record);
+ }
+ }
+
+ // 濡傛灉褰撳ぉ鏈夎褰曪紝鎵归噺淇濆瓨
+ if (!recordsToSave.isEmpty()) {
+ for (DeviceMaintenance record : recordsToSave) {
+ try {
+ deviceMaintenanceService.save(record);
+ System.out.println(" 鈫� 璁″垝鏃ユ湡: " + date + " | 璁惧: " + record.getDeviceName()
+ + " | 璁板綍ID: " + record.getId());
+ } catch (Exception e) {
+ System.out.println(" 鉁� 璁″垝鏃ユ湡: " + date + " | 璁惧: " + record.getDeviceName()
+ + " | 澶辫触: " + e.getMessage());
+ }
+ }
+ totalRecords += recordsToSave.size();
+ System.out.println(" === 鏃ユ湡 " + date + " 鍏辩敓鎴� " + recordsToSave.size() + " 鏉¤褰� ===\n");
+ }
+
+ currentDate = currentDate.plusDays(1);
+ }
+
+ System.out.println("=== 鎵ц瀹屾垚: 鍏辩敓鎴� " + totalRecords + " 鏉¤褰� ===");
+ }
+
+ /**
+ * 妫�鏌ユ寚瀹氭棩鏈熸槸鍚︾鍚堜换鍔$殑鎵ц棰戞
+ */
+ private boolean isExecutionDate(String frequencyType, String frequencyDetail, LocalDate startDate, LocalDate checkDate) {
+ if (checkDate.isBefore(startDate)) {
+ return false;
+ }
+
+ switch (frequencyType) {
+ case "DAILY":
+ return true; // 姣忓ぉ閮介渶瑕佹墽琛�
+ case "WEEKLY":
+ return isWeeklyMatch(frequencyDetail, checkDate);
+ case "MONTHLY":
+ return isMonthlyMatch(frequencyDetail, checkDate);
+ case "QUARTERLY":
+ return isQuarterlyMatch(frequencyDetail, checkDate);
+ default:
+ return false;
+ }
+ }
+
+ private boolean isWeeklyMatch(String detail, LocalDate date) {
+ String[] parts = detail.split(",");
+ String dayOfWeekStr = parts[0];
+ DayOfWeek targetDay = parseDayOfWeek(dayOfWeekStr);
+ return date.getDayOfWeek() == targetDay;
+ }
+
+ private boolean isMonthlyMatch(String detail, LocalDate date) {
+ String[] parts = detail.split(",");
+ int targetDay = Integer.parseInt(parts[0]);
+ return date.getDayOfMonth() == targetDay;
+ }
+
+ private boolean isQuarterlyMatch(String detail, LocalDate date) {
+ String[] parts = detail.split(",");
+ int quarterMonth = Integer.parseInt(parts[0]); // 瀛e害涓殑绗嚑涓湀
+ int targetDay = Integer.parseInt(parts[1]);
+
+ int currentMonth = date.getMonthValue();
+ int monthInQuarter = (currentMonth - 1) % 3 + 1;
+
+ return monthInQuarter == quarterMonth && date.getDayOfMonth() == targetDay;
+ }
+
+ private LocalTime getExecutionTime(String frequencyDetail) {
+ String[] parts = frequencyDetail.split(",");
+ if (parts.length >= 2 && (parts.length == 2 || parts.length == 3)) {
+ return LocalTime.parse(parts[parts.length - 1]);
+ }
+ return LocalTime.of(9, 0); // 榛樿鏃堕棿
+ }
+
+ /**
+ * 娴嬭瘯锛氭牴鎹墍鏈変繚鍏讳换鍔$敓鎴愯澶囦繚鍏昏褰�
+ * 鎸夐『搴忓鐞嗘瘡涓换鍔★紝浠庣櫥璁版棩鏈熷埌浠婂ぉ锛屾寜棰戞渚濇鐢熸垚鎵�鏈夌鍚堢殑璁板綍
+ */
+ @Test
+ void testGenerateMaintenanceRecordForAllTasks() {
+ // 鏌ヨ鎵�鏈夊惎鐢ㄧ殑淇濆吇浠诲姟锛屾寜ID鎺掑簭
+ List<MaintenanceTask> tasks = maintenanceTaskMapper.selectList(
+ new LambdaQueryWrapper<MaintenanceTask>()
+ .eq(MaintenanceTask::getIsActive, 1)
+ .eq(MaintenanceTask::getDeleted, 0)
+ .orderByAsc(MaintenanceTask::getId)
+ );
+
+ System.out.println("=== 鍏辨壘鍒� " + tasks.size() + " 涓繚鍏讳换鍔� ===\n");
+
+ int totalRecords = 0;
+ for (MaintenanceTask task : tasks) {
+ try {
+ // 鎸夐『搴忕敓鎴愯浠诲姟鎵�鏈夌鍚堥娆$殑璁板綍
+ int recordCount = generateRecordsForTaskSequentially(task);
+ totalRecords += recordCount;
+ System.out.println("鉁� 浠诲姟ID: " + task.getId() + " | " + task.getTaskName()
+ + " | 鐧昏鏃ユ湡: " + task.getRegistrationDate()
+ + " | 鐢熸垚璁板綍鏁�: " + recordCount);
+ } catch (Exception e) {
+ System.out.println("鉁� 浠诲姟ID: " + task.getId() + " | " + task.getTaskName() + " | 澶辫触: " + e.getMessage());
+ }
+ }
+
+ System.out.println("\n=== 鎵ц瀹屾垚: 鍏辩敓鎴� " + totalRecords + " 鏉¤褰� ===");
+ }
+
+ /**
+ * 涓哄崟涓换鍔℃寜椤哄簭鐢熸垚鎵�鏈夌鍚堥娆$殑璁板綍
+ */
+ private int generateRecordsForTaskSequentially(MaintenanceTask task) {
+ LocalDate startDate = task.getRegistrationDate();
+ if (startDate == null) {
+ startDate = LocalDate.now();
+ }
+ LocalDate endDate = LocalDate.now();
+
+ // 鏍规嵁棰戞鑾峰彇鎵�鏈夐渶瑕佹墽琛岀殑鏃ユ湡
+ List<LocalDateTime> executionDates = getExecutionDates(task.getFrequencyType(), task.getFrequencyDetail(), startDate, endDate);
+
+ if (executionDates.isEmpty()) {
+ return 0;
+ }
+
+ int count = 0;
+ for (LocalDateTime executionDate : executionDates) {
+ try {
+ // 鎸夐『搴忕敓鎴愪繚鍏昏褰�
+ DeviceMaintenance record = createMaintenanceRecord(task, executionDate);
+ deviceMaintenanceService.save(record);
+ count++;
+ } catch (Exception e) {
+ System.out.println(" 鉁� 鏃ユ湡: " + executionDate + " | 澶辫触: " + e.getMessage());
+ }
+ }
+
+ // 鏇存柊浠诲姟鐨勪笅娆℃墽琛屾椂闂�
+ if (count > 0) {
+ // first_execution = 绗竴鏉¤褰曠殑鏃ユ湡 = last_execution_time
+ LocalDateTime firstExecution = executionDates.get(0);
+ // next_execution = 鏈�鍚庝竴鏉¤褰曠殑涓嬩竴娆℃墽琛屾棩鏈�
+ LocalDateTime lastExecution = executionDates.get(executionDates.size() - 1);
+ LocalDateTime nextExecution = calculateNextExecutionTime(task.getFrequencyType(), task.getFrequencyDetail(), lastExecution);
+ updateTaskExecutionTime(task.getId(), firstExecution, nextExecution);
+ }
+
+ return count;
+ }
+
+ /**
+ * 鑾峰彇鎸囧畾鏃ユ湡鑼冨洿鍐呮墍鏈夌鍚堥娆$殑鎵ц鏃堕棿
+ */
+ private List<LocalDateTime> getExecutionDates(String frequencyType, String frequencyDetail, LocalDate startDate, LocalDate endDate) {
+ List<LocalDateTime> dates = new ArrayList<>();
+
+ switch (frequencyType) {
+ case "DAILY":
+ dates.addAll(getDailyDates(startDate, endDate, frequencyDetail));
+ break;
+ case "WEEKLY":
+ dates.addAll(getWeeklyDates(startDate, endDate, frequencyDetail));
+ break;
+ case "MONTHLY":
+ dates.addAll(getMonthlyDates(startDate, endDate, frequencyDetail));
+ break;
+ case "QUARTERLY":
+ dates.addAll(getQuarterlyDates(startDate, endDate, frequencyDetail));
+ break;
+ }
+
+ return dates;
+ }
+
+ private List<LocalDateTime> getDailyDates(LocalDate startDate, LocalDate endDate, String timeStr) {
+ List<LocalDateTime> dates = new ArrayList<>();
+ LocalTime time = LocalTime.parse(timeStr);
+
+ LocalDate current = startDate;
+ while (!current.isAfter(endDate)) {
+ dates.add(LocalDateTime.of(current, time));
+ current = current.plusDays(1);
+ }
+ return dates;
+ }
+
+ private List<LocalDateTime> getMonthlyDates(LocalDate startDate, LocalDate endDate, String detail) {
+ List<LocalDateTime> dates = new ArrayList<>();
+ String[] parts = detail.split(",");
+ int dayOfMonth = Integer.parseInt(parts[0]);
+ LocalTime time = LocalTime.parse(parts[1]);
+
+ // 浠庣櫥璁版棩鏈熸墍鍦ㄦ湀鎵剧涓�涓鍚堟潯浠剁殑鏃ユ湡
+ int actualDay = Math.min(dayOfMonth, startDate.lengthOfMonth());
+ LocalDate current = startDate.withDayOfMonth(actualDay);
+
+ // 濡傛灉杩欎釜鏃ユ湡鍦ㄧ櫥璁版棩鏈熶箣鍓嶏紝寰�鍚庢帹涓�涓湀
+ if (current.isBefore(startDate)) {
+ current = current.plusMonths(1);
+ actualDay = Math.min(dayOfMonth, current.lengthOfMonth());
+ current = current.withDayOfMonth(actualDay);
+ }
+
+ while (!current.isAfter(endDate)) {
+ dates.add(LocalDateTime.of(current, time));
+ current = current.plusMonths(1);
+ actualDay = Math.min(dayOfMonth, current.lengthOfMonth());
+ current = current.withDayOfMonth(actualDay);
+ }
+ return dates;
+ }
+
+ private List<LocalDateTime> getWeeklyDates(LocalDate startDate, LocalDate endDate, String detail) {
+ List<LocalDateTime> dates = new ArrayList<>();
+ String[] parts = detail.split(",");
+ String dayOfWeekStr = parts[0];
+ LocalTime time = LocalTime.parse(parts[1]);
+
+ java.time.DayOfWeek targetDay = parseDayOfWeek(dayOfWeekStr);
+
+ LocalDate current = startDate;
+ while (!current.isAfter(endDate)) {
+ if (current.getDayOfWeek() == targetDay) {
+ dates.add(LocalDateTime.of(current, time));
+ }
+ current = current.plusDays(1);
+ }
+ return dates;
+ }
+
+ private List<LocalDateTime> getQuarterlyDates(LocalDate startDate, LocalDate endDate, String detail) {
+ List<LocalDateTime> dates = new ArrayList<>();
+ String[] parts = detail.split(",");
+ int quarterMonth = Integer.parseInt(parts[0]);
+ int dayOfMonth = Integer.parseInt(parts[1]);
+ LocalTime time = LocalTime.parse(parts[2]);
+
+ int currentMonth = startDate.getMonthValue();
+ int targetMonth = ((currentMonth - 1) / 3) * 3 + quarterMonth;
+ int yearAdjust = 0;
+
+ if (targetMonth > 12) {
+ targetMonth -= 12;
+ yearAdjust = 1;
+ }
+
+ int actualDay = Math.min(dayOfMonth, YearMonth.of(startDate.getYear() + yearAdjust, targetMonth).lengthOfMonth());
+ LocalDate current = startDate.withYear(startDate.getYear() + yearAdjust)
+ .withMonth(targetMonth)
+ .withDayOfMonth(actualDay);
+
+ while (!current.isAfter(endDate)) {
+ dates.add(LocalDateTime.of(current, time));
+ current = current.plusMonths(3);
+ actualDay = Math.min(dayOfMonth, current.lengthOfMonth());
+ current = current.withDayOfMonth(actualDay);
+ }
+ return dates;
+ }
+
+ private java.time.DayOfWeek parseDayOfWeek(String dayOfWeekStr) {
+ switch (dayOfWeekStr.toUpperCase()) {
+ case "MON": return java.time.DayOfWeek.MONDAY;
+ case "TUE": return java.time.DayOfWeek.TUESDAY;
+ case "WED": return java.time.DayOfWeek.WEDNESDAY;
+ case "THU": return java.time.DayOfWeek.THURSDAY;
+ case "FRI": return java.time.DayOfWeek.FRIDAY;
+ case "SAT": return java.time.DayOfWeek.SATURDAY;
+ case "SUN": return java.time.DayOfWeek.SUNDAY;
+ default: throw new IllegalArgumentException("鏃犳晥鐨勬槦鏈熷嚑: " + dayOfWeekStr);
+ }
+ }
+
+ /**
+ * 鍒涘缓淇濆吇璁板綍
+ */
+ private DeviceMaintenance createMaintenanceRecord(MaintenanceTask task, LocalDateTime executionDate) {
+ DeviceMaintenance record = new DeviceMaintenance();
+ record.setDeviceName(task.getTaskName());
+ record.setMaintenanceTaskId(task.getId());
+ record.setDeviceLedgerId(task.getTaskId());
+ record.setMaintenancePlanTime(executionDate);
+ record.setMaintenanceActuallyName(task.getMaintenancePerson());
+ record.setFrequencyType(task.getFrequencyType());
+ record.setFrequencyDetail(task.getFrequencyDetail());
+ record.setTenantId(task.getTenantId());
+ record.setStatus(0); // 寰呬繚鍏�
+ record.setDeviceModel(task.getDeviceModel());
+ record.setMachineryCategory(task.getMachineryCategory());
+ record.setCreateUser(Integer.parseInt(task.getRegistrantId().toString()));
+ record.setUpdateTime(executionDate);
+ record.setCreateTime(executionDate);
+ record.setUpdateUser(Integer.parseInt(task.getRegistrantId().toString()));
+ return record;
+ }
+
+ /**
+ * 鏇存柊浠诲姟鐨勬墽琛屾椂闂�
+ */
+ private void updateTaskExecutionTime(Long taskId, LocalDateTime lastExecutionTime, LocalDateTime nextExecutionTime) {
+ String sql = "UPDATE maintenance_task SET last_execution_time = ?, next_execution_time = ? WHERE id = ?";
+ jdbcTemplate.update(sql, lastExecutionTime, nextExecutionTime, taskId);
+ }
+
+ /**
+ * 璁$畻涓嬫鎵ц鏃堕棿
+ */
+ private LocalDateTime calculateNextExecutionTime(String frequencyType, String frequencyDetail, LocalDateTime currentTime) {
+ return switch (frequencyType) {
+ case "DAILY" -> calculateDailyNextTime(frequencyDetail, currentTime);
+ case "WEEKLY" -> calculateWeeklyNextTime(frequencyDetail, currentTime);
+ case "MONTHLY" -> calculateMonthlyNextTime(frequencyDetail, currentTime);
+ case "QUARTERLY" -> calculateQuarterlyNextTime(frequencyDetail, currentTime);
+ default -> throw new IllegalArgumentException("涓嶆敮鎸佺殑棰戞绫诲瀷: " + frequencyType);
+ };
+ }
+
+ 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 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 calculateWeeklyNextTime(String detail, LocalDateTime current) {
+ return current.plusWeeks(1);
+ }
+
+ 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());
+ }
+}
--
Gitblit v1.9.3