feat: add empty address cleanup feature (#765)

* feat: add empty address cleanup feature

Add functionality to clean up email addresses that have never received any emails and were created more than N days ago.

Changes:
- Add emptyAddress cleanup type to backend cleanup logic
- Add enableEmptyAddressAutoCleanup and cleanEmptyAddressDays to CleanupSettings model
- Add scheduled task support for auto-cleanup of empty addresses
- Add UI controls in Maintenance page for manual and auto cleanup
- Add i18n support (English and Chinese translations)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: update dependencies

Update package.json and lock files across frontend, worker, pages, and vitepress-docs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* docs: update CHANGELOG for empty address cleanup feature

Add entry for new maintenance page feature to clean up email addresses with no emails older than N days

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Dream Hunter
2025-11-13 17:57:35 +08:00
committed by GitHub
parent 088bf3eefe
commit 113f9ad66b
12 changed files with 1237 additions and 1265 deletions

View File

@@ -49,7 +49,7 @@
"vite-plugin-wasm": "^3.5.0",
"workbox-build": "^7.3.0",
"workbox-window": "^7.3.0",
"wrangler": "^4.46.0"
"wrangler": "^4.47.0"
},
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39"
}

678
frontend/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,8 @@ const cleanupModel = ref({
cleanInactiveAddressDays: 30,
enableUnboundAddressAutoCleanup: false,
cleanUnboundAddressDays: 30,
enableEmptyAddressAutoCleanup: false,
cleanEmptyAddressDays: 30,
})
const { t } = useI18n({
@@ -31,6 +33,7 @@ const { t } = useI18n({
addressCreateLabel: "Cleanup the address created before n days",
inactiveAddressLabel: "Cleanup the inactive address before n days",
unboundAddressLabel: "Cleanup the unbound address before n days",
emptyAddressLabel: "Cleanup the empty address before n days",
cleanupNow: "Cleanup now",
autoCleanup: "Auto cleanup",
cleanupSuccess: "Cleanup success",
@@ -45,6 +48,7 @@ const { t } = useI18n({
addressCreateLabel: "清理 n 天前创建的地址",
inactiveAddressLabel: "清理 n 天前的未活跃地址",
unboundAddressLabel: "清理 n 天前的未绑定用户地址",
emptyAddressLabel: "清理 n 天前空邮件的邮箱地址",
autoCleanup: "自动清理",
cleanupSuccess: "清理成功",
cleanupNow: "立即清理",
@@ -177,6 +181,18 @@ onMounted(async () => {
{{ t('cleanupNow') }}
</n-button>
</n-form-item-row>
<n-form-item-row :label="t('emptyAddressLabel')">
<n-checkbox v-model:checked="cleanupModel.enableEmptyAddressAutoCleanup">
{{ t('autoCleanup') }}
</n-checkbox>
<n-input-number v-model:value="cleanupModel.cleanEmptyAddressDays" :placeholder="t('tip')" />
<n-button @click="cleanup('emptyAddress', cleanupModel.cleanEmptyAddressDays)">
<template #icon>
<n-icon :component="CleaningServicesFilled" />
</template>
{{ t('cleanupNow') }}
</n-button>
</n-form-item-row>
</n-form>
</n-card>
</div>