Files
freeshop/admin/admins.php
T
2026-08-14 10:55:06 +08:00

203 lines
10 KiB
PHP

<?php
// 后台:管理员 / 客服账户管理(增删改角色 + 终极管理员保护)
require __DIR__ . '/../includes/init.php';
requireStaff();
require '_common.php';
$isAdmin = isAdminStaff();
$me = currentStaff();
$db = db();
$msg = '';
$err = '';
// 客服只读
if (!$isAdmin && $_SERVER['REQUEST_METHOD'] === 'POST') {
$err = '客服账号仅可查看,如需操作请联系管理员。';
}
// ─── 编辑角色(admin ↔ cs)────
if (isset($_POST['edit_role']) && $isAdmin) {
verifyCsrf();
$id = (int) ($_POST['edit_role'] ?? 0);
$role = trim($_POST['new_role'] ?? '');
$role = in_array($role, ['admin', 'cs'], true) ? $role : '';
if ($id <= 0 || $role === '') {
$err = '参数不合法。';
} elseif ($id === (int) $me['id']) {
$err = '不能修改当前登录账号的角色。';
} elseif ($id === 1) {
$err = '不能修改终极管理员(ID=1)的角色。';
} else {
$row = $db->prepare('SELECT id, role, is_admin FROM ' . tn('users') . ' WHERE id = ? AND role IN (\'admin\',\'cs\')')->execute([$id])->fetch();
if (!$row) {
$err = '账号不存在。';
} else {
$newIsAdmin = ($role === 'admin') ? 1 : 0;
$db->prepare('UPDATE ' . tn('users') . ' SET role = ?, is_admin = ? WHERE id = ?')
->execute([$role, $newIsAdmin, $id]);
$msg = '已将账号 #' . $id . ' 角色改为「' . ($role === 'admin' ? '管理员' : '客服') . '」。';
}
}
}
// ─── 删除 ──
if (isset($_POST['delete']) && $isAdmin) {
verifyCsrf();
$id = (int) ($_POST['delete'] ?? 0);
if ($id === (int) $me['id']) {
$err = '不能删除当前登录的账号。';
} elseif ($id === 1) {
$err = '不能删除终极管理员(ID=1),该账号受系统保护。';
} else {
$row = $db->prepare('SELECT id, role, is_admin FROM ' . tn('users') . ' WHERE id = ? AND role IN (\'admin\',\'cs\')')->execute([$id])->fetch();
if (!$row) {
$err = '账号不存在。';
} elseif ((int) $row['is_admin'] === 1) {
// 管理员:确保至少保留一名管理员(含终极管理员)
$cnt = $db->query('SELECT COUNT(*) FROM ' . tn('users') . ' WHERE role = \'admin\' AND status = 1')->fetchColumn();
if ((int) $cnt <= 1) {
$err = '至少要保留一名管理员,不能继续删除。';
} else {
$db->prepare('DELETE FROM ' . tn('users') . ' WHERE id = ?')->execute([$id]);
$msg = '管理员已删除。';
}
} else {
$db->prepare('DELETE FROM ' . tn('users') . ' WHERE id = ?')->execute([$id]);
$msg = '客服已删除。';
}
}
}
// ─── 添加 ──
if (isset($_POST['add']) && $isAdmin) {
verifyCsrf();
$u = trim($_POST['username'] ?? '');
$em = trim($_POST['email'] ?? '');
$pw = $_POST['password'] ?? '';
$role = trim($_POST['role'] ?? 'admin');
$role = in_array($role, ['admin', 'cs'], true) ? $role : 'admin';
if (strlen($u) < 3) $err = '账号至少 3 个字符。';
elseif (!filter_var($em, FILTER_VALIDATE_EMAIL)) $err = '请填写有效的邮箱。';
elseif (strlen($pw) < 6) $err = '密码至少 6 位。';
else {
$chk = $db->prepare('SELECT id FROM ' . tn('users') . ' WHERE username = ?');
$chk->execute([$u]);
if ($chk->fetch()) {
$err = '该用户名已存在。';
} else {
$hash = password_hash($pw, PASSWORD_DEFAULT);
$code = genInviteCode();
$isAdminFlag = $role === 'admin' ? 1 : 0;
$db->prepare('INSERT INTO ' . tn('users') . ' (username,password,email,invite_code,is_admin,role,created_at) VALUES (?,?,?,?,?,?,NOW())')
->execute([$u, $hash, $em, $code, $isAdminFlag, $role]);
$msg = ($role === 'admin' ? '管理员' : '客服') . '已添加。';
}
}
}
$list = $db->query('SELECT id, username, email, status, role, created_at FROM ' . tn('users') . ' WHERE role IN (\'admin\',\'cs\') ORDER BY role DESC, id ASC')->fetchAll();
adminHeader('管理员', 'admins');
?>
<h1 class="page-title"><i class="fas fa-user-shield"></i> 管理员与客服</h1>
<?php if ($msg): ?><p class="banner-ok"><i class="fas fa-check-circle"></i> <?= h($msg) ?></p><?php endif; ?>
<?php if ($err): ?><p class="form-err"><?= h($err) ?></p><?php endif; ?>
<div class="panel">
<h3>添加账号(管理员 / 客服)</h3>
<?php if ($isAdmin): ?>
<p class="muted">管理员拥有全部后台权限;客服可查看所有页面但仅能处理工单相关操作。</p>
<form method="post" action="" class="grid-form" style="max-width:680px;">
<?= csrfField() ?>
<label>账号 *<input type="text" name="username" placeholder="至少 3 个字符" required></label>
<label>邮箱 *<input type="email" name="email" required></label>
<label>角色
<select name="role">
<option value="admin">管理员(全部权限)</option>
<option value="cs">客服(查看 + 工单操作)</option>
</select>
</label>
<label class="span2">密码 *<input type="password" name="password" placeholder="至少 6 位密码" required></label>
<div class="form-actions span2"><button type="submit" name="add" class="btn btn-primary"><i class="fas fa-user-plus"></i> 添加账号</button></div>
</form>
<?php else: ?>
<p class="muted">客服账号无法添加新管理员,如需操作请联系管理员。</p>
<?php endif; ?>
</div>
<div class="panel">
<h3>账号列表(共 <?= count($list) ?> 名)</h3>
<?php if (empty($list)): ?>
<p class="empty">暂无账号。</p>
<?php else: ?>
<table class="data-table">
<thead><tr><th>ID</th><th>账号</th><th>邮箱</th><th>角色</th><th>状态</th><th>注册时间</th><th>操作</th></tr></thead>
<tbody>
<?php foreach ($list as $a): ?>
<?php
$isMe = (int)$a['id'] === (int)$me['id'];
$isSuper = (int)$a['id'] === 1;
$isAdm = ($a['role'] === 'admin');
?>
<tr <?= $isSuper ? 'style="background:color-mix(in srgb,var(--primary) 6%,transparent)"' : '' ?>>
<td><?= (int) $a['id'] ?><?= $isSuper ? ' <sup style="color:var(--primary);font-size:.72rem">超级</sup>' : '' ?></td>
<td><?= h($a['username']) ?><?= $isMe ? ' <span class="badge-on">我</span>' : '' ?></td>
<td><?= h($a['email']) ?></td>
<td>
<?php if ($isAdmin && !$isMe && !$isSuper): ?>
<form method="post" action="" style="display:inline" onsubmit="return confirmRoleChange(<?= (int) $a['id'] ?>, '<?= h($a['username']) ?>');">
<?= csrfField() ?>
<input type="hidden" name="edit_role" value="<?= (int) $a['id'] ?>">
<select name="new_role" onchange="this.form.submit()" style="padding:2px 6px;border:1px solid var(--outline);border-radius:6px;font-size:.82rem;cursor:pointer;background:transparent;color:inherit">
<option value="admin" <?php if ($isAdm): ?>selected<?php endif; ?>>管理员</option>
<option value="cs" <?php if (!$isAdm): ?>selected<?php endif; ?>>客服</option>
</select>
</form>
<?php else: ?>
<?php if ($isAdm): ?>
<span class="badge-on">管理员</span>
<?php else: ?>
<span class="badge-on" style="background:var(--primary-container);color:var(--on-primary-container)">客服</span>
<?php endif; ?>
<?php if ($isSuper): ?><span class="muted" style="font-size:.75rem;margin-left:4px">(受保护)</span><?php endif; ?>
<?php endif; ?>
</td>
<td><?= (int) $a['status'] === 1 ? '<span class="badge-on">正常</span>' : '<span class="badge-off">封禁</span>' ?></td>
<td><?= date('Y-m-d', strtotime($a['created_at'])) ?></td>
<td class="row-actions">
<?php if ($isMe): ?>
<span class="muted">当前账号</span>
<?php elseif ($isAdmin): ?>
<?php if ($isSuper): ?>
<span class="muted" title="终极管理员受系统保护,不可删除"><i class="fas fa-shield-halved" style="color:var(--primary)"></i> 受保护</span>
<?php else: ?>
<form method="post" action="" style="display:inline" onsubmit="return confirm('确定删除该账号?此操作不可恢复。');">
<?= csrfField() ?>
<button type="submit" name="delete" value="<?= (int) $a['id'] ?>" class="mini-btn danger"><i class="fas fa-trash"></i></button>
</form>
<?php endif; ?>
<?php else: ?>
<span class="muted">—</span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php if ($isAdmin): ?>
<p class="muted" style="margin-top:10px;font-size:.82rem">
<i class="fas fa-info-circle"></i> 终极管理员(ID=1)受系统保护,不可被删除或降级。其他管理员可由同级管理员删除或改为客服。
</p>
<?php endif; ?>
<?php endif; ?>
</div>
<script>
function confirmRoleChange(id, name) {
var sel = event.target.form.elements.new_role;
var roleLabel = sel.options[sel.selectedIndex].text;
return confirm('确定将 ' + name + ' 的角色改为「' + roleLabel + '」?');
}
</script>
<?php adminFooter(); ?>