CarefreeCMS 文档CarefreeCMS 文档
指南
  • 内容管理
  • 多站点管理
  • AI文章生成
  • SEO优化
  • 静态化生成
API
  • FAQ
  • 更新日志
  • 贡献指南
  • v1.3.0
  • v1.2.0
  • v1.1.0
GitHub
指南
  • 内容管理
  • 多站点管理
  • AI文章生成
  • SEO优化
  • 静态化生成
API
  • FAQ
  • 更新日志
  • 贡献指南
  • v1.3.0
  • v1.2.0
  • v1.1.0
GitHub
  • API 文档

    • API 文档
    • 认证接口
    • 文章接口
    • 分类接口
    • 标签接口
    • 媒体接口
    • 评论接口
    • 用户接口

文章接口

文章管理相关的 API 接口,包括文章的增删改查、发布、审核等操作。

获取文章列表

接口信息

GET /api/articles
Authorization: Bearer {token}

请求参数

参数类型必填说明
pageinteger否页码,默认 1
page_sizeinteger否每页数量,默认 20
keywordstring否搜索关键词
category_idinteger否分类 ID
tag_idinteger否标签 ID
statusinteger否状态(0草稿/1已发布)
is_topinteger否是否置顶(0否/1是)
is_hotinteger否是否热门(0否/1是)
start_timestring否开始时间
end_timestring否结束时间
sortstring否排序字段(create_time/view_count)
orderstring否排序方式(asc/desc)

请求示例

GET /api/articles?page=1&page_size=20&category_id=1&status=1&sort=create_time&order=desc
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

响应示例

成功响应(200)

{
  "code": 200,
  "message": "获取成功",
  "data": {
    "list": [
      {
        "id": 1,
        "title": "Vue 3 Composition API 详解",
        "summary": "本文详细介绍 Vue 3 的 Composition API 用法...",
        "cover": "https://example.com/uploads/2024/01/15/cover.jpg",
        "author": {
          "id": 1,
          "username": "admin",
          "nickname": "管理员"
        },
        "category": {
          "id": 1,
          "name": "前端开发"
        },
        "tags": [
          {
            "id": 1,
            "name": "Vue.js"
          },
          {
            "id": 2,
            "name": "JavaScript"
          }
        ],
        "view_count": 1234,
        "is_top": 0,
        "is_hot": 1,
        "status": 1,
        "create_time": "2024-01-15 14:30:25",
        "update_time": "2024-01-15 15:20:10"
      }
    ],
    "total": 128,
    "page": 1,
    "page_size": 20,
    "total_pages": 7
  },
  "timestamp": 1705317025
}

代码示例

JavaScript (Axios)

import axios from 'axios'

const getArticles = async (params = {}) => {
  try {
    const response = await axios.get('/api/articles', {
      params: {
        page: params.page || 1,
        page_size: params.pageSize || 20,
        category_id: params.categoryId,
        status: params.status,
        keyword: params.keyword,
        sort: params.sort || 'create_time',
        order: params.order || 'desc'
      },
      headers: {
        Authorization: `Bearer ${localStorage.getItem('token')}`
      }
    })

    return response.data.data
  } catch (error) {
    console.error('获取文章列表失败:', error)
    throw error
  }
}

// 使用示例
getArticles({
  page: 1,
  pageSize: 20,
  categoryId: 1,
  status: 1
}).then(data => {
  console.log('文章列表:', data.list)
  console.log('总数:', data.total)
})

PHP (cURL)

<?php
$url = 'http://your-domain.com/api/articles?page=1&page_size=20&category_id=1';
$token = 'YOUR_JWT_TOKEN';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $token,
]);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);

if ($result['code'] === 200) {
    $articles = $result['data']['list'];
    foreach ($articles as $article) {
        echo $article['title'] . "\n";
    }
}

获取文章详情

接口信息

GET /api/articles/{id}
Authorization: Bearer {token}

路径参数

参数类型说明
idinteger文章 ID

响应示例

成功响应(200)

{
  "code": 200,
  "message": "获取成功",
  "data": {
    "id": 1,
    "title": "Vue 3 Composition API 详解",
    "content": "<p>文章正文内容...</p>",
    "summary": "文章摘要",
    "cover": "https://example.com/uploads/2024/01/15/cover.jpg",
    "author": {
      "id": 1,
      "username": "admin",
      "nickname": "管理员",
      "avatar": "https://example.com/avatar/admin.jpg"
    },
    "category": {
      "id": 1,
      "name": "前端开发",
      "alias": "frontend"
    },
    "tags": [
      {
        "id": 1,
        "name": "Vue.js",
        "alias": "vuejs"
      }
    ],
    "seo_title": "Vue 3 Composition API 详解 - 技术博客",
    "seo_keywords": "Vue3,Composition API,前端",
    "seo_description": "详细介绍 Vue 3 的 Composition API",
    "view_count": 1234,
    "like_count": 56,
    "comment_count": 12,
    "is_top": 0,
    "is_hot": 1,
    "is_recommend": 1,
    "status": 1,
    "create_time": "2024-01-15 14:30:25",
    "update_time": "2024-01-15 15:20:10",
    "publish_time": "2024-01-15 14:30:25"
  },
  "timestamp": 1705317025
}

文章不存在(404)

{
  "code": 404,
  "message": "文章不存在",
  "timestamp": 1705317025
}

创建文章

接口信息

POST /api/articles
Authorization: Bearer {token}
Content-Type: application/json

请求参数

参数类型必填说明
titlestring是文章标题
contentstring是文章内容
summarystring否摘要(留空自动提取)
coverstring否封面图片 URL
category_idinteger是主分类 ID
category_idsarray否副分类 ID 数组
tag_idsarray否标签 ID 数组
seo_titlestring否SEO 标题
seo_keywordsstring否SEO 关键词
seo_descriptionstring否SEO 描述
is_topinteger否是否置顶(0/1)
is_hotinteger否是否热门(0/1)
is_recommendinteger否是否推荐(0/1)
statusinteger否状态(0草稿/1发布),默认 0
publish_timestring否发布时间
templatestring否模板文件名

请求示例

{
  "title": "Vue 3 Composition API 详解",
  "content": "<p>文章正文内容...</p>",
  "summary": "本文详细介绍 Vue 3 的 Composition API",
  "cover": "https://example.com/uploads/2024/01/15/cover.jpg",
  "category_id": 1,
  "category_ids": [1, 2],
  "tag_ids": [1, 2, 3],
  "seo_title": "Vue 3 Composition API 详解 - 前端技术",
  "seo_keywords": "Vue3,Composition API,前端框架",
  "seo_description": "详细介绍 Vue 3 Composition API 的使用方法和最佳实践",
  "is_top": 0,
  "is_hot": 1,
  "is_recommend": 1,
  "status": 1,
  "publish_time": "2024-01-15 14:30:00"
}

响应示例

成功响应(201)

{
  "code": 201,
  "message": "创建成功",
  "data": {
    "id": 100,
    "title": "Vue 3 Composition API 详解",
    "create_time": "2024-01-15 14:30:25"
  },
  "timestamp": 1705317025
}

验证失败(422)

{
  "code": 422,
  "message": "数据验证失败",
  "errors": {
    "title": ["标题不能为空"],
    "content": ["内容不能为空"],
    "category_id": ["请选择分类"]
  },
  "timestamp": 1705317025
}

代码示例

const createArticle = async (data) => {
  try {
    const response = await axios.post('/api/articles', {
      title: data.title,
      content: data.content,
      summary: data.summary,
      cover: data.cover,
      category_id: data.categoryId,
      tag_ids: data.tagIds,
      seo_title: data.seoTitle,
      seo_keywords: data.seoKeywords,
      seo_description: data.seoDescription,
      status: data.status || 0
    }, {
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`,
        'Content-Type': 'application/json'
      }
    })

    return response.data
  } catch (error) {
    console.error('创建文章失败:', error)
    throw error
  }
}

// 使用示例
createArticle({
  title: 'Vue 3 入门教程',
  content: '<p>教程内容...</p>',
  categoryId: 1,
  tagIds: [1, 2, 3],
  status: 1
}).then(result => {
  console.log('文章创建成功,ID:', result.data.id)
})

更新文章

接口信息

PUT /api/articles/{id}
Authorization: Bearer {token}
Content-Type: application/json

路径参数

参数类型说明
idinteger文章 ID

请求参数

与创建文章相同,所有字段都是可选的,只更新传入的字段。

请求示例

{
  "title": "Vue 3 Composition API 完整指南",
  "content": "<p>更新后的内容...</p>",
  "is_hot": 1
}

响应示例

成功响应(200)

{
  "code": 200,
  "message": "更新成功",
  "data": {
    "id": 1,
    "title": "Vue 3 Composition API 完整指南",
    "update_time": "2024-01-15 16:45:30"
  },
  "timestamp": 1705317025
}

无权限(403)

{
  "code": 403,
  "message": "您没有权限编辑此文章",
  "timestamp": 1705317025
}

删除文章

接口信息

DELETE /api/articles/{id}
Authorization: Bearer {token}

路径参数

参数类型说明
idinteger文章 ID

响应示例

成功响应(200)

{
  "code": 200,
  "message": "删除成功",
  "timestamp": 1705317025
}

代码示例

const deleteArticle = async (id) => {
  try {
    await axios.delete(`/api/articles/${id}`, {
      headers: {
        Authorization: `Bearer ${localStorage.getItem('token')}`
      }
    })

    console.log('文章删除成功')
  } catch (error) {
    console.error('删除失败:', error)
    throw error
  }
}

// 使用示例
deleteArticle(1)

批量删除文章

接口信息

DELETE /api/articles/batch
Authorization: Bearer {token}
Content-Type: application/json

请求参数

参数类型必填说明
idsarray是文章 ID 数组

请求示例

{
  "ids": [1, 2, 3, 4, 5]
}

响应示例

{
  "code": 200,
  "message": "批量删除成功",
  "data": {
    "success_count": 5,
    "failed_count": 0
  },
  "timestamp": 1705317025
}

发布文章

接口信息

POST /api/articles/{id}/publish
Authorization: Bearer {token}
Content-Type: application/json

路径参数

参数类型说明
idinteger文章 ID

请求参数

参数类型必填说明
publish_timestring否发布时间,默认当前时间

请求示例

{
  "publish_time": "2024-01-15 18:00:00"
}

响应示例

{
  "code": 200,
  "message": "发布成功",
  "data": {
    "id": 1,
    "status": 1,
    "publish_time": "2024-01-15 18:00:00"
  },
  "timestamp": 1705317025
}

审核文章

接口信息

POST /api/articles/{id}/audit
Authorization: Bearer {token}
Content-Type: application/json

请求参数

参数类型必填说明
statusinteger是审核状态(1通过/2拒绝)
reasonstring否拒绝原因

请求示例

{
  "status": 1
}

或

{
  "status": 2,
  "reason": "内容不符合规范"
}

响应示例

{
  "code": 200,
  "message": "审核通过",
  "timestamp": 1705317025
}

文章点赞

接口信息

POST /api/articles/{id}/like
Authorization: Bearer {token}

响应示例

{
  "code": 200,
  "message": "点赞成功",
  "data": {
    "like_count": 57
  },
  "timestamp": 1705317025
}

文章收藏

接口信息

POST /api/articles/{id}/favorite
Authorization: Bearer {token}

响应示例

{
  "code": 200,
  "message": "收藏成功",
  "data": {
    "favorite_count": 23
  },
  "timestamp": 1705317025
}

增加浏览量

接口信息

POST /api/articles/{id}/view

响应示例

{
  "code": 200,
  "message": "操作成功",
  "data": {
    "view_count": 1235
  },
  "timestamp": 1705317025
}

获取相关文章

接口信息

GET /api/articles/{id}/related?limit=5

请求参数

参数类型必填说明
limitinteger否数量限制,默认 5

响应示例

{
  "code": 200,
  "message": "获取成功",
  "data": [
    {
      "id": 2,
      "title": "Vue 3 响应式原理解析",
      "summary": "深入解析 Vue 3 的响应式系统",
      "cover": "https://example.com/uploads/cover2.jpg",
      "create_time": "2024-01-14 10:20:00"
    }
  ],
  "timestamp": 1705317025
}

搜索文章

接口信息

GET /api/articles/search?keyword=Vue

请求参数

参数类型必填说明
keywordstring是搜索关键词
pageinteger否页码
page_sizeinteger否每页数量

响应示例

{
  "code": 200,
  "message": "搜索成功",
  "data": {
    "list": [
      {
        "id": 1,
        "title": "Vue 3 Composition API 详解",
        "summary": "本文详细介绍 Vue 3...",
        "highlight": {
          "title": "<em>Vue</em> 3 Composition API 详解",
          "content": "...介绍 <em>Vue</em> 3..."
        }
      }
    ],
    "total": 15,
    "page": 1,
    "page_size": 20
  },
  "timestamp": 1705317025
}

导出文章

接口信息

GET /api/articles/export?format=excel&ids=1,2,3
Authorization: Bearer {token}

请求参数

参数类型必填说明
formatstring是格式(excel/csv/pdf)
idsstring否文章ID,逗号分隔

响应

直接返回文件下载流

批量操作

批量更新状态

接口信息

PUT /api/articles/batch
Authorization: Bearer {token}
Content-Type: application/json

请求参数

{
  "ids": [1, 2, 3],
  "data": {
    "status": 1,
    "is_hot": 1
  }
}

响应示例

{
  "code": 200,
  "message": "批量更新成功",
  "data": {
    "success_count": 3,
    "failed_count": 0
  },
  "timestamp": 1705317025
}

错误处理

常见错误

422 验证错误

{
  "code": 422,
  "message": "数据验证失败",
  "errors": {
    "title": ["标题不能为空", "标题长度不能超过100个字符"],
    "category_id": ["分类不存在"],
    "content": ["内容不能为空"]
  }
}

403 权限错误

{
  "code": 403,
  "message": "您没有权限执行此操作"
}

404 未找到

{
  "code": 404,
  "message": "文章不存在或已被删除"
}

完整示例

Vue 3 组合式 API

<template>
  <div class="article-list">
    <el-table :data="articles" v-loading="loading">
      <el-table-column prop="id" label="ID" width="80" />
      <el-table-column prop="title" label="标题" />
      <el-table-column prop="category.name" label="分类" />
      <el-table-column prop="view_count" label="浏览量" width="100" />
      <el-table-column prop="create_time" label="创建时间" width="180" />
      <el-table-column label="操作" width="200">
        <template #default="{ row }">
          <el-button @click="editArticle(row.id)">编辑</el-button>
          <el-button type="danger" @click="deleteArticle(row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      :current-page="page"
      :page-size="pageSize"
      :total="total"
      @current-change="handlePageChange"
    />
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import articleApi from '@/api/article'

const articles = ref([])
const loading = ref(false)
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)

const fetchArticles = async () => {
  loading.value = true
  try {
    const res = await articleApi.getList({
      page: page.value,
      pageSize: pageSize.value
    })

    articles.value = res.list
    total.value = res.total
  } catch (error) {
    ElMessage.error('获取文章列表失败')
  } finally {
    loading.value = false
  }
}

const handlePageChange = (newPage) => {
  page.value = newPage
  fetchArticles()
}

const deleteArticle = async (id) => {
  try {
    await articleApi.delete(id)
    ElMessage.success('删除成功')
    fetchArticles()
  } catch (error) {
    ElMessage.error('删除失败')
  }
}

onMounted(() => {
  fetchArticles()
})
</script>

API 封装

// api/article.js
import request from '@/utils/request'

export default {
  // 获取列表
  getList(params) {
    return request.get('/articles', { params })
  },

  // 获取详情
  getDetail(id) {
    return request.get(`/articles/${id}`)
  },

  // 创建
  create(data) {
    return request.post('/articles', data)
  },

  // 更新
  update(id, data) {
    return request.put(`/articles/${id}`, data)
  },

  // 删除
  delete(id) {
    return request.delete(`/articles/${id}`)
  },

  // 批量删除
  batchDelete(ids) {
    return request.delete('/articles/batch', { data: { ids } })
  },

  // 发布
  publish(id, publishTime) {
    return request.post(`/articles/${id}/publish`, { publish_time: publishTime })
  },

  // 搜索
  search(keyword, page = 1) {
    return request.get('/articles/search', {
      params: { keyword, page }
    })
  }
}

相关接口

  • 分类接口
  • 标签接口
  • 媒体接口
  • 评论接口
在 GitHub 上编辑此页
Prev
认证接口
Next
分类接口