From 31a0b5f7d635e7f95e042ec02a63276aab3c0c25 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sun, 3 May 2026 11:47:34 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20med.php?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- med.php | 869 +++++++++++++++++++++++++------------------------------- 1 file changed, 383 insertions(+), 486 deletions(-) diff --git a/med.php b/med.php index cf38c52..4a21b15 100644 --- a/med.php +++ b/med.php @@ -1,195 +1,123 @@ ')); +define('DEFAULT_COVER', 'data:image/svg+xml;base64,' . base64_encode('')); + +// ---------- API 请求函数 ---------- function getContentSummary($contentId, $category, $token, $authCode) { - $baseUrl = 'http://nlm-api-cn.turtlesim.com/'; - $url = $baseUrl . 'Contents/GetSummary'; - - $requestData = [ - 'ContentID' => $contentId, - 'Category' => $category, - ]; - + $url = 'http://nlm-api-cn.turtlesim.com/Contents/GetSummary'; + $body = json_encode(['ContentID' => $contentId, 'Category' => $category]); $headers = [ - "Content-Type: application/json", - "Accept: application/json", - "Accept-Language: zh-CN", - "x-API-Token: " . $token, - "x-API-AuthCode: " . $authCode, + 'Content-Type: application/json', 'Accept: application/json', 'Accept-Language: zh-CN', + 'x-API-Token: ' . $token, 'x-API-AuthCode: ' . $authCode, ]; - $ch = curl_init($url); curl_setopt_array($ch, [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_POST => true, - CURLOPT_HTTPHEADER => $headers, - CURLOPT_POSTFIELDS => json_encode($requestData), - CURLOPT_FOLLOWLOCATION => true, - CURLOPT_TIMEOUT => 15, - CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', - CURLOPT_SSL_VERIFYPEER => true, + CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, CURLOPT_POST => true, + CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => $body, + CURLOPT_TIMEOUT => 15, CURLOPT_USERAGENT => 'Mozilla/5.0', CURLOPT_SSL_VERIFYPEER => true, ]); - $response = curl_exec($ch); - if ($response === false) { - curl_close($ch); - return null; - } - - $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $body = substr($response, $headerSize); + $bodyResp = substr($response, $headerSize); curl_close($ch); - - $responseData = json_decode($body, true); - return json_last_error() === JSON_ERROR_NONE ? $responseData : null; + $data = json_decode($bodyResp, true); + return (json_last_error() === JSON_ERROR_NONE) ? $data : null; } -// 获取改编列表 -function getDerivatives($contentId, $category, $token, $authCode) { - $baseUrl = 'http://nlm-api-cn.turtlesim.com/'; - $url = $baseUrl . 'Contents/GetDerivatives'; - - $requestData = [ - 'ContentID' => $contentId, - 'Category' => $category, - 'Language' => 'Chinese', - 'WithSummary' => true - ]; - +function getDerivativesAndSupporters($contentId, $category, $token, $authCode) { + $url = 'http://nlm-api-cn.turtlesim.com/Contents/GetDerivatives'; + $body = json_encode(['ContentID' => $contentId, 'Category' => $category]); $headers = [ - "Content-Type: application/json", - "Accept: application/json", - "Accept-Language: zh-CN", - "x-API-Token: " . $token, - "x-API-AuthCode: " . $authCode, + 'Content-Type: application/json', 'Accept: application/json', 'Accept-Language: zh-CN', + 'x-API-Token: ' . $token, 'x-API-AuthCode: ' . $authCode, ]; - $ch = curl_init($url); curl_setopt_array($ch, [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_POST => true, - CURLOPT_HTTPHEADER => $headers, - CURLOPT_POSTFIELDS => json_encode($requestData), - CURLOPT_FOLLOWLOCATION => true, + CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, + CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => $body, CURLOPT_TIMEOUT => 15, ]); - $response = curl_exec($ch); - $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $body = substr($response, $headerSize); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $curlError = curl_error($ch); curl_close($ch); - - $data = json_decode($body, true); - return json_last_error() === JSON_ERROR_NONE ? $data : null; + + // 调试日志(上线后可注释) + // error_log("GetDerivatives HTTP Code: $httpCode, Error: $curlError, Response: $response"); + + if ($response === false || $httpCode !== 200) return null; + $data = json_decode($response, true); + if (json_last_error() !== JSON_ERROR_NONE) return null; + return $data['Data'] ?? null; } -// 检查是否已收藏(Star) function isContentStarred($contentId, $category, $token, $authCode) { - $baseUrl = 'http://nlm-api-cn.turtlesim.com/'; - $url = $baseUrl . 'Contents/IsStarred'; - - $requestData = [ - 'ContentID' => $contentId, - 'Category' => $category, - ]; - + $url = 'http://nlm-api-cn.turtlesim.com/Contents/IsStarred'; + $body = json_encode(['ContentID' => $contentId, 'Category' => $category]); $headers = [ - "Content-Type: application/json", - "x-API-Token: " . $token, - "x-API-AuthCode: " . $authCode, + 'Content-Type: application/json', + 'x-API-Token: ' . $token, 'x-API-AuthCode: ' . $authCode, ]; - $ch = curl_init($url); curl_setopt_array($ch, [ - CURLOPT_RETURNTRANSFER => true, - CURLOPT_HEADER => true, - CURLOPT_POST => true, - CURLOPT_HTTPHEADER => $headers, - CURLOPT_POSTFIELDS => json_encode($requestData), - CURLOPT_TIMEOUT => 10, + CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, CURLOPT_POST => true, + CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => $body, CURLOPT_TIMEOUT => 10, ]); - $response = curl_exec($ch); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $body = substr($response, $headerSize); + $bodyResp = substr($response, $headerSize); curl_close($ch); - - $data = json_decode($body, true); - if ($data && isset($data['Data']) && is_bool($data['Data'])) { - return $data['Data']; - } - return false; -} - -// 获取作品详情 -$contentData = null; -if (!empty($contentId) && !empty($category)) { - $token = $_SESSION['token'] ?? ''; - $authCode = $_SESSION['authCode'] ?? ''; - - if (isset($token) && isset($authCode)) { - $contentData = getContentSummary($contentId, $category, $token, $authCode); - } + $data = json_decode($bodyResp, true); + return ($data && isset($data['Data']) && $data['Data'] === true); } +// ---------- 获取数据 ---------- +$contentData = getContentSummary($contentId, $category, $token, $authCode); $content = $contentData['Data'] ?? null; -// 获取改编列表 -$remixes = []; -$isStarred = false; -if ($content && $contentId && $category) { - $derivativesData = getDerivatives($contentId, $category, $token, $authCode); - if ($derivativesData && isset($derivativesData['Data']['Experiments']['Children-Models'])) { - $remixes = $derivativesData['Data']['Experiments']['Children-Models']; - } - // 获取初始收藏状态 - $isStarred = isContentStarred($contentId, $category, $token, $authCode); -} +// 改编 + 支持者 +$derivativesData = getDerivativesAndSupporters($contentId, $category, $token, $authCode); +$remixes = $derivativesData['Experiments']['Children-Models'] ?? []; +$supporters = $derivativesData['Supporters'] ?? []; +$parentModel = $derivativesData['Model'] ?? null; -// 处理日期格式 -function formatDate($timestamp) { - return date('Y年m月d日', $timestamp / 1000); +$isStarred = isContentStarred($contentId, $category, $token, $authCode); + +// ---------- 辅助函数 ---------- +function buildAvatarUrl($userId, $avatarId) { + if (!$avatarId || !$userId) return DEFAULT_AVATAR; + $base = 'http://netlogo-cn.oss-cn-hongkong.aliyuncs.com/users/avatars/'; + return $base . substr($userId,0,4) . '/' . substr($userId,4,2) . '/' . substr($userId,6,2) . '/' . substr($userId,8,16) . '/' . $avatarId . '.jpg!full'; } -// 页面标题映射 -$pageTitles = [ - 'explore' => '探索指南', - 'featured' => '精选实验', - 'daily' => '每日模型', - 'hot' => '热门实验', - 'new' => '最新实验', - 'visual' => '可视化编程', - 'knowledge' => '实验知识库' -]; -$pageTitle = $pageTitles[$type] ?? '作品详情'; +function buildThumbUrl($exp) { + if (($exp['Image'] ?? 0) < 0) return DEFAULT_COVER; + $base = 'http://netlogo-cn.oss-cn-hongkong.aliyuncs.com/experiments/images/'; + $id = $exp['ID']; + return $base . substr($id,0,4) . '/' . substr($id,4,2) . '/' . substr($id,6,2) . '/' . substr($id,8,16) . '/' . $exp['Image'] . '.jpg!full'; +} -// 自定义标签解析器类 class CustomTagParser { public static function parse(string $text): string { if (empty($text)) return ''; $text = htmlspecialchars($text); - $text = self::parseMarkdownHeadings($text); $text = nl2br($text); - $patterns = [ '/<user=([a-f0-9]+)>(.*?)<\/user>/i', '/<experiment=([a-f0-9]+)>(.*?)<\/experiment>/i', @@ -202,7 +130,6 @@ public static function parse(string $text): string { '/<i>(.*?)<\/i>/i', '/<a>(.*?)<\/a>/i' ]; - $replacements = [ '$2', '$2', @@ -215,21 +142,7 @@ public static function parse(string $text): string { '$1', '$1' ]; - $text = preg_replace($patterns, $replacements, $text); - $text = self::parseSimpleMarkdown($text); - return $text; - } - - private static function parseMarkdownHeadings(string $text): string { - $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; - } - - private static function parseSimpleMarkdown(string $text): string { $text = preg_replace('/\*\*(.*?)\*\*/', '$1', $text); $text = preg_replace('/\*(.*?)\*/', '$1', $text); $text = preg_replace('/~~(.*?)~~/', '$1', $text); @@ -244,204 +157,176 @@ private static function parseSimpleMarkdown(string $text): string { - - <?= htmlspecialchars($content['LocalizedSubject']['Chinese'] ?? $pageTitle) ?> - Turtle Universe Web + <?= htmlspecialchars($content['LocalizedSubject']['Chinese'] ?? $content['Subject'] ?? '作品详情') ?> - Turtle Universe Web - + -
-
- -
- -
- -
- - +
+
+ +
+
+ +
+ + +
+
+
+
+ +
+ + + + + + +
- - -
-
-
-
- -   - - - - - -
+
+
+
+
收藏
+
+
分享
- -
- -
-
- -
-
- 收藏 -
-
- -
-
- 分享 -
-
- - -
- - -
+
+ +
+
- -
-
-
-
-
-
简介
-
评论()
-
改编()
-
- -
-
- -
-