AI 与创作
背景
工具正在改变内容生产。
创作者需要新的工作流。
import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import test from 'node:test'; import { convertGenericPageHtmlToWechatArticle, convertPageHtmlToWechatArticle, convertRichMindSpacePageHtmlToWechatArticle, isNewsHotspotFormat, mindspaceWechatPageDraftInternals, resolvePagePublicUrl, resolveWechatDraftProfile, resolveWechatDraftThumbPath, validatePageForWechatDraft, } from './mindspace-wechat-page-draft.mjs'; import { buildDailyNewsWechatDraftArticle } from './wechat-news-morning-draft.mjs'; import { applyWechatDraftArticleLayout } from './wechat-draft-article-layout.mjs'; const SAMPLE_HTML = `
正文内容
`; const POEM_HTML = `甜是慢的
蝉声把正午拉得很长
蝉鸣没有起伏
八月的午后很难写。
一篇百字散文 · 秋日慢时光
午后阳光斜洒庭院石阶,桂花香气随微风四处飘散。
墙外梧桐叶纷纷飘落,金黄铺满青石板路,沙沙作响。
工具正在改变内容生产。
创作者需要新的工作流。
面向团队的知识助手
帮助每个团队拥有自己的 AI 大脑。
正文
', { publicUrl: 'https://m.tkmind.cn/u/demo/pages/test.html', qrcodeImageUrl: 'https://mmbiz.qpic.cn/qrcode.png', }); assert.match(content, /阅读原文/); assert.match(content, /欢迎关注 TKMind 智趣/); assert.match(content, /qrcode\.png/); assert.doesNotMatch(content, /点击阅读原文/); assert.ok(content.indexOf('正文') < content.indexOf('阅读原文')); assert.ok(content.indexOf('阅读原文') < content.indexOf('欢迎关注')); }); test('convertPageHtmlToWechatArticle uses rich mindspace converter', () => { const article = convertPageHtmlToWechatArticle(POEM_HTML, { pageTitle: '测试页面', pageSummary: '页面摘要', }); assert.equal(article.title, '八月午后'); assert.match(article.content, /蝉声把正午拉得很长/); assert.match(article.content, /创作手记/); assert.match(article.content, /意象/); }); test('isNewsHotspotFormat ignores mindspace imagery cards', () => { assert.equal(isNewsHotspotFormat(POEM_HTML), false); assert.equal(resolveWechatDraftProfile(POEM_HTML), 'mindspace-page'); }); test('validatePageForWechatDraft warns for mindspace pages', () => { const result = validatePageForWechatDraft(SAMPLE_HTML, { pageTitle: '测试页面', pageSummary: '页面摘要', publicUrl: 'https://example.com/page.html', }); assert.equal(result.ok, true); assert.equal(result.profile, 'generic'); }); test('convertRichMindSpacePageHtmlToWechatArticle preserves poem sections', () => { const article = convertRichMindSpacePageHtmlToWechatArticle(POEM_HTML, { pageTitle: '八月午后', imageUrlMap: new Map([['hero.webp', 'https://mmbiz.qpic.cn/hero.png']]), }); assert.match(article.content, /蝉声把正午拉得很长/); assert.match(article.content, /声音的长度/); assert.match(article.content, /https:\/\/mmbiz\.qpic\.cn\/hero\.png/); }); test('convertRichMindSpacePageHtmlToWechatArticle preserves prose essay sections', () => { const article = convertRichMindSpacePageHtmlToWechatArticle(PROSE_HTML, { pageTitle: '秋庭小憩 · 散文', pageSummary: '午后庭院,桂花飘香', imageUrlMap: new Map([['qiuting-xiaoxi.thumbnail.svg', 'https://mmbiz.qpic.cn/thumb.png']]), }); assert.equal(article.title, '秋庭小憩'); assert.match(article.content, /一篇百字散文 · 秋日慢时光/); assert.match(article.content, /午后阳光斜洒庭院石阶/); assert.match(article.content, /墙外梧桐叶纷纷飘落/); assert.match(article.content, /🍂 秋日/); assert.match(article.content, /thumb\.png/); assert.doesNotMatch(article.content, /data-mindspace-public-share/); }); test('resolveWechatDraftProfile treats mindspace-cover pages as mindspace-page', () => { assert.equal(resolveWechatDraftProfile(BLOG_HTML), 'mindspace-page'); assert.equal(resolveWechatDraftProfile(STARTUP_HTML), 'mindspace-page'); }); test('convertRichMindSpacePageHtmlToWechatArticle extracts blog and startup templates via fallback', () => { const blog = convertRichMindSpacePageHtmlToWechatArticle(BLOG_HTML, { pageTitle: 'AI 与创作', pageSummary: '产品观察', }); assert.equal(blog.title, 'AI 与创作'); assert.match(blog.content, /工具正在改变内容生产/); assert.match(blog.content, /创作者需要新的工作流/); assert.doesNotMatch(blog.content, /data-mindspace-public-share/); const startup = convertRichMindSpacePageHtmlToWechatArticle(STARTUP_HTML, { pageTitle: '创业路演', }); assert.equal(startup.title, '让 AI 更懂业务'); assert.match(startup.content, /面向团队的知识助手/); assert.match(startup.content, /帮助每个团队拥有自己的 AI 大脑/); }); test('collectPageImageCandidates adds sidecar thumbnail when hero image missing', () => { const publishDir = path.join(process.cwd(), 'MindSpace', '1c99b83b-0454-474f-a5d2-129d34506a32'); const html = fs.readFileSync(path.join(publishDir, 'public/qiuting-xiaoxi.html'), 'utf8'); const candidates = mindspaceWechatPageDraftInternals.collectPageImageCandidates(html, { publishDir, htmlRelativePath: 'public/qiuting-xiaoxi.html', }); assert.ok(candidates.some((item) => /\.thumbnail\.(png|svg)$/i.test(item.ref ?? ''))); }); test('convertGenericPageHtmlToWechatArticle truncates long content', () => { const longBody = `${'很长'.repeat(12000)}
`; const article = mindspaceWechatPageDraftInternals.convertGenericPageHtmlToWechatArticle( `${longBody}`, { pageTitle: '长文' }, ); assert.ok(article.content.length <= 20000); }); test('resolveWechatDraftThumbPath prefers hero image over thumbnail sidecar', () => { const userId = '1c99b83b-0454-474f-a5d2-129d34506a32'; const html = fs.readFileSync(`MindSpace/${userId}/public/august-afternoon.html`, 'utf8'); const resolved = resolveWechatDraftThumbPath(html, { h5Root: process.cwd(), userId, workspaceRelativePath: 'public/august-afternoon.html', publishDir: path.join(process.cwd(), 'MindSpace', userId), }); assert.equal(resolved.source, 'hero'); assert.match(resolved.path ?? '', /hero-ca5a45b835d8\.webp$/); }); test('resolveWechatDraftThumbPath falls back to raster sidecar when hero missing', () => { const userId = '1c99b83b-0454-474f-a5d2-129d34506a32'; const html = `