163 lines
4.9 KiB
JavaScript
163 lines
4.9 KiB
JavaScript
const { PrismaClient } = require('@prisma/client');
|
||
const fs = require('fs').promises;
|
||
const path = require('path');
|
||
|
||
const prisma = new PrismaClient();
|
||
|
||
// 判断是否是S3 URL
|
||
function isS3Url(filePath) {
|
||
if (!filePath) return false;
|
||
return filePath.startsWith('http://') || filePath.startsWith('https://');
|
||
}
|
||
|
||
// S3删除函数(需要在实际环境中使用)
|
||
let deleteFromS3 = null;
|
||
async function initS3Delete() {
|
||
try {
|
||
// 尝试导入S3模块(需要编译后的JS文件)
|
||
const s3Module = require('./lib/s3');
|
||
if (s3Module && s3Module.deleteFromS3) {
|
||
deleteFromS3 = s3Module.deleteFromS3;
|
||
} else {
|
||
console.warn('⚠️ 警告: 无法导入S3删除模块,S3文件将不会被删除');
|
||
}
|
||
} catch (err) {
|
||
console.warn('⚠️ 警告: S3模块导入失败,S3文件将不会被删除:', err.message);
|
||
}
|
||
}
|
||
|
||
async function deleteMaterialFiles(material) {
|
||
const filesToDelete = [];
|
||
|
||
if (material.zipFilePath) filesToDelete.push(material.zipFilePath);
|
||
if (material.videoSourceUrl && material.videoSourceUrl !== material.zipFilePath) {
|
||
filesToDelete.push(material.videoSourceUrl);
|
||
}
|
||
if (material.previewUrl) filesToDelete.push(material.previewUrl);
|
||
if (material.videoPreview540Url) filesToDelete.push(material.videoPreview540Url);
|
||
if (material.videoPreviewClipUrl) filesToDelete.push(material.videoPreviewClipUrl);
|
||
if (material.videoCoverUrl) filesToDelete.push(material.videoCoverUrl);
|
||
if (Array.isArray(material.displayImages) && material.displayImages.length > 0) {
|
||
filesToDelete.push(...material.displayImages.filter(img => img && img.trim()));
|
||
}
|
||
|
||
const uniqueFiles = Array.from(new Set(filesToDelete.filter(f => f && f.trim())));
|
||
|
||
let deletedCount = 0;
|
||
let failedCount = 0;
|
||
|
||
for (const filePath of uniqueFiles) {
|
||
try {
|
||
if (isS3Url(filePath)) {
|
||
// S3文件删除
|
||
if (deleteFromS3) {
|
||
try {
|
||
await deleteFromS3(filePath);
|
||
deletedCount++;
|
||
console.log(` ✓ 已删除S3文件: ${filePath}`);
|
||
} catch (err) {
|
||
console.error(` ✗ S3删除失败: ${filePath}`, err.message);
|
||
failedCount++;
|
||
}
|
||
} else {
|
||
console.warn(` ⚠ S3文件无法删除(模块未加载): ${filePath}`);
|
||
failedCount++;
|
||
}
|
||
} else {
|
||
// 本地文件删除
|
||
try {
|
||
await fs.unlink(filePath);
|
||
deletedCount++;
|
||
console.log(` ✓ 已删除本地文件: ${filePath}`);
|
||
} catch (err) {
|
||
if (err.code !== 'ENOENT') {
|
||
console.error(` ✗ 本地文件删除失败: ${filePath}`, err.message);
|
||
failedCount++;
|
||
} else {
|
||
console.log(` ⚠ 文件不存在(已忽略): ${filePath}`);
|
||
}
|
||
}
|
||
}
|
||
} catch (err) {
|
||
console.error(` ✗ 删除失败: ${filePath}`, err.message);
|
||
failedCount++;
|
||
}
|
||
}
|
||
|
||
return { deletedCount, failedCount };
|
||
}
|
||
|
||
async function deleteMaterials() {
|
||
// 初始化S3删除功能
|
||
await initS3Delete();
|
||
|
||
try {
|
||
const materials = await prisma.material.findMany({
|
||
where: {
|
||
productModel: {
|
||
startsWith: 'TEXT'
|
||
}
|
||
}
|
||
});
|
||
|
||
if (materials.length === 0) {
|
||
console.log('没有找到TEXT开头的素材');
|
||
return;
|
||
}
|
||
|
||
console.log(`\n找到 ${materials.length} 个TEXT开头的素材,开始删除...\n`);
|
||
console.log('='.repeat(80));
|
||
|
||
let totalDeletedFiles = 0;
|
||
let totalFailedFiles = 0;
|
||
|
||
for (const material of materials) {
|
||
console.log(`\n删除素材: ${material.productModel} (${material.id})`);
|
||
|
||
// 删除相关文件
|
||
const { deletedCount, failedCount } = await deleteMaterialFiles(material);
|
||
totalDeletedFiles += deletedCount;
|
||
totalFailedFiles += failedCount;
|
||
|
||
// 删除数据库记录
|
||
await prisma.material.delete({
|
||
where: { id: material.id }
|
||
});
|
||
console.log(` ✓ 已删除数据库记录`);
|
||
}
|
||
|
||
console.log('\n' + '='.repeat(80));
|
||
console.log(`\n删除完成!`);
|
||
console.log(` - 已删除素材: ${materials.length} 个`);
|
||
console.log(` - 已删除文件: ${totalDeletedFiles} 个`);
|
||
if (totalFailedFiles > 0) {
|
||
console.log(` - 失败文件: ${totalFailedFiles} 个`);
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('错误:', error);
|
||
process.exit(1);
|
||
} finally {
|
||
await prisma.$disconnect();
|
||
}
|
||
}
|
||
|
||
// 确认提示
|
||
const readline = require('readline');
|
||
const rl = readline.createInterface({
|
||
input: process.stdin,
|
||
output: process.stdout
|
||
});
|
||
|
||
rl.question('\n⚠️ 确认要删除所有TEXT开头的素材吗?这将删除数据库记录和相关文件!(yes/no): ', (answer) => {
|
||
if (answer.toLowerCase() === 'yes' || answer.toLowerCase() === 'y') {
|
||
rl.close();
|
||
deleteMaterials();
|
||
} else {
|
||
console.log('已取消删除操作');
|
||
rl.close();
|
||
process.exit(0);
|
||
}
|
||
});
|
||
|