feat: Initial commit of PDF Tools project

This commit is contained in:
2025-08-25 02:29:48 +08:00
parent af6827cd9e
commit 30180e50a2
48 changed files with 36364 additions and 1 deletions

279
server/routes/system.js Normal file
View File

@@ -0,0 +1,279 @@
const express = require('express');
const os = require('os');
const fs = require('fs');
const path = require('path');
const router = express.Router();
// 系统健康检查
router.get('/health', (req, res) => {
try {
const uptime = process.uptime();
const memoryUsage = process.memoryUsage();
const cpuUsage = process.cpuUsage();
const healthData = {
status: 'OK',
timestamp: new Date().toISOString(),
uptime: {
seconds: Math.floor(uptime),
readable: formatUptime(uptime)
},
memory: {
rss: formatBytes(memoryUsage.rss),
heapTotal: formatBytes(memoryUsage.heapTotal),
heapUsed: formatBytes(memoryUsage.heapUsed),
external: formatBytes(memoryUsage.external)
},
cpu: {
user: cpuUsage.user,
system: cpuUsage.system
},
system: {
platform: os.platform(),
arch: os.arch(),
nodeVersion: process.version,
totalMemory: formatBytes(os.totalmem()),
freeMemory: formatBytes(os.freemem()),
loadAverage: os.loadavg(),
cpuCount: os.cpus().length
}
};
res.json(healthData);
} catch (error) {
console.error('健康检查错误:', error);
res.status(500).json({
status: 'ERROR',
message: '系统健康检查失败',
timestamp: new Date().toISOString()
});
}
});
// 系统统计信息
router.get('/stats', (req, res) => {
try {
const uploadDir = path.join(__dirname, '../uploads');
let filesCount = 0;
let totalSize = 0;
if (fs.existsSync(uploadDir)) {
const files = fs.readdirSync(uploadDir);
filesCount = files.length;
files.forEach(file => {
const filePath = path.join(uploadDir, file);
const stats = fs.statSync(filePath);
totalSize += stats.size;
});
}
const statsData = {
files: {
count: filesCount,
totalSize: formatBytes(totalSize)
},
conversions: {
total: 0, // 这里应该从数据库查询
successful: 0,
failed: 0,
inProgress: 0
},
users: {
total: 0, // 这里应该从数据库查询
active: 0,
newToday: 0
},
performance: {
averageConversionTime: '0s',
queueLength: 0,
errorRate: '0%'
}
};
res.json({
success: true,
data: statsData,
timestamp: new Date().toISOString()
});
} catch (error) {
console.error('获取系统统计错误:', error);
res.status(500).json({
success: false,
message: '获取系统统计失败'
});
}
});
// 支持的格式信息
router.get('/formats', (req, res) => {
try {
const supportedFormats = {
input: [
{
format: 'pdf',
mimeType: 'application/pdf',
description: 'PDF文档',
maxSize: '50MB'
}
],
output: [
{
format: 'docx',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
description: 'Microsoft Word文档',
features: ['保持布局', '提取图片', 'OCR支持']
},
{
format: 'html',
mimeType: 'text/html',
description: 'HTML网页',
features: ['响应式设计', '嵌入图片', 'CSS框架']
},
{
format: 'txt',
mimeType: 'text/plain',
description: '纯文本',
features: ['提取文本', '保留换行', '字符编码']
},
{
format: 'png',
mimeType: 'image/png',
description: 'PNG图片',
features: ['高质量', '透明背景', '无损压缩']
},
{
format: 'jpg',
mimeType: 'image/jpeg',
description: 'JPEG图片',
features: ['压缩率高', '质量可调', '广泛支持']
}
]
};
res.json({
success: true,
data: supportedFormats
});
} catch (error) {
console.error('获取格式信息错误:', error);
res.status(500).json({
success: false,
message: '获取格式信息失败'
});
}
});
// 系统配置信息
router.get('/config', (req, res) => {
try {
const config = {
upload: {
maxFileSize: '50MB',
allowedTypes: ['application/pdf'],
uploadDir: process.env.UPLOAD_DIR || './uploads'
},
conversion: {
timeout: process.env.CONVERSION_TIMEOUT || 300000,
maxConcurrent: process.env.MAX_CONCURRENT_CONVERSIONS || 5,
queueLimit: 100
},
security: {
rateLimiting: process.env.ENABLE_RATE_LIMITING === 'true',
rateLimit: {
window: process.env.RATE_LIMIT_WINDOW || 900000,
max: process.env.RATE_LIMIT_MAX || 100
}
},
features: {
userRegistration: true,
batchConversion: true,
previewSupport: false,
cloudStorage: false
}
};
res.json({
success: true,
data: config
});
} catch (error) {
console.error('获取系统配置错误:', error);
res.status(500).json({
success: false,
message: '获取系统配置失败'
});
}
});
// 清理临时文件
router.post('/cleanup', (req, res) => {
try {
const uploadDir = path.join(__dirname, '../uploads');
const maxAge = 24 * 60 * 60 * 1000; // 24小时
const now = Date.now();
let cleanedCount = 0;
let cleanedSize = 0;
if (fs.existsSync(uploadDir)) {
const files = fs.readdirSync(uploadDir);
files.forEach(file => {
const filePath = path.join(uploadDir, file);
const stats = fs.statSync(filePath);
if (now - stats.mtime.getTime() > maxAge) {
cleanedSize += stats.size;
fs.unlinkSync(filePath);
cleanedCount++;
}
});
}
res.json({
success: true,
message: '临时文件清理完成',
data: {
cleanedFiles: cleanedCount,
freedSpace: formatBytes(cleanedSize)
}
});
} catch (error) {
console.error('清理临时文件错误:', error);
res.status(500).json({
success: false,
message: '清理临时文件失败'
});
}
});
// 辅助函数:格式化字节大小
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// 辅助函数:格式化运行时间
function formatUptime(uptime) {
const days = Math.floor(uptime / 86400);
const hours = Math.floor((uptime % 86400) / 3600);
const minutes = Math.floor((uptime % 3600) / 60);
const seconds = Math.floor(uptime % 60);
return `${days}d ${hours}h ${minutes}m ${seconds}s`;
}
module.exports = router;