prepare('INSERT INTO invite_codes (code, max_uses) VALUES (?, ?)'); for ($i = 0; $i < $count; $i++) { $code = strtoupper(bin2hex(random_bytes(4))); try { $stmt->execute([$code, $maxUses]); $inserted++; } catch (PDOException $e) { } } $_SESSION['flash_msg'] = '成功生成 ' . $inserted . ' 个邀请码(最大使用次数: ' . ($maxUses === 0 ? '不限' : $maxUses) . ')'; $_SESSION['flash_type'] = 'success'; header('Location: admin_settings.php'); exit; } // 修改邀请码次数 if (isset($_POST['edit_max_uses'])) { if (!verifyCsrf($_POST['csrf_token'] ?? '')) { die('CSRF token无效'); } $id = (int)($_POST['id'] ?? 0); $maxUses = max(0, (int)($_POST['max_uses'] ?? 1)); $stmt = $pdo->prepare('UPDATE invite_codes SET max_uses = ? WHERE id = ?'); $stmt->execute([$maxUses, $id]); $_SESSION['flash_msg'] = '已更新最大使用次数'; $_SESSION['flash_type'] = 'success'; header('Location: admin_settings.php'); exit; } // 删除邀请码(仅可删未使用的) if (isset($_GET['del_invite']) && is_numeric($_GET['del_invite'])) { if (!verifyCsrf($_GET['csrf_token'] ?? '')) { $msg = '
CSRF token无效
'; } else { $id = (int)$_GET['del_invite']; $stmt = $pdo->prepare('DELETE FROM invite_codes WHERE id = ? AND used_count = 0'); $stmt->execute([$id]); $msg = $stmt->rowCount() ? '
邀请码已删除
' : '
无法删除:已被使用或不存在
'; } } // 新增用户 if (isset($_POST['add_user'])) { if (!verifyCsrf($_POST['csrf_token'] ?? '')) { die('CSRF token无效'); } $username = trim($_POST['username'] ?? ''); $password = $_POST['password'] ?? ''; $role = $_POST['role'] ?? 'user'; $remark = trim($_POST['remark'] ?? ''); if (!in_array($role, ['admin', 'user'])) $role = 'user'; if ($username === '' || $password === '') { $msg = '
用户名和密码不能为空
'; } elseif (strlen($username) < 3 || strlen($username) > 20) { $msg = '
用户名长度3-20个字符
'; } elseif (strlen($password) < 6) { $msg = '
密码长度至少6位
'; } else { $stmt = $pdo->prepare('SELECT id FROM users WHERE username = ?'); $stmt->execute([$username]); if ($stmt->fetch()) { $msg = '
用户名已存在
'; } else { $productIds = array_map('intval', $_POST['product_ids'] ?? []); $productIds = array_filter($productIds, fn($v) => $v > 0); if (empty($productIds)) { $msg = '
至少选择一个产品
'; } else { $hash = password_hash($password, PASSWORD_DEFAULT); $stmt = $pdo->prepare('INSERT INTO users (username, password, role, remark) VALUES (?, ?, ?, ?)'); $stmt->execute([$username, $hash, $role, $remark ?: null]); $userId = (int)$pdo->lastInsertId(); $stmt = $pdo->prepare('INSERT INTO user_products (user_id, product_id) VALUES (?, ?)'); foreach ($productIds as $pid) { $stmt->execute([$userId, $pid]); } $_SESSION['flash_msg'] = '用户 ' . h($username) . ' 添加成功'; $_SESSION['flash_type'] = 'success'; header('Location: admin_settings.php'); exit; } } } } // 修改备注 if (isset($_POST['edit_remark'])) { if (!verifyCsrf($_POST['csrf_token'] ?? '')) { die('CSRF token无效'); } $id = (int)($_POST['user_id'] ?? 0); $remark = trim($_POST['remark'] ?? ''); $stmt = $pdo->prepare('UPDATE users SET remark = ? WHERE id = ?'); $stmt->execute([$remark ?: null, $id]); $_SESSION['flash_msg'] = '备注已更新'; $_SESSION['flash_type'] = 'success'; header('Location: admin_settings.php'); exit; } // 分配产品 if (isset($_POST['edit_user_products'])) { if (!verifyCsrf($_POST['csrf_token'] ?? '')) { die('CSRF token无效'); } $id = (int)($_POST['user_id'] ?? 0); $productIds = array_map('intval', $_POST['product_ids'] ?? []); $productIds = array_filter($productIds, fn($v) => $v > 0); if (empty($productIds)) { $msg = '
至少选择一个产品
'; } else { $stmt = $pdo->prepare('DELETE FROM user_products WHERE user_id = ?'); $stmt->execute([$id]); $stmt = $pdo->prepare('INSERT INTO user_products (user_id, product_id) VALUES (?, ?)'); foreach ($productIds as $pid) { $stmt->execute([$id, $pid]); } $_SESSION['flash_msg'] = '产品分配已更新'; $_SESSION['flash_type'] = 'success'; header('Location: admin_settings.php'); exit; } } // 禁用/启用用户 if (isset($_GET['toggle_disable']) && is_numeric($_GET['toggle_disable'])) { if (!verifyCsrf($_GET['csrf_token'] ?? '')) { $_SESSION['flash_msg'] = 'CSRF token无效'; $_SESSION['flash_type'] = 'danger'; } else { $id = (int)$_GET['toggle_disable']; if ($id === getCurrentUserId()) { $_SESSION['flash_msg'] = '不能禁用自己'; $_SESSION['flash_type'] = 'danger'; } else { $stmt = $pdo->prepare('SELECT disabled FROM users WHERE id = ?'); $stmt->execute([$id]); $current = (int)$stmt->fetchColumn(); $newDisabled = $current ? 0 : 1; $stmt = $pdo->prepare('UPDATE users SET disabled = ? WHERE id = ?'); $stmt->execute([$newDisabled, $id]); $_SESSION['flash_msg'] = $newDisabled ? '用户已禁用' : '用户已启用'; $_SESSION['flash_type'] = 'success'; } } header('Location: admin_settings.php'); exit; } // 修改用户角色 if (isset($_GET['set_role']) && is_numeric($_GET['set_role'])) { $id = (int)$_GET['set_role']; $role = $_GET['role'] ?? ''; if ($id === getCurrentUserId()) { $msg = '
不能修改自己的角色
'; } elseif (!in_array($role, ['admin', 'user'])) { $msg = '
无效的角色
'; } else { $stmt = $pdo->query("SELECT COUNT(*) FROM users WHERE role = 'admin'"); $adminCount = (int)$stmt->fetchColumn(); $stmt = $pdo->prepare('SELECT role FROM users WHERE id = ?'); $stmt->execute([$id]); $targetRole = $stmt->fetchColumn(); if ($role === 'user' && $targetRole === 'admin' && $adminCount <= 1) { $msg = '
至少保留一名管理员
'; } else { $stmt = $pdo->prepare('UPDATE users SET role = ? WHERE id = ?'); $stmt->execute([$role, $id]); $msg = '
角色已更新
'; } } } // 分页 - 邀请码 $page = max(1, (int)($_GET['p'] ?? 1)); $perPage = 20; $offset = ($page - 1) * $perPage; $stmt = $pdo->query('SELECT COUNT(*) FROM invite_codes'); $inviteTotal = (int)$stmt->fetchColumn(); $invitePages = max(1, ceil($inviteTotal / $perPage)); $stmt = $pdo->prepare('SELECT * FROM invite_codes ORDER BY id DESC LIMIT ? OFFSET ?'); $stmt->execute([$perPage, $offset]); $invites = $stmt->fetchAll(); // 用户列表 $stmt = $pdo->query('SELECT * FROM users ORDER BY id ASC'); $users = $stmt->fetchAll(); // 所有启用产品 $stmt = $pdo->query('SELECT id, name, code FROM products WHERE status = 1 ORDER BY id ASC'); $allProducts = $stmt->fetchAll(); // 用户-产品关联 $userProducts = []; $stmt = $pdo->query('SELECT user_id, product_id FROM user_products'); while ($row = $stmt->fetch()) { $userProducts[$row['user_id']][] = (int)$row['product_id']; } ?>

邀请码管理

0 && $i['used_count'] >= $i['max_uses']; ?>
ID 邀请码 使用次数 最大次数 状态 创建时间 操作
已用完 0): ?> 使用中 未使用

用户管理 + 新增用户

ID 用户名 角色 状态 可管理产品 备注 注册时间 操作
管理员 普通用户 已禁用 正常 $p['name'], array_filter($allProducts, fn($p) => in_array((int)$p['id'], $upIds))); echo $upNames ? h(implode(', ', $upNames)) : '-'; ?> 20 ? '...' : '' ?> - ✏️