openapi: 3.0.3 info: title: Baiyue IAM API / 百悦身份与权限 API description: Customer master data, members, roles, menus, pages, buttons and API permissions for the current single-tenant product. Historical tenant-named paths, schemas and fields are retained for compatibility; tenantId > 0 currently means customer ID, while 0 is technical scope for platform identities, RBAC, and public warehouse resources. / 当前单租户产品的客户主档、成员、角色、菜单、页面、按钮和 API 权限管理。tenant 命名的路径、模型和字段仅为历史兼容;tenantId 大于 0 当前表示客户 ID,0 表示平台身份、RBAC 和公共仓储资源技术作用域。 version: 1.0.1 servers: - url: / security: - bearerAuth: [] tags: - name: Platform Tenant / 平台租户 description: Historical tag for platform customer administration; it does not represent a real tenant layer. / 历史兼容标签,实际用于平台客户管理,不表示真实租户层。 - name: Merchant Tenant / 商户企业 description: Current customer profile and members; tenant naming is retained for compatibility. / 当前客户企业资料与成员;tenant 命名仅为兼容。 - name: IAM Resources / IAM 资源 description: Internal users, addresses and qualifications / 内部用户、地址与资质 - name: RBAC description: Platform and merchant role-permission management / 平台端与商户端角色权限管理 paths: /api/platform/v1/iam/tenants/contact-phone-availability: get: tags: [Platform Tenant / 平台租户] summary: 校验客户联系电话唯一性 parameters: - {name: contactPhone, in: query, required: true, schema: {type: string}} - {name: excludeTenantId, in: query, required: false, schema: {type: integer, format: int64}} responses: '200': description: 返回联系电话是否可作为登录用户名 content: application/json: schema: type: object properties: code: {type: string} message: {type: string} data: {type: boolean} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/tenants: get: tags: [Platform Tenant / 平台租户] summary: 查询企业客户列表 description: 分页查询商户企业客户,需要 `platform:customer:list` 权限;联系电话和邮箱仅返回脱敏摘要。 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: status, in: query, required: false, schema: {type: string, enum: [PROFILE_REQUIRED, PENDING, ACTIVE, REJECTED, DISABLED]}} responses: '200': description: 企业客户分页查询成功 content: application/json: schema: {$ref: '#/components/schemas/TenantPageApiResponse'} '400': {$ref: '#/components/responses/BadRequest'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} '422': {$ref: '#/components/responses/UnprocessableEntity'} post: tags: [Platform Tenant / 平台租户] summary: Register enterprise tenant / 创建企业客户草稿 description: Create a `PROFILE_REQUIRED` enterprise draft only. Saving the customer does not create a review task. / 仅创建待完善企业客户草稿,保存客户不会创建审核单。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/RegisterRequest'} responses: '200': {$ref: '#/components/responses/TenantSuccess'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /api/platform/v1/iam/authorization/permissions: get: tags: [IAM Resources / IAM 资源] summary: 查询当前用户有效权限 description: 返回当前有效平台成员权限编码;只要求有效 PLATFORM JWT,不依赖 `platform:role:list`。 responses: '200': description: 当前平台成员权限查询成功 content: application/json: schema: {$ref: '#/components/schemas/PermissionCodesApiResponse'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/tenants/{tenantId}: parameters: - {$ref: '#/components/parameters/TenantId'} get: tags: [Platform Tenant / 平台租户] summary: 查询企业客户档案 description: 需要独立的 `platform:customer:view` 权限,返回完整联系方式。 responses: '200': {$ref: '#/components/responses/TenantSuccess'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} put: tags: [Platform Tenant / 平台租户] summary: 编辑企业客户档案 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/UpdateTenantRequest'} responses: '200': {$ref: '#/components/responses/TenantSuccess'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/platform/v1/iam/tenants/{tenantId}/members: parameters: - {$ref: '#/components/parameters/TenantId'} get: tags: [Platform Tenant / 平台租户] summary: 查询企业客户成员及账号 description: 平台只读查询指定客户的全部企业成员,包含 OWNER 企业管理员并返回登录账号;需要 `platform:customer:view` 权限。 responses: '200': description: 企业成员查询成功 content: application/json: schema: $ref: '#/components/schemas/PlatformCustomerMembersApiResponse' '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/platform/v1/iam/tenants/{tenantId}/submit-review: parameters: - {$ref: '#/components/parameters/TenantId'} post: tags: [Platform Tenant / 平台租户] summary: 提交企业客户审核 description: 校验营业执照和法人身份证已上传后创建审核单,并把客户状态改为 `PENDING`;保存资料和上传文件均不会自动调用本接口。 responses: '200': {$ref: '#/components/responses/TenantSuccess'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} '409': {$ref: '#/components/responses/Conflict'} /api/platform/v1/iam/tenants/{tenantId}/addresses: parameters: - {$ref: '#/components/parameters/TenantId'} get: tags: [Platform Tenant / 平台租户] summary: 查询企业客户地址 description: 需要 `platform:customer:view` 权限;只读接口,不提供平台端地址写入。 responses: '200': description: 企业客户地址查询成功 content: application/json: schema: {$ref: '#/components/schemas/TenantAddressListApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/platform/v1/iam/tenants/{tenantId}/qualifications: parameters: - {$ref: '#/components/parameters/TenantId'} get: tags: [Platform Tenant / 平台租户] summary: 查询企业客户资质 description: 需要 `platform:customer:view` 权限;只读查询资质元数据,不授予审核权限。 responses: '200': description: 企业客户资质查询成功 content: application/json: schema: {$ref: '#/components/schemas/TenantQualificationListApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/platform/v1/iam/tenants/{tenantId}/status: parameters: - {$ref: '#/components/parameters/TenantId'} put: tags: [Platform Tenant / 平台租户] summary: 启停企业客户 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ChangeTenantStatusRequest'} responses: '200': {$ref: '#/components/responses/TenantSuccess'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} '409': {$ref: '#/components/responses/Conflict'} /api/merchant/v1/iam/authorization/permissions: get: tags: [IAM Resources / IAM 资源] summary: 查询当前用户有效权限 description: 返回当前有效商户成员权限编码。 responses: '200': description: 当前商户成员权限查询成功 content: application/json: schema: {$ref: '#/components/schemas/PermissionCodesApiResponse'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/reviews: get: tags: [Platform Tenant / 平台租户] summary: List pending tenant reviews / 查询待审核企业 description: Return enterprise registrations waiting for a platform decision. / 返回等待平台处理的企业注册审核记录。 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/reviews/{id}/approve: post: tags: [Platform Tenant / 平台租户] summary: Approve enterprise registration / 审核通过企业注册 description: Approve and activate the tenant. Client registrations keep the registration account as administrator. Only platform-created tenants without an owner receive a generated administrator and one-time credentials. / 审核通过并激活企业;客户端注册账号继续作为企业管理员,仅平台代建且没有所有者的企业自动创建管理员并返回一次性凭据。 parameters: - {$ref: '#/components/parameters/Id'} requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ReviewRequest'} responses: '200': description: 审核通过;data 返回开户结果及一次性初始凭据 content: application/json: schema: {$ref: '#/components/schemas/TenantApprovalApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} '409': {$ref: '#/components/responses/Conflict'} /api/platform/v1/iam/reviews/{id}/reject: post: tags: [Platform Tenant / 平台租户] summary: Reject enterprise registration / 驳回企业注册 description: Reject a pending registration and save the review comment. / 驳回待审核注册申请并保存审核意见。 parameters: - {$ref: '#/components/parameters/Id'} requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ReviewRequest'} responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} '409': {$ref: '#/components/responses/Conflict'} /api/platform/v1/iam/users: get: tags: [IAM Resources / IAM 资源] summary: 分页查询平台内部用户 parameters: - {name: page, in: query, schema: {type: integer, minimum: 1, default: 1}} - {name: size, in: query, schema: {type: integer, minimum: 1, maximum: 200, default: 20}} - {name: keyword, in: query, schema: {type: string}, description: 匹配姓名、手机号、邮箱或成员编号} - {name: status, in: query, schema: {type: string, enum: [ACTIVE, DISABLED]}} responses: '200': description: 仅返回 tenant_id=0 的平台内部用户分页 content: application/json: schema: {$ref: '#/components/schemas/PlatformManagedUserPageApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} post: tags: [IAM Resources / IAM 资源] summary: 新增平台内部用户 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/CreatePlatformManagedUserRequest'} responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/users/options: get: tags: [IAM Resources / IAM 资源] summary: 查询平台技术作用域和 PLATFORM 角色选项 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/users/{membershipId}: parameters: - {$ref: '#/components/parameters/MembershipId'} put: tags: [IAM Resources / IAM 资源] summary: 编辑平台内部用户资料及角色 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/UpdatePlatformManagedUserRequest'} responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/users/{membershipId}/status: parameters: - {$ref: '#/components/parameters/MembershipId'} put: tags: [IAM Resources / IAM 资源] summary: 启用或停用平台内部用户 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ChangeInternalUserStatusRequest'} responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/users/{membershipId}/password: parameters: - {$ref: '#/components/parameters/MembershipId'} put: tags: [IAM Resources / IAM 资源] summary: 重置平台内部用户密码 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ResetInternalUserPasswordRequest'} responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} /api/platform/v1/iam/internal-users: get: tags: [IAM Resources / IAM 资源] summary: 查询平台内部用户 responses: '200': description: 平台内部用户查询成功,公开主键为 membershipId 并回显 roleIds content: application/json: schema: {$ref: '#/components/schemas/InternalUserListApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} post: tags: [IAM Resources / IAM 资源] summary: 新增平台内部用户 description: 创建完整的 Auth/IAM 平台账号,也兼容通过 authUserId 关联已有账号。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/CreateInternalUserRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /api/platform/v1/iam/internal-users/{membershipId}: parameters: - {$ref: '#/components/parameters/MembershipId'} put: tags: [IAM Resources / IAM 资源] summary: 编辑平台内部用户 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/UpdateInternalUserRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} '409': {$ref: '#/components/responses/Conflict'} /api/platform/v1/iam/internal-users/{membershipId}/status: parameters: - {$ref: '#/components/parameters/MembershipId'} put: tags: [IAM Resources / IAM 资源] summary: 启用或停用平台内部用户 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ChangeInternalUserStatusRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/platform/v1/iam/internal-users/{membershipId}/password: parameters: - {$ref: '#/components/parameters/MembershipId'} put: tags: [IAM Resources / IAM 资源] summary: 重置平台内部用户密码 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ResetInternalUserPasswordRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/platform/v1/iam/internal-users/{membershipId}/roles: parameters: - {$ref: '#/components/parameters/MembershipId'} put: tags: [IAM 资源] summary: 全量分配平台内部用户角色 description: 仅允许分配平台技术作用域(tenant_id=0)下已启用的平台端角色;空集合表示清空角色。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/AssignInternalUserRolesRequest'} responses: '200': description: 角色分配成功并返回最新内部用户模型 content: application/json: schema: {$ref: '#/components/schemas/InternalUserApiResponse'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/merchant/v1/iam/tenant/profile: get: tags: [Merchant Tenant / 商户企业] summary: Get current tenant profile / 查询当前企业资料 description: The compatibility field tenant ID comes only from the verified JWT and currently identifies the customer. / 客户隔离兼容字段 tenant ID 仅取自已验证 JWT,当前表示登录客户 ID。 responses: '200': {$ref: '#/components/responses/Success'} '401': {$ref: '#/components/responses/Unauthorized'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} put: tags: [Merchant Tenant / 商户企业] summary: Update current tenant profile / 更新当前企业资料 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/UpdateProfileRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} /api/merchant/v1/iam/members: get: tags: [Merchant Tenant / 商户企业] summary: List enterprise members / 查询企业成员 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} post: tags: [Merchant Tenant / 商户企业] summary: Add enterprise member / 新增企业成员 description: 新增基础资料需要 merchant:member:create;roleIds 非空时还必须具有 merchant:member:grant-role,否则返回 403/A0403。空数组表示不分配角色。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/CreateMemberRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /api/merchant/v1/iam/members/{membershipId}: parameters: - name: membershipId in: path required: true description: 当前租户内的成员关系 ID schema: {type: string, pattern: '^\d+$'} get: tags: [Merchant Tenant / 商户企业] summary: 查询成员详情及当前角色 description: 返回当前客户成员资料,roleIds 为服务端实时查询的当前角色集合;跨客户成员按不存在处理。 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} put: tags: [Merchant Tenant / 商户企业] summary: 编辑成员资料及角色 description: 基础资料编辑需要 merchant:member:edit。仅当 roleIds 与当前角色集合实际不同时额外要求 merchant:member:grant-role;传空数组清空角色也属于角色变更。角色集合未变化时不误拒绝。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/UpdateMemberRequest'} responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} '404': {$ref: '#/components/responses/NotFound'} '409': {$ref: '#/components/responses/Conflict'} /api/merchant/v1/iam/tenant/addresses: get: tags: [IAM Resources / IAM 资源] summary: List tenant addresses / 查询企业地址 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} post: tags: [IAM Resources / IAM 资源] summary: Add tenant address / 新增企业地址 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/AddressRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} /api/merchant/v1/iam/tenant/qualifications: get: tags: [IAM Resources / IAM 资源] summary: List tenant qualifications / 查询企业资质 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} /api/merchant/v1/iam/tenant/qualifications/submit-review: 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. / 上传或替换资质不会自动送审;营业执照和法人身份证齐全后由此接口创建审核单,货代资质证书和银行开户许可证选填。 responses: '200': {$ref: '#/components/responses/TenantSuccess'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /api/{app}/v1/iam/roles: parameters: - {$ref: '#/components/parameters/App'} get: tags: [RBAC] summary: List roles / 查询角色 description: List roles in the selected application and current customer or platform technical scope. / 查询指定应用及当前客户范围或平台技术作用域内的角色。 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} post: tags: [RBAC] summary: Create role / 新增角色 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/CreateRoleRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /api/{app}/v1/iam/members/roles: put: tags: [RBAC] summary: Assign roles to member / 设置成员角色 description: Replace member role assignments in the same tenant and application. / 在同一租户和应用域内替换成员角色。 parameters: - {$ref: '#/components/parameters/App'} requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/AssignRolesRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} /api/{app}/v1/iam/permissions: parameters: - {$ref: '#/components/parameters/App'} get: tags: [RBAC] summary: List menu, page, button and API permissions / 查询菜单、页面、按钮和 API 权限 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} post: tags: [RBAC] summary: Create permission / 新增权限 description: Create a MENU, PAGE, BUTTON or API permission node. / 创建 MENU、PAGE、BUTTON 或 API 权限节点。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/CreatePermissionRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /api/{app}/v1/iam/roles/permissions: put: tags: [RBAC] summary: Grant permissions to role / 设置角色权限 description: Replace role permissions; cross-customer and cross-application grants are rejected. / 替换角色权限,拒绝跨客户和跨应用授权。 parameters: - {$ref: '#/components/parameters/App'} requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/GrantPermissionsRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} /api/{app}/v1/iam/permissions/{permissionId}: parameters: - {$ref: '#/components/parameters/App'} - {$ref: '#/components/parameters/PermissionId'} put: tags: [RBAC] summary: 编辑自定义权限资源 description: 权限编码和类型不可变更,系统预置资源不可修改。 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/UpdatePermissionRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} delete: tags: [RBAC] summary: 删除未绑定的自定义权限资源 description: 系统预置资源、存在子资源或已绑定角色的资源不可删除。 responses: '200': {$ref: '#/components/responses/Success'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /api/{app}/v1/iam/permissions/{permissionId}/status: parameters: - {$ref: '#/components/parameters/App'} - {$ref: '#/components/parameters/PermissionId'} put: tags: [RBAC] summary: 启停自定义权限资源 requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/ChangePermissionStatusRequest'} responses: '200': {$ref: '#/components/responses/Success'} '400': {$ref: '#/components/responses/BadRequest'} '403': {$ref: '#/components/responses/Forbidden'} '409': {$ref: '#/components/responses/Conflict'} /internal/iam/required-qualification-packages: post: tags: [IAM Resources / IAM 资源] summary: 商户必填资质包登记 description: 仅供 File Service 调用;在一个 IAM 事务中登记营业执照、统一社会信用代码和法人身份证。 security: [] parameters: - {$ref: '#/components/parameters/InternalServiceToken'} requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/RequiredQualificationPackageRequest'} responses: '200': description: 统一响应;仅 data 非空且 code 为 200 表示资质包已完整登记 content: application/json: schema: {$ref: '#/components/schemas/RequiredQualificationPackageApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} /internal/iam/platform-required-qualification-packages: post: tags: [IAM Resources / IAM 资源] summary: 平台代客户必填资质包登记 description: 仅供 File Service 调用;与商户入口使用相同的三项事务保存规则。 security: [] parameters: - {$ref: '#/components/parameters/InternalServiceToken'} requestBody: required: true content: application/json: schema: {$ref: '#/components/schemas/RequiredQualificationPackageRequest'} responses: '200': description: 统一响应;仅 data 非空且 code 为 200 表示资质包已完整登记 content: application/json: schema: {$ref: '#/components/schemas/RequiredQualificationPackageApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} /internal/exports/v1/CUSTOMER_LIST/batches: post: tags: [Internal Export Provider] summary: 分批提供企业客户导出数据 description: 仅供 File Service 调用;按平台访问域、签名最大 ID 快照和游标只读查询商户客户。 security: [] parameters: - name: X-Internal-Service-Token in: header required: true schema: {type: string} requestBody: required: true content: application/json: schema: type: object required: [taskId, tenantId, appCode, requestedBy, dispatchVersion, parameters, limit] properties: taskId: {type: string, pattern: '^\d+$'} tenantId: {type: string, pattern: '^\d+$'} appCode: {type: string, enum: [PLATFORM]} requestedBy: {type: string, pattern: '^\d+$'} dispatchVersion: {type: integer, minimum: 1} parameters: {type: object} cursor: {type: string, nullable: true} snapshotToken: {type: string, nullable: true, maxLength: 512} limit: {type: integer, minimum: 1, maximum: 500} responses: '200': description: 统一响应;data 为 ExportBatchResponse,Long 值以字符串传输 content: application/json: schema: {$ref: '#/components/schemas/ApiResponse'} '403': {$ref: '#/components/responses/Forbidden'} components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT parameters: InternalServiceToken: name: X-Internal-Service-Token in: header required: true schema: {type: string} Id: name: id in: path required: true description: Resource ID / 资源 ID schema: {type: integer, format: int64} example: 190000000000000001 App: name: app in: path required: true description: Application domain / 应用域 schema: {type: string, enum: [platform, merchant]} example: platform MembershipId: name: membershipId in: path required: true description: 平台成员关系 ID schema: {type: integer, format: int64} TenantId: name: tenantId in: path required: true description: 企业客户 ID;tenantId 为历史兼容参数名 schema: {type: string, pattern: '^\d+$'} PermissionId: name: permissionId in: path required: true description: 权限资源 ID schema: {type: integer, format: int64} responses: Success: {description: Operation succeeded / 操作成功, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}} TenantSuccess: {description: Enterprise tenant returned / 返回企业客户档案, content: {application/json: {schema: {$ref: '#/components/schemas/TenantApiResponse'}}}} BadRequest: {description: Invalid request / 请求参数错误, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}} Unauthorized: {description: Authentication required / 需要登录, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}} Forbidden: {description: Permission, customer scope or platform technical scope rejected / 权限、客户范围或平台技术作用域不匹配, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}} NotFound: {description: Resource not found / 资源不存在, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}} Conflict: {description: Resource conflict / 资源冲突, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}} UnprocessableEntity: {description: 参数校验失败, content: {application/json: {schema: {$ref: '#/components/schemas/ApiResponse'}}}} schemas: ApiResponse: type: object required: [code, message, timestamp] properties: code: {type: string, example: '00000'} message: {type: string, example: Success} data: {} requestId: {type: string} traceId: {type: string} timestamp: {type: string, format: date-time} PermissionCodesApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: type: array uniqueItems: true items: {type: string} TenantPageApiResponse: 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/TenantResponse'}} page: {type: integer, format: int64, minimum: 1} size: {type: integer, format: int64, minimum: 1} total: {type: integer, format: int64, minimum: 0} pages: {type: integer, format: int64, minimum: 0} TenantApprovalApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: {$ref: '#/components/schemas/TenantApprovalResponse'} TenantApprovalResponse: type: object required: [tenantId, administratorCreated] properties: tenantId: {type: string, pattern: '^\d+$', example: '190000000000000001'} administratorCreated: {type: boolean, description: 本次审核是否新建企业管理员} administratorUsername: {type: string, nullable: true, example: '13800138000'} temporaryPassword: {type: string, format: password, nullable: true, description: 一次性初始密码,仅新建管理员时返回} TenantApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: {$ref: '#/components/schemas/TenantResponse'} InternalUserListApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: {type: array, items: {$ref: '#/components/schemas/InternalUserResponse'}} InternalUserApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: {$ref: '#/components/schemas/InternalUserResponse'} PlatformCustomerMemberResponse: type: object required: [membershipId, userId, authUserId, username, displayName, memberType, status, roleIds, roleNames] properties: membershipId: {type: string, pattern: '^\d+$'} userId: {type: string, pattern: '^\d+$'} authUserId: {type: string, pattern: '^\d+$'} username: {type: string} displayName: {type: string} phone: {type: string} email: {type: string, format: email} memberType: {type: string, enum: [OWNER, EMPLOYEE]} memberNo: {type: string} status: {type: string, enum: [ACTIVE, DISABLED]} roleIds: {type: array, items: {type: string, pattern: '^\d+$'}} roleNames: {type: array, items: {type: string}} PlatformCustomerMembersApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: {type: array, items: {$ref: '#/components/schemas/PlatformCustomerMemberResponse'}} PlatformManagedUserPageApiResponse: 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/PlatformManagedUserResponse'}} page: {type: integer, minimum: 1} size: {type: integer, minimum: 1} total: {type: integer, minimum: 0} pages: {type: integer, minimum: 0} TenantResponse: type: object required: [id, tenantCode, tenantName, status, servicePackage] properties: id: {type: string, pattern: '^\d+$', example: '190000000000000001'} tenantCode: {type: string} tenantName: {type: string} status: {type: string, enum: [PROFILE_REQUIRED, PENDING, ACTIVE, REJECTED, DISABLED]} legalName: {type: string} legalRepresentative: {type: string, maxLength: 64} unifiedSocialCreditCode: {type: string} contactName: {type: string} contactPhone: {type: string} contactEmail: {type: string, format: email} contactWechat: {type: string, maxLength: 64} servicePackage: {type: string, maxLength: 64} salesOwnerName: {type: string, maxLength: 64} paymentTermDays: {type: integer, minimum: 0, maximum: 365} enterpriseType: {type: string, maxLength: 64} establishedDate: {type: string, format: date} registeredCapital: {type: number, format: decimal, minimum: 0} registeredCapitalCurrency: {type: string, pattern: '^[A-Z]{3}$', example: CNY} registeredAddress: {type: string, maxLength: 500} internalRemark: {type: string, maxLength: 1000, description: 仅平台端可见} createdAt: {type: string, format: date-time, description: 入驻时间} approvedAt: {type: string, format: date-time, description: 审批通过时间} TenantAddressListApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: type: array items: {$ref: '#/components/schemas/TenantAddress'} TenantQualificationListApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: type: array items: {$ref: '#/components/schemas/TenantQualification'} TenantAddress: type: object properties: id: {type: string, pattern: '^\d+$'} tenantId: {type: string, pattern: '^\d+$'} addressType: {type: string} countryCode: {type: string} province: {type: string} city: {type: string} district: {type: string} detail: {type: string} postalCode: {type: string} isDefault: {type: boolean} TenantQualification: type: object properties: id: {type: string, pattern: '^\d+$'} tenantId: {type: string, pattern: '^\d+$'} qualificationType: {type: string, enum: [BUSINESS_LICENSE, LEGAL_PERSON_ID, FREIGHT_FORWARDER_CERTIFICATE, BANK_ACCOUNT_LICENSE]} certificateNo: {type: string} documentUrl: {type: string} validFrom: {type: string, format: date} validTo: {type: string, format: date, nullable: true} status: {type: string, enum: [PENDING, APPROVED, REJECTED, SUPERSEDED]} reviewComment: {type: string} RequiredQualificationPackageRequest: type: object required: [tenantId, unifiedSocialCreditCode, businessLicenseDocumentUrl, replaceBusinessLicense, legalPersonIdDocumentUrl, replaceLegalPersonId] properties: tenantId: {type: string, pattern: '^\d+$'} unifiedSocialCreditCode: {type: string, pattern: '^[0-9A-Za-z]{18}$'} businessLicenseDocumentUrl: {type: string, minLength: 1} businessLicenseValidTo: {type: string, format: date, nullable: true} replaceBusinessLicense: {type: boolean} legalPersonIdDocumentUrl: {type: string, minLength: 1} legalPersonIdValidTo: {type: string, format: date, nullable: true} replaceLegalPersonId: {type: boolean} RequiredQualificationPackageResponse: type: object required: [businessLicenseQualificationId, legalPersonIdQualificationId, tenantStatus] properties: businessLicenseQualificationId: {type: string, pattern: '^\d+$'} legalPersonIdQualificationId: {type: string, pattern: '^\d+$'} tenantStatus: {type: string, enum: [PROFILE_REQUIRED, REJECTED]} replacedBusinessLicenseDocumentUrl: {type: string, nullable: true} replacedLegalPersonIdDocumentUrl: {type: string, nullable: true} RequiredQualificationPackageApiResponse: allOf: - {$ref: '#/components/schemas/ApiResponse'} - type: object properties: data: {$ref: '#/components/schemas/RequiredQualificationPackageResponse'} RegisterRequest: type: object required: [tenantName, legalName, legalRepresentative, contactName, contactPhone, servicePackage] properties: tenantName: {type: string, example: 深圳虫虫出海科技有限公司} legalName: {type: string, example: 深圳虫虫出海科技有限公司} legalRepresentative: {type: string, maxLength: 64, example: 张三} contactName: {type: string, example: 李四} contactPhone: {type: string, example: '13800138000'} contactEmail: {type: string, format: email, example: contact@example.com} contactWechat: {type: string, maxLength: 64} servicePackage: {type: string, maxLength: 64, example: 基础版} salesOwnerName: {type: string, maxLength: 64} paymentTermDays: {type: integer, minimum: 0, maximum: 365} enterpriseType: {type: string, maxLength: 64} establishedDate: {type: string, format: date} registeredCapital: {type: number, format: decimal, minimum: 0} registeredCapitalCurrency: {type: string, pattern: '^[A-Z]{3}$', example: CNY} registeredAddress: {type: string, maxLength: 500} internalRemark: {type: string, maxLength: 1000} UpdateProfileRequest: type: object required: [tenantName, legalName, legalRepresentative, contactName, contactPhone] properties: tenantName: {type: string} legalName: {type: string} legalRepresentative: {type: string, maxLength: 64} contactName: {type: string} contactPhone: {type: string} contactEmail: {type: string, format: email} UpdateTenantRequest: type: object required: [tenantName, legalName, legalRepresentative, contactName, contactPhone] properties: tenantName: {type: string} legalName: {type: string} legalRepresentative: {type: string, maxLength: 64} contactName: {type: string} contactPhone: {type: string} contactEmail: {type: string, format: email} contactWechat: {type: string, maxLength: 64} servicePackage: {type: string, maxLength: 64, example: 基础版} salesOwnerName: {type: string, maxLength: 64} paymentTermDays: {type: integer, minimum: 0, maximum: 365} enterpriseType: {type: string, maxLength: 64} establishedDate: {type: string, format: date} registeredCapital: {type: number, format: decimal, minimum: 0} registeredCapitalCurrency: {type: string, pattern: '^[A-Z]{3}$'} registeredAddress: {type: string, maxLength: 500} internalRemark: {type: string, maxLength: 1000} ChangeTenantStatusRequest: type: object required: [status] properties: status: {type: string, enum: [ACTIVE, DISABLED]} ReviewRequest: type: object properties: comment: {type: string, maxLength: 500, description: Review comment or rejection reason / 审核意见或驳回原因} CreatePlatformManagedUserRequest: type: object required: [username, displayName, phone, tenantId, roleIds, password, status] properties: username: {type: string, minLength: 4, maxLength: 64} displayName: {type: string, maxLength: 64} phone: {type: string, pattern: '^1\\d{10}$'} 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}} password: {type: string, format: password, minLength: 8, maxLength: 64, writeOnly: true} status: {type: string, enum: [ACTIVE, DISABLED]} UpdatePlatformManagedUserRequest: type: object required: [displayName, phone, tenantId, roleIds] properties: displayName: {type: string, maxLength: 64} phone: {type: string, pattern: '^1\\d{10}$'} 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}} CreateInternalUserRequest: type: object required: [displayName] properties: authUserId: {type: integer, format: int64, description: 兼容旧接口;填写后关联已有认证账号} userType: {type: string, enum: [INTERNAL, PLATFORM], description: 兼容旧接口,可省略} username: {type: string, minLength: 4, maxLength: 64} password: {type: string, format: password, minLength: 8, maxLength: 64, writeOnly: true} displayName: {type: string, maxLength: 64} phone: {type: string, maxLength: 32} email: {type: string, format: email, maxLength: 128} memberNo: {type: string, maxLength: 64} roleIds: {type: array, items: {type: integer, format: int64}} UpdateInternalUserRequest: type: object required: [displayName, memberNo, roleIds] properties: displayName: {type: string, maxLength: 64} phone: {type: string, maxLength: 32} email: {type: string, format: email, maxLength: 128} memberNo: {type: string, maxLength: 64} roleIds: {type: array, items: {type: integer, format: int64}} ChangeInternalUserStatusRequest: type: object required: [status] properties: status: {type: string, enum: [ACTIVE, DISABLED]} ResetInternalUserPasswordRequest: type: object required: [newPassword] properties: newPassword: {type: string, format: password, minLength: 8, maxLength: 64, writeOnly: true} AssignInternalUserRolesRequest: type: object required: [roleIds] properties: roleIds: {type: array, items: {type: integer, format: int64}} InternalUserResponse: type: object required: [membershipId, userId, authUserId, username, displayName, memberType, status, roleIds] properties: membershipId: {type: integer, format: int64} userId: {type: integer, format: int64} authUserId: {type: integer, format: int64} username: {type: string} displayName: {type: string} phone: {type: string} email: {type: string, format: email} memberType: {type: string, enum: [EMPLOYEE]} memberNo: {type: string} status: {type: string, enum: [ACTIVE, DISABLED]} roleIds: {type: array, items: {type: integer, format: int64}} PlatformManagedUserResponse: type: object required: [membershipId, userId, authUserId, username, displayName, tenantId, tenantName, memberType, status, roleIds, roleNames, protectedAccount] properties: membershipId: {type: string, pattern: '^\d+$'} userId: {type: string, pattern: '^\d+$'} authUserId: {type: string, pattern: '^\d+$'} username: {type: string} displayName: {type: string} phone: {type: string} email: {type: string, format: email} tenantId: {type: string, enum: ['0']} tenantName: {type: string, enum: [平台]} memberType: {type: string, enum: [EMPLOYEE]} memberNo: {type: string} status: {type: string, enum: [ACTIVE, DISABLED]} roleIds: {type: array, items: {type: string, pattern: '^\d+$'}} roleNames: {type: array, items: {type: string}} lastLoginAt: {type: string, format: date-time, nullable: true} protectedAccount: {type: boolean} CreateMemberRequest: type: object required: [username, password, displayName, memberType] properties: username: {type: string, minLength: 4, maxLength: 64} password: {type: string, format: password, minLength: 8, maxLength: 64} displayName: {type: string, maxLength: 64} phone: {type: string, maxLength: 32} email: {type: string, format: email, maxLength: 128} memberType: {type: string, enum: [EMPLOYEE]} memberNo: {type: string} roleIds: type: array description: 初始角色 ID;非空时额外要求 merchant:member:grant-role items: {type: string, pattern: '^\d+$'} UpdateMemberRequest: type: object required: [displayName, memberType] properties: displayName: {type: string, maxLength: 64} phone: {type: string, maxLength: 32} email: {type: string, format: email, maxLength: 128} memberType: {type: string, enum: [EMPLOYEE]} memberNo: {type: string, maxLength: 64} roleIds: type: array description: 完整目标角色集合;空数组表示清空,集合变化时额外要求 merchant:member:grant-role items: {type: string, pattern: '^\d+$'} AddressRequest: type: object required: [addressType, detail] properties: addressType: {type: string, enum: [OPERATING, BILLING, RETURN]} countryCode: {type: string, example: CN} province: {type: string} city: {type: string} district: {type: string} detail: {type: string} postalCode: {type: string} isDefault: {type: boolean} CreateRoleRequest: type: object required: [roleCode, roleName] properties: roleCode: {type: string, example: ORDER_OPERATOR} roleName: {type: string, example: 订单操作员} description: {type: string} CreatePermissionRequest: type: object required: [type, code, name] properties: type: {type: string, enum: [MENU, PAGE, BUTTON, API], example: BUTTON} code: {type: string, example: 'order:firstleg:submit'} name: {type: string, example: 提交头程订单} parentId: {type: integer, format: int64, example: 0} routePath: {type: string} httpMethod: {type: string, enum: [GET, POST, PUT, PATCH, DELETE]} sortNo: {type: integer, example: 10} UpdatePermissionRequest: type: object required: [name] properties: name: {type: string} parentId: {type: integer, format: int64} routePath: {type: string} httpMethod: {type: string, enum: [GET, POST, PUT, PATCH, DELETE]} sortNo: {type: integer} ChangePermissionStatusRequest: type: object required: [status] properties: status: {type: string, enum: [ACTIVE, DISABLED]} AssignRolesRequest: type: object required: [membershipId, roleIds] properties: membershipId: {type: integer, format: int64} roleIds: {type: array, items: {type: integer, format: int64}} GrantPermissionsRequest: type: object required: [roleId, permissionIds] properties: roleId: {type: integer, format: int64} permissionIds: {type: array, items: {type: integer, format: int64}}