|
@@ -0,0 +1,136 @@
|
|
|
|
|
+
|
|
|
|
|
+import { writeFile } from 'fs/promises';
|
|
|
|
|
+import { GetContentListParams, type GetContentDetailItem, type GetContentListItem } from '~/api/CommonContent';
|
|
|
|
|
+import ProjectsContent from '~/api/inheritor/ProjectsContent';
|
|
|
|
|
+
|
|
|
|
|
+const data = [] as Array<GetContentListItem & { detail?: GetContentDetailItem }>;
|
|
|
|
|
+
|
|
|
|
|
+const markdownText = ref('');
|
|
|
|
|
+
|
|
|
|
|
+// HTML转Markdown的简单实现
|
|
|
|
|
+function htmlToMarkdown(html: string): string {
|
|
|
|
|
+ if (!html) return '';
|
|
|
|
|
+
|
|
|
|
|
+ // 处理标题
|
|
|
|
|
+ html = html.replace(/<h1[^>]*>(.*?)<\/h1>/gi, '# $1\n\n');
|
|
|
|
|
+ html = html.replace(/<h2[^>]*>(.*?)<\/h2>/gi, '## $1\n\n');
|
|
|
|
|
+ html = html.replace(/<h3[^>]*>(.*?)<\/h3>/gi, '### $1\n\n');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理段落
|
|
|
|
|
+ html = html.replace(/<p[^>]*>(.*?)<\/p>/gi, '$1\n\n');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理加粗
|
|
|
|
|
+ html = html.replace(/<strong[^>]*>(.*?)<\/strong>/gi, '**$1**');
|
|
|
|
|
+ html = html.replace(/<b[^>]*>(.*?)<\/b>/gi, '**$1**');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理斜体
|
|
|
|
|
+ html = html.replace(/<em[^>]*>(.*?)<\/em>/gi, '*$1*');
|
|
|
|
|
+ html = html.replace(/<i[^>]*>(.*?)<\/i>/gi, '*$1*');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理列表
|
|
|
|
|
+ html = html.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, (match, content) => {
|
|
|
|
|
+ return content.replace(/<li[^>]*>(.*?)<\/li>/gi, '- $1\n') + '\n';
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ html = html.replace(/<ol[^>]*>([\s\S]*?)<\/ol>/gi, (match, content, index) => {
|
|
|
|
|
+ let count = 1;
|
|
|
|
|
+ return content.replace(/<li[^>]*>(.*?)<\/li>/gi, () => {
|
|
|
|
|
+ return `${count++}. $1\n`;
|
|
|
|
|
+ }) + '\n';
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 处理图片
|
|
|
|
|
+ html = html.replace(/<img[^>]*src="([^"]*)"[^>]*alt="([^"]*)"[^>]*>/gi, '');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理链接
|
|
|
|
|
+ html = html.replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/gi, '[$2]($1)');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理换行
|
|
|
|
|
+ html = html.replace(/<br[^>]*>/gi, '\n');
|
|
|
|
|
+
|
|
|
|
|
+ // 去除所有HTML标签
|
|
|
|
|
+ html = html.replace(/<[^>]*>/g, '');
|
|
|
|
|
+
|
|
|
|
|
+ // 处理多余的换行
|
|
|
|
|
+ html = html.replace(/\n\s*\n/g, '\n\n');
|
|
|
|
|
+
|
|
|
|
|
+ return html.trim();
|
|
|
|
|
+}
|
|
|
|
|
+// 生成Markdown文本
|
|
|
|
|
+function generateMarkdown(): string {
|
|
|
|
|
+ let md = '';
|
|
|
|
|
+
|
|
|
|
|
+ data.forEach((item, index) => {
|
|
|
|
|
+ if (index > 0) {
|
|
|
|
|
+ md += '\n\n---\n\n';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 基本信息
|
|
|
|
|
+ md += `# ${item.title}\n\n`;
|
|
|
|
|
+ md += `${item.desc || '无描述'}\n\n`;
|
|
|
|
|
+ md += `## 基本信息\n\n`;
|
|
|
|
|
+ md += `- 非遗级别: ${item.levelText || '无'}\n`;
|
|
|
|
|
+ md += `- 非遗类别: ${item.ichTypeText || '无'}\n`;
|
|
|
|
|
+ md += `- 地区: ${item.district || '无'}\n`;
|
|
|
|
|
+ md += `- 批次: ${item.batchText || '无'}\n`;
|
|
|
|
|
+ md += `- 保护单位: ${item.unit || '无'}\n\n`;
|
|
|
|
|
+
|
|
|
|
|
+ // 图片
|
|
|
|
|
+ if (item.images && item.images.length > 0) {
|
|
|
|
|
+ md += `## 图片\n\n`;
|
|
|
|
|
+ item.images.forEach(image => {
|
|
|
|
|
+ md += `\n\n`;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 详细信息
|
|
|
|
|
+ if (item.detail) {
|
|
|
|
|
+ // 简介
|
|
|
|
|
+ if (item.detail.intro) {
|
|
|
|
|
+ md += `## 简介\n\n`;
|
|
|
|
|
+ md += htmlToMarkdown(item.detail.intro) + '\n\n';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 传承人
|
|
|
|
|
+ if (item.detail.inheritorsList && item.detail.inheritorsList.length > 0) {
|
|
|
|
|
+ md += `## 相关传承人\n\n`;
|
|
|
|
|
+ if (item.detail.inheritor) {
|
|
|
|
|
+ md += htmlToMarkdown(item.detail.inheritor) + '\n\n';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ item.detail.inheritorsList.forEach(inheritor => {
|
|
|
|
|
+ md += `### ${inheritor.title}\n\n`;
|
|
|
|
|
+ md += `级别:${inheritor.levelLext || '无'}\n\n`;
|
|
|
|
|
+ if (inheritor.image) {
|
|
|
|
|
+ md += `\n\n`;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 传习所
|
|
|
|
|
+ if (item.detail.ichSitesList && item.detail.ichSitesList.length > 0) {
|
|
|
|
|
+ md += `## 相关传习所\n\n`;
|
|
|
|
|
+ item.detail.ichSitesList.forEach(site => {
|
|
|
|
|
+ md += `### ${site.title}\n\n`;
|
|
|
|
|
+ md += `级别:${site.levelLext || '无'}\n\n`;
|
|
|
|
|
+ md += `地址:${site.address || '无'}\n\n`;
|
|
|
|
|
+ if (site.image) {
|
|
|
|
|
+ md += `\n\n`;
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return md;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+(await ProjectsContent.getContentList(new GetContentListParams(), 1, 1000)).list.forEach(item => {
|
|
|
|
|
+ data.push(item);
|
|
|
|
|
+});
|
|
|
|
|
+for (const item of data) {
|
|
|
|
|
+ item.detail = (await ProjectsContent.getContentDetail(item.id)) as GetContentDetailItem;
|
|
|
|
|
+}
|
|
|
|
|
+// 生成Markdown文本
|
|
|
|
|
+markdownText.value = generateMarkdown();
|
|
|
|
|
+await writeFile('非遗项目数据.md', markdownText.value);
|