erp-frontend/diagnose.html
2026-04-06 21:14:31 +08:00

340 lines
12 KiB
HTML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ERP系统诊断页面</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1000px;
margin: 0 auto;
background: white;
border-radius: 16px;
padding: 40px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}
h1 {
color: #333;
margin-bottom: 10px;
font-size: 32px;
}
.subtitle {
color: #666;
margin-bottom: 30px;
font-size: 16px;
}
.status-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin: 30px 0;
}
.status-card {
background: #f8f9fa;
border-radius: 12px;
padding: 20px;
border-left: 5px solid;
}
.status-card.success { border-color: #28a745; }
.status-card.error { border-color: #dc3545; }
.status-card.warning { border-color: #ffc107; }
.status-card.info { border-color: #17a2b8; }
.status-title {
font-weight: 600;
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 10px;
}
.status-icon {
font-size: 20px;
}
.test-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin: 20px 0;
}
.test-btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s;
text-decoration: none;
display: inline-block;
text-align: center;
}
.test-btn.primary {
background: #007bff;
color: white;
}
.test-btn.secondary {
background: #6c757d;
color: white;
}
.test-btn.success {
background: #28a745;
color: white;
}
.test-btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.log-container {
background: #1e1e1e;
color: #d4d4d4;
border-radius: 8px;
padding: 20px;
margin-top: 20px;
font-family: 'Courier New', monospace;
font-size: 14px;
max-height: 300px;
overflow-y: auto;
}
.log-entry {
margin-bottom: 5px;
padding: 5px;
border-radius: 4px;
}
.log-entry.info { background: rgba(0, 123, 255, 0.1); }
.log-entry.success { background: rgba(40, 167, 69, 0.1); }
.log-entry.error { background: rgba(220, 53, 69, 0.1); }
.log-entry.warning { background: rgba(255, 193, 7, 0.1); }
.instructions {
background: #e7f3ff;
border-radius: 8px;
padding: 20px;
margin: 30px 0;
border-left: 5px solid #007bff;
}
.instructions h3 {
color: #0056b3;
margin-bottom: 10px;
}
.instructions ol {
margin-left: 20px;
}
.instructions li {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div class="container">
<h1>🔧 ERP系统诊断工具</h1>
<div class="subtitle">服务器状态检测与问题诊断</div>
<div class="status-grid">
<div class="status-card success" id="server-status">
<div class="status-title">
<span class="status-icon">🌐</span>
<span>服务器状态</span>
</div>
<div id="server-details">检测中...</div>
</div>
<div class="status-card info" id="port-status">
<div class="status-title">
<span class="status-icon">🔌</span>
<span>端口信息</span>
</div>
<div id="port-details">检测中...</div>
</div>
<div class="status-card warning" id="api-status">
<div class="status-title">
<span class="status-icon">🔄</span>
<span>API状态</span>
</div>
<div id="api-details">待测试</div>
</div>
<div class="status-card" id="vue-status">
<div class="status-title">
<span class="status-icon"></span>
<span>Vue应用状态</span>
</div>
<div id="vue-details">待测试</div>
</div>
</div>
<div class="instructions">
<h3>📋 诊断步骤</h3>
<ol>
<li>点击下面的测试按钮检查各项功能</li>
<li>查看右侧日志区域的结果</li>
<li>如果测试失败按F12查看浏览器控制台错误</li>
<li>将错误信息截图发送给技术支持</li>
</ol>
</div>
<div class="test-buttons">
<button class="test-btn primary" onclick="testServer()">测试服务器连接</button>
<button class="test-btn secondary" onclick="testStaticFiles()">测试静态文件</button>
<button class="test-btn success" onclick="testVueApp()">测试Vue应用</button>
<button class="test-btn" onclick="testMockAPI()">测试Mock API</button>
<button class="test-btn" onclick="clearLogs()">清空日志</button>
</div>
<div class="log-container" id="log-output">
<div class="log-entry info">诊断工具已加载,点击按钮开始测试...</div>
</div>
</div>
<script>
const logOutput = document.getElementById('log-output');
const serverDetails = document.getElementById('server-details');
const portDetails = document.getElementById('port-details');
const apiDetails = document.getElementById('api-details');
const vueDetails = document.getElementById('vue-details');
let logCount = 0;
function addLog(message, type = 'info') {
logCount++;
const logEntry = document.createElement('div');
logEntry.className = `log-entry ${type}`;
logEntry.innerHTML = `<strong>${logCount}.</strong> ${message}`;
logOutput.appendChild(logEntry);
logOutput.scrollTop = logOutput.scrollHeight;
}
function updateStatus(cardId, status, message) {
const card = document.getElementById(cardId);
card.className = `status-card ${status}`;
const details = document.getElementById(`${cardId.replace('-status', '-details')}`);
details.innerHTML = message;
}
async function testServer() {
addLog('开始测试服务器连接...', 'info');
try {
const response = await fetch('/');
if (response.ok) {
updateStatus('server-status', 'success', '✅ 服务器连接正常');
addLog('服务器连接测试成功', 'success');
} else {
updateStatus('server-status', 'error', '❌ 服务器响应异常');
addLog(`服务器响应异常: ${response.status} ${response.statusText}`, 'error');
}
} catch (error) {
updateStatus('server-status', 'error', '❌ 服务器连接失败');
addLog(`服务器连接失败: ${error.message}`, 'error');
}
}
async function testStaticFiles() {
addLog('开始测试静态文件加载...', 'info');
const testFiles = [
'/favicon.ico',
'/test-simple.html',
'/diagnose.html'
];
let successCount = 0;
let failCount = 0;
for (const file of testFiles) {
try {
const response = await fetch(file);
if (response.ok) {
successCount++;
addLog(`${file} 加载成功`, 'success');
} else {
failCount++;
addLog(`${file} 加载失败: ${response.status}`, 'error');
}
} catch (error) {
failCount++;
addLog(`${file} 加载失败: ${error.message}`, 'error');
}
}
if (failCount === 0) {
updateStatus('port-status', 'success', `✅ 所有静态文件加载正常 (${successCount}/${testFiles.length})`);
} else {
updateStatus('port-status', 'warning', `⚠️ 部分文件加载失败 (${successCount}成功/${failCount}失败)`);
}
}
async function testVueApp() {
addLog('开始测试Vue应用...', 'info');
try {
const response = await fetch('/');
const html = await response.text();
if (html.includes('vue') || html.includes('Vue') || html.includes('router-view')) {
updateStatus('vue-status', 'success', '✅ Vue应用结构正常');
addLog('Vue应用HTML结构检测正常', 'success');
} else {
updateStatus('vue-status', 'warning', '⚠️ Vue应用结构异常');
addLog('Vue应用HTML结构异常可能未正确加载', 'warning');
}
} catch (error) {
updateStatus('vue-status', 'error', '❌ Vue应用测试失败');
addLog(`Vue应用测试失败: ${error.message}`, 'error');
}
}
async function testMockAPI() {
addLog('开始测试Mock API...', 'info');
const apiEndpoints = [
'/api/print/batches',
'/api/print/orders',
'/api/system/status'
];
let successCount = 0;
let failCount = 0;
for (const endpoint of apiEndpoints) {
try {
const response = await fetch(endpoint);
if (response.ok) {
successCount++;
addLog(`${endpoint} 响应正常`, 'success');
} else {
failCount++;
addLog(`${endpoint} 响应异常: ${response.status}`, 'error');
}
} catch (error) {
failCount++;
addLog(`${endpoint} 请求失败: ${error.message}`, 'error');
}
}
if (successCount > 0) {
updateStatus('api-status', 'success', `✅ Mock API部分正常 (${successCount}成功/${failCount}失败)`);
} else {
updateStatus('api-status', 'error', `❌ Mock API全部失败 (${failCount}失败)`);
}
}
function clearLogs() {
logOutput.innerHTML = '';
logCount = 0;
addLog('日志已清空', 'info');
}
// 页面加载时自动测试
window.addEventListener('load', () => {
const currentUrl = window.location.href;
const port = currentUrl.split(':')[2]?.split('/')[0] || '未知';
portDetails.innerHTML = `当前端口: ${port}<br>URL: ${currentUrl}`;
// 自动测试服务器
setTimeout(testServer, 1000);
setTimeout(testStaticFiles, 1500);
});
</script>
</body>
</html>