liding
2025-05-15 56d1596d35e5de788c09f7a14e33a720a932c76e
src/main/java/com/ruoyi/purchase/service/impl/InvoicePurchaseServiceImpl.java
@@ -2,15 +2,38 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.purchase.dto.InvoicePurchaseDto;
import com.ruoyi.purchase.mapper.InvoicePurchaseMapper;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.pojo.InvoicePurchase;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.purchase.service.IInvoicePurchaseService;
import lombok.AllArgsConstructor;
import com.ruoyi.sales.mapper.CommonFileMapper;
import com.ruoyi.sales.pojo.CommonFile;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.Arrays;
import java.util.List;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 发票信息Service业务层处理
@@ -19,14 +42,80 @@
 * @date 2025-05-14
 */
@Service
@AllArgsConstructor
@RequiredArgsConstructor
@Slf4j
public class InvoicePurchaseServiceImpl extends ServiceImpl<InvoicePurchaseMapper, InvoicePurchase> implements IInvoicePurchaseService {
    private InvoicePurchaseMapper invoicePurchaseMapper;
    private final InvoicePurchaseMapper invoicePurchaseMapper;
    private final PurchaseLedgerMapper purchaseLedgerMapper;
    private final SysUserMapper userMapper;
    private final CommonFileMapper commonFileMapper;
    private final TempFileMapper tempFileMapper;
    @Value("${file.upload-dir}")
    private String uploadDir;
    @Override
    public List<InvoicePurchase> selectInvoicePurchaseList(InvoicePurchase invoicePurchase) {
        return invoicePurchaseMapper.selectList(new LambdaQueryWrapper<>());
    public List<InvoicePurchaseDto> selectInvoicePurchaseList(InvoicePurchaseDto invoicePurchaseDto) {
        // 构建发票查询条件
        LambdaQueryWrapper<InvoicePurchase> queryWrapper = new LambdaQueryWrapper<>();
        Optional.ofNullable(invoicePurchaseDto)
                .ifPresent(dto -> {
                    if (StringUtils.hasText(dto.getPurchaseContractNo())) {
                        queryWrapper.like(InvoicePurchase::getPurchaseContractNo, dto.getPurchaseContractNo());
                    }
                    if (StringUtils.hasText(dto.getSupplierName())) {
                        queryWrapper.like(InvoicePurchase::getSupplierName, dto.getSupplierName());
                    }
                    // 处理日期类型字段
                    if (dto.getIssueDate() != null) {
                        queryWrapper.eq(InvoicePurchase::getIssueDate,invoicePurchaseDto.getIssueDate());
                    }
                });
        // 查询发票列表
        List<InvoicePurchase> invoiceList = invoicePurchaseMapper.selectList(queryWrapper);
        // 如果没有查询到发票,直接返回空列表
        if (CollectionUtils.isEmpty(invoiceList)) {
            return Collections.emptyList();
        }
        // 提取所有发票ID
        List<Long> invoiceIds = invoiceList.stream()
                .map(InvoicePurchase::getId)
                .collect(Collectors.toList());
        // 批量查询这些发票关联的文件信息
        LambdaQueryWrapper<CommonFile> fileQueryWrapper = new LambdaQueryWrapper<>();
        fileQueryWrapper.in(CommonFile::getCommonId, invoiceIds)
                .eq(CommonFile::getType,"3");
        List<CommonFile> fileList = commonFileMapper.selectList(fileQueryWrapper);
        // 将文件信息映射到对应的发票ID
        Map<Long, String> fileMap = fileList.stream()
                .collect(Collectors.toMap(
                        CommonFile::getCommonId,
                        CommonFile::getName,
                        (existing, replacement) -> existing // 如果有多个文件,取第一个
                ));
        // 将文件信息设置到发票DTO中
        List<InvoicePurchaseDto> resultList = new ArrayList<>();
        for (InvoicePurchase invoice : invoiceList) {
            InvoicePurchaseDto dto = new InvoicePurchaseDto();
            // 将InvoicePurchase的属性复制到DTO
            BeanUtils.copyProperties(invoice, dto);
            // 设置文件名,如果存在的话
            dto.setFileName(fileMap.getOrDefault(invoice.getId(), null));
            resultList.add(dto);
        }
        return resultList;
    }
    @Override
@@ -35,11 +124,115 @@
    }
    @Override
    public int addOrUpdateInvoice(InvoicePurchase invoicePurchase) {
        if (invoicePurchase.getId() == null) {
            return invoicePurchaseMapper.insert(invoicePurchase);
    public int addOrUpdateInvoice(InvoicePurchaseDto invoicePurchaseDto) throws IOException {
        int i;
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(invoicePurchaseDto.getPurchaseLedgerId());
        InvoicePurchase invoicePurchase = new InvoicePurchase();
        BeanUtils.copyProperties(invoicePurchaseDto, invoicePurchase);
        invoicePurchase.setPurchaseContractNo(purchaseLedger.getPurchaseContractNumber());
        invoicePurchase.setSalesContractNo(purchaseLedger.getSalesContractNo());
        SysUser sysUser = userMapper.selectUserById(invoicePurchase.getIssUerId());
        invoicePurchase.setIssUer(sysUser.getNickName());
        invoicePurchase.setTenantId(purchaseLedger.getTenantId());
        if (invoicePurchaseDto.getId() == null) {
            i = invoicePurchaseMapper.insert(invoicePurchase);
        } else {
            return invoicePurchaseMapper.updateById(invoicePurchase);
            i = invoicePurchaseMapper.updateById(invoicePurchase);
        }
        // 迁移临时文件到正式目录
        if (invoicePurchaseDto.getTempFileIds() != null && !invoicePurchaseDto.getTempFileIds().isEmpty()) {
            migrateTempFilesToFormal(invoicePurchase.getId(), invoicePurchaseDto.getTempFileIds());
        }
        return i;
    }
    /**
     * 将临时文件迁移到正式目录
     *
     * @param businessId  业务ID(销售台账ID)
     * @param tempFileIds 临时文件ID列表
     * @throws IOException 文件操作异常
     */
    private void migrateTempFilesToFormal(Long businessId, List<String> tempFileIds) throws IOException {
        if (CollectionUtils.isEmpty(tempFileIds)) {
            return;
        }
        // 构建正式目录路径(按业务类型和日期分组)
        String formalDir = uploadDir + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        Path formalDirPath = Paths.get(formalDir);
        // 确保正式目录存在(递归创建)
        if (!Files.exists(formalDirPath)) {
            Files.createDirectories(formalDirPath);
        }
        for (String tempFileId : tempFileIds) {
            // 查询临时文件记录
            TempFile tempFile = tempFileMapper.selectById(tempFileId);
            if (tempFile == null) {
                log.warn("临时文件不存在,跳过处理: {}", tempFileId);
                continue;
            }
            // 构建正式文件名(包含业务ID和时间戳,避免冲突)
            String originalFilename = tempFile.getOriginalName();
            String fileExtension = FilenameUtils.getExtension(originalFilename);
            String formalFilename = businessId + "_" +
                    System.currentTimeMillis() + "_" +
                    UUID.randomUUID().toString().substring(0, 8) +
                    (com.ruoyi.common.utils.StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
            Path formalFilePath = formalDirPath.resolve(formalFilename);
            try {
                // 执行文件迁移(使用原子操作确保安全性)
                Files.move(
                        Paths.get(tempFile.getTempPath()),
                        formalFilePath,
                        StandardCopyOption.REPLACE_EXISTING,
                        StandardCopyOption.ATOMIC_MOVE
                );
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
                // 更新文件记录(关联到业务ID)
                CommonFile fileRecord = new CommonFile();
                fileRecord.setCommonId(businessId);
                fileRecord.setName(originalFilename);
                fileRecord.setUrl(formalFilePath.toString());
                fileRecord.setCreateTime(LocalDateTime.now());
                fileRecord.setType(tempFile.getType());
                commonFileMapper.insert(fileRecord);
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
            } catch (IOException e) {
                log.error("文件迁移失败: {}", tempFile.getTempPath(), e);
                // 可选择回滚事务或记录失败文件
                throw new IOException("文件迁移异常", e);
            }
        }
    }
    @Override
    public InvoicePurchaseDto getInvoiceById(InvoicePurchaseDto invoicePurchaseDto) {
        InvoicePurchase invoicePurchase = invoicePurchaseMapper.selectById(invoicePurchaseDto.getId());
        InvoicePurchaseDto resultDto = new InvoicePurchaseDto();
        BeanUtils.copyProperties(invoicePurchase, resultDto);
        // 查询上传文件
        LambdaQueryWrapper<CommonFile> commonFileLambdaQueryWrapper = new LambdaQueryWrapper<>();
        commonFileLambdaQueryWrapper.eq(CommonFile::getCommonId, invoicePurchaseDto.getId())
                .eq(CommonFile::getType, "3");
        List<CommonFile> commonFiles = commonFileMapper.selectList(commonFileLambdaQueryWrapper);
        resultDto.setCommonFiles(commonFiles);
        return resultDto;
    }
    @Override
    public List<InvoicePurchase> selectInvoicePurchaseLists(InvoicePurchase invoicePurchase) {
        return invoicePurchaseMapper.selectList(new LambdaQueryWrapper<>());
    }
}