116 lines
3.3 KiB
JavaScript
116 lines
3.3 KiB
JavaScript
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
// 书籍目录路径
|
||
const BOOK_DIR = path.join(__dirname, '../book');
|
||
const OUTPUT_FILE = path.join(__dirname, '../lib/book-data.ts');
|
||
|
||
// 扫描所有章节
|
||
function scanChapters() {
|
||
const chapters = [];
|
||
let index = 1;
|
||
|
||
// 添加序言
|
||
const prefaceFile = path.join(BOOK_DIR, '序言|为什么我每天早上6点在Soul开播?.md');
|
||
if (fs.existsSync(prefaceFile)) {
|
||
chapters.push({
|
||
index,
|
||
id: `preface`,
|
||
title: '序言|为什么我每天早上6点在Soul开播?',
|
||
filePath: prefaceFile,
|
||
partTitle: '序言',
|
||
updateTime: getFileTime(prefaceFile)
|
||
});
|
||
index++;
|
||
}
|
||
|
||
// 扫描五篇
|
||
const parts = [
|
||
{ dir: '第一篇|真实的人', title: '第一篇|真实的人' },
|
||
{ dir: '第二篇|真实的行业', title: '第二篇|真实的行业' },
|
||
{ dir: '第三篇|真实的错误', title: '第三篇|真实的错误' },
|
||
{ dir: '第四篇|真实的赚钱', title: '第四篇|真实的赚钱' },
|
||
{ dir: '第五篇|真实的社会', title: '第五篇|真实的社会' }
|
||
];
|
||
|
||
parts.forEach(part => {
|
||
const partDir = path.join(BOOK_DIR, part.dir);
|
||
if (!fs.existsSync(partDir)) return;
|
||
|
||
// 读取该篇下的所有章文件夹
|
||
const chapterDirs = fs.readdirSync(partDir)
|
||
.filter(name => !name.startsWith('.') && fs.statSync(path.join(partDir, name)).isDirectory())
|
||
.sort();
|
||
|
||
chapterDirs.forEach(chapterDir => {
|
||
const chapterPath = path.join(partDir, chapterDir);
|
||
const mdFiles = fs.readdirSync(chapterPath)
|
||
.filter(name => name.endsWith('.md'))
|
||
.sort();
|
||
|
||
mdFiles.forEach(mdFile => {
|
||
const filePath = path.join(chapterPath, mdFile);
|
||
const title = mdFile.replace('.md', '');
|
||
|
||
chapters.push({
|
||
index,
|
||
id: `chapter-${index}`,
|
||
title,
|
||
filePath,
|
||
partTitle: part.title,
|
||
chapterDir,
|
||
updateTime: getFileTime(filePath)
|
||
});
|
||
index++;
|
||
});
|
||
});
|
||
});
|
||
|
||
// 添加尾声
|
||
const epilogueFile = path.join(BOOK_DIR, '尾声|这本书的真实目的.md');
|
||
if (fs.existsSync(epilogueFile)) {
|
||
chapters.push({
|
||
index,
|
||
id: `epilogue`,
|
||
title: '尾声|这本书的真实目的',
|
||
filePath: epilogueFile,
|
||
partTitle: '尾声',
|
||
updateTime: getFileTime(epilogueFile)
|
||
});
|
||
}
|
||
|
||
return chapters;
|
||
}
|
||
|
||
function getFileTime(filePath) {
|
||
const stats = fs.statSync(filePath);
|
||
const now = Date.now();
|
||
const diff = now - stats.mtimeMs;
|
||
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||
|
||
if (days === 0) return '今天';
|
||
if (days === 1) return '昨天';
|
||
if (days < 7) return `${days}天前`;
|
||
if (days < 30) return `${Math.floor(days / 7)}周前`;
|
||
return `${Math.floor(days / 30)}个月前`;
|
||
}
|
||
|
||
// 生成TypeScript数据文件
|
||
function generateDataFile() {
|
||
const chapters = scanChapters();
|
||
|
||
console.log(`扫描到 ${chapters.length} 个章节`);
|
||
|
||
// 生成JSON
|
||
fs.writeFileSync(
|
||
path.join(__dirname, '../public/book-chapters.json'),
|
||
JSON.stringify(chapters, null, 2)
|
||
);
|
||
|
||
console.log('✅ 章节数据已生成:public/book-chapters.json');
|
||
console.log(` 共 ${chapters.length} 章`);
|
||
}
|
||
|
||
// 执行
|
||
generateDataFile();
|