[feature] migrate to monorepo
Some checks failed
Build Backend / Build Docker Image (push) Successful in 3m33s
Test Backend / test (push) Failing after 31s

This commit is contained in:
CDN 2025-02-21 00:49:20 +08:00
commit 05ddc1f783
Signed by: CDN
GPG key ID: 0C656827F9F80080
267 changed files with 75165 additions and 0 deletions

View file

@ -0,0 +1,70 @@
Page:
in: query
name: page
schema:
type: integer
minimum: 1
default: 1
description: 页码
required: false
PerPage:
in: query
name: per_page
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: 每页记录数
required: false
Language:
in: query
name: lang
schema:
type: string
enum:
- en
- zh-Hans
- zh-Hant
description: 语言代码
required: false
Sort:
in: query
name: sort
schema:
type: string
pattern: '^[a-zA-Z_]+:(asc|desc)$'
examples:
- 'created_at:desc'
description: '排序字段和方向,格式为 field:(asc|desc)'
required: false
Status:
in: query
name: status
schema:
type: string
enum:
- draft
- published
description: 内容状态过滤
required: false
Id:
in: path
name: id
schema:
type: integer
required: true
description: 资源 ID
Slug:
in: path
name: slug
schema:
type: string
required: true
description: 资源 Slug

View file

@ -0,0 +1,67 @@
Unauthorized:
description: 未授权访问
content:
application/json:
schema:
$ref: './schemas.yaml#/Error'
example:
error:
code: UNAUTHORIZED
message: 未授权访问,请先登录
Forbidden:
description: 禁止访问
content:
application/json:
schema:
$ref: './schemas.yaml#/Error'
example:
error:
code: FORBIDDEN
message: 您没有权限执行此操作
NotFound:
description: 资源未找到
content:
application/json:
schema:
$ref: './schemas.yaml#/Error'
example:
error:
code: NOT_FOUND
message: 请求的资源不存在
ValidationError:
description: 参数验证失败
content:
application/json:
schema:
$ref: './schemas.yaml#/Error'
example:
error:
code: VALIDATION_ERROR
message: 参数验证失败
details:
field: 错误描述
TooManyRequests:
description: 请求过多
content:
application/json:
schema:
$ref: './schemas.yaml#/Error'
example:
error:
code: TOO_MANY_REQUESTS
message: 请求过于频繁,请稍后再试
InternalError:
description: 服务器内部错误
content:
application/json:
schema:
$ref: './schemas.yaml#/Error'
example:
error:
code: INTERNAL_ERROR
message: 服务器内部错误,请稍后再试

View file

@ -0,0 +1,375 @@
Response:
type: object
required:
- data
properties:
data: {}
meta:
type: object
properties:
total:
type: integer
description: 总记录数
page:
type: integer
description: 当前页码
per_page:
type: integer
description: 每页记录数
total_pages:
type: integer
description: 总页数
links:
type: object
properties:
self:
type: string
format: uri
first:
type: string
format: uri
last:
type: string
format: uri
prev:
type: string
format: uri
next:
type: string
format: uri
Error:
type: object
required:
- error
properties:
error:
type: object
required:
- code
- message
properties:
code:
type: string
message:
type: string
details:
type: object
User:
type: object
required:
- id
- email
- role
- status
properties:
id:
type: integer
email:
type: string
format: email
role:
type: string
enum:
- admin
- editor
status:
type: string
enum:
- active
- inactive
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
Post:
type: object
required:
- id
- slug
- status
- contents
properties:
id:
type: integer
slug:
type: string
status:
type: string
enum:
- draft
- published
contents:
type: array
items:
$ref: '#/PostContent'
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
PostContent:
type: object
required:
- language_code
- title
- content_markdown
properties:
language_code:
type: string
enum:
- en
- zh-Hans
- zh-Hant
title:
type: string
content_markdown:
type: string
summary:
type: string
meta_keywords:
type: string
meta_description:
type: string
Category:
type: object
required:
- id
- contents
properties:
id:
type: integer
contents:
type: array
items:
$ref: '#/CategoryContent'
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
CategoryContent:
type: object
required:
- language_code
- name
- slug
properties:
language_code:
type: string
enum:
- en
- zh-Hans
- zh-Hant
name:
type: string
description:
type: string
slug:
type: string
Contributor:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
avatar_url:
type: string
format: uri
bio:
type: string
social_links:
type: array
items:
type: object
required:
- type
- value
properties:
type:
type: string
enum:
- WeChat
- Bilibili
- Douyin/TikTok
- Kuaishou
- NCM
- Xiaohongshu
- QQ_Personal
- QQ_Group
- QQ_Channel
- Zhihu
- SinaWeibo
- Feishu/Lark
- DingTalk
- Douban
- CoolAPK
- Tieba
- Keyoxide
- GitHub
- Codeberg
- SourceHut
- Forgejo
- Gitea
- Facebook
- Instagram
- Twitter/X
- Snapchat
- Telegram
- WhatsApp
- LinkedIn
- Reddit
- YouTube
- Pinterest
- Bluesky
- Mastodon
- Fediverse
- Matrix
- XMPP
- IRC
- HomePage
- AFDian
- Paypal
- LiberPay
- Patreon
- Ko-Fi
- Custom
name:
type: string
description: 'Optional name for the social link, required only for Custom type'
value:
type: string
description: The actual link or identifier value
user_id:
type: integer
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
Media:
type: object
required:
- id
- url
- mime_type
- original_name
- storage_id
- size
properties:
id:
type: integer
storage_id:
type: string
description: 存储系统中的唯一标识符
original_name:
type: string
description: 原始文件名
url:
type: string
format: uri
description: 文件访问 URL
mime_type:
type: string
description: 文件的 MIME 类型,图片将被转换为 image/webp
size:
type: integer
format: int64
description: 文件大小(字节)
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
created_by:
type: string
description: 创建者 ID
DailyCategory:
type: object
required:
- id
- contents
properties:
id:
type: integer
contents:
type: array
items:
type: object
required:
- language_code
- name
properties:
language_code:
type: string
enum:
- en
- zh-Hans
- zh-Hant
name:
type: string
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
Daily:
type: object
required:
- id
- category
- image_url
- contents
properties:
id:
type: string
pattern: '^\d{6}$'
examples:
- '250206'
category:
$ref: '#/DailyCategory'
image_url:
type: string
format: uri
contents:
type: array
items:
type: object
required:
- language_code
- quote
properties:
language_code:
type: string
enum:
- en
- zh-Hans
- zh-Hant
quote:
type: string
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time

123
api/schemas/openapi.yaml Normal file
View file

@ -0,0 +1,123 @@
openapi: 3.1.0
info:
title: TSS Rocks API
description: |
TSS Rocks REST API
version: 0.1.0
contact:
name: STARSET Mirror
url: 'https://mirror.starset.fans/about'
servers:
- url: 'https://tss.rocks/api/v1'
description: API v1 endpoints
security:
- BearerAuth: []
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
parameters:
Page:
$ref: './components/parameters.yaml#/Page'
PerPage:
$ref: './components/parameters.yaml#/PerPage'
Language:
$ref: './components/parameters.yaml#/Language'
Sort:
$ref: './components/parameters.yaml#/Sort'
Status:
$ref: './components/parameters.yaml#/Status'
Id:
$ref: './components/parameters.yaml#/Id'
Slug:
$ref: './components/parameters.yaml#/Slug'
responses:
Unauthorized:
$ref: './components/responses.yaml#/Unauthorized'
Forbidden:
$ref: './components/responses.yaml#/Forbidden'
NotFound:
$ref: './components/responses.yaml#/NotFound'
ValidationError:
$ref: './components/responses.yaml#/ValidationError'
TooManyRequests:
$ref: './components/responses.yaml#/TooManyRequests'
InternalError:
$ref: './components/responses.yaml#/InternalError'
schemas:
Response:
$ref: './components/schemas.yaml#/Response'
Error:
$ref: './components/schemas.yaml#/Error'
User:
$ref: './components/schemas.yaml#/User'
Post:
$ref: './components/schemas.yaml#/Post'
PostContent:
$ref: './components/schemas.yaml#/PostContent'
Category:
$ref: './components/schemas.yaml#/Category'
CategoryContent:
$ref: './components/schemas.yaml#/CategoryContent'
Contributor:
$ref: './components/schemas.yaml#/Contributor'
Media:
$ref: './components/schemas.yaml#/Media'
DailyCategory:
$ref: './components/schemas.yaml#/DailyCategory'
Daily:
$ref: './components/schemas.yaml#/Daily'
paths:
/auth/login:
$ref: './paths/auth.yaml#/login'
/auth/logout:
$ref: './paths/auth.yaml#/logout'
/posts:
$ref: './paths/posts.yaml#/posts'
'/posts/{slug}':
$ref: './paths/posts.yaml#/post_slug'
'/posts/{slug}/contributors':
$ref: './paths/posts.yaml#/post_contributors'
/categories:
$ref: './paths/categories.yaml#/categories'
'/categories/{slug}':
$ref: './paths/categories.yaml#/category_slug'
'/categories/{slug}/posts':
$ref: './paths/categories.yaml#/category_posts'
/contributors:
$ref: './paths/contributors.yaml#/contributors'
'/contributors/{id}':
$ref: './paths/contributors.yaml#/contributor_id'
'/contributors/{id}/posts':
$ref: './paths/contributors.yaml#/contributor_posts'
/users:
$ref: './paths/users.yaml#/users'
'/users/{id}':
$ref: './paths/users.yaml#/user_id'
/users/me:
$ref: './paths/users.yaml#/user_me'
/media:
$ref: './paths/media.yaml#/media'
'/media/{id}':
$ref: './paths/media.yaml#/media_id'
/daily:
$ref: './paths/daily.yaml#/daily'
'/daily/{id}':
$ref: './paths/daily.yaml#/daily_id'
tags:
- name: auth
description: 认证相关接口
- name: posts
description: 文章管理接口
- name: categories
description: 分类管理接口
- name: contributors
description: 贡献者管理接口
- name: media
description: 媒体文件管理接口
- name: daily
description: 每日一图管理接口
- name: users
description: 用户管理接口

View file

@ -0,0 +1,54 @@
login:
post:
tags:
- auth
summary: 用户登录
operationId: login
security: [] # 登录接口不需要认证
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
- password
properties:
email:
type: string
format: email
password:
type: string
format: password
responses:
'200':
description: 登录成功
content:
application/json:
schema:
type: object
required:
- token
- user
properties:
token:
type: string
user:
$ref: '../components/schemas.yaml#/User'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'422':
$ref: '../components/responses.yaml#/ValidationError'
logout:
post:
tags:
- auth
summary: 用户登出
operationId: logout
responses:
'204':
description: 登出成功
'401':
$ref: '../components/responses.yaml#/Unauthorized'

View file

@ -0,0 +1,165 @@
categories:
get:
tags:
- categories
summary: 获取分类列表
operationId: listCategories
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Language'
- $ref: '../components/parameters.yaml#/Sort'
responses:
'200':
description: 成功获取分类列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/Category'
post:
tags:
- categories
summary: 创建新分类
operationId: createCategory
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- contents
properties:
contents:
type: array
items:
$ref: '../components/schemas.yaml#/CategoryContent'
responses:
'201':
description: 分类创建成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Category'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'422':
$ref: '../components/responses.yaml#/ValidationError'
category_slug:
parameters:
- $ref: '../components/parameters.yaml#/Slug'
get:
tags:
- categories
summary: 获取分类详情
operationId: getCategory
parameters:
- $ref: '../components/parameters.yaml#/Language'
responses:
'200':
description: 成功获取分类详情
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Category'
'404':
$ref: '../components/responses.yaml#/NotFound'
put:
tags:
- categories
summary: 更新分类
operationId: updateCategory
parameters:
- $ref: '../components/parameters.yaml#/Slug'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
contents:
type: array
items:
$ref: '../components/schemas.yaml#/CategoryContent'
responses:
'200':
description: 分类更新成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Category'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
'422':
$ref: '../components/responses.yaml#/ValidationError'
delete:
tags:
- categories
summary: 删除分类
operationId: deleteCategory
parameters:
- $ref: '../components/parameters.yaml#/Slug'
responses:
'204':
description: 分类删除成功
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
category_posts:
parameters:
- $ref: '../components/parameters.yaml#/Slug'
get:
tags:
- categories
summary: 获取分类下的文章列表
operationId: getCategoryPosts
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Language'
- $ref: '../components/parameters.yaml#/Sort'
- $ref: '../components/parameters.yaml#/Status'
responses:
'200':
description: 成功获取文章列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/Post'
'404':
$ref: '../components/responses.yaml#/NotFound'

View file

@ -0,0 +1,139 @@
contributors:
get:
tags:
- contributors
summary: 获取贡献者列表
operationId: listContributors
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Sort'
responses:
'200':
description: 成功获取贡献者列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/Contributor'
post:
tags:
- contributors
summary: 创建新贡献者
operationId: createContributor
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas.yaml#/Contributor'
responses:
'201':
description: 贡献者创建成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Contributor'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'422':
$ref: '../components/responses.yaml#/ValidationError'
contributor_id:
parameters:
- $ref: '../components/parameters.yaml#/Id'
get:
tags:
- contributors
summary: 获取贡献者详情
operationId: getContributor
responses:
'200':
description: 成功获取贡献者详情
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Contributor'
'404':
$ref: '../components/responses.yaml#/NotFound'
put:
tags:
- contributors
summary: 更新贡献者信息
operationId: updateContributor
parameters:
- $ref: '../components/parameters.yaml#/Id'
requestBody:
required: true
content:
application/json:
schema:
$ref: '../components/schemas.yaml#/Contributor'
responses:
'200':
description: 贡献者信息更新成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Contributor'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
'422':
$ref: '../components/responses.yaml#/ValidationError'
contributor_posts:
parameters:
- $ref: '../components/parameters.yaml#/Id'
get:
tags:
- contributors
summary: 获取贡献者参与的文章列表
operationId: getContributorPosts
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Language'
- $ref: '../components/parameters.yaml#/Sort'
- $ref: '../components/parameters.yaml#/Status'
- name: role
in: query
schema:
type: string
description: 按贡献者角色筛选
responses:
'200':
description: 成功获取文章列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/Post'
'404':
$ref: '../components/responses.yaml#/NotFound'

View file

@ -0,0 +1,170 @@
daily:
get:
tags:
- daily
summary: 获取每日一图列表
operationId: listDaily
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Sort'
- $ref: '../components/parameters.yaml#/Language'
- name: category_id
in: query
schema:
type: integer
description: 按分类ID筛选
responses:
'200':
description: 成功获取每日一图列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/Daily'
post:
tags:
- daily
summary: 创建每日一图
operationId: createDaily
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- id
- category_id
- image_url
- contents
properties:
id:
type: string
pattern: '^\d{6}$'
examples:
- '250206'
category_id:
type: integer
image_url:
type: string
format: uri
contents:
type: array
items:
type: object
required:
- language_code
- quote
properties:
language_code:
type: string
enum:
- en
- zh-Hans
- zh-Hant
quote:
type: string
responses:
'201':
description: 每日一图创建成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Daily'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'422':
$ref: '../components/responses.yaml#/ValidationError'
daily_id:
parameters:
- name: id
in: path
required: true
schema:
type: string
pattern: '^\d{6}$'
examples:
- '250206'
get:
tags:
- daily
summary: 获取每日一图详情
operationId: getDaily
parameters:
- $ref: '../components/parameters.yaml#/Language'
responses:
'200':
description: 成功获取每日一图详情
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Daily'
'404':
$ref: '../components/responses.yaml#/NotFound'
put:
tags:
- daily
summary: 更新每日一图
operationId: updateDaily
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
category_id:
type: integer
image_url:
type: string
format: uri
contents:
type: array
items:
type: object
required:
- language_code
- quote
properties:
language_code:
type: string
enum:
- en
- zh-Hans
- zh-Hant
quote:
type: string
responses:
'200':
description: 每日一图更新成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Daily'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
'422':
$ref: '../components/responses.yaml#/ValidationError'

View file

@ -0,0 +1,111 @@
media:
get:
tags:
- media
summary: 获取媒体文件列表
operationId: listMedia
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Sort'
- name: mime_type
in: query
schema:
type: string
description: 按 MIME 类型筛选
responses:
'200':
description: 成功获取媒体文件列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/Media'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
post:
tags:
- media
summary: 上传媒体文件
description: |
上传媒体文件。对于图片文件:
- 支持的输入格式JPEG、PNG、GIF
- 所有图片将自动转换为 WebP 格式
- 使用无损压缩以保持图片质量
- 保持原始图片尺寸
operationId: uploadMedia
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
description: |
要上传的文件。
对于图片文件,将自动转换为 WebP 格式。
支持的图片格式image/jpeg, image/png, image/gif
responses:
'201':
description: 媒体文件上传成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Media'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'422':
$ref: '../components/responses.yaml#/ValidationError'
media_id:
parameters:
- $ref: '../components/parameters.yaml#/Id'
get:
tags:
- media
summary: 获取媒体文件详情
operationId: getMedia
responses:
'200':
description: 成功获取媒体文件详情
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Media'
'404':
$ref: '../components/responses.yaml#/NotFound'
delete:
tags:
- media
summary: 删除媒体文件
operationId: deleteMedia
parameters:
- $ref: '../components/parameters.yaml#/Id'
responses:
'204':
description: 媒体文件删除成功
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'

View file

@ -0,0 +1,198 @@
posts:
get:
tags:
- posts
summary: 获取文章列表
operationId: listPosts
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Language'
- $ref: '../components/parameters.yaml#/Sort'
- $ref: '../components/parameters.yaml#/Status'
- name: category
in: query
schema:
type: string
description: 按分类筛选
responses:
'200':
description: 成功获取文章列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/Post'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
post:
tags:
- posts
summary: 创建新文章
operationId: createPost
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- slug
- contents
properties:
slug:
type: string
status:
type: string
enum:
- draft
- published
default: draft
contents:
type: array
items:
$ref: '../components/schemas.yaml#/PostContent'
category_ids:
type: array
items:
type: integer
responses:
'201':
description: 文章创建成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Post'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'422':
$ref: '../components/responses.yaml#/ValidationError'
post_slug:
parameters:
- $ref: '../components/parameters.yaml#/Slug'
get:
tags:
- posts
summary: 获取文章详情
operationId: getPost
parameters:
- $ref: '../components/parameters.yaml#/Language'
responses:
'200':
description: 成功获取文章详情
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Post'
'404':
$ref: '../components/responses.yaml#/NotFound'
put:
tags:
- posts
summary: 更新文章
operationId: updatePost
parameters:
- $ref: '../components/parameters.yaml#/Slug'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
status:
type: string
enum:
- draft
- published
contents:
type: array
items:
$ref: '../components/schemas.yaml#/PostContent'
category_ids:
type: array
items:
type: integer
responses:
'200':
description: 文章更新成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/Post'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
'422':
$ref: '../components/responses.yaml#/ValidationError'
delete:
tags:
- posts
summary: 删除文章
operationId: deletePost
parameters:
- $ref: '../components/parameters.yaml#/Slug'
responses:
'204':
description: 文章删除成功
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
post_contributors:
parameters:
- $ref: '../components/parameters.yaml#/Slug'
get:
tags:
- posts
summary: 获取文章贡献者列表
operationId: getPostContributors
responses:
'200':
description: 成功获取贡献者列表
content:
application/json:
schema:
type: object
properties:
data:
type: array
items:
type: object
properties:
contributor:
$ref: '../components/schemas.yaml#/Contributor'
role:
type: string
language_code:
type: string
enum:
- en
- zh-Hans
- zh-Hant
'404':
$ref: '../components/responses.yaml#/NotFound'

View file

@ -0,0 +1,240 @@
users:
get:
tags:
- users
summary: 获取用户列表
operationId: listUsers
parameters:
- $ref: '../components/parameters.yaml#/Page'
- $ref: '../components/parameters.yaml#/PerPage'
- $ref: '../components/parameters.yaml#/Sort'
- name: role
in: query
schema:
type: string
enum:
- admin
- editor
description: 按角色筛选
- name: status
in: query
schema:
type: string
enum:
- active
- inactive
description: 按状态筛选
- name: email
in: query
schema:
type: string
description: 按邮箱搜索
responses:
'200':
description: 成功获取用户列表
content:
application/json:
schema:
allOf:
- $ref: '../components/schemas.yaml#/Response'
- type: object
properties:
data:
type: array
items:
$ref: '../components/schemas.yaml#/User'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
post:
tags:
- users
summary: 创建新用户
operationId: createUser
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
- password
- role
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
role:
type: string
enum:
- admin
- editor
responses:
'201':
description: 用户创建成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/User'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'422':
$ref: '../components/responses.yaml#/ValidationError'
user_id:
parameters:
- name: id
in: path
required: true
schema:
type: integer
get:
tags:
- users
summary: 获取用户详情
operationId: getUser
responses:
'200':
description: 成功获取用户详情
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/User'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
put:
tags:
- users
summary: 更新用户信息
operationId: updateUser
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
role:
type: string
enum:
- admin
- editor
status:
type: string
enum:
- active
- inactive
responses:
'200':
description: 用户更新成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/User'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
'422':
$ref: '../components/responses.yaml#/ValidationError'
delete:
tags:
- users
summary: 删除用户
operationId: deleteUser
responses:
'204':
description: 用户删除成功
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'403':
$ref: '../components/responses.yaml#/Forbidden'
'404':
$ref: '../components/responses.yaml#/NotFound'
'422':
description: 验证错误,例如用户还有关联的内容
content:
application/json:
schema:
$ref: '../components/schemas.yaml#/Error'
user_me:
get:
tags:
- users
summary: 获取当前用户信息
operationId: getCurrentUser
responses:
'200':
description: 成功获取当前用户信息
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/User'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
put:
tags:
- users
summary: 更新当前用户信息
operationId: updateCurrentUser
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
email:
type: string
format: email
current_password:
type: string
new_password:
type: string
minLength: 8
responses:
'200':
description: 用户信息更新成功
content:
application/json:
schema:
type: object
properties:
data:
$ref: '../components/schemas.yaml#/User'
'401':
$ref: '../components/responses.yaml#/Unauthorized'
'422':
$ref: '../components/responses.yaml#/ValidationError'