♻️ syncKingdeeInvoiceResult优化N+1问题,使用批量查询和批量插入/更新
This commit is contained in:
+40
-7
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
@@ -790,6 +791,12 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
continue;
|
||||
}
|
||||
log.info("金蝶开票结果回写批次查询成功:serialNo=[{}],返回单据数={}", batchSerialNos, result.getData().size());
|
||||
// 批量查询当前批次已存在的发票号码(避免 N+1)
|
||||
Set<String> existingInvoiceNos = batchQueryExistingInvoiceNos(batch);
|
||||
log.debug("金蝶开票结果回写:批次已存在发票号码数={}", existingInvoiceNos.size());
|
||||
// 收集待插入的发票记录和待更新的开票申请
|
||||
List<InvoiceApplicationInvoice> toInsertInvoices = new ArrayList<>();
|
||||
List<InvoiceApplication> toUpdateApplications = new ArrayList<>();
|
||||
for (BfiInvoiceApplyOpenApiBillVO bill : result.getData()) {
|
||||
String billNo = bill.getBillNo();
|
||||
InvoiceApplication application = applicationBySerialNo.get(billNo);
|
||||
@@ -802,11 +809,8 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
if (Func.isBlank(invoiceNo)) {
|
||||
continue;
|
||||
}
|
||||
Long exists = invoiceApplicationInvoiceMapper.selectCount(
|
||||
Wrappers.<InvoiceApplicationInvoice>lambdaQuery()
|
||||
.eq(InvoiceApplicationInvoice::getInvoiceApplicationId, application.getId())
|
||||
.eq(InvoiceApplicationInvoice::getInvoiceNo, invoiceNo));
|
||||
if (exists != null && exists > 0) {
|
||||
// 使用批量查询结果判断是否已存在
|
||||
if (existingInvoiceNos.contains(invoiceNo)) {
|
||||
log.debug("金蝶开票结果回写:发票号码[{}]已存在,跳过", invoiceNo);
|
||||
continue;
|
||||
}
|
||||
@@ -817,8 +821,10 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
record.setInvoiceDate(parseInvoiceDateTimestamp(invoice.getInvoiceDate()));
|
||||
record.setInvoiceAmount(invoice.getIncludeTaxAmount());
|
||||
record.setRawJson(JsonUtil.toJson(invoice));
|
||||
invoiceApplicationInvoiceMapper.insert(record);
|
||||
toInsertInvoices.add(record);
|
||||
inserted++;
|
||||
// 标记为已存在,避免同批次重复插入
|
||||
existingInvoiceNos.add(invoiceNo);
|
||||
log.info("金蝶开票结果回写:写入发票,申请单号=[{}],单据编号=[{}],发票号码=[{}],含税金额=[{}]",
|
||||
application.getApplicationNo(), billNo, invoiceNo, invoice.getIncludeTaxAmount());
|
||||
}
|
||||
@@ -826,11 +832,21 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
invoiceWritten += inserted;
|
||||
// 查到发票:开票申请单推进开票完成(终态)
|
||||
application.setKingdeeStatus(KingdeeBfiConstant.KINGDEE_STATUS_INVOICED);
|
||||
updateById(application);
|
||||
toUpdateApplications.add(application);
|
||||
invoicedCount++;
|
||||
log.info("金蝶开票结果回写:开票申请[{}]状态推进为invoiced,本次写入发票{}张", application.getApplicationNo(), inserted);
|
||||
}
|
||||
}
|
||||
// 批量插入发票记录
|
||||
if (!toInsertInvoices.isEmpty()) {
|
||||
Db.saveBatch(toInsertInvoices);
|
||||
log.info("金蝶开票结果回写:批量插入发票记录{}条", toInsertInvoices.size());
|
||||
}
|
||||
// 批量更新开票申请状态
|
||||
if (!toUpdateApplications.isEmpty()) {
|
||||
updateBatchById(toUpdateApplications);
|
||||
log.info("金蝶开票结果回写:批量更新开票申请状态{}笔", toUpdateApplications.size());
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
failed++;
|
||||
log.error("金蝶开票结果回写批次异常:serialNo=[{}]", batchSerialNos, exception);
|
||||
@@ -843,6 +859,23 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl<InvoiceApplic
|
||||
+ "笔),回写发票" + invoiceWritten + "张(开票完成" + invoicedCount + "笔,失败批次" + failed + "个)";
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量查询当前批次已存在的发票号码
|
||||
*
|
||||
* @param serialNos 单据编号列表
|
||||
* @return 已存在的发票号码集合
|
||||
*/
|
||||
private Set<String> batchQueryExistingInvoiceNos(List<String> serialNos) {
|
||||
List<InvoiceApplicationInvoice> existingList = invoiceApplicationInvoiceMapper.selectList(
|
||||
Wrappers.<InvoiceApplicationInvoice>lambdaQuery()
|
||||
.in(InvoiceApplicationInvoice::getSerialNo, serialNos)
|
||||
.select(InvoiceApplicationInvoice::getInvoiceNo));
|
||||
return existingList.stream()
|
||||
.map(InvoiceApplicationInvoice::getInvoiceNo)
|
||||
.filter(Func::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/** 从票易通原文 Map 中按候选键顺序取首个非空文本值 */
|
||||
private String firstText(Map<?, ?> map, String... keys) {
|
||||
for (String key : keys) {
|
||||
|
||||
Reference in New Issue
Block a user