wujianwei
2026-01-05 961f921a9d210a003e0e636255628c7b82d2049c
service/src/main/java/com/ruoyi/cwgl/service/impl/ReceivableFeeManagementServiceImpl.java
@@ -17,13 +17,13 @@
import com.ruoyi.common.utils.file.DownloadExportUtil;
import com.ruoyi.common.utils.file.DownloadExportUtil.ExprotStatus;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.cwgl.domain.ReceivableFeeDetail;
import com.ruoyi.cwgl.domain.ReceivableFeeManagementLog;
import com.ruoyi.cwgl.domain.*;
import com.ruoyi.cwgl.domain.vo.ReceivableFeeStatisticsVo;
import com.ruoyi.cwgl.service.*;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.service.ISystemDataNoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.stereotype.Service;
@@ -40,9 +40,6 @@
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.cwgl.mapper.ReceivableFeeManagementMapper;
import com.ruoyi.cwgl.domain.ReceivableFeeManagement;
import com.ruoyi.cwgl.domain.ReceivableBillManagement;
import com.ruoyi.cwgl.domain.ReceivableBillSettlementDetail;
import com.ruoyi.cwgl.domain.vo.ReceivableBillCreateVo;
import com.ruoyi.common.core.text.Convert;
@@ -83,6 +80,9 @@
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ITmsCustomerInfoService tmsCustomerInfoService;
    /**
     * 查询应收费用管理
@@ -611,10 +611,30 @@
                receivableFee.setCreateTime(now);
                receivableFee.setCreateBy(operName);
                
                // 根据客户名称查询客户ID
                if (receivableFee.getCustomerName() != null && !receivableFee.getCustomerName().isEmpty()) {
                    TmsCustomerInfo customerQuery = new TmsCustomerInfo();
                    customerQuery.setCustomerFullName(receivableFee.getCustomerName());
                    List<TmsCustomerInfo> customerList = tmsCustomerInfoService.selectTmsCustomerInfoList(customerQuery);
                    if (customerList != null && !customerList.isEmpty()) {
                        // 取第一个匹配的客户
                        TmsCustomerInfo customer = customerList.get(0);
                        receivableFee.setCustomerId(customer.getId());
                    } else {
                        // 如果没有找到匹配的客户,可以记录日志或抛出异常
                        logger.warn("未找到客户名称为 '{}' 的客户信息,customerId将设置为null", receivableFee.getCustomerName());
                    }
                }
                // 计算应收金额字符串描述
                if (receivableFee.getReceivableFeeDetailList() != null && !receivableFee.getReceivableFeeDetailList().isEmpty()) {
                    String receivableAmountStr = calculateReceivableAmountStr(receivableFee.getReceivableFeeDetailList());
                    receivableFee.setReceivableAmountStr(receivableAmountStr);
                }
                // 设置默认状态为待生成账单(0)
                if (receivableFee.getStatus() == null || receivableFee.getStatus().isEmpty()) {
                    receivableFee.setStatus("0");
                }
                
                // 插入主表数据
@@ -664,8 +684,20 @@
        DownloadExportUtil.deleteDownloadFile(redisCache, exportKey, ExprotStatus.XZZ.getStatus());
        
        try {
            // 创建多Sheet导入模板
            createMultiSheetImportTemplate(exportKey,fileName);
            // 创建空列表用于生成模板(只需要表头)
            List<ReceivableFeeManagement> mainList = new ArrayList<>();
            List<ReceivableFeeDetail> detailList = new ArrayList<>();
            // 使用我们新实现的exportMultiSheetData方法创建双sheet模板
            exportMultiSheetData(
                ReceivableFeeManagement.class,
                ReceivableFeeDetail.class,
                fileName,
                "应收费用主表",
                "应收费用明细",
                mainList,
                detailList
            );
            
            // 设置下载完成状态
            DownloadExportUtil.setDownloadFile(redisCache, exportKey, fileName);
@@ -676,192 +708,13 @@
            throw e;
        }
    }
    /**
     * 创建多Sheet导入模板
     * 包含Sheet1:应收费用主表模板
     * 包含Sheet2:应收费用明细表模板
     *
     * @param exportKey 导出功能的唯一标识
     * @param fileName
     */
    private void createMultiSheetImportTemplate(String exportKey, String fileName) {
        try {
            // 创建新的工作簿,包含两个Sheet
            SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
            // 创建主表Sheet
            Sheet mainSheet = workbook.createSheet("应收费用主表");
            createMainSheetTemplateWithExcelUtil(mainSheet);
            // 创建明细表Sheet
            Sheet detailSheet = workbook.createSheet("应收费用明细");
            createDetailSheetTemplateWithExcelUtil(detailSheet);
            // 保存工作簿到文件
            try (OutputStream out = Files.newOutputStream(Paths.get(getAbsoluteFile(fileName)))) {
                workbook.write(out);
            }
            workbook.close();
        } catch (Exception e) {
            logger.error("创建多Sheet导入模板失败: {}", e.getMessage(), e);
            throw new UtilException("导入模板生成失败!");
        }
    }
    /**
     * 使用ExcelUtil创建主表Sheet模板
     *
     * @param sheet Sheet对象
     */
    private void createMainSheetTemplateWithExcelUtil(Sheet sheet) {
        try {
            // 使用ExcelUtil创建主表模板
            ExcelUtil<ReceivableFeeManagement> mainSheetUtil = new ExcelUtil<>(ReceivableFeeManagement.class);
            // 初始化ExcelUtil
            mainSheetUtil.initialize("应收费用主表", "应收费用主表导入模板(请勿修改序号列)", Excel.Type.EXPORT);
            // 通过反射获取workbook字段
            Field workbookField = ExcelUtil.class.getDeclaredField("workbook");
            workbookField.setAccessible(true);
            SXSSFWorkbook excelUtilWorkbook = (SXSSFWorkbook) workbookField.get(mainSheetUtil);
            // 获取ExcelUtil生成的Sheet
            Sheet generatedSheet = excelUtilWorkbook.getSheetAt(0);
            // 复制标题行到目标Sheet
            copyRow(generatedSheet.getRow(0), sheet.createRow(0));
            // 复制表头行到目标Sheet
            copyRow(generatedSheet.getRow(1), sheet.createRow(1));
            // 添加说明行
            Row instructionRow = sheet.createRow(2);
            Cell instructionCell = instructionRow.createCell(0);
            instructionCell.setCellValue("说明:序号用于关联主表和明细表,请确保主表和明细表中的序号一致");
            // 设置列宽
            for (int i = 0; i < generatedSheet.getRow(1).getLastCellNum(); i++) {
                sheet.setColumnWidth(i, generatedSheet.getColumnWidth(i));
            }
        } catch (Exception e) {
            logger.error("使用ExcelUtil创建主表模板失败: {}", e.getMessage(), e);
            throw new UtilException("主表模板生成失败!");
        }
    }
    /**
     * 使用ExcelUtil创建明细表Sheet模板
     *
     * @param sheet Sheet对象
     */
    private void createDetailSheetTemplateWithExcelUtil(Sheet sheet) {
        try {
            // 使用ExcelUtil创建明细表模板
            ExcelUtil<ReceivableFeeDetail> detailSheetUtil = new ExcelUtil<>(ReceivableFeeDetail.class);
            // 初始化ExcelUtil
            detailSheetUtil.initialize("应收费用明细", "应收费用明细表导入模板(序号与主表对应)", Excel.Type.EXPORT);
            // 通过反射获取workbook字段
            Field workbookField = ExcelUtil.class.getDeclaredField("workbook");
            workbookField.setAccessible(true);
            SXSSFWorkbook excelUtilWorkbook = (SXSSFWorkbook) workbookField.get(detailSheetUtil);
            // 获取ExcelUtil生成的Sheet
            Sheet generatedSheet = excelUtilWorkbook.getSheetAt(0);
            // 复制标题行到目标Sheet
            copyRow(generatedSheet.getRow(0), sheet.createRow(0));
            // 复制表头行到目标Sheet
            copyRow(generatedSheet.getRow(1), sheet.createRow(1));
            // 添加说明行
            Row instructionRow = sheet.createRow(2);
            Cell instructionCell = instructionRow.createCell(0);
            instructionCell.setCellValue("说明:序号必须与主表中的序号一致,用于关联主表和明细表数据");
            // 设置列宽
            for (int i = 0; i < generatedSheet.getRow(1).getLastCellNum(); i++) {
                sheet.setColumnWidth(i, generatedSheet.getColumnWidth(i));
            }
        } catch (Exception e) {
            logger.error("使用ExcelUtil创建明细表模板失败: {}", e.getMessage(), e);
            throw new UtilException("明细表模板生成失败!");
        }
    }
    /**
     * 复制行内容
     *
     * @param sourceRow 源行
     * @param targetRow 目标行
     */
    private void copyRow(Row sourceRow, Row targetRow) {
        if (sourceRow == null) return;
        targetRow.setHeight(sourceRow.getHeight());
        for (int i = 0; i < sourceRow.getLastCellNum(); i++) {
            Cell sourceCell = sourceRow.getCell(i);
            if (sourceCell != null) {
                Cell targetCell = targetRow.createCell(i);
                copyCell(sourceCell, targetCell);
            }
        }
    }
    /**
     * 复制单元格内容和样式
     *
     * @param sourceCell 源单元格
     * @param targetCell 目标单元格
     */
    private void copyCell(Cell sourceCell, Cell targetCell) {
        // 复制单元格样式
        targetCell.setCellStyle(sourceCell.getCellStyle());
        // 复制单元格值
        switch (sourceCell.getCellType()) {
            case STRING:
                targetCell.setCellValue(sourceCell.getStringCellValue());
                break;
            case NUMERIC:
                targetCell.setCellValue(sourceCell.getNumericCellValue());
                break;
            case BOOLEAN:
                targetCell.setCellValue(sourceCell.getBooleanCellValue());
                break;
            case FORMULA:
                targetCell.setCellFormula(sourceCell.getCellFormula());
                break;
            default:
                targetCell.setCellValue(sourceCell.getStringCellValue());
        }
    }
    // 删除不再需要的方法
    /**
     * 获取文件的绝对路径
     *
     * @param fileName 文件名
     * @return 绝对路径
     */
    private String getAbsoluteFile(String fileName) {
    private File getAbsoluteFile(String fileName) {
        String downloadPath = RuoYiConfig.getDownloadPath();
        File desc = new File(downloadPath + File.separator + fileName);
        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                desc.getParentFile().mkdirs();
            }
        }
        return desc.getAbsolutePath();
        return new File(downloadPath + fileName);
    }
}