From 17f2b62c65cf909adffd294ef9c1db50e3e9e9c8 Mon Sep 17 00:00:00 2001
From: aike <17730485278@139.com>
Date: Tue, 4 Nov 2025 16:07:06 +0800
Subject: [PATCH] =?UTF-8?q?demand:=20=20=20=20TMS=E7=B3=BB=E7=BB=9F=20-=20?=
=?UTF-8?q?=E5=AE=A2=E6=88=B7=E8=B4=A6=E5=8D=95=E7=AE=A1=E7=90=86=20-=20?=
=?UTF-8?q?=E8=B4=A2=E5=8A=A1=E5=BC=80=E7=A5=A8=E5=A4=84=E7=90=86=20-=20?=
=?UTF-8?q?=E5=B7=B2=E5=BC=80=E7=A5=A8=20-=20=E6=96=B0=E5=A2=9E=E5=8A=A0?=
=?UTF-8?q?=E2=80=9C=E5=AE=9A=E5=88=B6=E5=AF=BC=E5=87=BA=E2=80=9D=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD=20committer:=20heyu?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../EmisSettleInvoiceRecordController.java | 46 ++-
.../emis/domain/EmisSettleInvoiceRecord.java | 2 +-
.../EmisSettleInvoiceRecordExportVO.java | 47 +++
.../IEmisSettleInvoiceRecordService.java | 10 +
...misSettleInvoiceRecordCustomExcelUtil.java | 297 ++++++++++++++++++
.../EmisSettleInvoiceRecordServiceImpl.java | 265 +++++++++++++++-
6 files changed, 656 insertions(+), 11 deletions(-)
create mode 100644 emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecordExportVO.java
create mode 100644 emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/EmisSettleInvoiceRecordCustomExcelUtil.java
diff --git a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceRecordController.java b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceRecordController.java
index 172b5490d..41c7ec72d 100644
--- a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceRecordController.java
+++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceRecordController.java
@@ -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:
开票记录表 控制器
*/
@@ -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 list = emisSettleInvoiceRecordService
+ .selectCustomExportList(emisSettleInvoiceRecord);
+ EmisSettleInvoiceRecordCustomExcelUtil.exportCustomExcel(response, list, "开票记录表定制导出数据");
+ }
+
/**
* 获取开票记录表详细信息
*/
diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecord.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecord.java
index a811b199a..63e5c6878 100644
--- a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecord.java
+++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecord.java
@@ -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;
diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecordExportVO.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecordExportVO.java
new file mode 100644
index 000000000..5f50b5f50
--- /dev/null
+++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRecordExportVO.java
@@ -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;
+}
+
+
diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisSettleInvoiceRecordService.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisSettleInvoiceRecordService.java
index 49b1a2ba1..dca5e7162 100644
--- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisSettleInvoiceRecordService.java
+++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisSettleInvoiceRecordService.java
@@ -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 selectInvoiceRecordListByBillCodes(List billCodes);
+ /**
+ * 查询开票记录定制导出数据列表
+ *
+ * @param emisSettleInvoiceRecord 开票记录表
+ * @return 导出数据列表
+ */
+ public List selectCustomExportList(
+ EmisSettleInvoiceRecord emisSettleInvoiceRecord);
+
}
diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/EmisSettleInvoiceRecordCustomExcelUtil.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/EmisSettleInvoiceRecordCustomExcelUtil.java
new file mode 100644
index 000000000..c532f4aef
--- /dev/null
+++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/EmisSettleInvoiceRecordCustomExcelUtil.java
@@ -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 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();
+ }
+ }
+}
+
diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettleInvoiceRecordServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettleInvoiceRecordServiceImpl.java
index 27fc06f9f..8eb2cda3d 100644
--- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettleInvoiceRecordServiceImpl.java
+++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettleInvoiceRecordServiceImpl.java
@@ -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 selectCustomExportList(
+ EmisSettleInvoiceRecord emisSettleInvoiceRecord) {
+ // 查询开票记录列表
+ List invoiceRecordList = emisSettleInvoiceRecordMapper
+ .selectEmisSettleInvoiceRecordList(emisSettleInvoiceRecord);
+
+ List 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 customerNameList = new ArrayList<>();
+ List paymentDateList = new ArrayList<>();
+ List registerDateList = new ArrayList<>();
+ Set 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 paymentGroupMap = new HashMap<>(); // key: custName_tradeDate
+ Map registerGroupMap = new HashMap<>(); // key: custName_createTime
+
+ // 直接使用settleBillNo(多个用逗号分隔)查询支付关联记录
+ if (StringUtils.isNotBlank(record.getSettleBillNo())) {
+ // 根据settleBillNo查询支付关联记录
+ List payRelList = emisSettlePayRelMapper
+ .selectHasPayListBySettleBillNo(record.getSettleBillNo());
+
+ if (!CollectionUtils.isEmpty(payRelList)) {
+ // 获取所有payId
+ Set payIdSet = payRelList.stream()
+ .map(EmisSettlePayRel::getPayId)
+ .filter(StringUtils::isNotBlank)
+ .distinct()
+ .collect(Collectors.toSet());
+
+ // 按payId查询收款记录,建立payId到payRecord的映射
+ Map payRecordMap = new HashMap<>();
+ for (String payId : payIdSet) {
+ EmisSettlePayRecord queryPayRecord = new EmisSettlePayRecord();
+ queryPayRecord.setPayId(payId);
+ queryPayRecord.setDelFlag("0");
+ List 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 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;
+ }
+
}