feat(web): add realname

This commit is contained in:
Baoshuo Ren 2022-03-17 18:26:29 +08:00
parent 1bc7762be6
commit 71a82c3a28
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
7 changed files with 90 additions and 16 deletions

View File

@ -195,7 +195,7 @@ UNLOCK TABLES;
CREATE TABLE `contests_asks` ( CREATE TABLE `contests_asks` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`contest_id` int(11) NOT NULL, `contest_id` int(11) NOT NULL,
`username` varchar(20) NOT NULL, `username` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`question` text NOT NULL, `question` text NOT NULL,
`answer` text NOT NULL, `answer` text NOT NULL,
`post_time` datetime NOT NULL, `post_time` datetime NOT NULL,
@ -245,7 +245,7 @@ UNLOCK TABLES;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */; /*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `contests_permissions` ( CREATE TABLE `contests_permissions` (
`username` varchar(20) NOT NULL, `username` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`contest_id` int(11) NOT NULL, `contest_id` int(11) NOT NULL,
PRIMARY KEY (`username`,`contest_id`) PRIMARY KEY (`username`,`contest_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
@ -289,7 +289,7 @@ UNLOCK TABLES;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */; /*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `contests_registrants` ( CREATE TABLE `contests_registrants` (
`username` varchar(20) NOT NULL, `username` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`contest_id` int(11) NOT NULL, `contest_id` int(11) NOT NULL,
`has_participated` tinyint(1) NOT NULL, `has_participated` tinyint(1) NOT NULL,
`rank` int(11) NOT NULL, `rank` int(11) NOT NULL,
@ -500,7 +500,7 @@ UNLOCK TABLES;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */; /*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `problems_permissions` ( CREATE TABLE `problems_permissions` (
`username` varchar(20) NOT NULL, `username` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`problem_id` int(11) NOT NULL, `problem_id` int(11) NOT NULL,
PRIMARY KEY (`username`,`problem_id`) PRIMARY KEY (`username`,`problem_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
@ -616,7 +616,8 @@ UNLOCK TABLES;
/*!40101 SET character_set_client = utf8mb4 */; /*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_info` ( CREATE TABLE `user_info` (
`usergroup` char(1) NOT NULL DEFAULT 'U', `usergroup` char(1) NOT NULL DEFAULT 'U',
`username` varchar(20) NOT NULL, `username` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`realname` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`email` varchar(50) NOT NULL, `email` varchar(50) NOT NULL,
`password` char(32) NOT NULL, `password` char(32) NOT NULL,
`svn_password` char(10) NOT NULL, `svn_password` char(10) NOT NULL,

View File

@ -158,6 +158,9 @@
$asrc = HTML::avatar_addr($poster, 80); $asrc = HTML::avatar_addr($poster, 80);
$replies = DB::selectAll("select id, poster, content, post_time from blogs_comments where reply_id = {$comment['id']} order by id"); $replies = DB::selectAll("select id, poster, content, post_time from blogs_comments where reply_id = {$comment['id']} order by id");
foreach ($replies as $idx => $reply) {
$replies[$idx]['poster_realname'] = queryUser($reply['poster'])['realname'];
}
$replies_json = json_encode($replies); $replies_json = json_encode($replies);
?> ?>
<div id="comment-<?= $comment['id'] ?>" class="list-group-item"> <div id="comment-<?= $comment['id'] ?>" class="list-group-item">

View File

@ -6,6 +6,34 @@
become403Page(); become403Page();
} }
$change_realname_form = new UOJForm('change_realname');
$change_realname_form->submit_button_config['align'] = 'compressed';
$change_realname_form->addInput('r_username', 'text', '用户名', '',
function ($r_username) {
if (!validateUsername($r_username)) {
return '用户名不合法';
}
if (!queryUser($r_username)) {
return '用户不存在';
}
return '';
},
null
);
$change_realname_form->addInput('r_realname', 'text', '真实姓名', '',
function ($r_realname) {
return '';
},
null
);
$change_realname_form->handle = function() {
$r_username = $_POST['r_username'];
$r_realname = $_POST['r_realname'];
DB::query("update user_info set realname = '$r_realname' where username = '$r_username'");
};
$change_realname_form->runAtServer();
$user_form = new UOJForm('user'); $user_form = new UOJForm('user');
$user_form->addInput('username', 'text', '用户名', '', $user_form->addInput('username', 'text', '用户名', '',
function ($username) { function ($username) {
@ -368,6 +396,8 @@ EOD;
<div class="col-sm-9"> <div class="col-sm-9">
<?php if ($cur_tab === 'users'): ?> <?php if ($cur_tab === 'users'): ?>
<?php $user_form->printHTML(); ?> <?php $user_form->printHTML(); ?>
<h3>修改用户真实姓名</h3>
<?php $change_realname_form->printHTML(); ?>
<h3>封禁名单</h3> <h3>封禁名单</h3>
<?php echoLongTable($banlist_cols, 'user_info', "usergroup='B'", '', $banlist_header_row, $banlist_print_row, $banlist_config) ?> <?php echoLongTable($banlist_cols, 'user_info', "usergroup='B'", '', $banlist_header_row, $banlist_print_row, $banlist_config) ?>
<?php elseif ($cur_tab === 'blogs'): ?> <?php elseif ($cur_tab === 'blogs'): ?>

View File

@ -32,7 +32,7 @@
<img class="media-object img-thumbnail d-block mx-auto" alt="<?= $user['username'] ?> Avatar" src="<?= HTML::avatar_addr($user, 256) ?>" /> <img class="media-object img-thumbnail d-block mx-auto" alt="<?= $user['username'] ?> Avatar" src="<?= HTML::avatar_addr($user, 256) ?>" />
</div> </div>
<div class="col-md-8 order-md-1"> <div class="col-md-8 order-md-1">
<h2><span class="uoj-honor"><?= $user['username'] ?></span> <span><strong style="<?= $col_sex ?>"><?= $esc_sex ?></strong></span></h2> <h2><span class="uoj-honor" data-realname="<?= $user['realname'] ?>"><?= $user['username'] ?></span> <span><strong style="<?= $col_sex ?>"><?= $esc_sex ?></strong></span></h2>
<div class="list-group"> <div class="list-group">
<div class="list-group-item"> <div class="list-group-item">
<h4 class="list-group-item-heading"><?= UOJLocale::get('email') ?></h4> <h4 class="list-group-item-heading"><?= UOJLocale::get('email') ?></h4>

View File

@ -82,7 +82,7 @@ function queryContestData($contest, $config = array()) {
} }
$people = []; $people = [];
$result = DB::query("select username from contests_registrants where contest_id = {$contest['id']} and has_participated = 1"); $result = DB::query("select a.username, b.realname from contests_registrants a inner join user_info b on a.username = b.username where a.contest_id = {$contest['id']} and a.has_participated = 1");
while ($row = DB::fetch($result, MYSQLI_NUM)) { while ($row = DB::fetch($result, MYSQLI_NUM)) {
$people[] = $row; $people[] = $row;
} }
@ -108,7 +108,7 @@ function calcStandings($contest, $contest_data, &$score, &$standings, $update_co
$score[$submission[2]][$submission[3]] = array($submission[4], $penalty, $submission[0]); $score[$submission[2]][$submission[3]] = array($submission[4], $penalty, $submission[0]);
} }
// standings: rank => score, penalty, [username], virtual_rank // standings: rank => score, penalty, [username, realname], virtual_rank
$standings = array(); $standings = array();
foreach ($contest_data['people'] as $person) { foreach ($contest_data['people'] as $person) {
$cur = array(0, 0, $person); $cur = array(0, 0, $person);

View File

@ -76,13 +76,34 @@ function become403Page() {
function getUserLink($username) { function getUserLink($username) {
if (validateUsername($username) && ($user = queryUser($username))) { if (validateUsername($username) && ($user = queryUser($username))) {
return '<span class="uoj-username">'.$username.'</span>'; $realname = $user['realname'];
if ($realname == "") {
return '<span class="uoj-username">'.$username.'</span>';
} else {
return '<span class="uoj-username" data-realname="'.$realname.'">'.$username.'</span>';
}
} else { } else {
$esc_username = HTML::escape($username); $esc_username = HTML::escape($username);
return '<span>'.$esc_username.'</span>'; return '<span>'.$esc_username.'</span>';
} }
} }
function getUserName($username, $realname = null) {
if ($realname == null) {
if (validateUsername($username) && ($user = queryUser($username))) {
$realname = $user['realname'];
}
}
if ($realname == "") {
return "$username";
} else {
return "$username ($realname)";
}
}
function getProblemLink($problem, $problem_title = '!title_only') { function getProblemLink($problem, $problem_title = '!title_only') {
if ($problem_title == '!title_only') { if ($problem_title == '!title_only') {
$problem_title = $problem['title']; $problem_title = $problem['title'];

View File

@ -118,7 +118,7 @@ function getColOfScore(score) {
} }
} }
function getUserLink(username) { function getUserLink(username, realname) {
if (!username) { if (!username) {
return ''; return '';
} }
@ -126,9 +126,12 @@ function getUserLink(username) {
if (username.charAt(0) == '@') { if (username.charAt(0) == '@') {
username = username.substr(1); username = username.substr(1);
} }
if (realname) {
text = text + ' (' + realname + ')';
}
return '<a class="uoj-username" href="' + uojHome + '/user/profile/' + username + '">' + text + '</a>'; return '<a class="uoj-username" href="' + uojHome + '/user/profile/' + username + '">' + text + '</a>';
} }
function getUserSpan(username) { function getUserSpan(username, realname) {
if (!username) { if (!username) {
return ''; return '';
} }
@ -136,18 +139,33 @@ function getUserSpan(username) {
if (username.charAt(0) == '@') { if (username.charAt(0) == '@') {
username = username.substr(1); username = username.substr(1);
} }
if (realname) {
text = text + ' (' + realname + ')';
}
return '<span class="uoj-username">' + text + '</span>'; return '<span class="uoj-username">' + text + '</span>';
} }
function replaceWithHighlightUsername() { function replaceWithHighlightUsername() {
var username = $(this).text(); var username = $(this).text();
var realname = $(this).data("realname");
if ($(this).data("link") != 0) { if ($(this).data("link") != 0) {
$(this).replaceWith(getUserLink(username)); $(this).replaceWith(getUserLink(username, realname));
} else { } else {
$(this).replaceWith(getUserSpan(username)); $(this).replaceWith(getUserSpan(username, realname));
} }
} }
$.fn.uoj_honor = function() {
return this.each(function() {
var honor = $(this).text();
var realname = $(this).data("realname");
if (realname) {
honor = honor + ' (' + realname + ')';
}
$(this).css('color', '#007bff').html(honor);
});
}
function showErrorHelp(name, err) { function showErrorHelp(name, err) {
if (err) { if (err) {
$('#div-' + name).addClass('has-error'); $('#div-' + name).addClass('has-error');
@ -364,6 +382,7 @@ $(document).ready(function() {
$.fn.uoj_highlight = function() { $.fn.uoj_highlight = function() {
return $(this).each(function() { return $(this).each(function() {
$(this).find("span.uoj-username").each(replaceWithHighlightUsername); $(this).find("span.uoj-username").each(replaceWithHighlightUsername);
$(this).find(".uoj-honor").uoj_honor();
$(this).find(".uoj-score").each(function() { $(this).find(".uoj-score").each(function() {
var score = parseInt($(this).text()); var score = parseInt($(this).text());
var maxscore = parseInt($(this).data('max')); var maxscore = parseInt($(this).data('max'));
@ -1010,7 +1029,7 @@ function showCommentReplies(id, replies) {
function(reply) { function(reply) {
return $('<tr id="' + 'comment-' + reply.id + '" />').append( return $('<tr id="' + 'comment-' + reply.id + '" />').append(
$('<td />').append( $('<td />').append(
$('<div class="comtbox6">' + getUserLink(reply.poster) + '' + reply.content + '</div>') $('<div class="comtbox6">' + getUserLink(reply.poster, reply.poster_realname) + '' + reply.content + '</div>')
).append( ).append(
$('<ul class="text-right list-inline bot-buffer-no" />').append( $('<ul class="text-right list-inline bot-buffer-no" />').append(
'<li>' + '<small class="text-muted">' + reply.post_time + '</small>' + '</li>' '<li>' + '<small class="text-muted">' + reply.post_time + '</small>' + '</li>'
@ -1048,7 +1067,7 @@ function showStandings() {
function(row) { function(row) {
var col_tr = '<tr>'; var col_tr = '<tr>';
col_tr += '<td>' + row[3] + '</td>'; col_tr += '<td>' + row[3] + '</td>';
col_tr += '<td>' + getUserLink(row[2][0]) + '</td>'; col_tr += '<td>' + getUserLink(row[2][0], row[2][1]) + '</td>';
col_tr += '<td>' + '<div><span class="uoj-score" data-max="' + problems.length * 100 + '" style="color:' + getColOfScore(row[0] / problems.length) + '">' + row[0] + '</span></div>' + '<div>' + getPenaltyTimeStr(row[1]) + '</div></td>'; col_tr += '<td>' + '<div><span class="uoj-score" data-max="' + problems.length * 100 + '" style="color:' + getColOfScore(row[0] / problems.length) + '">' + row[0] + '</span></div>' + '<div>' + getPenaltyTimeStr(row[1]) + '</div></td>';
for (var i = 0; i < problems.length; i++) { for (var i = 0; i < problems.length; i++) {
col_tr += '<td>'; col_tr += '<td>';