Files
wushu/ht/vote_api.php
2026-03-30 02:35:31 +08:00

490 lines
14 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* 投票API接口
* 支持POST和GET请求方式
* 提供投票列表、投票详情、提交投票、获取结果等功能
*/
// 引入必要文件
require_once 'inc/pubs.php';
require_once 'inc/sqls.php';
// 设置响应头
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
// 处理OPTIONS预检请求
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
// 获取请求参数支持GET和POST
function getRequestParams() {
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
return $_GET;
} elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
$json = file_get_contents('php://input');
return json_decode($json, true) ?: [];
}
return $_POST;
}
return [];
}
// 获取请求参数
$params = getRequestParams();
// 获取操作类型
$action = isset($params['act']) ? $params['act'] : '';
// 实例化数据库操作类
$db = new DB();
// 根据操作类型执行相应操作
switch ($action) {
// 获取投票列表
case 'getVoteList':
handleGetVoteList($params, $db);
break;
// 获取投票详情
case 'getVoteDetail':
handleGetVoteDetail($params, $db);
break;
// 提交投票
case 'submitVote':
handleSubmitVote($params, $db);
break;
// 获取投票结果
case 'getVoteResult':
handleGetVoteResult($params, $db);
break;
// 获取用户的投票记录
case 'getUserVotes':
handleGetUserVotes($params, $db);
break;
// 未知操作
default:
apiResponse(1, '未知操作');
break;
}
/**
* 处理获取投票列表
* @param array $params 请求参数
* @param DB $db 数据库操作对象
*/
function handleGetVoteList($params, $db) {
// 获取分页参数
$page = isset($params['page']) ? intval($params['page']) : 1;
$pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : 10;
// 获取筛选参数
$status = isset($params['status']) ? intval($params['status']) : -1;
$type = isset($params['type']) ? intval($params['type']) : -1;
// 构建查询条件
$whereConditions = [];
if ($status >= 0) {
$whereConditions[] = "status = $status";
}
if ($type >= 0) {
$whereConditions[] = "itype = $type";
}
$whereStr = !empty($whereConditions) ? implode(' AND ', $whereConditions) : '';
// 获取总记录数
$total = $db->count('vote', $whereStr);
// 计算分页信息
$pagination = getPagination($total, $page, $pageSize);
// 获取投票列表
$orderBy = "addtime DESC";
$limit = "{$pagination['offset']}, {$pagination['pageSize']}";
$voteList = $db->getAll('vote', $whereStr, '*', $orderBy, $limit);
// 当前时间,用于判断投票状态
$now = date('Y-m-d H:i:s');
// 处理投票状态
foreach ($voteList as &$vote) {
$vote['status_text'] = '';
$vote['status_class'] = '';
if ($vote['status'] == 0) {
$vote['status_text'] = '已禁用';
$vote['status_class'] = 'vote-status-disabled';
} else {
if ($vote['statime'] > $now) {
$vote['status_text'] = '未开始';
$vote['status_class'] = 'vote-status-pending';
} elseif ($vote['endtime'] < $now) {
$vote['status_text'] = '已结束';
$vote['status_class'] = 'vote-status-ended';
} else {
$vote['status_text'] = '进行中';
$vote['status_class'] = 'vote-status-active';
}
}
}
apiResponse(0, '获取成功', [
'list' => $voteList,
'pagination' => $pagination
]);
}
/**
* 处理获取投票详情
* @param array $params 请求参数
* @param DB $db 数据库操作对象
*/
function handleGetVoteDetail($params, $db) {
// 获取投票ID
$voteId = isset($params['id']) ? intval($params['id']) : 0;
if (!$voteId) {
apiResponse(1, '参数错误');
}
// 获取投票信息
$vote = $db->getOne('vote', "id = $voteId");
if (!$vote) {
apiResponse(1, '投票不存在');
}
// 更新浏览次数
$db->update('vote', ['iview' => $vote['iview'] + 1], "id = $voteId");
// 获取投票选项
$options = $db->getAll('xuan', "topic_id = $voteId", '*', 'sort ASC, id ASC');
// 当前时间,用于判断投票状态
$now = date('Y-m-d H:i:s');
// 处理投票状态
$vote['status_text'] = '';
$vote['status_class'] = '';
if ($vote['status'] == 0) {
$vote['status_text'] = '已禁用';
$vote['status_class'] = 'vote-status-disabled';
} else {
if ($vote['statime'] > $now) {
$vote['status_text'] = '未开始';
$vote['status_class'] = 'vote-status-pending';
} elseif ($vote['endtime'] < $now) {
$vote['status_text'] = '已结束';
$vote['status_class'] = 'vote-status-ended';
} else {
$vote['status_text'] = '进行中';
$vote['status_class'] = 'vote-status-active';
}
}
// 检查用户是否已投票
$hasVoted = false;
$userVotes = [];
$user = checkLogin();
if ($user) {
$userVoteRecords = $db->getAll('recs', "topic_id = $voteId AND user_id = {$user['id']}");
if (!empty($userVoteRecords)) {
$hasVoted = true;
foreach ($userVoteRecords as $record) {
$userVotes[] = $record['option_id'];
}
}
}
// 计算是否可以投票
$canVote = $vote['status'] == 1 && $vote['statime'] <= $now && $vote['endtime'] >= $now && !$hasVoted && $user;
apiResponse(0, '获取成功', [
'vote' => $vote,
'options' => $options,
'hasVoted' => $hasVoted,
'userVotes' => $userVotes,
'canVote' => $canVote
]);
}
/**
* 处理提交投票
* @param array $params 请求参数
* @param DB $db 数据库操作对象
*/
function handleSubmitVote($params, $db) {
// 验证权限
$user = checkLogin();
if (!$user) {
apiResponse(1, '请先登录');
}
// 获取参数
$topicId = isset($params['topic_id']) ? intval($params['topic_id']) : 0;
$options = isset($params['options']) ? $params['options'] : [];
// 参数验证
if (empty($topicId) || empty($options)) {
apiResponse(1, '参数错误');
}
// 确保options是数组
if (!is_array($options)) {
$options = explode(',', $options);
}
if (empty($options)) {
apiResponse(1, '请至少选择一个选项');
}
// 获取投票信息
$vote = $db->getOne('vote', "id = $topicId");
if (!$vote) {
apiResponse(1, '投票不存在');
}
// 验证投票状态
$now = date('Y-m-d H:i:s');
if ($vote['status'] != 1) {
apiResponse(1, '该投票已被禁用');
}
if ($vote['statime'] > $now) {
apiResponse(1, '该投票尚未开始');
}
if ($vote['endtime'] < $now) {
apiResponse(1, '该投票已经结束');
}
// 检查用户是否已投票
$hasVoted = $db->count('recs', "topic_id = $topicId AND user_id = {$user['id']}");
if ($hasVoted > 0) {
apiResponse(1, '您已经参与过该投票');
}
// 验证选项数量
if ($vote['itype'] == 1 && count($options) > $vote['maxtime']) {
apiResponse(1, "最多只能选择 {$vote['maxtime']}");
}
// 验证选项是否存在
foreach ($options as $optionId) {
$option = $db->getOne('xuan', "id = $optionId AND topic_id = $topicId");
if (!$option) {
apiResponse(1, '选项不存在');
}
}
// 开始事务
$db->startTransaction();
try {
// 添加投票记录
$ip = $_SERVER['REMOTE_ADDR'];
$time = date('Y-m-d H:i:s');
foreach ($options as $optionId) {
$result = $db->insert('recs', [
'topic_id' => $topicId,
'user_id' => $user['id'],
'option_id' => $optionId,
'vote_time' => $time,
'ip' => $ip
]);
if (!$result) {
throw new Exception('提交投票失败');
}
}
// 记录日志
writeLog($user['id'], 'vote', "参与投票:{$vote['title']}");
// 提交事务
$db->commit();
apiResponse(0, '投票成功');
} catch (Exception $e) {
// 回滚事务
$db->rollback();
apiResponse(1, $e->getMessage());
}
}
/**
* 处理获取投票结果
* @param array $params 请求参数
* @param DB $db 数据库操作对象
*/
function handleGetVoteResult($params, $db) {
// 获取投票ID
$voteId = isset($params['id']) ? intval($params['id']) : 0;
if (!$voteId) {
apiResponse(1, '参数错误');
}
// 获取投票信息
$vote = $db->getOne('vote', "id = $voteId");
if (!$vote) {
apiResponse(1, '投票不存在');
}
// 获取选项列表
$options = $db->getAll('xuan', "topic_id = $voteId", '*', 'sort ASC, id ASC');
if (empty($options)) {
apiResponse(1, '暂无投票选项');
}
// 获取投票结果
$sql = "SELECT option_id, COUNT(*) as vote_count FROM " . $db->table('recs') . " WHERE topic_id = $voteId GROUP BY option_id";
$result = $db->query($sql);
$voteResults = [];
$totalVotes = 0;
if ($result) {
while ($row = $result->fetch_assoc()) {
$voteResults[$row['option_id']] = $row['vote_count'];
$totalVotes += $row['vote_count'];
}
}
// 格式化结果
$formattedResults = [];
foreach ($options as $option) {
$voteCount = isset($voteResults[$option['id']]) ? $voteResults[$option['id']] : 0;
$percentage = $totalVotes > 0 ? round(($voteCount / $totalVotes) * 100, 1) : 0;
$formattedResults[] = [
'id' => $option['id'],
'name' => $option['name'],
'idesc' => $option['idesc'],
'imgs' => $option['imgs'],
'count' => $voteCount,
'percentage' => $percentage
];
}
// 用户是否已投票
$hasVoted = false;
$userVotes = [];
$user = checkLogin();
if ($user) {
$userVoteRecords = $db->getAll('recs', "topic_id = $voteId AND user_id = {$user['id']}");
if (!empty($userVoteRecords)) {
$hasVoted = true;
foreach ($userVoteRecords as $record) {
$userVotes[] = $record['option_id'];
}
}
}
apiResponse(0, '获取成功', [
'vote' => $vote,
'options' => $formattedResults,
'totalVotes' => $totalVotes,
'hasVoted' => $hasVoted,
'userVotes' => $userVotes
]);
}
/**
* 处理获取用户的投票记录
* @param array $params 请求参数
* @param DB $db 数据库操作对象
*/
function handleGetUserVotes($params, $db) {
// 验证权限
$user = checkLogin();
if (!$user) {
apiResponse(1, '请先登录');
}
// 获取分页参数
$page = isset($params['page']) ? intval($params['page']) : 1;
$pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : 10;
// 查询该用户参与的投票
$sql = "SELECT DISTINCT v.* FROM " . $db->table('vote') . " v
INNER JOIN " . $db->table('recs') . " r ON v.id = r.topic_id
WHERE r.user_id = " . $user['id'] . "
ORDER BY r.vote_time DESC";
$result = $db->query($sql);
$myVotes = [];
if ($result) {
while ($row = $result->fetch_assoc()) {
$myVotes[] = $row;
}
}
// 计算分页信息
$total = count($myVotes);
$pagination = getPagination($total, $page, $pageSize);
// 按分页截取数据
$myVotesList = array_slice($myVotes, $pagination['offset'], $pagination['pageSize']);
// 当前时间,用于判断投票状态
$now = date('Y-m-d H:i:s');
// 处理投票状态
foreach ($myVotesList as &$vote) {
$vote['status_text'] = '';
$vote['status_class'] = '';
if ($vote['status'] == 0) {
$vote['status_text'] = '已禁用';
$vote['status_class'] = 'vote-status-disabled';
} else {
if ($vote['statime'] > $now) {
$vote['status_text'] = '未开始';
$vote['status_class'] = 'vote-status-pending';
} elseif ($vote['endtime'] < $now) {
$vote['status_text'] = '已结束';
$vote['status_class'] = 'vote-status-ended';
} else {
$vote['status_text'] = '进行中';
$vote['status_class'] = 'vote-status-active';
}
}
}
apiResponse(0, '获取成功', [
'list' => $myVotesList,
'pagination' => $pagination
]);
}
/**
* 统一API响应格式
* @param int $code 状态码0表示成功非0表示失败
* @param string $msg 提示信息
* @param array $data 返回数据
*/
function apiResponse($code = 0, $msg = '', $data = []) {
echo json_encode([
'code' => $code,
'msg' => $msg,
'data' => $data
], JSON_UNESCAPED_UNICODE);
exit;
}