From b7080587bc00e5451aa8435f093f0d8cc6f80320 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期五, 16 十月 2026 22:39:04 +0800
Subject: [PATCH] feat: 设备巡检优化,巡检项目拆分
---
src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java | 213 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 192 insertions(+), 21 deletions(-)
diff --git a/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java b/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
index 779dc5f..e4156bd 100644
--- a/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
+++ b/src/main/java/com/ruoyi/inspectiontask/service/impl/TimingTaskServiceImpl.java
@@ -4,11 +4,16 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.inspectiontask.dto.TimingTaskDto;
+import com.ruoyi.inspectiontask.mapper.InspectionItemMapper;
+import com.ruoyi.inspectiontask.mapper.TimingTaskItemMapper;
import com.ruoyi.inspectiontask.mapper.TimingTaskMapper;
+import com.ruoyi.inspectiontask.pojo.InspectionItem;
import com.ruoyi.inspectiontask.pojo.TimingTask;
+import com.ruoyi.inspectiontask.pojo.TimingTaskItem;
import com.ruoyi.inspectiontask.service.TimingTaskService;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
@@ -18,9 +23,24 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.time.*;
+import java.time.DayOfWeek;
+import java.time.DateTimeException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.Year;
+import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -35,9 +55,11 @@
private final TimingTaskMapper timingTaskMapper;
private final TimingTaskScheduler timingTaskScheduler;
private final SysUserMapper sysUserMapper;
+ private final InspectionItemMapper inspectionItemMapper;
+ private final TimingTaskItemMapper timingTaskItemMapper;
+
private static final int ENABLED = 1;
private static final int DISABLED = 0;
-
@Override
public IPage<TimingTaskDto> selectTimingTaskList(Page<TimingTask> page, TimingTask timingTask) {
@@ -47,12 +69,12 @@
if (StringUtils.isNotBlank(timingTask.getTaskName())) {
queryWrapper.like(TimingTask::getTaskName, timingTask.getTaskName());
}
- if (StringUtils.isNotBlank(timingTask.getInspectionProject())) {
- queryWrapper.like(TimingTask::getInspectionProject, timingTask.getInspectionProject());
- }
+ queryWrapper.eq(TimingTask::getDeleted, 0);
if (timingTask.getIsEnabled() != null) {
queryWrapper.eq(TimingTask::getIsEnabled, timingTask.getIsEnabled());
}
+ // 鎸� ID 鍊掑簭鎺掑簭
+ queryWrapper.orderByDesc(TimingTask::getId);
IPage<TimingTask> taskPage = timingTaskMapper.selectPage(page, queryWrapper);
// 2. 濡傛灉娌℃湁鏁版嵁锛岀洿鎺ヨ繑鍥炵┖鍒嗛〉
@@ -111,6 +133,16 @@
dto.setInspector(inspectorNickNames);
}
+ List<TimingTaskItem> taskItems = timingTaskItemMapper.selectList(
+ new LambdaQueryWrapper<TimingTaskItem>()
+ .eq(TimingTaskItem::getTimingTaskId, task.getId())
+ .orderByAsc(TimingTaskItem::getSortNum));
+ dto.setInspectionItems(taskItems);
+ dto.setInspectionItemIds(taskItems.stream()
+ .map(TimingTaskItem::getInspectionItemId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList()));
+
return dto;
}).collect(Collectors.toList());
@@ -130,6 +162,11 @@
throw new IllegalArgumentException("瀹氭椂浠诲姟涓嶅瓨鍦�");
}
}
+ List<InspectionItem> selectedItems = resolveSelectedItems(timingTaskDto, oldTimingTask);
+ List<TimingTaskItem> customItems = normalizeCustomItems(timingTaskDto.getCustomItems());
+ if (selectedItems.isEmpty() && customItems.isEmpty()) {
+ throw new ServiceException("璇烽�夋嫨鎴栨坊鍔犺嚦灏戜竴涓贰妫�鍐呭");
+ }
TimingTask timingTask = new TimingTask();
BeanUtils.copyProperties(timingTaskDto, timingTask);
timingTask.setIsEnabled(resolveEnabledValue(timingTask.getIsEnabled(), oldTimingTask));
@@ -137,7 +174,7 @@
// 1. 瑙f瀽瀛楃涓蹭负 LocalDate锛堝彧鍖呭惈骞存湀鏃ワ級
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate localDate = LocalDate.now();
- if(StringUtils.isNotEmpty(timingTaskDto.getDateStr())){
+ if (StringUtils.isNotEmpty(timingTaskDto.getDateStr())) {
localDate = LocalDate.parse(timingTaskDto.getDateStr(), formatter);
}
// 2. 鑾峰彇褰撳墠绯荤粺鐨� LocalTime锛堝寘鍚椂鍒嗙锛�
@@ -154,17 +191,23 @@
LocalDateTime firstExecutionTime = calculateFirstExecutionTime(timingTask);
timingTask.setNextExecutionTime(firstExecutionTime);
int result = timingTaskMapper.insert(timingTask);
+ if (result > 0) {
+ saveTaskItems(timingTask, selectedItems, customItems);
+ }
if (result > 0 && isEnabled(timingTask.getIsEnabled(), timingTask.isActive())) {
// 鏂板鎴愬姛鍚庢坊鍔犲埌璋冨害鍣�
timingTaskScheduler.scheduleTimingTask(timingTask);
}
return result;
} else {
-
-
int result = timingTaskMapper.updateById(timingTask);
if (result > 0) {
- boolean oldEnabled = isEnabled(oldTimingTask == null ? null : oldTimingTask.getIsEnabled(), oldTimingTask != null && oldTimingTask.isActive());
+ timingTaskItemMapper.delete(new LambdaQueryWrapper<TimingTaskItem>()
+ .eq(TimingTaskItem::getTimingTaskId, timingTask.getId()));
+ saveTaskItems(timingTask, selectedItems, customItems);
+ boolean oldEnabled = isEnabled(
+ oldTimingTask == null ? null : oldTimingTask.getIsEnabled(),
+ oldTimingTask != null && oldTimingTask.isActive());
boolean newEnabled = isEnabled(timingTask.getIsEnabled(), timingTask.isActive());
if (!newEnabled) {
timingTaskScheduler.unscheduleTimingTask(timingTask.getId());
@@ -180,8 +223,94 @@
}
}
+ private List<InspectionItem> resolveSelectedItems(TimingTask request, TimingTask oldTask) {
+ List<Long> itemIds = request.getInspectionItemIds();
+ if (itemIds == null && oldTask != null) {
+ itemIds = timingTaskItemMapper.selectList(new LambdaQueryWrapper<TimingTaskItem>()
+ .eq(TimingTaskItem::getTimingTaskId, oldTask.getId()))
+ .stream().map(TimingTaskItem::getInspectionItemId).filter(Objects::nonNull).toList();
+ }
+ if (request.getTaskId() == null || StringUtils.isBlank(request.getFrequencyType())) {
+ throw new ServiceException("璁惧鍜屽贰妫�棰戠巼涓嶈兘涓虹┖");
+ }
+ if (itemIds == null || itemIds.isEmpty()) {
+ return new ArrayList<>();
+ }
+ if (new HashSet<>(itemIds).size() != itemIds.size()) {
+ throw new ServiceException("宸℃鍐呭涓嶈兘閲嶅閫夋嫨");
+ }
+ List<InspectionItem> items = inspectionItemMapper.selectBatchIds(itemIds);
+ if (items.size() != itemIds.size()) {
+ throw new ServiceException("鎵�閫夊贰妫�鍐呭涓嶅瓨鍦�");
+ }
+ Long deviceId = request.getTaskId().longValue();
+ String frequency = request.getFrequencyType();
+ Set<Long> oldItemIds = oldTask == null ? Collections.emptySet()
+ : new HashSet<>(timingTaskItemMapper.selectList(new LambdaQueryWrapper<TimingTaskItem>()
+ .eq(TimingTaskItem::getTimingTaskId, oldTask.getId()))
+ .stream().map(TimingTaskItem::getInspectionItemId).filter(Objects::nonNull).toList());
+ boolean invalid = items.stream().anyMatch(item ->
+ (item.getDeviceLedgerId() != null && !deviceId.equals(item.getDeviceLedgerId()))
+ || !(frequency.equals(item.getFrequencyType()) || "ALL".equals(item.getFrequencyType()))
+ || (item.getDeleted() != null && item.getDeleted() == 1
+ || item.getIsActive() == null || item.getIsActive() != 1) && !oldItemIds.contains(item.getId()));
+ if (invalid) {
+ throw new ServiceException("鎵�閫夊贰妫�鍐呭涓庤澶囨垨棰戠巼涓嶅尮閰�");
+ }
+ Map<Long, InspectionItem> itemMap = items.stream()
+ .collect(Collectors.toMap(InspectionItem::getId, Function.identity()));
+ return itemIds.stream().map(itemMap::get).toList();
+ }
+
+ private List<TimingTaskItem> normalizeCustomItems(List<TimingTaskItem> customItems) {
+ if (customItems == null) {
+ return new ArrayList<>();
+ }
+ return customItems.stream()
+ .filter(Objects::nonNull)
+ .filter(item -> StringUtils.isNotBlank(item.getItemProject())
+ && StringUtils.isNotBlank(item.getItemContent()))
+ .peek(item -> {
+ item.setItemProject(item.getItemProject().trim());
+ item.setItemContent(item.getItemContent().trim());
+ })
+ .toList();
+ }
+
+ private void saveTaskItems(
+ TimingTask task,
+ List<InspectionItem> selectedItems,
+ List<TimingTaskItem> customItems) {
+ for (int index = 0; index < selectedItems.size(); index++) {
+ InspectionItem source = selectedItems.get(index);
+ TimingTaskItem taskItem = new TimingTaskItem();
+ taskItem.setTimingTaskId(task.getId());
+ taskItem.setInspectionItemId(source.getId());
+ taskItem.setItemProject(source.getItemProject());
+ taskItem.setItemContent(source.getItemContent());
+ taskItem.setSortNum(index);
+ taskItem.setTenantId(task.getTenantId());
+ taskItem.setDeptId(task.getDeptId());
+ timingTaskItemMapper.insert(taskItem);
+ }
+ for (int index = 0; index < customItems.size(); index++) {
+ TimingTaskItem source = customItems.get(index);
+ TimingTaskItem taskItem = new TimingTaskItem();
+ taskItem.setTimingTaskId(task.getId());
+ taskItem.setItemProject(source.getItemProject());
+ taskItem.setItemContent(source.getItemContent());
+ taskItem.setSortNum(selectedItems.size() + index);
+ taskItem.setTenantId(task.getTenantId());
+ taskItem.setDeptId(task.getDeptId());
+ timingTaskItemMapper.insert(taskItem);
+ }
+ }
+
public LocalDateTime calculateFirstExecutionTime(TimingTask task) {
// 鏍规嵁棰戠巼绫诲瀷鍜岃鎯呰绠楅娆℃墽琛屾椂闂�
+ if (task == null || StringUtils.isBlank(task.getFrequencyDetail())) {
+ throw new IllegalArgumentException("璇峰~鍐欎换鍔℃墽琛屾棩鏈熷拰鏃堕棿");
+ }
String frequencyType = task.getFrequencyType();
if ("DAILY".equals(frequencyType)) {
// 濡傛灉鏄瘡澶╂墽琛岋紝璁$畻浠婂ぉ鎴栨槑澶╃殑鍏蜂綋鏃堕棿
@@ -212,6 +341,7 @@
// 鏄犲皠鏄熸湡绠�鍐欎笌DayOfWeek
private static final Map<String, DayOfWeek> WEEK_DAY_MAP = new HashMap<>();
+
static {
WEEK_DAY_MAP.put("MON", DayOfWeek.MONDAY);
WEEK_DAY_MAP.put("TUE", DayOfWeek.TUESDAY);
@@ -314,7 +444,31 @@
}
private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) {
- return null;
+ String[] parts = frequencyDetail.split(",");
+ if (parts.length != 3) {
+ throw new IllegalArgumentException("瀛e害棰戠巼鏍煎紡閿欒锛屽簲涓�'瀛e害鍐呮湀浠�,鏃ユ湡,鏃堕棿'");
+ }
+ int monthInQuarter = Integer.parseInt(parts[0]);
+ int dayOfMonth = Integer.parseInt(parts[1]);
+ LocalTime time = LocalTime.parse(parts[2], DateTimeFormatter.ofPattern("HH:mm"));
+ if (monthInQuarter < 1 || monthInQuarter > 3 || dayOfMonth < 1 || dayOfMonth > 31) {
+ throw new IllegalArgumentException("瀛e害棰戠巼鏃ユ湡鏃犳晥");
+ }
+
+ LocalDateTime now = LocalDateTime.now();
+ int currentMonthInQuarter = (now.getMonthValue() - 1) % 3 + 1;
+ int monthsUntilTarget = monthInQuarter - currentMonthInQuarter;
+ if (monthsUntilTarget < 0) {
+ monthsUntilTarget += 3;
+ }
+ YearMonth targetMonth = YearMonth.from(now).plusMonths(monthsUntilTarget);
+ int targetDay = Math.min(dayOfMonth, targetMonth.lengthOfMonth());
+ LocalDateTime target = targetMonth.atDay(targetDay).atTime(time);
+ if (!target.isAfter(now)) {
+ targetMonth = targetMonth.plusMonths(3);
+ target = targetMonth.atDay(Math.min(dayOfMonth, targetMonth.lengthOfMonth())).atTime(time);
+ }
+ return target;
}
@Override
@@ -462,13 +616,27 @@
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;
+ 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);
}
}
@@ -496,12 +664,15 @@
return activeFallback;
}
-
-
@Override
public int delByIds(Long[] ids) {
+ if (ids == null || ids.length == 0) {
+ return 0;
+ }
int i = timingTaskMapper.deleteBatchIds(Arrays.asList(ids));
- if(i > 0){
+ if (i > 0) {
+ timingTaskItemMapper.delete(new LambdaQueryWrapper<TimingTaskItem>()
+ .in(TimingTaskItem::getTimingTaskId, Arrays.asList(ids)));
for (Long id : ids) {
timingTaskScheduler.unscheduleTimingTask(id);
}
--
Gitblit v1.9.3