demand: TMS系统 - 客户账单管理 - 财务开票处理 - 定制导出性能优化
committer: heyu
This commit is contained in:
parent
945a731c35
commit
768c33a255
@ -16,6 +16,7 @@ import java.util.Map;
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRel;
|
import com.xdadan.erp.emis.domain.EmisSettleInvoiceRel;
|
||||||
import com.xdadan.erp.emis.domain.EmisSettlePayRel;
|
import com.xdadan.erp.emis.domain.EmisSettlePayRel;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
/**
|
/**
|
||||||
* @ClassName EmisSettlePayRelMapper
|
* @ClassName EmisSettlePayRelMapper
|
||||||
* @Description <p> 支付子账单关联表 Mapper 接口 </p>
|
* @Description <p> 支付子账单关联表 Mapper 接口 </p>
|
||||||
@ -33,6 +34,14 @@ public interface EmisSettlePayRelMapper extends BaseMapper<EmisSettlePayRel>
|
|||||||
|
|
||||||
public List<EmisSettlePayRel> selectHasPayListBySettleBillNo(String settleBillNo);
|
public List<EmisSettlePayRel> selectHasPayListBySettleBillNo(String settleBillNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据账单号列表查询支付关联记录
|
||||||
|
*
|
||||||
|
* @param settleBillNoList 账单号列表
|
||||||
|
* @return 支付关联记录列表
|
||||||
|
*/
|
||||||
|
public List<EmisSettlePayRel> selectHasPayListBySettleBillNoList(@Param("settleBillNoList") List<String> settleBillNoList);
|
||||||
|
|
||||||
public List<Map> selectHasPayMapList(String settleBillNo);
|
public List<Map> selectHasPayMapList(String settleBillNo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -42,6 +42,10 @@ import com.xdadan.erp.emis.mapper.EmisSettleInvoiceRecordMapper;
|
|||||||
import com.xdadan.erp.emis.service.IEmisSettleInvoiceRecordService;
|
import com.xdadan.erp.emis.service.IEmisSettleInvoiceRecordService;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import com.xdadan.erp.emis.mapper.EmisSettlePayRecordMapper;
|
import com.xdadan.erp.emis.mapper.EmisSettlePayRecordMapper;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开票记录表Service业务层处理
|
* 开票记录表Service业务层处理
|
||||||
@ -83,6 +87,40 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
@Autowired
|
@Autowired
|
||||||
private EmisSettlePayBillRelMapper emisSettlePayBillRelMapper;
|
private EmisSettlePayBillRelMapper emisSettlePayBillRelMapper;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
@Qualifier("dataQueryExecutor")
|
||||||
|
private ThreadPoolExecutor dataQueryExecutor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取或创建线程池
|
||||||
|
* 如果未注入线程池,则创建默认线程池
|
||||||
|
*/
|
||||||
|
private ThreadPoolExecutor getExecutor() {
|
||||||
|
if (dataQueryExecutor != null) {
|
||||||
|
return dataQueryExecutor;
|
||||||
|
}
|
||||||
|
// 如果未注入,创建默认线程池
|
||||||
|
int processors = Runtime.getRuntime().availableProcessors();
|
||||||
|
return new ThreadPoolExecutor(
|
||||||
|
Math.max(2, processors), // 核心线程数
|
||||||
|
processors, // 最大线程数
|
||||||
|
60L, // 空闲线程存活时间
|
||||||
|
TimeUnit.SECONDS, // 时间单位
|
||||||
|
new LinkedBlockingQueue<>(500), // 工作队列
|
||||||
|
new ThreadFactory() {
|
||||||
|
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread t = new Thread(r, "invoice-export-query-" + threadNumber.getAndIncrement());
|
||||||
|
t.setDaemon(true);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询开票记录表
|
* 查询开票记录表
|
||||||
*
|
*
|
||||||
@ -403,23 +441,69 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
@Override
|
@Override
|
||||||
public List<EmisSettleInvoiceRecordExportVO> selectCustomExportList(
|
public List<EmisSettleInvoiceRecordExportVO> selectCustomExportList(
|
||||||
EmisSettleInvoiceRecord emisSettleInvoiceRecord) {
|
EmisSettleInvoiceRecord emisSettleInvoiceRecord) {
|
||||||
// 查询开票记录列表
|
// 分页查询开票记录列表
|
||||||
List<EmisSettleInvoiceRecord> invoiceRecordList = emisSettleInvoiceRecordMapper
|
List<EmisSettleInvoiceRecord> invoiceRecordList = queryInvoiceRecordListByPage(emisSettleInvoiceRecord);
|
||||||
.selectSimpleInvoiceRecordList(emisSettleInvoiceRecord);
|
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(invoiceRecordList)) {
|
if (CollectionUtils.isEmpty(invoiceRecordList)) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<EmisSettleInvoiceRecordExportVO> exportList = new ArrayList<>();
|
// 收集所有需要批量查询的数据
|
||||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
|
Set<String> allSettleBillNoSet = collectSettleBillNos(invoiceRecordList);
|
||||||
|
Set<String> allPayIdSet = new HashSet<>();
|
||||||
|
Set<String> allBillNoSet = new HashSet<>();
|
||||||
|
|
||||||
// 第一步:收集所有需要批量查询的数据
|
// 查询支付关联记录并建立映射关系
|
||||||
Set<String> allSettleBillNoSet = new HashSet<>(); // 所有账单号
|
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap = queryPayRelListAndBuildMapping(
|
||||||
Set<String> allPayIdSet = new HashSet<>(); // 所有支付ID
|
allSettleBillNoSet, allPayIdSet, allBillNoSet, invoiceRecordList);
|
||||||
Set<String> allBillNoSet = new HashSet<>(); // 所有运单号
|
|
||||||
|
|
||||||
// 收集所有账单号
|
// 并行批量查询账单、收款记录、运单信息
|
||||||
|
QueryDataMaps queryDataMaps = parallelQueryRelatedData(allSettleBillNoSet, allPayIdSet, allBillNoSet);
|
||||||
|
|
||||||
|
// 组装导出数据
|
||||||
|
return buildExportDataList(invoiceRecordList, settleBillNoToPayRelListMap, queryDataMaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询开票记录列表,每次查询1000条
|
||||||
|
*
|
||||||
|
* @param emisSettleInvoiceRecord 查询条件
|
||||||
|
* @return 开票记录列表
|
||||||
|
*/
|
||||||
|
private List<EmisSettleInvoiceRecord> queryInvoiceRecordListByPage(
|
||||||
|
EmisSettleInvoiceRecord emisSettleInvoiceRecord) {
|
||||||
|
List<EmisSettleInvoiceRecord> invoiceRecordList = new ArrayList<>();
|
||||||
|
int pageSize = 1000;
|
||||||
|
int pageNum = 1;
|
||||||
|
boolean hasMore = true;
|
||||||
|
|
||||||
|
while (hasMore) {
|
||||||
|
PageHelper.startPage(pageNum, pageSize);
|
||||||
|
List<EmisSettleInvoiceRecord> pageList = emisSettleInvoiceRecordMapper
|
||||||
|
.selectSimpleInvoiceRecordList(emisSettleInvoiceRecord);
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(pageList)) {
|
||||||
|
hasMore = false;
|
||||||
|
} else {
|
||||||
|
invoiceRecordList.addAll(pageList);
|
||||||
|
// 如果查询结果少于pageSize,说明已经是最后一页
|
||||||
|
if (pageList.size() < pageSize) {
|
||||||
|
hasMore = false;
|
||||||
|
} else {
|
||||||
|
pageNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return invoiceRecordList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收集所有账单号
|
||||||
|
*
|
||||||
|
* @param invoiceRecordList 开票记录列表
|
||||||
|
* @return 账单号集合
|
||||||
|
*/
|
||||||
|
private Set<String> collectSettleBillNos(List<EmisSettleInvoiceRecord> invoiceRecordList) {
|
||||||
|
Set<String> allSettleBillNoSet = new HashSet<>();
|
||||||
for (EmisSettleInvoiceRecord record : invoiceRecordList) {
|
for (EmisSettleInvoiceRecord record : invoiceRecordList) {
|
||||||
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
||||||
String[] settleBillNoArr = record.getSettleBillNo().split(",");
|
String[] settleBillNoArr = record.getSettleBillNo().split(",");
|
||||||
@ -430,19 +514,88 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return allSettleBillNoSet;
|
||||||
|
}
|
||||||
|
|
||||||
// 批量查询所有支付关联记录(一次性查询所有settleBillNo对应的支付关联记录)
|
/**
|
||||||
|
* 查询支付关联记录并建立映射关系
|
||||||
|
*
|
||||||
|
* @param allSettleBillNoSet 账单号集合
|
||||||
|
* @param allPayIdSet 支付ID集合(输出参数)
|
||||||
|
* @param allBillNoSet 运单号集合(输出参数)
|
||||||
|
* @param invoiceRecordList 开票记录列表
|
||||||
|
* @return 账单号到支付关联记录的映射
|
||||||
|
*/
|
||||||
|
private Map<String, List<EmisSettlePayRel>> queryPayRelListAndBuildMapping(
|
||||||
|
Set<String> allSettleBillNoSet, Set<String> allPayIdSet, Set<String> allBillNoSet,
|
||||||
|
List<EmisSettleInvoiceRecord> invoiceRecordList) {
|
||||||
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap = new HashMap<>();
|
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap = new HashMap<>();
|
||||||
// 建立 payId -> Set<settleBillNo> 的映射关系
|
|
||||||
Map<String, Set<String>> payIdToSettleBillNoSetMap = new HashMap<>();
|
Map<String, Set<String>> payIdToSettleBillNoSetMap = new HashMap<>();
|
||||||
|
|
||||||
if (!allSettleBillNoSet.isEmpty()) {
|
if (allSettleBillNoSet.isEmpty()) {
|
||||||
// 一次性查询所有支付关联记录(合并所有settleBillNo)
|
return settleBillNoToPayRelListMap;
|
||||||
String allSettleBillNoStr = String.join(",", allSettleBillNoSet);
|
}
|
||||||
List<EmisSettlePayRel> allPayRelList = emisSettlePayRelMapper
|
|
||||||
.selectHasPayListBySettleBillNo(allSettleBillNoStr);
|
ThreadPoolExecutor executor = null;
|
||||||
|
try {
|
||||||
|
executor = getExecutor();
|
||||||
|
// 分批并行查询所有支付关联记录
|
||||||
|
List<EmisSettlePayRel> allPayRelList = batchQueryPayRelList(executor, allSettleBillNoSet);
|
||||||
|
|
||||||
// 收集所有payId和billNo
|
// 收集所有payId和billNo
|
||||||
|
collectPayIdAndBillNo(allPayRelList, allPayIdSet, allBillNoSet);
|
||||||
|
|
||||||
|
// 查询并建立 payId 到 settleBillNo 的映射关系
|
||||||
|
if (!allPayIdSet.isEmpty() && !allSettleBillNoSet.isEmpty()) {
|
||||||
|
queryPayBillRelMapping(executor, allSettleBillNoSet, allPayIdSet, payIdToSettleBillNoSetMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据每个记录的settleBillNo过滤对应的payRelList
|
||||||
|
buildSettleBillNoToPayRelMap(invoiceRecordList, allPayRelList, payIdToSettleBillNoSetMap,
|
||||||
|
settleBillNoToPayRelListMap);
|
||||||
|
} finally {
|
||||||
|
// 关闭线程池
|
||||||
|
if (executor != null && executor != dataQueryExecutor) {
|
||||||
|
executor.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return settleBillNoToPayRelListMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分批并行查询支付关联记录
|
||||||
|
*/
|
||||||
|
private List<EmisSettlePayRel> batchQueryPayRelList(ThreadPoolExecutor executor, Set<String> allSettleBillNoSet) {
|
||||||
|
List<EmisSettlePayRel> allPayRelList = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
List<String> settleBillNoList = new ArrayList<>(allSettleBillNoSet);
|
||||||
|
int batchSize = 1000;
|
||||||
|
List<Future<?>> futures = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < settleBillNoList.size(); i += batchSize) {
|
||||||
|
final int start = i;
|
||||||
|
final int end = Math.min(i + batchSize, settleBillNoList.size());
|
||||||
|
Future<?> future = executor.submit(() -> {
|
||||||
|
List<String> batch = settleBillNoList.subList(start, end);
|
||||||
|
List<EmisSettlePayRel> batchPayRelList = emisSettlePayRelMapper
|
||||||
|
.selectHasPayListBySettleBillNoList(batch);
|
||||||
|
if (CollectionUtils.isNotEmpty(batchPayRelList)) {
|
||||||
|
allPayRelList.addAll(batchPayRelList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
futures.add(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待所有任务完成
|
||||||
|
waitForFutures(futures, "查询支付关联记录异常");
|
||||||
|
return allPayRelList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收集payId和billNo
|
||||||
|
*/
|
||||||
|
private void collectPayIdAndBillNo(List<EmisSettlePayRel> allPayRelList, Set<String> allPayIdSet,
|
||||||
|
Set<String> allBillNoSet) {
|
||||||
for (EmisSettlePayRel payRel : allPayRelList) {
|
for (EmisSettlePayRel payRel : allPayRelList) {
|
||||||
if (StringUtils.isNotBlank(payRel.getPayId())) {
|
if (StringUtils.isNotBlank(payRel.getPayId())) {
|
||||||
allPayIdSet.add(payRel.getPayId());
|
allPayIdSet.add(payRel.getPayId());
|
||||||
@ -451,15 +604,35 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
allBillNoSet.add(payRel.getBillNo());
|
allBillNoSet.add(payRel.getBillNo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 查询 payId 到 settleBillNo 的映射关系
|
/**
|
||||||
if (!allPayIdSet.isEmpty() && !allSettleBillNoSet.isEmpty()) {
|
* 查询支付账单关联映射
|
||||||
// 根据allSettleBillNoSet批量查询相关的支付账单关联记录
|
*/
|
||||||
List<String> settleBillNoList = new ArrayList<>(allSettleBillNoSet);
|
private void queryPayBillRelMapping(ThreadPoolExecutor executor, Set<String> allSettleBillNoSet,
|
||||||
List<EmisSettlePayBillRel> payBillRelList = emisSettlePayBillRelMapper
|
Set<String> allPayIdSet, Map<String, Set<String>> payIdToSettleBillNoSetMap) {
|
||||||
.selectEmisSettlePayBillRelListBySettleBillNos(settleBillNoList);
|
List<EmisSettlePayBillRel> payBillRelList = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
List<String> payBillRelSettleBillNoList = new ArrayList<>(allSettleBillNoSet);
|
||||||
|
int payBillRelBatchSize = 1000;
|
||||||
|
List<Future<?>> payBillRelFutures = new ArrayList<>();
|
||||||
|
|
||||||
// 建立 payId -> Set<settleBillNo> 的映射(只处理相关的payId和settleBillNo)
|
for (int i = 0; i < payBillRelSettleBillNoList.size(); i += payBillRelBatchSize) {
|
||||||
|
final int start = i;
|
||||||
|
final int end = Math.min(i + payBillRelBatchSize, payBillRelSettleBillNoList.size());
|
||||||
|
Future<?> future = executor.submit(() -> {
|
||||||
|
List<String> batch = payBillRelSettleBillNoList.subList(start, end);
|
||||||
|
List<EmisSettlePayBillRel> batchPayBillRelList = emisSettlePayBillRelMapper
|
||||||
|
.selectEmisSettlePayBillRelListBySettleBillNos(batch);
|
||||||
|
if (CollectionUtils.isNotEmpty(batchPayBillRelList)) {
|
||||||
|
payBillRelList.addAll(batchPayBillRelList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
payBillRelFutures.add(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForFutures(payBillRelFutures, "查询支付账单关联记录异常");
|
||||||
|
|
||||||
|
// 建立 payId -> Set<settleBillNo> 的映射
|
||||||
for (EmisSettlePayBillRel payBillRel : payBillRelList) {
|
for (EmisSettlePayBillRel payBillRel : payBillRelList) {
|
||||||
if (StringUtils.isNotBlank(payBillRel.getPayId())
|
if (StringUtils.isNotBlank(payBillRel.getPayId())
|
||||||
&& StringUtils.isNotBlank(payBillRel.getSettleBillNo())
|
&& StringUtils.isNotBlank(payBillRel.getSettleBillNo())
|
||||||
@ -471,87 +644,207 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据每个记录的settleBillNo过滤对应的payRelList
|
/**
|
||||||
|
* 建立账单号到支付关联记录的映射
|
||||||
|
*/
|
||||||
|
private void buildSettleBillNoToPayRelMap(List<EmisSettleInvoiceRecord> invoiceRecordList,
|
||||||
|
List<EmisSettlePayRel> allPayRelList, Map<String, Set<String>> payIdToSettleBillNoSetMap,
|
||||||
|
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap) {
|
||||||
for (EmisSettleInvoiceRecord record : invoiceRecordList) {
|
for (EmisSettleInvoiceRecord record : invoiceRecordList) {
|
||||||
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
||||||
// 解析该记录的settleBillNo(可能是逗号分隔的多个)
|
Set<String> recordSettleBillNoSet = parseSettleBillNos(record.getSettleBillNo());
|
||||||
Set<String> recordSettleBillNoSet = new HashSet<>();
|
List<EmisSettlePayRel> recordPayRelList = filterPayRelListBySettleBillNo(
|
||||||
String[] settleBillNoArr = record.getSettleBillNo().split(",");
|
allPayRelList, recordSettleBillNoSet, payIdToSettleBillNoSetMap);
|
||||||
for (String settleBillNo : settleBillNoArr) {
|
|
||||||
if (StringUtils.isNotBlank(settleBillNo)) {
|
|
||||||
recordSettleBillNoSet.add(settleBillNo.trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 过滤出属于该记录的payRelList
|
|
||||||
List<EmisSettlePayRel> recordPayRelList = new ArrayList<>();
|
|
||||||
for (EmisSettlePayRel payRel : allPayRelList) {
|
|
||||||
if (StringUtils.isNotBlank(payRel.getPayId())) {
|
|
||||||
Set<String> payRelSettleBillNoSet = payIdToSettleBillNoSetMap.get(payRel.getPayId());
|
|
||||||
if (payRelSettleBillNoSet != null) {
|
|
||||||
// 判断该payRel的payId关联的settleBillNo是否包含在当前记录的settleBillNo中
|
|
||||||
boolean belongsToRecord = false;
|
|
||||||
for (String settleBillNo : recordSettleBillNoSet) {
|
|
||||||
if (payRelSettleBillNoSet.contains(settleBillNo)) {
|
|
||||||
belongsToRecord = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (belongsToRecord) {
|
|
||||||
recordPayRelList.add(payRel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
settleBillNoToPayRelListMap.put(record.getSettleBillNo(), recordPayRelList);
|
settleBillNoToPayRelListMap.put(record.getSettleBillNo(), recordPayRelList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第二步:批量查询所有数据
|
/**
|
||||||
// 批量查询账单
|
* 解析账单号字符串为集合
|
||||||
Map<String, EmisSettleBill> settleBillMap = new HashMap<>();
|
*/
|
||||||
|
private Set<String> parseSettleBillNos(String settleBillNoStr) {
|
||||||
|
Set<String> recordSettleBillNoSet = new HashSet<>();
|
||||||
|
String[] settleBillNoArr = settleBillNoStr.split(",");
|
||||||
|
for (String settleBillNo : settleBillNoArr) {
|
||||||
|
if (StringUtils.isNotBlank(settleBillNo)) {
|
||||||
|
recordSettleBillNoSet.add(settleBillNo.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return recordSettleBillNoSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据账单号过滤支付关联记录
|
||||||
|
*/
|
||||||
|
private List<EmisSettlePayRel> filterPayRelListBySettleBillNo(List<EmisSettlePayRel> allPayRelList,
|
||||||
|
Set<String> recordSettleBillNoSet, Map<String, Set<String>> payIdToSettleBillNoSetMap) {
|
||||||
|
List<EmisSettlePayRel> recordPayRelList = new ArrayList<>();
|
||||||
|
for (EmisSettlePayRel payRel : allPayRelList) {
|
||||||
|
if (StringUtils.isNotBlank(payRel.getPayId())) {
|
||||||
|
Set<String> payRelSettleBillNoSet = payIdToSettleBillNoSetMap.get(payRel.getPayId());
|
||||||
|
if (payRelSettleBillNoSet != null) {
|
||||||
|
for (String settleBillNo : recordSettleBillNoSet) {
|
||||||
|
if (payRelSettleBillNoSet.contains(settleBillNo)) {
|
||||||
|
recordPayRelList.add(payRel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return recordPayRelList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 并行批量查询相关数据(账单、收款记录、运单信息)
|
||||||
|
*/
|
||||||
|
private QueryDataMaps parallelQueryRelatedData(Set<String> allSettleBillNoSet, Set<String> allPayIdSet,
|
||||||
|
Set<String> allBillNoSet) {
|
||||||
|
QueryDataMaps queryDataMaps = new QueryDataMaps();
|
||||||
|
ThreadPoolExecutor executor = null;
|
||||||
|
try {
|
||||||
|
executor = getExecutor();
|
||||||
|
List<Future<?>> futures = new ArrayList<>();
|
||||||
|
|
||||||
|
// 并行查询账单
|
||||||
if (!allSettleBillNoSet.isEmpty()) {
|
if (!allSettleBillNoSet.isEmpty()) {
|
||||||
List<String> settleBillNoList = new ArrayList<>(allSettleBillNoSet);
|
submitBatchQueryTasks(executor, futures, new ArrayList<>(allSettleBillNoSet), 1000,
|
||||||
List<EmisSettleBill> settleBillList = emisSettleBillMapper
|
(batch) -> {
|
||||||
.selectSimpleBillsByNos(settleBillNoList);
|
List<EmisSettleBill> batchSettleBillList = emisSettleBillMapper
|
||||||
for (EmisSettleBill settleBill : settleBillList) {
|
.selectSimpleBillsByNos(batch);
|
||||||
|
if (CollectionUtils.isNotEmpty(batchSettleBillList)) {
|
||||||
|
for (EmisSettleBill settleBill : batchSettleBillList) {
|
||||||
if (StringUtils.isNotBlank(settleBill.getSettleBillNo())) {
|
if (StringUtils.isNotBlank(settleBill.getSettleBillNo())) {
|
||||||
settleBillMap.put(settleBill.getSettleBillNo(), settleBill);
|
queryDataMaps.settleBillMap.put(settleBill.getSettleBillNo(), settleBill);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 批量查询收款记录
|
// 并行查询收款记录
|
||||||
Map<String, EmisSettlePayRecord> payRecordMap = new HashMap<>();
|
|
||||||
if (!allPayIdSet.isEmpty()) {
|
if (!allPayIdSet.isEmpty()) {
|
||||||
List<String> payIdList = new ArrayList<>(allPayIdSet);
|
submitBatchQueryTasks(executor, futures, new ArrayList<>(allPayIdSet), 1000,
|
||||||
List<EmisSettlePayRecord> payRecordList = emisSettlePayRecordMapper
|
(batch) -> {
|
||||||
.selectEmisSettlePayRecordListByPayIds(payIdList);
|
List<EmisSettlePayRecord> batchPayRecordList = emisSettlePayRecordMapper
|
||||||
for (EmisSettlePayRecord payRecord : payRecordList) {
|
.selectEmisSettlePayRecordListByPayIds(batch);
|
||||||
|
if (CollectionUtils.isNotEmpty(batchPayRecordList)) {
|
||||||
|
for (EmisSettlePayRecord payRecord : batchPayRecordList) {
|
||||||
if (StringUtils.isNotBlank(payRecord.getPayId())) {
|
if (StringUtils.isNotBlank(payRecord.getPayId())) {
|
||||||
// 如果同一个payId有多条记录,取第一条(已按create_time desc排序)
|
queryDataMaps.payRecordMap.putIfAbsent(payRecord.getPayId(), payRecord);
|
||||||
payRecordMap.putIfAbsent(payRecord.getPayId(), payRecord);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 批量查询运单信息
|
// 并行查询运单信息
|
||||||
Map<String, EmisWaybill> waybillMap = new HashMap<>();
|
|
||||||
if (!allBillNoSet.isEmpty()) {
|
if (!allBillNoSet.isEmpty()) {
|
||||||
List<String> billNoList = new ArrayList<>(allBillNoSet);
|
submitBatchQueryTasks(executor, futures, new ArrayList<>(allBillNoSet), 1000,
|
||||||
List<EmisWaybill> waybillList = emisWaybillMapper.selectWaybillsByBillCodes(billNoList);
|
(batch) -> {
|
||||||
for (EmisWaybill waybill : waybillList) {
|
List<EmisWaybill> batchWaybillList = emisWaybillMapper.selectWaybillsByBillCodes(batch);
|
||||||
|
if (CollectionUtils.isNotEmpty(batchWaybillList)) {
|
||||||
|
for (EmisWaybill waybill : batchWaybillList) {
|
||||||
if (StringUtils.isNotBlank(waybill.getBillCode())) {
|
if (StringUtils.isNotBlank(waybill.getBillCode())) {
|
||||||
waybillMap.put(waybill.getBillCode(), waybill);
|
queryDataMaps.waybillMap.put(waybill.getBillCode(), waybill);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForFutures(futures, "并行查询数据异常");
|
||||||
|
} finally {
|
||||||
|
// 关闭线程池
|
||||||
|
if (executor != null && executor != dataQueryExecutor) {
|
||||||
|
executor.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryDataMaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提交批量查询任务
|
||||||
|
*/
|
||||||
|
private <T> void submitBatchQueryTasks(ThreadPoolExecutor executor, List<Future<?>> futures,
|
||||||
|
List<T> dataList, int batchSize, java.util.function.Consumer<List<T>> task) {
|
||||||
|
for (int i = 0; i < dataList.size(); i += batchSize) {
|
||||||
|
final int start = i;
|
||||||
|
final int end = Math.min(i + batchSize, dataList.size());
|
||||||
|
Future<?> future = executor.submit(() -> {
|
||||||
|
List<T> batch = dataList.subList(start, end);
|
||||||
|
task.accept(batch);
|
||||||
|
});
|
||||||
|
futures.add(future);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 等待所有Future完成
|
||||||
|
*/
|
||||||
|
private void waitForFutures(List<Future<?>> futures, String errorMsg) {
|
||||||
|
for (Future<?> future : futures) {
|
||||||
|
try {
|
||||||
|
future.get();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(errorMsg, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第三步:处理每个开票记录,组装导出数据
|
/**
|
||||||
|
* 组装导出数据列表
|
||||||
|
*/
|
||||||
|
private List<EmisSettleInvoiceRecordExportVO> buildExportDataList(
|
||||||
|
List<EmisSettleInvoiceRecord> invoiceRecordList,
|
||||||
|
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap,
|
||||||
|
QueryDataMaps queryDataMaps) {
|
||||||
|
List<EmisSettleInvoiceRecordExportVO> exportList = new ArrayList<>();
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
|
||||||
|
|
||||||
for (EmisSettleInvoiceRecord record : invoiceRecordList) {
|
for (EmisSettleInvoiceRecord record : invoiceRecordList) {
|
||||||
|
EmisSettleInvoiceRecordExportVO exportVO = buildExportVO(record, settleBillNoToPayRelListMap,
|
||||||
|
queryDataMaps, dateFormat);
|
||||||
|
exportList.add(exportVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exportList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建单个导出VO对象
|
||||||
|
*/
|
||||||
|
private EmisSettleInvoiceRecordExportVO buildExportVO(EmisSettleInvoiceRecord record,
|
||||||
|
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap,
|
||||||
|
QueryDataMaps queryDataMaps, SimpleDateFormat dateFormat) {
|
||||||
EmisSettleInvoiceRecordExportVO exportVO = new EmisSettleInvoiceRecordExportVO();
|
EmisSettleInvoiceRecordExportVO exportVO = new EmisSettleInvoiceRecordExportVO();
|
||||||
// 基础字段
|
|
||||||
|
// 设置基础字段
|
||||||
|
setBasicFields(exportVO, record);
|
||||||
|
|
||||||
|
// 处理账单类型
|
||||||
|
Set<String> settleTypeSet = processBillTypes(exportVO, record, queryDataMaps.settleBillMap);
|
||||||
|
|
||||||
|
// 处理支付关联记录和分组
|
||||||
|
List<String> customerNameList = new ArrayList<>();
|
||||||
|
List<String> paymentDateList = new ArrayList<>();
|
||||||
|
List<String> registerDateList = new ArrayList<>();
|
||||||
|
|
||||||
|
processPaymentGroups(record, settleBillNoToPayRelListMap, queryDataMaps, dateFormat,
|
||||||
|
customerNameList, paymentDateList, registerDateList);
|
||||||
|
|
||||||
|
// 设置分组后的数据
|
||||||
|
setGroupedFields(exportVO, customerNameList, paymentDateList, registerDateList, settleTypeSet);
|
||||||
|
|
||||||
|
return exportVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置基础字段
|
||||||
|
*/
|
||||||
|
private void setBasicFields(EmisSettleInvoiceRecordExportVO exportVO, EmisSettleInvoiceRecord record) {
|
||||||
exportVO.setApplyDate(record.getApplyDate());
|
exportVO.setApplyDate(record.getApplyDate());
|
||||||
exportVO.setApplyManName(record.getApplyManName());
|
exportVO.setApplyManName(record.getApplyManName());
|
||||||
exportVO.setApplyMoney(record.getApplyMoney());
|
exportVO.setApplyMoney(record.getApplyMoney());
|
||||||
@ -559,38 +852,47 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
exportVO.setOpManName(record.getOpManName());
|
exportVO.setOpManName(record.getOpManName());
|
||||||
exportVO.setCompanyName(record.getCompanyName());
|
exportVO.setCompanyName(record.getCompanyName());
|
||||||
exportVO.setInvoiceNo(record.getInvoiceNo());
|
exportVO.setInvoiceNo(record.getInvoiceNo());
|
||||||
|
exportVO.setInvoiceStatusDesc(getInvoiceStatusDesc(record.getInvoiceStatus()));
|
||||||
// 开票状态(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());
|
exportVO.setRecedMoney(record.getRecedMoney());
|
||||||
|
exportVO.setPaymentStatusDesc(getPaymentStatusDesc(record.getPaymentStatus()));
|
||||||
// 收款状态描述
|
|
||||||
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去重
|
private String getInvoiceStatusDesc(String invoiceStatus) {
|
||||||
|
if ("0".equals(invoiceStatus)) {
|
||||||
|
return "未开票";
|
||||||
|
} else if ("1".equals(invoiceStatus)) {
|
||||||
|
return "开票中";
|
||||||
|
} else if ("2".equals(invoiceStatus)) {
|
||||||
|
return "已开票";
|
||||||
|
} else if ("3".equals(invoiceStatus)) {
|
||||||
|
return "开票异常";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
// 查询账单类型(从settle_bill获取)
|
/**
|
||||||
|
* 获取收款状态描述
|
||||||
|
*/
|
||||||
|
private String getPaymentStatusDesc(String paymentStatus) {
|
||||||
|
if ("0".equals(paymentStatus)) {
|
||||||
|
return "未收款";
|
||||||
|
} else if ("1".equals(paymentStatus)) {
|
||||||
|
return "已收款";
|
||||||
|
} else if ("2".equals(paymentStatus)) {
|
||||||
|
return "部分收款";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理账单类型
|
||||||
|
*/
|
||||||
|
private Set<String> processBillTypes(EmisSettleInvoiceRecordExportVO exportVO,
|
||||||
|
EmisSettleInvoiceRecord record, Map<String, EmisSettleBill> settleBillMap) {
|
||||||
|
Set<String> settleTypeSet = new HashSet<>();
|
||||||
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
||||||
String[] settleBillNoArr = Arrays.stream(record.getSettleBillNo().split(",")).distinct()
|
String[] settleBillNoArr = Arrays.stream(record.getSettleBillNo().split(",")).distinct()
|
||||||
.toArray(String[]::new);
|
.toArray(String[]::new);
|
||||||
@ -608,27 +910,35 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return settleTypeSet;
|
||||||
// 根据发票对应的多个账单号查询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())) {
|
|
||||||
// 从缓存中获取该记录对应的支付关联记录
|
|
||||||
List<EmisSettlePayRel> payRelList = settleBillNoToPayRelListMap.get(record.getSettleBillNo());
|
|
||||||
if (CollectionUtils.isEmpty(payRelList)) {
|
|
||||||
// 如果缓存中没有,则查询(这种情况应该不会发生,但为了安全保留)
|
|
||||||
payRelList = emisSettlePayRelMapper.selectHasPayListBySettleBillNo(record.getSettleBillNo());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CollectionUtils.isEmpty(payRelList)) {
|
/**
|
||||||
// 遍历支付关联记录,按billNo查询waybill,按cust_name和trade_date/create_time分组
|
* 处理支付分组
|
||||||
|
*/
|
||||||
|
private void processPaymentGroups(EmisSettleInvoiceRecord record,
|
||||||
|
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap,
|
||||||
|
QueryDataMaps queryDataMaps, SimpleDateFormat dateFormat,
|
||||||
|
List<String> customerNameList, List<String> paymentDateList, List<String> registerDateList) {
|
||||||
|
if (StringUtils.isBlank(record.getSettleBillNo())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<EmisSettlePayRel> payRelList = settleBillNoToPayRelListMap.get(record.getSettleBillNo());
|
||||||
|
if (CollectionUtils.isEmpty(payRelList)) {
|
||||||
|
payRelList = emisSettlePayRelMapper.selectHasPayListBySettleBillNoList(
|
||||||
|
Collections.singletonList(record.getSettleBillNo()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(payRelList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, PaymentGroup> paymentGroupMap = new HashMap<>();
|
||||||
|
Map<String, PaymentGroup> registerGroupMap = new HashMap<>();
|
||||||
|
|
||||||
for (EmisSettlePayRel payRel : payRelList) {
|
for (EmisSettlePayRel payRel : payRelList) {
|
||||||
if (payRel.getPayMoney() == null
|
if (payRel.getPayMoney() == null || payRel.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|| payRel.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,68 +947,92 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从缓存中获取waybill信息
|
// 获取客户名称
|
||||||
String custName = "";
|
String custName = getCustomerName(billNo, queryDataMaps.waybillMap, customerNameList);
|
||||||
EmisWaybill waybill = waybillMap.get(billNo);
|
|
||||||
if (waybill != null && StringUtils.isNotBlank(waybill.getCustName())) {
|
|
||||||
custName = waybill.getCustName();
|
|
||||||
// 收集客户名称
|
|
||||||
if (!customerNameList.contains(custName)) {
|
|
||||||
customerNameList.add(custName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 从缓存中获取对应的收款记录
|
// 获取收款记录
|
||||||
EmisSettlePayRecord payRecord = payRecordMap.get(payRel.getPayId());
|
EmisSettlePayRecord payRecord = queryDataMaps.payRecordMap.get(payRel.getPayId());
|
||||||
if (payRecord == null) {
|
if (payRecord == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Date tradeDate = payRecord.getTradeDate();
|
// 处理付款日期分组
|
||||||
Date createTime = payRecord.getCreateTime();
|
processPaymentDateGroup(payRecord.getTradeDate(), custName, payRel.getPayMoney(),
|
||||||
|
paymentGroupMap, dateFormat);
|
||||||
|
|
||||||
// 客户付款日期分组(按custName + tradeDate分组)
|
// 处理登记日期分组
|
||||||
// 即使custName为空,也要记录付款日期
|
processRegisterDateGroup(payRecord.getCreateTime(), custName, payRel.getPayMoney(),
|
||||||
|
registerGroupMap, dateFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化并排序
|
||||||
|
formatPaymentGroups(paymentGroupMap, paymentDateList, dateFormat, "付款");
|
||||||
|
formatPaymentGroups(registerGroupMap, registerDateList, dateFormat, "登记");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户名称
|
||||||
|
*/
|
||||||
|
private String getCustomerName(String billNo, Map<String, EmisWaybill> waybillMap,
|
||||||
|
List<String> customerNameList) {
|
||||||
|
EmisWaybill waybill = waybillMap.get(billNo);
|
||||||
|
String custName = "";
|
||||||
|
if (waybill != null && StringUtils.isNotBlank(waybill.getCustName())) {
|
||||||
|
custName = waybill.getCustName();
|
||||||
|
if (!customerNameList.contains(custName)) {
|
||||||
|
customerNameList.add(custName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return custName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理付款日期分组
|
||||||
|
*/
|
||||||
|
private void processPaymentDateGroup(Date tradeDate, String custName, BigDecimal payMoney,
|
||||||
|
Map<String, PaymentGroup> paymentGroupMap, SimpleDateFormat dateFormat) {
|
||||||
if (tradeDate != null) {
|
if (tradeDate != null) {
|
||||||
String tradeDateStr = dateFormat.format(tradeDate);
|
String tradeDateStr = dateFormat.format(tradeDate);
|
||||||
String paymentKey = (StringUtils.isNotBlank(custName) ? custName : "") + "_" + tradeDateStr;
|
String paymentKey = (StringUtils.isNotBlank(custName) ? custName : "") + "_" + tradeDateStr;
|
||||||
PaymentGroup paymentGroup = paymentGroupMap.get(paymentKey);
|
PaymentGroup paymentGroup = paymentGroupMap.computeIfAbsent(paymentKey, k -> {
|
||||||
if (paymentGroup == null) {
|
PaymentGroup group = new PaymentGroup();
|
||||||
paymentGroup = new PaymentGroup();
|
group.custName = custName != null ? custName : "";
|
||||||
paymentGroup.custName = custName != null ? custName : "";
|
group.date = tradeDate;
|
||||||
paymentGroup.date = tradeDate;
|
group.dateStr = tradeDateStr;
|
||||||
paymentGroup.dateStr = tradeDateStr;
|
group.totalMoney = BigDecimal.ZERO;
|
||||||
paymentGroup.totalMoney = BigDecimal.ZERO;
|
return group;
|
||||||
paymentGroupMap.put(paymentKey, paymentGroup);
|
});
|
||||||
|
paymentGroup.totalMoney = paymentGroup.totalMoney.add(payMoney);
|
||||||
}
|
}
|
||||||
paymentGroup.totalMoney = paymentGroup.totalMoney.add(payRel.getPayMoney());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 收款登记日期分组(按custName + createTime分组)
|
/**
|
||||||
// 即使custName为空,也要记录登记日期
|
* 处理登记日期分组
|
||||||
|
*/
|
||||||
|
private void processRegisterDateGroup(Date createTime, String custName, BigDecimal payMoney,
|
||||||
|
Map<String, PaymentGroup> registerGroupMap, SimpleDateFormat dateFormat) {
|
||||||
if (createTime != null) {
|
if (createTime != null) {
|
||||||
String createTimeStr = dateFormat.format(createTime);
|
String createTimeStr = dateFormat.format(createTime);
|
||||||
String registerKey = (StringUtils.isNotBlank(custName) ? custName : "") + "_"
|
String registerKey = (StringUtils.isNotBlank(custName) ? custName : "") + "_" + createTimeStr;
|
||||||
+ createTimeStr;
|
PaymentGroup registerGroup = registerGroupMap.computeIfAbsent(registerKey, k -> {
|
||||||
PaymentGroup registerGroup = registerGroupMap.get(registerKey);
|
PaymentGroup group = new PaymentGroup();
|
||||||
if (registerGroup == null) {
|
group.custName = custName != null ? custName : "";
|
||||||
registerGroup = new PaymentGroup();
|
group.date = createTime;
|
||||||
registerGroup.custName = custName != null ? custName : "";
|
group.dateStr = createTimeStr;
|
||||||
registerGroup.date = createTime;
|
group.totalMoney = BigDecimal.ZERO;
|
||||||
registerGroup.dateStr = createTimeStr;
|
return group;
|
||||||
registerGroup.totalMoney = BigDecimal.ZERO;
|
});
|
||||||
registerGroupMap.put(registerKey, registerGroup);
|
registerGroup.totalMoney = registerGroup.totalMoney.add(payMoney);
|
||||||
}
|
|
||||||
registerGroup.totalMoney = registerGroup.totalMoney.add(payRel.getPayMoney());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化客户付款日期(格式:2025/10/30 付款2000元 A公司)
|
/**
|
||||||
// 按日期从小到大排序
|
* 格式化支付分组
|
||||||
List<PaymentGroup> sortedPaymentGroups = new ArrayList<>(paymentGroupMap.values());
|
*/
|
||||||
sortedPaymentGroups.sort((g1, g2) -> {
|
private void formatPaymentGroups(Map<String, PaymentGroup> groupMap, List<String> dateList,
|
||||||
|
SimpleDateFormat dateFormat, String type) {
|
||||||
|
List<PaymentGroup> sortedGroups = new ArrayList<>(groupMap.values());
|
||||||
|
sortedGroups.sort((g1, g2) -> {
|
||||||
if (g1.date == null && g2.date == null) {
|
if (g1.date == null && g2.date == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -710,66 +1044,44 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
|||||||
}
|
}
|
||||||
return g1.date.compareTo(g2.date);
|
return g1.date.compareTo(g2.date);
|
||||||
});
|
});
|
||||||
for (PaymentGroup group : sortedPaymentGroups) {
|
|
||||||
|
for (PaymentGroup group : sortedGroups) {
|
||||||
BigDecimal strippedMoney = group.totalMoney.stripTrailingZeros();
|
BigDecimal strippedMoney = group.totalMoney.stripTrailingZeros();
|
||||||
String paymentDateStr = group.dateStr + " 付款" + strippedMoney.toPlainString() + "元";
|
String dateStr = group.dateStr + " " + type + strippedMoney.toPlainString() + "元";
|
||||||
// 如果客户名称不为空,则追加客户名称
|
|
||||||
if (StringUtils.isNotBlank(group.custName)) {
|
if (StringUtils.isNotBlank(group.custName)) {
|
||||||
paymentDateStr += " " + group.custName;
|
dateStr += " " + group.custName;
|
||||||
|
}
|
||||||
|
dateList.add(dateStr);
|
||||||
}
|
}
|
||||||
paymentDateList.add(paymentDateStr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化收款登记日期(格式:2025/10/30 登记2000元 A公司)
|
/**
|
||||||
// 按日期从小到大排序
|
* 设置分组后的字段
|
||||||
List<PaymentGroup> sortedRegisterGroups = new ArrayList<>(registerGroupMap.values());
|
*/
|
||||||
sortedRegisterGroups.sort((g1, g2) -> {
|
private void setGroupedFields(EmisSettleInvoiceRecordExportVO exportVO, List<String> customerNameList,
|
||||||
if (g1.date == null && g2.date == null) {
|
List<String> paymentDateList, List<String> registerDateList, Set<String> settleTypeSet) {
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (g1.date == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (g2.date == null) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return g1.date.compareTo(g2.date);
|
|
||||||
});
|
|
||||||
for (PaymentGroup group : sortedRegisterGroups) {
|
|
||||||
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)) {
|
if (!CollectionUtils.isEmpty(customerNameList)) {
|
||||||
exportVO.setCustomerNames(String.join(",", customerNameList));
|
exportVO.setCustomerNames(String.join(",", customerNameList));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置客户付款日期(多个用逗号分隔)
|
|
||||||
if (!CollectionUtils.isEmpty(paymentDateList)) {
|
if (!CollectionUtils.isEmpty(paymentDateList)) {
|
||||||
exportVO.setCustomerPaymentDates(String.join(";", paymentDateList));
|
exportVO.setCustomerPaymentDates(String.join(";", paymentDateList));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置收款登记日期(多个用逗号分隔)
|
|
||||||
if (!CollectionUtils.isEmpty(registerDateList)) {
|
if (!CollectionUtils.isEmpty(registerDateList)) {
|
||||||
exportVO.setCollectionRegisterDates(String.join(";", registerDateList));
|
exportVO.setCollectionRegisterDates(String.join(";", registerDateList));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置账单类型(多个用逗号分隔)
|
|
||||||
if (!settleTypeSet.isEmpty()) {
|
if (!settleTypeSet.isEmpty()) {
|
||||||
List<String> settleTypeList = new ArrayList<>(settleTypeSet);
|
List<String> settleTypeList = new ArrayList<>(settleTypeSet);
|
||||||
exportVO.setBillType(String.join(",", settleTypeList));
|
exportVO.setBillType(String.join(",", settleTypeList));
|
||||||
}
|
}
|
||||||
|
|
||||||
exportList.add(exportVO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return exportList;
|
/**
|
||||||
|
* 查询数据映射内部类
|
||||||
|
*/
|
||||||
|
private static class QueryDataMaps {
|
||||||
|
Map<String, EmisSettleBill> settleBillMap = new ConcurrentHashMap<>();
|
||||||
|
Map<String, EmisSettlePayRecord> payRecordMap = new ConcurrentHashMap<>();
|
||||||
|
Map<String, EmisWaybill> waybillMap = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -79,6 +79,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
)
|
)
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectHasPayListBySettleBillNoList" parameterType="List" resultMap="EmisSettlePayRelWithSubBillResult">
|
||||||
|
select distinct a.id, a.pay_id, a.bill_no, a.pay_money, a.del_flag, a.create_by, a.create_time,
|
||||||
|
a.update_by, a.update_time, a.create_site, a.update_site
|
||||||
|
from emis_settle_pay_rel a
|
||||||
|
inner join emis_settle_pay_record b on a.pay_id = b.pay_id and b.del_flag = '0'
|
||||||
|
inner join emis_settle_pay_bill_rel espbr on a.pay_id = espbr.pay_id and espbr.del_flag = '0'
|
||||||
|
inner join emis_settle_sub_bill essb on a.bill_no = essb.bill_no and essb.del_flag = '0'
|
||||||
|
where a.del_flag = '0'
|
||||||
|
<if test="settleBillNoList != null and settleBillNoList.size() > 0">
|
||||||
|
and espbr.settle_bill_no in
|
||||||
|
<foreach item="settleBillNo" collection="settleBillNoList" open="(" separator="," close=")">
|
||||||
|
#{settleBillNo}
|
||||||
|
</foreach>
|
||||||
|
and essb.settle_bill_no in
|
||||||
|
<foreach item="settleBillNo" collection="settleBillNoList" open="(" separator="," close=")">
|
||||||
|
#{settleBillNo}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
<select id="selectHasPayMapList" parameterType="String" resultType="map">
|
<select id="selectHasPayMapList" parameterType="String" resultType="map">
|
||||||
select a.bill_no as billNo, sum(a.pay_money) sumMoney
|
select a.bill_no as billNo, sum(a.pay_money) sumMoney
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user