Files
2026-07-07 13:29:22 +08:00

606 lines
18 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
session_start();
// 会话超时:30分钟无操作自动登出,和dashboard逻辑统一
$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' ? '管理员' : '只读用户';
// 预加载现有配置,页面打开自动回填表单
$dbHost = "10.150.117.190";
$dbUser = "root";
$dbPwd = "hp93000";
$dbName = "alert_mail_stat";
$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName);
$configSql = "SELECT k,v FROM sys_config";
$configRes = mysqli_query($conn, $configSql);
$sysConfig = [];
while ($row = mysqli_fetch_assoc($configRes)) {
$sysConfig[$row['k']] = $row['v'];
}
mysqli_close($conn);
// 读取已有配置默认值
$pageTitle = $sysConfig['page_title'] ?? "告警监控系统";
$themeColor = $sysConfig['theme_color'] ?? "#409eff";
$pageSize = $sysConfig['page_size'] ?? "20";
$footerText = $sysConfig['footer_text'] ?? "";
$sidebarLinks = $sysConfig['sidebar_links'] ?? "";
?>
<!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;
display:flex;
flex-direction:column;
height:100vh;
overflow:hidden;
}
.wrap-main{
display:flex;
flex:1;
overflow:hidden;
}
/* 侧边栏 同dashboard深蓝色侧边 */
.sidebar{
width:240px;
background:#152c5b;
color:#e2e8f0;
flex-shrink:0;
overflow-y:auto;
}
.sidebar-brand{
padding:26px 24px;
border-bottom:1px solid rgba(255,255,255,0.1);
}
.sidebar-brand-en{
font-size:20px;
font-weight:700;
letter-spacing:1px;
color:#fff;
}
.sidebar-brand-cn{
font-size:13px;
color:#a5b4fc;
margin-top:4px;
}
.sidebar-menu{
padding:16px 0;
}
.menu-title{
padding:10px 24px;
font-size:12px;
color:#94a3b8;
letter-spacing:1px;
}
.menu-item{
display:flex;
align-items:center;
gap:12px;
padding:14px 24px;
cursor:pointer;
font-size:14px;
transition:0.2s;
color:#cbd5e1;
}
.menu-item i{
font-size:16px;
width:20px;
text-align:center;
}
.menu-item.active{
background:rgba(255,255,255,0.12);
color:#fff;
border-left:4px solid #3b82f6;
}
.menu-item:hover:not(.active){
background:rgba(255,255,255,0.06);
color:#fff;
}
/* 主内容区域 */
.main-content{
flex:1;
overflow-y:auto;
display:flex;
flex-direction:column;
}
/* 顶部导航栏 和dashboard完全一致 */
.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);
flex-shrink:0;
}
.header-left{
display:flex;
align-items:center;
gap:14px;
}
.header-brand-en{
font-size:24px;
font-weight:700;
letter-spacing:2px;
color:#152c5b;
}
.header-brand-cn{
font-size:15px;
color:#64748b;
}
.header-right{
display:flex;
align-items:center;
gap:18px;
font-size:14px;
flex-wrap:wrap;
}
.user-info,.time-info{
color:#475569;
display:flex;
align-items:center;
gap:6px;
}
.btn-base{
border:none;
padding:9px 20px;
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-danger{
background:#f56c6c;
color:#fff;
}
.btn-danger:hover{
background:#e53e3e;
}
/* 页面容器 */
.container{
padding:36px 40px;
max-width:100%;
flex:1;
}
.page-title{
font-size:24px;
font-weight:700;
color:#152c5b;
margin-bottom:26px;
display:flex;
align-items:center;
gap:12px;
}
.page-title i{
color:#2563eb;
font-size:26px;
}
/* Tab切换 */
.tab-box{
display:flex;
border-bottom:1px solid #eef2fb;
margin-bottom:36px;
}
.tab-item{
padding:14px 26px;
cursor:pointer;
font-size:15px;
color:#64748b;
border-bottom:3px solid transparent;
transition:0.2s;
}
.tab-item.active{
color:#2563eb;
border-bottom:3px solid #2563eb;
font-weight:600;
}
.tab-item:hover:not(.active){
color:#152c5b;
}
/* 统一企业卡片样式,和dashboard base-card完全一致 */
.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;
}
.form-row{
margin-bottom:20px;
display:flex;
align-items:center;
gap:12px;
flex-wrap:wrap;
}
.form-row label{
width:160px;
font-size:14px;
color:#475569;
font-weight:500;
}
.form-row input,.form-row textarea{
padding:10px 14px;
border:1px solid #dcdfe6;
border-radius:8px;
flex:1;
max-width:480px;
font-size:14px;
}
.form-row textarea{
min-height:120px;
resize:vertical;
}
.tip-text{
font-size:13px;
color:#94a3b8;
margin-top:-12px;
margin-bottom:16px;
padding-left:160px;
}
/* 提示消息框 */
#msg{
margin:20px 0;
padding:12px 16px;
border-radius:8px;
display:none;
font-size:14px;
}
.success{
background:#dcfce7;
color:#16a34a;
border:1px solid #bbf7d0;
}
.error{
background:#fee2e2;
color:#dc2626;
border:1px solid #fecdd3;
}
/* JSON返回结果框 */
#result{
margin-top:20px;
padding:20px;
background:#1e1e1e;
color:#fff;
border-radius:12px;
white-space:pre-wrap;
min-height:160px;
font-family:Consolas,monospace;
font-size:13px;
}
.hide{display:none}
.link-group{
margin-top:30px;
padding-top:20px;
border-top:1px solid #eef2fb;
display:flex;
gap:20px;
}
.link-group a{
color:#2563eb;
text-decoration:none;
display:flex;
align-items:center;
gap:6px;
}
.link-group a:hover{
text-decoration:underline;
}
/* 响应式适配 和dashboard统一 */
@media (max-width:1440px){
}
@media (max-width:992px){
.wrap-main{flex-direction:column;}
.sidebar{width:100%;height:auto}
}
@media (max-width:768px){
.header{padding:16px 24px;flex-direction:column;gap:16px;align-items:flex-start}
.header-right{flex-wrap:wrap}
.container{padding:24px}
.card{padding:24px}
.form-row{flex-direction:column;align-items:flex-start}
.form-row label{width:auto}
.form-row input,.form-row textarea{width:100%;max-width:100%}
.tip-text{padding-left:0}
.tab-item{padding:12px 16px}
}
</style>
</head>
<body>
<div class="wrap-main">
<!-- 左侧侧边栏 -->
<div class="sidebar">
<div class="sidebar-brand">
<div class="sidebar-brand-en">Advantest</div>
<div class="sidebar-brand-cn">运维监控管理后台</div>
</div>
<div class="sidebar-menu">
<div class="menu-title">系统管理</div>
<div class="menu-item active" data-tab="pwd">
<i class="fa fa-key"></i>
<span>修改登录密码</span>
</div>
<div class="menu-item" data-tab="theme">
<i class="fa fa-paint-brush"></i>
<span>界面外观配置</span>
</div>
<div class="menu-item" data-tab="link">
<i class="fa fa-link"></i>
<span>侧边栏外链管理</span>
</div>
</div>
</div>
<!-- 右侧主内容区 -->
<div class="main-content">
<!-- 顶部导航 -->
<div class="header">
<div class="header-left">
<div>
<div class="header-brand-en">Advantest</div>
<div class="header-brand-cn">系统后台管理面板</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.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>
<button class="btn-base btn-danger" onclick="location.href='logout.php'"><i class="fa fa-sign-out"></i>退出登录</button>
</div>
</div>
<div class="container">
<div class="page-title"><i class="fa fa-cog"></i>系统全局配置管理</div>
<!-- Tab切换 -->
<div class="tab-box">
<div class="tab-item active" data-tab="pwd">修改登录密码</div>
<div class="tab-item" data-tab="theme">界面外观配置</div>
<div class="tab-item" data-tab="link">侧边栏外链管理</div>
</div>
<!-- 1 修改密码模块 BCrypt兼容 -->
<div class="card tab-content" id="tab-pwd">
<h3><i class="fa fa-key"></i>账户密码修改(BCrypt哈希加密,与登录算法统一)</h3>
<div class="form-row">
<label>原登录密码:</label>
<input type="password" id="old_pwd" placeholder="输入当前正在使用的密码">
</div>
<div class="tip-text">输入你现在登录的密码用于身份校验</div>
<div class="form-row">
<label>新密码:</label>
<input type="password" id="new_pwd" placeholder="设置全新登录密码">
</div>
<div class="form-row">
<label>确认新密码:</label>
<input type="password" id="re_pwd" placeholder="再次输入新密码,保持一致">
</div>
<div class="form-row">
<button class="btn-base btn-primary" onclick="updatePwd()"><i class="fa fa-check"></i>提交修改密码</button>
</div>
<div id="msg"></div>
<div id="result"></div>
</div>
<!-- 2 界面外观配置(保存后dashboard实时生效) -->
<div class="card tab-content hide" id="tab-theme">
<h3><i class="fa fa-paint-brush"></i>监控大屏界面外观全局配置</h3>
<div class="form-row">
<label>页面标题:</label>
<input id="page_title" value="<?php echo htmlspecialchars($pageTitle); ?>" placeholder="告警监控系统">
</div>
<div class="form-row">
<label>主题主色值:</label>
<input id="theme_color" value="<?php echo htmlspecialchars($themeColor); ?>" placeholder="#409eff">
</div>
<div class="form-row">
<label>表格每页展示条数:</label>
<input id="page_size" value="<?php echo htmlspecialchars($pageSize); ?>" placeholder="20">
</div>
<div class="form-row">
<label>页面底部自定义文案:</label>
<textarea id="footer_text"><?php echo htmlspecialchars($footerText); ?></textarea>
</div>
<div class="form-row">
<button class="btn-base btn-success" onclick="saveTheme()"><i class="fa fa-save"></i>保存外观配置</button>
</div>
<div class="tip-text">保存后刷新告警监控大屏dashboard.php即可生效</div>
<div id="msg"></div>
<div id="result"></div>
</div>
<!-- 3 侧边栏外链管理(保存后dashboard侧边同步更新) -->
<div class="card tab-content hide" id="tab-link">
<h3><i class="fa fa-link"></i>监控大屏侧边导航外链配置</h3>
<div class="form-row">
<label>外链列表(格式:名称|地址,一行一条):</label>
<textarea id="sidebar_links"><?php echo htmlspecialchars($sidebarLinks); ?></textarea>
</div>
<div class="tip-text">示例:Prometheus|http://10.150.117.190:9090<br>保存后刷新dashboard侧边栏立即加载</div>
<div class="form-row">
<button class="btn-base btn-success" onclick="saveLink()"><i class="fa fa-save"></i>保存侧边外链配置</button>
</div>
<div id="msg"></div>
<div id="result"></div>
</div>
<!-- 底部跳转链接 -->
<div class="link-group">
<a href="./api/dev_panel.php" target="_blank"><i class="fa fa-code"></i>进入开发者调试面板(API可视化调用)</a>
<a href="dashboard.php"><i class="fa fa-line-chart"></i>返回告警监控总览大屏</a>
</div>
</div>
</div>
</div>
<script>
// 相对路径接口,适配站点部署
const api = "./api/index.php";
const msgBox = document.getElementById("msg");
const resultBox = document.getElementById("result");
// Tab切换逻辑
document.querySelectorAll(".tab-item").forEach(item=>{
item.onclick = ()=>{
document.querySelectorAll(".tab-item").forEach(t=>t.classList.remove("active"));
item.classList.add("active");
const tabId = item.dataset.tab;
document.querySelectorAll(".tab-content").forEach(c=>c.classList.add("hide"));
document.getElementById("tab-"+tabId).classList.remove("hide");
msgBox.style.display = "none";
resultBox.innerText = "";
}
})
// 侧边菜单同步Tab切换
$(".menu-item").click(function(){
const tabId = $(this).data("tab");
$(".tab-item").removeClass("active");
$(`.tab-item[data-tab="${tabId}"]`).addClass("active");
$(".tab-content").addClass("hide");
$("#tab-"+tabId).removeClass("hide");
msgBox.style.display = "none";
resultBox.innerText = "";
})
// 通用提示弹窗
function showMsg(text, type="success"){
msgBox.className = type;
msgBox.innerText = text;
msgBox.style.display = "block";
}
// 1 修改密码接口请求
function updatePwd(){
const old = document.getElementById("old_pwd").value.trim();
const new1 = document.getElementById("new_pwd").value.trim();
const new2 = document.getElementById("re_pwd").value.trim();
if(!old || !new1 || !new2) return showMsg("所有密码输入项不能为空","error");
if(new1 !== new2) return showMsg("两次输入的新密码不一致,请核对","error");
const params = new URLSearchParams();
params.append("act","change_pwd");
params.append("old_pwd",old);
params.append("new_pwd",new1);
fetch(`${api}?${params.toString()}`)
.then(r=>r.json())
.then(json=>{
resultBox.innerText = JSON.stringify(json,null,2);
if(json.code===0){
showMsg("密码修改成功,即将跳转登录页重新验证");
setTimeout(()=>location.href="login.php",1800);
}else{
showMsg(json.msg,"error");
}
})
.catch(e=>{
showMsg("接口请求失败:"+e,"error");
})
}
// 2 保存外观配置(存入sys_configdashboard读取渲染)
function saveTheme(){
const params = new URLSearchParams();
params.append("act","save_theme");
params.append("title",document.getElementById("page_title").value);
params.append("color",document.getElementById("theme_color").value);
params.append("pagesize",document.getElementById("page_size").value);
params.append("footer",document.getElementById("footer_text").value);
fetch(`${api}?${params.toString()}`)
.then(r=>r.json())
.then(json=>{
resultBox.innerText = JSON.stringify(json,null,2);
if(json.code===0){
showMsg("外观配置保存成功,刷新监控大屏即可生效");
}else{
showMsg(json.msg,"error");
}
})
.catch(e=>{
showMsg("接口请求失败:"+e,"error");
})
}
// 3 保存侧边外链(存入sys_configdashboard侧边读取渲染)
function saveLink(){
const params = new URLSearchParams();
params.append("act","save_sidebar_link");
params.append("link_text",document.getElementById("sidebar_links").value);
fetch(`${api}?${params.toString()}`)
.then(r=>r.json())
.then(json=>{
resultBox.innerText = JSON.stringify(json,null,2);
if(json.code===0){
showMsg("侧边外链保存成功,刷新监控大屏侧边栏立即更新");
}else{
showMsg(json.msg,"error");
}
})
.catch(e=>{
showMsg("接口请求失败:"+e,"error");
})
}
</script>
</body>
</html>