problem_set.php 14 KB

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