本文档详细介绍 Personal Blog 博客系统的所有 API 接口。
版本: v1.4.0
更新日期: 2026-02-17
基础路径: /api
- Content-Type:
application/json - 认证方式: Bearer Token (JWT)
所有接口统一返回以下格式:
interface ApiResponse<T> {
success: boolean;
data?: T;
error?: {
code: string;
message: string;
};
}需要认证的接口需在请求头中携带 Token:
Authorization: Bearer <your_jwt_token>
interface PaginationParams {
page?: number; // 页码,默认 1
limit?: number; // 每页数量,默认 10
sort?: string; // 排序字段
order?: 'asc' | 'desc'; // 排序方向
}
interface PaginatedResponse<T> {
items: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}| 错误码 | 说明 |
|---|---|
UNAUTHORIZED |
未授权,请先登录 |
FORBIDDEN |
无权限访问 |
NOT_FOUND |
资源不存在 |
VALIDATION_ERROR |
参数验证失败 |
DUPLICATE_ENTRY |
数据重复 |
RATE_LIMITED |
请求过于频繁 |
INTERNAL_ERROR |
服务器内部错误 |
POST /api/auth/register
请求体:
{
"email": "user@example.com",
"password": "password123",
"username": "username"
}响应:
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"username": "username"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}POST /api/auth/login
请求体:
{
"email": "user@example.com",
"password": "password123"
}响应:
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"username": "username",
"avatar": "https://...",
"role": "user"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}GET /api/auth/github
重定向到 GitHub 授权页面。
GET /api/auth/github/callback?code=xxx
响应: 重定向到前端并携带 Token
POST /api/auth/send-verification-code
请求体:
{
"email": "user@example.com",
"type": "register" | "reset_password"
}POST /api/auth/reset-password
请求体:
{
"email": "user@example.com",
"code": "123456",
"newPassword": "newpassword123"
}GET /api/auth/me
需要认证: 是
响应:
{
"success": true,
"data": {
"id": 1,
"email": "user@example.com",
"username": "username",
"avatar": "https://...",
"bio": "个人简介",
"role": "user",
"isEmailVerified": true,
"createdAt": "2024-01-01T00:00:00Z"
}
}PUT /api/auth/password
需要认证: 是
请求体:
{
"currentPassword": "oldpassword",
"newPassword": "newpassword123"
}GET /api/posts
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| page | number | 页码 |
| limit | number | 每页数量 |
| category | string | 分类 slug |
| column | string | 专栏 slug |
| tag | string | 标签 slug |
| status | string | 状态 (published/draft),管理员可用 |
| search | string | 搜索关键词 |
响应:
{
"success": true,
"data": {
"items": [
{
"id": 1,
"title": "文章标题",
"slug": "article-slug",
"excerpt": "文章摘要",
"coverImage": "https://...",
"author": {
"id": 1,
"username": "作者名",
"avatar": "https://..."
},
"category": {
"id": 1,
"name": "分类名",
"slug": "category-slug"
},
"column": {
"id": 1,
"name": "专栏名"
},
"tags": [
{ "id": 1, "name": "标签名", "slug": "tag-slug" }
],
"isPinned": false,
"isPasswordProtected": false,
"viewCount": 100,
"likeCount": 10,
"commentCount": 5,
"publishedAt": "2024-01-01T00:00:00Z",
"createdAt": "2024-01-01T00:00:00Z"
}
],
"total": 100,
"page": 1,
"limit": 10,
"totalPages": 10
}
}GET /api/posts/:slug
响应:
{
"success": true,
"data": {
"id": 1,
"title": "文章标题",
"slug": "article-slug",
"content": "Markdown 内容",
"excerpt": "文章摘要",
"coverImage": "https://...",
"author": {
"id": 1,
"username": "作者名",
"avatar": "https://...",
"bio": "作者简介"
},
"category": {
"id": 1,
"name": "分类名",
"slug": "category-slug"
},
"column": {
"id": 1,
"name": "专栏名",
"description": "专栏描述"
},
"tags": [
{ "id": 1, "name": "标签名", "slug": "tag-slug" }
],
"isPinned": false,
"isPasswordProtected": false,
"viewCount": 100,
"likeCount": 10,
"commentCount": 5,
"seoTitle": "SEO 标题",
"seoDescription": "SEO 描述",
"seoKeywords": "关键词1,关键词2",
"publishedAt": "2024-01-01T00:00:00Z",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-02T00:00:00Z"
}
}POST /api/posts
需要认证: 是 (管理员)
请求体:
{
"title": "文章标题",
"slug": "article-slug",
"content": "Markdown 内容",
"excerpt": "文章摘要",
"coverImage": "https://...",
"categoryId": 1,
"columnId": 1,
"tagIds": [1, 2, 3],
"status": "published",
"isPinned": false,
"isPasswordProtected": false,
"password": "可选密码",
"seoTitle": "SEO 标题",
"seoDescription": "SEO 描述",
"seoKeywords": "关键词1,关键词2"
}PUT /api/posts/:id
需要认证: 是 (管理员)
请求体: 同创建文章
DELETE /api/posts/:id
需要认证: 是 (管理员)
POST /api/posts/:id/verify-password
请求体:
{
"password": "文章密码"
}响应:
{
"success": true,
"data": {
"valid": true,
"content": "文章内容"
}
}GET /api/posts/hot
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| limit | number | 返回数量,默认 10 |
响应:
{
"success": true,
"data": [
{
"id": 1,
"title": "文章标题",
"slug": "article-slug",
"viewCount": 1000,
"likeCount": 50,
"coverImage": "https://..."
}
]
}GET /api/posts/:id/related
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| limit | number | 返回数量,默认 5 |
响应:
{
"success": true,
"data": [
{
"id": 2,
"title": "相关文章标题",
"slug": "related-slug",
"excerpt": "文章摘要",
"coverImage": "https://...",
"viewCount": 100,
"publishedAt": "2024-01-01T00:00:00Z"
}
]
}GET /api/posts/:id/neighbors
响应:
{
"success": true,
"data": {
"prev": {
"id": 1,
"title": "上一篇文章",
"slug": "prev-slug"
},
"next": {
"id": 3,
"title": "下一篇文章",
"slug": "next-slug"
}
}
}PUT /api/posts/:id/pin
需要认证: 是 (管理员)
请求体:
{
"isPinned": true
}POST /api/posts/:id/like
需要认证: 是
响应:
{
"success": true,
"data": {
"liked": true,
"likeCount": 11
}
}DELETE /api/posts/:id/like
需要认证: 是
POST /api/posts/:id/favorite
需要认证: 是
DELETE /api/posts/:id/favorite
需要认证: 是
GET /api/posts/:id/status
需要认证: 是
响应:
{
"success": true,
"data": {
"liked": true,
"favorited": false
}
}POST /api/posts/:id/history
需要认证: 是
GET /api/posts/history
需要认证: 是
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| page | number | 页码 |
| limit | number | 每页数量 |
GET /api/posts/search
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| q | string | 搜索关键词 |
| page | number | 页码 |
| limit | number | 每页数量 |
GET /api/columns
响应:
{
"success": true,
"data": [
{
"id": 1,
"name": "专栏名称",
"slug": "column-slug",
"description": "专栏描述",
"coverImage": "https://...",
"postCount": 10,
"viewCount": 1000,
"likeCount": 50,
"status": "active"
}
]
}GET /api/columns/:slug
GET /api/columns/:slug/posts
POST /api/columns
需要认证: 是 (管理员)
PUT /api/columns/:id
需要认证: 是 (管理员)
DELETE /api/columns/:id
需要认证: 是 (管理员)
POST /api/columns/:id/refresh-stats
需要认证: 是 (管理员)
GET /api/comments/post/:postId
响应:
{
"success": true,
"data": [
{
"id": 1,
"content": "评论内容",
"user": {
"id": 1,
"username": "用户名",
"avatar": "https://..."
},
"isAdmin": false,
"likeCount": 5,
"replies": [
{
"id": 2,
"content": "回复内容",
"user": { "id": 2, "username": "回复者" },
"replyTo": { "id": 1, "username": "被回复者" },
"likeCount": 2
}
],
"createdAt": "2024-01-01T00:00:00Z"
}
]
}POST /api/comments
需要认证: 是
请求体:
{
"postId": 1,
"content": "评论内容",
"parentId": null,
"replyToUserId": null
}DELETE /api/comments/:id
需要认证: 是
POST /api/comments/:id/like
需要认证: 是
GET /api/categories
响应:
{
"success": true,
"data": [
{
"id": 1,
"name": "分类名称",
"slug": "category-slug",
"description": "分类描述",
"postCount": 10
}
]
}
}POST /api/categories
需要认证: 是 (管理员)
PUT /api/categories/:id
需要认证: 是 (管理员)
DELETE /api/categories/:id
需要认证: 是 (管理员)
GET /api/tags
POST /api/tags
需要认证: 是 (管理员)
PUT /api/tags/:id
需要认证: 是 (管理员)
DELETE /api/tags/:id
需要认证: 是 (管理员)
GET /api/users/:id/profile
PUT /api/users/profile
需要认证: 是
请求体:
{
"username": "新用户名",
"avatar": "https://...",
"bio": "个人简介"
}GET /api/users/:id/posts
GET /api/users/favorites
需要认证: 是
GET /api/users/likes
需要认证: 是
GET /api/users/comments
需要认证: 是
GET /api/users/search
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| q | string | 搜索关键词 |
DELETE /api/users/account
需要认证: 是
GET /api/notifications
需要认证: 是
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| type | string | 通知类型 |
| isRead | boolean | 是否已读 |
| page | number | 页码 |
| limit | number | 每页数量 |
GET /api/notifications/unread-count
需要认证: 是
PUT /api/notifications/:id/read
需要认证: 是
PUT /api/notifications/read-all
需要认证: 是
GET /api/users/notification-settings
需要认证: 是
PUT /api/users/notification-settings
需要认证: 是
请求体:
{
"commentNotification": true,
"likeNotification": true,
"followNotification": true,
"systemNotification": true,
"doNotDisturb": false,
"doNotDisturbStart": "22:00",
"doNotDisturbEnd": "08:00",
"digestFrequency": "daily"
}GET /api/messages/threads
需要认证: 是
GET /api/messages/threads/:threadId
需要认证: 是
POST /api/messages
需要认证: 是
请求体:
{
"recipientId": 2,
"content": "消息内容"
}PUT /api/messages/:id/read
需要认证: 是
DELETE /api/messages/:id
需要认证: 是
GET /api/users/message-settings
需要认证: 是
PUT /api/users/message-settings
需要认证: 是
请求体:
{
"allowStrangers": false
}GET /api/admin/dashboard
需要认证: 是 (管理员)
响应:
{
"success": true,
"data": {
"totalPosts": 100,
"totalUsers": 50,
"totalComments": 200,
"totalViews": 10000,
"recentPosts": [...],
"recentComments": [...]
}
}GET /api/admin/users
PUT /api/admin/users/:id/status
PUT /api/admin/users/:id/role
DELETE /api/admin/users/:id
需要认证: 是 (管理员)
GET /api/admin/comments
PUT /api/admin/comments/:id/status
DELETE /api/admin/comments/:id
需要认证: 是 (管理员)
GET /api/admin/config
PUT /api/admin/config
需要认证: 是 (管理员)
POST /api/admin/notifications
需要认证: 是 (管理员)
请求体:
{
"title": "通知标题",
"content": "通知内容",
"type": "info",
"isActive": true,
"showOnHome": true
}GET /api/config/public
响应:
{
"success": true,
"data": {
"siteName": "博客名称",
"siteDescription": "博客描述",
"siteKeywords": "关键词",
"footerText": "页脚文字",
"socialLinks": {
"github": "https://github.com/...",
"twitter": "https://twitter.com/..."
}
}
}POST /api/upload
需要认证: 是
请求: multipart/form-data
| 字段 | 类型 | 说明 |
|---|---|---|
| file | File | 图片文件 |
响应:
{
"success": true,
"data": {
"url": "https://...",
"filename": "image.png"
}
}GET /api/analytics
需要认证: 是 (管理员)
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| range | string | 时间范围 (7d/30d/90d) |
响应:
{
"success": true,
"data": {
"views": {
"total": 10000,
"trend": [...]
},
"visitors": {
"total": 5000,
"trend": [...]
},
"popularPosts": [...]
}
}interface User {
id: number;
email: string;
username: string;
avatar?: string;
bio?: string;
role: 'user' | 'admin';
isEmailVerified: boolean;
createdAt: string;
updatedAt: string;
}interface Post {
id: number;
title: string;
slug: string;
content: string;
excerpt?: string;
coverImage?: string;
author: User;
category?: Category;
column?: Column;
tags: Tag[];
isPinned: boolean;
isPasswordProtected: boolean;
viewCount: number;
likeCount: number;
commentCount: number;
seoTitle?: string;
seoDescription?: string;
seoKeywords?: string;
status: 'draft' | 'published';
publishedAt?: string;
createdAt: string;
updatedAt: string;
}interface Comment {
id: number;
content: string;
user: User;
postId: number;
parentId?: number;
replyToUser?: User;
isAdmin: boolean;
likeCount: number;
status: 'pending' | 'approved' | 'rejected';
createdAt: string;
replies?: Comment[];
}interface Notification {
id: number;
type: 'system' | 'comment' | 'like' | 'follow' | 'mention';
title: string;
content: string;
isRead: boolean;
data?: Record<string, any>;
createdAt: string;
}版本: v1.4.0 | 更新日期: 2026-02-17