├── README.md ├── api ├── add_candidate.php ├── add_user.php ├── admin.php ├── change_password.php ├── config.php ├── dash.php ├── delete_candidate.php ├── delete_user.php ├── get_votes.php ├── install.php ├── login.php ├── logout.php ├── password.php ├── reset_all_votes.php ├── reset_votes.php ├── update_candidate.php ├── update_settings.php ├── update_user_role.php ├── update_votes.php └── vote.php ├── index.html └── vercel.json /README.md: -------------------------------------------------------------------------------- 1 | ## 开始使用 2 | 3 | 1. 准备好你的 MySQL 数据库; 4 | 2. 点击右侧按钮开始部署: 5 | [](https://vercel.com/new/clone?repository-url=https%3a%2f%2fgithub.com%2fSMNETSTUDIO%2fShineVote&env=DB_HOST&env=DB_NAME&env=DB_USER&env=DB_PASSWORD&project-name=shinevote&repository-name=shinevote) 6 | 3. 在环境变量页填入数据库信息; 7 | 4. 部署完毕后,即可开始使用 8 | 9 |  10 | -------------------------------------------------------------------------------- /api/add_candidate.php: -------------------------------------------------------------------------------- 1 | false, 'message' => '未登录']); 7 | exit; 8 | } 9 | 10 | $stmt = $pdo->prepare(" 11 | SELECT u.* 12 | FROM users u 13 | JOIN user_tokens t ON u.id = t.user_id 14 | WHERE t.token = ? AND u.is_admin = 1 15 | LIMIT 1 16 | "); 17 | $stmt->execute([$auth_token]); 18 | if (!$stmt->fetch()) { 19 | echo json_encode(['success' => false, 'message' => '无权限']); 20 | exit; 21 | } 22 | 23 | $name = $_POST['name'] ?? ''; 24 | if (!$name) { 25 | echo json_encode(['success' => false, 'message' => '请输入名称']); 26 | exit; 27 | } 28 | 29 | $stmt = $pdo->prepare("INSERT INTO candidates (name) VALUES (?)"); 30 | $result = $stmt->execute([$name]); 31 | 32 | echo json_encode(['success' => $result]); -------------------------------------------------------------------------------- /api/add_user.php: -------------------------------------------------------------------------------- 1 | false, 'message' => '无权限']); 7 | exit; 8 | } 9 | 10 | $stmt = $pdo->prepare(" 11 | SELECT u.* 12 | FROM users u 13 | JOIN user_tokens t ON u.id = t.user_id 14 | WHERE t.token = ? AND u.is_admin = 1 15 | LIMIT 1 16 | "); 17 | $stmt->execute([$auth_token]); 18 | $admin = $stmt->fetch(); 19 | 20 | if (!$admin) { 21 | echo json_encode(['success' => false, 'message' => '无权限']); 22 | exit; 23 | } 24 | 25 | if ($_SERVER['REQUEST_METHOD'] !== 'POST') { 26 | echo json_encode(['success' => false, 'message' => '无效的请求方法']); 27 | exit; 28 | } 29 | 30 | $username = trim($_POST['username'] ?? ''); 31 | $password = $_POST['password'] ?? ''; 32 | 33 | if (empty($username) || empty($password)) { 34 | echo json_encode(['success' => false, 'message' => '用户名和密码不能为空']); 35 | exit; 36 | } 37 | 38 | $stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE username = ?"); 39 | $stmt->execute([$username]); 40 | if ($stmt->fetchColumn() > 0) { 41 | echo json_encode(['success' => false, 'message' => '用户名已存在']); 42 | exit; 43 | } 44 | 45 | try { 46 | $hashedPassword = password_hash($password, PASSWORD_DEFAULT); 47 | $stmt = $pdo->prepare(" 48 | INSERT INTO users (username, password, is_admin, created_at) 49 | VALUES (?, ?, 0, NOW()) 50 | "); 51 | 52 | $stmt->execute([$username, $hashedPassword]); 53 | echo json_encode(['success' => true, 'message' => '用户添加成功']); 54 | 55 | } catch (PDOException $e) { 56 | error_log($e->getMessage()); 57 | echo json_encode(['success' => false, 'message' => '系统错误']); 58 | } -------------------------------------------------------------------------------- /api/admin.php: -------------------------------------------------------------------------------- 1 | prepare(" 11 | SELECT u.* 12 | FROM users u 13 | JOIN user_tokens t ON u.id = t.user_id 14 | WHERE t.token = ? AND u.is_admin = 1 15 | LIMIT 1 16 | "); 17 | $stmt->execute([$auth_token]); 18 | $admin = $stmt->fetch(); 19 | 20 | if (!$admin) { 21 | header('Location: /api/login.php'); 22 | exit; 23 | } 24 | 25 | $stmt = $pdo->query("SELECT * FROM users WHERE is_admin = 0"); 26 | $users = $stmt->fetchAll(); 27 | $stmt = $pdo->query(" 28 | SELECT c.*, 29 | COALESCE((SELECT COUNT(*) FROM votes v WHERE v.candidate_id = c.id), 0) as vote_count 30 | FROM candidates c 31 | "); 32 | $candidates = $stmt->fetchAll(); 33 | $stmt = $pdo->query("SELECT * FROM settings WHERE id = 1"); 34 | $settings = $stmt->fetch(); 35 | $stmt = $pdo->query("SELECT COUNT(*) as total_users FROM users WHERE is_admin = 0"); 36 | $totalUsers = $stmt->fetch()['total_users']; 37 | $today = date('Y-m-d'); 38 | $stmt = $pdo->prepare(" 39 | SELECT COUNT(DISTINCT user_id) as active_users 40 | FROM votes 41 | WHERE DATE(created_at) = ? 42 | "); 43 | $stmt->execute([$today]); 44 | $activeUsers = $stmt->fetch()['active_users']; 45 | $stmt = $pdo->query("SELECT COUNT(*) as total_votes FROM votes"); 46 | $totalVotes = $stmt->fetch()['total_votes']; 47 | ?> 48 | 49 | 50 | 51 |
52 |ID | 395 |用户名 | 396 |权限 | 397 |创建时间 | 398 |操作 | 399 |
---|---|---|---|---|
= $user['id'] ?> | 405 |= htmlspecialchars($user['username']) ?> | 406 |407 | 411 | | 412 |= $user['created_at'] ?> | 413 |414 | 415 | 416 | | 417 |
ID | 431 |名称 | 432 |当前票数 | 433 |操作 | 434 |
---|---|---|---|
= $candidate['id'] ?> | 440 |441 | 444 | | 445 |= $candidate['vote_count'] ?? 0 ?> | 446 |447 | 448 | 449 | | 450 |