gongxiangp2/scripts/diagnose-pdf.js
chenpei cd6e40d9d2 优化:网络传输性能和稳定性 - TCP缓冲区+并发控制优化
主要改动:
1. TCP缓冲区优化(16MB)- 解决公网上传速度慢问题
2. 并发数降低到1-3 - 避免4并发导致ERR_CONNECTION_RESET
3. 动态并发控制 - 根据网络环境自动调整
4. Nginx超时增加到120s - 支持大分片上传
5. 上传进度修复 - 修复剩余时间计算
6. 新增任务-页面上传器和详情组件
7. 统一部署文档为deploy-remote-build.ps1

问题修复:
- 公网用户上传从200-900KB/s提升到预期3-5MB/s
- 内网用户上传更稳定,无连接重置错误
- UploadProgress组件剩余时间计算修正

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-27 09:33:09 +08:00

182 lines
5.1 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

#!/usr/bin/env node
/**
* 品牌VI灵感素材预览图诊断脚本
*
* 用途:检查生产环境中品牌VI灵感素材的预览图问题
* 运行:node scripts/diagnose-pdf.js
*/
const { PrismaClient } = require('@prisma/client')
const fs = require('fs/promises')
const path = require('path')
const { exec } = require('child_process')
const { promisify } = require('util')
const execAsync = promisify(exec)
const prisma = new PrismaClient()
// 问题素材ID列表
const PROBLEM_MATERIAL_IDS = [
'3ce99933-4df8-427f-aa30-454148025e1c',
'390fe674-a2a6-47f1-9b5d-6e377e5cac2c',
'fc8ab566-fd0b-4760-b68d-35a46c94d1bc',
'905b709d-74ab-4def-930b-ac5b86dfd381',
'64137416-3f37-4243-a72b-75f11f3a0114'
]
async function checkSystem() {
console.log('\n=== 系统环境检查 ===\n')
// 检查 pdftoppm 是否安装
try {
const { stdout } = await execAsync('which pdftoppm')
console.log('✅ pdftoppm 路径:', stdout.trim())
// 检查版本
try {
const { stdout: version } = await execAsync('pdftoppm -v')
console.log('✅ pdftoppm 版本信息:', version.split('\n')[0])
} catch (e) {
console.log('⚠️ 无法获取 pdftoppm 版本')
}
} catch (e) {
console.log('❌ pdftoppm 未安装或不在 PATH 中')
}
// 检查上传目录
const uploadDir = process.env.UPLOAD_DIR || './uploads'
console.log('\n上传目录配置:', uploadDir)
try {
const stats = await fs.stat(uploadDir)
console.log('✅ 上传目录存在,权限:', stats.mode.toString(8))
} catch (e) {
console.log('❌ 上传目录不存在或无权限访问')
}
// 检查临时目录
const tmpDir = require('os').tmpdir()
console.log('临时目录:', tmp_dir)
try {
await fs.access(tmpDir, fs.constants.W_OK)
console.log('✅ 临时目录可写')
} catch (e) {
console.log('❌ 临时目录不可写')
}
}
async function diagnoseMaterial(materialId) {
console.log(`\n${'='.repeat(60)}`)
console.log(`诊断素材: ${materialId}`)
console.log('='.repeat(60))
// 1. 查询数据库
const material = await prisma.material.findUnique({
where: { id: materialId },
include: {
assets: true,
skus: true
}
})
if (!material) {
console.log('❌ 素材不存在')
return
}
console.log('\n📊 数据库信息:')
console.log(' - 产品型号:', material.productModel)
console.log(' - 素材类型:', material.materialType)
console.log(' - 预览URL:', material.previewUrl || '(空)')
console.log(' - ZIP文件路径:', material.zipFilePath || '(空)')
console.log(' - ZIP文件名:', material.zipFileName || '(空)')
console.log(' - 资源数量:', material.assets.length)
console.log(' - SKU数量:', material.skus.length)
// 2. 检查 PDF 文件是否存在
const pdfPath = material.zipFilePath
if (!pdfPath) {
console.log('\n❌ 没有保存 PDF 文件路径')
return
}
console.log('\n📁 文件系统检查:')
console.log(' - PDF 路径:', pdfPath)
try {
const stats = await fs.stat(pdfPath)
console.log(' ✅ PDF 文件存在')
console.log(' - 文件大小:', (stats.size / 1024 / 1024).toFixed(2), 'MB')
console.log(' - 修改时间:', stats.mtime)
// 检查文件是否为有效 PDF
const handle = await fs.open(pdfPath, 'r')
const buffer = Buffer.alloc(4)
await handle.read(buffer, 0, 4, 0)
await handle.close()
const header = buffer.toString('ascii', 0, 4)
if (header === '%PDF') {
console.log(' ✅ 文件格式正确 (PDF)')
} else {
console.log(' ❌ 文件格式错误,期望 %PDF,实际:', header)
return
}
// 3. 尝试提取预览图
console.log('\n🖼️ 尝试提取 PDF 预览图...')
const { generatePdfPreview } = require('../lib/pdf-processor')
const result = await generatePdfPreview(pdfPath)
if (result.success) {
console.log(' ✅ PDF 预览图提取成功!')
console.log(' - 预览图路径:', result.previewPath)
console.log(' - 尺寸:', result.width, 'x', result.height)
// 读取预览图大小
const previewStats = await fs.stat(result.previewPath)
console.log(' - 文件大小:', (previewStats.size / 1024).toFixed(2), 'KB')
// 清理测试生成的预览图
await fs.unlink(result.previewPath).catch(() => {})
console.log(' ✅ 测试预览图已清理')
} else {
console.log(' ❌ PDF 预览图提取失败')
console.log(' - 错误信息:', result.error)
}
} catch (e) {
console.log(' ❌ 文件访问错误:', e.message)
}
}
async function main() {
console.log('🔍 品牌VI灵感素材预览图诊断工具')
console.log('时间:', new Date().toLocaleString('zh-CN'))
try {
// 检查系统环境
await checkSystem()
// 诊断每个问题素材
for (const id of PROBLEM_MATERIAL_IDS) {
await diagnoseMaterial(id)
}
console.log('\n' + '='.repeat(60))
console.log('✅ 诊断完成')
console.log('='.repeat(60) + '\n')
} catch (error) {
console.error('\n❌ 诊断过程出错:', error)
} finally {
await prisma.$disconnect()
}
}
main()