fix(pda): allow receiving photo lookup by container
This commit is contained in:
+26
@@ -95,6 +95,19 @@ public class ReceivingContainerController {
|
||||
.contentLength(download.content().length).body(download.content());
|
||||
}
|
||||
|
||||
@GetMapping("/{containerNo}/unload-photos/files/{fileId}/download")
|
||||
public ResponseEntity<byte[]> downloadContainerPhoto(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable String containerNo,
|
||||
@PathVariable String fileId) {
|
||||
PdaWarehouseIdentity identity = identity(user);
|
||||
var download = service.downloadContainerPhoto(identity.overseasWarehouseId(), containerNo, fileId);
|
||||
return ResponseEntity.ok().cacheControl(CacheControl.noStore())
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
ContentDisposition.inline().filename(download.fileName(), StandardCharsets.UTF_8).build().toString())
|
||||
.contentType(MediaType.parseMediaType(download.contentType()))
|
||||
.contentLength(download.content().length).body(download.content());
|
||||
}
|
||||
|
||||
@GetMapping("/current/domestic-loading-photos/{evidenceType}/content")
|
||||
public ResponseEntity<byte[]> downloadDomesticLoadingPhoto(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable String evidenceType) {
|
||||
@@ -107,6 +120,19 @@ public class ReceivingContainerController {
|
||||
.contentLength(download.content().length).body(download.content());
|
||||
}
|
||||
|
||||
@GetMapping("/{containerNo}/domestic-loading-photos/{evidenceType}/content")
|
||||
public ResponseEntity<byte[]> downloadContainerDomesticLoadingPhoto(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable String containerNo,
|
||||
@PathVariable String evidenceType) {
|
||||
PdaWarehouseIdentity identity = identity(user);
|
||||
var download = service.downloadContainerDomesticLoadingPhoto(identity.overseasWarehouseId(), containerNo, evidenceType);
|
||||
return ResponseEntity.ok().cacheControl(CacheControl.noStore())
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
ContentDisposition.inline().filename(download.fileName(), StandardCharsets.UTF_8).build().toString())
|
||||
.contentType(MediaType.parseMediaType(download.contentType()))
|
||||
.contentLength(download.content().length).body(download.content());
|
||||
}
|
||||
|
||||
@PostMapping("/current/sign")
|
||||
public ApiResponse<ReceivingContainerResponses.Session> sign(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@Valid @RequestBody ReceivingContainerRequests.Sign request) {
|
||||
|
||||
+4
@@ -22,6 +22,10 @@ public interface ReceivingContainerSessionMapper extends BaseMapper<ReceivingCon
|
||||
"WHERE active_container_key=#{activeContainerKey} LIMIT 1")
|
||||
ReceivingContainerSession findActiveByContainer(@Param("activeContainerKey") String activeContainerKey);
|
||||
|
||||
@Select("SELECT * FROM ll_receiving_container_session " +
|
||||
"WHERE container_no=#{containerNo} ORDER BY created_at DESC LIMIT 1")
|
||||
ReceivingContainerSession findLatestByContainerNo(@Param("containerNo") String containerNo);
|
||||
|
||||
@Select("SELECT * FROM ll_receiving_container_session WHERE active_container_key IS NOT NULL")
|
||||
List<ReceivingContainerSession> findActiveContainers();
|
||||
|
||||
|
||||
+41
-2
@@ -70,8 +70,12 @@ public class ReceivingContainerService {
|
||||
private static final String PLATFORM_SCOPE = "0";
|
||||
private static final String PHOTO_DOWNLOAD_PATH =
|
||||
"/api/pda/v1/last-leg/receiving-containers/current/unload-photos/files/{fileId}/download";
|
||||
private static final String CONTAINER_PHOTO_DOWNLOAD_PATH =
|
||||
"/api/pda/v1/last-leg/receiving-containers/{containerNo}/unload-photos/files/{fileId}/download";
|
||||
private static final String DOMESTIC_PHOTO_DOWNLOAD_PATH =
|
||||
"/api/pda/v1/last-leg/receiving-containers/current/domestic-loading-photos/{type}/content";
|
||||
private static final String CONTAINER_DOMESTIC_PHOTO_DOWNLOAD_PATH =
|
||||
"/api/pda/v1/last-leg/receiving-containers/{containerNo}/domestic-loading-photos/{type}/content";
|
||||
private static final String PALLET_MERGE_HINT =
|
||||
"该入库计划可选择合托:合托时扫描同目的仓已使用的托盘码,独立收货时扫描新托盘码;不强制合托";
|
||||
private static final int MAX_PACKAGES_PER_PALLET = 66;
|
||||
@@ -275,6 +279,39 @@ public class ReceivingContainerService {
|
||||
return domesticEvidenceFiles.download(bookingId, evidence.getSourceFileId());
|
||||
}
|
||||
|
||||
public UnloadPhotoFileGateway.DownloadedFile downloadContainerPhoto(
|
||||
long overseasWarehouseId, String containerNo, String fileId) {
|
||||
ReceivingContainerSession session = requireContainerPhotoSession(overseasWarehouseId, containerNo);
|
||||
long parsedFileId = positiveFileId(fileId);
|
||||
if (signedPhotos(session).stream().noneMatch(photo -> fileId.equals(photo.fileId()))) {
|
||||
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "该柜没有对应的卸柜照片");
|
||||
}
|
||||
return unloadPhotos.download(PLATFORM_SCOPE, session.getId(), parsedFileId);
|
||||
}
|
||||
|
||||
public DomesticLoadingEvidenceGateway.DownloadedFile downloadContainerDomesticLoadingPhoto(
|
||||
long overseasWarehouseId, String containerNo, String evidenceType) {
|
||||
ReceivingContainerSession session = requireContainerPhotoSession(overseasWarehouseId, containerNo);
|
||||
String type = requiredEvidenceType(evidenceType);
|
||||
var evidence = domesticEvidence.find(session.getSourceContainerBookingId(), type);
|
||||
if (evidence == null) throw notFound("当前柜没有该国内装柜照片");
|
||||
long bookingId;
|
||||
try { bookingId = Long.parseLong(session.getSourceContainerBookingId()); }
|
||||
catch (NumberFormatException exception) { throw new ResponseStatusException(
|
||||
HttpStatus.SERVICE_UNAVAILABLE, "当前柜国内照片来源无效", exception); }
|
||||
return domesticEvidenceFiles.download(bookingId, evidence.getSourceFileId());
|
||||
}
|
||||
|
||||
private ReceivingContainerSession requireContainerPhotoSession(long overseasWarehouseId, String containerNo) {
|
||||
String value = trim(containerNo);
|
||||
if (value == null) throw notFound("柜号不能为空");
|
||||
ReceivingContainerSession session = sessions.findLatestByContainerNo(value);
|
||||
if (session == null || !Objects.equals(session.getOverseasWarehouseId(), overseasWarehouseId)) {
|
||||
throw notFound("当前仓没有该柜的照片");
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
public void requireCurrentWarehouse(String operatorKey, long overseasWarehouseId) {
|
||||
requireSessionWarehouse(sessions.findActiveByOperator(activeOperatorKey(operatorKey)), overseasWarehouseId);
|
||||
}
|
||||
@@ -1050,7 +1087,8 @@ public class ReceivingContainerService {
|
||||
if (bookingId == null) return List.of();
|
||||
return domesticEvidence.listByContainer(bookingId).stream()
|
||||
.map(value -> new ReceivingContainerResponses.DomesticLoadingPhoto(value.getEvidenceType(),
|
||||
evidenceLabel(value.getEvidenceType()), DOMESTIC_PHOTO_DOWNLOAD_PATH.replace("{type}", value.getEvidenceType())))
|
||||
evidenceLabel(value.getEvidenceType()), CONTAINER_DOMESTIC_PHOTO_DOWNLOAD_PATH
|
||||
.replace("{containerNo}", session.getContainerNo()).replace("{type}", value.getEvidenceType())))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@@ -1384,7 +1422,8 @@ public class ReceivingContainerService {
|
||||
private List<ReceivingContainerResponses.SignedPhoto> signPhotos(ReceivingContainerSession session) {
|
||||
return signedPhotos(session).stream()
|
||||
.map(photo -> new ReceivingContainerResponses.SignedPhoto(photo.role(), photo.fileId(),
|
||||
PHOTO_DOWNLOAD_PATH.replace("{fileId}", photo.fileId())))
|
||||
CONTAINER_PHOTO_DOWNLOAD_PATH.replace("{containerNo}", session.getContainerNo())
|
||||
.replace("{fileId}", photo.fileId())))
|
||||
.toList();
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,17 @@ paths:
|
||||
application/octet-stream: { schema: { type: string, format: binary } }
|
||||
'403': { description: fileId 未绑定到当前操作员的当前柜会话三类签收照片 }
|
||||
'404': { description: 当前柜会话或照片不存在 }
|
||||
/api/pda/v1/last-leg/receiving-containers/{containerNo}/unload-photos/files/{fileId}/download:
|
||||
get:
|
||||
summary: 按柜号下载卸柜签收照片
|
||||
description: 权限 lastleg:pda:operate;按当前 PDA 绑定仓和柜号读取历史或当前柜的签收照片,不要求存在未完成接柜会话。
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- { name: containerNo, in: path, required: true, schema: { type: string } }
|
||||
- { name: fileId, in: path, required: true, schema: { type: string, pattern: '^[1-9][0-9]{0,18}$' } }
|
||||
responses:
|
||||
'200': { description: 签收照片字节流, content: { image/jpeg: { schema: { type: string, format: binary } }, image/png: { schema: { type: string, format: binary } } } }
|
||||
'404': { description: 当前仓没有该柜或照片不存在 }
|
||||
/api/pda/v1/last-leg/receiving-containers/current/domestic-loading-photos/{evidenceType}/content:
|
||||
get:
|
||||
summary: 查看当前柜国内装柜照片
|
||||
@@ -100,6 +111,17 @@ paths:
|
||||
application/octet-stream: { schema: { type: string, format: binary } }
|
||||
'404': { description: 当前柜或指定类型照片不存在 }
|
||||
'503': { description: 国内照片服务暂不可用 }
|
||||
/api/pda/v1/last-leg/receiving-containers/{containerNo}/domestic-loading-photos/{evidenceType}/content:
|
||||
get:
|
||||
summary: 按柜号查看国内装柜照片
|
||||
description: 权限 lastleg:pda:operate;按当前 PDA 绑定仓和柜号读取历史或当前柜的国内装柜照片,不要求存在未完成接柜会话。
|
||||
security: [{ bearerAuth: [] }]
|
||||
parameters:
|
||||
- { name: containerNo, in: path, required: true, schema: { type: string } }
|
||||
- { name: evidenceType, in: path, required: true, schema: { type: string, enum: [PHOTO_STEP_1, PHOTO_STEP_2, PHOTO_STEP_3, PHOTO_STEP_4, SEAL] } }
|
||||
responses:
|
||||
'200': { description: 国内装柜照片字节流, content: { image/jpeg: { schema: { type: string, format: binary } }, image/png: { schema: { type: string, format: binary } } } }
|
||||
'404': { description: 当前仓没有该柜或指定类型照片不存在 }
|
||||
/api/pda/v1/last-leg/receiving-containers/current/sign:
|
||||
post:
|
||||
summary: 签收当前柜
|
||||
|
||||
+2
@@ -140,6 +140,8 @@ class ReceivingContainerContractTest {
|
||||
assertTrue(yaml.contains(prefix + "/current/receipts/pallet:"));
|
||||
assertTrue(yaml.contains(prefix + "/current/complete:"));
|
||||
assertTrue(yaml.contains(prefix + "/current/unload-photos/files/{fileId}/download:"));
|
||||
assertTrue(yaml.contains(prefix + "/{containerNo}/unload-photos/files/{fileId}/download:"));
|
||||
assertTrue(yaml.contains(prefix + "/{containerNo}/domestic-loading-photos/{evidenceType}/content:"));
|
||||
assertFalse(yaml.contains("/api/pda/v1/last-leg/receiving-containers/{planNo}"));
|
||||
String receivingPaths = yaml.substring(yaml.indexOf(prefix), yaml.indexOf("/api/platform/v1/last-leg/orders:"));
|
||||
List<String> successResponses = receivingPaths.lines().map(String::trim)
|
||||
|
||||
Reference in New Issue
Block a user