1、修复基础配置

2、修复业务模块
This commit is contained in:
2026-09-03 03:30:57 +08:00
parent 25fee0656d
commit 88b04b7dac
37 changed files with 615 additions and 103 deletions
@@ -77,6 +77,16 @@ public class ContractManageExcel implements Serializable {
private String contractStage;
@ExcelProperty("审核状态")
private String approvalStatus;
@ExcelProperty("结算币种")
private String settlementCurrency;
@ExcelProperty("结算方式")
private String settlementMode;
@ExcelProperty("开票周期(天)")
private Integer invoiceCycle;
@ExcelProperty("一式份数")
private Integer copyCount;
@ExcelProperty("回款账期(天)")
private Integer paymentDays;
@ExcelProperty("当前节点")
private String currentNode;
@ExcelProperty("当前处理人")
@@ -137,6 +137,10 @@
<bind name="driverNameLike" value="'%' + driver.driverName + '%'"/>
AND driver_name LIKE #{driverNameLike}
</if>
<if test="driver.posts != null and driver.posts != ''">
<bind name="postsLike" value="'%' + driver.posts + '%'"/>
AND posts LIKE #{postsLike}
</if>
<if test="driver.mobile != null and driver.mobile != ''">
<bind name="mobileLike" value="'%' + driver.mobile + '%'"/>
AND mobile LIKE #{mobileLike}
@@ -222,6 +222,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
|| !List.of(STATUS_APPROVED, STATUS_CHANGE_APPROVED, STATUS_CHANGE_REJECTED).contains(source.getApprovalStatus())) {
throw new ServiceException("当前合同状态不允许发起变更");
}
TransportBusinessSupport.validateRequired(request.getSettlementCurrency(), "请选择结算币种");
ContractManage candidate = new ContractManage();
BeanUtil.copyProperties(source, candidate);
candidate.setPartyB(TransportBusinessSupport.trimToNull(request.getPartyB()));
@@ -231,6 +232,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
source.setContractName(request.getContractName()); source.setPartyB(request.getPartyB());
source.setStartDate(request.getStartDate()); source.setEndDate(request.getEndDate()); source.setContractFormat(request.getContractFormat());
source.setSettlementMode(request.getSettlementMode()); source.setLegalSealFlag(request.getLegalSealFlag()); source.setCopyCount(request.getCopyCount());
source.setSettlementCurrency(TransportBusinessSupport.trimToNull(request.getSettlementCurrency())); source.setInvoiceCycle(request.getInvoiceCycle());
source.setPaymentDays(request.getPaymentDays()); source.setRemark(request.getRemark()); source.setBillingEnabled(request.getBillingEnabled()); source.setFeeGenerationMode(request.getFeeGenerationMode());
normalizeOptionalIntegerFields(source);
source.setBillingPlanJson(request.getBillingPlanJson()); source.setSettlementRuleJson(request.getSettlementRuleJson()); source.setPreSettlementConfigJson(request.getPreSettlementConfigJson()); source.setFormalSettlementConfigJson(request.getFormalSettlementConfigJson()); source.setPaymentRatioJson(request.getPaymentRatioJson());
@@ -444,6 +446,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
contractManage.setSettlementMode(TransportBusinessSupport.trimToNull(contractManage.getSettlementMode()));
contractManage.setContractFormat(TransportBusinessSupport.trimToNull(contractManage.getContractFormat()));
contractManage.setRemark(TransportBusinessSupport.trimToNull(contractManage.getRemark()));
contractManage.setSettlementCurrency(TransportBusinessSupport.trimToNull(contractManage.getSettlementCurrency()));
contractManage.setContractFileJson(TransportBusinessSupport.trimToNull(contractManage.getContractFileJson()));
contractManage.setAttachmentsJson(TransportBusinessSupport.trimToNull(contractManage.getAttachmentsJson()));
contractManage.setBillingPlanJson(TransportBusinessSupport.trimToNull(contractManage.getBillingPlanJson()));
@@ -461,11 +464,15 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
if (contractManage.getPaymentDays() != null && contractManage.getPaymentDays() <= 0) {
contractManage.setPaymentDays(null);
}
if (contractManage.getInvoiceCycle() != null && contractManage.getInvoiceCycle() <= 0) {
contractManage.setInvoiceCycle(null);
}
}
private void validateDraft(ContractManage contractManage) {
TransportBusinessSupport.validateRequired(contractManage.getContractName(), "请输入合同名称");
TransportBusinessSupport.validateRequired(contractManage.getContractCategory(), "请选择合同类别");
TransportBusinessSupport.validateRequired(contractManage.getSettlementCurrency(), "请选择结算币种");
validateContractNameUnique(contractManage);
TransportBusinessSupport.validateLength(contractManage.getRemark(), 2000, "备注不能超过2000字");
validateBillingPlans(contractManage.getBillingPlanJson());
@@ -591,6 +598,7 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
}
private void validateFormal(ContractManage contractManage) {
TransportBusinessSupport.validateRequired(contractManage.getSettlementCurrency(), "请选择结算币种");
TransportBusinessSupport.validateRequired(contractManage.getPartyA(), "请输入甲方");
TransportBusinessSupport.validateRequired(contractManage.getPartyB(), "请输入乙方");
TransportBusinessSupport.validateRequired(contractManage.getStartDate() == null ? null : contractManage.getStartDate().toString(), "请选择合同期限");
@@ -584,7 +584,9 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
private void validateCarrierContract(LoadingManage loadingManage, boolean required) {
if (!Objects.equals(loadingManage.getCarrierType(), "承运商")) {
loadingManage.setCarrierContractId(null);
loadingManage.setCarrierName(null);
if (!Objects.equals(loadingManage.getCarrierType(), CARRIER_SELF)) {
loadingManage.setCarrierName(null);
}
return;
}
if (Func.isEmpty(loadingManage.getCarrierContractId())) {
@@ -604,7 +606,9 @@ public class LoadingManageServiceImpl extends BaseServiceImpl<LoadingManageMappe
private void validateCompletedCarrierContract(LoadingManage loadingManage) {
if (!Objects.equals(loadingManage.getCarrierType(), "承运商")) {
loadingManage.setCarrierContractId(null);
loadingManage.setCarrierName(null);
if (!Objects.equals(loadingManage.getCarrierType(), CARRIER_SELF)) {
loadingManage.setCarrierName(null);
}
return;
}
if (Func.isEmpty(loadingManage.getCarrierContractId())) {
@@ -51,6 +51,8 @@ import java.util.Objects;
@Service
public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, MasterOrder> implements IMasterOrderService {
private static final String CARRIER_SELF = "自运";
private final IWaybillService waybillService;
private final ITransportPlanService transportPlanService;
private final IProjectApplyService projectApplyService;
@@ -418,7 +420,9 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
String carrierType = string(dispatch, "carrierType", "承运商");
if (!"承运商".equals(carrierType)) {
dispatch.remove("carrierContractId");
dispatch.remove("carrierName");
if (!CARRIER_SELF.equals(carrierType)) {
dispatch.remove("carrierName");
}
}
String carrierName = string(dispatch, "carrierName");
Long carrierContractId = longValue(dispatch, "carrierContractId");
@@ -441,7 +445,7 @@ public class MasterOrderServiceImpl extends BaseServiceImpl<MasterOrderMapper, M
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.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) < 0)) throw new ServiceException("自运或网货平台的车辆与人员信息不完整");
if (Func.isEmpty(string(dispatch, "driverName")) || Func.isEmpty(string(dispatch, "driverPhone")) || (Func.isNotEmpty(mileage) && decimal(dispatch, "mileage").compareTo(BigDecimal.ZERO) < 0)) throw new ServiceException("自运或网货平台的车辆与人员信息不完整");
}
private boolean isWaterTransport(String transportType) {
String value = transportType == null ? "" : transportType.trim().toLowerCase();
@@ -338,31 +338,73 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
if (isRoadTransport(shippingTemplate.getTransportType())) {
JSONArray freightItems = freight.getJSONArray("freightItems");
if (freightItems == null || freightItems.size() != goods.size()) {
throw new ServiceException("公路运输的运费明细必须与货物信息一一对应");
List<String> quantityUnits = goods.stream()
.map(item -> item instanceof JSONObject ? ((JSONObject) item).getString("quantityUnit") : null)
.map(TransportBusinessSupport::trimToNull)
.filter(Objects::nonNull)
.distinct()
.toList();
if (freightItems == null || (freightItems.size() != goods.size() && freightItems.size() != quantityUnits.size())) {
throw new ServiceException("公路运输的运费明细必须覆盖货物信息");
}
boolean groupedByQuantityUnit = freightItems.size() == quantityUnits.size() && freightItems.size() != goods.size();
BigDecimal totalFreightAmount = BigDecimal.ZERO;
for (int index = 0; index < freightItems.size(); index++) {
JSONObject freightItem = freightItems.getJSONObject(index);
if (freightItem == null) {
throw new ServiceException("" + (index + 1) + "条运费明细格式不正确");
}
String quantityUnit = TransportBusinessSupport.trimToNull(freightItem.getString("quantityUnit"));
if (groupedByQuantityUnit) {
quantityUnit = quantityUnit == null && index < quantityUnits.size() ? quantityUnits.get(index) : quantityUnit;
}
JSONObject goodsItem = groupedByQuantityUnit ? null : goods.getJSONObject(index);
if (quantityUnit == null && goodsItem != null) {
quantityUnit = TransportBusinessSupport.trimToNull(goodsItem.getString("quantityUnit"));
}
if (quantityUnit == null) {
throw new ServiceException("" + (index + 1) + "条运费明细数量单位不能为空");
}
final String itemQuantityUnit = quantityUnit;
BigDecimal quantity = groupedByQuantityUnit
? goods.stream()
.map(item -> item instanceof JSONObject ? (JSONObject) item : null)
.filter(item -> itemQuantityUnit.equals(TransportBusinessSupport.trimToNull(item.getString("quantityUnit"))))
.map(item -> amountValue(item.get("quantity"), "货物数量"))
.reduce(BigDecimal.ZERO, BigDecimal::add)
: amountValue(goodsItem == null ? null : goodsItem.get("quantity"), "" + (index + 1) + "条货物数量");
BigDecimal unitPrice = amountValue(freightItem.get("unitPrice"), "" + (index + 1) + "条货物单价");
String priceUnit = TransportBusinessSupport.trimToNull(freightItem.getString("priceUnit"));
if (StringUtil.isBlank(priceUnit)) {
throw new ServiceException("" + (index + 1) + "条货物计价单位不能为空");
}
JSONObject goodsItem = goods.getJSONObject(index);
BigDecimal quantity = amountValue(goodsItem == null ? null : goodsItem.get("quantity"), "" + (index + 1) + "条货物数量");
BigDecimal freightAmount = unitPrice.multiply(quantity);
BigDecimal calculatedAmount = unitPrice.multiply(quantity);
Object inputAmount = freightItem.get("freightAmount");
boolean autoCalculable = quantityUnits.size() == 1 && priceUnitMatchesQuantity(priceUnit, itemQuantityUnit)
&& freightItem.get("unitPrice") != null && StringUtil.isNotBlank(String.valueOf(freightItem.get("unitPrice")));
if (!autoCalculable && (inputAmount == null || StringUtil.isBlank(String.valueOf(inputAmount)))) {
throw new ServiceException("" + (index + 1) + "条货物运费不能为空");
}
boolean manualAmount = Boolean.TRUE.equals(freightItem.getBoolean("manualFreightAmount"))
|| Boolean.TRUE.equals(freightItem.getBoolean("freightAmountManual"));
if (!manualAmount && inputAmount != null && StringUtil.isNotBlank(String.valueOf(inputAmount))) {
BigDecimal enteredAmount = amountValue(inputAmount, "" + (index + 1) + "条货物运费");
manualAmount = enteredAmount.compareTo(calculatedAmount) != 0;
}
BigDecimal freightAmount = manualAmount
? amountValue(inputAmount, "" + (index + 1) + "条货物运费")
: calculatedAmount;
freightItem.put("cargoIndex", index);
freightItem.put("quantityUnit", quantityUnit);
freightItem.put("unitPrice", decimalText(unitPrice));
freightItem.put("priceUnit", priceUnit);
freightItem.put("quantity", decimalText(quantity));
freightItem.put("freightAmount", decimalText(freightAmount));
freightItem.put("manualFreightAmount", manualAmount);
totalFreightAmount = totalFreightAmount.add(freightAmount);
}
freight.put("totalFreightAmount", decimalText(totalFreightAmount));
BigDecimal otherFreightAmount = amountValue(freight.get("otherFreightAmount"), "其他运费合计");
freight.put("totalFreightAmount", decimalText(totalFreightAmount.add(otherFreightAmount)));
freight.remove("freightAmount");
freight.remove("quantity");
} else {
@@ -371,9 +413,11 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
.map(item -> amountValue(item == null ? null : item.get("quantity"), "货物数量"))
.reduce(BigDecimal.ZERO, BigDecimal::add);
freight.put("quantity", decimalText(quantity));
freight.put("freightAmount", amountText(freight.get("freightAmount"), "运费"));
String freightAmount = amountText(freight.get("freightAmount"), "运费");
freight.put("freightAmount", freightAmount);
BigDecimal otherFreightAmount = amountValue(freight.get("otherFreightAmount"), "其他运费合计");
freight.put("totalFreightAmount", decimalText(new BigDecimal(freightAmount).add(otherFreightAmount)));
freight.remove("freightItems");
freight.remove("totalFreightAmount");
}
shippingTemplate.setFreightJson(freight.toJSONString());
}
@@ -383,6 +427,26 @@ public class ShippingTemplateServiceImpl extends BaseServiceImpl<ShippingTemplat
return value.contains("公路") || value.contains("道路") || value.contains("road") || "gl".equals(value);
}
private boolean priceUnitMatchesQuantity(String priceUnit, String quantityUnit) {
String unit = normalizeQuantityUnit(quantityUnit).replaceAll("[·*.]", "");
String value = StringUtil.isBlank(priceUnit) ? "" : priceUnit.trim().toLowerCase().replaceAll("\\s+", "");
if (StringUtil.isBlank(unit) || StringUtil.isBlank(value)) return false;
String[] parts = value.split("/");
if (parts.length != 2) return false;
String left = normalizeQuantityUnit(parts[0]).replaceAll("[·*.]", "");
String right = normalizeQuantityUnit(parts[1]).replaceAll("[·*.]", "");
return (left.equals(unit) && isMoneyUnit(parts[1])) || (right.equals(unit) && isMoneyUnit(parts[0]));
}
private String normalizeQuantityUnit(String value) {
return StringUtil.isBlank(value) ? "" : value.trim().toLowerCase().replaceAll("\\s+", "")
.replace("立方米", "立方").replace("立方公尺", "立方").replace("", "立方");
}
private boolean isMoneyUnit(String value) {
return value.matches(".*(元|人民币|rmb|cny|\\$|美元|usd).*");
}
private String amountText(Object value, String fieldName) {
return decimalText(amountValue(value, fieldName));
}
@@ -42,11 +42,13 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.springblade.transport.mapper.TransportPlanMapper;
import org.springblade.transport.pojo.dto.TransportPlanDispatchRequest;
import org.springblade.transport.pojo.entity.ContractManage;
import org.springblade.transport.pojo.entity.TransportPlan;
import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
import org.springblade.transport.pojo.vo.TransportPlanVO;
import org.springblade.transport.pojo.vo.WaybillVO;
import org.springblade.transport.service.IContractManageService;
import org.springblade.transport.service.ITransportPlanService;
import org.springblade.transport.service.IWaybillService;
import org.springblade.transport.support.TransportBusinessSupport;
@@ -73,6 +75,7 @@ import java.util.stream.Collectors;
public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMapper, TransportPlan> implements ITransportPlanService {
private final IWaybillService waybillService;
private final IContractManageService contractManageService;
@Override
public IPage<TransportPlanVO> selectTransportPlanPage(IPage<TransportPlan> page, TransportPlanVO transportPlan) {
@@ -85,10 +88,30 @@ public class TransportPlanServiceImpl extends BaseServiceImpl<TransportPlanMappe
@Override
public TransportPlanVO detail(Long id) {
TransportPlanVO transportPlan = TransportPlanWrapper.build().entityVO(loadEditable(id, false));
fillContractNo(transportPlan);
fillDispatchRows(Collections.singletonList(transportPlan));
return transportPlan;
}
private void fillContractNo(TransportPlanVO transportPlan) {
ContractManage contract = resolveContract(transportPlan);
transportPlan.setContractNo(contract == null ? null : contract.getContractNo());
}
private ContractManage resolveContract(TransportPlanVO transportPlan) {
if (Func.isNotEmpty(transportPlan.getContractId())) {
ContractManage contract = contractManageService.getById(transportPlan.getContractId());
if (contract != null) return contract;
}
if (Func.isEmpty(transportPlan.getContractName())) return null;
LambdaQueryWrapper<ContractManage> query = new LambdaQueryWrapper<ContractManage>()
.eq(ContractManage::getContractName, transportPlan.getContractName());
if (Func.isNotEmpty(transportPlan.getProjectId())) {
query.eq(ContractManage::getProjectId, transportPlan.getProjectId());
}
return contractManageService.getOne(query, false);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean submit(TransportPlan transportPlan) {
@@ -39,6 +39,7 @@ import org.springblade.transport.mapper.WaybillMapper;
import org.springblade.transport.pojo.entity.LoadingManage;
import org.springblade.transport.pojo.entity.ContractManage;
import org.springblade.transport.pojo.entity.ProcessConfig;
import org.springblade.transport.pojo.entity.ProjectApply;
import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.dto.WaybillMileageRequest;
import org.springblade.transport.pojo.vo.BusinessRemoveResultVO;
@@ -46,6 +47,7 @@ import org.springblade.transport.pojo.vo.LoadingManageVO;
import org.springblade.transport.pojo.vo.WaybillVO;
import org.springblade.transport.service.ILoadingManageService;
import org.springblade.transport.service.IProcessConfigService;
import org.springblade.transport.service.IProjectApplyService;
import org.springblade.transport.service.IReceivablePayableDetailService;
import org.springblade.transport.service.IContractManageService;
import org.springblade.transport.service.IWaybillService;
@@ -81,6 +83,9 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
@jakarta.annotation.Resource
private IProcessConfigService processConfigService;
@jakarta.annotation.Resource
private IProjectApplyService projectApplyService;
@jakarta.annotation.Resource
private IContractManageService contractManageService;
@@ -135,11 +140,22 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
fillProjectProcessConfig(waybill);
}
prepare(waybill);
fillCustomerName(waybill);
if (created && Func.isEmpty(waybill.getWaybillNo())) {
waybill.setWaybillNo(nextCode());
}
}
private void fillCustomerName(Waybill waybill) {
if (Func.isNotEmpty(waybill.getCustomerName()) || Func.isEmpty(waybill.getProjectId())) {
return;
}
ProjectApply project = projectApplyService.getById(waybill.getProjectId());
if (project != null) {
waybill.setCustomerName(TransportBusinessSupport.trimToNull(project.getCustomerNames()));
}
}
private void fillProjectProcessConfig(Waybill waybill) {
if (Func.isNotEmpty(waybill.getProcessJson()) || Func.isEmpty(waybill.getProjectId())) {
return;
@@ -605,7 +621,7 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
waybill.setTaskRemark(TransportBusinessSupport.trimToNull(waybill.getTaskRemark()));
waybill.setOriginalNo(TransportBusinessSupport.trimToNull(waybill.getOriginalNo()));
waybill.setBusinessStatus(TransportBusinessSupport.trimToNull(waybill.getBusinessStatus()));
waybill.setDataSource(TransportBusinessSupport.trimToNull(waybill.getDataSource()));
waybill.setDataSource(TransportBusinessSupport.normalizeWaybillDataSource(waybill.getDataSource()));
waybill.setPlanName(TransportBusinessSupport.trimToNull(waybill.getPlanName()));
waybill.setMasterNo(TransportBusinessSupport.trimToNull(waybill.getMasterNo()));
waybill.setLoadingNo(TransportBusinessSupport.trimToNull(waybill.getLoadingNo()));
@@ -652,12 +668,6 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
} else {
TransportBusinessSupport.validateRequired(waybill.getDriverName(), "司机不能为空");
TransportBusinessSupport.validateRequired(waybill.getDriverPhone(), "司机手机号不能为空");
TransportBusinessSupport.validateRequired(waybill.getTrailerVehicleNo(), "挂车车牌号不能为空");
TransportBusinessSupport.validateRequired(waybill.getEscortName(), "押运人不能为空");
TransportBusinessSupport.validateRequired(waybill.getEscortPhone(), "押运人手机号不能为空");
if (Func.isEmpty(waybill.getMileage())) {
throw new ServiceException("里程不能为空");
}
}
}
TransportBusinessSupport.validateRequired(waybill.getCarrierJson(), "承运信息不能为空");
@@ -43,6 +43,7 @@ public final class TransportBusinessSupport {
public static final String DATA_SOURCE_BATCH_IMPORT = "批量导入";
public static final String DATA_SOURCE_MANUAL = "手工创建";
public static final String DATA_SOURCE_PLAN_DISPATCH = "计划调度";
public static final String DATA_SOURCE_EXTERNAL = "外部系统";
private static final Pattern PHONE_PATTERN = Pattern.compile("^(1\\d{10}|0\\d{2,3}-?\\d{7,8})$");
@@ -110,6 +111,23 @@ public final class TransportBusinessSupport {
};
}
/**
* 归一化运单数据来源保证列表只出现约定的三种来源
*
* @param value 原始数据来源
* @return 批量导入手工创建或计划调度
*/
public static String normalizeWaybillDataSource(String value) {
String source = trimToNull(value);
if (DATA_SOURCE_BATCH_IMPORT.equals(source)) {
return DATA_SOURCE_BATCH_IMPORT;
}
if (DATA_SOURCE_PLAN_DISPATCH.equals(source) || "多联总单调度".equals(source)) {
return DATA_SOURCE_PLAN_DISPATCH;
}
return DATA_SOURCE_MANUAL;
}
public static void validateRequired(String value, String message) {
if (Func.isEmpty(trimToNull(value))) {
throw new ServiceException(message);
@@ -29,6 +29,7 @@ import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.UserCache;
import org.springblade.transport.pojo.entity.Waybill;
import org.springblade.transport.pojo.vo.WaybillVO;
import org.springblade.transport.support.TransportBusinessSupport;
import java.util.Objects;
@@ -48,6 +49,7 @@ public class WaybillWrapper extends BaseEntityWrapper<Waybill, WaybillVO> {
WaybillVO waybillVO = Objects.requireNonNull(BeanUtil.copyProperties(waybill, WaybillVO.class));
waybillVO.setCreateUserName(UserCache.getUserRealName(waybill.getCreateUser()));
waybillVO.setUpdateUserName(UserCache.getUserRealName(waybill.getUpdateUser()));
waybillVO.setDataSource(TransportBusinessSupport.normalizeWaybillDataSource(waybill.getDataSource()));
Long currentDeptId = Func.firstLong(AuthUtil.getDeptId());
waybillVO.setReadonly(currentDeptId != null && !Objects.equals(waybill.getDeptId(), currentDeptId));
waybillVO.setBusinessStatusName(businessStatusName(waybill.getBusinessStatus()));