优化
This commit is contained in:
@@ -22,7 +22,7 @@ public interface IamOnboardingClient {
|
||||
@PathVariable("authUserId") Long authUserId);
|
||||
|
||||
record OnboardingRequest(Long authUserId, String displayName, String companyName,
|
||||
String legalPerson, String legalPhone, String contactEmail,
|
||||
String legalPerson, String administratorPhone, String contactEmail,
|
||||
String countryCode, String address) { }
|
||||
|
||||
record OnboardingResponse(Long tenantId, Long membershipId, String tenantStatus,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.baiyue.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Email;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(name = "MerchantRegisterRequest", description = "Phase-one merchant account registration")
|
||||
public record MerchantRegisterRequest(
|
||||
@@ -13,7 +13,8 @@ public record MerchantRegisterRequest(
|
||||
@NotBlank @Size(max = 64) String displayName,
|
||||
@NotBlank @Size(max = 128) String companyName,
|
||||
@NotBlank @Size(max = 64) String legalPerson,
|
||||
@NotBlank @Pattern(regexp = "^1[3-9]\\d{9}$") String legalPhone,
|
||||
@Schema(description = "首个企业管理员的登录手机号;注册时同时初始化企业联系电话,创建后两者独立维护")
|
||||
@NotBlank @Pattern(regexp = "^1[3-9]\\d{9}$") String phone,
|
||||
@Email @Size(max = 128) String contactEmail,
|
||||
@Size(min = 2, max = 2) String countryCode,
|
||||
@Size(max = 255) String address
|
||||
|
||||
@@ -38,7 +38,7 @@ public class MerchantRegistrationService {
|
||||
if (accountRepository.existsByUsername(request.username())) {
|
||||
throw new BizException(ResultCode.CONFLICT, "用户名已存在");
|
||||
}
|
||||
if (accountRepository.existsByPhone(request.legalPhone())) {
|
||||
if (accountRepository.existsByPhone(request.phone())) {
|
||||
throw new BizException(ResultCode.CONFLICT, "手机号已存在");
|
||||
}
|
||||
long accountId = IdWorker.getId();
|
||||
@@ -49,7 +49,7 @@ public class MerchantRegistrationService {
|
||||
try {
|
||||
var response = onboardingClient.register(internalToken,
|
||||
new IamOnboardingClient.OnboardingRequest(accountId, request.displayName(),
|
||||
request.companyName(), request.legalPerson(), request.legalPhone(),
|
||||
request.companyName(), request.legalPerson(), request.phone(),
|
||||
request.contactEmail(), request.countryCode(), request.address()));
|
||||
if (response == null) {
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "IAM registration failed");
|
||||
@@ -84,7 +84,7 @@ public class MerchantRegistrationService {
|
||||
AuthAccount account = new AuthAccount();
|
||||
account.setId(accountId);
|
||||
account.setUsername(request.username());
|
||||
account.setPhone(request.legalPhone());
|
||||
account.setPhone(request.phone());
|
||||
account.setPasswordHash(passwordHash);
|
||||
account.setDisplayName(request.displayName());
|
||||
account.setAccountStatus("ACTIVE");
|
||||
|
||||
@@ -96,15 +96,15 @@ public class PlatformTenantController {
|
||||
return ApiResponse.success(service.dimensionInitializationStatus(tenantId));
|
||||
}
|
||||
|
||||
@GetMapping("/tenants/contact-phone-availability")
|
||||
@PreAuthorize("hasAnyAuthority('platform:customer:create','platform:customer:edit')")
|
||||
@Operation(summary = "校验客户联系电话唯一性")
|
||||
public ApiResponse<Boolean> contactPhoneAvailability(
|
||||
@RequestParam String contactPhone,
|
||||
@RequestParam(required = false) Long excludeTenantId,
|
||||
@GetMapping("/tenants/administrator-phone-availability")
|
||||
@PreAuthorize("hasAuthority('platform:customer:create')")
|
||||
@Operation(summary = "校验首个管理员登录手机号唯一性",
|
||||
description = "仅用于创建客户前校验 Auth 登录手机号;企业联系电话本身不要求唯一。")
|
||||
public ApiResponse<Boolean> administratorPhoneAvailability(
|
||||
@RequestParam @Pattern(regexp = "^1[3-9]\\d{9}$") String phone,
|
||||
@AuthenticationPrincipal AuthenticatedUser user) {
|
||||
TenantGuard.tenant(user, "PLATFORM");
|
||||
return ApiResponse.success(service.contactPhoneAndUsernameAvailable(contactPhone, excludeTenantId));
|
||||
return ApiResponse.success(service.administratorPhoneAvailable(phone));
|
||||
}
|
||||
|
||||
@GetMapping("/tenants/{tenantId:\\d+}/members")
|
||||
|
||||
@@ -14,7 +14,7 @@ public final class OnboardingDtos {
|
||||
@NotBlank String displayName,
|
||||
@NotBlank String companyName,
|
||||
@NotBlank String legalPerson,
|
||||
@NotBlank String legalPhone,
|
||||
@NotBlank @Pattern(regexp = "^1[3-9]\\d{9}$") String administratorPhone,
|
||||
String contactEmail,
|
||||
String countryCode,
|
||||
String address
|
||||
|
||||
@@ -27,8 +27,8 @@ public final class TenantDtos {
|
||||
@Schema(description = "Legal entity name / 企业法定名称", example = "深圳虫虫出海科技有限公司") @NotBlank String legalName,
|
||||
@Schema(description = "Legal representative / 法定代表人", example = "张三") @NotBlank @Size(max = 64) String legalRepresentative,
|
||||
@Schema(description = "Primary contact / 联系人", example = "张三") @NotBlank String contactName,
|
||||
@Schema(description = "Contact phone and administrator username / 联系电话及管理员用户名", example = "13800138000")
|
||||
@NotBlank @Pattern(regexp = "[0-9-]{4,32}") String contactPhone,
|
||||
@Schema(description = "Company contact phone; also initializes the first administrator login phone at creation, then maintained independently / 公司联系电话;创建时同时初始化首个管理员登录手机号,之后独立维护", example = "13800138000")
|
||||
@NotBlank @Pattern(regexp = "^1[3-9]\\d{9}$") String contactPhone,
|
||||
@Schema(description = "Contact email / 联系邮箱", example = "ops@example.com") @Email String contactEmail,
|
||||
@NotBlank @Size(max = 64) String servicePackage,
|
||||
@Size(max = 64) String contactWechat,
|
||||
@@ -48,7 +48,8 @@ public final class TenantDtos {
|
||||
@Schema(description = "Legal entity name / 企业法定名称", example = "深圳虫虫出海科技有限公司") @NotBlank String legalName,
|
||||
@Schema(description = "Legal representative / 法定代表人", example = "张三") @NotBlank @Size(max = 64) String legalRepresentative,
|
||||
@Schema(description = "Primary contact / 联系人", example = "李四") @NotBlank String contactName,
|
||||
@Schema(description = "Contact phone / 联系电话", example = "13900139000") @NotBlank String contactPhone,
|
||||
@Schema(description = "Company contact phone, never used to resolve login identity / 公司联系电话,不作为登录标识", example = "0755-12345678")
|
||||
@NotBlank @Pattern(regexp = "[0-9-]{4,32}") String contactPhone,
|
||||
@Schema(description = "Contact email / 联系邮箱", example = "service@example.com") @Email String contactEmail
|
||||
) { }
|
||||
|
||||
@@ -59,6 +60,7 @@ public final class TenantDtos {
|
||||
@NotBlank String legalName,
|
||||
@NotBlank @Size(max = 64) String legalRepresentative,
|
||||
@NotBlank String contactName,
|
||||
@Schema(description = "Company contact phone, independent from every member login phone / 公司联系电话,与所有成员登录手机号独立")
|
||||
@NotBlank @Pattern(regexp = "[0-9-]{4,32}") String contactPhone,
|
||||
@Email String contactEmail,
|
||||
@NotBlank @Size(max = 64) String servicePackage,
|
||||
@@ -120,14 +122,14 @@ public final class TenantDtos {
|
||||
public record ApprovalResponse(
|
||||
@Schema(description = "Tenant ID / 企业租户 ID", example = "190000000000000001") Long tenantId,
|
||||
@Schema(description = "Whether this approval created the administrator / 本次审核是否新建管理员") boolean administratorCreated,
|
||||
@Schema(description = "Contact phone used as login username; null when an owner already exists / 使用联系电话作为登录账号,已有所有者时为空", nullable = true) String administratorUsername,
|
||||
@Schema(description = "Generated first-administrator username; independent from company contact phone / 自动生成的首个管理员用户名,与公司联系电话独立", nullable = true) String administratorUsername,
|
||||
@Schema(description = "One-time temporary password; only returned when created / 一次性初始密码,仅新建时返回", format = "password", nullable = true) String temporaryPassword
|
||||
) { }
|
||||
|
||||
@Schema(name = "TenantCreationResponse", description = "Created enterprise draft and one-time administrator credentials / 新建企业草稿及一次性管理员凭据")
|
||||
public record CreationResponse(
|
||||
@Schema(description = "Created enterprise draft / 新建企业草稿") TenantResponse tenant,
|
||||
@Schema(description = "Contact phone used as login username / 使用联系电话作为登录账号") String administratorUsername,
|
||||
@Schema(description = "Generated administrator username, independent from company contact phone / 自动生成的管理员用户名,与公司联系电话独立") String administratorUsername,
|
||||
@Schema(description = "One-time temporary password / 一次性初始密码", format = "password") String temporaryPassword
|
||||
) { }
|
||||
|
||||
|
||||
@@ -35,19 +35,6 @@ public class TenantRepository {
|
||||
.ne(IamTenant::getId, tenantId)) > 0;
|
||||
}
|
||||
|
||||
public boolean existsByContactPhone(String contactPhone) {
|
||||
return tenantMapper.selectCount(new LambdaQueryWrapper<IamTenant>()
|
||||
.eq(IamTenant::getTenantType, "MERCHANT")
|
||||
.eq(IamTenant::getContactPhone, contactPhone)) > 0;
|
||||
}
|
||||
|
||||
public boolean existsByContactPhoneForOtherTenant(String contactPhone, long tenantId) {
|
||||
return tenantMapper.selectCount(new LambdaQueryWrapper<IamTenant>()
|
||||
.eq(IamTenant::getTenantType, "MERCHANT")
|
||||
.eq(IamTenant::getContactPhone, contactPhone)
|
||||
.ne(IamTenant::getId, tenantId)) > 0;
|
||||
}
|
||||
|
||||
public IamTenant findTenant(Long tenantId) { return tenantMapper.selectById(tenantId); }
|
||||
public List<IamTenant> findMerchantsByIds(Collection<Long> tenantIds) {
|
||||
if (tenantIds == null || tenantIds.isEmpty()) return List.of();
|
||||
|
||||
@@ -74,7 +74,7 @@ public class MerchantOnboardingService {
|
||||
tenant.setLegalName(request.companyName());
|
||||
tenant.setLegalRepresentative(request.legalPerson());
|
||||
tenant.setContactName(request.displayName());
|
||||
tenant.setContactPhone(request.legalPhone());
|
||||
tenant.setContactPhone(request.administratorPhone());
|
||||
tenant.setContactEmail(request.contactEmail());
|
||||
tenant.setDeleted(false);
|
||||
tenant.setVersion(0);
|
||||
@@ -86,7 +86,7 @@ public class MerchantOnboardingService {
|
||||
user.setAuthUserId(request.authUserId());
|
||||
user.setUserType("ENTERPRISE");
|
||||
user.setDisplayName(request.displayName());
|
||||
user.setPhone(request.legalPhone());
|
||||
user.setPhone(request.administratorPhone());
|
||||
user.setEmail(request.contactEmail());
|
||||
user.setStatus("ACTIVE");
|
||||
userMapper.insert(user);
|
||||
|
||||
+13
-17
@@ -88,7 +88,8 @@ public class TenantAdministratorProvisioningService implements TenantApprovalIni
|
||||
long userId = IdWorker.getId();
|
||||
long membershipId = IdWorker.getId();
|
||||
String password = temporaryPassword();
|
||||
String username = createAuthAccountWithUniqueUsername(authUserId, password, tenant, membershipId);
|
||||
String username = createAuthAccount(authUserId, password, tenant, membershipId,
|
||||
tenant.getContactPhone(), tenant.getContactName());
|
||||
ProvisioningResult result = ProvisioningResult.created(authUserId, username, password);
|
||||
|
||||
try {
|
||||
@@ -153,8 +154,8 @@ public class TenantAdministratorProvisioningService implements TenantApprovalIni
|
||||
AuthAccountClient.AccountSummary account = findAuthAccount(user.getAuthUserId());
|
||||
if (account == null) {
|
||||
String password = temporaryPassword();
|
||||
String username = createAuthAccountWithUniqueUsername(user.getAuthUserId(), password,
|
||||
tenant, owner.getId());
|
||||
String username = createAuthAccount(user.getAuthUserId(), password, tenant, owner.getId(),
|
||||
user.getPhone(), user.getDisplayName());
|
||||
publishInitialSecurityProjection(user.getAuthUserId(), tenant.getId());
|
||||
return ProvisioningResult.created(user.getAuthUserId(), username, password);
|
||||
}
|
||||
@@ -204,19 +205,13 @@ public class TenantAdministratorProvisioningService implements TenantApprovalIni
|
||||
if (result.created()) compensate(result.authUserId());
|
||||
}
|
||||
|
||||
private String createAuthAccountWithUniqueUsername(long authUserId, String password,
|
||||
IamTenant tenant, long membershipId) {
|
||||
String username = username(tenant.getContactPhone());
|
||||
createAuthAccount(authUserId, username, password, tenant, membershipId);
|
||||
return username;
|
||||
}
|
||||
|
||||
private void createAuthAccount(long authUserId, String username, String password,
|
||||
IamTenant tenant, long membershipId) {
|
||||
private String createAuthAccount(long authUserId, String password, IamTenant tenant, long membershipId,
|
||||
String loginPhone, String displayName) {
|
||||
String username = generatedUsername(authUserId);
|
||||
try {
|
||||
ApiResponse<AuthAccountClient.AccountSummary> response = authClient.create(internalToken,
|
||||
new AuthAccountClient.CreateAccountRequest(authUserId, username, tenant.getContactPhone(), password,
|
||||
tenant.getContactName(), tenant.getId(), membershipId, "MERCHANT", "ACTIVE"));
|
||||
new AuthAccountClient.CreateAccountRequest(authUserId, username, loginPhone, password,
|
||||
displayName, tenant.getId(), membershipId, "MERCHANT", "ACTIVE"));
|
||||
if (response == null) throw unavailable();
|
||||
if (!response.successful()) {
|
||||
ResultCode code = ResultCode.of(response.code());
|
||||
@@ -224,9 +219,10 @@ public class TenantAdministratorProvisioningService implements TenantApprovalIni
|
||||
? code.message() : response.message());
|
||||
}
|
||||
if (response.data() == null) throw unavailable();
|
||||
return username;
|
||||
} catch (FeignException exception) {
|
||||
if (exception.status() == 409) {
|
||||
throw new BizException(ResultCode.CONFLICT, "联系电话已被其他账号使用,不能作为企业管理员登录用户名");
|
||||
throw new BizException(ResultCode.CONFLICT, "管理员用户名或登录手机号已被其他账号使用");
|
||||
}
|
||||
throw unavailable();
|
||||
} catch (BizException exception) {
|
||||
@@ -267,8 +263,8 @@ public class TenantAdministratorProvisioningService implements TenantApprovalIni
|
||||
return new String(value);
|
||||
}
|
||||
|
||||
private String username(String contactPhone) {
|
||||
return contactPhone == null ? "" : contactPhone.trim();
|
||||
private String generatedUsername(long authUserId) {
|
||||
return "merchant_" + authUserId;
|
||||
}
|
||||
|
||||
private char pick(char[] source) { return source[random.nextInt(source.length)]; }
|
||||
|
||||
@@ -162,7 +162,7 @@ public class TenantService {
|
||||
@Transactional
|
||||
public CreationResponse register(RegisterRequest request, long operatorId) {
|
||||
String contactPhone = normalizeContactPhone(request.contactPhone());
|
||||
ensureContactPhoneAvailable(contactPhone, null);
|
||||
ensureAdministratorPhoneAvailable(contactPhone);
|
||||
IamTenant tenant = new IamTenant();
|
||||
tenant.setId(IdWorker.getId());
|
||||
tenant.setTenantCode("TEN" + tenant.getId());
|
||||
@@ -364,24 +364,17 @@ public class TenantService {
|
||||
return dimensionRuleInitialization.status(tenantId);
|
||||
}
|
||||
|
||||
public boolean contactPhoneAvailable(String contactPhone, Long tenantId) {
|
||||
String normalized = normalizeContactPhone(contactPhone);
|
||||
return tenantId == null
|
||||
? !repository.existsByContactPhone(normalized)
|
||||
: !repository.existsByContactPhoneForOtherTenant(normalized, tenantId);
|
||||
}
|
||||
|
||||
public boolean contactPhoneAndUsernameAvailable(String contactPhone, Long tenantId) {
|
||||
String normalized = normalizeContactPhone(contactPhone);
|
||||
if (!contactPhoneAvailable(normalized, tenantId)) return false;
|
||||
/** Platform creation uses the same initial value for company contact and owner login phone. */
|
||||
public boolean administratorPhoneAvailable(String phone) {
|
||||
String normalized = normalizeContactPhone(phone);
|
||||
ApiResponse<Boolean> response;
|
||||
try {
|
||||
response = authClient.availability(internalToken, normalized);
|
||||
} catch (FeignException exception) {
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "认证账号服务暂时不可用,不能校验联系电话");
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "认证账号服务暂时不可用,不能校验管理员登录手机号");
|
||||
}
|
||||
if (response == null || !response.successful() || response.data() == null) {
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "认证账号服务暂时不可用,不能校验联系电话");
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE, "认证账号服务暂时不可用,不能校验管理员登录手机号");
|
||||
}
|
||||
return response.data();
|
||||
}
|
||||
@@ -393,13 +386,6 @@ public class TenantService {
|
||||
IamTenant tenant = requireMerchant(tenantId);
|
||||
ensureNotArchived(tenant);
|
||||
String contactPhone = normalizeContactPhone(request.contactPhone());
|
||||
String existingContactPhone = normalizeContactPhone(tenant.getContactPhone());
|
||||
if (!contactPhone.equals(existingContactPhone)) {
|
||||
if ("ACTIVE".equals(tenant.getStatus()) || "DISABLED".equals(tenant.getStatus())) {
|
||||
throw new BizException(ResultCode.CONFLICT, "客户已开户,联系电话作为登录用户名不能直接修改");
|
||||
}
|
||||
ensureContactPhoneAvailable(contactPhone, tenantId);
|
||||
}
|
||||
tenant.setTenantName(request.tenantName());
|
||||
tenant.setLegalName(request.legalName());
|
||||
tenant.setLegalRepresentative(request.legalRepresentative());
|
||||
@@ -446,7 +432,6 @@ public class TenantService {
|
||||
if (repository.findPendingReviewByTenant(tenantId) != null) {
|
||||
throw new BizException(ResultCode.CONFLICT, "Enterprise information is already under review / 客户资料已在审核中");
|
||||
}
|
||||
ensureContactPhoneAvailable(normalizeContactPhone(tenant.getContactPhone()), tenantId);
|
||||
if (tenant.getUnifiedSocialCreditCode() == null
|
||||
|| !tenant.getUnifiedSocialCreditCode().matches("[0-9A-Z]{18}")) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST,
|
||||
@@ -477,7 +462,7 @@ public class TenantService {
|
||||
tenant.setLegalName(request.legalName());
|
||||
tenant.setLegalRepresentative(request.legalRepresentative());
|
||||
tenant.setContactName(request.contactName());
|
||||
tenant.setContactPhone(request.contactPhone());
|
||||
tenant.setContactPhone(normalizeContactPhone(request.contactPhone()));
|
||||
tenant.setContactEmail(request.contactEmail());
|
||||
repository.saveTenant(tenant);
|
||||
return merchantVisibleResponse(tenant);
|
||||
@@ -497,9 +482,9 @@ public class TenantService {
|
||||
return contactPhone == null ? "" : contactPhone.trim();
|
||||
}
|
||||
|
||||
private void ensureContactPhoneAvailable(String contactPhone, Long tenantId) {
|
||||
if (!contactPhoneAvailable(contactPhone, tenantId)) {
|
||||
throw new BizException(ResultCode.CONFLICT, "联系电话已被其他客户使用,不能作为登录用户名");
|
||||
private void ensureAdministratorPhoneAvailable(String phone) {
|
||||
if (!administratorPhoneAvailable(phone)) {
|
||||
throw new BizException(ResultCode.CONFLICT, "管理员登录手机号已被其他账号使用");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ CREATE TABLE IF NOT EXISTS iam_tenant (
|
||||
legal_representative VARCHAR(64) NULL COMMENT '法定代表人',
|
||||
unified_social_credit_code VARCHAR(32) NULL COMMENT '统一社会信用代码',
|
||||
contact_name VARCHAR(64) NULL COMMENT '企业联系人',
|
||||
contact_phone VARCHAR(32) NULL COMMENT '联系电话',
|
||||
contact_phone VARCHAR(32) NULL COMMENT '公司联系电话,非登录标识且不要求跨企业唯一',
|
||||
contact_email VARCHAR(128) NULL COMMENT '联系邮箱',
|
||||
service_package VARCHAR(64) NOT NULL DEFAULT '基础版' COMMENT '客户服务套餐',
|
||||
contact_wechat VARCHAR(64) NULL COMMENT '联系微信',
|
||||
@@ -119,7 +119,7 @@ CREATE TABLE IF NOT EXISTS iam_user (
|
||||
auth_user_id BIGINT NOT NULL COMMENT '认证服务账号逻辑ID',
|
||||
user_type VARCHAR(20) NOT NULL DEFAULT 'ENTERPRISE' COMMENT '用户类型:ENTERPRISE企业用户、PLATFORM平台用户',
|
||||
display_name VARCHAR(64) NOT NULL COMMENT '用户展示名称',
|
||||
phone VARCHAR(32) NULL COMMENT '手机号',
|
||||
phone VARCHAR(32) NULL COMMENT '用户登录手机号,与企业联系电话独立',
|
||||
email VARCHAR(128) NULL COMMENT '邮箱',
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'ACTIVE' COMMENT '用户资料状态:ACTIVE正常、DISABLED停用',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
|
||||
@@ -67,16 +67,16 @@ paths:
|
||||
'401': {$ref: '#/components/responses/Unauthorized'}
|
||||
'403': {$ref: '#/components/responses/Forbidden'}
|
||||
'409': {$ref: '#/components/responses/Conflict'}
|
||||
/api/platform/v1/iam/tenants/contact-phone-availability:
|
||||
/api/platform/v1/iam/tenants/administrator-phone-availability:
|
||||
get:
|
||||
tags: [Platform Tenant / 平台租户]
|
||||
summary: 校验客户联系电话唯一性
|
||||
summary: 校验首个管理员登录手机号唯一性
|
||||
description: 仅在创建客户前校验 Auth 登录手机号;公司联系电话不要求跨企业唯一。
|
||||
parameters:
|
||||
- {name: contactPhone, in: query, required: true, schema: {type: string}}
|
||||
- {name: excludeTenantId, in: query, required: false, schema: {type: integer, format: int64}}
|
||||
- {name: phone, in: query, required: true, schema: {type: string, pattern: '^1[3-9]\d{9}$'}}
|
||||
responses:
|
||||
'200':
|
||||
description: 返回联系电话是否可作为登录用户名
|
||||
description: 返回手机号是否可作为首个管理员登录手机号
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -211,7 +211,7 @@ paths:
|
||||
post:
|
||||
tags: [Platform Tenant / 平台租户]
|
||||
summary: 提交企业客户审核
|
||||
description: 校验营业执照和法人身份证已上传后创建审核单,并把客户状态改为 `PENDING`;保存资料和上传文件均不会自动调用本接口。
|
||||
description: 校验营业执照和统一社会信用代码后创建审核单,并把客户状态改为 `PENDING`;法人身份证选填,保存资料和上传文件均不会自动调用本接口。
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/TenantSuccess'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
@@ -683,7 +683,7 @@ paths:
|
||||
post:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: Submit enterprise qualifications for review / 提交企业资质审核
|
||||
description: Uploading or replacing a qualification keeps the tenant in draft state. This endpoint creates the review after the business license and legal-person ID have been provided; the freight-forwarder certificate and bank account license are optional. / 上传或替换资质不会自动送审;营业执照和法人身份证齐全后由此接口创建审核单,货代资质证书和银行开户许可证选填。
|
||||
description: Uploading or replacing a qualification keeps the tenant in draft state. This endpoint requires only the business license and unified social credit code; legal-person ID, freight-forwarder certificate and bank account license are optional. / 上传或替换资质不会自动送审;本接口只要求营业执照和统一社会信用代码,法人身份证、货代资质证书和银行开户许可证选填。
|
||||
responses:
|
||||
'200': {$ref: '#/components/responses/TenantSuccess'}
|
||||
'400': {$ref: '#/components/responses/BadRequest'}
|
||||
@@ -813,8 +813,8 @@ paths:
|
||||
/internal/iam/required-qualification-packages:
|
||||
post:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: 商户必填资质包登记
|
||||
description: 仅供 File Service 调用;在一个 IAM 事务中登记营业执照、统一社会信用代码和法人身份证。
|
||||
summary: 商户营业执照资质包登记
|
||||
description: 仅供 File Service 调用;在一个 IAM 事务中登记必填营业执照与统一社会信用代码,法人身份证可选。
|
||||
security: []
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/InternalServiceToken'}
|
||||
@@ -833,8 +833,8 @@ paths:
|
||||
/internal/iam/platform-required-qualification-packages:
|
||||
post:
|
||||
tags: [IAM Resources / IAM 资源]
|
||||
summary: 平台代客户必填资质包登记
|
||||
description: 仅供 File Service 调用;与商户入口使用相同的三项事务保存规则。
|
||||
summary: 平台代客户登记营业执照资质包
|
||||
description: 仅供 File Service 调用;与商户入口使用相同规则,营业执照与统一社会信用代码必填,法人身份证可选。
|
||||
security: []
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/InternalServiceToken'}
|
||||
@@ -1318,7 +1318,7 @@ components:
|
||||
legalName: {type: string, example: 深圳虫虫出海科技有限公司}
|
||||
legalRepresentative: {type: string, maxLength: 64, example: 张三}
|
||||
contactName: {type: string, example: 李四}
|
||||
contactPhone: {type: string, example: '13800138000'}
|
||||
contactPhone: {type: string, pattern: '^1[3-9]\d{9}$', example: '13800138000', description: 创建时同时初始化公司联系电话与首个管理员登录手机号;创建后二者独立维护}
|
||||
contactEmail: {type: string, format: email, example: contact@example.com}
|
||||
contactWechat: {type: string, maxLength: 64}
|
||||
servicePackage: {type: string, maxLength: 64, example: 基础版}
|
||||
@@ -1338,7 +1338,7 @@ components:
|
||||
legalName: {type: string}
|
||||
legalRepresentative: {type: string, maxLength: 64}
|
||||
contactName: {type: string}
|
||||
contactPhone: {type: string}
|
||||
contactPhone: {type: string, pattern: '^[0-9-]{4,32}$', description: 公司联系电话,不作为登录标识且不要求跨企业唯一}
|
||||
contactEmail: {type: string, format: email}
|
||||
UpdateTenantRequest:
|
||||
type: object
|
||||
@@ -1348,7 +1348,7 @@ components:
|
||||
legalName: {type: string}
|
||||
legalRepresentative: {type: string, maxLength: 64}
|
||||
contactName: {type: string}
|
||||
contactPhone: {type: string}
|
||||
contactPhone: {type: string, pattern: '^[0-9-]{4,32}$', description: 公司联系电话,与管理员及成员登录手机号独立且不要求跨企业唯一}
|
||||
contactEmail: {type: string, format: email}
|
||||
contactWechat: {type: string, maxLength: 64}
|
||||
servicePackage: {type: string, maxLength: 64, example: 基础版}
|
||||
@@ -1398,7 +1398,7 @@ components:
|
||||
properties:
|
||||
username: {type: string, pattern: '^[A-Za-z][A-Za-z0-9_.@-]{3,63}$'}
|
||||
displayName: {type: string, maxLength: 64}
|
||||
phone: {type: string, pattern: '^1[3-9]\\d{9}$'}
|
||||
phone: {type: string, pattern: '^1[3-9]\\d{9}$', description: 平台账号登录手机号;修改时同步 Auth、撤销该账号会话并审计}
|
||||
email: {type: string, format: email, maxLength: 128}
|
||||
tenantId: {type: integer, format: int64, enum: [0], description: 保留的兼容字段,只允许平台技术作用域 0}
|
||||
roleIds: {type: array, minItems: 1, items: {type: integer, format: int64}}
|
||||
@@ -1410,7 +1410,7 @@ components:
|
||||
required: [displayName, phone, tenantId, roleIds]
|
||||
properties:
|
||||
displayName: {type: string, maxLength: 64}
|
||||
phone: {type: string, pattern: '^1[3-9]\\d{9}$'}
|
||||
phone: {type: string, pattern: '^1[3-9]\\d{9}$', description: 平台账号登录手机号;与任何企业联系电话无关}
|
||||
email: {type: string, format: email, maxLength: 128}
|
||||
tenantId: {type: integer, format: int64, enum: [0], description: 保留的兼容字段,只允许平台技术作用域 0}
|
||||
roleIds: {type: array, minItems: 1, items: {type: integer, format: int64}}
|
||||
@@ -1424,7 +1424,7 @@ components:
|
||||
username: {type: string, pattern: '^[A-Za-z][A-Za-z0-9_.@-]{3,63}$'}
|
||||
password: {type: string, format: password, minLength: 8, maxLength: 64, writeOnly: true}
|
||||
displayName: {type: string, maxLength: 64}
|
||||
phone: {type: string, pattern: '^1[3-9]\d{9}$'}
|
||||
phone: {type: string, pattern: '^1[3-9]\d{9}$', description: 企业成员登录手机号;修改时同步 Auth、撤销该账号会话并审计}
|
||||
email: {type: string, format: email, maxLength: 128}
|
||||
memberNo: {type: string, maxLength: 64}
|
||||
roleIds: {type: array, items: {type: integer, format: int64}}
|
||||
@@ -1433,7 +1433,7 @@ components:
|
||||
required: [displayName, memberNo, roleIds]
|
||||
properties:
|
||||
displayName: {type: string, maxLength: 64}
|
||||
phone: {type: string, pattern: '^1[3-9]\d{9}$'}
|
||||
phone: {type: string, pattern: '^1[3-9]\d{9}$', description: 企业成员登录手机号;与公司联系电话无关}
|
||||
email: {type: string, format: email, maxLength: 128}
|
||||
memberNo: {type: string, maxLength: 64}
|
||||
roleIds: {type: array, items: {type: integer, format: int64}}
|
||||
|
||||
Reference in New Issue
Block a user