feat(fleet): match cargo stops when binding dispatches

This commit is contained in:
2026-10-09 15:04:51 +08:00
parent 2ec5414b39
commit c4a7c2a22d
3 changed files with 51 additions and 1 deletions
@@ -206,11 +206,36 @@ public class FleetTripService {
try { if (bindings.insert(binding) != 1) throw conflict("排车单关联失败"); }
catch (DuplicateKeyException duplicate) { throw conflict("排车单已关联其他车次,请刷新后重试"); }
bookingReservations.bindIncoming(trip, dispatch, dispatches.sourceCargo(dispatch.dispatchNo()), operator);
var route = matchedStops(response(trip).stops(), dispatches.manifest(dispatch.dispatchNo(), false).cargo());
validatePlan(instant(trip.getPlannedDepartureAt()), instant(trip.getExpectedDriverEndAt()), route);
bookingReservations.requireRoute(trip, route);
trip.setStopsJson(write(route));
dispatches.assign(dispatch, assignment(trip));
persist(trip, request.recordVersion(), "BIND_DISPATCH", request.reason(), operator);
return detail(trip);
}
static List<FleetTripModels.Stop> matchedStops(List<FleetTripModels.Stop> existing, List<FleetExecutionModels.Cargo> cargo) {
// Keep established stop indexes/order: confirmed bookings may refer to them.
var result = new ArrayList<>(existing);
boolean onlyPlaceholder = existing.size() == 2 && existing.get(1).destinationKey() == null
&& existing.get(1).name().startsWith("待确定卸货点");
if (onlyPlaceholder) result.remove(1);
var keys = new HashSet<String>();
for (var stop : result) if (stop.destinationKey() != null) keys.add(stop.destinationKey());
for (var item : cargo) {
if (item.destinationKey() == null || item.destinationKey().isBlank())
throw conflict("排车货物目的地未确认,请先完善排车单目的地");
if (keys.add(item.destinationKey())) {
if (item.destinationLabel() == null || item.destinationLabel().isBlank())
throw conflict("排车货物目的地名称缺失,请先完善排车单");
result.add(new FleetTripModels.Stop(item.destinationLabel(), null, item.destinationKey()));
}
}
if (result.size() < 2) throw conflict("排车单没有可用卸货目的地");
return List.copyOf(result);
}
@Transactional
public FleetTripModels.Detail unbindDispatch(String tripNo, String operator, FleetTripModels.BindingCommand request) {
var trip = planned(tripNo, request.recordVersion());