<?php if (!Auth::check()) { redirectToLogin(); } if (!isNormalUser($myUser)) { become403Page(); } function handleMsgPost() { global $myUser; if (!isset($_POST['receiver'])) { return 'fail'; } if (!isset($_POST['message'])) { return 'fail'; } if (0 > strlen($_POST['message']) || strlen($_POST['message']) > 65535) { return 'fail'; } $receiver = $_POST['receiver']; $esc_message = DB::escape($_POST['message']); $sender = $myUser['username']; if (!validateUsername($receiver) || !queryUser($receiver)) { return 'fail'; } DB::query("insert into user_msg (sender, receiver, message, send_time) values ('$sender', '$receiver', '$esc_message', now())"); return "ok"; } function getConversations() { global $myUser; $username = $myUser['username']; $result = DB::query( "select * from user_msg where sender = '$username' or receiver = '$username' order by send_time DESC" ); $ret = array(); while ($msg = DB::fetch($result)) { if ($msg['sender'] !== $username) { if (isset($ret[$msg['sender']])) { $ret[$msg['sender']][1] |= ($msg['read_time'] == null); continue; } $ret[$msg['sender']] = array($msg['send_time'], ($msg['read_time'] == null)); } else { if (isset($ret[$msg['receiver']])) { continue; } $ret[$msg['receiver']] = array($msg['send_time'], 0); } } $res = []; foreach ($ret as $name => $con) { $res[] = [$con[0], $con[1], $name]; } usort($res, function($a, $b) { return -strcmp($a[0], $b[0]); }); return json_encode($res); } function getHistory() { global $myUser; $username = $myUser['username']; if (!isset($_GET['conversationName']) || !validateUsername($_GET['conversationName'])) { return '[]'; } if (!isset($_GET['pageNumber']) || !validateUInt($_GET['pageNumber'])) { return '[]'; } $conversationName = $_GET['conversationName']; $pageNumber = ($_GET['pageNumber'] - 1) * 10; DB::query("update user_msg set read_time = now() where sender = '$conversationName' and receiver = '$username' and read_time is null"); $result = DB::query("select * from user_msg where (sender = '$username' and receiver = '$conversationName') or (sender = '$conversationName' and receiver = '$username') order by send_time DESC limit $pageNumber, 11"); $ret = array(); while ($msg = DB::fetch($result)) { $ret[] = array($msg['message'], $msg['send_time'], $msg['read_time'], $msg['id'], ($msg['sender'] == $username)); } return json_encode($ret); } /* function deleteMsg($msgId) { return 1; $str = <<<EOD select * from user_msg where id = $msgId and read_time is null EOD; $result = DB::query($str); if (DB::fetch($result)) { $str = <<<EOD delete from user_msg where id = $msgId EOD; DB::query($str); return 1; } return 0; } */ if (isset($_POST['user_msg'])) { die(handleMsgPost()); } elseif (isset($_GET['getConversations'])) { die(getConversations()); } elseif (isset($_GET['getHistory'])) { die(getHistory()); } ?> <?php echoUOJPageHeader('私信') ?> <h1 class="page-header">私信</h1> <div id="conversations"> </div> <div id="history" style="display:none"> <div class="card border-primary"> <div class="card-header bg-primary text-white"> <button type="button" id="goBack" class="btn btn-info btn-sm" style="position:absolute">返回</button> <div id="conversation-name" class="text-center"></div> </div> <div class="card-body"> <ul class="pagination top-buffer-no justify-content-between"> <li class="previous"><a class="btn btn-outline-secondary text-primary" href="#" id="pageLeft">← 更早的消息</a></li> <li class="text-center" id="pageShow" style="line-height:32px"></li> <li class="next"><a class="btn btn-outline-secondary text-primary" href="#" id="pageRight">更新的消息 →</a></li> </ul> <div id="history-list" style="min-height: 200px;"> </div> <ul class="pagination top-buffer-no justify-content-between"> <li class="previous"><a class="btn btn-outline-secondary text-primary" href="#history" id="pageLeft2">← 更早的消息</a></li> <li class="next"><a class="btn btn-outline-secondary text-primary" href="#history" id="pageRight2">更新的消息 →</a></li> </ul> <hr /> <form id="form-message"> <div class="form-group" id="form-group-message"> <textarea id="input-message" class="form-control"></textarea> <span id="help-message" class="help-block"></span> </div> <div class="text-right"> <button type="submit" id="message-submit" class="btn btn-info btn-md">发送</button> </div> </form> </div> </div> </div> <script type="text/javascript"> $(document).ready(function() { $.ajaxSetup({async:false}); refreshConversations(); <?php if (isset($_GET['enter'])): ?> enterConversation(<?= json_encode($_GET['enter']) ?>); <?php endif ?> }); </script> <script type="text/javascript"> function addButton(conversationName, send_time, type) { $("#conversations").append( '<div class="row top-buffer-sm">' + '<div class="col-sm-3">' + '<button type="button" class="btn btn-' + ( type ? 'warning' : 'primary' ) + ' btn-block" ' + 'onclick="enterConversation(\'' + conversationName + '\')">' + conversationName + '</button>' + '</div>' + '<div class="col-sm-9" style="line-height:34px">' + '最后发送时间:' + send_time + '</div>' + '</div>' ); } function addBubble(content, send_time, read_time, msgId, conversation, page, type) { $("#history-list").append( '<div style=' + (type ? "margin-left:0%;margin-right:20%;" : "margin-left:20%;margin-right:0%;") + '>' + '<div class="card border-info mb-4">' + '<div class="card-body" style="background:#17a2b8; word-break: break-all">' + '<div style="white-space:pre-wrap">' + htmlspecialchars(content) + '</div>' + '</div>' + '<div>' + '<div class="row">' + '<div class="col-sm-6">' + '发送时间:' + send_time + '</div>' + '<div class="col-sm-6 text-right">' + '查看时间:' + (read_time == null ? '<strong>未查看</strong>' : read_time) + '</div>' + '</div>' + '</div>' + '</div>' + '</div>' ); } function submitMessagePost(conversationName) { if ($('#input-message').val().length == 0 || $('#input-message').val().length >= 65536) { $('#help-message').text('私信长度必须在1~65535之间。'); $('#form-group-message').addClass('has-error'); return; } $('#help-message').text(''); $('#form-group-message').removeClass('has-error'); $.post('/user/msg', { user_msg : 1, receiver : conversationName, message : $('#input-message').val() }, function(msg) { $('#input-message').val(""); }); } function refreshHistory(conversation, page) { $("#history-list").empty(); var ret = false; $('#conversation-name').text(conversation); $('#pageShow').text("第" + page.toString() + "页"); $.get('/user/msg', { getHistory : '', conversationName : conversation, pageNumber : page }, function(msg) { var result = JSON.parse(msg); var cnt = 0, flag = 0, F = 0; if (result.length == 11) flag = 1, F = 1; result.reverse(); for (msg in result) { if (flag) {flag = 0; continue;} var message = result[msg]; addBubble(message[0], message[1], message[2], message[3], conversation, page, message[4]); if ((++cnt) + 1 == result.length && F) break; } if (result.length == 11) ret = true; }); return ret; } function refreshConversations() { $("#conversations").empty(); $.get('/user/msg', { getConversations : "" }, function(msg) { var result = JSON.parse(msg); for (i in result) { var conversation = result[i]; if (conversation[1] == 1) { addButton(conversation[2], conversation[0], conversation[1]); } } for (i in result) { var conversation = result[i]; if (conversation[1] == 0) { addButton(conversation[2], conversation[0], conversation[1]); } } } ); } function enterConversation(conversationName) { var slideTime = 300; var page = 1; $("#conversations").hide(slideTime); var changeAble = refreshHistory(conversationName, page); $("#history").slideDown(slideTime); $('#form-message').unbind("submit").submit(function() { submitMessagePost(conversationName); page = 1; changeAble = refreshHistory(conversationName, page); refreshConversations(); return false; }); $('#goBack').unbind("click").click(function() { refreshConversations(); $("#history").slideUp(slideTime); $("#conversations").show(slideTime); return; }); $('#pageLeft').unbind("click").click(function() { if (changeAble) page++; changeAble = refreshHistory(conversationName, page); return false; }); $('#pageLeft2').unbind("click").click(function() { if (changeAble) page++; changeAble = refreshHistory(conversationName, page); }); $('#pageRight').unbind("click").click(function() { if (page > 1) page--; changeAble = refreshHistory(conversationName, page); return false; }); $('#pageRight2').unbind("click").click(function() { if (page > 1) page--; changeAble = refreshHistory(conversationName, page); }); } </script> <?php echoUOJPageFooter() ?>