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
2 changes: 1 addition & 1 deletion comment/comment.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<button id='start' style='margin: 10px'>&nbsp;发一条友善的评论吧</button>
<button id='start' data-rid="" style='margin: 10px'>&nbsp;发一条友善的评论吧</button>
<dialog data-type='prompt,all' data-ed='编辑 评论内容' data-eb='sm(),red,提交'>发一条友善的评论吧</dialog>
<script src='../scripts/comment.js'></script>
45 changes: 7 additions & 38 deletions comment/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ function formatCommentTime($timestamp) {
// 处理回复内容中的@用户标签
function processReplyContent($content) {
// 匹配 <user=用户ID>@用户名 格式
$pattern = '/<user=([a-f0-9]+)>@([^<]+)/';
$replacement = '<span class="RUser" data-user="$1">@$2</span>';
$pattern = '/<user=([a-f0-9]+)>([^<]+)<\/user>/';
$replacement = '<span class="RUser" data-user="$1">$2</span>';

return preg_replace($pattern, $replacement, $content);
}
Expand All @@ -202,13 +202,13 @@ function processReplyContent($content) {
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
}*/
}

.scroll-container {
max-width: 80vh;
margin: 0 auto;
/*padding: 16px;*/
}
padding: 16px;
}*/

#notification_container {
display: flex;
Expand Down Expand Up @@ -324,7 +324,7 @@ function processReplyContent($content) {
<?php else: ?>
<?php foreach ($comments as $index => $comment): ?>
<div>
<div id="notification_container">
<div id="notification_container" data-rid="<?= $comment['UserID'] ?? '' ?>">
<div class="img">
<img id="avatar"
src="<?= getAvatarUrl($comment['UserID'] ?? '', $comment['Avatar'] ?? 0) ?>"
Expand All @@ -338,7 +338,7 @@ function processReplyContent($content) {
</div>
<div id="notification_message" class="notification_message">
<div id="notification_text" class="notification_text">
<?= processReplyContent(nl2br(htmlspecialchars($comment['Content'] ?? ''))) ?>
<?= processReplyContent($comment['Content'] ?? '') ?>
</div>
</div>
</div>
Expand All @@ -355,34 +355,3 @@ function processReplyContent($content) {
<div class="observer-element" style="margin-top: 0px;"></div>
<?php endif; ?>
</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 onClick = function() {
// 这里可以添加跳转到用户页面的逻辑
console.log('点击用户:', this.textContent || this.alt);
};

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

// 点击@用户时跳转到对应用户页面
const rUsers = document.querySelectorAll('.RUser');
rUsers.forEach(rUser => {
rUser.addEventListener('click', function() {
const userId = this.getAttribute('data-user');
const userName = this.textContent;
console.log('点击@用户:', userName, 'ID:', userId);
// 这里可以添加跳转到对应用户页面的逻辑
});
});
});
</script>
152 changes: 152 additions & 0 deletions comment/send.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php
session_start();

// 设置响应头为JSON
header('Content-Type: application/json');

$id = $_GET['id'] ?? '';
$content = $_GET['con'] ?? '';
$type = $_GET['category'] ?? 'Discussion';
$rid = $_GET['rid'] ?? '';

// 检查必需参数
if (empty($id)) {
http_response_code(400);
echo json_encode(['error' => '缺少ID参数']);
exit;
}

if (empty($content)) {
http_response_code(400);
echo json_encode(['error' => '缺少内容参数']);
exit;
}

// 检查登录状态
if (!isset($_SESSION['token']) || empty($_SESSION['token'])) {
http_response_code(401);
echo json_encode(['error' => '未登录或会话已过期']);
exit;
}

function sendMessages(
$TargetID,
$Content,
$TargetType = "Discussion",
$ReplyID = "",
$token = null,
$authCode = null
) {
// 验证必需参数
if (empty($TargetID)) {
throw new Exception("TargetID参数不能为空");
}

if (empty($Content)) {
throw new Exception("消息内容不能为空");
}

$baseUrl = "http://nlm-api-cn.turtlesim.com/";

// 准备请求数据
$requestData = [
'TargetID' => $TargetID,
'TargetType' => $TargetType,
'Language' => "Chinese",
'ReplyID' => $ReplyID,
'Content' => $Content,
'Special' => null,
];

// 准备请求头
$headers = [
'Content-Type: application/json',
'Accept: application/json',
'Accept-Language: zh-CN',
];

// 添加认证头
if ($token && !empty($token)) {
$headers[] = 'x-API-Token: ' . $token;
}

if ($authCode && !empty($authCode)) {
$headers[] = 'x-API-AuthCode: ' . $authCode;
}

// 发送POST请求
$url = $baseUrl . 'Messages/PostComment';

$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($requestData, JSON_UNESCAPED_UNICODE),
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);
}

// 解析JSON响应
$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;
}

try {
// 修复参数顺序问题
$result = sendMessages(
$id, // TargetID
$content, // Content
$type, // TargetType
$rid, // ReplyID (空字符串)
$_SESSION['token'] ?? null, // token
$_SESSION['authCode'] ?? null // authCode
);

echo json_encode([
'success' => true,
'data' => $result
]);

} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'error' => $e->getMessage()
]);
}
?>
37 changes: 36 additions & 1 deletion med.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function formatDate($timestamp) {
<meta name="referrer" content="no-referrer">
<meta name="google" content="notranslate">
<title><?= htmlspecialchars($content['LocalizedSubject']['Chinese'] ?? $pageTitle) ?> - Turtle Universe Web</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<link rel='stylesheet' href='../styles/comment.css'/>
<style>
*{margin:0;padding:0;box-sizing:border-box}body{font-family:v-sans,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:14px;line-height:1.6;margin:0;background:#f5f7fa;color:#333}.RUser{color:cornflowerblue}a[internal]{color:cornflowerblue;text-decoration:none}.basic-layout{display:flex;height:100vh}.layout-left{flex:1;position:relative}.layout-right{flex:1;overflow:hidden}.cover{height:100%;background-size:cover;background-position:center;position:relative;display:flex;flex-direction:column;padding:20px}.return{width:2.7em;cursor:pointer}.title{font-size:24px;font-weight:bold;color:white;margin:10px 0;text-align:left}.tag{display:inline-block;padding:4px 12px;margin:2px;border-radius:16px;background:rgba(255,255,255,0.2);color:white;font-size:12px}.coverBottom{margin-top:auto}.btns{display:flex;justify-content:space-around}.enter{padding:8px 24px;border-radius:25px;background:#2080f0;color:white;border:none;cursor:pointer;font-size:14px}.scroll-container{height:100%;overflow-y:auto}.context{padding:20px}.n-tabs{width:100%}.n-tabs-wrapper{display:flex;justify-content:space-evenly}.n-tabs-tab{padding:10px 0;cursor:pointer;color:#666}.n-tabs-tab--active{color:#18a058;font-weight:500}.n-tab-pane{margin-top:20px}.gray{background:#f8f9fa;border-radius:12px;padding:15px}.intro{text-align:left;line-height:1.8}.intro p{margin-bottom:15px}.intro h1,.intro h2,.intro h3{color:#2080f0;margin:20px 0 10px}.intro ul,.intro ol{margin:10px 0;padding-left:20px}.intro li{margin:5px 0}.user-info{display:flex;align-items:center;padding:15px;background:white;border-radius:10px;margin:5px 0}.user-avatar{width:50px;height:50px;border-radius:50%;margin-right:15px}.user-details{text-align:left}.user-name{color:#007bff;margin:0;font-size:16px}.user-bio{color:gray;margin:5px 0 0}.action-buttons{display:flex;gap:10px;margin:20px 0}.btn{padding:10px 20px;border-radius:20px;border:none;cursor:pointer;font-size:14px}.btn-primary{background:#2080f0;color:white}.btn-secondary{background:#f8f9fa;color:#333;border:1px solid #ddd}.error{text-align:center;padding:60px 20px;color:#e74c3c}.empty{text-align:center;padding:60px 20px;color:#666}.back-button{position:absolute;top:20px;left:20px;background:rgba(255,255,255,0.2);color:white;border:none;padding:8px 16px;border-radius:20px;cursor:pointer;z-index:10}.footer{position:fixed;bottom:0;left:0;right:0;background:white;display:flex;justify-content:space-around;padding:10px 0;box-shadow:0 -2px 10px rgba(0,0,0,0.1);z-index:1000}.footer div{display:flex;flex-direction:column;align-items:center;gap:5px;font-size:12px;color:#666}.footer div.active{color:#667eea}.footer i{font-size:20px}.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:15px 0}.stat-item{text-align:center;padding:10px;background:white;border-radius:8px}.stat-number{font-size:18px;font-weight:bold;color:#2080f0}.stat-label{font-size:12px;color:#666}.markdown-content h1{font-size:24px;margin:20px 0 10px}.markdown-content h2{font-size:20px;margin:15px 0 8px}.markdown-content h3{font-size:16px;margin:12px 0 6px}.markdown-content ul,.markdown-content ol{padding-left:20px}.markdown-content li{margin:5px 0}@media (max-width:768px){.basic-layout{flex-direction:column}.layout-left,.layout-right{flex:none}.layout-left{height:50vh}.layout-right{height:50vh}.stats-grid{grid-template-columns:repeat(2,1fr)}}
Expand Down Expand Up @@ -133,7 +134,7 @@ function formatDate($timestamp) {
<div style="position: absolute; z-index: 100;">
<div class="tag" style="color: aquamarine; font-weight: bold;">
<?= htmlspecialchars($content['Category'] === 'Model' ? 'Model' : 'Experiment') ?>
</div>
</div><div class="tag"><i class="fas fa-eye"></i>&nbsp;<?= $content['Visits'] ?? 0 ?></div>
<?php if ($content && isset($content['Tags'])): ?>
<?php foreach (array_slice($content['Tags'], 0, 5) as $tag): ?>
<div class="tag"><?= htmlspecialchars($tag) ?></div>
Expand Down Expand Up @@ -270,5 +271,39 @@ function remixExperiment() {
document.getElementById('comments').innerHTML = '<div class="error">加载评论失败</div>';
});
</script>
<script>
setInterval(()=>{
// 点击用户头像或名称时跳转到用户页面
const userElements = document.querySelectorAll('#notification_container');
userElements.forEach(container => {
const avatar = container.querySelector('#avatar');
const name = container.querySelector('.name');
container.addEventListener('click', function(){
document.body.querySelector('textarea').value='回复@'+name.innerHTML+': ';
const bt=document.getElementById('start');
bt.innerText=' 回复@'+name.innerText+':';
bt.style.color='black';
bt.dataset.rid=container.dataset.rid;
});
const onClick = function() {
/*this.textContent || this.alt*/
};

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

// 点击@用户时跳转到对应用户页面
const rUsers = document.querySelectorAll('.RUser');
rUsers.forEach(rUser => {
rUser.addEventListener('click', function() {
const userId = this.getAttribute('data-user');
const userName = this.textContent;
console.log('点击@用户:', userName, 'ID:', userId);
// 这里可以添加跳转到对应用户页面的逻辑
});
});
}, 500);
</script>
</body>
</html>
13 changes: 12 additions & 1 deletion scripts/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@

/* 示例sm函数 */
function sm(value) {
//向服务器通信
var rid = document.getElementById('start').dataset.rid;
fetch('/comment/send.php?'+location.href.split('?')[1]+'&con='+value+'&rid='+rid)
.then(() => {
fetch('/comment/?'+location.href.split('?')[1])
.then(response => response.text())
.then(html => {
document.getElementById('comments').innerHTML = html;
})
.catch(error => {
document.getElementById('comments').innerHTML = '<div class="error">加载评论失败</div>';
});
});
document.querySelector('dialog').close();
}