✨ 导入运单支持未结算整批删除并调整结算单导入模板
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+6
@@ -20,6 +20,12 @@ public class WaybillImportBatchVO extends WaybillImportBatch {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String importTypeName;
|
||||
private String statusName;
|
||||
/** 结算状态:unsettled/partial/settled */
|
||||
@Schema(description = "结算状态")
|
||||
private String settlementStatus;
|
||||
/** 结算状态名称:未结算/部分结算/已结算 */
|
||||
@Schema(description = "结算状态名称")
|
||||
private String settlementStatusName;
|
||||
private String createUserName;
|
||||
private String updateUserName;
|
||||
}
|
||||
|
||||
+1
-5
@@ -37,7 +37,7 @@ import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 导入结算单 Excel 模板(固定列 + 运输单价 + *运输费 + 示例费用项)
|
||||
* 导入结算单 Excel 固定列模型(失败明细兜底导出;费用项由用户在原模板中自行增列)。
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@@ -96,10 +96,6 @@ public class SettlementImportTemplateExcel implements Serializable {
|
||||
private BigDecimal unitPrice;
|
||||
@ExcelProperty("*运输费")
|
||||
private BigDecimal transportFee;
|
||||
@ExcelProperty("装卸费")
|
||||
private BigDecimal loadingFee;
|
||||
@ExcelProperty("过路费")
|
||||
private BigDecimal tollFee;
|
||||
/** 模板已去掉结算金额列;仅失败明细内部保留,不导出为表头 */
|
||||
@ExcelIgnore
|
||||
private BigDecimal settlementAmount;
|
||||
|
||||
+24
-32
@@ -47,12 +47,12 @@ import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 导入结算单模板导出:填写说明 + 数据表头 + 运输方式下拉 + 系统费用项列。
|
||||
* 导入结算单模板导出:填写说明 + 固定数据表头 + 运输方式下拉。
|
||||
* <p>
|
||||
* 模板不预置费用项列;用户可在「*运输费」与后续固定列之间自行插入系统已启用的费用项列。
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@@ -93,15 +93,18 @@ public final class SettlementImportTemplateExporter {
|
||||
"同一运单标识号"
|
||||
);
|
||||
|
||||
private static final List<String> DEFAULT_FEE_ITEMS = List.of("装卸费", "过路费");
|
||||
|
||||
private SettlementImportTemplateExporter() {
|
||||
}
|
||||
|
||||
public static void export(HttpServletResponse response, List<String> transportTypeOptions,
|
||||
List<String> feeItemNames) {
|
||||
List<String> headers = buildHeaders(feeItemNames);
|
||||
List<String> transportOptions = defaultTransportOptions(transportTypeOptions);
|
||||
List<String> headers = buildHeaders();
|
||||
// 运输方式由调用方传入业务字典 transport_type 的字典名称,禁止写死
|
||||
List<String> transportOptions = transportTypeOptions == null ? List.of() : transportTypeOptions.stream()
|
||||
.filter(item -> item != null && !item.isBlank())
|
||||
.map(String::trim)
|
||||
.distinct()
|
||||
.toList();
|
||||
try (Workbook workbook = new XSSFWorkbook()) {
|
||||
writeInstructionSheet(workbook, transportOptions, feeItemNames);
|
||||
Sheet dataSheet = workbook.createSheet("导入结算单模板");
|
||||
@@ -127,20 +130,9 @@ public final class SettlementImportTemplateExporter {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> buildHeaders(List<String> feeItemNames) {
|
||||
/** 固定列模板:不预置费用项列,由用户自行插入。 */
|
||||
private static List<String> buildHeaders() {
|
||||
List<String> headers = new ArrayList<>(FIXED_HEADERS_BEFORE_FEE);
|
||||
Set<String> feeNames = new LinkedHashSet<>();
|
||||
if (feeItemNames != null) {
|
||||
for (String name : feeItemNames) {
|
||||
if (name != null && !name.isBlank()) {
|
||||
feeNames.add(name.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (feeNames.isEmpty()) {
|
||||
feeNames.addAll(DEFAULT_FEE_ITEMS);
|
||||
}
|
||||
headers.addAll(feeNames);
|
||||
headers.addAll(FIXED_HEADERS_AFTER_FEE);
|
||||
return headers;
|
||||
}
|
||||
@@ -154,18 +146,24 @@ public final class SettlementImportTemplateExporter {
|
||||
titleStyle.setFont(titleFont);
|
||||
List<String> lines = new ArrayList<>();
|
||||
lines.add("导入结算单填写说明");
|
||||
lines.add("1. 请不要修改「导入结算单模板」工作表的表头;带 * 号为必填项。");
|
||||
lines.add("2. 运输方式请从下拉项中选择,须与系统字典一致。");
|
||||
lines.add("1. 请不要修改「导入结算单模板」工作表的固定表头;带 * 号为必填项。");
|
||||
lines.add("2. 运输方式请从下拉项中选择,须与业务字典 transport_type 的字典名称一致。");
|
||||
lines.add("3. 日期请填写 yyyy-MM-dd(如 2026-01-01);Excel 日期单元格也可直接选择。");
|
||||
lines.add("4. 里程(km) 可为空;填写时须为正数。");
|
||||
lines.add("5. 「*运输费」之后、「*实际发货时间」之前的列为费用项,列名须与系统费用项主数据名称完全一致;金额不为 0 时若不存在或已停用则无法导入。");
|
||||
lines.add("5. 「*运输费」之后、「*实际发货时间」之前可按需自行插入费用项列,列名须与系统已启用费用项名称完全一致;金额不为 0 时若不存在或已停用则无法导入。");
|
||||
lines.add("6. 模板不含结算金额列;导入后系统按「运输费 + 各费用项」自动合计结算金额。");
|
||||
lines.add("7. 当前可选运输方式:" + String.join("、", transportOptions) + "。");
|
||||
if (transportOptions != null && !transportOptions.isEmpty()) {
|
||||
lines.add("7. 当前可选运输方式(业务字典 transport_type 名称):"
|
||||
+ String.join("、", transportOptions) + "。");
|
||||
} else {
|
||||
lines.add("7. 运输方式请从业务字典 transport_type 维护的名称中选择。");
|
||||
}
|
||||
if (feeItemNames != null && !feeItemNames.isEmpty()) {
|
||||
lines.add("8. 当前启用费用项示例:" + String.join("、", feeItemNames.stream().limit(30).toList())
|
||||
lines.add("8. 费用项请按实际需要在模板中自行增列,列名须与系统已启用费用项一致;当前系统已启用费用项:"
|
||||
+ String.join("、", feeItemNames.stream().limit(30).toList())
|
||||
+ (feeItemNames.size() > 30 ? " 等" : "") + "。");
|
||||
} else {
|
||||
lines.add("8. 模板默认包含装卸费、过路费列,可按系统费用项主数据增删费用列。");
|
||||
lines.add("8. 费用项请按实际需要在模板中自行增列,列名须与系统已启用的费用项主数据名称完全一致。");
|
||||
}
|
||||
for (int index = 0; index < lines.size(); index++) {
|
||||
Row row = sheet.createRow(index);
|
||||
@@ -201,10 +199,4 @@ public final class SettlementImportTemplateExporter {
|
||||
return style;
|
||||
}
|
||||
|
||||
private static List<String> defaultTransportOptions(List<String> transportTypeOptions) {
|
||||
if (transportTypeOptions != null && !transportTypeOptions.isEmpty()) {
|
||||
return transportTypeOptions;
|
||||
}
|
||||
return List.of("公路运输", "铁路运输", "水路运输", "航空运输");
|
||||
}
|
||||
}
|
||||
|
||||
+10
-22
@@ -41,7 +41,6 @@ import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.system.cache.DictBizCache;
|
||||
import org.springblade.system.cache.DictCache;
|
||||
import org.springblade.system.cache.UserCache;
|
||||
import org.springblade.system.feign.ISysClient;
|
||||
import org.springblade.system.pojo.entity.DictBiz;
|
||||
@@ -824,7 +823,7 @@ public class SettlementImportBatchServiceImpl
|
||||
for (Map.Entry<String, BigDecimal> entry : feeItems.entrySet()) {
|
||||
String name = normalizeFeeName(entry.getKey());
|
||||
BigDecimal amount = entry.getValue() == null ? BigDecimal.ZERO : entry.getValue();
|
||||
// 模板自带的装卸费、过路费等列未填写时金额为 0,不要求费用项主数据存在同名档案
|
||||
// 用户自行增列的费用项金额为 0 时跳过校验;金额不为 0 须匹配系统已启用费用项
|
||||
if (Func.isEmpty(name) || amount.compareTo(BigDecimal.ZERO) == 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -1149,9 +1148,6 @@ public class SettlementImportBatchServiceImpl
|
||||
excel.setMileage(decimalValue(row, "mileage", "里程(km)", "里程"));
|
||||
excel.setUnitPrice(decimalValue(row, "unitPrice", "运输单价", "单价"));
|
||||
excel.setTransportFee(decimalValue(row, "transportFee", "*运输费", "运输费"));
|
||||
Map<String, BigDecimal> feeItems = extractFeeItems(row, List.of("装卸费", "过路费"));
|
||||
excel.setLoadingFee(feeItems.get("装卸费"));
|
||||
excel.setTollFee(feeItems.get("过路费"));
|
||||
excel.setSettlementAmount(decimalValue(row, "settlementAmount", "结算金额"));
|
||||
excel.setActualStartDate(stringValue(row, "actualStartDate", "*实际发货时间", "实际发货时间"));
|
||||
excel.setActualEndDate(stringValue(row, "actualEndDate", "*实际完成时间", "实际完成时间"));
|
||||
@@ -1330,34 +1326,26 @@ public class SettlementImportBatchServiceImpl
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
/**
|
||||
* 运输方式取业务字典 transport_type 的字典名称(dictValue),不写死枚举。
|
||||
*/
|
||||
private List<String> loadTransportTypeLabels() {
|
||||
LinkedHashSet<String> labels = new LinkedHashSet<>();
|
||||
try {
|
||||
List<DictBiz> dictBizList = DictBizCache.getList("transport_type");
|
||||
if (Func.isNotEmpty(dictBizList)) {
|
||||
dictBizList.stream()
|
||||
.map(DictBiz::getDictValue)
|
||||
.filter(dict -> dict != null && Func.isNotEmpty(dict.getDictValue())
|
||||
&& !"-1".equals(Func.toStr(dict.getDictKey())))
|
||||
.map(dict -> dict.getDictValue().trim())
|
||||
.filter(Func::isNotEmpty)
|
||||
.map(String::trim)
|
||||
.forEach(labels::add);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 业务字典不可用时继续读取系统字典
|
||||
}
|
||||
try {
|
||||
List<org.springblade.system.pojo.entity.Dict> dictList = DictCache.getList("transport_type");
|
||||
if (Func.isNotEmpty(dictList)) {
|
||||
dictList.stream()
|
||||
.map(org.springblade.system.pojo.entity.Dict::getDictValue)
|
||||
.filter(Func::isNotEmpty)
|
||||
.map(String::trim)
|
||||
.forEach(labels::add);
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 忽略
|
||||
} catch (Exception exception) {
|
||||
throw new ServiceException("业务字典 transport_type 读取失败,请检查业务字典配置");
|
||||
}
|
||||
if (labels.isEmpty()) {
|
||||
return List.of("公路运输", "铁路运输", "水路运输", "航空运输");
|
||||
throw new ServiceException("业务字典 transport_type 未配置运输方式,请先维护字典名称");
|
||||
}
|
||||
return new ArrayList<>(labels);
|
||||
}
|
||||
|
||||
+171
-9
@@ -30,7 +30,9 @@ import org.springblade.transport.excel.WaybillImportBatchExcel;
|
||||
import org.springblade.transport.mapper.WaybillImportBatchMapper;
|
||||
import org.springblade.transport.pojo.dto.WaybillImportBatchRequest;
|
||||
import org.springblade.transport.pojo.entity.CustomerArchive;
|
||||
import org.springblade.transport.pojo.entity.LoadingManage;
|
||||
import org.springblade.transport.pojo.entity.ProjectApply;
|
||||
import org.springblade.transport.pojo.entity.ReceivablePayableDetail;
|
||||
import org.springblade.transport.pojo.entity.TransportPlan;
|
||||
import org.springblade.transport.pojo.entity.Waybill;
|
||||
import org.springblade.transport.pojo.entity.WaybillImportBatch;
|
||||
@@ -76,6 +78,13 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
||||
private static final String STATUS_COMPLETED = "completed";
|
||||
private static final String IMPORT_TYPE_WAYBILL = "waybill";
|
||||
private static final String IMPORT_TYPE_SETTLEMENT = "settlement";
|
||||
/** 批次结算状态:全部运单均未进入预/正式结算。 */
|
||||
private static final String SETTLEMENT_UNSETTLED = "unsettled";
|
||||
/** 批次结算状态:部分运单已进入结算。 */
|
||||
private static final String SETTLEMENT_PARTIAL = "partial";
|
||||
/** 批次结算状态:全部运单均已进入结算。 */
|
||||
private static final String SETTLEMENT_SETTLED = "settled";
|
||||
private static final String LOADING_DATA_SOURCE_IMPORT = "批量导入";
|
||||
/** 车牌号校验正则:首位汉字,次位大写字母,总长度7或8位 */
|
||||
private static final Pattern VEHICLE_NO_PATTERN = Pattern.compile("^[一-龥][A-Z][A-Z0-9]{5,6}$");
|
||||
/** 中国机动车号牌省份简称。 */
|
||||
@@ -358,6 +367,7 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
||||
}
|
||||
IPage<WaybillImportBatch> entityPage = page(page, queryWrapper);
|
||||
List<WaybillImportBatchVO> records = entityPage.getRecords().stream().map(this::toVO).toList();
|
||||
fillSettlementStatus(records);
|
||||
Page<WaybillImportBatchVO> resultPage = new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal());
|
||||
resultPage.setRecords(records);
|
||||
return resultPage;
|
||||
@@ -389,18 +399,33 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
||||
List<WaybillImportBatch> batches = listByIds(idList).stream()
|
||||
.filter(batch -> !Objects.equals(batch.getIsDeleted(), 1))
|
||||
.toList();
|
||||
// 与前端一致:仅草稿可删;选中含已完成/进行中时整批拒绝
|
||||
boolean hasNonDraft = batches.stream()
|
||||
.anyMatch(batch -> !STATUS_DRAFT.equals(batch.getImportStatus()));
|
||||
if (hasNonDraft) {
|
||||
throw new ServiceException("已完成运单不可删除");
|
||||
if (Func.isEmpty(batches)) {
|
||||
throw new ServiceException("运单批次不存在或已删除");
|
||||
}
|
||||
Map<Long, List<Waybill>> waybillsByBatchId = listWaybillsByBatchIds(
|
||||
batches.stream().map(WaybillImportBatch::getId).toList());
|
||||
List<Long> allWaybillIds = waybillsByBatchId.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.map(Waybill::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
Set<Long> settledWaybillIds = receivablePayableDetailService.settlementLinkedWaybillIds(allWaybillIds);
|
||||
// 仅未结算批次可整批删除;选中含部分结算/已结算时整批拒绝
|
||||
for (WaybillImportBatch batch : batches) {
|
||||
List<Waybill> waybills = waybillsByBatchId.getOrDefault(batch.getId(), List.of());
|
||||
String settlementStatus = resolveSettlementStatus(waybills, settledWaybillIds);
|
||||
if (!SETTLEMENT_UNSETTLED.equals(settlementStatus)) {
|
||||
throw new ServiceException("仅未结算的运单批次可以删除");
|
||||
}
|
||||
}
|
||||
BusinessRemoveResultVO result = new BusinessRemoveResultVO();
|
||||
for (WaybillImportBatch batch : batches) {
|
||||
List<Waybill> waybills = waybillService.list(Wrappers.<Waybill>lambdaQuery()
|
||||
.eq(Waybill::getImportBatchId, batch.getId()).eq(Waybill::getIsDeleted, 0));
|
||||
if (Func.isNotEmpty(waybills)) {
|
||||
waybillService.deleteLogic(waybills.stream().map(Waybill::getId).toList());
|
||||
List<Waybill> waybills = waybillsByBatchId.getOrDefault(batch.getId(), List.of());
|
||||
List<Long> waybillIds = waybills.stream().map(Waybill::getId).filter(Objects::nonNull).toList();
|
||||
if (Func.isNotEmpty(waybillIds)) {
|
||||
clearUnsettledReceivableDetails(waybillIds);
|
||||
clearImportedLoadings(waybills);
|
||||
waybillService.deleteLogic(waybillIds);
|
||||
}
|
||||
deleteLogic(List.of(batch.getId()));
|
||||
result.setSuccessCount(result.getSuccessCount() + 1);
|
||||
@@ -671,11 +696,148 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl<WaybillImport
|
||||
if (vo == null) throw new ServiceException("运单批次数据转换失败");
|
||||
vo.setImportTypeName(IMPORT_TYPE_SETTLEMENT.equals(batch.getImportType()) ? "结算单" : "运单");
|
||||
vo.setStatusName(importStatusName(batch.getImportStatus()));
|
||||
vo.setSettlementStatus(SETTLEMENT_UNSETTLED);
|
||||
vo.setSettlementStatusName(settlementStatusName(SETTLEMENT_UNSETTLED));
|
||||
vo.setCreateUserName(UserCache.getUserRealName(batch.getCreateUser()));
|
||||
vo.setUpdateUserName(UserCache.getUserRealName(batch.getUpdateUser()));
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按批次下运单是否已关联预/正式结算单,汇总结算状态:
|
||||
* 全部未关联=未结算,部分关联=部分结算,全部关联=已结算。
|
||||
*/
|
||||
private void fillSettlementStatus(List<WaybillImportBatchVO> records) {
|
||||
if (Func.isEmpty(records)) {
|
||||
return;
|
||||
}
|
||||
List<Long> batchIds = records.stream().map(WaybillImportBatchVO::getId).filter(Objects::nonNull).toList();
|
||||
Map<Long, List<Waybill>> waybillsByBatchId = listWaybillsByBatchIds(batchIds);
|
||||
List<Long> allWaybillIds = waybillsByBatchId.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.map(Waybill::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
Set<Long> settledWaybillIds = receivablePayableDetailService.settlementLinkedWaybillIds(allWaybillIds);
|
||||
for (WaybillImportBatchVO record : records) {
|
||||
List<Waybill> waybills = waybillsByBatchId.getOrDefault(record.getId(), List.of());
|
||||
String settlementStatus = resolveSettlementStatus(waybills, settledWaybillIds);
|
||||
record.setSettlementStatus(settlementStatus);
|
||||
record.setSettlementStatusName(settlementStatusName(settlementStatus));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Long, List<Waybill>> listWaybillsByBatchIds(List<Long> batchIds) {
|
||||
if (Func.isEmpty(batchIds)) {
|
||||
return Map.of();
|
||||
}
|
||||
List<Waybill> waybills = waybillService.list(Wrappers.<Waybill>lambdaQuery()
|
||||
.select(Waybill::getId, Waybill::getImportBatchId, Waybill::getLoadingNo)
|
||||
.in(Waybill::getImportBatchId, batchIds)
|
||||
.eq(Waybill::getIsDeleted, 0));
|
||||
return waybills.stream()
|
||||
.filter(waybill -> waybill.getImportBatchId() != null)
|
||||
.collect(Collectors.groupingBy(Waybill::getImportBatchId));
|
||||
}
|
||||
|
||||
private String resolveSettlementStatus(List<Waybill> waybills, Set<Long> settledWaybillIds) {
|
||||
if (Func.isEmpty(waybills)) {
|
||||
return SETTLEMENT_UNSETTLED;
|
||||
}
|
||||
int settledCount = 0;
|
||||
for (Waybill waybill : waybills) {
|
||||
if (waybill.getId() != null && settledWaybillIds.contains(waybill.getId())) {
|
||||
settledCount++;
|
||||
}
|
||||
}
|
||||
if (settledCount <= 0) {
|
||||
return SETTLEMENT_UNSETTLED;
|
||||
}
|
||||
if (settledCount >= waybills.size()) {
|
||||
return SETTLEMENT_SETTLED;
|
||||
}
|
||||
return SETTLEMENT_PARTIAL;
|
||||
}
|
||||
|
||||
private String settlementStatusName(String settlementStatus) {
|
||||
if (SETTLEMENT_SETTLED.equals(settlementStatus)) {
|
||||
return "已结算";
|
||||
}
|
||||
if (SETTLEMENT_PARTIAL.equals(settlementStatus)) {
|
||||
return "部分结算";
|
||||
}
|
||||
return "未结算";
|
||||
}
|
||||
|
||||
/** 删除批次前清理尚未进入预/正式结算的应收应付明细,避免残留待结算数据。 */
|
||||
private void clearUnsettledReceivableDetails(List<Long> waybillIds) {
|
||||
if (Func.isEmpty(waybillIds)) {
|
||||
return;
|
||||
}
|
||||
List<ReceivablePayableDetail> details = receivablePayableDetailService.list(
|
||||
Wrappers.<ReceivablePayableDetail>lambdaQuery()
|
||||
.in(ReceivablePayableDetail::getWaybillId, waybillIds)
|
||||
.eq(ReceivablePayableDetail::getIsDeleted, 0)
|
||||
.and(wrapper -> wrapper.isNull(ReceivablePayableDetail::getPreSettlementNo)
|
||||
.or().eq(ReceivablePayableDetail::getPreSettlementNo, ""))
|
||||
.and(wrapper -> wrapper.isNull(ReceivablePayableDetail::getFormalSettlementNo)
|
||||
.or().eq(ReceivablePayableDetail::getFormalSettlementNo, "")));
|
||||
if (Func.isNotEmpty(details)) {
|
||||
receivablePayableDetailService.deleteLogic(
|
||||
details.stream().map(ReceivablePayableDetail::getId).toList());
|
||||
}
|
||||
}
|
||||
|
||||
/** 清理本批次运单关联的批量导入配载单(配载单运单均属本批时整单删除)。 */
|
||||
private void clearImportedLoadings(List<Waybill> waybills) {
|
||||
if (Func.isEmpty(waybills)) {
|
||||
return;
|
||||
}
|
||||
Set<Long> batchWaybillIds = waybills.stream()
|
||||
.map(Waybill::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
Set<String> loadingNos = waybills.stream()
|
||||
.map(Waybill::getLoadingNo)
|
||||
.filter(Func::isNotEmpty)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
if (Func.isEmpty(loadingNos)) {
|
||||
return;
|
||||
}
|
||||
List<LoadingManage> loadings = loadingManageService.list(Wrappers.<LoadingManage>lambdaQuery()
|
||||
.in(LoadingManage::getLoadingNo, loadingNos)
|
||||
.eq(LoadingManage::getDataSource, LOADING_DATA_SOURCE_IMPORT)
|
||||
.eq(LoadingManage::getIsDeleted, 0));
|
||||
List<Long> deleteLoadingIds = new ArrayList<>();
|
||||
for (LoadingManage loading : loadings) {
|
||||
List<Long> loadingWaybillIds = parseLoadingWaybillIds(loading.getWaybillIdsJson());
|
||||
if (Func.isEmpty(loadingWaybillIds) || batchWaybillIds.containsAll(loadingWaybillIds)) {
|
||||
deleteLoadingIds.add(loading.getId());
|
||||
}
|
||||
}
|
||||
if (Func.isNotEmpty(deleteLoadingIds)) {
|
||||
loadingManageService.deleteLogic(deleteLoadingIds);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Long> parseLoadingWaybillIds(String waybillIdsJson) {
|
||||
if (Func.isEmpty(waybillIdsJson)) {
|
||||
return List.of();
|
||||
}
|
||||
try {
|
||||
Object parsed = JsonUtil.parse(waybillIdsJson, List.class);
|
||||
if (parsed instanceof List<?> list) {
|
||||
return list.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(item -> Long.valueOf(String.valueOf(item)))
|
||||
.toList();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
// 兼容历史逗号分隔存储
|
||||
}
|
||||
return Func.toLongList(waybillIdsJson);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String nextBatchNo() {
|
||||
return nextCode();
|
||||
|
||||
Reference in New Issue
Block a user