This commit is contained in:
2026-08-14 12:50:37 +08:00
parent 91e781b3ff
commit ce6963a25e
46 changed files with 664 additions and 76 deletions
@@ -16,6 +16,8 @@ import com.baiyue.iam.service.MerchantOnboardingService;
import com.baiyue.iam.service.ProfileResourceService;
import com.baiyue.iam.service.TenantService;
import com.baiyue.iam.dto.CustomerExportDtos.CustomerExportBatch;
import com.baiyue.common.core.api.PageResult;
import com.baiyue.iam.dto.TenantDtos.FinanceCustomerSummary;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
@@ -106,6 +108,18 @@ public class InternalTenantController {
return ApiResponse.success(tenantService.orderEligibility(tenantId));
}
@GetMapping("/finance-customers")
public ApiResponse<PageResult<FinanceCustomerSummary>> financeCustomers(
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
@RequestParam(defaultValue = "1") @Min(1) long page,
@RequestParam(defaultValue = "20") @Min(1) @Max(200) long size,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) @Pattern(regexp = "ACTIVE|DISABLED") String status,
@RequestParam(required = false) Long customerId) {
verify(token);
return ApiResponse.success(tenantService.pageFinanceCustomers(page, size, keyword, status, customerId));
}
@GetMapping("/exports/customers")
public ApiResponse<CustomerExportBatch> exportCustomers(
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
@@ -49,7 +49,7 @@ public class PlatformTenantController {
@GetMapping("/tenants")
@PreAuthorize("hasAuthority('platform:customer:list')")
@Operation(summary = "查询企业列表", description = "平台端分页查询商户企业,支持企业名称、统一社会信用代码、联系人和状态筛选。")
@Operation(summary = "查询企业列表", description = "平台端分页查询商户企业,支持客户名称和状态筛选。客户编号、联系人等仅作展示信息,不作为搜索条件。")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "企业列表查询成功"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "400", description = "分页参数类型无效"),
@@ -124,4 +124,8 @@ public final class TenantDtos {
LocalDate establishedDate, BigDecimal registeredCapital,
String registeredCapitalCurrency, String registeredAddress,
String internalRemark, LocalDateTime createdAt, LocalDateTime approvedAt) { }
/** Full customer contact summary for trusted internal finance read models. */
public record FinanceCustomerSummary(Long id, String tenantCode, String tenantName, String status,
String contactName, String contactPhone) { }
}
@@ -44,14 +44,7 @@ public class CustomerListExportProviderRepository {
.eq(IamTenant::getTenantType, "MERCHANT")
.eq(StringUtils.hasText(status), IamTenant::getStatus, status);
if (StringUtils.hasText(keyword)) {
wrapper.and(condition -> condition
.like(IamTenant::getTenantCode, keyword)
.or().like(IamTenant::getTenantName, keyword)
.or().like(IamTenant::getLegalName, keyword)
.or().like(IamTenant::getUnifiedSocialCreditCode, keyword)
.or().like(IamTenant::getContactName, keyword)
.or().like(IamTenant::getContactPhone, keyword)
.or().like(IamTenant::getSalesOwnerName, keyword));
wrapper.like(IamTenant::getTenantName, keyword);
}
return wrapper;
}
@@ -91,15 +91,28 @@ public class TenantRepository {
.eq(IamTenant::getTenantType, "MERCHANT")
.eq(StringUtils.hasText(status), IamTenant::getStatus, status)
.orderByDesc(IamTenant::getCreatedAt);
if (StringUtils.hasText(keyword)) {
wrapper.like(IamTenant::getTenantName, keyword);
}
return PageResult.from(tenantMapper.selectPage(new Page<>(page, size), wrapper));
}
public PageResult<IamTenant> pageFinanceCustomers(long page, long size, String keyword, String status, Long customerId) {
LambdaQueryWrapper<IamTenant> wrapper = new LambdaQueryWrapper<IamTenant>()
.eq(IamTenant::getTenantType, "MERCHANT")
.eq(customerId != null, IamTenant::getId, customerId)
.in(!StringUtils.hasText(status), IamTenant::getStatus, List.of("ACTIVE", "DISABLED"))
.eq(StringUtils.hasText(status), IamTenant::getStatus, status)
.orderByDesc(IamTenant::getCreatedAt);
if (StringUtils.hasText(keyword)) {
wrapper.and(condition -> condition
.like(IamTenant::getTenantCode, keyword)
.or().like(IamTenant::getTenantName, keyword)
.or().like(IamTenant::getLegalName, keyword)
.or().like(IamTenant::getUnifiedSocialCreditCode, keyword)
.or().like(IamTenant::getContactName, keyword)
.or().like(IamTenant::getContactPhone, keyword)
.or().like(IamTenant::getSalesOwnerName, keyword));
.like(IamTenant::getTenantCode, keyword)
.or().like(IamTenant::getTenantName, keyword)
.or().like(IamTenant::getLegalName, keyword)
.or().like(IamTenant::getUnifiedSocialCreditCode, keyword)
.or().like(IamTenant::getContactName, keyword)
.or().like(IamTenant::getContactPhone, keyword)
.or().like(IamTenant::getSalesOwnerName, keyword));
}
return PageResult.from(tenantMapper.selectPage(new Page<>(page, size), wrapper));
}
@@ -21,6 +21,7 @@ import com.baiyue.iam.dto.OnboardingDtos.OrderEligibilityResponse;
import com.baiyue.iam.dto.TenantDtos.RegisterRequest;
import com.baiyue.iam.dto.TenantDtos.TenantResponse;
import com.baiyue.iam.dto.TenantDtos.FinanceCustomerSummary;
import com.baiyue.iam.dto.TenantDtos.UpdateProfileRequest;
import com.baiyue.iam.dto.TenantDtos.UpdateTenantRequest;
import com.baiyue.iam.dto.TenantDtos.ChangeTenantStatusRequest;
@@ -198,6 +199,14 @@ public class TenantService {
source.page(), source.size(), source.total(), source.pages());
}
public PageResult<FinanceCustomerSummary> pageFinanceCustomers(long page, long size, String keyword, String status, Long customerId) {
PageResult<IamTenant> source = repository.pageFinanceCustomers(page, size, keyword, status, customerId);
return new PageResult<>(source.records().stream().map(tenant -> new FinanceCustomerSummary(
tenant.getId(), tenant.getTenantCode(), tenant.getTenantName(), tenant.getStatus(),
tenant.getContactName(), tenant.getContactPhone())).toList(),
source.page(), source.size(), source.total(), source.pages());
}
public CustomerExportBatch exportMerchants(Long cursor, int limit, String keyword, String status) {
int boundedLimit = Math.min(Math.max(limit, 1), 500);
List<IamTenant> source = repository.exportMerchants(cursor, boundedLimit, keyword, status);
+44 -1
View File
@@ -44,7 +44,7 @@ paths:
parameters:
- {name: page, in: query, required: false, schema: {type: integer, minimum: 1, default: 1}}
- {name: size, in: query, required: false, schema: {type: integer, minimum: 1, maximum: 200, default: 20}}
- {name: keyword, in: query, required: false, schema: {type: string}, description: 企业编码、名称、信用代码或联系人关键字}
- {name: keyword, in: query, required: false, schema: {type: string}, description: 客户名称关键字,不支持客户编号、信用代码或联系人搜索}
- {name: status, in: query, required: false, schema: {type: string, enum: [PROFILE_REQUIRED, PENDING, ACTIVE, REJECTED, DISABLED]}}
responses:
'200':
@@ -740,6 +740,39 @@ paths:
application/json:
schema: {$ref: '#/components/schemas/RequiredQualificationPackageApiResponse'}
'403': {$ref: '#/components/responses/Forbidden'}
/internal/iam/finance-customers:
get:
tags: [IAM Resources / IAM 资源]
summary: 提供财务客户主数据摘要
description: 仅供 Finance Service 调用;只返回正常/停用客户及财务账户所需的客户编号、名称和联系方式,不依赖财务表是否已有记录。
security: []
parameters:
- {$ref: '#/components/parameters/InternalServiceToken'}
- {name: page, in: query, required: false, schema: {type: integer, minimum: 1, default: 1}}
- {name: size, in: query, required: false, schema: {type: integer, minimum: 1, maximum: 200, default: 20}}
- {name: keyword, in: query, required: false, schema: {type: string}}
- {name: status, in: query, required: false, schema: {type: string, enum: [ACTIVE, DISABLED]}}
- {name: customerId, in: query, required: false, schema: {type: integer, format: int64, minimum: 1}}
responses:
'200':
description: 财务客户主数据分页摘要
content:
application/json:
schema:
allOf:
- {$ref: '#/components/schemas/ApiResponse'}
- type: object
properties:
data:
type: object
required: [records, page, size, total, pages]
properties:
records: {type: array, items: {$ref: '#/components/schemas/FinanceCustomerSummary'}}
page: {type: integer}
size: {type: integer}
total: {type: integer, format: int64}
pages: {type: integer}
'403': {$ref: '#/components/responses/Forbidden'}
/internal/exports/v1/CUSTOMER_LIST/batches:
post:
tags: [Internal Export Provider]
@@ -971,6 +1004,16 @@ components:
internalRemark: {type: string, maxLength: 1000, description: 仅平台端可见}
createdAt: {type: string, format: date-time, description: 入驻时间}
approvedAt: {type: string, format: date-time, description: 审批通过时间}
FinanceCustomerSummary:
type: object
required: [id, tenantCode, tenantName, status]
properties:
id: {type: string, pattern: '^\d+$'}
tenantCode: {type: string}
tenantName: {type: string}
status: {type: string, enum: [ACTIVE, DISABLED]}
contactName: {type: string, nullable: true}
contactPhone: {type: string, nullable: true}
TenantAddressListApiResponse:
allOf:
- {$ref: '#/components/schemas/ApiResponse'}