feat: 添加管理员操作功能以支持重判和删除提交

This commit is contained in:
2026-04-05 13:55:10 +08:00
parent 489f11ce35
commit 0c7297afd7
4 changed files with 191 additions and 0 deletions

131
web/admin/status_action.php Normal file
View File

@@ -0,0 +1,131 @@
<?php
require_once("../include/db_info.inc.php");
require_once("../include/my_func.inc.php");
if (!(isset($_SESSION[$OJ_NAME.'_'.'administrator']))) {
header("Location: ../loginpage.php");
exit(1);
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header("Location: ../status.php");
exit(0);
}
require_once("../include/check_post_key.php");
function status_action_can_delete($result) {
return $result >= 4 && !in_array($result, array(12, 15, 16, 17), true);
}
function status_action_get_return_url() {
$default_url = "../status.php";
if (!isset($_POST['return_url'])) {
return $default_url;
}
$return_url = trim($_POST['return_url']);
if ($return_url === "") {
return $default_url;
}
$parts = parse_url($return_url);
if ($parts === false || !isset($parts['path']) || basename($parts['path']) !== 'status.php') {
return $default_url;
}
$safe_url = $parts['path'];
if (isset($parts['query']) && $parts['query'] !== "") {
$safe_url .= "?".$parts['query'];
}
return $safe_url;
}
function status_action_redirect($return_url) {
header("Location: ".$return_url);
exit(0);
}
$return_url = status_action_get_return_url();
$sid = isset($_POST['sid']) ? intval($_POST['sid']) : 0;
$action = isset($_POST['action']) ? $_POST['action'] : "";
if ($sid <= 0 || ($action !== 'rejudge' && $action !== 'delete')) {
status_action_redirect($return_url);
}
$solution = pdo_query("SELECT `solution_id`,`problem_id`,`user_id`,`contest_id`,`result` FROM `solution` WHERE `solution_id`=? LIMIT 1", $sid);
if (empty($solution)) {
status_action_redirect($return_url);
}
$row = $solution[0];
$problem_id = intval($row['problem_id']);
$contest_id = intval($row['contest_id']);
$user_id = $row['user_id'];
$result = intval($row['result']);
if ($action === 'rejudge') {
pdo_query("DELETE FROM `sim` WHERE `s_id`=?", $sid);
pdo_query("UPDATE `solution` SET `result`=1,`pass_rate`=0 WHERE `solution_id`=? AND `problem_id`>0", $sid);
if ($OJ_REDIS && class_exists('Redis')) {
$redis_class = 'Redis';
$redis = new $redis_class();
$redis->connect($OJ_REDISSERVER, $OJ_REDISPORT);
if (isset($OJ_REDISAUTH)) {
$redis->auth($OJ_REDISAUTH);
}
$redis->lpush($OJ_REDISQNAME, $sid);
$redis->close();
}
if (isset($OJ_UDP) && $OJ_UDP) {
trigger_judge($sid);
}
status_action_redirect($return_url);
}
if (!status_action_can_delete($result)) {
status_action_redirect($return_url);
}
pdo_query("DELETE FROM `sim` WHERE `s_id`=? OR `sim_s_id`=?", $sid, $sid);
pdo_query("DELETE FROM `source_code` WHERE `solution_id`=?", $sid);
pdo_query("DELETE FROM `source_code_user` WHERE `solution_id`=?", $sid);
pdo_query("DELETE FROM `runtimeinfo` WHERE `solution_id`=?", $sid);
pdo_query("DELETE FROM `compileinfo` WHERE `solution_id`=?", $sid);
pdo_query("DELETE FROM `custominput` WHERE `solution_id`=?", $sid);
pdo_query("DELETE FROM `solution` WHERE `solution_id`=? LIMIT 1", $sid);
if ($problem_id > 0) {
pdo_query(
"UPDATE `problem` SET `accepted`=(SELECT count(1) FROM `solution` WHERE `problem_id`=? AND `result`=4), `submit`=(SELECT count(1) FROM `solution` WHERE `problem_id`=?) WHERE `problem_id`=?",
$problem_id,
$problem_id,
$problem_id
);
}
if ($contest_id > 0 && $problem_id > 0) {
pdo_query(
"UPDATE `contest_problem` SET `c_accepted`=(SELECT count(1) FROM `solution` WHERE `problem_id`=? AND `contest_id`=? AND `result`=4), `c_submit`=(SELECT count(1) FROM `solution` WHERE `problem_id`=? AND `contest_id`=?) WHERE `problem_id`=? AND `contest_id`=?",
$problem_id,
$contest_id,
$problem_id,
$contest_id,
$problem_id,
$contest_id
);
}
pdo_query(
"UPDATE `users` SET `solved`=(SELECT count(DISTINCT `problem_id`) FROM `solution` WHERE `user_id`=? AND `result`=4), `submit`=(SELECT count(*) FROM `solution` WHERE `user_id`=? AND `problem_id`>0) WHERE `user_id`=?",
$user_id,
$user_id,
$user_id
);
status_action_redirect($return_url);
?>