import { Router, Request, Response } from 'express'; import { runFullCleanup, emptyAllTrash } from '../cloud/cleanup.service'; const router = Router(); // ============ Cleanup & Storage Management ============ /** * POST /api/admin/cleanup/run * Manually trigger a cleanup cycle: * - Trash old date folders from cloud drives * - Delete old save_records * - Empty recycle bin */ router.post('/admin/cleanup/run', async (_req: Request, res: Response) => { try { const stats = await runFullCleanup(); res.json({ success: stats.errors.length === 0, files_trashed: stats.filesTrashed, logs_deleted: stats.logsDeleted, trash_emptied: stats.trashEmptied, errors: stats.errors, message: stats.errors.length === 0 ? `✅ 清理完成:移入回收站 ${stats.filesTrashed} 个文件夹,删除 ${stats.logsDeleted} 条日志,清空回收站${stats.trashEmptied ? '✓' : '-'}` : `清理完成,但有 ${stats.errors.length} 个错误`, }); } catch (err: any) { res.status(500).json({ success: false, error: err.message }); } }); /** * POST /api/admin/cleanup/empty-trash * Empty recycle bin for all cloud drives (permanently delete, frees space). */ router.post('/admin/cleanup/empty-trash', async (_req: Request, res: Response) => { try { const result = await emptyAllTrash(); res.json({ success: result.errors.length === 0, emptied: result.emptied, errors: result.errors, message: result.emptied ? '✅ 回收站已清空,存储空间已释放' : (result.errors.length > 0 ? `清空回收站部分失败:${result.errors.join('; ')}` : '没有可清空的网盘'), }); } catch (err: any) { res.status(500).json({ success: false, error: err.message }); } }); /** * Extract genre tags from search result titles. */ function extractTagsFromResults(results: any[], keyword: string): string[] { const tags: string[] = []; if (keyword) tags.push(keyword); const genreKeywords: Record = { '动画': '动画', '动漫': '动画', '国漫': '国漫', '剧场版': '剧场版', '年番': '年番', '动作': '动作', '奇幻': '奇幻', '玄幻': '玄幻', '仙侠': '仙侠', '古装': '古装', '爱情': '爱情', '科幻': '科幻', '喜剧': '喜剧', '悬疑': '悬疑', '恐怖': '恐怖', '惊悚': '惊悚', '剧情': '剧情', '冒险': '冒险', '战争': '战争', '武侠': '武侠', '纪录': '纪录片', '真人': '真人秀', '短片': '短片', }; const seen = new Set(); for (const r of results) { const title = (r.title || r.note || '') as string; for (const [key, val] of Object.entries(genreKeywords)) { if (title.includes(key) && !seen.has(val)) { seen.add(val); tags.push(val); } } } return tags; } export default router;