diff --git a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisTmsSiteBatchMissStatisticsController.java b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisTmsSiteBatchMissStatisticsController.java new file mode 100644 index 000000000..eef6a9c0a --- /dev/null +++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisTmsSiteBatchMissStatisticsController.java @@ -0,0 +1,107 @@ +package com.xdadan.erp.web.emis; + +import com.xdadan.erp.common.annotation.Log; +import com.xdadan.erp.common.core.controller.BaseController; +import com.xdadan.erp.common.core.page.TableDataInfo; +import com.xdadan.erp.common.enums.BusinessType; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMissStatistics; +import com.xdadan.erp.emis.service.IEmisTmsSiteBatchMissStatisticsService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.List; + +import static com.xdadan.erp.common.utils.PageUtils.startPage; + +/** + * 漏组批次统计Controller + * + * @author heyu + * @date 2025-09-27 + */ +@RestController +@RequestMapping("/emis/emisTmsSiteBatchMissStatistics") +@Slf4j +public class EmisTmsSiteBatchMissStatisticsController extends BaseController { + + @Autowired + private IEmisTmsSiteBatchMissStatisticsService statisticsService; + + /** + * 查询漏组批次统计列表 + */ + @PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMissStatistics:list')") + @GetMapping("/list") + public TableDataInfo list(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { + try { + startPage(); + List list = statisticsService + .selectStatisticsList(emisTmsSiteBatchMissStatistics); + return getDataTable(list); + } catch (Exception e) { + log.error("查询漏组批次统计列表失败", e); + TableDataInfo tableDataInfo = getDataTable(new ArrayList<>()); + tableDataInfo.setCode(500); + tableDataInfo.setMsg("查询失败:" + e.getMessage()); + return tableDataInfo; + } + } + + /** + * 导出漏组详细数据(按月份分sheet) + * 优化版本:支持异步处理、流式导出、缓存优化 + */ + @PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMissStatistics:exportDetail')") + @Log(title = "漏组详细数据导出", businessType = BusinessType.EXPORT) + @PostMapping("/exportDetail") + public void exportDetail(HttpServletResponse response, + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { + try { + // 设置响应头,支持流式传输 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Cache-Control", "no-cache"); + response.setHeader("Pragma", "no-cache"); + response.setHeader("Expires", "0"); + + // 异步流式导出,避免内存溢出 + statisticsService.exportDetailDataByMonthStream(response, emisTmsSiteBatchMissStatistics); + } catch (Exception e) { + log.error("导出漏组详细数据失败", e); + try { + // 检查响应是否已经开始 + if (!response.isCommitted()) { + response.reset(); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().write("{\"success\":false,\"message\":\"导出失败:" + e.getMessage() + "\"}"); + } + } catch (Exception ex) { + log.error("写入错误信息失败", ex); + } + } + } + + /** + * 导出漏组批次统计查询接口数据 + */ + @PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMissStatistics:exportStatistics')") + @Log(title = "漏组批次统计导出", businessType = BusinessType.EXPORT) + @PostMapping("/exportStatistics") + public void exportStatistics(HttpServletResponse response, + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { + try { + statisticsService.exportStatisticsData(response, emisTmsSiteBatchMissStatistics); + } catch (Exception e) { + log.error("导出漏组批次统计数据失败", e); + try { + response.getWriter().write("导出失败:" + e.getMessage()); + } catch (Exception ex) { + log.error("写入错误信息失败", ex); + } + } + } +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRel.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRel.java index 13398f2e3..cb800ba7e 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRel.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceRel.java @@ -23,16 +23,14 @@ import java.math.BigDecimal; import java.util.Date; import lombok.Data; - /** * @ClassName EmisSettleInvoiceRel * @Description 开票子账单关联表 * @author linfso * @date 2024-07-21 13:31:27 */ - @Data -public class EmisSettleInvoiceRel extends BaseEntity -{ +@Data +public class EmisSettleInvoiceRel extends BaseEntity { private static final long serialVersionUID = 1L; /* id */ @@ -46,8 +44,10 @@ public class EmisSettleInvoiceRel extends BaseEntity private String billNo; /* 申请开票金额 */ private BigDecimal money; + /* 已收金额 */ + private BigDecimal recedMoney; - // 扩展参数 + // 扩展参数 private EmisWaybill waybillDetail; } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettlePayRel.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettlePayRel.java index e72f3109b..fd61dd5ea 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettlePayRel.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettlePayRel.java @@ -1,10 +1,10 @@ -/** +/** * @Project: emis * @Title: EmisSettlePayRel.java * @author linfso * @date 2024-07-21 13:31:24 * @Copyright: ShangHai Duta 2022 All rights reserved. - * @version v1.0 + * @version v1.0 * @Description:

支付子账单关联表 实体类

*/ @@ -44,6 +44,8 @@ public class EmisSettlePayRel extends BaseEntity private String billNo; /* 金额 */ private BigDecimal payMoney; + /* 发票申请序号 */ + private String applySeqNo; // 扩展参数 private EmisWaybill waybillDetail; diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissExport.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissExport.java new file mode 100644 index 000000000..b4df2f265 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissExport.java @@ -0,0 +1,99 @@ +package com.xdadan.erp.emis.domain; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * 漏组批次信息导出DTO + * 根据实际Excel截图字段设计,专门用于Excel导出 + * + * @author heyu + * @date 2025-09-27 + */ +@Data +public class EmisTmsSiteBatchMissExport { + + @ExcelProperty("运单号") + private String billCode; + + @ExcelProperty("稽核时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date auditTime; + + @ExcelProperty("发货日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + private Date sendDate; + + @ExcelProperty("异常提示") + private String missReason; + + @ExcelProperty("起始节点") + private String startSiteName; + + @ExcelProperty("下一节点") + private String nextSiteName; + + @ExcelProperty("寄件网点") + private String sendSiteName; + + @ExcelProperty("线路") + private String lineName; + + @ExcelProperty("产品类型") + private String productTypeName; + + @ExcelProperty("供应商") + private String supplierName; + + @ExcelProperty("寄件国") + private String sendCountryName; + + @ExcelProperty("目的国") + private String receiveCountryName; + + @ExcelProperty("支付方式") + private String paymentType; + + @ExcelProperty("件数") + private Integer parcelQty; + + @ExcelProperty("实际重量") + private BigDecimal billWeight; + + @ExcelProperty("总体积") + private BigDecimal totalVolume; + + @ExcelProperty("节点负责") + private String manager; + + @ExcelProperty("线路负责") + private String transManager; + + @ExcelProperty("是否问题") + private String blIsQuestion; + + @ExcelProperty("录单备注") + private String waybillRemark; + + @ExcelProperty("目的网点") + private String destinationName; + + @ExcelProperty("修改原因") + private String manualRemark; + + @ExcelProperty("完成状态") + private String blManual; + + @ExcelProperty("销售联系") + private String salesmen; + + @ExcelProperty("回款联系") + private String payee; + + @ExcelProperty("录入人") + private String registerManName; +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissStatistics.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissStatistics.java new file mode 100644 index 000000000..7bb4d6195 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissStatistics.java @@ -0,0 +1,36 @@ +package com.xdadan.erp.emis.domain; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.xdadan.erp.common.core.domain.BaseEntity; +import lombok.Data; + +import java.util.Date; + +/** + * 漏组批次统计查询结果DTO + * + * @author heyu + * @date 2025-09-27 + */ +@Data +public class EmisTmsSiteBatchMissStatistics extends BaseEntity { + + /** 起始网点编码 */ + private String startSiteCode; + + /** 起始网点名称 */ + private String startSiteName; + + /** 寄件月份(精确到月) */ + @JsonFormat(pattern = "yyyy-MM", timezone = "GMT+8") + private Date billMonth; + + /** 票数 */ + private Integer ticketCount; + + /** 开始月份(含),格式:yyyy-MM */ + private String startTime; + + /** 结束月份(含),格式:yyyy-MM */ + private String endTime; +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissStatisticsExport.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissStatisticsExport.java new file mode 100644 index 000000000..dc6311901 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisTmsSiteBatchMissStatisticsExport.java @@ -0,0 +1,56 @@ +package com.xdadan.erp.emis.domain; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +/** + * 漏组批次统计导出DTO + * + * @author heyu + * @date 2025-09-27 + */ +@Data +public class EmisTmsSiteBatchMissStatisticsExport { + + @ExcelProperty("始发网点") + private String startSiteName; + + @ExcelProperty("汇总票数") + private Integer totalTicketCount; + + @ExcelProperty("1月票数") + private Integer januaryCount; + + @ExcelProperty("2月票数") + private Integer februaryCount; + + @ExcelProperty("3月票数") + private Integer marchCount; + + @ExcelProperty("4月票数") + private Integer aprilCount; + + @ExcelProperty("5月票数") + private Integer mayCount; + + @ExcelProperty("6月票数") + private Integer juneCount; + + @ExcelProperty("7月票数") + private Integer julyCount; + + @ExcelProperty("8月票数") + private Integer augustCount; + + @ExcelProperty("9月票数") + private Integer septemberCount; + + @ExcelProperty("10月票数") + private Integer octoberCount; + + @ExcelProperty("11月票数") + private Integer novemberCount; + + @ExcelProperty("12月票数") + private Integer decemberCount; +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisTmsSiteBatchMissStatisticsMapper.java b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisTmsSiteBatchMissStatisticsMapper.java new file mode 100644 index 000000000..120c32606 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/mapper/EmisTmsSiteBatchMissStatisticsMapper.java @@ -0,0 +1,54 @@ +package com.xdadan.erp.emis.mapper; + +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMiss; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMissStatistics; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 漏组批次统计Mapper接口 + * + * @author heyu + * @date 2025-09-27 + */ +public interface EmisTmsSiteBatchMissStatisticsMapper { + + /** + * 查询漏组批次统计列表 + * + * @param emisTmsSiteBatchMissStatistics 查询条件对象 + * @return 统计结果列表 + */ + List selectStatisticsList( + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics); + + /** + * 查询漏组详细数据列表(按月份分组) + * + * @param emisTmsSiteBatchMissStatistics 查询条件 + * @return 详细数据列表 + */ + List selectDetailDataByMonth(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics); + + /** + * 分页查询漏组详细数据列表(按月份分组)- 性能优化版本 + * + * @param emisTmsSiteBatchMissStatistics 查询条件 + * @param offset 偏移量 + * @param limit 限制数量 + * @return 详细数据列表 + */ + List selectDetailDataByMonthWithPaging( + @Param("query") EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics, + @Param("offset") int offset, + @Param("limit") int limit); + + /** + * 统计漏组详细数据总数 + * + * @param emisTmsSiteBatchMissStatistics 查询条件 + * @return 总记录数 + */ + long countDetailDataByMonth(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics); +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisTmsSiteBatchMissStatisticsService.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisTmsSiteBatchMissStatisticsService.java new file mode 100644 index 000000000..2d464eef2 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/IEmisTmsSiteBatchMissStatisticsService.java @@ -0,0 +1,45 @@ +package com.xdadan.erp.emis.service; + +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMiss; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMissStatistics; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMissStatisticsExport; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 漏组批次统计Service接口 + * + * @author heyu + * @date 2025-09-27 + */ +public interface IEmisTmsSiteBatchMissStatisticsService { + + /** + * 查询漏组批次统计列表 + * + * @param emisTmsSiteBatchMissStatistics 查询条件 + * @return 统计结果列表 + */ + List selectStatisticsList( + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics); + + /** + * 流式导出漏组详细数据(按月份分sheet)- 性能优化版本 + * 支持大数据量导出,避免内存溢出 + * + * @param response HTTP响应 + * @param emisTmsSiteBatchMissStatistics 查询条件 + */ + void exportDetailDataByMonthStream(HttpServletResponse response, + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics); + + /** + * 导出漏组批次统计查询接口数据 + * + * @param response HTTP响应 + * @param emisTmsSiteBatchMissStatistics 查询条件 + */ + void exportStatisticsData(HttpServletResponse response, + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics); +} diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettlePayRecordServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettlePayRecordServiceImpl.java index 32c95ffbe..bd5674035 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettlePayRecordServiceImpl.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisSettlePayRecordServiceImpl.java @@ -1,12 +1,12 @@ - /** - * @Project: emis - * @Title: EmisSettlePayRecordServiceImpl.java - * @author linfso - * @date 2024-07-21 13:31:24 - * @Copyright: ShangHai Duta 2022 All rights reserved. - * @version v1.0 - * @Description:

账单收退款记录 实体类

- */ +/** +* @Project: emis +* @Title: EmisSettlePayRecordServiceImpl.java +* @author linfso +* @date 2024-07-21 13:31:24 +* @Copyright: ShangHai Duta 2022 All rights reserved. +* @version v1.0 +* @Description:

账单收退款记录 实体类

+*/ package com.xdadan.erp.emis.service.impl; @@ -15,8 +15,11 @@ import java.time.LocalDate; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -75,6 +78,12 @@ public class EmisSettlePayRecordServiceImpl extends EmisBaseService implements I @Autowired private EmisSettlePayInvoiceRelMapper emisSettlePayInvoiceRelMapper; + @Autowired + private EmisSettleSubBillMapper emisSettleSubBillMapper; + + @Autowired + private EmisWaybillMapper emisWaybillMapper; + /** * 查询账单收退款记录 * @@ -82,8 +91,7 @@ public class EmisSettlePayRecordServiceImpl extends EmisBaseService implements I * @return 账单收退款记录 */ @Override - public EmisSettlePayRecord selectEmisSettlePayRecordById(Long id) - { + public EmisSettlePayRecord selectEmisSettlePayRecordById(Long id) { return emisSettlePayRecordMapper.selectEmisSettlePayRecordById(id); } @@ -446,7 +454,8 @@ public class EmisSettlePayRecordServiceImpl extends EmisBaseService implements I emisSettlePayRecord.setSettleBillNo(WaybillHelper.formatQueryValue(emisSettlePayRecord.getSettleBillNo())); // 多账单合并收款 - List settleBillNoArr = Arrays.stream(emisSettlePayRecord.getSettleBillNo().split(",")).distinct().collect(Collectors.toList()); + List settleBillNoArr = Arrays.stream(emisSettlePayRecord.getSettleBillNo().split(",")).distinct() + .collect(Collectors.toList()); for (int i = 0; i < settleBillNoArr.size(); i++) { String settleBillNo = settleBillNoArr.get(i); @@ -514,13 +523,17 @@ public class EmisSettlePayRecordServiceImpl extends EmisBaseService implements I // 插入数据 emisSettlePayRecordMapper.insertEmisSettlePayRecord(emisSettlePayRecord); - // 重新计算账单收款信息 - for (int i = 0; i < settleBillNoArr.size(); i++) { - String settleBillNo = settleBillNoArr.get(i); - if (!StringUtils.isEmpty(settleBillNo)) { - emisSettleBillService.reCalcSettleBillPayStatus(settleBillNo); - } - } + // // 重新计算账单收款信息 + // for (int i = 0; i < settleBillNoArr.size(); i++) { + // String settleBillNo = settleBillNoArr.get(i); + // if (!StringUtils.isEmpty(settleBillNo)) { + // emisSettleBillService.reCalcSettleBillPayStatus(settleBillNo); + // } + // } + + // 处理部分收款逻辑 - 更新各个维度的收款状态 + updatePartialPaymentStatus(emisSettlePayRecord, settleBillNoArr); + return 1; } @@ -661,4 +674,257 @@ public class EmisSettlePayRecordServiceImpl extends EmisBaseService implements I } } + /** + * 更新部分收款状态 + * 根据emis_settle_sub_bill的已收金额和本次运单的申请金额加起来与运费比较 + * 更新emis_settle_sub_bill、emis_waybill的收款状态、已收金额 + * 从账单维度更新emis_settle_bill、从发票维度更新emis_settle_invoice_record的对应字段 + * + * @param emisSettlePayRecord 收款记录 + * @param settleBillNoArr 账单号数组 + */ + private void updatePartialPaymentStatus(EmisSettlePayRecord emisSettlePayRecord, List settleBillNoArr) { + try { + // 处理运单收款关联 + List payRelList = emisSettlePayRecord.getPayRelList(); + if (!CollectionUtils.isEmpty(payRelList)) { + for (EmisSettlePayRel payRel : payRelList) { + updateWaybillPaymentStatus(payRel); + } + } + + // 处理发票收款关联 + List payInvoiceRelList = emisSettlePayRecord.getPayInvoiceRelList(); + if (!CollectionUtils.isEmpty(payInvoiceRelList)) { + for (EmisSettlePayInvoiceRel payInvoiceRel : payInvoiceRelList) { + updateInvoicePaymentStatus(payInvoiceRel, payRelList); + } + } + + // 处理账单收款状态 + for (String settleBillNo : settleBillNoArr) { + if (!StringUtils.isEmpty(settleBillNo)) { + updateSettleBillPaymentStatus(settleBillNo); + } + } + + } catch (Exception e) { + log.error("更新部分收款状态失败", e); + throw new RuntimeException("更新收款状态失败:" + e.getMessage()); + } + } + + /** + * 更新运单收款状态 + * + * @param payRel 运单收款关联 + */ + private void updateWaybillPaymentStatus(EmisSettlePayRel payRel) { + try { + String billCode = payRel.getBillNo(); + if (StringUtils.isEmpty(billCode)) { + return; + } + + // 获取子账单信息 + List subBillList = emisSettleSubBillMapper.selectSettleSubBillListByBillCode(billCode); + if (CollectionUtils.isEmpty(subBillList)) { + log.warn("未找到运单号 {} 对应的子账单", billCode); + return; + } + + // 获取运单信息 + EmisWaybill waybill = emisWaybillMapper.selectEmisWaybillByBillCode(billCode); + if (waybill == null) { + log.warn("未找到运单号 {} 对应的运单信息", billCode); + return; + } + + // 计算本次收款金额 + BigDecimal currentPayMoney = payRel.getPayMoney() != null ? payRel.getPayMoney() : BigDecimal.ZERO; + + // 获取唯一的子账单(一个运单只对应一个子账单) + EmisSettleSubBill subBill = subBillList.get(0); + + // 获取子账单的已收金额 + BigDecimal currentRecedMoney = subBill.getRecedMoney() != null ? subBill.getRecedMoney() + : BigDecimal.ZERO; + + // 计算新的已收金额 + BigDecimal newRecedMoney = currentRecedMoney.add(currentPayMoney); + + // 获取子账单的运费 + BigDecimal billFee = subBill.getBillFee() != null ? subBill.getBillFee() : BigDecimal.ZERO; + + // 根据已收金额和运费比较,确定收款状态 + String paymentStatus; + if (newRecedMoney.compareTo(BigDecimal.ZERO) == 0) { + paymentStatus = "0"; // 未付款 + } else if (newRecedMoney.compareTo(billFee) >= 0) { + paymentStatus = "1"; // 已付款 + } else { + paymentStatus = "2"; // 部分付款 + } + + // 更新子账单收款状态和已收金额 + EmisSettleSubBill updateSubBill = new EmisSettleSubBill(); + updateSubBill.setBillCode(subBill.getBillCode()); + updateSubBill.setPaymentStatus(paymentStatus); + updateSubBill.setRecedMoney(newRecedMoney); + emisSettleSubBillMapper.updatePayedStatus(updateSubBill); + + // 更新运单收款状态 + EmisWaybill updateWaybill = new EmisWaybill(); + updateWaybill.setBillCode(billCode); + updateWaybill.setPaymentStatus(paymentStatus); + emisWaybillMapper.updatePayedStatus(updateWaybill); + + log.info("更新运单收款状态成功,运单号: {}, 子账单号: {}, 收款状态: {}, 已收金额: {}, 运费: {}", + billCode, subBill.getBillNo(), paymentStatus, newRecedMoney, billFee); + + } catch (Exception e) { + log.error("更新运单收款状态失败,运单号: {}", payRel.getBillNo(), e); + throw e; + } + } + + /** + * 更新发票收款状态 + * + * @param payInvoiceRel 发票收款关联 + * @param payRelList 收款关联列表 + */ + private void updateInvoicePaymentStatus(EmisSettlePayInvoiceRel payInvoiceRel, List payRelList) { + try { + String applySeqNo = payInvoiceRel.getApplySeqNo(); + if (StringUtils.isEmpty(applySeqNo)) { + return; + } + + // 获取发票记录 + EmisSettleInvoiceRecord invoiceRecord = emisSettleInvoiceRecordMapper + .selectInvoiceRecordByApplySeqNo(applySeqNo); + if (invoiceRecord == null) { + log.warn("未找到申请序号 {} 对应的发票记录", applySeqNo); + return; + } + BigDecimal money = invoiceRecord.getApplyMoney() != null ? invoiceRecord.getApplyMoney() + : BigDecimal.ZERO; + + // 获取发票之前的收款金额 + BigDecimal previousRecedMoney = invoiceRecord.getRecedMoney() != null ? invoiceRecord.getRecedMoney() + : BigDecimal.ZERO; + + // 计算当前收款记录中与该发票相关的运单收款金额(以applySeqNo关联) + BigDecimal currentInvoicePayMoney = calculateCurrentInvoicePayment(applySeqNo, payRelList); + + // 计算新的总收款金额 = 之前的收款金额 + 当前收款金额 + BigDecimal totalRecedMoney = previousRecedMoney.add(currentInvoicePayMoney); + + String paymentStatus; + if (totalRecedMoney.compareTo(BigDecimal.ZERO) == 0) { + paymentStatus = "0"; // 未付款 + } else if (totalRecedMoney.compareTo(money) >= 0) { + paymentStatus = "1"; // 已付款 + } else { + paymentStatus = "2"; // 部分付款 + } + + // 更新发票记录收款状态 + EmisSettleInvoiceRecord updateInvoiceRecord = new EmisSettleInvoiceRecord(); + updateInvoiceRecord.setId(invoiceRecord.getId()); + updateInvoiceRecord.setPaymentStatus(paymentStatus); + updateInvoiceRecord.setRecedMoney(totalRecedMoney); + emisSettleInvoiceRecordMapper.updateEmisSettleInvoiceRecord(updateInvoiceRecord); + + log.info("更新发票收款状态成功,申请序号: {}, 收款状态: {}, 总收款金额: {}, 当前收款金额: {}, 申请金额: {}", + applySeqNo, paymentStatus, totalRecedMoney, currentInvoicePayMoney, money); + + } catch (Exception e) { + log.error("更新发票收款状态失败,申请序号: {}", payInvoiceRel.getApplySeqNo(), e); + throw e; + } + } + + /** + * 计算当前收款记录中与该发票相关的运单收款金额(按applySeqNo关联) + * + * @param applySeqNo 发票申请序号 + * @param payRelList 当前收款记录中的运单收款列表 + * @return 当前收款金额 + */ + private BigDecimal calculateCurrentInvoicePayment(String applySeqNo, List payRelList) { + try { + if (StringUtils.isEmpty(applySeqNo) || CollectionUtils.isEmpty(payRelList)) { + return BigDecimal.ZERO; + } + + BigDecimal currentPayment = BigDecimal.ZERO; + for (EmisSettlePayRel payRel : payRelList) { + if (applySeqNo.equals(payRel.getApplySeqNo()) && payRel.getPayMoney() != null) { + currentPayment = currentPayment.add(payRel.getPayMoney()); + } + } + return currentPayment; + } catch (Exception e) { + log.error("计算当前发票收款金额失败,申请序号: {}", applySeqNo, e); + return BigDecimal.ZERO; + } + } + + /** + * 更新账单收款状态 + * + * @param settleBillNo 账单号 + */ + private void updateSettleBillPaymentStatus(String settleBillNo) { + try { + // 获取账单信息 + EmisSettleBill settleBill = emisSettleBillMapper.selectSettleBillBySettleBillNo(settleBillNo); + if (settleBill == null) { + log.warn("未找到账单号 {} 对应的账单信息", settleBillNo); + return; + } + + // 获取账单下的所有子账单 + List subBillList = emisSettleSubBillMapper.selectSubBillListBySettleBillNo(settleBillNo); + if (CollectionUtils.isEmpty(subBillList)) { + log.warn("账单号 {} 下没有子账单", settleBillNo); + return; + } + + // 计算总已收金额 + BigDecimal totalRecedMoney = BigDecimal.ZERO; + for (EmisSettleSubBill subBill : subBillList) { + BigDecimal recedMoney = subBill.getRecedMoney() != null ? subBill.getRecedMoney() : BigDecimal.ZERO; + totalRecedMoney = totalRecedMoney.add(recedMoney); + } + + // 根据已收金额和应收金额比较,确定收款状态 + BigDecimal recMoney = settleBill.getRecMoney() != null ? settleBill.getRecMoney() : BigDecimal.ZERO; + String paymentStatus; + if (totalRecedMoney.compareTo(BigDecimal.ZERO) == 0) { + paymentStatus = "0"; // 未付款 + } else if (totalRecedMoney.compareTo(recMoney) >= 0) { + paymentStatus = "1"; // 已付款 + } else { + paymentStatus = "2"; // 部分付款 + } + + // 更新账单收款状态和已收金额 + EmisSettleBill updateSettleBill = new EmisSettleBill(); + updateSettleBill.setId(settleBill.getId()); + updateSettleBill.setPaymentStatus(paymentStatus); + updateSettleBill.setRecedMoney(totalRecedMoney); + emisSettleBillMapper.updateEmisSettleBill(updateSettleBill); + + log.info("更新账单收款状态成功,账单号: {}, 收款状态: {}, 已收金额: {}, 应收金额: {}", + settleBillNo, paymentStatus, totalRecedMoney, recMoney); + + } catch (Exception e) { + log.error("更新账单收款状态失败,账单号: {}", settleBillNo, e); + throw e; + } + } + } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchMissStatisticsServiceImpl.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchMissStatisticsServiceImpl.java new file mode 100644 index 000000000..36236454e --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/impl/EmisTmsSiteBatchMissStatisticsServiceImpl.java @@ -0,0 +1,449 @@ +package com.xdadan.erp.emis.service.impl; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMiss; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMissStatistics; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMissStatisticsExport; +import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMissExport; +import com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissStatisticsMapper; +import com.xdadan.erp.emis.service.IEmisTmsSiteBatchMissStatisticsService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.URLEncoder; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +/** + * 漏组批次统计Service业务层处理 + * + * @author heyu + * @date 2025-09-27 + */ +@Service +@Slf4j +public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBatchMissStatisticsService { + + @Autowired + private EmisTmsSiteBatchMissStatisticsMapper statisticsMapper; + + // 重用SimpleDateFormat对象,避免重复创建 + private static final SimpleDateFormat MONTH_FORMAT = new SimpleDateFormat("yyyy-MM"); + private static final SimpleDateFormat MONTH_ONLY_FORMAT = new SimpleDateFormat("MM"); + + /** + * 查询漏组批次统计列表 + */ + @Override + public List selectStatisticsList( + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { + log.info("查询漏组批次统计列表,startSiteCode: {}, billMonth: {}", + emisTmsSiteBatchMissStatistics.getStartSiteCode(), emisTmsSiteBatchMissStatistics.getBillMonth()); + + List result = statisticsMapper + .selectStatisticsList(emisTmsSiteBatchMissStatistics); + + return result; + } + + /** + * 导出漏组批次统计查询接口数据 + */ + @Override + public void exportStatisticsData(HttpServletResponse response, + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { + try { + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode("漏组批次统计汇总_" + System.currentTimeMillis(), "UTF-8").replaceAll("\\+", + "%20"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + + // 查询统计数据 + List statisticsList = selectStatisticsList(emisTmsSiteBatchMissStatistics); + + // 转换为导出格式 + List exportList = convertToExportFormat(statisticsList); + + // 添加合计行 + addTotalRow(exportList); + + // 导出Excel + EasyExcel.write(response.getOutputStream(), EmisTmsSiteBatchMissStatisticsExport.class) + .sheet("漏组批次统计汇总") + .doWrite(exportList); + + } catch (IOException e) { + log.error("导出漏组批次统计数据失败", e); + throw new RuntimeException("导出失败:" + e.getMessage()); + } + } + + /** + * 转换为导出格式 + */ + private List convertToExportFormat( + List statisticsList) { + // 按起始网点分组,处理null值 + Map> groupedBySite = statisticsList.stream() + .filter(Objects::nonNull) // 过滤掉null对象 + .collect(Collectors.groupingBy(stat -> { + String siteCode = stat.getStartSiteCode(); + return siteCode != null ? siteCode : "未知网点"; // 处理null的startSiteCode + })); + + List exportList = new ArrayList<>(); + + for (Map.Entry> entry : groupedBySite.entrySet()) { + String siteCode = entry.getKey(); + List siteStatistics = entry.getValue(); + + if (siteStatistics == null || siteStatistics.isEmpty()) { + log.warn("网点 {} 的统计数据为空,跳过处理", siteCode); + continue; + } + + EmisTmsSiteBatchMissStatisticsExport export = new EmisTmsSiteBatchMissStatisticsExport(); + // 安全获取网点名称,处理null值 + String siteName = siteStatistics.get(0).getStartSiteName(); + export.setStartSiteName(siteName != null ? siteName : "未知网点"); + + // 初始化各月份数据 + export.setJanuaryCount(0); + export.setFebruaryCount(0); + export.setMarchCount(0); + export.setAprilCount(0); + export.setMayCount(0); + export.setJuneCount(0); + export.setJulyCount(0); + export.setAugustCount(0); + export.setSeptemberCount(0); + export.setOctoberCount(0); + export.setNovemberCount(0); + export.setDecemberCount(0); + + int totalCount = 0; + + // 填充各月份数据 + for (EmisTmsSiteBatchMissStatistics stat : siteStatistics) { + if (stat != null && stat.getBillMonth() != null) { + String month; + synchronized (MONTH_ONLY_FORMAT) { + month = MONTH_ONLY_FORMAT.format(stat.getBillMonth()); // 获取月份部分 + } + // 安全获取票数,处理null值 + int count = stat.getTicketCount() != null ? stat.getTicketCount() : 0; + totalCount += count; + + switch (month) { + case "01": + export.setJanuaryCount(count); + break; + case "02": + export.setFebruaryCount(count); + break; + case "03": + export.setMarchCount(count); + break; + case "04": + export.setAprilCount(count); + break; + case "05": + export.setMayCount(count); + break; + case "06": + export.setJuneCount(count); + break; + case "07": + export.setJulyCount(count); + break; + case "08": + export.setAugustCount(count); + break; + case "09": + export.setSeptemberCount(count); + break; + case "10": + export.setOctoberCount(count); + break; + case "11": + export.setNovemberCount(count); + break; + case "12": + export.setDecemberCount(count); + break; + } + } + } + + export.setTotalTicketCount(totalCount); + exportList.add(export); + } + + return exportList; + } + + /** + * 添加合计行 + */ + private void addTotalRow(List exportList) { + EmisTmsSiteBatchMissStatisticsExport totalRow = new EmisTmsSiteBatchMissStatisticsExport(); + totalRow.setStartSiteName("合计"); + totalRow.setTotalTicketCount(0); + totalRow.setJanuaryCount(0); + totalRow.setFebruaryCount(0); + totalRow.setMarchCount(0); + totalRow.setAprilCount(0); + totalRow.setMayCount(0); + totalRow.setJuneCount(0); + totalRow.setJulyCount(0); + totalRow.setAugustCount(0); + totalRow.setSeptemberCount(0); + totalRow.setOctoberCount(0); + totalRow.setNovemberCount(0); + totalRow.setDecemberCount(0); + + // 计算合计 + for (EmisTmsSiteBatchMissStatisticsExport item : exportList) { + totalRow.setTotalTicketCount(totalRow.getTotalTicketCount() + item.getTotalTicketCount()); + totalRow.setJanuaryCount(totalRow.getJanuaryCount() + item.getJanuaryCount()); + totalRow.setFebruaryCount(totalRow.getFebruaryCount() + item.getFebruaryCount()); + totalRow.setMarchCount(totalRow.getMarchCount() + item.getMarchCount()); + totalRow.setAprilCount(totalRow.getAprilCount() + item.getAprilCount()); + totalRow.setMayCount(totalRow.getMayCount() + item.getMayCount()); + totalRow.setJuneCount(totalRow.getJuneCount() + item.getJuneCount()); + totalRow.setJulyCount(totalRow.getJulyCount() + item.getJulyCount()); + totalRow.setAugustCount(totalRow.getAugustCount() + item.getAugustCount()); + totalRow.setSeptemberCount(totalRow.getSeptemberCount() + item.getSeptemberCount()); + totalRow.setOctoberCount(totalRow.getOctoberCount() + item.getOctoberCount()); + totalRow.setNovemberCount(totalRow.getNovemberCount() + item.getNovemberCount()); + totalRow.setDecemberCount(totalRow.getDecemberCount() + item.getDecemberCount()); + } + + exportList.add(totalRow); + } + + /** + * 流式导出漏组详细数据(按月份分sheet)- 性能优化版本 + * 支持大数据量导出,避免内存溢出 + */ + @Override + public void exportDetailDataByMonthStream(HttpServletResponse response, + EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { + long startTime = System.currentTimeMillis(); + try { + // 设置响应头 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + String fileName = URLEncoder.encode("漏组详细数据_" + System.currentTimeMillis(), "UTF-8").replaceAll("\\+", + "%20"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); + + // 先获取总记录数,用于进度跟踪 + long totalCount = statisticsMapper.countDetailDataByMonth(emisTmsSiteBatchMissStatistics); + log.info("开始流式导出漏组详细数据,总记录数: {}, 查询条件: {}", totalCount, emisTmsSiteBatchMissStatistics); + + if (totalCount == 0) { + // 创建空Excel + EasyExcel.write(response.getOutputStream(), EmisTmsSiteBatchMiss.class) + .sheet("无数据") + .doWrite(new ArrayList<>()); + return; + } + + // 简化版本:直接查询所有数据并导出,避免复杂的流式处理 + // 如果数据量很大,可以考虑分批处理 + List allData = statisticsMapper + .selectDetailDataByMonth(emisTmsSiteBatchMissStatistics); + + log.info("查询到数据条数: {}", allData != null ? allData.size() : 0); + + if (allData == null || allData.isEmpty()) { + EasyExcel.write(response.getOutputStream(), EmisTmsSiteBatchMissExport.class) + .sheet("无数据") + .doWrite(new ArrayList<>()); + return; + } + + // 转换为专门的导出DTO,避免Map类型问题 + List exportData = allData.stream() + .filter(Objects::nonNull) + .map(this::convertToExportDto) + .collect(Collectors.toList()); + + log.info("转换后数据条数: {}", exportData.size()); + + // 按月份分组数据 + Map> dataByMonth = exportData.stream() + .collect(Collectors.groupingBy(item -> { + if (item.getSendDate() != null) { + synchronized (MONTH_FORMAT) { + return MONTH_FORMAT.format(item.getSendDate()); + } + } + return "未知月份"; + })); + + // 创建Excel写入器 + ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build(); + + // 按月份从小到大排序 + List sortedMonths = dataByMonth.keySet().stream() + .filter(month -> !"未知月份".equals(month)) + .sorted() + .collect(Collectors.toList()); + + // 如果有未知月份,放在最后 + if (dataByMonth.containsKey("未知月份")) { + sortedMonths.add("未知月份"); + } + + int sheetIndex = 0; + for (String month : sortedMonths) { + List monthData = dataByMonth.get(month); + + if (monthData != null && !monthData.isEmpty()) { + // 创建sheet,使用月份作为sheet名称 + String sheetName = month + "月"; + WriteSheet writeSheet = EasyExcel.writerSheet(sheetIndex, sheetName) + .head(EmisTmsSiteBatchMissExport.class) + .build(); + + // 写入数据 + excelWriter.write(monthData, writeSheet); + sheetIndex++; + log.info("写入{}月数据,条数: {}", month, monthData.size()); + } + } + + // 关闭写入器 + excelWriter.finish(); + log.info("Excel写入成功,共创建{}个sheet", sheetIndex); + + long endTime = System.currentTimeMillis(); + long duration = endTime - startTime; + log.info("流式导出完成,总处理记录数: {}, 耗时: {}ms, 平均处理速度: {}/s", + allData.size(), duration, allData.size() > 0 ? (allData.size() * 1000 / duration) : 0); + + } catch (IOException e) { + long endTime = System.currentTimeMillis(); + log.error("流式导出漏组详细数据失败,耗时: {}ms", endTime - startTime, e); + // 不抛出异常,避免重复处理响应 + try { + if (!response.isCommitted()) { + response.reset(); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().write("{\"success\":false,\"message\":\"导出失败:" + e.getMessage() + "\"}"); + } + } catch (Exception ex) { + log.error("写入错误响应失败", ex); + } + } catch (Exception e) { + long endTime = System.currentTimeMillis(); + log.error("流式导出漏组详细数据发生未知错误,耗时: {}ms", endTime - startTime, e); + try { + if (!response.isCommitted()) { + response.reset(); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().write("{\"success\":false,\"message\":\"导出失败:" + e.getMessage() + "\"}"); + } + } catch (Exception ex) { + log.error("写入错误响应失败", ex); + } + } + } + + /** + * 将EmisTmsSiteBatchMiss转换为EmisTmsSiteBatchMissExport用于导出 + * 根据实际Excel截图字段进行映射 + */ + private EmisTmsSiteBatchMissExport convertToExportDto(EmisTmsSiteBatchMiss miss) { + EmisTmsSiteBatchMissExport export = new EmisTmsSiteBatchMissExport(); + + // 根据Excel截图字段进行映射 + export.setBillCode(miss.getBillCode()); + export.setAuditTime(miss.getCreateTime()); // 稽核时间使用创建时间 + export.setSendDate(miss.getSendDate()); + export.setMissReason(miss.getMissReason()); + export.setStartSiteName(miss.getStartSiteName()); + export.setNextSiteName(miss.getNextSiteName()); + export.setSendSiteName(miss.getSendSiteName()); + export.setLineName(miss.getLineName()); + export.setProductTypeName(miss.getProductTypeName()); + export.setSupplierName(miss.getSupplierName()); + export.setSendCountryName(miss.getSendCountryName()); + export.setReceiveCountryName(miss.getReceiveCountryName()); + export.setPaymentType(convertPaymentType(miss.getPaymentType())); + export.setParcelQty(miss.getParcelQty()); + export.setBillWeight(miss.getBillWeight()); + export.setTotalVolume(miss.getTotalVolume()); + export.setManager(miss.getManager()); + export.setTransManager(miss.getTransManager()); + export.setBlIsQuestion(convertBlIsQuestion(miss.getBlIsQuestion())); + export.setWaybillRemark(miss.getWaybillRemark()); + export.setDestinationName(miss.getDestinationName()); + export.setManualRemark(miss.getManualRemark()); + export.setBlManual(miss.getBlManual()); + export.setSalesmen(miss.getSalesmen()); + export.setPayee(miss.getPayee()); + export.setRegisterManName(miss.getRegisterManName()); + + return export; + } + + /** + * 转换支付方式 + * 根据图2的规则进行转换 + */ + private String convertPaymentType(String paymentType) { + if (paymentType == null) { + return "其他"; + } + + switch (paymentType) { + case "1": + return "现金"; + case "2": + return "月结"; + case "3": + return "到付"; + case "4": + return "到付月结"; + case "5": + return "第三方月结"; + case "6": + return "其他"; + default: + return paymentType; // 如果不在转换范围内,返回原值 + } + } + + /** + * 转换是否问题件 + * 1-是 0-否 + */ + private String convertBlIsQuestion(String blIsQuestion) { + if (blIsQuestion == null) { + return "否"; + } + + if ("1".equals(blIsQuestion)) { + return "是"; + } else if ("0".equals(blIsQuestion)) { + return "否"; + } else { + return blIsQuestion; // 如果不在转换范围内,返回原值 + } + } + +} diff --git a/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRecordMapper.xml b/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRecordMapper.xml index 90dc49859..ca2f0fac0 100644 --- a/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRecordMapper.xml +++ b/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRecordMapper.xml @@ -223,7 +223,7 @@ diff --git a/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRelMapper.xml b/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRelMapper.xml index 760da47df..6a9053d3a 100644 --- a/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRelMapper.xml +++ b/emis-biz/src/main/resources/mapper/EmisSettleInvoiceRelMapper.xml @@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -21,29 +22,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select id, apply_seq_no, pay_id, bill_no, money, del_flag, create_by, create_time, update_by, update_time, create_site, update_site from emis_settle_invoice_rel + select r.id, r.apply_seq_no, r.pay_id, r.bill_no, r.money, + COALESCE(i.reced_money, 0) as reced_money, + r.del_flag, r.create_by, r.create_time, r.update_by, r.update_time, r.create_site, r.update_site + from emis_settle_invoice_rel r + left join emis_settle_invoice_record i on r.apply_seq_no = i.apply_seq_no and i.del_flag = '0' - select id, apply_seq_no, pay_id, bill_no, money, del_flag, create_by, create_time, update_by, update_time, create_site, update_site - from emis_settle_invoice_rel a - where a.id = #{id} + select r.id, r.apply_seq_no, r.pay_id, r.bill_no, r.money, + COALESCE(i.reced_money, 0) as reced_money, + r.del_flag, r.create_by, r.create_time, r.update_by, r.update_time, r.create_site, r.update_site + from emis_settle_invoice_rel r + left join emis_settle_invoice_record i on r.apply_seq_no = i.apply_seq_no and i.del_flag = '0' + where r.id = #{id} diff --git a/emis-biz/src/main/resources/mapper/EmisSettlePayRecordMapper.xml b/emis-biz/src/main/resources/mapper/EmisSettlePayRecordMapper.xml index 3645a4bb1..fd041a8a1 100644 --- a/emis-biz/src/main/resources/mapper/EmisSettlePayRecordMapper.xml +++ b/emis-biz/src/main/resources/mapper/EmisSettlePayRecordMapper.xml @@ -640,7 +640,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + SELECT + bm.start_site_code, + s.site_name as start_site_name, + STR_TO_DATE(CONCAT(DATE_FORMAT(w.send_date, '%Y-%m'), '-01'), '%Y-%m-%d') as bill_month, + COUNT(*) as ticket_count + FROM emis_tms_site_batch_miss bm + LEFT JOIN emis_waybill w ON bm.bill_code = w.bill_code + LEFT JOIN emis_site s ON bm.start_site_code = s.site_code + WHERE 1=1 + + AND bm.start_site_code = #{startSiteCode} + + + AND DATE_FORMAT(w.send_date, '%Y-%m') = ]]> #{startTime} + + + AND DATE_FORMAT(w.send_date, '%Y-%m') #{endTime} + + + + AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m') + + + GROUP BY bm.start_site_code, s.site_name, DATE_FORMAT(w.send_date, '%Y-%m') + ORDER BY w.send_date,bm.start_site_code + + + + + + + + + + +