diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java index e0f09fdf..350c0e92 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/DriverWaybillServiceImpl.java @@ -1086,10 +1086,16 @@ public class DriverWaybillServiceImpl implements IDriverWaybillService { card.setVehicleNo(Func.toStr(trip.getVehicleNo(), "")); card.setCreateTime(formatDateTime(trip.getSortTime())); card.setPublishTime(card.getCreateTime()); - // 计划时间与备注:配载运次取配载单,未配载的照运单卡片自己的值,不回填空 - if (Func.isNotEmpty(card.getLoadingNo())) { + // 计划时间两条路同源:配载运次取配载单,未配载运次取那张运单自己的。 + // 未配载详情进来时卡片已照运单填过,运次级为空就保留它,不覆盖成空 + if (trip.getEstimatedStartDate() != null) { card.setPlanShipTime(formatLocalDateYmd(trip.getEstimatedStartDate())); + } + if (trip.getEstimatedEndDate() != null) { card.setPlanFinishTime(formatLocalDateYmd(trip.getEstimatedEndDate())); + } + // 备注只有配载运次有运次级的值,未配载的保留运单卡片自己带来的备注 + if (Func.isNotEmpty(card.getLoadingNo())) { card.setRemark(Func.toStr(trip.getTaskRemark(), "")); } card.setFromName(Func.toStrWithEmpty(trip.getDepartureName(), Func.toStr(trip.getDepartureAddress(), ""))); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageWaybillServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageWaybillServiceImpl.java index 41ab9cc2..7cab655b 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageWaybillServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ManageWaybillServiceImpl.java @@ -246,7 +246,7 @@ public class ManageWaybillServiceImpl implements IManageWaybillService { } /** - * 运次卡片页:一次算清这一页的重派标记、异常与未配载运次的计划时间,再逐条拼卡片 + * 运次卡片页:一次算清这一页的重派标记与异常,再逐条拼卡片 */ private Page tripCardPage(List trips, int pageNo, int pageSize, long total, Set exceptionWaybillIds) { @@ -254,9 +254,8 @@ public class ManageWaybillServiceImpl implements IManageWaybillService { if (!trips.isEmpty()) { Set reassignKeys = loadReassignTripKeys( trips.stream().map(this::tripKeyOf).collect(Collectors.toCollection(LinkedHashSet::new))); - Map loneWaybills = loadLoneWaybills(trips); for (TripVO trip : trips) { - cards.add(toTripCard(trip, exceptionWaybillIds, reassignKeys, loneWaybills)); + cards.add(toTripCard(trip, exceptionWaybillIds, reassignKeys)); } } Page page = new Page<>(pageNo, pageSize, total); @@ -265,12 +264,12 @@ public class ManageWaybillServiceImpl implements IManageWaybillService { } /** - * 运次卡片:展示单号、整趟车起/经/终与站点数、货物汇总都取运次字段。 + * 运次卡片:展示单号、整趟车起/经/终与站点数、货物汇总、计划时间都取运次字段。 * 旧字段 id / waybillNo 保留运单语义(未配载就是这张运单,配载取第一张可见子运单), * 打卡订正、重新派单等按运单进入的入口仍靠它们。 */ private AdminWaybillCardVO toTripCard(TripVO trip, Set exceptionWaybillIds, - Set reassignTripIds, Map loneWaybills) { + Set reassignTripIds) { AdminWaybillCardVO card = new AdminWaybillCardVO(); List children = trip.getWaybills() == null ? List.of() : trip.getWaybills(); Long firstChildId = children.isEmpty() ? null : parseId(children.get(0).getId()); @@ -293,15 +292,9 @@ public class ManageWaybillServiceImpl implements IManageWaybillService { String weight = formatWeight(trip.getTotalQuantity(), trip.getQuantityUnit()); card.setWeight(weight); card.setTotalWeight(weight); - if (loaded) { - card.setPlanTime(formatLocalDate(trip.getEstimatedStartDate())); - card.setPlanTimeEnd(formatLocalDate(trip.getEstimatedEndDate())); - } else { - // 未配载运次不带计划时间,按运单主键补一次;缺失时留空,不与其他运次串值 - Waybill waybill = loneWaybills.get(parseId(trip.getId())); - card.setPlanTime(formatLocalDate(waybill == null ? null : waybill.getEstimatedStartTime())); - card.setPlanTimeEnd(formatLocalDate(waybill == null ? null : waybill.getEstimatedEndTime())); - } + // 计划时间两条路同源:配载运次取配载单,未配载运次取那张运单自己的 + card.setPlanTime(formatLocalDate(trip.getEstimatedStartDate())); + card.setPlanTimeEnd(formatLocalDate(trip.getEstimatedEndDate())); card.setStatus(trip.getStatus()); card.setDriverName(Func.toStr(trip.getDriverName(), "")); card.setVehicleNo(Func.toStr(trip.getVehicleNo(), "")); @@ -312,25 +305,6 @@ public class ManageWaybillServiceImpl implements IManageWaybillService { return card; } - /** - * 未配载运次(每张运单自成运次)的计划时间:运次读服务不下发它,一页一次批量补查 - */ - private Map loadLoneWaybills(List trips) { - Set loneIds = trips.stream() - .filter(trip -> Func.isEmpty(trip.getLoadingNo())) - .map(trip -> parseId(trip.getId())) - .filter(Objects::nonNull) - .collect(Collectors.toCollection(LinkedHashSet::new)); - if (loneIds.isEmpty()) { - return Map.of(); - } - return waybillService.list(Wrappers.lambdaQuery() - .select(Waybill::getId, Waybill::getEstimatedStartTime, Waybill::getEstimatedEndTime) - .in(Waybill::getId, loneIds)) - .stream() - .collect(Collectors.toMap(Waybill::getId, Function.identity(), (first, ignored) -> first)); - } - /** 这一页里带「子单被拒」标记的运次主键:判据与重派待办一致(已拒单 + 未取消未完成) */ private Set loadReassignTripKeys(Set tripIds) { if (Func.isEmpty(tripIds)) { diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TripQueryServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TripQueryServiceImpl.java index 7af9b79f..d4c45658 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TripQueryServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TripQueryServiceImpl.java @@ -231,7 +231,9 @@ public class TripQueryServiceImpl implements ITripQueryService { Waybill::getCargoName, Waybill::getCargoType, Waybill::getQuantity, Waybill::getQuantityUnit, Waybill::getDepartureName, Waybill::getDepartureAddress, Waybill::getArrivalName, Waybill::getArrivalAddress, Waybill::getDriverName, Waybill::getDriverPhone, Waybill::getVehicleNo, - Waybill::getCustomerName, Waybill::getTransportType, Waybill::getTaskRemark, Waybill::getCreateTime) + Waybill::getCustomerName, Waybill::getTransportType, Waybill::getTaskRemark, + // 未配载运次没有配载单可依,计划时间要取运单自己的,故必须随行取回 + Waybill::getEstimatedStartTime, Waybill::getEstimatedEndTime, Waybill::getCreateTime) .in(Waybill::getBusinessStatus, TripAggregation.CHILD_STATUSES) .and(visible -> visible.isNull(Waybill::getDriverAcceptStatus) .or().ne(Waybill::getDriverAcceptStatus, WaybillProcessSupport.ACCEPT_REJECTED)); @@ -545,6 +547,9 @@ public class TripQueryServiceImpl implements ITripQueryService { trip.setCargoType(Func.toStr(waybill.getCargoType(), "")); trip.setDepartureAddress(Func.toStr(waybill.getDepartureAddress(), "")); trip.setArrivalAddress(Func.toStr(waybill.getArrivalAddress(), "")); + // 未配载没有配载单可依,计划时间只能取这张运单自己的 + trip.setEstimatedStartDate(waybill.getEstimatedStartTime()); + trip.setEstimatedEndDate(waybill.getEstimatedEndTime()); trip.setTaskRemark(Func.toStr(waybill.getTaskRemark(), "")); if (withPayload) { trip.setRouteJson(waybill.getRouteJson()); diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverTripCardTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverTripCardTest.java index 612bb192..966ac370 100644 --- a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverTripCardTest.java +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/DriverTripCardTest.java @@ -191,6 +191,8 @@ class DriverTripCardTest { assertEquals("", card.getLoadingNo()); assertEquals("YD-20260920-0003", card.getTripNo()); assertEquals("common", card.getTransportOrgType()); + assertEquals("2026-09-20", card.getPlanShipTime(), "未配载运次的卡片也要带计划时间"); + assertEquals("2026-09-22", card.getPlanFinishTime()); } @Test @@ -400,6 +402,8 @@ class DriverTripCardTest { trip.setRequireAccept(true); trip.setAcceptStatus("pending"); trip.setSortTime(new Date(1787629629000L)); + trip.setEstimatedStartDate(java.time.LocalDate.of(2026, 9, 20)); + trip.setEstimatedEndDate(java.time.LocalDate.of(2026, 9, 22)); trip.setDepartureName("南宁武鸣"); trip.setArrivalName("钦州港"); trip.setStationCount(2); diff --git a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/TripQueryServiceImplTest.java b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/TripQueryServiceImplTest.java index e981e71e..7c1a9420 100644 --- a/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/TripQueryServiceImplTest.java +++ b/blade-service/blade-transport/src/test/java/org/springblade/transport/service/impl/TripQueryServiceImplTest.java @@ -23,6 +23,7 @@ import org.springblade.transport.service.ILoadingManageService; import org.springblade.transport.service.IProcessConfigService; import org.springblade.transport.service.IWaybillService; +import java.time.LocalDate; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -112,6 +113,8 @@ class TripQueryServiceImplTest { String select = String.valueOf(capturedRowQuery().getSqlSelect()); assertTrue(select.contains("process_json"), "分档要按过程配置推导,必须取:" + select); assertTrue(select.contains("create_time"), "排序键要用:" + select); + assertTrue(select.contains("estimated_start_time"), "未配载运次的计划时间取自运单,必须取:" + select); + assertTrue(select.contains("estimated_end_time"), select); assertFalse(select.contains("route_json"), "运单表上的大 JSON 列不必拖回:" + select); assertFalse(select.contains("goods_json"), select); assertFalse(select.contains("task_info_json"), select); @@ -258,6 +261,28 @@ class TripQueryServiceImplTest { assertEquals("YD-20260920-0003", trip.getTripNo()); } + @Test + @DisplayName("未配载运次的计划时间取自这张运单:没有配载单可依,不能留空") + void unloadedTripPlanTimeComesFromWaybill() { + Waybill row = waybill(WAYBILL_ID, "YD-20260920-0003", null, "running", null, at(1000L), ACCEPT_NO); + row.setEstimatedStartTime(LocalDate.of(2026, 8, 7)); + row.setEstimatedEndTime(LocalDate.of(2026, 8, 24)); + stubRows(row); + + TripVO listed = service.page(TripQueryVO.forDriver(PHONE)).getRecords().get(0); + + assertEquals(LocalDate.of(2026, 8, 7), listed.getEstimatedStartDate(), "列表卡片与详情同源,不能只在列表补"); + assertEquals(LocalDate.of(2026, 8, 24), listed.getEstimatedEndDate()); + + when(loadingManageService.getById(WAYBILL_ID)).thenReturn(null); + when(waybillService.getById(WAYBILL_ID)).thenReturn(row); + + TripVO detailed = service.detail(tripQuery(String.valueOf(WAYBILL_ID))); + + assertEquals(LocalDate.of(2026, 8, 7), detailed.getEstimatedStartDate(), "管理端详情走这条路,不留空"); + assertEquals(LocalDate.of(2026, 8, 24), detailed.getEstimatedEndDate()); + } + @Test @DisplayName("配载单在两次查询之间被删掉时,不给出没有主键的运次") void loadingMissingIsDropped() {