Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
317 changes: 242 additions & 75 deletions comment/index.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<?php
session_start();

// 获取参数
$category = $_GET['category'] ?? 'Model';
// 获取参数,category首字母大写
$category = isset($_GET['category']) ? ucfirst($_GET['category']) : 'Model';
$contentId = $_GET['id'] ?? '';
$skp = number_format($_GET['skip']) ?? 0;
$skp = isset($_GET['skip']) ? (int)$_GET['skip'] : 0;

// 获取用户数据
$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 . '&skip=' . $skp);
header('Location: ' . $redirectUrl);
exit;
$redirectUrl = '/getv.php?r=' . urlencode('med.php?category=' . $category . '&id=' . $contentId . '&skip=' . $skp);
header('Location: ' . $redirectUrl);
exit;
}

// 类形式的实现(可选)
// 类形式的实现
class MessageService {
private $token;
private $authCode;
Expand Down Expand Up @@ -135,14 +135,14 @@ public function setAuth($token, $authCode) {
}

// 类形式的使用示例:
$messageService = new MessageService($_SESSION['token'], $_SESSION['authCode']);
$messageService = new MessageService($_SESSION['token'] ?? null, $_SESSION['authCode'] ?? null);
try {
$messages = $messageService->getMessages($contentId, $category, 20);
$messages = $messageService->getMessages($contentId, $category, 20, null, $skp);
$target = $messages['Data']['Target'] ?? [];
$comments = $messages['Data']['Comments'] ?? [];
$totalComments = $messages['Data']['Count'] ?? 0;
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
$error = $e->getMessage();
}

// 生成头像URL函数
Expand Down Expand Up @@ -181,35 +181,99 @@ function formatCommentTime($timestamp) {
return "{$date} {$period}{$displayHour}:{$minute}";
}

// 处理回复内容中的@用户标签
function processReplyContent($content) {
// 匹配 <user=用户ID>@用户名 格式
$pattern = '/<user=([a-f0-9]+)>([^<]+)<\/user>/';
$replacement = '<span class="RUser" data-user="$1">$2</span>';
// 自定义标签解析器类
class CustomTagParser {

return preg_replace($pattern, $replacement, $content);
}
?>
<style>
/* * {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
/**
* 解析包含自定义标签的文本
*/
public static function parse(string $text): string {
if (empty($text)) {
return '';
}

body {
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
}
// 先转义HTML特殊字符,防止XSS攻击
$text = htmlspecialchars($text);

// 将换行符转换为<br>
$text = nl2br($text);

// 解析自定义标签
$patterns = [
// user标签 - 保持原有格式
'/&lt;user=([a-f0-9]+)&gt;(.*?)&lt;\/user&gt;/i',
// experiment标签 - 跳转链接
'/&lt;experiment=([a-f0-9]+)&gt;(.*?)&lt;\/experiment&gt;/i',
// discussion标签 - 跳转链接
'/&lt;discussion=([a-f0-9]+)&gt;(.*?)&lt;\/discussion&gt;/i',
// model标签 - 跳转链接
'/&lt;model=([a-f0-9]+)&gt;(.*?)&lt;\/model&gt;/i',
// external标签 - 外部链接
'/&lt;external=([^&]+)&gt;(.*?)&lt;\/external&gt;/i',
// size标签
'/&lt;size=([^&]+)&gt;(.*?)&lt;\/size&gt;/i',
// color标签 - 新增
'/&lt;color=([^&]+)&gt;(.*?)&lt;\/color&gt;/i',
// b标签
'/&lt;b&gt;(.*?)&lt;\/b&gt;/i',
// i标签
'/&lt;i&gt;(.*?)&lt;\/i&gt;/i',
// a标签 - 深蓝色标签
'/&lt;a&gt;(.*?)&lt;\/a&gt;/i'
];

$replacements = [
// user标签
'<span class="RUser" data-user="$1">$2</span>',
// experiment标签
'<a href="med.php?id=$1&category=Experiment" class="experiment-link">$2</a>',
// discussion标签
'<a href="med.php?id=$1&category=Discussion" class="discussion-link">$2</a>',
// model标签
'<a href="med.php?id=$1&category=Model" class="model-link">$2</a>',
// external标签
'<a href="$1" target="_blank" rel="noopener noreferrer nofollow" class="external-link">$2</a>',
// size标签
'<span style="font-size: $1;">$2</span>',
// color标签 - 新增
'<span style="color: $1;">$2</span>',
// b标签
'<strong>$1</strong>',
// i标签
'<em>$1</em>',
// a标签
'<span class="blue-tag">$1</span>'
];

$text = preg_replace($patterns, $replacements, $text);

// 解析简单的Markdown格式
$text = self::parseSimpleMarkdown($text);

return $text;
}

/**
* 解析简单的Markdown格式
*/
private static function parseSimpleMarkdown(string $text): string {
// 粗体
$text = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $text);

// 斜体
$text = preg_replace('/\*(.*?)\*/', '<em>$1</em>', $text);

.scroll-container {
max-width: 80vh;
margin: 0 auto;
padding: 16px;
}*/
// 删除线
$text = preg_replace('/~~(.*?)~~/', '<del>$1</del>', $text);

// 行内代码
$text = preg_replace('/`([^`]+)`/', '<code>$1</code>', $text);

return $text;
}
}
?>
<style>
#notification_container {
display: flex;
padding: 12px 0;
Expand Down Expand Up @@ -309,49 +373,152 @@ function processReplyContent($content) {
margin-bottom: 16px;
color: #d9d9d9;
}
</style>
<div class="scroll-container">
<?php if (isset($error)): ?>
<div class="error-message">
<strong>加载失败:</strong><?= htmlspecialchars($error) ?>
</div>
<?php endif; ?>

<?php if (empty($comments)): ?>
<div class="empty-state">
<p>暂无评论</p>
</div>
<?php else: ?>
<?php foreach ($comments as $index => $comment): ?>
<div>
<div id="notification_container" data-rid="<?= $comment['UserID'] ?? '' ?>">
<div class="img">
<img id="avatar"
src="<?= getAvatarUrl($comment['UserID'] ?? '', $comment['Avatar'] ?? 0) ?>"
alt="<?= htmlspecialchars($comment['Nickname'] ?? '用户') ?>"
onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiByeD0iMjAiIGZpbGw9IiNGRjVFNjYiLz4KPHN2ZyB4PSI4IiB5PSI4IiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyQzIgMTcuNTIgNi40OCAyMiAxMiAyMkMxNy41MiAyMiAyMiAxNy41MiAyMiAxMkMyMiA2LjQ4IDE3LjUyIDIgMTIgMlpNMTIgNUMxMy42NiA1IDE1IDYuMzQgMTUgOEMxNSA5LjY2IDEzLjY2IDExIDEyIDExQzEwLjM0IDExIDkgOS42NiA5IDhDOSA2LjM0IDEwLjM0IDUgMTIgNVpNMTIgMTkuMkM5LjUgMTkuMiA3LjIxIDE3LjkyIDYgMTUuOThDNi4wMSAxMy45OSAxMCAxMi45IDEyIDEyLjlDMTMuOTkgMTIuOSAxNy45OSAxMy45OSAxOCAxNS45OEMxNi43OSAxNy45MiAxNC41IDE5LjIgMTIgMTkuMloiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo8L3N2Zz4K'">
</style>
<style>
/* <a>标签样式 - 深蓝色标签,无边框,大小与普通字体一样 */
.blue-tag {
color: #0000FF;
font-size: 1em;
text-decoration: none;
border: none;
padding: 0;
margin: 0;
background: none;
font-weight: normal;
}

/* 会跳转的标签样式 - 包括experiment, discussion, model, external */
.experiment-link,
.discussion-link,
.model-link,
.external-link {
color: #2881E0;
font-size: 1em;
text-decoration: none;
border: none;
padding: 0;
margin: 0 2px;
background: none;
font-weight: normal;
}

.experiment-link:hover,
.discussion-link:hover,
.model-link:hover,
.external-link:hover {
text-decoration: underline;
}

/* color标签样式 - 继承父元素字体大小 */
.notification_text [style*="color:"] {
font-size: inherit;
border: none;
padding: 0;
margin: 0;
background: none;
}

/* Markdown代码样式 */
.notification_text code {
background-color: #f5f5f5;
padding: 2px 4px;
border-radius: 2px;
font-family: monospace;
font-size: 0.9em;
color: #c7254e;
}

.notification_text del {
color: #999;
text-decoration: line-through;
}

.notification_text strong {
font-weight: 600;
}

.notification_text em {
font-style: italic;
}
</style>

<div id="top-con"></div>
<div class="scroll-container">
<?php if (isset($error)): ?>
<div class="error-message">
<strong>加载失败:</strong><?= htmlspecialchars($error) ?>
</div>
<?php endif; ?>

<?php if (empty($comments)): ?>
<div class="empty-state">
<p>暂无评论</p>
</div>
<?php else: ?>
<?php foreach ($comments as $index => $comment): ?>
<div>
<div id="notification_container" data-rid="<?= htmlspecialchars($comment['UserID'] ?? '') ?>">
<div class="img">
<img id="avatar"
src="<?= getAvatarUrl($comment['UserID'] ?? '', $comment['Avatar'] ?? 0) ?>"
alt="<?= htmlspecialchars($comment['Nickname'] ?? '用户') ?>"
onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjQwIiBoZWlnaHQ9IjQwIiByeD0iMjAiIGZpbGw9IiNGRjVFNjYiLz4KPHN2ZyB4PSI4IiB5PSI4IiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyQzIgMTcuNTIgNi40OCAyMiAxMiAyMkMxNy41MiAyMiAyMiAxNy41MiAyMiAxMkMyMiA2LjQ4IDE3LjUyIDIgMTIgMlpNMTIgNUMxMy42NiA1IDE1IDYuMzQgMTUgOEMxNSA5LjY2IDEzLjY2IDExIDEyIDExQzEwLjM0IDExIDkgOS42NiA5IDhDOSA2LjM0IDEwLjM0IDUgMTIgNVpNMTIgMTkuMkM5LjUgMTkuMiA3LjIxIDE3LjkyIDYgMTUuOThDNi4wMSAxMy45OSAxMCAxMi45IDEyIDEyLjlDMTMuOTkgMTIuOSAxNy45OSAxMy45OSAxOCAxNS45OEMxNi43OSAxNy45MiAxNC41IDE5LjIgMTIgMTkuMloiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo8L3N2Zz4K'">
</div>
<div id="notification" class="notification">
<div id="notification_title" class="notification_title">
<div class="name"><?= htmlspecialchars($comment['Nickname'] ?? '匿名用户') ?></div>
<div class="time"><?= formatCommentTime($comment['Timestamp'] ?? 0) ?></div>
</div>
<div id="notification" class="notification">
<div id="notification_title" class="notification_title">
<div class="name"><?= htmlspecialchars($comment['Nickname'] ?? '匿名用户') ?></div>
<div class="time"><?= formatCommentTime($comment['Timestamp'] ?? 0) ?></div>
</div>
<div id="notification_message" class="notification_message">
<div id="notification_text" class="notification_text">
<?= processReplyContent($comment['Content'] ?? '') ?>
</div>
<div id="notification_message" class="notification_message">
<div id="notification_text" class="notification_text">
<?= CustomTagParser::parse($comment['Content'] ?? '') ?>
</div>
</div>
</div>

<?php if ($index < count($comments) - 1): ?>
<div role="separator" class="n-divider n-divider--no-title" style="--n-bezier: cubic-bezier(0.4, 0, 0.2, 1); --n-color: rgb(239, 239, 245); --n-text-color: rgb(31, 34, 37); --n-font-weight: 500; margin: 0px;">
<div class="n-divider__line n-divider__line--left"></div>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>

<div class="observer-element" style="margin-top: 0px;"></div>
<?php endif; ?>
</div>

<?php if ($index < count($comments) - 1): ?>
<div role="separator" class="n-divider n-divider--no-title" style="--n-bezier: cubic-bezier(0.4, 0, 0.2, 1); --n-color: rgb(239, 239, 245); --n-text-color: rgb(31, 34, 37); --n-font-weight: 500; margin: 0px;">
<div class="n-divider__line n-divider__line--left"></div>
</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div id="bottom-con" style="margin-top: 0px;"></div>

<script>
// 添加点击交互功能
document.addEventListener('DOMContentLoaded', function() {
// 点击用户头像或名称时跳转到用户页面
const userElements = document.querySelectorAll('#notification_container');
userElements.forEach(container => {
const avatar = container.querySelector('#avatar');
const name = container.querySelector('.name');
const userId = container.getAttribute('data-rid');

const onClick = function() {
// 跳转到用户页面
if (userId) {
window.location.href = 'user.php?id=' + userId;
}
};

if (avatar) avatar.addEventListener('click', onClick);
if (name) name.addEventListener('click', onClick);
});

// 点击@用户时跳转到对应用户页面
const rUsers = document.querySelectorAll('.RUser');
rUsers.forEach(rUser => {
rUser.addEventListener('click', function(e) {
e.stopPropagation();
const userId = this.getAttribute('data-user');
if (userId) {
window.location.href = 'user.php?id=' + userId;
}
});
});
});
</script>
Loading