mach-cms的前台,用vue写的
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

820 lines
19 KiB

openapi: 3.1.0
info:
title: Mach-CMS API
description: |
Mach-CMS 后端 API 规范。前后端契约文件,任何接口变更必须同步修改此文件。
- 所有业务接口返回统一包装体 `Response<T>`
- 列表查询返回 `PageResult<T>`
- 认证方式:JWT Bearer Token
- 时间格式:ISO-8601(`2024-01-15T08:30:00Z`)
version: 0.1.0
contact:
name: Mach-CMS Team
servers:
- url: http://localhost:8080/api
description: 本地开发环境
security:
- bearerAuth: []
tags:
- name: Auth
description: 认证与授权
- name: Public
description: 公开接口(无需认证)
- name: Article
description: 文章(前台只读)
- name: ArticleAdmin
description: 文章管理(需 ADMIN/EDITOR)
- name: Tag
description: 标签(前台只读)
- name: TagAdmin
description: 标签管理(需 ADMIN)
- name: Media
description: 媒体文件上传
- name: Search
description: 全文搜索
- name: User
description: 用户管理(需 ADMIN)
paths:
# ==================== Public ====================
/public/health:
get:
tags: [Public]
summary: 健康检查
security: []
responses:
'200':
description: 服务正常
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseString'
example:
code: 0
message: success
data: UP
# ==================== Auth ====================
/auth/register:
post:
tags: [Auth]
summary: 用户注册
security: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegisterRequest'
responses:
'200':
description: 注册成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseTokenPair'
/auth/login:
post:
tags: [Auth]
summary: 用户登录
security: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LoginRequest'
responses:
'200':
description: 登录成功,返回双 Token
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseTokenPair'
/auth/refresh:
post:
tags: [Auth]
summary: 刷新 Access Token
security: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RefreshTokenRequest'
responses:
'200':
description: 刷新成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseTokenPair'
/auth/logout:
post:
tags: [Auth]
summary: 退出登录(吊销 Refresh Token)
responses:
'200':
description: 退出成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseVoid'
# ==================== Article (Public) ====================
/articles:
get:
tags: [Article]
summary: 文章列表(分页)
security: []
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: size
in: query
schema:
type: integer
default: 10
maximum: 100
- name: status
in: query
schema:
$ref: '#/components/schemas/ArticleStatus'
default: PUBLISHED
- name: tag
in: query
description: 标签 slug 过滤
schema:
type: string
responses:
'200':
description: 文章列表
content:
application/json:
schema:
$ref: '#/components/schemas/ResponsePageArticleListItem'
/articles/{slug}:
get:
tags: [Article]
summary: 文章详情(按 slug)
security: []
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: 文章详情
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseArticleDetail'
'404':
description: 文章不存在
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseVoid'
/articles/search:
get:
tags: [Search]
summary: 全文搜索文章
security: []
parameters:
- name: q
in: query
required: true
description: 搜索关键词
schema:
type: string
minLength: 1
maxLength: 100
- name: page
in: query
schema:
type: integer
default: 1
- name: size
in: query
schema:
type: integer
default: 10
maximum: 50
responses:
'200':
description: 搜索结果
content:
application/json:
schema:
$ref: '#/components/schemas/ResponsePageArticleListItem'
# ==================== ArticleAdmin ====================
/admin/articles:
post:
tags: [ArticleAdmin]
summary: 创建文章
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ArticleCreateRequest'
responses:
'200':
description: 创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseArticleDetail'
/admin/articles/{id}:
put:
tags: [ArticleAdmin]
summary: 更新文章
parameters:
- name: id
in: path
required: true
schema:
type: integer
format: int64
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ArticleUpdateRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseArticleDetail'
delete:
tags: [ArticleAdmin]
summary: 删除文章
parameters:
- name: id
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: 删除成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseVoid'
/admin/articles/{id}/publish:
patch:
tags: [ArticleAdmin]
summary: 发布文章(状态机:DRAFT → PUBLISHED)
parameters:
- name: id
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: 发布成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseArticleDetail'
/admin/articles/{id}/archive:
patch:
tags: [ArticleAdmin]
summary: 归档文章
parameters:
- name: id
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: 归档成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseArticleDetail'
# ==================== Tag (Public) ====================
/tags:
get:
tags: [Tag]
summary: 标签列表(带文章计数)
security: []
responses:
'200':
description: 标签列表
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseListTagWithCount'
# ==================== TagAdmin ====================
/admin/tags:
post:
tags: [TagAdmin]
summary: 创建标签
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TagCreateRequest'
responses:
'200':
description: 创建成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseTag'
/admin/tags/{id}:
put:
tags: [TagAdmin]
summary: 更新标签
parameters:
- name: id
in: path
required: true
schema:
type: integer
format: int64
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TagUpdateRequest'
responses:
'200':
description: 更新成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseTag'
delete:
tags: [TagAdmin]
summary: 删除标签
parameters:
- name: id
in: path
required: true
schema:
type: integer
format: int64
responses:
'200':
description: 删除成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseVoid'
# ==================== Media ====================
/media/upload:
post:
tags: [Media]
summary: 上传文件
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
description: 文件内容
directory:
type: string
default: images
description: 存储目录
responses:
'200':
description: 上传成功
content:
application/json:
schema:
$ref: '#/components/schemas/ResponseStoredFile'
# ==================== User ====================
/admin/users:
get:
tags: [User]
summary: 用户列表(分页)
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: size
in: query
schema:
type: integer
default: 20
responses:
'200':
description: 用户列表
content:
application/json:
schema:
$ref: '#/components/schemas/ResponsePageUserInfo'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
在请求头中携带 `Authorization: Bearer <access_token>`。
Access Token 有效期 15 分钟,过期后用 Refresh Token 调用 `/auth/refresh` 换取新的 Access Token。
schemas:
# ---------- 通用包装体 ----------
Response:
type: object
properties:
code:
type: integer
description: 0 表示成功,非 0 为业务错误码
message:
type: string
data:
description: 业务数据,类型由具体接口决定
required: [code, message]
PageResult:
type: object
properties:
list:
type: array
items: {}
total:
type: integer
format: int64
page:
type: integer
size:
type: integer
totalPages:
type: integer
required: [list, total, page, size, totalPages]
# ---------- 枚举 ----------
ArticleStatus:
type: string
enum: [DRAFT, PUBLISHED, ARCHIVED]
description: |
- DRAFT: 草稿,仅后台可见
- PUBLISHED: 已发布,前台可见
- ARCHIVED: 已归档,前台不可见但保留数据
UserRole:
type: string
enum: [ADMIN, EDITOR, VISITOR]
# ---------- Auth ----------
RegisterRequest:
type: object
properties:
username:
type: string
minLength: 3
maxLength: 50
password:
type: string
minLength: 6
maxLength: 100
email:
type: string
format: email
required: [username, password]
LoginRequest:
type: object
properties:
username:
type: string
password:
type: string
required: [username, password]
RefreshTokenRequest:
type: object
properties:
refreshToken:
type: string
required: [refreshToken]
TokenPair:
type: object
properties:
accessToken:
type: string
refreshToken:
type: string
expiresIn:
type: integer
description: Access Token 有效期(秒)
required: [accessToken, refreshToken, expiresIn]
# ---------- Article ----------
ArticleCreateRequest:
type: object
properties:
title:
type: string
maxLength: 200
summary:
type: string
maxLength: 500
content:
type: string
coverImage:
type: string
description: 封面图 URL
tagIds:
type: array
items:
type: integer
format: int64
required: [title, content]
ArticleUpdateRequest:
type: object
properties:
title:
type: string
maxLength: 200
summary:
type: string
maxLength: 500
content:
type: string
coverImage:
type: string
tagIds:
type: array
items:
type: integer
format: int64
required: [title, content]
ArticleListItem:
type: object
properties:
id:
type: integer
format: int64
title:
type: string
slug:
type: string
summary:
type: string
coverImage:
type: string
status:
$ref: '#/components/schemas/ArticleStatus'
publishedAt:
type: string
format: date-time
createdAt:
type: string
format: date-time
authorName:
type: string
tagNames:
type: array
items:
type: string
required: [id, title, slug, status, createdAt, authorName, tagNames]
ArticleDetail:
type: object
properties:
id:
type: integer
format: int64
title:
type: string
slug:
type: string
summary:
type: string
content:
type: string
coverImage:
type: string
status:
$ref: '#/components/schemas/ArticleStatus'
viewCount:
type: integer
format: int64
publishedAt:
type: string
format: date-time
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
authorName:
type: string
tagNames:
type: array
items:
type: string
required: [id, title, slug, content, status, viewCount, createdAt, updatedAt, authorName, tagNames]
# ---------- Tag ----------
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
slug:
type: string
description:
type: string
articleCount:
type: integer
description: 关联文章数量(查询时计算)
createdAt:
type: string
format: date-time
required: [id, name, slug, articleCount, createdAt]
TagCreateRequest:
type: object
properties:
name:
type: string
maxLength: 50
description:
type: string
maxLength: 200
required: [name]
TagUpdateRequest:
type: object
properties:
name:
type: string
maxLength: 50
description:
type: string
maxLength: 200
required: [name]
# ---------- Media ----------
StoredFile:
type: object
properties:
originalName:
type: string
storedPath:
type: string
url:
type: string
size:
type: integer
format: int64
contentType:
type: string
required: [originalName, storedPath, url, size]
# ---------- User ----------
UserInfo:
type: object
properties:
id:
type: integer
format: int64
username:
type: string
email:
type: string
avatar:
type: string
role:
$ref: '#/components/schemas/UserRole'
enabled:
type: boolean
createdAt:
type: string
format: date-time
required: [id, username, role, enabled, createdAt]
# ---------- 包装体实例化 ----------
ResponseString:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
type: string
ResponseVoid:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
type: "null"
ResponseTokenPair:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
$ref: '#/components/schemas/TokenPair'
ResponseArticleDetail:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
$ref: '#/components/schemas/ArticleDetail'
ResponsePageArticleListItem:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
allOf:
- $ref: '#/components/schemas/PageResult'
properties:
list:
type: array
items:
$ref: '#/components/schemas/ArticleListItem'
ResponseTag:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
$ref: '#/components/schemas/Tag'
ResponseListTagWithCount:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
type: array
items:
$ref: '#/components/schemas/Tag'
ResponseStoredFile:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
$ref: '#/components/schemas/StoredFile'
ResponsePageUserInfo:
allOf:
- $ref: '#/components/schemas/Response'
properties:
data:
allOf:
- $ref: '#/components/schemas/PageResult'
properties:
list:
type: array
items:
$ref: '#/components/schemas/UserInfo'