Browse Source

排名显示昵称

master
richie 5 years ago
parent
commit
0ca735cc07
  1. 16
      modules/api.js
  2. 2
      modules/user.js
  3. 3
      utility.js
  4. 4
      views/index.ejs
  5. 2
      views/ranklist.ejs
  6. 174
      views/sign_up.ejs
  7. 6
      views/user.ejs
  8. 234
      views/user_edit.ejs

16
modules/api.js

@ -72,6 +72,14 @@ app.post('/api/sign_up', async (req, res) => {
user = await User.findOne({ where: { email: req.body.email } }); user = await User.findOne({ where: { email: req.body.email } });
if (user) throw 2009; if (user) throw 2009;
if (!req.body.nickname) {
res.send({
error_code: 2300,
message : "昵称不能为空"
});
return;
}
// Because the salt is "syzoj2_xxx" and the "syzoj2_xxx" 's md5 is"59cb..." // Because the salt is "syzoj2_xxx" and the "syzoj2_xxx" 's md5 is"59cb..."
// the empty password 's md5 will equal "59cb.." // the empty password 's md5 will equal "59cb.."
@ -79,6 +87,13 @@ app.post('/api/sign_up', async (req, res) => {
if (req.body.password === syzoj2_xxx_md5) throw 2007; if (req.body.password === syzoj2_xxx_md5) throw 2007;
if (!(req.body.email = req.body.email.trim())) throw 2006; if (!(req.body.email = req.body.email.trim())) throw 2006;
if (!syzoj.utils.isValidUsername(req.body.username)) throw 2002; if (!syzoj.utils.isValidUsername(req.body.username)) throw 2002;
if (!syzoj.utils.isValidEmail(req.body.email)) {
res.send({
error_code: 2300,
message : "邮箱需要以" + syzoj.config.email_suffix + "结尾"
});
return;
}
if (syzoj.config.register_mail) { if (syzoj.config.register_mail) {
let sendObj = { let sendObj = {
@ -110,6 +125,7 @@ app.post('/api/sign_up', async (req, res) => {
user = await User.create({ user = await User.create({
username: req.body.username, username: req.body.username,
password: req.body.password, password: req.body.password,
nickname:req.body.nickname,
email: req.body.email, email: req.body.email,
is_show: syzoj.config.default.user.show, is_show: syzoj.config.default.user.show,
rating: syzoj.config.default.user.rating, rating: syzoj.config.default.user.rating,

2
modules/user.js

@ -175,6 +175,8 @@ app.post('/user/:id/edit', async (req, res) => {
user.username = req.body.username; user.username = req.body.username;
user.email = req.body.email; user.email = req.body.email;
} }
if (!req.body.nickname) throw new ErrorMessage('昵称不能为空。');
user.nickname = req.body.nickname;
if (res.locals.user && res.locals.user.is_admin) { if (res.locals.user && res.locals.user.is_admin) {
if (!req.body.privileges) { if (!req.body.privileges) {

3
utility.js

@ -270,6 +270,9 @@ module.exports = {
isValidUsername(s) { isValidUsername(s) {
return RegExp(syzoj.config.username_regex).test(s); return RegExp(syzoj.config.username_regex).test(s);
}, },
isValidEmail(s) {
return s.endsWith(syzoj.config.email_suffix || "");
},
locks: [], locks: [],
lock(key, cb) { lock(key, cb) {
let s = JSON.stringify(key); let s = JSON.stringify(key);

4
views/index.ejs

@ -28,7 +28,7 @@
<thead> <thead>
<tr> <tr>
<th style="width: 50px; ">#</th> <th style="width: 50px; ">#</th>
<th style="width: 170px; ">用户</th> <th style="width: 170px; ">用户</th>
<th style="width: 170px; ">积分</th> <th style="width: 170px; ">积分</th>
<th>个性签名</th> <th>个性签名</th>
</tr> </tr>
@ -53,7 +53,7 @@
%> %>
<tr> <tr>
<td><b><%= i %></b></td> <td><b><%= i %></b></td>
<td><a href="<%= syzoj.utils.makeUrl(['user', user.id]) %>"><%= user.username %></a><% if (user.nameplate) { %><%- user.nameplate %><% } %></td> <td><a href="<%= syzoj.utils.makeUrl(['user', user.id]) %>"><%= user.nickname %></a><% if (user.nameplate) { %><%- user.nameplate %><% } %></td>
<td><%= user.rating %></td> <td><%= user.rating %></td>
<td style="font-content"> <td style="font-content">
<script id="user-infomation-script-<%= i %>"> <script id="user-infomation-script-<%= i %>">

2
views/ranklist.ejs

@ -42,7 +42,7 @@
<td><a href="<%= syzoj.utils.makeUrl(['user', user.id]) %>"><%= user.username %></a><% if (user.nameplate) { %><%- user.nameplate %><% } %></td> <td><a href="<%= syzoj.utils.makeUrl(['user', user.id]) %>"><%= user.username %></a><% if (user.nameplate) { %><%- user.nameplate %><% } %></td>
<td><%= user.ac_num %></td> <td><%= user.ac_num %></td>
<td><%= user.submit_num %></td> <td><%= user.submit_num %></td>
<td><%= user.submit_num == 0 ? 0 : Math.round(user.ac_num / user.submit_num * 10000) / 100.00 + "%" %></td> <td><%= user.ac_num && user.submit_num ? Math.round(user.ac_num / user.submit_num * 10000) / 100.00 + "%" : 0%></td>
<td><%= user.rating %></td> <td><%= user.rating %></td>
</tr> </tr>
<% } %> <% } %>

174
views/sign_up.ejs

@ -5,110 +5,118 @@
<div class="ui error message" id="error" data-am-alert hidden> <div class="ui error message" id="error" data-am-alert hidden>
<p id="error_info"></p> <p id="error_info"></p>
</div> </div>
<form class="ui form"> <form class="ui form">
<div class="field"> <div class="field">
<label for="username">用户名</label> <label for="username">用户名</label>
<input type="text" placeholder="" id="username"> <input type="text" placeholder="" id="username">
</div> </div>
<div class="field"> <div class="field">
<label for="email">邮箱</label> <label for="nickname">昵称</label>
<input type="email" placeholder="" id="email"> <input type="text" placeholder="" id="nickname">
</div> </div>
<div class="two fields"> <div class="field">
<div class="field"> <label for="email">邮箱</label>
<label class="ui header">密码</label> <input type="email" placeholder="" id="email">
<input type="password" placeholder="" id="password1"> </div>
</div> <div class="two fields">
<div class="field"> <div class="field">
<label class="ui header">确认密码</label> <label class="ui header">密码</label>
<input type="password" placeholder="" id="password2"> <input type="password" placeholder="" id="password1">
</div> </div>
</div> <div class="field">
<a id="sign_up" class="ui button" href="javascript:submit();">注册</a> <label class="ui header">确认密码</label>
</form> <input type="password" placeholder="" id="password2">
</div>
</div>
<a id="sign_up" class="ui button" href="javascript:submit();">注册</a>
</form>
</div> </div>
<script src="<%- lib('blueimp-md5/2.10.0/js/md5.min.js') %>"></script> <script src="<%- lib('blueimp-md5/2.10.0/js/md5.min.js') %>"></script>
<script type="text/javascript"> <script type="text/javascript">
function show_error(error) { function show_error(error) {
$("#error_info").text(error); $("#error_info").text(error);
$("#error").show(); $("#error").show();
} }
function success() { function success() {
alert("注册成功!"); alert("注册成功!");
window.location.href = location.protocol + '//' + location.host + <%- serializejs(req.query.url || '/') %>; window.location.href = location.protocol + '//' + location.host + <%- serializejs(req.query.url || '/') %>;
} }
function mail_required() { function mail_required() {
alert("注册确认邮件已经发送到您的邮箱的垃圾箱,点击邮件内的链接即可完成注册。"); alert("注册确认邮件已经发送到您的邮箱的垃圾箱,点击邮件内的链接即可完成注册。");
var s = $("#email").val(); var s = $("#email").val();
var mailWebsite = 'https://mail.' + s.substring(s.indexOf('@') + 1, s.length); var mailWebsite = 'https://mail.' + s.substring(s.indexOf('@') + 1, s.length);
if (mailWebsite === 'https://mail.gmail.com') mailWebsite = 'https://mail.google.com'; if (mailWebsite === 'https://mail.gmail.com') mailWebsite = 'https://mail.google.com';
window.location.href = mailWebsite; window.location.href = mailWebsite;
} }
function submit() { function submit() {
if ($("#password1").val() != $("#password2").val()) { if ($("#password1").val() != $("#password2").val()) {
show_error("两次输入的密码不一致"); show_error("两次输入的密码不一致");
return; return;
} }
password = md5($("#password1").val() + "syzoj2_xxx") password = md5($("#password1").val() + "syzoj2_xxx")
$("#sign_up").addClass("loading"); $("#sign_up").addClass("loading");
$.ajax({ $.ajax({
url: '/api/sign_up', url: '/api/sign_up',
type: 'POST', type: 'POST',
async: true, async: true,
data: { data: {
username: $("#username").val(), username: $("#username").val(),
password: password, nickname: $("#nickname").val(),
email: $("#email").val(), password: password,
prevUrl: <%- serializejs(req.query.url || '/') %> email: $("#email").val(),
}, prevUrl: <%- serializejs(req.query.url || '/') %>
success: function(data) { },
error_code = data.error_code; success: function (data) {
switch(error_code){ error_code = data.error_code;
case 2001: switch (error_code) {
show_error("服务器未收到数据"); case 2001:
break; show_error("服务器未收到数据");
case 2005: break;
case 2002: case 2005:
show_error("用户名需要大于 3 个字符小于 16 个字符,仅允许字母数字和下划线"); case 2002:
break; show_error("用户名仅允许字母数字和下划线和点");
case 2007: break;
case 2003: case 2007:
show_error("密码不得为空"); case 2003:
break; show_error("密码不得为空");
case 2004: break;
case 2006: case 2004:
show_error("请输入正确的邮箱"); case 2006:
break; show_error("请输入正确的邮箱");
case 2008: break;
show_error("已经有人用过这个用户名了"); case 2008:
break; show_error("已经有人用过这个用户名了");
case 2009: break;
show_error("邮箱地址已被占用"); case 2009:
break; show_error("邮箱地址已被占用");
case 2010: break;
show_error("验证邮件发送失败:\n" + data.message); case 2010:
break; show_error("验证邮件发送失败:\n" + data.message);
case 1: break;
success(); case 2300:
break; show_error(data.message);
case 2: break;
mail_required(); case 1:
break; success();
default: break;
show_error("未知错误:" + JSON.stringify(data)); case 2:
break; mail_required();
} break;
$("#sign_up").removeClass("loading"); default:
}, show_error("未知错误:" + JSON.stringify(data));
error: function(XMLHttpRequest, textStatus, errorThrown) { break;
alert(XMLHttpRequest.responseText);
show_error("未知错误");
$("#sign_up").removeClass("loading");
} }
$("#sign_up").removeClass("loading");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.responseText);
show_error("未知错误");
$("#sign_up").removeClass("loading");
}
}); });
} }
</script> </script>
<% include footer %> <% include footer %>

6
views/user.ejs

@ -50,6 +50,12 @@
<div class="ui bottom attached segment"><%= show_user.username %><% if (show_user.nameplate) { %><%- show_user.nameplate %><% } %></div> <div class="ui bottom attached segment"><%= show_user.username %><% if (show_user.nameplate) { %><%- show_user.nameplate %><% } %></div>
</div> </div>
</div> </div>
<div class="row">
<div class="column">
<h4 class="ui top attached block header">昵称</h4>
<div class="ui bottom attached segment"><%= show_user.nickname %></div>
</div>
</div>
<% if (show_user.emailVisible) { %> <% if (show_user.emailVisible) { %>
<div class="row"> <div class="row">
<div class="column"> <div class="column">

234
views/user_edit.ejs

@ -2,58 +2,79 @@
<% include header %> <% include header %>
<% include monaco-editor %> <% include monaco-editor %>
<div class="padding"> <div class="padding">
<div class="ui <% if (error_info === '') { %>success<% } else { %>error<% } %> message" id="error" <% if (error_info === null) { %>hidden<% } %>> <div class="ui <% if (error_info === '') { %>success<% } else { %>error<% } %> message" id="error"
<% if (error_info !== null) { <% if (error_info === null) { %>hidden
if (error_info === '') error_info = '修改成功。'; <% } %>
%> >
<p id="error_info"><%= error_info %></p> <% if (error_info !== null) {
<% } %> if (error_info === '') error_info = '修改成功。';
</div> %>
<form id="form" action="<%= syzoj.utils.makeUrl(['user', edited_user.id, 'edit']) %>" method="post" onsubmit="return check()"> <p id="error_info"><%= error_info %></p>
<div class="ui form"> <% } %>
</div>
<form id="form" action="<%= syzoj.utils.makeUrl(['user', edited_user.id, 'edit']) %>" method="post"
onsubmit="return check()">
<div class="ui form">
<div class="field"> <div class="field">
<label for="username">用户名</label> <label for="username">用户名</label>
<input type="text" id="username" name="username" value="<%= edited_user.username %>"<% if (!user.allowedManage) { %> readonly<% } %>> <input type="text" id="username" name="username" value="<%= edited_user.username %>"
</div> <% if (!user.allowedManage) { %> readonly
<% } %>
>
</div>
<div class="field"> <div class="field">
<label for="sex">性别</label> <label for="sex">性别</label>
<select class="ui dropdown" name="sex"> <select class="ui dropdown" name="sex">
<option value="0" <%= edited_user.sex == 0 ? 'selected': '' %>>其它</option> <option value="0" <%= edited_user.sex == 0 ? 'selected' : '' %>>其它</option>
<option value="1" <%= edited_user.sex == 1 ? 'selected': '' %>>男</option> <option value="1" <%= edited_user.sex == 1 ? 'selected' : '' %>>男</option>
<option value="-1" <%= edited_user.sex == -1 ? 'selected': '' %>>女</option> <option value="-1" <%= edited_user.sex == -1 ? 'selected' : '' %>>女</option>
</select> </select>
</div> </div>
<div class="field"> <div class="field">
<label for="email">Email</label> <label for="email">Email</label>
<input class="font-content" type="email" id="email" name="email" value="<%= edited_user.email %>"<% if (!user.allowedManage) { %> readonly<% } %>> <input class="font-content" type="email" id="email" name="email" value="<%= edited_user.email %>"
</div> <% if (!user.allowedManage) { %> readonly
<% } %>
>
</div>
<div class="inline field"> <div class="inline field">
<label class="ui header">公开 Email</label> <label class="ui header">公开 Email</label>
<div class="ui toggle checkbox"> <div class="ui toggle checkbox">
<input id="public_email" name="public_email" type="checkbox" <% if (edited_user.public_email) { %> checked<% } %>> <input id="public_email" name="public_email" type="checkbox"
<% if (edited_user.public_email) { %> checked
<% } %>
>
<label> </label> <label> </label>
</div> </div>
</div> </div>
<div class="inline field"> <div class="inline field">
<label class="ui header">默认显示格式化后的代码(如果可用)</label> <label class="ui header">默认显示格式化后的代码(如果可用)</label>
<div class="ui toggle checkbox"> <div class="ui toggle checkbox">
<input id="prefer_formatted_code" name="prefer_formatted_code" type="checkbox" <% if (edited_user.prefer_formatted_code) { %> checked<% } %>> <input id="prefer_formatted_code" name="prefer_formatted_code" type="checkbox"
<% if (edited_user.prefer_formatted_code) { %> checked
<% } %>
>
<label> </label> <label> </label>
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label for="information">个性签名</label> <label for="information">个性签名</label>
</div> </div>
</div>
<div class="editor editor-with-border" id="information" style="width: 100%; height: 100px; margin-bottom: 1em; ">
<%- this.showLoadingEditor(); %>
</div>
<input type="hidden" name="information">
<div class="ui form">
<div class="field">
<label class="ui header">昵称</label>
<input type="text" placeholder="昵称" name="nickname" value="<%= edited_user.nickname %>" id="nickname">
</div> </div>
<div class="editor editor-with-border" id="information" style="width: 100%; height: 100px; margin-bottom: 1em; ">
<%- this.showLoadingEditor(); %>
</div>
<input type="hidden" name="information">
<div class="ui form">
<div class="field"> <div class="field">
<label class="ui header">密码</label> <label class="ui header">密码</label>
<input type="password" placeholder="原密码(留空则不修改)" name="old_password" id="old_password"> <input type="password" placeholder="原密码(留空则不修改)" name="old_password" id="old_password">
</div> </div>
<div class="two fields" id="new_password_field"> <div class="two fields" id="new_password_field">
@ -70,95 +91,114 @@
<div class="inline field"> <div class="inline field">
<label class="ui header">权限</label> <label class="ui header">权限</label>
<div class="ui toggle disabled checkbox" style="margin-right: 20px; "> <div class="ui toggle disabled checkbox" style="margin-right: 20px; ">
<input disabled="disabled" type="checkbox" <% if (edited_user.is_admin) { %> checked<% } %>> <input disabled="disabled" type="checkbox"
<% if (edited_user.is_admin) { %> checked
<% } %>
>
<label>全站管理员</label> <label>全站管理员</label>
</div> </div>
<div class="ui toggle <% if (!allowedManagePrivilege) { %>disabled <% } %>checkbox checkbox_privilege" data-name="manage_problem" style="margin-right: 20px; "> <div class="ui toggle <% if (!allowedManagePrivilege) { %>disabled <% } %>checkbox checkbox_privilege"
<input <% if (!allowedManagePrivilege) { %>disabled="disabled" <% } %>type="checkbox"<% if (edited_user.privileges.includes('manage_problem')) { %> checked<% } %>> data-name="manage_problem" style="margin-right: 20px; ">
<input <% if (!allowedManagePrivilege) { %>disabled="disabled" <% } %>type="checkbox"
<% if (edited_user.privileges.includes('manage_problem')) { %> checked
<% } %>
>
<label>管理题目</label> <label>管理题目</label>
</div> </div>
<div class="ui toggle <% if (!allowedManagePrivilege) { %>disabled <% } %>checkbox checkbox_privilege" data-name="manage_problem_tag" style="margin-right: 20px; "> <div class="ui toggle <% if (!allowedManagePrivilege) { %>disabled <% } %>checkbox checkbox_privilege"
<input <% if (!allowedManagePrivilege) { %>disabled="disabled" <% } %>type="checkbox"<% if (edited_user.privileges.includes('manage_problem_tag')) { %> checked<% } %>> data-name="manage_problem_tag" style="margin-right: 20px; ">
<input <% if (!allowedManagePrivilege) { %>disabled="disabled" <% } %>type="checkbox"
<% if (edited_user.privileges.includes('manage_problem_tag')) { %> checked
<% } %>
>
<label>管理题目标签</label> <label>管理题目标签</label>
</div> </div>
<div class="ui toggle <% if (!allowedManagePrivilege) { %>disabled <% } %>checkbox checkbox_privilege" data-name="manage_user"> <div class="ui toggle <% if (!allowedManagePrivilege) { %>disabled <% } %>checkbox checkbox_privilege"
<input <% if (!allowedManagePrivilege) { %>disabled="disabled" <% } %>type="checkbox"<% if (edited_user.privileges.includes('manage_user')) { %> checked<% } %>> data-name="manage_user">
<input <% if (!allowedManagePrivilege) { %>disabled="disabled" <% } %>type="checkbox"
<% if (edited_user.privileges.includes('manage_user')) { %> checked
<% } %>
>
<label>管理用户</label> <label>管理用户</label>
</div> </div>
</div> </div>
<div style="text-align: center; margin-top: 30px; "> <div style="text-align: center; margin-top: 30px; ">
<button id="submit_button" type="submit" class="ui disabled blue labeled icon button"><i class="ui icon edit"></i>修改</button> <button id="submit_button" type="submit" class="ui disabled blue labeled icon button"><i
<a href="<%= syzoj.utils.makeUrl(['user', edited_user.id]) %>" class="ui labeled icon button"><i class="ui icon angle left"></i>返回</a> class="ui icon edit"></i>修改
</button>
<a href="<%= syzoj.utils.makeUrl(['user', edited_user.id]) %>" class="ui labeled icon button"><i
class="ui icon angle left"></i>返回</a>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
<script> <script>
var bakDefine = define; var bakDefine = define;
define = undefined; define = undefined;
</script> </script>
<script src="<%- lib('blueimp-md5/2.10.0/js/md5.min.js') %>"></script> <script src="<%- lib('blueimp-md5/2.10.0/js/md5.min.js') %>"></script>
<script> <script>
define = bakDefine; define = bakDefine;
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
var editors = { var editors = {
information: { defaultValue: <%- serializejs(edited_user.information) %> }, information: {defaultValue: <%- serializejs(edited_user.information) %> },
}; };
window.onEditorLoaded(function () { window.onEditorLoaded(function () {
for (var name in editors) { for (var name in editors) {
var editor = editors[name]; var editor = editors[name];
var editorElement = document.getElementById(name); var editorElement = document.getElementById(name);
var input = document.getElementsByName(name)[0]; var input = document.getElementsByName(name)[0];
editor.editor = window.createMarkdownEditor(editorElement, editor.defaultValue, input); editor.editor = window.createMarkdownEditor(editorElement, editor.defaultValue, input);
} }
$('#submit_button').removeClass('disabled');
});
function make_md5(tag) { $('#submit_button').removeClass('disabled');
if (tag.val()) { });
tag.val(md5(tag.val() + "syzoj2_xxx"));
}
}
function check() {
old_password = $("#old_password");
password1 = $("#password1");
password2 = $("#password2");
if ($("#old_password").val() && password1.val() != password2.val()) {
$("#error").removeClass("success");
$("#error").removeClass("error");
$("#error").addClass("error");
$("#error_info").html("两次输入的密码不一致。");
$("#error").show();
return false;
}
make_md5(old_password);
make_md5(password1);
make_md5(password2);
<% if (allowedManagePrivilege) { %> function make_md5(tag) {
$('.checkbox_privilege').each(function () { if (tag.val()) {
if ($(this).checkbox('is checked')) { tag.val(md5(tag.val() + "syzoj2_xxx"));
var name = $(this).data('name'); }
}
var elem = document.createElement('input'); function check() {
elem.type = 'hidden'; old_password = $("#old_password");
elem.value = name; password1 = $("#password1");
elem.name = 'privileges'; password2 = $("#password2");
document.getElementById('form').appendChild(elem); if ($("#old_password").val() && password1.val() != password2.val()) {
$("#error").removeClass("success");
$("#error").removeClass("error");
$("#error").addClass("error");
$("#error_info").html("两次输入的密码不一致。");
$("#error").show();
return false;
} }
}); make_md5(old_password);
<% } %> make_md5(password1);
make_md5(password2);
<% if (allowedManagePrivilege) { %>
$('.checkbox_privilege').each(function () {
if ($(this).checkbox('is checked')) {
var name = $(this).data('name');
return true; var elem = document.createElement('input');
} elem.type = 'hidden';
elem.value = name;
elem.name = 'privileges';
document.getElementById('form').appendChild(elem);
}
});
<% } %>
return true;
}
</script> </script>
<script> <script>
$(function () { $(function () {
$('.ui.dropdown:not(.simple)').dropdown(); $('.ui.dropdown:not(.simple)').dropdown();
}); });
</script> </script>
<% include footer %> <% include footer %>

Loading…
Cancel
Save