Naposledy aktivní 2 months ago

友人帐页面新增延迟展示

Joe

qxzhan's Avatar qxzhan revidoval tento gist 2 months ago. Přejít na revizi

1 file changed, 223 insertions

php(vytvořil soubor)

@@ -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>
Novější Starší