Files
memind/wechat-draft-publication-standard.mjs
T
john d8eaef3fbd feat(wechat): MindSpace public draft push with 143 host defaults
Add public-page WeChat draft button, publication standard conversion for poem/prose/generic pages, and quick push APIs. Default Studio release SSH targets to john@180.159.29.143 with 105 edge upstream via 10.10.0.2.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-11 12:32:13 +08:00

90 lines
2.9 KiB
JavaScript

/**
* MindSpace / 公众号草稿推送格式标准(2026-09-11)。
* 所有页面推送到微信草稿箱时必须经过同一套 layout + 封面解析。
* 实现入口:mindspace-wechat-page-draft.mjs → buildWechatDraftPublicationBundleForPush
* 布局模块:wechat-draft-article-layout.mjs
*/
export const WECHAT_DRAFT_PUBLICATION_STANDARD_VERSION = '2026-09-11';
export const WECHAT_DRAFT_PUBLICATION_STANDARD = Object.freeze({
version: WECHAT_DRAFT_PUBLICATION_STANDARD_VERSION,
/** 正文区块顺序(不含 daily-news 专有栏目,其仍复用底部 layout) */
bodyLayout: Object.freeze([
'hero-image-if-present',
'page-content',
'read-original-link',
'follow-footer',
]),
readOriginal: Object.freeze({
position: 'after-content-before-footer',
label: '阅读原文',
style: 'compact-link-12px',
forbidLegacyLargeButton: true,
}),
followFooter: Object.freeze({
title: '欢迎关注 TKMind 智趣',
includeLogo: false,
includeSubtitle: false,
includeQrcode: true,
}),
cover: Object.freeze({
priority: Object.freeze(['hero-raster', 'thumbnail-png-sidecar', 'thumbnail-svg-sidecar', 'placeholder']),
allowSvgSidecarAsRasterFallback: true,
heroSources: Object.freeze([
'mindspace-cover.cover',
'css-hero-background-image',
'hero-img',
]),
mustMatchBodyHeroWhenPresent: true,
}),
images: Object.freeze({
bodyUpload: 'wechat-uploadimg',
coverUpload: 'wechat-permanent-thumb',
preferHttps: true,
}),
limits: Object.freeze({
maxContentChars: 20000,
}),
});
export function verifyWechatDraftPublicationContent(
content,
{ publicUrl = '', requireReadOriginal = Boolean(publicUrl) } = {},
) {
const issues = [];
const text = String(content ?? '');
if (requireReadOriginal && !text.includes('阅读原文')) {
issues.push('缺少「阅读原文」链接');
}
if (!text.includes(WECHAT_DRAFT_PUBLICATION_STANDARD.followFooter.title)) {
issues.push('缺少底部关注区标题');
}
if (text.includes('点击阅读原文')) {
issues.push('不得使用旧版大按钮「点击阅读原文」');
}
if (/alt="TKMind 智趣"/.test(text)) {
issues.push('底部关注区不得包含 logo 图片');
}
if (/获取更多精彩内容|每日早报不错过/.test(text)) {
issues.push('底部关注区不得包含额外导语');
}
const readIdx = text.indexOf('阅读原文');
const followIdx = text.indexOf(WECHAT_DRAFT_PUBLICATION_STANDARD.followFooter.title);
if (readIdx >= 0 && followIdx >= 0 && readIdx > followIdx) {
issues.push('「阅读原文」须位于正文之后、关注区之前');
}
return { ok: issues.length === 0, issues };
}
export function verifyWechatDraftCoverResolution(resolved) {
const issues = [];
if (!resolved?.source) {
issues.push('缺少封面来源');
}
return { ok: issues.length === 0, issues };
}