problem_set.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. requirePHPLib('form');
  3. requirePHPLib('judger');
  4. requirePHPLib('data');
  5. if ($_POST['migrate_problem_submit'] == 'submit') {
  6. $group = queryUser(DB::escape($_POST['target_group']));
  7. $start = $_POST['start_pid'];
  8. $end = $_POST['end_pid'];
  9. if (!validateUInt($start) || !validateUInt($end)) {
  10. $errmsg = 'Error: 不合法起始终止题号';
  11. becomeMsgPage('<div>' . $errmsg . '</div><a href="/problems">返回</a>');
  12. }
  13. if (!group) {
  14. $errmsg = "Error: 未找到组 {$_POST['target_group']}";
  15. becomeMsgPage('<div>' . $errmsg . '</div><a href="/problems">返回</a>');
  16. }
  17. if (!hasGroupCtrlPermission($myUser, $group)) {
  18. $errmsg = "Error: 你对组 {$group['username']} 没有控制权";
  19. becomeMsgPage('<div>' . $errmsg . '</div><a href="/problems">返回</a>');
  20. }
  21. for ($i = $start; $i <= $end; $i++) {
  22. if (!hasProblemCtrlPermission($myUser, queryProblemBrief($i))) {
  23. $errmsg = "Error: 你对题目 $i 没有控制权";
  24. becomeMsgPage('<div>' . $errmsg . '</div><a href="/problems">返回</a>');
  25. }
  26. }
  27. for ($i = $start; $i <= $end; $i++) {
  28. attachProblemToGroup(queryProblemBrief($i), $group);
  29. DB::update("update problems set ctrl = '{$group['username']}' where id = $i");
  30. }
  31. }
  32. if ($_POST['copy_problem_submit'] == 'submit') {
  33. $problems = explode(',', $_POST['copy_problem_list']);
  34. if (count($problems) > 10) {
  35. $errmsg = "Error: 你不能一次复制超过 10 个题目";
  36. becomeMsgPage('<div>' . $errmsg . '</div><a href="/problems">返回</a>');
  37. }
  38. foreach ($problems as $pid)
  39. if (!hasProblemCtrlPermission($myUser, queryProblemBrief($pid))) {
  40. $errmsg = "Error: 你对题目 $i 没有控制权";
  41. becomeMsgPage('<div>' . $errmsg . '</div><a href="/problems">返回</a>');
  42. }
  43. foreach ($problems as $pid) {
  44. $p = queryProblemBrief($pid);
  45. $title = DB::escape($p['title']);
  46. $q = queryProblemContent($pid);
  47. $stat = DB::escape($q['statement']);
  48. $statmd = DB::escape($q['statement_md']);
  49. DB::query("insert into problems (title, is_hidden, submission_requirement, ctrl) values ('$title', {$p['is_hidden']}, '{$p['submission_requirement']}', '{$p['ctrl']}')");
  50. $id = DB::insert_id();
  51. DB::query("insert into problems_contents (id, statement, statement_md) values ($id, '$stat', '$statmd')");
  52. dataCopyProblemData($pid, $id);
  53. attachProblemToGroup(queryProblemBrief($id), queryUser($p['ctrl']));
  54. }
  55. }
  56. function echoProblem($problem) {
  57. global $myUser;
  58. if (isProblemVisibleToUser($problem, $myUser)) {
  59. echo '<tr class="text-center">';
  60. if ($problem['submission_id']) {
  61. echo '<td class="table-success">';
  62. } else {
  63. echo '<td>';
  64. }
  65. echo '#', $problem['id'], '</td>';
  66. echo '<td class="text-left">';
  67. if ($problem['is_hidden']) {
  68. echo ' <span class="text-danger">[隐藏]</span> ';
  69. }
  70. echo '<a href="/problem/', $problem['id'], '">', $problem['title'], '</a>';
  71. if (isset($_COOKIE['show_tags_mode'])) {
  72. foreach (queryProblemTags($problem['id']) as $tag) {
  73. echo '<a class="uoj-problem-tag">', '<span class="badge badge-pill badge-secondary">', HTML::escape($tag), '</span>', '</a>';
  74. }
  75. }
  76. echo '</td>';
  77. if (isset($_COOKIE['show_submit_mode'])) {
  78. $perc = $problem['submit_num'] > 0 ? round(100 * $problem['ac_num'] / $problem['submit_num']) : 0;
  79. echo <<<EOD
  80. <td><a href="/submissions?problem_id={$problem['id']}&min_score=100&max_score=100">&times;{$problem['ac_num']}</a></td>
  81. <td><a href="/submissions?problem_id={$problem['id']}">&times;{$problem['submit_num']}</a></td>
  82. <td>
  83. <div class="progress bot-buffer-no">
  84. <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="$perc" aria-valuemin="0" aria-valuemax="100" style="width: $perc%; min-width: 20px;">{$perc}%</div>
  85. </div>
  86. </td>
  87. EOD;
  88. }
  89. echo '<td class="text-middle">', getClickZanBlock('P', $problem['id'], $problem['zan']), '</td>';
  90. echo '</tr>';
  91. }
  92. }
  93. $cond = array();
  94. $search_tag = null;
  95. $cur_tab = isset($_GET['tab']) ? $_GET['tab'] : 'all';
  96. if ($cur_tab == 'template') {
  97. $search_tag = "模板题";
  98. }
  99. if (isset($_GET['tag'])) {
  100. $search_tag = $_GET['tag'];
  101. }
  102. if ($search_tag) {
  103. $cond[] = "'".DB::escape($search_tag)."' in (select tag from problems_tags where problems_tags.problem_id = problems.id)";
  104. }
  105. if (isset($_GET["search"])) {
  106. $cond[]="title like '%".DB::escape($_GET["search"])."%' or id like '%".DB::escape($_GET["search"])."%'";
  107. }
  108. if (isset($_GET['group'])) {
  109. $groupname = $_GET['group'];
  110. $cur_tab = $groupname;
  111. $group = queryUser($groupname);
  112. if ($group == null) become404Page();
  113. if (!in_array($groupname, queryUserExtgroups($myUser))) become403Page();
  114. $cond[] = "find_in_set(id, (select privs from user_info where username = '$groupname'))";
  115. }
  116. else {
  117. $group = queryUser('group_default');
  118. $groupname = 'group_default';
  119. }
  120. if ($cond) {
  121. $cond = join($cond, ' and ');
  122. } else {
  123. $cond = '1';
  124. }
  125. $print_new_problem_form = false;
  126. $print_mig_problem_form = false;
  127. $print_copy_problem_form = false;
  128. $print_datum_button = false;
  129. /*
  130. if (($cur_tab == 'all' || $cur_tab == 'template') and isSuperUser($myUser)) {
  131. $print_new_problem_form = true;
  132. $new_problem_form = new UOJForm('new_problem');
  133. $new_problem_form->handle = function() {
  134. global $group;
  135. DB::query("insert into problems (title, is_hidden, submission_requirement, ctrl) values ('New Problem', 1, '{}', 'group_default')");
  136. $id = DB::insert_id();
  137. DB::query("insert into problems_contents (id, statement, statement_md) values ($id, '', '')");
  138. dataNewProblem($id);
  139. attachProblemToGroup(queryProblemBrief($id), $group);
  140. };
  141. $new_problem_form->submit_button_config['align'] = 'right';
  142. $new_problem_form->submit_button_config['class_str'] = 'btn btn-primary';
  143. $new_problem_form->submit_button_config['text'] = UOJLocale::get('problems::add new');
  144. $new_problem_form->submit_button_config['smart_confirm'] = '';
  145. $new_problem_form->runAtServer();
  146. }
  147. */
  148. if (isSuperUser($myUser))
  149. $print_datum_button = true;
  150. if ($group != null and hasGroupCtrlPermission($myUser, $group)) {
  151. $print_new_problem_form = true;
  152. $print_copy_problem_form = true;
  153. $new_problem_form = new UOJForm('new_problem');
  154. $new_problem_form->handle = function() {
  155. global $groupname;
  156. global $group;
  157. DB::query("insert into problems (title, is_hidden, submission_requirement, ctrl) values ('New Problem', 1, '{}', '" . $groupname . "')");
  158. $id = DB::insert_id();
  159. DB::query("insert into problems_contents (id, statement, statement_md) values ($id, '', '')");
  160. dataNewProblem($id);
  161. attachProblemToGroup(queryProblemBrief($id), $group);
  162. };
  163. $new_problem_form->submit_button_config['align'] = 'right';
  164. $new_problem_form->submit_button_config['class_str'] = 'btn btn-primary';
  165. $new_problem_form->submit_button_config['text'] = UOJLocale::get('problems::add new');
  166. $new_problem_form->submit_button_config['smart_confirm'] = '';
  167. $new_problem_form->runAtServer();
  168. $print_mig_problem_form = true;
  169. }
  170. $header = '<tr>';
  171. $header .= '<th class="text-center" style="width:5em;">ID</th>';
  172. $header .= '<th>'.UOJLocale::get('problems::problem').'</th>';
  173. if (isset($_COOKIE['show_submit_mode'])) {
  174. $header .= '<th class="text-center" style="width:5em;">'.UOJLocale::get('problems::ac').'</th>';
  175. $header .= '<th class="text-center" style="width:5em;">'.UOJLocale::get('problems::submit').'</th>';
  176. $header .= '<th class="text-center" style="width:150px;">'.UOJLocale::get('problems::ac rate').'</th>';
  177. }
  178. $header .= '<th class="text-center" style="width:220px;">'.UOJLocale::get('appraisal').'</th>';
  179. $header .= '</tr>';
  180. $tabs_info = array(
  181. 'all' => array(
  182. 'name' => UOJLocale::get('problems::all problems'),
  183. 'url' => "/problems"
  184. ),
  185. 'template' => array(
  186. 'name' => UOJLocale::get('problems::template problems'),
  187. 'url' => "/problems/template"
  188. )
  189. );
  190. foreach (queryUserExtgroups($myUser) as $i => $grp)
  191. if ($grp != '')
  192. $tabs_info[$grp] = array(
  193. 'name' => '团队 ' . $grp .' 题目',
  194. 'url' => "/problems/group/" . $grp
  195. );
  196. $pag_config = array('page_len' => 100);
  197. $pag_config['col_names'] = array('*');
  198. $pag_config['table_name'] = "problems left join best_ac_submissions on best_ac_submissions.submitter = '{$myUser['username']}' and problems.id = best_ac_submissions.problem_id";
  199. $pag_config['cond'] = $cond;
  200. $pag_config['tail'] = "order by id asc";
  201. $pag = new Paginator($pag_config);
  202. $div_classes = array('table-responsive', 'shadow');
  203. $table_classes = array('table', 'table-bordered', 'table-hover', 'table-striped');
  204. ?>
  205. <?php echoUOJPageHeader(UOJLocale::get('problems')) ?>
  206. <div class="row my-4">
  207. <div class="col-sm-9">
  208. <?= HTML::tablist($tabs_info, $cur_tab, 'nav-pills') ?>
  209. </div>
  210. <div class="col-sm-3 order-sm-9 checkbox text-right">
  211. <label class="checkbox-inline" for="input-show_tags_mode"><input type="checkbox" id="input-show_tags_mode" <?= isset($_COOKIE['show_tags_mode']) ? 'checked="checked" ': ''?>/> <?= UOJLocale::get('problems::show tags') ?></label>
  212. <label class="checkbox-inline" for="input-show_submit_mode"><input type="checkbox" id="input-show_submit_mode" <?= isset($_COOKIE['show_submit_mode']) ? 'checked="checked" ': ''?>/> <?= UOJLocale::get('problems::show statistics') ?></label>
  213. </div>
  214. </div>
  215. <div class="top-buffer-sm"></div>
  216. <script type="text/javascript">
  217. $('#input-show_tags_mode').click(function() {
  218. if (this.checked) {
  219. $.cookie('show_tags_mode', '', {path: '/problems'});
  220. } else {
  221. $.removeCookie('show_tags_mode', {path: '/problems'});
  222. }
  223. location.reload();
  224. });
  225. $('#input-show_submit_mode').click(function() {
  226. if (this.checked) {
  227. $.cookie('show_submit_mode', '', {path: '/problems'});
  228. } else {
  229. $.removeCookie('show_submit_mode', {path: '/problems'});
  230. }
  231. location.reload();
  232. });
  233. </script>
  234. <?php
  235. echo '<div class="', join($div_classes, ' '), '">';
  236. echo '<table class="', join($table_classes, ' '), '">';
  237. echo '<thead>';
  238. echo $header;
  239. echo '</thead>';
  240. echo '<tbody>';
  241. foreach ($pag->get() as $idx => $row) {
  242. echoProblem($row);
  243. echo "\n";
  244. }
  245. if ($pag->isEmpty()) {
  246. echo '<tr><td class="text-center" colspan="233">'.UOJLocale::get('none').'</td></tr>';
  247. }
  248. echo '</tbody>';
  249. echo '</table>';
  250. echo '</div>';
  251. if ($print_new_problem_form)
  252. $new_problem_form->printHTML();
  253. if ($print_mig_problem_form) {
  254. echo <<<EOF
  255. <div class="text-right">
  256. <button type="button" class="mt-2 btn btn-secondary" data-toggle="modal" data-target="#MigrateProblemModal">迁移题目</button>
  257. </div>
  258. <div class="modal fade" id="MigrateProblemModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  259. <div class="modal-dialog">
  260. <div class="modal-content">
  261. <div class="modal-header">
  262. <h4 class="modal-title" id="myModalLabel">迁移题目</h4>
  263. <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
  264. </div>
  265. <div class="modal-body">
  266. <form class="form-horizontal" action="" method="post" role="form">
  267. <div class="form-group row">
  268. <input type="hidden" name="migrate_problem_submit" value="submit">
  269. <label for="target_group" class="col-sm-5 control-label">目标组</label>
  270. <div class="col-sm-7">
  271. <input type="text" class="form-control" id="target_group" name="target_group" placeholder="group_default">
  272. </div>
  273. <label for="start_pid" class="col-sm-5 control-label">起始题号</label>
  274. <div class="col-sm-7">
  275. <input type="text" class="form-control" id="start_pid" name="start_pid" placeholder="您必须对范围内的">
  276. </div>
  277. <label for="end_pid" class="col-sm-5 control-label">终止题号</label>
  278. <div class="col-sm-7">
  279. <input type="text" class="form-control" id="end_pid" name="end_pid" placeholder="所有题目都有控制权">
  280. </div>
  281. </div>
  282. </div>
  283. <div class="modal-footer">
  284. <button type="submit" class="btn btn-success">确定</button>
  285. </form>
  286. <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
  287. </div>
  288. </div>
  289. </div>
  290. </div>
  291. EOF;
  292. }
  293. if ($print_copy_problem_form) {
  294. echo <<<EOF
  295. <div class="text-right">
  296. <button type="button" class="mt-2 btn btn-secondary" data-toggle="modal" data-target="#CopyProblemModal">复制题目</button>
  297. </div>
  298. <div class="modal fade" id="CopyProblemModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  299. <div class="modal-dialog">
  300. <div class="modal-content">
  301. <div class="modal-header">
  302. <h4 class="modal-title" id="myModalLabel">复制题目</h4>
  303. <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
  304. </div>
  305. <div class="modal-body">
  306. <form class="form-horizontal" action="" method="post" role="form">
  307. <div class="form-group row">
  308. <input type="hidden" name="copy_problem_submit" value="submit">
  309. <label for="copy_problem_list" class="col-sm-5 control-label">题目列表</label>
  310. <div class="col-sm-7">
  311. <input type="text" class="form-control" id="copy_problem_list" name="copy_problem_list" placeholder="逗号分隔,复制后将连续">
  312. </div>
  313. </div>
  314. </div>
  315. <div class="modal-footer">
  316. <button type="submit" class="btn btn-success">确定</button>
  317. </form>
  318. <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
  319. </div>
  320. </div>
  321. </div>
  322. </div>
  323. EOF;
  324. }
  325. if ($print_datum_button) {
  326. echo <<<EOF
  327. <div class="text-right">
  328. <a type="button" class="mt-2 btn btn-secondary" href="/datums">自动生成数据</a>
  329. </div>
  330. EOF;
  331. }
  332. echo "<div class='mt-4'>";
  333. echo $pag->pagination();
  334. echo "</div>";
  335. ?>
  336. <?php echoUOJPageFooter() ?>