创新实训(七)系统消息页面 比赛通知
系统消息还有一个功能就接受有关比赛的通知
这一部分的消息生成的代码在contest_inside.php
中实现
获取通知信息
执行if判断,检查客户端是否发送了名为 check_notice 的 POST 请求并采取相应操作
if (isset($_POST['check_notice'])) {
$result = DB::query("select * from contests_notice where contest_id = '${contest['id']}' order by time desc limit 10");
$ch = array();
$flag = false;
try {
while ($row = DB::fetch($result)) {
if (new DateTime($row['time']) > new DateTime($_POST['last_time'])) {
$ch[] = $row['title'].': '.$row['content'];
}
}
} catch (Exception $e) {
}
global $myUser;
$result=DB::query("select * from contests_asks where contest_id='${contest['id']}' and username='${myUser['username']}' order by reply_time desc limit 10");
try {
while ($row = DB::fetch($result)) {
if (new DateTime($row['reply_time']) > new DateTime($_POST['last_time'])) {
$ch[] = $row['question'].': '.$row['answer'];
}
}
} catch (Exception $e) {
}
if ($ch) {
die(json_encode(array('msg' => $ch, 'time' => UOJTime::$time_now_str)));
} else {
die(json_encode(array('time' => UOJTime::$time_now_str)));
}
}
详解:
-
查询比赛通知信息:
- 从数据库中查询与特定比赛
contest_id
相关的通知信息,按时间降序取前 10 条。 - 使用
new DateTime
将数据库中的时间字符串转换为DateTime
对象,与客户端传递的last_time
比较,以确定是否有新的通知。 - 如果有新通知,则将通知的标题和内容组合成字符串并存入
$ch
数组中。
- 从数据库中查询与特定比赛
-
查询用户的问题和回答信息:
- 查询当前用户在该比赛中提交的问题和管理员的回复,同样按时间降序取前 10 条。
- 同样使用
new DateTime
比较时间,如果有新的问题或回答,将其组合成字符串并存入$ch
数组中。
-
返回 JSON 响应:
- 如果
$ch
数组不为空,表示有新的通知或回答,将结果以 JSON 格式返回客户端,包括消息和当前时间。 - 如果
$ch
数组为空,则只返回当前时间,表示没有新的通知或回答。
- 如果
超级管理员发送通知部分
这一部分主要在一个if分支中实现,这里只展示实现了发送通知信息的部分。
1.检查是否为超级管理员:
- 使用
isSuperUser($myUser)
函数判断当前用户是否是超级管理员。
if (isSuperUser($myUser)) {
2.这个分支的前半部分会通过各种方法计算用户排名和排名变化,并将排名结果通知用户,通知部分的代码如下
// 发送rating变化通知
for ($i = 0; $i < count($standings); $i++) {
$user = queryUser($standings[$i][2][0]);
$change = $ratings[$i] - $user['rating'];
$user_link = getUserLink($user['username']);
if ($change != 0) {
$tail = '<strong style="color:red">' . ($change > 0 ? '+' : '') . $change . '</strong>';
$content = <<<EOD
<p>${user_link} 您好:</p>
<p class="indent2">您在 <a href="/contest/{$contest['id']}">{$contest['name']}</a> 这场比赛后的Rating变化为${tail},当前Rating为 <strong style="color:red">{$ratings[$i]}</strong>。</p>
EOD;
} else {
$content = <<<EOD
<p>${user_link} 您好:</p>
<p class="indent2">您在 <a href="/contest/{$contest['id']}">{$contest['name']}</a> 这场比赛后Rating没有变化。当前Rating为 <strong style="color:red">{$ratings[$i]}</strong>。</p>
EOD;
}
sendSystemMsg($user['username'], 'Rating变化通知', $content);
DB::query("update user_info set rating = {$ratings[$i]} where username = '{$standings[$i][2][0]}'");
DB::query("update contests_registrants set rank = {$standings[$i][3]} where contest_id = {$contest['id']} and username = '{$standings[$i][2][0]}'");
}
DB::query("update contests set status = 'finished' where id = {$contest['id']}");
};
$publish_result_form->submit_button_config['class_str'] = 'btn btn-danger btn-block';
$publish_result_form->submit_button_config['smart_confirm'] = '';
$publish_result_form->submit_button_config['text'] = '公布成绩';
$publish_result_form->runAtServer();
遍历 $standings 数组,对每位参赛者执行以下操作:
使用 queryUser() 函数获取用户信息,包括用户名和当前评分。
计算评分变化 $change,并根据变化情况构建通知内容 $content,包括用户名、比赛链接、评分变化和当前评分。
调用 sendSystemMsg() 函数向用户发送评分变化通知,主题为 'Rating变化通知'。
更新数据库中用户的评分信息和比赛参与者的排名信息。
系统消息页面
下面对系统消息页面的具体前端代码进行介绍,这部分代码的实现在user_system_msg.php文件中实现。
代码解释
-
初始检查和重定向:
- 如果
$myUser
是null
(表示用户未登录),则调用redirectToLogin()
函数将用户重定向到登录页面,确保只有已验证的用户可以访问系统消息。
if ($myUser == null) { redirectToLogin(); }
- 如果
-
HTML 表头行:
- 使用 heredoc 语法 (
<<<EOD ... EOD;
) 定义 HTML 表格的表头行,用于显示系统消息。
$header_row = <<<EOD <tr> <th>消息</th> <th style="width:15em">时间</th> </tr> EOD;
- 使用 heredoc 语法 (
-
输出系统消息的函数:
echoSysMsg($msg)
函数用于将每条系统消息输出为表格行 (<tr>
)。- 函数检查消息是否已读 (
$msg['read_time'] == null
),如果未读,则添加class="warning"
来突出显示该行。 - 显示消息标题 (
$msg['title']
) 作为<h4>
标题和消息内容 ($msg['content']
)。 - 显示消息发送时间 (
$msg['send_time']
)。
function echoSysMsg($msg) { echo $msg['read_time'] == null ? '<tr class="warning">' : '<tr>'; echo '<td>'; echo '<h4>'.$msg['title'].'</h4>'; echo $msg['content']; echo '</td>'; echo '<td>'.$msg['send_time'].'</td>'; echo '</tr>'; }
-
显示页面标题:
- 调用
echoUOJPageHeader('系统消息')
输出页面标题为'系统消息'
。
<?php echoUOJPageHeader('系统消息') ?>
- 调用
-
显示系统消息表格:
- 使用
echoLongTable()
函数生成和显示包含系统消息的表格 (user_system_msg
)。 - 函数根据当前认证用户 (
Auth::id()
) 过滤接收者为该用户的消息。 - 按
id
降序排序消息。 - 使用之前定义的
$header_row
作为表头行模板。 - 对每一行调用
echoSysMsg
函数输出消息详细信息。 - 提供额外选项,如设置表格类 (
'table'
)。
<?php echoLongTable(array('*'), 'user_system_msg', "receiver='" . Auth::id() . "'", 'order by id desc', $header_row, 'echoSysMsg', array('table_classes' => array('table'))) ?>
- 使用
-
标记消息为已读:
- 更新
user_system_msg
表,将接收者为当前用户的消息的read_time
设置为当前时间 (now()
).
<?php DB::update("update user_system_msg set read_time = now() where receiver = '" . Auth::id() . "'") ?>
- 更新
-
显示页面页脚:
- 调用
echoUOJPageFooter()
输出页面页脚,关闭必要的 HTML 标签。
<?php echoUOJPageFooter() ?>
- 调用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!