95 lines
2.7 KiB
TypeScript
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 }
|
|
)
|
|
}
|
|
}
|
|
|