From 0bb2eb4c3647f18ada49fc94286459f409a79a04 Mon Sep 17 00:00:00 2001 From: admin <605696661@qq.com> Date: Thu, 9 Jul 2026 16:31:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin.php | 619 ++++++ admin.php.1 | 203 ++ admin.php.2 | 605 ++++++ admin.php.3 | 625 ++++++ alert_index.php | 375 ++++ alert_index1.php | 340 +++ alert_list.php | 369 ++++ alert_list.php.1 | 650 ++++++ alert_list.php.bak | 374 ++++ alert_subscribe.php | 132 ++ api/__pycache__/docker.cpython-36.pyc | Bin 0 -> 3102 bytes api/api_alert_list.php | 198 ++ api/api_alert_list.php.bak | 143 ++ api/config_save.php | 40 + api/debug.php | 3 + api/dev_panel.php | 205 ++ api/dev_panel.php.2 | 411 ++++ api/df.php | 60 + api/df.php.bak | 51 + api/docker.php | 165 ++ api/docker_api.py | 752 +++++++ api/docker_api.py.bak | 100 + api/docker_api.py1 | 669 ++++++ api/docker_api.sh | 9 + api/index.php | 436 ++++ api/index.php0.09版本 | 45 + api/index.php0.1版本 | 49 + api/index.php0.2版本 | 49 + api/index.php0.3版本 | 106 + api/index.php0.4版本 | 140 ++ api/index.php0.5版本 | 139 ++ api/index.php0.6版本 | 330 +++ api/index.php最早版 | 46 + api/login.php | 12 + api/oldapi.php | 126 ++ api/panel.php | 440 ++++ api/panel.php.2 | 411 ++++ api/subscribe_api.php | 89 + api/subscribe_api.php.bak | 130 ++ api/system_config.json | 14 + api/user_info.json | 6 + api/user_pass.php | 35 + api/webhook.php | 64 + api/work_order_api.php | 528 +++++ api/work_order_api.php.1 | 117 ++ api/work_order_api.php.2.0 | 144 ++ api/work_order_api.php.3.0 | 146 ++ api/work_order_api.php.4.0 | 247 +++ api/work_order_api.php.5.0 | 267 +++ api/work_order_api.php.6.0 | 378 ++++ api/work_order_api.php.7.0 | 407 ++++ api/work_order_api.php.8.0 | 427 ++++ api/work_order_api.php.9.0 | 515 +++++ api/work_order_api.php.bak | 104 + auth.php | 163 ++ dashbaord.en-zh.php | 1094 ++++++++++ dashbaord.php.local.9 | 954 +++++++++ dashboard.html | 707 +++++++ dashboard.html.6-30 | 711 +++++++ dashboard.html.bak | 97 + dashboard.html.bak2 | 663 ++++++ dashboard.php | 1193 +++++++++++ dashboard.php.1.0.3 | 1175 +++++++++++ dashboard.php.1.0.4 | 1193 +++++++++++ dashboard.php.2 | 601 ++++++ dashboard.php.2.0版本 | 1267 +++++++++++ dashboard.php.3 | 899 ++++++++ dashboard.php.4 | 1066 ++++++++++ dashboard.php.5 | 916 ++++++++ dashboard.php.6 | 970 +++++++++ dashboard.php.7 | 1087 ++++++++++ dashboard.php.8 | 1126 ++++++++++ dashboard.php.9 | 1161 ++++++++++ dashboard.php.bak | 365 ++++ dashboard2.0.html | 638 ++++++ dashboard3.0.html | 644 ++++++ dashboard4.0.html | 776 +++++++ dashboard5.0.html | 749 +++++++ disk.html | 246 +++ docker_mgr.php | 1469 +++++++++++++ docker_mgr.php.bak | 1483 +++++++++++++ gen.php | 6 + gen_pwd.php | 3 + login.html | 163 ++ login.php | 275 +++ login.php.1.0 | 278 +++ login.php.bak | 259 +++ login.php1 | 116 + login.php2 | 116 + logintiaoshi.php | 139 ++ logout.php | 5 + panel.php.1.0 | 206 ++ php-fpm/www.conf | 11 + python_api依赖.txt | 20 + role_manage.php | 218 ++ smtp_config.php | 536 +++++ smtp_config.php.1.0 | 444 ++++ smtp_config.php.2.0 | 452 ++++ smtp_config.php.3.0 | 545 +++++ smtp_config.php.bak | 192 ++ static/css/font-awesome.min.css | 4 + static/fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes static/fonts/fontawesome-webfont.svg | 2671 ++++++++++++++++++++++++ static/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes static/fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes static/fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes static/js/chart.js | 14 + static/js/echarts.min.js | 45 + static/js/jquery.min.js | 2 + system_manage.php | 414 ++++ system_manage.php.1.0 | 374 ++++ system_manage.php.bak | 378 ++++ user_manage.php | 225 ++ work_order.php | 1005 +++++++++ work_order.php.1.0.0 | 917 ++++++++ work_order.php.1.0.0优化 | 917 ++++++++ work_order.php.1.0.1 | 916 ++++++++ work_order.php.1.0.1开发中 | 866 ++++++++ work_order.php.1.0.2 | 952 +++++++++ work_order.php.1.0.3 | 955 +++++++++ work_order.php.2.0 | 894 ++++++++ work_order.php.3.0 | 957 +++++++++ work_order.php.4.0 | 894 ++++++++ work_order.php.5.0 | 823 ++++++++ work_order.php.6.0 | 849 ++++++++ work_order.php.7.0 | 400 ++++ work_order.php.8.0 | 936 +++++++++ work_order.php.9.0 | 926 ++++++++ work_order.php.bak | 387 ++++ 优化版.php | 1114 ++++++++++ 完成版.php | 954 +++++++++ 速度优化版.php | 991 +++++++++ 132 files changed, 61222 insertions(+) create mode 100644 admin.php create mode 100644 admin.php.1 create mode 100644 admin.php.2 create mode 100644 admin.php.3 create mode 100644 alert_index.php create mode 100644 alert_index1.php create mode 100644 alert_list.php create mode 100644 alert_list.php.1 create mode 100644 alert_list.php.bak create mode 100644 alert_subscribe.php create mode 100644 api/__pycache__/docker.cpython-36.pyc create mode 100644 api/api_alert_list.php create mode 100644 api/api_alert_list.php.bak create mode 100644 api/config_save.php create mode 100644 api/debug.php create mode 100644 api/dev_panel.php create mode 100644 api/dev_panel.php.2 create mode 100644 api/df.php create mode 100644 api/df.php.bak create mode 100644 api/docker.php create mode 100644 api/docker_api.py create mode 100644 api/docker_api.py.bak create mode 100644 api/docker_api.py1 create mode 100644 api/docker_api.sh create mode 100644 api/index.php create mode 100644 api/index.php0.09版本 create mode 100644 api/index.php0.1版本 create mode 100644 api/index.php0.2版本 create mode 100644 api/index.php0.3版本 create mode 100644 api/index.php0.4版本 create mode 100644 api/index.php0.5版本 create mode 100644 api/index.php0.6版本 create mode 100644 api/index.php最早版 create mode 100644 api/login.php create mode 100644 api/oldapi.php create mode 100644 api/panel.php create mode 100644 api/panel.php.2 create mode 100644 api/subscribe_api.php create mode 100644 api/subscribe_api.php.bak create mode 100644 api/system_config.json create mode 100644 api/user_info.json create mode 100644 api/user_pass.php create mode 100644 api/webhook.php create mode 100644 api/work_order_api.php create mode 100644 api/work_order_api.php.1 create mode 100644 api/work_order_api.php.2.0 create mode 100644 api/work_order_api.php.3.0 create mode 100644 api/work_order_api.php.4.0 create mode 100644 api/work_order_api.php.5.0 create mode 100644 api/work_order_api.php.6.0 create mode 100644 api/work_order_api.php.7.0 create mode 100644 api/work_order_api.php.8.0 create mode 100644 api/work_order_api.php.9.0 create mode 100644 api/work_order_api.php.bak create mode 100644 auth.php create mode 100644 dashbaord.en-zh.php create mode 100644 dashbaord.php.local.9 create mode 100644 dashboard.html create mode 100644 dashboard.html.6-30 create mode 100644 dashboard.html.bak create mode 100644 dashboard.html.bak2 create mode 100644 dashboard.php create mode 100644 dashboard.php.1.0.3 create mode 100644 dashboard.php.1.0.4 create mode 100644 dashboard.php.2 create mode 100644 dashboard.php.2.0版本 create mode 100644 dashboard.php.3 create mode 100644 dashboard.php.4 create mode 100644 dashboard.php.5 create mode 100644 dashboard.php.6 create mode 100644 dashboard.php.7 create mode 100644 dashboard.php.8 create mode 100644 dashboard.php.9 create mode 100644 dashboard.php.bak create mode 100644 dashboard2.0.html create mode 100644 dashboard3.0.html create mode 100644 dashboard4.0.html create mode 100644 dashboard5.0.html create mode 100644 disk.html create mode 100644 docker_mgr.php create mode 100644 docker_mgr.php.bak create mode 100644 gen.php create mode 100644 gen_pwd.php create mode 100644 login.html create mode 100644 login.php create mode 100644 login.php.1.0 create mode 100644 login.php.bak create mode 100644 login.php1 create mode 100644 login.php2 create mode 100644 logintiaoshi.php create mode 100644 logout.php create mode 100644 panel.php.1.0 create mode 100644 php-fpm/www.conf create mode 100644 python_api依赖.txt create mode 100644 role_manage.php create mode 100644 smtp_config.php create mode 100644 smtp_config.php.1.0 create mode 100644 smtp_config.php.2.0 create mode 100644 smtp_config.php.3.0 create mode 100644 smtp_config.php.bak create mode 100644 static/css/font-awesome.min.css create mode 100644 static/fonts/fontawesome-webfont.eot create mode 100644 static/fonts/fontawesome-webfont.svg create mode 100644 static/fonts/fontawesome-webfont.ttf create mode 100644 static/fonts/fontawesome-webfont.woff create mode 100644 static/fonts/fontawesome-webfont.woff2 create mode 100644 static/js/chart.js create mode 100644 static/js/echarts.min.js create mode 100644 static/js/jquery.min.js create mode 100644 system_manage.php create mode 100644 system_manage.php.1.0 create mode 100644 system_manage.php.bak create mode 100644 user_manage.php create mode 100644 work_order.php create mode 100644 work_order.php.1.0.0 create mode 100644 work_order.php.1.0.0优化 create mode 100644 work_order.php.1.0.1 create mode 100644 work_order.php.1.0.1开发中 create mode 100644 work_order.php.1.0.2 create mode 100644 work_order.php.1.0.3 create mode 100644 work_order.php.2.0 create mode 100644 work_order.php.3.0 create mode 100644 work_order.php.4.0 create mode 100644 work_order.php.5.0 create mode 100644 work_order.php.6.0 create mode 100644 work_order.php.7.0 create mode 100644 work_order.php.8.0 create mode 100644 work_order.php.9.0 create mode 100644 work_order.php.bak create mode 100644 优化版.php create mode 100644 完成版.php create mode 100644 速度优化版.php diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..d63b483 --- /dev/null +++ b/admin.php @@ -0,0 +1,619 @@ + $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); +mysqli_set_charset($conn, "utf8mb4"); +$res = mysqli_query($conn, "SELECT k,v FROM sys_config"); +$config = []; +while ($row = mysqli_fetch_assoc($res)) { + $config[$row['k']] = $row['v']; +} +mysqli_close($conn); + +// 赋值表单默认值 +$pageTitle = $config['page_title'] ?? "告警监控系统"; +$themeColor = $config['theme_color'] ?? "#409eff"; +$pageSize = $config['page_size'] ?? "20"; +$footerText = $config['footer_text'] ?? ""; +$sidebarLinks = $config['sidebar_links'] ?? ""; +?> + + +
+ + +| 数据加载中... |
| 数据加载中... |
| 数据加载中... |
| Loading... |
|
+
+ Loading...
+ |
+
关联告警ID:$relateId
+标题:$title
+$content"; +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.1 b/api/work_order_api.php.1 new file mode 100644 index 0000000..62697b4 --- /dev/null +++ b/api/work_order_api.php.1 @@ -0,0 +1,117 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 数据库本地连接,避免远程拦截 +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() + ]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +// 获取当前用户是否管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($conn, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、新建工单(修复第50行引用报错) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $status = 1; // 单独定义变量,不能直接写1传入bind_param + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,status,create_time,update_time) VALUES (?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn, $sql); + // 全部使用变量传参,禁止直接写数字/字符串 + mysqli_stmt_bind_param($stmt, 'ssssi', $title, $content, $loginUid, $assign, $status); + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '工单提交成功']); + } else { + echo json_encode(['code' => 500, 'msg' => '提交失败:' . mysqli_error($conn)]); + } + exit; +} + +// 2、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + // 普通用户权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 3、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 无效操作 +echo json_encode(['code' => 400, 'msg' => '无效操作']); +mysqli_close($conn); +exit; +?> diff --git a/api/work_order_api.php.2.0 b/api/work_order_api.php.2.0 new file mode 100644 index 0000000..c80f790 --- /dev/null +++ b/api/work_order_api.php.2.0 @@ -0,0 +1,144 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 数据库本地连接 +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() + ]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +// 获取当前用户是否管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($conn, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、新建工单 +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,status,create_time,update_time) VALUES (?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ssssi', $title, $content, $loginUid, $assign, $status); + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '工单提交成功']); + } else { + echo json_encode(['code' => 500, 'msg' => '提交失败:' . mysqli_error($conn)]); + } + exit; +} + +// 2、编辑工单(新增,支持修改标题、内容备注、分配人) +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'sssi', $title, $content, $assign, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单修改备注保存成功']); + exit; +} + +// 3、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 4、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +echo json_encode(['code' => 400, 'msg' => '无效操作']); +mysqli_close($conn); +exit; +?> diff --git a/api/work_order_api.php.3.0 b/api/work_order_api.php.3.0 new file mode 100644 index 0000000..9230ec7 --- /dev/null +++ b/api/work_order_api.php.3.0 @@ -0,0 +1,146 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单数据库本地连接 +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() + ]); + exit; +} +mysqli_set_charset($conn, 'utf8mb4'); + +// 判断管理员 +$isAdmin = 0; +$roleSql = "SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($conn, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) $isAdmin = intval($roleRow['is_admin']); + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、新建工单(新增relate_alert_id字段) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,status,create_time,update_time) VALUES (?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $loginUid, $assign, $relateAlertId, $status); + $ok = mysqli_stmt_execute($stmt); + if ($ok) { + echo json_encode(['code' => 0, 'msg' => '工单提交成功']); + } else { + echo json_encode(['code' => 500, 'msg' => '提交失败:' . mysqli_error($conn)]); + } + exit; +} + +// 2、编辑工单(不修改关联告警ID) +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'sssi', $title, $content, $assign, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单修改备注保存成功']); + exit; +} + +// 3、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($conn, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 4、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 无匹配操作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($conn); +exit; +?> diff --git a/api/work_order_api.php.4.0 b/api/work_order_api.php.4.0 new file mode 100644 index 0000000..cc5d80f --- /dev/null +++ b/api/work_order_api.php.4.0 @@ -0,0 +1,247 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = 'localhost'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtRole)); +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、获取当前活跃告警(解决前端下拉空白) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(新增通知用户、通知渠道、关联告警) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + // 发送通知 + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发']); + exit; +} + +// 3、编辑工单(更新通知、不修改关联告警) +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单 +if ($action === "assign_order") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 通知发送统一函数 +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 获取SMTP配置 + $smtpRow = mysqli_fetch_assoc(mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1")); + $smtpConfig = $smtpRow ?? []; + + // 获取工单详情 + $orderRow = mysqli_fetch_assoc(mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId")); + $title = $orderRow['title']; + $content = $orderRow['content']; + + // 遍历渠道发送 + foreach ($channelArr as $ch) { + switch ($ch) { + case "mail": + sendMailNotify($smtpConfig, $userArr, $title, $content); + break; + case "dingtalk": + // 此处填入钉钉机器人发送逻辑,按需补充 + break; + case "wecom": + // 此处填入企业微信机器人发送逻辑,按需补充 + break; + } + } +} + +// 邮件发送函数 +function sendMailNotify($smtp, $uidList, $title, $content) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_user']) || empty($smtp['smtp_pass'])) return; + // 查询用户邮箱 + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", $emailList); + $subject = "【工单通知】" . $title; + $body = "
".$content.""; + // PHPMailer 发送逻辑,环境需安装phpmailer + /* + require_once 'PHPMailer.php'; + require_once 'SMTP.php'; + $mail = new PHPMailer\PHPMailer\PHPMailer(true); + try { + $mail->isSMTP(); + $mail->Host = $smtp['smtp_host']; + $mail->SMTPAuth = true; + $mail->Username = $smtp['smtp_user']; + $mail->Password = $smtp['smtp_pass']; + $mail->SMTPSecure = $smtp['smtp_ssl'] ? PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS : ''; + $mail->Port = $smtp['smtp_port']; + $mail->setFrom($smtp['send_from'], $smtp['send_from']); + $mail->addAddress($to); + $mail->isHTML(true); + $mail->Subject = $subject; + $mail->Body = $body; + $mail->send(); + } catch (Exception $e) {} + */ +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.5.0 b/api/work_order_api.php.5.0 new file mode 100644 index 0000000..c1f6af8 --- /dev/null +++ b/api/work_order_api.php.5.0 @@ -0,0 +1,267 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + $status = 1; + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发']); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "
关联告警ID:$relateId
+标题:$title
+$content"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.6.0 b/api/work_order_api.php.6.0 new file mode 100644 index 0000000..7502531 --- /dev/null +++ b/api/work_order_api.php.6.0 @@ -0,0 +1,378 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 新增1:根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 新增2:自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理恢复告警(完全独立,无需index.php) +if ($action === "sync_prom_alerts") { + header("Content-Type: application/json;charset=utf-8"); + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新,无需额外调用 + $syncWorkUrl = apiOrder . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "
关联告警ID:$relateId
+标题:$title
+$content"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.7.0 b/api/work_order_api.php.7.0 new file mode 100644 index 0000000..6a210d6 --- /dev/null +++ b/api/work_order_api.php.7.0 @@ -0,0 +1,407 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 新增1:根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 新增2:自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssssi', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'sssssi', $title, $content, $assign, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理恢复告警(完全独立,无需index.php) +if ($action === "sync_prom_alerts") { + header("Content-Type: application/json;charset=utf-8"); + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新,无需额外调用 + $syncWorkUrl = apiOrder . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 定时同步:告警恢复自动完工单 +if($_POST['action'] === "sync_alert_auto_close"){ + // 1、拉取仪表盘实时未恢复告警 + $alertApi = "./index.php?act=active_firing"; + $raw = file_get_contents($alertApi); + $activeList = json_decode($raw, true) ?: []; + $activeKeys = []; + foreach($activeList as $item){ + $activeKeys[] = $item['alert_name'] . "|" . $item['instance']; + } + // 2、查询所有未完成、绑定告警的工单 + $sql = "SELECT id, relate_alert_id FROM work_order WHERE status IN(1,2) AND relate_alert_id <> ''"; + $res = mysqli_query($conn, $sql); + while($row = mysqli_fetch_assoc($res)){ + // 工单关联告警不在当前活跃列表=已恢复,自动设为完成 + if(!in_array($row['relate_alert_id'], $activeKeys)){ + $updateSql = "UPDATE work_order SET status=3, update_time=NOW() WHERE id = ".(int)$row['id']; + mysqli_query($conn, $updateSql); + } + } + echo json_encode(['code'=>0, 'msg'=>'同步完成']); + exit; +} + +// 读取通知配置 +$notifyRow = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_workorder_notify LIMIT 1")); +if(!$notifyRow || $notifyRow['notify_open'] != 1) return; +// 组装钉钉、企业微信请求,curl发送webhook + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($GLOBALS['connWork'], "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "
关联告警ID:$relateId
+标题:$title
+$content"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.8.0 b/api/work_order_api.php.8.0 new file mode 100644 index 0000000..63e3a97 --- /dev/null +++ b/api/work_order_api.php.8.0 @@ -0,0 +1,427 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleSql = "SELECT r.is_admin, r.perm_list FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 新增1:根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 新增2:自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + // 新增工单默认未读 is_read=0 + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,is_read,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,0,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssss', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,relate_alert_id=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssi', $title, $content, $assign, $relateAlertId, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + // 修改状态自动标记已读 + $sql = "UPDATE work_order SET status=?,is_read=1,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员分发工单(前端统一action=assign,废弃assign_order) +if ($action === "assign") { + if ($isAdmin !== 1) { + echo json_encode(['code' => 403, 'msg' => '仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + // 修复BUG:仅按工单唯一ID更新,不再使用标题模糊匹配,选中哪一行只修改该行工单 + $sql = "UPDATE work_order SET assign_uid=?,is_read=0,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 一键标记当前用户全部待处理工单为已读 +if ($action === 'mark_all_read') { + $uid = $post['uid'] ?? ''; + $sql = "UPDATE work_order SET is_read=1 WHERE assign_uid=? AND status=1"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, "s", $uid); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '已全部标记为已读']); + exit; +} + +// 语言切换 +if ($action === 'save_lang') { + $lang = $post['lang'] ?? 'zh'; + $sql = "UPDATE sys_config SET v=? WHERE k='lang'"; + $stmt = mysqli_prepare($connConf, $sql); + mysqli_stmt_bind_param($stmt, "s", $lang); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '成功']); + exit; +} + +// 新增:同步Prometheus实时告警,自动清理恢复告警(完全独立,无需index.php) +if ($action === "sync_prom_alerts") { + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新 + $syncWorkUrl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 定时同步:告警恢复自动完工单 +if($action === "sync_alert_auto_close"){ + // 1、拉取仪表盘实时未恢复告警 + $alertApi = "./index.php?act=active_firing"; + $raw = @file_get_contents($alertApi); + $activeList = json_decode($raw, true) ?: []; + $activeKeys = []; + foreach($activeList as $item){ + $activeKeys[] = $item['alert_name'] . "|" . $item['instance']; + } + // 2、查询所有未完成、绑定告警的工单 + $sql = "SELECT id, relate_alert_id FROM work_order WHERE status IN(1,2) AND relate_alert_id <> ''"; + $res = mysqli_query($connWork, $sql); + while($row = mysqli_fetch_assoc($res)){ + // 工单关联告警不在当前活跃列表=已恢复,自动设为完成 + if(!in_array($row['relate_alert_id'], $activeKeys)){ + $updateSql = "UPDATE work_order SET status=3, update_time=NOW() WHERE id = ".(int)$row['id']; + mysqli_query($connWork, $updateSql); + } + } + echo json_encode(['code'=>0, 'msg'=>'同步完成']); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $connWork, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $connWork, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($connWork, "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "
关联告警ID:$relateId
+标题:$title
+$content"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.9.0 b/api/work_order_api.php.9.0 new file mode 100644 index 0000000..e2dfc88 --- /dev/null +++ b/api/work_order_api.php.9.0 @@ -0,0 +1,515 @@ + 0, 'msg' => 'ok']); + exit; +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time']) > $expire) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 工单业务库 monitor +$dbWorkHost = '10.150.117.190'; +$dbWorkUser = 'root'; +$dbWorkPwd = 'hp93000'; +$dbWorkName = 'monitor'; +$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName); +if (!$connWork) { + echo json_encode(['code' => 500, 'msg' => '工单数据库连接失败:' . mysqli_connect_error()]); + exit; +} +mysqli_set_charset($connWork, 'utf8mb4'); + +// 配置库 alert_mail_stat(告警、通知配置统一此处) +$dbConfHost = "10.150.117.190"; +$dbConfUser = "root"; +$dbConfPwd = "hp93000"; +$dbConfName = "alert_mail_stat"; +$connConf = mysqli_connect($dbConfHost, $dbConfUser, $dbConfPwd, $dbConfName); +if(!$connConf){ + echo json_encode(['code' => 500, 'msg' => '配置库连接失败']); + exit; +} +mysqli_set_charset($connConf, "utf8mb4"); + +// 获取当前用户角色权限 +$isAdmin = 0; +$permList = ""; +$roleId = 0; +$roleSql = "SELECT r.is_admin, r.perm_list, u.role_id FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid = ?"; +$stmtRole = mysqli_prepare($connWork, $roleSql); +mysqli_stmt_bind_param($stmtRole, 's', $loginUid); +mysqli_stmt_execute($stmtRole); +$roleRes = mysqli_stmt_get_result($stmtRole); +$roleRow = $roleRes ? mysqli_fetch_assoc($roleRes) : []; +if ($roleRow) { + $isAdmin = intval($roleRow['is_admin']); + $permList = $roleRow['perm_list']; + $roleId = intval($roleRow['role_id'] ?? 0); +} + +// 读取当前角色页面权限列表(用于分发工单权限判断) +$allowPages = []; +if ($roleId > 0) { + $permSql = "SELECT page_key FROM sys_role_permission WHERE role_id = ?"; + $stmtPerm = mysqli_prepare($connWork, $permSql); + mysqli_stmt_bind_param($stmtPerm, 'i', $roleId); + mysqli_stmt_execute($stmtPerm); + $pRes = mysqli_stmt_get_result($stmtPerm); + while ($p = mysqli_fetch_assoc($pRes)) { + $allowPages[] = $p['page_key']; + } +} + +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"), true) ?: []; + +// ===================== 工单列表查询(新增,解决数据可见权限隔离) ===================== +if ($action === "get_list") { + $page = intval($_GET['page'] ?? 1); + $size = intval($_GET['size'] ?? 20); + $offset = ($page - 1) * $size; + $status = trim($_GET['status'] ?? ''); + $keyword = trim($_GET['keyword'] ?? ''); + + $where = []; + $param = []; + $paramType = ''; + + // 普通用户:仅能查看自己创建 或 分配给自己的工单;管理员无限制查看全部 + if ($isAdmin !== 1) { + $where[] = "(create_uid = ? OR assign_uid = ?)"; + $param[] = $loginUid; + $param[] = $loginUid; + $paramType .= 'ss'; + } + + if ($status !== '') { + $where[] = "status = ?"; + $param[] = $status; + $paramType .= 'i'; + } + if ($keyword !== '') { + $where[] = "(title LIKE ? OR content LIKE ?)"; + $param[] = "%$keyword%"; + $param[] = "%$keyword%"; + $paramType .= 'ss'; + } + + $whereSql = $where ? "WHERE " . implode(" AND ", $where) : ""; + + // 分页列表 + $listSql = "SELECT * FROM work_order $whereSql ORDER BY create_time DESC LIMIT ?,?"; + $param[] = $offset; + $param[] = $size; + $paramType .= 'ii'; + + $stmtList = mysqli_prepare($connWork, $listSql); + mysqli_stmt_bind_param($stmtList, $paramType, ...$param); + mysqli_stmt_execute($stmtList); + $res = mysqli_stmt_get_result($stmtList); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + + // 总数统计 + $countSql = "SELECT COUNT(id) total FROM work_order $whereSql"; + $stmtCount = mysqli_prepare($connWork, $countSql); + array_pop($param); + array_pop($param); + $paramTypeCount = rtrim($paramType, 'ii'); + if ($paramTypeCount) { + mysqli_stmt_bind_param($stmtCount, $paramTypeCount, ...$param); + } + mysqli_stmt_execute($stmtCount); + $countRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCount)); + $total = intval($countRow['total']); + + echo json_encode([ + 'code' => 0, + 'list' => $list, + 'total' => $total, + 'page' => $page, + 'size' => $size + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// ===================== 根据告警ID查询关联工单 ===================== +if ($action === "get_workorder_by_alertid") { + $alertId = trim($_GET['alert_id'] ?? ''); + if (empty($alertId)) { + echo json_encode(['code' => 400, 'msg' => '缺少告警ID参数']); + exit; + } + $alertEsc = mysqli_real_escape_string($connWork, $alertId); + $sql = "SELECT id,title,status,assign_uid,create_time FROM work_order WHERE relate_alert_id = ? ORDER BY create_time DESC"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 's', $alertEsc); + mysqli_stmt_execute($stmt); + $res = mysqli_stmt_get_result($stmt); + $list = []; + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// ===================== 自动同步告警状态,批量更新工单为已完成 ===================== +if ($action === "auto_sync_workorder_status") { + // 1. 查询所有已恢复的告警(alert_type=2),去重获取告警ID + $resolveSql = "SELECT DISTINCT CONCAT(alert_name,'_',instance) as alert_id FROM alert_log WHERE alert_type=2"; + $resolveRes = mysqli_query($connConf, $resolveSql); + $resolveAlertIds = []; + while ($row = mysqli_fetch_assoc($resolveRes)) { + $resolveAlertIds[] = $row['alert_id']; + } + if (empty($resolveAlertIds)) { + echo json_encode(['code' => 0, 'msg' => '暂无已恢复告警,无需更新工单', 'update_count' => 0]); + exit; + } + + // 2. 拼接IN条件,查询未完成、关联该告警的工单 + $inStr = implode("','", array_map(function($v) use ($connWork) { + return mysqli_real_escape_string($connWork, $v); + }, $resolveAlertIds)); + // status=1待处理 / status=2处理中,统一改为3已完成 + $updateSql = "UPDATE work_order SET status=3,update_time=NOW() WHERE relate_alert_id IN ('$inStr') AND status IN (1,2)"; + mysqli_query($connWork, $updateSql); + $updateCnt = mysqli_affected_rows($connWork); + + echo json_encode([ + 'code' => 0, + 'msg' => '工单状态自动同步完成,已恢复告警绑定工单全部置为已完成', + 'update_count' => $updateCnt + ], JSON_UNESCAPED_UNICODE); + exit; +} + +// 1、获取实时活跃告警(alert_mail_stat.alert_firing 数据源) +if ($action === "get_firing_alert") { + $alertSql = "SELECT alert_id,alert_name,instance FROM alert_firing WHERE status='firing' ORDER BY receive_time DESC LIMIT 100"; + $res = mysqli_query($connConf, $alertSql); + $list = []; + if($res instanceof mysqli_result){ + while ($row = mysqli_fetch_assoc($res)) { + $list[] = $row; + } + } + echo json_encode(['code' => 0, 'list' => $list]); + exit; +} + +// 2、新建工单(关联告警、多渠道通知 + 自动判断告警是否已恢复) +if ($action === "create") { + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + // 默认待处理1;若关联告警已恢复,直接置完成3 + $status = 1; + + if (!$title || !$content) { + echo json_encode(['code' => 400, 'msg' => '标题和内容不能为空']); + exit; + } + + // 关联了告警,判断该告警是否存在恢复记录 + if (!empty($relateAlertId)) { + $alertEsc = mysqli_real_escape_string($connConf, $relateAlertId); + $checkResolveSql = "SELECT 1 FROM alert_log WHERE CONCAT(alert_name,'_',instance) = ? AND alert_type=2 LIMIT 1"; + $stmtCheck = mysqli_prepare($connConf, $checkResolveSql); + mysqli_stmt_bind_param($stmtCheck, 's', $alertEsc); + mysqli_stmt_execute($stmtCheck); + $checkRes = mysqli_stmt_get_result($stmtCheck); + if (mysqli_num_rows($checkRes) > 0) { + $status = 3; + } + } + + // 新增工单默认未读 is_read=0 + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,relate_alert_id,notify_user,notify_channel,status,is_read,create_time,update_time) VALUES (?,?,?,?,?,?,?,?,0,NOW(),NOW())"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssss', $title, $content, $loginUid, $assign, $relateAlertId, $notifyUser, $notifyChannel, $status); + $ok = mysqli_stmt_execute($stmt); + if (!$ok) { + echo json_encode(['code' => 500, 'msg' => '创建失败:' . mysqli_error($connWork)]); + exit; + } + $orderId = mysqli_insert_id($connWork); + sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单提交成功,通知已下发', 'init_status' => $status]); + exit; +} + +// 3、编辑工单 +if ($action === "edit") { + $id = intval($post['id'] ?? 0); + $title = trim($post['title'] ?? ''); + $content = trim($post['content'] ?? ''); + $assign = trim($post['assign_uid'] ?? ''); + $relateAlertId = trim($post['relate_alert_id'] ?? ''); + $notifyUser = trim($post['notify_user'] ?? ''); + $notifyChannel = trim($post['notify_channel'] ?? ''); + if ($id <= 0 || empty($title) || empty($content)) { + echo json_encode(['code' => 400, 'msg' => '参数不能为空']); + exit; + } + // 非管理员权限校验 + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限编辑该工单']); + exit; + } + } + $sql = "UPDATE work_order SET title=?,content=?,assign_uid=?,relate_alert_id=?,notify_user=?,notify_channel=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ssssssi', $title, $content, $assign, $relateAlertId, $notifyUser, $notifyChannel, $id); + mysqli_stmt_execute($stmt); + sendWorkOrderNotify($connConf, $connWork, $id, $notifyUser, $notifyChannel); + echo json_encode(['code' => 0, 'msg' => '工单保存成功,通知已更新下发']); + exit; +} + +// 4、修改工单状态 +if ($action === "update_status") { + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if ($id <= 0) { + echo json_encode(['code' => 400, 'msg' => '工单ID错误']); + exit; + } + if ($isAdmin !== 1) { + $chkSql = "SELECT id FROM work_order WHERE id=? AND (create_uid=? OR assign_uid=?)"; + $stmtChk = mysqli_prepare($connWork, $chkSql); + mysqli_stmt_bind_param($stmtChk, 'iss', $id, $loginUid, $loginUid); + mysqli_stmt_execute($stmtChk); + $chkRes = mysqli_stmt_get_result($stmtChk); + if (mysqli_num_rows($chkRes) === 0) { + echo json_encode(['code' => 403, 'msg' => '无权限操作该工单']); + exit; + } + } + // 修改状态自动标记已读 + $sql = "UPDATE work_order SET status=?,is_read=1,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'ii', $status, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '状态更新成功']); + exit; +} + +// 5、管理员/拥有system_manage权限角色 分发工单 +if ($action === "assign") { + // 修复:超级管理员 或 拥有system_manage页面权限均可分发工单 + if ($isAdmin !== 1 && !in_array("system_manage", $allowPages)) { + echo json_encode(['code' => 403, 'msg' => '无工单分发权限,请联系管理员']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = trim($post['assign_uid'] ?? ''); + // 修复BUG:仅按工单唯一ID更新,不再使用标题模糊匹配,选中哪一行只修改该行工单 + $sql = "UPDATE work_order SET assign_uid=?,is_read=0,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, 'si', $assignUid, $id); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '工单分发成功']); + exit; +} + +// 一键标记当前用户全部待处理工单为已读 +if ($action === 'mark_all_read') { + $uid = $post['uid'] ?? ''; + $sql = "UPDATE work_order SET is_read=1 WHERE assign_uid=? AND status=1"; + $stmt = mysqli_prepare($connWork, $sql); + mysqli_stmt_bind_param($stmt, "s", $uid); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '已全部标记为已读']); + exit; +} + +// 语言切换 +if ($action === 'save_lang') { + $lang = $post['lang'] ?? 'zh'; + $sql = "UPDATE sys_config SET v=? WHERE k='lang'"; + $stmt = mysqli_prepare($connConf, $sql); + mysqli_stmt_bind_param($stmt, "s", $lang); + mysqli_stmt_execute($stmt); + echo json_encode(['code' => 0, 'msg' => '成功']); + exit; +} + +// 同步Prometheus实时告警,自动清理恢复告警 +if ($action === "sync_prom_alerts") { + $promUrl = "http://10.150.117.190:9090/api/v1/alerts"; + $resp = @file_get_contents($promUrl); + if($resp === false){ + echo json_encode(["code"=>500,"msg"=>"无法连接Prometheus接口"],JSON_UNESCAPED_UNICODE); + exit; + } + $promData = json_decode($resp,true); + if(!isset($promData['data']['alerts'])){ + echo json_encode(["code"=>500,"msg"=>"Prometheus返回数据异常"],JSON_UNESCAPED_UNICODE); + exit; + } + + // 1. 先将表内所有告警标记为已恢复 + mysqli_query($connConf,"UPDATE alert_firing SET status='resolved'"); + + // 2. 遍历当前Prometheus活跃告警,写入/更新 + $alerts = $promData['data']['alerts'] ?? []; + foreach($alerts as $item){ + $alertName = $item['labels']['alertname'] ?? "unknown"; + $instance = $item['labels']['instance'] ?? "unknown"; + $alertId = $alertName."_".$instance; + $sql = "INSERT INTO alert_firing(alert_id,alert_name,instance,status,receive_time) VALUES (?,?,?,'firing',NOW()) ON DUPLICATE KEY UPDATE status='firing',receive_time=NOW()"; + $stmt = mysqli_prepare($connConf,$sql); + mysqli_stmt_bind_param($stmt,"sss",$alertId,$alertName,$instance); + mysqli_stmt_execute($stmt); + } + $syncNum = count($alerts); + + // 同步完成后自动执行工单状态更新 + $syncWorkUrl = $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . "?action=auto_sync_workorder_status"; + @file_get_contents($syncWorkUrl); + + echo json_encode([ + "code"=>0, + "msg"=>"Prometheus告警同步完成,已自动同步工单状态", + "active_alert_total"=>$syncNum + ],JSON_UNESCAPED_UNICODE); + exit; +} + +// 定时同步:告警恢复自动完工单 +if($action === "sync_alert_auto_close"){ + // 1、拉取仪表盘实时未恢复告警 + $alertApi = "./index.php?act=active_firing"; + $raw = @file_get_contents($alertApi); + $activeList = json_decode($raw, true) ?: []; + $activeKeys = []; + foreach($activeList as $item){ + $activeKeys[] = $item['alert_name'] . "|" . $item['instance']; + } + // 2、查询所有未完成、绑定告警的工单 + $sql = "SELECT id, relate_alert_id FROM work_order WHERE status IN(1,2) AND relate_alert_id <> ''"; + $res = mysqli_query($connWork, $sql); + while($row = mysqli_fetch_assoc($res)){ + // 工单关联告警不在当前活跃列表=已恢复,自动设为完成 + if(!in_array($row['relate_alert_id'], $activeKeys)){ + $updateSql = "UPDATE work_order SET status=3, update_time=NOW() WHERE id = ".(int)$row['id']; + mysqli_query($connWork, $updateSql); + } + } + echo json_encode(['code'=>0, 'msg'=>'同步完成']); + exit; +} + +// ==================== 全局通知统一函数 ==================== +function sendWorkOrderNotify($connConf, $connWork, $orderId, $notifyUserStr, $channelStr) +{ + if (empty($notifyUserStr) || empty($channelStr)) return; + $userArr = explode(",", $notifyUserStr); + $channelArr = explode(",", $channelStr); + + // 读取完整通知配置(邮箱+钉钉+企微) + $cfgRes = mysqli_query($connConf, "SELECT * FROM sys_smtp_config WHERE id=1"); + $notifyCfg = $cfgRes ? mysqli_fetch_assoc($cfgRes) : []; + if(empty($notifyCfg)) return; + + // 获取工单完整信息 + $orderRes = mysqli_query($connWork, "SELECT * FROM work_order WHERE id=$orderId"); + $order = $orderRes ? mysqli_fetch_assoc($orderRes) : []; + $title = $order['title']; + $content = $order['content']; + $relateId = $order['relate_alert_id'] ?: "无"; + + $msgText = "【运维工单通知】\n工单ID:$orderId\n关联告警:$relateId\n标题:$title\n详情:$content"; + + foreach ($channelArr as $ch) { + $ch = trim($ch); + switch ($ch) { + case "mail": + sendMailNotify($notifyCfg, $connWork, $userArr, $title, $content, $relateId, $orderId); + break; + case "dingtalk": + sendDingNotify($notifyCfg, $msgText); + break; + case "wecom": + sendWecomNotify($notifyCfg, $msgText); + break; + } + } +} + +// 邮件发送 +function sendMailNotify($smtp, $connWork, $uidList, $title, $content, $relateId, $orderId) +{ + if (empty($smtp['smtp_host']) || empty($smtp['smtp_account'])) return; + $emailList = []; + foreach ($uidList as $uid) { + $uid = trim($uid); + if (empty($uid)) continue; + $res = mysqli_query($connWork, "SELECT email FROM sys_user WHERE uid='$uid'"); + $u = mysqli_fetch_assoc($res); + if (!empty($u['email'])) $emailList[] = $u['email']; + } + if (empty($emailList)) return; + $to = implode(",", array_unique($emailList)); + $subject = "【工单通知】#$orderId $title"; + $body = "
关联告警ID:$relateId
+标题:$title
+$content"; + // 此处接入PHPMailer发送逻辑 +} + +// 钉钉机器人推送 +function sendDingNotify($cfg, $text) +{ + $webhook = $cfg['ding_webhook'] ?? ''; + $secret = $cfg['ding_secret'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 企业微信机器人推送 +function sendWecomNotify($cfg, $text) +{ + $webhook = $cfg['wecom_webhook'] ?? ''; + if(empty($webhook)) return; + $data = json_encode([ + "msgtype" => "text", + "text" => ["content" => $text] + ]); + $opts = ["http" => ["method" => "POST", "header" => "Content-Type:application/json", "content" => $data]]; + file_get_contents($webhook, false, stream_context_create($opts)); +} + +// 无匹配动作 +echo json_encode(['code' => 400, 'msg' => '无效请求动作']); +mysqli_close($connWork); +mysqli_close($connConf); +exit; +?> diff --git a/api/work_order_api.php.bak b/api/work_order_api.php.bak new file mode 100644 index 0000000..ce696eb --- /dev/null +++ b/api/work_order_api.php.bak @@ -0,0 +1,104 @@ + 0])); +} +session_start(); +$expire = 1800; +if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) { + echo json_encode(['code' => 401, 'msg' => '登录失效']); + exit; +} +$loginUid = $_SESSION['user_id']; + +// 数据库配置,优先本地localhost +$dbHost = '10.150.117.190'; +$dbUser = 'root'; +$dbPwd = 'hp93000'; +$dbName = 'monitor'; +$dbPort = 3306; + +// 关键:连接后立刻判断是否失败 +$conn = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName, $dbPort); +if (!$conn) { + echo json_encode([ + 'code' => 500, + 'msg' => '数据库连接失败:' . mysqli_connect_error() . ' 错误码:' . mysqli_connect_errno() + ]); + exit; +} +// 只有连接成功才执行字符集 +mysqli_set_charset($conn, 'utf8mb4'); + +// 下面原有业务代码不变 ... +// 获取角色 +$isAdmin = 0; +$r = mysqli_query($conn,"SELECT r.is_admin FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid='$loginUid'"); +if($rr = mysqli_fetch_assoc($r)) $isAdmin = intval($rr['is_admin']); +$action = $_REQUEST['action'] ?? ''; +$post = json_decode(file_get_contents("php://input"),true) ?: []; + +// 1、新建工单 +if($action === "create"){ + $title = $post['title'] ?? ''; + $content = $post['content'] ?? ''; + $assign = $post['assign_uid'] ?? ''; + if(!$title || !$content){ + echo json_encode(['code'=>400,'msg'=>'标题和内容不能为空']); + exit; + } + $sql = "INSERT INTO work_order(title,content,create_uid,assign_uid,status,create_time,update_time) VALUES (?,?,?,?,?,NOW(),NOW())"; + $stmt = mysqli_prepare($conn,$sql); + mysqli_stmt_bind_param($stmt,'ssssi',$title,$content,$loginUid,$assign,1); + $ok = mysqli_stmt_execute($stmt); + if($ok) echo json_encode(['code'=>0,'msg'=>'工单提交成功']); + else echo json_encode(['code'=>500,'msg'=>'提交失败:'.mysqli_error($conn)]); + exit; +} + +// 2、修改工单状态 +if($action === "update_status"){ + $id = intval($post['id'] ?? 0); + $status = intval($post['status'] ?? 1); + if($id <=0){ + echo json_encode(['code'=>400,'msg'=>'工单ID错误']); + exit; + } + // 权限校验:普通用户只能改自己创建/分配给自己的工单 + if($isAdmin !== 1){ + $chk = mysqli_query($conn,"SELECT id FROM work_order WHERE id=$id AND (create_uid='$loginUid' OR assign_uid='$loginUid')"); + if(mysqli_num_rows($chk) === 0){ + echo json_encode(['code'=>403,'msg'=>'无权限操作该工单']); + exit; + } + } + $sql = "UPDATE work_order SET status=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn,$sql); + mysqli_stmt_bind_param($stmt,'ii',$status,$id); + mysqli_stmt_execute($stmt); + echo json_encode(['code'=>0,'msg'=>'状态更新成功']); + exit; +} + +// 3、管理员分发工单 +if($action === "assign_order"){ + if($isAdmin !== 1){ + echo json_encode(['code'=>403,'msg'=>'仅管理员可分发工单']); + exit; + } + $id = intval($post['id'] ?? 0); + $assignUid = $post['assign_uid'] ?? ''; + $sql = "UPDATE work_order SET assign_uid=?,update_time=NOW() WHERE id=?"; + $stmt = mysqli_prepare($conn,$sql); + mysqli_stmt_bind_param($stmt,'si',$assignUid,$id); + mysqli_stmt_execute($stmt); + echo json_encode(['code'=>0,'msg'=>'工单分发成功']); + exit; +} + +echo json_encode(['code'=>400,'msg'=>'无效操作']); +mysqli_close($conn); +exit; +?> diff --git a/auth.php b/auth.php new file mode 100644 index 0000000..126661c --- /dev/null +++ b/auth.php @@ -0,0 +1,163 @@ + $expireTime) { + session_destroy(); + header("Location: login.php"); + exit; +} +$_SESSION['login_time'] = time(); + +// 登录用户基础信息 +$loginUserId = $_SESSION['user_id']; +$userName = htmlspecialchars($_SESSION['username'] ?? ''); +$isAdmin = intval($_SESSION['is_admin'] ?? 0); +$userRoleId = intval($_SESSION['role_id'] ?? 0); + +// ====================== 双库固定连接 ====================== +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPass = "hp93000"; + +// 业务库 alert_mail_stat(工单、SMTP、大盘) +$dbAlertName = "alert_mail_stat"; +$connAlert = mysqli_connect($dbHost, $dbUser, $dbPass, $dbAlertName); +if (!$connAlert) { + die("业务库alert_mail_stat连接失败:" . mysqli_connect_error()); +} +mysqli_set_charset($connAlert, "utf8mb4"); + +// 权限库 monitor(用户、角色、权限、消息) +$dbMonitorName = "monitor"; +$connMonitor = mysqli_connect($dbHost, $dbUser, $dbPass, $dbMonitorName); +if (!$connMonitor) { + die("权限库monitor连接失败:" . mysqli_connect_error()); +} +mysqli_set_charset($connMonitor, "utf8mb4"); +// ======================================================================== + +// ========== 新增:读取角色真实名称 ========== +$roleRealName = "未知角色"; +if ($userRoleId > 0) { + $getRoleSql = "SELECT role_name FROM sys_role WHERE id = $userRoleId"; + $roleResult = mysqli_query($connMonitor, $getRoleSql); + if ($roleResult && $roleRow = mysqli_fetch_assoc($roleResult)) { + $roleRealName = $roleRow['role_name']; + } +} +// 超级管理员强制覆盖文字 +if ($isAdmin === 1) { + $roleRealName = "超级管理员"; +} +// =========================================== + +// 1. 登录时一次性加载当前角色全部权限,存入全局变量(侧边栏共用) +$allowPages = []; +if ($userRoleId > 0) { + $permSql = "SELECT page_key FROM sys_role_permission WHERE role_id = $userRoleId"; + $permRes = mysqli_query($connMonitor, $permSql); + if ($permRes) { + while ($row = mysqli_fetch_assoc($permRes)) { + $allowPages[] = $row['page_key']; + } + } +} + +// 2. 获取当前访问页面文件名(去掉.php后缀) +$currentPage = basename($_SERVER['SCRIPT_NAME'], '.php'); + +// 3. 非管理员自动拦截无权限页面(全局统一校验,无需每个页面重复写) +if ($isAdmin !== 1 && !in_array($currentPage, $allowPages)) { + echo ""; + exit; +} + +// 读取右上角未读消息数量 +$unreadMsgCount = 0; +$msgSql = "SELECT COUNT(id) cnt FROM sys_user_msg WHERE user_id = $loginUserId AND is_read = 0"; +$msgRes = mysqli_query($connMonitor, $msgSql); +if ($msgRes) { + $msgRow = mysqli_fetch_assoc($msgRes); + $unreadMsgCount = intval($msgRow['cnt']); +} + +// 读取系统基础配置 +$sysConfig = []; +$configSql = "SELECT k, v FROM sys_config"; +$configRes = mysqli_query($connAlert, $configSql); +if ($configRes) { + while ($row = mysqli_fetch_assoc($configRes)) { + $sysConfig[$row['k']] = $row['v']; + } +} +$currentLang = $sysConfig['lang'] ?? "zh"; +$sidebarRawLinks = $sysConfig['quick_link'] ?? ""; + +// 多语言字典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_title' => '运维监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警总览', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'notify_config' => '消息通知配置', + 'role_manage' => '角色管理', + 'user_manage' => '用户管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh' => '刷新页面', + 'logout' => '退出登录', + 'unread_msg' => '未读消息' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_title' => "Monitor Platform", + 'monitor_panel' => "Monitor Panel", + 'alert_overview' => "Alert Dashboard", + 'quick_link' => "Quick Link", + 'system_manage' => "System Manage", + 'notify_config' => "Notify Config", + 'role_manage' => "Role Manage", + 'user_manage' => "User Manage", + 'current_user' => "User: ", + 'sys_time' => "Time: ", + 'refresh' => "Refresh", + 'logout' => "Logout", + 'unread_msg' => "Unread Msg" + ] +]; +$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); + if (count($item) === 2) { + $sidebarLinkList[] = [ + 'name' => trim($item[0]), + 'url' => trim($item[1]) + ]; + } + } +} + +// 【已删除冲突无用函数 hasPagePerm】 +?> diff --git a/dashbaord.en-zh.php b/dashbaord.en-zh.php new file mode 100644 index 0000000..82f6e8c --- /dev/null +++ b/dashbaord.en-zh.php @@ -0,0 +1,1094 @@ + $expire)) { + session_destroy(); + header("Location: login.php"); + exit; +} +// 刷新登录计时 +$_SESSION['login_time'] = time(); +$userName = htmlspecialchars($_SESSION['username']); +$userRole = $_SESSION['role']; +$roleText = $userRole === 'admin' ? '管理员' : '只读用户'; + +// 读取全局系统配置(admin后台保存后同步生效) +$dbHost = "10.150.117.190"; +$dbUser = "root"; +$dbPwd = "hp93000"; +$dbName = "alert_mail_stat"; +$connConfig = mysqli_connect($dbHost, $dbUser, $dbPwd, $dbName); +mysqli_set_charset($connConfig, "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']; +} +mysqli_close($connConfig); + +// 赋值全局配置 +$pageTitle = htmlspecialchars($sysConfig['page_title'] ?? "告警监控系统"); +$themeColor = htmlspecialchars($sysConfig['theme_color'] ?? "#409eff"); +$pageSize = $sysConfig['page_size'] ?? "20"; +$footerText = htmlspecialchars($sysConfig['footer_text'] ?? ""); +$sidebarRawLinks = $sysConfig['sidebar_links'] ?? ""; +// 读取语言配置 zh=中文 en=英文 +$currentLang = $sysConfig['lang'] ?? "zh"; + +// 全局多语言词典 +$langMap = [ + 'zh' => [ + 'html_lang' => 'zh-CN', + 'page_subtitle' => '爱德万测试 · 运维告警监控平台', + 'monitor_panel' => '监控面板', + 'alert_overview' => '告警监控总览', + 'disk_capacity' => '服务器磁盘容量', + 'quick_link' => '快捷外链', + 'system_manage' => '系统管理', + 'system_config' => '后台配置管理', + 'current_user' => '当前用户:', + 'sys_time' => '系统时间:', + 'refresh_all' => '刷新全部数据', + 'export_csv' => '导出告警CSV', + 'logout' => '退出登录', + 'lang_text' => '语言:', + 'today_fire' => '今日触发告警', + 'unresolved_now' => '当前未恢复告警', + 'resolved_today' => '今日恢复告警', + 'instance_total' => '故障实例总数', + 'recovery_rate' => '告警恢复率', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => '今日告警频次 TOP 10', + 'active_alert' => '当前未恢复活跃告警', + 'alert_count' => '条未恢复故障', + 'all_alert_log' => '今日全量告警明细列表', + 'total_alert' => '条告警记录', + 'tag' => '告警状态', + 'alert_name' => '告警名称', + 'instance_addr' => '实例地址', + 'severity' => '告警级别', + 'occur_time' => '故障发生时间', + 'empty_normal' => '当前无未恢复告警,系统运行正常', + 'empty_no_data' => '暂无今日告警数据', + 'disk_stat' => '用户目录磁盘占用统计', + 'filter_ip' => '筛选实例IP:', + 'export_disk' => '导出当前表格CSV', + 'all_instance' => '全部实例', + 'disk_loading' => '磁盘数据加载中...', + 'no_disk_data' => '暂无磁盘指标数据', + 'no_ip_data' => '该实例下无目录数据', + 'csv_tip' => '正在生成CSV报表,请稍候...', + 'alert_axis' => '告警次数', + 'data_fail' => '数据加载失败,请重新登录', + 'server_fail' => '接口数据加载失败,请检查后端服务', + 'disk_api_fail' => '磁盘接口异常:', + 'disk_request_fail' => '请求df.php接口失败,请检查服务', + 'no_export_data' => '无数据可导出' + ], + 'en' => [ + 'html_lang' => 'en', + 'page_subtitle' => 'Advantest · O&M Alert Monitor Platform', + 'monitor_panel' => 'Monitor Panel', + 'alert_overview' => 'Alert Overview', + 'disk_capacity' => 'Server Disk Capacity', + 'quick_link' => 'Quick Links', + 'system_manage' => 'System Manage', + 'system_config' => 'System Config', + 'current_user' => 'User: ', + 'sys_time' => 'System Time: ', + 'refresh_all' => 'Refresh All Data', + 'export_csv' => 'Export Alert CSV', + 'logout' => 'Logout', + 'lang_text' => 'Lang: ', + 'today_fire' => 'Today Triggered Alerts', + 'unresolved_now' => 'Unresolved Alerts', + 'resolved_today' => 'Resolved Today', + 'instance_total' => 'Affected Instances', + 'recovery_rate' => 'Daily Recovery Rate', + 'today_fire_sub' => 'Total Firing Today', + 'unresolved_sub' => 'Unresolved Now', + 'resolved_sub' => 'Resolved Today', + 'instance_sub' => 'Affected Host Instance', + 'rate_sub' => 'Daily Recovery Rate', + 'top10_alert' => 'Top 10 Alert Frequency Today', + 'active_alert' => 'Active Unresolved Alerts', + 'alert_count' => ' unresolved alerts', + 'all_alert_log' => 'Today Full Alert List', + 'total_alert' => ' alert records', + 'tag' => 'Status', + 'alert_name' => 'Alert Name', + 'instance_addr' => 'Instance IP', + 'severity' => 'Severity', + 'occur_time' => 'Occur Time', + 'empty_normal' => 'No active alerts, system normal', + 'empty_no_data' => 'No alert data today', + 'disk_stat' => 'User Directory Disk Usage', + 'filter_ip' => 'Filter IP: ', + 'export_disk' => 'Export Table CSV', + 'all_instance' => 'All Instances', + 'disk_loading' => 'Loading disk data...', + 'no_disk_data' => 'No disk data available', + 'no_ip_data' => 'No directory data for this instance', + 'csv_tip' => 'Generating CSV file, please wait...', + 'alert_axis' => 'Alert Count', + 'data_fail' => 'Data load failed, please relogin', + 'server_fail' => 'API request failed, check backend service', + 'disk_api_fail' => 'Disk API Error: ', + 'disk_request_fail' => 'Request df.php failed, check service', + 'no_export_data' => 'No data to export' + ] +]; +$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]) + ]; + } + } +} +?> + + + + + +
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| IP | +Username | +Path | +Size(GB) | +
|---|---|---|---|
| + + + | +|||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
|
+
+ 磁盘数据加载中...
+ |
+ |||
| 状态 | +告警名称 | +实例地址 | +级别 | +故障开始时间 | +接收时间 | +
|---|---|---|---|---|---|
|
+
+
+
+ 数据加载中...
+ |
+ |||||
| 状态 | +告警名称 | +实例地址 | +级别 | +故障开始时间 | +恢复时间 | +接收时间 | +
|---|---|---|---|---|---|---|
|
+
+
+
+ 数据加载中...
+ |
+ ||||||
0
+0
+0
+| 类型 | +告警名称 | +实例 | +级别 | +故障开始 | +恢复时间 | +邮件接收时间 | +
|---|
| 状态 | +告警名称 | +实例地址 | +级别 | +故障开始时间 | +恢复时间 | +接收时间 | +
|---|---|---|---|---|---|---|
|
+
+
+
+ 数据加载中...
+ |
+ ||||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| IP | +Username | +Path | +Size(GB) | +
|---|---|---|---|
| + + + | +|||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| IP | +Username | +Path | +Size(GB) | +
|---|---|---|---|
| + + + | +|||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| IP | +Username | +Path | +Size(GB) | +
|---|---|---|---|
| + + + | +|||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| IP | +Username | +Path | +Size(GB) | +
|---|---|---|---|
| + + + | +|||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
|
+
+ 磁盘数据加载中...
+ |
+ |||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
|
+
+ 磁盘数据加载中...
+ |
+ |||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
|
+
+ 磁盘数据加载中...
+ |
+ |||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
|
+
+ 磁盘数据加载中...
+ |
+ |||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
|
+
+ 磁盘数据加载中...
+ |
+ |||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
|
+
+ 磁盘数据加载中...
+ |
+ |||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
| IP | +Username | +Path | +Size(GB) | +
|---|---|---|---|
| + + + | +|||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 当前无未恢复告警,系统运行正常
+ |
+ ||||
| 告警状态 | +告警名称 | +实例地址 | +告警级别 | +故障发生时间 | +
|---|---|---|---|---|
|
+
+
+
+ 暂无今日告警数据
+ |
+ ||||
| 实例IP | +用户名 | +目录路径 | +占用容量 | +
|---|---|---|---|
| 数据加载中... | +|||
| + | + | + | + | + | + | + |
|---|---|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||||
| + | + | + | + | + | + |
|---|---|---|---|---|---|
|
+
+
+
+
+ |
+ |||||
| + | + | + | + | + | + | + |
|---|---|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||||
| + | + | + | + | + |
|---|---|---|---|---|
|
+
+
+
+
+ |
+ ||||
C6ZElh(DA_jLN=MkxobFd(kG6wqbsm-{)G2ROAL$rK4<&wrWS4F}$7>VLjZ~K@NB#Cl
zO&Qzj{Xrj9Q?1IwthH&{H`*sEN1LX>TEL$T9bDBnzAi-V%H>rqOSs{8i9DPnOQEm?
zKnSNAa;HMY+M##OP3;`0pT=G%gsg(SQ~>24N?A+(Cl^G2rTi+Y_Xmo`>Wi*@@Y*8%
zxO%^0W62$lakMd)^-st?P%lI2t
z)Hp`>W4-6c4x>S@{PH(^%>AB~t9w+1&30NhSzJq;*3A}|Fx76iJC$XzW&Y(3cE8JR
zb!47(SvFgpOI(&s!0&j{;v!y#gh|u^kVZJ9B^rTLKq!cWhf6jz7>B3{VIyUy6St8`
zt}7v#!kob_%sj7rhkZ`%r086h2XZFre!9|+So+}e;-=^KDM@y(a^Sx%DRgARg`+6@
zF2u-VGLQ-ZWzz#K(++!YiRJ=~3|GVj`!3)x5$zUkh)3uGfML}Os*EV|5hF(UJ{A{;
zN;^ys#azEYS4VvUT}QTW$g@cuN;(_~!om}CfZ=y>M0q>J?!6&0ot>C}-$GouFs%Hh
zTmXOk#{D|~3BT@JuRegi$szQ;LUnyKd=u@?UxB<`_Ui-kIc(E;I{yK`ZY?|iTsd&P
z-Ds3oUP!mxQvQ9=j3s~$dYyr~$?Q9b+{-|eMivJd_6zn%Diy*g%^dgph0WMnjlyQm
zYvbd%&X(IOX1{WrZT72MGXRGk%-(<@szG$F^a0wjK{JzM4tXi@39NXYNK<*-69LR<
zHA_JJax@?fIF6fq^$B30HaB2{+{uk~5)kSg_1^k+EuCO#z)8DSy4iVj*ToiH!~Bac
z@4lm}>JH~j*Yjl;)*~sL(K7eK*OTEpx-0KkaM|Wbua?%#Xj@*tK(C(|>l{C&ZhWb0
zMo~pu{jBOKI=QucYE5gb!YQVnoLhYCh8f$YkM&BY2iPFc51wjZM;I&Xyq~eb&xB70
zb!DyRW$vzMsVFjQ1?9U8snP5KICcCp+z|F5YaW9djR7^>S60XQbPOU4qinn+8ToxO
zNmqH=nTD{Wfv@awt2Of=f=NR|5D_7WgKt``%4VxKRM|4nPih20e86-edqM8Km6$g(
zF)F>V8F&FIKjPI0
r
z(+>fwmj~Z*h2;hVYe