mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 08:23:20 +00:00
Merge branch 'dev' into hohoTT-dev
This commit is contained in:
commit
c0d8d900cd
@ -1,3 +1,14 @@
|
|||||||
from django.shortcuts import render
|
# coding=utf-8
|
||||||
|
from django.conf import settings
|
||||||
|
from django.http import HttpResponse, Http404
|
||||||
|
|
||||||
# Create your views here.
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
|
||||||
|
class AdminTemplateView(APIView):
|
||||||
|
def get(self, request, template_dir, template_name):
|
||||||
|
path = settings.TEMPLATE_DIRS[0] + "/admin/" + template_dir + "/" + template_name + ".html"
|
||||||
|
try:
|
||||||
|
return HttpResponse(open(path).read(), content_type="text/html")
|
||||||
|
except IOError:
|
||||||
|
raise Http404
|
||||||
|
@ -6,11 +6,12 @@ from django.views.generic import TemplateView
|
|||||||
from account.views import UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView, \
|
from account.views import UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, UserChangePasswordAPIView, \
|
||||||
EmailCheckAPIView
|
EmailCheckAPIView
|
||||||
from announcement.views import AnnouncementAPIView
|
from announcement.views import AnnouncementAPIView
|
||||||
|
from admin.views import AdminTemplateView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url("^$", TemplateView.as_view(template_name="oj/index.html"), name="index_page"),
|
url("^$", TemplateView.as_view(template_name="oj/index.html"), name="index_page"),
|
||||||
url(r'^docs/', include('rest_framework_swagger.urls')),
|
url(r'^docs/', include('rest_framework_swagger.urls')),
|
||||||
url(r'^admin/$', TemplateView.as_view(template_name="admin/index.html"), name="admin_index_page"),
|
url(r'^admin/$', TemplateView.as_view(template_name="admin/admin.html"), name="admin_spa_page"),
|
||||||
url(r'^login/$', TemplateView.as_view(template_name="oj/account/login.html"), name="user_login_page"),
|
url(r'^login/$', TemplateView.as_view(template_name="oj/account/login.html"), name="user_login_page"),
|
||||||
url(r'^register/$', TemplateView.as_view(template_name="oj/account/register.html"), name="user_register_page"),
|
url(r'^register/$', TemplateView.as_view(template_name="oj/account/register.html"), name="user_register_page"),
|
||||||
url(r'^change_password/$', TemplateView.as_view(template_name="oj/account/change_password.html"), name="user_change_password_page"),
|
url(r'^change_password/$', TemplateView.as_view(template_name="oj/account/change_password.html"), name="user_change_password_page"),
|
||||||
@ -24,4 +25,5 @@ urlpatterns = [
|
|||||||
|
|
||||||
url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), name="add_contest_page"),
|
url(r'^admin/contest/$', TemplateView.as_view(template_name="admin/contest/add_contest.html"), name="add_contest_page"),
|
||||||
url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"),
|
url(r'^problems/$', TemplateView.as_view(template_name="oj/problem/problem_list.html"), name="problem_list_page"),
|
||||||
|
url(r'^admin/template/(?P<template_dir>\w+)/(?P<template_name>\w+).html', AdminTemplateView.as_view(), name="admin_template")
|
||||||
]
|
]
|
||||||
|
31
static/src/js/app/admin/admin.js
Normal file
31
static/src/js/app/admin/admin.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
define("admin", ["jquery", "avalon"], function($, avalon){
|
||||||
|
function li_active(selector){
|
||||||
|
$(selector).attr("class", "list-group-item active");
|
||||||
|
}
|
||||||
|
|
||||||
|
function li_inactive(selector){
|
||||||
|
$(".list-group-item").attr("class", "list-group-item");
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = window.location.hash.substring(1);
|
||||||
|
|
||||||
|
if(hash){
|
||||||
|
li_active("#li-" + hash);
|
||||||
|
}else {
|
||||||
|
li_active("#li-index");
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onhashchange = function() {
|
||||||
|
var hash = window.location.hash.substring(1);
|
||||||
|
if(hash){
|
||||||
|
li_inactive(".list-group-item");
|
||||||
|
li_active("#li-" + hash);
|
||||||
|
vm.template_url = "template/index/" + hash + ".html";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var vm = avalon.define({
|
||||||
|
$id: "admin",
|
||||||
|
template_url: "template/index/index.html"
|
||||||
|
});
|
||||||
|
});
|
@ -2,6 +2,11 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf
|
|||||||
$("#register-form")
|
$("#register-form")
|
||||||
.formValidation({
|
.formValidation({
|
||||||
framework: "bootstrap",
|
framework: "bootstrap",
|
||||||
|
icon: {
|
||||||
|
valid: 'glyphicon glyphicon-ok',
|
||||||
|
invalid: 'glyphicon glyphicon-remove',
|
||||||
|
validating: 'glyphicon glyphicon-refresh'
|
||||||
|
},
|
||||||
fields: {
|
fields: {
|
||||||
username: {
|
username: {
|
||||||
validators: {
|
validators: {
|
||||||
@ -13,8 +18,10 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf
|
|||||||
max: 30,
|
max: 30,
|
||||||
message: '用户名长度必须在3到30位之间'
|
message: '用户名长度必须在3到30位之间'
|
||||||
},
|
},
|
||||||
usernameCheck:{
|
remote: {
|
||||||
message: '用户名已存在'
|
message: "用户名已存在",
|
||||||
|
url: "/api/username_check/",
|
||||||
|
field: 'username'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -50,6 +57,21 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf
|
|||||||
message: "两次输入的密码必须一致"
|
message: "两次输入的密码必须一致"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
validators: {
|
||||||
|
notEmpty: {
|
||||||
|
message: "请填写电子邮箱邮箱地址"
|
||||||
|
},
|
||||||
|
emailAddress: {
|
||||||
|
message: "请填写有效的邮箱地址"
|
||||||
|
},
|
||||||
|
remote: {
|
||||||
|
message: "您已经注册过了",
|
||||||
|
url: "/api/email_check/",
|
||||||
|
field: 'email'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,8 +94,6 @@ require(["jquery", "bs_alert", "csrf", "validation"], function($, bs_alert, csrf
|
|||||||
bs_alert(data.data);
|
bs_alert(data.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
@ -15,6 +15,7 @@ var require = {
|
|||||||
submit_code: "app/oj/problem/submit_code",
|
submit_code: "app/oj/problem/submit_code",
|
||||||
contest: "app/admin/contest/contest",
|
contest: "app/admin/contest/contest",
|
||||||
csrf: "utils/csrf",
|
csrf: "utils/csrf",
|
||||||
|
admin: "app/admin/admin",
|
||||||
|
|
||||||
//formValidation 不要在代码中单独使用,而是使用和修改utils/validation
|
//formValidation 不要在代码中单独使用,而是使用和修改utils/validation
|
||||||
base: "lib/formValidation/base",
|
base: "lib/formValidation/base",
|
||||||
@ -26,8 +27,9 @@ var require = {
|
|||||||
"validator/date": "lib/formValidation/validator/date",
|
"validator/date": "lib/formValidation/validator/date",
|
||||||
"validator/integer": "lib/formValidation/validator/integer",
|
"validator/integer": "lib/formValidation/validator/integer",
|
||||||
"validator/between": "lib/formValidation/validator/between",
|
"validator/between": "lib/formValidation/validator/between",
|
||||||
'validator/confirm':"lib/formValidation/validator/confirm",
|
"validator/confirm":"lib/formValidation/validator/confirm",
|
||||||
"validator/usernameCheck":"lib/formValidation/validator/usernameCheck",
|
"validator/remote":"lib/formValidation/validator/remote",
|
||||||
|
"validator/emailAddress":"lib/formValidation/validator/emailAddress",
|
||||||
//富文本编辑器 不要直接使用,而是使用上面的editor
|
//富文本编辑器 不要直接使用,而是使用上面的editor
|
||||||
simditor: "lib/simditor/simditor",
|
simditor: "lib/simditor/simditor",
|
||||||
"simple-module": "lib/simditor/module",
|
"simple-module": "lib/simditor/module",
|
||||||
|
@ -1,146 +1,46 @@
|
|||||||
/**
|
/**
|
||||||
* remote validator
|
* remote validator
|
||||||
*
|
|
||||||
* @link http://formvalidation.io/validators/remote/
|
|
||||||
* @author https://twitter.com/nghuuphuoc
|
|
||||||
* @copyright (c) 2013 - 2015 Nguyen Huu Phuoc
|
|
||||||
* @license http://formvalidation.io/license/
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function(root, factory) {
|
(function(root, factory) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// AMD module is defined
|
// AMD module is defined
|
||||||
if (typeof define === "function" && define.amd) {
|
if (typeof define === "function" && define.amd) {
|
||||||
define("validator/remote", ["jquery", "base"], factory);
|
define("validator/remote", ["jquery", "base", "csrf"], factory);
|
||||||
} else {
|
} else {
|
||||||
// planted over the root!
|
// planted over the root!
|
||||||
factory(root.jQuery, root.FormValidation);
|
factory(root.jQuery, root.FormValidation);
|
||||||
}
|
}
|
||||||
|
}(this, function ($, FormValidation, csrfHeader) {
|
||||||
}(this, function ($, FormValidation) {
|
|
||||||
FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
|
FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
|
||||||
'en_US': {
|
'en_US': {
|
||||||
remote: {
|
remote: {
|
||||||
'default': 'Please enter a valid value'
|
'default': ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
FormValidation.Validator.remote = {
|
FormValidation.Validator.remote = {
|
||||||
html5Attributes: {
|
|
||||||
message: 'message',
|
|
||||||
name: 'name',
|
|
||||||
type: 'type',
|
|
||||||
url: 'url',
|
|
||||||
data: 'data',
|
|
||||||
delay: 'delay'
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy the timer when destroying the bootstrapValidator (using validator.destroy() method)
|
|
||||||
*/
|
|
||||||
destroy: function(validator, $field, options) {
|
|
||||||
var ns = validator.getNamespace(),
|
|
||||||
timer = $field.data(ns + '.remote.timer');
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
$field.removeData(ns + '.remote.timer');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request a remote server to check the input value
|
|
||||||
*
|
|
||||||
* @param {FormValidation.Base} validator Plugin instance
|
|
||||||
* @param {jQuery} $field Field element
|
|
||||||
* @param {Object} options Can consist of the following keys:
|
|
||||||
* - url {String|Function}
|
|
||||||
* - type {String} [optional] Can be GET or POST (default)
|
|
||||||
* - data {Object|Function} [optional]: By default, it will take the value
|
|
||||||
* {
|
|
||||||
* <fieldName>: <fieldValue>
|
|
||||||
* }
|
|
||||||
* - delay
|
|
||||||
* - name {String} [optional]: Override the field name for the request.
|
|
||||||
* - message: The invalid message
|
|
||||||
* - headers: Additional headers
|
|
||||||
* @returns {Deferred}
|
|
||||||
*/
|
|
||||||
validate: function(validator, $field, options) {
|
validate: function(validator, $field, options) {
|
||||||
var ns = validator.getNamespace(),
|
var dfd = new $.Deferred(), ajaxData = {};
|
||||||
value = validator.getFieldValue($field, 'remote'),
|
ajaxData[options.field] = $field.val();
|
||||||
dfd = new $.Deferred();
|
if ($field.val() === '')
|
||||||
if (value === '') {
|
return true;
|
||||||
dfd.resolve($field, 'remote', { valid: true });
|
var url = options.url;
|
||||||
return dfd;
|
var xhr = $.ajax({
|
||||||
}
|
beforeSend: csrfHeader,
|
||||||
|
url: url,
|
||||||
var name = $field.attr('data-' + ns + '-field'),
|
dataType: 'json',
|
||||||
data = options.data || {},
|
data: ajaxData,
|
||||||
url = options.url,
|
method: "post"
|
||||||
type = options.type || 'GET',
|
});
|
||||||
headers = options.headers || {};
|
xhr.success(function(response) {
|
||||||
|
dfd.resolve($field, 'remote',{valid:!response.data, message:options.msg});
|
||||||
// Support dynamic data
|
})
|
||||||
if ('function' === typeof data) {
|
.error(function(response) {
|
||||||
data = data.call(this, validator);
|
dfd.resolve($field, 'remote', {valid: false});
|
||||||
}
|
});
|
||||||
|
return dfd;
|
||||||
// Parse string data from HTML5 attribute
|
|
||||||
if ('string' === typeof data) {
|
|
||||||
data = JSON.parse(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Support dynamic url
|
|
||||||
if ('function' === typeof url) {
|
|
||||||
url = url.call(this, validator);
|
|
||||||
}
|
|
||||||
|
|
||||||
data[options.name || name] = value;
|
|
||||||
function runCallback() {
|
|
||||||
var xhr = $.ajax({
|
|
||||||
type: type,
|
|
||||||
headers: headers,
|
|
||||||
url: url,
|
|
||||||
dataType: 'json',
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
|
|
||||||
xhr
|
|
||||||
.success(function(response) {
|
|
||||||
response.valid = response.valid === true || response.valid === 'true';
|
|
||||||
dfd.resolve($field, 'remote', response);
|
|
||||||
})
|
|
||||||
.error(function(response) {
|
|
||||||
dfd.resolve($field, 'remote', {
|
|
||||||
valid: false
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
dfd.fail(function() {
|
|
||||||
xhr.abort();
|
|
||||||
});
|
|
||||||
|
|
||||||
return dfd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.delay) {
|
|
||||||
// Since the form might have multiple fields with the same name
|
|
||||||
// I have to attach the timer to the field element
|
|
||||||
if ($field.data(ns + '.remote.timer')) {
|
|
||||||
clearTimeout($field.data(ns + '.remote.timer'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$field.data(ns + '.remote.timer', setTimeout(runCallback, options.delay));
|
|
||||||
return dfd;
|
|
||||||
} else {
|
|
||||||
return runCallback();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return FormValidation.Validator.remote;
|
|
||||||
}));
|
}));
|
||||||
|
146
static/src/js/lib/formValidation/validator/remotex.js
Normal file
146
static/src/js/lib/formValidation/validator/remotex.js
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/**
|
||||||
|
* remote validator
|
||||||
|
*
|
||||||
|
* @link http://formvalidation.io/validators/remote/
|
||||||
|
* @author https://twitter.com/nghuuphuoc
|
||||||
|
* @copyright (c) 2013 - 2015 Nguyen Huu Phuoc
|
||||||
|
* @license http://formvalidation.io/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(root, factory) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// AMD module is defined
|
||||||
|
if (typeof define === "function" && define.amd) {
|
||||||
|
define("validator/remote", ["jquery", "base"], factory);
|
||||||
|
} else {
|
||||||
|
// planted over the root!
|
||||||
|
factory(root.jQuery, root.FormValidation);
|
||||||
|
}
|
||||||
|
|
||||||
|
}(this, function ($, FormValidation) {
|
||||||
|
FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
|
||||||
|
'en_US': {
|
||||||
|
remote: {
|
||||||
|
'default': 'Please enter a valid value'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FormValidation.Validator.remote = {
|
||||||
|
html5Attributes: {
|
||||||
|
message: 'message',
|
||||||
|
name: 'name',
|
||||||
|
type: 'type',
|
||||||
|
url: 'url',
|
||||||
|
data: 'data',
|
||||||
|
delay: 'delay'
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the timer when destroying the bootstrapValidator (using validator.destroy() method)
|
||||||
|
*/
|
||||||
|
destroy: function(validator, $field, options) {
|
||||||
|
var ns = validator.getNamespace(),
|
||||||
|
timer = $field.data(ns + '.remote.timer');
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer);
|
||||||
|
$field.removeData(ns + '.remote.timer');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a remote server to check the input value
|
||||||
|
*
|
||||||
|
* @param {FormValidation.Base} validator Plugin instance
|
||||||
|
* @param {jQuery} $field Field element
|
||||||
|
* @param {Object} options Can consist of the following keys:
|
||||||
|
* - url {String|Function}
|
||||||
|
* - type {String} [optional] Can be GET or POST (default)
|
||||||
|
* - data {Object|Function} [optional]: By default, it will take the value
|
||||||
|
* {
|
||||||
|
* <fieldName>: <fieldValue>
|
||||||
|
* }
|
||||||
|
* - delay
|
||||||
|
* - name {String} [optional]: Override the field name for the request.
|
||||||
|
* - message: The invalid message
|
||||||
|
* - headers: Additional headers
|
||||||
|
* @returns {Deferred}
|
||||||
|
*/
|
||||||
|
validate: function(validator, $field, options) {
|
||||||
|
var ns = validator.getNamespace(),
|
||||||
|
value = validator.getFieldValue($field, 'remote'),
|
||||||
|
dfd = new $.Deferred();
|
||||||
|
if (value === '') {
|
||||||
|
dfd.resolve($field, 'remote', { valid: true });
|
||||||
|
return dfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = $field.attr('data-' + ns + '-field'),
|
||||||
|
data = options.data || {},
|
||||||
|
url = options.url,
|
||||||
|
type = options.type || 'GET',
|
||||||
|
headers = options.headers || {};
|
||||||
|
|
||||||
|
// Support dynamic data
|
||||||
|
if ('function' === typeof data) {
|
||||||
|
data = data.call(this, validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse string data from HTML5 attribute
|
||||||
|
if ('string' === typeof data) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support dynamic url
|
||||||
|
if ('function' === typeof url) {
|
||||||
|
url = url.call(this, validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
data[options.name || name] = value;
|
||||||
|
function runCallback() {
|
||||||
|
var xhr = $.ajax({
|
||||||
|
type: type,
|
||||||
|
headers: headers,
|
||||||
|
url: url,
|
||||||
|
dataType: 'json',
|
||||||
|
data: data
|
||||||
|
});
|
||||||
|
|
||||||
|
xhr
|
||||||
|
.success(function(response) {
|
||||||
|
response.valid = response.valid === true || response.valid === 'true';
|
||||||
|
dfd.resolve($field, 'remote', response);
|
||||||
|
})
|
||||||
|
.error(function(response) {
|
||||||
|
dfd.resolve($field, 'remote', {
|
||||||
|
valid: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
dfd.fail(function() {
|
||||||
|
xhr.abort();
|
||||||
|
});
|
||||||
|
|
||||||
|
return dfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.delay) {
|
||||||
|
// Since the form might have multiple fields with the same name
|
||||||
|
// I have to attach the timer to the field element
|
||||||
|
if ($field.data(ns + '.remote.timer')) {
|
||||||
|
clearTimeout($field.data(ns + '.remote.timer'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$field.data(ns + '.remote.timer', setTimeout(runCallback, options.delay));
|
||||||
|
return dfd;
|
||||||
|
} else {
|
||||||
|
return runCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return FormValidation.Validator.remote;
|
||||||
|
}));
|
@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* usernameCheck validator
|
|
||||||
*/
|
|
||||||
(function(root, factory) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// AMD module is defined
|
|
||||||
if (typeof define === "function" && define.amd) {
|
|
||||||
define("validator/usernameCheck", ["jquery", "base", "csrf"], factory);
|
|
||||||
} else {
|
|
||||||
// planted over the root!
|
|
||||||
factory(root.jQuery, root.FormValidation);
|
|
||||||
}
|
|
||||||
}(this, function ($, FormValidation, csrfHeader) {
|
|
||||||
FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
|
|
||||||
'en_US': {
|
|
||||||
usernameCheck: {
|
|
||||||
'default': 'Please input the same value'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
FormValidation.Validator.usernameCheck = {
|
|
||||||
validate: function(validator, $field, options) {
|
|
||||||
if ($field.val() == '')
|
|
||||||
return true;
|
|
||||||
return !$.ajax({
|
|
||||||
async: false,
|
|
||||||
beforeSend: csrfHeader,
|
|
||||||
url: "/api/username_check/",
|
|
||||||
data: {username: $field.val()},
|
|
||||||
dataType: "json",
|
|
||||||
method: "post",
|
|
||||||
}).responseJSON.data;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}));
|
|
@ -9,6 +9,7 @@ define("validation",
|
|||||||
'validator/integer',
|
'validator/integer',
|
||||||
'validator/between',
|
'validator/between',
|
||||||
'validator/confirm',
|
'validator/confirm',
|
||||||
'validator/usernameCheck'],
|
'validator/remote',
|
||||||
|
'validator/emailAddress'],
|
||||||
function () {
|
function () {
|
||||||
});
|
});
|
122
template/admin/admin.html
Normal file
122
template/admin/admin.html
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="renderer" content="webkit">
|
||||||
|
|
||||||
|
<title>在线评测系统 - 后台管理</title>
|
||||||
|
|
||||||
|
<!-- custom css begin -->
|
||||||
|
{% block css_block %}{% endblock %}
|
||||||
|
<!-- custom css end -->
|
||||||
|
|
||||||
|
<!-- global css begin -->
|
||||||
|
<link href="/static/css/admin.css" rel="stylesheet">
|
||||||
|
<!-- global css end -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- nav begin -->
|
||||||
|
<nav class="navbar navbar-masthead navbar-default navbar-static-top">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
|
||||||
|
aria-expanded="false" aria-controls="navbar">
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<a class="navbar-brand" href="#">qduoj admin</a>
|
||||||
|
</div>
|
||||||
|
<div id="navbar" class="navbar-collapse collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li class="active"><a href="#">主页</a></li>
|
||||||
|
<li><a href="#about">题目</a></li>
|
||||||
|
<li><a href="#contact">提交</a></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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<!-- nav end -->
|
||||||
|
|
||||||
|
<!--browser happy begin -->
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<div class="alert alert-danger text-center" role="alert">
|
||||||
|
当前网页 <strong>不支持</strong> 你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>.
|
||||||
|
</div>
|
||||||
|
<![endif]-->
|
||||||
|
<!-- browser happy end -->
|
||||||
|
|
||||||
|
<div class="container" ms-controller="admin">
|
||||||
|
<div class="row">
|
||||||
|
<!-- admin left begin-->
|
||||||
|
<div class="col-md-2">
|
||||||
|
<ul class="list-group">
|
||||||
|
<li class="list-group-header">List header</li>
|
||||||
|
<li class="list-group-item" id="li-index"><a href="#index">主页</a></li>
|
||||||
|
<li class="list-group-item" id="li-announcement"><a href="#announcement">公告</a></li>
|
||||||
|
<li class="list-group-item"><a href="#">Applications</a></li>
|
||||||
|
<li class="list-group-header">Another list header</li>
|
||||||
|
<li class="list-group-item"><a href="#">Help</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- admin left end -->
|
||||||
|
|
||||||
|
<!-- custom body begin -->
|
||||||
|
<div ms-include-src="template_url"></div>
|
||||||
|
<!-- custom body end -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal fade" id="modal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-sm">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title">提示</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p id="modal-text"></p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/js/config.js"></script>
|
||||||
|
<script src="/static/js/require.js"></script>
|
||||||
|
<script>
|
||||||
|
require(["bootstrap", "admin"]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- footer begin -->
|
||||||
|
<div class="footer">
|
||||||
|
<p class="text-muted text-center">Copyright © 2015 青岛大学信息工程学院 创新实验室</p>
|
||||||
|
</div>
|
||||||
|
<!-- footer end -->
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,4 +0,0 @@
|
|||||||
{% extends "admin_base.html" %}
|
|
||||||
{% block body %}
|
|
||||||
Hello world
|
|
||||||
{% endblock %}
|
|
1
template/admin/index/index.html
Normal file
1
template/admin/index/index.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h1>Hello world</h1>
|
@ -65,14 +65,14 @@
|
|||||||
<![endif]-->
|
<![endif]-->
|
||||||
<!-- browser happy end -->
|
<!-- browser happy end -->
|
||||||
|
|
||||||
<div class="container">
|
<div class="container" ms-controller="admin">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<!-- admin left begin-->
|
<!-- admin left begin-->
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
<li class="list-group-header">List header</li>
|
<li class="list-group-header">List header</li>
|
||||||
<li class="list-group-item active"><a href="#">Home</a></li>
|
<li class="list-group-item" id="li-index"><a href="#index">主页</a></li>
|
||||||
<li class="list-group-item"><a href="#">Library</a></li>
|
<li class="list-group-item" id="li-announcement"><a href="#announcement">公告</a></li>
|
||||||
<li class="list-group-item"><a href="#">Applications</a></li>
|
<li class="list-group-item"><a href="#">Applications</a></li>
|
||||||
<li class="list-group-header">Another list header</li>
|
<li class="list-group-header">Another list header</li>
|
||||||
<li class="list-group-item"><a href="#">Help</a></li>
|
<li class="list-group-item"><a href="#">Help</a></li>
|
||||||
@ -108,7 +108,7 @@
|
|||||||
<script src="/static/js/config.js"></script>
|
<script src="/static/js/config.js"></script>
|
||||||
<script src="/static/js/require.js"></script>
|
<script src="/static/js/require.js"></script>
|
||||||
<script>
|
<script>
|
||||||
require(["bootstrap"]);
|
require(["bootstrap", "admin"]);
|
||||||
</script>
|
</script>
|
||||||
{% block js_block %}{% endblock %}
|
{% block js_block %}{% endblock %}
|
||||||
<!-- footer begin -->
|
<!-- footer begin -->
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
<label for="real_name">真实姓名</label>
|
<label for="real_name">真实姓名</label>
|
||||||
<input type="text" class="form-control input-lg" id="real_name" name="real_name" placeholder="真实姓名">
|
<input type="text" class="form-control input-lg" id="real_name" name="real_name" placeholder="真实姓名">
|
||||||
</div>
|
</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">
|
<div class="form-group">
|
||||||
<label for="password">密码</label>
|
<label for="password">密码</label>
|
||||||
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
|
<input type="password" class="form-control input-lg" id="password" name="password" placeholder="密码">
|
||||||
|
Loading…
Reference in New Issue
Block a user