This commit is contained in:
2026-08-03 13:24:06 +08:00
45 changed files with 1479 additions and 403 deletions
+211 -28
View File
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: Baiyue IAM API / 百悦身份与权限 API
description: 业务成功和失败均使用 HTTP 200;仅响应体 code 为字符串 "200" 时表示成功,其他 code 表示失败。鉴权和协议层异常仍使用真实 HTTP 状态码。Tenant, member, role, menu, page, button and API permission management.
description: Tenant, member, role, menu, page, button and API permission management. / 租户、成员、角色、菜单、页面、按钮和 API 权限管理。
version: 1.0.1
servers:
- url: /
@@ -21,7 +21,7 @@ paths:
get:
tags: [Platform Tenant / 平台租户]
summary: 查询企业客户列表
description: 分页查询商户企业客户,需要 `platform:customer:list` 权限。
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}}
@@ -33,8 +33,10 @@ paths:
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 / 创建企业租户
@@ -45,8 +47,10 @@ paths:
application/json:
schema: {$ref: '#/components/schemas/RegisterRequest'}
responses:
'200': {$ref: '#/components/responses/Success'}
'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 资源]
@@ -66,9 +70,11 @@ paths:
get:
tags: [Platform Tenant / 平台租户]
summary: 查询企业客户档案
description: 需要独立的 `platform:customer:view` 权限,返回完整联系方式。
responses:
'200': {$ref: '#/components/responses/Success'}
'200': {$ref: '#/components/responses/TenantSuccess'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
put:
tags: [Platform Tenant / 平台租户]
summary: 编辑企业客户档案
@@ -78,8 +84,40 @@ paths:
application/json:
schema: {$ref: '#/components/schemas/UpdateTenantRequest'}
responses:
'200': {$ref: '#/components/responses/Success'}
'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}/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'}
@@ -92,8 +130,11 @@ paths:
application/json:
schema: {$ref: '#/components/schemas/ChangeTenantStatusRequest'}
responses:
'200': {$ref: '#/components/responses/Success'}
'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 资源]
@@ -130,6 +171,8 @@ paths:
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/reviews/{id}/reject:
post:
tags: [Platform Tenant / 平台租户]
@@ -145,6 +188,8 @@ paths:
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 资源]
@@ -234,7 +279,9 @@ paths:
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'}
@@ -248,7 +295,10 @@ paths:
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'}
@@ -262,7 +312,9 @@ paths:
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'}
@@ -276,7 +328,9 @@ paths:
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'}
@@ -295,7 +349,9 @@ paths:
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 / 商户企业]
@@ -305,6 +361,7 @@ paths:
'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 / 更新当前企业资料
@@ -315,7 +372,9 @@ paths:
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 / 商户企业]
@@ -326,7 +385,7 @@ paths:
post:
tags: [Merchant Tenant / 商户企业]
summary: Add enterprise member / 新增企业成员
description: Attach an existing IAM user to the current tenant. / 将已有 IAM 用户加入当前企业。
description: 新增基础资料需要 merchant:member:create;roleIds 非空时还必须具有 merchant:member:grant-role,否则返回 403/A0403。空数组表示不分配角色。
requestBody:
required: true
content:
@@ -334,7 +393,38 @@ paths:
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 资源]
@@ -352,6 +442,7 @@ paths:
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:
@@ -380,7 +471,9 @@ paths:
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]
@@ -395,6 +488,7 @@ paths:
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:
@@ -416,7 +510,9 @@ paths:
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]
@@ -431,6 +527,7 @@ paths:
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:
@@ -447,7 +544,9 @@ paths:
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: 删除未绑定的自定义权限资源
@@ -455,6 +554,7 @@ paths:
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'}
@@ -469,7 +569,9 @@ paths:
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'}
components:
securitySchemes:
bearerAuth:
@@ -502,7 +604,7 @@ components:
in: path
required: true
description: 企业客户租户 ID
schema: {type: integer, format: int64, minimum: 1}
schema: {type: string, pattern: '^\d+$'}
PermissionId:
name: permissionId
in: path
@@ -511,14 +613,19 @@ components:
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 or tenant 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: '200', description: 200 表示成功,其他值表示业务失败}
code: {type: string, example: '00000'}
message: {type: string, example: Success}
data: {}
requestId: {type: string}
@@ -547,6 +654,12 @@ components:
size: {type: integer, format: int64, minimum: 1}
total: {type: integer, format: int64, minimum: 0}
pages: {type: integer, format: int64, minimum: 0}
TenantApiResponse:
allOf:
- {$ref: '#/components/schemas/ApiResponse'}
- type: object
properties:
data: {$ref: '#/components/schemas/TenantResponse'}
InternalUserListApiResponse:
allOf:
- {$ref: '#/components/schemas/ApiResponse'}
@@ -563,7 +676,7 @@ components:
type: object
required: [id, tenantCode, tenantName, status]
properties:
id: {type: integer, format: int64}
id: {type: string, pattern: '^\d+$', example: '190000000000000001'}
tenantCode: {type: string}
tenantName: {type: string}
status: {type: string, enum: [PROFILE_REQUIRED, PENDING, ACTIVE, REJECTED, DISABLED]}
@@ -572,12 +685,58 @@ components:
contactName: {type: string}
contactPhone: {type: string}
contactEmail: {type: string, format: email}
servicePackage: {type: string, maxLength: 64}
creditDays: {type: integer, minimum: 0}
salesPerson: {type: string, maxLength: 64}
businessAddress: {type: string, maxLength: 255}
remark: {type: string, maxLength: 500}
createdAt: {type: string, format: date-time}
contactWechat: {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}
certificateNo: {type: string}
documentUrl: {type: string}
validFrom: {type: string, format: date}
validTo: {type: string, format: date}
status: {type: string}
reviewComment: {type: string}
RegisterRequest:
type: object
required: [tenantName, legalName, unifiedSocialCreditCode, contactName, contactPhone]
@@ -588,11 +747,15 @@ components:
contactName: {type: string, example: 李四}
contactPhone: {type: string, example: '13800138000'}
contactEmail: {type: string, format: email, example: contact@example.com}
servicePackage: {type: string, maxLength: 64, example: 标准版}
creditDays: {type: integer, minimum: 0, example: 30}
salesPerson: {type: string, maxLength: 64, example: 李四}
businessAddress: {type: string, maxLength: 255}
remark: {type: string, maxLength: 500}
contactWechat: {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}
UpdateProfileRequest:
type: object
required: [tenantName, legalName, contactName, contactPhone]
@@ -611,11 +774,15 @@ components:
contactName: {type: string}
contactPhone: {type: string}
contactEmail: {type: string, format: email}
servicePackage: {type: string, maxLength: 64}
creditDays: {type: integer, minimum: 0}
salesPerson: {type: string, maxLength: 64}
businessAddress: {type: string, maxLength: 255}
remark: {type: string, maxLength: 500}
contactWechat: {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}$'}
registeredAddress: {type: string, maxLength: 500}
internalRemark: {type: string, maxLength: 1000}
ChangeTenantStatusRequest:
type: object
required: [status]
@@ -707,9 +874,25 @@ components:
displayName: {type: string, maxLength: 64}
phone: {type: string, maxLength: 32}
email: {type: string, format: email, maxLength: 128}
memberType: {type: string, enum: [OWNER, ADMIN, EMPLOYEE]}
memberType: {type: string, enum: [EMPLOYEE]}
memberNo: {type: string}
roleIds: {type: array, items: {type: integer, format: int64}}
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]