✨ 运单查询新增可配载开关与按主键回查

This commit is contained in:
2026-10-18 14:03:41 +08:00
parent 4011577491
commit 543a690902
5 changed files with 425 additions and 0 deletions
@@ -68,6 +68,7 @@ import org.springblade.transport.service.IReceivablePayableDetailService;
import org.springblade.transport.service.IContractManageService;
import org.springblade.transport.service.IWaybillService;
import org.springblade.transport.support.LiveProcessConfigSupport;
import org.springblade.transport.support.LoadableAdmissionSupport;
import org.springblade.transport.support.TransportBusinessSupport;
import org.springblade.transport.support.WaybillProcessSupport;
import org.springblade.transport.wrapper.WaybillWrapper;
@@ -1735,6 +1736,12 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
if (Objects.equals(waybill.getOnlyUnassignedLoading(), 1)) {
queryWrapper.and(wrapper -> wrapper.isNull(Waybill::getLoadingNo).or().eq(Waybill::getLoadingNo, ""));
}
if (Func.isNotEmpty(waybill.getIds())) {
queryWrapper.in(Waybill::getId, waybill.getIds());
}
if (Objects.equals(waybill.getLoadableOnly(), 1)) {
LoadableAdmissionSupport.applyLoadableConditions(queryWrapper);
}
if (Func.isNotEmpty(waybill.getBatchNo())) {
queryWrapper.like(Waybill::getBatchNo, waybill.getBatchNo());
}
@@ -0,0 +1,144 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.transport.support;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springblade.transport.pojo.entity.Waybill;
import java.util.List;
import java.util.Locale;
/**
* 可配载准入判据:公路 + 待执行 + 未关联其它配载单 + 未拒单。
* <p>
* 候选列表取数与配载提交/编辑/重新派单的校验共用这一份定义。
*/
public final class LoadableAdmissionSupport {
/** 可配载只放行待执行:已完成、已取消、草稿与调度中间态一律不可配载 */
public static final String LOADABLE_BUSINESS_STATUS = WaybillProcessSupport.STATUS_PENDING;
/**
* 公路运输方式的同义写法,按「包含」比对,与前端运单管理页的识别口径一致。
* <p>
* 运输方式字典只有 road/railway/river/ocean/air,而库里存在「公路运输」「水路运输」这类中文取值,
* 因此词表写在代码里,不从字典取。
*/
public static final List<String> ROAD_TRANSPORT_KEYWORDS = List.of("公路", "道路", "汽车", "陆运", "road", "highway");
/** 公路运输方式的历史短码,按整体相等比对(按包含比对会误伤含 gl 的其它取值) */
public static final List<String> ROAD_TRANSPORT_CODES = List.of("gl");
private LoadableAdmissionSupport() {
}
/**
* 是否公路运输。未知或为空一律按非公路处理。
*
* @param transportType 运单的运输方式取值
* @return true-公路
*/
public static boolean isRoadTransport(String transportType) {
String value = text(transportType).toLowerCase(Locale.ROOT);
if (value.isEmpty()) {
return false;
}
if (ROAD_TRANSPORT_CODES.contains(value)) {
return true;
}
for (String keyword : ROAD_TRANSPORT_KEYWORDS) {
if (value.contains(keyword)) {
return true;
}
}
return false;
}
/**
* 该运单此刻是否可被配载:要求未关联任何配载单。
*
* @param waybill 运单
* @return true-可配载
*/
public static boolean isLoadable(Waybill waybill) {
return isLoadable(waybill, null);
}
/**
* 该运单此刻是否可被配载。
* <p>
* ownLoadingNo 是正在编辑或重新派单的配载单号:运单已挂在本单上不算冲突,
* 否则编辑保存会把自己的子运单判为不可用。
*
* @param waybill 运单
* @param ownLoadingNo 本配载单号;新建时传 null
* @return true-可配载
*/
public static boolean isLoadable(Waybill waybill, String ownLoadingNo) {
if (waybill == null) {
return false;
}
if (!isRoadTransport(waybill.getTransportType())
|| !LOADABLE_BUSINESS_STATUS.equals(text(waybill.getBusinessStatus()))
|| WaybillProcessSupport.isRejected(waybill.getDriverAcceptStatus())) {
return false;
}
String loadingNo = text(waybill.getLoadingNo());
return loadingNo.isEmpty() || loadingNo.equals(text(ownLoadingNo));
}
/**
* 把整条可配载判据加到运单查询上:公路 + 待执行 + 未配载 + 非拒单。
*
* @param wrapper 运单列表查询条件
*/
public static void applyLoadableConditions(LambdaQueryWrapper<Waybill> wrapper) {
applyRoadTransportCondition(wrapper);
wrapper.eq(Waybill::getBusinessStatus, LOADABLE_BUSINESS_STATUS);
wrapper.and(nested -> nested.isNull(Waybill::getLoadingNo).or().eq(Waybill::getLoadingNo, ""));
// 接单状态绝大多数为 NULL,而 NULL <> 'rejected' 不成立,只写不等于会把它们一起滤掉
wrapper.and(nested -> nested.isNull(Waybill::getDriverAcceptStatus)
.or().ne(Waybill::getDriverAcceptStatus, WaybillProcessSupport.ACCEPT_REJECTED));
}
private static void applyRoadTransportCondition(LambdaQueryWrapper<Waybill> wrapper) {
wrapper.and(nested -> {
boolean started = false;
for (String keyword : ROAD_TRANSPORT_KEYWORDS) {
if (started) {
nested.or();
}
nested.like(Waybill::getTransportType, keyword);
started = true;
}
for (String code : ROAD_TRANSPORT_CODES) {
nested.or().eq(Waybill::getTransportType, code);
}
});
}
private static String text(String value) {
return value == null ? "" : value.trim();
}
}