mirror of
https://github.com/renbaoshuo/S2OJ.git
synced 2024-11-22 15:28:41 +00:00
refactor(contest/self_reviews): allow admins edit participants' self_reviews
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
58ba28d9b9
commit
946ea8283f
@ -236,97 +236,85 @@ if ($cur_tab == 'dashboard') {
|
|||||||
$reply_question = null;
|
$reply_question = null;
|
||||||
}
|
}
|
||||||
} elseif ($cur_tab == 'self_reviews') {
|
} elseif ($cur_tab == 'self_reviews') {
|
||||||
if (UOJContest::cur()->userHasMarkedParticipated(Auth::user())) {
|
$self_reviews_update_form = new UOJForm('self_reviews_update');
|
||||||
$self_reviews_update_form = new UOJForm('self_review_update');
|
$self_reviews_update_form->config['ctrl_enter_submit'] = true;
|
||||||
$self_reviews_update_form->config['ctrl_enter_submit'] = true;
|
$self_reviews_update_form->addHidden('self_reviews_update__username', '', function ($username, &$vdata) {
|
||||||
|
if (!validateUsername($username)) {
|
||||||
$contest_problems = DB::selectAll([
|
return '无效用户名';
|
||||||
"select problem_id",
|
|
||||||
"from", "contests_problems",
|
|
||||||
"where", ["contest_id" => $contest['id']],
|
|
||||||
"order by level, problem_id"
|
|
||||||
]);
|
|
||||||
for ($i = 0; $i < count($contest_problems); $i++) {
|
|
||||||
$contest_problems[$i]['problem'] = UOJContestProblem::query($contest_problems[$i]['problem_id']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for ($i = 0; $i < count($contest_problems); $i++) {
|
if ($username != Auth::id() && !UOJContest::cur()->userCanManage(Auth::user())) {
|
||||||
$content = DB::selectSingle([
|
return '权限不足';
|
||||||
"select content",
|
|
||||||
"from", "contests_reviews",
|
|
||||||
"where", [
|
|
||||||
"contest_id" => $contest['id'],
|
|
||||||
"problem_id" => $contest_problems[$i]['problem_id'],
|
|
||||||
"poster" => Auth::id(),
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
$self_reviews_update_form->addTextArea('self_review_update__problem_' . $contest_problems[$i]['problem']->getLetter(), [
|
|
||||||
'div_class' => 'mb-3',
|
|
||||||
'label' => '<b>' . $contest_problems[$i]['problem']->getLetter() . '</b>: ' . $contest_problems[$i]['problem']->info['title'],
|
|
||||||
'default_value' => $content,
|
|
||||||
'validator_php' => function ($content) {
|
|
||||||
if (strlen($content) > 200) {
|
|
||||||
return '总结不能超过200字';
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = DB::selectSingle([
|
return '';
|
||||||
"select content",
|
}, null);
|
||||||
"from", "contests_reviews",
|
|
||||||
"where", [
|
$contest_problems = array_map(fn ($row) => UOJContestProblem::query($row['problem_id']), DB::selectAll([
|
||||||
"contest_id" => $contest['id'],
|
"select problem_id",
|
||||||
"problem_id" => -1,
|
"from", "contests_problems",
|
||||||
"poster" => Auth::id(),
|
"where", ["contest_id" => $contest['id']],
|
||||||
],
|
"order by level, problem_id"
|
||||||
]);
|
]));
|
||||||
$self_reviews_update_form->addTextArea('self_review_update__overall', [
|
|
||||||
'label' => '比赛总结',
|
foreach ($contest_problems as $cp) {
|
||||||
'default_value' => $content,
|
$self_reviews_update_form->addTextArea('self_reviews_update__problem_' . $cp->getLetter(), [
|
||||||
|
'div_class' => 'mb-3',
|
||||||
|
'label' => $cp->getTitle(['with' => 'letter']),
|
||||||
|
'default_value' => '',
|
||||||
'validator_php' => function ($content) {
|
'validator_php' => function ($content) {
|
||||||
if (strlen($content) > 200) {
|
if (strlen($content) > 200) {
|
||||||
return '总结不能超过200字';
|
return '长度超过限制';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '';
|
return '';
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$self_reviews_update_form->handle = function () use ($contest, $contest_problems) {
|
|
||||||
for ($i = 0; $i < count($contest_problems); $i++) {
|
|
||||||
if (isset($_POST['self_review_update__problem_' . $contest_problems[$i]['problem']->getLetter()])) {
|
|
||||||
DB::query([
|
|
||||||
"replace into contests_reviews",
|
|
||||||
"(contest_id, problem_id, poster, content)",
|
|
||||||
"values", DB::tuple([
|
|
||||||
$contest['id'],
|
|
||||||
$contest_problems[$i]['problem_id'],
|
|
||||||
Auth::id(),
|
|
||||||
$_POST['self_review_update__problem_' . $contest_problems[$i]['problem']->getLetter()],
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_POST['self_review_update__overall'])) {
|
|
||||||
DB::query([
|
|
||||||
"replace into contests_reviews",
|
|
||||||
"(contest_id, problem_id, poster, content)",
|
|
||||||
"values", DB::tuple([
|
|
||||||
$contest['id'],
|
|
||||||
-1,
|
|
||||||
Auth::id(),
|
|
||||||
$_POST['self_review_update__overall'],
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$self_reviews_update_form->runAtServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$self_reviews_update_form->addTextArea('self_reviews_update__overall', [
|
||||||
|
'label' => '比赛总结',
|
||||||
|
'validator_php' => function ($content) {
|
||||||
|
if (strlen($content) > 300) {
|
||||||
|
return '长度超过限制';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
$self_reviews_update_form->handle = function (&$vdata) use ($contest_problems) {
|
||||||
|
foreach ($contest_problems as $cp) {
|
||||||
|
DB::update([
|
||||||
|
"replace into contests_reviews",
|
||||||
|
DB::bracketed_fields([
|
||||||
|
"contest_id",
|
||||||
|
"problem_id",
|
||||||
|
"poster",
|
||||||
|
"content"
|
||||||
|
]),
|
||||||
|
"values", DB::tuple([
|
||||||
|
UOJContest::info('id'),
|
||||||
|
$cp->info['id'],
|
||||||
|
$_POST['self_reviews_update__username'],
|
||||||
|
$_POST['self_reviews_update__problem_' . $cp->getLetter()],
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::update([
|
||||||
|
"replace into contests_reviews",
|
||||||
|
"(contest_id, problem_id, poster, content)",
|
||||||
|
"values", DB::tuple([
|
||||||
|
UOJContest::info('id'),
|
||||||
|
-1,
|
||||||
|
$_POST['self_reviews_update__username'],
|
||||||
|
$_POST['self_reviews_update__overall'],
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
$self_reviews_update_form->runAtServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
function echoDashboard() {
|
function echoDashboard() {
|
||||||
@ -469,9 +457,12 @@ function echoStandings($is_after_contest_query = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function echoSelfReviews() {
|
function echoSelfReviews() {
|
||||||
global $contest;
|
global $contest, $self_reviews_update_form;
|
||||||
|
|
||||||
uojIncludeView('contest-reviews', ['contest' => $contest] + UOJContest::cur()->queryResult());
|
uojIncludeView('contest-reviews', [
|
||||||
|
'contest' => $contest,
|
||||||
|
'self_reviews_update_form' => $self_reviews_update_form,
|
||||||
|
] + UOJContest::cur()->queryResult());
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<?php echoUOJPageHeader($tabs_info[$cur_tab]['name'] . ' - ' . UOJContest::info('name') . ' - ' . UOJLocale::get('contests::contest')) ?>
|
<?php echoUOJPageHeader($tabs_info[$cur_tab]['name'] . ' - ' . UOJContest::info('name') . ' - ' . UOJLocale::get('contests::contest')) ?>
|
||||||
@ -538,17 +529,7 @@ function echoSelfReviews() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($cur_tab == 'standings' || $cur_tab == 'after_contest_standings') : ?>
|
<?php if ($cur_tab == 'standings' || $cur_tab == 'after_contest_standings' || $cur_tab == 'self_reviews') : ?>
|
||||||
<?php elseif ($cur_tab == 'self_reviews') : ?>
|
|
||||||
<?php if (isset($self_reviews_update_form)) : ?>
|
|
||||||
<hr />
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h4>修改我的赛后总结</h4>
|
|
||||||
<div class="small">赛后总结支持 Markdown 语法。</div>
|
|
||||||
<?php $self_reviews_update_form->printHTML(); ?>
|
|
||||||
</div>
|
|
||||||
<?php endif ?>
|
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
<div class="d-md-none">
|
<div class="d-md-none">
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -5,7 +5,9 @@ $parsedown = HTML::parsedown(['username_with_color' => true]);
|
|||||||
$purifier = HTML::purifier_inline();
|
$purifier = HTML::purifier_inline();
|
||||||
|
|
||||||
foreach ($contest_data['people'] as $person) {
|
foreach ($contest_data['people'] as $person) {
|
||||||
$reviews[$person[0]] = [];
|
$reviews[$person[0]] = [
|
||||||
|
'_can_edit' => Auth::id() == $person[0] || UOJContest::cur()->userCanManage(Auth::user()),
|
||||||
|
];
|
||||||
|
|
||||||
foreach ($contest_data['problems'] as $problem) {
|
foreach ($contest_data['problems'] as $problem) {
|
||||||
$content = DB::selectSingle([
|
$content = DB::selectSingle([
|
||||||
@ -18,7 +20,8 @@ foreach ($contest_data['people'] as $person) {
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$reviews[$person[0]][$problem] = $purifier->purify($parsedown->line($content));
|
$reviews[$person[0]][$problem]['raw'] = $content;
|
||||||
|
$reviews[$person[0]][$problem]['html'] = $purifier->purify($parsedown->line($content));
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = DB::selectSingle([
|
$content = DB::selectSingle([
|
||||||
@ -31,19 +34,34 @@ foreach ($contest_data['people'] as $person) {
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$reviews[$person[0]]['all'] = $purifier->purify($parsedown->line($content));
|
$reviews[$person[0]]['_all']['raw'] = $content;
|
||||||
|
$reviews[$person[0]]['_all']['html'] = $purifier->purify($parsedown->line($content));
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div id="standings"></div>
|
<div id="standings"></div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="UpdateSelfReviewsModal" tabindex="-1" aria-labelledby="UpdateSelfReviewsModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="UpdateSelfReviewsModalLabel">更新赛后总结</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<?php $self_reviews_update_form->printHTML(); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var contest_id = <?= $contest['id'] ?>;
|
var contest_id = <?= $contest['id'] ?>;
|
||||||
var standings = <?= json_encode($standings) ?>;
|
var standings = <?= json_encode($standings) ?>;
|
||||||
var score = <?= json_encode($score) ?>;
|
var score = <?= json_encode($score) ?>;
|
||||||
var problems = <?= json_encode($contest_data['problems']) ?>;
|
var problems = <?= json_encode($contest_data['problems']) ?>;
|
||||||
var reviews = <?= json_encode($reviews) ?>;
|
var reviews = <?= json_encode($reviews, JSON_FORCE_OBJECT) ?>;
|
||||||
var standings_config = <?= json_encode(isset($standings_config) ? $standings_config : ['_config' => true]) ?>;
|
var standings_config = <?= json_encode(isset($standings_config) ? $standings_config : [], JSON_FORCE_OBJECT) ?>;
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$("#standings").long_table(
|
$("#standings").long_table(
|
||||||
@ -59,33 +77,75 @@ foreach ($contest_data['people'] as $person) {
|
|||||||
'<th style="width:16em">赛后总结</th>' +
|
'<th style="width:16em">赛后总结</th>' +
|
||||||
'</tr>',
|
'</tr>',
|
||||||
function(row) {
|
function(row) {
|
||||||
var col_tr = '<tr>';
|
if (reviews[row[2][0]]['_can_edit']) {
|
||||||
col_tr += '<td>' + row[3] + '</td>';
|
var button_update_review = $('<button class="btn btn-sm btn-outline-secondary ms-2" />').append('<i class="bi bi-pencil"></i>');
|
||||||
col_tr += '<td>' + getUserLink(row[2][0], row[2][1]) + '</td>';
|
|
||||||
col_tr += '<td>' + '<span class="uoj-score" data-max="' + problems.length * 100 + '" style="color:' + getColOfScore(row[0] / problems.length) + '">' + row[0] + '</span>' + '</td>';
|
button_update_review.click(function() {
|
||||||
|
$('#UpdateSelfReviewsModalLabel').text('更新 ' + row[2][0] + ' 的赛后总结');
|
||||||
|
$('#input-self_reviews_update__username').val(row[2][0]);
|
||||||
|
|
||||||
|
$.map(problems, function(col, idx) {
|
||||||
|
$('#input-self_reviews_update__problem_' + String.fromCharCode('A'.charCodeAt(0) + idx)).val(reviews[row[2][0]][col]['raw'] || '');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#input-self_reviews_update__overall').val(reviews[row[2][0]]['_all']['raw'] || '');
|
||||||
|
$('#UpdateSelfReviewsModal').modal('show');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var button_update_review = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var res = $('<tr />')
|
||||||
|
.append($('<td />').append(row[3]))
|
||||||
|
.append($('<td />').append(getUserLink(row[2][0], row[2][1])).append(button_update_review))
|
||||||
|
.append($('<td />').append($('<span class="uoj-score" />').attr('data-max', problems.length * 100).css('color', getColOfScore(row[0] / problems.length)).append(row[0])));
|
||||||
|
|
||||||
for (var i = 0; i < problems.length; i++) {
|
for (var i = 0; i < problems.length; i++) {
|
||||||
col_tr += '<td class="align-text-top">';
|
var td = $('<td class="align-text-top" />');
|
||||||
|
|
||||||
col = score[row[2][0]][i];
|
col = score[row[2][0]][i];
|
||||||
|
|
||||||
if (col != undefined) {
|
if (col != undefined) {
|
||||||
col_tr += '<div>';
|
td.append($('<div />').append($('<a class="uoj-score" />').attr('href', '/submission/' + col[2]).attr('data-max', 100).css('color', getColOfScore(col[0])).append(col[0])));
|
||||||
|
|
||||||
if (col[2]) col_tr += '<a href="/submission/' + col[2] + '" class="uoj-score" style="color:' + getColOfScore(col[0]) + '">' + col[0] + '</a>';
|
if (col[2]) {
|
||||||
else col_tr += '<span class="uoj-score" style="color:' + getColOfScore(col[0]) + '">' + col[0] + '</span>';
|
td.append(
|
||||||
|
$('<div />').append(
|
||||||
col_tr += '</div>';
|
$('<a class="uoj-score" />')
|
||||||
|
.attr('href', '/submission/' + col[2])
|
||||||
|
.attr('data-max', 100)
|
||||||
|
.css('color', getColOfScore(col[0]))
|
||||||
|
.append(col[0])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
td.append(
|
||||||
|
$('<div />').append(
|
||||||
|
$('<span class="uoj-score" />')
|
||||||
|
.data('max', 100)
|
||||||
|
.css('color', getColOfScore(col[0]))
|
||||||
|
.append(col[0])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
col_tr += '<div> </div>';
|
td.append($('<div />').append(' '));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reviews[row[2][0]][problems[i]]) {
|
if (reviews[row[2][0]][problems[i]]) {
|
||||||
col_tr += '<div class="mt-2 pt-2 border-top">' + reviews[row[2][0]][problems[i]] + '</div>';
|
td.append($('<div class="mt-2 pt-2 border-top" />').append(reviews[row[2][0]][problems[i]]['html']));
|
||||||
}
|
}
|
||||||
|
|
||||||
col_tr += '</td>';
|
res.append(td);
|
||||||
}
|
}
|
||||||
col_tr += '<td>' + reviews[row[2][0]]['all'] + '</td>';
|
|
||||||
col_tr += '</tr>';
|
if (reviews[row[2][0]]['_all']) {
|
||||||
return col_tr;
|
res.append($('<td />').append(reviews[row[2][0]]['_all']['html']));
|
||||||
|
} else {
|
||||||
|
res.append($('<td />').append(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.uoj_highlight();
|
||||||
}, {
|
}, {
|
||||||
div_classes: standings_config.div_classes ? standings_config.div_classes : ['table-responsive', 'card', 'my-3'],
|
div_classes: standings_config.div_classes ? standings_config.div_classes : ['table-responsive', 'card', 'my-3'],
|
||||||
table_classes: standings_config.table_classes ? standings_config.table_classes : ['table', 'table-bordered', 'text-center', 'align-middle', 'uoj-table', 'uoj-standings-table', 'mb-0'],
|
table_classes: standings_config.table_classes ? standings_config.table_classes : ['table', 'table-bordered', 'text-center', 'align-middle', 'uoj-table', 'uoj-standings-table', 'mb-0'],
|
||||||
|
Loading…
Reference in New Issue
Block a user