gongxiangp2/scripts/check-preview-urls.js

98 lines
3.0 KiB
JavaScript

/**
* 检查素材预览图URL的脚本
* 用于调试预览图不加载的问题
*
* 使用方法:
* node scripts/check-preview-urls.js
*/
const { PrismaClient } = require('@prisma/client')
const https = require('https')
const http = require('http')
const prisma = new PrismaClient()
// 检查URL是否可访问
function checkUrl(url) {
return new Promise((resolve) => {
const protocol = url.startsWith('https') ? https : http
const req = protocol.request(url, { method: 'HEAD', timeout: 5000 }, (res) => {
resolve({ ok: res.statusCode >= 200 && res.statusCode < 400, status: res.statusCode })
})
req.on('error', (e) => resolve({ ok: false, error: e.message }))
req.on('timeout', () => { req.destroy(); resolve({ ok: false, error: 'timeout' }) })
req.end()
})
}
async function main() {
console.log('=== 检查素材预览图URL ===\n')
// 获取所有素材(不限类型),按域名分组
const materials = await prisma.material.findMany({
where: { deletedAt: null },
orderBy: { createdAt: 'desc' },
select: {
id: true,
productModel: true,
previewUrl: true,
materialType: true,
createdAt: true,
}
})
// 按域名分组统计
const domainStats = {}
materials.forEach((m) => {
if (m.previewUrl) {
try {
const url = new URL(m.previewUrl)
const domain = url.hostname
const bucket = url.pathname.split('/')[1] // 获取bucket名
const key = `${domain}/${bucket}`
if (!domainStats[key]) {
domainStats[key] = {
domain, bucket, count: 0,
firstDate: m.createdAt, lastDate: m.createdAt,
testUrls: []
}
}
domainStats[key].count++
if (m.createdAt < domainStats[key].firstDate) domainStats[key].firstDate = m.createdAt
if (m.createdAt > domainStats[key].lastDate) domainStats[key].lastDate = m.createdAt
if (domainStats[key].testUrls.length < 2) {
domainStats[key].testUrls.push({ name: m.productModel, url: m.previewUrl })
}
} catch (e) {
console.log(`❌ 无效URL: ${m.productModel} - ${m.previewUrl}`)
}
}
})
console.log('=== 存储桶统计 ===\n')
for (const key of Object.keys(domainStats)) {
const stat = domainStats[key]
console.log(`📌 ${stat.domain} / ${stat.bucket}`)
console.log(` 素材数量: ${stat.count}`)
console.log(` 日期范围: ${stat.firstDate.toISOString().split('T')[0]} ~ ${stat.lastDate.toISOString().split('T')[0]}`)
// 测试URL可访问性
console.log(' 测试访问:')
for (const test of stat.testUrls) {
const result = await checkUrl(test.url)
const status = result.ok ? '✅ 可访问' : `❌ 不可访问 (${result.error || result.status})`
console.log(` ${test.name}: ${status}`)
}
console.log('')
}
console.log(`总计: ${materials.length} 个素材`)
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect())