Initial commit
This commit is contained in:
@@ -0,0 +1,894 @@
|
||||
<?php
|
||||
session_start();
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
header("Pragma: no-cache");
|
||||
header("Expires: Thu, 01 Jan 1970 00:00:00 GMT");
|
||||
|
||||
$expire = 1800;
|
||||
if (empty($_SESSION['user_id']) || (time() - $_SESSION['login_time'] > $expire)) {
|
||||
session_destroy();
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
}
|
||||
$_SESSION['login_time'] = time();
|
||||
$userName = htmlspecialchars($_SESSION['username']);
|
||||
$userRole = $_SESSION['role'];
|
||||
$roleText = $userRole === 'admin' ? '管理员' : '只读用户';
|
||||
|
||||
// 读取全局配置库(和dashboard共用配置库)
|
||||
$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'] ?? "";
|
||||
$currentLang = $sysConfig['lang'] ?? "zh";
|
||||
|
||||
// 多语言词典(继承dashboard全部词条,新增工单词条)
|
||||
$langMap = [
|
||||
'zh' => [
|
||||
'html_lang' => 'zh-CN',
|
||||
'page_subtitle' => '爱德万测试 · 运维告警监控平台',
|
||||
'monitor_panel' => '监控面板',
|
||||
'alert_overview' => '告警监控总览',
|
||||
'disk_capacity' => '服务器磁盘容量',
|
||||
'alert_list_page' => '历史告警查询',
|
||||
'quick_link' => '快捷外链',
|
||||
'system_manage' => '系统管理',
|
||||
'system_config' => '后台配置管理',
|
||||
'current_user' => '当前用户:',
|
||||
'sys_time' => '系统时间:',
|
||||
'refresh_all' => '刷新全部数据',
|
||||
'export_csv' => '导出CSV',
|
||||
'logout' => '退出登录',
|
||||
'lang_text' => '语言:',
|
||||
// 工单新增词条
|
||||
'work_order_mgr' => '工单系统',
|
||||
'work_order_title' => '工单管理',
|
||||
'work_create' => '新建工单',
|
||||
'work_edit' => '编辑工单',
|
||||
'work_assign' => '分发工单',
|
||||
'work_status' => '工单状态',
|
||||
'work_creator' => '创建人',
|
||||
'work_handler' => '处理人',
|
||||
'work_content' => '工单内容/备注',
|
||||
'work_title' => '工单标题',
|
||||
'work_create_time' => '创建时间',
|
||||
'work_update_time' => '更新时间',
|
||||
'work_all_list' => '全部工单列表',
|
||||
'work_no_data' => '暂无工单记录',
|
||||
'work_save' => '保存',
|
||||
'work_cancel' => '取消',
|
||||
'work_placeholder_title' => '填写故障/需求标题',
|
||||
'work_placeholder_content' => '详细描述故障、操作步骤、处理备注',
|
||||
'work_select_handler' => '选择处理人(留空暂不分配)',
|
||||
'status_1' => '待处理',
|
||||
'status_2' => '处理中',
|
||||
'status_3' => '已完成',
|
||||
'status_4' => '已关闭'
|
||||
],
|
||||
'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',
|
||||
'alert_list_page' => 'Alert Pagination List',
|
||||
'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 CSV',
|
||||
'logout' => 'Logout',
|
||||
'lang_text' => 'Lang: ',
|
||||
// 工单英文词条
|
||||
'work_order_mgr' => 'Work Order System',
|
||||
'work_order_title' => 'Work Order Manage',
|
||||
'work_create' => 'Create Order',
|
||||
'work_edit' => 'Edit Order',
|
||||
'work_assign' => 'Assign Order',
|
||||
'work_status' => 'Status',
|
||||
'work_creator' => 'Creator',
|
||||
'work_handler' => 'Handler',
|
||||
'work_content' => 'Content / Remark',
|
||||
'work_title' => 'Order Title',
|
||||
'work_create_time' => 'Create Time',
|
||||
'work_update_time' => 'Update Time',
|
||||
'work_all_list' => 'All Work Order List',
|
||||
'work_no_data' => 'No order data',
|
||||
'work_save' => 'Save',
|
||||
'work_cancel' => 'Cancel',
|
||||
'work_placeholder_title' => 'Fill fault or demand title',
|
||||
'work_placeholder_content' => 'Describe fault, steps and handling remark',
|
||||
'work_select_handler' => 'Select handler (empty for unassigned)',
|
||||
'status_1' => 'Pending',
|
||||
'status_2' => 'Processing',
|
||||
'status_3' => 'Finished',
|
||||
'status_4' => 'Closed'
|
||||
]
|
||||
];
|
||||
$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])
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 工单业务数据库(monitor库)==========
|
||||
$dbWorkHost = "10.150.117.190";
|
||||
$dbWorkUser = "root";
|
||||
$dbWorkPwd = "hp93000";
|
||||
$dbWorkName = "monitor";
|
||||
$connWork = mysqli_connect($dbWorkHost, $dbWorkUser, $dbWorkPwd, $dbWorkName);
|
||||
if (!$connWork) die("Work DB connect fail: " . mysqli_connect_error());
|
||||
mysqli_set_charset($connWork, "utf8mb4");
|
||||
$loginUid = $_SESSION['user_id'];
|
||||
|
||||
// 获取当前用户是否管理员
|
||||
$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($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']);
|
||||
|
||||
// 获取所有用户下拉
|
||||
$userOptions = "";
|
||||
$userRes = mysqli_query($connWork, "SELECT uid, real_name, username FROM sys_user WHERE enable = 1");
|
||||
while ($u = mysqli_fetch_assoc($userRes)) {
|
||||
$userOptions .= '<option value="' . $u['uid'] . '">' . $u['real_name'] . '(' . $u['username'] . ')</option>';
|
||||
}
|
||||
// 分页参数
|
||||
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
|
||||
// 强制转为数字,最小10,防止0
|
||||
$pageSize = intval($sysConfig['page_size'] ?? 20);
|
||||
if ($pageSize < 1) $pageSize = 20;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
|
||||
// 权限过滤
|
||||
if ($isAdmin === 1) {
|
||||
$whereSql = " 1=1 ";
|
||||
} else {
|
||||
$whereSql = " (create_uid = ? OR assign_uid = ?) ";
|
||||
}
|
||||
|
||||
// 统计总数
|
||||
$cntSql = "SELECT COUNT(*) total FROM work_order WHERE " . $whereSql;
|
||||
$stmtCnt = mysqli_prepare($connWork, $cntSql);
|
||||
if ($isAdmin !== 1) {
|
||||
mysqli_stmt_bind_param($stmtCnt, 'ss', $loginUid, $loginUid);
|
||||
}
|
||||
mysqli_stmt_execute($stmtCnt);
|
||||
$cntRow = mysqli_fetch_assoc(mysqli_stmt_get_result($stmtCnt));
|
||||
$total = intval($cntRow['total'] ?? 0);
|
||||
|
||||
// 防除零
|
||||
if ($pageSize <= 0) {
|
||||
$totalPage = 1;
|
||||
} else {
|
||||
$totalPage = ceil($total / $pageSize);
|
||||
}
|
||||
// 工单列表
|
||||
$listSql = "SELECT wo.*, uc.real_name create_name, ua.real_name assign_name
|
||||
FROM work_order wo
|
||||
LEFT JOIN sys_user uc ON wo.create_uid = uc.uid
|
||||
LEFT JOIN sys_user ua ON wo.assign_uid = ua.uid
|
||||
WHERE " . $whereSql . " ORDER BY create_time DESC LIMIT ?, ?";
|
||||
$stmtList = mysqli_prepare($connWork, $listSql);
|
||||
if ($isAdmin === 1) {
|
||||
mysqli_stmt_bind_param($stmtList, 'ii', $offset, $pageSize);
|
||||
} else {
|
||||
mysqli_stmt_bind_param($stmtList, 'ssii', $loginUid, $loginUid, $offset, $pageSize);
|
||||
}
|
||||
mysqli_stmt_execute($stmtList);
|
||||
$listResult = mysqli_stmt_get_result($stmtList);
|
||||
$orderList = [];
|
||||
while ($row = mysqli_fetch_assoc($listResult)) {
|
||||
$orderList[] = $row;
|
||||
}
|
||||
mysqli_close($connWork);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="<?php echo $t['html_lang']; ?>">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?php echo $pageTitle; ?> - Advantest <?php echo $t['work_order_mgr']; ?></title>
|
||||
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
|
||||
<script src="/static/js/echarts.min.js"></script>
|
||||
<script src="/static/js/jquery.min.js"></script>
|
||||
<!-- 完全复用dashboard整套CSS,无新增自定义样式 -->
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
body{
|
||||
background:#f9fafc;
|
||||
font-family:"Inter","PingFang SC","Microsoft YaHei";
|
||||
color:#1d2939;
|
||||
line-height:1.6;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
height:100vh;
|
||||
overflow:hidden;
|
||||
}
|
||||
.wrap-main{
|
||||
display:flex;
|
||||
flex:1;
|
||||
overflow:hidden;
|
||||
}
|
||||
.sidebar{
|
||||
width:240px;
|
||||
background:#152c5b;
|
||||
color:#e2e8f0;
|
||||
flex-shrink:0;
|
||||
overflow-y:auto;
|
||||
}
|
||||
.sidebar-brand{
|
||||
padding:26px 24px;
|
||||
border-bottom:1px solid rgba(255,255,255,0.1);
|
||||
}
|
||||
.sidebar-brand-en{
|
||||
font-size:20px;
|
||||
font-weight:700;
|
||||
letter-spacing:1px;
|
||||
color:#fff;
|
||||
}
|
||||
.sidebar-brand-cn{
|
||||
font-size:13px;
|
||||
color:#a5b4fc;
|
||||
margin-top:4px;
|
||||
}
|
||||
.sidebar-menu{
|
||||
padding:16px 0;
|
||||
}
|
||||
.menu-title{
|
||||
padding:10px 24px;
|
||||
font-size:12px;
|
||||
color:#94a3b8;
|
||||
letter-spacing:1px;
|
||||
}
|
||||
.menu-item{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:12px;
|
||||
padding:14px 24px;
|
||||
cursor:pointer;
|
||||
font-size:14px;
|
||||
transition:0.2s;
|
||||
color:#cbd5e1;
|
||||
}
|
||||
.menu-item i{
|
||||
font-size:16px;
|
||||
width:20px;
|
||||
text-align:center;
|
||||
}
|
||||
.menu-item.active{
|
||||
background:rgba(255,255,255,0.12);
|
||||
color:#fff;
|
||||
border-left:4px solid #3b82f6;
|
||||
}
|
||||
.menu-item:hover:not(.active){
|
||||
background:rgba(255,255,255,0.06);
|
||||
color:#fff;
|
||||
}
|
||||
.main-content{
|
||||
flex:1;
|
||||
overflow-y:auto;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
.header{
|
||||
background:#ffffff;
|
||||
border-bottom:1px solid #eef2fb;
|
||||
color:#152c5b;
|
||||
padding:20px 40px;
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
box-shadow:0 2px 12px rgba(21,44,91,0.05);
|
||||
flex-shrink:0;
|
||||
}
|
||||
.header-left{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:14px;
|
||||
}
|
||||
.header-brand-en{
|
||||
font-size:24px;
|
||||
font-weight:700;
|
||||
letter-spacing:2px;
|
||||
color:#152c5b;
|
||||
}
|
||||
.header-brand-cn{
|
||||
font-size:15px;
|
||||
color:#64748b;
|
||||
}
|
||||
.header-right{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:18px;
|
||||
font-size:14px;
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
.user-info,.time-info,.lang-box{
|
||||
color:#475569;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
}
|
||||
.lang-box select{
|
||||
padding:4px 8px;
|
||||
border:1px solid #cbd5e1;
|
||||
border-radius:6px;
|
||||
}
|
||||
.btn-base{
|
||||
border:none;
|
||||
padding:9px 20px;
|
||||
border-radius:8px;
|
||||
cursor:pointer;
|
||||
font-size:14px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
.btn-outline{
|
||||
background:#ffffff;
|
||||
color:#152c5b;
|
||||
border:1px solid #cbd5e1;
|
||||
}
|
||||
.btn-outline:hover{
|
||||
background:#f7f8fc;
|
||||
border-color:#152c5b;
|
||||
}
|
||||
.btn-primary{
|
||||
background:#152c5b;
|
||||
color:#fff;
|
||||
}
|
||||
.btn-primary:hover{
|
||||
background:#0f1e42;
|
||||
}
|
||||
.btn-success{
|
||||
background:#10b981;
|
||||
color:#fff;
|
||||
}
|
||||
.btn-success:hover{
|
||||
background:#059669;
|
||||
}
|
||||
.mask{
|
||||
position:fixed;
|
||||
left:0;top:0;
|
||||
width:100%;height:100%;
|
||||
background:rgba(255,255,255,0.85);
|
||||
display:none;
|
||||
z-index:999;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
.mask-box{
|
||||
background:#fff;
|
||||
padding:30px 40px;
|
||||
border-radius:14px;
|
||||
font-size:15px;
|
||||
display:flex;
|
||||
gap:14px;
|
||||
align-items:center;
|
||||
box-shadow:0 8px 30px rgba(21,44,91,0.12);
|
||||
border:1px solid #eef2fb;
|
||||
}
|
||||
.loading{
|
||||
display:inline-block;
|
||||
width:20px;height:20px;
|
||||
border:2px solid #e2e8f0;
|
||||
border-top-color:#152c5b;
|
||||
border-radius:50%;
|
||||
animation:spin 0.8s linear infinite;
|
||||
}
|
||||
@keyframes spin{to{transform:rotate(360deg)}}
|
||||
.container{
|
||||
padding:36px 40px;
|
||||
max-width:100%;
|
||||
flex:1;
|
||||
}
|
||||
.page-panel{
|
||||
display:none;
|
||||
}
|
||||
.page-panel.active{
|
||||
display:block;
|
||||
}
|
||||
.base-card{
|
||||
background:#fff;
|
||||
border-radius:16px;
|
||||
padding:32px;
|
||||
box-shadow:0 3px 18px rgba(21,44,91,0.06);
|
||||
border:1px solid #eef2fb;
|
||||
margin-bottom:36px;
|
||||
}
|
||||
.title-wrap{
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
margin-bottom:26px;
|
||||
padding-bottom:16px;
|
||||
border-bottom:1px solid #eef2fb;
|
||||
}
|
||||
.title-left{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:12px;
|
||||
font-size:19px;
|
||||
font-weight:600;
|
||||
color:#152c5b;
|
||||
}
|
||||
.title-left i{color:#2563eb;font-size:21px}
|
||||
.table-count{font-size:14px;color:#64748b}
|
||||
.table-wrap{overflow-x:auto}
|
||||
table{width:100%;border-collapse:collapse;font-size:14px}
|
||||
th{
|
||||
background:#f9fafc;
|
||||
color:#475569;
|
||||
font-weight:600;
|
||||
padding:16px 18px;
|
||||
text-align:left;
|
||||
border-bottom:2px solid #e2e8f0;
|
||||
white-space:nowrap;
|
||||
}
|
||||
th i{margin-right:6px;font-size:13px;color:#94a3b8}
|
||||
td{
|
||||
padding:18px;
|
||||
border-bottom:1px solid #f1f5f9;
|
||||
color:#334155;
|
||||
}
|
||||
tbody tr{transition:background 0.2s}
|
||||
tbody tr:hover{background:#f7f8fc}
|
||||
tbody tr:nth-child(even){background:#fbfcfe}
|
||||
.empty-state{
|
||||
text-align:center;
|
||||
padding:80px 20px;
|
||||
color:#94a3b8;
|
||||
font-size:15px;
|
||||
}
|
||||
.empty-icon{
|
||||
font-size:56px;
|
||||
margin-bottom:18px;
|
||||
opacity:0.35;
|
||||
}
|
||||
/* 弹窗表单 复用全局卡片圆角 */
|
||||
.modal-mask{
|
||||
position:fixed;top:0;left:0;width:100%;height:100%;
|
||||
background:rgba(0,0,0,0.4);display:none;align-items:center;justify-content:center;z-index:999;
|
||||
}
|
||||
.modal-box{
|
||||
width:680px;background:#fff;border-radius:16px;padding:32px;
|
||||
box-shadow:0 8px 30px rgba(21,44,91,0.12);
|
||||
}
|
||||
.modal-head{
|
||||
display:flex;justify-content:space-between;align-items:center;margin-bottom:26px;
|
||||
padding-bottom:16px;border-bottom:1px solid #eef2fb;
|
||||
}
|
||||
.modal-close{cursor:pointer;font-size:22px;color:#94a3b8;}
|
||||
.form-row{margin-bottom:20px;}
|
||||
.form-row label{display:block;margin-bottom:8px;color:#475569;font-weight:500;}
|
||||
.form-row input,.form-row select,.form-row textarea{
|
||||
width:100%;padding:10px 14px;border:1px solid #cbd5e1;border-radius:8px;font-size:14px;
|
||||
}
|
||||
.form-row textarea{height:140px;resize:none;}
|
||||
.btn-group{display:flex;gap:14px;margin-top:10px;}
|
||||
.select-sm{
|
||||
padding:6px 8px;border:1px solid #cbd5e1;border-radius:6px;font-size:13px;
|
||||
}
|
||||
/* 状态标签复用全局样式 */
|
||||
.status-tag{
|
||||
display:inline-flex;
|
||||
align-items:center;
|
||||
gap:5px;
|
||||
padding:6px 14px;
|
||||
border-radius:24px;
|
||||
font-size:13px;
|
||||
font-weight:500;
|
||||
}
|
||||
.status-1{background:#ffedd5;color:#ea580c}
|
||||
.status-2{background:#dbeafe;color:#2563eb}
|
||||
.status-3{background:#dcfce7;color:#16a34a}
|
||||
.status-4{background:#f1f5f9;color:#64748b}
|
||||
/* 分页极简样式,复用dashboard统一风格 */
|
||||
.page-pagination{
|
||||
display:flex;justify-content:space-between;align-items:center;margin-top:20px;
|
||||
}
|
||||
.page-pag-btn{
|
||||
padding:8px 16px;border:1px solid #cbd5e1;background:#fff;border-radius:8px;cursor:pointer;font-size:14px;
|
||||
}
|
||||
.page-pag-btn:hover{background:#f7f8fc;border-color:#152c5b;}
|
||||
@media (max-width:768px){
|
||||
.wrap-main{flex-direction:column;}
|
||||
.sidebar{width:100%;height:auto}
|
||||
.header{padding:16px 24px;flex-direction:column;gap:16px;align-items:flex-start}
|
||||
.header-right{flex-wrap:wrap}
|
||||
.container{padding:24px}
|
||||
.base-card{padding:24px}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mask" id="exportMask">
|
||||
<div class="mask-box">
|
||||
<span class="loading"></span>
|
||||
<span><?php echo $t['csv_tip'] ?? ""; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wrap-main">
|
||||
<!-- 左侧侧边栏 和dashboard完全同源 -->
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-brand">
|
||||
<div class="sidebar-brand-en">Advantest</div>
|
||||
<div class="sidebar-brand-cn"><?php echo $t['page_subtitle']; ?></div>
|
||||
</div>
|
||||
<div class="sidebar-menu">
|
||||
<div class="menu-title"><?php echo $t['monitor_panel']; ?></div>
|
||||
<div class="menu-item" data-page="alertPage" onclick="location.href='dashboard.php'">
|
||||
<i class="fa fa-line-chart"></i>
|
||||
<span><?php echo $t['alert_overview']; ?></span>
|
||||
</div>
|
||||
<div class="menu-item" data-page="diskPage" onclick="location.href='dashboard.php#diskPage'">
|
||||
<i class="fa fa-hdd-o"></i>
|
||||
<span><?php echo $t['disk_capacity']; ?></span>
|
||||
</div>
|
||||
<div class="menu-item" onclick="window.open('alert_list.php','_blank')">
|
||||
<i class="fa fa-list"></i>
|
||||
<span><?php echo $t['alert_list_page']; ?></span>
|
||||
</div>
|
||||
<!-- 工单系统 当前激活 -->
|
||||
<div class="menu-item active" data-page="workOrderPage">
|
||||
<i class="fa fa-ticket"></i>
|
||||
<span><?php echo $t['work_order_mgr']; ?></span>
|
||||
</div>
|
||||
<?php if (!empty($sidebarLinkList)): ?>
|
||||
<div class="menu-title"><?php echo $t['quick_link']; ?></div>
|
||||
<?php foreach ($sidebarLinkList as $link): ?>
|
||||
<div class="menu-item" onclick="window.open('<?php echo htmlspecialchars($link['url']); ?>')">
|
||||
<i class="fa fa-external-link"></i>
|
||||
<span><?php echo htmlspecialchars($link['name']); ?></span>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
<div class="menu-title"><?php echo $t['system_manage']; ?></div>
|
||||
<div class="menu-item" onclick="location.href='admin.php'">
|
||||
<i class="fa fa-cog"></i>
|
||||
<span><?php echo $t['system_config']; ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="header">
|
||||
<div class="header-left">
|
||||
<div>
|
||||
<div class="header-brand-en">Advantest</div>
|
||||
<div class="header-brand-cn"><?php echo $t['page_subtitle']; ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<span class="user-info"><i class="fa fa-user-circle"></i><?php echo $t['current_user']; ?><?php echo $userName; ?>(<?php echo $roleText; ?>)</span>
|
||||
<span class="time-info"><i class="fa fa-clock-o"></i><?php echo $t['sys_time']; ?><span id="updateTime">--</span></span>
|
||||
<div class="lang-box">
|
||||
<span><?php echo $t['lang_text']; ?></span>
|
||||
<select id="langSwitch">
|
||||
<option value="zh" <?php echo $currentLang==='zh'?'selected':''; ?>>中文</option>
|
||||
<option value="en" <?php echo $currentLang==='en'?'selected':''; ?>>EN</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn-base btn-outline" onclick="loadAllData()"><i class="fa fa-refresh"></i><?php echo $t['refresh_all']; ?></button>
|
||||
<button class="btn-base btn-primary" id="logoutBtn"><i class="fa fa-sign-out"></i><?php echo $t['logout']; ?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="page-panel active" id="workOrderPage">
|
||||
<div class="base-card">
|
||||
<div class="title-wrap">
|
||||
<div class="title-left"><i class="fa fa-ticket"></i><?php echo $t['work_all_list']; ?></div>
|
||||
<button class="btn-base btn-success" id="openCreateModal"><i class="fa fa-plus"></i><?php echo $t['work_create']; ?></button>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th><i class="fa fa-file-text"></i><?php echo $t['work_title']; ?></th>
|
||||
<th><i class="fa fa-user"></i><?php echo $t['work_creator']; ?></th>
|
||||
<th><i class="fa fa-user-o"></i><?php echo $t['work_handler']; ?></th>
|
||||
<th><i class="fa fa-tag"></i><?php echo $t['work_status']; ?></th>
|
||||
<th><i class="fa fa-calendar"></i><?php echo $t['work_create_time']; ?></th>
|
||||
<th><i class="fa fa-clock-o"></i><?php echo $t['work_update_time']; ?></th>
|
||||
<th><?php echo $t['work_assign']; ?> / <?php echo $t['work_edit']; ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (count($orderList) === 0): ?>
|
||||
<tr>
|
||||
<td colspan="8">
|
||||
<div class="empty-state">
|
||||
<div class="empty-icon"><i class="fa fa-ticket"></i></div>
|
||||
<div><?php echo $t['work_no_data']; ?></div>
|
||||
</div>
|
||||
</td>
|
||||
<?php else: ?>
|
||||
<?php foreach ($orderList as $item): ?>
|
||||
<?php
|
||||
$statusText = '';
|
||||
$statusClass = '';
|
||||
switch ($item['status']) {
|
||||
case 1: $statusText = $t['status_1']; $statusClass = 'status-1'; break;
|
||||
case 2: $statusText = $t['status_2']; $statusClass = 'status-2'; break;
|
||||
case 3: $statusText = $t['status_3']; $statusClass = 'status-3'; break;
|
||||
case 4: $statusText = $t['status_4']; $statusClass = 'status-4'; break;
|
||||
}
|
||||
?>
|
||||
<tr data-id="<?php echo $item['id']; ?>"
|
||||
data-title="<?php echo htmlspecialchars($item['title']); ?>"
|
||||
data-content="<?php echo htmlspecialchars($item['content']); ?>"
|
||||
data-assign="<?php echo $item['assign_uid']; ?>"
|
||||
data-status="<?php echo $item['status']; ?>">
|
||||
<td><?php echo $item['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($item['title']); ?></td>
|
||||
<td><?php echo $item['create_name'] ?? '-'; ?></td>
|
||||
<td><?php echo $item['assign_name'] ?? '-'; ?></td>
|
||||
<td><span class="status-tag <?php echo $statusClass; ?>"><?php echo $statusText; ?></span></td>
|
||||
<td><?php echo $item['create_time']; ?></td>
|
||||
<td><?php echo $item['update_time'] ?? '-'; ?></td>
|
||||
<td style="display:flex;gap:6px;align-items:center;">
|
||||
<?php if ($isAdmin === 1): ?>
|
||||
<select class="assign-user select-sm">
|
||||
<option value="">--</option>
|
||||
<?php echo $userOptions; ?>
|
||||
</select>
|
||||
<?php endif; ?>
|
||||
<select class="status-select select-sm">
|
||||
<option value="1" <?php echo $item['status']==1?'selected':''; ?>><?php echo $t['status_1']; ?></option>
|
||||
<option value="2" <?php echo $item['status']==2?'selected':''; ?>><?php echo $t['status_2']; ?></option>
|
||||
<option value="3" <?php echo $item['status']==3?'selected':''; ?>><?php echo $t['status_3']; ?></option>
|
||||
<option value="4" <?php echo $item['status']==4?'selected':''; ?>><?php echo $t['status_4']; ?></option>
|
||||
</select>
|
||||
<button class="btn-base btn-outline btn-sm edit-order"><i class="fa fa-edit"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- 极简分页,无多余分页面板卡片 -->
|
||||
<div class="page-pagination">
|
||||
<div><?php echo $currentLang==='zh'?'共 ':'Total '; ?><?php echo $total; ?> <?php echo $currentLang==='zh'?'条':'records'; ?></div>
|
||||
<div style="display:flex;gap:10px;align-items:center;">
|
||||
<?php if ($page > 1): ?>
|
||||
<button class="page-pag-btn" onclick="location.href='work_order.php?page=<?php echo $page-1; ?>'"><?php echo $currentLang==='zh'?'上一页':'Prev' ?></button>
|
||||
<?php endif; ?>
|
||||
<span><?php echo $currentLang==='zh'?'第':'Page '; ?><?php echo $page; ?> / <?php echo $totalPage; ?></span>
|
||||
<?php if ($page < $totalPage): ?>
|
||||
<button class="page-pag-btn" onclick="location.href='work_order.php?page=<?php echo $page+1; ?>'"><?php echo $currentLang==='zh'?'下一页':'Next' ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新建工单弹窗 -->
|
||||
<div class="modal-mask" id="createModal">
|
||||
<div class="modal-box">
|
||||
<div class="modal-head">
|
||||
<h3 class="title-left"><i class="fa fa-plus"></i><?php echo $t['work_create']; ?></h3>
|
||||
<span class="modal-close" id="closeCreateModal">×</span>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><?php echo $t['work_title']; ?></label>
|
||||
<input type="text" id="orderTitle" placeholder="<?php echo $t['work_placeholder_title']; ?>">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><?php echo $t['work_content']; ?></label>
|
||||
<textarea id="orderContent" placeholder="<?php echo $t['work_placeholder_content']; ?>"></textarea>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><?php echo $t['work_handler']; ?></label>
|
||||
<select id="orderAssign">
|
||||
<option value=""><?php echo $t['work_select_handler']; ?></option>
|
||||
<?php echo $userOptions; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn-base btn-primary" id="submitOrder"><i class="fa fa-save"></i><?php echo $t['work_save']; ?></button>
|
||||
<button class="btn-base btn-outline" id="resetForm"><?php echo $t['work_cancel']; ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 编辑工单弹窗 -->
|
||||
<div class="modal-mask" id="editModal">
|
||||
<div class="modal-box">
|
||||
<div class="modal-head">
|
||||
<h3 class="title-left"><i class="fa fa-edit"></i><?php echo $t['work_edit']; ?></h3>
|
||||
<span class="modal-close" id="closeEditModal">×</span>
|
||||
</div>
|
||||
<input type="hidden" id="editOrderId">
|
||||
<div class="form-row">
|
||||
<label><?php echo $t['work_title']; ?></label>
|
||||
<input type="text" id="editTitle">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><?php echo $t['work_content']; ?></label>
|
||||
<textarea id="editContent"></textarea>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label><?php echo $t['work_handler']; ?></label>
|
||||
<select id="editAssign">
|
||||
<option value="">--</option>
|
||||
<?php echo $userOptions; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn-base btn-primary" id="saveEdit"><i class="fa fa-save"></i><?php echo $t['work_save']; ?></button>
|
||||
<button class="btn-base btn-outline" id="cancelEdit"><?php echo $t['work_cancel']; ?></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const apiOrder = "./api/work_order_api.php";
|
||||
const loginUid = "<?php echo $loginUid; ?>";
|
||||
const isAdmin = <?php echo $isAdmin; ?>;
|
||||
const currentLang = "<?php echo $currentLang; ?>";
|
||||
|
||||
// 语言切换
|
||||
$("#langSwitch").change(function(){
|
||||
const newLang = $(this).val();
|
||||
fetch("./api/index.php",{
|
||||
method:"POST",
|
||||
headers:{"Content-Type":"application/x-www-form-urlencoded"},
|
||||
body:"act=save_lang&lang="+newLang
|
||||
}).then(()=>location.href = "work_order.php?_t="+new Date().getTime());
|
||||
})
|
||||
|
||||
// 弹窗控制
|
||||
$("#openCreateModal").click(()=>$("#createModal").css("display","flex"));
|
||||
$("#closeCreateModal,#resetForm").click(()=>$("#createModal").hide());
|
||||
$(document).on("click",".edit-order",function(){
|
||||
const tr = $(this).closest("tr");
|
||||
$("#editOrderId").val(tr.data("id"));
|
||||
$("#editTitle").val(tr.data("title"));
|
||||
$("#editContent").val(tr.data("content"));
|
||||
$("#editAssign").val(tr.data("assign"));
|
||||
$("#editModal").css("display","flex");
|
||||
});
|
||||
$("#closeEditModal,#cancelEdit").click(()=>$("#editModal").hide());
|
||||
|
||||
// 提交新建工单
|
||||
$("#submitOrder").click(function(){
|
||||
const title = $("#orderTitle").val().trim();
|
||||
const content = $("#orderContent").val().trim();
|
||||
const assign = $("#orderAssign").val();
|
||||
if(!title) return alert(currentLang==='zh'?"请填写工单标题":"Fill order title");
|
||||
if(!content) return alert(currentLang==='zh'?"请填写工单内容":"Fill order content");
|
||||
$.ajax({
|
||||
url: apiOrder + "?action=create",
|
||||
method: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify({title,content,assign_uid:assign}),
|
||||
dataType: "json",
|
||||
success(res){
|
||||
alert(res.msg);
|
||||
if(res.code === 0) location.reload();
|
||||
},
|
||||
error(){alert(currentLang==='zh'?"提交失败,接口异常":"Submit failed, API error")}
|
||||
})
|
||||
});
|
||||
|
||||
// 保存编辑工单
|
||||
$("#saveEdit").click(function(){
|
||||
const id = $("#editOrderId").val();
|
||||
const title = $("#editTitle").val().trim();
|
||||
const content = $("#editContent").val().trim();
|
||||
const assign = $("#editAssign").val();
|
||||
if(!title || !content) return alert(currentLang==='zh'?"标题和内容不能为空":"Title and content required");
|
||||
$.ajax({
|
||||
url: apiOrder + "?action=edit",
|
||||
method: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify({id,title,content,assign_uid:assign}),
|
||||
dataType: "json",
|
||||
success(res){
|
||||
alert(res.msg);
|
||||
if(res.code === 0) location.reload();
|
||||
},
|
||||
error(){alert(currentLang==='zh'?"编辑保存失败":"Edit save failed")}
|
||||
})
|
||||
});
|
||||
|
||||
// 修改工单状态
|
||||
$(document).on("change", ".status-select", function(){
|
||||
const tr = $(this).closest("tr");
|
||||
const id = tr.data("id");
|
||||
const status = $(this).val();
|
||||
$.ajax({
|
||||
url: apiOrder + "?action=update_status",
|
||||
method: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify({id,status}),
|
||||
dataType: "json",
|
||||
success(res){
|
||||
if(res.code !== 0) alert(res.msg);
|
||||
else location.reload();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// 管理员分发工单
|
||||
$(document).on("change", ".assign-user", function(){
|
||||
const tr = $(this).closest("tr");
|
||||
const id = tr.data("id");
|
||||
const assignUid = $(this).val();
|
||||
$.ajax({
|
||||
url: apiOrder + "?action=assign_order",
|
||||
method: "POST",
|
||||
contentType: "application/json",
|
||||
data: JSON.stringify({id,assign_uid:assignUid}),
|
||||
dataType: "json",
|
||||
success(res){
|
||||
if(res.code !== 0) alert(res.msg);
|
||||
else location.reload();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// 顶部时间刷新
|
||||
function updateTime() {
|
||||
const now = new Date();
|
||||
const Y = now.getFullYear();
|
||||
const M = String(now.getMonth() + 1).padStart(2, '0');
|
||||
const D = String(now.getDate()).padStart(2, '0');
|
||||
const h = String(now.getHours()).padStart(2, '0');
|
||||
const m = String(now.getMinutes()).padStart(2, '0');
|
||||
const s = String(now.getSeconds()).padStart(2, '0');
|
||||
$("#updateTime").text(`${Y}-${M}-${D} ${h}:${m}:${s}`);
|
||||
}
|
||||
function loadAllData(){
|
||||
updateTime();
|
||||
}
|
||||
$(function() {
|
||||
loadAllData();
|
||||
setInterval(updateTime, 1000);
|
||||
$("#logoutBtn").click(function(){location.href="logout.php";})
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user