fix(news): count lead cards in degradation check, add draft dry-run script
Trying to push a WeChat draft locally surfaced two problems. isNewsMorningContentDegraded matched cards with `class="card(?:\s|")`, which never matches news002's `class="lead-card"`. Headline cards were therefore invisible to the check, so a healthy news002 page could be flagged as degraded and regenerated. Count cards through the shared extractor instead, which handles card, lead-card and highlight-box alike. Add scripts/dryrun-news-morning-draft.mjs to run a page through the dedup gate, degradation check, inline conversion and footer layout without calling the WeChat API, since local IPs are not in the official account whitelist (errcode 40164) and a real push would write into the production draft box. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/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 = [
|
||||
// 微信不支持 <style>,早报路径必须全部内联。
|
||||
['无 <style> 块(已内联)', !/<style/i.test(article.content)],
|
||||
['正文使用内联 style', (article.content.match(/style="/g) ?? []).length > 20],
|
||||
['含「阅读原文」引导', /阅读原文/u.test(article.content)],
|
||||
['含关注二维码区', /<img[^>]+dryrun-qrcode/i.test(article.content)],
|
||||
['无 <script> 残留', !/<script/i.test(article.content)],
|
||||
['无 MindSpace 平台水印', !/data-mindspace-page-tag/i.test(article.content)],
|
||||
];
|
||||
console.log('\n[5] 合规检查:');
|
||||
for (const [label, ok] of checks) console.log(` ${ok ? '✅' : '❌'} ${label}`);
|
||||
|
||||
const base = path.basename(input, '.html');
|
||||
const outHtml = path.join(outDir, `${base}.wechat-draft.html`);
|
||||
fs.writeFileSync(outHtml, `<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>${article.title}(微信草稿 dry-run)</title></head>${article.content}</html>`);
|
||||
console.log(`\n草稿正文已写入:${outHtml}`);
|
||||
|
||||
const outDeduped = path.join(outDir, `${base}.deduped.html`);
|
||||
if (deduped.changed) {
|
||||
fs.writeFileSync(outDeduped, deduped.html);
|
||||
console.log(`去重后页面已写入:${outDeduped}`);
|
||||
}
|
||||
Reference in New Issue
Block a user