修改 js 的命名风格

This commit is contained in:
virusdefender 2015-08-15 13:54:30 +08:00
parent d031f14a68
commit 025335b40a
50 changed files with 1403 additions and 896 deletions

View File

@ -33,8 +33,14 @@ class CreateProblemSerializer(serializers.Serializer):
hint = serializers.CharField(max_length=3000, required=False, default=None)
class ProblemTagSerializer(serializers.ModelSerializer):
class Meta:
model = ProblemTag
class ProblemSerializer(serializers.ModelSerializer):
samples = JSONField()
tags = ProblemTagSerializer(many=True)
class UserSerializer(serializers.ModelSerializer):
class Meta:
@ -58,17 +64,11 @@ class EditProblemSerializer(serializers.Serializer):
time_limit = serializers.IntegerField()
memory_limit = serializers.IntegerField()
difficulty = serializers.IntegerField()
tags = serializers.ListField(child=serializers.IntegerField())
tags = serializers.ListField(child=serializers.CharField(max_length=20))
samples = ProblemSampleSerializer()
hint = serializers.CharField(max_length=10000)
visible = serializers.BooleanField()
class ProblemTagSerializer(serializers.ModelSerializer):
class Meta:
model = ProblemTag
class CreateProblemTagSerializer(serializers.Serializer):
name = serializers.CharField(max_length=10)

View File

@ -60,6 +60,7 @@ class ProblemAdminAPIView(APIView):
serializer = CreateProblemSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
print data
problem = Problem.objects.create(title=data["title"],
description=data["description"],
input_description=data["input_description"],
@ -114,20 +115,30 @@ class ProblemAdminAPIView(APIView):
# 删除原有的标签的对应关系
problem.tags.remove(*problem.tags.all())
# 重新添加所有的标签
problem.tags.add(*ProblemTag.objects.filter(id__in=data["tags"]))
for tag in data["tags"]:
try:
tag = ProblemTag.objects.get(name=tag)
except ProblemTag.DoesNotExist:
tag = ProblemTag.objects.create(name=tag)
problem.tags.add(tag)
problem.save()
return success_response(ProblemSerializer(problem).data)
else:
return serializer_invalid_response(serializer)
class ProblemAPIView(APIView):
def get(self, request):
"""
题目分页json api接口
---
response_serializer: ProblemSerializer
"""
problem_id = request.GET.get("problem_id", None)
if problem_id:
try:
problem = Problem.objects.get(id=problem_id)
return success_response(ProblemSerializer(problem).data)
except Problem.DoesNotExist:
return error_response(u"题目不存在")
problem = Problem.objects.all().order_by("-last_update_time")
visible = request.GET.get("visible", None)
if visible:
@ -209,8 +220,7 @@ class TestCaseUploadAPIView(APIView):
file_info["test_cases"][str(i + 1)] = {"input_name": str(i + 1) + ".in",
"output_name": str(i + 1) + ".out",
"output_md5": md5.hexdigest(),
"output_size": os.path.getsize(
test_case_dir + str(i + 1) + ".out")}
"output_size": os.path.getsize(test_case_dir + str(i + 1) + ".out")}
# 写入配置文件
open(test_case_dir + "info", "w").write(json.dumps(file_info))
@ -222,12 +232,28 @@ class TestCaseUploadAPIView(APIView):
def problem_list_page(request, page=1):
# 正常情况
problems = Problem.objects.all()
# 搜索的情况
keyword = request.GET.get("keyword", None)
if keyword:
problems = problems.filter(title__contains=keyword)
# 按照标签筛选
tag_text = request.GET.get("tag", None)
if tag_text:
try:
tag = ProblemTag.objects.get(name=tag_text)
except ProblemTag.DoesNotExist:
return error_page(request, u"标签不存在")
problems = tag.problem_set.all()
paginator = Paginator(problems, 20)
try:
current_page = paginator.page(int(page))
except Exception:
return error_response(u"不存在的页码")
return error_page(request, u"不存在的页码")
previous_page = next_page = None
@ -241,5 +267,7 @@ def problem_list_page(request, page=1):
except Exception:
pass
return render(request, "oj/problem/problem_list.html", {"problems": current_page, "page": int(page),
"previous_page": previous_page, "next_page": next_page})
return render(request, "oj/problem/problem_list.html",
{"problems": current_page, "page": int(page),
"previous_page": previous_page, "next_page": next_page,
"keyword": keyword, "tag": tag_text})

View File

@ -32,4 +32,9 @@
.pie-chart-container{
width: 50%;
float: left;
}
.tag-editor{
border: 1px solid #d9d9d9;
border-top-color: silver;
}

View File

@ -28,4 +28,8 @@ label {
[ms-controller] {
display: none
}
.right{
float: right;
}

View File

@ -24,17 +24,23 @@ define("admin", ["jquery", "avalon"], function ($, avalon) {
var vm = avalon.define({
$id: "admin",
template_url: "template/" + hash + ".html",
group_id: -1,
groupId: -1,
problemId: -1,
hide_loading: function () {
$("#loading-gif").hide();
}
});
vm.$watch("showGroupDetailPage", function(group_id){
vm.group_id = group_id;
vm.$watch("showGroupDetailPage", function(groupId){
vm.groupId = groupId;
vm.template_url = "template/group/group_detail.html";
});
vm.$watch("showEditProblemPage", function(problemId){
vm.problemId = problemId;
vm.template_url = "template/problem/edit_problem.html";
});
avalon.scan();
li_active("#li-" + hash.replace("/", "-"));

View File

@ -1,171 +1,166 @@
require(["jquery", "avalon", "csrf", "bs_alert", "editor", "validation"], function ($, avalon, csrfHeader, bs_alert, editor) {
require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "formValidation"],
function ($, avalon, csrfTokenHeader, bsAlert, editor) {
avalon.vmodels.announcement = null;
// avalon:定义模式 announcement
avalon.ready(function () {
var announcementEditor = editor("#editor"); //创建新建公告的内容编辑器
var editAnnouncementEditor = editor("#editAnnouncementEditor");
avalon.ready(function () {
avalon.vmodels.announcement = null;
var vm = avalon.define({
$id: "announcement",
//通用变量
announcement: [], // 公告列表数据项
previous_page: 0, // 之前的页数
next_page: 0, // 之后的页数
page: 1, // 当前页数
isEditing: 0, // 正在编辑的公告的ID 为零说明未在编辑
page_count: 1, // 总页数
visableOnly: false, //仅显示可见公告
// 编辑
announcementVisible: 0,
getState: function (el) { //获取公告当前状态,显示
if (el.visible)
return "可见";
else
return "隐藏";
},
getNext: function () {
if (!vm.next_page)
return;
getPageData(vm.page + 1);
},
getPrevious: function () {
if (!vm.previous_page)
return;
getPageData(vm.page - 1);
},
getBtnClass: function (btn) { //上一页/下一页按钮启用禁用逻辑
if (btn) {
return vm.next_page ? "btn btn-primary" : "btn btn-primary disabled";
}
else {
return vm.previous_page ? "btn btn-primary" : "btn btn-primary disabled";
}
var createAnnouncementEditor = editor("#create-announcement-editor");
var editAnnouncementEditor = editor("#edit-announcement-editor");
},
enEdit: function (el) { //点击编辑按钮的事件,显示/隐藏编辑区
$("#newTitle").val(el.title);
editAnnouncementEditor.setValue(el.content);
vm.announcementVisible = el.visible;
if (vm.isEditing == el.id)
vm.isEditing = 0;
else
vm.isEditing = el.id;
editAnnouncementEditor.focus();
},
disEdit: function () { //收起编辑框
vm.isEditing = 0;
},
submitChange: function () { // 处理编辑公告提交事件,顺便验证字段为空
var title = $("#newTitle").val(), content = editAnnouncementEditor.getValue();
if (title != "") {
if (content != "") {
$.ajax({ //发送修改公告请求
beforeSend: csrfHeader,
var vm = avalon.define({
$id: "announcement",
//通用变量
announcementList: [], // 公告列表数据项
previousPage: 0, // 之前的页数
nextPage: 0, // 之后的页数
page: 1, // 当前页数
editingAnnouncementId: 0, // 正在编辑的公告的ID 为零说明未在编辑
totalPage: 1, // 总页数
showVisibleOnly: false, //仅显示可见公告
// 编辑
announcementVisible: 0,
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) {
$("#newTitle").val(announcement.title);
editAnnouncementEditor.setValue(announcement.content);
vm.announcementVisible = announcement.visible;
if (vm.editingAnnouncementId == announcement.id)
vm.editingAnnouncementId = 0;
else
vm.editingAnnouncementId = announcement.id;
editAnnouncementEditor.focus();
},
cancelEdit: function () {
vm.editingAnnouncementId = 0;
},
submitChange: function () {
var title = $("#newTitle").val();
var content = editAnnouncementEditor.getValue();
if (content && title) {
$.ajax({
beforeSend: csrfTokenHeader,
url: "/api/admin/announcement/",
dataType: "json",
method: "put",
data: {
id: vm.isEditing,
id: vm.editingAnnouncementId,
title: title,
content: content,
visible: vm.announcementVisible
},
success: function (data) {
if (!data.code) {
bs_alert("修改成功");
vm.isEditing = 0;
bsAlert("修改成功");
vm.editingAnnouncementId = 0;
getPageData(1);
}
else {
bs_alert(data.data);
bsAlert(data.data);
}
}
});
}
else
bs_alert("公告内容不得为空");
}
else
bs_alert("公告标题不能为空");
}
});
vm.$watch("visableOnly", function () {
getPageData(1);
});
avalon.scan();
getPageData(1); //公告列表初始化
//Ajax get数据
function getPageData(page) {
var visible = '';
if (vm.visableOnly == true)
visible = "&visible=true";
$.ajax({
beforeSend: csrfHeader,
url: "/api/announcements/?paging=true&page=" + page + "&page_size=10" + visible,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.announcement = data.data.results;
vm.page_count = data.data.total_page;
vm.previous_page = data.data.previous_page;
vm.next_page = data.data.next_page;
vm.page = page;
}
else {
bs_alert(data.data);
bsAlert("标题和公告内容不得为空");
}
}
});
}
vm.$watch("showVisibleOnly", function () {
getPageData(1);
});
//新建公告表单验证与数据提交
$("#announcement-form")
.formValidation({
framework: "bootstrap",
fields: {
title: {
validators: {
notEmpty: {
message: "请填写公告标题"
getPageData(1);
function getPageData(page) {
var url = "/api/announcements/?paging=true&page=" + page + "&page_size=10";
if (vm.showVisibleOnly)
url += "&visible=true";
$.ajax({
url: url,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.announcementList = 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 {
bs_alert(data.data);
}
}
});
}
//新建公告表单验证与数据提交
$("#announcement-form")
.formValidation({
framework: "bootstrap",
fields: {
title: {
validators: {
notEmpty: {
message: "请填写公告标题"
}
}
}
}
}
}
).on('success.form.fv', function (e) {
e.preventDefault();
var title = $("#title").val();
var content = announcementEditor.getValue();
if (content == "") {
bs_alert("请填写公告内容");
return;
}
$.ajax({
beforeSend: csrfHeader,
url: "/api/admin/announcement/",
data: {title: title, content: content},
dataType: "json",
method: "post",
success: function (data) {
if (!data.code) {
bs_alert("提交成功!");
$("#title").val("");
announcementEditor.setValue("");
getPageData(1);
} else {
bs_alert(data.data);
}
).on('success.form.fv', function (e) {
e.preventDefault();
var title = $("#title").val();
var content = createAnnouncementEditor.getValue();
if (content == "") {
bsAlert("请填写公告内容");
return;
}
})
});
});
});
$.ajax({
beforeSend: csrfTokenHeader,
url: "/api/admin/announcement/",
data: {title: title, content: content},
dataType: "json",
method: "post",
success: function (data) {
if (!data.code) {
bsAlert("提交成功!");
$("#title").val("");
createAnnouncementEditor.setValue("");
getPageData(1);
} else {
bs_alert(data.data);
}
}
})
});
});
avalon.scan();
});

View File

@ -1,73 +1,74 @@
require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, avalon, csrfHeader, bs_alert) {
avalon.vmodels.group = null;
require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) {
// avalon:定义模式 group_list
avalon.ready(function () {
avalon.vmodels.group = null;
var vm = avalon.define({
$id: "group",
//通用变量
group_list: [], // 用户列表数据项
previous_page: 0, // 之前的页数
next_page: 0, // 之后的页数
groupList: [], // 用户列表数据项
previousPage: 0, // 之前的页数
nextPage: 0, // 之后的页数
page: 1, // 当前页数
page_count: 1, // 总页数
totalPage: 1, // 总页数
keyword: "",
getNext: function () {
if (!vm.next_page)
if (!vm.nextPage)
return;
getPageData(vm.page + 1);
},
getPrevious: function () {
if (!vm.previous_page)
if (!vm.previousPage)
return;
getPageData(vm.page - 1);
},
getBtnClass: function (btn) { //上一页/下一页按钮启用禁用逻辑
if (btn) {
return vm.next_page ? "btn btn-primary" : "btn btn-primary disabled";
getBtnClass: function (btnType) {
if (btnType == "next") {
return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled";
}
else {
return vm.previous_page ? "btn btn-primary" : "btn btn-primary disabled";
return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled";
}
},
getPage: function (page_index) {
getPageData(page_index);
search: function(){
getPageData(1);
},
getGroupSettingString: function(setting){
getGroupSettingString: function (setting) {
return {0: "允许任何人加入", 1: "提交请求后管理员审核", 2: "不允许任何人加入"}[setting]
},
showGroupDetailPage: function(group_id){
vm.$fire("up!showGroupDetailPage", group_id);
showGroupDetailPage: function (groupId) {
vm.$fire("up!showGroupDetailPage", groupId);
}
});
getPageData(1);
avalon.scan();
getPageData(1); //用户列表初始化
//Ajax get数据
function getPageData(page) {
var url = "/api/admin/group/?paging=true&page=" + page + "&page_size=10";
if (vm.keyword != "")
if (vm.keyword)
url += "&keyword=" + vm.keyword;
$.ajax({
beforeSend: csrfHeader,
url: url,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.group_list = data.data.results;
vm.page_count = data.data.total_page;
vm.previous_page = data.data.previous_page;
vm.next_page = data.data.next_page;
vm.groupList = 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 {
bs_alert(data.data);
bsAlert(data.data);
}
}
});
}
});
avalon.scan();
});

View File

@ -1,51 +1,50 @@
require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, avalon, csrfHeader, bs_alert) {
avalon.vmodels.group_detail = null;
require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) {
// avalon:定义模式 group_list
avalon.ready(function () {
avalon.vmodels.groupDetail = null;
var vm = avalon.define({
$id: "group_detail",
$id: "groupDetail",
//通用变量
member_list: [],
previous_page: 0,
next_page: 0,
memberList: [],
previousPage: 0,
nextPage: 0,
page: 1,
page_count: 1,
totalPage: 1,
name: "",
description: "",
checked_setting: "0",
checkedSetting: "0",
getNext: function () {
if (!vm.next_page)
if (!vm.nextPage)
return;
getPageData(vm.page + 1);
},
getPrevious: function () {
if (!vm.previous_page)
if (!vm.previousPage)
return;
getPageData(vm.page - 1);
},
getBtnClass: function (btn) {
if (btn) {
return vm.next_page ? "btn btn-primary" : "btn btn-primary disabled";
if (btn == "next") {
return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled";
}
else {
return vm.previous_page ? "btn btn-primary" : "btn btn-primary disabled";
return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled";
}
},
getPage: function (page_index) {
getPageData(page_index);
},
removeMember: function (relation) {
$.ajax({
beforeSend: csrfHeader,
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.member_list.remove(relation);
bs_alert(data.data);
vm.memberList.remove(relation);
bsAlert(data.data);
}
})
}
@ -55,90 +54,90 @@ require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, ava
getPageData(1);
function getPageData(page) {
var url = "/api/admin/group_member/?paging=true&page=" + page +
"&page_size=10&group_id=" + avalon.vmodels.admin.group_id;
"&page_size=10&group_id=" + avalon.vmodels.admin.groupId;
$.ajax({
url: url,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.member_list = data.data.results;
vm.page_count = data.data.total_page;
vm.previous_page = data.data.previous_page;
vm.next_page = data.data.next_page;
vm.memberList = 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 {
bs_alert(data.data);
bsAlert(data.data);
}
}
});
}
$.ajax({
url: "/api/admin/group/?group_id=" + avalon.vmodels.admin.group_id,
url: "/api/admin/group/?group_id=" + avalon.vmodels.admin.groupId,
method: "get",
dataType: "json",
success: function (data) {
if (!data.code) {
vm.name = data.data.name;
vm.description = data.data.description;
vm.checked_setting = data.data.join_group_setting.toString();
vm.checkedSetting = data.data.join_group_setting.toString();
}
else {
bs_alert(data.data);
bsAlert(data.data);
}
}
})
});
$("#edit_group_form")
.formValidation({
framework: "bootstrap",
fields: {
name: {
validators: {
notEmpty: {
message: "请填写小组名"
},
stringLength: {
max: 20,
message: '小组名长度必须在20位之内'
}
.formValidation({
framework: "bootstrap",
fields: {
name: {
validators: {
notEmpty: {
message: "请填写小组名"
},
stringLength: {
max: 20,
message: '小组名长度必须在20位之内'
}
},
description: {
validators: {
notEmpty: {
message: "请填写描述"
},
stringLength: {
max: 300,
message: '描述长度必须在300位之内'
}
}
},
description: {
validators: {
notEmpty: {
message: "请填写描述"
},
stringLength: {
max: 300,
message: '描述长度必须在300位之内'
}
}
}
}
).on('success.form.fv', function (e) {
}
).on('success.form.fv', function (e) {
e.preventDefault();
var data = {
group_id: avalon.vmodels.admin.group_id,
group_id: avalon.vmodels.admin.groupId,
name: vm.name,
description: vm.description,
join_group_setting: vm.checked_setting
join_group_setting: vm.checkedSetting
};
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: "/api/admin/group/",
method: "put",
data: data,
dataType: "json",
success: function (data) {
if (!data.code) {
bs_alert("修改成功");
bsAlert("修改成功");
}
else {
bs_alert(data.data);
bsAlert(data.data);
}
}
})

View File

@ -1,46 +1,47 @@
require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, avalon, csrfHeader, bs_alert) {
avalon.vmodels.request_list = null;
require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) {
// avalon:定义模式 group_list
avalon.ready(function () {
avalon.vmodels.requestList = null;
var vm = avalon.define({
$id: "request_list",
$id: "requestList",
//通用变量
request_list: [], // 列表数据项
previous_page: 0, // 之前的页数
next_page: 0, // 之后的页数
requestList: [], // 列表数据项
previousPage: 0, // 之前的页数
nextPage: 0, // 之后的页数
page: 1, // 当前页数
page_count: 1, // 总页数
totalPage: 1, // 总页数
getNext: function () {
if (!vm.next_page)
if (!vm.nextPage)
return;
getPageData(vm.page + 1);
},
getPrevious: function () {
if (!vm.previous_page)
if (!vm.previousPage)
return;
getPageData(vm.page - 1);
},
getBtnClass: function (btn) { //上一页/下一页按钮启用禁用逻辑
if (btn) {
return vm.next_page ? "btn btn-primary" : "btn btn-primary disabled";
if (btn == "next") {
return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled";
}
else {
return vm.previous_page ? "btn btn-primary" : "btn btn-primary disabled";
return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled";
}
},
getPage: function (page_index) {
getPageData(page_index);
},
processRequest: function(request_id, status){
processRequest: function(request, status){
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: "/api/admin/join_group_request/",
method: "put",
data: {request_id: request_id, status: status},
data: {request_id: request.id, status: status},
success: function(data){
bs_alert(data.data);
vm.requestList.remove(request);
bsAlert(data.data);
}
})
}
@ -52,20 +53,20 @@ require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, ava
function getPageData(page) {
var url = "/api/admin/join_group_request/?paging=true&page=" + page + "&page_size=10";
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: url,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.request_list = data.data.results;
vm.page_count = data.data.total_page;
vm.previous_page = data.data.previous_page;
vm.next_page = data.data.next_page;
vm.requestList = 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 {
bs_alert(data.data);
bsAlert(data.data);
}
}
});
@ -134,11 +135,11 @@ require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, ava
method: "put",
success: function (data) {
if (!data.code) {
bs_alert("提交成功!");
bsAlert("提交成功!");
getPageData(1);
$("#password").val("");
} else {
bs_alert(data.data);
bsAlert(data.data);
}
}
})

View File

@ -1,219 +1,218 @@
require(["jquery", "avalon", "editor", "uploader", "bs_alert", "csrf", "tagEditor", "validation", "jqueryUI"],
function ($, avalon, editor, uploader, bs_alert, csrfHeader) {
avalon.vmodels.add_problem = null;
$("#add-problem-form")
.formValidation({
framework: "bootstrap",
fields: {
title: {
validators: {
notEmpty: {
message: "请填写题目名称"
},
stringLength: {
min: 1,
max: 30,
message: "名称不能超过30个字"
require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagEditor", "formValidation", "jqueryUI"],
function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) {
avalon.ready(function () {
avalon.vmodels.addProblem = null;
$("#add-problem-form")
.formValidation({
framework: "bootstrap",
fields: {
title: {
validators: {
notEmpty: {
message: "请填写题目名称"
},
stringLength: {
min: 1,
max: 30,
message: "名称不能超过30个字"
}
}
}
},
cpu: {
validators: {
notEmpty: {
message: "请输入时间限制"
},
integer: {
message: "请输入一个合法的数字"
},
between: {
inclusive: true,
min: 1,
max: 5000,
message: "只能在1-5000之间"
},
cpu: {
validators: {
notEmpty: {
message: "请输入时间限制"
},
integer: {
message: "请输入一个合法的数字"
},
between: {
inclusive: true,
min: 1,
max: 5000,
message: "只能在1-5000之间"
}
}
}
},
memory: {
validators: {
notEmpty: {
message: "请输入内存限制"
},
integer: {
message: "请输入一个合法的数字"
},
memory: {
validators: {
notEmpty: {
message: "请输入内存限制"
},
integer: {
message: "请输入一个合法的数字"
}
}
}
},
difficulty: {
validators: {
notEmpty: {
message: "请输入难度"
},
integer: {
message: "难度用一个整数表示"
},
difficulty: {
validators: {
notEmpty: {
message: "请输入难度"
},
integer: {
message: "难度用一个整数表示"
}
}
}
},
input_description: {
validators: {
notEmpty: {
message: "请填写输入描述"
},
input_description: {
validators: {
notEmpty: {
message: "请填写输入描述"
}
}
}
},
output_description: {
validators: {
notEmpty: {
message: "请填写输出描述"
},
output_description: {
validators: {
notEmpty: {
message: "请填写输出描述"
}
}
}
}
}
})
.on("success.form.fv", function (e) {
e.preventDefault();
if (vm.test_case_id == '') {
bs_alert("你还没有上传测试数据!");
return;
}
if (vm.description == '') {
bs_alert("题目描述不能为空!");
return;
}
var ajaxData = {
title: vm.title,
description: vm.description,
time_limit: vm.cpu,
memory_limit: vm.memory,
samples: [],
test_case_id: vm.test_case_id,
hint: vm.hint,
source: vm.source,
tags: $("#tags").tagEditor("getTags")[0].tags,
input_description: vm.input_description,
output_description: vm.output_description,
difficulty: vm.difficulty
};
if (vm.samples.length == 0) {
bs_alert("请至少添加一组样例!");
return;
}
for(var i = 0; i < vm.samples.length; i++){
if (vm.samples[i].input == "" || vm.samples[i].output == ""){
bs_alert("样例输入与样例输出不能为空!");
return;
}
}
if (tags.length == 0) {
bs_alert("请至少添加一个标签,这将有利于用户发现你的题目!");
return;
}
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});
}
$.ajax({
beforeSend: csrfHeader,
url: "/api/admin/problem/",
dataType: "json",
data: JSON.stringify(ajaxData),
method: "post",
contentType: "application/json",
success: function (data) {
if (!data.code) {
bs_alert("successful!");
console.log(data);
}
else {
bs_alert(data.data);
}
}
})
});
var problemDiscription = editor("#problemDescription");
var testCaseUploader = uploader("#testCaseFile", "/api/admin/test_case_upload/", function (file, respond) {
if (respond.code)
bs_alert(respond.data);
else {
vm.test_case_id = respond.data.test_case_id;
vm.uploadSuccess = true;
vm.testCaseList = [];
for (var i = 0; i < respond.data.file_list.input.length; i++) {
vm.testCaseList.push({
input: respond.data.file_list.input[i],
output: respond.data.file_list.output[i]
});
}
bs_alert("测试数据添加成功!共添加"+vm.testCaseList.length +"组测试数据");
}
});
var hinteditor = editor("#hint");
var tagList = [], completeList = [];
var vm = avalon.define({
$id: "add_problem",
title: "",
description: "",
cpu: 1000,
memory: 256,
samples: [{input: "", output: "", "visible": true}],
hint: "",
visible: true,
difficulty: 0,
tags: [],
tag: "",
input_description: "",
output_description: "",
test_case_id: "",
testCaseList: [],
uploadSuccess: false,
source: "",
add_sample: function () {
vm.samples.push({input: "", output: "", "visible": true});
},
del_sample: function (sample) {
if (confirm("你确定要删除么?")) {
vm.samples.remove(sample);
}
},
toggle_sample: function (sample) {
sample.visible = !sample.visible;
},
getBtnContent: function (item) {
if (item.visible)
return "折叠";
return "展开";
}
});
$.ajax({
beforeSend: csrfHeader,
url: "/api/admin/tag/",
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
tagList = data.data;
completeList = [];
for (var i = 0; i < tagList.length; i++) {
completeList.push(tagList[i].name);
.on("success.form.fv", function (e) {
e.preventDefault();
if (vm.testCaseId == "") {
bsAlert("你还没有上传测试数据!");
return;
}
$("#tags").tagEditor({
autocomplete: {
delay: 0, // show suggestions immediately
position: {collision: 'flip'}, // automatic menu position up/down
source: completeList
if (vm.description == "") {
bsAlert("题目描述不能为空!");
return;
}
if (vm.samples.length == 0) {
bsAlert("请至少添加一组样例!");
return;
}
for (var i = 0; i < vm.samples.length; i++) {
if (vm.samples[i].input == "" || vm.samples[i].output == "") {
bsAlert("样例输入与样例输出不能为空!");
return;
}
});
}
else {
bs_alert(data.data);
}
}
}
if (tags.length == 0) {
bsAlert("请至少添加一个标签,这将有利于用户发现你的题目!");
return;
}
var ajaxData = {
title: vm.title,
description: vm.description,
time_limit: vm.timeLimit,
memory_limit: vm.memoryLimit,
samples: [],
test_case_id: vm.testCaseId,
hint: vm.hint,
source: vm.source,
tags: $("#tags").tagEditor("getTags")[0].tags,
input_description: vm.inputDescription,
output_description: vm.outputDescription,
difficulty: vm.difficulty
};
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});
}
$.ajax({
beforeSend: csrfTokenHeader,
url: "/api/admin/problem/",
dataType: "json",
data: JSON.stringify(ajaxData),
method: "post",
contentType: "application/json",
success: function (data) {
if (!data.code) {
bsAlert("题目添加成功!");
}
else {
bsAlert(data.data);
}
}
})
});
var testCaseUploader = uploader("#testCaseFile", "/api/admin/test_case_upload/", function (file, response) {
if (response.code)
bsAlert(response.data);
else {
vm.testCaseId = response.data.test_case_id;
vm.uploadSuccess = true;
vm.testCaseList = [];
for (var i = 0; i < response.data.file_list.input.length; i++) {
vm.testCaseList.push({
input: response.data.file_list.input[i],
output: response.data.file_list.output[i]
});
}
bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据");
}
});
var hintEditor = editor("#hint");
var problemDescription = editor("#problemDescription");
var vm = avalon.define({
$id: "addProblem",
title: "",
description: "",
cpu: 1000,
memory: 256,
samples: [{input: "", output: "", "visible": true}],
hint: "",
visible: true,
difficulty: 0,
tags: [],
inputDescription: "",
outputDescription: "",
testCaseId: "",
testCaseList: [],
uploadSuccess: false,
source: "",
addSample: function () {
vm.samples.push({input: "", output: "", "visible": true});
},
delSample: function (sample) {
if (confirm("你确定要删除么?")) {
vm.samples.remove(sample);
}
},
toggleSample: function (sample) {
sample.visible = !sample.visible;
},
getBtnContent: function (item) {
if (item.visible)
return "折叠";
return "展开";
}
});
var tagAutoCompleteList = [];
$.ajax({
beforeSend: csrfTokenHeader,
url: "/api/admin/tag/",
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
for (var i = 0; i < data.data.length; i++) {
tagAutoCompleteList.push(data.data[i].name);
}
$("#tags").tagEditor({
autocomplete: {
delay: 0, // show suggestions immediately
position: {collision: 'flip'}, // automatic menu position up/down
source: tagAutoCompleteList
}
});
}
else {
bsAlert(data.data);
}
}
});
});
avalon.scan();
});

View File

@ -0,0 +1,257 @@
require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagEditor", "formValidation", "jqueryUI"],
function ($, avalon, editor, uploader, bsAlert, csrfTokenHeader) {
avalon.ready(function () {
avalon.vmodels.editProblem = null;
$("#edit-problem-form")
.formValidation({
framework: "bootstrap",
fields: {
title: {
validators: {
notEmpty: {
message: "请填写题目名称"
},
stringLength: {
min: 1,
max: 30,
message: "名称不能超过30个字"
}
}
},
cpu: {
validators: {
notEmpty: {
message: "请输入时间限制"
},
integer: {
message: "请输入一个合法的数字"
},
between: {
inclusive: true,
min: 1,
max: 5000,
message: "只能在1-5000之间"
}
}
},
memory: {
validators: {
notEmpty: {
message: "请输入内存限制"
},
integer: {
message: "请输入一个合法的数字"
}
}
},
difficulty: {
validators: {
notEmpty: {
message: "请输入难度"
},
integer: {
message: "难度用一个整数表示"
}
}
},
input_description: {
validators: {
notEmpty: {
message: "请填写输入描述"
}
}
},
output_description: {
validators: {
notEmpty: {
message: "请填写输出描述"
}
}
}
}
})
.on("success.form.fv", function (e) {
e.preventDefault();
if (vm.testCaseId == "") {
bsAlert("你还没有上传测试数据!");
return;
}
if (vm.description == "") {
bsAlert("题目描述不能为空!");
return;
}
if (vm.samples.length == 0) {
bsAlert("请至少添加一组样例!");
return;
}
for (var i = 0; i < vm.samples.length; i++) {
if (vm.samples[i].input == "" || vm.samples[i].output == "") {
bsAlert("样例输入与样例输出不能为空!");
return;
}
}
if (tags.length == 0) {
bsAlert("请至少添加一个标签,这将有利于用户发现你的题目!");
return;
}
var ajaxData = {
id: avalon.vmodels.admin.problemId,
title: vm.title,
description: vm.description,
time_limit: vm.timeLimit,
memory_limit: vm.memoryLimit,
samples: [],
test_case_id: vm.testCaseId,
hint: vm.hint,
source: vm.source,
visible: vm.visible,
tags: $("#tags").tagEditor("getTags")[0].tags,
input_description: vm.inputDescription,
output_description: vm.outputDescription,
difficulty: vm.difficulty
};
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});
}
$.ajax({
beforeSend: csrfTokenHeader,
url: "/api/admin/problem/",
dataType: "json",
data: JSON.stringify(ajaxData),
method: "put",
contentType: "application/json",
success: function (data) {
if (!data.code) {
bsAlert("题目编辑成功!");
}
else {
bsAlert(data.data);
}
}
})
});
var vm = avalon.define({
$id: "editProblem",
title: "",
description: "",
timeLimit: -1,
memoryLimit: -1,
samples: [],
hint: "",
visible: true,
difficulty: 0,
inputDescription: "",
outputDescription: "",
testCaseIdd: "",
uploadSuccess: false,
source: "",
testCaseList: [],
addSample: function () {
vm.samples.push({input: "", output: "", "visible": true});
},
delSample: function (sample) {
if (confirm("你确定要删除么?")) {
vm.samples.remove(sample);
}
},
toggleSample: function (sample) {
sample.visible = !sample.visible;
},
getBtnContent: function (item) {
if (item.visible)
return "折叠";
return "展开";
}
});
var hintEditor = editor("#hint");
var descriptionEditor = editor("#problemDescription");
var testCaseUploader = uploader("#testCaseFile", "/api/admin/test_case_upload/", function (file, response) {
if (response.code)
bsAlert(response.data);
else {
vm.testCaseId = response.data.test_case_id;
vm.uploadSuccess = true;
vm.testCaseList = [];
for (var i = 0; i < response.data.file_list.input.length; i++) {
vm.testCaseList.push({
input: response.data.file_list.input[i],
output: response.data.file_list.output[i]
});
}
bsAlert("测试数据添加成功!共添加" + vm.testCaseList.length + "组测试数据");
}
});
$.ajax({
url: "/api/admin/problem/?problem_id=" + avalon.vmodels.admin.problemId,
method: "get",
dataType: "json",
success: function (data) {
if (data.code) {
bsAlert(data.data);
}
else {
var problem = data.data;
console.log(problem);
vm.title = problem.title;
vm.description = problem.description;
vm.timeLimit = problem.time_limit;
vm.memoryLimit = problem.memory_limit;
for (var i = 0; i < problem.samples.length; i++) {
vm.samples.push({
input: problem.samples[i].input,
output: problem.samples[i].output,
visible: false
})
}
vm.hint = problem.hint;
vm.visible = problem.visible;
vm.difficulty = problem.difficulty;
vm.inputDescription = problem.input_description;
vm.outputDescription = problem.output_description;
vm.testCaseId = problem.test_case_id;
vm.source = problem.source;
var problemTags = problem.tags;
hintEditor.setValue(vm.hint);
descriptionEditor.setValue(vm.description);
$.ajax({
url: "/api/admin/tag/",
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
var tagAutoCompleteList = [], tags = [];
for (var i = 0; i < data.data.length; i++) {
tagAutoCompleteList.push(data.data[i].name);
}
for (var j = 0; j < problem.tags.length; j++) {
tags.push(problemTags[j].name);
}
$("#tags").tagEditor({
initialTags: tags,
autocomplete: {
delay: 0,
position: {collision: 'flip'},
source: tagAutoCompleteList
}
});
}
else {
bsAlert(data.data);
}
}
});
}
}
});
});
avalon.scan();
});

View File

@ -0,0 +1,65 @@
require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) {
avalon.ready(function () {
avalon.vmodels.problemList = null;
var vm = avalon.define({
$id: "problemList",
problemList: [],
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 (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);
},
showEditProblemPage: function (problem_id) {
vm.$fire("up!showEditProblemPage", problem_id);
}
});
function getPageData(page) {
var url = "/api/admin/problem/?paging=true&page=" + page + "&page_size=10";
if (vm.keyword != "")
url += "&keyword=" + vm.keyword;
$.ajax({
url: url,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.problemList = 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);
}
}
});
}
getPageData(1);
});
avalon.scan();
});

View File

@ -1,59 +1,58 @@
require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, avalon, csrfHeader, bs_alert) {
avalon.vmodels.user_list = null;
require(["jquery", "avalon", "csrfToken", "bsAlert", "formValidation"], function ($, avalon, csrfTokenHeader, bsAlert) {
// avalon:定义模式 user_list
// avalon:定义模式 userList
avalon.ready(function () {
avalon.vmodels.userList = null;
var vm = avalon.define({
$id: "user_list",
$id: "userList",
//通用变量
user_list: [], // 用户列表数据项
previous_page: 0, // 之前的页数
next_page: 0, // 之后的页数
page: 1, // 当前页数
isEditing: 0, // 正在编辑的公告的ID 为零说明未在编辑
page_count: 1, // 总页数
user_type: ["一般用户", "管理员", "超级管理员"],
key_word: "",
userList: [],
previousPage: 0,
nextPage: 0,
page: 1,
editingUserId: 0,
totalPage: 1,
userType: ["一般用户", "管理员", "超级管理员"],
keyword: "",
showAdminOnly: false,
//编辑区域同步变量
username: "",
real_name: "",
realName: "",
email: "",
admin_type: 0,
adminType: 0,
id: 0,
last_login: "",
create_time: "",
getNext: function () {
if (!vm.next_page)
if (!vm.nextPage)
return;
getPageData(vm.page + 1);
},
getPrevious: function () {
if (!vm.previous_page)
if (!vm.previousPage)
return;
getPageData(vm.page - 1);
},
getBtnClass: function (btn) { //上一页/下一页按钮启用禁用逻辑
if (btn) {
return vm.next_page ? "btn btn-primary" : "btn btn-primary disabled";
return vm.nextPage ? "btn btn-primary" : "btn btn-primary disabled";
}
else {
return vm.previous_page ? "btn btn-primary" : "btn btn-primary disabled";
return vm.previousPage ? "btn btn-primary" : "btn btn-primary disabled";
}
},
enEdit: function (el) { //点击编辑按钮的事件,显示/隐藏编辑区
vm.username = el.username;
vm.real_name = el.real_name;
vm.admin_type = el.admin_type;
vm.email = el.email;
vm.id = el.id;
if (vm.isEditing == el.id)
vm.isEditing = 0;
editUser: function (user) { //点击编辑按钮的事件,显示/隐藏编辑区
vm.username = user.username;
vm.realName = user.real_name;
vm.adminType = user.admin_type;
vm.email = user.email;
vm.id = user.id;
if (vm.editingUserId == user.id)
vm.editingUserId = 0;
else
vm.isEditing = el.id;
vm.editingUserId = user.id;
},
getPage: function (page_index) {
getPageData(page_index);
search: function () {
getPageData(1);
}
});
vm.$watch("showAdminOnly", function () {
@ -66,23 +65,23 @@ require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, ava
var url = "/api/admin/user/?paging=true&page=" + page + "&page_size=10";
if (vm.showAdminOnly == true)
url += "&admin_type=1";
if (vm.key_word != "")
url += "&keyword=" + vm.key_word;
if (vm.keyword != "")
url += "&keyword=" + vm.keyword;
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: url,
dataType: "json",
method: "get",
success: function (data) {
if (!data.code) {
vm.user_list = data.data.results;
vm.page_count = data.data.total_page;
vm.previous_page = data.data.previous_page;
vm.next_page = data.data.next_page;
vm.userList = 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 {
bs_alert(data.data);
bsAlert(data.data);
}
}
});
@ -136,26 +135,26 @@ require(["jquery", "avalon", "csrf", "bs_alert", "validation"], function ($, ava
e.preventDefault();
var data = {
username: vm.username,
real_name: vm.real_name,
real_name: vm.realName,
email: vm.email,
id: vm.id,
admin_type: vm.admin_type
admin_type: vm.adminType
};
if ($("#password").val() !== "")
data.password = $("#password").val();
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: "/api/admin/user/",
data: data,
dataType: "json",
method: "put",
success: function (data) {
if (!data.code) {
bs_alert("提交成功!");
bsAlert("提交成功!");
getPageData(1);
$("#password").val("");
} else {
bs_alert(data.data);
bsAlert(data.data);
}
}
})

View File

@ -1,4 +1,4 @@
require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csrfHeader) {
require(["jquery", "bsAlert", "csrfToken", "formValidation"], function ($, bsAlert, csrfTokenHeader) {
$("#change_password-form").formValidation({
framework: "bootstrap",
fields: {
@ -47,21 +47,20 @@ require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csr
).on('success.form.fv', function (e) {
e.preventDefault();
var username = $("#username").val();
var new_password = $("#new_password ").val();
var newPassword = $("#new_password ").val();
var password = $("#password").val();
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: "/api/change_password/",
data: {username: username, new_password: new_password, old_password: password},
data: {username: username, new_password: newPassword, old_password: password},
dataType: "json",
method: "post",
success: function (data) {
if (!data.code) {
window.location.href = "/login/";
}
else {
bs_alert(data.data);
bsAlert(data.data);
}
}
})

View File

@ -1,4 +1,4 @@
require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csrfHeader) {
require(["jquery", "bsAlert", "csrfToken", "formValidation"], function ($, bsAlert, csrfTokenHeader) {
$("#login-form")
.formValidation({
framework: "bootstrap",
@ -24,7 +24,7 @@ require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csr
var username = $("#username").val();
var password = $("#password").val();
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: "/api/login/",
data: {username: username, password: password},
dataType: "json",
@ -34,7 +34,7 @@ require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csr
window.location.href = "/";
}
else {
bs_alert(data.data);
bsAlert(data.data);
}
}

View File

@ -1,4 +1,4 @@
require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csrfHeader) {
require(["jquery", "bsAlert", "csrfToken", "validation"], function ($, bsAlert, csrfTokenHeader) {
$("#register-form")
.formValidation({
framework: "bootstrap",
@ -73,13 +73,13 @@ require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csr
).on('success.form.fv', function (e) {
e.preventDefault();
var username = $("#username").val();
var real_name = $("#real_name").val();
var realName = $("#real_name").val();
var password = $("#password").val();
var email = $("#email").val();
$.ajax({
beforeSend: csrfHeader,
url: "/api/register/",
data: {username: username, real_name: real_name, password: password, email: email},
data: {username: username, real_name: realName, password: password, email: email},
dataType: "json",
method: "post",
success: function (data) {
@ -87,7 +87,7 @@ require(["jquery", "bs_alert", "csrf", "validation"], function ($, bs_alert, csr
window.location.href = "/login/";
}
else {
bs_alert(data.data);
bsAlert(data.data);
}
}
})

View File

@ -1,12 +1,12 @@
require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror, csrfHeader, bs_alert) {
var code_editor = code_mirror($("#code-editor")[0], "text/x-csrc");
require(["jquery", "codeMirror", "csrfToken", "bsAlert"], function ($, codeMirror, csrfTokenHeader, bsAlert) {
var codeEditor = codeMirror($("#code-editor")[0], "text/x-csrc");
var language = $("input[name='language'][checked]").val();
var submission_id;
var submissionId;
$("input[name='language']").change(function () {
language = this.value;
var language_types = {"1": "text/x-csrc", "2": "text/x-c++src", "3": "text/x-java"};
code_editor.setOption("mode", language_types[language]);
var languageTypes = {"1": "text/x-csrc", "2": "text/x-c++src", "3": "text/x-java"};
codeEditor.setOption("mode", languageTypes[language]);
});
$("#show-more-btn").click(function () {
@ -14,18 +14,17 @@ require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror,
$("#show-more-btn").hide();
});
function show_loading() {
function showLoading() {
$("#submit-code-button").attr("disabled", "disabled");
$("#loading-gif").show();
}
function hide_loading() {
function hideLoading() {
$("#submit-code-button").removeAttr("disabled");
$("#loading-gif").hide();
}
function get_result_html(data) {
function getResultHtml(data) {
// 0 结果正确 1 运行错误 2 超时 3 超内存 4 编译错误
// 5 格式错误 6 结果错误 7 系统错误 8 等待判题
var results = {
@ -49,14 +48,14 @@ require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror,
if (!data.result) {
html += "CPU time: " + data.accepted_answer_info.time + "ms &nbsp;&nbsp;";
}
html += ('<a href="/my_submission/' + submission_id + '/" target="_blank">查看详情</a></div> </div>');
html += ('<a href="/my_submission/' + submissionId + '/" target="_blank">查看详情</a></div> </div>');
return html;
}
function get_result() {
function getResult() {
$.ajax({
url: "/api/submission/?submission_id=" + submission_id,
url: "/api/submission/?submission_id=" + submissionId,
method: "get",
dataType: "json",
success: function (data) {
@ -64,54 +63,54 @@ require(["jquery", "code_mirror", "csrf", "bs_alert"], function ($, code_mirror,
// 8是还没有完成判题
if (data.data.result == 8) {
// 1秒之后重新去获取
setTimeout(get_result, 1000);
setTimeout(getResult, 1000);
}
else {
hide_loading();
$("#result").html(get_result_html(data.data));
hideLoading();
$("#result").html(getResultHtml(data.data));
}
}
else {
bs_alert(data.data);
hide_loading();
bsAlert(data.data);
hideLoading();
}
}
})
}
$("#submit-code-button").click(function () {
var problem_id = window.location.pathname.split("/")[2];
var code = code_editor.getValue();
var problemId = window.location.pathname.split("/")[2];
var code = codeEditor.getValue();
show_loading();
showLoading();
if(!code.trim()){
bs_alert("请填写代码!");
hide_loading();
hideLoading();
return false;
}
$("#result").html("");
$.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: "/api/submission/",
method: "post",
data: JSON.stringify({
problem_id: window.location.pathname.split("/")[2],
problem_id: problemId,
language: language,
code: code_editor.getValue()
code: codeEditor.getValue()
}),
contentType: "application/json",
success: function (data) {
if (!data.code) {
submission_id = data.data.submission_id;
submissionId = data.data.submission_id;
// 获取到id 之后2秒去查询一下判题结果
setTimeout(get_result, 2000);
setTimeout(getResult, 2000);
}
else {
bs_alert(data.data);
hide_loading();
hideLoading();
}
}
});

View File

@ -2,24 +2,28 @@ var require = {
// RequireJS 通过一个相对的路径 baseUrl来加载所有代码。baseUrl通常被设置成data-main属性指定脚本的同级目录。
baseUrl: "/static/js/",
paths: {
//百度webuploader
webuploader: "lib/webuploader/webuploader",
jquery: "lib/jquery/jquery",
avalon: "lib/avalon/avalon",
editor: "utils/editor",
uploader: "utils/uploader",
validation: "utils/validation",
code_mirror: "utils/code_mirror",
bs_alert: "utils/bs_alert",
formValidation: "utils/formValidation",
codeMirror: "utils/codeMirror",
bsAlert: "utils/bsAlert",
problem: "app/oj/problem/problem",
contest: "app/admin/contest/contest",
csrf: "utils/csrf",
csrfToken: "utils/csrfToken",
admin: "app/admin/admin",
chart: "lib/chart/Chart",
tagEditor: "lib/tagEditor/jquery.tag-editor.min",
jqueryUI: "lib/jqueryUI/jquery-ui",
//formValidation 不要在代码中单独使用而是使用和修改utils/validation
bootstrap: "lib/bootstrap/bootstrap",
datetimePicker: "lib/datetime_picker/bootstrap-datetimepicker.zh-CN",
// ------ 下面写的都不要直接用,而是使用上面的封装版本 ------
//formValidation -> utils/validation
base: "lib/formValidation/base",
helper: "lib/formValidation/helper",
"language/zh_CN": "lib/formValidation/language/zh_CN",
@ -32,26 +36,25 @@ var require = {
"validator/confirm":"lib/formValidation/validator/confirm",
"validator/remote":"lib/formValidation/validator/remote",
"validator/emailAddress":"lib/formValidation/validator/emailAddress",
//富文本编辑器 不要直接使用而是使用上面的editor
//富文本编辑器simditor -> editor
simditor: "lib/simditor/simditor",
"simple-module": "lib/simditor/module",
"simple-hotkeys": "lib/simditor/hotkeys",
"simple-uploader": "lib/simditor/uploader",
//code mirroe 代码编辑器
_code_mirror: "lib/codeMirror/codemirror",
code_mirror_clang: "lib/codeMirror/language/clike",
//code mirror 代码编辑器 ->codeMirror
_codeMirror: "lib/codeMirror/codemirror",
codeMirrorClang: "lib/codeMirror/language/clike",
//bootstrap
bootstrap: "lib/bootstrap/bootstrap",
//百度webuploader -> uploader
webUploader: "lib/webuploader/webuploader",
//
"_datetimepicker": "lib/datetime_picker/bootstrap-datetimepicker",
"datetimepicker": "lib/datetime_picker/bootstrap-datetimepicker.zh-CN"
"_datetimePicker": "lib/datetime_picker/bootstrap-datetimepicker"
},
shim: {
"bootstrap": {"deps": ['jquery']},
"_datetimepicker": {"deps": ["jquery"]},
"datetimepicker": {"deps": ["_datetimepicker"]}
bootstrap: {deps: ["jquery"]},
_datetimePicker: {dep: ["jquery"]},
datetimePicker: {deps: ["_datetimePicker"]}
}
};

View File

@ -5,7 +5,7 @@
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["_code_mirror"], mod);
define(["_codeMirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {

View File

@ -7,12 +7,12 @@
// AMD module is defined
if (typeof define === "function" && define.amd) {
define("validator/remote", ["jquery", "base", "csrf"], factory);
define("validator/remote", ["jquery", "base", "csrfToken"], factory);
} else {
// planted over the root!
factory(root.jQuery, root.FormValidation);
}
}(this, function ($, FormValidation, csrfHeader) {
}(this, function ($, FormValidation, csrfTokenHeader) {
FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
'en_US': {
remote: {
@ -28,7 +28,7 @@
return true;
var url = options.url;
var xhr = $.ajax({
beforeSend: csrfHeader,
beforeSend: csrfTokenHeader,
url: url,
dataType: 'json',
data: ajaxData,

View File

@ -1,5 +1,5 @@
define("bs_alert", ["jquery", "bootstrap"], function($){
function bs_alert(content){
define("bsAlert", ["jquery", "bootstrap"], function($){
function bsAlert(content){
if(!$("#alert-modal").length) {
var html = '<div class="modal fade" id="alert-modal" tabindex="-1" role="dialog"> ' +
'<div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> ' +
@ -13,5 +13,5 @@ define("bs_alert", ["jquery", "bootstrap"], function($){
$("#modal-text").html(content);
$("#alert-modal").modal();
}
return bs_alert;
return bsAlert;
});

View File

@ -1,5 +1,5 @@
define("code_mirror", ["_code_mirror", "code_mirror_clang"], function(CodeMirror){
function code_mirror(selector, language){
define("codeMirror", ["_codeMirror", "codeMirrorClang"], function(CodeMirror){
function codeMirror(selector, language){
return CodeMirror.fromTextArea(selector,
{
indentUnit: 4,
@ -8,5 +8,5 @@ define("code_mirror", ["_code_mirror", "code_mirror_clang"], function(CodeMirror
mode: language
});
}
return code_mirror;
return codeMirror;
});

View File

@ -1,5 +1,5 @@
define("csrf",function(){
function get_cookie(cookie_name) {
define("csrfToken",function(){
function getCookie(cookie_name) {
var name = cookie_name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
@ -9,15 +9,15 @@ define("csrf",function(){
}
return "";
}
function csrfHeader(){
function csrfTokenHeader(){
// jquery的请求
if(arguments.length == 2) {
arguments[0].setRequestHeader("X-CSRFToken", get_cookie("csrftoken"));
arguments[0].setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
}
// 百度webuploader 的请求
else if(arguments.length == 3){
arguments[2]["X-CSRFToken"] = get_cookie("csrftoken");
arguments[2]["X-CSRFToken"] = getCookie("csrftoken");
}
}
return csrfHeader;
return csrfTokenHeader;
});

View File

@ -1,4 +1,4 @@
define("validation",
define("formValidation",
[ 'base',
'helper',
'framework/bootstrap',

View File

@ -1,4 +0,0 @@
/**
* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);

View File

@ -1,24 +0,0 @@
function _notify(notify_type, title, content){
$.notify({
title: title,
message: content
}, {
type: notify_type,
placement: {
from: "top",
align: "center"
},
offset: {
y: 50
},
delay: 3000,
timer: 1000
});
}
function show_info(title, content) {
_notify("info", title, content);
}
function show_warning(title, content) {
_notify("warning", title, content);
}

View File

@ -1,5 +0,0 @@
/*! Respond.js v1.4.2: min/max-width media query polyfill * Copyright 2013 Scott Jehl
* Licensed under https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT
* */
!function(a){"use strict";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement("body"),f=a.createElement("div");return f.id="mq-test-1",f.style.cssText="position:absolute;top:-100em",e.style.background="none",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media="'+a+'"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){u(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))};if(c.ajax=f,c.queue=d,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var g,h,i,j=a.document,k=j.documentElement,l=[],m=[],n=[],o={},p=30,q=j.getElementsByTagName("head")[0]||k,r=j.getElementsByTagName("base")[0],s=q.getElementsByTagName("link"),t=function(){var a,b=j.createElement("div"),c=j.body,d=k.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=j.createElement("body"),c.style.background="none"),k.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&k.insertBefore(c,k.firstChild),a=b.offsetWidth,f?k.removeChild(c):c.removeChild(b),k.style.fontSize=d,e&&(c.style.fontSize=e),a=i=parseFloat(a)},u=function(b){var c="clientWidth",d=k[c],e="CSS1Compat"===j.compatMode&&d||j.body[c]||d,f={},o=s[s.length-1],r=(new Date).getTime();if(b&&g&&p>r-g)return a.clearTimeout(h),h=a.setTimeout(u,p),void 0;g=r;for(var v in l)if(l.hasOwnProperty(v)){var w=l[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?i||t():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?i||t():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(m[w.rules]))}for(var C in n)n.hasOwnProperty(C)&&n[C]&&n[C].parentNode===q&&q.removeChild(n[C]);n.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=j.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,q.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(j.createTextNode(F)),n.push(E)}},v=function(a,b,d){var e=a.replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var g=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},h=!f&&d;b.length&&(b+="/"),h&&(f=1);for(var i=0;f>i;i++){var j,k,n,o;h?(j=d,m.push(g(a))):(j=e[i].match(c.regex.findStyles)&&RegExp.$1,m.push(RegExp.$2&&g(RegExp.$2))),n=j.split(","),o=n.length;for(var p=0;o>p;p++)k=n[p],l.push({media:k.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:m.length-1,hasquery:k.indexOf("(")>-1,minw:k.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:k.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},w=function(){if(d.length){var b=d.shift();f(b.href,function(c){v(c,b.href,b.media),o[b.href]=!0,a.setTimeout(function(){w()},0)})}},x=function(){for(var b=0;b<s.length;b++){var c=s[b],e=c.href,f=c.media,g=c.rel&&"stylesheet"===c.rel.toLowerCase();e&&g&&!o[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(v(c.styleSheet.rawCssText,e,f),o[e]=!0):(!/^([a-zA-Z:]*\/\/)/.test(e)&&!r||e.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&("//"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}w()};x(),c.update=x,c.getEmValue=t,a.addEventListener?a.addEventListener("resize",b,!1):a.attachEvent&&a.attachEvent("onresize",b)}}(this);

View File

@ -1,4 +1,4 @@
define("uploader", ["webuploader", "csrf"], function(webuploader,csrf){
define("uploader", ["webUploader", "csrfToken"], function(webuploader,csrfTokenHeader){
function uploader(selector, server, onSuccess, beforeUpload) {
var Webuploader= webuploader.create({
auto: true,
@ -11,9 +11,9 @@ define("uploader", ["webuploader", "csrf"], function(webuploader,csrf){
pick: selector,
// 不压缩image, 默认如果是jpeg文件上传前会压缩一把再上传
resize: false,
uploadBeforeSend : csrf
uploadBeforeSend : csrfTokenHeader
});
Webuploader.on("uploadBeforeSend",csrf);
Webuploader.on("uploadBeforeSend",csrfTokenHeader);
Webuploader.on("uploadSuccess", onSuccess);
Webuploader.on("beforeFileQueued", beforeUpload);
return Webuploader;

View File

@ -101,9 +101,6 @@
<li class="list-group-item" id="li-user-user_list">
<a href="#user/user_list">用户列表</a>
</li>
<li class="list-group-item" id="li-user-user_group">
<a href="#user/user_group">用户分组</a>
</li>
<li class="list-group-header">小组管理</li>
<li class="list-group-item" id="li-group-group">
<a href="#group/group">小组列表</a>
@ -124,8 +121,6 @@
</div>
<script src="/static/js/config.js"></script>
<script src="/static/js/require.js"></script>
<script>

View File

@ -1,5 +1,5 @@
<div ms-controller="announcement" class="col-md-9">
<h1>Announcement</h1>
<h1>公告管理</h1>
<table class="table table-striped">
<tr>
<th>编号</th>
@ -8,36 +8,38 @@
<th>更新时间</th>
<th>创建者</th>
<th>状态</th>
<th>操作</th>
<th></th>
</tr>
<tr ms-repeat="announcement">
<td>{{el.id}}</td>
<td>{{el.title}}</td>
<td>{{el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{el.last_update_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{el.created_by.username}}</td>
<td>{{getState(el)}}</td>
<tr ms-repeat="announcementList">
<td>{{ el.id }}</td>
<td>{{ el.title }}</td>
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.last_update_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.created_by.username }}</td>
<td>{{ getState(el)}}</td>
<td>
<button class="btn-sm btn-info" ms-click="enEdit(el)">编辑</button>
<button class="btn-sm btn-info" ms-click="editAnnouncement(el)">编辑</button>
</td>
</tr>
</table>
<div class="form-group">
<label>仅显示可见 <input ms-duplex-checked="visableOnly" type="checkbox"/></label>
<label>仅显示可见 <input ms-duplex-checked="showVisibleOnly" type="checkbox"/></label>
</div>
<div class="text-right">
页数:{{page}}/{{page_count}}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass(0)" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass(1)" ms-click="getNext">下一页</button>
<div class="right">
页数:{{ page }}/{{ totalPage }}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass('pre')" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass('next')" ms-click="getNext">下一页</button>
</div>
<div ms-visible="isEditing">
<div ms-visible="editingAnnouncementId">
<h3>编辑公告</h3>
<div class="form-group"><label for="title">标题</label>
<div class="form-group">
<label>标题</label>
<input name="title" type="text" class="form-control" id="newTitle" placeholder="公告标题" value=""></div>
<div class="form-group">
<label>内容</label>
<textarea id="editAnnouncementEditor"></textarea>
<textarea id="edit-announcement-editor"></textarea>
</div>
<div class="form-group">
<label>可见 <input ms-duplex-checked="announcementVisible" type="checkbox"/></label>
@ -45,17 +47,17 @@
<div class="form-group">
<button ms-click="submitChange()" class="btn btn-primary">提交</button>
&nbsp;&nbsp;
<button ms-click="disEdit()" class="btn btn-danger">取消</button>
<button ms-click="cancelEdit()" class="btn btn-danger">取消</button>
</div>
</div>
<h3>添加公告</h3>
<form id="announcement-form">
<div class="form-group"><label for="title">标题</label>
<div class="form-group"><label>标题</label>
<input name="title" type="text" class="form-control" id="title" placeholder="公告标题"></div>
<div class="form-group">
<label>内容</label>
<textarea id="editor" placeholder="公告内容"></textarea>
<textarea id="create-announcement-editor" placeholder="公告内容"></textarea>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>

View File

@ -75,13 +75,18 @@
<div class="col-md-12">
<label>添加题目</label>
<a href="javascript:void(0)" class="btn btn-primary btn-sm" ms-click="add_problem()">添加</a>
<div class="col-md-12">
<label>上传测试用例</label>
<label>选择题号</label><select ms-duplex="problemNo"><option value="-1">未指定</option><option ms-repeat="problems" ms-attr-value="$index+1">{{$index+1}}</option></select>
<div id="uploader">
<div>选择文件</div>
</div>
</div>
<div class="col-md-12">
<label>上传测试用例</label>
<label>选择题号</label><select ms-duplex="problemNo">
<option value="-1">未指定</option>
<option ms-repeat="problems" ms-attr-value="$index+1">{{$index+1}}</option>
</select>
<div id="uploader">
<div>选择文件</div>
</div>
</div>
</div>
<div class="col-md-12">
<div class="problem" ms-repeat-problem="problems">
@ -89,7 +94,7 @@
<div class="panel-heading">
<span class="panel-title">题目{{$index + 1}} </span>
<a href="javascript:void(0)" class="btn btn-primary btn-sm" ms-click="toggle(problem)">
{{getBtnContent(problem)}}
{{ getBtnContent(problem)}}
</a>
<a href="javascript:void(0)" class="btn btn-danger btn-sm" ms-click="del_problem(problem)">
删除
@ -97,17 +102,19 @@
</div>
<div class="panel-body" ms-visible="problem.visible">
<div class="form-group col-md-12">
<label>题目标题</label>
<input type="text" name="problem_name[]" class="form-control" ms-duplex="problem.title">
<label>题目标题</label>
<input type="text" name="problem_name[]" class="form-control" ms-duplex="problem.title">
</div>
<div class="form-group col-md-12">
<label>题目描述</label>
<textarea ms-attr-id="problem-{{ problem.id }}-description" placeholder="这里输入内容"
ms-duplex="problem.description"></textarea>
<small ms-visible="problem.description==''" style="color:red">请填写题目描述</small>
</div>
<div class="form-group col-md-12">
<label>题目描述</label>
<textarea ms-attr-id="problem-{{ problem.id }}-description" placeholder="这里输入内容" ms-duplex="problem.description"></textarea>
<small ms-visible="problem.description==''" style="color:red">请填写题目描述</small>
</div>
<div class="form-group col-md-12">
<label>提示</label>
<textarea ms-attr-id="problem-{{ problem.id }}-hint" placeholder="这里输入内容" ms-duplex="problem.hint"></textarea>
<textarea ms-attr-id="problem-{{ problem.id }}-hint" placeholder="这里输入内容"
ms-duplex="problem.hint"></textarea>
</div>
<div class="col-md-3 form-group">
<label>cpu</label>
@ -119,19 +126,24 @@
</div>
<div class="col-md-3 form-group">
<label>难度</label>
<input type="number" name="difficulty[]" class="form-control" ms-duplex="problem.difficulty">
<input type="number" name="difficulty[]" class="form-control"
ms-duplex="problem.difficulty">
</div>
<div class="col-md-12">
<label>样例</label>
<a href="javascript:void(0)" class="btn btn-primary btn-sm" ms-click="add_sample(problem)">添加</a>
<a href="javascript:void(0)" class="btn btn-primary btn-sm"
ms-click="add_sample(problem)">添加</a>
<div class="sample">
<div class="panel panel-default sample-panel" ms-repeat-sample="problem.samples">
<div class="panel-heading">
<span class="panel-title">样例{{$index + 1}}</span>
<a href="javascript:void(0)" class="btn btn-primary btn-sm" ms-click="toggle(sample)">
{{getBtnContent(sample)}}
<a href="javascript:void(0)" class="btn btn-primary btn-sm"
ms-click="toggle(sample)">
{{ getBtnContent(sample)}}
</a>
<a href="javascript:void(0)" class="btn btn-danger btn-sm" ms-click="del_sample(problem, sample)">
<a href="javascript:void(0)" class="btn btn-danger btn-sm"
ms-click="del_sample(problem, sample)">
删除
</a>
</div>
@ -167,8 +179,8 @@
</tr>
<tr ms-repeat="problem.testCaseList">
<td>{{$index}}</td>
<td>{{el.input}}</td>
<td>{{el.output}}</td>
<td>{{ el.input }}</td>
<td>{{ el.output }}</td>
</tr>
</table>
</div>

View File

@ -1,14 +1,14 @@
<div ms-controller="group" class="col-md-9">
<h1>小组管理</h1>
<div class="text-right">
<div class="right">
<form class="form-inline" onsubmit="return false;">
<div class="form-group-sm">
<label>搜索</label>
<input class="form-control" placeholder="请输入关键词" ms-duplex="keyword">
<input type="submit" value="搜索" class="btn btn-primary" ms-click="getPage(1)">
<input type="submit" value="搜索" class="btn btn-primary" ms-click="search()">
</div>
</form>
<br>
</div>
<table class="table table-striped">
<tr>
@ -20,10 +20,10 @@
<th>设置</th>
<th></th>
</tr>
<tr ms-repeat="group_list">
<td>{{el.id}}</td>
<td>{{el.name}}</td>
<td>{{el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<tr ms-repeat="groupList">
<td>{{ el.id }}</td>
<td>{{ el.name }}</td>
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.members_number }}</td>
<td>{{ getGroupSettingString(el.join_group_setting) }}</td>
@ -33,10 +33,10 @@
</tr>
</table>
<div class="text-right">
页数:{{page}}/{{page_count}}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass(0)" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass(1)" ms-click="getNext">下一页</button>
<div class="right">
页数:{{ page }}/{{ totalPage }}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass('pre')" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass('next')" ms-click="getNext">下一页</button>
</div>
</div>

View File

@ -1,4 +1,4 @@
<div ms-controller="group_detail" class="col-md-9">
<div ms-controller="groupDetail" class="col-md-9">
<h1>小组成员管理</h1>
<table class="table table-striped">
<tr>
@ -8,7 +8,7 @@
<th>加入时间</th>
<th></th>
</tr>
<tr ms-repeat="member_list">
<tr ms-repeat="memberList">
<td>{{ el.user.id }}</td>
<td>{{ el.user.username }}</td>
<td>{{ el.user.real_name }}</td>
@ -21,9 +21,9 @@
</table>
<div class="text-right">
页数:{{ page }}/{{ page_count }}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass(0)" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass(1)" ms-click="getNext">下一页</button>
页数:{{ page }}/{{ totalPage }}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass('pre')" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass('next')" ms-click="getNext">下一页</button>
</div>
<h1>修改小组信息</h1>
@ -42,9 +42,9 @@
<div class="form-group">
<label>加入小组设置</label>
<input type="radio" name="join_group_setting" value="0" ms-duplex-string="checked_setting">允许任何人加入
<input type="radio" name="join_group_setting" value="1" ms-duplex-string="checked_setting">提交请求后管理员审核
<input type="radio" name="join_group_setting" value="2" ms-duplex-string="checked_setting">不允许任何人加入
<input type="radio" name="join_group_setting" value="0" ms-duplex-string="checkedSetting">允许任何人加入
<input type="radio" name="join_group_setting" value="1" ms-duplex-string="checkedSetting">提交请求后管理员审核
<input type="radio" name="join_group_setting" value="2" ms-duplex-string="checkedSetting">不允许任何人加入
</div>
<button class="btn btn-primary" type="submit">提交</button>
@ -52,4 +52,4 @@
</form>
</div>
<script src="/static/js/app/admin/group/group_detail.js"></script>
<script src="/static/js/app/admin/group/groupDetail.js"></script>

View File

@ -1,31 +1,31 @@
<div ms-controller="request_list" class="col-md-9">
<div ms-controller="requestList" class="col-md-9">
<h1>加入小组请求管理</h1>
<table class="table table-striped">
<tr>
<th>创建时间</th>
<th>用户</th>
<th>小组</th>
<th>用户</th>
<th>附加消息</th>
<th></th>
</tr>
<tr ms-repeat="request_list">
<td>{{el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<tr ms-repeat="requestList">
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.group.name }}</td>
<td>{{ el.user.username }}</td>
<td>{{ el.message }}</td>
<td>
<button class="btn-sm btn-success" ms-click="processRequest(el.id, true)">同意</button>
<button class="btn-sm btn-danger" ms-click="processRequest(el.id, false)">拒绝</button>
<button class="btn-sm btn-success" ms-click="processRequest(el, true)">同意</button>
<button class="btn-sm btn-danger" ms-click="processRequest(el, false)">拒绝</button>
</td>
</tr>
</table>
<div class="text-right">
页数:{{page}}/{{page_count}}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass(0)" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass(1)" ms-click="getNext">下一页</button>
页数:{{ page }}/{{ totalPage }}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass('pre')" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass('next')" ms-click="getNext">下一页</button>
</div>
</div>
<script src="/static/js/app/admin/group/join_group_request_list.js"></script>
<script src="/static/js/app/admin/group/joinGroupRequestList.js"></script>

View File

@ -1,4 +1,4 @@
<div ms-controller="add_problem" class="col-md-9">
<div ms-controller="addProblem" class="col-md-9">
<form id="add-problem-form">
<div class="form-group col-md-12">
@ -41,27 +41,27 @@
<div class="col-md-12 form-group">
<label>输入描述</label><br>
<textarea class="form-control" rows="5" name="input_description"
ms-duplex="input_description"></textarea>
ms-duplex="inputDescription"></textarea>
</div>
<div class="col-md-12 form-group">
<label>输出描述</label><br>
<textarea class="form-control" rows="5" name="output_description"
ms-duplex="output_description"></textarea>
ms-duplex="outputDescription"></textarea>
</div>
<div class="col-md-12"><br>
<label>样例</label>
<a href="javascript:void(0)" class="btn btn-primary btn-sm" ms-click="add_sample()">添加</a>
<a href="javascript:void(0)" class="btn btn-primary btn-sm" ms-click="addSample()">添加</a>
<div class="sample">
<div class="panel panel-default sample-panel" ms-repeat-sample="samples">
<div class="panel-heading">
<span class="panel-title">样例{{$index + 1}}</span>
<a href="javascript:void(0)" class="btn btn-primary btn-sm"
ms-click="toggle_sample(sample)">
ms-click="toggleSample(sample)">
{{ getBtnContent(sample)}}
</a>
<a href="javascript:void(0)" class="btn btn-danger btn-sm"
ms-click="del_sample(sample)">
ms-click="delSample(sample)">
删除
</a>
</div>

View File

@ -0,0 +1,123 @@
<div ms-controller="editProblem" class="col-md-9">
<form id="edit-problem-form">
<div class="form-group col-md-12">
<label>题目标题</label>
<input type="text" name="title" autofocus class="form-control" ms-duplex="title">
</div>
<div class="form-group col-md-12">
<label>题目描述</label>
<textarea id="problemDescription" placeholder="这里输入内容(此内容不能为空)" ms-duplex="description"></textarea>
<small ms-visible="description==''" style="color:red">请填写题目描述</small>
</div>
<div class="col-md-3">
<div class="form-group"><label>时间限制(ms)</label>
<input type="number" name="cpu" class="form-control" ms-duplex="timeLimit">
</div>
</div>
<div class="col-md-3">
<div class="form-group"><label>内存限制(MB)</label>
<input type="number" name="memory" class="form-control" ms-duplex="memoryLimit">
</div>
</div>
<div class="col-md-3">
<div class="form-group"><label>难度</label>
<input type="number" name="difficulty" class="form-control" ms-duplex="difficulty">
</div>
</div>
<div class="col-md-3 form-group">
<label>前台是否可见</label><br>
<label><input type="checkbox" ms-duplex-checked="visible">
<small> 可见</small>
</label>
</div>
<div id="tag" class="col-md-12">
<label>标签</label><br>
<input type="text" id="tags">
</div>
<div class="col-md-12 form-group">
<label>输入描述</label><br>
<textarea class="form-control" rows="5" name="input_description"
ms-duplex="inputDescription"></textarea>
</div>
<div class="col-md-12 form-group">
<label>输出描述</label><br>
<textarea class="form-control" rows="5" name="output_escription"
ms-duplex="outputDescription"></textarea>
</div>
<div class="col-md-12"><br>
<label>样例</label>
<a href="javascript:void(0)" class="btn btn-primary btn-sm" ms-click="addSample()">添加</a>
<div class="sample">
<div class="panel panel-default sample-panel" ms-repeat-sample="samples">
<div class="panel-heading">
<span class="panel-title">样例{{$index + 1}}</span>
<a href="javascript:void(0)" class="btn btn-primary btn-sm"
ms-click="toggleSample(sample)">
{{ getBtnContent(sample)}}
</a>
<a href="javascript:void(0)" class="btn btn-danger btn-sm"
ms-click="delSample(sample)">
删除
</a>
</div>
<div class="panel-body row" ms-visible="sample.visible">
<div class="col-md-6">
<div class="form-group">
<label>样例输入</label>
<textarea class="form-control" rows="5" ms-duplex="sample.input"></textarea>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>样例输出</label>
<textarea class="form-control" rows="5" ms-duplex="sample.output"></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12"><br>
<label>测试数据(当前已上传,继续上传将覆盖原有测试用例)</label><br>
<small class="text-info">请将所有测试用例打包在一个文件中上传所有文件要在压缩包的根目录且输入输出文件名要以从1开始连续数字标识要对应例如<br>
1.in 1.out 2.in 2.out
</small>
<table class="table table-striped" ms-visible="uploadSuccess">
<tr>
<td>编号</td>
<td>输入文件名</td>
<td>输出文件名</td>
</tr>
<tr ms-repeat="testCaseList">
<td>{{ $index + 1 }}</td>
<td>{{ el.input }}</td>
<td>{{ el.output }}</td>
</tr>
</table>
</div>
<div class="col-md-12">
<div class="form-group">
<div id="testCaseFile">选择文件</div>
</div>
</div>
<div class="form-group col-md-12">
<label>提示</label>
<textarea id="hint" placeholder="这里输入内容" ms-duplex="hint"></textarea>
</div>
<div class="form-group col-md-12">
<label>来源</label>
<input type="text" name="source" class="form-control" ms-duplex="source">
</div>
<div class="col-md-12">
<input type="submit" class="btn btn-success btn-lg" value="发布题目" id="submitBtn">
</div>
</form>
</div>
<script src="/static/js/app/admin/problem/edit_problem.js"></script>

View File

@ -0,0 +1,40 @@
<div ms-controller="problemList" class="col-md-9">
<h1>题目列表</h1>
<div class="right">
<form class="form-inline" onsubmit="return false;">
<div class="form-group-sm">
<label>搜索</label>
<input name="keyWord" class="form-control" placeholder="请输入关键词" ms-duplex="keyword">
<input type="submit" value="搜索" class="btn btn-primary" ms-click="getPage(1)">
</div>
</form>
<br>
</div>
<table class="table table-striped">
<tr>
<th>ID</th>
<th>题目</th>
<th>创建时间</th>
<th>作者</th>
<td>通过次数/提交总数</td>
<td></td>
</tr>
<tr ms-repeat="problemList">
<td>{{ el.id }}</td>
<td>{{ el.title }}</td>
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.created_by.username }}</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 class="text-right">
页数:{{ page }}/{{ totalPage }}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass('pre')" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass('next')" ms-click="getNext">下一页</button>
</div>
</div>
<script src="/static/js/app/admin/problem/problem.js"></script>

View File

@ -1,11 +1,12 @@
<div ms-controller="user_list" class="col-md-9">
<h1>User</h1>
<div class="text-right">
<div ms-controller="userList" class="col-md-9">
<h1>用户管理</h1>
<div class="right">
<form class="form-inline" onsubmit="return false;">
<div class="form-group-sm">
<label>搜索</label>
<input name="keyWord" class="form-control" placeholder="请输入关键词" ms-duplex="key_word">
<input type="submit" value="搜索" class="btn btn-primary" ms-click="getPage(1)">
<input name="keyWord" class="form-control" placeholder="请输入关键词" ms-duplex="keyWord">
<input type="submit" value="搜索" class="btn btn-primary" ms-click="search()">
</div>
</form>
<br>
@ -21,16 +22,16 @@
<th>用户类型</th>
<th>修改</th>
</tr>
<tr ms-repeat="user_list">
<td>{{el.id}}</td>
<td>{{el.username}}</td>
<td>{{el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{el.last_login|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{el.real_name}}</td>
<td>{{el.email}}</td>
<td>{{user_type[el.admin_type]}}</td>
<tr ms-repeat="userList">
<td>{{ el.id }}</td>
<td>{{ el.username }}</td>
<td>{{ el.create_time|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.last_login|date("yyyy-MM-dd HH:mm:ss")}}</td>
<td>{{ el.real_name }}</td>
<td>{{ el.email }}</td>
<td>{{ userType[el.admin_type]}}</td>
<td>
<button class="btn-sm btn-info" ms-click="enEdit(el)">编辑</button>
<button class="btn-sm btn-info" ms-click="editUser(el)">编辑</button>
</td>
</tr>
</table>
@ -38,12 +39,13 @@
<label>仅显示管理员 <input ms-duplex-checked="showAdminOnly" type="checkbox"/></label>
</div>
<div class="text-right">
页数:{{page}}/{{page_count}}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass(0)" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass(1)" ms-click="getNext">下一页</button>
页数:{{ page }}/{{ totalPage }}&nbsp;&nbsp;
<button ms-attr-class="getBtnClass('pre')" ms-click="getPrevious">上一页</button>
<button ms-attr-class="getBtnClass('next')" ms-click="getNext">下一页</button>
</div>
<div ms-visible="isEditing">
<div ms-visible="editingUserId">
<h3>修改用户信息</h3>
<form id="edit_user-form">
<div class="row">
<div class="form-group col-md-4"><label>ID</label>
@ -53,7 +55,7 @@
<input name="username" type="text" class="form-control" ms-duplex="username">
</div>
<div class="form-group col-md-4"><label>真实姓名</label>
<input name="real_name" type="text" class="form-control" ms-duplex="real_name">
<input name="real_name" type="text" class="form-control" ms-duplex="realName">
</div>
</div>
<div class="row">
@ -65,8 +67,8 @@
<input name="email" type="email" class="form-control" ms-duplex="email">
</div>
<div class="form-group col-md-4"><label>用户类型</label>
<select name="admin_type" class="form-control" ms-duplex="admin_type">
<option ms-repeat="user_type" ms-attr-value="$index">{{el}}</option>
<select name="admin_type" class="form-control" ms-duplex="adminType">
<option ms-repeat="userType" ms-attr-value="$index">{{ el }}</option>
</select>
</div>
</div>
@ -76,4 +78,4 @@
</form>
</div>
</div>
<script src="/static/js/app/admin/user/user_list.js"></script>
<script src="/static/js/app/admin/user/userList.js"></script>

View File

@ -1,34 +1,36 @@
{% extends "oj_base.html" %}
{% block body %}
<div class="container main">
<div class="col-md-6 col-md-offset-3">
<h2 class="text-center">修改密码</h2>
<div class="container main">
<div class="col-md-6 col-md-offset-3">
<h2 class="text-center">修改密码</h2>
<form id="change_password-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control input-lg" id="username" name="username" placeholder="用户名"
autofocus>
</div>
<div class="form-group">
<label for="password">旧密码</label>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
</div>
<div class="form-group">
<label for="new_password">新密码</label>
<input type="password" class="form-control input-lg" id="new_password" name="new_password" placeholder="新密码">
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" class="form-control input-lg" id="confirm_password" name="confirm_password" placeholder="确认密码">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
<form id="change_password-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control input-lg" id="username" name="username" placeholder="用户名"
autofocus>
</div>
<div class="form-group">
<label for="password">旧密码</label>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
</div>
<div class="form-group">
<label for="new_password">新密码</label>
<input type="password" class="form-control input-lg" id="new_password" name="new_password"
placeholder="新密码">
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" class="form-control input-lg" id="confirm_password" name="confirm_password"
placeholder="确认密码">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js_block %}
<script src="/static/js/app/oj/account/change_password.js"></script>
<script src="/static/js/app/oj/account/change_password.js"></script>
{% endblock %}

View File

@ -1,26 +1,26 @@
{% extends "oj_base.html" %}
{% block body %}
<div class="container main">
<div class="col-md-6 col-md-offset-3">
<h2 class="text-center">用户登录</h2>
<div class="container main">
<div class="col-md-6 col-md-offset-3">
<h2 class="text-center">用户登录</h2>
<form id="login-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control input-lg" id="username" name="username" placeholder="用户名"
autofocus>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
<form id="login-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control input-lg" id="username" name="username" placeholder="用户名"
autofocus>
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js_block %}
<script src="/static/js/app/oj/account/login.js"></script>
<script src="/static/js/app/oj/account/login.js"></script>
{% endblock %}

View File

@ -1,38 +1,39 @@
{% extends "oj_base.html" %}
{% block body %}
<div class="container main">
<div class="col-md-6 col-md-offset-3">
<h2 class="text-center">用户注册</h2>
<div class="container main">
<div class="col-md-6 col-md-offset-3">
<h2 class="text-center">用户注册</h2>
<form id="register-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control input-lg" id="username" name="username" placeholder="用户名"
autofocus>
</div>
<div class="form-group">
<label for="real_name">真实姓名</label>
<input type="text" class="form-control input-lg" id="real_name" name="real_name" placeholder="真实姓名">
</div>
<div class="form-group">
<label for="email">邮箱地址</label>
<input type="email" class="form-control input-lg" id="email" name="email" placeholder="邮箱地址">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" class="form-control input-lg" id="confirm_password" name="confirm_password" placeholder="确认密码">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
<form id="register-form">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control input-lg" id="username" name="username" placeholder="用户名"
autofocus>
</div>
<div class="form-group">
<label for="real_name">真实姓名</label>
<input type="text" class="form-control input-lg" id="real_name" name="real_name" placeholder="真实姓名">
</div>
<div class="form-group">
<label for="email">邮箱地址</label>
<input type="email" class="form-control input-lg" id="email" name="email" placeholder="邮箱地址">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
</div>
<div class="form-group">
<label for="confirm_password">确认密码</label>
<input type="password" class="form-control input-lg" id="confirm_password" name="confirm_password"
placeholder="确认密码">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">提交</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block js_block %}
<script src="/static/js/app/oj/account/register.js"></script>
<script src="/static/js/app/oj/account/register.js"></script>
{% endblock %}

View File

@ -1,22 +1,22 @@
{% extends "oj_base.html" %}
{% block body %}
<div class="container main">
<h1 class="text-center">{{ announcement.title }}</h1>
<div class="container main">
<h1 class="text-center">{{ announcement.title }}</h1>
<p class="text-muted text-center">
作者:{{ announcement.created_by }}
&nbsp;&nbsp;&nbsp;
创建时间:{{ announcement.create_time }}
{% ifequal announcement.create_time announcement.last_update_time %}
{% else %}
&nbsp;&nbsp;&nbsp;
最后更新:{{ announcement.last_update_time }}
{% endifequal %}
</p>
<p class="text-muted text-center">
作者:{{ announcement.created_by }}
&nbsp;&nbsp;&nbsp;
创建时间:{{ announcement.create_time }}
{% ifequal announcement.create_time announcement.last_update_time %}
{% else %}
&nbsp;&nbsp;&nbsp;
最后更新:{{ announcement.last_update_time }}
{% endifequal %}
</p>
<div>
<p>{{ announcement.content|safe }}</p>
<div>
<p>{{ announcement.content|safe }}</p>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,15 +1,15 @@
{% extends "oj_base.html" %}
{% block body %}
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation" class="active">
<a href="problem.html">题目</a></li>
<li role="presentation"><a href="my_solutions_list.html">我的提交</a></li>
<li role="presentation"><a href="#">排名</a></li>
</ul>
<h2 class="text-center">第一次比赛</h2>
<div class="container main">
<ul class="nav nav-tabs nav-tabs-google">
<li role="presentation" class="active">
<a href="problem.html">题目</a></li>
<li role="presentation"><a href="my_solutions_list.html">我的提交</a></li>
<li role="presentation"><a href="#">排名</a></li>
</ul>
<h2 class="text-center">第一次比赛</h2>
<p class="text-muted text-center"><b>开始时间:</b> 2015-6-8 19:00 <b>结束时间:</b> 2015-9-1 12:00</p>
<p class="text-muted text-center"><b>开始时间:</b> 2015-6-8 19:00 <b>结束时间:</b> 2015-9-1 12:00</p>
</div>
</div>
{% endblock %}

View File

@ -1,37 +1,39 @@
{% extends "oj_base.html" %}
{% block body %}
<div class="container">
<div class="container">
<div class="container">
<div class="jumbotron">
<h1>青岛大学在线评测平台</h1>
<div class="jumbotron">
<h1>青岛大学在线评测平台</h1>
<p class="lead">走心的在线评测平台和算法交流社区,全新登场~</p>
<p class="lead">走心的在线评测平台和算法交流社区,全新登场~</p>
<p><a class="btn btn-lg btn-primary" href="/problems/" role="button">开始刷题!</a></p>
</div>
<!-- Example row of columns -->
<div class="row">
<div class="col-lg-4">
<h2>全新UI 全新设计</h2>
<p>精心设计的UI和交互让你。。。编不下去了 </p>
</div>
<div class="col-lg-4">
<h2>分布式评测</h2>
<p>技术领先的高性能分布式评测机制,根据提交数量自动伸缩判题机器实例。</p>
</div>
<div class="col-lg-4">
<h2>高质量原创题目</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id
ligula
porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum
nibh,
ut fermentum massa.</p>
</div>
</div>
<p><a class="btn btn-lg btn-primary" href="/problems/" role="button">开始刷题!</a></p>
</div>
<!-- Example row of columns -->
<div class="row">
<div class="col-lg-4">
<h2>全新UI 全新设计</h2>
<p>精心设计的UI和交互让你。。。编不下去了 </p>
</div>
<div class="col-lg-4">
<h2>分布式评测</h2>
<p>技术领先的高性能分布式评测机制,根据提交数量自动伸缩判题机器实例。</p>
</div>
<div class="col-lg-4">
<h2>高质量原创题目</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula
porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh,
ut fermentum massa.</p>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,4 +1,3 @@
<h2 class="text-center">{{ problem.title }}</h2>
<p class="text-muted text-center">发布时间 : {{ problem.create_time }}&nbsp;&nbsp;

View File

@ -1,9 +1,9 @@
{% extends 'oj_base.html' %}
{% block css_block %}
<style>
.CodeMirror{
height: auto;
}
.CodeMirror {
height: auto;
}
</style>
{% endblock %}
{% block body %}
@ -29,7 +29,7 @@
{% ifequal submission.result 4 %}
<p>{{ submission.info }}</p>
{% endifequal %}
<p>提交时间 : {{ submission.create_time }}</p>
<p>提交时间 : {{ submission.create_time }}</p>
</div>
</div>
<div id="code-field">
@ -40,7 +40,7 @@
{% endblock %}
{% block js_block %}
<script>
require(["jquery", "code_mirror"], function ($, code_mirror) {
require(["jquery", "codeMirror"], function ($, codeMirror) {
{% ifequal submission.language 1 %}
var language = "text/x-csrc";
{% else %}
@ -50,8 +50,8 @@
var language = "text/x-java";
{% endifequal %}
{% endifequal %}
var code_editor = code_mirror($("#code-editor")[0], language);
code_editor.setOption("readOnly", true);
var codeEditor = codeMirror($("#code-editor")[0], language);
codeEditor.setOption("readOnly", true);
});
</script>
{% endblock %}

View File

@ -5,7 +5,7 @@
<div class="row">
<div class="col-lg-9">
<div class="row">
<div style="float: right;">
<div class="search-box">
<form class="form-inline" onsubmit="return false;">
<div class="form-group-sm">
<input name="keyWord" class="form-control" placeholder="请输入关键词" ms-duplex="key_word">
@ -28,7 +28,7 @@
{% for item in problems %}
<tr>
<th scope="row"><a href="/problem/{{ item.id }}/">{{ item.id }}</a></th>
<td><a href="/problem/1/">{{ item.title }}</a></td>
<td><a href="/problem/{{ item.id }}/">{{ item.title }}</a></td>
<td>{{ item.difficulty }}</td>
<td>{{ item|accepted_radio }}</td>
</tr>
@ -38,11 +38,13 @@
<nav>
<ul class="pager">
{% if previous_page %}
<li class="previous"><a href="/problems/{{ previous_page }}/"><span
aria-hidden="true">&larr;</span> 上一页</a></li>
<li class="previous"><a
href="/problems/{{ previous_page }}/{% if keyword %}?keyword={{ keyword }}{% endif %}{% if tag %}?tag={{ tag }}{% endif %}">
<span aria-hidden="true">&larr;</span> 上一页</a></li>
{% endif %}
{% if next_page %}
<li class="next"><a href="/problems/{{ next_page }}/">下一页 <span
<li class="next"><a
href="/problems/{{ next_page }}/{% if keyword %}?keyword={{ keyword }}{% endif %}{% if tag %}?tag={{ tag }}{% endif %}">下一页 <span
aria-hidden="true">&rarr;</span></a></li>
{% endif %}
</ul>

View File

@ -48,28 +48,28 @@
<li><a href="/about/">关于</a></li>
</ul>
{% if request.user.is_authenticated %}
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">
李扬
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">我的提交</a></li>
<li><a href="#">我的资料</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">退出</a></li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">
李扬
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">我的提交</a></li>
<li><a href="#">我的资料</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">退出</a></li>
</ul>
</li>
</ul>
{% else %}
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="/login/" class="dropdown-toggle">
登录
</a>
</li>
</ul>
<li class="dropdown">
<a href="/login/" class="dropdown-toggle">
登录
</a>
</li>
</ul>
{% endif %}
</div>
</div>