mirror of
https://github.com/Ed1s0nZ/PrivHunterAI.git
synced 2025-09-17 20:41:37 +00:00
Update index.html
This commit is contained in:
parent
9abae5800f
commit
a0d22436f6
159
index.html
159
index.html
@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>PrivHunterAI</title>
|
<title>PrivHunterAI</title>
|
||||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
@ -140,8 +140,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
|
text-align: center;
|
||||||
text-align: right;
|
|
||||||
padding: 50px 20px;
|
padding: 50px 20px;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
@ -201,7 +200,6 @@
|
|||||||
max-width: 550px;
|
max-width: 550px;
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.foldable-row .result-status {
|
.foldable-row .result-status {
|
||||||
@ -334,14 +332,8 @@
|
|||||||
<div class="results-header">
|
<div class="results-header">
|
||||||
<h3>漏洞扫描结果</h3>
|
<h3>漏洞扫描结果</h3>
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
<select class="filter-select" id="filter-type">
|
|
||||||
<option value="all">所有漏洞类型</option>
|
|
||||||
<option value="true">漏洞请求</option>
|
|
||||||
<option value="unknown">未知状态</option>
|
|
||||||
<option value="false">安全请求</option>
|
|
||||||
</select>
|
|
||||||
<select class="filter-select" id="filter-result">
|
<select class="filter-select" id="filter-result">
|
||||||
<option value="all">所有检测结果</option>
|
<option value="">所有状态</option>
|
||||||
<option value="true">漏洞请求</option>
|
<option value="true">漏洞请求</option>
|
||||||
<option value="unknown">未知状态</option>
|
<option value="unknown">未知状态</option>
|
||||||
<option value="false">安全请求</option>
|
<option value="false">安全请求</option>
|
||||||
@ -353,7 +345,7 @@
|
|||||||
<table class="data-table">
|
<table class="data-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<!-- <th colspan="2">扫描结果</th> -->
|
<th colspan="2">扫描结果</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="data-body">
|
<tbody id="data-body">
|
||||||
@ -363,6 +355,13 @@
|
|||||||
|
|
||||||
<!-- 分页控制 -->
|
<!-- 分页控制 -->
|
||||||
<div class="pagination" id="pagination">
|
<div class="pagination" id="pagination">
|
||||||
|
<select id="page-size">
|
||||||
|
<option value="5">5 条/页</option>
|
||||||
|
<option value="10" selected>10 条/页</option>
|
||||||
|
<option value="20">20 条/页</option>
|
||||||
|
<option value="50">50 条/页</option>
|
||||||
|
<option value="100">100 条/页</option>
|
||||||
|
</select>
|
||||||
<button onclick="prevPage()" id="prev-btn" disabled>上一页</button>
|
<button onclick="prevPage()" id="prev-btn" disabled>上一页</button>
|
||||||
<span id="page-info">第 1 页,共 1 页</span>
|
<span id="page-info">第 1 页,共 1 页</span>
|
||||||
<button onclick="nextPage()" id="next-btn" disabled>下一页</button>
|
<button onclick="nextPage()" id="next-btn" disabled>下一页</button>
|
||||||
@ -375,68 +374,52 @@
|
|||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 原始数据存储
|
|
||||||
let originalData = [];
|
|
||||||
// 当前显示的数据
|
|
||||||
let currentData = [];
|
|
||||||
// 分页相关变量
|
// 分页相关变量
|
||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
let itemsPerPage = 10;
|
let itemsPerPage = 10;
|
||||||
let totalPages = 1;
|
let totalPages = 1;
|
||||||
|
let currentData = [];
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData(page = 1, pageSize = itemsPerPage, resultFilter = '') {
|
||||||
try {
|
try {
|
||||||
// 从你的接口获取数据
|
document.body.style.cursor = 'wait';
|
||||||
const response = await fetch('/data');
|
|
||||||
if (!response.ok) throw new Error('Network response was not ok');
|
|
||||||
originalData = await response.json();
|
|
||||||
currentData = [...originalData];
|
|
||||||
|
|
||||||
// 更新统计信息
|
// 获取统计数据
|
||||||
updateStatistics();
|
const statsResponse = await fetch('/stats');
|
||||||
|
if (!statsResponse.ok) throw new Error('Failed to fetch statistics');
|
||||||
|
const stats = await statsResponse.json();
|
||||||
|
updateStatistics(stats);
|
||||||
|
|
||||||
// 更新分页信息
|
// 获取分页数据
|
||||||
updatePagination();
|
const dataResponse = await fetch(`/data?page=${page}&pageSize=${pageSize}&result=${resultFilter}`);
|
||||||
|
if (!dataResponse.ok) throw new Error('Failed to fetch data');
|
||||||
|
const data = await dataResponse.json();
|
||||||
|
currentData = data.data;
|
||||||
|
|
||||||
|
currentPage = data.currentPage;
|
||||||
|
itemsPerPage = data.pageSize;
|
||||||
|
totalPages = data.totalPages;
|
||||||
|
|
||||||
// 更新表格数据
|
|
||||||
updateTableData();
|
updateTableData();
|
||||||
|
updatePaginationControls();
|
||||||
|
|
||||||
} catch (error) {
|
} finally {
|
||||||
console.error('Failed to fetch data:', error);
|
document.body.style.cursor = 'default';
|
||||||
alert('加载数据失败,请重试');
|
|
||||||
// 清空表格
|
|
||||||
document.getElementById('data-body').innerHTML = '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStatistics() {
|
function updateStatistics(stats) {
|
||||||
// 更新总数据统计
|
document.getElementById('total-requests').textContent = stats.total;
|
||||||
document.getElementById('total-requests').textContent = originalData.length;
|
document.getElementById('vulnerable-requests').textContent = stats.vulnerable;
|
||||||
|
document.getElementById('unknown-requests').textContent = stats.unknown;
|
||||||
// 计算漏洞请求 (Result为true)
|
document.getElementById('safe-requests').textContent = stats.safe;
|
||||||
const vulnerableRequests = originalData.filter(item => item.result === "true").length;
|
|
||||||
document.getElementById('vulnerable-requests').textContent = vulnerableRequests;
|
|
||||||
|
|
||||||
// 计算未知状态 (Result为unknown)
|
|
||||||
const unknownRequests = originalData.filter(item => item.result === 'unknown').length;
|
|
||||||
document.getElementById('unknown-requests').textContent = unknownRequests;
|
|
||||||
|
|
||||||
// 计算安全请求 (Result为false)
|
|
||||||
const safeRequests = originalData.filter(item => item.result === "false").length;
|
|
||||||
document.getElementById('safe-requests').textContent = safeRequests;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTableData() {
|
function updateTableData() {
|
||||||
const tableBody = document.getElementById('data-body');
|
const tableBody = document.getElementById('data-body');
|
||||||
tableBody.innerHTML = '';
|
tableBody.innerHTML = '';
|
||||||
|
|
||||||
// 计算当前页面的数据范围
|
if (currentData.length === 0) {
|
||||||
const startIndex = (currentPage - 1) * itemsPerPage;
|
|
||||||
const endIndex = Math.min(startIndex + itemsPerPage, currentData.length);
|
|
||||||
const paginatedData = currentData.slice(startIndex, endIndex);
|
|
||||||
|
|
||||||
// 如果没有数据,显示空状态
|
|
||||||
if (paginatedData.length === 0) {
|
|
||||||
const emptyRow = document.createElement('tr');
|
const emptyRow = document.createElement('tr');
|
||||||
emptyRow.innerHTML = `
|
emptyRow.innerHTML = `
|
||||||
<td colspan="2" class="empty-state">
|
<td colspan="2" class="empty-state">
|
||||||
@ -448,23 +431,15 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 渲染当前页面的数据
|
currentData.forEach(item => {
|
||||||
paginatedData.forEach(item => {
|
|
||||||
// 创建折叠行
|
|
||||||
const foldableRow = document.createElement('tr');
|
const foldableRow = document.createElement('tr');
|
||||||
foldableRow.className = 'foldable-row';
|
foldableRow.className = 'foldable-row';
|
||||||
foldableRow.onclick = function() {
|
foldableRow.onclick = function() {
|
||||||
const detailsRow = this.nextElementSibling;
|
const detailsRow = this.nextElementSibling;
|
||||||
if (detailsRow.classList.contains('active')) {
|
detailsRow.classList.toggle('active');
|
||||||
detailsRow.classList.remove('active');
|
this.style.fontWeight = detailsRow.classList.contains('active') ? 'bold' : 'normal';
|
||||||
this.style.fontWeight = 'normal';
|
|
||||||
} else {
|
|
||||||
detailsRow.classList.add('active');
|
|
||||||
this.style.fontWeight = 'bold';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 根据结果类型设置行样式
|
|
||||||
if (item.result === 'true') {
|
if (item.result === 'true') {
|
||||||
foldableRow.style.borderLeft = '4px solid #e74c3c';
|
foldableRow.style.borderLeft = '4px solid #e74c3c';
|
||||||
} else if (item.result === 'unknown') {
|
} else if (item.result === 'unknown') {
|
||||||
@ -489,7 +464,6 @@
|
|||||||
`;
|
`;
|
||||||
tableBody.appendChild(foldableRow);
|
tableBody.appendChild(foldableRow);
|
||||||
|
|
||||||
// 创建详情行
|
|
||||||
const detailsRow = document.createElement('tr');
|
const detailsRow = document.createElement('tr');
|
||||||
detailsRow.className = 'details-row';
|
detailsRow.className = 'details-row';
|
||||||
detailsRow.innerHTML = `
|
detailsRow.innerHTML = `
|
||||||
@ -534,69 +508,36 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePagination() {
|
function updatePaginationControls() {
|
||||||
// 计算总页数
|
|
||||||
totalPages = Math.ceil(currentData.length / itemsPerPage);
|
|
||||||
|
|
||||||
// 更新页码显示
|
|
||||||
document.getElementById('page-info').textContent =
|
document.getElementById('page-info').textContent =
|
||||||
`第 ${currentPage} 页,共 ${totalPages} 页`;
|
`第 ${currentPage} 页,共 ${totalPages} 页`;
|
||||||
|
|
||||||
// 更新按钮状态
|
|
||||||
document.getElementById('prev-btn').disabled = currentPage === 1;
|
document.getElementById('prev-btn').disabled = currentPage === 1;
|
||||||
document.getElementById('next-btn').disabled = currentPage === totalPages;
|
document.getElementById('next-btn').disabled = currentPage === totalPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
function prevPage() {
|
function prevPage() {
|
||||||
if (currentPage > 1) {
|
if (currentPage > 1) {
|
||||||
currentPage--;
|
fetchData(currentPage - 1, itemsPerPage, document.getElementById('filter-result').value);
|
||||||
updateTableData();
|
|
||||||
updatePagination();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextPage() {
|
function nextPage() {
|
||||||
if (currentPage < totalPages) {
|
if (currentPage < totalPages) {
|
||||||
currentPage++;
|
fetchData(currentPage + 1, itemsPerPage, document.getElementById('filter-result').value);
|
||||||
updateTableData();
|
|
||||||
updatePagination();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterData() {
|
function filterData() {
|
||||||
const filterType = document.getElementById('filter-type').value;
|
const resultFilter = document.getElementById('filter-result').value;
|
||||||
const filterResult = document.getElementById('filter-result').value;
|
fetchData(1, itemsPerPage, resultFilter);
|
||||||
|
|
||||||
// 根据筛选条件过滤数据
|
|
||||||
if (filterType !== 'all') {
|
|
||||||
if (filterType === 'true') {
|
|
||||||
currentData = originalData.filter(item => item.result === 'true');
|
|
||||||
} else if (filterType === 'unknown') {
|
|
||||||
currentData = originalData.filter(item => item.result === 'unknown');
|
|
||||||
} else if (filterType === 'false') {
|
|
||||||
currentData = originalData.filter(item => item.result === 'false');
|
|
||||||
}
|
|
||||||
} else if (filterResult !== 'all') {
|
|
||||||
if (filterResult === 'true') {
|
|
||||||
currentData = originalData.filter(item => item.result === 'true');
|
|
||||||
} else if (filterResult === 'unknown') {
|
|
||||||
currentData = originalData.filter(item => item.result === 'unknown');
|
|
||||||
} else if (filterResult === 'false') {
|
|
||||||
currentData = originalData.filter(item => item.result === 'false');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
currentData = [...originalData];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置页码
|
|
||||||
currentPage = 1;
|
|
||||||
|
|
||||||
// 更新表格数据和分页信息
|
|
||||||
updateTableData();
|
|
||||||
updatePagination();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化时尝试获取数据
|
document.getElementById('page-size').addEventListener('change', function() {
|
||||||
|
itemsPerPage = parseInt(this.value);
|
||||||
|
fetchData(1, itemsPerPage, document.getElementById('filter-result').value);
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
fetchData();
|
fetchData();
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user