95 lines
2.7 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
import { isCurrentSuperAdmin } from '@/lib/admin-permissions'
import {
collectMaterialStorageUrls,
deleteMaterialStorageFiles,
} from '@/lib/material-storage-cleanup'
// Cleanup materials deleted more than 7 days ago (admin only)
export async function POST(req: NextRequest) {
try {
const session = await getServerSession(authOptions)
if (
!session ||
(session.user as any).role !== 'ADMIN' ||
!(await isCurrentSuperAdmin(session))
) {
return NextResponse.json(
{ error: '仅最高权限账号可清理过期删除素材' },
{ status: 403 }
)
}
// 计算7天前的日期
const sevenDaysAgo = new Date()
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7)
// 查找7天前删除的素材
const deletedMaterials = await prisma.material.findMany({
where: {
deletedAt: {
not: null,
lte: sevenDaysAgo,
},
},
})
let deletedFiles = 0
let skippedFiles = 0
let failedFiles = 0
const safeToDeleteMaterialIds: string[] = []
const failedMaterials: Array<{
id: string
failedFiles: number
failures: Array<{ fileUrl: string; reason: string }>
}> = []
for (const material of deletedMaterials) {
const cleanupResult = await deleteMaterialStorageFiles(collectMaterialStorageUrls(material), {
logPrefix: `[Cleanup] Material ${material.id}`,
})
deletedFiles += cleanupResult.deletedFiles
skippedFiles += cleanupResult.skippedFiles
failedFiles += cleanupResult.failedFiles
if (cleanupResult.failedFiles > 0) {
failedMaterials.push({
id: material.id,
failedFiles: cleanupResult.failedFiles,
failures: cleanupResult.failures.slice(0, 10),
})
} else {
safeToDeleteMaterialIds.push(material.id)
}
}
if (safeToDeleteMaterialIds.length > 0) {
await prisma.material.deleteMany({
where: { id: { in: safeToDeleteMaterialIds } },
})
}
return NextResponse.json({
message: failedMaterials.length > 0 ? '部分清理完成,文件删除失败的素材记录已保留' : '清理完成',
deletedCount: safeToDeleteMaterialIds.length,
retainedCount: failedMaterials.length,
deletedFiles,
skippedFiles,
failedFiles,
failedMaterials,
})
} catch (error) {
console.error('[Materials] CLEANUP error:', error)
return NextResponse.json(
{ error: '清理失败' },
{ status: 500 }
)
}
}