优化
This commit is contained in:
+29
@@ -14,6 +14,11 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.http.ContentDisposition;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.MediaType;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
@RestController
|
||||
@@ -55,6 +60,29 @@ public class RelabelApplicationController {
|
||||
requirePlatform(user);
|
||||
return ApiResponse.success(service.changeStatus(null, relabelNo, operator(user), request));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{relabelNo}/files", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@PreAuthorize("hasAuthority('" + OverseasPermissions.RELABEL_ORDER_CREATE + "')")
|
||||
public ApiResponse<RelabelResponses.Detail> uploadFile(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable String relabelNo, @RequestParam String scope, @RequestParam(required = false) Long itemId,
|
||||
@RequestPart("file") MultipartFile file) {
|
||||
requirePlatform(user);
|
||||
String customerId = service.customerId(relabelNo);
|
||||
return ApiResponse.success("ITEM".equalsIgnoreCase(scope)
|
||||
? service.uploadItemFile(customerId, relabelNo, itemId == null ? 0L : itemId, operatorLong(user), file)
|
||||
: service.uploadTotalFile(customerId, relabelNo, operatorLong(user), file));
|
||||
}
|
||||
|
||||
@GetMapping("/{relabelNo}/files/{fileId}/download")
|
||||
@PreAuthorize("hasAuthority('" + OverseasPermissions.RELABEL_ORDER_LIST + "')")
|
||||
public ResponseEntity<byte[]> downloadFile(@AuthenticationPrincipal AuthenticatedUser user,
|
||||
@PathVariable String relabelNo, @PathVariable long fileId, @RequestParam String scope,
|
||||
@RequestParam(required = false) Long itemId) {
|
||||
requirePlatform(user);
|
||||
var file = service.downloadFile(service.customerId(relabelNo), relabelNo, scope, itemId, fileId);
|
||||
return ResponseEntity.ok().header("Content-Disposition", ContentDisposition.inline().filename(file.fileName(), StandardCharsets.UTF_8).build().toString())
|
||||
.contentType(org.springframework.http.MediaType.parseMediaType(file.contentType())).contentLength(file.content().length).body(file.content());
|
||||
}
|
||||
private void requirePlatform(AuthenticatedUser user) {
|
||||
if (user == null || user.tenantId() == null) throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||
if (!"PLATFORM".equals(user.appCode()) || user.tenantId() != 0L) {
|
||||
@@ -69,4 +97,5 @@ public class RelabelApplicationController {
|
||||
return value;
|
||||
}
|
||||
private String operator(AuthenticatedUser user) { return user.userId() == null ? user.username() : String.valueOf(user.userId()); }
|
||||
private long operatorLong(AuthenticatedUser user) { return user.userId() == null ? 0L : user.userId(); }
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public final class RelabelResponses {
|
||||
String customerOrderNo, String overseasWarehouseId, LocalDateTime labelDeadline,
|
||||
String contactName, String contactPhone, String status, int itemCount,
|
||||
int totalPackageCount, int notifiedPackageCount, String skuCodes,
|
||||
String totalFileId, String totalFileName, String totalFileUrl,
|
||||
BigDecimal chargeAmount, String chargeCurrency, String walletStatus,
|
||||
String walletErrorMessage,
|
||||
LocalDateTime createdAt) {}
|
||||
|
||||
+3
@@ -21,6 +21,9 @@ public class RelabelApplication {
|
||||
private String contactName;
|
||||
private String contactPhone;
|
||||
private String remark;
|
||||
private String totalFileId;
|
||||
private String totalFileName;
|
||||
private String totalFileUrl;
|
||||
private String status;
|
||||
private Integer itemCount;
|
||||
private Integer totalPackageCount;
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.baiyue.lastleg.relabel.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 HttpRelabelDocumentFileGateway implements RelabelDocumentFileGateway {
|
||||
@Resource private RestClient.Builder restClientBuilder;
|
||||
@Resource private LastlegRestClientFactory restClientFactory;
|
||||
@Resource private LastlegRestClientProperties restClientProperties;
|
||||
@Value("${baiyue.clients.file.url:http://127.0.0.1:9205}") 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, String businessType, String businessId, 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_PDF : MediaType.parseMediaType(file.getContentType())); }
|
||||
catch (IOException e) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "无法读取换标PDF", e); }
|
||||
MetadataEnvelope response = client.post().uri("/internal/file/v1/business-files/{tenantId}/{businessType}/{businessId}", tenantId(customerId), businessType, businessId)
|
||||
.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 new ResponseStatusException(HttpStatus.BAD_REQUEST, "换标PDF上传失败"); })
|
||||
.body(MetadataEnvelope.class);
|
||||
requireSuccess(response, "换标PDF上传失败"); Metadata data = response == null ? null : response.data();
|
||||
if (data == null || data.fileId() == null) throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "文件服务未返回换标PDF信息");
|
||||
return new UploadedFile(data.fileId(), data.fileName(), data.contentType(), data.sizeBytes() == null ? 0 : data.sizeBytes());
|
||||
}
|
||||
|
||||
@Override public DownloadedFile download(String customerId, String businessType, String businessId, long fileId) {
|
||||
ResponseEntity<byte[]> response = client.get().uri("/internal/file/v1/business-files/{tenantId}/{businessType}/{businessId}/{fileId}/content", tenantId(customerId), businessType, businessId, fileId)
|
||||
.header("X-Internal-Service-Token", internalToken).retrieve().onStatus(HttpStatusCode::isError, (request, result) -> {
|
||||
throw new ResponseStatusException(result.getStatusCode().is4xxClientError() ? HttpStatus.NOT_FOUND : HttpStatus.SERVICE_UNAVAILABLE, "换标PDF读取失败");
|
||||
}).toEntity(byte[].class);
|
||||
String name = response.getHeaders().getContentDisposition().getFilename();
|
||||
return new DownloadedFile(response.getBody() == null ? new byte[0] : response.getBody(), name == null ? fileId + ".pdf" : name,
|
||||
response.getHeaders().getContentType() == null ? MediaType.APPLICATION_PDF_VALUE : response.getHeaders().getContentType().toString());
|
||||
}
|
||||
|
||||
private long tenantId(String value) { try { return Long.parseLong(value); } catch (NumberFormatException e) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "客户ID格式无效", e); } }
|
||||
private static void requireSuccess(MetadataEnvelope response, String message) { if (response == null || !"200".equals(response.code())) throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, message); }
|
||||
private record MetadataEnvelope(String code, String message, Metadata data) { }
|
||||
private record Metadata(Long fileId, String fileName, String contentType, Long sizeBytes) { }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.baiyue.lastleg.relabel.gateway;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public interface RelabelDocumentFileGateway {
|
||||
UploadedFile upload(String customerId, String businessType, String businessId, long operatorId, MultipartFile file);
|
||||
DownloadedFile download(String customerId, String businessType, String businessId, long fileId);
|
||||
|
||||
record UploadedFile(long fileId, String fileName, String contentType, long sizeBytes) { }
|
||||
record DownloadedFile(byte[] content, String fileName, String contentType) { }
|
||||
}
|
||||
+10
@@ -366,6 +366,16 @@ public class RelabelApplicationService implements WalletResultHandler {
|
||||
private LastlegOrder insertTailOrder(String customerId, RelabelRequests.Create request, String requestHash,
|
||||
String relabelNo, String warehouseId, int packageCount,
|
||||
LocalDateTime now) {
|
||||
String customerOrderNo = request.customerOrderNo().trim();
|
||||
LastlegOrder existingReturn = orders.selectOne(new LambdaQueryWrapper<LastlegOrder>()
|
||||
.eq(LastlegOrder::getCustomerId, customerId).eq(LastlegOrder::getOrderType, "RETURN_RELABEL")
|
||||
.and(w -> w.eq(LastlegOrder::getSourceOrderNo, customerOrderNo).or().eq(LastlegOrder::getOrderNo, customerOrderNo))
|
||||
.last("LIMIT 1"));
|
||||
if (existingReturn != null) {
|
||||
existingReturn.setRelabelOrderNo(relabelNo); existingReturn.setRelabelStatus(PENDING_PROCESSING);
|
||||
existingReturn.setSubOrderStatus("RETURN_RELABEL:" + PENDING_PROCESSING); existingReturn.setPackageCount(packageCount);
|
||||
existingReturn.setUpdatedAt(now); orders.updateById(existingReturn); return existingReturn;
|
||||
}
|
||||
LastlegOrder order = new LastlegOrder();
|
||||
order.setId(IdWorker.getId());
|
||||
order.setOrderNo(orderNoGenerator.next("RELABEL", warehouseId, order.getId()));
|
||||
|
||||
Reference in New Issue
Block a user