Files
AIOA/contracts/openapi/aioa-v1.yaml
T
2026-07-19 07:55:12 +08:00

770 lines
28 KiB
YAML

openapi: 3.1.0
info:
title: AIOA API
version: 0.17.0
servers:
- url: /api/v1
security:
- bearerAuth: []
paths:
/admin/process-configuration/forms:
get: { operationId: listFormVersions, summary: 查询表单版本与发布状态, responses: { "200": { description: 表单版本列表 } } }
post: { operationId: createFormVersion, summary: 创建安全校验后的表单草稿版本, responses: { "200": { description: 已创建表单草稿版本 } } }
/admin/process-configuration/forms/{key}/{version}/publish:
post: { operationId: publishFormVersion, summary: 发布表单版本并退役旧发布版本, parameters: [{ name: key, in: path, required: true, schema: { type: string } }, { name: version, in: path, required: true, schema: { type: integer } }], responses: { "200": { description: 已发布 } } }
/admin/process-configuration/bindings:
get: { operationId: listProcessBindings, summary: 查询业务表单与流程绑定, responses: { "200": { description: 流程绑定列表 } } }
post: { operationId: createProcessBinding, summary: 创建业务流程路由绑定, responses: { "200": { description: 已创建并启用绑定 } } }
/admin/process-configuration/bindings/{id}/status:
put: { operationId: updateProcessBindingStatus, summary: 启用或停用流程绑定, parameters: [{ name: id, in: path, required: true, schema: { type: string, format: uuid } }], responses: { "200": { description: 状态已更新 } } }
/admin/process-configuration/processes/deploy:
post: { operationId: deployProcessTemplate, summary: 校验并部署受约束的可视化流程模板, responses: { "200": { description: Flowable 流程定义已部署 } } }
/admin/process-configuration/processes:
get: { operationId: listProcessTemplates, summary: 查询可重新编辑的可视化流程部署历史, responses: { "200": { description: 流程模板版本列表 } } }
/admin/process-configuration/approver-rules:
get: { operationId: listApproverRules, summary: 查询流程设计器可用的组织审批人规则, responses: { "200": { description: 审批人规则目录 } } }
/admin/organization/departments:
get: { operationId: listAdminDepartments, summary: OA 管理员查询租户部门, responses: { "200": { description: 部门列表 } } }
post: { operationId: createAdminDepartment, summary: OA 管理员创建部门, responses: { "200": { description: 已创建部门 } } }
/admin/organization/roles:
get: { operationId: listAdminRoles, summary: OA 管理员查询租户角色, responses: { "200": { description: 角色列表 } } }
/admin/organization/users:
get: { operationId: listAdminUsers, summary: OA 管理员查询租户用户与任职角色, responses: { "200": { description: 用户列表 } } }
/admin/organization/users/{id}/roles:
put: { operationId: replaceAdminUserRoles, summary: OA 管理员替换用户角色, parameters: [{ name: id, in: path, required: true, schema: { type: string, format: uuid } }], responses: { "200": { description: 角色已更新 } } }
/admin/organization/users/{id}/assignment:
put: { operationId: replaceAdminUserAssignment, summary: OA 管理员替换用户主任职, parameters: [{ name: id, in: path, required: true, schema: { type: string, format: uuid } }], responses: { "200": { description: 任职已更新 } } }
/admin/workflows/definitions:
get: { operationId: listWorkflowDefinitions, summary: 查询流程定义及版本, responses: { "200": { description: 流程定义列表 } } }
/admin/workflows/instances:
get: { operationId: listTenantWorkflowInstances, summary: 查询当前租户流程实例, responses: { "200": { description: 流程实例列表 } } }
/admin/metrics:
get: { operationId: getTenantOperationsMetrics, summary: 查询业务流程推送运行指标, responses: { "200": { description: 聚合运行指标 } } }
/admin/audit-events:
get:
operationId: listRedactedTenantAuditEvents
summary: OA 管理员按租户脱敏查询审计记录
parameters:
- { name: traceId, in: query, schema: { type: string, maxLength: 128 } }
- { name: action, in: query, schema: { type: string, maxLength: 120 } }
- { name: resourceType, in: query, schema: { type: string, maxLength: 120 } }
- { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 200, default: 100 } }
responses:
"200": { description: 当前租户的脱敏审计记录 }
"403": { description: 仅 OA 管理员可查询 }
/devices/register:
post:
operationId: registerCurrentDevice
summary: 注册或刷新当前用户设备会话
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [id, name, platform]
properties:
id: { type: string, format: uuid }
name: { type: string, minLength: 1, maxLength: 200 }
platform: { type: string, enum: [IOS, ANDROID, OTHER] }
appVersion: { type: [string, "null"], maxLength: 64 }
responses:
"200": { description: 已注册的设备会话 }
"401": { description: 设备已被撤销,禁止重新注册 }
/devices:
get:
operationId: listOwnDevices
summary: 查询当前用户的登录设备
responses:
"200": { description: 当前用户设备列表 }
/devices/{id}:
delete:
operationId: revokeOwnDevice
summary: 撤销当前用户的一台设备并使其后续请求失效
parameters:
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
responses:
"200": { description: 已撤销设备 }
"404": { description: 设备不存在或不属于当前用户 }
/devices/{id}/push-token:
put:
operationId: updateCurrentDevicePushToken
summary: 注册、刷新或清除当前设备的 FCM 推送令牌
parameters:
- { name: id, in: path, required: true, schema: { type: string, format: uuid } }
- { name: X-AIOA-Device-Id, in: header, required: true, schema: { type: string, format: uuid } }
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
token: { type: [string, "null"], maxLength: 4096 }
responses:
"200": { description: 推送令牌已更新 }
"403": { description: 路径设备与当前设备不一致 }
/ai/leave-progress-answers:
post:
operationId: answerOwnLeaveProgress
summary: 使用自然语言只读查询本人请假流程进度
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [text, timezone]
properties:
text: { type: string, minLength: 1, maxLength: 2000 }
timezone: { type: string, default: Asia/Shanghai }
selectedRequestId: { type: string, format: uuid }
responses:
"200":
description: 回答或需要用户选择的本人申请候选列表
"400": { $ref: "#/components/responses/BadRequest" }
"502":
description: AI 上游不可用或输出无效
/ai/leave-draft-suggestions:
post:
operationId: suggestLeaveDraft
summary: 将自然语言转换为需要用户确认的请假草稿建议
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [text, timezone]
properties:
text: { type: string, minLength: 1, maxLength: 2000 }
timezone: { type: string, default: Asia/Shanghai }
responses:
"200":
description: 受约束的草稿建议,不执行业务写操作
content:
application/json:
schema: { $ref: "#/components/schemas/AiLeaveDraftSuggestion" }
"400": { $ref: "#/components/responses/BadRequest" }
"502":
description: AI 上游不可用或输出无效
/notifications:
get:
operationId: listOwnNotifications
summary: 查询当前用户站内通知
responses:
"200":
description: 通知列表
content:
application/json:
schema:
type: array
items: { $ref: "#/components/schemas/Notification" }
/notifications/unread-count:
get:
operationId: getUnreadNotificationCount
summary: 查询未读通知数
responses:
"200":
description: 未读数
content:
application/json:
schema:
type: object
required: [unreadCount]
properties:
unreadCount: { type: integer, minimum: 0 }
/notifications/{id}/read:
post:
operationId: markNotificationRead
summary: 标记本人通知已读
parameters:
- name: id
in: path
required: true
schema: { type: string, format: uuid }
responses:
"200":
description: 已读通知
content:
application/json:
schema: { $ref: "#/components/schemas/Notification" }
"404": { $ref: "#/components/responses/NotFound" }
/form-definitions/{formKey}:
get:
operationId: getFormDefinition
summary: 获取版本化表单定义
parameters:
- name: formKey
in: path
required: true
schema: { type: string }
responses:
"200":
description: JSON Schema 与移动端 UI Schema
content:
application/json:
schema:
$ref: "#/components/schemas/FormDefinition"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
/me:
get:
operationId: getCurrentUser
summary: 获取当前登录用户
responses:
"200":
description: 当前用户
content:
application/json:
schema:
$ref: "#/components/schemas/CurrentUser"
"401":
$ref: "#/components/responses/Unauthorized"
/leave-requests:
get:
operationId: listOwnLeaveRequests
summary: 查询当前用户的请假申请
responses:
"200":
description: 申请列表
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/LeaveRequest"
"401":
$ref: "#/components/responses/Unauthorized"
/leave-requests/drafts:
post:
operationId: createLeaveRequestDraft
summary: 创建请假草稿
parameters:
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SaveLeaveDraft"
responses:
"201":
description: 已创建
content:
application/json:
schema:
$ref: "#/components/schemas/LeaveRequest"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"403":
$ref: "#/components/responses/Forbidden"
"409":
$ref: "#/components/responses/Conflict"
/leave-requests/{id}:
parameters:
- name: id
in: path
required: true
schema: { type: string, format: uuid }
get:
operationId: getOwnLeaveRequest
summary: 查询当前用户的单条请假申请
responses:
"200":
description: 请假申请
content:
application/json:
schema:
$ref: "#/components/schemas/LeaveRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
put:
operationId: updateLeaveRequestDraft
summary: 修改当前用户的请假草稿
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SaveLeaveDraft"
responses:
"200":
description: 已修改
content:
application/json:
schema:
$ref: "#/components/schemas/LeaveRequest"
"400":
$ref: "#/components/responses/BadRequest"
"401":
$ref: "#/components/responses/Unauthorized"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/Conflict"
/leave-requests/{id}/submit:
post:
operationId: submitLeaveRequest
summary: 提交请假草稿
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/TransitionRequest"
responses:
"200":
description: 已提交或幂等重放
content:
application/json:
schema:
$ref: "#/components/schemas/LeaveRequest"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/Conflict"
/leave-requests/{id}/withdraw:
post:
operationId: withdrawLeaveRequest
summary: 撤回待审批申请
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/TransitionRequest"
responses:
"200":
description: 已撤回或幂等重放
content:
application/json:
schema:
$ref: "#/components/schemas/LeaveRequest"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/Conflict"
/leave-requests/{id}/timeline:
get:
operationId: getLeaveRequestTimeline
summary: 查询本人申请状态时间线
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
responses:
"200":
description: 状态事件列表
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/LeaveRequestEvent"
"404":
$ref: "#/components/responses/NotFound"
/leave-requests/{id}/attachments/upload-tasks:
post:
operationId: createLeaveAttachmentUpload
summary: 创建附件直传任务
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateAttachmentUpload"
responses:
"201":
description: 已创建上传任务
content:
application/json:
schema:
$ref: "#/components/schemas/AttachmentUpload"
"400": { $ref: "#/components/responses/BadRequest" }
"404": { $ref: "#/components/responses/NotFound" }
"409": { $ref: "#/components/responses/Conflict" }
/leave-requests/{id}/attachments:
get:
operationId: listLeaveAttachments
summary: 查询请假附件
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
responses:
"200":
description: 附件列表
content:
application/json:
schema:
type: array
items: { $ref: "#/components/schemas/LeaveAttachment" }
/leave-requests/{id}/attachments/{attachmentId}/complete:
post:
operationId: completeLeaveAttachmentUpload
summary: 确认附件上传完成
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
- $ref: "#/components/parameters/AttachmentId"
responses:
"200":
description: 附件已就绪
content:
application/json:
schema: { $ref: "#/components/schemas/LeaveAttachment" }
/leave-requests/{id}/attachments/{attachmentId}/download:
get:
operationId: createLeaveAttachmentDownload
summary: 获取附件短期下载地址
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
- $ref: "#/components/parameters/AttachmentId"
responses:
"200":
description: 短期下载地址
content:
application/json:
schema:
type: object
required: [downloadUrl]
properties:
downloadUrl: { type: string, format: uri }
/leave-requests/{id}/attachments/{attachmentId}:
delete:
operationId: deleteLeaveAttachment
summary: 删除草稿附件
parameters:
- $ref: "#/components/parameters/LeaveRequestId"
- $ref: "#/components/parameters/AttachmentId"
responses:
"204": { description: 已删除 }
/approval-tasks:
get:
operationId: listAssignedApprovalTasks
summary: 查询分配给当前用户的审批待办
responses:
"200":
description: 待办列表
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ApprovalTask"
/approval-tasks/{taskId}/approve:
post:
operationId: approveTask
summary: 批准审批任务
parameters:
- $ref: "#/components/parameters/ApprovalTaskId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ApprovalDecision"
responses:
"200":
description: 已批准或幂等重放
content:
application/json:
schema:
$ref: "#/components/schemas/LeaveRequest"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/Conflict"
/approval-tasks/{taskId}/reject:
post:
operationId: rejectTask
summary: 驳回审批任务
parameters:
- $ref: "#/components/parameters/ApprovalTaskId"
- $ref: "#/components/parameters/IdempotencyKey"
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ApprovalDecision"
responses:
"200":
description: 已驳回或幂等重放
content:
application/json:
schema:
$ref: "#/components/schemas/LeaveRequest"
"404":
$ref: "#/components/responses/NotFound"
"409":
$ref: "#/components/responses/Conflict"
components:
securitySchemes:
bearerAuth:
type: oauth2
flows:
authorizationCode:
authorizationUrl: http://localhost:8081/realms/aioa/protocol/openid-connect/auth
tokenUrl: http://localhost:8081/realms/aioa/protocol/openid-connect/token
scopes:
openid: OpenID Connect identity
profile: Basic profile
email: Email address
parameters:
LeaveRequestId:
name: id
in: path
required: true
schema: { type: string, format: uuid }
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
schema:
type: string
minLength: 16
maxLength: 128
ApprovalTaskId:
name: taskId
in: path
required: true
schema: { type: string }
AttachmentId:
name: attachmentId
in: path
required: true
schema: { type: string, format: uuid }
responses:
BadRequest:
description: 请求无效
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
Unauthorized:
description: 未认证
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
Forbidden:
description: 无权操作
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
NotFound:
description: 资源不存在或当前用户不可见
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
Conflict:
description: 幂等键、状态或乐观锁冲突
content:
application/problem+json:
schema:
$ref: "#/components/schemas/Problem"
schemas:
AiLeaveDraftSuggestion:
type: object
required: [suggestion, model, requiresUserConfirmation]
properties:
suggestion:
type: object
required: [assumptions, needsClarification]
properties:
type: { type: [string, "null"], enum: [PERSONAL, SICK, ANNUAL, null] }
startsAt: { type: [string, "null"], format: date-time }
endsAt: { type: [string, "null"], format: date-time }
reason: { type: [string, "null"], maxLength: 2000 }
assumptions:
type: array
items: { type: string }
needsClarification:
type: array
items: { type: string }
model: { type: string }
requiresUserConfirmation: { type: boolean, const: true }
Notification:
type: object
required: [id, type, title, body, createdAt]
properties:
id: { type: string, format: uuid }
type: { type: string }
title: { type: string }
body: { type: string }
resourceType: { type: [string, "null"] }
resourceId: { type: [string, "null"] }
createdAt: { type: string, format: date-time }
readAt: { type: [string, "null"], format: date-time }
CreateAttachmentUpload:
type: object
required: [fileName, contentType, sizeBytes]
properties:
fileName: { type: string, minLength: 1, maxLength: 255 }
contentType:
type: string
enum: [image/jpeg, image/png, application/pdf]
sizeBytes: { type: integer, format: int64, minimum: 1, maximum: 10485760 }
AttachmentUpload:
type: object
required: [attachment, uploadUrl]
properties:
attachment: { $ref: "#/components/schemas/LeaveAttachment" }
uploadUrl: { type: string, format: uri }
LeaveAttachment:
type: object
required: [id, fileName, contentType, sizeBytes, status, createdAt]
properties:
id: { type: string, format: uuid }
fileName: { type: string }
contentType: { type: string }
sizeBytes: { type: integer, format: int64 }
status: { type: string, enum: [PENDING, READY] }
createdAt: { type: string, format: date-time }
completedAt: { type: [string, "null"], format: date-time }
FormDefinition:
type: object
required: [key, version, dataSchema, uiSchema]
properties:
key: { type: string }
version: { type: integer, minimum: 1 }
dataSchema:
type: object
additionalProperties: true
uiSchema:
type: object
additionalProperties: true
CurrentUser:
type: object
required: [id, tenantId, username, displayName, roles, permissions, dataScopes]
properties:
id: { type: string, format: uuid }
tenantId: { type: string, format: uuid }
username: { type: string }
displayName: { type: string }
email:
type: [string, "null"]
format: email
department:
oneOf:
- $ref: "#/components/schemas/OrganizationRef"
- type: "null"
position:
oneOf:
- $ref: "#/components/schemas/OrganizationRef"
- type: "null"
roles:
type: array
uniqueItems: true
items: { type: string }
permissions:
type: array
uniqueItems: true
items:
type: string
enum: [LEAVE_REQUEST_READ_OWN, LEAVE_REQUEST_WRITE_OWN, LEAVE_ATTACHMENT_MANAGE_OWN, NOTIFICATION_READ_OWN, AI_LEAVE_DRAFT_SUGGEST, AI_LEAVE_PROGRESS_READ_OWN, APPROVAL_TASK_READ_ASSIGNED, APPROVAL_TASK_DECIDE_ASSIGNED, AUDIT_READ_TENANT_REDACTED, ORGANIZATION_MANAGE_TENANT, WORKFLOW_READ_TENANT, OPERATIONS_METRICS_READ_TENANT, PROCESS_CONFIGURATION_MANAGE_TENANT]
dataScopes:
type: array
uniqueItems: true
items: { type: string, enum: [OWN, ASSIGNED, TENANT] }
OrganizationRef:
type: object
required: [id, name]
properties:
id: { type: string, format: uuid }
name: { type: string }
SaveLeaveDraft:
type: object
required: [type, startsAt, endsAt, reason, version]
properties:
type:
type: string
enum: [PERSONAL, SICK, ANNUAL]
startsAt: { type: string, format: date-time }
endsAt: { type: string, format: date-time }
reason: { type: string, minLength: 1, maxLength: 2000 }
version: { type: integer, format: int64, minimum: 0 }
LeaveRequest:
type: object
required: [id, applicantId, type, startsAt, endsAt, reason, status, version, createdAt, updatedAt]
properties:
id: { type: string, format: uuid }
applicantId: { type: string, format: uuid }
type:
type: string
enum: [PERSONAL, SICK, ANNUAL]
startsAt: { type: string, format: date-time }
endsAt: { type: string, format: date-time }
reason: { type: string }
status:
type: string
enum: [DRAFT, PENDING, APPROVED, REJECTED, WITHDRAWN]
version: { type: integer, minimum: 0 }
createdAt: { type: string, format: date-time }
updatedAt: { type: string, format: date-time }
processInstanceId:
type: [string, "null"]
processDefinitionId:
type: [string, "null"]
TransitionRequest:
type: object
required: [version]
properties:
version: { type: integer, format: int64, minimum: 0 }
LeaveRequestEvent:
type: object
required: [id, eventType, fromStatus, toStatus, actorId, traceId, occurredAt]
properties:
id: { type: string, format: uuid }
eventType: { type: string }
fromStatus:
type: string
enum: [DRAFT, PENDING, APPROVED, REJECTED, WITHDRAWN]
toStatus:
type: string
enum: [DRAFT, PENDING, APPROVED, REJECTED, WITHDRAWN]
actorId: { type: string, format: uuid }
traceId: { type: string }
occurredAt: { type: string, format: date-time }
ApprovalDecision:
type: object
required: [version]
properties:
version: { type: integer, format: int64, minimum: 0 }
comment:
type: [string, "null"]
maxLength: 1000
ApprovalTask:
type: object
required: [id, name, createdAt, leaveRequest]
properties:
id: { type: string }
name: { type: string }
createdAt: { type: string, format: date-time }
leaveRequest:
$ref: "#/components/schemas/LeaveRequest"
Problem:
type: object
required: [type, title, status, code, traceId]
properties:
type: { type: string, format: uri-reference }
title: { type: string }
status: { type: integer }
detail: { type: string }
code: { type: string }
traceId: { type: string }