v0.2.7: 修复Redis连接 + 启动管理后台
- 修复Redis认证 (配置密码) - 启动Python管理后台 (端口9531, 15个功能开关) - 统一版本号 0.2.7 - 更新docker-compose.yml (镜像版本/Redis URL/Admin服务)
This commit is contained in:
87
source_clean/src/routes/cleanup.routes.ts
Normal file
87
source_clean/src/routes/cleanup.routes.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
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<string, string> = {
|
||||
'动画': '动画', '动漫': '动画', '国漫': '国漫',
|
||||
'剧场版': '剧场版', '年番': '年番',
|
||||
'动作': '动作', '奇幻': '奇幻', '玄幻': '玄幻',
|
||||
'仙侠': '仙侠', '古装': '古装', '爱情': '爱情',
|
||||
'科幻': '科幻', '喜剧': '喜剧', '悬疑': '悬疑',
|
||||
'恐怖': '恐怖', '惊悚': '惊悚', '剧情': '剧情',
|
||||
'冒险': '冒险', '战争': '战争', '武侠': '武侠',
|
||||
'纪录': '纪录片', '真人': '真人秀', '短片': '短片',
|
||||
};
|
||||
|
||||
const seen = new Set<string>();
|
||||
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;
|
||||
Reference in New Issue
Block a user