#!/usr/bin/env node /** * 本地 dry-run:把一张早报 HTML 走完「去重闸门 → 微信 inline 转换 → 统一页脚」全链路, * 输出最终草稿正文,但不调用任何微信接口、不落 DB。 * * 用于在本机 IP 不在公众号白名单时验证 news001 / news002 的草稿产出。 * * 用法: * node scripts/dryrun-news-morning-draft.mjs <页面.html> [输出目录] */ import fs from 'node:fs'; import path from 'node:path'; import { dedupeNewsMorningHtml, formatNewsMorningDedupeSummary, } from '../wechat-news-morning-dedup.mjs'; import { convertNewsPageHtmlToWechatArticle, isDailyNewsFormat, isNewsMorningContentDegraded, } from '../wechat-news-morning-draft.mjs'; const MAX_WECHAT_CONTENT_CHARS = 20000; const input = process.argv[2]; const outDir = process.argv[3] || path.dirname(input ?? '.'); if (!input || !fs.existsSync(input)) { console.error('用法:node scripts/dryrun-news-morning-draft.mjs <页面.html> [输出目录]'); process.exit(1); } const publicUrl = 'https://m.tkmind.cn/MindSpace/dry-run/public/daily-news-dryrun.html'; const raw = fs.readFileSync(input, 'utf8'); console.log(`输入:${input}(${raw.length} 字符)`); // 1. 去重闸门 const deduped = dedupeNewsMorningHtml(raw); console.log(`\n[1] 去重闸门:${formatNewsMorningDedupeSummary(deduped)}`); if (deduped.removedSectionIds.length) { console.log(` 移除空栏目:${deduped.removedSectionIds.join(', ')}`); } // 2. 降级检测 const degraded = isNewsMorningContentDegraded(deduped.html); console.log(`\n[2] 降级检测:${degraded ? '❌ 判定为降级页(卡片不足/检索失败)' : '✅ 正常'}`); // 3. 识别版式 + 转换为微信草稿 console.log(`\n[3] 版式识别:${isDailyNewsFormat(deduped.html) ? '✅ daily-news' : '❌ 非早报版式'}`); const article = convertNewsPageHtmlToWechatArticle( deduped.html, { publicUrl, qrcodeImageUrl: 'https://mmbiz.qpic.cn/dryrun-qrcode.png' }, ); console.log('\n[4] 草稿产出:'); console.log(` 标题:${article.title}`); console.log(` 摘要:${String(article.digest ?? '').slice(0, 60)}`); console.log(` 正文长度:${article.content.length} / ${MAX_WECHAT_CONTENT_CHARS}` + (article.content.length > MAX_WECHAT_CONTENT_CHARS ? ' ❌ 超限' : ' ✅ 未超限')); const checks = [ // 微信不支持