diff --git a/contest_submission/tests.py b/contest_submission/tests.py index 7ce503c2..b1eace12 100644 --- a/contest_submission/tests.py +++ b/contest_submission/tests.py @@ -1,3 +1,84 @@ -from django.test import TestCase +import json + +from django.core.urlresolvers import reverse +from account.models import User, ADMIN, SUPER_ADMIN + +from contest.models import Contest, ContestProblem +from submission.models import Submission +from rest_framework.test import APITestCase, APIClient + # Create your tests here. + +class SubmissionAPITest(APITestCase): + def setUp(self): + self.client = APIClient() + self.url = reverse('contest_submission_admin_api_view') + self.userA = User.objects.create(username="test1", admin_type=ADMIN) + self.userA.set_password("testaa") + self.userA.save() + self.userS = User.objects.create(username="test2", admin_type=SUPER_ADMIN) + self.userS.set_password("testbb") + self.userS.save() + self.global_contest = Contest.objects.create(title="titlex", description="descriptionx", mode=1, + contest_type=2, show_rank=True, show_user_submission=True, + start_time="2015-08-15T10:00:00.000Z", + end_time="2015-08-15T12:00:00.000Z", + password="aacc", created_by=self.userS + ) + self.problem = ContestProblem.objects.create(title="title1", + description="description1", + input_description="input1_description", + output_description="output1_description", + test_case_id="1", + sort_index="1", + samples=json.dumps([{"input": "1 1", "output": "2"}]), + time_limit=100, + memory_limit=1000, + hint="hint1", + contest=self.global_contest, + created_by=self.userS) + self.submission = Submission.objects.create(user_id=self.userA.id, + language=1, + code='#include "stdio.h"\nint main(){\n\treturn 0;\n}', + problem_id=self.problem.id) + self.submissionS = Submission.objects.create(user_id=self.userS.id, + language=2, + code='#include "stdio.h"\nint main(){\n\treturn 0;\n}', + problem_id=self.problem.id) + + def test_submission_contest_does_not_exist(self): + self.client.login(username="test2", password="testbb") + response = self.client.get(self.url + "?contest_id=99") + self.assertEqual(response.data["code"], 1) + + def test_submission_contest_parameter_error(self): + self.client.login(username="test2", password="testbb") + response = self.client.get(self.url) + self.assertEqual(response.data["code"], 1) + + def test_submission_access_denied(self): + self.client.login(username="test1", password="testaa") + response = self.client.get(self.url + "?problem_id=" + str(self.problem.id)) + self.assertEqual(response.data["code"], 1) + + def test_submission_access_denied_with_contest_id(self): + self.client.login(username="test1", password="testaa") + response = self.client.get(self.url + "?contest_id=" + str(self.global_contest.id)) + self.assertEqual(response.data["code"], 1) + + def test_get_submission_successfully(self): + self.client.login(username="test2", password="testbb") + response = self.client.get( + self.url + "?contest_id=" + str(self.global_contest.id) + "&problem_id=" + str(self.problem.id)) + self.assertEqual(response.data["code"], 0) + + def test_get_submission_successfully_problem(self): + self.client.login(username="test2", password="testbb") + response = self.client.get(self.url + "?problem_id=" + str(self.problem.id)) + self.assertEqual(response.data["code"], 0) + + def test_get_submission_problem_do_not_exist(self): + self.client.login(username="test2", password="testbb") + response = self.client.get(self.url + "?problem_id=9999") + self.assertEqual(response.data["code"], 1) diff --git a/contest_submission/views.py b/contest_submission/views.py index 0dba7cb4..003ad8a6 100644 --- a/contest_submission/views.py +++ b/contest_submission/views.py @@ -21,6 +21,7 @@ from utils.shortcuts import serializer_invalid_response, error_response, success from submission.models import Submission from .serializers import CreateContestSubmissionSerializer +from submission.serializers import SubmissionSerializer class ContestSubmissionAPIView(APIView): @@ -76,7 +77,8 @@ def contest_problem_my_submissions_list_page(request, contest_id, contest_proble contest_problem = ContestProblem.objects.get(id=contest_problem_id, visible=True) except Problem.DoesNotExist: return error_page(request, u"比赛问题不存在") - submissions = Submission.objects.filter(user_id=request.user.id, problem_id=contest_problem.id).order_by("-create_time"). \ + submissions = Submission.objects.filter(user_id=request.user.id, problem_id=contest_problem.id).order_by( + "-create_time"). \ values("id", "result", "create_time", "accepted_answer_time", "language") return render(request, "oj/contest/my_submissions_list.html", {"submissions": submissions, "problem": contest_problem}) @@ -112,4 +114,38 @@ def contest_problem_submissions_list_page(request, contest_id, page=1): return render(request, "oj/contest/submissions_list.html", {"submissions": current_page, "page": int(page), "previous_page": previous_page, "next_page": next_page, "start_id": int(page) * 20 - 20, - "contest": contest}) \ No newline at end of file + "contest": contest}) + + +class ContestSubmissionAdminAPIView(APIView): + def get(self, request): + """ + 查询比赛提交,单个比赛题目提交的adminAPI + --- + response_serializer: SubmissionSerializer + """ + problem_id = request.GET.get("problem_id", None) + contest_id = request.GET.get("contest_id", None) + if contest_id: + try: + contest = Contest.objects.get(pk=contest_id) + except Contest.DoesNotExist: + return error_response(u"比赛不存在!") + if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user: + return error_response(u"您无权查看该信息!") + submissions = Submission.objects.filter(contest_id=contest_id).order_by("-create_time") + else: + if problem_id: + try: + contest_problem = ContestProblem.objects.get(pk=problem_id) + except ContestProblem.DoesNotExist: + return error_response(u"问题不存在!") + if request.user.admin_type != SUPER_ADMIN and contest_problem.contest.created_by != request.user: + return error_response(u"您无权查看该信息!") + submissions = Submission.objects.filter(contest_id=contest_problem.contest_id).order_by("-create_time") + else: + return error_response(u"参数错误!") + if problem_id: + submissions = submissions.filter(problem_id=problem_id) + + return paginate(request, submissions, SubmissionSerializer) diff --git a/oj/urls.py b/oj/urls.py index adb7ef00..74a44c2f 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -17,7 +17,7 @@ from admin.views import AdminTemplateView from problem.views import TestCaseUploadAPIView, ProblemTagAdminAPIView, ProblemAdminAPIView from submission.views import SubmissionAPIView, SubmissionAdminAPIView -from contest_submission.views import ContestSubmissionAPIView +from contest_submission.views import ContestSubmissionAPIView, ContestSubmissionAdminAPIView from monitor.views import QueueLengthMonitorAPIView from contest_submission.views import contest_problem_my_submissions_list_page @@ -65,7 +65,7 @@ urlpatterns = [ name="join_group_request_admin_api"), url(r'^api/admin/submission/$', SubmissionAdminAPIView.as_view(), name="submission_admin_api_view"), url(r'^api/admin/monitor/$', QueueLengthMonitorAPIView.as_view(), name="queue_length_monitor_api"), - + url(r'^api/admin/contest_submission/$', ContestSubmissionAdminAPIView.as_view(), name="contest_submission_admin_api_view"), url(r'^contest/(?P\d+)/problem/(?P\d+)/$', "contest.views.contest_problem_page", diff --git a/static/src/css/admin.css b/static/src/css/admin.css index f7e75810..fb9c9f25 100644 --- a/static/src/css/admin.css +++ b/static/src/css/admin.css @@ -55,3 +55,12 @@ list-style-type: none; margin: 5px; } + +.error-info { + color: #dd4b39; + font-family: + Arial,Helvetica,sans-serif; + font-size: 13px; + line-height: 1.4; + font-weight: 600; +} diff --git a/static/src/js/app/admin/admin.js b/static/src/js/app/admin/admin.js index bd0d51e2..9246f7f3 100644 --- a/static/src/js/app/admin/admin.js +++ b/static/src/js/app/admin/admin.js @@ -133,11 +133,17 @@ define("admin", ["jquery", "avalon"], function ($, avalon) { vm.template_url = "template/contest/edit_problem.html"; }); - vm.$watch("showContestListPage", function (problemId) { - vm.problemId = problemId; + vm.$watch("showContestListPage", function () { vm.template_url = "template/contest/contest_list.html"; }); + vm.$watch("showContestSubmissionPage", function (problemId, contestId, contestMode) { + vm.$problemId = problemId; + vm.$contestId = contestId; + vm.$contestMode = contestMode + vm.template_url = "template/contest/submission_list.html"; + }); + avalon.scan(); window.onhashchange = function () { diff --git a/static/src/js/app/admin/announcement/announcement.js b/static/src/js/app/admin/announcement/announcement.js index 7dd2051b..4c67ef2e 100644 --- a/static/src/js/app/admin/announcement/announcement.js +++ b/static/src/js/app/admin/announcement/announcement.js @@ -1,163 +1,163 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"], function ($, avalon, csrfTokenHeader, bsAlert, editor) { avalon.ready(function () { - avalon.vmodels.announcement = null; var createAnnouncementEditor = editor("#create-announcement-editor"); var editAnnouncementEditor = editor("#edit-announcement-editor"); + if (avalon.vmodels.announcement){ + var vm = avalon.vmodels.announcement; + announcementList = []; + } + else { - var vm = avalon.define({ - $id: "announcement", - //通用变量 - announcementList: [], // 公告列表数据项 - previousPage: 0, // 之前的页数 - nextPage: 0, // 之后的页数 - page: 1, // 当前页数 - editingAnnouncementId: 0, // 正在编辑的公告的ID, 为零说明未在编辑 - totalPage: 1, // 总页数 - showVisibleOnly: false, //仅显示可见公告 - // 编辑 - newTitle: "", - announcementVisible: 0, - showGlobalViewRadio: true, - isGlobal: true, - allGroups: [], - getState: function (el) { //获取公告当前状态,显示 - if (el.visible) - return "可见"; - else - return "隐藏"; - }, - getNext: function () { - if (!vm.nextPage) - return; - getPageData(vm.page + 1); - }, - getPrevious: function () { - if (!vm.previousPage) - return; - getPageData(vm.page - 1); - }, - getBtnClass: function (btnType) { - if (btnType == "next") { - return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; - } - else { - return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; - } - - }, - editAnnouncement: function (announcement) { - vm.newTitle = announcement.title; - editAnnouncementEditor.setValue(announcement.content); - vm.announcementVisible = announcement.visible; - if (vm.editingAnnouncementId == announcement.id) + var vm = avalon.define({ + $id: "announcement", + //通用变量 + announcementList: [], // 公告列表数据项 + previousPage: 0, // 之前的页数 + nextPage: 0, // 之后的页数 + page: 1, // 当前页数 + editingAnnouncementId: 0, // 正在编辑的公告的ID, 为零说明未在编辑 + totalPage: 1, // 总页数 + showVisibleOnly: false, //仅显示可见公告 + // 编辑 + newTitle: "", + announcementVisible: 0, + showGlobalViewRadio: true, + isGlobal: true, + allGroups: [], + getNext: function () { + if (!vm.nextPage) + return; + getPageData(vm.page + 1); + }, + getPrevious: function () { + if (!vm.previousPage) + return; + getPageData(vm.page - 1); + }, + getBtnClass: function (btnType) { + if (btnType == "next") { + return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + else { + return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + }, + editAnnouncement: function (announcement) { + vm.newTitle = announcement.title; + editAnnouncementEditor.setValue(announcement.content); + vm.announcementVisible = announcement.visible; + if (vm.editingAnnouncementId == announcement.id) + vm.editingAnnouncementId = 0; + else + vm.editingAnnouncementId = announcement.id; + vm.isGlobal = announcement.is_global; + for (var i = 0; i < announcement.groups.length; i++) { + for (var j = 0; j < vm.allGroups.length; j++) { + if (announcement.groups[i] == vm.allGroups[j].id) { + vm.allGroups[j].isSelected = true; + } + } + } + editAnnouncementEditor.focus(); + }, + cancelEdit: function () { vm.editingAnnouncementId = 0; - else - vm.editingAnnouncementId = announcement.id; - vm.isGlobal = announcement.is_global; - for (var i = 0; i < announcement.groups.length; i++) { - for (var j = 0; j < vm.allGroups.length; j++) { - if (announcement.groups[i] == vm.allGroups[j].id) { - vm.allGroups[j].isSelected = true; + }, + submitChange: function () { + var title = vm.newTitle; + var content = editAnnouncementEditor.getValue(); + + if (content == "" || title == "") { + bsAlert("标题和内容都不能为空"); + return false; + } + + var selectedGroups = []; + if (!vm.isGlobal) { + for (var i = 0; i < vm.allGroups.length; i++) { + if (vm.allGroups[i].isSelected) { + selectedGroups.push(vm.allGroups[i].id); + } } } - } - editAnnouncementEditor.focus(); - }, - cancelEdit: function () { - vm.editingAnnouncementId = 0; - }, - submitChange: function () { - var title = vm.newTitle; - var content = editAnnouncementEditor.getValue(); - if (content == "" || title == "") { - bsAlert("标题和内容都不能为空"); - return false; - } - - var selectedGroups = []; - if (!vm.isGlobal) { - for (var i = 0; i < vm.allGroups.length; i++) { - if (vm.allGroups[i].isSelected) { - selectedGroups.push(vm.allGroups[i].id); - } + if (!vm.isGlobal && !selectedGroups.length) { + bsAlert("请至少选择一个小组"); + return false; } - } - if (!vm.isGlobal && !selectedGroups.length) { - bsAlert("请至少选择一个小组"); - return false; - } - - $.ajax({ - beforeSend: csrfTokenHeader, - url: "/api/admin/announcement/", - contentType: "application/json", - dataType: "json", - method: "put", - data: JSON.stringify({ - id: vm.editingAnnouncementId, - title: title, - content: content, - visible: vm.announcementVisible, - is_global: vm.isGlobal, - groups: selectedGroups - }), - success: function (data) { - if (!data.code) { - bsAlert("修改成功"); - vm.editingAnnouncementId = 0; - getPageData(1); + $.ajax({ + beforeSend: csrfTokenHeader, + url: "/api/admin/announcement/", + contentType: "application/json", + dataType: "json", + method: "put", + data: JSON.stringify({ + id: vm.editingAnnouncementId, + title: title, + content: content, + visible: vm.announcementVisible, + is_global: vm.isGlobal, + groups: selectedGroups + }), + success: function (data) { + if (!data.code) { + bsAlert("修改成功"); + vm.editingAnnouncementId = 0; + getPageData(1); + } + else { + bsAlert(data.data); + } } - else { - bsAlert(data.data); - } - } - }); + }); - } - }); - vm.$watch("showVisibleOnly", function () { - getPageData(1); - }); + } + }); + vm.$watch("showVisibleOnly", function () { + getPageData(1); + }); + } getPageData(1); - $.ajax({ - url: "/api/admin/group/", - method: "get", - dataType: "json", - success: function (data) { - if (!data.code) { - if (!data.data.length) { - bsAlert("您的用户权限只能创建组内公告,但是您还没有创建过小组"); - return; - } - for (var i = 0; i < data.data.length; i++) { - var item = data.data[i]; - item["isSelected"] = false; - vm.allGroups.push(item); - } - } - else { - bsAlert(data.data); - } - } - }); - $.ajax({ url: "/api/user/", method: "get", dataType: "json", success: function (data) { if (!data.code) { + var admin_type = data.data.admin_type; if (data.data.admin_type == 1) { vm.isGlobal = false; vm.showGlobalViewRadio = false; + } } + $.ajax({ + url: "/api/admin/group/", + method: "get", + dataType: "json", + success: function (data) { + if (!data.code) { + if (!data.data.length) { + if (admin_type != 2) + bsAlert("您的用户权限只能创建组内公告,但是您还没有创建过小组"); + return; + } + for (var i = 0; i < data.data.length; i++) { + var item = data.data[i]; + item["isSelected"] = false; + vm.allGroups.push(item); + } + } + else { + bsAlert(data.data); + } + } + }); } }); diff --git a/static/src/js/app/admin/contest/addContest.js b/static/src/js/app/admin/contest/addContest.js index 437fbdf3..d4beadb3 100644 --- a/static/src/js/app/admin/contest/addContest.js +++ b/static/src/js/app/admin/contest/addContest.js @@ -131,7 +131,6 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date success: function (data) { if (!data.code) { if (!data.data.length) { - bsAlert("您的用户权限只能创建组内比赛,但是您还没有创建过小组"); return; } for (var i = 0; i < data.data.length; i++) { diff --git a/static/src/js/app/admin/contest/contestList.js b/static/src/js/app/admin/contest/contestList.js index 9c1ba71b..f63cdccd 100644 --- a/static/src/js/app/admin/contest/contestList.js +++ b/static/src/js/app/admin/contest/contestList.js @@ -234,15 +234,17 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker", vm.groupList[vm.choseGroupList[groupIndex].index].chose = false; vm.choseGroupList.remove(vm.choseGroupList[groupIndex]); }, - add_problem: function () { + addProblem: function () { vm.$fire("up!showContestProblemPage", 0, vm.contestList[vm.editingProblemContestIndex-1].id, vm.editMode); }, - showProblemEditor: function(el) { + showProblemEditPage: function(el) { vm.$fire("up!showContestProblemPage", el.id, vm.contestList[vm.editingProblemContestIndex-1].id, vm.editMode); }, - getYesOrNo: function(yORn) { - if (yORn) return "是"; - return "否"; + showSubmissionPage: function(el) { + var problemId = 0 + if (el) + problemId = el.id; + vm.$fire("up!showContestSubmissionPage", problemId, vm.contestList[vm.editingProblemContestIndex-1].id, vm.editMode); } }); vm.$watch("showVisibleOnly", function() { diff --git a/static/src/js/app/admin/contest/submissionList.js b/static/src/js/app/admin/contest/submissionList.js new file mode 100644 index 00000000..34fd5914 --- /dev/null +++ b/static/src/js/app/admin/contest/submissionList.js @@ -0,0 +1,88 @@ +require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfTokenHeader, bsAlert) { + + avalon.ready(function () { + + if (avalon.vmodels.contestSubmissionList){ + var vm = avalon.vmodels.contestSubmissionList; + } + else { + + var vm = avalon.define({ + $id: "contestSubmissionList", + submissionList: [], + previousPage: 0, + nextPage: 0, + page: 1, + totalPage: 1, + results : { + 0: "Accepted", + 1: "Runtime Error", + 2: "Time Limit Exceeded", + 3: "Memory Limit Exceeded", + 4: "Compile Error", + 5: "Format Error", + 6: "Wrong Answer", + 7: "System Error", + 8: "Waiting" + }, + 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) { + if (!page_index) + var page_index = vm.page; + getPageData(page_index); + }, + showSubmissionDetailPage: function (submissionId) { + + }, + goBack: function(check){ + vm.$fire("up!showContestListPage"); + } + }); + } + + getPageData(1); + + function getPageData(page) { + var url = "/api/admin/contest_submission/?paging=true&page=" + page + "&page_size=10&contest_id=" + avalon.vmodels.admin.$contestId; + if (avalon.vmodels.admin.$problemId) + url += "&problem_id=" + avalon.vmodels.admin.$problemId + $.ajax({ + url: url, + dataType: "json", + method: "get", + success: function (data) { + if (!data.code) { + vm.submissionList = 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); + } + } + }); + } + + + }); + avalon.scan(); +}); \ No newline at end of file diff --git a/static/src/js/app/admin/group/group.js b/static/src/js/app/admin/group/group.js index 470f9caf..425e4bbf 100644 --- a/static/src/js/app/admin/group/group.js +++ b/static/src/js/app/admin/group/group.js @@ -1,51 +1,57 @@ require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfTokenHeader, bsAlert) { - avalon.ready(function () { - avalon.vmodels.group = null; - var vm = avalon.define({ - $id: "group", - //通用变量 - groupList: [], // 用户列表数据项 - previousPage: 0, // 之前的页数 - nextPage: 0, // 之后的页数 - page: 1, // 当前页数 - totalPage: 1, // 总页数 - keyword: "", + //avalon.vmodels.group = null; + if (avalon.vmodels.group) { + var vm = avalon.vmodels.group; + } + else { - getNext: function () { - if (!vm.nextPage) - return; - getPageData(vm.page + 1); - }, - getPrevious: function () { - if (!vm.previousPage) - return; - getPageData(vm.page - 1); - }, - getBtnClass: function (btnType) { - if (btnType == "next") { - return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; - } - else { - return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; - } + var vm = avalon.define({ + $id: "group", + //通用变量 + groupList: [], // 用户列表数据项 + previousPage: 0, // 之前的页数 + nextPage: 0, // 之后的页数 + page: 1, // 当前页数 + totalPage: 1, // 总页数 + keyword: "", + + getNext: function () { + if (!vm.nextPage) + return; + getPageData(vm.page + 1); + }, + getPrevious: function () { + if (!vm.previousPage) + return; + getPageData(vm.page - 1); + }, + getBtnClass: function (btnType) { + if (btnType == "next") { + return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + else { + return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + + }, + search: function(){ + getPageData(1); + }, + getGroupSettingString: function (setting) { + return {0: "允许任何人加入", 1: "提交请求后管理员审核", 2: "不允许任何人加入"}[setting] + }, + showGroupDetailPage: function (groupId) { + vm.$fire("up!showGroupDetailPage", groupId); + } + }); + } - }, - search: function(){ - getPageData(1); - }, - getGroupSettingString: function (setting) { - return {0: "允许任何人加入", 1: "提交请求后管理员审核", 2: "不允许任何人加入"}[setting] - }, - showGroupDetailPage: function (groupId) { - vm.$fire("up!showGroupDetailPage", groupId); - } - }); getPageData(1); function getPageData(page) { - var url = "/api/admin/group/?paging=true&page=" + page + "&page_size=2"; + var url = "/api/admin/group/?paging=true&page=" + page + "&page_size=10"; if (vm.keyword) url += "&keyword=" + vm.keyword; $.ajax({ diff --git a/static/src/js/app/admin/group/groupDetail.js b/static/src/js/app/admin/group/groupDetail.js index cddc755d..c06f9ce0 100644 --- a/static/src/js/app/admin/group/groupDetail.js +++ b/static/src/js/app/admin/group/groupDetail.js @@ -3,55 +3,60 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "validator"], function ($, // avalon:定义模式 group_list avalon.ready(function () { - avalon.vmodels.groupDetail = null; - var vm = avalon.define({ - $id: "groupDetail", - //通用变量 - memberList: [], - previousPage: 0, - nextPage: 0, - page: 1, - totalPage: 1, - name: "", - description: "", - checkedSetting: "0", - 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"; - } - }, + if (avalon.vmodels.groupDetail) { + var vm = avalon.vmodels.groupDetail; + } + else { + var vm = avalon.define({ + $id: "groupDetail", + //通用变量 + memberList: [], + previousPage: 0, + nextPage: 0, + page: 1, + totalPage: 1, + name: "", + description: "", + checkedSetting: "0", - removeMember: function (relation) { - $.ajax({ - beforeSend: csrfTokenHeader, - url: "/api/admin/group_member/", - method: "put", - data: JSON.stringify({group_id: relation.group, members: [relation.user.id]}), - contentType: "application/json", - success: function (data) { - vm.memberList.remove(relation); - bsAlert(data.data); + 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"; } - }) - }, - showGroupListPage: function () { - vm.$fire("up!showGroupListPage"); - } - }); + else { + return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled"; + } + }, + + removeMember: function (relation) { + $.ajax({ + beforeSend: csrfTokenHeader, + url: "/api/admin/group_member/", + method: "put", + data: JSON.stringify({group_id: relation.group, members: [relation.user.id]}), + contentType: "application/json", + success: function (data) { + vm.memberList.remove(relation); + bsAlert(data.data); + } + }) + }, + showGroupListPage: function () { + vm.$fire("up!showGroupListPage"); + } + }); + } avalon.scan(); getPageData(1); diff --git a/static/src/js/app/admin/group/joinGroupRequestList.js b/static/src/js/app/admin/group/joinGroupRequestList.js index e565aad7..b178a801 100644 --- a/static/src/js/app/admin/group/joinGroupRequestList.js +++ b/static/src/js/app/admin/group/joinGroupRequestList.js @@ -1,51 +1,57 @@ -require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) { +require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfTokenHeader, bsAlert) { // avalon:定义模式 group_list avalon.ready(function () { - avalon.vmodels.requestList = null; - var vm = avalon.define({ - $id: "requestList", - //通用变量 - requestList: [], // 列表数据项 - previousPage: 0, // 之前的页数 - nextPage: 0, // 之后的页数 - page: 1, // 当前页数 - totalPage: 1, // 总页数 - 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); - }, - processRequest: function(request, status){ - $.ajax({ - beforeSend: csrfTokenHeader, - url: "/api/admin/join_group_request/", - method: "put", - data: {request_id: request.id, status: status}, - success: function(data){ - vm.requestList.remove(request); - bsAlert(data.data); + if (avalon.vmodels.requestList) { + var vm = avalon.vmodels.requestList; + } + else { + + var vm = avalon.define({ + $id: "requestList", + //通用变量 + requestList: [], // 列表数据项 + previousPage: 0, // 之前的页数 + nextPage: 0, // 之后的页数 + page: 1, // 当前页数 + totalPage: 1, // 总页数 + + 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); + }, + processRequest: function(request, status){ + $.ajax({ + beforeSend: csrfTokenHeader, + url: "/api/admin/join_group_request/", + method: "put", + data: {request_id: request.id, status: status}, + success: function(data){ + vm.requestList.remove(request); + bsAlert(data.data); + } + }) + } + }); + } avalon.scan(); getPageData(1); @@ -72,78 +78,6 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function }); } - /*$("#edit_user-form") - .formValidation({ - framework: "bootstrap", - fields: { - username: { - validators: { - notEmpty: { - message: "请填写用户名" - }, - stringLength: { - min: 3, - max: 30, - message: '用户名长度必须在3到30位之间' - } - } - }, - real_name: { - validators: { - notEmpty: { - message: "请填写真实姓名" - } - } - }, - email: { - validators: { - notEmpty: { - message: "请填写电子邮箱邮箱地址" - }, - emailAddress: { - message: "请填写有效的邮箱地址" - } - } - }, - password: { - validators: { - stringLength: { - min: 6, - max: 30, - message: '密码长度必须在6到30位之间' - } - } - } - } - } - ).on('success.form.fv', function (e) { - e.preventDefault(); - var data = { - username: vm.username, - real_name: vm.real_name, - email: vm.email, - id: vm.id, - admin_type: vm.admin_type - }; - if ($("#password").val() !== "") - data.password = $("#password").val(); - $.ajax({ - beforeSend: csrfHeader, - url: "/api/admin/user/", - data: data, - dataType: "json", - method: "put", - success: function (data) { - if (!data.code) { - bsAlert("提交成功!"); - getPageData(1); - $("#password").val(""); - } else { - bsAlert(data.data); - } - } - }) - });*/ }); }); \ No newline at end of file diff --git a/static/src/js/app/admin/problem/problem.js b/static/src/js/app/admin/problem/problem.js index 2632ebf5..9fe56df5 100644 --- a/static/src/js/app/admin/problem/problem.js +++ b/static/src/js/app/admin/problem/problem.js @@ -3,6 +3,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfT avalon.ready(function () { if(avalon.vmodels.problemList){ vm = avalon.vmodels.problemList; + problemList = []; } else { var vm = avalon.define({ @@ -13,6 +14,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfT page: 1, totalPage: 1, keyword: "", + showVisibleOnly: false, getNext: function () { if (!vm.nextPage) return; @@ -41,12 +43,17 @@ require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfT vm.$fire("up!showProblemSubmissionPage", problemId); } }); + vm.$watch("showVisibleOnly", function () { + getPageData(1); + }); } getPageData(1); function getPageData(page) { var url = "/api/admin/problem/?paging=true&page=" + page + "&page_size=10"; if (vm.keyword != "") url += "&keyword=" + vm.keyword; + if (vm.showVisibleOnly) + url += "&visible=true"; $.ajax({ url: url, dataType: "json", diff --git a/static/src/js/app/admin/problem/submissionList.js b/static/src/js/app/admin/problem/submissionList.js index 405cffa7..1af2e6ce 100644 --- a/static/src/js/app/admin/problem/submissionList.js +++ b/static/src/js/app/admin/problem/submissionList.js @@ -1,53 +1,59 @@ require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfTokenHeader, bsAlert) { avalon.ready(function () { - avalon.vmodels.submissionList = null; - var vm = avalon.define({ - $id: "submissionList", - submissionList: [], - previousPage: 0, - nextPage: 0, - page: 1, - totalPage: 1, - results : { - 0: "Accepted", - 1: "Runtime Error", - 2: "Time Limit Exceeded", - 3: "Memory Limit Exceeded", - 4: "Compile Error", - 5: "Format Error", - 6: "Wrong Answer", - 7: "System Error", - 8: "Waiting" - }, - 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); - }, - showSubmissionDetailPage: function (submissionId) { - }, - showProblemListPage: function(){ - vm.$fire("up!showProblemListPage"); - } - }); + if (avalon.vmodels.submissionList){ + var vm = avalon.vmodels.submissionList; + } + else { + + var vm = avalon.define({ + $id: "submissionList", + submissionList: [], + previousPage: 0, + nextPage: 0, + page: 1, + totalPage: 1, + results : { + 0: "Accepted", + 1: "Runtime Error", + 2: "Time Limit Exceeded", + 3: "Memory Limit Exceeded", + 4: "Compile Error", + 5: "Format Error", + 6: "Wrong Answer", + 7: "System Error", + 8: "Waiting" + }, + 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); + }, + showSubmissionDetailPage: function (submissionId) { + + }, + showProblemListPage: function(){ + vm.$fire("up!showProblemListPage"); + } + }); + } getPageData(1); diff --git a/static/src/js/app/admin/user/userList.js b/static/src/js/app/admin/user/userList.js index 3f80c89d..d2949f05 100644 --- a/static/src/js/app/admin/user/userList.js +++ b/static/src/js/app/admin/user/userList.js @@ -3,12 +3,12 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "validator"], function ($, // avalon:定义模式 userList avalon.ready(function () { - //avalon.vmodels.userList = null; + if (avalon.vmodels.userList) { var vm = avalon.vmodels.userList; // initialize avalon object - userList = []; previousPage= 0; nextPage= 0; page = 1; - editingUserId= 0; totalPage = 1; keyword= ""; showAdminOnly= false; + userList = []; //previousPage= 0; nextPage= 0; page = 1; + //editingUserId= 0; totalPage = 1; keyword= ""; showAdminOnly= false; //user editor fields username= ""; realName= ""; email= ""; adminType= 0; id= 0; } diff --git a/submission/tests.py b/submission/tests.py index e745bdea..04f0a86d 100644 --- a/submission/tests.py +++ b/submission/tests.py @@ -41,7 +41,7 @@ class SubmissionsListPageTest(TestCase): def test_submissionsListPage_page_not_exist(self): self.client.login(username="gogoing", password="666666") - response = self.client.get('/submissions/5/') + response = self.client.get('/submissions/999/') self.assertTemplateUsed(response, "utils/error.html") def test_submissionsListPage_have_no_submission(self): diff --git a/template/src/admin/announcement/announcement.html b/template/src/admin/announcement/announcement.html index 3bfd605d..f08ccb04 100644 --- a/template/src/admin/announcement/announcement.html +++ b/template/src/admin/announcement/announcement.html @@ -7,8 +7,8 @@ 创建时间 更新时间 创建者 - 可见范围 - 状态 + 类型 + 可见 @@ -18,7 +18,7 @@ {{ el.last_update_time|date("yyyy-MM-dd HH:mm:ss")}} {{ el.created_by.username }} - {{ getState(el)}} + @@ -38,7 +38,8 @@
-
+
@@ -66,7 +67,7 @@
- +   
@@ -78,12 +79,14 @@ +
+
@@ -91,10 +94,16 @@
- 全局可见 + - 小组内可见 +
@@ -106,7 +115,7 @@
- +
diff --git a/template/src/admin/contest/add_contest.html b/template/src/admin/contest/add_contest.html index 6f237c55..b374ec82 100644 --- a/template/src/admin/contest/add_contest.html +++ b/template/src/admin/contest/add_contest.html @@ -18,9 +18,7 @@
- -
- 请填写比赛描述 +

请填写比赛描述

diff --git a/template/src/admin/contest/contest_list.html b/template/src/admin/contest/contest_list.html index 5c156299..7418a569 100644 --- a/template/src/admin/contest/contest_list.html +++ b/template/src/admin/contest/contest_list.html @@ -15,22 +15,22 @@ ID 比赛 - 公开排名 - 可见 + 排名 创建时间 创建者 + 可见 {{ el.id }} {{ el.title }} - {{ getYesOrNo(el.show_rank) }} - {{ getYesOrNo(el.visible) }} + {{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}} {{ el.created_by.username }} + - 编辑 - 编辑问题 + 编辑 + 题目 @@ -63,7 +63,7 @@
- 请填写比赛描述 +

请填写比赛描述

@@ -152,13 +152,14 @@
- +
- 添加 + 添加题目 + 查看提交 @@ -176,7 +177,9 @@
编号{{ el.create_time|date("yyyy-MM-dd HH:mm:ss") }} 编辑 + ms-click="showProblemEditPage(el)">编辑 + 提交
diff --git a/template/src/admin/contest/edit_problem.html b/template/src/admin/contest/edit_problem.html index 331917ce..87a7976f 100644 --- a/template/src/admin/contest/edit_problem.html +++ b/template/src/admin/contest/edit_problem.html @@ -23,7 +23,7 @@
- 请填写题目描述 +

请填写题目描述

@@ -130,7 +130,7 @@
- +
diff --git a/template/src/admin/contest/submission_list.html b/template/src/admin/contest/submission_list.html new file mode 100644 index 00000000..18474085 --- /dev/null +++ b/template/src/admin/contest/submission_list.html @@ -0,0 +1,37 @@ +
+ +

提交列表

+ + 刷新 + + + + + + + + + + + + + + + + + +
ID创建时间作者结果
{{ el.id }}{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}{{ el.user }}{{ results[el.result] }} + 详情 +
+
+ 页数:{{ page }}/{{ totalPage }}   + + +
+
+ \ No newline at end of file diff --git a/template/src/admin/problem/add_problem.html b/template/src/admin/problem/add_problem.html index 38c22c62..70bd5249 100644 --- a/template/src/admin/problem/add_problem.html +++ b/template/src/admin/problem/add_problem.html @@ -11,7 +11,7 @@
- 请填写题目描述 +

请填写题目描述

diff --git a/template/src/admin/problem/edit_problem.html b/template/src/admin/problem/edit_problem.html index 0a2b7b57..d2587b3e 100644 --- a/template/src/admin/problem/edit_problem.html +++ b/template/src/admin/problem/edit_problem.html @@ -17,7 +17,7 @@
- 请填写题目描述 +

请填写题目描述

diff --git a/template/src/admin/problem/problem_list.html b/template/src/admin/problem/problem_list.html index 01f86712..a571cfe8 100644 --- a/template/src/admin/problem/problem_list.html +++ b/template/src/admin/problem/problem_list.html @@ -17,7 +17,8 @@ 题目 创建时间 作者 - 通过次数/提交总数 + 可见 + 通过次数/提交总数 @@ -25,6 +26,7 @@ {{ el.title }} {{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}} {{ el.created_by.username }} + {{ getYesOrNo(el.visible) }} {{ el.total_accepted_number }}/{{ el.total_submit_number }} @@ -32,6 +34,9 @@ +
+ +
页数:{{ page }}/{{ totalPage }}   diff --git a/template/src/admin/problem/submission_list.html b/template/src/admin/problem/submission_list.html index 70aacb82..28eaebd4 100644 --- a/template/src/admin/problem/submission_list.html +++ b/template/src/admin/problem/submission_list.html @@ -21,7 +21,7 @@ {{ el.user }} {{ results[el.result] }} - 详情 + 详情