This commit is contained in:
2026-09-07 19:59:31 +08:00
parent df8610f458
commit 4895c4f738
5 changed files with 37 additions and 16 deletions
@@ -55,9 +55,9 @@ public class DeliveryTransferController {
@PreAuthorize("hasAuthority('" + OverseasPermissions.OUTBOUND_LIST + "')") @PreAuthorize("hasAuthority('" + OverseasPermissions.OUTBOUND_LIST + "')")
public ApiResponse<DeliveryResponses.OutboundDetail> outboundDetail( public ApiResponse<DeliveryResponses.OutboundDetail> outboundDetail(
@AuthenticationPrincipal AuthenticatedUser user, @AuthenticationPrincipal AuthenticatedUser user,
@PathVariable String outboundNo, @Valid DeliveryRequests.PalletQuery query) { @PathVariable String outboundNo) {
requirePlatform(user); requirePlatform(user);
return ApiResponse.success(service.outboundDetail(outboundNo, query)); return ApiResponse.success(service.outboundDetail(outboundNo));
} }
@PostMapping("/outbound-orders/{outboundNo}/cancel") @PostMapping("/outbound-orders/{outboundNo}/cancel")
@@ -43,11 +43,6 @@ public final class DeliveryRequests {
public Query { if (page == 0) page = 1; if (size == 0) size = 20; } public Query { if (page == 0) page = 1; if (size == 0) size = 20; }
} }
public record PalletQuery(@Min(1) long page, @Min(1) @Max(200) long size,
String destinationWarehouseCode) {
public PalletQuery { if (page == 0) page = 1; if (size == 0) size = 20; }
}
public record OneClickOutbound(@NotBlank @Size(max=1000) String recipient, public record OneClickOutbound(@NotBlank @Size(max=1000) String recipient,
@NotNull @Size(min=1, max=200) List<@Valid OneClickItem> items, @NotNull @Size(min=1, max=200) List<@Valid OneClickItem> items,
@Size(max=1000) String remark, @Size(max=1000) String remark,
@@ -476,8 +476,7 @@ public class DeliveryTransferService {
return page(page, page.getRecords().stream().map(this::outboundRow).toList()); return page(page, page.getRecords().stream().map(this::outboundRow).toList());
} }
public DeliveryResponses.OutboundDetail outboundDetail(String outboundNo, public DeliveryResponses.OutboundDetail outboundDetail(String outboundNo) {
DeliveryRequests.PalletQuery query) {
OutboundOrder outbound = outboundOrders.findGlobalByNo(trim(outboundNo)); OutboundOrder outbound = outboundOrders.findGlobalByNo(trim(outboundNo));
if (outbound == null) throw notFound("Outbound order not found"); if (outbound == null) throw notFound("Outbound order not found");
String customerId = outbound.getCustomerId(); String customerId = outbound.getCustomerId();
@@ -11,6 +11,12 @@ import com.baiyue.lastleg.security.OverseasPermissions;
import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Select;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.method.annotation.AuthenticationPrincipalArgumentResolver;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;
@@ -25,8 +31,31 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
class PlatformDispatchOutboundContractTest { class PlatformDispatchOutboundContractTest {
@Test
void outboundDetailAcceptsTheDocumentUrlWithoutPagingParameters() throws Exception {
DeliveryTransferController controller = new DeliveryTransferController();
ReflectionTestUtils.setField(controller, "service",
mock(com.baiyue.lastleg.delivery.service.DeliveryTransferService.class));
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setCustomArgumentResolvers(new AuthenticationPrincipalArgumentResolver())
.build();
AuthenticatedUser platform = new AuthenticatedUser(1000001L, 0L, 0L, 1L, "platform_admin",
"PLATFORM", "WEB", Set.of(OverseasPermissions.OUTBOUND_LIST));
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(platform, null, Set.of()));
try {
mockMvc.perform(get("/api/platform/v1/last-leg/outbound-orders/OB-WH-20260907-030529"))
.andExpect(status().isOk());
} finally {
SecurityContextHolder.clearContext();
}
}
@Test @Test
void platformActionsHaveIndependentPermissionsAndNoCustomerParameter() throws Exception { void platformActionsHaveIndependentPermissionsAndNoCustomerParameter() throws Exception {
Method update = DispatchController.class.getMethod("update", AuthenticatedUser.class, Method update = DispatchController.class.getMethod("update", AuthenticatedUser.class,
@@ -35,7 +64,7 @@ class PlatformDispatchOutboundContractTest {
Method transfer = DeliveryTransferController.class.getMethod("transfer", AuthenticatedUser.class, Method transfer = DeliveryTransferController.class.getMethod("transfer", AuthenticatedUser.class,
String.class, DeliveryRequests.Transfer.class); String.class, DeliveryRequests.Transfer.class);
Method outboundDetail = DeliveryTransferController.class.getMethod("outboundDetail", Method outboundDetail = DeliveryTransferController.class.getMethod("outboundDetail",
AuthenticatedUser.class, String.class, DeliveryRequests.PalletQuery.class); AuthenticatedUser.class, String.class);
Method outboundCancel = DeliveryTransferController.class.getMethod("cancelOutbound", Method outboundCancel = DeliveryTransferController.class.getMethod("cancelOutbound",
AuthenticatedUser.class, String.class, DeliveryRequests.Cancel.class); AuthenticatedUser.class, String.class, DeliveryRequests.Cancel.class);
@@ -43,6 +72,7 @@ class PlatformDispatchOutboundContractTest {
assertPermission(cancel, OverseasPermissions.DISPATCH_CANCEL); assertPermission(cancel, OverseasPermissions.DISPATCH_CANCEL);
assertPermission(transfer, OverseasPermissions.DISPATCH_TRANSFER_DELIVERY); assertPermission(transfer, OverseasPermissions.DISPATCH_TRANSFER_DELIVERY);
assertPermission(outboundDetail, OverseasPermissions.OUTBOUND_LIST); assertPermission(outboundDetail, OverseasPermissions.OUTBOUND_LIST);
assertEquals(2, outboundDetail.getParameterCount());
assertPermission(outboundCancel, OverseasPermissions.OUTBOUND_CANCEL); assertPermission(outboundCancel, OverseasPermissions.OUTBOUND_CANCEL);
for (Method method : Set.of(update, cancel, transfer, outboundDetail, outboundCancel)) { for (Method method : Set.of(update, cancel, transfer, outboundDetail, outboundCancel)) {
assertTrue(Arrays.stream(method.getParameters()) assertTrue(Arrays.stream(method.getParameters())
@@ -91,8 +121,7 @@ class PlatformDispatchOutboundContractTest {
() -> dispatchController.cancel(merchant, "DSP-101")); () -> dispatchController.cancel(merchant, "DSP-101"));
ResponseStatusException outboundRejected = org.junit.jupiter.api.Assertions.assertThrows( ResponseStatusException outboundRejected = org.junit.jupiter.api.Assertions.assertThrows(
ResponseStatusException.class, ResponseStatusException.class,
() -> deliveryController.outboundDetail(merchant, "OUT-101", () -> deliveryController.outboundDetail(merchant, "OUT-101"));
new DeliveryRequests.PalletQuery(1, 20, null)));
assertEquals(403, dispatchRejected.getStatusCode().value()); assertEquals(403, dispatchRejected.getStatusCode().value());
assertEquals(403, outboundRejected.getStatusCode().value()); assertEquals(403, outboundRejected.getStatusCode().value());
@@ -276,8 +276,7 @@ class DeliveryTransferServiceTest {
when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound); when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound);
when(deliveryOrders.lockByOutbound("TENANT-A", 301L)).thenReturn(delivery); when(deliveryOrders.lockByOutbound("TENANT-A", 301L)).thenReturn(delivery);
DeliveryResponses.OutboundDetail detail = service.outboundDetail("OUT-301", DeliveryResponses.OutboundDetail detail = service.outboundDetail("OUT-301");
new DeliveryRequests.PalletQuery(1, 20, null));
assertEquals("OUT-301", detail.outbound().outboundNo()); assertEquals("OUT-301", detail.outbound().outboundNo());
assertEquals("DEL-401", detail.delivery().deliveryNo()); assertEquals("DEL-401", detail.delivery().deliveryNo());
@@ -293,8 +292,7 @@ class DeliveryTransferServiceTest {
when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound); when(outboundOrders.findGlobalByNo("OUT-301")).thenReturn(outbound);
when(deliveryOrders.lockByOutbound("TENANT-A", 301L)).thenReturn(delivery); when(deliveryOrders.lockByOutbound("TENANT-A", 301L)).thenReturn(delivery);
DeliveryResponses.OutboundDetail detail = service.outboundDetail("OUT-301", DeliveryResponses.OutboundDetail detail = service.outboundDetail("OUT-301");
new DeliveryRequests.PalletQuery(1, 20, null));
assertEquals("OUT-301", detail.outbound().outboundNo()); assertEquals("OUT-301", detail.outbound().outboundNo());
verify(deliveryOrders).lockByOutbound("TENANT-A", 301L); verify(deliveryOrders).lockByOutbound("TENANT-A", 301L);