98 lines
3.0 KiB
JavaScript
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())
|