重构后台比赛的添加编辑和题目的添加和编辑

This commit is contained in:
virusdefender 2015-10-29 17:26:41 +08:00
parent f9c4356683
commit a72e0e7388
9 changed files with 214 additions and 214 deletions

View File

@ -73,6 +73,8 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "bootstrap"], function ($,
adminNavList: [], adminNavList: [],
contestId: -1, contestId: -1,
contestProblemStatus: "edit",
hide_loading: function () { hide_loading: function () {
$("#loading-gif").hide(); $("#loading-gif").hide();
}, },

View File

@ -27,7 +27,8 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
// todo 修改template_url // todo 修改template_url
}, },
showContestProblems: function(contestId){ showContestProblems: function(contestId){
// todo avalon.vmodels.admin.contestId = contestId;
avalon.vmodels.admin.template_url = "template/contest/problem_list.html";
} }
}) })
} }

View File

@ -0,0 +1,43 @@
require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfTokenHeader, bsAlert) {
avalon.ready(function () {
if (avalon.vmodels.contestProblemList) {
vm = avalon.vmodels.contestProblemList;
}
else {
var vm = avalon.define({
$id: "contestProblemList",
problemList: [],
showEditProblemPage: function (problemId) {
avalon.vmodels.admin.contestProblemStatus = "edit";
avalon.vmodels.admin.problemId = problemId;
avalon.vmodels.admin.template_url = "template/contest/edit_problem.html";
},
addProblem: function(){
avalon.vmodels.admin.contestProblemStatus = "add";
avalon.vmodels.admin.template_url = "template/contest/edit_problem.html";
},
goBack: function(){
avalon.vmodels.admin.template_url = "template/contest/contest_list.html"
}
});
}
$.ajax({
url: "/api/admin/contest_problem/?contest_id=" + avalon.vmodels.admin.contestId,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.problemList = data.data;
}
else {
bsAlert(data.data);
}
}
});
avalon.scan();
});
});

View File

@ -1,22 +1,22 @@
require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagEditor", "validator", "jqueryUI"], require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagEditor", "validator", "editorComponent"],
function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) { function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) {
avalon.ready(function () { avalon.ready(function () {
$("#edit-problem-form").validator() $("#edit-problem-form").validator()
.on('submit', function (e) { .on('submit', function (e) {
if (!e.isDefaultPrevented()){ if (!e.isDefaultPrevented()) {
e.preventDefault(); e.preventDefault();
if (vm.testCaseId == "") { if (vm.testCaseId == "") {
bsAlert("你还没有上传测试数据!"); bsAlert("你还没有上传测试数据!");
return false; return false;
} }
if (vm.description == "") { if (avalon.vmodels.contestProblemDescriptionEditor.content == "") {
bsAlert("题目描述不能为空!"); bsAlert("题目描述不能为空!");
return false; return false;
} }
if (vm.timeLimit < 1000 || vm.timeLimit > 5000) { if (vm.timeLimit < 30 || vm.timeLimit > 5000) {
bsAlert("保证时间限制是一个1000-5000的合法整数"); bsAlert("保证时间限制是一个30-5000的合法整数");
return false; return false;
} }
if (vm.samples.length == 0) { if (vm.samples.length == 0) {
@ -31,33 +31,34 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
} }
var ajaxData = { var ajaxData = {
title: vm.title, title: vm.title,
description: vm.description, description: avalon.vmodels.contestProblemDescriptionEditor.content,
time_limit: vm.timeLimit, time_limit: vm.timeLimit,
memory_limit: vm.memoryLimit, memory_limit: vm.memoryLimit,
samples: [], samples: [],
test_case_id: vm.testCaseId, test_case_id: vm.testCaseId,
hint: vm.hint, hint: avalon.vmodels.contestProblemHintEditor.content,
visible: vm.visible, visible: vm.visible,
contest_id: avalon.vmodels.admin.$contestId, contest_id: avalon.vmodels.admin.contestId,
input_description: vm.inputDescription, input_description: vm.inputDescription,
output_description: vm.outputDescription, output_description: vm.outputDescription,
sort_index: vm.sortIndex, sort_index: vm.sortIndex
}; };
if (vm.contestMode == '2') {
if (!vm.score) { if (avalon.vmodels.admin.contestProblemStatus == "edit") {
bsAlert("请输入有效的分值!") var method = "put";
return false; ajaxData["id"] = avalon.vmodels.admin.problemId;
} var alertContent = "题目编辑成功";
ajaxData.score = vm.score;
} }
var method = "post"; else{
if (avalon.vmodels.admin.$problemId) { var method = "post";
method = "put"; var alertContent = "题目创建成功";
ajaxData.id = avalon.vmodels.admin.$problemId;
} }
for (var i = 0; i < vm.samples.$model.length; i++) { for (var i = 0; i < vm.samples.$model.length; i++) {
ajaxData.samples.push({input: vm.samples.$model[i].input, output: vm.samples.$model[i].output}); ajaxData.samples.push({
input: vm.samples.$model[i].input,
output: vm.samples.$model[i].output
});
} }
$.ajax({ $.ajax({
@ -69,8 +70,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
contentType: "application/json;charset=UTF-8", contentType: "application/json;charset=UTF-8",
success: function (data) { success: function (data) {
if (!data.code) { if (!data.code) {
bsAlert("题目编辑成功!"); bsAlert(alertContent);
vm.goBack(true);
} }
else { else {
bsAlert(data.data); bsAlert(data.data);
@ -82,93 +82,101 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
} }
}); });
if (!avalon.vmodels.editProblem) if (!avalon.vmodels.editProblem)
var vm = avalon.define({ var vm = avalon.define({
$id: "editProblem", $id: "editProblem",
title: "", title: "",
description: "", description: "",
timeLimit: 0, timeLimit: 1000,
memoryLimit: 0, memoryLimit: 128,
samples: [], samples: [],
hint: "", hint: "",
sortIndex: "", sortIndex: "",
visible: true, visible: true,
inputDescription: "", inputDescription: "",
outputDescription: "", outputDescription: "",
testCaseIdd: "", testCaseId: "",
contestMode: 0, testCaseList: [],
score: 1, uploadSuccess: false,
uploadSuccess: false,
testCaseList: [], contestProblemDescriptionEditor: {
addSample: function () { editorId: "contest-problem-description-editor",
vm.samples.push({input: "", output: "", "visible": true}); placeholder: "题目描述"
}, },
delSample: function (sample) { contestProblemHintEditor: {
if (confirm("你确定要删除么?")) { editorId: "contest-problem-hint-editor",
vm.samples.remove(sample); placeholder: "提示"
} },
},
toggleSample: function (sample) { addSample: function () {
sample.visible = !sample.visible; vm.samples.push({input: "", output: "", "visible": true});
}, },
getBtnContent: function (item) {
if (item.visible) delSample: function (sample) {
return "折叠"; if (confirm("你确定要删除么?")) {
return "展开"; vm.samples.remove(sample);
}, }
goBack: function(check){ },
if (check||confirm("这将丢失所有的改动,确定要继续么?")) {
vm.$fire("up!showContestListPage"); toggleSample: function (sample) {
} sample.visible = !sample.visible;
} },
});
else getBtnContent: function (item) {
vm = avalon.vmodels.editProblem; if (item.visible)
return "折叠";
return "展开";
},
goBack: function (check) {
avalon.vmodels.admin.template_url = "template/contest/problem_list.html";
}
});
else {
var vm = avalon.vmodels.editProblem;
}
var hintEditor = editor("#hint");
var descriptionEditor = editor("#problemDescription");
var testCaseUploader = uploader("#testCaseFile", "/api/admin/test_case_upload/", function (file, response) { var testCaseUploader = uploader("#testCaseFile", "/api/admin/test_case_upload/", function (file, response) {
if (response.code) if (response.code)
bsAlert(response.data); bsAlert(response.data);
else { else {
vm.testCaseId = response.data.test_case_id; vm.testCaseId = response.data.test_case_id;
vm.uploadSuccess = true;
vm.testCaseList = []; vm.testCaseList = [];
for (var i = 0; i < response.data.file_list.input.length; i++) { for(var key in response.data.file_list){
vm.testCaseList.push({ vm.testCaseList.push({
input: response.data.file_list.input[i], input: response.data.file_list[key].input_name,
output: response.data.file_list.output[i] output: response.data.file_list[key].output_name
}); })
} }
vm.uploadSuccess = true;
bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据"); bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据");
} }
}); });
vm.contestMode = avalon.vmodels.admin.$contestMode; if (avalon.vmodels.admin.contestProblemStatus == "edit") {
if (avalon.vmodels.admin.$problemId){
$.ajax({ $.ajax({
url: "/api/admin/contest_problem/?contest_problem_id=" + avalon.vmodels.admin.$problemId, url: "/api/admin/contest_problem/?contest_problem_id=" + avalon.vmodels.admin.problemId,
method: "get", method: "get",
dataType: "json", dataType: "json",
success: function (data) { success: function (data) {
if (data.code) { if (data.code) {
bsAlert(data.data); bsAlert(data.data);
} }
else { // Edit mode load the problem data else {
var problem = data.data; var problem = data.data;
vm.testCaseList = []; vm.testCaseList = [];
vm.sortIndex = problem.sort_index; vm.sortIndex = problem.sort_index;
vm.title = problem.title; vm.title = problem.title;
vm.description = problem.description; avalon.vmodels.contestProblemDescriptionEditor.content = problem.description;
vm.timeLimit = problem.time_limit; vm.timeLimit = problem.time_limit;
vm.memoryLimit = problem.memory_limit; vm.memoryLimit = problem.memory_limit;
vm.hint = problem.hint; vm.hint = problem.hint;
vm.visible = problem.visible; vm.visible = problem.visible;
vm.inputDescription = problem.input_description; vm.inputDescription = problem.input_description;
vm.outputDescription = problem.output_description; vm.outputDescription = problem.output_description;
vm.score = problem.score; vm.score = problem.score;
vm.samples = []; vm.testCaseId = problem.test_case_id;
vm.testCaseId = problem.test_case_id; vm.samples = [];
for (var i = 0; i < problem.samples.length; i++) { for (var i = 0; i < problem.samples.length; i++) {
vm.samples.push({ vm.samples.push({
input: problem.samples[i].input, input: problem.samples[i].input,
@ -176,26 +184,32 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
visible: false visible: false
}) })
} }
hintEditor.setValue(vm.hint); avalon.vmodels.contestProblemHintEditor.content = problem.hint;
descriptionEditor.setValue(vm.description); $.ajax({
url: "/api/admin/test_case_upload/?test_case_id=" + vm.testCaseId,
method: "get",
dataType: "json",
success: function(response){
if(response.code){
bsAlert(response.data);
}
else {
vm.testCaseList = [];
for (var key in response.data.file_list) {
vm.testCaseList.push({
input: response.data.file_list[key].input_name,
output: response.data.file_list[key].output_name
})
}
vm.uploadSuccess = true;
}
}
})
} }
} }
}); });
}
else { //Create new problem Set default values
vm.testCaseList = [];
vm.title = "";
vm.timeLimit = 1000;
vm.memoryLimit = 256;
vm.samples = [];
vm.visible = true;
vm.inputDescription = "";
vm.outputDescription = "";
vm.testCaseId = "";
vm.sortIndex = "";
vm.score = 0;
hintEditor.setValue("");
descriptionEditor.setValue("");
} }
}); });
avalon.scan(); avalon.scan();

View File

@ -1,88 +0,0 @@
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();
});

View File

@ -135,11 +135,11 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
vm.testCaseId = response.data.test_case_id; vm.testCaseId = response.data.test_case_id;
vm.uploadSuccess = true; vm.uploadSuccess = true;
vm.testCaseList = []; vm.testCaseList = [];
for (var i = 0; i < response.data.file_list.input.length; i++) { for(var key in response.data.file_list){
vm.testCaseList.push({ vm.testCaseList.push({
input: response.data.file_list.input[i], input: response.data.file_list[key].input_name,
output: response.data.file_list.output[i] output: response.data.file_list[key].output_name
}); })
} }
bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据"); bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据");
} }

View File

@ -137,11 +137,11 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
vm.testCaseId = response.data.test_case_id; vm.testCaseId = response.data.test_case_id;
vm.uploadSuccess = true; vm.uploadSuccess = true;
vm.testCaseList = []; vm.testCaseList = [];
for (var i = 0; i < response.data.file_list.input.length; i++) { for(var key in response.data.file_list){
vm.testCaseList.push({ vm.testCaseList.push({
input: response.data.file_list.input[i], input: response.data.file_list[key].input_name,
output: response.data.file_list.output[i] output: response.data.file_list[key].output_name
}); })
} }
bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据"); bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据");
} }

View File

@ -2,7 +2,7 @@
<form id="edit-problem-form"> <form id="edit-problem-form">
<nav> <nav>
<ul class="pager"> <ul class="pager">
<li class="previous" ms-click="goBack(0)"><a href="javascript:void(0)"><span <li class="previous" ms-click="goBack()"><a href="javascript:void(0)"><span
aria-hidden="true">&larr;</span> 返回</a></li> aria-hidden="true">&larr;</span> 返回</a></li>
</ul> </ul>
</nav> </nav>
@ -22,15 +22,14 @@
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>题目描述</label> <label>题目描述</label>
<textarea id="problemDescription" placeholder="这里输入内容(此内容不能为空)" ms-duplex="description"></textarea> <ms:editor $id="contestProblemDescriptionEditor" config="contestProblemDescriptionEditor"></ms:editor>
<p class="error-info" ms-visible="description==''">请填写题目描述</p>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="form-group"><label>时间限制(ms)</label> <div class="form-group"><label>时间限制(ms)</label>
<input type="number" name="timeLimit" class="form-control" ms-duplex="timeLimit" <input type="number" name="timeLimit" class="form-control" ms-duplex="timeLimit"
data-error="请输入时间限制(保证是一个1000-5000的合法整数)" required> data-error="请输入时间限制(保证是一个30-5000的合法整数)" required>
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
</div> </div>
@ -41,11 +40,6 @@
<div class="help-block with-errors"></div> <div class="help-block with-errors"></div>
</div> </div>
</div> </div>
<div class="col-md-3" ms-visible="contestMode=='2'">
<div class="form-group"><label>分值(仅计分模式)</label>
<input type="number" name="score" class="form-control" ms-duplex="score">
</div>
</div>
<div class="col-md-3 form-group"> <div class="col-md-3 form-group">
<label>是否可见</label><br> <label>是否可见</label><br>
<label><input type="checkbox" ms-duplex-checked="visible"> <label><input type="checkbox" ms-duplex-checked="visible">
@ -103,7 +97,7 @@
</div> </div>
</div> </div>
<div class="col-md-12"><br> <div class="col-md-12"><br>
<label>测试数据(多次上传将覆盖原有测试用例)</label><br> <label>测试数据<span ms-if="uploadSuccess">(当前已上传,继续上传将覆盖原有测试用例)</span></label><br>
<small class="text-info">请将所有测试用例打包在一个文件中上传所有文件要在压缩包的根目录且输入输出文件名要以从1开始连续数字标识要对应例如<br> <small class="text-info">请将所有测试用例打包在一个文件中上传所有文件要在压缩包的根目录且输入输出文件名要以从1开始连续数字标识要对应例如<br>
1.in 1.out 2.in 2.out 1.in 1.out 2.in 2.out
</small> </small>
@ -127,7 +121,7 @@
</div> </div>
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>提示</label> <label>提示</label>
<textarea id="hint" placeholder="这里输入内容" ms-duplex="hint"></textarea> <ms:editor $id="contestProblemHintEditor" config="contestProblemHintEditor"></ms:editor>
</div> </div>
<div class="col-md-12"> <div class="col-md-12">
<button type="submit" class="btn btn-success btn-lg">发布题目</button> <button type="submit" class="btn btn-success btn-lg">发布题目</button>

View File

@ -0,0 +1,34 @@
<div ms-controller="contestProblemList" class="col-md-9">
<nav>
<ul class="pager">
<li class="previous" ms-click="goBack()"><a href="javascript:void(0)">
<span aria-hidden="true">&larr;</span> 返回</a>
</li>
</ul>
</nav>
<h1>比赛题目列表</h1>
<div>
<button class="btn btn-primary" ms-click="addProblem()">创建题目</button>
</div>
<table class="table table-striped">
<tr>
<th>ID</th>
<th>题目</th>
<th>创建时间</th>
<th>可见</th>
<th>通过次数/提交总数</th>
<td></td>
</tr>
<tr ms-repeat="problemList">
<td>{{ el.sort_index }}</td>
<td>{{ el.title }}</td>
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td ms-text="el.visible?'可见':'不可见'"></td>
<td>{{ el.total_accepted_number }}/{{ el.total_submit_number }}</td>
<td>
<button class="btn-sm btn-info" ms-click="showEditProblemPage(el.id)">编辑</button>
</td>
</tr>
</table>
</div>
<script src="/static/js/app/admin/contest/contestProblemList.js"></script>