调整配载、总单

This commit is contained in:
2026-08-22 21:11:12 +08:00
parent 3e265fc71e
commit 79f4c35235
5 changed files with 28 additions and 84 deletions
@@ -56,10 +56,9 @@ public class LoadingManageController extends BladeController {
@GetMapping("/carrier-contracts")
@ApiOperationSupport(order = 13)
@Operation(summary = "可选承运商合同", description = "根据运单ID集合查询共同可用的承运商合同")
public R<List<LoadingCarrierContractVO>> carrierContracts(
@Parameter(description = "运单ID集合", required = true) @RequestParam List<Long> waybillIds) {
return R.data(loadingManageService.carrierContracts(waybillIds));
@Operation(summary = "可选承运商合同", description = "查询已审核生效的承运商合同")
public R<List<LoadingCarrierContractVO>> carrierContracts() {
return R.data(loadingManageService.carrierContracts());
}
@GetMapping("/list")
@@ -25,7 +25,7 @@ public interface ILoadingManageService extends BaseService<LoadingManage> {
LoadingManageVO detail(Long id);
List<LoadingCarrierContractVO> carrierContracts(List<Long> waybillIds);
List<LoadingCarrierContractVO> carrierContracts();
boolean saveDraft(LoadingManage loadingManage);
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.jackson.JsonUtil;
@@ -39,10 +40,7 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 配载管理 服务实现类
@@ -50,6 +48,7 @@ import java.util.stream.Collectors;
* @author Chill
*/
@Service
@Slf4j
public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMapper, LoadingManage> implements ILoadingManageService {
private static final String STATUS_DRAFT = "draft";
@@ -86,8 +85,8 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
}
@Override
public List<LoadingCarrierContractVO> carrierContracts(List<Long> waybillIds) {
return findCarrierContracts(waybillIds).stream().map(contract -> {
public List<LoadingCarrierContractVO> carrierContracts() {
return availableCarrierContracts().stream().map(contract -> {
LoadingCarrierContractVO option = new LoadingCarrierContractVO();
option.setId(contract.getId());
option.setContractName(contract.getContractName());
@@ -292,9 +291,8 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
LoadingManage loadingManage = loadEditable(id, true);
validateCompletedCarrierContract(loadingManage);
if (!Objects.equals(loadingManage.getBusinessStatus(), STATUS_RUNNING)
&& !(Objects.equals(loadingManage.getBusinessStatus(), STATUS_PENDING)
&& allAssociatedWaybillsCompletable(loadingManage))) {
throw new ServiceException("仅进行中,或关联运单全部进行中/已完成的待执行配载单允许完成");
&& !Objects.equals(loadingManage.getBusinessStatus(), STATUS_PENDING)) {
throw new ServiceException("仅待执行或进行中状态允许完成");
}
loadingManage.setBusinessStatus(STATUS_COMPLETED);
boolean result = updateById(loadingManage);
@@ -358,28 +356,17 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
complete(loadingManage.getId());
result.setSuccessCount(result.getSuccessCount() + 1);
} catch (Exception exception) {
String failureReason = Func.isEmpty(exception.getMessage()) ? "完成失败" : exception.getMessage();
log.error("批量完成配载单失败,loadingId:{}, loadingNo:{}, failureReason:{}",
loadingManage.getId(), loadingManage.getLoadingNo(), failureReason, exception);
result.setSkippedCount(result.getSkippedCount() + 1);
result.getSkippedCodes().add(loadingManage.getLoadingNo());
result.getSkippedReasons().add(loadingManage.getLoadingNo() + "" + failureReason);
}
}
return result;
}
private boolean allAssociatedWaybillsCompletable(LoadingManage loadingManage) {
List<Long> waybillIdList = waybillIds(loadingManage.getWaybillIdsJson());
if (Func.isEmpty(waybillIdList)) {
return false;
}
List<Waybill> waybillList = waybillMapper.selectList(Wrappers.<Waybill>lambdaQuery()
.eq(Waybill::getIsDeleted, 0)
.in(Waybill::getId, waybillIdList));
if (waybillList.size() != waybillIdList.size()) {
return false;
}
return waybillList.stream().allMatch(waybill -> Objects.equals(waybill.getBusinessStatus(), STATUS_RUNNING))
|| waybillList.stream().allMatch(waybill -> Objects.equals(waybill.getBusinessStatus(), STATUS_COMPLETED));
}
private LambdaQueryWrapper<LoadingManage> buildQuery(LoadingManageVO loadingManage) {
TransportBusinessSupport.validateAllDept(loadingManage.getAllDept(), "配载管理");
LambdaQueryWrapper<LoadingManage> queryWrapper = Wrappers.<LoadingManage>lambdaQuery().eq(LoadingManage::getIsDeleted, 0);
@@ -604,11 +591,10 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
loadingManage.setCarrierName(null);
return;
}
ContractManage carrierContract = findCarrierContracts(
waybillIds(loadingManage.getWaybillIdsJson())).stream()
ContractManage carrierContract = availableCarrierContracts().stream()
.filter(contract -> Objects.equals(contract.getId(), loadingManage.getCarrierContractId()))
.findFirst()
.orElseThrow(() -> new ServiceException("所选承运商合同与运单绑定的客户合同不匹配或已失效"));
.orElseThrow(() -> new ServiceException("所选承运商合同不存在、未审核通过或已失效"));
loadingManage.setCarrierName(carrierContract.getPartyB());
}
@@ -623,58 +609,10 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
}
}
private List<ContractManage> findCarrierContracts(List<Long> waybillIds) {
if (Func.isEmpty(waybillIds)) {
return new ArrayList<>();
}
List<Long> distinctWaybillIds = waybillIds.stream()
.filter(Objects::nonNull)
.distinct()
.toList();
if (Func.isEmpty(distinctWaybillIds)) {
return new ArrayList<>();
}
List<Waybill> waybillList = waybillMapper.selectList(Wrappers.<Waybill>lambdaQuery()
.eq(Waybill::getIsDeleted, 0)
.in(Waybill::getId, distinctWaybillIds));
if (waybillList.size() != distinctWaybillIds.size()) {
throw new ServiceException("待配载运单不存在或已删除");
}
waybillList.forEach(waybill ->
TransportBusinessSupport.assertCurrentDept(waybill.getDeptId(), "运单管理"));
if (waybillList.stream().anyMatch(waybill -> Func.isEmpty(waybill.getContractId()))) {
throw new ServiceException("所选运单存在未绑定客户合同的数据");
}
List<Long> customerContractIds = waybillList.stream()
.map(Waybill::getContractId)
.distinct()
.toList();
Map<Long, ContractManage> customerContractMap = contractManageService.listByIds(customerContractIds)
.stream()
.filter(contract -> Objects.equals(contract.getIsDeleted(), 0))
.collect(Collectors.toMap(ContractManage::getId, Function.identity()));
if (customerContractMap.size() != customerContractIds.size()) {
throw new ServiceException("所选运单绑定的客户合同不存在或已删除");
}
Waybill firstWaybill = waybillList.get(0);
ContractManage firstCustomerContract = customerContractMap.get(firstWaybill.getContractId());
if (!Objects.equals(firstCustomerContract.getContractCategory(), "客户合同")
|| Func.isEmpty(firstCustomerContract.getPartyA())) {
throw new ServiceException("所选运单绑定的客户合同信息不完整");
}
boolean relationMismatch = waybillList.stream().anyMatch(waybill -> {
ContractManage customerContract = customerContractMap.get(waybill.getContractId());
return !Objects.equals(customerContract.getContractCategory(), "客户合同")
|| !Objects.equals(waybill.getProjectId(), firstWaybill.getProjectId())
|| !Objects.equals(customerContract.getPartyA(), firstCustomerContract.getPartyA());
});
if (relationMismatch) {
throw new ServiceException("所选运单的客户合同不属于同一项目和甲方,无法共用承运商合同");
}
private List<ContractManage> availableCarrierContracts() {
return contractManageService.list(Wrappers.<ContractManage>lambdaQuery()
.eq(ContractManage::getIsDeleted, 0)
.eq(ContractManage::getProjectId, firstWaybill.getProjectId())
.eq(ContractManage::getPartyA, firstCustomerContract.getPartyA())
.eq(ContractManage::getStatus, 1)
.eq(ContractManage::getContractCategory, "承运商合同")
.in(ContractManage::getApprovalStatus, "approved", "change_approved")
.and(wrapper -> wrapper.isNull(ContractManage::getContractStage)
@@ -697,6 +635,7 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
.set(Waybill::getLoadingNo, loadingManage.getLoadingNo())
.set(Waybill::getBusinessStatus, status)
.set(Waybill::getCarrierType, loadingManage.getCarrierType())
.set(Waybill::getCarrierContractId, loadingManage.getCarrierContractId())
.set(Waybill::getCarrierName, loadingManage.getCarrierName())
.set(Waybill::getDriverName, loadingManage.getDriverName())
.set(Waybill::getDriverPhone, loadingManage.getDriverPhone())
@@ -719,6 +658,8 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
waybillMapper.update(null, Wrappers.<Waybill>lambdaUpdate()
.in(Waybill::getId, waybillIds)
.set(Waybill::getLoadingNo, null)
.set(Waybill::getCarrierContractId, null)
.set(Waybill::getCarrierName, null)
.set(Waybill::getBusinessStatus, status));
}
@@ -428,18 +428,19 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
throw new ServiceException("所选承运商不属于总单客户合同对应项目的有效承运商合同乙方");
}
boolean road = string(dispatch, "transportType", "").toLowerCase().contains("road") || string(dispatch, "transportType", "").contains("公路");
String mileage = string(dispatch, "mileage");
if (!road) {
if (Func.isEmpty(string(dispatch, "vehicleNo")) || Func.isEmpty(string(dispatch, "captainName")) || Func.isEmpty(string(dispatch, "driverPhone")) || Func.isEmpty(string(dispatch, "containerNo")) || Func.isEmpty(string(dispatch, "cabinNo")) || Func.isEmpty(string(dispatch, "mileage")) || decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) <= 0 || ("承运商".equals(carrierType) && Func.isEmpty(string(dispatch, "carrierName")))) {
if (Func.isEmpty(string(dispatch, "vehicleNo")) || Func.isEmpty(string(dispatch, "captainName")) || Func.isEmpty(string(dispatch, "driverPhone")) || Func.isEmpty(string(dispatch, "containerNo")) || Func.isEmpty(string(dispatch, "cabinNo")) || (Func.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) <= 0) || ("承运商".equals(carrierType) && Func.isEmpty(string(dispatch, "carrierName")))) {
throw new ServiceException("非公路运输的承运信息不完整");
}
return;
}
if (Func.isEmpty(string(dispatch, "vehicleNo"))) throw new ServiceException("运单车牌号不能为空");
if ("承运商".equals(carrierType)) {
if (Func.isEmpty(string(dispatch, "carrierName")) || Func.isEmpty(string(dispatch, "mileage")) || decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) <= 0) throw new ServiceException("承运商、里程不能为空里程必须为正");
if (Func.isEmpty(string(dispatch, "carrierName")) || (Func.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) <= 0)) throw new ServiceException("承运商不能为空里程填写时必须为正数");
return;
}
if (Func.isEmpty(string(dispatch, "driverName")) || Func.isEmpty(string(dispatch, "driverPhone")) || Func.isEmpty(string(dispatch, "trailerVehicleNo")) || Func.isEmpty(string(dispatch, "escortName")) || Func.isEmpty(string(dispatch, "escortPhone")) || Func.isEmpty(string(dispatch, "mileage")) || decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) < 0) throw new ServiceException("自运或网货平台的车辆与人员信息不完整");
if (Func.isEmpty(string(dispatch, "driverName")) || Func.isEmpty(string(dispatch, "driverPhone")) || Func.isEmpty(string(dispatch, "trailerVehicleNo")) || Func.isEmpty(string(dispatch, "escortName")) || Func.isEmpty(string(dispatch, "escortPhone")) || (Func.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) < 0)) throw new ServiceException("自运或网货平台的车辆与人员信息不完整");
}
private BigDecimal dispatchedQuantity(String masterNo, String segmentNo) {
return dispatchedGoods(masterNo, segmentNo).values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);