init 全新仓库,清除全部历史
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>服务器磁盘目录容量监控 | Dashboard</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Microsoft YaHei", system-ui, -apple-system, sans-serif;
|
||||
}
|
||||
body {
|
||||
background-color: #f4f7fa;
|
||||
padding: 24px;
|
||||
color: #2d3748;
|
||||
}
|
||||
.dashboard-card {
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 16px rgba(0, 30, 80, 0.08);
|
||||
padding: 24px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
padding-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
gap:16px;
|
||||
}
|
||||
.card-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a202c;
|
||||
}
|
||||
.card-desc {
|
||||
font-size: 13px;
|
||||
color: #718096;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.filter-box{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:10px;
|
||||
}
|
||||
.filter-box label{
|
||||
font-size:14px;
|
||||
}
|
||||
#ipSelect{
|
||||
padding:6px 10px;
|
||||
border:1px solid #cbd5e0;
|
||||
border-radius:6px;
|
||||
font-size:14px;
|
||||
min-width:200px;
|
||||
}
|
||||
#exportBtn{
|
||||
padding:6px 14px;
|
||||
background:#2b6cb0;
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:6px;
|
||||
cursor:pointer;
|
||||
font-size:14px;
|
||||
}
|
||||
#exportBtn:hover{
|
||||
background:#2c5282;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top:10px;
|
||||
}
|
||||
thead tr {
|
||||
background-color: #2b6cb0;
|
||||
color: #fff;
|
||||
}
|
||||
th, td {
|
||||
padding: 14px 16px;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
}
|
||||
th {
|
||||
font-weight: 500;
|
||||
}
|
||||
tbody tr {
|
||||
border-bottom: 1px solid #edf2f7;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
tbody tr:hover {
|
||||
background-color: #f7fafc;
|
||||
}
|
||||
.num-big {
|
||||
color: #c53030;
|
||||
font-weight: 500;
|
||||
}
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: #718096;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="dashboard-card">
|
||||
<div class="card-header">
|
||||
<div>
|
||||
<h2 class="card-title">用户目录磁盘占用统计</h2>
|
||||
<div class="card-desc">多服务器 /serverhome 目录容量实时采集,支持按实例IP筛选、导出表格</div>
|
||||
</div>
|
||||
<div class="filter-box">
|
||||
<label>筛选实例IP:</label>
|
||||
<select id="ipSelect">
|
||||
<option value="all">全部实例</option>
|
||||
</select>
|
||||
<button id="exportBtn">导出当前表格CSV</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>实例IP</th>
|
||||
<th>用户名</th>
|
||||
<th>目录路径</th>
|
||||
<th>占用容量</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="diskTableBody">
|
||||
<tr>
|
||||
<td colspan="4" class="loading">数据加载中...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let sourceData = [];
|
||||
let currentFilterIp = "all";
|
||||
const ipSelect = document.getElementById('ipSelect');
|
||||
const tbody = document.getElementById('diskTableBody');
|
||||
const exportBtn = document.getElementById('exportBtn');
|
||||
|
||||
// 拉取全量数据
|
||||
fetch('/api/df.php', {
|
||||
headers: {
|
||||
"Accept": "application/json;charset=utf-8"
|
||||
}
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(ret => {
|
||||
if(ret.code !== 0){
|
||||
tbody.innerHTML = `<tr><td colspan="4" class="loading">接口异常:${ret.msg}</td></tr>`;
|
||||
return;
|
||||
}
|
||||
sourceData = ret.list;
|
||||
if(sourceData.length === 0){
|
||||
tbody.innerHTML = `<tr><td colspan="4" class="loading">暂无磁盘指标数据</td></tr>`;
|
||||
return;
|
||||
}
|
||||
// 提取所有不重复IP写入下拉框
|
||||
const ipSet = new Set();
|
||||
sourceData.forEach(item=>ipSet.add(item.instance_ip));
|
||||
ipSet.forEach(ip=>{
|
||||
let opt = document.createElement('option');
|
||||
opt.value = ip;
|
||||
opt.innerText = ip;
|
||||
ipSelect.appendChild(opt);
|
||||
})
|
||||
// 初始渲染全部
|
||||
renderTable("all");
|
||||
})
|
||||
.catch(err => {
|
||||
tbody.innerHTML = `<tr><td colspan="4" class="loading">接口请求失败:${err}</td></tr>`;
|
||||
})
|
||||
|
||||
// 筛选切换事件
|
||||
ipSelect.addEventListener('change', function(){
|
||||
currentFilterIp = this.value;
|
||||
renderTable(currentFilterIp);
|
||||
})
|
||||
|
||||
// 渲染表格
|
||||
function renderTable(filterIp){
|
||||
tbody.innerHTML = "";
|
||||
let showList = [];
|
||||
if(filterIp === "all"){
|
||||
showList = sourceData;
|
||||
}else{
|
||||
showList = sourceData.filter(item=>item.instance_ip === filterIp);
|
||||
}
|
||||
if(showList.length === 0){
|
||||
tbody.innerHTML = `<tr><td colspan="4" class="loading">该实例下无目录数据</td></tr>`;
|
||||
return;
|
||||
}
|
||||
showList.forEach(row => {
|
||||
let tr = document.createElement('tr');
|
||||
tr.innerHTML = `
|
||||
<td>${row.instance_ip}</td>
|
||||
<td>${row.username}</td>
|
||||
<td>${row.directory}</td>
|
||||
<td class="num-big">${row.size_gb}GB</td>
|
||||
`;
|
||||
tbody.appendChild(tr);
|
||||
})
|
||||
}
|
||||
|
||||
// 导出CSV
|
||||
exportBtn.addEventListener('click', function(){
|
||||
let showList = [];
|
||||
if(currentFilterIp === "all"){
|
||||
showList = sourceData;
|
||||
}else{
|
||||
showList = sourceData.filter(item=>item.instance_ip === currentFilterIp);
|
||||
}
|
||||
if(showList.length === 0){
|
||||
alert("无数据可导出");
|
||||
return;
|
||||
}
|
||||
// CSV表头
|
||||
let csvContent = "\uFEFF实例IP,用户名,目录路径,占用容量(GB)\n";
|
||||
showList.forEach(item=>{
|
||||
const line = [
|
||||
`"${item.instance_ip}"`,
|
||||
`"${item.username}"`,
|
||||
`"${item.directory}"`,
|
||||
`"${item.size_gb}GB"`
|
||||
];
|
||||
csvContent += line.join(",") + "\n";
|
||||
});
|
||||
// 下载文件
|
||||
const blob = new Blob([csvContent], {type:"text/csv;charset=utf-8"});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "磁盘目录容量_"+new Date().getTime()+".csv";
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user