340 lines
12 KiB
HTML
Executable File
340 lines
12 KiB
HTML
Executable File
<!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> |