Files
2026-08-16 17:23:53 +08:00

35 lines
1.7 KiB
JavaScript

import { readdir, readFile, writeFile } from 'node:fs/promises';
import { existsSync } from 'node:fs';
import path from 'node:path';
const root = process.cwd();
const reportsRoot = path.join(root, 'reports');
const output = path.join(root, 'data', 'reports.json');
const categoryNames = { daily: '每日复盘', intraday: '盘中项目', sector: '行业观察', stock: '个股跟踪' };
const files = [];
async function walk(dir) {
if (!existsSync(dir)) return;
for (const item of await readdir(dir, { withFileTypes: true })) {
const full = path.join(dir, item.name);
if (item.isDirectory()) await walk(full);
else if (item.name.endsWith('.html')) files.push(full);
}
}
await walk(reportsRoot);
const records = [];
for (const file of files) {
const rel = path.relative(root, file).split(path.sep).join('/');
const parts = rel.split('/');
const category = parts[1];
const match = parts.at(-1).match(/^(\d{4}-\d{2}-\d{2})-(.+)\.html$/);
if (!match) { console.warn(`Skipped (expected YYYY-MM-DD-slug.html): ${rel}`); continue; }
const [, date, slug] = match;
const html = await readFile(file, 'utf8');
const title = html.match(/<title>(.*?)<\/title>/i)?.[1]?.trim() || slug.replaceAll('-', ' ');
const summary = html.match(/<meta\s+name=["']description["']\s+content=["'](.*?)["']/i)?.[1] || '打开查看详细研究内容';
records.push({ id: `${category}-${date}-${slug}`, category, categoryName: categoryNames[category] || category, date, title, summary, tags: [category.toUpperCase()], path: rel });
}
records.sort((a, b) => b.date.localeCompare(a.date) || a.title.localeCompare(b.title));
await writeFile(output, `${JSON.stringify(records, null, 2)}\n`);
console.log(`Indexed ${records.length} report(s) → ${path.relative(root, output)}`);