demand: 扫描运单组批次柯桥市场部-柯桥分拨中心-杭州不再互换 根据批次/批量扫描组批次针对分批运单做适应 查询漏组批次增加查询分批后未组完的运单

committer: heyu
This commit is contained in:
aike 2025-08-05 16:22:51 +08:00
parent 5b48f25cc9
commit 1dd0c4d6d8
6 changed files with 118 additions and 46 deletions

View File

@ -120,7 +120,7 @@ public class EmisTmsSiteBatchMiss extends BaseEntity {
private Integer missCount;
/**
* 漏组属性.0:其他,1:没有创建线路,2:没有组批次,3:组批次全错,默认为0
* 漏组属性.0:其他,1:没有创建线路,2:没有组批次,3:组批次全错,4:运单分批后未组完,默认为0
*/
private String missType;

View File

@ -4386,7 +4386,8 @@ public class EmisBaseService {
if (CollectionUtil.isEmpty(billCodes)) {
return;
}
List<String> lineCodes = emisWaybills.stream().map(EmisWaybill::getTransLineType).distinct().collect(Collectors.toList());
List<String> lineCodes = emisWaybills.stream().map(EmisWaybill::getTransLineType).distinct()
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(lineCodes)) {
return;
}
@ -4417,14 +4418,21 @@ public class EmisBaseService {
failedBillCodes.addAll(result.getFailedBillCodes());
// 批量插入运单组批次状态记录
if (!result.getBatchStatusList().isEmpty()) {
List<EmisWaybillBatchStatus> batchStatusList = result.getBatchStatusList();
List<EmisTmsSiteBatchMiss> missRecords = result.getMissRecords();
if (!batchStatusList.isEmpty()) {
filterBatchStatusList(batchStatusList, missRecords);
}
// 批量插入运单组批次状态记录
if (!batchStatusList.isEmpty()) {
emisWaybillBatchStatusMapper.batchInsertEmisWaybillBatchStatus(result.getBatchStatusList());
totalBatchStatusRecords += result.getBatchStatusList().size();
}
// 批量保存漏组记录
if (!result.getMissRecords().isEmpty()) {
List<EmisTmsSiteBatchMiss> filteredRecords = result.getMissRecords().stream()
if (!missRecords.isEmpty()) {
List<EmisTmsSiteBatchMiss> filteredRecords = missRecords.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(
record -> record.getBillCode() + "_" + record.getMissReason(),
@ -4439,7 +4447,8 @@ public class EmisBaseService {
long processTime = endTime - startTime;
// 保存扫描记录
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes,totalBatchStatusRecords,totalMissRecords);
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes, totalBatchStatusRecords,
totalMissRecords);
log.info(
"Auto scan completed. Total processed: {}, Success: {}, Failed: {}, Time taken: {}ms, Batch status records: {}, Miss records: {}",
@ -4453,6 +4462,52 @@ public class EmisBaseService {
}
}
public void filterBatchStatusList(List<EmisWaybillBatchStatus> batchStatusList, List<EmisTmsSiteBatchMiss> missRecords) {
// 获取所有运单号
List<String> batchStatusBillCodes = batchStatusList.stream()
.map(EmisWaybillBatchStatus::getBillCode)
.collect(Collectors.toList());
// 查询emis_tms_site_batch_dtl中waybill_batch_status=1的运单
EmisTmsSiteBatchDtl queryCondition = new EmisTmsSiteBatchDtl();
queryCondition.getParams().put("billCodes", batchStatusBillCodes);
queryCondition.setWaybillBatchStatus("1");
List<EmisTmsSiteBatchDtl> filteredBatchDtls = emisTmsSiteBatchDtlMapper
.selectEmisTmsSiteBatchDtlList(queryCondition);
// 获取已分批的运单号集合
Set<String> filteredBillCodes = filteredBatchDtls.stream()
.map(EmisTmsSiteBatchDtl::getBillCode)
.collect(Collectors.toSet());
if (CollectionUtil.isEmpty(filteredBillCodes)) {
return;
}
// 将waybill_batch_status=1的运单进行去重处理添加到漏组记录
Set<String> processedBillCodes = new HashSet<>();
if (CollectionUtil.isNotEmpty(missRecords)) {
for (EmisWaybillBatchStatus batchStatus : batchStatusList) {
if (filteredBillCodes.contains(batchStatus.getBillCode())
&& processedBillCodes.add(batchStatus.getBillCode())) {
// 创建漏组记录
EmisTmsSiteBatchMiss missRecord = new EmisTmsSiteBatchMiss();
missRecord.setBillCode(batchStatus.getBillCode());
missRecord.setMissReason("运单分批后未组完");
missRecord.setMissType("4");
missRecord.setCreateBy("system");
missRecord.setCreateTime(new Date());
missRecord.setCreateSite("88888");
// 添加到漏组记录列表
missRecords.add(missRecord);
}
}
}
// 从batchStatusList中剔除waybill_batch_status=1的运单
batchStatusList.removeIf(batchStatus -> filteredBillCodes.contains(batchStatus.getBillCode()));
}
public void saveRecord(int totalProcessed, int successCount, int failCount, long processTime,
List<String> failedBillCodes, int totalBatchStatusRecords, int totalMissRecords) {
EmisTmsSiteBatchMissRecord record = new EmisTmsSiteBatchMissRecord();
@ -4684,11 +4739,6 @@ public class EmisBaseService {
.filter(rule -> "51000".equals(rule.getStartSiteCode())
|| "51200".equals(rule.getStartSiteCode()))
.collect(Collectors.toList()); // 无锡,张家港
} else if ("57502".equals(sendSiteCode) || "57501".equals(sendSiteCode) || "57100".equals(sendSiteCode)) {
filteredRuleList = ruleList.stream()
.filter(rule -> "57502".equals(rule.getStartSiteCode())
|| "57501".equals(rule.getStartSiteCode()) || "57100".equals(rule.getStartSiteCode()))
.collect(Collectors.toList()); // 柯桥市场部、柯桥分拨中心、杭州
} else if ("25001".equals(sendSiteCode) || "25000".equals(sendSiteCode)) {
filteredRuleList = ruleList.stream()
.filter(rule -> "25001".equals(rule.getStartSiteCode())

View File

@ -320,6 +320,10 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
(existing, replacement) -> existing));
List<EmisTmsSiteBatchMiss> uniqueMissRecords = new ArrayList<>(missMap.values());
if (!uniqueBatchStatus.isEmpty()) {
filterBatchStatusList(uniqueBatchStatus, uniqueMissRecords);
}
// 批量插入 - 每次插入5000条
if (!uniqueBatchStatus.isEmpty()) {
int batchSize = 5000;

View File

@ -174,6 +174,7 @@ public class EmisTmsSiteBatchServiceImpl extends EmisBaseService implements IEmi
if (isParcelQtyEqual && isWeightEqual && isVolumeEqual) {
checkUnique(oldSiteBatch, itemDtl.getBillCode());
compareWaybillAndBatch(oldSiteBatch, itemDtl, emisWaybill, rule, false);
return;
}
@ -190,12 +191,53 @@ public class EmisTmsSiteBatchServiceImpl extends EmisBaseService implements IEmi
throw new EmisBizError(EmisBizErrorType.FAIL, itemDtl.getBillCode() + "的批次体积必须大于0");
}
compareWaybillAndBatch(oldSiteBatch, itemDtl, emisWaybill, rule,true);
}
private void compareWaybillAndBatch(EmisTmsSiteBatch oldSiteBatch, EmisTmsSiteBatchDtl itemDtl, EmisWaybill emisWaybill, EmisTransPlanRule rule, boolean isBatch) throws EmisBizError {
// 根据起始网点、下一网点和运单号查询TMS组批次
List<EmisTmsSiteBatch> existingBatches = selectTmsSiteBatchBySiteAndBillCode(
oldSiteBatch.getStartSiteCode(),
oldSiteBatch.getNextSiteCode(),
itemDtl.getBillCode(), itemDtl.getId());
// 检查rule.supplierCode是否包含多个供应商编码(用逗号隔开)
if (StringUtils.isNotBlank(rule.getSupplierCode()) && rule.getSupplierCode().contains(",")) {
// 将supplierCode按逗号分割成数组
String[] supplierCodes = rule.getSupplierCode().split(",");
List<String> supplierCodeList = Arrays.asList(supplierCodes);
// 检查现有批次中是否有supplierCode在rule.supplierCode内
boolean hasMatchingSupplier = existingBatches.stream()
.anyMatch(batch -> supplierCodeList.contains(batch.getSupplierCode()));
if (hasMatchingSupplier) {
// 找到匹配的批次,检查重量、体积、件数是否一致
EmisTmsSiteBatch matchingBatch = existingBatches.stream()
.filter(batch -> supplierCodeList.contains(batch.getSupplierCode()))
.findFirst()
.orElse(null);
if (matchingBatch != null) {
// 检查批次重量、体积、件数是否一致
boolean isBatchWeightEqual = matchingBatch.getTotalWeight() != null
&& itemDtl.getBatchWeight() != null
&& matchingBatch.getTotalWeight().compareTo(itemDtl.getBatchWeight()) == 0;
boolean isBatchVolumeEqual = matchingBatch.getTotalVolume() != null
&& itemDtl.getBatchVolume() != null
&& matchingBatch.getTotalVolume().compareTo(itemDtl.getBatchVolume()) == 0;
boolean isBatchParcelQtyEqual = Objects.equals(matchingBatch.getTotalParcelQty(),
itemDtl.getBatchParcelQty());
if (!isBatchWeightEqual || !isBatchVolumeEqual || !isBatchParcelQtyEqual) {
throw new EmisBizError(EmisBizErrorType.FAIL,
itemDtl.getBillCode() + "的批次重量、体积、件数与批次" + matchingBatch.getBatchNo() + "不一致,请检查后重新录入");
}
}
}
}
// 创建包含当前批次的临时批次列表用于分组去重
List<EmisTmsSiteBatch> allBatches = new ArrayList<>(existingBatches);
@ -279,41 +321,8 @@ public class EmisTmsSiteBatchServiceImpl extends EmisBaseService implements IEmi
itemDtl.getBillCode() + "的批次总体积(" + totalVolume + ")超过运单体积(" + emisWaybill.getTotalVolume() + ")");
}
// 检查rule.supplierCode是否包含多个供应商编码(用逗号隔开)
if (StringUtils.isNotBlank(rule.getSupplierCode()) && rule.getSupplierCode().contains(",")) {
// 将supplierCode按逗号分割成数组
String[] supplierCodes = rule.getSupplierCode().split(",");
List<String> supplierCodeList = Arrays.asList(supplierCodes);
// 检查现有批次中是否有supplierCode在rule.supplierCode内
boolean hasMatchingSupplier = existingBatches.stream()
.anyMatch(batch -> supplierCodeList.contains(batch.getSupplierCode()));
if (hasMatchingSupplier) {
// 找到匹配的批次,检查重量、体积、件数是否一致
EmisTmsSiteBatch matchingBatch = existingBatches.stream()
.filter(batch -> supplierCodeList.contains(batch.getSupplierCode()))
.findFirst()
.orElse(null);
if (matchingBatch != null) {
// 检查批次重量、体积、件数是否一致
boolean isBatchWeightEqual = matchingBatch.getTotalWeight() != null
&& itemDtl.getBatchWeight() != null
&& matchingBatch.getTotalWeight().compareTo(itemDtl.getBatchWeight()) == 0;
boolean isBatchVolumeEqual = matchingBatch.getTotalVolume() != null
&& itemDtl.getBatchVolume() != null
&& matchingBatch.getTotalVolume().compareTo(itemDtl.getBatchVolume()) == 0;
boolean isBatchParcelQtyEqual = Objects.equals(matchingBatch.getTotalParcelQty(),
itemDtl.getBatchParcelQty());
if (!isBatchWeightEqual || !isBatchVolumeEqual || !isBatchParcelQtyEqual) {
throw new EmisBizError(EmisBizErrorType.FAIL,
itemDtl.getBillCode() + "的批次重量、体积、件数与批次" + matchingBatch.getBatchNo() + "不一致,请检查后重新录入");
}
}
}
if (!isBatch) {
return;
}
// 安全比较:检查批次数据是否与运单数据完全一致

View File

@ -50,6 +50,12 @@
<if test="batchWeight != null"> and batch_weight = #{batchWeight}</if>
<if test="waybillBatchStatus != null and waybillBatchStatus != ''"> and waybill_batch_status = #{waybillBatchStatus}</if>
<if test="params.billCodes != null and params.billCodes.size() > 0"> and bill_code in
<foreach item="billCode" collection="params.billCodes" open="(" separator="," close=")">
#{billCode}
</foreach>
</if>
<if test="remark != null and remark != ''"> and remark like concat('%', #{remark}, '%')</if>
<if test="tenantId != null and tenantId != ''"> and tenant_id like concat('%', #{tenantId}, '%')</if>
<if test="delFlag != null and delFlag != ''"> and del_flag like concat('%', #{delFlag}, '%')</if>

View File

@ -224,6 +224,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<when test="missCount == -3">
AND m.miss_type = 1
</when>
<when test="missCount == -6">
AND m.miss_type = 4
</when>
<when test="missCount == -5">
AND m.bill_code IN (
SELECT bill_code