贴标申请,仓储转运
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
||||
package com.baiyue.lastleg.transfer.gateway;
|
||||
|
||||
import com.baiyue.lastleg.config.LastlegRestClientFactory;
|
||||
import com.baiyue.lastleg.config.LastlegRestClientProperties;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.client.MultipartBodyBuilder;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Component
|
||||
public class HttpTransferMeasurementPhotoFileGateway implements TransferMeasurementPhotoFileGateway {
|
||||
private static final String TYPE = "OVERSEAS_TRANSFER_MEASUREMENT_PHOTO";
|
||||
@Resource private RestClient.Builder restClientBuilder;
|
||||
@Resource private LastlegRestClientFactory restClientFactory;
|
||||
@Resource private LastlegRestClientProperties restClientProperties;
|
||||
@Value("${baiyue.clients.file.url:http://127.0.0.1:9206}") private String baseUrl;
|
||||
@Value("${baiyue.security.internal-service-token:}") private String internalToken;
|
||||
private RestClient client;
|
||||
|
||||
@PostConstruct void initializeClient() {
|
||||
client = restClientFactory.build(restClientBuilder, baseUrl, restClientProperties.getRelabelPhotoFile());
|
||||
}
|
||||
|
||||
@Override public UploadedFile upload(String customerId, long transferId, long operatorId, MultipartFile file) {
|
||||
MultipartBodyBuilder body = new MultipartBodyBuilder();
|
||||
try {
|
||||
body.part("file", new ByteArrayResource(file.getBytes()) {
|
||||
@Override public String getFilename() { return file.getOriginalFilename(); }
|
||||
}).contentType(file.getContentType() == null ? MediaType.APPLICATION_OCTET_STREAM
|
||||
: MediaType.parseMediaType(file.getContentType()));
|
||||
} catch (IOException exception) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Cannot read transfer measurement photo", exception);
|
||||
}
|
||||
MetadataEnvelope response = client.post().uri("/internal/file/v1/business-files/{tenant}/{type}/{business}",
|
||||
tenant(customerId), TYPE, transferId)
|
||||
.header("X-Internal-Service-Token", internalToken).header("X-Operator-Id", String.valueOf(operatorId))
|
||||
.contentType(MediaType.MULTIPART_FORM_DATA).body(body.build()).retrieve()
|
||||
.onStatus(HttpStatusCode::isError, (request, result) -> { throw failure(result.getStatusCode(), "Transfer measurement photo upload failed"); })
|
||||
.body(MetadataEnvelope.class);
|
||||
Metadata data = success(response, "Transfer measurement photo upload failed");
|
||||
return new UploadedFile(data.fileId(), data.fileName(), data.contentType(), data.sizeBytes() == null ? 0 : data.sizeBytes());
|
||||
}
|
||||
|
||||
@Override public void validate(String customerId, long transferId, long fileId) {
|
||||
long tenant = tenant(customerId);
|
||||
MetadataEnvelope response = client.get().uri("/internal/file/v1/business-files/{tenant}/{type}/{business}/{file}",
|
||||
tenant, TYPE, transferId, fileId).header("X-Internal-Service-Token", internalToken).retrieve()
|
||||
.onStatus(HttpStatusCode::isError, (request, result) -> { throw failure(result.getStatusCode(), "Transfer measurement photo ownership is invalid"); })
|
||||
.body(MetadataEnvelope.class);
|
||||
Metadata data = success(response, "Transfer measurement photo ownership is invalid");
|
||||
if (data.fileId() != fileId || data.tenantId() == null || data.tenantId() != tenant
|
||||
|| !TYPE.equals(data.businessType()) || !String.valueOf(transferId).equals(data.businessId())) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Transfer measurement photo ownership is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
@Override public DownloadedFile download(String customerId, long transferId, long fileId) {
|
||||
validate(customerId, transferId, fileId);
|
||||
ResponseEntity<byte[]> response = client.get().uri("/internal/file/v1/business-files/{tenant}/{type}/{business}/{file}/content",
|
||||
tenant(customerId), TYPE, transferId, fileId).header("X-Internal-Service-Token", internalToken).retrieve()
|
||||
.onStatus(HttpStatusCode::isError, (request, result) -> { throw failure(result.getStatusCode(), "Transfer measurement photo download failed"); })
|
||||
.toEntity(byte[].class);
|
||||
String name = response.getHeaders().getContentDisposition().getFilename();
|
||||
String type = response.getHeaders().getContentType() == null ? MediaType.APPLICATION_OCTET_STREAM_VALUE
|
||||
: response.getHeaders().getContentType().toString();
|
||||
return new DownloadedFile(response.getBody() == null ? new byte[0] : response.getBody(),
|
||||
name == null ? "transfer-measurement-photo" : name, type);
|
||||
}
|
||||
|
||||
private static long tenant(String value) {
|
||||
try { return Long.parseLong(value); }
|
||||
catch (NumberFormatException exception) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Customer ID must be numeric", exception); }
|
||||
}
|
||||
private static Metadata success(MetadataEnvelope response, String fallback) {
|
||||
if (response == null) throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, fallback);
|
||||
if (!"200".equals(response.code())) {
|
||||
HttpStatus status = switch (String.valueOf(response.code())) {
|
||||
case "A0400", "A0422" -> HttpStatus.BAD_REQUEST;
|
||||
case "A0403" -> HttpStatus.FORBIDDEN;
|
||||
case "A0404" -> HttpStatus.NOT_FOUND;
|
||||
default -> HttpStatus.SERVICE_UNAVAILABLE;
|
||||
};
|
||||
throw new ResponseStatusException(status,
|
||||
response.message() == null || response.message().isBlank() ? fallback : response.message());
|
||||
}
|
||||
if (response.data() == null || response.data().fileId() == null) {
|
||||
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE,
|
||||
"File service returned no transfer measurement photo metadata");
|
||||
}
|
||||
return response.data();
|
||||
}
|
||||
private static ResponseStatusException failure(HttpStatusCode status, String message) {
|
||||
return new ResponseStatusException(status.is4xxClientError() ? HttpStatus.BAD_REQUEST : HttpStatus.SERVICE_UNAVAILABLE, message);
|
||||
}
|
||||
private record MetadataEnvelope(String code, String message, Metadata data) {}
|
||||
private record Metadata(Long fileId, Long tenantId, String businessType, String businessId,
|
||||
String fileName, String contentType, Long sizeBytes) {}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baiyue.lastleg.transfer.gateway;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface TransferMeasurementPhotoFileGateway {
|
||||
UploadedFile upload(String customerId, long transferId, long operatorId, MultipartFile file);
|
||||
void validate(String customerId, long transferId, long fileId);
|
||||
DownloadedFile download(String customerId, long transferId, long fileId);
|
||||
|
||||
record UploadedFile(long fileId, String fileName, String contentType, long sizeBytes) {}
|
||||
record DownloadedFile(byte[] content, String fileName, String contentType) {}
|
||||
}
|
||||
Reference in New Issue
Block a user