适用于栏目管理、文章草稿、发布和下架。后台管理使用管理员 JWT 和角色权限;自动发文可使用独立发文令牌,不需要验证码。生产基础地址为 https://ynsmhy.com/smhy-api。
下载 OpenAPI,可导入 Apifox、Postman 或 Swagger 工具。登录管理后台后,在“内容管理 → 文章管理”开始操作。
使用流程
验证码仅用于网页登录流程:/login、/auth/sms/login、/auth/wechat/start。这些入口须先 GET /auth/captcha/config 获取新挑战并验证。发文、生成发文令牌、注册、短信发送、微信绑定不弹验证码;原有权限、密码复核、注册开关、短信额度和限流仍生效。
- 登录后台 → 内容管理 → 文章管理 → 发文令牌,填写用途和有效天数后生成。复制只显示一次的
smhy_pub_...,存入自动任务的密钥配置(CMS_TOKEN)。默认 90 天,支持 1–365 天,到期可重新生成,原令牌可随时撤销。推荐用具有文章查询/新增/修改/发布权限的专用运营账号签发。 - 查询栏目,找到目标
columnId。 - 创建草稿,保存返回的
id、version。提供唯一externalId可识别重复请求。 - 查看草稿预览,必要时修改并保存。
- 使用最新
version调用发布接口。发布后官网正文、栏目列表和动态 sitemap 读取已发布快照。
“数美动态”下已配置五个发文栏目,按下列顺序展示。先查询 /cms/columns,按 code 取实际 id,发文请求将该 id 放入 columnId。
| 栏目 | code | 公开栏目地址 |
|---|---|---|
| 融智管家 | rongzhi-guanjia |
/news/rongzhi-guanjia/ |
| 知意客 | zhiyike |
/news/zhiyike/ |
| 茶语客 | chayuke |
/news/chayuke/ |
| 滇有戏 | dianyouxi |
/news/dianyouxi/ |
| 问渠客 | wenquke |
/news/wenquke/ |
/news/ 汇总这些子栏目的已发布文章,各子栏目显示自身内容;栏目页提供切换入口。原文章地址保持不变。
保存草稿不会改变正在展示的文章。下架会隐藏整个文章;删除须先下架。地址、栏目和外部编号创建后固定,避免旧链接失效。栏目有子栏目或文章时不能删除;停用栏目会隐藏下级全部公开内容。新建“独立页面”栏目后,可为它创建一份内容,地址就是栏目地址;“导航链接”类型不承载文章。
认证与响应
Authorization: Bearer <发文令牌或后台登录 token>
Content-Type: application/json
自动任务直接携带发文令牌调用下列 CMS 接口,不再调用 /login,不需要账号密码,也不需要验证码。密码登录仍是原 POST /login 并要求 ALTCHA;后台登录 Token 仍可用,但有管理会话时限。
发文令牌允许栏目和文章查询、草稿新增/修改/预览、图片上传及发布“数美动态”和子栏目的 ARTICLE。禁止系统管理、栏目写入、官网 PAGE 编辑、下架、删除和令牌管理。每次请求检查原账号状态和当前文章权限,撤销或过期后返回 401;超范围返回 403。数据库只存 SHA-256,无法重新查看原文。正文编辑与发布继续使用 version。
令牌管理接口仅接受后台登录 Token,操作当前用户自己的令牌:
| 方法 | 路径 | 参数/结果 |
|---|---|---|
| GET | /cms/publishing-tokens |
返回记录、前缀、到期/撤销/最近使用,不返回原文或 hash |
| POST | /cms/publishing-tokens |
{"name":"公众号自动同步","days":90};data.token 仅本次返回,data.record.id 用于撤销 |
| DELETE | /cms/publishing-tokens/{id} |
即时撤销;不删除审计记录 |
三个接口均要求 cms:article:publish;签发还要求原账号具有 query/add/edit/publish 四项文章权限。发文令牌本身不能调用这些管理接口。
成功响应:{"code":200,"msg":"操作成功","data":{...}}。文章分页列表沿用后台格式 {"code":200,"rows":[],"total":44}。公开文章列表为 data.items 和 data.total。
须同时检查 HTTP 状态与 JSON 中的 code:现有后台约定部分业务错误仍返回 HTTP 200。常见业务码:400 输入不合法,401 未登录,403 无权限,404 不存在/未发布,409 内容已变更或地址重复,429 请求过于频繁。
后台接口
以下路径均相对于基础地址。
| 方法 | 路径 | 用途 | 权限 |
|---|---|---|---|
| GET | /cms/columns |
栏目列表,含数量与版本 | 栏目查询或文章查询/新增/修改 |
| POST | /cms/columns |
创建栏目 | cms:column:add |
| PUT | /cms/columns/{id} |
修改栏目 | cms:column:edit |
| DELETE | /cms/columns/{id}?version=0 |
删除空栏目 | cms:column:remove |
| GET | /cms/articles?pageNum=1&pageSize=15&columnId=9&status=DRAFT&keyword=产品 |
文章分页,筛选项可省略 | cms:article:query |
| GET | /cms/articles/{id} |
完整草稿与当前版本 | cms:article:query |
| GET | /cms/articles/by-external-id?externalId=job%3A123 |
按外部编号查文章 | cms:article:query |
| POST | /cms/articles |
创建草稿 | cms:article:add |
| PUT | /cms/articles/{id} |
保存草稿,需完整可编辑字段及最新版本 | cms:article:edit |
| GET | /cms/articles/{id}/preview |
返回 data.html,预览已保存草稿 |
cms:article:query |
| POST | /cms/articles/{id}/publish |
发布已保存草稿 | cms:article:publish |
| POST | /cms/articles/{id}/offline |
下架 | cms:article:publish |
| DELETE | /cms/articles/{id}?version=2 |
删除未发布或下架内容 | cms:article:remove |
| POST | /cms/media |
multipart file 上传图片 |
文章新增或修改 |
发布和下架请求体均为 {"version":最新版本号}。更新、发布、下架、删除都会递增版本;遇到 409 后重新查询并处理冲突,不要盲目覆盖。
创建草稿
{
"columnId": 9,
"title": "数美汇云产品更新",
"slug": "product-update-20261020",
"externalId": "editorial:product-update-20261020",
"summary": "介绍本次产品更新与适用场景。",
"contentHtml": "<h2>本次更新</h2><p>这里填写已确认的文章正文。</p>",
"coverUrl": "/assets/brand-202609/hero.webp",
"author": "数美汇云",
"tag": "产品动态",
"seoTitle": "数美汇云产品更新 - 数美汇云",
"keywords": "数美汇云,产品更新",
"displayDate": "2026-10-20",
"sortOrder": 0,
"version": 0
}
columnId 示例不代表生产固定值,必须以查询结果为准。slug 为小写字母、数字和短横线;列表栏目地址自动组合为 栏目路径 + slug + /。externalId 可选,最长 80 字符,允许字母数字及 ._:/-,创建后固定。同编号重试返回原草稿,不会覆盖原文或再次发布;并发请求若返回 409,可按编号查询。文章删除后不重用其旧地址或编号。
必填项:columnId、title、slug、contentHtml。title ≤200 字符,摘要 ≤1000,HTML ≤500000,作者 ≤80,标签 ≤100,SEO 标题 ≤200,关键词 ≤300,sortOrder 0–9999。displayDate 为展示日期,省略时使用服务端当天;它不是定时发布。新建和更新都不能直接传入发布状态,必须显式调用发布接口。
后台使用解析器白名单清理 HTML,保留常用图文、视频和既有页面必要布局,删除脚本、事件属性、危险 URL 和不允许的样式。保存后以返回的 contentHtml 为准。清理依据:jsoup HTML 白名单。
图片上传支持 JPG/JPEG、PNG、GIF,最大 10MB、2500 万像素,返回 data.url(/smhy-api/profile/...)。填写到 coverUrl 或正文 <img src="..."> 中。封面也允许已有 /assets/... 和 HTTPS 图片地址。生产复用 /smhy-api/profile/,不占用其他项目 /profile/。
可运行的命令行客户端
下载命令行客户端和文章示例,保存在同一文件夹,使用 Node.js 20 或更新版本运行。从 JSON 文件读取文章;默认只创建草稿,--publish 才发布。
$env:CMS_API_BASE = 'https://ynsmhy.com/smhy-api'
$env:CMS_TOKEN = '替换为后台生成的发文令牌'
node publish-article.mjs article.example.json
# 确认草稿内容后,再显式发布:
node publish-article.mjs article.example.json --publish
示例文件的 columnId 要先根据栏目查询结果调整。不要将真实 Token 写进示例文件、Git 或日志。
官网只读接口
无需 Token,路径可同源 /content/... 或经 /smhy-api/content/... 访问。
| GET 路径 | 返回 |
|---|---|
/content/columns |
启用的栏目,排除停用上级的子栏目 |
/content/articles?columnId=9&pageNum=1&pageSize=20 |
已发布列表,pageSize 最大 100,不返回正文与内部编辑信息 |
/content/page?path=%2Fnews%2Fproduct-update-20261020%2F |
指定地址的已发布正文 |
/content/render?path=%2Fnews%2Fproduct-update-20261020%2F |
完整服务端 HTML,带 canonical、元数据及结构化数据 |
/content/sitemap.xml |
当前可公开访问的内容地址 |
草稿、下架、删除及停用栏目的内容不会通过公开接口返回。公开渲染端不从磁盘读取请求路径,也不执行发布者提供的脚本。