[前端-后台]比赛管理,对添加,编辑,列表页面的avalon使用方法做了统一的改变,防止出现页内模板改变但页面不刷新的情况下导致avalon功能间歇性异常的问题,但是代码量变大了一些,还算是整洁.具体是所有页面的avalon只在页面第一次加载的时候初始化,再次加载时只对vm内部变量重新初始化,而不调用avalon.define了[CI SKIP]

This commit is contained in:
esp 2015-08-24 12:36:08 +08:00
parent eb073c8ac9
commit e40f9deccf
7 changed files with 217 additions and 117 deletions

View File

@ -75,6 +75,9 @@ define("admin", ["jquery", "avalon"], function ($, avalon) {
groupId: -1,
problemId: -1,
adminNavList: [],
$contestMode: -1,
$problemId: -1,
$contestId: -1,
hide_loading: function () {
$("#loading-gif").hide();
},
@ -123,9 +126,10 @@ define("admin", ["jquery", "avalon"], function ($, avalon) {
vm.template_url = "template/problem/submission_list.html";
});
vm.$watch("showContestProblemPage", function (problemId, contestId) {
vm.problemId = problemId;
vm.contestId = contestId;
vm.$watch("showContestProblemPage", function (problemId, contestId, contestMode) {
vm.$problemId = problemId;
vm.$contestId = contestId;
vm.$contestMode = contestMode
vm.template_url = "template/contest/edit_problem.html";
});

View File

@ -2,66 +2,81 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date
"validator"],
function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) {
avalon.vmodels.add_contest = null;
//avalon.vmodels.add_contest = null;
$("#add-contest-form").validator().on('submit', function (e) {
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,
start_time: vm.startTime,
end_time: vm.endTime,
visible: false
};
if (vm.choseGroupsList.length == 0) {
bsAlert("你没有选择参赛用户!");
return false;
}
if (vm.choseGroupsList[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.choseGroupsList[i]; i++)
ajaxData.groups.push(parseInt(vm.choseGroupsList[i].id))
}
var ajaxData = {
title: vm.title,
description: vm.description,
mode: vm.mode,
contest_type: 0,
show_rank: vm.showRank,
show_user_submission: vm.showSubmission,
start_time: vm.startTime,
end_time: vm.endTime,
visible: false
};
if (vm.choseGroupList.length == 0) {
bsAlert("你没有选择参赛用户!");
return false;
}
if (vm.choseGroupList[0].id == 0) { //everyone | public contest
if (vm.password) {
ajaxData.password = vm.password;
ajaxData.contest_type = 2;
}
else{
ajaxData.contest_type = 1;
}
}
else { // Add groups info
ajaxData.groups = [];
for (var i = 0; vm.choseGroupList[i]; i++)
ajaxData.groups.push(parseInt(vm.choseGroupList[i].id))
}
console.log(ajaxData);
$.ajax({ // Add contest
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("添加成功!将转到比赛列表页以便为比赛添加问题(注意比赛当前状态为:隐藏)");
location.hash = "#contest/contest_list";
console.log(data);
}
else {
bsAlert(data.data);
console.log(data);
}
console.log(ajaxData);
$.ajax({ // Add contest
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("添加成功!将转到比赛列表页以便为比赛添加问题(注意比赛当前状态为:隐藏)");
vm.title = "";
vm.description = "";
vm.startTime = "";
vm.endTime = "";
vm.password = "";
vm.mode = "";
vm.showRank = false;
vm.showSubmission = false;
vm.group = "-1";
vm.groupList = [];
vm.choseGroupList = [];
vm.passwordUsable = false;
location.hash = "#contest/contest_list";
}
else {
bsAlert(data.data);
console.log(data);
}
}
});
console.log(JSON.stringify(ajaxData));
}
return false;
});
});
console.log(JSON.stringify(ajaxData));
}
return false;
});
editor("#editor");
if (avalon.vmodels.add_contest)
var vm = avalon.vmodels.add_contest;
else
var vm = avalon.define({
$id: "add_contest",
title: "",
@ -74,34 +89,34 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date
showSubmission: false,
group: "-1",
groupList: [],
choseGroupsList: [],
choseGroupList: [],
passwordUsable: false,
addGroup: function() {
if (vm.group == -1) return;
if (vm.groupList[vm.group].id == 0){
vm.passwordUsable = true;
vm.choseGroupsList = [];
vm.choseGroupList = [];
for (var key in vm.groupList){
vm.groupList[key].chose = true;
}
}
vm.groupList[vm.group]. chose = true;
vm.choseGroupsList.push({name:vm.groupList[vm.group].name, index:vm.group, id:vm.groupList[vm.group].id});
vm.choseGroupList.push({name:vm.groupList[vm.group].name, index:vm.group, id:vm.groupList[vm.group].id});
vm.group = -1;
},
removeGroup: function(groupIndex){
if (vm.groupList[vm.choseGroupsList[groupIndex].index].id == 0){
if (vm.groupList[vm.choseGroupList[groupIndex].index].id == 0){
vm.passwordUsable = false;
for (key in vm.groupList){
vm.groupList[key].chose = false;
}
}
vm.groupList[vm.choseGroupsList[groupIndex].index].chose = false;
vm.choseGroupsList.remove(vm.choseGroupsList[groupIndex]);
vm.groupList[vm.choseGroupList[groupIndex].index].chose = false;
vm.choseGroupList.remove(vm.choseGroupList[groupIndex]);
}
});
$.ajax({ // Get current user type
$.ajax({ // Get current user type
url: "/api/user/",
method: "get",
dataType: "json",
@ -109,7 +124,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date
if (!data.code) {
if (data.data.admin_type == 2) { // Is super user
vm.isGlobal = true;
vm.groupList.push({id:0,name:"所有人",chose:false});
vm.groupList.push({id:0,name:"所有人",chose:false});
}
$.ajax({ // Get the group list of current user
beforeSend: csrfTokenHeader,
@ -151,4 +166,4 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date
weekStart: 1,
language: "zh-CN"
});
});
});

View File

@ -2,8 +2,6 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
avalon.ready(function () {
avalon.vmodels.contestList=null;
$("#edit-contest-form").validator().on('submit', function (e) {
if (!e.isDefaultPrevented()){
e.preventDefault();
@ -23,12 +21,15 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
bsAlert("你没有选择参赛用户!");
return false;
}
if (vm.choseGroupList[0].id == 0) //everyone | public contest
if (vm.password == "")
ajaxData.contest_type = 1;
else{
if (vm.choseGroupList[0].id == 0) { //everyone | public contest
if (vm.password) {
ajaxData.password = vm.password;
ajaxData.contest_type = 2;
}
else{
ajaxData.contest_type = 1;
}
}
else { // Add groups info
ajaxData.groups = [];
for (var i = 0; vm.choseGroupList[i]; i++)
@ -61,6 +62,35 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
return false;
});
if(avalon.vmodels.contestList){
// this page has been loaded before, so set the default value
var vm = avalon.vmodels.contestList;
vm.contestList= [];
vm.previousPage= 0;
vm.nextPage= 0;
vm.page= 1;
vm.totalPage= 1;
vm.group= "-1";
vm.groupList= [];
vm.choseGroupList= [];
vm.passwordUsable= false;
vm.keyword= "";
vm.editingContestId= 0;
vm.editTitle= "";
vm.editDescription= "";
vm.editProblemList= [];
vm.editPassword= "";
vm.editStartTime= "";
vm.editEndTime= "";
vm.editMode= "";
vm.editShowRank= false;
vm.editShowSubmission= false;
vm.editProblemList= [];
vm.editVisible= false;
vm.editChoseGroupList= [];
vm.editingProblemContestIndex= 0;
}
else
var vm = avalon.define({
$id: "contestList",
contestList: [],
@ -119,20 +149,34 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
vm.editEndTime = vm.contestList[contestId-1].end_time.substring(0,16).replace("T"," ");
vm.editMode = vm.contestList[contestId-1].mode;
editVisible = vm.contestList[contestId-1].visible;
vm.editChoseGroupList = [];
for (var i = 0; i < vm.contestList[contestId-1].groups.length; i++){
var id = parseInt(vm.contestList[contestId-1].groups[i]);
var index = 0;
for (; vm.groupList[index]; index++) {
if (vm.groupList[index].id == id)
break;
if (vm.contestList[contestId-1].contest_type == 0) { //contest type == 0, contest in group
//Clear the choseGroupList
var stack = [], sp;
for (sp = 0; i < vm.editChoseGroupList.length; sp++){
stack.push(vm.editChoseGroupList[i].index);
}
vm.groupList[index].chose = true;
vm.choseGroupList.push({
name:vm.groupList[i].name,
index:index,
id:id
});
while (sp--){
vm.removeGroup(stack[sp]);
}
for (var i = 0; i < vm.contestList[contestId-1].groups.length; i++){
var id = parseInt(vm.contestList[contestId-1].groups[i]);
var index = 0;
for (; vm.groupList[index]; index++) {
if (vm.groupList[index].id == id)
break;
}
vm.groupList[index].chose = true;
vm.choseGroupList.push({
name:vm.groupList[index].name,
index:index,
id:id
});
}
}
else{
vm.group = "0";
vm.addGroup()//vm.editChoseGroupList = [0]; id 0 is for the group of everyone~
}
vm.editShowRank = vm.contestList[contestId-1].show_rank;
vm.editShowSubmission = vm.contestList[contestId-1].show_user_submission;
@ -145,7 +189,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
vm.editingProblemContestIndex = 0;
return;
}
if (vm.editingContestId&&!confirm("如果继续将丢失保存的信息,是否继续?")){
if (vm.editingContestId&&!confirm("如果继续将丢失保存的信息,是否继续?")){
return;
}
$.ajax({ // Get the problem list of current contest
@ -164,6 +208,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
});
vm.editingContestId = 0;
vm.editingProblemContestIndex = contestId;
vm.editMode = vm.contestList[contestId-1].mode;
},
addGroup: function() {
if (vm.group == -1) return;
@ -175,9 +220,10 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
}
}
vm.groupList[vm.group]. chose = true;
// index of the group is relative. It is related to user
vm.choseGroupList.push({name:vm.groupList[vm.group].name, index:vm.group, id:vm.groupList[vm.group].id});
vm.group = -1;
},
},
removeGroup: function(groupIndex){
if (vm.groupList[vm.choseGroupList[groupIndex].index].id == 0){
vm.passwordUsable = false;
@ -189,16 +235,18 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
vm.choseGroupList.remove(vm.choseGroupList[groupIndex]);
},
add_problem: function () {
vm.$fire("up!showContestProblemPage", 0, vm.contestList[vm.editingProblemContestIndex-1].id);
vm.$fire("up!showContestProblemPage", 0, vm.contestList[vm.editingProblemContestIndex-1].id, vm.editMode);
},
showProblemEditor: function(el) {
console.log(el);
vm.$fire("up!showContestProblemPage", el.id, vm.contestList[vm.editingProblemContestIndex-1].id);
vm.$fire("up!showContestProblemPage", el.id, vm.contestList[vm.editingProblemContestIndex-1].id, vm.editMode);
},
getYesOrNo: function(yORn) {
if (yORn) return "是";
return "否";
}
});
getPageData(1);
vm.editingContestId = 0;
vm.editingProblemContestIndex = 0;
//init time picker
$("#contest_start_time").datetimepicker({
@ -255,7 +303,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
success: function (data) {
if (!data.code) {
if (!data.data.length) {
//bsAlert("您的用户权限只能创建组内比赛,但是您还没有创建过小组");
//this user have no group can use
return;
}
for (var i = 0; i < data.data.length; i++) {
@ -273,7 +321,6 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
}
});
});
avalon.scan();
});

View File

@ -2,7 +2,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) {
avalon.ready(function () {
avalon.vmodels.editProblem = null;
$("#edit-problem-form").validator()
.on('submit', function (e) {
if (!e.isDefaultPrevented()){
@ -38,15 +38,22 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
test_case_id: vm.testCaseId,
hint: vm.hint,
visible: vm.visible,
contest_id: avalon.vmodels.admin.contestId,
contest_id: avalon.vmodels.admin.$contestId,
input_description: vm.inputDescription,
output_description: vm.outputDescription,
sort_index: vm.sortIndex,
};
if (vm.contestMode == '2') {
if (!vm.score) {
bsAlert("请输入有效的分值!")
return false;
}
ajaxData.score = vm.score;
}
var method = "post";
if (avalon.vmodels.admin.problemId) {
if (avalon.vmodels.admin.$problemId) {
method = "put";
ajaxData.id = avalon.vmodels.admin.problemId;
ajaxData.id = avalon.vmodels.admin.$problemId;
}
for (var i = 0; i < vm.samples.$model.length; i++) {
@ -75,6 +82,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
}
});
if (!avalon.vmodels.editProblem)
var vm = avalon.define({
$id: "editProblem",
title: "",
@ -85,12 +93,12 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
hint: "",
sortIndex: "",
visible: true,
//difficulty: 0,
inputDescription: "",
outputDescription: "",
testCaseIdd: "",
contestMode: 0,
score: 1,
uploadSuccess: false,
//source: "",
testCaseList: [],
addSample: function () {
vm.samples.push({input: "", output: "", "visible": true});
@ -114,6 +122,9 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
}
}
});
else
vm = avalon.vmodels.editProblem;
var hintEditor = editor("#hint");
var descriptionEditor = editor("#problemDescription");
var testCaseUploader = uploader("#testCaseFile", "/api/admin/test_case_upload/", function (file, response) {
@ -133,24 +144,31 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
}
});
if (avalon.vmodels.admin.problemId){
vm.contestMode = avalon.vmodels.admin.$contestMode;
if (avalon.vmodels.admin.$problemId){
$.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",
dataType: "json",
success: function (data) {
if (data.code) {
bsAlert(data.data);
}
else {
else { // Edit mode load the problem data
var problem = data.data;
console.log(problem);
vm.sortIndex = problem.sort_index;
vm.title = problem.title;
vm.description = problem.description;
vm.timeLimit = problem.time_limit;
vm.memoryLimit = problem.memory_limit;
vm.testCaseList = [];
vm.sortIndex = problem.sort_index;
vm.title = problem.title;
vm.description = problem.description;
vm.timeLimit = problem.time_limit;
vm.memoryLimit = problem.memory_limit;
vm.hint = problem.hint;
vm.visible = problem.visible;
vm.inputDescription = problem.input_description;
vm.outputDescription = problem.output_description;
vm.score = problem.score;
vm.samples = [];
vm.testCaseId = problem.test_case_id;
for (var i = 0; i < problem.samples.length; i++) {
vm.samples.push({
input: problem.samples[i].input,
@ -158,18 +176,27 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
visible: false
})
}
vm.hint = problem.hint;
vm.visible = problem.visible;
vm.inputDescription = problem.input_description;
vm.outputDescription = problem.output_description;
vm.testCaseId = problem.test_case_id;
vm.source = problem.source;
hintEditor.setValue(vm.hint);
descriptionEditor.setValue(vm.description);
}
}
});
}
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();

View File

@ -57,7 +57,7 @@
</div>
</div>
<div class="col-md-12">
<div ms-repeat="choseGroupsList" class="group-tag" ms-click="removeGroup($index)">{{el.name}}</div>
<div ms-repeat="choseGroupList" class="group-tag" ms-click="removeGroup($index)">{{el.name}}</div>
</div>
<div class="col-md-6">
<label>排名方式</label>

View File

@ -24,8 +24,8 @@
<tr ms-repeat="contestList">
<td>{{ el.id }}</td>
<td>{{ el.title }}</td>
<td>{{ el.show_rank }}</td>
<td>{{ el.visible }}</td>
<td>{{ getYesOrNo(el.show_rank) }}</td>
<td>{{ getYesOrNo(el.visible) }}</td>
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.created_by.username }}</td>
<td>
@ -160,12 +160,14 @@
<tr>
<th>编号</th>
<th>题目</th>
<th ms-visible="editMode=='2'">分值</th>
<th>创建时间</th>
<td></td>
</tr>
<tr ms-repeat="editProblemList">
<td>{{ el.sort_index }}</td>
<td>{{ el.title }}</td>
<td ms-visible="editMode=='2'">{{ el.score}}</td>
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss") }}</td>
<td>
<a href="javascript:void(0)" class="btn-sm btn-info"

View File

@ -41,6 +41,11 @@
<div class="help-block with-errors"></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">
<label>是否可见</label><br>
<label><input type="checkbox" ms-duplex-checked="visible">