Files
2026-07-09 16:31:30 +08:00

415 lines
21 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php require_once 'auth.php';
$pageTitle = "系统权限管理";
$activeTab = $_GET['tab'] ?? 'role';
$conn = $connMonitor;
require_once 'auth.php';
// ========== 角色操作逻辑 ==========
if ($_POST['act'] == "save_role") {
$roleName = trim($_POST['role_name']);
$roleId = intval($_POST['role_id'] ?? 0);
$pages = $_POST['page_perm'] ?? [];
if (empty($roleName)) {
echo "<script>alert('角色名称不能为空');location.href='system_manage.php?tab=role';</script>";
exit;
}
if ($roleId == 0) {
mysqli_query($conn, "INSERT INTO sys_role(role_name) VALUES('".mysqli_real_escape_string($conn,$roleName)."')");
$roleId = mysqli_insert_id($conn);
} else {
mysqli_query($conn, "UPDATE sys_role SET role_name='".mysqli_real_escape_string($conn,$roleName)."' WHERE id=$roleId");
mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$roleId");
}
foreach ($pages as $page) {
$page = mysqli_real_escape_string($conn, $page);
mysqli_query($conn, "INSERT IGNORE INTO sys_role_permission(role_id,page_key) VALUES($roleId,'$page')");
}
echo "<script>alert('角色保存成功');location.href='system_manage.php?tab=role';</script>";
exit;
}
if (!empty($_GET['del_role'])) {
$delId = intval($_GET['del_role']);
mysqli_query($conn, "DELETE FROM sys_role_permission WHERE role_id=$delId");
mysqli_query($conn, "DELETE FROM sys_role WHERE id=$delId");
header("Location: system_manage.php?tab=role");
exit;
}
// 修复警告:强制初始化为空数组,in_array不会报null
$editRole = ['id'=>0,'role_name'=>'','perms'=>[]];
if (!empty($_GET['edit_role'])) {
$eid = intval($_GET['edit_role']);
$er = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_role WHERE id=$eid"));
if ($er) {
$editRole = $er;
$permRes = mysqli_query($conn, "SELECT page_key FROM sys_role_permission WHERE role_id=$eid");
$permsArr = [];
while ($p = mysqli_fetch_assoc($permRes)) {
$permsArr[] = $p['page_key'];
}
$editRole['perms'] = $permsArr;
}
}
$roleList = [];
$roleRes = mysqli_query($conn, "SELECT * FROM sys_role ORDER BY id DESC");
while ($r = mysqli_fetch_assoc($roleRes)) $roleList[] = $r;
// ========== 用户操作逻辑(沿用bak可创建逻辑 + 自动生成uid修复空值) ==========
if ($_POST['act'] == "save_user") {
$uid = intval($_POST['user_id'] ?? 0);
$username = trim($_POST['username']);
$realName = trim($_POST['real_name']);
$roleId = intval($_POST['role_id']);
$pwd = trim($_POST['password']);
$status = intval($_POST['status']);
if (empty($username) || empty($realName) || $roleId == 0) {
echo "<script>alert('账号、姓名、角色不能为空');location.href='system_manage.php?tab=user';</script>";
exit;
}
if ($uid == 0) {
if (empty($pwd)) {
echo "<script>alert('新建用户必须填写密码');location.href='system_manage.php?tab=user';</script>";
exit;
}
// 自动生成唯一数字uid,解决空uid问题
$maxUidRow = mysqli_fetch_assoc(mysqli_query($conn, "SELECT MAX(CAST(uid AS UNSIGNED)) max_uid FROM sys_user"));
$newUid = empty($maxUidRow['max_uid']) ? 1000 : intval($maxUidRow['max_uid']) + 1;
$pwdHash = password_hash($pwd, PASSWORD_DEFAULT);
// INSERT 补充uid字段,不再空白
$insertSql = "INSERT INTO sys_user(uid,username,real_name,password,role_id,enable,is_admin)
VALUES('$newUid','".mysqli_real_escape_string($conn,$username)."','".mysqli_real_escape_string($conn,$realName)."','$pwdHash',$roleId,$status,0)";
mysqli_query($conn, $insertSql);
} else {
$updateSql = "UPDATE sys_user SET
username='".mysqli_real_escape_string($conn,$username)."',
real_name='".mysqli_real_escape_string($conn,$realName)."',
role_id=$roleId,
enable=$status
WHERE id=$uid";
if (!empty($pwd)) {
$pwdHash = password_hash($pwd, PASSWORD_DEFAULT);
$updateSql .= ", password='$pwdHash'";
}
mysqli_query($conn, $updateSql);
}
echo "<script>alert('用户保存成功');location.href='system_manage.php?tab=user';</script>";
exit;
}
if (!empty($_GET['del_user'])) {
$delId = intval($_GET['del_user']);
mysqli_query($conn, "DELETE FROM sys_user_msg WHERE user_id=$delId");
mysqli_query($conn, "DELETE FROM sys_user WHERE id=$delId");
header("Location: system_manage.php?tab=user");
exit;
}
$roleOptionHtml = "";
$roleDropRes = mysqli_query($conn, "SELECT id,role_name FROM sys_role");
while ($r = mysqli_fetch_assoc($roleDropRes)) {
$roleOptionHtml .= "<option value='{$r['id']}'>{$r['role_name']}</option>";
}
// 用户列表过滤空uid异常用户
$userList = [];
$uRes = mysqli_query($conn, "SELECT u.*,r.role_name FROM sys_user u LEFT JOIN sys_role r ON u.role_id=r.id WHERE u.uid <> '' ORDER BY u.id DESC");
while ($u = mysqli_fetch_assoc($uRes)) $userList[] = $u;
$editUser = ['id'=>0,'username'=>'','real_name'=>'','role_id'=>0,'status'=>1];
if (!empty($_GET['edit_user'])) {
$eid = intval($_GET['edit_user']);
$eu = mysqli_fetch_assoc(mysqli_query($conn, "SELECT * FROM sys_user WHERE id=$eid"));
if ($eu) $editUser = $eu;
}
$allPagePerms = [
['key'=>'dashboard','name'=>'告警总览'],
['key'=>'work_order','name'=>'工单系统'],
['key'=>'disk','name'=>'磁盘容量'],
['key'=>'history_query','name'=>'历史查询'],
['key'=>'smtp_config','name'=>'消息通知配置'],
['key'=>'system_manage','name'=>'系统权限管理'],
['key'=>'docker_mgr','name'=>'Docker容器管理'],
];
?>
<!DOCTYPE html>
<html lang="<?php echo $t['html_lang']; ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $pageTitle; ?></title>
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
<script src="/static/js/jquery.min.js"></script>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{background:#f8fafc;font-family:"Inter","PingFang SC","Microsoft YaHei",sans-serif;color:#1e293b;line-height:1.5;display:flex;flex-direction:column;height:100vh;overflow:hidden;font-size:13px;}
.wrap-main{display:flex;flex:1;overflow:hidden;}
/* 侧边栏 */
.sidebar{width:220px;background:#152c5b;color:#cbd5e1;flex-shrink:0;overflow-y:auto;}
.sidebar-brand{padding:20px 16px;border-bottom:1px solid rgba(255,255,255,0.06);}
.sidebar-brand-en{font-size:18px;font-weight:700;color:#fff;letter-spacing:1px;}
.sidebar-brand-cn{font-size:12px;color:#a5b4fc;margin-top:4px;}
.sidebar-menu{padding:12px 0;}
.menu-title{padding:8px 16px 4px;font-size:11px;color:#94a3b8;text-transform:uppercase;letter-spacing:1px;}
.menu-item{display:flex;align-items:center;gap:10px;padding:10px 16px;cursor:pointer;font-size:13px;color:#cbd5e1;transition:0.2s;}
.menu-item i{width:18px;text-align:center;font-size:14px;}
.menu-item.active{background:rgba(37,99,235,0.15);color:#fff;border-left:4px solid #2563eb;}
.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 紧凑整洁 */
.header{background:#fff;border-bottom:1px solid #e2e8f0;padding:12px 20px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0;}
.header-left{display:flex;align-items:center;gap:12px;}
.header-brand-en{font-size:20px;font-weight:700;color:#152c5b;}
.header-brand-cn{font-size:12px;color:#64748b;}
.header-right{display:flex;align-items:center;gap:12px;font-size:12px;flex-wrap:wrap;}
.user-info,.time-info,.lang-box{display:flex;align-items:center;gap:4px;color:#475569;}
.lang-box select{padding:3px 6px;border:1px solid #cbd5e1;border-radius:4px;font-size:12px;}
.msg-badge{position:relative;cursor:pointer;}
.msg-badge span{position:absolute;top:-5px;right:-5px;background:#ef4444;color:#fff;font-size:10px;border-radius:99px;width:14px;height:14px;text-align:center;line-height:14px;}
/* 按钮 */
.btn-base{border:none;padding:7px 16px;border-radius:6px;cursor:pointer;font-size:12px;font-weight:500;display:flex;align-items:center;gap:6px;transition:0.2s;}
.btn-outline{background:#fff;color:#152c5b;border:1px solid #cbd5e1;}
.btn-outline:hover{background:#f1f5f9;}
.btn-primary{background:#2563eb;color:#fff;box-shadow:0 2px 8px rgba(37,99,235,0.15);}
.btn-primary:hover{background:#1d4ed8;}
/* 容器 */
.container{padding:16px 20px;flex:1;}
/* 卡片100%自适应宽度,移除max-width */
.base-card{background:#fff;border-radius:12px;padding:20px;border:1px solid #e2e8f0;box-shadow:0 1px 2px rgba(0,0,0,0.04);width:100%;margin-bottom:16px;}
.title-wrap{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;color:#152c5b;margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid #f1f5f9;}
.title-wrap i{color:#2563eb;font-size:16px;}
/* Tab */
.tab-wrap{display:flex;gap:2px;margin-bottom:16px;border-bottom:1px solid #e2e8f0;}
.tab-item{padding:8px 18px;cursor:pointer;border-bottom:2px solid transparent;color:#64748b;font-size:12px;font-weight:500;}
.tab-item.active{color:#2563eb;border-bottom-color:#2563eb;}
.tab-content{display:none;}
.tab-content.show{display:block;}
/* 表单响应式 */
.form-row{margin-bottom:14px;}
.form-row label{display:block;margin-bottom:4px;font-size:12px;font-weight:500;color:#334155;}
.form-row input,.form-row select{width:320px;height:36px;padding:0 12px;border:1px solid #d1d5db;border-radius:6px;font-size:12px;background:#f8fafc;transition:0.2s;}
.form-row input:hover,.form-row select:hover{border-color:#94a3b8;background:#fff;}
.form-row input:focus,.form-row select:focus{outline:none;border-color:#2563eb;box-shadow:0 0 0 2px rgba(37,99,235,0.1);background:#fff;}
/* 权限勾选 完全匹配你要求的3列自适应布局 */
.check-group{
display:grid;
grid-template-columns:repeat(3,max-content);
gap:10px 30px;
margin:8px 0 14px;
}
.check-item{
display:flex;
align-items:center;
gap:4px;
padding:6px 0;
border:none;
background:transparent;
font-size:12px;
white-space:nowrap;
}
/* 表格外层滚动容器,解决溢出 */
.table-wrap{width:100%;overflow-x:auto;margin-top:12px;}
table{min-width:700px;width:100%;border-collapse:collapse;}
th,td{border:1px solid #e2e8f0;padding:10px 12px;font-size:12px;text-align:left;white-space:nowrap;}
th{background:#f8fafc;font-weight:600;color:#1e293b;}
.operate a{margin-right:8px;color:#2563eb;text-decoration:none;font-size:12px;}
.operate a.del{color:#dc2626;}
/* 媒体查询 多分辨率兼容 */
@media screen and (max-width:1366px){
.sidebar{width:200px;}
.form-row input,.form-row select{width:280px;}
}
@media screen and (max-width:1080px){
.sidebar{width:180px;}
.form-row input,.form-row select{width:100%;}
}
@media screen and (max-width:768px){
.wrap-main{flex-direction:column;}
.sidebar{width:100%;height:auto;}
.container{padding:12px 14px;}
.header-right{gap:8px;flex-wrap:wrap;}
/* 移动端自动改为单列,防止横向溢出 */
.check-group{grid-template-columns:repeat(1, max-content);gap:10px 0;}
}
input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}
input[type="number"]{-moz-appearance:textfield;}
</style>
</head>
<body>
<div class="wrap-main">
<div class="sidebar">
<div class="sidebar-brand">
<div class="sidebar-brand-en">Advantest</div>
<div class="sidebar-brand-cn"><?php echo $pageTitle; ?></div>
</div>
<div class="sidebar-menu">
<div class="menu-title">业务模块</div>
<div class="menu-item" onclick="location.href='dashboard.php'"><i class="fa fa-line-chart"></i><span>告警总览</span></div>
<div class="menu-item" onclick="location.href='work_order.php'"><i class="fa fa-ticket"></i><span>工单系统</span></div>
<div class="menu-item" onclick="location.href='alert_list.php'"><i class="fa fa-search"></i><span>历史查询</span></div>
<div class="menu-title">系统管理</div>
<div class="menu-item" onclick="location.href='smtp_config.php'"><i class="fa fa-bell"></i><span>消息通知配置</span></div>
<div class="menu-item active"><i class="fa fa-cogs"></i><span>系统权限管理</span></div>
</div>
</div>
<div class="main-content">
<div class="header">
<div class="header-left">
<div>
<div class="header-brand-en">Advantest</div>
<div class="header-brand-cn"><?php echo $pageTitle; ?></div>
</div>
</div>
<div class="header-right">
<span class="msg-badge" onclick="location.href='work_order.php'">
<i class="fa fa-bell-o"></i>
<?php if($unreadMsgCount>0):?><span><?php echo $unreadMsgCount; ?></span><?php endif;?>
</span>
<span class="user-info"><i class="fa fa-user-circle"></i><?php echo $t['current_user']; ?><?php echo $userName; ?><?php echo $roleRealName; ?></span>
<span class="time-info"><i class="fa fa-clock-o"></i><span id="nowTime">--</span></span>
<div class="lang-box">
<select id="langSwitch">
<option value="zh" <?php echo $currentLang=='zh'?'selected':''; ?>>中文</option>
<option value="en" <?php echo $currentLang=='en'?'selected':''; ?>>EN</option>
</select>
</div>
<button class="btn-base btn-outline" onclick="location.reload()"><i class="fa fa-refresh"></i><?php echo $t['refresh']; ?></button>
<button class="btn-base btn-primary" onclick="location.href='logout.php'"><i class="fa fa-sign-out"></i><?php echo $t['logout']; ?></button>
</div>
</div>
<div class="container">
<div class="base-card">
<div class="title-wrap"><i class="fa fa-cogs"></i><?php echo $pageTitle; ?></div>
<div class="tab-wrap">
<div class="tab-item <?php echo $activeTab=='role'?'active':''; ?>" data-tab="role">角色管理</div>
<div class="tab-item <?php echo $activeTab=='user'?'active':''; ?>" data-tab="user">用户管理</div>
</div>
<!-- 角色Tab -->
<div class="tab-content <?php echo $activeTab=='role'?'show':''; ?>" id="tab-role">
<form method="post">
<input type="hidden" name="act" value="save_role">
<input type="hidden" name="role_id" value="<?php echo $editRole['id']; ?>">
<div class="form-row">
<label>角色名称</label>
<input name="role_name" value="<?php echo htmlspecialchars($editRole['role_name']); ?>" placeholder="例:运维人员">
</div>
<div class="form-row">
<label>可访问页面权限(勾选)</label>
<div class="check-group">
<?php foreach ($allPagePerms as $p): ?>
<div class="check-item">
<input type="checkbox" name="page_perm[]" value="<?php echo $p['key']; ?>" id="p_<?php echo $p['key']; ?>"
<?php echo in_array($p['key'],$editRole['perms'])?'checked':''; ?>>
<label for="p_<?php echo $p['key']; ?>"><?php echo $p['name']; ?></label>
</div>
<?php endforeach; ?>
</div>
</div>
<button class="btn-base btn-primary" type="submit"><i class="fa fa-save"></i>保存角色</button>
</form>
<div class="table-wrap">
<table>
<tr>
<th>ID</th>
<th>角色名称</th>
<th>操作</th>
</tr>
<?php foreach ($roleList as $r): ?>
<tr>
<td><?php echo $r['id']; ?></td>
<td><?php echo htmlspecialchars($r['role_name']); ?></td>
<td class="operate">
<a href="?tab=role&edit_role=<?php echo $r['id']; ?>">编辑</a>
<a href="?tab=role&del_role=<?php echo $r['id']; ?>" class="del" onclick="return confirm('确认删除该角色?')">删除</a>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
</div>
<!-- 用户Tab -->
<div class="tab-content <?php echo $activeTab=='user'?'show':''; ?>" id="tab-user">
<form method="post">
<input type="hidden" name="act" value="save_user">
<input type="hidden" name="user_id" value="<?php echo $editUser['id']; ?>">
<div class="form-row">
<label>登录账号</label>
<input name="username" value="<?php echo htmlspecialchars($editUser['username']); ?>" placeholder="登录账号">
</div>
<div class="form-row">
<label>真实姓名</label>
<input name="real_name" value="<?php echo htmlspecialchars($editUser['real_name']); ?>" placeholder="员工姓名">
</div>
<div class="form-row">
<label>所属角色</label>
<select name="role_id">
<option value="">请选择角色</option>
<?php echo $roleOptionHtml; ?>
</select>
<script>$("select[name=role_id]").val(<?php echo $editUser['role_id']; ?>)</script>
</div>
<div class="form-row">
<label>登录密码(编辑留空不修改)</label>
<input name="password" type="password" placeholder="新建用户必填">
</div>
<div class="form-row">
<label>账号状态</label>
<select name="status">
<option value="1">启用</option>
<option value="0">禁用</option>
</select>
<script>$("select[name=status]").val(<?php echo $editUser['status']; ?>)</script>
</div>
<button class="btn-base btn-primary" type="submit"><i class="fa fa-save"></i>保存用户</button>
</form>
<div class="table-wrap">
<table>
<tr>
<th>ID</th>
<th>登录账号</th>
<th>姓名</th>
<th>所属角色</th>
<th>状态</th>
<th>操作</th>
</tr>
<?php foreach ($userList as $u): ?>
<tr>
<td><?php echo $u['id']; ?></td>
<td><?php echo htmlspecialchars($u['username']); ?></td>
<td><?php echo htmlspecialchars($u['real_name']); ?></td>
<td><?php echo htmlspecialchars($u['role_name'] ?? '无'); ?></td>
<td><?php echo $u['enable']==1?'启用':'禁用'; ?></td>
<td class="operate">
<a href="?tab=user&edit_user=<?php echo $u['id']; ?>">编辑</a>
<a href="?tab=user&del_user=<?php echo $u['id']; ?>" class="del" onclick="return confirm('确认删除该用户?')">删除</a>
</td>
</tr>
<?php endforeach; ?>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(".tab-item").click(function(){
const tab = $(this).data("tab");
location.href = "system_manage.php?tab="+tab;
})
function updateNowTime(){
const d=new Date();
const Y=d.getFullYear();
const M=String(d.getMonth()+1).padStart(2,'0');
const D=String(d.getDate()).padStart(2,'0');
const h=String(d.getHours()).padStart(2,'0');
const m=String(d.getMinutes()).padStart(2,'0');
const s=String(d.getSeconds()).padStart(2,'0');
$("#nowTime").text(`${Y}-${M}-${D} ${h}:${m}:${s}`);
}
setInterval(updateNowTime,1000);
updateNowTime();
$("#langSwitch").change(function(){
const lang = $(this).val();
$.post("system_manage.php",{action:"save_lang",lang:lang},()=>location.reload());
})
</script>
</body>
</html>