10 小时以前 d24942ee210bcc108fe9218c3a6c448afa613d00
src/main/java/com/ruoyi/inspectiontask/service/impl/InspectionTaskServiceImpl.java
@@ -5,20 +5,16 @@
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.StorageBlobDTO;
import com.ruoyi.basic.mapper.StorageAttachmentMapper;
import com.ruoyi.basic.mapper.StorageBlobMapper;
import com.ruoyi.basic.pojo.StorageBlob;
import com.ruoyi.basic.service.StorageAttachmentService;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.utils.MinioUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.device.mapper.DeviceAreaMapper;
import com.ruoyi.device.mapper.DeviceLedgerMapper;
import com.ruoyi.device.mapper.DeviceRepairMapper;
import com.ruoyi.device.pojo.DeviceArea;
import com.ruoyi.device.pojo.DeviceLedger;
import com.ruoyi.device.pojo.DeviceRepair;
import com.ruoyi.inspectiontask.dto.InspectionTaskDto;
import com.ruoyi.inspectiontask.mapper.InspectionTaskMapper;
import com.ruoyi.inspectiontask.pojo.InspectionTask;
@@ -36,9 +32,19 @@
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
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;
@@ -52,22 +58,13 @@
    private static final int INSPECTION_STATUS_PENDING = 1;
    private static final int INSPECTION_STATUS_COMPLETED = 2;
    private static final int INSPECTION_RESULT_NORMAL = 1;
    private static final int INSPECTION_RESULT_ABNORMAL = 2;
    private static final int DEVICE_REPAIR_STATUS_PENDING = 0;
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    @Autowired
    private InspectionTaskMapper inspectionTaskMapper;
    @Autowired
    private StorageAttachmentService storageAttachmentService;
    @Autowired
    private StorageBlobMapper storageBlobMapper;
    @Autowired
    private StorageAttachmentMapper storageAttachmentMapper;
    @Autowired
    private MinioUtils minioUtils;
    @Autowired
    private SysUserMapper sysUserMapper;
@@ -84,6 +81,9 @@
    @Autowired
    private DeviceAreaMapper deviceAreaMapper;
    @Autowired
    private DeviceRepairMapper deviceRepairMapper;
    @Override
    public IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) {
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
@@ -95,6 +95,7 @@
        if (inspectionTaskDto.getAreaId() != null) {
            queryWrapper.eq(InspectionTask::getAreaId, inspectionTaskDto.getAreaId());
        }
        LocalDateTime createTimeStart = inspectionTaskDto.getCreateTimeStart();
        LocalDateTime createTimeEnd = inspectionTaskDto.getCreateTimeEnd();
        if (createTimeStart == null && createTimeEnd == null) {
@@ -108,107 +109,383 @@
        if (createTimeEnd != null) {
            queryWrapper.le(InspectionTask::getCreateTime, createTimeEnd);
        }
        IPage<InspectionTask> entityPage = inspectionTaskMapper.selectPage(page, queryWrapper);
        //  无数据提前返回
        if (CollectionUtils.isEmpty(entityPage.getRecords())) {
            return new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal());
        List<InspectionTask> inspectionTasks = inspectionTaskMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(inspectionTasks)) {
            return new Page<>(page.getCurrent(), page.getSize(), 0);
        }
        // 获取id集合
        List<Long> ids = entityPage.getRecords().stream().map(InspectionTask::getId).collect(Collectors.toList());
        Map<Long, String> areaNameMap = buildAreaNameMap(entityPage.getRecords().stream()
        List<InspectionTaskDto> mergedRecords = mergeInspectionTasksByTimingId(inspectionTasks);
        return buildPagedResult(page, mergedRecords);
    }
    @Override
    public List<InspectionTaskDto> selectInspectionTaskRecordListByTimingId(Long timingId) {
        LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
        LocalDate today = LocalDate.now();
        queryWrapper.eq(InspectionTask::getTimingId, timingId);
        queryWrapper.ge(InspectionTask::getCreateTime, today.atStartOfDay());
        queryWrapper.le(InspectionTask::getCreateTime, today.atTime(23, 59, 59));
        queryWrapper.orderByDesc(InspectionTask::getCreateTime);
        queryWrapper.orderByDesc(InspectionTask::getId);
        List<InspectionTask> records = inspectionTaskMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(records)) {
            return new ArrayList<>();
        }
        return buildInspectionTaskDtoList(records);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrEditInspectionTask(List<InspectionTaskDto> inspectionTaskDtoList) throws IOException {
        if (CollectionUtils.isEmpty(inspectionTaskDtoList)) {
            return 0;
        }
        int affected = 0;
        // 同一次提交里同一区域只保留一条异常记录,用于后续生成一张维修单。
        Map<Long, InspectionTaskDto> abnormalAreaTaskMap = new LinkedHashMap<>();
        for (InspectionTaskDto inspectionTaskDto : inspectionTaskDtoList) {
            if (inspectionTaskDto == null) {
                continue;
            }
            InspectionTask savedTask = saveOrUpdateInspectionTask(inspectionTaskDto);
            affected++;
            if (Objects.equals(savedTask.getInspectionResult(), INSPECTION_RESULT_ABNORMAL) && savedTask.getAreaId() != null) {
                abnormalAreaTaskMap.putIfAbsent(savedTask.getAreaId(), copyRepairSourceTask(inspectionTaskDto, savedTask));
            }
        }
        createDeviceRepairRecords(abnormalAreaTaskMap);
        return affected;
    }
    private InspectionTask saveOrUpdateInspectionTask(InspectionTaskDto inspectionTaskDto) throws IOException {
        InspectionTask inspectionTask = new InspectionTask();
        BeanUtils.copyProperties(inspectionTaskDto, inspectionTask);
        boolean hasUploadedFiles = CollectionUtils.isNotEmpty(inspectionTaskDto.getTempFileIds());
        if (inspectionTask.getAreaId() == null && inspectionTask.getTaskId() != null) {
            DeviceLedger deviceLedger = deviceLedgerMapper.selectById(Long.valueOf(inspectionTask.getTaskId()));
            if (deviceLedger != null) {
                inspectionTask.setAreaId(deviceLedger.getAreaId());
            }
        }
        inspectionTask.setRegistrantId(SecurityUtils.getLoginUser().getUserId());
        inspectionTask.setRegistrant(SecurityUtils.getLoginUser().getUsername());
        if (inspectionTaskDto.getId() == null) {
            inspectionTask.setInspectionStatus(hasUploadedFiles ? INSPECTION_STATUS_COMPLETED : INSPECTION_STATUS_PENDING);
            inspectionTaskMapper.insert(inspectionTask);
        } else {
            if (hasUploadedFiles) {
                inspectionTask.setInspectionStatus(INSPECTION_STATUS_COMPLETED);
            } else if (inspectionTask.getInspectionStatus() == null) {
                InspectionTask existingTask = inspectionTaskMapper.selectById(inspectionTaskDto.getId());
                if (existingTask != null) {
                    inspectionTask.setInspectionStatus(existingTask.getInspectionStatus());
                }
            }
            inspectionTaskMapper.updateById(inspectionTask);
        }
        commonFileService.migrateTempFilesToFormal(inspectionTask.getId(), inspectionTaskDto.getTempFileIds());
        return inspectionTask;
    }
    private InspectionTaskDto copyRepairSourceTask(InspectionTaskDto sourceDto, InspectionTask savedTask) {
        InspectionTaskDto taskDto = new InspectionTaskDto();
        BeanUtils.copyProperties(sourceDto, taskDto);
        taskDto.setId(savedTask.getId());
        taskDto.setAreaId(savedTask.getAreaId());
        taskDto.setTaskId(savedTask.getTaskId());
        taskDto.setTaskName(savedTask.getTaskName());
        taskDto.setRemarks(savedTask.getRemarks());
        taskDto.setInspectionLocation(savedTask.getInspectionLocation());
        return taskDto;
    }
    private void createDeviceRepairRecords(Map<Long, InspectionTaskDto> abnormalAreaTaskMap) {
        if (abnormalAreaTaskMap.isEmpty()) {
            return;
        }
        LocalDate today = LocalDate.now();
        LocalDateTime startOfDay = today.atStartOfDay();
        LocalDateTime endOfDay = today.atTime(23, 59, 59);
        for (Map.Entry<Long, InspectionTaskDto> entry : abnormalAreaTaskMap.entrySet()) {
            Long areaId = entry.getKey();
            InspectionTaskDto inspectionTaskDto = entry.getValue();
            // 当天该区域已经有待维修单时直接跳过,避免重复生成。
            Long count = deviceRepairMapper.selectCount(new LambdaQueryWrapper<DeviceRepair>()
                    .eq(DeviceRepair::getAreaId, areaId)
                    .eq(DeviceRepair::getStatus, DEVICE_REPAIR_STATUS_PENDING)
                    .ge(DeviceRepair::getCreateTime, startOfDay)
                    .le(DeviceRepair::getCreateTime, endOfDay));
            if (count != null && count > 0) {
                continue;
            }
            DeviceRepair deviceRepair = new DeviceRepair();
            deviceRepair.setAreaId(areaId);
            if (inspectionTaskDto.getTaskId() != null) {
                deviceRepair.setDeviceLedgerId(Long.valueOf(inspectionTaskDto.getTaskId()));
            }
            deviceRepair.setRepairName(SecurityUtils.getLoginUser().getUsername());
            deviceRepair.setRepairTime(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));
            deviceRepair.setStatus(DEVICE_REPAIR_STATUS_PENDING);
            deviceRepair.setRemark(buildRepairRemark(inspectionTaskDto));
            deviceRepairMapper.insert(deviceRepair);
        }
    }
    private String buildRepairRemark(InspectionTaskDto inspectionTaskDto) {
        List<String> parts = new ArrayList<>();
        if (StringUtils.isNotBlank(inspectionTaskDto.getTaskName())) {
            parts.add("巡检任务:" + inspectionTaskDto.getTaskName());
        }
        if (StringUtils.isNotBlank(inspectionTaskDto.getInspectionLocation())) {
            parts.add("巡检地点:" + inspectionTaskDto.getInspectionLocation());
        }
        if (StringUtils.isNotBlank(inspectionTaskDto.getRemarks())) {
            parts.add("异常说明:" + inspectionTaskDto.getRemarks());
        } else {
            parts.add("异常说明:巡检异常自动生成维修单");
        }
        return String.join(";", parts);
    }
    private IPage<InspectionTaskDto> buildPagedResult(Page<InspectionTask> page, List<InspectionTaskDto> mergedRecords) {
        long requestedSize = page.getSize();
        long size = requestedSize <= 0 ? mergedRecords.size() : requestedSize;
        long current = page.getCurrent() <= 0 ? 1 : page.getCurrent();
        int fromIndex = (int) Math.min((current - 1) * size, mergedRecords.size());
        int toIndex = (int) Math.min(fromIndex + size, mergedRecords.size());
        Page<InspectionTaskDto> resultPage = new Page<>(current, size, mergedRecords.size());
        resultPage.setRecords(mergedRecords.subList(fromIndex, toIndex));
        return resultPage;
    }
    private List<InspectionTaskDto> mergeInspectionTasksByTimingId(List<InspectionTask> inspectionTasks) {
        Map<Long, String> areaNameMap = buildAreaNameMap(inspectionTasks.stream()
                .map(InspectionTask::getAreaId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));
        //登记人ids
        List<Long> registrantIds = entityPage.getRecords().stream().map(InspectionTask::getRegistrantId).collect(Collectors.toList());
        // 批量查询登记人
        Map<Long, SysUser> sysUserMap;
        if (!registrantIds.isEmpty()) {
            List<SysUser> sysUsers = sysUserMapper.selectUsersByIds(registrantIds);
            sysUserMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
        } else {
            sysUserMap = new HashMap<>();
        }
        //巡检人ids
        List<String> inspectorIds = entityPage.getRecords().stream().map(InspectionTask::getInspectorId).collect(Collectors.toList());
        Map<Long, SysUser> registrantMap = buildRegistrantMap(inspectionTasks);
        Map<Long, String> inspectorNameMap = buildInspectorNameMap(inspectionTasks);
        Map<Long, List<CommonFile>> commonFileMap = buildCommonFileMap(inspectionTasks);
        //获取所有不重复的用户ID
        Set<Long> allUserIds = entityPage.getRecords().stream()
                .map(InspectionTask::getInspectorId) // 获取"2,3"这样的字符串
        Map<String, List<InspectionTask>> groupedTasks = inspectionTasks.stream()
                .collect(Collectors.groupingBy(this::buildTimingGroupKey, LinkedHashMap::new, Collectors.toList()));
        // 列表接口按 timingId 聚合,同一个定时任务只返回一条。
        return groupedTasks.values().stream()
                .map(tasks -> buildMergedInspectionTaskDto(tasks, areaNameMap, registrantMap, inspectorNameMap, commonFileMap))
                .sorted(Comparator.comparing(InspectionTaskDto::getTimingId, Comparator.nullsLast(Long::compareTo))
                        .thenComparing(InspectionTaskDto::getCreateTime, Comparator.nullsLast(Comparator.reverseOrder())))
                .collect(Collectors.toList());
    }
    private List<InspectionTaskDto> buildInspectionTaskDtoList(List<InspectionTask> records) {
        Map<Long, String> areaNameMap = buildAreaNameMap(records.stream()
                .map(InspectionTask::getAreaId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));
        Map<Long, SysUser> registrantMap = buildRegistrantMap(records);
        Map<Long, String> inspectorNameMap = buildInspectorNameMap(records);
        Map<Long, List<CommonFile>> commonFileMap = buildCommonFileMap(records);
        return records.stream()
                .map(task -> buildInspectionTaskDto(task, areaNameMap, registrantMap, inspectorNameMap, commonFileMap))
                .collect(Collectors.toList());
    }
    private Map<Long, SysUser> buildRegistrantMap(List<InspectionTask> tasks) {
        List<Long> registrantIds = tasks.stream()
                .map(InspectionTask::getRegistrantId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (registrantIds.isEmpty()) {
            return new HashMap<>();
        }
        return sysUserMapper.selectUsersByIds(registrantIds).stream()
                .collect(Collectors.toMap(SysUser::getUserId, Function.identity()));
    }
    private Map<Long, String> buildInspectorNameMap(List<InspectionTask> tasks) {
        Set<Long> allUserIds = tasks.stream()
                .map(InspectionTask::getInspectorId)
                .filter(StringUtils::isNotBlank)
                .flatMap(idsStr -> Arrays.stream(idsStr.split(",")))
                .map(idStr -> {
                .map(String::trim)
                .map(this::parseLongSafely)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        if (allUserIds.isEmpty()) {
            return Collections.emptyMap();
        }
        return sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds)).stream()
                .collect(Collectors.toMap(SysUser::getUserId, SysUser::getNickName, (left, right) -> left));
    }
    private Map<Long, List<CommonFile>> buildCommonFileMap(List<InspectionTask> tasks) {
        List<Long> ids = tasks.stream()
                .map(InspectionTask::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (ids.isEmpty()) {
            return Collections.emptyMap();
        }
        List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
                .in(CommonFile::getCommonId, ids)
                .in(CommonFile::getType, Arrays.asList(
                        FileNameType.INSPECTION.getValue(),
                        FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue(),
                        FileNameType.INSPECTION_PRODUCTION_AFTER.getValue()
                )));
        if (commonFiles == null || commonFiles.isEmpty()) {
            return Collections.emptyMap();
        }
        return commonFiles.stream().collect(Collectors.groupingBy(CommonFile::getCommonId));
    }
    private String buildTimingGroupKey(InspectionTask inspectionTask) {
        return inspectionTask.getTimingId() != null ? "TIMING_" + inspectionTask.getTimingId() : "TASK_" + inspectionTask.getId();
    }
    private InspectionTaskDto buildMergedInspectionTaskDto(List<InspectionTask> tasks,
                                                           Map<Long, String> areaNameMap,
                                                           Map<Long, SysUser> registrantMap,
                                                           Map<Long, String> inspectorNameMap,
                                                           Map<Long, List<CommonFile>> commonFileMap) {
        List<InspectionTask> sortedTasks = tasks.stream()
                .sorted(Comparator.comparing(InspectionTask::getCreateTime, Comparator.nullsLast(Comparator.reverseOrder()))
                        .thenComparing(InspectionTask::getId, Comparator.nullsLast(Comparator.reverseOrder())))
                .collect(Collectors.toList());
        InspectionTask latestTask = sortedTasks.get(0);
        InspectionTaskDto dto = new InspectionTaskDto();
        BeanUtils.copyProperties(latestTask, dto);
        dto.setAreaName(areaNameMap.get(latestTask.getAreaId()));
        dto.setTaskName(joinDistinctValues(sortedTasks.stream().map(InspectionTask::getTaskName).collect(Collectors.toList())));
        dto.setInspectorId(joinDistinctValues(sortedTasks.stream()
                .map(InspectionTask::getInspectorId)
                .filter(StringUtils::isNotBlank)
                .flatMap(idsStr -> Arrays.stream(idsStr.split(",")))
                .map(String::trim)
                .collect(Collectors.toList())));
        dto.setInspector(joinDistinctValues(sortedTasks.stream()
                .map(InspectionTask::getInspectorId)
                .filter(StringUtils::isNotBlank)
                .flatMap(idsStr -> Arrays.stream(idsStr.split(",")))
                .map(String::trim)
                .map(idStr -> resolveInspectorName(idStr, inspectorNameMap))
                .collect(Collectors.toList())));
        dto.setRegistrant(joinDistinctValues(sortedTasks.stream()
                .map(InspectionTask::getRegistrantId)
                .filter(Objects::nonNull)
                .map(registrantMap::get)
                .filter(Objects::nonNull)
                .map(SysUser::getNickName)
                .collect(Collectors.toList())));
        dto.setRemarks(joinDistinctValues(sortedTasks.stream().map(InspectionTask::getRemarks).collect(Collectors.toList())));
        dto.setInspectionLocation(joinDistinctValues(sortedTasks.stream().map(InspectionTask::getInspectionLocation).collect(Collectors.toList())));
        dto.setFrequencyType(joinDistinctValues(sortedTasks.stream().map(InspectionTask::getFrequencyType).collect(Collectors.toList())));
        dto.setFrequencyDetail(joinDistinctValues(sortedTasks.stream().map(InspectionTask::getFrequencyDetail).collect(Collectors.toList())));
        dto.setInspectionStatus(sortedTasks.stream().allMatch(task -> Objects.equals(task.getInspectionStatus(), INSPECTION_STATUS_COMPLETED))
                ? INSPECTION_STATUS_COMPLETED : INSPECTION_STATUS_PENDING);
        List<Integer> inspectionResults = sortedTasks.stream()
                .map(InspectionTask::getInspectionResult)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (inspectionResults.isEmpty()) {
            dto.setInspectionResult(null);
        } else {
            dto.setInspectionResult(inspectionResults.stream().anyMatch(result -> Objects.equals(result, INSPECTION_RESULT_ABNORMAL))
                    ? INSPECTION_RESULT_ABNORMAL : INSPECTION_RESULT_NORMAL);
        }
        if (dto.getCreateTime() != null) {
            dto.setDateStr(dto.getCreateTime().format(DATE_FORMATTER));
        }
        List<CommonFile> mergedFiles = sortedTasks.stream()
                .map(InspectionTask::getId)
                .filter(Objects::nonNull)
                .map(commonFileMap::get)
                .filter(Objects::nonNull)
                .flatMap(List::stream)
                .collect(Collectors.toList());
        dto.setCommonFileList(filterCommonFilesByType(mergedFiles, FileNameType.INSPECTION.getValue()));
        dto.setCommonFileListBefore(filterCommonFilesByType(mergedFiles, FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue()));
        dto.setCommonFileListAfter(filterCommonFilesByType(mergedFiles, FileNameType.INSPECTION_PRODUCTION_AFTER.getValue()));
        return dto;
    }
    private InspectionTaskDto buildInspectionTaskDto(InspectionTask task,
                                                     Map<Long, String> areaNameMap,
                                                     Map<Long, SysUser> registrantMap,
                                                     Map<Long, String> inspectorNameMap,
                                                     Map<Long, List<CommonFile>> commonFileMap) {
        InspectionTaskDto dto = new InspectionTaskDto();
        BeanUtils.copyProperties(task, dto);
        dto.setAreaName(areaNameMap.get(task.getAreaId()));
        SysUser registrant = registrantMap.get(task.getRegistrantId());
        if (registrant != null) {
            dto.setRegistrant(registrant.getNickName());
        }
        if (StringUtils.isNotBlank(task.getInspectorId())) {
            dto.setInspector(Arrays.stream(task.getInspectorId().split(","))
                    .map(String::trim)
                    .map(idStr -> resolveInspectorName(idStr, inspectorNameMap))
                    .collect(Collectors.joining(",")));
        }
        if (task.getCreateTime() != null) {
            dto.setDateStr(task.getCreateTime().format(DATE_FORMATTER));
        }
        List<CommonFile> commonFiles = commonFileMap.getOrDefault(task.getId(), Collections.emptyList());
        dto.setCommonFileList(filterCommonFilesByType(commonFiles, FileNameType.INSPECTION.getValue()));
        dto.setCommonFileListBefore(filterCommonFilesByType(commonFiles, FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue()));
        dto.setCommonFileListAfter(filterCommonFilesByType(commonFiles, FileNameType.INSPECTION_PRODUCTION_AFTER.getValue()));
        return dto;
    }
    private Long parseLongSafely(String value) {
                    try {
                        return Long.parseLong(idStr.trim());
            return Long.parseLong(value);
                    } catch (NumberFormatException e) {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        // 使用SQL批量查询用户信息
        Map<Long, String> userIdToNameMap = allUserIds.isEmpty()
                ? Collections.emptyMap()
                : sysUserMapper.selectUsersByIds(new ArrayList<>(allUserIds))
                .stream()
                .collect(Collectors.toMap(
                        SysUser::getUserId,
                        SysUser::getNickName,
                        (existing, replacement) -> existing));
        //处理附件
        List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
                .in(CommonFile::getCommonId, ids)
                .in(CommonFile::getType, Arrays.asList(FileNameType.INSPECTION.getValue(), FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue(), FileNameType.INSPECTION_PRODUCTION_AFTER.getValue())));
        if(commonFiles == null){
            commonFiles = new ArrayList<>();
        }
        AtomicReference<List<CommonFile>> finalCommonFiles = new AtomicReference<>(commonFiles);
        List<InspectionTaskDto> dtoList = entityPage.getRecords().stream().map(inspectionTask -> {
            InspectionTaskDto dto = new InspectionTaskDto();
            BeanUtils.copyProperties(inspectionTask, dto);  // 复制主对象属性
            // 设置登记人
            SysUser sysUser = sysUserMap.get(inspectionTask.getRegistrantId());
            if (sysUser != null) {
                dto.setRegistrant(sysUser.getNickName());
            }
            dto.setAreaName(areaNameMap.get(inspectionTask.getAreaId()));
            // 处理巡检人名称
            if (StringUtils.isNotBlank(inspectionTask.getInspectorId())) {
                String inspectorNames = Arrays.stream(inspectionTask.getInspectorId().split(","))
                        .map(String::trim)
                        .map(idStr -> {
                            try {
                                Long userId = Long.parseLong(idStr);
                                return userIdToNameMap.getOrDefault(userId, "未知用户(" + idStr + ")");
                            } catch (NumberFormatException e) {
    private String resolveInspectorName(String idStr, Map<Long, String> inspectorNameMap) {
        Long userId = parseLongSafely(idStr);
        if (userId == null) {
                                return "无效ID(" + idStr + ")";
                            }
                        })
                        .collect(Collectors.joining(","));
                dto.setInspector(inspectorNames);
        return inspectorNameMap.getOrDefault(userId, "未知用户(" + idStr + ")");
            }
            dto.setDateStr(inspectionTask.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            finalCommonFiles.set(finalCommonFiles.get().stream().filter(commonFile -> commonFile.getCommonId().equals(inspectionTask.getId())).collect(Collectors.toList()));
            // 初始化三个附件列表
            dto.setCommonFileList(finalCommonFiles.get().stream().filter(commonFile -> commonFile.getType().equals(FileNameType.INSPECTION.getValue())).collect(Collectors.toList()));
            dto.setCommonFileListAfter(finalCommonFiles.get().stream().filter(commonFile -> commonFile.getType().equals(FileNameType.INSPECTION_PRODUCTION_AFTER.getValue())).collect(Collectors.toList()));
            dto.setCommonFileListBefore(finalCommonFiles.get().stream().filter(commonFile -> commonFile.getType().equals(FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue())).collect(Collectors.toList()));
    private String joinDistinctValues(List<String> values) {
        return values.stream()
                .filter(StringUtils::isNotBlank)
                .map(String::trim)
                .distinct()
                .collect(Collectors.joining(","));
    }
            return dto;
        }).collect(Collectors.toList());
        // 7. 构建返回分页对象
        IPage<InspectionTaskDto> resultPage = new Page<>();
        BeanUtils.copyProperties(entityPage, resultPage);
        resultPage.setRecords(dtoList);
        return resultPage;
    private List<CommonFile> filterCommonFilesByType(List<CommonFile> commonFiles, Integer type) {
        return commonFiles.stream()
                .filter(commonFile -> Objects.equals(commonFile.getType(), type))
                .collect(Collectors.toList());
    }
    private Map<Long, String> buildAreaNameMap(Set<Long> areaIds) {
@@ -219,65 +496,9 @@
                .collect(Collectors.toMap(DeviceArea::getId, DeviceArea::getAreaName, (left, right) -> left));
    }
    // 提取创建BlobDTO的公共方法
    private StorageBlobDTO createBlobDto(StorageBlob blob) {
        StorageBlobDTO dto = new StorageBlobDTO();
        BeanUtils.copyProperties(blob, dto);
        // 设置URL
        dto.setUrl(minioUtils.getPreviewUrls(
                blob.getBucketFilename(),
                blob.getBucketName(),
                true
        ));
        // 设置下载URL
        dto.setDownloadUrl(minioUtils.getDownloadUrls(
                blob.getBucketFilename(),
                blob.getBucketName(),
                blob.getOriginalFilename(),
                true
        ));
        return dto;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto) throws IOException {
        InspectionTask inspectionTask = new InspectionTask();
        BeanUtils.copyProperties(inspectionTaskDto, inspectionTask);
        boolean hasUploadedFiles = CollectionUtils.isNotEmpty(inspectionTaskDto.getTempFileIds());
        if (inspectionTask.getAreaId() == null && inspectionTask.getTaskId() != null) {
            DeviceLedger deviceLedger = deviceLedgerMapper.selectById(Long.valueOf(inspectionTask.getTaskId()));
            if (deviceLedger != null) {
                inspectionTask.setAreaId(deviceLedger.getAreaId());
            }
        }
        inspectionTask.setRegistrantId(SecurityUtils.getLoginUser().getUserId());
        inspectionTask.setRegistrant(SecurityUtils.getLoginUser().getUsername());
        int i;
        if (Objects.isNull(inspectionTaskDto.getId())) {
            inspectionTask.setInspectionStatus(hasUploadedFiles ? INSPECTION_STATUS_COMPLETED : INSPECTION_STATUS_PENDING);
            i = inspectionTaskMapper.insert(inspectionTask);
        } else {
            if (hasUploadedFiles) {
                inspectionTask.setInspectionStatus(INSPECTION_STATUS_COMPLETED);
            } else if (inspectionTask.getInspectionStatus() == null) {
                InspectionTask existingTask = inspectionTaskMapper.selectById(inspectionTaskDto.getId());
                if (existingTask != null) {
                    inspectionTask.setInspectionStatus(existingTask.getInspectionStatus());
                }
            }
            i = inspectionTaskMapper.updateById(inspectionTask);
        }
        commonFileService.migrateTempFilesToFormal(inspectionTask.getId(),inspectionTaskDto.getTempFileIds());
        return i;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delByIds(Long[] ids) {
        // 检查参数
        if (ids == null || ids.length == 0) {
            return 0;
        }
@@ -286,5 +507,4 @@
        commonFileService.deleteByBusinessIds(Arrays.asList(ids),FileNameType.INSPECTION_PRODUCTION_AFTER.getValue());
        return inspectionTaskMapper.deleteBatchIds(Arrays.asList(ids));
    }
}