feat: 首次推送到Gitea - 完整项目代码 + 安全加固 + 知识库
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
// 论坛内容 备份+清空 工具(在 app 容器内运行)
|
||||
// 用法: node _forum-clear.mjs dump <out.json> | node _forum-clear.mjs clear
|
||||
const fs = require("fs");
|
||||
const { PrismaMariaDb } = require("@prisma/adapter-mariadb");
|
||||
const { PrismaClient } = require("@prisma/client");
|
||||
const env = fs.readFileSync("/app/.env", "utf8");
|
||||
const m = env.match(/^DATABASE_URL=(.+)$/m);
|
||||
let base = m[1].trim().replace(/^["']|["']$/g, "");
|
||||
if (base.includes("?")) base = base.split("?")[0];
|
||||
const p = new PrismaClient({ adapter: new PrismaMariaDb(base + "?connection_limit=5&pool_timeout=30") });
|
||||
|
||||
const MODE = process.argv[2];
|
||||
|
||||
async function dump(outPath) {
|
||||
const [categories, topics, posts, topicLikes, postLikes, tags, topicTags, bookmarks, reports, subscriptions, moderationLogs] =
|
||||
await Promise.all([
|
||||
p.forumCategory.findMany(),
|
||||
p.forumTopic.findMany(),
|
||||
p.forumPost.findMany(),
|
||||
p.forumTopicLike.findMany(),
|
||||
p.forumPostLike.findMany(),
|
||||
p.forumTag.findMany(),
|
||||
p.forumTopicTag.findMany(),
|
||||
p.forumTopicBookmark.findMany(),
|
||||
p.forumReport.findMany(),
|
||||
p.forumTopicSubscription.findMany(),
|
||||
p.forumModerationLog.findMany(),
|
||||
]);
|
||||
const data = { categories, topics, posts, topicLikes, postLikes, tags, topicTags, bookmarks, reports, subscriptions, moderationLogs };
|
||||
fs.writeFileSync(outPath, JSON.stringify(data));
|
||||
console.log(`DUMP_OK topics=${topics.length} posts=${posts.length} likes=${topicLikes.length + postLikes.length} tags=${tags.length} -> ${outPath} (${(fs.statSync(outPath).size / 1024 / 1024).toFixed(2)}MB)`);
|
||||
}
|
||||
|
||||
async function clearData() {
|
||||
const del = async (name, fn) => {
|
||||
try {
|
||||
const r = await fn();
|
||||
console.log(`cleared ${name}: ${r.count ?? r} rows`);
|
||||
return r.count ?? r;
|
||||
} catch (e) {
|
||||
console.log(`clear ${name} skipped: ${e.message.slice(0, 80)}`);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
await del("forum_topic_subscriptions", () => p.forumTopicSubscription.deleteMany());
|
||||
await del("forum_reports", () => p.forumReport.deleteMany());
|
||||
await del("forum_moderation_logs", () => p.forumModerationLog.deleteMany());
|
||||
await del("forum_topic_bookmarks", () => p.forumTopicBookmark.deleteMany());
|
||||
await del("forum_topic_tags", () => p.forumTopicTag.deleteMany());
|
||||
await del("forum_post_likes", () => p.forumPostLike.deleteMany());
|
||||
await del("forum_topic_likes", () => p.forumTopicLike.deleteMany());
|
||||
await del("forum_posts", () => p.forumPost.deleteMany());
|
||||
await del("forum_topics", () => p.forumTopic.deleteMany());
|
||||
await del("forum_tags", () => p.forumTag.deleteMany());
|
||||
const upd = await p.forumCategory.updateMany({ data: { topicCount: 0 } });
|
||||
console.log(`reset forum_categories.topic_count: ${upd.count}`);
|
||||
const [tc, pc] = await Promise.all([p.forumTopic.count(), p.forumPost.count()]);
|
||||
console.log(`FINAL topics=${tc} posts=${pc}`);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
if (MODE === "dump") {
|
||||
await dump(process.argv[3] || "/tmp/forum-dump.json");
|
||||
} else if (MODE === "clear") {
|
||||
await clearData();
|
||||
} else {
|
||||
console.error("usage: dump <out> | clear");
|
||||
process.exit(1);
|
||||
}
|
||||
})().catch((e) => { console.error("ERR:", e.message); process.exit(1); }).finally(() => p.$disconnect());
|
||||
Reference in New Issue
Block a user