mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-12-29 08:32:08 +00:00
初步完成编辑VJ题目的功能
This commit is contained in:
parent
cf2fc9df1a
commit
bbaebc4d70
30
contest/migrations/0014_auto_20160310_1917.py
Normal file
30
contest/migrations/0014_auto_20160310_1917.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.1 on 2016-03-10 11:17
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0013_auto_20151017_1511'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
name='vj_name',
|
||||||
|
field=models.CharField(blank=True, max_length=20, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
name='vj_problem_url',
|
||||||
|
field=models.URLField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
name='test_case_id',
|
||||||
|
field=models.CharField(blank=True, max_length=40, null=True),
|
||||||
|
),
|
||||||
|
]
|
20
contest/migrations/0015_contestproblem_spj.py
Normal file
20
contest/migrations/0015_contestproblem_spj.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.1 on 2016-03-10 12:09
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0014_auto_20160310_1917'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
name='spj',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
20
contest/migrations/0016_contestproblem_vj_problem_id.py
Normal file
20
contest/migrations/0016_contestproblem_vj_problem_id.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.1 on 2016-03-10 12:11
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contest', '0015_contestproblem_spj'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
name='vj_problem_id',
|
||||||
|
field=models.CharField(blank=True, max_length=40, null=True),
|
||||||
|
),
|
||||||
|
]
|
@ -67,6 +67,11 @@ class ContestProblem(AbstractProblem):
|
|||||||
sort_index = models.CharField(max_length=30)
|
sort_index = models.CharField(max_length=30)
|
||||||
# 是否已经公开了题目,防止重复公开
|
# 是否已经公开了题目,防止重复公开
|
||||||
is_public = models.BooleanField(default=False)
|
is_public = models.BooleanField(default=False)
|
||||||
|
spj = models.BooleanField(default=False)
|
||||||
|
# 如果是vj题目才会使用
|
||||||
|
vj_name = models.CharField(max_length=20, blank=True, null=True)
|
||||||
|
vj_problem_id = models.CharField(max_length=40, blank=True, null=True)
|
||||||
|
vj_problem_url = models.URLField(blank=True, null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "contest_problem"
|
db_table = "contest_problem"
|
||||||
|
@ -105,9 +105,26 @@ class EditContestProblemSerializer(serializers.Serializer):
|
|||||||
hint = serializers.CharField(max_length=3000, allow_blank=True)
|
hint = serializers.CharField(max_length=3000, allow_blank=True)
|
||||||
visible = serializers.BooleanField()
|
visible = serializers.BooleanField()
|
||||||
sort_index = serializers.CharField(max_length=30)
|
sort_index = serializers.CharField(max_length=30)
|
||||||
score = serializers.IntegerField(required=False, default=0)
|
|
||||||
|
|
||||||
|
|
||||||
class ContestPasswordVerifySerializer(serializers.Serializer):
|
class ContestPasswordVerifySerializer(serializers.Serializer):
|
||||||
contest_id = serializers.IntegerField()
|
contest_id = serializers.IntegerField()
|
||||||
password = serializers.CharField(max_length=30)
|
password = serializers.CharField(max_length=30)
|
||||||
|
|
||||||
|
|
||||||
|
class CreateContestVJProblemSerializer(serializers.Serializer):
|
||||||
|
contest_id = serializers.IntegerField()
|
||||||
|
oj = serializers.CharField(max_length=30)
|
||||||
|
url = serializers.URLField()
|
||||||
|
|
||||||
|
|
||||||
|
class EditContestVJProblemSerializer(serializers.Serializer):
|
||||||
|
id = serializers.IntegerField()
|
||||||
|
title = serializers.CharField(max_length=50)
|
||||||
|
description = serializers.CharField(max_length=10000)
|
||||||
|
input_description = serializers.CharField(max_length=10000)
|
||||||
|
output_description = serializers.CharField(max_length=10000)
|
||||||
|
samples = ContestProblemSampleSerializer()
|
||||||
|
hint = serializers.CharField(max_length=3000, allow_blank=True)
|
||||||
|
visible = serializers.BooleanField()
|
||||||
|
sort_index = serializers.CharField(max_length=30)
|
@ -1,7 +1,8 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
import redis
|
import logging
|
||||||
|
import requests
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
@ -28,7 +29,11 @@ from .decorators import check_user_contest_permission
|
|||||||
from .serializers import (CreateContestSerializer, ContestSerializer, EditContestSerializer,
|
from .serializers import (CreateContestSerializer, ContestSerializer, EditContestSerializer,
|
||||||
CreateContestProblemSerializer, ContestProblemSerializer,
|
CreateContestProblemSerializer, ContestProblemSerializer,
|
||||||
ContestPasswordVerifySerializer,
|
ContestPasswordVerifySerializer,
|
||||||
EditContestProblemSerializer)
|
EditContestProblemSerializer, CreateContestVJProblemSerializer,
|
||||||
|
EditContestVJProblemSerializer)
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger("app_info")
|
||||||
|
|
||||||
|
|
||||||
class ContestAdminAPIView(APIView):
|
class ContestAdminAPIView(APIView):
|
||||||
@ -278,12 +283,98 @@ class ContestProblemAdminAPIView(APIView):
|
|||||||
return paginate(request, contest_problems, ContestProblemSerializer)
|
return paginate(request, contest_problems, ContestProblemSerializer)
|
||||||
|
|
||||||
|
|
||||||
|
class ContestVJProblemAPIView(APIView):
|
||||||
|
def post(self, request):
|
||||||
|
serializer = CreateContestVJProblemSerializer(data=request.data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
data = serializer.data
|
||||||
|
try:
|
||||||
|
contest = Contest.objects.get(id=data["contest_id"])
|
||||||
|
if request.user.admin_type != SUPER_ADMIN:
|
||||||
|
contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all())
|
||||||
|
if contest not in contest_set:
|
||||||
|
return error_response(u"比赛不存在")
|
||||||
|
except Contest.DoesNotExist:
|
||||||
|
return error_response(u"比赛不存在")
|
||||||
|
|
||||||
|
url = "http://127.0.0.1:8000/problem/?oj=%s&url=%s" % (data["oj"], data["url"])
|
||||||
|
try:
|
||||||
|
r = requests.get(url).json()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Exception %s when fetching url: %s" % (str(e), url))
|
||||||
|
return error_response(u"请求VJ API失败")
|
||||||
|
if r["code"] == 0:
|
||||||
|
# 爬取完成
|
||||||
|
if r["data"]["status"] == 0:
|
||||||
|
vj_problem = r["data"]
|
||||||
|
try:
|
||||||
|
ContestProblem.objects.get(contest=contest, vj_problem_id=vj_problem["id"])
|
||||||
|
return error_response(u"该VJ题目已经存在")
|
||||||
|
except ContestProblem.DoesNotExist:
|
||||||
|
pass
|
||||||
|
ContestProblem.objects.create(contest=contest,
|
||||||
|
title=vj_problem["title"],
|
||||||
|
description=vj_problem["description"],
|
||||||
|
input_description=vj_problem["input_description"],
|
||||||
|
output_description=vj_problem["output_description"],
|
||||||
|
samples=json.dumps(vj_problem["samples"]),
|
||||||
|
time_limit=vj_problem["time_limit"],
|
||||||
|
memory_limit=vj_problem["memory_limit"],
|
||||||
|
created_by=request.user,
|
||||||
|
is_public=True,
|
||||||
|
spj=vj_problem["spj"],
|
||||||
|
hint=vj_problem["hint"],
|
||||||
|
sort_index="_vj", vj_name=data["oj"],
|
||||||
|
vj_problem_id=vj_problem["id"],
|
||||||
|
vj_problem_url=data["url"])
|
||||||
|
return success_response(r)
|
||||||
|
# 正在爬取
|
||||||
|
elif r["data"]["status"] == 1:
|
||||||
|
return success_response({"status": 1})
|
||||||
|
# 失败
|
||||||
|
elif r["data"]["status"] == 2:
|
||||||
|
return error_response(u"VJ 题目爬取失败")
|
||||||
|
else:
|
||||||
|
logger.error("VJ API return %s" % json.dumps(r))
|
||||||
|
return error_response(u"请求VJ API失败, 返回信息: " + r["data"])
|
||||||
|
else:
|
||||||
|
return serializer_invalid_response(serializer)
|
||||||
|
|
||||||
|
def put(self, request):
|
||||||
|
serializer = EditContestVJProblemSerializer(data=request.data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
data = serializer.data
|
||||||
|
|
||||||
|
try:
|
||||||
|
contest_problem = ContestProblem.objects.get(id=data["id"])
|
||||||
|
except ContestProblem.DoesNotExist:
|
||||||
|
return error_response(u"该比赛题目不存在!")
|
||||||
|
contest = Contest.objects.get(id=contest_problem.contest_id)
|
||||||
|
if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user:
|
||||||
|
return error_response(u"比赛不存在")
|
||||||
|
contest_problem.title = data["title"]
|
||||||
|
contest_problem.description = data["description"]
|
||||||
|
contest_problem.input_description = data["input_description"]
|
||||||
|
contest_problem.output_description = data["output_description"]
|
||||||
|
contest_problem.samples = json.dumps(data["samples"])
|
||||||
|
contest_problem.hint = data["hint"]
|
||||||
|
contest_problem.visible = data["visible"]
|
||||||
|
contest_problem.sort_index = data["sort_index"]
|
||||||
|
contest_problem.last_update_time = now()
|
||||||
|
contest_problem.save()
|
||||||
|
return success_response(ContestProblemSerializer(contest_problem).data)
|
||||||
|
else:
|
||||||
|
return serializer_invalid_response(serializer)
|
||||||
|
|
||||||
|
|
||||||
class MakeContestProblemPublicAPIView(APIView):
|
class MakeContestProblemPublicAPIView(APIView):
|
||||||
@super_admin_required
|
@super_admin_required
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
problem_id = request.data.get("problem_id", -1)
|
problem_id = request.data.get("problem_id", -1)
|
||||||
try:
|
try:
|
||||||
problem = ContestProblem.objects.get(id=problem_id)
|
problem = ContestProblem.objects.get(id=problem_id)
|
||||||
|
if problem.is_public:
|
||||||
|
return error_response(u"题目已经公开")
|
||||||
problem.is_public = True
|
problem.is_public = True
|
||||||
problem.save()
|
problem.save()
|
||||||
except ContestProblem.DoesNotExist:
|
except ContestProblem.DoesNotExist:
|
||||||
@ -296,8 +387,6 @@ class MakeContestProblemPublicAPIView(APIView):
|
|||||||
hint=problem.hint, created_by=problem.created_by,
|
hint=problem.hint, created_by=problem.created_by,
|
||||||
time_limit=problem.time_limit, memory_limit=problem.memory_limit,
|
time_limit=problem.time_limit, memory_limit=problem.memory_limit,
|
||||||
visible=False, difficulty=-1, source=problem.contest.title)
|
visible=False, difficulty=-1, source=problem.contest.title)
|
||||||
problem.is_public = True
|
|
||||||
problem.save()
|
|
||||||
return success_response(u"创建成功")
|
return success_response(u"创建成功")
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ from announcement.views import AnnouncementAdminAPIView
|
|||||||
|
|
||||||
from contest.views import (ContestAdminAPIView, ContestProblemAdminAPIView,
|
from contest.views import (ContestAdminAPIView, ContestProblemAdminAPIView,
|
||||||
ContestPasswordVerifyAPIView, ContestTimeAPIView,
|
ContestPasswordVerifyAPIView, ContestTimeAPIView,
|
||||||
MakeContestProblemPublicAPIView)
|
MakeContestProblemPublicAPIView, ContestVJProblemAPIView)
|
||||||
|
|
||||||
from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView,
|
from group.views import (GroupAdminAPIView, GroupMemberAdminAPIView,
|
||||||
JoinGroupAPIView, JoinGroupRequestAdminAPIView, GroupPrometAdminAPIView)
|
JoinGroupAPIView, JoinGroupRequestAdminAPIView, GroupPrometAdminAPIView)
|
||||||
@ -65,6 +65,7 @@ urlpatterns = [
|
|||||||
|
|
||||||
url(r'^api/admin/problem/$', ProblemAdminAPIView.as_view(), name="problem_admin_api"),
|
url(r'^api/admin/problem/$', ProblemAdminAPIView.as_view(), name="problem_admin_api"),
|
||||||
url(r'^api/admin/contest_problem/$', ContestProblemAdminAPIView.as_view(), name="contest_problem_admin_api"),
|
url(r'^api/admin/contest_problem/$', ContestProblemAdminAPIView.as_view(), name="contest_problem_admin_api"),
|
||||||
|
url(r'^api/admin/contest_vj_problem/$', ContestVJProblemAPIView.as_view(), name="contest_vj_problem_admin_api"),
|
||||||
url(r'^api/admin/contest_problem/public/', MakeContestProblemPublicAPIView.as_view(),
|
url(r'^api/admin/contest_problem/public/', MakeContestProblemPublicAPIView.as_view(),
|
||||||
name="make_contest_problem_public"),
|
name="make_contest_problem_public"),
|
||||||
url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"),
|
url(r'^api/admin/test_case_upload/$', TestCaseUploadAPIView.as_view(), name="test_case_upload_api"),
|
||||||
|
@ -24,7 +24,7 @@ class AbstractProblem(models.Model):
|
|||||||
# 样例输入 可能会存储 json 格式的数据
|
# 样例输入 可能会存储 json 格式的数据
|
||||||
samples = models.TextField(blank=True)
|
samples = models.TextField(blank=True)
|
||||||
# 测试用例id 这个id 可以用来拼接得到测试用例的文件存储位置
|
# 测试用例id 这个id 可以用来拼接得到测试用例的文件存储位置
|
||||||
test_case_id = models.CharField(max_length=40)
|
test_case_id = models.CharField(max_length=40, blank=True, null=True)
|
||||||
# 提示
|
# 提示
|
||||||
hint = RichTextField(blank=True, null=True)
|
hint = RichTextField(blank=True, null=True)
|
||||||
# 创建时间
|
# 创建时间
|
||||||
|
@ -25,21 +25,23 @@ require(["jquery", "avalon", "csrfToken", "bsAlert"], function ($, avalon, csrfT
|
|||||||
},
|
},
|
||||||
|
|
||||||
makeProblemPublic: function(problem){
|
makeProblemPublic: function(problem){
|
||||||
$.ajax({
|
if(confirm("您确定要公开题目么? 请勿在比赛未结束的时候公开题目。")) {
|
||||||
url: "/api/admin/contest_problem/public/",
|
$.ajax({
|
||||||
method: "post",
|
url: "/api/admin/contest_problem/public/",
|
||||||
dataType: "json",
|
method: "post",
|
||||||
data: {"problem_id": problem.id},
|
dataType: "json",
|
||||||
success: function(response){
|
data: {"problem_id": problem.id},
|
||||||
if(response.code){
|
success: function (response) {
|
||||||
bsAlert(response.data);
|
if (response.code) {
|
||||||
|
bsAlert(response.data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
problem.is_public = true;
|
||||||
|
bsAlert("公开题目成功,现在处于隐藏状态,请添加标签难度等信息。");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{
|
})
|
||||||
problem.is_public = true;
|
}
|
||||||
alert("公开题目成功,现在处于隐藏状态,请添加标签难度等信息。");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -107,10 +107,9 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
if (!data.data.length) {
|
if (!data.data.length && admin_type != 2) {
|
||||||
if (admin_type != 2)
|
|
||||||
bsAlert("您的用户权限只能创建小组内比赛,但是您还没有创建过小组");
|
bsAlert("您的用户权限只能创建小组内比赛,但是您还没有创建过小组");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vm.allGroups = [];
|
vm.allGroups = [];
|
||||||
for (var i = 0; i < data.data.length; i++) {
|
for (var i = 0; i < data.data.length; i++) {
|
||||||
|
@ -8,18 +8,25 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
|
|||||||
.on('submit', function (e) {
|
.on('submit', function (e) {
|
||||||
if (!e.isDefaultPrevented()) {
|
if (!e.isDefaultPrevented()) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!avalon.vmodels.testCaseUploader.uploaded) {
|
if(!vm.isVJ) {
|
||||||
bsAlert("你还没有上传测试数据!");
|
if (!avalon.vmodels.testCaseUploader.uploaded) {
|
||||||
return false;
|
bsAlert("你还没有上传测试数据!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (vm.timeLimit < 30 || vm.timeLimit > 5000) {
|
||||||
|
bsAlert("保证时间限制是一个30-5000的合法整数");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (vm.memoryLimit < 32) {
|
||||||
|
bsAlert("内存不得小于32M");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (avalon.vmodels.contestProblemDescriptionEditor.content == "") {
|
if (avalon.vmodels.contestProblemDescriptionEditor.content == "") {
|
||||||
bsAlert("题目描述不能为空!");
|
bsAlert("题目描述不能为空!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (vm.timeLimit < 30 || vm.timeLimit > 5000) {
|
|
||||||
bsAlert("保证时间限制是一个30-5000的合法整数");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (vm.samples.length == 0) {
|
if (vm.samples.length == 0) {
|
||||||
bsAlert("请至少添加一组样例!");
|
bsAlert("请至少添加一组样例!");
|
||||||
return false;
|
return false;
|
||||||
@ -55,6 +62,13 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
|
|||||||
var alertContent = "题目创建成功";
|
var alertContent = "题目创建成功";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(vm.isVJ) {
|
||||||
|
var url = "/api/admin/contest_vj_problem/";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var url = "/api/admin/contest_problem/";
|
||||||
|
}
|
||||||
|
|
||||||
for (var i = 0; i < vm.samples.$model.length; i++) {
|
for (var i = 0; i < vm.samples.$model.length; i++) {
|
||||||
ajaxData.samples.push({
|
ajaxData.samples.push({
|
||||||
input: vm.samples.$model[i].input,
|
input: vm.samples.$model[i].input,
|
||||||
@ -64,7 +78,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
|
|||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
beforeSend: csrfTokenHeader,
|
beforeSend: csrfTokenHeader,
|
||||||
url: "/api/admin/contest_problem/",
|
url: url,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: JSON.stringify(ajaxData),
|
data: JSON.stringify(ajaxData),
|
||||||
method: method,
|
method: method,
|
||||||
@ -99,6 +113,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
|
|||||||
outputDescription: "",
|
outputDescription: "",
|
||||||
testCaseId: "",
|
testCaseId: "",
|
||||||
testCaseList: [],
|
testCaseList: [],
|
||||||
|
isVJ: false,
|
||||||
|
|
||||||
contestProblemDescriptionEditor: {
|
contestProblemDescriptionEditor: {
|
||||||
editorId: "contest-problem-description-editor",
|
editorId: "contest-problem-description-editor",
|
||||||
@ -147,6 +162,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
|
|||||||
vm.outputDescription = "";
|
vm.outputDescription = "";
|
||||||
vm.testCaseId = "";
|
vm.testCaseId = "";
|
||||||
vm.testCaseList = [];
|
vm.testCaseList = [];
|
||||||
|
vm.isVJ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avalon.vmodels.admin.contestProblemStatus == "edit") {
|
if (avalon.vmodels.admin.contestProblemStatus == "edit") {
|
||||||
@ -170,8 +186,11 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert",
|
|||||||
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.isVJ = problem.test_case_id == null;
|
||||||
avalon.vmodels.testCaseUploader.setTestCase(problem.test_case_id);
|
// vj题目不需要上传数据
|
||||||
|
if (!vm.isVJ) {
|
||||||
|
avalon.vmodels.testCaseUploader.setTestCase(problem.test_case_id);
|
||||||
|
}
|
||||||
vm.samples = [];
|
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({
|
||||||
|
@ -29,14 +29,15 @@
|
|||||||
<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="请输入时间限制(保证是一个30-5000的合法整数)" required>
|
data-error="请输入时间限制(保证是一个30-5000的合法整数)" required ms-attr-disabled="isVJ">
|
||||||
<div class="help-block with-errors"></div>
|
<div class="help-block with-errors"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="form-group"><label>内存限制(MB)</label>
|
<div class="form-group"><label>内存限制(MB)</label>
|
||||||
<input type="number" name="memory" class="form-control" ms-duplex="memoryLimit"
|
<input type="number" name="memory" class="form-control"
|
||||||
data-error="请输入内存限制(保证是一个合法整数)" required>
|
title="非VJ的题目内存低于512M可能会造成Java代码无法启动" ms-duplex="memoryLimit"
|
||||||
|
data-error="请输入内存限制(保证是一个合法整数)" required ms-attr-disabled="isVJ">
|
||||||
<div class="help-block with-errors"></div>
|
<div class="help-block with-errors"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -96,7 +97,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ms:testcaseuploader $id="testCaseUploader"></ms:testcaseuploader>
|
<div ms-if="!isVJ">
|
||||||
|
<ms:testcaseuploader $id="testCaseUploader"></ms:testcaseuploader>
|
||||||
|
</div>
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
<label>提示</label>
|
<label>提示</label>
|
||||||
<ms:editor $id="contestProblemHintEditor" config="contestProblemHintEditor"></ms:editor>
|
<ms:editor $id="contestProblemHintEditor" config="contestProblemHintEditor"></ms:editor>
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ms-repeat="problemList">
|
<tr ms-repeat="problemList">
|
||||||
<td>{{ el.sort_index }}</td>
|
<td><span ms-if="el.vj_name" class="glyphicon glyphicon-send" title="Virtual Judge"></span> {{ el.sort_index }}</td>
|
||||||
<td>{{ el.title }}</td>
|
<td>{{ el.title }}</td>
|
||||||
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
|
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
|
||||||
<td ms-text="el.visible?'可见':'不可见'"></td>
|
<td ms-text="el.visible?'可见':'不可见'"></td>
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
<div class="problem-section">
|
<div class="problem-section">
|
||||||
<label class="problem-label">输入</label>
|
<label class="problem-label">输入</label>
|
||||||
|
|
||||||
<p class="problem-detail">{{ problem.input_description }}</p>
|
<p class="problem-detail">{{ problem.input_description|linebreaksbr }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="problem-section">
|
<div class="problem-section">
|
||||||
<label class="problem-label">输出</label>
|
<label class="problem-label">输出</label>
|
||||||
|
|
||||||
<p class="problem-detail">{{ problem.output_description }}</p>
|
<p class="problem-detail">{{ problem.output_description|linebreaksbr }}</p>
|
||||||
</div>
|
</div>
|
||||||
{% for item in samples %}
|
{% for item in samples %}
|
||||||
<div class="problem-section">
|
<div class="problem-section">
|
||||||
|
Loading…
Reference in New Issue
Block a user