You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
5.6 KiB
138 lines
5.6 KiB
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>ADS-B 攻击检测系统</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: 'Segoe UI', sans-serif; background: #f0f2f5; display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: 20px; }
|
|
.container { background: white; padding: 40px; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); width: 600px; max-width: 100%; text-align: center; }
|
|
h1 { color: #333; margin-bottom: 30px; display: flex; align-items: center; justify-content: center; gap: 10px; }
|
|
.upload-area { border: 2px dashed #ccc; padding: 40px 20px; border-radius: 8px; cursor: pointer; margin-bottom: 20px; transition: 0.3s; }
|
|
.upload-area:hover { border-color: #007bff; background: #f8f9fa; }
|
|
input[type="file"] { display: none; }
|
|
.file-name { margin-top: 10px; color: #666; }
|
|
button { background: #007bff; color: white; border: none; padding: 12px 40px; border-radius: 6px; font-size: 16px; cursor: pointer; transition: 0.3s; }
|
|
button:hover { background: #0056b3; }
|
|
button:disabled { background: #ccc; cursor: not-allowed; }
|
|
.result-box { margin-top: 30px; padding: 25px; background: #e9ecef; border-radius: 8px; display: none; text-align: left; }
|
|
.result-box h3 { text-align: center; margin-bottom: 20px; }
|
|
.stat { display: flex; justify-content: space-between; margin: 12px 0; font-size: 18px; }
|
|
.danger { color: #dc3545; font-weight: bold; }
|
|
.safe { color: #28a745; font-weight: bold; }
|
|
.primary { color: #007bff; font-weight: bold; }
|
|
.loading { display: none; margin-top: 20px; color: #666; }
|
|
.accuracy { margin-top: 20px; padding-top: 15px; border-top: 1px solid #ccc; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div class="container">
|
|
<h1>🛡️ ADS-B 攻击检测系统</h1>
|
|
|
|
<div class="upload-area" onclick="document.getElementById('fileInput').click()">
|
|
<p>点击这里上传 CSV 文件</p>
|
|
<p class="file-name" id="fileName">未选择文件</p>
|
|
<input type="file" id="fileInput" accept=".csv">
|
|
</div>
|
|
|
|
<button id="submitBtn" onclick="uploadAndPredict()" disabled>开始检测</button>
|
|
|
|
<div class="loading" id="loading">
|
|
<p>正在检测中,请稍候...</p>
|
|
</div>
|
|
|
|
<div class="result-box" id="resultBox">
|
|
<h3>检测结果</h3>
|
|
<div class="stat">
|
|
<span>上传总样本数:</span>
|
|
<span id="totalOriginal">0</span>
|
|
</div>
|
|
<div class="stat">
|
|
<span>有效检测样本数:</span>
|
|
<span id="totalValid">0</span>
|
|
</div>
|
|
<div class="stat">
|
|
<span>正常数据:</span>
|
|
<span id="normal" class="safe">0</span>
|
|
</div>
|
|
<div class="stat">
|
|
<span>⚠️ 攻击数据:</span>
|
|
<span id="attack" class="danger">0</span>
|
|
</div>
|
|
<div class="stat">
|
|
<span>攻击占比:</span>
|
|
<span id="rate" class="danger">0%</span>
|
|
</div>
|
|
<div class="accuracy" id="accuracyBox" style="display: none;">
|
|
<div class="stat">
|
|
<span>模型检测准确率:</span>
|
|
<span id="accuracy" class="primary">0%</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const fileInput = document.getElementById('fileInput');
|
|
const submitBtn = document.getElementById('submitBtn');
|
|
const fileName = document.getElementById('fileName');
|
|
const resultBox = document.getElementById('resultBox');
|
|
const loading = document.getElementById('loading');
|
|
const accuracyBox = document.getElementById('accuracyBox');
|
|
|
|
fileInput.addEventListener('change', function() {
|
|
if (this.files.length) {
|
|
fileName.textContent = this.files[0].name;
|
|
submitBtn.disabled = false;
|
|
} else {
|
|
fileName.textContent = "未选择文件";
|
|
submitBtn.disabled = true;
|
|
}
|
|
});
|
|
|
|
async function uploadAndPredict() {
|
|
const formData = new FormData();
|
|
formData.append('file', fileInput.files[0]);
|
|
|
|
submitBtn.disabled = true;
|
|
loading.style.display = 'block';
|
|
resultBox.style.display = 'none';
|
|
accuracyBox.style.display = 'none';
|
|
|
|
try {
|
|
const response = await fetch('/predict', {
|
|
method: 'POST',
|
|
body: formData
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.status === 'success') {
|
|
document.getElementById('totalOriginal').textContent = data.total_original;
|
|
document.getElementById('totalValid').textContent = data.total_valid;
|
|
document.getElementById('normal').textContent = data.normal;
|
|
document.getElementById('attack').textContent = data.attack;
|
|
document.getElementById('rate').textContent = data.attack_rate + '%';
|
|
|
|
if (data.accuracy !== null) {
|
|
document.getElementById('accuracy').textContent = data.accuracy + '%';
|
|
accuracyBox.style.display = 'block';
|
|
}
|
|
|
|
resultBox.style.display = 'block';
|
|
} else {
|
|
alert('检测失败:' + data.error);
|
|
}
|
|
} catch (error) {
|
|
alert('请求出错:' + error);
|
|
} finally {
|
|
submitBtn.disabled = false;
|
|
loading.style.display = 'none';
|
|
}
|
|
}
|
|
</script>
|
|
|
|
</body>
|
|
</html> |