|
| 1 | +<?php |
| 2 | +session_start(); |
| 3 | +$dt = null; |
| 4 | +if (isset($_SESSION['responseBody'])) { |
| 5 | + $dt = is_string($_SESSION['responseBody']) ? json_decode($_SESSION['responseBody'], true) : $_SESSION['responseBody']; |
| 6 | +} else { |
| 7 | + $redirectUrl = '/getv.php?r=me.php'; |
| 8 | + if (!headers_sent()) { |
| 9 | + header('Location: ' . $redirectUrl); |
| 10 | + exit; |
| 11 | + } else { |
| 12 | + // 如果已经有输出,使用JavaScript重定向作为备用 |
| 13 | + echo '<script>window.location.href = "' . $redirectUrl . '";</script>'; |
| 14 | + exit; |
| 15 | + } |
| 16 | +} |
| 17 | + |
| 18 | +// 检查登录状态 |
| 19 | +$isLoggedIn = isset($dt['Data']['User']['Nickname']) && $dt['Data']['User']['Nickname'] !== '点击登录'; |
| 20 | + |
| 21 | +// 获取API数据 |
| 22 | +function getCommunityData() { |
| 23 | + $baseUrl = "http://nlm-api-cn.turtlesim.com/"; |
| 24 | + |
| 25 | + // 准备请求数据 |
| 26 | + $requestData = [ |
| 27 | + 'Identifier' => 'Workspace', |
| 28 | + 'Language' => "Chinese" |
| 29 | + ]; |
| 30 | + |
| 31 | + // 准备请求头 |
| 32 | + $headers = [ |
| 33 | + 'Content-Type: application/json', |
| 34 | + 'Accept: application/json', |
| 35 | + 'Accept-Language: zh-CN', |
| 36 | + ]; |
| 37 | + |
| 38 | + // 添加认证头(修复了多余的大括号) |
| 39 | + $headers[] = 'x-API-Token: ' . $_SESSION['token']; |
| 40 | + $headers[] = 'x-API-AuthCode: ' . $_SESSION['authCode']; |
| 41 | + |
| 42 | + // 发送POST请求 |
| 43 | + $url = $baseUrl . 'Contents/GetLibrary'; |
| 44 | + |
| 45 | + $ch = curl_init(); |
| 46 | + curl_setopt_array($ch, [ |
| 47 | + CURLOPT_URL => $url, |
| 48 | + CURLOPT_POST => true, |
| 49 | + CURLOPT_POSTFIELDS => json_encode($requestData, JSON_UNESCAPED_UNICODE), |
| 50 | + CURLOPT_HTTPHEADER => $headers, |
| 51 | + CURLOPT_RETURNTRANSFER => true, |
| 52 | + CURLOPT_SSL_VERIFYPEER => false, |
| 53 | + CURLOPT_TIMEOUT => 30, |
| 54 | + ]); |
| 55 | + |
| 56 | + $response = curl_exec($ch); |
| 57 | + curl_close($ch); |
| 58 | + $data = json_decode($response, true); |
| 59 | + return $data; |
| 60 | +} |
| 61 | + |
| 62 | +// 处理日期格式 |
| 63 | +function formatDate($id) { |
| 64 | + return (strlen($id) >= 8) ? date('m/d', hexdec(substr($id, 0, 8)) * 1000 / 1000) : '未知日期'; |
| 65 | +} |
| 66 | + |
| 67 | +// 获取数据 |
| 68 | +$communityData = getCommunityData(); |
| 69 | + |
| 70 | +// 模块配置 |
| 71 | +$modules = [ |
| 72 | + ['title' => '本地实验', 'count' => 4, 'featured' => false, 'type' => 'explore', 'category' => 'Local'], |
| 73 | + ['title' => '创建模型', 'count' => 3, 'featured' => true, 'type' => 'featured', 'category' => 'Model'], |
| 74 | + ['title' => '我的模型', 'count' => 4, 'featured' => false, 'type' => 'daily', 'category' => 'Model'], |
| 75 | + ['title' => '我的实验', 'count' => 4, 'featured' => false, 'type' => 'hot', 'category' => 'Experiment'], |
| 76 | + ['title' => '我的讨论', 'count' => 4, 'featured' => false, 'type' => 'new', 'category' => 'Discussion'], |
| 77 | + ['title' => '我支持的模型', 'count' => 4, 'featured' => false, 'type' => 'daily', 'category' => 'Model'], |
| 78 | + ['title' => '我支持的实验', 'count' => 4, 'featured' => false, 'type' => 'hot', 'category' => 'Experiment'], |
| 79 | + ['title' => '我支持的讨论', 'count' => 4, 'featured' => false, 'type' => 'new', 'category' => 'Discussion'], |
| 80 | + ['title' => '我收藏的模型', 'count' => 4, 'featured' => false, 'type' => 'daily', 'category' => 'Model'], |
| 81 | + ['title' => '我收藏的实验', 'count' => 4, 'featured' => false, 'type' => 'hot', 'category' => 'Experiment'], |
| 82 | + ['title' => '我收藏的讨论', 'count' => 4, 'featured' => false, 'type' => 'new', 'category' => 'Discussion'] |
| 83 | +]; |
| 84 | +?> |
| 85 | +<!DOCTYPE html> |
| 86 | +<html> |
| 87 | +<head> |
| 88 | + <meta charset="utf-8"> |
| 89 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 90 | + <meta name="referrer" content="no-referrer"> |
| 91 | + <title>Turtle Universe Web - Workspace</title> |
| 92 | + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> |
| 93 | + <style> |
| 94 | + *{margin:0;padding:0;box-sizing:border-box}body{font-family:'Arial','Microsoft YaHei',sans-serif;background-color:#f5f7fa;color:#333;line-height:1.6;padding:0;margin:0}.header{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:white;padding:15px 20px;display:flex;justify-content:space-between;align-items:center;box-shadow:0 2px 10px rgba(0,0,0,0.1);position:sticky;top:0;z-index:1000}.user-info{display:flex;align-items:center;gap:12px;cursor:pointer;transition:opacity 0.3s ease}.user-info:hover{opacity:0.8}.user-info.login-prompt{cursor:pointer}.avatar{width:45px;height:45px;background:rgba(255,255,255,0.2);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:20px}.user-details{display:flex;flex-direction:column}.nickname{font-weight:bold;font-size:16px}.level{font-size:12px;opacity:0.8}.resources{display:flex;gap:15px}.coin,.diamond{display:flex;align-items:center;gap:5px;font-size:14px}.coin i{color:#ffd700}.diamond i{color:#b9f2ff}.content{padding:20px 15px 70px;max-width:1200px;margin:0 auto}.page-title{text-align:center;margin-bottom:25px;color:#333}.page-title h1{font-size:24px;margin-bottom:8px;color:#667eea}.page-title p{color:#666;font-size:14px}.community-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:20px;margin-top:20px}.block{background:white;border-radius:15px;padding:20px;box-shadow:0 4px 15px rgba(0,0,0,0.1);transition:transform 0.3s ease,box-shadow 0.3s ease;position:relative;overflow:hidden}.block:hover{transform:translateY(-5px);box-shadow:0 8px 25px rgba(0,0,0,0.15)}.block-header{color:#667eea;font-size:18px;font-weight:bold;margin-bottom:15px;padding-bottom:10px;border-bottom:2px solid #f0f0f0}.block-content{max-height:400px;overflow-y:auto}.item{display:flex;align-items:center;padding:12px 0;border-bottom:1px solid #f5f5f5;transition:background-color 0.3s ease;cursor:pointer}.item:hover{background-color:#f8f9ff;border-radius:8px;padding:12px 8px}.item:last-child{border-bottom:none}.item-img{width:60px;height:60px;border-radius:10px;object-fit:cover;margin-right:15px;flex-shrink:0;border:2px solid #e0e0e0}.item-details{flex:1}.item-title{font-weight:bold;font-size:14px;margin-bottom:5px;color:#333;line-height:1.3}.item-meta{font-size:12px;color:#666;margin-bottom:5px}.item-tags{display:flex;flex-wrap:wrap;gap:5px}.tag{background:#e3f2fd;color:#1976d2;padding:2px 8px;border-radius:12px;font-size:10px;font-weight:500}.featured-block{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:white}.featured-block .block-header{color:white;border-bottom-color:rgba(255,255,255,0.3)}.featured-block .item-title{color:white}.featured-block .item-meta{color:rgba(255,255,255,0.8)}.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;transition:color 0.3s ease;cursor:pointer}.footer div.active{color:#667eea}.footer i{font-size:20px}.error{text-align:center;padding:40px 20px;color:#e74c3c}.retry-btn{background:#667eea;color:white;border:none;padding:10px 20px;border-radius:20px;margin-top:15px;cursor:pointer;transition:background 0.3s ease}.retry-btn:hover{background:#5a6fd8}.more-button-container{text-align:center;margin-top:15px;padding-top:15px;border-top:1px solid rgba(255,255,255,0.3)}.featured-block .more-button-container{border-top-color:rgba(255,255,255,0.3)}.more-button{background:rgba(255,255,255,0.2);color:white;border:1px solid rgba(255,255,255,0.5);padding:8px 20px;border-radius:20px;cursor:pointer;font-size:14px;transition:all 0.3s ease}.more-button:hover{background:rgba(255,255,255,0.3);transform:translateY(-2px)}.block:not(.featured-block) .more-button-container{border-top-color:#f0f0f0}.block:not(.featured-block) .more-button{background:#667eea;color:white;border:none}.block:not(.featured-block) .more-button:hover{background:#5a6fd8}@media (max-width:768px){.community-grid{grid-template-columns:1fr}.header{padding:12px 15px}.content{padding:15px 10px 70px}.avatar{width:40px;height:40px;font-size:18px}.nickname{font-size:14px}.resources{gap:10px}}@media (max-width:480px){.block{padding:15px}.item-img{width:50px;height:50px;margin-right:12px}.item-title{font-size:13px}}.block-content::-webkit-scrollbar{width:4px}.block-content::-webkit-scrollbar-track{background:#f1f1f1;border-radius:2px}.block-content::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:2px}.block-content::-webkit-scrollbar-thumb:hover{background:#a8a8a8} |
| 95 | + </style> |
| 96 | +</head> |
| 97 | +<body> |
| 98 | + <header class="header"> |
| 99 | + <h2>我的实验室</h2> |
| 100 | + </header> |
| 101 | + |
| 102 | + <main class="content"> |
| 103 | + <?php if ($communityData && isset($communityData['Data']['Blocks'])): ?> |
| 104 | + <?php $blocks = $communityData['Data']['Blocks']; ?> |
| 105 | + <div class="community-grid"> |
| 106 | + <?php foreach ($modules as $index => $module): ?> |
| 107 | + <?php if (isset($blocks[$index])): ?> |
| 108 | + <?php |
| 109 | + $block = $blocks[$index]; |
| 110 | + $summaries = $block['Summaries'] ?? []; |
| 111 | + ?> |
| 112 | + <div class="block <?= $module['featured'] ? 'featured-block' : '' ?>"> |
| 113 | + <div class="block-header"><?= $module['title'] ?></div> |
| 114 | + <div class="block-content"> |
| 115 | + <?php foreach (array_slice($summaries, 0, $module['count']) as $exp): ?> |
| 116 | + <?php |
| 117 | + $subject = $exp['Subject'] ?? ($exp['LocalizedSubject']['Chinese'] ?? '未知主题'); |
| 118 | + $author = $exp['User']['Nickname'] ?? '未知作者'; |
| 119 | + $date = formatDate($exp['ID'] ?? ''); |
| 120 | + $tags = $exp['Tags'] ?? []; |
| 121 | + $imgSrc = 'http://netlogo-cn.oss-cn-hongkong.aliyuncs.com/experiments/images/' . |
| 122 | + substr($exp['ID'] ?? '0000000000000000', 0, 4) . '/' . |
| 123 | + substr($exp['ID'] ?? '0000000000000000', 4, 2) . '/' . |
| 124 | + substr($exp['ID'] ?? '0000000000000000', 6, 2) . '/' . |
| 125 | + substr($exp['ID'] ?? '0000000000000000', 8, 16) . '/' . |
| 126 | + ($exp['Image'] ?? 'default') . '.jpg!full'; |
| 127 | + ?> |
| 128 | + <div class="item" onclick="window.location='med.php?category=<?= $module['category'] ?>&id=<?= $exp['ID'] ?>'"> |
| 129 | + <img src="<?= htmlspecialchars($imgSrc) ?>" alt="<?= htmlspecialchars($subject) ?>" class="item-img" onerror="this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjYwIiBoZWlnaHQ9IjYwIiBmaWxsPSIjRjBGMEYwIi8+CjxwYXRoIGQ9Ik0zMCAzNEMzMy4zMTM3IDM0IDM2IDMxLjMxMzcgMzYgMjhDMzYgMjQuNjg2MyAzMy4zMTM3IDIyIDMwIDIyQzI2LjY4NjMgMjIgMjQgMjQuNjg2MyAyNCAyOEMyNCAzMS4zMTM3IDI2LjY4NjMgMzQgMzAgMzRaIiBmaWxsPSIjQ0VDRUNFIi8+CjxwYXRoIGQ9Ik0zNiAzOEgyNEMyMi44OTU0IDM4IDIyIDM3LjEwNDYgMjIgMzZWMjRDMjIgMjIuODk1NCAyMi44OTU0IDIyIDI0IDIySDM2QzM3LjEwNDYgMjIgMzggMjIuODk1NCAzOCAyNFYzNkMzOCAzNy4xMDQ2IDM3LjEwNDYgMzggMzYgMzhaTTI0IDI0VjM2SDM2VjI0SDI0WiIgZmlsbD0iI0NFQ0VDRSIvPgo8L3N2Zz4K'"> |
| 130 | + <div class="item-details"> |
| 131 | + <div class="item-title"><?= htmlspecialchars($subject) ?></div> |
| 132 | + <div class="item-meta"><?= htmlspecialchars($author) ?> - <?= $date ?></div> |
| 133 | + <?php if (!empty($tags)): ?> |
| 134 | + <div class="item-tags"> |
| 135 | + <?php foreach (array_slice($tags, 0, 3) as $tag): ?> |
| 136 | + <span class="tag"><?= htmlspecialchars($tag) ?></span> |
| 137 | + <?php endforeach; ?> |
| 138 | + </div> |
| 139 | + <?php endif; ?> |
| 140 | + </div> |
| 141 | + </div> |
| 142 | + <?php endforeach; ?> |
| 143 | + </div> |
| 144 | + <div class="more-button-container"> |
| 145 | + <button class="more-button" onclick="window.location='med.php?category=<?= $module['category'] ?>&type=<?= $module['type'] ?>'">查看更多</button> |
| 146 | + </div> |
| 147 | + </div> |
| 148 | + <?php endif; ?> |
| 149 | + <?php endforeach; ?> |
| 150 | + </div> |
| 151 | + <?php else: ?> |
| 152 | + <div class="error"> |
| 153 | + <p>无法加载社区数据,请检查网络连接或稍后重试</p> |
| 154 | + <button class="retry-btn" onclick="window.location.reload()">重新加载</button> |
| 155 | + </div> |
| 156 | + <?php endif; ?> |
| 157 | + </main> |
| 158 | + |
| 159 | + <div class="footer"> |
| 160 | + <div onclick="location.href='/'"><i class="fas fa-home"></i><span>首页</span></div> |
| 161 | + <div class="active"><i class="fas fa-user"></i><span>我的</span></div> |
| 162 | + <div onclick="location.href='discussion.php'"><i class="fas fa-water"></i><span>海水</span></div> |
| 163 | + <div onclick="location.href='model.php'"><i class="fas fa-cube"></i><span>模型库</span></div> |
| 164 | + <div onclick="location.href='nof.php'"><i class="fas fa-bell"></i><span>通知</span></div> |
| 165 | + </div> |
| 166 | + |
| 167 | + <script> |
| 168 | + document.addEventListener('DOMContentLoaded', function() { |
| 169 | + const footerItems = document.querySelectorAll('.footer div'); |
| 170 | + footerItems.forEach(item => { |
| 171 | + item.addEventListener('click', function() { |
| 172 | + footerItems.forEach(i => i.classList.remove('active')); |
| 173 | + this.classList.add('active'); |
| 174 | + }); |
| 175 | + }); |
| 176 | + }); |
| 177 | + </script> |
| 178 | +</body> |
| 179 | +</html> |
0 commit comments