demand: TMS系统 - 客户账单管理 - 财务开票处理 - 已开票 - 新增加“定制导出”功能

committer: heyu
This commit is contained in:
aike 2025-11-04 16:07:06 +08:00
parent 478a4b5bd2
commit 17f2b62c65
6 changed files with 656 additions and 11 deletions

View File

@ -1,11 +1,11 @@
/**
/**
* @Project: emis
* @Title: EmisSettleInvoiceRecordController.java
* @author linfso
* @date 2024-07-21 13:31:26
* @Copyright: ShangHai Duta 2022 All rights reserved.
* @version v1.0
* @version v1.0
* @Description: <p> 开票记录表 控制器 </p>
*/
@ -38,18 +38,19 @@ import com.xdadan.erp.common.utils.StringUtils;
import com.xdadan.erp.common.utils.poi.ExcelUtil;
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRecord;
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRecordExportVO;
import com.xdadan.erp.emis.service.IEmisSettleInvoiceRecordService;
import com.xdadan.erp.emis.service.excelCellStrategy.EmisSettleInvoiceRecordCustomExcelUtil;
/**
* 开票记录表Controller
*
*
* @author linfso
* @date 2024-07-21 13:31:26
*/
@RestController
@RequestMapping("/emis/emisSettleInvoiceRecord")
public class EmisSettleInvoiceRecordController extends BaseController
{
public class EmisSettleInvoiceRecordController extends BaseController {
@Autowired
private IEmisSettleInvoiceRecordService emisSettleInvoiceRecordService;
@ -83,8 +84,8 @@ public class EmisSettleInvoiceRecordController extends BaseController
/**
* 检查是否重复
*
* @param emisSettleInvoiceRecord
*
* @param emisSettleInvoiceRecord
* @return 数量
*/
@PreAuthorize("@ss.hasPermi('emis:emisSettleInvoiceRecord:list')")
@ -109,6 +110,37 @@ public class EmisSettleInvoiceRecordController extends BaseController
util.exportExcel(response, list, "开票记录表数据");
}
/**
* 定制导出开票记录表列表
*
*/
@PreAuthorize("@ss.hasPermi('emis:emisSettleInvoiceRecord:customExport')")
@Log(title = "开票记录表定制导出", businessType = BusinessType.EXPORT)
@PostMapping("/customExport")
public void customExport(HttpServletResponse response, EmisSettleInvoiceRecord emisSettleInvoiceRecord) {
setPrivParams(emisSettleInvoiceRecord);
if (!StringUtils.isEmpty(emisSettleInvoiceRecord.getSettleBillNo())) {
emisSettleInvoiceRecord
.setSettleBillNo(WaybillHelper.formatQueryValue(emisSettleInvoiceRecord.getSettleBillNo()));
}
if (!StringUtils.isEmpty(emisSettleInvoiceRecord.getInvoiceNo())) {
emisSettleInvoiceRecord
.setInvoiceNo(WaybillHelper.formatQueryValue(emisSettleInvoiceRecord.getInvoiceNo()));
}
if (emisSettleInvoiceRecord.getParams().get("billCode") != null) {
String billCodeStr = WaybillHelper
.formatQueryValue(emisSettleInvoiceRecord.getParams().get("billCode").toString());
emisSettleInvoiceRecord.getParams().put("billCode", billCodeStr);
}
List<EmisSettleInvoiceRecordExportVO> list = emisSettleInvoiceRecordService
.selectCustomExportList(emisSettleInvoiceRecord);
EmisSettleInvoiceRecordCustomExcelUtil.exportCustomExcel(response, list, "开票记录表定制导出数据");
}
/**
* 获取开票记录表详细信息
*/

View File

@ -98,7 +98,7 @@ public class EmisSettleInvoiceRecord extends BaseEntity
private BigDecimal recedMoney;
/* 付款状态 0-未付款 1-已付款 2-部分付款 */
private String paymentStatus;
/* 开票状态 0-待开票 1-已开票 2-拒绝开票 */
/* 开票状态 0-未开票 1-开票中 2-已开票 3-开票异常 */
private String invoiceStatus;
/* 开票状态描述 */
private String invoiceStatusDesc;

View File

@ -0,0 +1,47 @@
package com.xdadan.erp.emis.domain;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
* 开票记录定制导出VO
*
* @author heyu
* @date 2025-11-04
*/
@Data
public class EmisSettleInvoiceRecordExportVO {
// 发票申请日期
private Date applyDate;
// 发票申请人
private String applyManName;
// 申请开票金额
private BigDecimal applyMoney;
// 开票日期
private Date opDate;
// 开票人
private String opManName;
// 开票抬头
private String companyName;
// 发票号
private String invoiceNo;
// 账单编号(多个用逗号分隔)
private String billNos;
// 开票状态
private String invoiceStatusDesc;
// 收款状态
private String paymentStatusDesc;
// 已收金额
private BigDecimal recedMoney;
// 客户名称(多个用逗号分隔)
private String customerNames;
// 客户付款日期(多个用逗号分隔,格式:2025/10/30 付款2000元)
private String customerPaymentDates;
// 收款登记日期(多个用逗号分隔,格式:2025/10/30 登记2000元)
private String collectionRegisterDates;
// 账单类型(现金账单,月结账单)
private String billType;
}

View File

@ -12,6 +12,7 @@ package com.xdadan.erp.emis.service;
import java.util.List;
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRecord;
import com.xdadan.erp.emis.domain.exception.EmisBizError;
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRecordExportVO;
/**
* @ClassName EmisSettleInvoiceRecordService
@ -96,4 +97,13 @@ public interface IEmisSettleInvoiceRecordService {
*/
public List<EmisSettleInvoiceRecord> selectInvoiceRecordListByBillCodes(List<String> billCodes);
/**
* 查询开票记录定制导出数据列表
*
* @param emisSettleInvoiceRecord 开票记录表
* @return 导出数据列表
*/
public List<EmisSettleInvoiceRecordExportVO> selectCustomExportList(
EmisSettleInvoiceRecord emisSettleInvoiceRecord);
}

View File

@ -0,0 +1,297 @@
package com.xdadan.erp.emis.service.excelCellStrategy;
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRecordExportVO;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.List;
/**
* 开票记录定制导出Excel工具类
*
* @author heyu
* @date 2025-11-04
*/
public class EmisSettleInvoiceRecordCustomExcelUtil {
private static final String[] HEADERS = {
"发票申请日期", "发票申请人", "申请开票金额", "开票日期", "开票人", "开票抬头",
"发票号", "账单编号", "开票状态", "收款状态", "已收金额", "客户名称",
"客户付款日期", "收款登记日期", "账单类型"
};
private static final int[] COLUMN_WIDTHS = {
20, 15, 15, 20, 15, 30,
25, 25, 15, 15, 15, 30,
30, 30, 20
};
/**
* 导出定制Excel
*
* @param response HTTP响应
* @param dataList 数据列表
* @param sheetName 工作表名称
*/
public static void exportCustomExcel(HttpServletResponse response, List<EmisSettleInvoiceRecordExportVO> dataList,
String sheetName) {
try {
// 创建工作簿
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
Sheet sheet = workbook.createSheet(sheetName);
// 创建样式
CellStyle headerStyle = createHeaderStyle(workbook);
CellStyle dataStyle = createDataStyle(workbook);
CellStyle dateStyle = createDateStyle(workbook);
CellStyle numberStyle = createNumberStyle(workbook);
// 创建表头
createHeader(sheet, headerStyle);
// 填充数据
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
int rowIndex = 1;
for (EmisSettleInvoiceRecordExportVO data : dataList) {
Row row = sheet.createRow(rowIndex++);
// 发票申请日期
createCell(row, 0, data.getApplyDate() != null ? dateFormat.format(data.getApplyDate()) : "",
dateStyle);
// 发票申请人
createCell(row, 1, data.getApplyManName() != null ? data.getApplyManName() : "", dataStyle);
// 申请开票金额(去除末尾多余的0)
BigDecimal applyMoney = data.getApplyMoney();
if (applyMoney != null) {
applyMoney = applyMoney.stripTrailingZeros();
}
createCell(row, 2, applyMoney, numberStyle);
// 开票日期
createCell(row, 3, data.getOpDate() != null ? dateFormat.format(data.getOpDate()) : "", dateStyle);
// 开票人
createCell(row, 4, data.getOpManName() != null ? data.getOpManName() : "", dataStyle);
// 开票抬头
createCell(row, 5, data.getCompanyName() != null ? data.getCompanyName() : "", dataStyle);
// 发票号
createCell(row, 6, data.getInvoiceNo() != null ? data.getInvoiceNo() : "", dataStyle);
// 账单编号
createCell(row, 7, data.getBillNos() != null ? data.getBillNos() : "", dataStyle);
// 开票状态
createCell(row, 8, data.getInvoiceStatusDesc() != null ? data.getInvoiceStatusDesc() : "", dataStyle);
// 收款状态
createCell(row, 9, data.getPaymentStatusDesc() != null ? data.getPaymentStatusDesc() : "", dataStyle);
// 已收金额(去除末尾多余的0)
BigDecimal recedMoney = data.getRecedMoney();
if (recedMoney != null) {
recedMoney = recedMoney.stripTrailingZeros();
}
createCell(row, 10, recedMoney, numberStyle);
// 客户名称
createCell(row, 11, data.getCustomerNames() != null ? data.getCustomerNames() : "", dataStyle);
// 客户付款日期
createCell(row, 12, data.getCustomerPaymentDates() != null ? data.getCustomerPaymentDates() : "",
dataStyle);
// 收款登记日期
createCell(row, 13, data.getCollectionRegisterDates() != null ? data.getCollectionRegisterDates() : "",
dataStyle);
// 账单类型
createCell(row, 14, data.getBillType() != null ? data.getBillType() : "", dataStyle);
}
// 设置列宽
setColumnWidths(sheet);
// 输出文件
outputFile(response, workbook, sheetName);
} catch (Exception e) {
throw new RuntimeException("导出Excel失败:" + e.getMessage(), e);
}
}
/**
* 创建表头样式
*/
private static CellStyle createHeaderStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
// 设置字体
Font font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12);
font.setBold(true);
style.setFont(font);
// 设置背景色(绿色)
style.setFillForegroundColor(IndexedColors.LIGHT_GREEN.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// 设置边框
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
// 设置对齐方式
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
return style;
}
/**
* 创建数据样式
*/
private static CellStyle createDataStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
// 设置字体
Font font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12);
style.setFont(font);
// 设置边框
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
// 设置对齐方式
style.setAlignment(HorizontalAlignment.LEFT);
style.setVerticalAlignment(VerticalAlignment.CENTER);
return style;
}
/**
* 创建日期样式
*/
private static CellStyle createDateStyle(Workbook workbook) {
CellStyle style = createDataStyle(workbook);
style.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd hh:mm"));
return style;
}
/**
* 创建数字样式
*/
private static CellStyle createNumberStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
// 设置字体
Font font = workbook.createFont();
font.setFontName("宋体");
font.setFontHeightInPoints((short) 12);
style.setFont(font);
// 设置边框
style.setBorderTop(BorderStyle.THIN);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
// 设置数字格式
style.setDataFormat(workbook.createDataFormat().getFormat("#,##0.00"));
// 设置对齐方式
style.setAlignment(HorizontalAlignment.RIGHT);
style.setVerticalAlignment(VerticalAlignment.CENTER);
return style;
}
/**
* 创建表头
*/
private static void createHeader(Sheet sheet, CellStyle headerStyle) {
Row headerRow = sheet.createRow(0);
headerRow.setHeightInPoints(25);
for (int i = 0; i < HEADERS.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(HEADERS[i]);
cell.setCellStyle(headerStyle);
}
}
/**
* 创建单元格
*/
private static void createCell(Row row, int columnIndex, String value, CellStyle style) {
Cell cell = row.createCell(columnIndex);
cell.setCellValue(value != null ? value : "");
cell.setCellStyle(style);
}
/**
* 创建数字单元格(去除末尾多余的0)
*/
private static void createCell(Row row, int columnIndex, BigDecimal value, CellStyle style) {
Cell cell = row.createCell(columnIndex);
// 如果BigDecimal值为null或为0,则设置为空字符串
if (value == null || value.compareTo(BigDecimal.ZERO) == 0) {
cell.setCellValue("");
} else {
// 去除末尾多余的0,然后使用toPlainString()避免科学计数法
BigDecimal stripped = value.stripTrailingZeros();
// 如果scale为负数,说明有尾随0被移除,需要重新构造
if (stripped.scale() < 0) {
stripped = stripped.setScale(0);
}
cell.setCellValue(stripped.toPlainString());
}
cell.setCellStyle(style);
}
/**
* 设置列宽
*/
private static void setColumnWidths(Sheet sheet) {
for (int i = 0; i < COLUMN_WIDTHS.length; i++) {
sheet.setColumnWidth(i, COLUMN_WIDTHS[i] * 256);
}
}
/**
* 输出文件
*/
private static void outputFile(HttpServletResponse response, Workbook workbook, String sheetName)
throws IOException {
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(sheetName + ".xlsx", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName);
// 输出文件
try (OutputStream outputStream = response.getOutputStream()) {
workbook.write(outputStream);
workbook.close();
}
}
}

View File

@ -11,9 +11,7 @@
package com.xdadan.erp.emis.service.impl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
import com.xdadan.erp.emis.domain.*;
import com.xdadan.erp.emis.domain.enumtype.EmisBizErrorType;
@ -22,9 +20,18 @@ import com.xdadan.erp.emis.mapper.EmisSettleBillMapper;
import com.xdadan.erp.emis.mapper.EmisSettleInvoiceRelMapper;
import com.xdadan.erp.emis.mapper.EmisSettleSubBillMapper;
import com.xdadan.erp.emis.mapper.EmisCustomerInvoiceInfoMapper;
import com.xdadan.erp.emis.mapper.EmisWaybillMapper;
import com.xdadan.erp.emis.mapper.EmisSettlePayRelMapper;
import com.xdadan.erp.emis.service.EmisBaseService;
import com.xdadan.erp.emis.service.IEmisSettleBillService;
import com.xdadan.erp.emis.utils.WaybillHelper;
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRecordExportVO;
import com.xdadan.erp.emis.domain.EmisSettlePayRecord;
import com.xdadan.erp.emis.domain.EmisWaybill;
import com.xdadan.erp.emis.domain.EmisSettleBill;
import java.text.SimpleDateFormat;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@ -66,6 +73,12 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
@Autowired
private EmisSettlePayRecordMapper emisSettlePayRecordMapper;
@Autowired
private EmisWaybillMapper emisWaybillMapper;
@Autowired
private EmisSettlePayRelMapper emisSettlePayRelMapper;
/**
* 查询开票记录表
*
@ -377,4 +390,250 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
return emisSettleInvoiceRecordMapper.selectInvoiceRecordListByBillCodes(billCodes);
}
/**
* 查询开票记录定制导出数据列表
*
* @param emisSettleInvoiceRecord 开票记录表
* @return 导出数据列表
*/
@Override
public List<EmisSettleInvoiceRecordExportVO> selectCustomExportList(
EmisSettleInvoiceRecord emisSettleInvoiceRecord) {
// 查询开票记录列表
List<EmisSettleInvoiceRecord> invoiceRecordList = emisSettleInvoiceRecordMapper
.selectEmisSettleInvoiceRecordList(emisSettleInvoiceRecord);
List<EmisSettleInvoiceRecordExportVO> exportList = new ArrayList<>();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
for (EmisSettleInvoiceRecord record : invoiceRecordList) {
EmisSettleInvoiceRecordExportVO exportVO = new EmisSettleInvoiceRecordExportVO();
// 基础字段
exportVO.setApplyDate(record.getApplyDate());
exportVO.setApplyManName(record.getApplyManName());
exportVO.setApplyMoney(record.getApplyMoney());
exportVO.setOpDate(record.getOpDate());
exportVO.setOpManName(record.getOpManName());
exportVO.setCompanyName(record.getCompanyName());
exportVO.setInvoiceNo(record.getInvoiceNo());
// 开票状态(0-未开票 1-开票中 2-已开票 3-开票异常)
String invoiceStatusDesc = "";
if ("0".equals(record.getInvoiceStatus())) {
invoiceStatusDesc = "未开票";
} else if ("1".equals(record.getInvoiceStatus())) {
invoiceStatusDesc = "开票中";
} else if ("2".equals(record.getInvoiceStatus())) {
invoiceStatusDesc = "已开票";
} else if ("3".equals(record.getInvoiceStatus())) {
invoiceStatusDesc = "开票异常";
}
exportVO.setInvoiceStatusDesc(invoiceStatusDesc);
exportVO.setRecedMoney(record.getRecedMoney());
// 收款状态描述
String paymentStatusDesc = "";
if ("0".equals(record.getPaymentStatus())) {
paymentStatusDesc = "未收款";
} else if ("1".equals(record.getPaymentStatus())) {
paymentStatusDesc = "已收款";
} else if ("2".equals(record.getPaymentStatus())) {
paymentStatusDesc = "部分收款";
}
exportVO.setPaymentStatusDesc(paymentStatusDesc);
List<String> customerNameList = new ArrayList<>();
List<String> paymentDateList = new ArrayList<>();
List<String> registerDateList = new ArrayList<>();
Set<String> settleTypeSet = new HashSet<>(); // 使用Set去重
// 查询账单类型(从settle_bill获取)
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
String[] settleBillNoArr = Arrays.stream(record.getSettleBillNo().split(",")).distinct()
.toArray(String[]::new);
exportVO.setBillNos(record.getSettleBillNo());
for (String settleBillNo : settleBillNoArr) {
if (StringUtils.isNotBlank(settleBillNo)) {
EmisSettleBill settleBill = emisSettleBillService
.selectEmisSettleBillBySettleBillNo(settleBillNo.trim());
if (settleBill != null && StringUtils.isNotBlank(settleBill.getSettleType())) {
if ("1".equals(settleBill.getSettleType())) {
settleTypeSet.add("现金账单");
} else if ("2".equals(settleBill.getSettleType())) {
settleTypeSet.add("月结账单");
}
}
}
}
}
// 根据发票对应的多个账单号查询emis_settle_pay_rel并关联emis_settle_pay_record、emis_waybill
// 按照cust_name、trade_date分组(客户付款日期)
// 按照cust_name、create_time分组(收款登记日期)
Map<String, PaymentGroup> paymentGroupMap = new HashMap<>(); // key: custName_tradeDate
Map<String, PaymentGroup> registerGroupMap = new HashMap<>(); // key: custName_createTime
// 直接使用settleBillNo(多个用逗号分隔)查询支付关联记录
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
// 根据settleBillNo查询支付关联记录
List<EmisSettlePayRel> payRelList = emisSettlePayRelMapper
.selectHasPayListBySettleBillNo(record.getSettleBillNo());
if (!CollectionUtils.isEmpty(payRelList)) {
// 获取所有payId
Set<String> payIdSet = payRelList.stream()
.map(EmisSettlePayRel::getPayId)
.filter(StringUtils::isNotBlank)
.distinct()
.collect(Collectors.toSet());
// 按payId查询收款记录,建立payId到payRecord的映射
Map<String, EmisSettlePayRecord> payRecordMap = new HashMap<>();
for (String payId : payIdSet) {
EmisSettlePayRecord queryPayRecord = new EmisSettlePayRecord();
queryPayRecord.setPayId(payId);
queryPayRecord.setDelFlag("0");
List<EmisSettlePayRecord> payRecordList = emisSettlePayRecordMapper
.selectEmisSettlePayRecordList(queryPayRecord);
if (!CollectionUtils.isEmpty(payRecordList)) {
// 只处理收款记录(recType = "1"),不包括退款
EmisSettlePayRecord payRecord = payRecordList.stream()
.filter(pr -> "1".equals(pr.getRecType()))
.findFirst()
.orElse(null);
if (payRecord != null) {
payRecordMap.put(payId, payRecord);
}
}
}
// 遍历支付关联记录,按billNo查询waybill,按cust_name和trade_date/create_time分组
for (EmisSettlePayRel payRel : payRelList) {
if (payRel.getPayMoney() == null
|| payRel.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
String billNo = payRel.getBillNo();
if (StringUtils.isBlank(billNo)) {
continue;
}
// 查询waybill获取客户名称
String custName = "";
EmisWaybill waybill = emisWaybillMapper.selectWaybillBaseInfoByBillCode(billNo);
if (waybill != null && StringUtils.isNotBlank(waybill.getCustName())) {
custName = waybill.getCustName();
// 收集客户名称
if (!customerNameList.contains(custName)) {
customerNameList.add(custName);
}
}
// 获取对应的收款记录
EmisSettlePayRecord payRecord = payRecordMap.get(payRel.getPayId());
if (payRecord == null) {
continue;
}
Date tradeDate = payRecord.getTradeDate();
Date createTime = payRecord.getCreateTime();
// 客户付款日期分组(按custName + tradeDate分组)
// 即使custName为空,也要记录付款日期
if (tradeDate != null) {
String tradeDateStr = dateFormat.format(tradeDate);
String paymentKey = (StringUtils.isNotBlank(custName) ? custName : "") + "_" + tradeDateStr;
PaymentGroup paymentGroup = paymentGroupMap.get(paymentKey);
if (paymentGroup == null) {
paymentGroup = new PaymentGroup();
paymentGroup.custName = custName != null ? custName : "";
paymentGroup.date = tradeDate;
paymentGroup.dateStr = tradeDateStr;
paymentGroup.totalMoney = BigDecimal.ZERO;
paymentGroupMap.put(paymentKey, paymentGroup);
}
paymentGroup.totalMoney = paymentGroup.totalMoney.add(payRel.getPayMoney());
}
// 收款登记日期分组(按custName + createTime分组)
// 即使custName为空,也要记录登记日期
if (createTime != null) {
String createTimeStr = dateFormat.format(createTime);
String registerKey = (StringUtils.isNotBlank(custName) ? custName : "") + "_"
+ createTimeStr;
PaymentGroup registerGroup = registerGroupMap.get(registerKey);
if (registerGroup == null) {
registerGroup = new PaymentGroup();
registerGroup.custName = custName != null ? custName : "";
registerGroup.date = createTime;
registerGroup.dateStr = createTimeStr;
registerGroup.totalMoney = BigDecimal.ZERO;
registerGroupMap.put(registerKey, registerGroup);
}
registerGroup.totalMoney = registerGroup.totalMoney.add(payRel.getPayMoney());
}
}
}
}
// 格式化客户付款日期(格式:2025/10/30 付款2000元 A公司)
for (PaymentGroup group : paymentGroupMap.values()) {
BigDecimal strippedMoney = group.totalMoney.stripTrailingZeros();
String paymentDateStr = group.dateStr + " 付款" + strippedMoney.toPlainString() + "元";
// 如果客户名称不为空,则追加客户名称
if (StringUtils.isNotBlank(group.custName)) {
paymentDateStr += " " + group.custName;
}
paymentDateList.add(paymentDateStr);
}
// 格式化收款登记日期(格式:2025/10/30 登记2000元 A公司)
for (PaymentGroup group : registerGroupMap.values()) {
BigDecimal strippedMoney = group.totalMoney.stripTrailingZeros();
String registerDateStr = group.dateStr + " 登记" + strippedMoney.toPlainString() + "元";
// 如果客户名称不为空,则追加客户名称
if (StringUtils.isNotBlank(group.custName)) {
registerDateStr += " " + group.custName;
}
registerDateList.add(registerDateStr);
}
// 设置客户名称(多个用逗号分隔)
if (!CollectionUtils.isEmpty(customerNameList)) {
exportVO.setCustomerNames(String.join(",", customerNameList));
}
// 设置客户付款日期(多个用逗号分隔)
if (!CollectionUtils.isEmpty(paymentDateList)) {
exportVO.setCustomerPaymentDates(String.join(";", paymentDateList));
}
// 设置收款登记日期(多个用逗号分隔)
if (!CollectionUtils.isEmpty(registerDateList)) {
exportVO.setCollectionRegisterDates(String.join(";", registerDateList));
}
// 设置账单类型(多个用逗号分隔)
if (!settleTypeSet.isEmpty()) {
List<String> settleTypeList = new ArrayList<>(settleTypeSet);
exportVO.setBillType(String.join(",", settleTypeList));
}
exportList.add(exportVO);
}
return exportList;
}
/**
* 付款分组内部类
*/
private static class PaymentGroup {
String custName;
Date date;
String dateStr;
BigDecimal totalMoney;
}
}