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.constant.StorageAttachmentConstants; 
 | 
import com.ruoyi.common.utils.MinioUtils; 
 | 
import com.ruoyi.common.utils.bean.BeanUtils; 
 | 
import com.ruoyi.inspectiontask.dto.QrCodeScanRecordDto; 
 | 
import com.ruoyi.inspectiontask.mapper.QrCodeMapper; 
 | 
import com.ruoyi.inspectiontask.mapper.QrCodeScanRecordMapper; 
 | 
import com.ruoyi.inspectiontask.pojo.QrCode; 
 | 
import com.ruoyi.inspectiontask.pojo.QrCodeScanRecord; 
 | 
import com.ruoyi.inspectiontask.service.QrCodeScanRecordService; 
 | 
import com.ruoyi.project.system.domain.SysUser; 
 | 
import com.ruoyi.project.system.mapper.SysUserMapper; 
 | 
import lombok.AllArgsConstructor; 
 | 
import lombok.Getter; 
 | 
import lombok.extern.slf4j.Slf4j; 
 | 
import org.springframework.beans.factory.annotation.Autowired; 
 | 
import org.springframework.stereotype.Service; 
 | 
  
 | 
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.QrCodeScanRecords; 
 | 
  
 | 
/** 
 | 
 * @author :yys 
 | 
 * @date : 2025/9/19 10:54 
 | 
 */ 
 | 
@Service 
 | 
@Slf4j 
 | 
public class QrCodeScanRecordServiceImpl extends ServiceImpl<QrCodeScanRecordMapper, QrCodeScanRecord> implements QrCodeScanRecordService { 
 | 
  
 | 
    @Autowired 
 | 
    private QrCodeScanRecordMapper qrCodeScanRecordMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private QrCodeMapper qrCodeMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private StorageAttachmentService storageAttachmentService; 
 | 
  
 | 
    @Autowired 
 | 
    private StorageBlobMapper storageBlobMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private StorageAttachmentMapper storageAttachmentMapper; 
 | 
  
 | 
    @Autowired 
 | 
    private MinioUtils minioUtils; 
 | 
  
 | 
    @Autowired 
 | 
    private SysUserMapper sysUserMapper; 
 | 
  
 | 
    @Override 
 | 
    public IPage<QrCodeScanRecordDto> selectQrCodeScanRecordList(Page<QrCodeScanRecord> page, QrCodeScanRecordDto qrCodeScanRecordDto) { 
 | 
        // 1. 构建基础查询条件 
 | 
        LambdaQueryWrapper<QrCodeScanRecord> queryWrapper = new LambdaQueryWrapper<>(); 
 | 
        queryWrapper.orderByDesc(QrCodeScanRecord::getCreateTime); 
 | 
  
 | 
        // 2. 执行分页查询 
 | 
        IPage<QrCodeScanRecord> scanRecordIPage = qrCodeScanRecordMapper.selectPage(page, queryWrapper); 
 | 
  
 | 
        // 3. 无数据提前返回 
 | 
        if (CollectionUtils.isEmpty(scanRecordIPage.getRecords())) { 
 | 
            return new Page<>(scanRecordIPage.getCurrent(), scanRecordIPage.getSize(), scanRecordIPage.getTotal()); 
 | 
        } 
 | 
  
 | 
        // 4. 批量获取所有记录ID和二维码ID 
 | 
        List<Long> recordIds = scanRecordIPage.getRecords().stream() 
 | 
                .map(QrCodeScanRecord::getId) 
 | 
                .collect(Collectors.toList()); 
 | 
  
 | 
        Set<Long> qrCodeIds = scanRecordIPage.getRecords().stream() 
 | 
                .map(QrCodeScanRecord::getQrCodeId) 
 | 
                .filter(Objects::nonNull) 
 | 
                .collect(Collectors.toSet()); 
 | 
  
 | 
        // 5. 批量查询关联数据(使用最新API) 
 | 
        // 5.1 查询二维码信息(替换selectBatchIds为selectByIds) 
 | 
        Map<Long, QrCode> qrCodeMap = qrCodeIds.isEmpty() 
 | 
                ? Collections.emptyMap() 
 | 
                : qrCodeMapper.selectBatchIds(qrCodeIds).stream() 
 | 
                .collect(Collectors.toMap(QrCode::getId, Function.identity())); 
 | 
  
 | 
        // 5.2 查询附件关联关系 
 | 
        Map<Long, List<StorageAttachment>> attachmentsMap = storageAttachmentMapper 
 | 
                .selectList(new LambdaQueryWrapper<StorageAttachment>() 
 | 
                        .in(StorageAttachment::getRecordId, recordIds) 
 | 
                        .eq(StorageAttachment::getRecordType, QrCodeScanRecords.ordinal())) 
 | 
                .stream() 
 | 
                .collect(Collectors.groupingBy(StorageAttachment::getRecordId)); 
 | 
  
 | 
        // 5.3 查询文件数据(使用selectByIds) 
 | 
        Set<Long> blobIds = attachmentsMap.values().stream() 
 | 
                .flatMap(List::stream) 
 | 
                .map(StorageAttachment::getStorageBlobId) 
 | 
                .collect(Collectors.toSet()); 
 | 
  
 | 
        Map<Long, StorageBlob> blobMap = blobIds.isEmpty() 
 | 
                ? Collections.emptyMap() 
 | 
                : storageBlobMapper.selectBatchIds(blobIds).stream() 
 | 
                .collect(Collectors.toMap(StorageBlob::getId, Function.identity())); 
 | 
  
 | 
        // 6. 组装DTO数据 
 | 
        List<QrCodeScanRecordDto> dtoList = scanRecordIPage.getRecords().stream().map(record -> { 
 | 
            QrCodeScanRecordDto dto = new QrCodeScanRecordDto(); 
 | 
            BeanUtils.copyProperties(record, dto); 
 | 
  
 | 
            SysUser sysUser = sysUserMapper.selectUserById(record.getScannerId()); 
 | 
            dto.setScanner(sysUser.getNickName()); 
 | 
  
 | 
            // 6.1 设置二维码信息 
 | 
            Optional.ofNullable(qrCodeMap.get(record.getQrCodeId())) 
 | 
                    .ifPresent(qrCode -> { 
 | 
                        BeanUtils.copyProperties(qrCode, dto); // 复制到父类 
 | 
                        dto.setQrCode(qrCode); // 设置完整对象 
 | 
                    }); 
 | 
  
 | 
            // 6.2 设置附件信息 
 | 
            dto.setStorageBlobDTO( 
 | 
                    Optional.ofNullable(attachmentsMap.get(record.getId())) 
 | 
                            .orElse(Collections.emptyList()) 
 | 
                            .stream() 
 | 
                            .map(att -> { 
 | 
                                StorageBlobDTO blobDTO = new StorageBlobDTO(); 
 | 
                                Optional.ofNullable(blobMap.get(att.getStorageBlobId())) 
 | 
                                        .ifPresent(blob -> { 
 | 
                                            BeanUtils.copyProperties(blob, blobDTO); 
 | 
                                            blobDTO.setUrl(minioUtils.getPreviewUrls(blob.getBucketFilename(), blob.getBucketName(), true)); 
 | 
                                            blobDTO.setDownloadUrl(minioUtils.getDownloadUrls(blob.getBucketFilename(),blob.getBucketName(),blob.getOriginalFilename(),true)); 
 | 
                                        }); 
 | 
                                return blobDTO; 
 | 
                            }) 
 | 
                            .filter(blobDTO -> blobDTO.getId() != null) // 过滤无效附件 
 | 
                            .collect(Collectors.toList()) 
 | 
            ); 
 | 
            return dto; 
 | 
        }).collect(Collectors.toList()); 
 | 
  
 | 
        // 7. 构建返回分页对象 
 | 
        IPage<QrCodeScanRecordDto> resultPage = new Page<>(); 
 | 
        BeanUtils.copyProperties(scanRecordIPage, resultPage); 
 | 
        resultPage.setRecords(dtoList); 
 | 
  
 | 
        return resultPage; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public int addOrEditQrCodeRecord(QrCodeScanRecordDto qrCodeScanRecordDto) { 
 | 
        QrCodeScanRecord qrCodeScanRecord = new QrCodeScanRecord(); 
 | 
        BeanUtils.copyProperties(qrCodeScanRecordDto, qrCodeScanRecord); 
 | 
        int i; 
 | 
        if (Objects.isNull(qrCodeScanRecordDto.getId())) { 
 | 
            i = qrCodeScanRecordMapper.insert(qrCodeScanRecord); 
 | 
        } else { 
 | 
            i = qrCodeScanRecordMapper.updateById(qrCodeScanRecord); 
 | 
        } 
 | 
  
 | 
        if (qrCodeScanRecordDto.getStorageBlobDTO() != null && !qrCodeScanRecordDto.getStorageBlobDTO().isEmpty()) { 
 | 
            List<StorageAttachment> attachments = new ArrayList<>(); 
 | 
  
 | 
            for (StorageBlobDTO storageBlobDTO : qrCodeScanRecordDto.getStorageBlobDTO()) { 
 | 
                StorageAttachment storageAttachment = new StorageAttachment( 
 | 
                        StorageAttachmentFile, 
 | 
                        (long) QrCodeScanRecords.ordinal(), 
 | 
                        qrCodeScanRecord.getId() 
 | 
                ); 
 | 
                storageAttachment.setStorageBlobDTO(storageBlobDTO); 
 | 
                attachments.add(storageAttachment); 
 | 
            } 
 | 
            storageAttachmentService.saveStorageAttachment(attachments, qrCodeScanRecord.getId(), QrCodeScanRecords, StorageAttachmentFile); 
 | 
        } 
 | 
        return i; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    public int delByIds(Long[] ids) { 
 | 
        return qrCodeScanRecordMapper.deleteBatchIds(Arrays.asList(ids)); 
 | 
    } 
 | 
  
 | 
} 
 |