Files
aler_dashboard_git/alert_dashboard/www/smtp_config.php
T

534 lines
24 KiB
PHP

<?php
session_start();
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
header("Expires: Thu, 01 Jan 1970 00:00:00 GMT");
// 兼容低PHP版本 str_contains
if (!function_exists('str_contains')) {
function str_contains($haystack, $needle) {
return $needle === '' || strpos($haystack, $needle) !== false;
}
}
$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']);
$userRoleId = $_SESSION['role_id'];
// 全局配置库连接
$dbConfigHost = "10.150.117.190";
$dbConfigUser = "root";
$dbConfigPwd = "hp93000";
$dbConfigName = "alert_mail_stat";
$connConfig = mysqli_connect($dbConfigHost, $dbConfigUser, $dbConfigPwd, $dbConfigName);
if(!$connConfig){
die("配置库连接失败");
}
mysqli_set_charset($connConfig, "utf8mb4");
// 自动创建SMTP配置表,不存在则新建
mysqli_query($connConfig, "CREATE TABLE IF NOT EXISTS sys_smtp_config (
id INT PRIMARY KEY AUTO_INCREMENT,
smtp_host VARCHAR(200) NOT NULL DEFAULT '',
smtp_port INT NOT NULL DEFAULT 25,
smtp_ssl TINYINT NOT NULL DEFAULT 0,
smtp_user VARCHAR(200) NOT NULL DEFAULT '',
smtp_pass VARCHAR(200) NOT NULL DEFAULT '',
send_from VARCHAR(200) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
$checkRow = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT id FROM sys_smtp_config LIMIT 1"));
if (empty($checkRow)) {
mysqli_query($connConfig, "INSERT INTO sys_smtp_config (id) VALUES (1)");
}
// 自动创建工单推送通知表
mysqli_query($connConfig, "CREATE TABLE IF NOT EXISTS sys_workorder_notify (
id INT PRIMARY KEY AUTO_INCREMENT,
dingtalk_webhook VARCHAR(500) NOT NULL DEFAULT '',
dingtalk_secret VARCHAR(200) NOT NULL DEFAULT '',
wecom_webhook VARCHAR(500) NOT NULL DEFAULT '',
wecom_mention VARCHAR(300) NOT NULL DEFAULT '',
notify_open TINYINT NOT NULL DEFAULT 0,
update_time DATETIME NOT NULL DEFAULT NOW()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
$configSql = "SELECT k,v FROM sys_config";
$configRes = mysqli_query($connConfig, $configSql);
$sysConfig = [];
while ($row = mysqli_fetch_assoc($configRes)) {
$sysConfig[$row['k']] = $row['v'];
}
// 安全读取SMTP配置,杜绝mysqli警告
$smtpRow = [];
$sqlSmtp = "SELECT * FROM sys_smtp_config WHERE id=1";
if (!empty(trim($sqlSmtp))) {
$smtpQuery = mysqli_query($connConfig, $sqlSmtp);
if ($smtpQuery !== false && $smtpQuery instanceof mysqli_result) {
$smtpRow = mysqli_fetch_assoc($smtpQuery) ?: [];
}
}
$smtpConfig = $smtpRow ?? [];
// 安全读取推送通知配置
$notifyConfig = [];
$notifyQuery = mysqli_query($connConfig, "SELECT * FROM sys_workorder_notify LIMIT 1");
if ($notifyQuery instanceof mysqli_result) {
$notifyConfig = mysqli_fetch_assoc($notifyQuery) ?: [];
}
$pageTitle = htmlspecialchars($sysConfig['page_subtitle'] ?? "工单消息通知配置");
$currentLang = $sysConfig['lang'] ?? "zh";
$sidebarRawLinks = $sysConfig['sidebar_links'] ?? "";
mysqli_close($connConfig);
// 多语言词典(菜单文字全部替换:SMTP配置 → 工单消息通知配置)
$langMap = [
'zh' => [
'html_lang' => 'zh-CN',
'page_subtitle' => '工单消息通知配置',
'monitor_panel' => '监控面板',
'alert_overview' => '告警总览',
'quick_link' => '快捷外链',
'system_manage' => '系统管理',
'notify_config' => '工单消息通知配置',
'current_user' => '当前用户:',
'sys_time' => '系统时间:',
'refresh_all' => '刷新页面',
'export_csv' => '导出CSV',
'logout' => '退出登录',
'lang_text' => '语言:',
'work_order_mgr' => '工单系统',
'save_all' => '保存全部通知配置',
'card_title' => '工单消息推送 & 发件邮箱统一配置',
'group_mail' => '邮箱SMTP发件设置',
'smtp_host' => 'SMTP服务器',
'smtp_port' => '端口',
'smtp_ssl' => '启用SSL/TLS加密',
'smtp_account' => '登录账号',
'smtp_pwd' => '授权密码',
'smtp_from' => '发件人邮箱',
'group_push' => '工单变更推送配置',
'notify_switch' => '开启工单变更自动推送',
'dingtalk_webhook' => '钉钉Webhook地址',
'dingtalk_secret' => '钉钉安全密钥(可选)',
'wecom_webhook' => '企业微信Webhook地址',
'wecom_mention' => '@提醒人员(多个逗号分隔,all=全员)',
'placeholder_webhook' => '输入完整Webhook链接',
'placeholder_secret' => '无安全校验则留空',
'placeholder_mention' => '填写手机号,all代表所有人',
'save_success' => '配置保存成功'
],
'en' => [
'html_lang' => 'en',
'page_subtitle' => 'Work Order Notification Config',
'monitor_panel' => 'Monitor Panel',
'alert_overview' => 'Alert Overview',
'quick_link' => 'Quick Links',
'system_manage' => 'System Manage',
'notify_config' => 'Work Order Notification Config',
'current_user' => 'User: ',
'sys_time' => 'System Time: ',
'refresh_all' => 'Refresh',
'export_csv' => 'Export CSV',
'logout' => 'Logout',
'lang_text' => 'Lang: ',
'work_order_mgr' => 'Work Order System',
'save_all' => 'Save All Notification Config',
'card_title' => 'Work Order Push & Mail Sender Config',
'group_mail' => 'SMTP Mail Sender',
'smtp_host' => 'SMTP Host',
'smtp_port' => 'Port',
'smtp_ssl' => 'Enable SSL/TLS',
'smtp_account' => 'Account',
'smtp_pwd' => 'Auth Password',
'smtp_from' => 'Sender Email',
'group_push' => 'Work Order Push Setting',
'notify_switch' => 'Auto push on order change',
'dingtalk_webhook' => 'DingTalk Webhook',
'dingtalk_secret' => 'DingTalk Secret (Optional)',
'wecom_webhook' => 'WeCom Webhook',
'wecom_mention' => 'Mention user (split by comma, all=everyone)',
'placeholder_webhook' => 'Full webhook url',
'placeholder_secret' => 'Leave empty if no secret',
'placeholder_mention' => 'Mobile number or all',
'save_success' => 'Config saved successfully'
]
];
$t = $langMap[$currentLang];
// 解析外链菜单
$sidebarLinkList = [];
if (!empty($sidebarRawLinks)) {
$lines = explode("\n", $sidebarRawLinks);
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) continue;
$item = explode("|", $line, 2);
if (count($item) === 2) {
$sidebarLinkList[] = ["name" => trim($item[0]), "url" => trim($item[1])];
}
}
}
// 统一保存表单提交逻辑(SMTP+推送一次保存)
if ($_POST['act'] === "save_all") {
// 更新SMTP邮箱配置
$host = trim($_POST['smtp_host'] ?? '');
$port = intval($_POST['smtp_port'] ?? 25);
$ssl = intval($_POST['smtp_ssl'] ?? 0);
$user = trim($_POST['smtp_user'] ?? '');
$pwd = trim($_POST['smtp_pass'] ?? '');
$from = trim($_POST['smtp_from'] ?? '');
mysqli_query($connConfig, "UPDATE sys_smtp_config SET smtp_host='$host',smtp_port=$port,smtp_ssl=$ssl,smtp_user='$user',smtp_pass='$pwd',send_from='$from' WHERE id=1");
// 更新工单推送配置
$ding_webhook = trim($_POST['dingtalk_webhook'] ?? '');
$ding_secret = trim($_POST['dingtalk_secret'] ?? '');
$wecom_webhook = trim($_POST['wecom_webhook'] ?? '');
$wecom_mention = trim($_POST['wecom_mention'] ?? '');
$notify_open = intval($_POST['notify_open'] ?? 0);
$existNotify = mysqli_fetch_assoc(mysqli_query($connConfig, "SELECT id FROM sys_workorder_notify LIMIT 1"));
if ($existNotify) {
mysqli_query($connConfig, "UPDATE sys_workorder_notify SET dingtalk_webhook='$ding_webhook', dingtalk_secret='$ding_secret', wecom_webhook='$wecom_webhook', wecom_mention='$wecom_mention', notify_open=$notify_open, update_time=NOW() WHERE id = {$existNotify['id']}");
} else {
mysqli_query($connConfig, "INSERT INTO sys_workorder_notify (dingtalk_webhook,dingtalk_secret,wecom_webhook,wecom_mention,notify_open) VALUES ('$ding_webhook','$ding_secret','$wecom_webhook','$wecom_mention',$notify_open)");
}
echo "<script>alert('".$t['save_success']."');location.href='smtp_config.php';</script>";
exit;
}
?>
<!DOCTYPE html>
<html lang="<?php echo $t['html_lang']; ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $pageTitle; ?></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:#f8fafc; font-family:"Inter","PingFang SC","Microsoft YaHei",system-ui,sans-serif; color:#1e293b; line-height:1.55; display:flex; flex-direction:column; height:100vh; overflow:hidden; }
.wrap-main{display:flex;flex:1;overflow:hidden;}
/* 侧边栏 深蓝导航 */
.sidebar{ width:240px; background:#152c5b; color:#e2e8f0; flex-shrink:0; overflow-y:auto; }
.sidebar-brand{ padding:30px 24px; border-bottom:1px solid rgba(255,255,255,0.06); }
.sidebar-brand-en{ font-size:20px; font-weight:600; letter-spacing:0.5px; color:#ffffff; }
.sidebar-brand-cn{ font-size:12px; color:#a5b4fc; margin-top:6px; opacity:0.9; }
.sidebar-menu{padding:20px 0;}
.menu-title{ padding:10px 24px 6px; font-size:11px; color:#94a3b8; letter-spacing:0.5px; text-transform:uppercase; }
.menu-item{ display:flex; align-items:center; gap:12px; padding:13px 24px; cursor:pointer; font-size:14px; transition:background 0.2s ease; color:#cbd5e1; }
.menu-item i{ font-size:16px; width:20px; text-align:center; }
.menu-item.active{ background:rgba(59,130,246,0.15); color:#ffffff; border-left:4px solid #3b82f6; }
.menu-item:hover:not(.active){ background:rgba(255,255,255,0.06); color:#ffffff; }
/* 顶部Header */
.main-content{ flex:1; overflow-y:auto; display:flex; flex-direction:column; }
.header{ background:#ffffff; border-bottom:1px solid #e2e8f0; padding:20px 40px; display:flex; justify-content:space-between; align-items:center; flex-shrink:0; }
.header-left{display:flex;align-items:center;gap:14px;}
.header-brand-en{ font-size:24px; font-weight:700; color:#152c5b; letter-spacing:1px; }
.header-brand-cn{font-size:13px;color:#64748b;}
.header-right{display:flex;align-items:center;gap:20px;font-size:14px;}
.user-info,.time-info,.lang-box{color:#475569;display:flex;align-items:center;gap:6px;}
.lang-box select{padding:4px 8px;border:1px solid #cbd5e1;border-radius:6px;}
/* 通用按钮基础 */
.btn-base{ border:none; padding:10px 24px; border-radius:999px; cursor:pointer; font-size:14px; font-weight:500; display:flex; align-items:center; gap:8px; transition:all 0.2s ease; }
.btn-outline{
background:#fff;
color:#152c5b;
border:1px solid #cbd5e1;
}
.btn-outline:hover{
background:#f7f8fc;
}
.container{padding:36px 40px;flex:1;}
/* ====================== 四、升级卡片样式 ====================== */
.base-card{
background:#fff;
border-radius:18px;
padding:36px;
border:1px solid #e5e7eb;
box-shadow:
0 1px 3px rgba(0,0,0,.04),
0 8px 24px rgba(15,23,42,.04);
max-width:900px;
}
.title-wrap{ display:flex; align-items:center; gap:12px; font-size:17px; font-weight:600; color:#152c5b; margin-bottom:26px; padding-bottom:16px; border-bottom:1px solid #f1f5f9; }
.title-wrap i{font-size:18px;color:#2563eb;}
.group-title{ font-size:15px; font-weight:600; color:#334155; margin:32px 0 18px; padding-bottom:10px; border-bottom:1px solid #f1f5f9; }
.group-title:first-of-type{margin-top:0;}
/* ====================== 一、企业级输入框统一样式 ====================== */
.form-row{
margin-bottom:22px;
}
.form-row label{
display:block;
margin-bottom:8px;
font-size:13px;
font-weight:600;
color:#334155;
letter-spacing:.2px;
}
/* 全部文本输入框统一短款360px宽度 */
.form-row input.short-width{
width:360px;
height:46px;
padding:0 16px;
border:1px solid #d6dce5;
border-radius:10px;
background:#ffffff;
font-size:14px;
color:#1e293b;
transition:all .2s ease;
}
.form-row input[type="text"]:hover,
.form-row input[type="password"]:hover,
.form-row input[type="number"]:hover{
border-color:#94a3b8;
}
.form-row input[type="text"]:focus,
.form-row input[type="password"]:focus,
.form-row input[type="number"]:focus{
outline:none;
border-color:#2563eb;
box-shadow:0 0 0 3px rgba(37,99,235,.12);
background:#fff;
}
.form-row input::placeholder{
color:#94a3b8;
font-size:13px;
}
.form-row input:disabled{
background:#f8fafc;
color:#94a3b8;
cursor:not-allowed;
}
/* 数字框去除上下箭头 */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button{
-webkit-appearance:none;
margin:0;
}
input[type="number"]{
-moz-appearance:textfield;
}
/* 勾选框容器,通栏100%宽度 */
.checkbox-input-box{
display:flex;
align-items:center;
gap:10px;
width:100%;
height:46px;
padding:0 16px;
border:1px solid #d6dce5;
border-radius:10px;
background:#fff;
transition:all .2s ease;
}
.checkbox-input-box:hover{
border-color:#94a3b8;
}
.checkbox-input-box input[type="checkbox"]{
width:18px;
height:18px;
accent-color:#2563eb;
cursor:pointer;
}
.checkbox-input-box label{
margin:0;
cursor:pointer;
font-size:14px;
color:#334155;
}
/* ====================== 三、主保存渐变按钮升级 ====================== */
.btn-primary{
background:linear-gradient(135deg,#1d4ed8,#2563eb);
color:#fff;
min-width:220px;
justify-content:center;
box-shadow:0 6px 18px rgba(37,99,235,.25);
}
.btn-primary:hover{
transform:translateY(-1px);
box-shadow:0 10px 24px rgba(37,99,235,.32);
background:linear-gradient(135deg,#1d4ed8,#2563eb);
}
.form-submit{margin-top: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"><?php echo $t['page_subtitle']; ?></div>
</div>
<div class="sidebar-menu">
<div class="menu-title"><?php echo $t['monitor_panel']; ?></div>
<!-- 1.告警总览 -->
<div class="menu-item" onclick="location.href='dashboard.php'">
<i class="fa fa-line-chart"></i><span><?php echo $t['alert_overview']; ?></span>
</div>
<!-- 2.工单系统 -->
<div class="menu-item" onclick="location.href='work_order.php'">
<i class="fa fa-ticket"></i><span><?php echo $t['work_order_mgr']; ?></span>
</div>
<!-- 快捷外链 -->
<?php if (!empty($sidebarLinkList)): ?>
<div class="menu-title"><?php echo $t['quick_link']; ?></div>
<?php foreach ($sidebarLinkList as $link): ?>
<div class="menu-item" onclick="window.open('<?php echo htmlspecialchars($link['url']); ?>','_blank')">
<i class="fa fa-external-link"></i><span><?php echo htmlspecialchars($link['name']); ?></span>
</div>
<?php endforeach; ?>
<?php endif; ?>
<!-- 系统管理分组,工单通知配置放这里 -->
<div class="menu-title"><?php echo $t['system_manage']; ?></div>
<div class="menu-item active">
<i class="fa fa-bell"></i><span><?php echo $t['notify_config']; ?></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"><?php echo $t['page_subtitle']; ?></div>
</div>
</div>
<div class="header-right">
<span class="user-info"><i class="fa fa-user-circle"></i><?php echo $t['current_user']; ?><?php echo $userName; ?></span>
<span class="time-info"><i class="fa fa-clock-o"></i><span id="nowTime">--</span></span>
<div class="lang-box">
<span><?php echo $t['lang_text']; ?></span>
<select id="langSwitch">
<option value="zh" <?php echo $currentLang==='zh'?'selected':''; ?>>中文</option>
<option value="en" <?php echo $currentLang==='en'?'selected':''; ?>>EN</option>
</select>
</div>
<button class="btn-base btn-outline" onclick="location.reload()"><i class="fa fa-refresh"></i><?php echo $t['refresh_all']; ?></button>
<button class="btn-base btn-primary" onclick="location.href='logout.php'"><i class="fa fa-sign-out"></i><?php echo $t['logout']; ?></button>
</div>
</div>
<div class="container">
<!-- 配置卡片 -->
<div class="base-card">
<div class="title-wrap"><i class="fa fa-bell"></i><?php echo $t['card_title']; ?></div>
<form method="post">
<input type="hidden" name="act" value="save_all">
<!-- 邮箱SMTP配置组 -->
<div class="group-title"><?php echo $t['group_mail']; ?></div>
<div class="form-row">
<label><?php echo $t['smtp_host']; ?></label>
<input class="short-width" name="smtp_host" value="<?php echo htmlspecialchars($smtpConfig['smtp_host'] ?? ''); ?>" placeholder="smtp.company.com">
</div>
<div class="form-row">
<label><?php echo $t['smtp_port']; ?></label>
<input class="short-width" name="smtp_port" type="number" value="<?php echo intval($smtpConfig['smtp_port'] ?? 25); ?>" min="1" max="65535">
</div>
<!-- SSL勾选框,通栏输入框容器 -->
<div class="form-row">
<label><?php echo $t['smtp_ssl']; ?></label>
<div class="checkbox-input-box">
<input type="checkbox" name="smtp_ssl" id="smtp_ssl" value="1" <?php echo ($smtpConfig['smtp_ssl'] ?? 0) == 1 ? 'checked' : ''; ?>>
<label for="smtp_ssl"><?php echo $t['smtp_ssl']; ?></label>
</div>
</div>
<div class="form-row">
<label><?php echo $t['smtp_account']; ?></label>
<input class="short-width" name="smtp_user" value="<?php echo htmlspecialchars($smtpConfig['smtp_user'] ?? ''); ?>">
</div>
<div class="form-row">
<label><?php echo $t['smtp_pwd']; ?></label>
<input class="short-width" name="smtp_pass" type="password" value="<?php echo htmlspecialchars($smtpConfig['smtp_pass'] ?? ''); ?>">
</div>
<div class="form-row">
<label><?php echo $t['smtp_from']; ?></label>
<input class="short-width" name="smtp_from" value="<?php echo htmlspecialchars($smtpConfig['send_from'] ?? ''); ?>">
</div>
<!-- 工单推送配置组 -->
<div class="group-title"><?php echo $t['group_push']; ?></div>
<!-- 推送总开关,通栏输入框容器 -->
<div class="form-row">
<label><?php echo $t['notify_switch']; ?></label>
<div class="checkbox-input-box">
<input type="checkbox" name="notify_open" id="notify_open" value="1" <?php echo ($notifyConfig['notify_open'] ?? 0) == 1 ? 'checked' : ''; ?>>
<label for="notify_open"><?php echo $t['notify_switch']; ?></label>
</div>
</div>
<div class="form-row">
<label><?php echo $t['dingtalk_webhook']; ?></label>
<input class="short-width" name="dingtalk_webhook" placeholder="<?php echo $t['placeholder_webhook']; ?>" value="<?php echo htmlspecialchars($notifyConfig['dingtalk_webhook'] ?? ''); ?>">
</div>
<div class="form-row">
<label><?php echo $t['dingtalk_secret']; ?></label>
<input class="short-width" name="dingtalk_secret" placeholder="<?php echo $t['placeholder_secret']; ?>" value="<?php echo htmlspecialchars($notifyConfig['dingtalk_secret'] ?? ''); ?>">
</div>
<div class="form-row">
<label><?php echo $t['wecom_webhook']; ?></label>
<input class="short-width" name="wecom_webhook" placeholder="<?php echo $t['placeholder_webhook']; ?>" value="<?php echo htmlspecialchars($notifyConfig['wecom_webhook'] ?? ''); ?>">
</div>
<div class="form-row">
<label><?php echo $t['wecom_mention']; ?></label>
<input class="short-width" name="wecom_mention" placeholder="<?php echo $t['placeholder_mention']; ?>" value="<?php echo htmlspecialchars($notifyConfig['wecom_mention'] ?? ''); ?>">
</div>
<!-- 统一保存按钮 -->
<div class="form-submit">
<button class="btn-base btn-primary" type="submit"><i class="fa fa-save"></i><?php echo $t['save_all']; ?></button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
// 实时系统时间
function updateNowTime() {
const d = new Date();
const Y = d.getFullYear();
const M = String(d.getMonth()+1).padStart(2,'0');
const D = String(d.getDate()).padStart(2,'0');
const h = String(d.getHours()).padStart(2,'0');
const m = String(d.getMinutes()).padStart(2,'0');
const s = String(d.getSeconds()).padStart(2,'0');
$("#nowTime").text(`${Y}-${M}-${D} ${h}:${m}:${s}`);
}
setInterval(updateNowTime,1000);
updateNowTime();
// 语言切换
$("#langSwitch").change(function(){
const lang = $(this).val();
$.post("smtp_config.php", {action:"save_lang",lang:lang}, ()=>location.reload());
})
</script>
</body>
</html>