Files
baiyue-firstleg/file/src/main/java/com/baiyue/file/controller/QualificationFileController.java
T

114 lines
6.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.baiyue.file.controller;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.common.security.AuthenticatedUser;
import com.baiyue.file.client.IamQualificationClient;
import com.baiyue.file.service.LocalQualificationStorage;
import com.baiyue.file.service.QualificationPackageService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
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 java.time.LocalDate;
@RestController
@RequestMapping("/api/merchant/v1/files/qualifications")
public class QualificationFileController {
private static final Logger LOGGER = LoggerFactory.getLogger(QualificationFileController.class);
@Resource private LocalQualificationStorage storage;
@Resource private IamQualificationClient iamClient;
@Resource private QualificationPackageService packageService;
@Value("${baiyue.security.internal-service-token}") private String internalToken;
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@PreAuthorize("hasAuthority('merchant:qualification:upload')")
public ApiResponse<UploadResponse> upload(
@AuthenticationPrincipal AuthenticatedUser user,
@RequestPart("file") MultipartFile file,
@RequestParam String qualificationType,
@RequestParam(value = "certificateNo", required = false) String certificateNo,
@RequestParam(required = false) LocalDate validTo,
@RequestParam(defaultValue = "false") boolean replace) {
long tenantId = merchantTenant(user);
qualificationType = QualificationTypes.requireSingleUpload(qualificationType);
var stored = storage.store(tenantId, file);
try {
var response = iamClient.submit(internalToken,
new IamQualificationClient.QualificationRequest(tenantId, qualificationType,
certificateNo, stored.documentUrl(), validTo, replace));
if (response == null) {
throw new IllegalStateException("IAM qualification response is empty");
}
if (!response.successful()) {
ResultCode code = ResultCode.of(response.code());
String message = response.message() == null || response.message().isBlank()
? code.message() : response.message();
storage.delete(stored);
throw new BizException(code, message);
}
if (response.data() == null) {
throw new IllegalStateException("IAM qualification response data is empty");
}
var data = response.data();
if (!stored.documentUrl().equals(data.replacedDocumentUrl())) {
storage.deleteByDocumentUrl(tenantId, data.replacedDocumentUrl());
}
return ApiResponse.success(new UploadResponse(data.qualificationId(), data.reviewId(),
data.tenantStatus(), stored.documentUrl()));
} catch (BizException exception) {
throw exception;
} catch (RuntimeException exception) {
LOGGER.error("IAM 资质登记结果未知,保留已写入文件等待重试或对账,tenantId={},documentUrl={}",
tenantId, stored.documentUrl(), exception);
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "IAM qualification service is unavailable");
}
}
@PostMapping(value = "/required-package", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@PreAuthorize("hasAuthority('merchant:qualification:upload')")
public ApiResponse<QualificationPackageService.PackageUploadResult> uploadRequiredPackage(
@AuthenticationPrincipal AuthenticatedUser user,
@RequestPart(value = "businessLicense", required = false) MultipartFile businessLicense,
@RequestPart(value = "legalPersonId", required = false) MultipartFile legalPersonId,
@RequestParam String unifiedSocialCreditCode,
@RequestParam(required = false) LocalDate businessLicenseValidTo,
@RequestParam(required = false) LocalDate legalPersonIdValidTo,
@RequestParam(defaultValue = "false") boolean replaceBusinessLicense,
@RequestParam(defaultValue = "false") boolean replaceLegalPersonId) {
return ApiResponse.success(packageService.upload(merchantTenant(user), businessLicense, legalPersonId,
unifiedSocialCreditCode, businessLicenseValidTo, legalPersonIdValidTo,
replaceBusinessLicense, replaceLegalPersonId, false));
}
@GetMapping("/{fileName}")
public ResponseEntity<org.springframework.core.io.Resource> download(
@AuthenticationPrincipal AuthenticatedUser user, @PathVariable String fileName) {
var resource = storage.load(merchantTenant(user), fileName);
String mediaType = fileName.endsWith(".png") ? MediaType.IMAGE_PNG_VALUE
: (fileName.endsWith(".pdf") ? MediaType.APPLICATION_PDF_VALUE : MediaType.IMAGE_JPEG_VALUE);
return ResponseEntity.ok().cacheControl(CacheControl.noStore())
.contentType(MediaType.parseMediaType(mediaType)).body(resource);
}
private long merchantTenant(AuthenticatedUser user) {
if (user == null || !"MERCHANT".equalsIgnoreCase(user.appCode())
|| user.tenantId() == null || user.tenantId() <= 0) {
throw new BizException(ResultCode.FORBIDDEN, "Merchant identity is required");
}
return user.tenantId();
}
public record UploadResponse(Long qualificationId, Long reviewId,
String tenantStatus, String documentUrl) { }
}