From 0eb5b0f62ac100e2b2f0ac793b6d790aab06a677 Mon Sep 17 00:00:00 2001 From: esp Date: Tue, 18 Aug 2015 13:21:33 +0800 Subject: [PATCH 01/17] =?UTF-8?q?[=E5=89=8D=E7=AB=AF]=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E9=87,=E6=AF=94=E8=B5=9B=E5=88=97=E8=A1=A8js?= =?UTF-8?q?=E7=9A=84=E6=96=87=E4=BB=B6=E5=90=8D=5Flist.js.=20=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86=E6=AF=94=E8=B5=9B=E5=88=97=E8=A1=A8=E5=92=8C?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=AF=94=E8=B5=9B=E7=9A=84=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?(=E5=A4=A7=E4=BD=93=E5=A4=E6=A0=B7=E5=BC=8F)[CI=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/js/app/admin/contest/contest.js | 242 --------------------- template/admin/contest/add_contest.html | 4 +- 2 files changed, 2 insertions(+), 244 deletions(-) delete mode 100644 static/src/js/app/admin/contest/contest.js diff --git a/static/src/js/app/admin/contest/contest.js b/static/src/js/app/admin/contest/contest.js deleted file mode 100644 index 736ce58..0000000 --- a/static/src/js/app/admin/contest/contest.js +++ /dev/null @@ -1,242 +0,0 @@ -require(["jquery", "avalon", "editor", "uploader", "bs_alert", "datetimepicker", - "validation",], - function ($, avalon, editor, uploader, bs_alert) { - avalon.vmodels.add_contest = null; - $("#add-contest-form") - .formValidation({ - framework: "bootstrap", - fields: { - name: { - validators: { - notEmpty: { - message: "请填写比赛名称" - }, - stringLength: { - min: 1, - max: 30, - message: "名称不能超过30个字" - } - } - }, - description: { - validators: { - notEmpty: { - message: "请输入描述" - } - } - }, - start_time: { - validators: { - notEmpty: { - message: "请填写开始时间" - - }, - date: { - format: "YYYY-MM-DD h:m", - message: "请输入一个正确的日期格式" - } - } - }, - end_time: { - validators: { - notEmpty: { - message: "请填写结束时间" - }, - date: { - format: "YYYY-MM-DD h:m", - message: "请输入一个正确的日期格式" - } - } - }, - password: { - validators: { - stringLength: { - min: 0, - max: 30, - message: "密码不能超过10个字符" - } - } - }, - "problem_name[]": { - validators: { - notEmpty: { - message: "请输入题目名称" - }, - stringLength: { - min: 1, - max: 30, - message: "题目不能超过30个字符" - } - } - }, - "cpu[]": { - validators: { - notEmpty: { - message: "请输入时间限制" - }, - integer: { - message: "时间限制用整数表示" - }, - between: { - inclusive: true, - min: 1, - max: 5000, - message: "只能在1-5000之间" - } - } - }, - "memory[]": { - validators: { - notEmpty: { - message: "请输入内存" - }, - integer: { - message: "请输入一个合法的数字" - } - } - } - } - }) - .on("success.form.fv", function (e) { - e.preventDefault(); - var data = { - title: vm.title, description: vm.description, start_time: vm.startTime, end_time: vm.endTime, - password: vm.password, model: vm.model, open_rank: vm.openRank, problems: [] - }; - for (var i = 0; i < vm.problems.length; i++) { - var problem = { - title: vm.problems[i].title, description: vm.problems[i].description, - cpu: vm.problems[i].cpu, memory: vm.problems[i].memory, samples: [] - }; - for (var j = 0; j < vm.problems[i].samples.length; j++) { - problem.samples.push({ - input: vm.problems[i].samples[j].input, - output: vm.problems[i].samples[j].output - }) - } - data.problems.push(problem); - } - console.log(data); - }); - function make_id() { - var text = ""; - var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - for (var i = 0; i < 5; i++) - text += possible.charAt(Math.floor(Math.random() * possible.length)); - return text; - } - var upLoaderInited = false; - editor("#editor"); - - var vm = avalon.define({ - $id: "add_contest", - title: "", - problemCount: 0, - description: "", - startTime: "", - endTime: "", - password: "", - model: "", - openRank: false, - problems: [], - problemNo: "-1", - add_problem: function () { - var problem_id = make_id(); - var problem = { - id: problem_id, - title: "", - cpu: 1000, - memory: 256, - description: "", - samples: [], - visible: true, - test_case_id: "", - testCaseList: [], - hint: "", - difficulty: 0, - uploadSuccess: false - }; - vm.problems.push(problem); - var id = vm.problems.length - 1; - editor("#problem-" + problem_id + "-description"); - var hinteditor = editor("#problem-" + problem_id +"-hint"); - $("#add-contest-form").formValidation('addField', $('[name="problem_name[]"]')); - $("#add-contest-form").formValidation('addField', $('[name="cpu[]"]')); - $("#add-contest-form").formValidation('addField', $('[name="memory[]"]')); - }, - del_problem: function (problem) { - if (confirm("你确定要删除么?")) { - vm.problems.remove(problem); - } - }, - toggle: function (item) { - item.visible = !item.visible; - }, - add_sample: function (problem) { - problem.samples.push({id: make_id(), visible: true, input: "", output: ""}); - }, - del_sample: function (problem, sample) { - if (confirm("你确定要删除么?")) { - problem.samples.remove(sample); - } - }, - getBtnContent: function (item) { - if (item.visible) - return "折叠"; - return "展开"; - } - }); - - uploader("#uploader", "/api/admin/test_case_upload/", function (file, respond) { - if (respond.code) - bs_alert(respond.data); - else { - var index = parseInt(vm.problemNo)-1; - vm.problems[index].test_case_id = respond.data.test_case_id; - vm.problems[index].uploadSuccess = true; - vm.problems[index].testCaseList = []; - for (var i = 0; i < respond.data.file_list.input.length; i++) { - vm.problems[index].testCaseList.push({ - input: respond.data.file_list.input[i], - output: respond.data.file_list.output[i] - }); - } - bs_alert("测试数据添加成功!共添加"+vm.problems[index].testCaseList.length +"组测试数据"); - } - }, - function(){ - console.log(vm.problemNo); - if (vm.problemNo == "-1") - { - bs_alert("你还未指定一道题目!"); - return false; - } - } - ); - isUploaderInited = true; - - avalon.scan(); - - $("#contest_start_time").datetimepicker({ - format: "yyyy-mm-dd hh:ii", - minuteStep: 5, - weekStart: 1, - language: "zh-CN" - }); - $("#contest_end_time").datetimepicker({ - format: "yyyy-mm-dd hh:ii", - minuteStep: 5, - weekStart: 1, - language: "zh-CN" - }); - $("#contest_start_time").datetimepicker() - .on("hide", function (ev) { - $("#add-contest-form") - .formValidation("revalidateField", "start_time"); - }); - $("#contest_end_time").datetimepicker() - .on("hide", function (ev) { - $("#add-contest-form") - .formValidation("revalidateField", "end_time"); - }); - }); \ No newline at end of file diff --git a/template/admin/contest/add_contest.html b/template/admin/contest/add_contest.html index 1d27710..f3481cb 100644 --- a/template/admin/contest/add_contest.html +++ b/template/admin/contest/add_contest.html @@ -196,5 +196,5 @@ - - \ No newline at end of file + + From c7d7bc7ef11f8c4fb49b25836c814e65e08977b3 Mon Sep 17 00:00:00 2001 From: esp Date: Tue, 18 Aug 2015 13:28:02 +0800 Subject: [PATCH 02/17] =?UTF-8?q?=E6=B7[=E5=89=8D=E7=AB=AF]=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=AF=94=E8=E5=90=8E=E5=8F=B0=E6=AF=94=E8=B5=9B?= =?UTF-8?q?=E5=88=97=E8=A1=A8[CI=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/js/app/admin/contest/add_contest.js | 252 ++++++++++++++++++ .../src/js/app/admin/contest/contest_list.js | 87 ++++++ template/admin/contest/contest_list.html | 96 +++++++ 3 files changed, 435 insertions(+) create mode 100644 static/src/js/app/admin/contest/add_contest.js create mode 100644 static/src/js/app/admin/contest/contest_list.js create mode 100644 template/admin/contest/contest_list.html diff --git a/static/src/js/app/admin/contest/add_contest.js b/static/src/js/app/admin/contest/add_contest.js new file mode 100644 index 0000000..1e88501 --- /dev/null +++ b/static/src/js/app/admin/contest/add_contest.js @@ -0,0 +1,252 @@ +require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "datetimePicker", + "formValidation",], + function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) { + avalon.vmodels.add_contest = null; + $("#add-contest-form") + .formValidation({ + framework: "bootstrap", + fields: { + name: { + validators: { + notEmpty: { + message: "请填写比赛名称" + }, + stringLength: { + min: 1, + max: 30, + message: "名称不能超过30个字" + } + } + }, + description: { + validators: { + notEmpty: { + message: "请输入描述" + } + } + }, + start_time: { + validators: { + notEmpty: { + message: "请填写开始时间" + + }, + date: { + format: "YYYY-MM-DD h:m", + message: "请输入一个正确的日期格式" + } + } + }, + end_time: { + validators: { + notEmpty: { + message: "请填写结束时间" + }, + date: { + format: "YYYY-MM-DD h:m", + message: "请输入一个正确的日期格式" + } + } + }, + password: { + validators: { + stringLength: { + min: 0, + max: 30, + message: "密码不能超过10个字符" + } + } + }, + "problem_name[]": { + validators: { + notEmpty: { + message: "请输入题目名称" + }, + stringLength: { + min: 1, + max: 30, + message: "题目不能超过30个字符" + } + } + }, + "cpu[]": { + validators: { + notEmpty: { + message: "请输入时间限制" + }, + integer: { + message: "时间限制用整数表示" + }, + between: { + inclusive: true, + min: 1, + max: 5000, + message: "只能在1-5000之间" + } + } + }, + "memory[]": { + validators: { + notEmpty: { + message: "请输入内存" + }, + integer: { + message: "请输入一个合法的数字" + } + } + } + } + }) + .on("success.form.fv", function (e) { + e.preventDefault(); + var data = { + title: vm.title, + description: vm.description, + start_time: vm.startTime, + end_time: vm.endTime, + password: vm.password, + mode: vm.model, + show_rank: vm.openRank + }; + $.ajax({ + beforeSend: csrfTokenHeader, + url: "/api/admin/contest/", + dataType: "json", + data: data, + method: "post", + contentType: "application/json", + success: function (data) { + if (!data.code) { + bsAlert("添加成功!"); + console.log(data); + } + else { + bsAlert(data.data); + console.log(data); + } + } + }); + console.log(data); + }); + function make_id() { + var text = ""; + var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for (var i = 0; i < 5; i++) + text += possible.charAt(Math.floor(Math.random() * possible.length)); + return text; + } + var upLoaderInited = false; + editor("#editor"); + + var vm = avalon.define({ + $id: "add_contest", + title: "", + problemCount: 0, + description: "", + startTime: "", + endTime: "", + password: "", + model: "", + openRank: false, + problems: [], + problemNo: "-1", + add_problem: function () { + var problem_id = make_id(); + var problem = { + id: problem_id, + title: "", + cpu: 1000, + memory: 256, + description: "", + samples: [], + visible: true, + test_case_id: "", + testCaseList: [], + hint: "", + difficulty: 0, + uploadSuccess: false + }; + vm.problems.push(problem); + var id = vm.problems.length - 1; + editor("#problem-" + problem_id + "-description"); + var hinteditor = editor("#problem-" + problem_id +"-hint"); + $("#add-contest-form").formValidation('addField', $('[name="problem_name[]"]')); + $("#add-contest-form").formValidation('addField', $('[name="cpu[]"]')); + $("#add-contest-form").formValidation('addField', $('[name="memory[]"]')); + }, + del_problem: function (problem) { + if (confirm("你确定要删除么?")) { + vm.problems.remove(problem); + } + }, + toggle: function (item) { + item.visible = !item.visible; + }, + add_sample: function (problem) { + problem.samples.push({id: make_id(), visible: true, input: "", output: ""}); + }, + del_sample: function (problem, sample) { + if (confirm("你确定要删除么?")) { + problem.samples.remove(sample); + } + }, + getBtnContent: function (item) { + if (item.visible) + return "折叠"; + return "展开"; + } + }); + + uploader("#uploader", "/api/admin/test_case_upload/", function (file, respond) { + if (respond.code) + bsAlert(respond.data); + else { + var index = parseInt(vm.problemNo)-1; + vm.problems[index].test_case_id = respond.data.test_case_id; + vm.problems[index].uploadSuccess = true; + vm.problems[index].testCaseList = []; + for (var i = 0; i < respond.data.file_list.input.length; i++) { + vm.problems[index].testCaseList.push({ + input: respond.data.file_list.input[i], + output: respond.data.file_list.output[i] + }); + } + bsAlert("测试数据添加成功!共添加"+vm.problems[index].testCaseList.length +"组测试数据"); + } + }, + function(){ + console.log(vm.problemNo); + if (vm.problemNo == "-1") + { + bsAlert("你还未指定一道题目!"); + return false; + } + } + ); + isUploaderInited = true; + + avalon.scan(); + + $("#contest_start_time").datetimepicker({ + format: "yyyy-mm-dd hh:ii", + minuteStep: 5, + weekStart: 1, + language: "zh-CN" + }); + $("#contest_end_time").datetimepicker({ + format: "yyyy-mm-dd hh:ii", + minuteStep: 5, + weekStart: 1, + language: "zh-CN" + }); + $("#contest_start_time").datetimepicker() + .on("hide", function (ev) { + $("#add-contest-form") + .formValidation("revalidateField", "start_time"); + }); + $("#contest_end_time").datetimepicker() + .on("hide", function (ev) { + $("#add-contest-form") + .formValidation("revalidateField", "end_time"); + }); + }); \ No newline at end of file diff --git a/static/src/js/app/admin/contest/contest_list.js b/static/src/js/app/admin/contest/contest_list.js new file mode 100644 index 0000000..823179e --- /dev/null +++ b/static/src/js/app/admin/contest/contest_list.js @@ -0,0 +1,87 @@ +require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"], function ($, avalon, csrfTokenHeader, bsAlert, editor) { + + avalon.ready(function () { + if(avalon.vmodels.contestList){ + vm = avalon.vmodels.contestList; + vm.editingContest = 0; + } + else { + var vm = avalon.define({ + $id: "contestList", + contestList: [], + previousPage: 0, + nextPage: 0, + page: 1, + totalPage: 1, + keyword: "", + editingContestId: 0, + editTitle: "", + getNext: function () { + if (!vm.nextPage) + return; + getPageData(vm.page + 1); + }, + getPrevious: function () { + if (!vm.previousPage) + return; + getPageData(vm.page - 1); + }, + getBtnClass: function (btn) { + if (btn == "next") { + return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + else { + return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + }, + getPage: function (page_index) { + getPageData(page_index); + }, + showEditContestArea: function (contestId) { + if (contestId == vm.editingContestId) + vm.editingContestId = 0; + else { + vm.editingContestId = contestId; + vm.editTitle = vm.contestList[contestId-1].title; + editor("#editor").setValue(vm.contestList[contestId-1].description); + } + } + }); + + getPageData(1); + } + + function getPageData(page) { +/* + var url = "/api/admin/contest/?paging=true&page=" + page + "&page_size=10"; + if (vm.keyword != "") + url += "&keyword=" + vm.keyword; + $.ajax({ + url: url, + dataType: "json", + method: "get", + success: function (data) { + if (!data.code) { + vm.contestList = data.data.results; + vm.totalPage = data.data.total_page; + vm.previousPage = data.data.previous_page; + vm.nextPage = data.data.next_page; + vm.page = page; + } + else { + bsAlert(data.data); + } + } + }); +*/ + vm.contestList =[{id: 1, title:"The first contest", created_by: {username:"owen"}, description:"

this contest is just for

fun

"}]; + vm.totalPage = 1; + vm.previousPage = false; + vm.nextPage = false; + vm.page = 1; + } + + + }); + avalon.scan(); +}); diff --git a/template/admin/contest/contest_list.html b/template/admin/contest/contest_list.html new file mode 100644 index 0000000..0df7ba3 --- /dev/null +++ b/template/admin/contest/contest_list.html @@ -0,0 +1,96 @@ +
+

比赛列表

+ +
+
+
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ID比赛比赛类型比赛模式公开排名开始时间结束时间创建时间创建者
{{ el.id }}{{ el.title }}{{ el.type }}{{ el.mode }}{{ el.show_rank }}{{ el.start_time|date("yyyy-MM-dd HH:mm:ss")}}{{ el.end_time|date("yyyy-MM-dd HH:mm:ss")}}{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}{{ el.created_by.username }} + +
+
+ 页数:{{ page }}/{{ totalPage }}   + + +
+
+
+ + + + + 请填写比赛描述 +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
+ From 766fc20dbef1452c56722fa352899c2a62890e2c Mon Sep 17 00:00:00 2001 From: esp Date: Tue, 18 Aug 2015 20:37:36 +0800 Subject: [PATCH 03/17] =?UTF-8?q?[=E5=89=8D=E7=AB=AF]=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86=E6=B7=BB=E5=8A=A0=E6=AF=94=E8=B5=9B=E9=A1=B5=E7=9A=84?= =?UTF-8?q?=E5=BD=A2=E5=BC=8F=E7=BB=93=E6=9E=84,=E4=BB=8D=E6=9C=89bug[CI?= =?UTF-8?q?=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/js/app/admin/contest/add_contest.js | 172 +++++------------- template/admin/contest/add_contest.html | 91 ++++----- 2 files changed, 92 insertions(+), 171 deletions(-) diff --git a/static/src/js/app/admin/contest/add_contest.js b/static/src/js/app/admin/contest/add_contest.js index 1e88501..e461bf7 100644 --- a/static/src/js/app/admin/contest/add_contest.js +++ b/static/src/js/app/admin/contest/add_contest.js @@ -1,103 +1,8 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "datetimePicker", - "formValidation",], + "validator"], function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) { avalon.vmodels.add_contest = null; - $("#add-contest-form") - .formValidation({ - framework: "bootstrap", - fields: { - name: { - validators: { - notEmpty: { - message: "请填写比赛名称" - }, - stringLength: { - min: 1, - max: 30, - message: "名称不能超过30个字" - } - } - }, - description: { - validators: { - notEmpty: { - message: "请输入描述" - } - } - }, - start_time: { - validators: { - notEmpty: { - message: "请填写开始时间" - - }, - date: { - format: "YYYY-MM-DD h:m", - message: "请输入一个正确的日期格式" - } - } - }, - end_time: { - validators: { - notEmpty: { - message: "请填写结束时间" - }, - date: { - format: "YYYY-MM-DD h:m", - message: "请输入一个正确的日期格式" - } - } - }, - password: { - validators: { - stringLength: { - min: 0, - max: 30, - message: "密码不能超过10个字符" - } - } - }, - "problem_name[]": { - validators: { - notEmpty: { - message: "请输入题目名称" - }, - stringLength: { - min: 1, - max: 30, - message: "题目不能超过30个字符" - } - } - }, - "cpu[]": { - validators: { - notEmpty: { - message: "请输入时间限制" - }, - integer: { - message: "时间限制用整数表示" - }, - between: { - inclusive: true, - min: 1, - max: 5000, - message: "只能在1-5000之间" - } - } - }, - "memory[]": { - validators: { - notEmpty: { - message: "请输入内存" - }, - integer: { - message: "请输入一个合法的数字" - } - } - } - } - }) - .on("success.form.fv", function (e) { + $("#add-contest-form").validator().on('submit', function (e) { e.preventDefault(); var data = { title: vm.title, @@ -127,7 +32,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date } }); console.log(data); - }); + }) function make_id() { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; @@ -135,13 +40,11 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date text += possible.charAt(Math.floor(Math.random() * possible.length)); return text; } - var upLoaderInited = false; editor("#editor"); var vm = avalon.define({ $id: "add_contest", title: "", - problemCount: 0, description: "", startTime: "", endTime: "", @@ -149,45 +52,61 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date model: "", openRank: false, problems: [], - problemNo: "-1", + editingProblemId: 0, + editSamples: [], + editTestCaseList: [], + showProblemEditArea: function (problemIndex) { + if (vm.editingProblemId == problemIndex){ + vm.problems[vm.editingProblemId-1].samples = vm.editSamples; + vm.editingProblemId = 0; + } + else { + vm.problems[problemIndex-1].samples = vm.editSamples; + vm.problems[problemIndex-1].testCaseList = vm.editTestCaseList; + vm.editingProblemId = problemIndex; + editSamples = vm.problems[vm.editingProblemId-1].samples; + editTestCaseList = vm.problems[vm.editingProblemId-1].testCaseList; + } + }, add_problem: function () { var problem_id = make_id(); var problem = { - id: problem_id, title: "", - cpu: 1000, - memory: 256, + timeLimit: 1000, + memoryLimit: 256, description: "", samples: [], visible: true, test_case_id: "", testCaseList: [], hint: "", - difficulty: 0, - uploadSuccess: false + score: 0, + uploadSuccess: false, }; vm.problems.push(problem); - var id = vm.problems.length - 1; - editor("#problem-" + problem_id + "-description"); - var hinteditor = editor("#problem-" + problem_id +"-hint"); - $("#add-contest-form").formValidation('addField', $('[name="problem_name[]"]')); - $("#add-contest-form").formValidation('addField', $('[name="cpu[]"]')); - $("#add-contest-form").formValidation('addField', $('[name="memory[]"]')); + vm.showProblemEditArea(vm.problems.length); }, - del_problem: function (problem) { + del_problem: function (problemIndex) { if (confirm("你确定要删除么?")) { - vm.problems.remove(problem); + vm.editingProblemId = 0; + vm.problems.remove(vm.problems[problemIndex-1]); } }, + hidden: function () { + vm.problems[vm.editingProblemId-1].samples = editSamples; + vm.problems[vm.editingProblemId-1].testCaseList = editTestCaseList; + vm.editingProblemId = 0; + }, toggle: function (item) { item.visible = !item.visible; }, - add_sample: function (problem) { - problem.samples.push({id: make_id(), visible: true, input: "", output: ""}); + add_sample: function () { + //vm.problems[vm.editingProblemId-1].samples.push({visible: true, input: "", output: ""}); + vm.editSamples.push({visible: true, input: "", output: ""}); }, - del_sample: function (problem, sample) { + del_sample: function (sample) { if (confirm("你确定要删除么?")) { - problem.samples.remove(sample); + editSamples.remove(sample); } }, getBtnContent: function (item) { @@ -201,29 +120,28 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date if (respond.code) bsAlert(respond.data); else { - var index = parseInt(vm.problemNo)-1; - vm.problems[index].test_case_id = respond.data.test_case_id; - vm.problems[index].uploadSuccess = true; - vm.problems[index].testCaseList = []; + vm.problems[vm.editingProblemId-1].test_case_id = respond.data.test_case_id; + vm.problems[vm.editingProblemId-1].uploadSuccess = true; + vm.editTestCaseList = []; for (var i = 0; i < respond.data.file_list.input.length; i++) { - vm.problems[index].testCaseList.push({ + vm.editTestCaseList.push({ input: respond.data.file_list.input[i], output: respond.data.file_list.output[i] }); } - bsAlert("测试数据添加成功!共添加"+vm.problems[index].testCaseList.length +"组测试数据"); + vm.problems[vm.editingProblemId-1].testCaseList = vm.editTestCaseList; + bsAlert("测试数据添加成功!共添加"+editTestCaseList.length +"组测试数据"); } }, function(){ console.log(vm.problemNo); - if (vm.problemNo == "-1") + if (vm.editingProblemId == 0) { bsAlert("你还未指定一道题目!"); return false; } } ); - isUploaderInited = true; avalon.scan(); @@ -249,4 +167,4 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date $("#add-contest-form") .formValidation("revalidateField", "end_time"); }); - }); \ No newline at end of file + }); diff --git a/template/admin/contest/add_contest.html b/template/admin/contest/add_contest.html index f3481cb..7db52c7 100644 --- a/template/admin/contest/add_contest.html +++ b/template/admin/contest/add_contest.html @@ -75,77 +75,78 @@
添加 - -
- - - -
-
选择文件
-
-
+ + + + + + + + + + + + + +
编号题目测试数据
题目{{ $index+1 }}{{ el.title }}{{ el.testCaseList.length }}组 + 编辑 + 删除 +
+
-
+ +
-
+
- +
- - 请填写题目描述 + + 请填写题目描述
- +
- +
- +
- - + +
添加 - -
-
-
+ ms-click="add_sample()">添加 +
+
+
样例{{$index + 1}} - {{ getBtnContent(sample)}} - + ms-click="toggle(sample)">{{ getBtnContent(sample)}} - 删除 - + ms-click="del_sample(sample)">删除
@@ -167,17 +168,20 @@
-
+ +
+
选择文件
+
请将所有测试用例打包在一个文件中上传,所有文件要在压缩包的根目录,且输入输出文件名要以从1开始连续数字标识要对应例如:
1.in 1.out 2.in 2.out
- +
- + @@ -197,4 +201,3 @@ - From 78050548aa2217522b21f1145f531a2cd9093517 Mon Sep 17 00:00:00 2001 From: esp Date: Wed, 19 Aug 2015 10:50:09 +0800 Subject: [PATCH 04/17] =?UTF-8?q?[=E5=89=8D=E7=AB=AF]=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=AF=94=E8=B5=9B=E9=A1=B5=E9=9D=A2=E8=BF=9B=E4=B8=80=E6=AD=A5?= =?UTF-8?q?=E5=AE=8C=E5=96=84,=E6=B7=BB=E5=8A=A0=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=8C=85=E6=8B=AC=E6=98=AF=E5=90=A6=E6=98=BE=E7=A4=BA=E6=8F=90?= =?UTF-8?q?=E4=BA=A4,=E6=AF=94=E8=B5=9B=E6=A8=A1=E5=BC=8F,=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=88=86=E5=80=BC,=E5=85=81=E8=AE=B8=E5=8F=82?= =?UTF-8?q?=E5=8A=A0=E6=AF=94=E8=B5=9B=E7=9A=84=E7=94=A8=E6=88=B7=E7=BB=84?= =?UTF-8?q?,=E5=B9=B6=E5=AE=8C=E5=96=84=E5=86=85=E9=83=A8=E9=80=BB?= =?UTF-8?q?=E8=BE=91,=E5=9F=BA=E6=9C=AC=E5=8F=AF=E7=94=A8=E4=BA=86,?= =?UTF-8?q?=E5=8F=AA=E6=98=AF=E6=B2=A1=E5=86=99ajax=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E6=95=B0=E6=8D=AE,=E5=92=8C=E5=95=E6=8B=89=E5=E5=8F=96?= =?UTF-8?q?=E5=B0=8F=E7=BB=84=E4=BF=A1=E6=81=AF=E7=9A=84=E9=83=A8=E5=88=86?= =?UTF-8?q?[CI=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/css/add_contest.css | 5 + .../src/js/app/admin/contest/add_contest.js | 135 ++++++++++-------- template/admin/contest/add_contest.html | 111 ++++++++------ 3 files changed, 153 insertions(+), 98 deletions(-) create mode 100644 static/src/css/add_contest.css diff --git a/static/src/css/add_contest.css b/static/src/css/add_contest.css new file mode 100644 index 0000000..f9a00e6 --- /dev/null +++ b/static/src/css/add_contest.css @@ -0,0 +1,5 @@ +.group-tag { + padding-left: 5px; color: #46799b; background: #e0eaf1; white-space: nowrap; + overflow: hidden; cursor: pointer; border-radius: 2px 0 0 2px; + float: left; padding: 0 4px;box-sizing: border-box;list-style-type: none; margin: 5px; +} diff --git a/static/src/js/app/admin/contest/add_contest.js b/static/src/js/app/admin/contest/add_contest.js index e461bf7..8b89c79 100644 --- a/static/src/js/app/admin/contest/add_contest.js +++ b/static/src/js/app/admin/contest/add_contest.js @@ -3,44 +3,44 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) { avalon.vmodels.add_contest = null; $("#add-contest-form").validator().on('submit', function (e) { - e.preventDefault(); - var data = { - title: vm.title, - description: vm.description, - start_time: vm.startTime, - end_time: vm.endTime, - password: vm.password, - mode: vm.model, - show_rank: vm.openRank - }; - $.ajax({ - beforeSend: csrfTokenHeader, - url: "/api/admin/contest/", - dataType: "json", - data: data, - method: "post", - contentType: "application/json", - success: function (data) { - if (!data.code) { - bsAlert("添加成功!"); - console.log(data); - } - else { - bsAlert(data.data); - console.log(data); - } - } - }); - console.log(data); + if (!e.isDefaultPrevented()){ + alert("smoething went wrong!"); + } + else{ + var data = { + title: vm.title, + description: vm.description, + start_time: vm.startTime, + end_time: vm.endTime, + password: vm.password, + mode: vm.model, + show_rank: vm.openRank + }; + $.ajax({ + beforeSend: csrfTokenHeader, + url: "/api/admin/contest/", + dataType: "json", + data: data, + method: "post", + contentType: "application/json", + success: function (data) { + if (!data.code) { + bsAlert("添加成功!"); + console.log(data); + } + else { + bsAlert(data.data); + console.log(data); + } + } + }); + console.log(data); + } + return false; }) - function make_id() { - var text = ""; - var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - for (var i = 0; i < 5; i++) - text += possible.charAt(Math.floor(Math.random() * possible.length)); - return text; - } editor("#editor"); + editor("#problemDescriptionEditor"); + editor("#problemHintEditor"); var vm = avalon.define({ $id: "add_contest", @@ -49,27 +49,36 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date startTime: "", endTime: "", password: "", - model: "", - openRank: false, + mode: "", + showRank: false, + showSubmission: false, problems: [], editingProblemId: 0, editSamples: [], editTestCaseList: [], + group: "-1", + groupList: [{name:"Every one", id:1, choosed: false},{name:"Group one", id :3, choosed: false},{name:"Group two", id:5, choosed: false}], + choosedGroupList: [], showProblemEditArea: function (problemIndex) { if (vm.editingProblemId == problemIndex){ vm.problems[vm.editingProblemId-1].samples = vm.editSamples; vm.editingProblemId = 0; } else { - vm.problems[problemIndex-1].samples = vm.editSamples; - vm.problems[problemIndex-1].testCaseList = vm.editTestCaseList; - vm.editingProblemId = problemIndex; - editSamples = vm.problems[vm.editingProblemId-1].samples; - editTestCaseList = vm.problems[vm.editingProblemId-1].testCaseList; + if (vm.editingProblemId) + { + vm.problems[vm.editingProblemId-1].samples = vm.editSamples; + vm.problems[vm.editingProblemId-1].testCaseList = vm.editTestCaseList; + } + vm.editingProblemId = problemIndex; + vm.editSamples = []; + vm.editSamples = vm.problems[vm.editingProblemId-1].samples; + vm.editTestCaseList = []; + vm.editTestCaseList = vm.problems[vm.editingProblemId-1].testCaseList; } }, + passwordUsable: false, add_problem: function () { - var problem_id = make_id(); var problem = { title: "", timeLimit: 1000, @@ -101,7 +110,6 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date item.visible = !item.visible; }, add_sample: function () { - //vm.problems[vm.editingProblemId-1].samples.push({visible: true, input: "", output: ""}); vm.editSamples.push({visible: true, input: "", output: ""}); }, del_sample: function (sample) { @@ -113,7 +121,29 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date if (item.visible) return "折叠"; return "展开"; - } + }, + addGroup: function() { + if (vm.group == -1) return; + if (vm.groupList[vm.group].id == 1){ + vm.passwordUsable = true; + vm.choosedGroupList = []; + for (var key in vm.groupList){ + vm.groupList[key].choosed = true; + } + } + vm.groupList[vm.group]. choosed = true; + vm.choosedGroupList .push({name:vm.groupList[vm.group].name, index:vm.group, id:vm.groupList[vm.group].id}); + }, + unchoosed: function(groupIndex){ + if (vm.groupList[vm.choosedGroupList[groupIndex].index].id == 1){ + vm.passwordUsable = false; + for (key in vm.groupList){ + vm.groupList[key].choosed = false; + } + } + vm.groupList[vm.choosedGroupList[groupIndex].index].choosed = false; + vm.choosedGroupList.remove(vm.choosedGroupList[groupIndex]); + } }); uploader("#uploader", "/api/admin/test_case_upload/", function (file, respond) { @@ -130,11 +160,10 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date }); } vm.problems[vm.editingProblemId-1].testCaseList = vm.editTestCaseList; - bsAlert("测试数据添加成功!共添加"+editTestCaseList.length +"组测试数据"); + bsAlert("测试数据添加成功!共添加"+vm.editTestCaseList.length +"组测试数据"); } }, function(){ - console.log(vm.problemNo); if (vm.editingProblemId == 0) { bsAlert("你还未指定一道题目!"); @@ -157,14 +186,4 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date weekStart: 1, language: "zh-CN" }); - $("#contest_start_time").datetimepicker() - .on("hide", function (ev) { - $("#add-contest-form") - .formValidation("revalidateField", "start_time"); - }); - $("#contest_end_time").datetimepicker() - .on("hide", function (ev) { - $("#add-contest-form") - .formValidation("revalidateField", "end_time"); - }); }); diff --git a/template/admin/contest/add_contest.html b/template/admin/contest/add_contest.html index 7db52c7..f4be26d 100644 --- a/template/admin/contest/add_contest.html +++ b/template/admin/contest/add_contest.html @@ -6,7 +6,9 @@
- + +
@@ -15,6 +17,7 @@
+
请填写比赛描述
@@ -27,51 +30,75 @@
+ ms-duplex="startTime" data-error="请填写比赛开始时间" required> +
- + +
- -
+
+ +
+
-
- -
-
- +
+
+ +
- +
+
+
{{el.name}}
+
+
+ +
+ +
+
+ +
+
- -
-
- +
+
+ +
+
添加 @@ -100,17 +127,14 @@
题目{{editingProblemId}} - - 隐藏 - - - 删除 - + 隐藏 + 删除
- + +
@@ -125,15 +149,18 @@
- + +
- + +
-
+
- + +
@@ -168,14 +195,9 @@
- -
-
选择文件
-
- 请将所有测试用例打包在一个文件中上传,所有文件要在压缩包的根目录,且输入输出文件名要以从1开始连续数字标识要对应例如:
- 1.in 1.out 2.in 2.out -
-
编号 输入文件名 输出文件名
{{$index}} {{ el.input }} {{ el.output }}
+ + +
@@ -193,6 +215,14 @@
+ +
+
选择文件
+
+ 请将所有测试用例打包在一个文件中上传,所有文件要在压缩包的根目录,且输入输出文件名要以从1开始连续数字标识要对应例如:
+ 1.in 1.out 2.in 2.out +

+
@@ -201,3 +231,4 @@ + From 919b64869556247cee052b2e1213a886ee011d79 Mon Sep 17 00:00:00 2001 From: esp Date: Thu, 20 Aug 2015 12:38:52 +0800 Subject: [PATCH 05/17] =?UTF-8?q?[=E5=89=8D=E7=AB=AF]=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=AF=94=E8=B5=9B=E9=A1=B5=E9=9D=A2,?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86=E4=BD=BF=E7=94=A8=E5=B0=8F=E7=BB=84?= =?UTF-8?q?api=E6=9F=A5=E8=AF=A2=E8=AF=A5=E7=94=A8=E6=88=B7=E6=89=80?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E7=9A=84=E6=89=80=E6=9C=89=E7=9A=84=E5=B0=8F?= =?UTF-8?q?=E7=BB=84=E7=9A=84=E5=8A=9F=E8=83=BD[CI=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/js/app/admin/contest/add_contest.js | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/static/src/js/app/admin/contest/add_contest.js b/static/src/js/app/admin/contest/add_contest.js index 8b89c79..d3a7900 100644 --- a/static/src/js/app/admin/contest/add_contest.js +++ b/static/src/js/app/admin/contest/add_contest.js @@ -57,7 +57,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date editSamples: [], editTestCaseList: [], group: "-1", - groupList: [{name:"Every one", id:1, choosed: false},{name:"Group one", id :3, choosed: false},{name:"Group two", id:5, choosed: false}], + groupList: [{name:"Group one", id :3, choosed: false},{name:"Group two", id:5, choosed: false}], choosedGroupList: [], showProblemEditArea: function (problemIndex) { if (vm.editingProblemId == problemIndex){ @@ -124,7 +124,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date }, addGroup: function() { if (vm.group == -1) return; - if (vm.groupList[vm.group].id == 1){ + if (vm.groupList[vm.group].id == 0){ vm.passwordUsable = true; vm.choosedGroupList = []; for (var key in vm.groupList){ @@ -135,7 +135,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date vm.choosedGroupList .push({name:vm.groupList[vm.group].name, index:vm.group, id:vm.groupList[vm.group].id}); }, unchoosed: function(groupIndex){ - if (vm.groupList[vm.choosedGroupList[groupIndex].index].id == 1){ + if (vm.groupList[vm.choosedGroupList[groupIndex].index].id == 0){ vm.passwordUsable = false; for (key in vm.groupList){ vm.groupList[key].choosed = false; @@ -145,6 +145,33 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date vm.choosedGroupList.remove(vm.choosedGroupList[groupIndex]); } }); + + var isSuperAdmin = true; + $.ajax({ //用于获取该用户创建的所有小组的ajax请求 + beforeSend: csrfTokenHeader, + url: "/api/admin/group/?my_group=true", + dataType: "json", + method: "get", + contentType: "application/json", + success: function (data) { + if (!data.code) { + for (var key in data.data) + { + data.data[key].choosed = false; + vm.groupList.push(data.data[key]); + } + if (isSuperAdmin) + vm.groupList.push({id:0, name:"everyone", choosed: false}); + console.log(data); + } + else { + bsAlert(data.data); + console.log(data); + } + } + }); + + uploader("#uploader", "/api/admin/test_case_upload/", function (file, respond) { if (respond.code) From 75eb1192fb9f42b13461eea1bdf91b4658610f1d Mon Sep 17 00:00:00 2001 From: esp Date: Thu, 20 Aug 2015 21:23:53 +0800 Subject: [PATCH 06/17] =?UTF-8?q?[=E5=90=8E=E7=AB=AF-=E5=89=8D=E5=8F=B0]?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86submissions=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E6=98=BE=E7=A4=BA(=E5=8F=AA=E6=98=BE=E7=A4=BA=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E7=94=A8=E6=88=B7=E7=9A=84=E6=8F=90=E4=BA=A4),?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E5=B7=B2=E6=9C=89=E7=9A=84view=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E5=8D=95=E4=B8=AAsubmission=E7=9A=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA.=E6=98=BE=E7=A4=BA=E7=95=8C=E9=9D=A2=E4=B8=8E?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E5=88=86=E9=A1=B5=E6=98=BE=E7=A4=BA=E7=BB=9F?= =?UTF-8?q?=E4=B8=80.=E9=97=AE=E9=A2=98=E6=98=AFid=E7=9A=84=E6=98=BE?= =?UTF-8?q?=E7=A4=BA.url:http://127.0.0.1:8000/my=5Fsubmissions/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- oj/urls.py | 2 + submission/views.py | 32 +++++++++- .../oj/submission/my_submissions_list.html | 60 +++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 template/oj/submission/my_submissions_list.html diff --git a/oj/urls.py b/oj/urls.py index ba7c997..f5b94e5 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -59,5 +59,7 @@ urlpatterns = [ name="join_group_request_admin_api"), url(r'^api/submission/$', SubmissionAPIView.as_view(), name="submission_api"), url(r'^api/admin/submission/$', SubmissionAdminAPIView.as_view(), name="submission_admin_api_view"), + url(r'^my_submissions/$', "submission.views.my_submission_list_page", name="my_submission_list_page"), + url(r'^my_submissions/(?P\d+)/$', "submission.views.my_submission_list_page", name="my_submission_list_page"), ] diff --git a/submission/views.py b/submission/views.py index 10c7786..a331984 100644 --- a/submission/views.py +++ b/submission/views.py @@ -13,6 +13,7 @@ from problem.models import Problem from utils.shortcuts import serializer_invalid_response, error_response, success_response, error_page, paginate from .models import Submission from .serializers import CreateSubmissionSerializer, SubmissionSerializer +from django.core.paginator import Paginator class SubmissionAPIView(APIView): @@ -101,4 +102,33 @@ class SubmissionAdminAPIView(APIView): if not problem_id: return error_response(u"参数错误") submissions = Submission.objects.filter(problem_id=problem_id).order_by("-create_time") - return paginate(request, submissions, SubmissionSerializer) \ No newline at end of file + return paginate(request, submissions, SubmissionSerializer) + +@login_required +def my_submission_list_page(request, page = 1): + try: + submissions = Submission.objects.filter(user_id=request.user.id) + except Submission.DoesNotExist: + return error_page(request, u"你还没有提交过任何问题") + paginator = Paginator(submissions, 20) + try: + current_page = paginator.page(int(page)) + except Exception: + return error_page(request, u"不存在的页码") + previous_page = next_page = None + try: + previous_page = current_page.previous_page_number() + except Exception: + pass + + try: + next_page = current_page.next_page_number() + except Exception: + pass + + return render(request, "oj/submission/my_submissions_list.html", + {"submissions": current_page, "page": int(page), + "previous_page": previous_page, "next_page": next_page}) + + + return render(request, "oj/submission/my_submissions_list.html", {"submissions": submission}) diff --git a/template/oj/submission/my_submissions_list.html b/template/oj/submission/my_submissions_list.html new file mode 100644 index 0000000..b381f5c --- /dev/null +++ b/template/oj/submission/my_submissions_list.html @@ -0,0 +1,60 @@ +{% extends 'oj_base.html' %} + +{% block body %} + + {% load submission %} +
+ + +
编号 输入文件名
+ + + + + + + + + + + {% for item in submissions %} + + + + + + + + {% endfor %} + + +
#提交时间结果运行时间语言
{{ item.id }}{{ item.create_time }}{{ item.result|translate_result }} + {% if item.accepted_answer_time %} + {{ item.accepted_answer_time }}ms + {% else %} + -- + {% endif %} + + {{ item.language|translate_language }} +
+ +
+{% endblock %} From d2242a78c69c74d3e7f44135d9144848f69f4aab Mon Sep 17 00:00:00 2001 From: esp Date: Fri, 21 Aug 2015 20:58:04 +0800 Subject: [PATCH 07/17] =?UTF-8?q?[=E5=90=8E=E7=AB=AF]=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=88=91=E7=9A=84=E6=8F=90=E4=BA=A4=E9=A1=B5=E9=9D=A2,?= =?UTF-8?q?=E5=8E=BB=E6=8E=89=E4=BA=86=E5=86=97=E4=BD=99=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?,=E5=B9=B6=E6=B7=BB=E5=8A=A0=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- submission/tests.py | 43 ++++++++++++++++++++++++++++++++++++++++++- submission/views.py | 11 +++-------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/submission/tests.py b/submission/tests.py index 7ce503c..c31741b 100644 --- a/submission/tests.py +++ b/submission/tests.py @@ -1,3 +1,44 @@ from django.test import TestCase +from account.models import User, REGULAR_USER +from submission.models import Submission +from rest_framework.test import APITestCase, APIClient -# Create your tests here. + +class SubmissionsListPageTest(TestCase): + def setUp(self): + self.client = APIClient() + self.user = User.objects.create(username="gogoing", admin_type=REGULAR_USER) + self.user2 = User.objects.create(username="cool", admin_type=REGULAR_USER) + self.user2.set_password("666666") + self.user.set_password("666666") + self.user.save() + # self.client.login(username="gogoing", password="666666") + self.submission = Submission.objects.create(user_id=self.user.id, + language=1, + code='#include "stdio.h"\nint main(){\n\treturn 0;\n}', + problem_id=1) + + def test_visit_submissionsListPage_successfully(self): + self.client.login(username="gogoing", password="666666") + response = self.client.get('/my_submissions/1/') + self.assertEqual(response.status_code, 200) + + def test_visit_submissionsListPage_without_page_successfully(self): + self.client.login(username="gogoing", password="666666") + response = self.client.get('/my_submissions/') + self.assertEqual(response.status_code, 200) + + def test_submissionsListPage_does_not_exist(self): + self.client.login(username="gogoing", password="666666") + response = self.client.get('/my_submissions/5/') + self.assertTemplateUsed(response, "utils/error.html") + + def test_submissionsListPage_page_not_exist(self): + self.client.login(username="gogoing", password="666666") + response = self.client.get('/my_submissions/5/') + self.assertTemplateUsed(response, "utils/error.html") + + def test_submissionsListPage_have_no_submission(self): + self.client.login(username="cool", password="666666") + response = self.client.get('/my_submissions/') + self.assertEqual(response.status_code, 200) diff --git a/submission/views.py b/submission/views.py index a331984..5e0c7b6 100644 --- a/submission/views.py +++ b/submission/views.py @@ -106,10 +106,9 @@ class SubmissionAdminAPIView(APIView): @login_required def my_submission_list_page(request, page = 1): - try: - submissions = Submission.objects.filter(user_id=request.user.id) - except Submission.DoesNotExist: - return error_page(request, u"你还没有提交过任何问题") + if not page: + page = 1 + submissions = Submission.objects.filter(user_id=request.user.id) paginator = Paginator(submissions, 20) try: current_page = paginator.page(int(page)) @@ -120,7 +119,6 @@ def my_submission_list_page(request, page = 1): previous_page = current_page.previous_page_number() except Exception: pass - try: next_page = current_page.next_page_number() except Exception: @@ -129,6 +127,3 @@ def my_submission_list_page(request, page = 1): return render(request, "oj/submission/my_submissions_list.html", {"submissions": current_page, "page": int(page), "previous_page": previous_page, "next_page": next_page}) - - - return render(request, "oj/submission/my_submissions_list.html", {"submissions": submission}) From 133371cbc5e6917d9b486083adbfb2357dbb7f2e Mon Sep 17 00:00:00 2001 From: esp Date: Fri, 21 Aug 2015 20:59:21 +0800 Subject: [PATCH 08/17] =?UTF-8?q?[=E5=90=8E=E7=AB=AF]=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86=E6=88=91=E7=9A=84=E6=8F=90=E4=BA=A4=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E7=9A=84=E6=A8=A1=E6=9D=BF=E6=A0=B7=E5=BC=8F,=E6=95=B4?= =?UTF-8?q?=E7=90=86=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oj/submission/my_submissions_list.html | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/template/oj/submission/my_submissions_list.html b/template/oj/submission/my_submissions_list.html index b381f5c..e13d978 100644 --- a/template/oj/submission/my_submissions_list.html +++ b/template/oj/submission/my_submissions_list.html @@ -2,59 +2,59 @@ {% block body %} - {% load submission %} -
- - - - - - - - - - - - - - {% for item in submissions %} - - - - - - - - {% endfor %} +{% load submission %} +
+ +
+
#提交时间结果运行时间语言
{{ item.id }}{{ item.create_time }}{{ item.result|translate_result }} - {% if item.accepted_answer_time %} - {{ item.accepted_answer_time }}ms - {% else %} - -- - {% endif %} - - {{ item.language|translate_language }} -
+ + + + + + + + + + + {% for item in submissions %} + + + + + + + + {% endfor %} - -
#提交时间结果运行时间语言
{{ item.id }}{{ item.create_time }}{{ item.result|translate_result }} + {% if item.accepted_answer_time %} + {{ item.accepted_answer_time }}ms + {% else %} + -- + {% endif %} + + {{ item.language|translate_language }} +
- -
+ + + +
{% endblock %} From 1824b1d69a4ad48dfede69d2da73322f7aeac762 Mon Sep 17 00:00:00 2001 From: esp Date: Fri, 21 Aug 2015 21:00:18 +0800 Subject: [PATCH 09/17] =?UTF-8?q?[=E5=89=8D=E7=AB=AF]=E6=AF=94=E8=B5=9B?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E9=A1=B5=E9=9D=A2(=E5=90=8E=E5=8F=B0)?= =?UTF-8?q?=E7=9A=84=E8=BF=9B=E4=B8=80=E6=AD=A5=E5=AE=8C=E5=96=84,?= =?UTF-8?q?=E4=B8=8D=E5=8C=85=E5=90=ABapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/js/app/admin/contest/contest_list.js | 27 ++++++----- template/admin/contest/contest_list.html | 45 ++++++++++++++----- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/static/src/js/app/admin/contest/contest_list.js b/static/src/js/app/admin/contest/contest_list.js index 823179e..ceafce1 100644 --- a/static/src/js/app/admin/contest/contest_list.js +++ b/static/src/js/app/admin/contest/contest_list.js @@ -14,8 +14,9 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"] page: 1, totalPage: 1, keyword: "", - editingContestId: 0, - editTitle: "", + editingContestId: 0, + editTitle: "", + editingProblemList: [], getNext: function () { if (!vm.nextPage) return; @@ -38,13 +39,14 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"] getPageData(page_index); }, showEditContestArea: function (contestId) { - if (contestId == vm.editingContestId) - vm.editingContestId = 0; - else { - vm.editingContestId = contestId; - vm.editTitle = vm.contestList[contestId-1].title; - editor("#editor").setValue(vm.contestList[contestId-1].description); - } + if (contestId == vm.editingContestId) + vm.editingContestId = 0; + else { + vm.editingContestId = contestId; + vm.editTitle = vm.contestList[contestId-1].title; + editor("#editor").setValue(vm.contestList[contestId-1].description); + vm.editingProblemList = vm.contestList[contestId-1].problemList; + } } }); @@ -74,7 +76,12 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"] } }); */ - vm.contestList =[{id: 1, title:"The first contest", created_by: {username:"owen"}, description:"

this contest is just for

fun

"}]; + vm.contestList =[{ + id: 1, title:"The first contest", + created_by: {username:"owen"}, + description:"

this contest is just for

fun

", + problemList:[{title:"A+B problem", id:1, testCaseList:[1,2], samples:[1,2]}] + }]; vm.totalPage = 1; vm.previousPage = false; vm.nextPage = false; diff --git a/template/admin/contest/contest_list.html b/template/admin/contest/contest_list.html index 0df7ba3..9fd4874 100644 --- a/template/admin/contest/contest_list.html +++ b/template/admin/contest/contest_list.html @@ -52,32 +52,32 @@ 请填写比赛描述
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -86,10 +86,31 @@
- +
+ +
+
+ + + + + + + + + + + + + +
编号题目测试数据
题目{{ $index+1 }}{{ el.title }}{{ el.testCaseList.length }}组 + 编辑 + 删除 +
+
From 093ec3fc799fcdd010f6482d32402b4f888108ab Mon Sep 17 00:00:00 2001 From: esp Date: Sat, 22 Aug 2015 13:45:24 +0800 Subject: [PATCH 10/17] =?UTF-8?q?[=E5=90=8E=E7=AB=AF]=E5=89=8D=E5=8F=B0?= =?UTF-8?q?=E6=88=91=E7=9A=84=E6=8F=90=E4=BA=A4=E9=A1=B5=E9=9D=A2=20?= =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E6=8F=90=E4=BA=A4=E5=BA=8F=E5=8F=B7=E7=9A=84?= =?UTF-8?q?=E6=98=BE=E7=A4=BA,=E5=8E=9F=E6=9D=A5=E6=98=AF=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E7=9C=9F=E5=AE=9Eid=E5=8D=B3=E9=9A=8F=E6=9C=BA?= =?UTF-8?q?=E7=9A=84=E6=95=A3=E5=88=97=E5=80=BC,=E4=B8=8D=E5=A5=BD?= =?UTF-8?q?=E7=9C=8B,=E7=8E=B0=E5=9C=A8=E6=94=B9=E6=88=90=E8=87=AA?= =?UTF-8?q?=E7=84=B6=E6=95=B0=E5=BA=8F=E5=88=97,=E4=BD=86=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E7=BB=93=E5=90=88javascript=E7=94=9F=E6=88=90,?= =?UTF-8?q?=E4=B8=94=E6=98=AF=E7=9B=B8=E5=AF=B9=E5=80=BC,=E5=9B=A0?= =?UTF-8?q?=E4=B8=BA=E6=95=B0=E6=8D=AE=E5=BA=93=E9=87=8C=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E8=BF=99=E4=B8=AA=E5=AD=97=E6=AE=B5,=E6=9C=89=E7=82=B9?= =?UTF-8?q?=E5=88=AB=E6=89=AD=E4=BA=86.=20=20=20=E7=AC=AC=E4=BA=8C,?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E7=94=A8=E6=88=B7=E6=B2=A1=E6=9C=89?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E8=AE=B0=E5=BD=95=E7=9A=84=E5=8F=8D=E9=A6=88?= =?UTF-8?q?.=20=20=20=E7=AC=AC=E4=B8=89,=E6=9C=AC=E6=89=93=E7=AE=97?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=AD=9B=E9=80=89=E5=8A=9F=E8=83=BD,?= =?UTF-8?q?=E4=BD=86=E5=9B=A0=E4=B8=BAURL=E9=9A=BE=E4=BB=A5=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E4=BD=9C=E7=BD=A2,=E5=8F=AA=E6=9C=89=E5=9C=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=B0=E7=9A=84url=E6=89=8D=E8=83=BD?= =?UTF-8?q?=E8=BE=83=E5=A5=BD=E7=9A=84=E5=A4=84=E7=90=86,=E4=B8=8B?= =?UTF-8?q?=E6=AC=A1=E5=86=8D=E8=AF=B4=E6=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- submission/views.py | 11 ++++++----- template/oj/submission/my_submissions_list.html | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/submission/views.py b/submission/views.py index fed235a..39aa5b8 100644 --- a/submission/views.py +++ b/submission/views.py @@ -85,7 +85,7 @@ def problem_my_submissions_list_page(request, problem_id): problem = Problem.objects.get(id=problem_id, visible=True) except Problem.DoesNotExist: return error_page(request, u"问题不存在") - submissions = Submission.objects.filter(user_id=request.user.id, problem_id=problem.id).order_by("-create_time").\ + submissions = Submission.objects.filter(user_id=request.user.id, problem_id=problem.id).order_by("-create_time"). \ values("id", "result", "create_time", "accepted_answer_time", "language") return render(request, "oj/problem/my_submissions_list.html", {"submissions": submissions, "problem": problem}) @@ -117,7 +117,6 @@ def my_submission(request, submission_id): {"submission": submission, "problem": problem, "info": info}) - class SubmissionAdminAPIView(APIView): def get(self, request): problem_id = request.GET.get("problem_id", None) @@ -126,11 +125,13 @@ class SubmissionAdminAPIView(APIView): submissions = Submission.objects.filter(problem_id=problem_id).order_by("-create_time") return paginate(request, submissions, SubmissionSerializer) + @login_required -def my_submission_list_page(request, page = 1): +def my_submission_list_page(request, page=1): if not page: - page = 1 - submissions = Submission.objects.filter(user_id=request.user.id) + page = 1 + submissions = Submission.objects.filter(user_id=request.user.id). \ + values("id", "result", "create_time", "accepted_answer_time", "language") paginator = Paginator(submissions, 20) try: current_page = paginator.page(int(page)) diff --git a/template/oj/submission/my_submissions_list.html b/template/oj/submission/my_submissions_list.html index e13d978..259f176 100644 --- a/template/oj/submission/my_submissions_list.html +++ b/template/oj/submission/my_submissions_list.html @@ -10,7 +10,9 @@ +
+ {% if submissions %} @@ -24,7 +26,8 @@ {% for item in submissions %} - +
{{ item.id }}{{ forloop.counter + }} {{ item.create_time }} {{ item.result|translate_result }} @@ -42,6 +45,9 @@
+ {% else %} +

你还没有提交记录!

+ {% endif %}
+ {% endblock %} From 7be01753320b284afb4c841636ee5ef4ebe212ee Mon Sep 17 00:00:00 2001 From: esp Date: Sat, 22 Aug 2015 14:27:11 +0800 Subject: [PATCH 11/17] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=86=97=E4=BD=99?= =?UTF-8?q?=E8=AF=AD=E5=8F=A5,=E5=9B=A0=E4=B8=BApage=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=B7=B2=E7=BB=8F=E6=9C=89=E9=BB=98=E8=AE=A4=E5=80=BC=E4=BA=86?= =?UTF-8?q?,=E4=B8=8D=E8=83=BD=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- submission/views.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/submission/views.py b/submission/views.py index 39aa5b8..423e1c8 100644 --- a/submission/views.py +++ b/submission/views.py @@ -128,8 +128,6 @@ class SubmissionAdminAPIView(APIView): @login_required def my_submission_list_page(request, page=1): - if not page: - page = 1 submissions = Submission.objects.filter(user_id=request.user.id). \ values("id", "result", "create_time", "accepted_answer_time", "language") paginator = Paginator(submissions, 20) From 0bf84d1c4047ecfd74c526ffd5777d256a3e4b6a Mon Sep 17 00:00:00 2001 From: hohoTT <609029365@qq.com> Date: Sat, 22 Aug 2015 16:08:39 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=89=8D=E5=8F=B0?= =?UTF-8?q?=E6=AF=94=E8=B5=9B=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contest/views.py | 49 +++++++++++- oj/urls.py | 3 + template/oj/contest/contest_list.html | 106 ++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 template/oj/contest/contest_list.html diff --git a/contest/views.py b/contest/views.py index d00bee5..0f0cf70 100644 --- a/contest/views.py +++ b/contest/views.py @@ -1,15 +1,18 @@ # coding=utf-8 import json +import datetime from django.shortcuts import render from django.db import IntegrityError from django.utils import dateparse from django.db.models import Q +from django.core.paginator import Paginator from rest_framework.views import APIView from utils.shortcuts import (serializer_invalid_response, error_response, success_response, paginate, rand_str, error_page) from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN from group.models import Group +from announcement.models import Announcement from .models import Contest, ContestProblem from .serializers import (CreateContestSerializer, ContestSerializer, EditContestSerializer, @@ -17,7 +20,11 @@ from .serializers import (CreateContestSerializer, ContestSerializer, EditContes def contest_page(request, contest_id): - pass + try: + contest = Contest.objects.get(id=contest_id, visible=True) + except Contest.DoesNotExist: + return error_page(request, u"比赛不存在") + return render(request, "oj/contest/problems.html", {"contest": contest}) class ContestAdminAPIView(APIView): @@ -220,4 +227,42 @@ class ContestProblemAdminAPIView(APIView): contest_problem = contest_problem.filter(Q(title__contains=keyword) | Q(description__contains=keyword)) - return paginate(request, contest_problem, ContestProblemSerializer) \ No newline at end of file + return paginate(request, contest_problem, ContestProblemSerializer) + + +def contest_list_page(request, page=1): + # 正常情况 + contests = Contest.objects.filter(visible=True) + + # 搜索的情况 + keyword = request.GET.get("keyword", None) + if keyword: + contests = contests.filter(title__contains=keyword) + + paginator = Paginator(contests, 20) + try: + current_page = paginator.page(int(page)) + except Exception: + return error_page(request, u"不存在的页码") + + previous_page = next_page = None + + try: + previous_page = current_page.previous_page_number() + except Exception: + pass + + try: + next_page = current_page.next_page_number() + except Exception: + pass + + # 右侧的公告列表 + announcements = Announcement.objects.filter(is_global=True, visible=True).order_by("-create_time") + # 系统当前时间 + now = datetime.datetime.now() + return render(request, "oj/contest/contest_list.html", + {"problems": current_page, "page": int(page), + "previous_page": previous_page, "next_page": next_page, + "keyword": keyword, "announcements": announcements, + "now": now}) diff --git a/oj/urls.py b/oj/urls.py index 6dc7606..106b966 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -40,12 +40,15 @@ urlpatterns = [ url(r'^api/admin/contest/$', ContestAdminAPIView.as_view(), name="contest_admin_api"), url(r'^api/admin/user/$', UserAdminAPIView.as_view(), name="user_admin_api"), url(r'^problem/(?P\d+)/$', "problem.views.problem_page", name="problem_page"), + url(r'^contest/(?P\d+)/$', "contest.views.contest_page", name="contest_page"), url(r'^announcement/(?P\d+)/$', "announcement.views.announcement_page", name="announcement_page"), url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), name="add_contest_page"), url(r'^problems/$', "problem.views.problem_list_page", name="problem_list_page"), url(r'^problems/(?P\d+)/$', "problem.views.problem_list_page", name="problem_list_page"), + url(r'^contests/$', "contest.views.contest_list_page", name="contest_list_page"), + url(r'^contests/(?P\d+)/$', "contest.views.contest_list_page", name="contest_list_page"), url(r'^admin/template/(?P\w+)/(?P\w+).html$', AdminTemplateView.as_view(), name="admin_template"), url(r'^api/admin/group/$', GroupAdminAPIView.as_view(), name="group_admin_api"), diff --git a/template/oj/contest/contest_list.html b/template/oj/contest/contest_list.html new file mode 100644 index 0000000..3233a6e --- /dev/null +++ b/template/oj/contest/contest_list.html @@ -0,0 +1,106 @@ +{% extends "oj_base.html" %} +{% block body %} + {% load problem %} +
+
+
+
+
+
+
+ + +
+
+
+
+
+ + + + + + + + + + + + + + {% for item in contests %} + + + + + + {% ifequal item.mode 0 %} + + {% endifequal %} + {% ifequal item.mode 1 %} + + {% endifequal %} + {% ifequal item.mode 2 %} + + {% endifequal %} + + {% ifequal item.contest_type 0 %} + + {% endifequal %} + {% ifequal item.contest_type 1 %} + + {% endifequal %} + {% ifequal item.contest_type 2 %} + + {% endifequal %} + + {% if now < item_start_time %} + + {% elif item.start_time <= now and now <= item_end_time %} + + {% else %} + + {% endif %} + + {% endfor %} + +
#比赛名称开始时间比赛模式比赛类型状态
{{ item.id }}{{ item.title }}{{ item.start_time }}acm模式AC数量模式AC总分排名模式小组赛公开赛公开赛(密码保护)比赛还未开始比赛正在进行比赛已结束
+ +
+
+ +
+
+
+

+ + 公告 +

+
+ {% for item in announcements %} + {{ forloop.counter }}.  {{ item.title }} +
+ {% endfor %} +
+
+
+
+
+{% endblock %} + +{% block js_block %} + +{% endblock %} \ No newline at end of file From 7c5b30a830723af3d5da33b1457ee6a439bdb90a Mon Sep 17 00:00:00 2001 From: esp Date: Sat, 22 Aug 2015 19:16:50 +0800 Subject: [PATCH 13/17] =?UTF-8?q?[=E5=90=8E=E7=AB=AF]=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86contest=E4=B8=AD=20api-docs=20=E7=9A=84=E5=B0=8Fbug[CI?= =?UTF-8?q?=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contest/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contest/views.py b/contest/views.py index d00bee5..bc9eb35 100644 --- a/contest/views.py +++ b/contest/views.py @@ -202,7 +202,7 @@ class ContestProblemAdminAPIView(APIView): """ 比赛题目分页json api接口 --- - response_serializer: ProblemSerializer + response_serializer: ContestProblemSerializer """ contest_problem_id = request.GET.get("contest_problem_id", None) if contest_problem_id: From c0b4999b1aa8c88db020c739cb1a90b54dd4d69b Mon Sep 17 00:00:00 2001 From: esp Date: Sat, 22 Aug 2015 19:18:05 +0800 Subject: [PATCH 14/17] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86css=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E6=96=B9=E5=BC=8F[CI=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/src/css/admin.css | 1 + 1 file changed, 1 insertion(+) diff --git a/static/src/css/admin.css b/static/src/css/admin.css index 9eb4f9c..6618630 100644 --- a/static/src/css/admin.css +++ b/static/src/css/admin.css @@ -6,6 +6,7 @@ @import url("webuploader/webuploader.css"); @import url("datetime_picker/bootstrap-datetimepicker.css"); @import url("tagEditor/jquery.tag-editor.css"); +@import url("add_contest.css"); #loading-gif{ width: 40px; From 4361f4d6e4b819d2a69646552f05cb6b6f107cdf Mon Sep 17 00:00:00 2001 From: esp Date: Sat, 22 Aug 2015 19:20:22 +0800 Subject: [PATCH 15/17] =?UTF-8?q?[=E5=89=8D=E7=AB=AF]=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=86=E6=B7=BB=E5=8A=A0=E6=AF=94=E8=B5=9B?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2,=20=20=E6=AF=94=E8=B5=9B=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BB=8D=E4=B8=8D=E5=85=A8=E9=9D=A2,?= =?UTF-8?q?=E7=A8=8D=E5=90=8E=E6=94=B9=E8=BF=9B[CI=20SKIP]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/js/app/admin/contest/add_contest.js | 149 ++++++++------- .../src/js/app/admin/contest/contest_list.js | 71 +++++-- template/admin/contest/add_contest.html | 5 +- template/admin/contest/contest_list.html | 177 +++++++++++------- 4 files changed, 255 insertions(+), 147 deletions(-) diff --git a/static/src/js/app/admin/contest/add_contest.js b/static/src/js/app/admin/contest/add_contest.js index d3a7900..dfa8d60 100644 --- a/static/src/js/app/admin/contest/add_contest.js +++ b/static/src/js/app/admin/contest/add_contest.js @@ -3,41 +3,58 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) { avalon.vmodels.add_contest = null; $("#add-contest-form").validator().on('submit', function (e) { - if (!e.isDefaultPrevented()){ - alert("smoething went wrong!"); + if (!e.isDefaultPrevented()){ + e.preventDefault(); + var ajaxData = { + title: vm.title, + description: vm.description, + mode: vm.mode, + contest_type: 0, + show_rank: vm.showRank, + show_user_submission: vm.showSubmission, + //password: vm.password, + start_time: vm.startTime, + end_time: vm.endTime, + visible: true + }; + if (vm.choseGroupList[0].id == 0) //everyone | public contest + if (vm.password == "") + ajaxData.contest_type = 1; + else{ + ajaxData.password = vm.password; + } + else { // Add groups info + ajaxData.groups = []; + for (var i = 0; vm.choseGroupList[i]; i++) + ajaxData.groups.push(parseInt(vm.choseGroupList[i].id)) } - else{ - var data = { - title: vm.title, - description: vm.description, - start_time: vm.startTime, - end_time: vm.endTime, - password: vm.password, - mode: vm.model, - show_rank: vm.openRank - }; - $.ajax({ - beforeSend: csrfTokenHeader, - url: "/api/admin/contest/", - dataType: "json", - data: data, - method: "post", - contentType: "application/json", - success: function (data) { - if (!data.code) { - bsAlert("添加成功!"); - console.log(data); - } - else { - bsAlert(data.data); - console.log(data); - } - } - }); - console.log(data); - } - return false; - }) + + + console.log(ajaxData); + $.ajax({ + beforeSend: csrfTokenHeader, + url: "/api/admin/contest/", + dataType: "json", + contentType: "application/json", + data: JSON.stringify(ajaxData), + method: "post", + contentType: "application/json", + success: function (data) { + if (!data.code) { + bsAlert("添加成功!"); + console.log(data); + } + else { + bsAlert(data.data); + console.log(data); + } + } + }); + console.log(JSON.stringify(ajaxData)); + } + return false; + }); + editor("#editor"); editor("#problemDescriptionEditor"); editor("#problemHintEditor"); @@ -57,8 +74,8 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date editSamples: [], editTestCaseList: [], group: "-1", - groupList: [{name:"Group one", id :3, choosed: false},{name:"Group two", id:5, choosed: false}], - choosedGroupList: [], + groupList: [], + choseGroupList: [], showProblemEditArea: function (problemIndex) { if (vm.editingProblemId == problemIndex){ vm.problems[vm.editingProblemId-1].samples = vm.editSamples; @@ -126,50 +143,48 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date if (vm.group == -1) return; if (vm.groupList[vm.group].id == 0){ vm.passwordUsable = true; - vm.choosedGroupList = []; + vm.choseGroupList = []; for (var key in vm.groupList){ - vm.groupList[key].choosed = true; + vm.groupList[key].chose = true; } } - vm.groupList[vm.group]. choosed = true; - vm.choosedGroupList .push({name:vm.groupList[vm.group].name, index:vm.group, id:vm.groupList[vm.group].id}); + vm.groupList[vm.group]. chose = true; + vm.choseGroupList.push({name:vm.groupList[vm.group].name, index:vm.group, id:vm.groupList[vm.group].id}); }, - unchoosed: function(groupIndex){ - if (vm.groupList[vm.choosedGroupList[groupIndex].index].id == 0){ + unchose: function(groupIndex){ + if (vm.groupList[vm.choseGroupList[groupIndex].index].id == 0){ vm.passwordUsable = false; for (key in vm.groupList){ - vm.groupList[key].choosed = false; + vm.groupList[key].chose = false; } } - vm.groupList[vm.choosedGroupList[groupIndex].index].choosed = false; - vm.choosedGroupList.remove(vm.choosedGroupList[groupIndex]); + vm.groupList[vm.choseGroupList[groupIndex].index].chose = false; + vm.choseGroupList.remove(vm.choseGroupList[groupIndex]); } }); var isSuperAdmin = true; $.ajax({ //用于获取该用户创建的所有小组的ajax请求 - beforeSend: csrfTokenHeader, - url: "/api/admin/group/?my_group=true", - dataType: "json", - method: "get", - contentType: "application/json", - success: function (data) { - if (!data.code) { - for (var key in data.data) - { - data.data[key].choosed = false; - vm.groupList.push(data.data[key]); - } - if (isSuperAdmin) - vm.groupList.push({id:0, name:"everyone", choosed: false}); - console.log(data); - } - else { - bsAlert(data.data); - console.log(data); - } - } - }); + beforeSend: csrfTokenHeader, + url: "/api/admin/group/?my_group=true", + dataType: "json", + method: "get", + contentType: "application/json", + success: function (data) { + if (!data.code) { + if (isSuperAdmin) + vm.groupList.push({id:0, name:"所有人", chose: false}); + for (var key in data.data) { + data.data[key].chose = false; + vm.groupList.push(data.data[key]); + } + } + else { + bsAlert(data.data); + console.log(data); + } + } + }); diff --git a/static/src/js/app/admin/contest/contest_list.js b/static/src/js/app/admin/contest/contest_list.js index ceafce1..a7378e1 100644 --- a/static/src/js/app/admin/contest/contest_list.js +++ b/static/src/js/app/admin/contest/contest_list.js @@ -13,10 +13,25 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"] nextPage: 0, page: 1, totalPage: 1, + group: "-1", + groupList: [], keyword: "", editingContestId: 0, editTitle: "", - editingProblemList: [], + editProblemList: [], + editPassword: "", + editStartTime: "", + editEndTime: "", + editMode: "", + editShowRank: false, + editShowSubmission: false, + editProblemList: [], + editingProblemId: 0, + editSamples: [], + editTestCaseList: [], + editChoseGroupList: [], + modelNameList: ["ACM", "AC总数", "分数"], + contestTypeNameList: ["小组赛", "公开赛", "有密码保护的公开赛"], getNext: function () { if (!vm.nextPage) return; @@ -44,6 +59,24 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"] else { vm.editingContestId = contestId; vm.editTitle = vm.contestList[contestId-1].title; + vm.editEndTime = vm.contestList[contestId-1].end_time; + vm.editPassword = vm.contestList[contestId-1].password; + vm.editStartTime = vm.contestList[contestId-1].start_time; + vm.editMode = vm.contestList[contestId-1].mode; + vm.editChoseGroupList = []; + //= vm.contestList[contestId-1].group;// + /*for (var key in vm.contestList[contestId-1].groups){ + var id = parseInt(vm.contestList[contestId-1].groups); + for () + vm.editChoseGroupList.push({ + name:vm.groupList[vm.group].name, + index:index, + id:parseInt(vm.contestList[contestId-1].groups) + }); + }*/ + vm.editShowRank = vm.contestList[contestId-1].show_rank; + vm.editShowSubmission = vm.contestList[contestId-1].show_user_submission; + //vm.editProblemList = vm.contestList[contestId-1].problems editor("#editor").setValue(vm.contestList[contestId-1].description); vm.editingProblemList = vm.contestList[contestId-1].problemList; } @@ -54,7 +87,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"] } function getPageData(page) { -/* + var url = "/api/admin/contest/?paging=true&page=" + page + "&page_size=10"; if (vm.keyword != "") url += "&keyword=" + vm.keyword; @@ -75,20 +108,30 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker"] } } }); -*/ - vm.contestList =[{ - id: 1, title:"The first contest", - created_by: {username:"owen"}, - description:"

this contest is just for

fun

", - problemList:[{title:"A+B problem", id:1, testCaseList:[1,2], samples:[1,2]}] - }]; - vm.totalPage = 1; - vm.previousPage = false; - vm.nextPage = false; - vm.page = 1; } - + var isSuperAdmin = true; + $.ajax({ //用于获取该用户创建的所有小组的ajax请求 + beforeSend: csrfTokenHeader, + url: "/api/admin/group/?my_group=true", + dataType: "json", + method: "get", + contentType: "application/json", + success: function (data) { + if (!data.code) { + if (isSuperAdmin) + vm.groupList.push({id:0, name:"所有人", chose: false}); + for (var key in data.data) { + data.data[key].chose = false; + vm.groupList.push(data.data[key]); + } + } + else { + bsAlert(data.data); + console.log(data); + } + } + }); }); avalon.scan(); }); diff --git a/template/admin/contest/add_contest.html b/template/admin/contest/add_contest.html index f4be26d..44ae98a 100644 --- a/template/admin/contest/add_contest.html +++ b/template/admin/contest/add_contest.html @@ -51,7 +51,7 @@
@@ -61,7 +61,7 @@
-
{{el.name}}
+
{{el.name}}
@@ -231,4 +231,3 @@
- diff --git a/template/admin/contest/contest_list.html b/template/admin/contest/contest_list.html index 9fd4874..ab878ae 100644 --- a/template/admin/contest/contest_list.html +++ b/template/admin/contest/contest_list.html @@ -16,27 +16,21 @@ ID 比赛 比赛类型 - 比赛模式 公开排名 开始时间 结束时间 创建时间 创建者 - - + {{ el.id }} {{ el.title }} - {{ el.type }} - {{ el.mode }} + {{ contestTypeNameList[el.contest_type] }} {{ el.show_rank }} {{ el.start_time|date("yyyy-MM-dd HH:mm:ss")}} {{ el.end_time|date("yyyy-MM-dd HH:mm:ss")}} {{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}} {{ el.created_by.username }} - - -
@@ -45,72 +39,129 @@
-
- - - +
+ +
+
+
+ + +
+
+
+
+ +
+
+
+
请填写比赛描述
-
- -
-
- -
-
+
+
+ +
+
+ +
+
+
+ ms-duplex="editStartTime" data-error="请填写比赛开始时间" required> +
-
- +
+
+
+ +
-
- +
+
+ +
+
+ +
+
+
+
-
- +
+
+
+
-
- +
+
+
{{el.name}}
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
-
- +
+
+
+
-
- - +
+
+
+
-
-
- -
-
-
- - - - - - - - - - - - - -
编号题目测试数据
题目{{ $index+1 }}{{ el.title }}{{ el.testCaseList.length }}组 - 编辑 - 删除 -
-
+
+
+ + 添加 + + + + + + + + + + + + + +
编号题目测试数据
题目{{ $index+1 }}{{ el.title }}{{ el.testCaseList.length }}组 + 编辑 + 删除 +
+ +
From 35c4b09f57df8c055410c7d9c1fa7f5ff5c40a43 Mon Sep 17 00:00:00 2001 From: esp Date: Sat, 22 Aug 2015 19:38:51 +0800 Subject: [PATCH 16/17] =?UTF-8?q?[=E5=90=8E=E7=AB=AF]=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E4=BA=86=E7=94=A8=E4=BA=8E=E7=94=9F=E4=BA=A7=E5=BA=8F=E5=8F=B7?= =?UTF-8?q?=E7=9A=84javascript,=E6=94=B9=E4=B8=BA=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E8=BF=87=E6=BB=A4=E5=99=A8=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?(=E6=88=91=E7=9A=84=E6=89=80=E6=9C=89=E6=8F=90=E4=BA=A4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- submission/views.py | 2 +- template/oj/submission/my_submissions_list.html | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/submission/views.py b/submission/views.py index 423e1c8..2841909 100644 --- a/submission/views.py +++ b/submission/views.py @@ -147,4 +147,4 @@ def my_submission_list_page(request, page=1): return render(request, "oj/submission/my_submissions_list.html", {"submissions": current_page, "page": int(page), - "previous_page": previous_page, "next_page": next_page}) + "previous_page": previous_page, "next_page": next_page, "startId":int(page)*20-20}) diff --git a/template/oj/submission/my_submissions_list.html b/template/oj/submission/my_submissions_list.html index 259f176..c6fcacb 100644 --- a/template/oj/submission/my_submissions_list.html +++ b/template/oj/submission/my_submissions_list.html @@ -26,8 +26,8 @@ {% for item in submissions %} - {{ forloop.counter - }} + + {{ forloop.counter |add:startId }} {{ item.create_time }} {{ item.result|translate_result }} @@ -63,12 +63,4 @@
- {% endblock %} From 48d48a0f3040115b75c9fc3d9f0126c7d25b2896 Mon Sep 17 00:00:00 2001 From: hohoTT <609029365@qq.com> Date: Sat, 22 Aug 2015 20:42:21 +0800 Subject: [PATCH 17/17] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E6=AF=94?= =?UTF-8?q?=E8=B5=9B=E5=88=97=E8=A1=A8=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contest/views.py | 12 +++-- .../oj/announcement/_announcement_panel.html | 12 +++++ template/oj/contest/contest_list.html | 51 +++++-------------- template/oj/problem/problem_list.html | 13 +---- utils/templatetags/contest.py | 29 +++++++++++ 5 files changed, 64 insertions(+), 53 deletions(-) create mode 100644 template/oj/announcement/_announcement_panel.html create mode 100644 utils/templatetags/contest.py diff --git a/contest/views.py b/contest/views.py index 0f0cf70..cabfff9 100644 --- a/contest/views.py +++ b/contest/views.py @@ -1,6 +1,7 @@ # coding=utf-8 import json import datetime +from django.utils.timezone import localtime from django.shortcuts import render from django.db import IntegrityError from django.utils import dateparse @@ -209,7 +210,7 @@ class ContestProblemAdminAPIView(APIView): """ 比赛题目分页json api接口 --- - response_serializer: ProblemSerializer + response_serializer: ContestProblemSerializer """ contest_problem_id = request.GET.get("contest_problem_id", None) if contest_problem_id: @@ -239,6 +240,11 @@ def contest_list_page(request, page=1): if keyword: contests = contests.filter(title__contains=keyword) + # 筛选我能参加的比赛 + join = request.GET.get("join", None) + if join: + contests = Contest.objects.filter(Q(contest_type__in=[1, 2]) | Q(groups__in=request.user.group_set.all())) + paginator = Paginator(contests, 20) try: current_page = paginator.page(int(page)) @@ -262,7 +268,7 @@ def contest_list_page(request, page=1): # 系统当前时间 now = datetime.datetime.now() return render(request, "oj/contest/contest_list.html", - {"problems": current_page, "page": int(page), + {"contests": current_page, "page": int(page), "previous_page": previous_page, "next_page": next_page, "keyword": keyword, "announcements": announcements, - "now": now}) + "join": join, "now": now}) diff --git a/template/oj/announcement/_announcement_panel.html b/template/oj/announcement/_announcement_panel.html new file mode 100644 index 0000000..f17a9ce --- /dev/null +++ b/template/oj/announcement/_announcement_panel.html @@ -0,0 +1,12 @@ +
+
+

+ + 公告 +

+
+ {% for item in announcements %} +

{{ forloop.counter }}.  {{ item.title }}

+ {% endfor %} +
+
\ No newline at end of file diff --git a/template/oj/contest/contest_list.html b/template/oj/contest/contest_list.html index 3233a6e..1689cee 100644 --- a/template/oj/contest/contest_list.html +++ b/template/oj/contest/contest_list.html @@ -1,6 +1,6 @@ {% extends "oj_base.html" %} {% block body %} - {% load problem %} + {% load contest %}
@@ -18,11 +18,9 @@ - - @@ -30,19 +28,9 @@ {% for item in contests %} - - {% ifequal item.mode 0 %} - - {% endifequal %} - {% ifequal item.mode 1 %} - - {% endifequal %} - {% ifequal item.mode 2 %} - - {% endifequal %} {% ifequal item.contest_type 0 %} @@ -54,27 +42,26 @@ {% endifequal %} - {% if now < item_start_time %} - - {% elif item.start_time <= now and now <= item_end_time %} - - {% else %} - - {% endif %} + {% endfor %}
# 比赛名称 开始时间比赛模式 比赛类型 状态
{{ item.id }} {{ item.title }} {{ item.start_time }}acm模式AC数量模式AC总分排名模式小组赛公开赛(密码保护)比赛还未开始比赛正在进行比赛已结束{{ item|contest_status }}
+
+ +
-
-
-

- - 公告 -

-
- {% for item in announcements %} - {{ forloop.counter }}.  {{ item.title }} -
- {% endfor %} -
-
+ {% include "oj/announcement/_announcement_panel.html" %}
{% endblock %} + {% block js_block %} - {% endblock %} \ No newline at end of file diff --git a/template/oj/problem/problem_list.html b/template/oj/problem/problem_list.html index 073cfe7..21833a7 100644 --- a/template/oj/problem/problem_list.html +++ b/template/oj/problem/problem_list.html @@ -55,18 +55,7 @@
-
-
-

- - 公告 -

-
- {% for item in announcements %} - {{ forloop.counter }}.  {{ item.title }} - {% endfor %} -
-
+ {% include "oj/announcement/_announcement_panel.html" %}

diff --git a/utils/templatetags/contest.py b/utils/templatetags/contest.py new file mode 100644 index 0000000..818d7f6 --- /dev/null +++ b/utils/templatetags/contest.py @@ -0,0 +1,29 @@ +# coding=utf-8 +import datetime +from django.utils.timezone import localtime + + +def get_contest_status(contest): + now = datetime.datetime.now() + if localtime(contest.start_time).replace(tzinfo=None) > now: + return "没有开始" + if localtime(contest.end_time).replace(tzinfo=None) < now: + return "已经结束" + return "正在进行" + + +def get_contest_status_color(contest): + now = datetime.datetime.now() + if localtime(contest.start_time).replace(tzinfo=None) > now: + return "info" + if localtime(contest.end_time).replace(tzinfo=None) < now: + return "warning" + return "success" + + +from django import template + +register = template.Library() +register.filter("contest_status", get_contest_status) +register.filter("contest_status_color", get_contest_status_color) +