From a194246bb9d75b06a81a43c0695b4dac1bcd2d4b Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 10:08:10 +0800 Subject: [PATCH 01/17] Add styles for comment dialog and related elements --- styles/comment.css | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 styles/comment.css diff --git a/styles/comment.css b/styles/comment.css new file mode 100644 index 0000000..262ebfb --- /dev/null +++ b/styles/comment.css @@ -0,0 +1,63 @@ +dialog { + position: fixed; + top: 0%; + left: 0%; + height: 100%; + width: 100%; + border: none; + z-index: 100; + overflow: hidden; +} + +#dt { + position: absolute; + top: 10%; + left: 0%; + height: 90%; + width: 100%; + border: none; + font-size: 3vh; +} + +#dh { + position: absolute; + top: 0%; + left: 0%; + height: 10%; + width: 100%; + background-color: #eee; + } + +.red { + background-color: #e00; + position: absolute; + top: 20%; + left: 88%; + height: 60%; + width: 10%; + color: white; + font-size: 2.5vh; + border-radius: 10px; +} + +.mid { + position: absolute; + top: -10%; + left: 8%; +} + +#start { + height: 30px; + width: 50%; + border: 1px solid #111; + border-radius: none; + text-align: left; + color: gray; + background-color: #eee; +} + +textarea:focus { + border-color: rgba(0,0,0,0); + outline: none; + box-shadow: 0 0 0.1px rgba(255,255,255,0); +} From 1f4de04085990127be38bd77c28cf052c4404afd Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 11:34:11 +0800 Subject: [PATCH 02/17] Implement comment dialog functionality --- scripts/comment.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 scripts/comment.js diff --git a/scripts/comment.js b/scripts/comment.js new file mode 100644 index 0000000..1f57fe8 --- /dev/null +++ b/scripts/comment.js @@ -0,0 +1,70 @@ +document.addEventListener('DOMContentLoaded', () => { + const dialog = document.querySelector('dialog'); + const originalText = dialog.innerHTML.trim(); // 获取原始文本 "编辑评论内容" + + // 解析属性 + const types = dialog.dataset.type.split(','); + const inputPlaceholder = dialog.dataset.ed; + const [methodStr, btnClass, btnText] = dialog.dataset.eb.split(','); + const methodName = methodStr.replace('()', ''); // 提取方法名 "sm" + + // 清空dialog原有内容 + dialog.innerHTML = ''; + + // 创建输入框 + const input = document.createElement('textarea'); + input.id='dt'; + input.placeholder = inputPlaceholder; + dialog.appendChild(input); + + const header = document.createElement('div'); + header.id='dh'; + header.innerHTML='

'+inputPlaceholder+'

'; + dialog.appendChild(header); + + // 创建提交按钮 + const submitBtn = document.createElement('button'); + submitBtn.className = btnClass; + submitBtn.textContent = btnText; + header.appendChild(submitBtn); + + // 提交按钮点击事件 + submitBtn.addEventListener('click', () => { + if (typeof window[methodName] === 'function') { + window[methodName](input.value); // 调用sm函数并传入输入值 + } + dialog.close(); + }); + + // 点击外部关闭对话框 + dialog.addEventListener('click', (e) => { + const rect = dialog.getBoundingClientRect(); + if ( + e.clientX < rect.left || + e.clientX > rect.right || + e.clientY < rect.top || + e.clientY > rect.bottom + ) { + dialog.close(); + } + }); + + // 创建触发按钮并添加到页面 + const trigger = document.createElement('button'); + trigger.textContent = originalText; + trigger.id='start'; + trigger.style.margin = '10px'; // 添加间距 + document.body.insertBefore(trigger, dialog); // 插入到dialog前面 + + // 点击触发按钮打开对话框 + trigger.addEventListener('click', () => { + dialog.showModal(); + input.focus(); // 自动聚焦输入框 + }); +}); + +/* 示例sm函数 */ +function sm(value) { + //向服务器通信 + document.querySelector('dialog').close(); +} From 124e0ca6fec1335379fd0a48a00b2eb4344201bd Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 12:05:29 +0800 Subject: [PATCH 03/17] Implement AuthService for user authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增了 AuthService 类以处理用户登录,并存储 API 响应主体到 session。 --- getv.php | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 getv.php diff --git a/getv.php b/getv.php new file mode 100644 index 0000000..b9a6485 --- /dev/null +++ b/getv.php @@ -0,0 +1,143 @@ +username = $username; + $this->password = $password; + } + + public function login() { + $identifier = bin2hex(random_bytes(20)); + $identifier = str_pad($identifier, 40, '0', STR_PAD_LEFT); + + $requestData = [ + 'Login' => $this->username, + 'Password' => $this->password, + 'Version' => 2411, + 'Device' => [ + 'Identifier' => $identifier, + 'Language' => "Chinese", + ], + 'Statistic' => null, + ]; + + $headers = [ + "Content-Type: application/json", + "Accept: application/json", + "Accept-Language: zh-CN", + ]; + + $response = $this->postRequest("Users/Authenticate", $requestData, $headers); + $statusCode = $response['status']; + $this->responseBody = $response['body']; // 存储原始响应主体 + + $responseData = json_decode($this->responseBody, true); + + // 检查JSON解码是否成功 + if (json_last_error() !== JSON_ERROR_NONE) { + throw new Exception("API响应格式错误: " . json_last_error_msg()); + } + + // 优先检查业务状态码 + if (isset($responseData['Status'])) { + if ($responseData['Status'] === 200) { + $this->token = $responseData['Token'] ?? ''; + $this->authCode = $responseData['AuthCode'] ?? ''; + return $responseData; + } else { + $errorMsg = $responseData['Message'] ?? '登录失败'; + throw new Exception($errorMsg); + } + } + // 处理 HTTP 错误 + elseif ($statusCode >= 400) { + $errorMap = [ + 403 => '访问被拒绝(403)', + 404 => '资源不存在(404)', + 500 => '服务器错误(500)' + ]; + $errorMsg = $errorMap[$statusCode] ?? "HTTP 错误: $statusCode"; + throw new Exception($errorMsg); + } + // 完全无效的响应 + else { + throw new Exception("无效的API响应"); + } + } + + private function postRequest($endpoint, $data, $headers = []) { + $url = $this->baseUrl . $endpoint; + + $ch = curl_init($url); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_POST => true, + CURLOPT_HTTPHEADER => $headers, + CURLOPT_POSTFIELDS => json_encode($data), + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_TIMEOUT => 15, + CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', + CURLOPT_SSL_VERIFYPEER => true, + ]); + + $response = curl_exec($ch); + + if ($response === false) { + $error = curl_error($ch); + curl_close($ch); + throw new Exception("请求失败: $error"); + } + + $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + + $body = substr($response, $headerSize); + + curl_close($ch); + + return [ + 'status' => $statusCode, + 'body' => $body + ]; + } +} + +try { + if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $username = $_POST['username'] ?? ''; + $password = $_POST['password'] ?? ''; + + if (!empty($username) && !empty($password)) { + $authService = new AuthService($username, $password); + $loginData = $authService->login(); + + // 登录成功,保存到session + $_SESSION['username'] = $username; + $_SESSION['token'] = $authService->token; + $_SESSION['authCode'] = $authService->authCode; + $_SESSION['responseBody'] = $authService->responseBody; // 存储响应主体到session + + // 重定向或显示成功消息 + header('Location: /'); + exit; + } else { + $error = "用户名和密码不能为空"; + } + } +} catch (Exception $e) { + +} +?> From 562e3f974d88c801f96b2d950a1a031799dcd464 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 12:06:34 +0800 Subject: [PATCH 04/17] Refactor login method to remove constructor Removed constructor and initialized login credentials as empty strings. --- getv.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/getv.php b/getv.php index b9a6485..13b542c 100644 --- a/getv.php +++ b/getv.php @@ -13,18 +13,13 @@ class AuthService { public $authCode; public $responseBody; // 新增:存储API响应主体 - public function __construct($username, $password) { - $this->username = $username; - $this->password = $password; - } - public function login() { $identifier = bin2hex(random_bytes(20)); $identifier = str_pad($identifier, 40, '0', STR_PAD_LEFT); $requestData = [ - 'Login' => $this->username, - 'Password' => $this->password, + 'Login' => '', + 'Password' => '', 'Version' => 2411, 'Device' => [ 'Identifier' => $identifier, From 271295daf0a25ca7c610ebbff1033cc323178d8d Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 12:53:33 +0800 Subject: [PATCH 05/17] Refactor authentication to use empty credentials Removed username and password handling from POST request. --- getv.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/getv.php b/getv.php index 13b542c..44d9142 100644 --- a/getv.php +++ b/getv.php @@ -1,6 +1,6 @@ login(); // 登录成功,保存到session @@ -128,11 +123,5 @@ private function postRequest($endpoint, $data, $headers = []) { // 重定向或显示成功消息 header('Location: /'); exit; - } else { - $error = "用户名和密码不能为空"; - } } -} catch (Exception $e) { - -} ?> From f6561b3b8336d5263cafcf0a84fc227354469cf2 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 13:40:09 +0800 Subject: [PATCH 06/17] Refactor login handling and error management --- getv.php | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/getv.php b/getv.php index 44d9142..3f42f20 100644 --- a/getv.php +++ b/getv.php @@ -1,17 +1,23 @@ postRequest("Users/Authenticate", $requestData, $headers); $statusCode = $response['status']; - $this->responseBody = $response['body']; // 存储原始响应主体 + $this->responseBody = $response['body']; $responseData = json_decode($this->responseBody, true); @@ -110,18 +116,22 @@ private function postRequest($endpoint, $data, $headers = []) { } } - if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $authService = new AuthService('', ''); - $loginData = $authService->login(); - - // 登录成功,保存到session - $_SESSION['username'] = $username; - $_SESSION['token'] = $authService->token; - $_SESSION['authCode'] = $authService->authCode; - $_SESSION['responseBody'] = $authService->responseBody; // 存储响应主体到session - - // 重定向或显示成功消息 - header('Location: /'); - exit; +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + try { + $authService = new AuthService(); + $loginData = $authService->login(); + + // 登录成功,保存到session + $_SESSION['username'] = $loginData['Data']['User']['Nickname'] ?? '匿名用户'; + $_SESSION['token'] = $authService->token; + $_SESSION['authCode'] = $authService->authCode; + $_SESSION['responseBody'] = $authService->responseBody; + + // 重定向到首页 + header('Location: /'); + exit; + } catch (Exception $e) { + $errorMsg = $e->getMessage(); } +} ?> From 19409799ec5bdeb6b316e3a514b4c2f98fea23aa Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 13:42:23 +0800 Subject: [PATCH 07/17] Add login check and redirect to getv.php Redirect to getv.php if user is not logged in. --- index.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/index.php b/index.php index eae1fef..2504aaa 100644 --- a/index.php +++ b/index.php @@ -7,7 +7,10 @@ // 检查登录状态 $isLoggedIn = isset($dt['Data']['User']['Nickname']) && $dt['Data']['User']['Nickname'] !== '点击登录'; - +if(!$isLoggedIn){ + header('Location: getv.php'); + exit; +} // 获取API数据 function getCommunityData() { $apiUrl = 'https://nlm-api-cn.turtlesim.com/Users'; From 7939a13e06ef031430df2836387da4463b6c8cb9 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 14:58:49 +0800 Subject: [PATCH 08/17] Add redirection for missing session responseBody Redirect to getv.php if responseBody is not set in session. --- med.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/med.php b/med.php index 66dc68a..808518f 100644 --- a/med.php +++ b/med.php @@ -10,6 +10,10 @@ $dt = null; if (isset($_SESSION['responseBody'])) { $dt = is_string($_SESSION['responseBody']) ? json_decode($_SESSION['responseBody'], true) : $_SESSION['responseBody']; +} else { + $redirectUrl = '/getv.php?r=' . urlencode('med.php?category=' . $category . '&id=' . $contentId . '&type=' . $type); + header('Location: ' . $redirectUrl); + exit; } // 获取作品详情的函数 @@ -66,7 +70,7 @@ function getContentSummary($contentId, $category, $token, $authCode) { $token = $_SESSION['token'] ?? ''; $authCode = $_SESSION['authCode'] ?? ''; - if (!empty($token) && !empty($authCode)) { + if (isset($token) && isset($authCode)) { $contentData = getContentSummary($contentId, $category, $token, $authCode); } } From 5729b2103cd650c689b00cf281f334afdda398cf Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 14:59:25 +0800 Subject: [PATCH 09/17] Update redirection logic based on session response Redirect to a specific URL if a response body is set in the session. --- getv.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/getv.php b/getv.php index 3f42f20..bc7fde4 100644 --- a/getv.php +++ b/getv.php @@ -1,9 +1,9 @@ login(); - - // 登录成功,保存到session - $_SESSION['username'] = $loginData['Data']['User']['Nickname'] ?? '匿名用户'; $_SESSION['token'] = $authService->token; $_SESSION['authCode'] = $authService->authCode; $_SESSION['responseBody'] = $authService->responseBody; // 重定向到首页 - header('Location: /'); + header('Location: /' . $r); exit; } catch (Exception $e) { $errorMsg = $e->getMessage(); + echo $errorMsg; } -} ?> From 11335004296c6250a8ca1c544cf5bd1343eb60c9 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 15:00:05 +0800 Subject: [PATCH 10/17] Implement session check and redirect if not set Add redirection logic for session response handling. --- index.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/index.php b/index.php index 2504aaa..60a1648 100644 --- a/index.php +++ b/index.php @@ -3,14 +3,21 @@ $dt = null; if (isset($_SESSION['responseBody'])) { $dt = is_string($_SESSION['responseBody']) ? json_decode($_SESSION['responseBody'], true) : $_SESSION['responseBody']; +} else { + $redirectUrl = '/getv.php'; + if (!headers_sent()) { + header('Location: ' . $redirectUrl); + exit; + } else { + // 如果已经有输出,使用JavaScript重定向作为备用 + echo ''; + exit; + } } // 检查登录状态 $isLoggedIn = isset($dt['Data']['User']['Nickname']) && $dt['Data']['User']['Nickname'] !== '点击登录'; -if(!$isLoggedIn){ - header('Location: getv.php'); - exit; -} + // 获取API数据 function getCommunityData() { $apiUrl = 'https://nlm-api-cn.turtlesim.com/Users'; From 47b6bf653e216fcd440adba931f2cb5a252b7a78 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 15:11:54 +0800 Subject: [PATCH 11/17] Add comment.html for editing comments --- comment/comment.html | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 comment/comment.html diff --git a/comment/comment.html b/comment/comment.html new file mode 100644 index 0000000..aa474a1 --- /dev/null +++ b/comment/comment.html @@ -0,0 +1,13 @@ + + + + + + 编辑评论 + + + + 发一条友善的评论吧 + + + From 6ad20a3ac3843c84253c542b1ef8bc7446777b4c Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sat, 29 Nov 2025 19:18:46 +0800 Subject: [PATCH 12/17] Update content display logic in med.php --- med.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/med.php b/med.php index 808518f..c76d079 100644 --- a/med.php +++ b/med.php @@ -76,7 +76,6 @@ function getContentSummary($contentId, $category, $token, $authCode) { } $content = $contentData['Data'] ?? null; - // 处理日期格式 function formatDate($timestamp) { return date('Y年m月d日', $timestamp / 1000); @@ -130,7 +129,7 @@ function formatDate($timestamp) { } ?>');">
-
+
@@ -212,7 +211,7 @@ function formatDate($timestamp) { -

暂无作品介绍

+ ', $content['Description']) ?>
From 888e3be582ae738664f5eabdac98405d634706e9 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sun, 30 Nov 2025 16:09:04 +0800 Subject: [PATCH 13/17] Update dialog styles and layout for responsiveness Refactor dialog styles for improved layout and responsiveness. --- styles/comment.css | 191 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 147 insertions(+), 44 deletions(-) diff --git a/styles/comment.css b/styles/comment.css index 262ebfb..d938a86 100644 --- a/styles/comment.css +++ b/styles/comment.css @@ -1,33 +1,3 @@ -dialog { - position: fixed; - top: 0%; - left: 0%; - height: 100%; - width: 100%; - border: none; - z-index: 100; - overflow: hidden; -} - -#dt { - position: absolute; - top: 10%; - left: 0%; - height: 90%; - width: 100%; - border: none; - font-size: 3vh; -} - -#dh { - position: absolute; - top: 0%; - left: 0%; - height: 10%; - width: 100%; - background-color: #eee; - } - .red { background-color: #e00; position: absolute; @@ -40,24 +10,157 @@ dialog { border-radius: 10px; } +textarea:focus { + border-color: rgba(0,0,0,0); + outline: none; + box-shadow: 0 0 0.1px rgba(255,255,255,0); +} + +/* 评论框样式修复 */ +dialog { + position: fixed; + top: 5%; + left: 5%; + z-index: 80; + height: 90%; + width: 90%; + border: none; + border-radius: 12px; + box-shadow: 0 10px 30px rgba(0,0,0,0.3); + background: white; + overflow: hidden; +} + +#dt { + position: absolute; + top: 10%; + left: 0%; + height: 90%; + width: 100%; + border: none; + font-size: 16px; + padding: 20px; + resize: none; + font-family: inherit; + line-height: 1.5; + background: #fafafa; +} + +#dh { + position: absolute; + top: 0%; + left: 0%; + height: 10%; + width: 100%; + background-color: #f8f9fa; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 20px; + border-bottom: 1px solid #e9ecef; + } + +#dh img { + cursor: pointer; + padding: 8px; + border-radius: 50%; + transition: background-color 0.2s; +} + +#dh img:hover { + background-color: rgba(0,0,0,0.1); +} + .mid { - position: absolute; - top: -10%; - left: 8%; + font-size: 18px; + font-weight: 600; + color: #333; + margin: 0; +} + +.red { + background-color: red; + position: static; + height: auto; + width: auto; + color: white; + font-size: 14px; + border-radius: 10px; + border: none; + padding: 8px 20px; + cursor: pointer; + transition: background-color 0.3s; + margin: 0; +} + +.red:hover { + background-color: #1060c0; } +/* 移除原有的绝对定位样式 */ +.red, +.mid { + position: static; + top: auto; + left: auto; +} + +/* 移动端适配 */ +@media (max-width: 768px) { + dialog { + top: 2%; + left: 2%; + height: 96%; + width: 96%; + } + + #dt { + font-size: 14px; + padding: 15px; + } + + .mid { + font-size: 16px; + } + + .red { + padding: 6px 16px; + font-size: 13px; + } + + #dh { + padding: 0 15px; + } +} + +/* 对话框背景遮罩 */ +dialog::backdrop { + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(2px); +} + +/* #start 按钮位置和尺寸修复 */ #start { - height: 30px; - width: 50%; - border: 1px solid #111; - border-radius: none; - text-align: left; - color: gray; - background-color: #eee; + position: fixed; + bottom: 0px; + right: 0%; + transform: translateY(-10%); + height: 40px; + width: 48%; + z-index: 70; + border: 1px solid #111; + border-radius: none; + text-align: left; + color: gray; + background-color: #f6f6f6; } -textarea:focus { - border-color: rgba(0,0,0,0); - outline: none; - box-shadow: 0 0 0.1px rgba(255,255,255,0); +/* 移动端适配 */ +@media (max-width: 768px) { + #start { + bottom: 0px; + width: 98%; + max-width: 700px; + height: 45px; + } } From a65d799745f1ec843853c0802c8cbe48d7895d9f Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sun, 30 Nov 2025 16:09:54 +0800 Subject: [PATCH 14/17] Fix image source and refactor trigger button logic Updated image source path and modified trigger button handling. --- scripts/comment.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/scripts/comment.js b/scripts/comment.js index 1f57fe8..fa43547 100644 --- a/scripts/comment.js +++ b/scripts/comment.js @@ -1,4 +1,3 @@ -document.addEventListener('DOMContentLoaded', () => { const dialog = document.querySelector('dialog'); const originalText = dialog.innerHTML.trim(); // 获取原始文本 "编辑评论内容" @@ -19,7 +18,7 @@ document.addEventListener('DOMContentLoaded', () => { const header = document.createElement('div'); header.id='dh'; - header.innerHTML='

'+inputPlaceholder+'

'; + header.innerHTML='

'+inputPlaceholder+'

'; dialog.appendChild(header); // 创建提交按钮 @@ -49,19 +48,11 @@ document.addEventListener('DOMContentLoaded', () => { } }); - // 创建触发按钮并添加到页面 - const trigger = document.createElement('button'); - trigger.textContent = originalText; - trigger.id='start'; - trigger.style.margin = '10px'; // 添加间距 - document.body.insertBefore(trigger, dialog); // 插入到dialog前面 - // 点击触发按钮打开对话框 - trigger.addEventListener('click', () => { + document.getElementById('start').addEventListener('click', () => { dialog.showModal(); input.focus(); // 自动聚焦输入框 }); -}); /* 示例sm函数 */ function sm(value) { From 22c2d27739d2158ea9bf0601697111cd197c4699 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sun, 30 Nov 2025 16:10:46 +0800 Subject: [PATCH 15/17] Refactor comment.html to use a button for comments --- comment/comment.html | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/comment/comment.html b/comment/comment.html index aa474a1..6fcaf77 100644 --- a/comment/comment.html +++ b/comment/comment.html @@ -1,13 +1,3 @@ - - - - - - 编辑评论 - - - - 发一条友善的评论吧 - - - + +发一条友善的评论吧 + From 4f49b28fe6dbba06f76607c72c6c0ad7fa55d738 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sun, 30 Nov 2025 16:11:46 +0800 Subject: [PATCH 16/17] Refactor user info section with tabs Updated the layout to include a tabbed interface for user information and comments, and removed the statistics section. --- med.php | 103 ++++++++++++++------------------------------------------ 1 file changed, 26 insertions(+), 77 deletions(-) diff --git a/med.php b/med.php index c76d079..d27151b 100644 --- a/med.php +++ b/med.php @@ -102,7 +102,7 @@ function formatDate($timestamp) { <?= htmlspecialchars($content['LocalizedSubject']['Chinese'] ?? $pageTitle) ?> - Turtle Universe Web - + @@ -154,7 +154,18 @@ function formatDate($timestamp) {
- + +
+
+
简介
+
评论()
+
+ +
+
+ +
+
- - -
-
-
-
访问量
-
-
-
-
收藏
-
-
-
-
支持
-
-
-
-
评论
-
-
- - -
-
-
简介
-
详细信息
-
- -
-
- -
-
+

作品介绍

@@ -218,50 +197,11 @@ function formatDate($timestamp) {
- - - -
- - - -
@@ -275,7 +215,7 @@ function formatDate($timestamp) { // 标签页切换 function switchTab(tabName) { // 隐藏所有标签内容 - document.querySelectorAll('.tab-content').forEach(tab => { + document.querySelectorAll('.qh').forEach(tab => { tab.style.display = 'none'; }); @@ -320,6 +260,15 @@ function shareExperiment() { function remixExperiment() { alert('改编功能即将开放'); } - +// 使用JavaScript动态加载评论 +fetch('/comment/?category=&id=') + .then(response => response.text()) + .then(html => { + document.getElementById('comments').innerHTML = html; + }) + .catch(error => { + document.getElementById('comments').innerHTML = '
加载评论失败
'; + }); + From 7997007444fd3ef9596d683f25e06850925b5a96 Mon Sep 17 00:00:00 2001 From: Tiaotiao <65841827@qq.com> Date: Sun, 30 Nov 2025 16:12:56 +0800 Subject: [PATCH 17/17] Add comment handling functionality in index.php --- comment/index.php | 388 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 388 insertions(+) create mode 100644 comment/index.php diff --git a/comment/index.php b/comment/index.php new file mode 100644 index 0000000..0f9698e --- /dev/null +++ b/comment/index.php @@ -0,0 +1,388 @@ +token = $token; + $this->authCode = $authCode; + } + + /** + * 获取留言/评论信息 + */ + public function getMessages( + $ID, + $type = "Discussion", + $take = 20, + $from = null, + $skip = 0 + ) { + // 验证必需参数 + if (empty($ID)) { + throw new Exception("ID参数不能为空"); + } + + if (empty($type)) { + throw new Exception("类型参数不能为空"); + } + + if ($take > 100) { + throw new Exception("消息获取数量一次最多为100条"); + } + + $take = -$take; + + $requestData = [ + 'TargetID' => $ID, + 'TargetType' => $type, + 'Take' => $take, + 'Skip' => $skip, + ]; + + // 只有在提供了from参数时才添加CommentID字段 + if ($from !== null) { + $requestData['CommentID'] = $from; + } + + $headers = [ + 'Content-Type: application/json', + 'Accept: application/json', + 'Accept-Language: zh-CN', + ]; + + if ($this->token && !empty($this->token)) { + $headers[] = 'x-API-Token: ' . $this->token; + } + + if ($this->authCode && !empty($this->authCode)) { + $headers[] = 'x-API-AuthCode: ' . $this->authCode; + } + + $url = $this->baseUrl . 'Messages/GetComments'; + + $ch = curl_init(); + curl_setopt_array($ch, [ + CURLOPT_URL => $url, + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => json_encode($requestData), + CURLOPT_HTTPHEADER => $headers, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_TIMEOUT => 30, + ]); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $error = curl_error($ch); + curl_close($ch); + + if ($error) { + throw new Exception("请求失败: " . $error); + } + + if ($httpCode !== 200) { + $errorInfo = ''; + if ($response) { + $responseData = json_decode($response, true); + if (isset($responseData['Message'])) { + $errorInfo = ' - ' . $responseData['Message']; + } + } + throw new Exception("API请求失败,HTTP状态码: " . $httpCode . $errorInfo); + } + + $data = json_decode($response, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new Exception("JSON解析失败: " . json_last_error_msg()); + } + + // 检查API返回的业务状态码 + if (isset($data['Status']) && $data['Status'] !== 200) { + $errorMsg = $data['Message'] ?? '未知错误'; + throw new Exception("API返回错误: " . $errorMsg); + } + + return $data; + } + + // 设置认证信息 + public function setAuth($token, $authCode) { + $this->token = $token; + $this->authCode = $authCode; + return $this; + } +} + +// 类形式的使用示例: +$messageService = new MessageService($_SESSION['token'], $_SESSION['authCode']); +try { + $messages = $messageService->getMessages($contentId, $category, 20); + $target = $messages['Data']['Target'] ?? []; + $comments = $messages['Data']['Comments'] ?? []; + $totalComments = $messages['Data']['Count'] ?? 0; +} catch (Exception $e) { + echo "错误: " . $e->getMessage(); +} + +// 生成头像URL函数 +function getAvatarUrl($userID, $avatarNumber) { + // 根据用户ID构建头像路径 + $part1 = substr($userID, 0, 4); + $part2 = substr($userID, 4, 2); + $part3 = substr($userID, 6, 2); + $part4 = substr($userID, 8, 16); + + return "http://netlogo-static-cn.turtlesim.com/users/avatars/{$part1}/{$part2}/{$part3}/{$part4}/{$avatarNumber}.jpg!full"; +} + +// 格式化时间函数 +function formatCommentTime($timestamp) { + if (!$timestamp) return '未知时间'; + + // 如果是毫秒时间戳,转换为秒 + if ($timestamp > 9999999999) { + $timestamp = $timestamp / 1000; + } + + $date = date('n/j', $timestamp); + $hour = date('G', $timestamp); + $minute = date('i', $timestamp); + + // 转换为12小时制并添加上午/下午 + if ($hour < 12) { + $period = '上午'; + $displayHour = $hour == 0 ? 12 : $hour; + } else { + $period = '下午'; + $displayHour = $hour > 12 ? $hour - 12 : $hour; + } + + return "{$date} {$period}{$displayHour}:{$minute}"; +} + +// 处理回复内容中的@用户标签 +function processReplyContent($content) { + // 匹配 @用户名 格式 + $pattern = '/@([^<]+)/'; + $replacement = '@$2'; + + return preg_replace($pattern, $replacement, $content); +} +?> + +
+ +
+ 加载失败: +
+ + + +
+

暂无评论

+
+ + $comment): ?> +
+
+
+ <?= htmlspecialchars($comment['Nickname'] ?? '用户') ?> +
+
+
+
+
+
+
+
+ +
+
+
+
+ + + + +
+ + +
+ +
+ +