gongxiangp2/scripts/check-old-materials-external-server-quick.ts

195 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 快速检查老素材在外网服务器上的源文件(简化版)
* 只统计,不实际检查每个文件
*/
import { PrismaClient } from '@prisma/client'
import { writeFile } from 'fs/promises'
const prisma = new PrismaClient()
const cutoffDate = new Date('2025-10-27T23:59:59.999Z')
/**
* 判断是否为老素材
*/
function isOldMaterial(material: any): boolean {
if (material.createdAt <= cutoffDate) return true
const previewUrl = material.previewUrl || ''
if (previewUrl.includes('s3.1080p.hk') &&
previewUrl.includes('/jsxiangche/') &&
!previewUrl.includes('由壹点AI/')) {
return true
}
return false
}
/**
* 构建外网服务器URL
*/
function buildExternalUrl(zipFilePath: string): string {
if (zipFilePath.startsWith('http://') || zipFilePath.startsWith('https://')) {
return zipFilePath
}
const fileName = zipFilePath.replace(/^uploads\//, '').replace(/^\/app\/uploads\//, '').replace(/^\.\/uploads\//, '')
return `http://103.118.245.6/uploads/${fileName}`
}
async function main() {
console.log('='.repeat(60))
console.log('老素材外网服务器源文件统计(快速版)')
console.log('='.repeat(60))
console.log()
// 查询所有素材
console.log('📋 查询所有素材...')
const allMaterials = await prisma.material.findMany({
where: {
deletedAt: null,
},
select: {
id: true,
materialType: true,
productModel: true,
authorName: true,
categoryName: true,
createdAt: true,
previewUrl: true,
zipFilePath: true,
zipFileName: true,
zipFileSize: true,
},
})
console.log(` 总素材数: ${allMaterials.length}`)
// 过滤老素材
const oldMaterials = allMaterials.filter(isOldMaterial)
console.log(` 老素材数: ${oldMaterials.length}`)
console.log()
// 分析源文件路径
console.log('🔍 分析源文件路径...')
const stats = {
total: oldMaterials.length,
hasLocalPath: 0, // uploads/格式
hasHttpUrl: 0, // http://格式
hasS3Url: 0, // S3 URL
noSourceFile: 0, // 没有源文件路径
}
const results: Array<{
id: string
materialType: string
productModel: string
authorName: string
categoryName: string
zipFilePath: string | null
zipFileName: string | null
zipFileSize: number | null
externalUrl: string
sourceType: string
createdAt: Date
}> = []
for (const material of oldMaterials) {
let sourceType = 'none'
let externalUrl = ''
if (material.zipFilePath) {
if (material.zipFilePath.startsWith('uploads/') ||
material.zipFilePath.startsWith('/app/uploads/') ||
material.zipFilePath.startsWith('./uploads/')) {
sourceType = 'local'
stats.hasLocalPath++
externalUrl = buildExternalUrl(material.zipFilePath)
} else if (material.zipFilePath.startsWith('http://') ||
material.zipFilePath.startsWith('https://')) {
sourceType = 'http'
stats.hasHttpUrl++
externalUrl = material.zipFilePath
}
}
// 检查zipFileName是否是S3 URL
if (material.zipFileName &&
(material.zipFileName.startsWith('http://') ||
material.zipFileName.startsWith('https://'))) {
if (sourceType === 'none') {
sourceType = 's3'
stats.hasS3Url++
}
}
if (sourceType === 'none') {
stats.noSourceFile++
}
results.push({
id: material.id,
materialType: material.materialType || '',
productModel: material.productModel || '',
authorName: material.authorName || '',
categoryName: material.categoryName || '',
zipFilePath: material.zipFilePath,
zipFileName: material.zipFileName,
zipFileSize: material.zipFileSize ? Number(material.zipFileSize) : null,
externalUrl: externalUrl || '',
sourceType,
createdAt: material.createdAt,
})
}
console.log(` 有本地路径(uploads/): ${stats.hasLocalPath} 个`)
console.log(` 有HTTP URL: ${stats.hasHttpUrl} 个`)
console.log(` 有S3 URL: ${stats.hasS3Url} 个`)
console.log(` 无源文件路径: ${stats.noSourceFile} 个`)
console.log()
// 生成CSV报告
const reportRows: string[] = []
reportRows.push('素材ID,素材类型,产品型号,作者,使用店铺,源文件路径,外网服务器URL,源文件类型,源文件大小(字节),创建时间')
for (const r of results) {
const row = [
r.id,
r.materialType,
r.productModel,
r.authorName,
r.categoryName,
r.zipFilePath || '',
r.externalUrl,
r.sourceType,
r.zipFileSize?.toString() || '',
r.createdAt.toISOString(),
]
reportRows.push(row.map(field => {
if (field === null || field === undefined) return ''
const str = String(field)
if (str.includes(',') || str.includes('"') || str.includes('\n')) {
return `"${str.replace(/"/g, '""')}"`
}
return str
}).join(','))
}
const reportFile = '/tmp/老素材外网服务器统计报告.csv'
await writeFile(reportFile, reportRows.join('\n'), 'utf-8')
console.log(`✅ 报告已生成: ${reportFile}`)
console.log(` 包含 ${results.length} 个老素材的统计信息`)
console.log()
console.log(`📊 总结:`)
console.log(` - 需要检查外网服务器的老素材: ${stats.hasLocalPath} 个(uploads/格式)`)
console.log(` - 已经是HTTP URL的: ${stats.hasHttpUrl} 个`)
console.log(` - S3 URL的: ${stats.hasS3Url} 个`)
console.log()
await prisma.$disconnect()
}
main().catch((error) => {
console.error('执行失败:', error)
process.exit(1)
})