This commit is contained in:
2026-10-14 13:42:58 +08:00
parent bc9c78122b
commit d017f5d881
9 changed files with 239 additions and 6 deletions
@@ -20,6 +20,20 @@ import org.springframework.web.bind.annotation.RestController;
@PreAuthorize("hasAuthority('lastleg:pda:operate') and hasAuthority('ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR')")
public class PdaPalletOperationController {
@Resource private PdaPalletOperationService service;
@Resource private com.baiyue.lastleg.relabel.service.RelabelPalletMeasurementService measurements;
@PostMapping("/relabel-pallet-measurements")
public ApiResponse<java.util.List<com.baiyue.lastleg.relabel.service.RelabelPalletMeasurementService.Measurement>> measurements(
@AuthenticationPrincipal AuthenticatedUser user, @Valid @RequestBody PalletOperationRequests.RelabelSources request) {
return ApiResponse.success(measurements.list(PdaWarehouseIdentity.require(user), request.relabelNo()));
}
@PostMapping("/relabel-pallet-measure")
public ApiResponse<java.util.List<com.baiyue.lastleg.relabel.service.RelabelPalletMeasurementService.Measurement>> measure(
@AuthenticationPrincipal AuthenticatedUser user,
@Valid @RequestBody com.baiyue.lastleg.relabel.service.RelabelPalletMeasurementService.Measure request) {
return ApiResponse.success(measurements.save(PdaWarehouseIdentity.require(user), request));
}
@PostMapping("/pallets/resolve")
public ApiResponse<PalletOperationResponses.PalletContent> resolve(
@@ -233,7 +233,6 @@ public class PdaPalletOperationService {
List.of(request.target())).get(code(request.target().palletCode()));
PalletPhysicalGateway.PalletReference source = request.source() == null ? null
: resolvePallets(identity.overseasWarehouseId(), List.of(request.source())).get(code(request.source().palletCode()));
if (source != null && source.palletId() == target.palletId()) throw conflict("原托盘和目标托盘不能相同");
Map<String, PalletPhysicalGateway.PalletReference> pallets = new LinkedHashMap<>();
if (source != null) pallets.put(source.palletCode(), source);
pallets.put(target.palletCode(), target);
@@ -283,8 +282,37 @@ public class PdaPalletOperationService {
}
}
if (returnRelabel) {
if (source != null && source.palletId() == target.palletId()) throw conflict("退货换标请使用独立目标托盘");
return bindReturnRelabelPallet(identity, application, selected, source, target, request, unboundReturnRelabel);
}
if (source.palletId() == target.palletId()) {
return transaction.execute(status -> {
var lockedApp = relabelApplications.lockAnyByRelabelNo(application.getRelabelNo());
requireRelabelWork(identity, lockedApp);
long total = mapper.palletPackages(String.valueOf(identity.overseasWarehouseId()), source.palletId());
long selectedPackages = selected.stream().mapToLong(i -> value(i.getNotifiedPackageCount())).sum();
if (total <= 0 || total != selectedPackages) throw conflict("部分贴标必须拆到新托盘;只有整托全部贴标可保留原托盘");
Map<Long, List<RelabelItem>> byPosition = selected.stream().collect(Collectors.groupingBy(RelabelItem::getSourceInventoryPositionId));
Map<Long, InventoryPosition> retained = new LinkedHashMap<>();
for (var entry : byPosition.entrySet()) {
var row = mapper.lockPosition(application.getOverseasWarehouseId(), entry.getKey());
long count = entry.getValue().stream().mapToLong(i -> value(i.getNotifiedPackageCount())).sum();
if (row == null || !application.getCustomerId().equals(row.getCustomerId())
|| !Objects.equals(row.getPalletId(), source.palletId()) || value(row.getHoldPackages()) < count)
throw conflict("原托盘换标库存已变化,请刷新后核对");
requirePalletReservation(application.getCustomerId(), entry.getKey(), inventoryCommands.relabelTransfer(application.getCustomerId(), application.getId()));
retained.put(entry.getKey(), positions.selectById(entry.getKey()));
}
requireRelabelDestination(identity.overseasWarehouseId(), selected, target);
Set<String> bound = boundRelabelMarks(application);
if (!marks.stream().allMatch(bound::contains)) {
if (marks.stream().anyMatch(bound::contains)) throw conflict("本批包含已绑定箱唛,请刷新后重试");
recordRelabelBinding(identity, new RelabelMutation(application, byPosition, Map.of()), retained);
}
return new PalletOperationResponses.Operation(IdWorker.getId(), "RELABEL_PALLET_RETAIN", request.idempotencyKey(),
"COMPLETED", false, LocalDateTime.now(), List.of(content(identity.overseasWarehouseId(), source)));
});
}
for (RelabelItem item : selected) {
if (item.getSourceInventoryPositionId() == null || item.getNotifiedPackageCount() == null
|| item.getNotifiedPackageCount() <= 0) throw conflict("换标箱唛缺少库存位置或箱数快照");
@@ -808,7 +836,9 @@ public class PdaPalletOperationService {
record.setCreatedAt(LocalDateTime.now());
record.setDetailJson(write(Map.of("round", Objects.toString(task.getReviewedAt(), "INITIAL"),
"cartonMarks", mutation.itemsByPosition().values().stream().flatMap(List::stream).map(RelabelItem::getCartonMark).toList(),
"targetPallets", targets.values().stream().map(InventoryPosition::getPalletNo).distinct().toList())));
"targetPallets", targets.values().stream().map(InventoryPosition::getPalletNo).distinct().toList(),
"sourcePallets", mutation.itemsByPosition().keySet().stream().map(positions::selectById)
.filter(Objects::nonNull).map(InventoryPosition::getPalletNo).distinct().toList())));
relabelWorkHistory.insert(record);
}