Files
2026-07-18 08:36:18 +08:00

394 lines
12 KiB
YAML

openapi: 3.1.0
info:
title: AIOA API
version: 0.4.0
servers:
- url: /api/v1
paths:
/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"
/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:
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 }
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:
CurrentUser:
type: object
required: [id, tenantId, username, displayName, roles]
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 }
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 }