请先登录
+登录后查看通知消息
+ +暂无通知
+还没有收到任何通知消息
+From d0d6de1eac5022cf738bbbd9614899b3771cdf27 Mon Sep 17 00:00:00 2001
From: Tiaotiao <65841827@qq.com>
Date: Tue, 20 Jan 2026 14:55:27 +0800
Subject: [PATCH 1/7] Update print statement from 'Hello' to 'Goodbye'
---
nof.php | 972 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 972 insertions(+)
create mode 100644 nof.php
diff --git a/nof.php b/nof.php
new file mode 100644
index 0000000..7b769b0
--- /dev/null
+++ b/nof.php
@@ -0,0 +1,972 @@
+alert("请先登录"); window.location.href = "login.php";';
+ exit();
+ }
+}
+
+// 检查session数据
+$dt = null;
+if (isset($_SESSION['responseBody'])) {
+ $dt = is_string($_SESSION['responseBody']) ? json_decode($_SESSION['responseBody'], true) : $_SESSION['responseBody'];
+} else {
+ $redirectUrl = 'getv.php?r=nof.php';
+ if (!headers_sent()) {
+ header('Location: ' . $redirectUrl);
+ exit;
+ } else {
+ echo '';
+ exit;
+ }
+}
+
+// 检查登录状态
+$isLoggedIn = isset($dt['Data']['User']['Nickname']) && $dt['Data']['User']['Nickname'] !== '点击登录';
+
+// 调用API函数
+function callAPI($endpoint, $method = 'GET', $data = [], $isRetry = false) {
+ $url = API_BASE_URL . ltrim($endpoint, '/');
+
+ $headers = [
+ 'X-API-Token: ' . $_SESSION['token'],
+ 'X-API-AuthCode: ' . $_SESSION['authCode'],
+ 'Content-Type: application/json',
+ 'Accept: application/json'
+ ];
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
+
+ if ($method === 'POST') {
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ } elseif ($method === 'PUT') {
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
+ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
+ } elseif ($method === 'DELETE') {
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
+ }
+
+ $response = curl_exec($ch);
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ $error = curl_error($ch);
+
+ curl_close($ch);
+
+ if ($error) {
+ return [
+ 'Status' => 500,
+ 'Message' => 'CURL Error: ' . $error,
+ 'Data' => null
+ ];
+ }
+
+ $result = json_decode($response, true);
+
+ // 如果token过期,尝试刷新
+ if ($httpCode === 401 && !$isRetry) {
+ $refreshResult = refreshToken();
+ if ($refreshResult['success']) {
+ return callAPI($endpoint, $method, $data, true);
+ }
+ }
+
+ return [
+ 'Status' => $httpCode,
+ 'Message' => $result['Message'] ?? ($httpCode === 200 ? 'Success' : 'Unknown error'),
+ 'Data' => $result['Data'] ?? $result
+ ];
+}
+
+// 刷新token
+function refreshToken() {
+ if (!isset($_SESSION['refreshToken'])) {
+ return ['success' => false];
+ }
+
+ $data = [
+ 'refreshToken' => $_SESSION['refreshToken']
+ ];
+
+ $response = callAPI('/Auth/RefreshToken', 'POST', $data);
+
+ if ($response['Status'] === 200) {
+ $_SESSION['token'] = $response['Data']['Token'];
+ $_SESSION['authCode'] = $response['Data']['AuthCode'];
+ if (isset($response['Data']['RefreshToken'])) {
+ $_SESSION['refreshToken'] = $response['Data']['RefreshToken'];
+ }
+ return ['success' => true];
+ }
+
+ return ['success' => false];
+}
+
+// 获取头像URL - 修复avatarNumber问题
+function getAvatarUrl($userID, $avatarNumber = 0) {
+ if (empty($userID) || strlen($userID) < 24) {
+ return '';
+ }
+
+ $part1 = substr($userID, 0, 4);
+ $part2 = substr($userID, 4, 2);
+ $part3 = substr($userID, 6, 2);
+ $part4 = substr($userID, 8, 16);
+
+ return "http://netlogo-cn.oss-cn-hongkong.aliyuncs.com/users/avatars/{$part1}/{$part2}/{$part3}/{$part4}/{$avatarNumber}.jpg!full";
+}
+
+// 获取消息列表 - 一次加载100条
+function getMessages($categoryID, $skip = 0, $take = 20, $noTemplates = false) {
+ $data = [
+ 'CategoryID' => $categoryID,
+ 'Skip' => $skip,
+ 'Take' => $take,
+ 'NoTemplates' => $noTemplates
+ ];
+
+ return callAPI('/Messages/GetMessages', 'POST', $data);
+}
+
+// 转换函数
+function convertUIIndexToCategoryID($n) {
+ return $n === 3 ? 2 : ($n === 2 ? 3 : $n);
+}
+
+function convertCategoryIDToUIIndex($n) {
+ return $n === 2 ? 3 : ($n === 3 ? 2 : $n);
+}
+
+// 模板填充函数
+function fillInTemplate($data, $message, $userInfo) {
+ if (empty($data)) return '';
+
+ // 替换用户标记
+ if (strpos($data, '{Users}') !== false) {
+ $usersHtml = '';
+ if (isset($message['Users']) && isset($message['UserNames'])) {
+ foreach ($message['Users'] as $index => $userId) {
+ $userName = $message['UserNames'][$index] ?? '';
+ $usersHtml .= '
+ $text = nl2br($text);
+
+ // 解析自定义标签
+ $patterns = [
+ // user标签 - 保持原有格式
+ '/<user=([a-f0-9]+)>(.*?)<\/user>/i',
+ // experiment标签 - 跳转链接
+ '/<experiment=([a-f0-9]+)>(.*?)<\/experiment>/i',
+ // discussion标签 - 跳转链接
+ '/<discussion=([a-f0-9]+)>(.*?)<\/discussion>/i',
+ // model标签 - 跳转链接
+ '/<model=([a-f0-9]+)>(.*?)<\/model>/i',
+ // external标签 - 外部链接
+ '/<external=([^&]+)>(.*?)<\/external>/i',
+ // size标签
+ '/<size=([^&]+)>(.*?)<\/size>/i',
+ // color标签 - 新增
+ '/<color=([^&]+)>(.*?)<\/color>/i',
+ // b标签
+ '/<b>(.*?)<\/b>/i',
+ // i标签
+ '/<i>(.*?)<\/i>/i',
+ // a标签 - 深蓝色标签
+ '/<a>(.*?)<\/a>/i'
+ ];
+
+ $replacements = [
+ // user标签
+ '$2',
+ // experiment标签
+ '$2',
+ // discussion标签
+ '$2',
+ // model标签
+ '$2',
+ // external标签
+ '$2',
+ // size标签
+ '$2',
+ // color标签 - 新增
+ '$2',
+ // b标签
+ '$1',
+ // i标签
+ '$1',
+ // a标签
+ '$1'
+ ];
+
+ $text = preg_replace($patterns, $replacements, $text);
+
+ // 解析简单的Markdown格式
+ $text = self::parseSimpleMarkdown($text);
+
+ return $text;
+ }
+
+ /**
+ * 解析Markdown标题
+ */
+ private static function parseMarkdownHeadings(string $text): string {
+ // 支持1-6级标题
+ // 一级标题: # 标题
+ $text = preg_replace('/^# (.+)$/m', '$1', $text);
+
+ // 二级标题: ## 标题
+ $text = preg_replace('/^## (.+)$/m', '$1', $text);
+
+ // 三级标题: ### 标题
+ $text = preg_replace('/^### (.+)$/m', '$1', $text);
+
+ // 四级标题: #### 标题
+ $text = preg_replace('/^#### (.+)$/m', '$1', $text);
+
+ return $text;
+ }
+
+ /**
+ * 解析简单的Markdown格式
+ */
+ private static function parseSimpleMarkdown(string $text): string {
+ // 粗体
+ $text = preg_replace('/\*\*(.*?)\*\*/', '$1', $text);
+
+ // 斜体
+ $text = preg_replace('/\*(.*?)\*/', '$1', $text);
+
+ // 删除线
+ $text = preg_replace('/~~(.*?)~~/', '$1', $text);
+
+ // 行内代码
+ $text = preg_replace('/`([^`]+)`/', '$1', $text);
+
+ return $text;
+ }
+}
+
+// 根据消息类型获取图标URL
+function getMsgIconUrl($msgType) {
+ $icons = [
+ 1 => 'notifications_system.png',
+ 2 => 'notifications_comments.png',
+ 3 => 'notifications_followers.png',
+ 4 => 'notifications_projects.png',
+ 5 => 'notifications_admin.png'
+ ];
+
+ $icon = $icons[$msgType] ?? 'notifications_system.png';
+ return "/assets/icons/{$icon}";
+}
+
+// 获取路径
+function getPath($path) {
+ $baseUrl = rtrim($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']), '/');
+
+ if (strpos($path, '/@base/') === 0) {
+ return $baseUrl . '/assets' . substr($path, 7);
+ } elseif (strpos($path, '/@root/') === 0) {
+ return $baseUrl . substr($path, 7);
+ } else {
+ return $baseUrl . '/' . ltrim($path, '/');
+ }
+}
+
+// 获取消息类型名称
+function getMsgTypeName($msgType) {
+ $names = [
+ 1 => '系统',
+ 2 => '评论',
+ 3 => '关注',
+ 4 => '作品',
+ 5 => '管理'
+ ];
+ return $names[$msgType] ?? '消息';
+}
+
+// 根据ID计算相对时间
+function formatTimeAgo($id) {
+ if (!empty($id) && strlen($id) >= 8) {
+ try {
+ $timestamp = hexdec(substr($id, 0, 8)) * 1000;
+ $now = time() * 1000;
+ $diff = $now - $timestamp;
+
+ if ($diff < 60000) return '刚刚';
+ elseif ($diff < 3600000) return floor($diff / 60000) . '分钟前';
+ elseif ($diff < 86400000) return floor($iff / 3600000) . '小时前';
+ elseif ($diff < 604800000) return floor($diff / 86400000) . '天前';
+ else return date('Y-m-d', $timestamp / 1000);
+ } catch (Exception $e) {
+ return '刚刚';
+ }
+ }
+ return '刚刚';
+}
+
+// 渲染单个通知项
+function renderNotificationItem($item) {
+ // 头像URL - 从消息中获取avatarNumber
+ $avatarNumber = isset($item['avatar_number']) ? $item['avatar_number'] : 0;
+ $avatarUrl = '';
+ if (!empty($item['uid'])) {
+ $avatarUrl = getAvatarUrl($item['uid'], $avatarNumber);
+ }
+
+ // 默认头像
+ $defaultAvatar = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjYwIiBoZWlnaHQ9IjYwIiBmaWxsPSIjRjBGMEYwIi8+CjxwYXRoIGQ9Ik0zMCAzNEMzMy4zMTM3IDM0IDM2IDMxLjMxMzcgMzYgMjhDMzYgMjQuNjg2MyAzMy4zMTM3IDIyIDMwIDIyQzI2LjY4NjMgMjIgMjQgMjQuNjg2MyAyNCAyOEMyNCAzMS4zMTM3IDI2LjY4NjMgMzQgMzAgMzRaIiBmaWxsPSIjQ0VDRUNFIi8+CjxwYXRoIGQ9Ik0zNiAzOEgyNEMyMi44OTU0IDM4IDIyIDM3LjEwNDYgMjIgMzZWMjRDMjIgMjIuODk1NCAyMi44OTU0IDIyIDI0IDIySDM2QzM3LjEwNDYgMjIgMzggMjIuODk1NCAzOCAyNFYzNkMzOCAzNy4xMDQ2IDM3LjEwNDYgMzggMzYgMzhaTTI0IDI0VjM2SDM2VjI0SDI0WiIgZmlsbD0iI0NFQ0VDRSIvPgo8L3N2Zz4K';
+
+ // 图标URL
+ $iconUrl = getMsgIconUrl($item['msg_type']);
+ $typeName = getMsgTypeName($item['msg_type']);
+
+ // 格式化时间
+ $timeAgo = formatTimeAgo($item['id']);
+
+ // 点击跳转URL
+ $onclick = '';
+ if ($item['msg_type'] === 2 && !empty($item['tid'])) {
+ $onclick = 'onclick="window.location.href=\'med.php?category=' . htmlspecialchars($item['category']) . '&id=' . htmlspecialchars($item['tid']) . '\'"';
+ $style = 'style="cursor: pointer;"';
+ } else {
+ $style = 'style="cursor: default;"';
+ }
+
+ $html = '
登录后查看通知消息
+ +还没有收到任何通知消息
+