Files
aler_dashboard_git/smtp_config.php
T
2026-07-09 16:31:30 +08:00

537 lines
24 KiB
PHP
Raw 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();
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");
require_once 'auth.php';
// 兼容低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; ?><?php echo $roleRealName; ?></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>