refactor(web/problem): problem difficulty

This commit is contained in:
Baoshuo Ren 2022-12-04 17:27:16 +08:00
parent 61a35c457a
commit dbdc49e73a
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
8 changed files with 213 additions and 9 deletions

View File

@ -617,10 +617,11 @@ CREATE TABLE `problems` (
`is_hidden` tinyint(1) NOT NULL DEFAULT '0',
`submission_requirement` mediumtext COLLATE utf8mb4_unicode_ci,
`hackable` tinyint(1) NOT NULL DEFAULT '0',
`extra_config` varchar(500) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '{"view_content_type":"ALL","view_details_type":"ALL"}',
`zan` int(11) NOT NULL DEFAULT '0',
`ac_num` int(11) NOT NULL DEFAULT '0',
`submit_num` int(11) NOT NULL DEFAULT '0',
`extra_config` json NOT NULL,
`zan` int NOT NULL DEFAULT '0',
`ac_num` int NOT NULL DEFAULT '0',
`submit_num` int NOT NULL DEFAULT '0',
`difficulty` int NOT NULL DEFAULT '-1',
`assigned_to_judger` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'any',
PRIMARY KEY (`id`),
KEY `assigned_to_judger` (`assigned_to_judger`),

View File

@ -116,7 +116,7 @@ function getProblemTR($info) {
$html .= '</td>';
}
if (isset($_COOKIE['show_difficulty'])) {
$html .= HTML::tag('td', [], $problem->getExtraConfig('difficulty'));
$html .= HTML::tag('td', [], UOJProblem::getDifficultyHTML($problem->info['difficulty']));
}
$html .= HTML::tag('td', [], ClickZans::getCntBlock($problem->info['zan']));
$html .= HTML::tag_end('tr');
@ -179,7 +179,7 @@ if (isset($_COOKIE['show_submit_mode'])) {
$header .= '<th class="text-center" style="width:125px;">' . UOJLocale::get('problems::ac ratio') . '</th>';
}
if (isset($_COOKIE['show_difficulty'])) {
$header .= '<th class="text-center" style="width:3em;">' . UOJLocale::get('problems::difficulty') . '</th>';
$header .= '<th class="text-center" style="width:8em;">' . UOJLocale::get('problems::difficulty') . '</th>';
}
$header .= '<th class="text-center" style="width:50px;">' . UOJLocale::get('appraisal') . '</th>';
$header .= '</tr>';

View File

@ -62,6 +62,24 @@ $problem_editor->save = function ($data) {
};
$problem_editor->runAtServer();
$difficulty_form = new UOJForm('difficulty');
$difficulty_form->addSelect('difficulty', [
'options' => UOJProblem::$difficulty,
'default_value' => UOJProblem::info('difficulty'),
]);
$difficulty_form->handle = function () {
DB::update([
"update problems",
"set", [
"difficulty" => $_POST['difficulty'],
],
"where", [
"id" => UOJProblem::info('id'),
],
]);
};
$difficulty_form->runAtServer();
?>
<?php echoUOJPageHeader('题面编辑 - ' . HTML::stripTags(UOJProblem::info('title'))) ?>
@ -153,7 +171,14 @@ $problem_editor->runAtServer();
</div>
</div>
<?php uojIncludeView('sidebar') ?>
<div class="card mt-3">
<div class="card-header fw-bold">
题目难度
</div>
<div class="card-body">
<?php $difficulty_form->printHTML() ?>
</div>
</div>
</aside>
</div>

View File

@ -158,6 +158,60 @@ class UOJForm {
$this->addNoVal($name, $html);
}
public function addSelect($name, $config) {
$config += [
'div_class' => '',
'select_class' => 'form-select',
'options' => [],
'default_value' => '',
'label' => '',
'label_class' => 'form-check-label',
'help' => '',
'help_class' => 'form-text',
'disabled' => false,
];
$html = '';
$html .= HTML::tag_begin('div', ['id' => "div-$name", 'class' => $config['div_class']]);
// Label
if ($config['label']) {
$html .= HTML::tag('label', [
'class' => $config['label_class'],
'for' => "input-$name",
], $config['label']);
}
// Select
$html .= HTML::tag_begin('select', ['id' => "input-$name", 'name' => $name, 'class' => $config['select_class']]);
foreach ($config['options'] as $opt_name => $opt_label) {
if ($opt_name == $config['default_value']) {
$html .= HTML::tag('option', ['value' => $opt_name, 'selected' => 'selected'], $opt_label);
} else {
$html .= HTML::tag('option', ['value' => $opt_name], $opt_label);
}
}
$html .= HTML::tag_end('select');
// Help text
if ($config['help']) {
$html .= HTML::tag('div', ['class' => $config['help_class']], $config['help']);
}
$html .= HTML::tag_end('div');
$this->add(
$name,
$html,
function ($opt) use ($config) {
return isset($config['options'][$opt]) ? '' : "无效选项";
},
null
);
}
public function printHTML() {
echo HTML::tag_begin('form', [
'action' => UOJContext::requestURI(),

View File

@ -8,6 +8,28 @@ class UOJProblem {
use UOJDataTrait;
use UOJArticleTrait;
public static array $difficulty = [
-1 => '暂无评定',
1 => '入门',
2 => '普及-',
3 => '普及/提高-',
4 => '普及+/提高',
6 => '提高+/省选-',
8 => '省选/NOI-',
10 => 'NOI/NOI+/CTSC',
];
public static array $difficulty_color = [
-1 => '#bfbfbf',
1 => '#fe4c61',
2 => '#f39c11',
3 => '#ffc116',
4 => '#52c41a',
6 => '#3498db',
8 => '#9d3dcf',
10 => '#0e1d69',
];
public static function query($id) {
if (!isset($id) || !validateUInt($id)) {
return null;
@ -56,6 +78,14 @@ class UOJProblem {
return isSuperUser($user) || UOJUser::checkPermission($user, 'problems.create');
}
public static function getDifficultyHTML($difficulty = -1) {
$difficulty = (int)$difficulty;
$difficulty_text = self::$difficulty[$difficulty] ?: self::$difficulty[-1];
$difficulty_color = self::$difficulty_color[$difficulty] ?: self::$difficulty_color[-1];
return HTML::tag('span', ['class' => 'uoj-difficulty', 'style' => "color: $difficulty_color"], $difficulty_text);
}
public function __construct($info) {
$this->info = $info;
}

View File

@ -0,0 +1,2 @@
ALTER TABLE `problems` ADD `difficulty` int NOT NULL DEFAULT '-1' AFTER `submit_num`;
ALTER TABLE `problems` MODIFY `extra_config` json NOT NULL;

View File

@ -0,0 +1,91 @@
<?php
return function ($type) {
if ($type == 'up_after_sql') {
DB::init();
for ($i = 0; $i < 10; $i++) {
for ($j = 0; $j < 10; $j++) {
echo "Tag: {$i}.{$j}\n";
$tag_info = DB::selectAll([
"select *",
"from problems_tags",
"where", [
"tag" => "{$i}.{$j}",
]
]);
foreach ($tag_info as $tag) {
DB::delete([
"delete from problems_tags",
"where", [
"id" => $tag['id'],
],
]);
$problem = UOJProblem::query($tag['problem_id']);
$extra_config = $problem->getExtraConfig();
$extra_config['difficulty'] = doubleval("{$i}.{$j}");
DB::update([
"update problems",
"set", [
"extra_config" => json_encode($extra_config),
],
"where", [
"id" => $problem->info['id'],
],
]);
echo "{$problem->info['id']}: {$extra_config['difficulty']}\n";
}
}
}
echo "Tag: DONE";
$problems = DB::selectAll("select * from problems");
foreach ($problems as $info) {
$problem = new UOJProblem($info);
$difficulty = -1;
$extra_config = $problem->getExtraConfig();
if (isset($extra_config['difficulty'])) {
$old_difficulty = $extra_config['difficulty'];
if (0 <= $old_difficulty && $old_difficulty < 2) {
$difficulty = 1;
} else if (2 <= $old_difficulty && $old_difficulty < 3) {
$difficulty = 2;
} else if (3 <= $old_difficulty && $old_difficulty < 4) {
$difficulty = 2;
} else if (4 <= $old_difficulty && $old_difficulty < 5) {
$difficulty = 4;
} else if (5 <= $old_difficulty && $old_difficulty < 6) {
$difficulty = 6;
} else if (6 <= $old_difficulty && $old_difficulty < 8) {
$difficulty = 8;
} else if (8 <= $old_difficulty) {
$difficulty = 10;
}
}
DB::update([
"update problems",
"set", [
"difficulty" => $difficulty,
],
"where", [
"id" => $problem->info['id'],
]
]);
echo "Problem: {$problem->info['id']}";
}
}
};

View File

@ -82,8 +82,9 @@ h6,
padding-right: 5px;
}
.float-right {
float: right;
.uoj-difficulty {
font-size: 0.9em;
font-weight: bold;
}
.uoj-table > tbody > tr:last-child,