user_msg.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <?php
  2. if ($myUser == null) {
  3. redirectToLogin();
  4. }
  5. function handleMsgPost() {
  6. global $myUser;
  7. if (!isset($_POST['receiver'])) {
  8. return 'fail';
  9. }
  10. if (!isset($_POST['message'])) {
  11. return 'fail';
  12. }
  13. if (0 > strlen($_POST['message']) || strlen($_POST['message']) > 65535) {
  14. return 'fail';
  15. }
  16. $receiver = $_POST['receiver'];
  17. $esc_message = DB::escape($_POST['message']);
  18. $sender = $myUser['username'];
  19. if (!validateUsername($receiver) || !queryUser($receiver)) {
  20. return 'fail';
  21. }
  22. DB::query("insert into user_msg (sender, receiver, message, send_time) values ('$sender', '$receiver', '$esc_message', now())");
  23. return "ok";
  24. }
  25. function getConversations() {
  26. global $myUser;
  27. $username = $myUser['username'];
  28. $result = DB::query( "select * from user_msg where sender = '$username' or receiver = '$username' order by send_time DESC" );
  29. $ret = array();
  30. while ($msg = DB::fetch($result)) {
  31. if ($msg['sender'] !== $username) {
  32. if (isset($ret[$msg['sender']])) {
  33. $ret[$msg['sender']][1] |= ($msg['read_time'] == null);
  34. continue;
  35. }
  36. $ret[$msg['sender']] = array($msg['send_time'], ($msg['read_time'] == null));
  37. } else {
  38. if (isset($ret[$msg['receiver']])) {
  39. continue;
  40. }
  41. $ret[$msg['receiver']] = array($msg['send_time'], 0);
  42. }
  43. }
  44. $res = [];
  45. foreach ($ret as $name => $con) {
  46. $res[] = [$con[0], $con[1], $name];
  47. }
  48. usort($res, function($a, $b) {
  49. return -strcmp($a[0], $b[0]);
  50. });
  51. return json_encode($res);
  52. }
  53. function getHistory() {
  54. global $myUser;
  55. $username = $myUser['username'];
  56. if (!isset($_GET['conversationName']) || !validateUsername($_GET['conversationName'])) {
  57. return '[]';
  58. }
  59. if (!isset($_GET['pageNumber']) || !validateUInt($_GET['pageNumber'])) {
  60. return '[]';
  61. }
  62. $conversationName = $_GET['conversationName'];
  63. $pageNumber = ($_GET['pageNumber'] - 1) * 10;
  64. DB::query("update user_msg set read_time = now() where sender = '$conversationName' and receiver = '$username' and read_time is null");
  65. $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");
  66. $ret = array();
  67. while ($msg = DB::fetch($result)) {
  68. $ret[] = array($msg['message'], $msg['send_time'], $msg['read_time'], $msg['id'], ($msg['sender'] == $username));
  69. }
  70. return json_encode($ret);
  71. }
  72. /*
  73. function deleteMsg($msgId) {
  74. return 1;
  75. $str = <<<EOD
  76. select * from user_msg
  77. where id = $msgId
  78. and read_time is null
  79. EOD;
  80. $result = DB::query($str);
  81. if (DB::fetch($result)) {
  82. $str = <<<EOD
  83. delete from user_msg
  84. where id = $msgId
  85. EOD;
  86. DB::query($str);
  87. return 1;
  88. }
  89. return 0;
  90. }
  91. */
  92. if (isset($_POST['user_msg'])) {
  93. die(handleMsgPost());
  94. } elseif (isset($_GET['getConversations'])) {
  95. die(getConversations());
  96. } elseif (isset($_GET['getHistory'])) {
  97. die(getHistory());
  98. }
  99. ?>
  100. <?php echoUOJPageHeader('私信') ?>
  101. <h1 class="page-header">私信</h1>
  102. <div id="conversations">
  103. </div>
  104. <div id="history" style="display:none">
  105. <div class="card border-primary">
  106. <div class="card-header bg-primary text-white">
  107. <button type="button" id="goBack" class="btn btn-info btn-sm" style="position:absolute">返回</button>
  108. <div id="conversation-name" class="text-center"></div>
  109. </div>
  110. <div class="card-body">
  111. <ul class="pagination top-buffer-no justify-content-between">
  112. <li class="previous"><a class="btn btn-outline-secondary text-primary" href="#" id="pageLeft">&larr; 更早的消息</a></li>
  113. <li class="text-center" id="pageShow" style="line-height:32px"></li>
  114. <li class="next"><a class="btn btn-outline-secondary text-primary" href="#" id="pageRight">更新的消息 &rarr;</a></li>
  115. </ul>
  116. <div id="history-list" style="min-height: 200px;">
  117. </div>
  118. <ul class="pagination top-buffer-no justify-content-between">
  119. <li class="previous"><a class="btn btn-outline-secondary text-primary" href="#history" id="pageLeft2">&larr; 更早的消息</a></li>
  120. <li class="next"><a class="btn btn-outline-secondary text-primary" href="#history" id="pageRight2">更新的消息 &rarr;</a></li>
  121. </ul>
  122. <hr />
  123. <form id="form-message">
  124. <div class="form-group" id="form-group-message">
  125. <textarea id="input-message" class="form-control"></textarea>
  126. <span id="help-message" class="help-block"></span>
  127. </div>
  128. <div class="text-right">
  129. <button type="submit" id="message-submit" class="btn btn-info btn-md">发送</button>
  130. </div>
  131. </form>
  132. </div>
  133. </div>
  134. </div>
  135. <script type="text/javascript">
  136. $(document).ready(function() {
  137. $.ajaxSetup({async:false});
  138. refreshConversations();
  139. <?php if (isset($_GET['enter'])): ?>
  140. enterConversation(<?= json_encode($_GET['enter']) ?>);
  141. <?php endif ?>
  142. });
  143. </script>
  144. <script type="text/javascript">
  145. function addButton(conversationName, send_time, type) {
  146. $("#conversations").append(
  147. '<div class="row top-buffer-sm">' +
  148. '<div class="col-sm-3">' +
  149. '<button type="button" class="btn btn-' + ( type ? 'warning' : 'primary' ) + ' btn-block" ' +
  150. 'onclick="enterConversation(\'' + conversationName + '\')">' +
  151. conversationName +
  152. '</button>' +
  153. '</div>' +
  154. '<div class="col-sm-9" style="line-height:34px">' +
  155. '最后发送时间:' + send_time +
  156. '</div>' +
  157. '</div>'
  158. );
  159. }
  160. function addBubble(content, send_time, read_time, msgId, conversation, page, type) {
  161. $("#history-list").append(
  162. '<div style=' + (type ? "margin-left:40%;margin-right:0%;" : "margin-left:0%;margin-right:40%;") + '>' +
  163. '<div class="card border-info mb-4">' +
  164. '<div class="card-body" style="background:' + (type ? '#4d92d8' : '#beb7b7') + '; word-break: break-all">' +
  165. '<div style="white-space:pre-wrap" ' + (type ? 'class="text-right"' : 'class="text-left"') + '>' +
  166. htmlspecialchars(content) +
  167. '</div>' +
  168. '</div>' +
  169. '<div>' +
  170. '<div class="row">' +
  171. '<div class="col-sm-6">' +
  172. '发送时间:' + send_time +
  173. '</div>' +
  174. '<div class="col-sm-6 text-right">' +
  175. '查看时间:' + (read_time == null ? '<strong>未查看</strong>' : read_time) +
  176. '</div>' +
  177. '</div>' +
  178. '</div>' +
  179. '</div>' +
  180. '</div>'
  181. );
  182. }
  183. function submitMessagePost(conversationName) {
  184. if ($('#input-message').val().length == 0 || $('#input-message').val().length >= 65536) {
  185. $('#help-message').text('私信长度必须在1~65535之间。');
  186. $('#form-group-message').addClass('has-error');
  187. return;
  188. }
  189. $('#help-message').text('');
  190. $('#form-group-message').removeClass('has-error');
  191. $.post('/user/msg', {
  192. user_msg : 1,
  193. receiver : conversationName,
  194. message : $('#input-message').val()
  195. }, function(msg) {
  196. $('#input-message').val("");
  197. });
  198. }
  199. function refreshHistory(conversation, page) {
  200. $("#history-list").empty();
  201. var ret = false;
  202. $('#conversation-name').text(conversation);
  203. $('#pageShow').text("第" + page.toString() + "页");
  204. $.get('/user/msg', {
  205. getHistory : '',
  206. conversationName : conversation,
  207. pageNumber : page
  208. }, function(msg) {
  209. var result = JSON.parse(msg);
  210. var cnt = 0, flag = 0, F = 0;
  211. if (result.length == 11) flag = 1, F = 1;
  212. result.reverse();
  213. for (msg in result) {
  214. if (flag) {flag = 0; continue;}
  215. var message = result[msg];
  216. addBubble(message[0], message[1], message[2], message[3], conversation, page, message[4]);
  217. if ((++cnt) + 1 == result.length && F) break;
  218. }
  219. if (result.length == 11) ret = true;
  220. });
  221. return ret;
  222. }
  223. function refreshConversations() {
  224. $("#conversations").empty();
  225. $.get('/user/msg', {
  226. getConversations : ""
  227. }, function(msg) {
  228. var result = JSON.parse(msg);
  229. for (i in result) {
  230. var conversation = result[i];
  231. if (conversation[1] == 1) {
  232. addButton(conversation[2], conversation[0], conversation[1]);
  233. }
  234. }
  235. for (i in result) {
  236. var conversation = result[i];
  237. if (conversation[1] == 0) {
  238. addButton(conversation[2], conversation[0], conversation[1]);
  239. }
  240. }
  241. }
  242. );
  243. }
  244. function enterConversation(conversationName) {
  245. var slideTime = 300;
  246. var page = 1;
  247. $("#conversations").hide(slideTime);
  248. var changeAble = refreshHistory(conversationName, page);
  249. $("#history").slideDown(slideTime);
  250. $('#form-message').unbind("submit").submit(function() {
  251. submitMessagePost(conversationName);
  252. page = 1;
  253. changeAble = refreshHistory(conversationName, page);
  254. refreshConversations();
  255. return false;
  256. });
  257. $('#goBack').unbind("click").click(function() {
  258. refreshConversations();
  259. $("#history").slideUp(slideTime);
  260. $("#conversations").show(slideTime);
  261. return;
  262. });
  263. $('#pageLeft').unbind("click").click(function() {
  264. if (changeAble) page++;
  265. changeAble = refreshHistory(conversationName, page);
  266. return false;
  267. });
  268. $('#pageLeft2').unbind("click").click(function() {
  269. if (changeAble) page++;
  270. changeAble = refreshHistory(conversationName, page);
  271. });
  272. $('#pageRight').unbind("click").click(function() {
  273. if (page > 1) page--;
  274. changeAble = refreshHistory(conversationName, page);
  275. return false;
  276. });
  277. $('#pageRight2').unbind("click").click(function() {
  278. if (page > 1) page--;
  279. changeAble = refreshHistory(conversationName, page);
  280. });
  281. }
  282. </script>
  283. <?php echoUOJPageFooter() ?>