fix: 修复后台文章计数为0 + 分类编辑补全描述字段 + CSP放行外部图片 + 更新关于页描述
- 文章管理:计数请求补 page=1 参数,命中分页接口返回正确的 total - 分类管理:编辑模式新增描述输入框,保存时一并提交 description - CSP:img-src 加入 https: 允许加载外部图片 - 关于页:数据存储描述从 JSON 文件更正为 SQLite 数据库 - Footer:添加 ICP 备案号
This commit is contained in:
+19
-136
@@ -1,141 +1,24 @@
|
||||
/**
|
||||
* Seed script — run once to populate initial data from mock posts.
|
||||
* Usage: npx tsx src/lib/seed.ts
|
||||
* Seed 脚本入口 — 可手动运行:`npx tsx src/lib/seed.ts`
|
||||
*
|
||||
* 运行时自动初始化已在 store.ts 的 ensureSeed() 中处理,
|
||||
* 本脚本仅作为显式重置/查看用途。
|
||||
*/
|
||||
import { createPost, createCategory, createTag, getPosts, getCategories, getTags } from "./store";
|
||||
import { ensureSeed, getPosts, getCategories, getTags } from "./store";
|
||||
|
||||
const seedPosts = [
|
||||
{
|
||||
slug: "on-writing-and-silence",
|
||||
title: "论写作与沉默",
|
||||
excerpt: "有些话适合写在纸上,有些话适合留在风里。写作不是填满空白的过程,而是从空白中提炼意义的旅程。",
|
||||
content: "<p>有些话适合写在纸上,有些话适合留在风里。</p><p>我常常觉得,沉默是一种被低估的能力。在这个信息过载的时代,我们急于表达、急于分享,却很少给自己留出沉默的空间。写作不是填满空白的过程,而是从空白中提炼意义的旅程。</p><p>每一次落笔,都是一次与自己的对话。那些在深夜里涌现的念头,像潮水一样涌来,又像退潮后的贝壳,最终留下的才是最珍贵的。</p><p>我开始学会在写作之前先沉默。让想法在脑海中沉淀,让语言在时间里发酵。好的文字从来不是急出来的。</p>",
|
||||
date: "2026-06-15",
|
||||
category: "随笔",
|
||||
tags: ["写作", "思考", "生活哲学"],
|
||||
readingTime: 4,
|
||||
featured: true,
|
||||
status: "published" as const,
|
||||
},
|
||||
{
|
||||
slug: "a-walk-in-the-mountains",
|
||||
title: "山中漫步",
|
||||
excerpt: "大别山的清晨,雾气从谷底升起,像是大地在缓缓呼吸。脚下的石板路被露水打湿,每一步都需要格外小心。",
|
||||
content: "<p>大别山的清晨,雾气从谷底升起,像是大地在缓缓呼吸。</p><p>脚下的石板路被露水打湿,每一步都需要格外小心。路旁的野花在薄雾中若隐若现,紫色和白色交替出现,像是大自然精心编排的欢迎仪式。</p><p>山里的时间过得格外慢。没有手机的信号,没有城市的喧嚣,只有鸟鸣和溪流的声音。这种安静让我想起小时候在外婆家的日子。</p>",
|
||||
date: "2026-06-10",
|
||||
category: "旅行",
|
||||
tags: ["旅行", "自然", "六安"],
|
||||
readingTime: 6,
|
||||
featured: true,
|
||||
status: "published" as const,
|
||||
},
|
||||
{
|
||||
slug: "notes-on-digital-twin",
|
||||
title: "数字孪生笔记:从3D建模到Web可视化",
|
||||
excerpt: "从 Three.js 到 React Three Fiber,Web 3D 的门槛比想象中低很多,但要做好,需要理解的东西远不止代码。",
|
||||
content: "<p>从 Three.js 到 React Three Fiber,Web 3D 的门槛比想象中低很多。</p><p>但要做好,需要理解的东西远不止代码。光照、材质、相机、性能优化,每一个都是深坑。这篇文章记录我在数字孪生项目中的一些实践和思考。</p>",
|
||||
date: "2026-06-05",
|
||||
category: "技术",
|
||||
tags: ["Web3D", "React", "Three.js", "前端"],
|
||||
readingTime: 8,
|
||||
featured: false,
|
||||
status: "published" as const,
|
||||
},
|
||||
{
|
||||
slug: "reading-list-spring",
|
||||
title: "春日书单:五本改变我看世界方式的书",
|
||||
excerpt: "春天适合读一些柔软的书。不是那种让人醍醐灌顶的大部头,而是像春雨一样润物细无声的文字。",
|
||||
content: "<p>春天适合读一些柔软的书。</p><p>不是那种让人醍醐灌顶的大部头,而是像春雨一样润物细无声的文字。以下五本书,在这个春天给了我很多安静的力量。</p>",
|
||||
date: "2026-05-28",
|
||||
category: "阅读",
|
||||
tags: ["阅读", "书单", "生活"],
|
||||
readingTime: 5,
|
||||
featured: true,
|
||||
status: "published" as const,
|
||||
},
|
||||
{
|
||||
slug: "stable-diffusion-local-setup",
|
||||
title: "本地部署 Stable Diffusion 踩坑记",
|
||||
excerpt: "M3 16GB 的统一内存是优势也是限制。记录在 Apple Silicon 上跑 SD 1.5 和 SDXL 的完整过程。",
|
||||
content: "<p>M3 16GB 的统一内存是优势也是限制。</p><p>这篇文章记录在 Apple Silicon 上跑 SD 1.5 和 SDXL 的完整过程,包括环境搭建、模型选择、LoRA 训练的一些尝试。</p>",
|
||||
date: "2026-05-20",
|
||||
category: "技术",
|
||||
tags: ["AI", "Stable Diffusion", "Apple Silicon"],
|
||||
readingTime: 10,
|
||||
featured: false,
|
||||
status: "published" as const,
|
||||
},
|
||||
{
|
||||
slug: "lightbox-dream",
|
||||
title: "灯箱:一个小城青年的创业梦",
|
||||
excerpt: "标识灯箱这个行业,外行人觉得简单,内行人知道水深。从3D预览到商业模式,记录 sui_lightbox 的诞生过程。",
|
||||
content: "<p>标识灯箱这个行业,外行人觉得简单,内行人知道水深。</p><p>从最初的一个想法,到3D预览原型的实现,再到商业模式的探索。这篇文章记录 sui_lightbox 项目从0到1的过程。</p>",
|
||||
date: "2026-05-12",
|
||||
category: "创业",
|
||||
tags: ["创业", "灯箱", "产品", "sui_lightbox"],
|
||||
readingTime: 7,
|
||||
featured: true,
|
||||
status: "published" as const,
|
||||
},
|
||||
{
|
||||
slug: "rainy-day-thoughts",
|
||||
title: "雨天杂记",
|
||||
excerpt: "六月的梅雨季,窗外的梧桐叶被雨打得东倒西歪。泡一壶六安瓜片,坐在窗前看雨,什么都不想。",
|
||||
content: "<p>六月的梅雨季,窗外的梧桐叶被雨打得东倒西歪。</p><p>泡一壶六安瓜片,坐在窗前看雨,什么都不想。这种无所事事的下午,反而是一周中最有创造力的时刻。</p>",
|
||||
date: "2026-05-05",
|
||||
category: "随笔",
|
||||
tags: ["随笔", "生活", "六安"],
|
||||
readingTime: 3,
|
||||
featured: false,
|
||||
status: "published" as const,
|
||||
},
|
||||
{
|
||||
slug: "next-js-blog-from-scratch",
|
||||
title: "从零搭建一个博客系统",
|
||||
excerpt: "为什么选择 Next.js + Halo CMS?为什么不用 WordPress?这篇文章聊聊技术选型的思考过程。",
|
||||
content: "<p>为什么选择 Next.js + Halo CMS?为什么不用 WordPress?</p><p>作为一个前端开发者,我希望能完全掌控博客的UI和交互体验。Halo CMS 提供了足够好的内容管理API,而 Next.js 则让我可以自由设计前端展示。</p>",
|
||||
date: "2026-04-28",
|
||||
category: "技术",
|
||||
tags: ["Next.js", "博客", "Halo CMS", "前端"],
|
||||
readingTime: 6,
|
||||
featured: false,
|
||||
status: "published" as const,
|
||||
},
|
||||
];
|
||||
|
||||
const seedCategories = [
|
||||
{ name: "技术", description: "代码、架构与技术探索" },
|
||||
{ name: "随笔", description: "生活感悟与碎片思考" },
|
||||
{ name: "旅行", description: "在路上看到的风景与人" },
|
||||
{ name: "阅读", description: "书中世界与阅读心得" },
|
||||
{ name: "创业", description: "产品思考与创业记录" },
|
||||
];
|
||||
|
||||
const seedTags = [
|
||||
"写作", "思考", "生活哲学", "旅行", "自然", "六安",
|
||||
"Web3D", "React", "Three.js", "前端", "阅读", "书单",
|
||||
"生活", "AI", "Stable Diffusion", "Apple Silicon",
|
||||
"创业", "灯箱", "产品", "sui_lightbox", "随笔",
|
||||
"Next.js", "博客", "Halo CMS",
|
||||
];
|
||||
|
||||
// Only seed if empty
|
||||
if (getPosts().length === 0) {
|
||||
console.log("Seeding posts...");
|
||||
seedPosts.forEach((p) => createPost(p));
|
||||
console.log(` Created ${seedPosts.length} posts`);
|
||||
async function main() {
|
||||
await ensureSeed();
|
||||
const [posts, categories, tags] = await Promise.all([
|
||||
getPosts(),
|
||||
getCategories(),
|
||||
getTags(),
|
||||
]);
|
||||
console.log("Seed complete:", {
|
||||
posts: posts.length,
|
||||
categories: categories.length,
|
||||
tags: tags.length,
|
||||
});
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (getCategories().length === 0) {
|
||||
console.log("Seeding categories...");
|
||||
seedCategories.forEach((c) => createCategory(c));
|
||||
console.log(` Created ${seedCategories.length} categories`);
|
||||
}
|
||||
|
||||
if (getTags().length === 0) {
|
||||
console.log("Seeding tags...");
|
||||
seedTags.forEach((t) => createTag({ name: t }));
|
||||
console.log(` Created ${seedTags.length} tags`);
|
||||
}
|
||||
|
||||
console.log("Seed complete.");
|
||||
main();
|
||||
|
||||
Reference in New Issue
Block a user