qxzhan revised this gist 2 months ago. Go to revision
1 file changed, 223 insertions
php(file created)
| @@ -0,0 +1,223 @@ | |||
| 1 | + | <?php | |
| 2 | + | ||
| 3 | + | /** | |
| 4 | + | * 友链 | |
| 5 | + | * | |
| 6 | + | * @package custom | |
| 7 | + | * | |
| 8 | + | **/ | |
| 9 | + | ||
| 10 | + | if (!defined('__TYPECHO_ROOT_DIR__')) { | |
| 11 | + | http_response_code(404); | |
| 12 | + | exit; | |
| 13 | + | } | |
| 14 | + | $this->need('module/single/pjax.php'); | |
| 15 | + | ?> | |
| 16 | + | <!DOCTYPE html> | |
| 17 | + | <html lang="zh-CN"> | |
| 18 | + | ||
| 19 | + | <head> | |
| 20 | + | <?php $this->need('module/head.php') ?> | |
| 21 | + | <link rel="stylesheet" href="<?= joe\theme_url('assets/css/joe.friend.css') ?>"> | |
| 22 | + | <style> | |
| 23 | + | .status-tag { | |
| 24 | + | position: absolute; | |
| 25 | + | top: 0px; | |
| 26 | + | right: 0px; | |
| 27 | + | padding: 3px 8px; | |
| 28 | + | border-radius: 0px 12px 0px 12px; | |
| 29 | + | font-size: 12px; | |
| 30 | + | color: white; | |
| 31 | + | font-weight: bold; | |
| 32 | + | transition: font-size 0.3s ease-out, width 0.3s ease-out, opacity 0.3s ease-out; | |
| 33 | + | z-index: 1; | |
| 34 | + | } | |
| 35 | + | .joe_detail__friends-item:hover .status-tag { | |
| 36 | + | font-size: 0px; | |
| 37 | + | opacity: 0; | |
| 38 | + | } | |
| 39 | + | /* 固态颜色 */ | |
| 40 | + | .status-tag-green { | |
| 41 | + | background-color: #005E00; /* 绿色 */ | |
| 42 | + | } | |
| 43 | + | .status-tag-light-yellow { | |
| 44 | + | background-color: #FED101; /* 浅黄色 */ | |
| 45 | + | } | |
| 46 | + | .status-tag-dark-yellow { | |
| 47 | + | background-color: #F0B606; /* 深黄色 */ | |
| 48 | + | } | |
| 49 | + | .status-tag-red { | |
| 50 | + | background-color: #B90000; /* 红色 */ | |
| 51 | + | } | |
| 52 | + | ||
| 53 | + | /* 修改卡片样式,使用头像作为背景 */ | |
| 54 | + | .joe_detail__friends-item .contain { | |
| 55 | + | position: relative; | |
| 56 | + | overflow: hidden; | |
| 57 | + | background: rgba(255, 255, 255, 0.1) !important; | |
| 58 | + | backdrop-filter: blur(10px); | |
| 59 | + | box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); | |
| 60 | + | border-radius: 12px; | |
| 61 | + | transition: transform 0.3s ease, box-shadow 0.3s ease; | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | .joe_detail__friends-item .contain::before { | |
| 65 | + | content: ''; | |
| 66 | + | position: absolute; | |
| 67 | + | top: 0; | |
| 68 | + | left: 0; | |
| 69 | + | right: 0; | |
| 70 | + | bottom: 0; | |
| 71 | + | background-image: var(--bg-image); | |
| 72 | + | background-size: cover; | |
| 73 | + | background-position: center; | |
| 74 | + | opacity: 0.5; | |
| 75 | + | z-index: -1; | |
| 76 | + | border-radius: 12px; | |
| 77 | + | } | |
| 78 | + | ||
| 79 | + | .joe_detail__friends-item .contain:hover { | |
| 80 | + | transform: translateY(-5px); | |
| 81 | + | box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); | |
| 82 | + | } | |
| 83 | + | ||
| 84 | + | .joe_detail__friends-item .content { | |
| 85 | + | position: relative; | |
| 86 | + | z-index: 2; | |
| 87 | + | } | |
| 88 | + | ||
| 89 | + | .joe_detail__friends-item .title { | |
| 90 | + | color: #fff; | |
| 91 | + | text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5); | |
| 92 | + | font-weight: bold; | |
| 93 | + | } | |
| 94 | + | ||
| 95 | + | .joe_detail__friends-item .desc { | |
| 96 | + | color: rgba(255, 255, 255, 0.9); | |
| 97 | + | text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); | |
| 98 | + | } | |
| 99 | + | ||
| 100 | + | .joe_detail__friends-item .avatar { | |
| 101 | + | border: 2px solid rgba(255, 255, 255, 0.8); | |
| 102 | + | box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); | |
| 103 | + | } | |
| 104 | + | </style> | |
| 105 | + | </head> | |
| 106 | + | ||
| 107 | + | <body> | |
| 108 | + | <?php $this->need('module/header.php'); ?> | |
| 109 | + | <div id="Joe"> | |
| 110 | + | <div class="joe_container"> | |
| 111 | + | <main class="joe_main"> | |
| 112 | + | <div class="joe_detail" data-cid="<?= $this->cid ?>"> | |
| 113 | + | <?php $this->need('module/single/batten.php'); ?> | |
| 114 | + | <?php $this->need('module/single/article.php'); ?> | |
| 115 | + | <?php | |
| 116 | + | $friends = think\facade\Db::name('friends')->where('status', 1)->whereFindInSet('position', 'single')->order('order', 'desc')->select()->toArray(); | |
| 117 | + | ?> | |
| 118 | + | <?php if (sizeof($friends) > 0 && ($this->options->JFriendsSpiderHide != 'on' || !joe\detectSpider())) : ?> | |
| 119 | + | <style> | |
| 120 | + | .joe_detail__article { | |
| 121 | + | margin-bottom: 0px; | |
| 122 | + | } | |
| 123 | + | </style> | |
| 124 | + | <ul class="joe_detail__friends"> | |
| 125 | + | <?php | |
| 126 | + | if ($this->options->JFriends_shuffle == 'on') shuffle($friends); | |
| 127 | + | foreach ($friends as $item) : | |
| 128 | + | ?> | |
| 129 | + | <li class="joe_detail__friends-item"> | |
| 130 | + | <a class="contain" href="<?= $item['url'] ?>" target="_blank" rel="<?= $item['rel'] ?>" referrer="unsafe-url" style="--bg-image: url('<?= $item['logo'] ?>')"> | |
| 131 | + | <span class="title"><?= $item['title'] ?></span> | |
| 132 | + | <div class="content"> | |
| 133 | + | <div class="desc"><?= $item['description'] ?></div> | |
| 134 | + | <img referrerpolicy="no-referrer" rel="noreferrer" width="40" height="40" class="avatar lazyload" onerror="Joe.avatarError(this)" src="<?= joe\getAvatarLazyload(); ?>" data-src="<?= $item['logo'] ?>" alt="<?= $item['title'] ?>" /> | |
| 135 | + | </div> | |
| 136 | + | </a> | |
| 137 | + | </li> | |
| 138 | + | <?php endforeach; ?> | |
| 139 | + | </ul> | |
| 140 | + | <?php endif; ?> | |
| 141 | + | <?php | |
| 142 | + | if ($this->options->JFriends_Submit == 'on') $this->need('module/friends/submit.php'); | |
| 143 | + | ?> | |
| 144 | + | <?php $this->need('module/single/handle.php'); ?> | |
| 145 | + | <?php $this->need('module/single/copyright.php'); ?> | |
| 146 | + | </div> | |
| 147 | + | <?php $this->need('module/single/comment.php'); ?> | |
| 148 | + | </main> | |
| 149 | + | <?php joe\isPc() ? $this->need('module/aside.php') : null ?> | |
| 150 | + | </div> | |
| 151 | + | <?php $this->need('module/bottom.php'); ?> | |
| 152 | + | </div> | |
| 153 | + | <?php $this->need('module/footer.php') ?> | |
| 154 | + | <script> | |
| 155 | + | function addStatusTagsWithCache(jsonUrl) { | |
| 156 | + | const cacheKey = "statusTagsData"; | |
| 157 | + | const cacheExpirationTime = 30 * 60 * 1000; // 半小时 | |
| 158 | + | function applyStatusTags(data) { | |
| 159 | + | const linkStatus = data.link_status; | |
| 160 | + | document.querySelectorAll('.joe_detail__friends-item').forEach(card => { | |
| 161 | + | const linkAnchor = card.querySelector('a.contain'); | |
| 162 | + | if (!linkAnchor) return; | |
| 163 | + | const link = linkAnchor.href.replace(/\/$/, ''); | |
| 164 | + | const statusTag = document.createElement('div'); | |
| 165 | + | statusTag.classList.add('status-tag'); | |
| 166 | + | let matched = false; | |
| 167 | + | // 查找链接状态 | |
| 168 | + | const status = linkStatus.find(item => item.link.replace(/\/$/, '') === link); | |
| 169 | + | if (status) { | |
| 170 | + | let latencyText = '未知'; | |
| 171 | + | let className = 'status-tag-red'; // 默认红色 | |
| 172 | + | if (status.latency === -1) { | |
| 173 | + | latencyText = '未知'; | |
| 174 | + | } else { | |
| 175 | + | latencyText = status.latency.toFixed(2) + ' s'; | |
| 176 | + | if (status.latency <= 2) { | |
| 177 | + | className = 'status-tag-green'; | |
| 178 | + | } else if (status.latency <= 5) { | |
| 179 | + | className = 'status-tag-light-yellow'; | |
| 180 | + | } else if (status.latency <= 10) { | |
| 181 | + | className = 'status-tag-dark-yellow'; | |
| 182 | + | } | |
| 183 | + | } | |
| 184 | + | statusTag.textContent = latencyText; | |
| 185 | + | statusTag.classList.add(className); | |
| 186 | + | matched = true; | |
| 187 | + | } | |
| 188 | + | if (matched) { | |
| 189 | + | card.style.position = 'relative'; | |
| 190 | + | card.appendChild(statusTag); | |
| 191 | + | } | |
| 192 | + | }); | |
| 193 | + | } | |
| 194 | + | function fetchDataAndUpdateUI() { | |
| 195 | + | fetch(jsonUrl) | |
| 196 | + | .then(response => response.json()) | |
| 197 | + | .then(data => { | |
| 198 | + | applyStatusTags(data); | |
| 199 | + | const cacheData = { | |
| 200 | + | data: data, | |
| 201 | + | timestamp: Date.now() | |
| 202 | + | }; | |
| 203 | + | localStorage.setItem(cacheKey, JSON.stringify(cacheData)); | |
| 204 | + | }) | |
| 205 | + | .catch(error => console.error('Error fetching test-flink result.json:', error)); | |
| 206 | + | } | |
| 207 | + | const cachedData = localStorage.getItem(cacheKey); | |
| 208 | + | if (cachedData) { | |
| 209 | + | const { data, timestamp } = JSON.parse(cachedData); | |
| 210 | + | if (Date.now() - timestamp < cacheExpirationTime) { | |
| 211 | + | applyStatusTags(data); | |
| 212 | + | return; | |
| 213 | + | } | |
| 214 | + | } | |
| 215 | + | fetchDataAndUpdateUI(); | |
| 216 | + | } | |
| 217 | + | setTimeout(() => { | |
| 218 | + | addStatusTagsWithCache('https://你的部署地址/result.json'); | |
| 219 | + | }, 0); | |
| 220 | + | </script> | |
| 221 | + | </body> | |
| 222 | + | ||
| 223 | + | </html> | |
Newer
Older