182 行
9.0 KiB
PHP
182 行
9.0 KiB
PHP
<?php
|
|
require __DIR__ . '/../includes/init.php';
|
|
requireStaff();
|
|
require '_common.php';
|
|
$isAdmin = isAdminStaff();
|
|
$db = db();
|
|
$msg = '';
|
|
$err = '';
|
|
if (!$isAdmin && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$err = '客服账号仅可查看,如需操作请联系管理员。';
|
|
}
|
|
if (isset($_POST['toggle'])) {
|
|
verifyCsrf();
|
|
$id = (int) ($_POST['toggle'] ?? 0);
|
|
$stmt = $db->prepare('SELECT id, is_admin, status FROM ' . tn('users') . ' WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
$row = $stmt->fetch();
|
|
if (!$row) {
|
|
$err = '用户不存在';
|
|
} elseif ((int) $row['is_admin'] === 1) {
|
|
$err = '不能对管理员执行该操作';
|
|
} else {
|
|
$next = ((int) $row['status'] === 1) ? 0 : 1;
|
|
$db->prepare('UPDATE ' . tn('users') . ' SET status = ? WHERE id = ?')->execute([$next, $id]);
|
|
$msg = $next === 0 ? '该用户已被封禁,无法再登录。' : '已解除封禁。';
|
|
}
|
|
}
|
|
if (isset($_POST['delete'])) {
|
|
verifyCsrf();
|
|
$id = (int) ($_POST['delete'] ?? 0);
|
|
$stmt = $db->prepare('SELECT id, is_admin FROM ' . tn('users') . ' WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
$row = $stmt->fetch();
|
|
if (!$row) {
|
|
$err = '用户不存在';
|
|
} elseif ((int) $row['is_admin'] === 1) {
|
|
$err = '不能删除管理员账户';
|
|
} else {
|
|
$db->prepare('DELETE FROM ' . tn('users') . ' WHERE id = ? AND is_admin = 0')->execute([$id]);
|
|
$msg = '用户已删除';
|
|
}
|
|
}
|
|
if (isset($_POST['add'])) {
|
|
verifyCsrf();
|
|
$u = trim($_POST['username'] ?? '');
|
|
$em = trim($_POST['email'] ?? '');
|
|
$pw = $_POST['password'] ?? '';
|
|
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();
|
|
$db->prepare('INSERT INTO ' . tn('users') . ' (username,password,email,invite_code,created_at) VALUES (?,?,?,?,NOW())')
|
|
->execute([$u, $hash, $em, $code]);
|
|
$msg = '用户已添加';
|
|
}
|
|
}
|
|
}
|
|
if (isset($_POST['adjust'])) {
|
|
verifyCsrf();
|
|
$target = trim($_POST['target'] ?? '');
|
|
$amount = (int) ($_POST['amount'] ?? 0);
|
|
$remark = trim($_POST['remark'] ?? '');
|
|
if ($target === '') $err = '请填写用户 ID 或用户名';
|
|
elseif ($amount === 0) $err = '积分变动不能为 0';
|
|
elseif ($remark === '') $err = '请填写调整备注(便于留痕)';
|
|
else {
|
|
if (is_numeric($target)) {
|
|
$stmt = $db->prepare('SELECT id, is_admin FROM ' . tn('users') . ' WHERE id = ?');
|
|
$stmt->execute([(int) $target]);
|
|
} else {
|
|
$stmt = $db->prepare('SELECT id, is_admin FROM ' . tn('users') . ' WHERE username = ?');
|
|
$stmt->execute([$target]);
|
|
}
|
|
$row = $stmt->fetch();
|
|
if (!$row) {
|
|
$err = '未找到该用户';
|
|
} else {
|
|
$res = addPoints((int) $row['id'], 'manual', $amount, '后台手动调整:' . $remark);
|
|
if ($res['ok']) {
|
|
$msg = '已为用户
|
|
} else {
|
|
$err = '调整失败:' . $res['error'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (isset($_POST['toggle_verify'])) {
|
|
verifyCsrf();
|
|
$id = (int) ($_POST['toggle_verify'] ?? 0);
|
|
$stmt = $db->prepare('SELECT id, verified FROM ' . tn('users') . ' WHERE id = ?');
|
|
$stmt->execute([$id]);
|
|
$row = $stmt->fetch();
|
|
if (!$row) {
|
|
$err = '用户不存在';
|
|
} else {
|
|
$next = (int) $row['verified'] === 1 ? 0 : 1;
|
|
$db->prepare('UPDATE ' . tn('users') . ' SET verified = ? WHERE id = ?')->execute([$next, $id]);
|
|
$msg = $next === 1 ? '已标记该用户邮箱为已验证。' : '已将该用户邮箱设为未验证。';
|
|
}
|
|
}
|
|
$list = $db->query('SELECT id, username, email, status, points, verified, created_at FROM ' . tn('users') . ' WHERE is_admin = 0 ORDER BY created_at DESC')->fetchAll();
|
|
$orderCnt = $db->query('SELECT user_id, COUNT(*) c FROM ' . tn('orders') . ' GROUP BY user_id')->fetchAll(PDO::FETCH_KEY_PAIR);
|
|
adminHeader('用户管理', 'users');
|
|
?>
|
|
<h1 class="page-title"><i class="fas fa-users"></i> 用户管理(共 <?= count($list) ?> 人)</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>
|
|
<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 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>
|
|
</div>
|
|
<div class="panel">
|
|
<h3>手动调整积分</h3>
|
|
<form method="post" action="" class="grid-form" style="max-width:720px;">
|
|
<?= csrfField() ?>
|
|
<label>用户 ID 或用户名 *<input type="text" name="target" placeholder="如 12 或 xiaoming" required></label>
|
|
<label>积分变动 *<input type="number" name="amount" placeholder="正数=增加,负数=扣减" required></label>
|
|
<label class="span2">调整备注 *<input type="text" name="remark" placeholder="如「活动奖励」「误扣退回」等" required></label>
|
|
<div class="form-actions span2">
|
|
<button type="submit" name="adjust" class="btn btn-primary"><i class="fas fa-coins"></i> 提交调整</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="panel">
|
|
<h3>用户列表</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><th>注册时间</th><th>操作</th></tr></thead>
|
|
<tbody>
|
|
<?php foreach ($list as $u): ?>
|
|
<tr>
|
|
<td><?= (int) $u['id'] ?></td>
|
|
<td><?= h($u['username']) ?></td>
|
|
<td><?= h($u['email']) ?></td>
|
|
<td><?= (int) ($u['points'] ?? 0) ?></td>
|
|
<td><?= (int) ($orderCnt[$u['id']] ?? 0) ?></td>
|
|
<td>
|
|
<?php if ((int) $u['verified'] === 1): ?>
|
|
<span class="badge-on">已验证</span>
|
|
<?php else: ?>
|
|
<span class="badge-off" style="background:var(--warn);color:
|
|
<?php endif; ?>
|
|
</td>
|
|
<td><?= (int) $u['status'] === 1 ? '<span class="badge-on">正常</span>' : '<span class="badge-off">已封禁</span>' ?></td>
|
|
<td><?= date('Y-m-d', strtotime($u['created_at'])) ?></td>
|
|
<td class="row-actions">
|
|
<form method="post" action="" style="display:inline" onsubmit="return confirm('确定<?= (int)$u['status']===1?'封禁':'解封' ?>该用户?');">
|
|
<?= csrfField() ?>
|
|
<button type="submit" name="toggle" value="<?= (int) $u['id'] ?>" class="mini-btn <?= (int)$u['status']===1?'warn':'ok' ?>"><i class="fas fa-<?= (int)$u['status']===1?'ban':'check' ?>"></i></button>
|
|
</form>
|
|
<form method="post" action="" style="display:inline" onsubmit="return confirm('确定<?= (int)$u['verified']===1?'取消验证':'标记已验证' ?>?');">
|
|
<?= csrfField() ?>
|
|
<button type="submit" name="toggle_verify" value="<?= (int) $u['id'] ?>" class="mini-btn <?= (int)$u['verified']===1?'warn':'ok' ?>" title="切换邮箱验证状态"><i class="fas fa-<?= (int)$u['verified']===1?'envelope':'envelope-circle-check' ?>"></i></button>
|
|
</form>
|
|
<form method="post" action="" style="display:inline" onsubmit="return confirm('确定删除该用户?此操作不可恢复。');">
|
|
<?= csrfField() ?>
|
|
<button type="submit" name="delete" value="<?= (int) $u['id'] ?>" class="mini-btn danger"><i class="fas fa-trash"></i></button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php adminFooter(); ?>
|