Initial commit

This commit is contained in:
2026-07-07 13:29:22 +08:00
commit 3fdd9ec927
154 changed files with 56566 additions and 0 deletions
+411
View File
@@ -0,0 +1,411 @@
<?php
session_start();
// 会话超时:30分钟无操作自动登出
$expire = 1800;
if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) {
session_destroy();
header("Location: ../login.php");
exit;
}
// 刷新登录时间
$_SESSION['login_time'] = time();
$userName = htmlspecialchars($_SESSION['username']);
$userRole = $_SESSION['role'];
$roleText = $userRole === 'admin' ? '管理员' : '只读用户';
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>开发者调试面板 - Advantest 运维告警监控平台</title>
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<script src="/static/js/jquery.min.js"></script>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{
background:#f9fafc;
font-family:"Inter","PingFang SC","Microsoft YaHei";
color:#1d2939;
line-height:1.6;
}
/* 顶部导航 */
.header{
background:#ffffff;
border-bottom:1px solid #eef2fb;
color:#152c5b;
padding:20px 40px;
display:flex;
justify-content:space-between;
align-items:center;
box-shadow:0 2px 12px rgba(21,44,91,0.05);
}
.header-left{
display:flex;
align-items:center;
gap:14px;
}
.header-title{
font-size:24px;
font-weight:700;
letter-spacing:1px;
color:#152c5b;
}
.header-sub{
font-size:14px;
color:#64748b;
}
.header-right{
display:flex;
align-items:center;
gap:18px;
font-size:14px;
flex-wrap:wrap;
}
.user-info{
color:#475569;
display:flex;
align-items:center;
gap:6px;
}
.btn-base{
border:none;
padding:9px 18px;
border-radius:8px;
cursor:pointer;
font-size:14px;
display:flex;
align-items:center;
gap:6px;
transition:all 0.2s ease;
}
.btn-outline{
background:#ffffff;
color:#152c5b;
border:1px solid #cbd5e1;
}
.btn-outline:hover{
background:#f7f8fc;
border-color:#152c5b;
}
.btn-primary{
background:#152c5b;
color:#fff;
}
.btn-primary:hover{
background:#0f1e42;
}
.btn-success{
background:#10b981;
color:#fff;
}
.btn-success:hover{
background:#059669;
}
.btn-warning{
background:#e6a23c;
color:#fff;
}
.btn-danger{
background:#f56c6c;
color:#fff;
}
/* 主容器 */
.container{
padding:36px 40px;
max-width:1600px;
margin:0 auto;
}
h1{
display:none;
}
/* 卡片样式 统一企业面板风格 */
.card{
background:#fff;
border-radius:16px;
padding:32px;
margin-bottom:36px;
box-shadow:0 3px 18px rgba(21,44,91,0.06);
border:1px solid #eef2fb;
}
.card h3{
display:flex;
align-items:center;
gap:10px;
margin-bottom:26px;
padding-bottom:16px;
border-bottom:1px solid #eef2fb;
font-size:19px;
font-weight:600;
color:#152c5b;
}
.card h3 i{
color:#2563eb;
font-size:20px;
}
.row{
display:flex;
gap:12px;
align-items:center;
margin-bottom:10px;
flex-wrap:wrap;
}
label{
font-size:14px;
color:#475569;
width:110px;
}
input{
padding:8px 12px;
border:1px solid #dcdfe6;
border-radius:8px;
width:280px;
font-size:14px;
}
input[type="date"]{
width:200px;
}
button{
padding:9px 18px;
border:none;
border-radius:8px;
cursor:pointer;
font-size:14px;
display:flex;
align-items:center;
gap:6px;
}
button.normal{
background:#409eff;
color:#fff;
}
button.normal:hover{
background:#2979e0;
}
.tip{
font-size:13px;
color:#94a3b8;
margin-top:8px;
padding-left:110px;
}
/* 返回结果区块 */
#result{
margin-top:20px;
padding:20px;
background:#1e1e1e;
color:#fff;
border-radius:12px;
white-space:pre-wrap;
min-height:260px;
font-family:Consolas,monospace;
font-size:13px;
}
/* 响应式适配 */
@media (max-width:768px){
.header{padding:16px 24px;flex-direction:column;gap:16px;align-items:flex-start}
.container{padding:24px}
.card{padding:24px}
.row{flex-direction:column;align-items:flex-start}
label{width:auto}
input{width:100% !important;max-width:320px}
}
</style>
</head>
<body>
<!-- 顶部导航 -->
<div class="header">
<div class="header-left">
<div>
<div class="header-title"><i class="fa fa-code"></i> 开发者调试面板</div>
<div class="header-sub">全部告警接口可视化调用 · 后端API调试工具</div>
</div>
</div>
<div class="header-right">
<span class="user-info"><i class="fa fa-user-circle"></i><?php echo $userName; ?><?php echo $roleText; ?></span>
<button class="btn-base btn-outline" onclick="location.href='../admin.php'"><i class="fa fa-arrow-left"></i>返回系统后台</button>
<button class="btn-base btn-outline" onclick="location.reload()"><i class="fa fa-refresh"></i>刷新页面</button>
<button class="btn-base btn-primary" onclick="location.href='../dashboard.php'"><i class="fa fa-line-chart"></i>告警监控大屏</button>
</div>
</div>
<div class="container">
<!-- 1 临时清理单实例告警 clear_single_instance -->
<div class="card">
<h3><i class="fa fa-eraser"></i>1. 临时隐藏单实例告警 clear_single_instance</h3>
<div class="row">
<label>rule_name</label>
<input id="c_rule" placeholder="例 Port_Down">
<label>instance</label>
<input id="c_ins" placeholder="例 10.150.10.82:389">
<button class="normal" onclick="req('clear_single_instance','c_rule','c_ins')"><i class="fa fa-play"></i>执行清理</button>
</div>
<div class="tip">仅插入恢复日志,下次故障自动重新展示;instance冒号无需手动编码,JS自动处理</div>
</div>
<!-- 2 永久屏蔽单实例 offline_single_instance -->
<div class="card">
<h3><i class="fa fa-ban"></i>2. 永久屏蔽单实例 offline_single_instance</h3>
<div class="row">
<label>rule_name</label>
<input id="off_rule" placeholder="例 Port_Down">
<label>instance</label>
<input id="off_ins" placeholder="例 10.150.10.82:389">
<button class="btn-danger" onclick="req('offline_single_instance','off_rule','off_ins')"><i class="fa fa-ban"></i>永久屏蔽</button>
</div>
<div class="tip">修改monitor_rule状态0,不执行恢复接口则永久不展示该实例告警</div>
</div>
<!-- 3 恢复单实例 restore_single_instance -->
<div class="card">
<h3><i class="fa fa-check-circle"></i>3. 恢复单实例 restore_single_instance</h3>
<div class="row">
<label>rule_name</label>
<input id="res_rule" placeholder="例 Port_Down">
<label>instance</label>
<input id="res_ins" placeholder="例 10.150.10.82:389">
<button class="btn-success" onclick="req('restore_single_instance','res_rule','res_ins')"><i class="fa fa-unlock"></i>恢复实例告警</button>
</div>
<div class="tip">解除单实例永久屏蔽状态,新故障会正常展示</div>
</div>
<!-- 4 整条规则下线 clear_offline_rule -->
<div class="card">
<h3><i class="fa fa-cog"></i>4. 整条规则全部下线 clear_offline_rule</h3>
<div class="row">
<label>rule_name</label>
<input id="cr_rule" placeholder="例 Host_Ping_Offline">
<button class="btn-danger" onclick="reqSingle('clear_offline_rule','cr_rule')"><i class="fa fa-power-off"></i>下线整条规则</button>
</div>
</div>
<!-- 5 恢复整条规则 restore_rule -->
<div class="card">
<h3><i class="fa fa-cog"></i>5. 恢复整条规则 restore_rule</h3>
<div class="row">
<label>rule_name</label>
<input id="rr_rule" placeholder="例 Host_Ping_Offline">
<button class="btn-success" onclick="reqSingle('restore_rule','rr_rule')"><i class="fa fa-refresh"></i>恢复整条规则</button>
</div>
</div>
<!-- 6 删除单实例全部日志 delete_single_instance_log -->
<div class="card">
<h3><i class="fa fa-trash"></i>6. 删除单实例所有告警日志 delete_single_instance_log</h3>
<div class="row">
<label>rule_name</label>
<input id="del_rule" placeholder="例 Port_Down">
<label>instance</label>
<input id="del_ins" placeholder="例 10.150.10.82:389">
<button class="btn-warning" onclick="req('delete_single_instance_log','del_rule','del_ins')"><i class="fa fa-trash"></i>清空日志</button>
</div>
</div>
<!-- 7 同步Prometheus实时告警 sync_prom_alerts -->
<div class="card">
<h3><i class="fa fa-refresh"></i>7. 手动同步Prometheus告警(清除脏恢复记录)</h3>
<div class="row">
<button class="normal" onclick="simpleReq('sync_prom_alerts')"><i class="fa fa-sync"></i>立即同步校准数据库</button>
</div>
<div class="tip">自动删除故障中残留的手动恢复记录,修复前端“故障存在但页面不显示”bug</div>
</div>
<!-- 8 数据查询接口 -->
<div class="card">
<h3><i class="fa fa-database"></i>8. 数据查询接口(获取面板原始数据)</h3>
<div class="row">
<button class="normal" onclick="simpleReq('day_total')"><i class="fa fa-bar-chart"></i>今日统计 day_total</button>
<button class="normal" onclick="simpleReq('top_alert')"><i class="fa fa-pie-chart"></i>告警TOP10 top_alert</button>
<button class="normal" onclick="simpleReq('log_list')"><i class="fa fa-list"></i>今日明细 log_list</button>
<button class="normal" onclick="simpleReq('active_firing')"><i class="fa fa-exclamation-circle"></i>当前未恢复 active_firing</button>
</div>
</div>
<!-- 9 导出CSV报表(带日历选择) -->
<div class="card">
<h3><i class="fa fa-download"></i>9. 导出告警CSV报表(支持历史日期)</h3>
<div class="row">
<label>选择日期:</label>
<input type="date" id="csv_date" placeholder="留空导出今日">
<button class="btn-success" onclick="exportCsv()"><i class="fa fa-download"></i>下载对应日期报表</button>
</div>
<div class="tip">不选择日期默认导出今日告警;选择历史日期可下载过往报表</div>
</div>
<!-- 返回结果输出 -->
<div class="card">
<h3><i class="fa fa-terminal"></i>接口返回结果(JSON)</h3>
<div id="result">等待执行接口操作...</div>
</div>
</div>
<script>
// 接口路径 同目录 index.php
const apiUrl = "./index.php";
const resultDom = document.getElementById("result");
// 双参数接口 act + rule_name + instance
function req(act, ruleId, insId){
const rule = document.getElementById(ruleId).value.trim();
const ins = document.getElementById(insId).value.trim();
if(!rule || !ins){
resultDom.innerText = "错误:rule_name 和 instance 不能为空";
return;
}
const params = new URLSearchParams();
params.append("act", act);
params.append("rule_name", rule);
params.append("instance", ins);
fetch(`${apiUrl}?${params.toString()}`)
.then(r=>r.json())
.then(json=>{
resultDom.innerText = JSON.stringify(json,null,2);
})
.catch(e=>{
resultDom.innerText = "请求异常:"+e;
})
}
// 单参数接口 act + rule_name
function reqSingle(act, ruleId){
const rule = document.getElementById(ruleId).value.trim();
if(!rule){
resultDom.innerText = "错误:rule_name 不能为空";
return;
}
const params = new URLSearchParams();
params.append("act", act);
params.append("rule_name", rule);
fetch(`${apiUrl}?${params.toString()}`)
.then(r=>r.json())
.then(json=>{
resultDom.innerText = JSON.stringify(json,null,2);
})
.catch(e=>{
resultDom.innerText = "请求异常:"+e;
})
}
// 无参数接口
function simpleReq(act){
fetch(`${apiUrl}?act=${act}`)
.then(r=>r.json())
.then(json=>{
resultDom.innerText = JSON.stringify(json,null,2);
})
.catch(e=>{
resultDom.innerText = "请求异常:"+e;
})
}
// 导出CSV 支持日历选择日期
function exportCsv(){
const dateVal = document.getElementById("csv_date").value.trim();
let url = `${apiUrl}?act=export_csv`;
if(dateVal){
url += `&date=${encodeURIComponent(dateVal)}`;
}
window.open(url,"_blank");
}
</script>
</body>
</html>