/** * 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 }; }