316 lines
13 KiB
PHP
316 lines
13 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>用户管理 - 后台 - 笔记小站</title>
|
|
<link rel="stylesheet" href="css/style.css">
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<nav class="navbar">
|
|
<a class="navbar-brand" href="index.html"><span class="logo-icon">📝</span> 笔记小站</a>
|
|
<div class="navbar-actions" id="navbarActions"></div>
|
|
</nav>
|
|
|
|
<div class="admin-layout">
|
|
<aside class="admin-sidebar">
|
|
<nav class="admin-nav">
|
|
<a class="admin-nav-item" href="admin_categories.php">
|
|
<span>📂</span> 分类管理
|
|
</a>
|
|
<a class="admin-nav-item" href="admin_notes.php">
|
|
<span>📝</span> 笔记管理
|
|
</a>
|
|
<a class="admin-nav-item" href="admin_comments.php">
|
|
<span>💬</span> 评论管理
|
|
</a>
|
|
<a class="admin-nav-item active" href="admin_users.php">
|
|
<span>👥</span> 用户管理
|
|
</a>
|
|
</nav>
|
|
</aside>
|
|
|
|
<main class="admin-main">
|
|
<div class="admin-panel">
|
|
<div class="admin-panel-header">
|
|
<h3>👥 用户管理</h3>
|
|
<button class="btn btn-primary btn-sm" onclick="openUserModal(0)">+ 新增用户</button>
|
|
</div>
|
|
<div class="admin-panel-body">
|
|
<table class="admin-table">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>头像</th>
|
|
<th>用户名</th>
|
|
<th>邮箱</th>
|
|
<th>角色</th>
|
|
<th>时间</th>
|
|
<th>操作</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php
|
|
require 'function/db.php';
|
|
$sql = 'SELECT * FROM users where status = 1';
|
|
$result = mysqli_query($conn, $sql);
|
|
while ($row = mysqli_fetch_assoc($result)) {
|
|
$uid = $row['id'];
|
|
$username = $row['username'];
|
|
$email = $row['email'];
|
|
$avatar = !empty($row['avatar']) ? $row['avatar'] : '😊';
|
|
$role = !empty($row['role']) ? $row['role'] : 'user';
|
|
$roleText = ($role === 'admin') ? '管理员' : '普通用户';
|
|
$created = !empty($row['created_at']) ? $row['created_at'] : '—';
|
|
$password = $row['password'];
|
|
?>
|
|
<tr>
|
|
<td><?= $uid ?></td>
|
|
<td><?= $avatar ?></td>
|
|
<td><?= $username ?></td>
|
|
<td><?= $email ?></td>
|
|
<td><span class="badge badge-<?= $role ?>"><?= $roleText ?></span></td>
|
|
<td><?= $created ?></td>
|
|
<td class="actions">
|
|
<button class="btn btn-sm" onclick="openUserModal(<?= $uid ?>,'<?= $username ?>','<?= $email ?>','<?= $password ?>','<?= $role ?>')">编辑</button>
|
|
<button class="btn btn-sm btn-danger" onclick="deleteUser(<?= $uid ?>)">删除</button>
|
|
</td>
|
|
</tr>
|
|
<?php } ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- ==================== 新增 / 编辑用户 模态框 ==================== -->
|
|
<div class="modal-overlay" id="userModal" style="display:none;">
|
|
<div class="form-modal" onclick="event.stopPropagation()">
|
|
<h3 id="userModalTitle">新增用户</h3>
|
|
|
|
<!-- 隐藏域:编辑时存放用户 ID,新增时为 0 -->
|
|
<input type="hidden" id="fid" value="0">
|
|
|
|
<div class="form-group">
|
|
<label>用户名</label>
|
|
<input type="text" id="fname" placeholder="请输入用户名">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>邮箱</label>
|
|
<input type="text" id="femail" placeholder="请输入邮箱">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>密码</label>
|
|
<input type="password" id="fpassword" placeholder="新增时必填,编辑时留空则不修改">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>角色</label>
|
|
<select id="frole">
|
|
<option value="user">普通用户</option>
|
|
<option value="admin">管理员</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button class="btn" onclick="closeUserModal()">取消</button>
|
|
<button class="btn btn-primary" onclick="saveUser()">保存</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ==================== 删除确认模态框 ==================== -->
|
|
<div class="modal-overlay" id="deleteModal" style="display:none;">
|
|
<div class="form-modal" onclick="event.stopPropagation()">
|
|
<h3>⚠️ 确认删除</h3>
|
|
<input type="hidden" id="deleteId" value="">
|
|
<p style="margin-bottom:16px;">确定要删除该用户吗?此操作不可恢复。</p>
|
|
<div class="form-actions">
|
|
<button class="btn" onclick="closeDeleteModal()">取消</button>
|
|
<button class="btn btn-danger" onclick="confirmDeleteUser()">确认删除</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="toast-container" id="toastContainer"></div>
|
|
|
|
<script src="js/common.js"></script>
|
|
<script>
|
|
/* ==================== 用户模态框 ==================== */
|
|
|
|
/**
|
|
* 打开新增/编辑用户的模态框
|
|
* @param {number} id - 用户 ID,传 0 表示新增
|
|
*
|
|
* 编辑时请在此函数中拉取用户数据并填入表单:
|
|
* document.getElementById('fid').value = 用户ID
|
|
* document.getElementById('fname').value = 用户名
|
|
* document.getElementById('femail').value = 邮箱
|
|
* document.getElementById('fpassword').value = '' (编辑时密码留空)
|
|
* document.getElementById('frole').value = 角色 (user / admin)
|
|
*/
|
|
function openUserModal(id,username='',email='',password='', role='') {
|
|
var titleEl = document.getElementById('userModalTitle');
|
|
var fidEl = document.getElementById('fid');
|
|
var nameEl = document.getElementById('fname');
|
|
var emailEl = document.getElementById('femail');
|
|
var pwdEl = document.getElementById('fpassword');
|
|
var roleEl = document.getElementById('frole');
|
|
|
|
if (id === 0) {
|
|
// ---- 新增模式 ----
|
|
titleEl.textContent = '新增用户';
|
|
fidEl.value = '0';
|
|
nameEl.value = '';
|
|
emailEl.value = '';
|
|
pwdEl.value = '';
|
|
pwdEl.placeholder = '请设置密码';
|
|
roleEl.value = 'user';
|
|
} else {
|
|
// ---- 编辑模式 ----
|
|
titleEl.textContent = '编辑用户';
|
|
fidEl.value = id;
|
|
pwdEl.value = '';
|
|
pwdEl.placeholder = '留空则不修改密码';
|
|
|
|
// TODO: 开发者自行拉取用户数据并填入以下字段
|
|
// 示例:
|
|
nameEl.value = username;
|
|
emailEl.value = email;
|
|
roleEl.value = role;
|
|
}
|
|
|
|
document.getElementById('userModal').style.display = 'flex';
|
|
}
|
|
|
|
/** 关闭用户模态框 */
|
|
function closeUserModal() {
|
|
document.getElementById('userModal').style.display = 'none';
|
|
document.getElementById('fid').value = '0';
|
|
}
|
|
|
|
/**
|
|
* 保存用户(新增或编辑)
|
|
* 开发者在此处实现提交逻辑(Ajax / 表单提交)
|
|
*/
|
|
function saveUser() {
|
|
var id = document.getElementById('fid').value;
|
|
var username = document.getElementById('fname').value.trim();
|
|
var email = document.getElementById('femail').value.trim();
|
|
var password = document.getElementById('fpassword').value;
|
|
var role = document.getElementById('frole').value;
|
|
|
|
// 前端校验
|
|
if (!username || !email) {
|
|
showToast('请填写用户名和邮箱', 'error');
|
|
return;
|
|
}
|
|
|
|
// 新增时密码必填
|
|
if (id === '0' && !password) {
|
|
showToast('请设置密码', 'error');
|
|
return;
|
|
}
|
|
|
|
// 判断是新增还是编辑
|
|
if(id === '0'){
|
|
var action = "register";
|
|
}else{
|
|
var action = "update";
|
|
}
|
|
|
|
fetch('/function/user.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
'action': action,
|
|
'id': id,
|
|
'username': username,
|
|
'email': email,
|
|
'password': password,
|
|
'role' : role,
|
|
})
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.code === 0) {
|
|
showToast(data.message, 'success');
|
|
setTimeout(() => {
|
|
location.href = location.href;
|
|
}, 1000);
|
|
} else {
|
|
showToast(data.message, 'error');
|
|
}
|
|
})
|
|
.catch(err => {
|
|
showToast(err.message, 'error');
|
|
});
|
|
|
|
closeUserModal();
|
|
|
|
}
|
|
|
|
/* ==================== 删除确认模态框 ==================== */
|
|
|
|
/** 打开删除确认弹窗 */
|
|
function deleteUser(id) {
|
|
document.getElementById('deleteId').value = id;
|
|
document.getElementById('deleteModal').style.display = 'flex';
|
|
}
|
|
|
|
/** 关闭删除弹窗 */
|
|
function closeDeleteModal() {
|
|
document.getElementById('deleteModal').style.display = 'none';
|
|
}
|
|
|
|
/** 确认删除 */
|
|
function confirmDeleteUser() {
|
|
var id = document.getElementById('deleteId').value;
|
|
|
|
fetch('/function/user.php', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
'action': 'delete',
|
|
'id': id
|
|
})
|
|
})
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
if (data.code === 0) {
|
|
showToast('删除成功', 'success');
|
|
setTimeout(() => {
|
|
location.href = location.href;
|
|
}, 1000);
|
|
} else {
|
|
showToast(data.message, 'error');
|
|
}
|
|
})
|
|
.catch(err => {
|
|
showToast(err.message, 'error');
|
|
});
|
|
|
|
closeDeleteModal();
|
|
|
|
// 删除成功后刷新列表:
|
|
// window.location.reload();
|
|
}
|
|
|
|
/* ==================== 点击遮罩关闭模态框 ==================== */
|
|
document.getElementById('userModal').addEventListener('click', function(e) {
|
|
if (e.target === this) closeUserModal();
|
|
});
|
|
document.getElementById('deleteModal').addEventListener('click', function(e) {
|
|
if (e.target === this) closeDeleteModal();
|
|
});
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|