307 lines
9.1 KiB
YAML
307 lines
9.1 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: AIOA API
|
|
version: 0.3.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"
|
|
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
|
|
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 }
|
|
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 }
|
|
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 }
|