之前写完「分发」功能,只能把文章推到关联的 WordPress 站点 和 博客园账号。这次补上第三个渠道:另一台写字台。
需求
- 文章列表界面点「分发」按钮,目标里可以选写字台账号;
- 要记住哪些写字台账号已经分发过;已发过的,用户能决定是「更新之前分发的文章」还是「分发一个新文章」;
- 分发时可选原文分发或转载分发;转载的话,发出去的文章尾部要带上转载链接。
为什么写字台渠道不能照抄 WordPress
写字台之间本来就是靠一套开放 API 互通的(/api/v1/articles 读、/api/v1/publish 写),所以「分发」这一步天然就能复用关联账号时填好的接口地址与对接密钥。但有三个地方必须单独处理。
一、正文格式要按渠道归一
分发的「正文格式」是个全局选项:WordPress 站点没装 Markdown 插件时要选「转成 HTML」,博客园则要送 Markdown 原文(并带上 [Markdown] 分类)。
问题是,写字台的开放 API 收的正文就是 Markdown——对方入库后由前台按 Markdown 渲染。如果一次分发里既有 WordPress 又有写字台,用户把格式选成 HTML,那发到写字台的就是一堆 <p> 标签,代码块和表格全废。
所以写字台渠道忽略请求里的格式选项,一律按 Markdown 原文发,并在结果里回一条说明(⚠ 写字台正文一律按 Markdown 发送,已忽略「转成 HTML」),让用户知道选项被无视了、而不是悄悄失效。
二、往同一个站发第二篇,不能带 slug
「分发一个新文章」意味着同一篇原文会在同一台写字台上出现第二份。如果照 WP 的做法把本地 slug 传过去,对方的 articles.slug 唯一索引当场就撞了——过去的表现是对方接口 500,而调用方只看到一句「对方接口返回 HTTP 500」,根本猜不到是 slug 冲突。
处理办法是发写字台时干脆不传 slug,让对端按标题自己生成(对端本来就有「同前缀自动加序号」的逻辑)。因为「更新」走的是远端文章 id,跟 slug 没有任何关系,所以不传 slug 不影响后续更新。
顺带把对方的发布接口自身也加固了:显式传了 slug 且已存在时,自动退化成 xxx-2、xxx-3,不再是 500。
三、对端原来只能「发」,不能「改」
要支持「更新之前分发的文章」,对端必须有个更新接口——而原来只有 POST /api/v1/publish(只会新建)。于是补了一个:
PUT /api/v1/articles/{id}
权限上做了收敛:只认「Token 所属账号 == 文章作者」的那一篇,别人的文章一律 403;没有 Token 401;不改 slug、不发通知。否则任何一个持有 Token 的账号都能篡改全站文章,那是比功能缺失严重得多的问题。
没传的字段(摘要、封面、SEO 关键词)保持原值——分发时本地摘要为空,不该把对方已有的摘要抹掉。
数据结构:还是那一张表
分发记录表本来就以 文章 × 目标 为粒度,记录远端 id、远端链接、分发次数与时间。写字台渠道只是多了一个 channel 取值(xz),行里顺手存下对端的接口地址与账号名快照——账号被删或被改名后,历史记录仍然显示成人看得懂的样子,而不是一条光秃秃的 id。
删掉一个写字台账号时,指向它的分发记录也一并清掉,免得列表上留下一堆点不开的「已分发」徽标。
前端
分发弹窗的目标清单按渠道分组:写字台账号 / WordPress 站点 / 博客园账号。已分发过的目标会自动勾上,并带出「处理方式」下拉(默认「更新之前分发的文章」)与「查看已发文章」链接;文章列表行上用「已分发 · 账号名」徽标一眼看出这篇发过哪些地方。
写字台面板上也加了一句提示:同一个账号既是导入源,也是分发目标。
验证
- 单测/集成测试 60/60 通过:新增两组——开放 API 的更新接口(越权 403、无 Token 401、缺字段 400、不存在 404、显式 slug 撞车自动去重),以及分发到写字台(目标清单、Markdown 归一、转载尾注、更新复用远端 id、徽标、删账号清记录)。
- 端到端 24/24 通过:新写了一个脚本,用本地 mock 的「对方写字台」把整条链路真跑一遍——分组渲染、未分发过时不显示「处理方式」、转载分发后对方收到的是 Markdown 原文且尾部带「本文由写字台首发 + 原文链接」、列表出现「已分发」徽标、再开弹窗显示「已分发过 1 次」并默认「更新」、选更新时对方只收到
PUT且远端 id 不变、选「另发新篇」时才又走POST并拿到新 id。 - 回归:原有的 WordPress / 博客园分发脚本 25/25、写字台跨站导入脚本 29/29 仍全绿。
一个细节:对方接口的链接回填必须用返回值拼绝对地址(url 字段是根级路径),否则列表里点开的「查看已发文章」会指到本站域名上、变成 404。
小结
分发这件事的核心从来不是「把字符串 POST 出去」,而是三件配套的事:记住发过谁(幂等的前提)、能更新而不是重复创建(内容演进的前提)、让对方站点收到的是它真正能渲染的形态(不然功能「成功」了但页面是坏的)。这三点在三个渠道上表现各不相同,得逐个想清楚。