import fs from 'fs/promises'; import path from 'path'; const DEBUG_DIR = 'debug'; // 确保调试目录存在 async function ensureDebugDir() { try { await fs.access(DEBUG_DIR); } catch { await fs.mkdir(DEBUG_DIR, { recursive: true }); } } // 保存截图 export async function saveScreenshot(debugId: string, screenshot: Buffer): Promise { await ensureDebugDir(); const screenshotPath = path.join(DEBUG_DIR, `${debugId}.png`); await fs.writeFile(screenshotPath, screenshot); } // 保存调试信息 export async function saveDebugInfo(debugId: string, info: any): Promise { await ensureDebugDir(); const infoPath = path.join(DEBUG_DIR, `${debugId}.json`); await fs.writeFile(infoPath, JSON.stringify(info, null, 2)); } // 保存错误信息 export async function saveErrorInfo(debugId: string, error: any): Promise { await ensureDebugDir(); const errorPath = path.join(DEBUG_DIR, `${debugId}_error.json`); await fs.writeFile(errorPath, JSON.stringify(error, null, 2)); } // 获取所有调试信息 export async function getAllDebugInfo(): Promise { try { await ensureDebugDir(); const files = await fs.readdir(DEBUG_DIR); const debugItems = []; // 获取所有 .json 文件(排除 _error.json) const infoFiles = files.filter(file => file.endsWith('.json') && !file.endsWith('_error.json')); for (const file of infoFiles) { try { const debugId = file.replace('.json', ''); const infoPath = path.join(DEBUG_DIR, file); const errorPath = path.join(DEBUG_DIR, `${debugId}_error.json`); const screenshotPath = path.join(DEBUG_DIR, `${debugId}.png`); // 读取基本信息 const infoData = await fs.readFile(infoPath, 'utf-8'); const info = JSON.parse(infoData); // 检查是否有错误信息 let errorInfo = null; try { const errorData = await fs.readFile(errorPath, 'utf-8'); errorInfo = JSON.parse(errorData); } catch { // 没有错误文件,忽略 } // 检查是否有截图 let hasScreenshot = false; try { await fs.access(screenshotPath); hasScreenshot = true; } catch { // 没有截图文件,忽略 } debugItems.push({ debugId, ...info, hasError: !!errorInfo, errorMessage: errorInfo?.error || null, hasScreenshot, screenshotUrl: hasScreenshot ? `/api/debug/screenshot?id=${debugId}` : null }); } catch (error) { console.error(`Error reading debug file ${file}:`, error); } } // 按时间戳排序(最新的在前) debugItems.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()); return debugItems; } catch (error) { console.error('Error reading debug directory:', error); return []; } } // 获取截图 export async function getScreenshot(debugId: string): Promise { try { const screenshotPath = path.join(DEBUG_DIR, `${debugId}.png`); return await fs.readFile(screenshotPath); } catch { return null; } } // 清理旧的调试文件 export async function cleanupOldDebugFiles(daysToKeep: number = 7): Promise { try { await ensureDebugDir(); const files = await fs.readdir(DEBUG_DIR); const cutoffTime = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000); let deletedCount = 0; for (const file of files) { try { const filePath = path.join(DEBUG_DIR, file); const stats = await fs.stat(filePath); if (stats.mtime.getTime() < cutoffTime) { await fs.unlink(filePath); deletedCount++; } } catch (error) { console.error(`Error processing file ${file}:`, error); } } return deletedCount; } catch (error) { console.error('Error cleaning up debug files:', error); return 0; } }