创新实训(七)系统消息页面 比赛通知

系统消息还有一个功能就接受有关比赛的通知
这一部分的消息生成的代码在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)));
    }
}

详解:

  1. 查询比赛通知信息

    • 从数据库中查询与特定比赛 contest_id 相关的通知信息,按时间降序取前 10 条。
    • 使用 new DateTime 将数据库中的时间字符串转换为 DateTime 对象,与客户端传递的 last_time 比较,以确定是否有新的通知。
    • 如果有新通知,则将通知的标题和内容组合成字符串并存入 $ch 数组中。
  2. 查询用户的问题和回答信息

    • 查询当前用户在该比赛中提交的问题和管理员的回复,同样按时间降序取前 10 条。
    • 同样使用 new DateTime 比较时间,如果有新的问题或回答,将其组合成字符串并存入 $ch 数组中。
  3. 返回 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文件中实现。

代码解释

  1. 初始检查和重定向:

    • 如果 $myUsernull(表示用户未登录),则调用 redirectToLogin() 函数将用户重定向到登录页面,确保只有已验证的用户可以访问系统消息。
    if ($myUser == null) {
        redirectToLogin();
    }
    
  2. HTML 表头行:

    • 使用 heredoc 语法 (<<<EOD ... EOD;) 定义 HTML 表格的表头行,用于显示系统消息。
    $header_row = <<<EOD
    <tr>
        <th>消息</th>
        <th style="width:15em">时间</th>
    </tr>
    EOD;
    
  3. 输出系统消息的函数:

    • 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>';
    }
    
  4. 显示页面标题:

    • 调用 echoUOJPageHeader('系统消息') 输出页面标题为 '系统消息'
    <?php echoUOJPageHeader('系统消息') ?>
    
  5. 显示系统消息表格:

    • 使用 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'))) ?>
    
  6. 标记消息为已读:

    • 更新 user_system_msg 表,将接收者为当前用户的消息的 read_time 设置为当前时间 (now()).
    <?php DB::update("update user_system_msg set read_time = now() where receiver = '" . Auth::id() . "'") ?>
    
  7. 显示页面页脚:

    • 调用 echoUOJPageFooter() 输出页面页脚,关闭必要的 HTML 标签。
    <?php echoUOJPageFooter() ?>
    
posted @   贺丁  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示