新闻资讯插件 API 文档
1. 文档信息
| 项目 | 内容 |
|---|---|
| 插件 ID | news |
| 插件版本 | 0.0.1 |
| 核心版本 | 0.0.1 |
| 文档更新时间 | 2026-09-28 |
| 管理端前缀 | /admin/plugin/news |
| 用户端前缀 | /api/plugin/news |
当前版本没有第三方回调接口。新闻阅读与评论读取公开,评论、点赞、分享及个人互动状态需要用户登录。
2. 通用约定
2.1 统一响应
成功响应:
{
"code": 0,
"msg": "success",
"data": {}
}失败响应:
{
"code": 400,
"msg": "参数错误"
}| code | 说明 |
|---|---|
0 | 成功 |
400 | 参数绑定或校验失败 |
401 | 未登录或登录已失效 |
403 | 没有接口权限 |
500 | 业务处理失败 |
503 | 权限或依赖服务暂时不可用 |
除认证和权限等 HTTP 错误外,业务错误通常仍返回 HTTP 200,应以响应中的 code 判断结果。
2.2 管理端认证与权限
管理端接口全部注册到 Permission 路由组,请求头必须携带:
Authorization: Bearer <access-token>
Content-Type: application/json角色还必须拥有与请求方法及完整路径一致的菜单接口权限。写接口会进入宿主操作日志链路。
2.3 分页与时间
page默认1;page_size默认20,最大100;- 时间使用宿主 JSON 时间格式,管理端展示到秒;
- 文件字段中的
cover是数据库相对路径,cover_url是根据当前存储配置动态补全的访问地址。
3. 数据结构
3.1 分类对象 CategoryItem
| 字段 | 类型 | 说明 |
|---|---|---|
id | integer | 分类 ID |
name | string | 分类名称,最长 64 字符 |
slug | string | 唯一分类标识,最长 64 字符 |
sort | integer | 排序值,越大越靠前 |
status | integer | 1 启用,2 停用 |
remark | string | 分类备注 |
created_at | string | 创建时间 |
updated_at | string | 更新时间 |
3.2 文章对象 ArticleItem
| 字段 | 类型 | 说明 |
|---|---|---|
id | integer | 文章 ID |
category_id | integer | 分类 ID |
category | object | 关联分类,包含 id、name、slug |
title | string | 文章标题,最长 200 字符 |
slug | string | 唯一文章标识,最长 128 字符 |
summary | string | 文章摘要,最长 500 字符 |
author | string | 文章作者,最长 100 字符 |
source_name | string | 来源平台名称,最长 100 字符 |
source_url | string | 来源外部链接,仅支持 HTTP/HTTPS,最长 1024 字符 |
cover | string | 封面相对路径 |
cover_url | string | 封面完整访问地址 |
content | string | 文章正文;管理端和详情接口返回,用户端列表省略 |
status | integer | 1 草稿,2 已发布,3 已下线 |
enable_status | integer | 1 启用,2 禁用;禁用文章不对用户端开放 |
sort | integer | 排序值,越大越靠前 |
view_count | integer | 真实浏览次数 |
virtual_view_count | integer | 后台配置的虚拟浏览次数 |
total_view_count | integer | 展示浏览次数,为真实与虚拟数量之和 |
published_at | string/null | 最近发布时间 |
created_at | string | 创建时间,仅管理端返回 |
updated_at | string | 更新时间,仅管理端返回 |
4. 管理端分类接口
4.1 分类列表
GET /admin/plugin/news/category/list
| Query 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
keyword | string | 否 | 匹配分类名称或标识,最长 64 字符 |
status | integer | 否 | 1 启用,2 停用 |
page | integer | 否 | 页码 |
page_size | integer | 否 | 每页数量,最大 100 |
data 为 { "list": CategoryItem[], "total": integer }。
4.2 保存分类
POST /admin/plugin/news/category/save
新增时 id 传 0,修改时传现有分类 ID。管理端新增页面会自动生成标识,保存前允许修改;分类创建后 slug 不可变,修改请求中的该字段不会覆盖数据库原值。
{
"id": 0,
"name": "公司新闻",
"slug": "company",
"sort": 100,
"status": 1,
"remark": "公司动态与公告"
}成功时 data 返回完整 CategoryItem。slug 受数据库唯一索引保护,并发提交相同标识只会有一个请求成功。
常见失败:分类标识已存在、修改对象不存在、字段不符合长度或枚举约束。
4.3 删除分类
POST /admin/plugin/news/category/delete
{ "id": 12 }成功时 data 为 null。该接口在事务中检查文章引用;分类下存在未删除文章时拒绝删除。重复删除返回“分类不存在”,不作为幂等成功处理。
5. 管理端文章接口
5.1 文章列表
GET /admin/plugin/news/article/list
| Query 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
keyword | string | 否 | 匹配标题、文章标识、作者或来源平台,最长 200 字符 |
category_id | integer | 否 | 分类 ID |
status | integer | 否 | 1 草稿,2 已发布,3 已下线 |
enable_status | integer | 否 | 1 启用,2 禁用 |
page | integer | 否 | 页码 |
page_size | integer | 否 | 每页数量,最大 100 |
data 为 { "list": ArticleItem[], "total": integer },分类通过预加载返回。
5.2 文章详情
GET /admin/plugin/news/article/detail?id=100
| Query 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | integer | 是 | 文章 ID |
成功时 data 返回完整 ArticleItem,包括正文和关联分类。
5.3 保存文章
POST /admin/plugin/news/article/save
新增文章始终保存为草稿;修改文章不会隐式改变当前发布状态。管理端新增页面会自动生成标识,保存前允许修改;文章创建后 slug 不可变,修改请求中的该字段不会覆盖数据库原值。封面可以提交上传接口返回的相对路径或当前存储域名下的完整地址,后端统一转换为相对路径保存。
{
"id": 0,
"category_id": 12,
"title": "新闻插件正式发布",
"slug": "news-plugin-release",
"summary": "新闻资讯插件 0.0.1 发布说明",
"author": "编辑部",
"source_name": "项目官网",
"source_url": "https://www.tutudati.com/news/plugin-release",
"cover": "uploads/2026/09/news-cover.webp",
"content": "<p>正文内容</p>",
"enable_status": 1,
"virtual_view_count": 100,
"sort": 100
}成功时 data 返回完整 ArticleItem。slug 受数据库唯一索引保护。source_url 为空时表示不提供来源跳转,非空时必须是合法 HTTP/HTTPS 地址。正文允许保存 HTML,面向最终用户渲染时,客户端必须采用可信内容策略,不能把未经授权用户提交的内容直接作为 HTML 执行。
5.4 发布或下线文章
POST /admin/plugin/news/article/status
{
"id": 100,
"status": 2
}status 只允许:
2:发布,同时将published_at更新为当前时间;3:下线,保留原发布时间。
重复发布会刷新发布时间,重复下线保持下线状态。调用方需要避免无意义重复请求。
5.5 删除文章
POST /admin/plugin/news/article/delete
{ "id": 100 }执行软删除,不会物理移除数据库记录和已上传封面。重复删除返回“文章不存在”。
6. 用户端公开接口
公开接口无需 Token。调用方应在网关层结合部署规模设置限流;插件分页最大为 100 条,禁止通过大分页一次性抓取全部文章。
6.1 启用分类列表
GET /api/plugin/news/categories
返回启用分类数组:
{
"code": 0,
"msg": "success",
"data": [
{ "id": 12, "name": "公司新闻", "slug": "company" }
]
}6.2 已发布文章列表
GET /api/plugin/news/articles
| Query 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
category_slug | string | 否 | 启用分类的稳定标识 |
keyword | string | 否 | 标题关键字,最长 100 字符 |
page | integer | 否 | 页码 |
page_size | integer | 否 | 每页数量,最大 100 |
列表仅返回状态为已发布且启用的文章,按 sort、published_at、id 倒序排列,不返回 content。data 为 { "list": ArticleItem[], "total": integer }。
请求示例:
curl 'https://example.com/api/plugin/news/articles?category_slug=company&page=1&page_size=20'6.3 已发布文章详情
GET /api/plugin/news/article/detail?slug=news-plugin-release
| Path 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
slug | string | 是 | Query 参数,文章稳定标识,最长 128 字符 |
只返回已发布且启用的文章。每次成功查询会在数据库事务中使用 view_count = view_count + 1 原子累加真实浏览量;客户端重试会再次计数,因此该读取接口的计数副作用不具备幂等性。
响应示例:
{
"code": 0,
"msg": "success",
"data": {
"id": 100,
"category_id": 12,
"category": { "id": 12, "name": "公司新闻", "slug": "company" },
"title": "新闻插件正式发布",
"slug": "news-plugin-release",
"summary": "新闻资讯插件 0.0.1 发布说明",
"author": "编辑部",
"source_name": "项目官网",
"source_url": "https://www.tutudati.com/news/plugin-release",
"cover": "uploads/2026/09/news-cover.webp",
"cover_url": "https://static.example.com/uploads/2026/09/news-cover.webp",
"content": "<p>正文内容</p>",
"view_count": 101,
"virtual_view_count": 100,
"total_view_count": 201,
"published_at": "2026-09-24T18:30:00+08:00"
}
}7. 0.0.1 用户互动接口
7.1 安全约定
- 用户端文章对象从本版本开始增加
uid、like_count、share_count、comment_count;不再返回文章id、category_id与分类id。 - 对外业务关联只使用唯一
uid。会员身份只从登录令牌读取,客户端不能提交member_sn。 - 评论读取属于公开接口;评论、回复、点赞、取消点赞、分享及个人互动状态接口必须登录。
- 评论和分享写入必须携带客户端生成的
request_uid,同一会员重复提交相同标识只处理一次。
7.2 评论与回复读取
| 方法 | 地址 | 说明 |
|---|---|---|
| GET | /api/plugin/news/article/comments?article_uid=xxx | 已展示一级评论分页 |
| GET | /api/plugin/news/comment/replies?comment_uid=xxx | 指定一级评论下的已展示回复分页 |
Query 支持 page、page_size,每页最多 50 条。评论项只返回 uid、nickname、avatar_url、reply_nickname、content、images、like_count、reply_count、is_liked、is_mine、created_at。公开接口中的个人状态字段固定为 false,不会返回会员 SN、账号和 IP。
7.3 发表评论与回复
POST /api/auth/plugin/news/article/comment,Body 携带article_uidPOST /api/auth/plugin/news/comment/reply,Body 携带comment_uid
{
"content": "这篇文章很有帮助",
"images": ["uploads/2026/09/comment.webp"],
"request_uid": "news_1790600000000_ab12cd34"
}图片最多 3 张,只保存相对路径。成功返回评论 uid 与状态 1;新评论默认待审核,管理端显示后才进入公开列表。
7.4 点赞、取消点赞与互动状态
| 方法 | 地址 | 说明 |
|---|---|---|
| POST | /api/auth/plugin/news/article/like | 切换文章点赞,Body 携带 article_uid |
| POST | /api/auth/plugin/news/comment/like | 切换评论点赞,Body 携带 comment_uid |
| GET | /api/auth/plugin/news/article/interaction?article_uid=xxx | 返回 { "liked": true, "collected": false } |
点赞与收藏使用 POST 切换状态,在数据库事务中原子维护计数。
7.5 记录分享
POST /api/auth/plugin/news/article/share
{
"article_uid": "cf12345678",
"request_uid": "news_1790600000000_ef56gh78",
"share_channel": 1
}渠道:1 微信好友、2 微信朋友圈、3 系统分享、4 复制链接。该接口记录分享发起,不代表第三方平台最终完成分享。
8. 管理端评论接口
| 方法 | 地址 | 说明 |
|---|---|---|
| GET | /admin/plugin/news/article/comment/list | 一级评论分页 |
| GET | /admin/plugin/news/article/comment/replies | 回复分页,必须传 root_uid |
| POST | /admin/plugin/news/article/comment/status | 评论显示或关闭 |
列表支持 article_uid、root_uid、keyword、status、page、page_size。后台响应返回业务 uid、内容、图片、状态、互动计数、平台、昵称、头像、脱敏账号和脱敏 IP,不返回会员 SN 与数据库主键。
状态请求:
{
"comment_uid": "cf12345678",
"status": 2
}status 只允许 2(显示)或 3(关闭)。评论状态与文章一级评论数、一级评论回复数在同一事务更新。
9. 安全与性能
- 评论每会员每分钟最多 5 次,点赞 30 次,分享 10 次,限流依赖 Redis;
- 点赞状态、审核状态与统计计数使用事务、行锁和原子表达式;
- 评论列表批量查询会员公开资料与图片,避免逐条查询;
- 数据库唯一索引同时约束业务
uid、用户互动状态和写入幂等键。
10. 基线说明
0.0.1 是重新规划版本后的完整基线,0.0.1 增加作者和来源,0.0.1 优化用户端展示,0.0.1 增加评论、点赞和分享。本文件合并记录截至 0.0.1 的完整接口定义。
新闻插件 API 0.0.1
文章点赞
- 请求:
POST /api/auth/plugin/news/article/like - 鉴权:用户端登录鉴权
- 参数:
article_uid,兼容传入文章业务 UID 或公开 slug - 行为:服务端在事务内原子切换点赞状态,不使用 DELETE 请求
- 响应:
active为最新点赞状态,count为最新点赞数
文章收藏
- 请求:
POST /api/auth/plugin/news/article/collection - 鉴权:用户端登录鉴权
- 参数:
article_uid,兼容传入文章业务 UID 或公开 slug - 行为:服务端在事务内原子切换收藏状态
- 响应:
active为最新收藏状态,count为最新收藏数
互动状态
- 请求:
GET /api/auth/plugin/news/article/interaction?article_uid=... - 响应仅返回
liked与collected,不暴露会员标识和数据库主键。
管理端文章列表
- 请求:
GET /admin/plugin/news/article/list - 新增响应字段:
collection_count - 新增参数:
order_by、order order_by白名单:view_count、virtual_view_count、total_view_count、like_count、share_count、collection_count、comment_countorder:asc或desc
新闻插件 API 0.0.1
版本说明
本版本新增的是管理端资讯复用交互,不新增、不删除也不修改后端接口。复用页面读取原资讯详情后,使用新的文章标识调用现有保存接口创建独立资讯。
管理端复用流程
GET /admin/plugin/news/article/detail?id={id}读取选中资讯;- 管理端清除数据库主键,生成约 11 位的可编辑短文章标识,并清零统计信息;
POST /admin/plugin/news/article/save提交新资讯,其中id=0;- 服务端沿用新增校验、权限校验和唯一标识约束,不修改原资讯。
上述接口均由管理端鉴权与菜单权限中间件保护。复用操作复用“文章详情”和“保存文章”权限,不增加重复权限节点。
字段处理规则
| 字段 | 复用行为 |
|---|---|
id、uid | 不复用;提交 id=0,新 UID 由服务端新增逻辑生成 |
slug | 重新生成 n + 6 位时间片 + 4 位随机值 的短标识,保存前允许修改 |
title | 复用原值并追加“(复用)”,提醒编辑人员确认标题 |
| 分类、摘要、作者、来源、封面、正文、启用状态、排序 | 预填原资讯数据 |
| 发布状态、发布时间 | 不复用,新资讯按新增流程处理 |
| 真实阅读、虚拟阅读、点赞、收藏、分享、评论 | 不复用,全部从零开始 |
短标识总长度约 11 位,随机部分使用浏览器 crypto.getRandomValues 生成,并继续由服务端唯一索引做最终冲突校验。
兼容性
- 0.0.1 的接口路径、参数和响应保持兼容;
- 点赞、收藏、分享、评论及互动状态接口保持不变;
- 用户端接口不返回管理端复用状态或其他冗余字段。
广告配置与公开查询
管理端接口统一注册在 Permission 路由组:
| 方法 | 地址 | 参数与响应 |
|---|---|---|
| GET | /admin/plugin/news/advertisement/list | 返回当前插件广告配置列表,包含配置ID、广告ID、位置、状态与广告内容 |
| GET | /admin/plugin/news/advertisement/options | 返回可关联的核心广告选项 |
| POST | /admin/plugin/news/advertisement/save | Body:id(新增为0)、advertisement_id(必填)、position(1列表,2详情)、status(1启用,2停用) |
| POST | /admin/plugin/news/advertisement/delete | Body:id,删除当前插件配置,不删除核心广告 |
| GET | /api/plugin/news/advertisements | 公开接口,Query:position=1或2;返回数组,字段为 id、name、ad_id、format、description |
广告不存在、未分配给当前插件、位置或状态非法时返回参数或业务错误。公开查询只返回核心和插件配置均满足启用条件的广告,不返回广告密钥或内部配置。
发布与 SQL
当前版本统一为 0.0.1;发行包提供 database/0.0.1/full.sql 和 incremental.sql,接口路径不变。新安装只执行全量,后续升级按严格递增版本执行增量。