122 lines
4.0 KiB
JavaScript
122 lines
4.0 KiB
JavaScript
// 素材数据和记录清理脚本
|
||
const { PrismaClient } = require('@prisma/client')
|
||
const fs = require('fs').promises
|
||
const path = require('path')
|
||
|
||
const prisma = new PrismaClient()
|
||
|
||
async function cleanupMaterials() {
|
||
try {
|
||
console.log('开始清理素材数据和记录...\n')
|
||
|
||
// 获取所有素材记录
|
||
const materials = await prisma.material.findMany({
|
||
select: {
|
||
id: true,
|
||
zipFileName: true,
|
||
zipFilePath: true,
|
||
previewUrl: true,
|
||
displayImages: true,
|
||
productModel: true,
|
||
createdAt: true,
|
||
},
|
||
})
|
||
|
||
console.log(`找到 ${materials.length} 条素材记录\n`)
|
||
|
||
let deletedFiles = 0
|
||
let deletedRecords = 0
|
||
let failedFiles = 0
|
||
let failedRecords = 0
|
||
|
||
// 清理每个素材
|
||
for (const material of materials) {
|
||
try {
|
||
// 1. 删除本地文件
|
||
if (material.zipFilePath && material.zipFilePath !== '') {
|
||
try {
|
||
// 检查文件是否存在
|
||
await fs.access(material.zipFilePath)
|
||
await fs.unlink(material.zipFilePath)
|
||
console.log(` ✓ 删除文件: ${material.zipFileName}`)
|
||
deletedFiles++
|
||
} catch (fileError) {
|
||
if (fileError.code === 'ENOENT') {
|
||
console.log(` - 文件不存在(已跳过): ${material.zipFileName}`)
|
||
} else {
|
||
console.error(` ✗ 删除文件失败: ${material.zipFileName}`, fileError.message)
|
||
failedFiles++
|
||
}
|
||
}
|
||
} else {
|
||
console.log(` - 无文件路径(已跳过): ${material.productModel}`)
|
||
}
|
||
|
||
// 2. 删除数据库记录(使用原始 SQL 避免字段不存在的问题)
|
||
await prisma.$executeRawUnsafe(`
|
||
DELETE FROM materials WHERE id = $1
|
||
`, material.id)
|
||
console.log(` ✓ 删除记录: ${material.productModel} (ID: ${material.id})`)
|
||
deletedRecords++
|
||
} catch (error) {
|
||
console.error(` ✗ 删除记录失败: ${material.productModel} (ID: ${material.id})`, error.message)
|
||
failedRecords++
|
||
}
|
||
}
|
||
|
||
// 清理关联的点赞记录(应该通过 CASCADE 自动删除,但为了安全起见也清理一下)
|
||
console.log('\n清理关联的点赞记录...')
|
||
const likesCount = await prisma.materialLike.count()
|
||
if (likesCount > 0) {
|
||
// 由于素材已删除,点赞记录应该已经通过 CASCADE 自动删除
|
||
// 但如果有残留,这里可以手动清理
|
||
const remainingLikes = await prisma.materialLike.findMany({
|
||
select: { id: true },
|
||
})
|
||
if (remainingLikes.length > 0) {
|
||
console.log(` 发现 ${remainingLikes.length} 条残留点赞记录,正在清理...`)
|
||
await prisma.materialLike.deleteMany({})
|
||
console.log(` ✓ 清理了 ${remainingLikes.length} 条点赞记录`)
|
||
} else {
|
||
console.log(' ✓ 点赞记录已自动清理')
|
||
}
|
||
} else {
|
||
console.log(' - 没有点赞记录需要清理')
|
||
}
|
||
|
||
// 统计信息
|
||
console.log('\n清理完成!')
|
||
console.log('='.repeat(50))
|
||
console.log('清理统计:')
|
||
console.log(` 删除文件: ${deletedFiles} 个`)
|
||
console.log(` 删除记录: ${deletedRecords} 条`)
|
||
if (failedFiles > 0) {
|
||
console.log(` 文件删除失败: ${failedFiles} 个`)
|
||
}
|
||
if (failedRecords > 0) {
|
||
console.log(` 记录删除失败: ${failedRecords} 条`)
|
||
}
|
||
console.log('='.repeat(50))
|
||
|
||
// 验证清理结果
|
||
const remainingMaterials = await prisma.material.count()
|
||
console.log(`\n剩余素材记录: ${remainingMaterials} 条`)
|
||
} catch (error) {
|
||
console.error('清理失败:', error)
|
||
process.exit(1)
|
||
} finally {
|
||
await prisma.$disconnect()
|
||
}
|
||
}
|
||
|
||
// 确认提示
|
||
console.log('⚠️ 警告:此操作将删除所有素材数据和记录!')
|
||
console.log('⚠️ 此操作不可恢复!')
|
||
console.log('')
|
||
console.log('如果确定要继续,请修改脚本并取消注释 cleanupMaterials() 调用')
|
||
console.log('')
|
||
|
||
// 执行清理
|
||
cleanupMaterials()
|
||
|