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.xdadan.erp.emis.domain.EmisSettleInvoiceRel;
|
||||
import com.xdadan.erp.emis.domain.EmisSettlePayRel;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
/**
|
||||
* @ClassName EmisSettlePayRelMapper
|
||||
* @Description <p> 支付子账单关联表 Mapper 接口 </p>
|
||||
@ -33,6 +34,14 @@ public interface EmisSettlePayRelMapper extends BaseMapper<EmisSettlePayRel>
|
||||
|
||||
public List<EmisSettlePayRel> selectHasPayListBySettleBillNo(String settleBillNo);
|
||||
|
||||
/**
|
||||
* 根据账单号列表查询支付关联记录
|
||||
*
|
||||
* @param settleBillNoList 账单号列表
|
||||
* @return 支付关联记录列表
|
||||
*/
|
||||
public List<EmisSettlePayRel> selectHasPayListBySettleBillNoList(@Param("settleBillNoList") List<String> settleBillNoList);
|
||||
|
||||
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 org.springframework.transaction.annotation.Transactional;
|
||||
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业务层处理
|
||||
@ -83,6 +87,40 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
||||
@Autowired
|
||||
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
|
||||
public List<EmisSettleInvoiceRecordExportVO> selectCustomExportList(
|
||||
EmisSettleInvoiceRecord emisSettleInvoiceRecord) {
|
||||
// 查询开票记录列表
|
||||
List<EmisSettleInvoiceRecord> invoiceRecordList = emisSettleInvoiceRecordMapper
|
||||
.selectSimpleInvoiceRecordList(emisSettleInvoiceRecord);
|
||||
|
||||
// 分页查询开票记录列表
|
||||
List<EmisSettleInvoiceRecord> invoiceRecordList = queryInvoiceRecordListByPage(emisSettleInvoiceRecord);
|
||||
if (CollectionUtils.isEmpty(invoiceRecordList)) {
|
||||
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<>(); // 所有账单号
|
||||
Set<String> allPayIdSet = new HashSet<>(); // 所有支付ID
|
||||
Set<String> allBillNoSet = new HashSet<>(); // 所有运单号
|
||||
// 查询支付关联记录并建立映射关系
|
||||
Map<String, List<EmisSettlePayRel>> settleBillNoToPayRelListMap = queryPayRelListAndBuildMapping(
|
||||
allSettleBillNoSet, allPayIdSet, allBillNoSet, invoiceRecordList);
|
||||
|
||||
// 收集所有账单号
|
||||
// 并行批量查询账单、收款记录、运单信息
|
||||
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) {
|
||||
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
||||
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<>();
|
||||
// 建立 payId -> Set<settleBillNo> 的映射关系
|
||||
Map<String, Set<String>> payIdToSettleBillNoSetMap = new HashMap<>();
|
||||
|
||||
if (!allSettleBillNoSet.isEmpty()) {
|
||||
// 一次性查询所有支付关联记录(合并所有settleBillNo)
|
||||
String allSettleBillNoStr = String.join(",", allSettleBillNoSet);
|
||||
List<EmisSettlePayRel> allPayRelList = emisSettlePayRelMapper
|
||||
.selectHasPayListBySettleBillNo(allSettleBillNoStr);
|
||||
if (allSettleBillNoSet.isEmpty()) {
|
||||
return settleBillNoToPayRelListMap;
|
||||
}
|
||||
|
||||
ThreadPoolExecutor executor = null;
|
||||
try {
|
||||
executor = getExecutor();
|
||||
// 分批并行查询所有支付关联记录
|
||||
List<EmisSettlePayRel> allPayRelList = batchQueryPayRelList(executor, allSettleBillNoSet);
|
||||
|
||||
// 收集所有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) {
|
||||
if (StringUtils.isNotBlank(payRel.getPayId())) {
|
||||
allPayIdSet.add(payRel.getPayId());
|
||||
@ -451,15 +604,35 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
||||
allBillNoSet.add(payRel.getBillNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 查询 payId 到 settleBillNo 的映射关系
|
||||
if (!allPayIdSet.isEmpty() && !allSettleBillNoSet.isEmpty()) {
|
||||
// 根据allSettleBillNoSet批量查询相关的支付账单关联记录
|
||||
List<String> settleBillNoList = new ArrayList<>(allSettleBillNoSet);
|
||||
List<EmisSettlePayBillRel> payBillRelList = emisSettlePayBillRelMapper
|
||||
.selectEmisSettlePayBillRelListBySettleBillNos(settleBillNoList);
|
||||
/**
|
||||
* 查询支付账单关联映射
|
||||
*/
|
||||
private void queryPayBillRelMapping(ThreadPoolExecutor executor, Set<String> allSettleBillNoSet,
|
||||
Set<String> allPayIdSet, Map<String, Set<String>> payIdToSettleBillNoSetMap) {
|
||||
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) {
|
||||
if (StringUtils.isNotBlank(payBillRel.getPayId())
|
||||
&& 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) {
|
||||
if (StringUtils.isNotBlank(record.getSettleBillNo())) {
|
||||
// 解析该记录的settleBillNo(可能是逗号分隔的多个)
|
||||
Set<String> recordSettleBillNoSet = new HashSet<>();
|
||||
String[] settleBillNoArr = record.getSettleBillNo().split(",");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<String> recordSettleBillNoSet = parseSettleBillNos(record.getSettleBillNo());
|
||||
List<EmisSettlePayRel> recordPayRelList = filterPayRelListBySettleBillNo(
|
||||
allPayRelList, recordSettleBillNoSet, payIdToSettleBillNoSetMap);
|
||||
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()) {
|
||||
List<String> settleBillNoList = new ArrayList<>(allSettleBillNoSet);
|
||||
List<EmisSettleBill> settleBillList = emisSettleBillMapper
|
||||
.selectSimpleBillsByNos(settleBillNoList);
|
||||
for (EmisSettleBill settleBill : settleBillList) {
|
||||
submitBatchQueryTasks(executor, futures, new ArrayList<>(allSettleBillNoSet), 1000,
|
||||
(batch) -> {
|
||||
List<EmisSettleBill> batchSettleBillList = emisSettleBillMapper
|
||||
.selectSimpleBillsByNos(batch);
|
||||
if (CollectionUtils.isNotEmpty(batchSettleBillList)) {
|
||||
for (EmisSettleBill settleBill : batchSettleBillList) {
|
||||
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()) {
|
||||
List<String> payIdList = new ArrayList<>(allPayIdSet);
|
||||
List<EmisSettlePayRecord> payRecordList = emisSettlePayRecordMapper
|
||||
.selectEmisSettlePayRecordListByPayIds(payIdList);
|
||||
for (EmisSettlePayRecord payRecord : payRecordList) {
|
||||
submitBatchQueryTasks(executor, futures, new ArrayList<>(allPayIdSet), 1000,
|
||||
(batch) -> {
|
||||
List<EmisSettlePayRecord> batchPayRecordList = emisSettlePayRecordMapper
|
||||
.selectEmisSettlePayRecordListByPayIds(batch);
|
||||
if (CollectionUtils.isNotEmpty(batchPayRecordList)) {
|
||||
for (EmisSettlePayRecord payRecord : batchPayRecordList) {
|
||||
if (StringUtils.isNotBlank(payRecord.getPayId())) {
|
||||
// 如果同一个payId有多条记录,取第一条(已按create_time desc排序)
|
||||
payRecordMap.putIfAbsent(payRecord.getPayId(), payRecord);
|
||||
queryDataMaps.payRecordMap.putIfAbsent(payRecord.getPayId(), payRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 批量查询运单信息
|
||||
Map<String, EmisWaybill> waybillMap = new HashMap<>();
|
||||
// 并行查询运单信息
|
||||
if (!allBillNoSet.isEmpty()) {
|
||||
List<String> billNoList = new ArrayList<>(allBillNoSet);
|
||||
List<EmisWaybill> waybillList = emisWaybillMapper.selectWaybillsByBillCodes(billNoList);
|
||||
for (EmisWaybill waybill : waybillList) {
|
||||
submitBatchQueryTasks(executor, futures, new ArrayList<>(allBillNoSet), 1000,
|
||||
(batch) -> {
|
||||
List<EmisWaybill> batchWaybillList = emisWaybillMapper.selectWaybillsByBillCodes(batch);
|
||||
if (CollectionUtils.isNotEmpty(batchWaybillList)) {
|
||||
for (EmisWaybill waybill : batchWaybillList) {
|
||||
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) {
|
||||
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();
|
||||
// 基础字段
|
||||
|
||||
// 设置基础字段
|
||||
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.setApplyManName(record.getApplyManName());
|
||||
exportVO.setApplyMoney(record.getApplyMoney());
|
||||
@ -559,38 +852,47 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
||||
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.setInvoiceStatusDesc(getInvoiceStatusDesc(record.getInvoiceStatus()));
|
||||
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(getPaymentStatusDesc(record.getPaymentStatus()));
|
||||
}
|
||||
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())) {
|
||||
String[] settleBillNoArr = Arrays.stream(record.getSettleBillNo().split(",")).distinct()
|
||||
.toArray(String[]::new);
|
||||
@ -608,27 +910,35 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据发票对应的多个账单号查询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());
|
||||
return settleTypeSet;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (payRel.getPayMoney() == null
|
||||
|| payRel.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
if (payRel.getPayMoney() == null || payRel.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -637,68 +947,92 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
||||
continue;
|
||||
}
|
||||
|
||||
// 从缓存中获取waybill信息
|
||||
String custName = "";
|
||||
EmisWaybill waybill = waybillMap.get(billNo);
|
||||
if (waybill != null && StringUtils.isNotBlank(waybill.getCustName())) {
|
||||
custName = waybill.getCustName();
|
||||
// 收集客户名称
|
||||
if (!customerNameList.contains(custName)) {
|
||||
customerNameList.add(custName);
|
||||
}
|
||||
}
|
||||
// 获取客户名称
|
||||
String custName = getCustomerName(billNo, queryDataMaps.waybillMap, customerNameList);
|
||||
|
||||
// 从缓存中获取对应的收款记录
|
||||
EmisSettlePayRecord payRecord = payRecordMap.get(payRel.getPayId());
|
||||
// 获取收款记录
|
||||
EmisSettlePayRecord payRecord = queryDataMaps.payRecordMap.get(payRel.getPayId());
|
||||
if (payRecord == null) {
|
||||
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) {
|
||||
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 paymentGroup = paymentGroupMap.computeIfAbsent(paymentKey, k -> {
|
||||
PaymentGroup group = new PaymentGroup();
|
||||
group.custName = custName != null ? custName : "";
|
||||
group.date = tradeDate;
|
||||
group.dateStr = tradeDateStr;
|
||||
group.totalMoney = BigDecimal.ZERO;
|
||||
return group;
|
||||
});
|
||||
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) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
String registerKey = (StringUtils.isNotBlank(custName) ? custName : "") + "_" + createTimeStr;
|
||||
PaymentGroup registerGroup = registerGroupMap.computeIfAbsent(registerKey, k -> {
|
||||
PaymentGroup group = new PaymentGroup();
|
||||
group.custName = custName != null ? custName : "";
|
||||
group.date = createTime;
|
||||
group.dateStr = createTimeStr;
|
||||
group.totalMoney = BigDecimal.ZERO;
|
||||
return group;
|
||||
});
|
||||
registerGroup.totalMoney = registerGroup.totalMoney.add(payMoney);
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化客户付款日期(格式: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) {
|
||||
return 0;
|
||||
}
|
||||
@ -710,66 +1044,44 @@ public class EmisSettleInvoiceRecordServiceImpl extends EmisBaseService implemen
|
||||
}
|
||||
return g1.date.compareTo(g2.date);
|
||||
});
|
||||
for (PaymentGroup group : sortedPaymentGroups) {
|
||||
|
||||
for (PaymentGroup group : sortedGroups) {
|
||||
BigDecimal strippedMoney = group.totalMoney.stripTrailingZeros();
|
||||
String paymentDateStr = group.dateStr + " 付款" + strippedMoney.toPlainString() + "元";
|
||||
// 如果客户名称不为空,则追加客户名称
|
||||
String dateStr = group.dateStr + " " + type + strippedMoney.toPlainString() + "元";
|
||||
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) -> {
|
||||
if (g1.date == null && g2.date == null) {
|
||||
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);
|
||||
}
|
||||
|
||||
// 设置客户名称(多个用逗号分隔)
|
||||
/**
|
||||
* 设置分组后的字段
|
||||
*/
|
||||
private void setGroupedFields(EmisSettleInvoiceRecordExportVO exportVO, List<String> customerNameList,
|
||||
List<String> paymentDateList, List<String> registerDateList, Set<String> settleTypeSet) {
|
||||
if (!CollectionUtils.isEmpty(customerNameList)) {
|
||||
exportVO.setCustomerNames(String.join(",", customerNameList));
|
||||
}
|
||||
|
||||
// 设置客户付款日期(多个用逗号分隔)
|
||||
if (!CollectionUtils.isEmpty(paymentDateList)) {
|
||||
exportVO.setCustomerPaymentDates(String.join(";", paymentDateList));
|
||||
}
|
||||
|
||||
// 设置收款登记日期(多个用逗号分隔)
|
||||
if (!CollectionUtils.isEmpty(registerDateList)) {
|
||||
exportVO.setCollectionRegisterDates(String.join(";", registerDateList));
|
||||
}
|
||||
|
||||
// 设置账单类型(多个用逗号分隔)
|
||||
if (!settleTypeSet.isEmpty()) {
|
||||
List<String> settleTypeList = new ArrayList<>(settleTypeSet);
|
||||
exportVO.setBillType(String.join(",", settleTypeList));
|
||||
}
|
||||
|
||||
exportList.add(exportVO);
|
||||
}
|
||||
|
||||
return exportList;
|
||||
/**
|
||||
* 查询数据映射内部类
|
||||
*/
|
||||
private static class 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 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 a.bill_no as billNo, sum(a.pay_money) sumMoney
|
||||
|
||||
Loading…
Reference in New Issue
Block a user