package com.ruoyi.inspectiontask.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
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.StorageAttachment;
|
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.inspectiontask.dto.InspectionTaskDto;
|
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.InspectionTaskService;
|
import com.ruoyi.project.system.domain.SysUser;
|
import com.ruoyi.project.system.mapper.SysUserMapper;
|
import com.ruoyi.sales.mapper.CommonFileMapper;
|
import com.ruoyi.sales.pojo.CommonFile;
|
import com.ruoyi.sales.service.impl.CommonFileServiceImpl;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.io.IOException;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.*;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
import static com.ruoyi.common.constant.StorageAttachmentConstants.StorageAttachmentFile;
|
import static com.ruoyi.common.enums.StorageAttachmentRecordType.InspectionTasks;
|
|
/**
|
* @author :yys
|
* @date : 2025/9/19 10:54
|
*/
|
@Service
|
@Slf4j
|
public class InspectionTaskServiceImpl extends ServiceImpl<InspectionTaskMapper, InspectionTask> implements InspectionTaskService {
|
|
|
@Autowired
|
private InspectionTaskMapper inspectionTaskMapper;
|
|
@Autowired
|
private StorageAttachmentService storageAttachmentService;
|
|
@Autowired
|
private StorageBlobMapper storageBlobMapper;
|
|
@Autowired
|
private StorageAttachmentMapper storageAttachmentMapper;
|
|
@Autowired
|
private MinioUtils minioUtils;
|
|
@Autowired
|
private SysUserMapper sysUserMapper;
|
|
@Autowired
|
private CommonFileMapper commonFileMapper;
|
|
@Autowired
|
private CommonFileServiceImpl commonFileService;
|
|
@Autowired
|
private TimingTaskMapper timingTaskMapper;
|
|
@Override
|
public IPage<InspectionTaskDto> selectInspectionTaskList(Page<InspectionTask> page, InspectionTaskDto inspectionTaskDto) {
|
LambdaQueryWrapper<InspectionTask> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.orderByDesc(InspectionTask::getCreateTime);
|
if (StringUtils.isNotBlank(inspectionTaskDto.getTaskName())) {
|
queryWrapper.like(InspectionTask::getTaskName, inspectionTaskDto.getTaskName());
|
}
|
IPage<InspectionTask> entityPage = inspectionTaskMapper.selectPage(page, queryWrapper);
|
|
// 无数据提前返回
|
if (CollectionUtils.isEmpty(entityPage.getRecords())) {
|
return new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal());
|
}
|
// 获取id集合
|
List<Long> ids = entityPage.getRecords().stream().map(InspectionTask::getId).collect(Collectors.toList());
|
//登记人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());
|
|
//获取所有不重复的用户ID
|
Set<Long> allUserIds = entityPage.getRecords().stream()
|
.map(InspectionTask::getInspectorId) // 获取"2,3"这样的字符串
|
.filter(StringUtils::isNotBlank)
|
.flatMap(idsStr -> Arrays.stream(idsStr.split(",")))
|
.map(idStr -> {
|
try {
|
return Long.parseLong(idStr.trim());
|
} 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<>();
|
}
|
List<CommonFile> finalCommonFiles = commonFiles;
|
|
// 批量查询定时任务获取nextExecutionTime
|
List<Long> timingTaskIds = entityPage.getRecords().stream()
|
.map(InspectionTask::getTimingTaskId)
|
.filter(Objects::nonNull)
|
.collect(Collectors.toList());
|
Map<Long, TimingTask> timingTaskMap = new HashMap<>();
|
if (!timingTaskIds.isEmpty()) {
|
List<TimingTask> timingTasks = timingTaskMapper.selectBatchIds(timingTaskIds);
|
timingTaskMap = timingTasks.stream()
|
.collect(Collectors.toMap(TimingTask::getId, Function.identity()));
|
}
|
final Map<Long, TimingTask> finalTimingTaskMap = timingTaskMap;
|
final LocalDateTime now = LocalDateTime.now();
|
|
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());
|
}
|
// 处理巡检人名称
|
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) {
|
return "无效ID(" + idStr + ")";
|
}
|
})
|
.collect(Collectors.joining(","));
|
dto.setInspector(inspectorNames);
|
}
|
|
dto.setDateStr(inspectionTask.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
|
// 初始化三个附件列表,按commonId和type过滤
|
Long taskId = inspectionTask.getId();
|
dto.setCommonFileList(finalCommonFiles.stream()
|
.filter(commonFile -> commonFile.getCommonId().equals(taskId) && commonFile.getType().equals(FileNameType.INSPECTION.getValue()))
|
.collect(Collectors.toList()));
|
dto.setCommonFileListAfter(finalCommonFiles.stream()
|
.filter(commonFile -> commonFile.getCommonId().equals(taskId) && commonFile.getType().equals(FileNameType.INSPECTION_PRODUCTION_AFTER.getValue()))
|
.collect(Collectors.toList()));
|
dto.setCommonFileListBefore(finalCommonFiles.stream()
|
.filter(commonFile -> commonFile.getCommonId().equals(taskId) && commonFile.getType().equals(FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue()))
|
.collect(Collectors.toList()));
|
|
// 计算状态:已过期 > 巡检中 > 待巡检
|
String status = calculateStatus(inspectionTask, finalTimingTaskMap, now);
|
dto.setStatus(status);
|
|
// 设置nextExecutionTime用于前端展示
|
if (inspectionTask.getTimingTaskId() != null) {
|
TimingTask timingTask = finalTimingTaskMap.get(inspectionTask.getTimingTaskId());
|
if (timingTask != null) {
|
dto.setNextExecutionTime(timingTask.getNextExecutionTime());
|
}
|
}
|
|
return dto;
|
}).collect(Collectors.toList());
|
|
// 7. 构建返回分页对象
|
IPage<InspectionTaskDto> resultPage = new Page<>();
|
BeanUtils.copyProperties(entityPage, resultPage);
|
resultPage.setRecords(dtoList);
|
return resultPage;
|
}
|
|
// 提取创建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;
|
}
|
|
/**
|
* 计算巡检任务状态
|
* 优先级:已过期 > 巡检中 > 待巡检
|
* @param inspectionTask 巡检任务
|
* @param timingTaskMap 定时任务Map
|
* @param now 当前时间
|
* @return 状态:EXPIRED-已过期,IN_PROGRESS-巡检中,PENDING-待巡检
|
*/
|
private String calculateStatus(InspectionTask inspectionTask, Map<Long, TimingTask> timingTaskMap, LocalDateTime now) {
|
// 1. 判断是否已过期
|
if (inspectionTask.getTimingTaskId() != null) {
|
TimingTask timingTask = timingTaskMap.get(inspectionTask.getTimingTaskId());
|
if (timingTask != null && timingTask.getNextExecutionTime() != null) {
|
if (now.isAfter(timingTask.getNextExecutionTime())) {
|
return "EXPIRED";
|
}
|
}
|
}else {
|
return "EXPIRED";
|
}
|
|
// 2. 判断是否巡检中(任一异常字段不为null)
|
if (inspectionTask.getHasExceptionBefore() != null
|
|| inspectionTask.getHasExceptionAfter() != null
|
|| inspectionTask.getHasExceptionIssue() != null) {
|
return "IN_PROGRESS";
|
}
|
|
// 3. 待巡检
|
return "PENDING";
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int addOrEditInspectionTask(InspectionTaskDto inspectionTaskDto) throws IOException {
|
InspectionTask inspectionTask = new InspectionTask();
|
BeanUtils.copyProperties(inspectionTaskDto, inspectionTask);
|
inspectionTask.setRegistrantId(SecurityUtils.getLoginUser().getUserId());
|
inspectionTask.setRegistrant(SecurityUtils.getLoginUser().getUsername());
|
int i;
|
if (Objects.isNull(inspectionTaskDto.getId())) {
|
i = inspectionTaskMapper.insert(inspectionTask);
|
} else {
|
i = inspectionTaskMapper.updateById(inspectionTask);
|
// 编辑时处理附件删除逻辑
|
handleFileDeletion(inspectionTask.getId(), inspectionTaskDto);
|
}
|
|
commonFileService.migrateTempFilesToFormal(inspectionTask.getId(),inspectionTaskDto.getTempFileIds());
|
return i;
|
}
|
|
/**
|
* 处理附件删除逻辑:对比原有附件和传入的附件,删除被移除的附件
|
*/
|
private void handleFileDeletion(Long taskId, InspectionTaskDto inspectionTaskDto) {
|
// 查询原有的三种类型附件
|
List<CommonFile> existingFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>()
|
.eq(CommonFile::getCommonId, taskId)
|
.in(CommonFile::getType, Arrays.asList(
|
FileNameType.INSPECTION.getValue(),
|
FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue(),
|
FileNameType.INSPECTION_PRODUCTION_AFTER.getValue())));
|
|
if (CollectionUtils.isEmpty(existingFiles)) {
|
return;
|
}
|
|
// 获取前端传入的附件ID集合
|
Set<Long> submittedFileIds = new HashSet<>();
|
if (inspectionTaskDto.getCommonFileList() != null) {
|
inspectionTaskDto.getCommonFileList().stream()
|
.map(CommonFile::getId)
|
.filter(Objects::nonNull)
|
.forEach(submittedFileIds::add);
|
}
|
if (inspectionTaskDto.getCommonFileListBefore() != null) {
|
inspectionTaskDto.getCommonFileListBefore().stream()
|
.map(CommonFile::getId)
|
.filter(Objects::nonNull)
|
.forEach(submittedFileIds::add);
|
}
|
if (inspectionTaskDto.getCommonFileListAfter() != null) {
|
inspectionTaskDto.getCommonFileListAfter().stream()
|
.map(CommonFile::getId)
|
.filter(Objects::nonNull)
|
.forEach(submittedFileIds::add);
|
}
|
|
// 找出需要删除的附件ID(原有但前端没传的)
|
List<Long> toDeleteIds = existingFiles.stream()
|
.map(CommonFile::getId)
|
.filter(id -> !submittedFileIds.contains(id))
|
.collect(Collectors.toList());
|
|
// 删除附件
|
if (!toDeleteIds.isEmpty()) {
|
commonFileService.delCommonFileByIds(toDeleteIds.toArray(new Long[0]));
|
}
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int delByIds(Long[] ids) {
|
// 检查参数
|
if (ids == null || ids.length == 0) {
|
return 0;
|
}
|
commonFileService.deleteByBusinessIds(Arrays.asList(ids),FileNameType.INSPECTION.getValue());
|
commonFileService.deleteByBusinessIds(Arrays.asList(ids),FileNameType.INSPECTION_PRODUCTION_BEFORE.getValue());
|
commonFileService.deleteByBusinessIds(Arrays.asList(ids),FileNameType.INSPECTION_PRODUCTION_AFTER.getValue());
|
return inspectionTaskMapper.deleteBatchIds(Arrays.asList(ids));
|
}
|
|
}
|