├── 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 | [![Deploy with Vercel](https://vercel.com/button)](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 | ![image](https://github.com/user-attachments/assets/1839e903-9b10-4fdb-a54e-17bd23dd5686) 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 | 管理后台 53 | 54 | 334 | 335 | 336 | 337 | 346 | 347 |
348 | 359 | 360 |
361 |
362 |
363 |
364 |
365 |
366 |
总用户数
367 |

368 |
369 |
370 |
371 |
372 |
373 |
374 |
今日活跃用户
375 |

376 |
377 |
378 |
379 |
380 |
381 |
382 |
总投票数
383 |

384 |
385 |
386 |
387 |
388 |

用户管理

389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 412 | 413 | 417 | 418 | 419 | 420 |
ID用户名权限创建时间操作
407 | 411 | 414 | 415 | 416 |
421 |
422 | 423 |
424 |

候选人管理

425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 445 | 446 | 450 | 451 | 452 | 453 |
ID名称当前票数操作
441 | 444 | 447 | 448 | 449 |
454 |
455 | 456 |
457 |

投票设置

458 |
459 |
460 | 461 | 463 |
464 |
465 | 466 | 468 |
469 |
470 | 471 | 475 |
476 |
477 | 478 | 480 |
481 |
482 | 483 | 485 |
486 |
487 | 488 | 492 |
493 |
494 | 495 | 496 |
497 |
498 |
499 |
500 |
501 | 502 | 521 | 522 | 545 | 546 | 562 | 563 | 590 | 591 | 592 | 814 | 815 | 816 | -------------------------------------------------------------------------------- /api/change_password.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 = ? 15 | LIMIT 1 16 | "); 17 | $stmt->execute([$auth_token]); 18 | $user = $stmt->fetch(); 19 | 20 | if (!$user) { 21 | echo json_encode(['success' => false, 'message' => '用户不存在']); 22 | exit; 23 | } 24 | 25 | $current_password = $_POST['current_password'] ?? ''; 26 | if (!password_verify($current_password, $user['password'])) { 27 | echo json_encode(['success' => false, 'message' => '当前密码错误']); 28 | exit; 29 | } 30 | 31 | $new_password = $_POST['new_password'] ?? ''; 32 | $hashed_password = password_hash($new_password, PASSWORD_DEFAULT); 33 | 34 | $stmt = $pdo->prepare("UPDATE users SET password = ? WHERE id = ?"); 35 | $result = $stmt->execute([$hashed_password, $user['id']]); 36 | 37 | echo json_encode(['success' => $result]); -------------------------------------------------------------------------------- /api/config.php: -------------------------------------------------------------------------------- 1 | setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 10 | } catch(PDOException $e) { 11 | die("连接失败: " . $e->getMessage()); 12 | } -------------------------------------------------------------------------------- /api/dash.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 = ? 15 | LIMIT 1 16 | "); 17 | $stmt->execute([$auth_token]); 18 | $user = $stmt->fetch(); 19 | 20 | if (!$user) { 21 | header('Location: login.php'); 22 | exit; 23 | } 24 | 25 | $stmt = $pdo->query("SELECT * FROM settings WHERE id = 1"); 26 | $settings = $stmt->fetch(); 27 | 28 | $now = new DateTime(); 29 | $startTime = new DateTime($settings['voting_start_time']); 30 | $endTime = new DateTime($settings['voting_end_time']); 31 | $votingEnabled = $settings['voting_enabled'] && $now >= $startTime && $now <= $endTime; 32 | 33 | $stmt = $pdo->prepare("SELECT COUNT(*) as vote_count FROM votes WHERE user_id = ?"); 34 | $stmt->execute([$user['id']]); 35 | $userVoteCount = $stmt->fetch()['vote_count']; 36 | $canVote = $userVoteCount < $settings['max_votes_per_user']; 37 | 38 | $stmt = $pdo->query(" 39 | SELECT c.*, COUNT(v.id) as vote_count 40 | FROM candidates c 41 | LEFT JOIN votes v ON c.id = v.candidate_id 42 | GROUP BY c.id 43 | ORDER BY COUNT(v.id) DESC 44 | "); 45 | $candidates = $stmt->fetchAll(); 46 | ?> 47 | 48 | 49 | 50 | 51 | <?= htmlspecialchars($settings['voting_name']) ?> 52 | 53 | 54 | 231 | 232 | 233 | 234 | 243 | 244 |
245 |
253 | 254 | 255 | 投票已暂停 256 | 257 | 投票还未开始,开始时间:format('Y-m-d H:i') ?> 258 | 259 | 投票已结束 260 | 261 | = $settings['max_votes_per_user']): ?> 262 | 您已完成所有可投票数(票),感谢参与! 263 | 264 | 您还可以投票 265 | 266 |
267 | 268 | = $settings['max_votes_per_user']): ?> 269 |
270 |
实时投票结果
271 |
272 | 273 |
274 |
275 | 276 | 277 |
278 | 279 |
280 |
281 |
282 |
283 |

当前票数:

284 | 289 |
290 |
291 |
292 | 293 |
294 |
295 | 296 | 383 | 384 | 385 | -------------------------------------------------------------------------------- /api/delete_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 | $id = $_POST['id'] ?? ''; 24 | 25 | if (!$id) { 26 | echo json_encode(['success' => false, 'message' => '参数错误']); 27 | exit; 28 | } 29 | 30 | $pdo->beginTransaction(); 31 | 32 | try { 33 | $stmt = $pdo->prepare("DELETE FROM votes WHERE candidate_id = ?"); 34 | $stmt->execute([$id]); 35 | $stmt = $pdo->prepare("DELETE FROM candidates WHERE id = ?"); 36 | $stmt->execute([$id]); 37 | $pdo->commit(); 38 | echo json_encode(['success' => true]); 39 | } catch (Exception $e) { 40 | $pdo->rollBack(); 41 | echo json_encode(['success' => false, 'message' => $e->getMessage()]); 42 | } -------------------------------------------------------------------------------- /api/delete_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 | $user_id = $_POST['user_id'] ?? ''; 26 | if (!$user_id) { 27 | echo json_encode(['success' => false, 'message' => '参数错误']); 28 | exit; 29 | } 30 | 31 | try { 32 | $pdo->beginTransaction(); 33 | $stmt = $pdo->prepare("DELETE FROM votes WHERE user_id = ?"); 34 | $stmt->execute([$user_id]); 35 | $stmt = $pdo->prepare("DELETE FROM user_tokens WHERE user_id = ?"); 36 | $stmt->execute([$user_id]); 37 | $stmt = $pdo->prepare("DELETE FROM users WHERE id = ?"); 38 | $stmt->execute([$user_id]); 39 | $pdo->commit(); 40 | 41 | echo json_encode(['success' => true]); 42 | } catch (Exception $e) { 43 | $pdo->rollBack(); 44 | echo json_encode(['success' => false, 'message' => '删除失败:' . $e->getMessage()]); 45 | } -------------------------------------------------------------------------------- /api/get_votes.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 = ? 15 | LIMIT 1 16 | "); 17 | $stmt->execute([$auth_token]); 18 | $user = $stmt->fetch(); 19 | 20 | if (!$user) { 21 | echo json_encode([]); 22 | exit; 23 | } 24 | 25 | $stmt = $pdo->query("SELECT * FROM settings WHERE id = 1"); 26 | $settings = $stmt->fetch(); 27 | 28 | $stmt = $pdo->prepare("SELECT COUNT(*) as vote_count FROM votes WHERE user_id = ?"); 29 | $stmt->execute([$user['id']]); 30 | $userVoteCount = $stmt->fetch()['vote_count']; 31 | 32 | if (!$settings['show_results'] && $userVoteCount < $settings['max_votes_per_user']) { 33 | echo json_encode([]); 34 | exit; 35 | } 36 | 37 | $stmt = $pdo->query(" 38 | SELECT 39 | c.id, 40 | c.name, 41 | COUNT(v.id) as vote_count 42 | FROM candidates c 43 | LEFT JOIN votes v ON c.id = v.candidate_id 44 | GROUP BY c.id 45 | ORDER BY vote_count DESC 46 | "); 47 | 48 | $candidates = $stmt->fetchAll(PDO::FETCH_ASSOC); 49 | 50 | header('Content-Type: application/json'); 51 | 52 | echo json_encode($candidates); -------------------------------------------------------------------------------- /api/install.php: -------------------------------------------------------------------------------- 1 | prepare("SHOW TABLES LIKE ?"); 13 | $stmt->execute([$table]); 14 | if ($stmt->fetch()) { 15 | $existing_tables[] = $table; 16 | } 17 | } 18 | 19 | if (count($existing_tables) === count($tables)) { 20 | header('Location: /api/login.php'); 21 | exit; 22 | } 23 | 24 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { 25 | $pdo->exec('SET FOREIGN_KEY_CHECKS=0'); 26 | $sql = " 27 | DROP TABLE IF EXISTS `candidates`; 28 | DROP TABLE IF EXISTS `settings`; 29 | DROP TABLE IF EXISTS `user_tokens`; 30 | DROP TABLE IF EXISTS `users`; 31 | DROP TABLE IF EXISTS `votes`; 32 | 33 | CREATE TABLE `candidates` ( 34 | `id` int NOT NULL AUTO_INCREMENT, 35 | `name` varchar(100) NOT NULL, 36 | `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 37 | PRIMARY KEY (`id`) 38 | ); 39 | 40 | CREATE TABLE `settings` ( 41 | `id` int NOT NULL, 42 | `voting_name` varchar(255) NOT NULL DEFAULT '投票系统', 43 | `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 44 | `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 45 | `max_votes_per_user` int NOT NULL DEFAULT '1', 46 | `voting_enabled` tinyint(1) NOT NULL DEFAULT '1', 47 | `voting_start_time` datetime DEFAULT NULL, 48 | `voting_end_time` datetime DEFAULT NULL, 49 | `show_results` tinyint(1) NOT NULL DEFAULT '1', 50 | PRIMARY KEY (`id`) 51 | ); 52 | 53 | CREATE TABLE `users` ( 54 | `id` int NOT NULL AUTO_INCREMENT, 55 | `username` varchar(50) NOT NULL, 56 | `password` varchar(255) NOT NULL, 57 | `is_admin` tinyint(1) DEFAULT '0', 58 | `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 59 | PRIMARY KEY (`id`), 60 | UNIQUE KEY `username` (`username`) 61 | ); 62 | 63 | CREATE TABLE `user_tokens` ( 64 | `id` int NOT NULL AUTO_INCREMENT, 65 | `user_id` int NOT NULL, 66 | `token` varchar(36) NOT NULL, 67 | `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 68 | PRIMARY KEY (`id`), 69 | KEY `user_id` (`user_id`), 70 | CONSTRAINT `user_tokens_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) 71 | ); 72 | 73 | CREATE TABLE `votes` ( 74 | `id` int NOT NULL AUTO_INCREMENT, 75 | `user_id` int DEFAULT NULL, 76 | `candidate_id` int DEFAULT NULL, 77 | `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 78 | PRIMARY KEY (`id`), 79 | KEY `user_id` (`user_id`), 80 | KEY `candidate_id` (`candidate_id`), 81 | CONSTRAINT `votes_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`), 82 | CONSTRAINT `votes_ibfk_2` FOREIGN KEY (`candidate_id`) REFERENCES `candidates` (`id`) 83 | )"; 84 | 85 | $pdo->exec($sql); 86 | $admin_password = password_hash('admin', PASSWORD_DEFAULT); 87 | $stmt = $pdo->prepare("INSERT INTO users (username, password, is_admin) VALUES (?, ?, 1)"); 88 | $stmt->execute(['admin', $admin_password]); 89 | $stmt = $pdo->prepare("INSERT INTO settings (id, voting_name) VALUES (1, '投票系统')"); 90 | $stmt->execute(); 91 | $pdo->exec('SET FOREIGN_KEY_CHECKS=1'); 92 | $success = '安装成功!默认管理员账号:admin,密码:admin'; 93 | } 94 | 95 | } catch(PDOException $e) { 96 | $error = '安装过程出错:' . $e->getMessage(); 97 | } 98 | ?> 99 | 100 | 101 | 102 | 103 | 投票系统 - 安装 104 | 105 | 182 | 183 | 184 |
185 |
186 |
187 |
188 |
189 |
190 |
投票系统
191 |
192 | 系统安装向导 193 |
194 |
195 | 196 |
197 | 198 | 199 | 200 |
201 | 202 |

203 | 立即登录 204 |
205 | 206 |

欢迎使用投票系统,点击下方按钮开始安装:

207 |
208 | 209 |
210 | 211 |
212 |
213 |
214 |
215 |
216 | 217 | -------------------------------------------------------------------------------- /api/login.php: -------------------------------------------------------------------------------- 1 | prepare("SHOW TABLES LIKE ?"); 13 | $stmt->execute([$table]); 14 | if (!$stmt->fetch()) { 15 | $missing_tables[] = $table; 16 | } 17 | } 18 | 19 | if (!empty($missing_tables)) { 20 | header('Location: /api/install.php'); 21 | exit; 22 | } 23 | } catch(PDOException $e) { 24 | $error = '数据库连接错误,请检查配置!'; 25 | } 26 | 27 | if ($_SERVER['REQUEST_METHOD'] == 'POST') { 28 | $username = $_POST['username']; 29 | $password = $_POST['password']; 30 | 31 | try { 32 | $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?"); 33 | $stmt->execute([$username]); 34 | $user = $stmt->fetch(); 35 | 36 | if ($user && password_verify($password, $user['password'])) { 37 | $token = uniqid(rand(), true); 38 | $stmt = $pdo->prepare("INSERT INTO user_tokens (user_id, token) VALUES (?, ?)"); 39 | $stmt->execute([$user['id'], $token]); 40 | setcookie('auth_token', $token, time() + (7 * 24 * 60 * 60), '/'); 41 | 42 | if ($user['is_admin']) { 43 | header('Location: /api/admin.php'); 44 | } else { 45 | header('Location: /api/dash.php'); 46 | } 47 | exit; 48 | } else { 49 | $error = '用户名或密码错误!'; 50 | } 51 | } catch(PDOException $e) { 52 | $error = '系统错误,请稍后再试!'; 53 | } 54 | } 55 | ?> 56 | 57 | 58 | 59 | 60 | 投票系统 - 登录 61 | 62 | 241 | 242 | 243 | 244 |
245 |
246 |
247 |

投票系统

248 |
249 |
用户登录
250 |
251 | 252 |
253 | 254 |
255 |
256 | 257 | 258 |
259 |
260 | 261 | 262 |
263 | 264 |
265 |
266 |
267 |
268 |
269 |
270 | 271 | -------------------------------------------------------------------------------- /api/logout.php: -------------------------------------------------------------------------------- 1 | prepare("DELETE FROM user_tokens WHERE token = ?"); 8 | $stmt->execute([$auth_token]); 9 | setcookie('auth_token', '', time() - 3600, '/'); 10 | $success = true; 11 | } catch (Exception $e) { 12 | $success = false; 13 | $error_message = '登出失败:' . $e->getMessage(); 14 | } 15 | } else { 16 | $success = true; 17 | } 18 | ?> 19 | 20 | 21 | 22 | 23 | 退出登录 24 | 25 | 84 | 85 | 86 |
87 |
88 | 89 |
90 | 91 |
92 | 93 |
94 | 95 |
96 | 97 | 退出登录成功 98 | 99 | 100 | 101 |
102 | 103 | 104 |
105 | 3 秒后返回登录页面 106 |
107 | 108 |
109 | 110 | 126 | 127 | -------------------------------------------------------------------------------- /api/password.php: -------------------------------------------------------------------------------- 1 | 12 | 13 | 14 | 15 | 16 | 密码哈希生成器 17 | 18 | 19 | 20 |
21 |
22 |
23 |
24 |
密码哈希生成器
25 |
26 |
27 |
28 | 29 | 30 |
31 | 32 |
33 | 34 | 35 |
36 |
生成结果:
37 |
38 |

原始密码:

39 |

哈希值:

40 |
41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 | 49 | -------------------------------------------------------------------------------- /api/reset_all_votes.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 | $stmt = $pdo->query("TRUNCATE TABLE votes"); 24 | echo json_encode(['success' => true]); -------------------------------------------------------------------------------- /api/reset_votes.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 | $candidate_id = $_POST['candidate_id'] ?? ''; 24 | 25 | if (!$candidate_id) { 26 | echo json_encode(['success' => false, 'message' => '参数错误']); 27 | exit; 28 | } 29 | 30 | $stmt = $pdo->prepare("DELETE FROM votes WHERE candidate_id = ?"); 31 | $result = $stmt->execute([$candidate_id]); 32 | 33 | echo json_encode(['success' => $result]); -------------------------------------------------------------------------------- /api/update_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 | $id = $_POST['id'] ?? ''; 24 | $name = $_POST['name'] ?? ''; 25 | 26 | if (!$id || !$name) { 27 | echo json_encode(['success' => false, 'message' => '参数错误']); 28 | exit; 29 | } 30 | 31 | $stmt = $pdo->prepare("UPDATE candidates SET name = ? WHERE id = ?"); 32 | $result = $stmt->execute([$name, $id]); 33 | 34 | echo json_encode(['success' => $result]); -------------------------------------------------------------------------------- /api/update_settings.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 | $data = json_decode(file_get_contents('php://input'), true); 26 | 27 | if (empty($data['voting_name'])) { 28 | echo json_encode(['success' => false, 'message' => '投票系统名称不能为空']); 29 | exit; 30 | } 31 | 32 | try { 33 | $stmt = $pdo->prepare(" 34 | INSERT INTO settings ( 35 | id, 36 | voting_name, 37 | max_votes_per_user, 38 | voting_enabled, 39 | voting_start_time, 40 | voting_end_time, 41 | show_results 42 | ) VALUES ( 43 | 1, ?, ?, ?, ?, ?, ? 44 | ) ON DUPLICATE KEY UPDATE 45 | voting_name = ?, 46 | max_votes_per_user = ?, 47 | voting_enabled = ?, 48 | voting_start_time = ?, 49 | voting_end_time = ?, 50 | show_results = ? 51 | "); 52 | 53 | $params = [ 54 | $data['voting_name'], 55 | (int)$data['max_votes_per_user'], 56 | (int)$data['voting_enabled'], 57 | $data['voting_start_time'], 58 | $data['voting_end_time'], 59 | (int)$data['show_results'], 60 | $data['voting_name'], 61 | (int)$data['max_votes_per_user'], 62 | (int)$data['voting_enabled'], 63 | $data['voting_start_time'], 64 | $data['voting_end_time'], 65 | (int)$data['show_results'] 66 | ]; 67 | 68 | $stmt->execute($params); 69 | echo json_encode(['success' => true]); 70 | } catch (PDOException $e) { 71 | echo json_encode(['success' => false, 'message' => '数据库错误']); 72 | } -------------------------------------------------------------------------------- /api/update_user_role.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 | $user_id = $_POST['user_id'] ?? ''; 24 | $is_admin = $_POST['is_admin'] ?? ''; 25 | 26 | if (!$user_id) { 27 | echo json_encode(['success' => false, 'message' => '参数错误']); 28 | exit; 29 | } 30 | 31 | $stmt = $pdo->prepare("UPDATE users SET is_admin = ? WHERE id = ?"); 32 | $result = $stmt->execute([$is_admin, $user_id]); 33 | 34 | echo json_encode(['success' => $result]); -------------------------------------------------------------------------------- /api/update_votes.php: -------------------------------------------------------------------------------- 1 | false, 'message' => '未登录']); 9 | exit; 10 | } 11 | 12 | $stmt = $pdo->prepare(" 13 | SELECT u.* 14 | FROM users u 15 | JOIN user_tokens t ON u.id = t.user_id 16 | WHERE t.token = ? AND u.is_admin = 1 17 | LIMIT 1 18 | "); 19 | $stmt->execute([$auth_token]); 20 | $admin = $stmt->fetch(); 21 | 22 | if (!$admin) { 23 | echo json_encode(['success' => false, 'message' => '无权限']); 24 | exit; 25 | } 26 | 27 | $candidate_id = filter_input(INPUT_POST, 'candidate_id', FILTER_VALIDATE_INT); 28 | $votes = filter_input(INPUT_POST, 'votes', FILTER_VALIDATE_INT); 29 | 30 | if ($candidate_id === false || $candidate_id === null || $votes === false || $votes === null || $votes < 0) { 31 | echo json_encode(['success' => false, 'message' => '参数无效']); 32 | exit; 33 | } 34 | 35 | try { 36 | $stmt = $pdo->prepare(" 37 | UPDATE candidates 38 | SET votes_count = ? 39 | WHERE id = ? 40 | "); 41 | 42 | if (!$stmt->execute([$votes, $candidate_id])) { 43 | throw new Exception('更新失败'); 44 | } 45 | 46 | if ($stmt->rowCount() === 0) { 47 | throw new Exception('候选人不存在'); 48 | } 49 | 50 | echo json_encode(['success' => true, 'message' => '更新成功']); 51 | exit; 52 | } catch (Exception $e) { 53 | echo json_encode(['success' => false, 'message' => $e->getMessage()]); 54 | exit; 55 | } -------------------------------------------------------------------------------- /api/vote.php: -------------------------------------------------------------------------------- 1 | false, 'message' => '请先登录']); 9 | exit; 10 | } 11 | 12 | $stmt = $pdo->prepare(" 13 | SELECT u.* 14 | FROM users u 15 | JOIN user_tokens t ON u.id = t.user_id 16 | WHERE t.token = ? 17 | LIMIT 1 18 | "); 19 | $stmt->execute([$auth_token]); 20 | $user = $stmt->fetch(); 21 | 22 | if (!$user) { 23 | echo json_encode(['success' => false, 'message' => '用户验证失败']); 24 | exit; 25 | } 26 | 27 | if ($_SERVER['REQUEST_METHOD'] !== 'POST') { 28 | echo json_encode(['success' => false, 'message' => '无效的请求方法']); 29 | exit; 30 | } 31 | 32 | $candidate_id = $_POST['candidate_id'] ?? ''; 33 | if (!$candidate_id) { 34 | echo json_encode(['success' => false, 'message' => '请选择候选人']); 35 | exit; 36 | } 37 | 38 | $stmt = $pdo->prepare("SELECT id FROM votes WHERE user_id = ?"); 39 | $stmt->execute([$user['id']]); 40 | if ($stmt->fetch()) { 41 | echo json_encode(['success' => false, 'message' => '您已经投过票了']); 42 | exit; 43 | } 44 | 45 | $stmt = $pdo->prepare("SELECT id FROM candidates WHERE id = ?"); 46 | $stmt->execute([$candidate_id]); 47 | if (!$stmt->fetch()) { 48 | echo json_encode(['success' => false, 'message' => '无效的候选人']); 49 | exit; 50 | } 51 | 52 | $stmt = $pdo->query("SELECT * FROM settings WHERE id = 1"); 53 | $settings = $stmt->fetch(); 54 | 55 | if (!$settings['voting_enabled']) { 56 | echo json_encode(['success' => false, 'message' => '投票已暂停']); 57 | exit; 58 | } 59 | 60 | $now = new DateTime(); 61 | $startTime = new DateTime($settings['voting_start_time']); 62 | $endTime = new DateTime($settings['voting_end_time']); 63 | 64 | if ($now < $startTime) { 65 | echo json_encode(['success' => false, 'message' => '投票还未开始']); 66 | exit; 67 | } 68 | 69 | if ($now > $endTime) { 70 | echo json_encode(['success' => false, 'message' => '投票已结束']); 71 | exit; 72 | } 73 | 74 | $stmt = $pdo->prepare("SELECT COUNT(*) as vote_count FROM votes WHERE user_id = ?"); 75 | $stmt->execute([$user['id']]); 76 | $userVoteCount = $stmt->fetch()['vote_count']; 77 | 78 | if ($userVoteCount >= $settings['max_votes_per_user']) { 79 | echo json_encode(['success' => false, 'message' => '您已达到最大投票次数']); 80 | exit; 81 | } 82 | 83 | try { 84 | $pdo->beginTransaction(); 85 | $stmt = $pdo->prepare("INSERT INTO votes (user_id, candidate_id, created_at) VALUES (?, ?, NOW())"); 86 | $stmt->execute([$user['id'], $candidate_id]); 87 | $pdo->commit(); 88 | 89 | echo json_encode(['success' => true, 'message' => '投票成功']); 90 | } catch (Exception $e) { 91 | $pdo->rollBack(); 92 | echo json_encode(['success' => false, 'message' => $e->getMessage()]); 93 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 跳转中... 6 | 7 | 8 |

正在跳转到登录页面...

9 | 10 | 11 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "functions": { 3 | "api/*.php": { 4 | "runtime": "vercel-php@0.7.3" 5 | } 6 | } 7 | } --------------------------------------------------------------------------------