| | |
| | | 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; |
| | |
| | | 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; |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private RedisCache redisCache; |
| | | |
| | | @Autowired |
| | | private ITmsCustomerInfoService tmsCustomerInfoService; |
| | | |
| | | /** |
| | | * 查询应收费用管理 |
| | |
| | | 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"); |
| | | } |
| | | |
| | | // 插入主表数据 |
| | |
| | | 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); |
| | |
| | | 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); |
| | | } |
| | | } |