Browse Source

feat(config): admin toggles for media orphan auto-sweep

Made-with: Cursor
main
npmrun 10 hours ago
parent
commit
fd47913043
  1. 28
      app/pages/me/admin/config/index.vue
  2. 15
      server/service/config/registry.ts

28
app/pages/me/admin/config/index.vue

@ -8,6 +8,8 @@ type GlobalConfigPayload = {
config: { config: {
siteName: string siteName: string
allowRegister: boolean allowRegister: boolean
mediaOrphanAutoSweepEnabled: boolean
mediaOrphanAutoSweepIntervalMinutes: number
} }
} }
@ -18,6 +20,8 @@ const loading = ref(true)
const saving = ref(false) const saving = ref(false)
const siteName = ref('') const siteName = ref('')
const allowRegister = ref(true) const allowRegister = ref(true)
const mediaOrphanAutoSweepEnabled = ref(false)
const mediaOrphanAutoSweepIntervalMinutes = ref(60)
async function ensureAdmin() { async function ensureAdmin() {
await refresh(true) await refresh(true)
@ -33,6 +37,8 @@ async function load() {
const cfg = unwrapApiBody(res).config const cfg = unwrapApiBody(res).config
siteName.value = cfg.siteName siteName.value = cfg.siteName
allowRegister.value = cfg.allowRegister allowRegister.value = cfg.allowRegister
mediaOrphanAutoSweepEnabled.value = cfg.mediaOrphanAutoSweepEnabled
mediaOrphanAutoSweepIntervalMinutes.value = cfg.mediaOrphanAutoSweepIntervalMinutes
} finally { } finally {
loading.value = false loading.value = false
} }
@ -55,6 +61,8 @@ async function save() {
try { try {
await putKey('siteName', siteName.value.trim()) await putKey('siteName', siteName.value.trim())
await putKey('allowRegister', allowRegister.value) await putKey('allowRegister', allowRegister.value)
await putKey('mediaOrphanAutoSweepEnabled', mediaOrphanAutoSweepEnabled.value)
await putKey('mediaOrphanAutoSweepIntervalMinutes', mediaOrphanAutoSweepIntervalMinutes.value)
await load() await load()
await refreshGlobalConfig() await refreshGlobalConfig()
} finally { } finally {
@ -69,7 +77,7 @@ async function save() {
应用配置 应用配置
</h1> </h1>
<p class="text-sm text-muted"> <p class="text-sm text-muted">
全局设置站点名称与开放注册 全局设置站点名称开放注册与媒体孤儿自动清扫
</p> </p>
<UCard> <UCard>
@ -89,6 +97,24 @@ async function save() {
> >
<UCheckbox v-model="allowRegister" label="开启" /> <UCheckbox v-model="allowRegister" label="开启" />
</UFormField> </UFormField>
<UFormField
label="媒体孤儿自动清扫"
description="全站生效、仅删除已过宽限期且无引用的图片、建议先在「图片孤儿审查」确认。"
>
<UCheckbox v-model="mediaOrphanAutoSweepEnabled" label="开启定时自动清扫" />
</UFormField>
<UFormField
label="清扫间隔(分钟)"
description="15–1440;与定时任务触发频率配合,任务内会按此间隔节流。"
>
<UInput
v-model.number="mediaOrphanAutoSweepIntervalMinutes"
type="number"
:min="15"
:max="1440"
step="1"
/>
</UFormField>
<UButton :loading="saving" @click="save"> <UButton :loading="saving" @click="save">
保存 保存
</UButton> </UButton>

15
server/service/config/registry.ts

@ -31,6 +31,21 @@ const CONFIG_REGISTRY = {
defaultValue: true, defaultValue: true,
userOverridable: false, userOverridable: false,
}), }),
mediaOrphanAutoSweepEnabled: defineConfig<boolean>({
key: "mediaOrphanAutoSweepEnabled",
scope: "global",
valueType: "boolean",
defaultValue: false,
userOverridable: false,
}),
mediaOrphanAutoSweepIntervalMinutes: defineConfig<number>({
key: "mediaOrphanAutoSweepIntervalMinutes",
scope: "global",
valueType: "number",
defaultValue: 60,
userOverridable: false,
validate: (value: number) => Number.isInteger(value) && value >= 15 && value <= 1440,
}),
theme: defineConfig<string>({ theme: defineConfig<string>({
key: "theme", key: "theme",
scope: "both", scope: "both",

Loading…
Cancel
Save