From 4b2c151a8e81406eb06120f91516830c51318565 Mon Sep 17 00:00:00 2001 From: npmrun <1549469775@qq.com> Date: Sat, 18 Apr 2026 20:50:06 +0800 Subject: [PATCH] feat(nitro): scheduled media orphan sweep task Made-with: Cursor --- nuxt.config.ts | 6 ++++++ server/tasks/media/orphan-sweep.ts | 27 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 server/tasks/media/orphan-sweep.ts diff --git a/nuxt.config.ts b/nuxt.config.ts index 375bfc6..c4473f5 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -15,6 +15,12 @@ export default defineNuxtConfig({ } }, nitro: { + experimental: { + tasks: true, + }, + scheduledTasks: { + '5 * * * *': ['media:orphan-sweep'], + }, typescript: { tsConfig: { compilerOptions: { diff --git a/server/tasks/media/orphan-sweep.ts b/server/tasks/media/orphan-sweep.ts new file mode 100644 index 0000000..01508c0 --- /dev/null +++ b/server/tasks/media/orphan-sweep.ts @@ -0,0 +1,27 @@ +import { getGlobalConfigValue } from "#server/service/config"; +import { purgeAllDeletableOrphansGlobally } from "#server/service/media"; + +let lastRunAt = 0; + +export default defineTask({ + meta: { + name: "media:orphan-sweep", + description: "Delete deletable orphan media when admin global switch is on", + }, + async run() { + const enabled = await getGlobalConfigValue("mediaOrphanAutoSweepEnabled"); + if (!enabled) { + return { result: "skipped: disabled" }; + } + + const intervalMinutes = await getGlobalConfigValue("mediaOrphanAutoSweepIntervalMinutes"); + const intervalMs = intervalMinutes * 60_000; + if (Date.now() - lastRunAt < intervalMs) { + return { result: "skipped: throttle" }; + } + + lastRunAt = Date.now(); + const deletedCount = await purgeAllDeletableOrphansGlobally(50); + return { result: "ok", deletedCount }; + }, +});