This commit is contained in:
2026-11-04 11:13:29 +08:00
parent 413e1e83e8
commit ba49035942
10 changed files with 173 additions and 2 deletions
@@ -37,6 +37,16 @@ import java.security.MessageDigest;
@RestController
@RequestMapping("/internal/firstleg/v1/inbounds")
public class InternalInboundOrderController {
/** 海外废弃溯源只读取已生成的有效箱唛,不触发打印或补建。 */
@org.springframework.web.bind.annotation.GetMapping("/{inboundId}/existing-carton-marks")
public ApiResponse<List<String>> existingCartonMarks(
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
@org.springframework.web.bind.annotation.PathVariable long inboundId,
@org.springframework.web.bind.annotation.RequestParam long customerId,
@org.springframework.web.bind.annotation.RequestParam String inboundCode) {
requireToken(token);
return ApiResponse.success(cartonLabels.existingCartonMarks(customerId, inboundId, inboundCode));
}
@Resource
private InboundOrderCreationService service;
@Resource
@@ -45,6 +45,16 @@ public class InboundCartonLabelService implements CartonLabelBindingResolver {
@Resource private InboundOrderCreationService inboundOrderCreationService;
@Value("${baiyue.security.internal-service-token}") private String internalToken;
/** 海外按数量收货后的只读溯源:仅读已有有效批次,不生成或修改箱号。 */
public List<String> existingCartonMarks(long customerId, long inboundId, String inboundCode) {
requireIds(customerId, inboundId);
var labels = repository.findActiveByInbound(customerId, inboundId);
if (labels.isEmpty()) return List.of();
return requireConsistent(labels).stream()
.filter(label -> inboundCode.equals(label.getInboundCode()))
.map(InboundCartonLabelEntity::getBoxCode).toList();
}
@Transactional
public InboundCartonLabels.Batch getOrCreate(long tenantId, long inboundId) {
requireIds(tenantId, inboundId);
@@ -0,0 +1,18 @@
openapi: 3.0.3
info: { title: 原入仓有效箱唛内部查询, version: 1.0.0 }
security: [{ internalToken: [] }]
paths:
/internal/firstleg/v1/inbounds/{inboundId}/existing-carton-marks:
get:
summary: 只读查询指定客户及原入仓已有有效箱唛批次,不补建箱号
parameters:
- { in: path, name: inboundId, required: true, schema: { type: integer, format: int64, minimum: 1 } }
- { in: query, name: customerId, required: true, schema: { type: integer, format: int64, minimum: 1 } }
- { in: query, name: inboundCode, required: true, schema: { type: string } }
responses:
'200':
description: 统一响应;data为有效箱唛字符串数组,归属不匹配或无已有批次时为空;批次不完整返回业务错误
'403': { description: 内部服务凭证缺失或无效 }
components:
securitySchemes:
internalToken: { type: apiKey, in: header, name: X-Internal-Service-Token }
@@ -30,6 +30,18 @@ import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class InboundCartonLabelServiceTest {
/** 海外溯源必须使用已有批次,不得因空记录补建箱号。 */
@Test void existingMarksAreReadOnlyAndCheckInboundCode() {
when(repository.findActiveByInbound(1L, 2L)).thenReturn(List.of());
assertThat(service.existingCartonMarks(1L, 2L, "IN")).isEmpty();
var label = new InboundCartonLabelEntity();
label.setTotalCartonCount(1); label.setCartonIndex(1); label.setLabelVersion(1);
label.setBatchStatus("ACTIVE"); label.setInboundCode("IN"); label.setBoxCode("IN#1-1");
when(repository.findActiveByInbound(1L, 2L)).thenReturn(List.of(label));
assertThat(service.existingCartonMarks(1L, 2L, "IN")).containsExactly("IN#1-1");
assertThat(service.existingCartonMarks(1L, 2L, "OTHER")).isEmpty();
org.mockito.Mockito.verifyNoInteractions(orderCargoClient, inboundOrderCreationService, labelSkus);
}
@Mock private InboundCartonLabelRepository repository;
@Mock private OrderCargoClient orderCargoClient;
@Mock private PrintableOrderInboundClient printableOrderInboundClient;