feat: WC2026 赛事 seed、生产上线初始化脚本与目录归档
重构 seed 为 WC2026 72 场小组赛与 48 强优胜盘;新增 production 模式仅保留 admin 与赛事示例;提供 prod-init-db 全量重置脚本;管理端 i18n 分包与赛事归档能力。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
18
apps/api/src/shared/uploads/delete-upload-file.ts
Normal file
18
apps/api/src/shared/uploads/delete-upload-file.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { unlink } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
import { getUploadRoot } from './upload-paths';
|
||||
|
||||
const UPLOAD_URL_PREFIX = '/uploads/';
|
||||
|
||||
/** 按 `/uploads/{category}/{filename}` 删除磁盘文件;路径非法或文件不存在时静默跳过 */
|
||||
export async function deleteUploadFileByUrl(url: string): Promise<void> {
|
||||
if (!url?.startsWith(UPLOAD_URL_PREFIX)) return;
|
||||
const relative = url.slice(UPLOAD_URL_PREFIX.length);
|
||||
if (!relative || relative.includes('..') || relative.includes('\\')) return;
|
||||
const root = getUploadRoot();
|
||||
try {
|
||||
await unlink(join(root, relative));
|
||||
} catch {
|
||||
/* already removed */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user