提交代码
This commit is contained in:
@@ -9,6 +9,7 @@ import com.baiyue.iam.dto.OnboardingDtos.OrderEligibilityResponse;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.QualificationSubmissionRequest;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.QualificationSubmissionResponse;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.PlatformQualificationRegistrationRequest;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.PlatformQualificationRegistrationResponse;
|
||||
import com.baiyue.iam.service.MerchantOnboardingService;
|
||||
import com.baiyue.iam.service.ProfileResourceService;
|
||||
import com.baiyue.iam.service.TenantService;
|
||||
@@ -50,7 +51,7 @@ public class InternalTenantController {
|
||||
}
|
||||
|
||||
@PostMapping("/platform-qualifications")
|
||||
public ApiResponse<QualificationSubmissionResponse> registerPlatformQualification(
|
||||
public ApiResponse<PlatformQualificationRegistrationResponse> registerPlatformQualification(
|
||||
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
|
||||
@Valid @RequestBody PlatformQualificationRegistrationRequest request) {
|
||||
verify(token);
|
||||
|
||||
@@ -36,7 +36,15 @@ public final class OnboardingDtos {
|
||||
@NotBlank @Pattern(regexp = "BUSINESS_LICENSE|LEGAL_PERSON_ID|FREIGHT_FORWARDER_CERTIFICATE|BANK_ACCOUNT_LICENSE") String qualificationType,
|
||||
String certificateNo,
|
||||
@NotBlank String documentUrl,
|
||||
LocalDate validTo
|
||||
LocalDate validTo,
|
||||
boolean replace
|
||||
) { }
|
||||
|
||||
public record PlatformQualificationRegistrationResponse(
|
||||
Long qualificationId,
|
||||
Long reviewId,
|
||||
String tenantStatus,
|
||||
String replacedDocumentUrl
|
||||
) { }
|
||||
|
||||
public record OrderEligibilityResponse(boolean eligible, String tenantStatus, String reason) { }
|
||||
|
||||
@@ -34,6 +34,12 @@ public class ProfileResourceRepository {
|
||||
public void saveQualification(IamTenantQualification qualification) { qualificationMapper.updateById(qualification); }
|
||||
public List<IamTenantAddress> findAddresses(long tenantId) { return addressMapper.selectList(new LambdaQueryWrapper<IamTenantAddress>().eq(IamTenantAddress::getTenantId, tenantId)); }
|
||||
public List<IamTenantQualification> findQualifications(long tenantId) { return qualificationMapper.selectList(new LambdaQueryWrapper<IamTenantQualification>().eq(IamTenantQualification::getTenantId, tenantId)); }
|
||||
public List<IamTenantQualification> findQualificationsForUpdate(long tenantId) {
|
||||
return qualificationMapper.selectList(new LambdaQueryWrapper<IamTenantQualification>()
|
||||
.eq(IamTenantQualification::getTenantId, tenantId)
|
||||
.orderByAsc(IamTenantQualification::getId)
|
||||
.last("FOR UPDATE"));
|
||||
}
|
||||
public long countApprovedQualifications(long tenantId) {
|
||||
return qualificationMapper.selectCount(new LambdaQueryWrapper<IamTenantQualification>()
|
||||
.eq(IamTenantQualification::getTenantId, tenantId)
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.QualificationSubmissionRequest;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.QualificationSubmissionResponse;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.PlatformQualificationRegistrationRequest;
|
||||
import com.baiyue.iam.dto.OnboardingDtos.PlatformQualificationRegistrationResponse;
|
||||
import com.baiyue.iam.dto.ProfileDtos.AddressRequest;
|
||||
import com.baiyue.iam.entity.IamTenant;
|
||||
import com.baiyue.iam.entity.IamTenantAddress;
|
||||
@@ -92,7 +93,7 @@ public class ProfileResourceService {
|
||||
@Transactional
|
||||
@BusinessAudit(event = "PLATFORM_TENANT_QUALIFICATION_UPLOAD", resourceType = "TENANT_QUALIFICATION",
|
||||
resourceId = "#request.tenantId", description = "平台代客户上传资质", captureAfter = false)
|
||||
public QualificationSubmissionResponse registerPlatformQualification(PlatformQualificationRegistrationRequest request) {
|
||||
public PlatformQualificationRegistrationResponse registerPlatformQualification(PlatformQualificationRegistrationRequest request) {
|
||||
IamTenant tenant = tenantRepository.findTenant(request.tenantId());
|
||||
if (tenant == null || !"MERCHANT".equals(tenant.getTenantType())) {
|
||||
throw new BizException(ResultCode.NOT_FOUND, "Enterprise not found / 企业客户不存在");
|
||||
@@ -100,15 +101,26 @@ public class ProfileResourceService {
|
||||
if (!"PROFILE_REQUIRED".equals(tenant.getStatus()) && !"REJECTED".equals(tenant.getStatus())) {
|
||||
throw new BizException(ResultCode.CONFLICT, "Qualifications can only be uploaded before review / 仅待完善或已驳回客户可上传资质");
|
||||
}
|
||||
if (repository.findQualifications(tenant.getId()).stream().anyMatch(item ->
|
||||
request.qualificationType().equals(item.getQualificationType()) && !"REJECTED".equals(item.getStatus()))) {
|
||||
IamTenantQualification existing = repository.findQualificationsForUpdate(tenant.getId()).stream()
|
||||
.filter(item -> request.qualificationType().equals(item.getQualificationType())
|
||||
&& !"REJECTED".equals(item.getStatus()))
|
||||
.findFirst().orElse(null);
|
||||
if (existing != null && !request.replace()) {
|
||||
throw new BizException(ResultCode.CONFLICT, "Qualification type already uploaded / 该类资质已上传");
|
||||
}
|
||||
String replacedDocumentUrl = null;
|
||||
if (existing != null) {
|
||||
replacedDocumentUrl = existing.getDocumentUrl();
|
||||
existing.setStatus("REJECTED");
|
||||
existing.setReviewComment("平台在送审前替换文件");
|
||||
repository.saveQualification(existing);
|
||||
}
|
||||
IamTenantQualification qualification = createQualification(tenant.getId(), request.qualificationType(),
|
||||
request.certificateNo(), request.documentUrl());
|
||||
qualification.setValidTo(request.validTo());
|
||||
repository.saveQualification(qualification);
|
||||
return new QualificationSubmissionResponse(qualification.getId(), null, tenant.getStatus());
|
||||
return new PlatformQualificationRegistrationResponse(
|
||||
qualification.getId(), null, tenant.getStatus(), replacedDocumentUrl);
|
||||
}
|
||||
|
||||
private IamTenantQualification createQualification(long tenant, String type, String certificateNo, String url) {
|
||||
|
||||
+32
-2
@@ -15,6 +15,7 @@ import java.util.List;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -29,11 +30,11 @@ class PlatformQualificationRegistrationTest {
|
||||
IamTenant tenant = new IamTenant();
|
||||
tenant.setId(10001L); tenant.setTenantType("MERCHANT"); tenant.setStatus("PROFILE_REQUIRED");
|
||||
when(tenantRepository.findTenant(10001L)).thenReturn(tenant);
|
||||
when(repository.findQualifications(10001L)).thenReturn(List.of());
|
||||
when(repository.findQualificationsForUpdate(10001L)).thenReturn(List.of());
|
||||
|
||||
var response = service.registerPlatformQualification(new PlatformQualificationRegistrationRequest(
|
||||
10001L, "LEGAL_PERSON_ID", null, "/api/merchant/v1/files/qualifications/file.pdf",
|
||||
LocalDate.of(2030, 12, 31)));
|
||||
LocalDate.of(2030, 12, 31), false));
|
||||
|
||||
ArgumentCaptor<IamTenantQualification> captor = ArgumentCaptor.forClass(IamTenantQualification.class);
|
||||
verify(repository).insertQualification(captor.capture());
|
||||
@@ -42,5 +43,34 @@ class PlatformQualificationRegistrationTest {
|
||||
assertEquals(LocalDate.of(2030, 12, 31), captor.getValue().getValidTo());
|
||||
assertEquals("PROFILE_REQUIRED", response.tenantStatus());
|
||||
assertNull(response.reviewId());
|
||||
assertNull(response.replacedDocumentUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformCanReplaceAnUploadedQualificationBeforeReview() {
|
||||
ProfileResourceRepository repository = mock(ProfileResourceRepository.class);
|
||||
TenantRepository tenantRepository = mock(TenantRepository.class);
|
||||
ProfileResourceService service = new ProfileResourceService();
|
||||
ReflectionTestUtils.setField(service, "repository", repository);
|
||||
ReflectionTestUtils.setField(service, "tenantRepository", tenantRepository);
|
||||
IamTenant tenant = new IamTenant();
|
||||
tenant.setId(10001L); tenant.setTenantType("MERCHANT"); tenant.setStatus("PROFILE_REQUIRED");
|
||||
IamTenantQualification existing = new IamTenantQualification();
|
||||
existing.setId(88L); existing.setTenantId(10001L); existing.setQualificationType("LEGAL_PERSON_ID");
|
||||
existing.setStatus("PENDING");
|
||||
existing.setDocumentUrl("/api/merchant/v1/files/qualifications/old-file.pdf");
|
||||
when(tenantRepository.findTenant(10001L)).thenReturn(tenant);
|
||||
when(repository.findQualificationsForUpdate(10001L)).thenReturn(List.of(existing));
|
||||
|
||||
var response = service.registerPlatformQualification(new PlatformQualificationRegistrationRequest(
|
||||
10001L, "LEGAL_PERSON_ID", null, "/api/merchant/v1/files/qualifications/new-file.pdf",
|
||||
LocalDate.of(2031, 12, 31), true));
|
||||
|
||||
ArgumentCaptor<IamTenantQualification> captor = ArgumentCaptor.forClass(IamTenantQualification.class);
|
||||
verify(repository, times(2)).saveQualification(captor.capture());
|
||||
assertEquals("REJECTED", existing.getStatus());
|
||||
assertEquals("平台在送审前替换文件", existing.getReviewComment());
|
||||
assertEquals(existing.getDocumentUrl(), response.replacedDocumentUrl());
|
||||
assertEquals("PENDING", captor.getAllValues().get(1).getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user